Impact
Part A (timeout): Any recall() call on a slower or less stable connection will abort after exactly 15 seconds with no way to extend it there is no timeoutMs (or equivalent) field anywhere in the public RecallOptions/RecallParams types. This is a strictly worse experience than remember()'s equivalent path, which at least exposes a configurable timeoutMs via waitForRememberJob.
Part B (total semantics): RecallResult.total has zero JSDoc anywhere it's declared, across both the single-item and bulk-accepted result types. In practice, total reflects the count of items returned in this specific response (bounded by limit, default 10), not the count of matching records that exist in the namespace. A developer who reasonably assumes total means "how many records match in the whole namespace" will draw false conclusions about their data for example, believing writes were lost or a namespace was cleared, when the real explanation is simply the default/requested limit being reached.
Expected Behavior
recall() should expose a configurable timeout, consistent with waitForRememberJob's pattern.
RecallResult.total (and RememberBulkAcceptedResult.total) should carry a doc comment clarifying exactly what is being counted.
Actual Behavior
Timeout (memwal.js, inside recall()):
const ac = new AbortController();
const tid = setTimeout(() => ac.abort(), 15000);
This value is not derived from any option in RecallOptions/RecallParams (types.d.ts), which only exposes limit, topK, namespace, and maxDistance — no timeoutMs field exists to override it.
total field (types.d.ts):
export interface RecallResult {
results: RecallMemory[];
total: number;
}
No doc comment on total, in contrast to nearly every other field in the same file (e.g. limit, maxDistance, and every field in ScoringWeights carry explicit /** ... */ comments).
Reproduction
// Timeout: no way to extend past 15s even if intentionally desired
const result = await memwal.recall({ query: "...", namespace: "big-namespace" });
// On a slow connection: [DOMException [AbortError]: This operation was aborted]
// with zero configuration option to work around it.
// total semantics: misleading on a namespace with more than `limit` records
const r1 = await memwal.recall({ query: "x", namespace: "ns", limit: 5 });
console.log(r1.total); // 5 — easy to misread as "5 records exist in ns"
const r2 = await memwal.recall({ query: "x", namespace: "ns", limit: 20 });
console.log(r2.total); // 8 — the real count, only visible once limit is raised
Real-world evidence
Encountered directly during development: a recall() call against a namespace known to contain real, previously-confirmed blobs (verified separately via unique blob IDs returned at write time) intermittently returned total: 0, and separately returned inconsistent totals (4 vs. 8) across near-identical queries against the same namespace both fully explained once the default limit: 10 behavior was understood, but not documented anywhere in the type surface.
Suggested Fix
Add a timeoutMs option to RecallOptions, threaded through to the internal AbortController, defaulting to the current hardcoded 15000ms for backward compatibility.
Add a doc comment to RecallResult.total and RememberBulkAcceptedResult.total explicitly stating whether it reflects "items in this response" vs. "items matching in the namespace" — and if it is the former, consider renaming to returned or exposing a separate namespaceTotal for the latter, since total strongly implies the whole-namespace count to most readers.
(Evidence for this issue is a direct source-code citation plus a real-world friction log, both quoted exactly above.)
Impact
Part A (timeout): Any recall() call on a slower or less stable connection will abort after exactly 15 seconds with no way to extend it there is no timeoutMs (or equivalent) field anywhere in the public RecallOptions/RecallParams types. This is a strictly worse experience than remember()'s equivalent path, which at least exposes a configurable timeoutMs via waitForRememberJob.
Part B (total semantics): RecallResult.total has zero JSDoc anywhere it's declared, across both the single-item and bulk-accepted result types. In practice, total reflects the count of items returned in this specific response (bounded by limit, default 10), not the count of matching records that exist in the namespace. A developer who reasonably assumes total means "how many records match in the whole namespace" will draw false conclusions about their data for example, believing writes were lost or a namespace was cleared, when the real explanation is simply the default/requested limit being reached.
Expected Behavior
recall() should expose a configurable timeout, consistent with waitForRememberJob's pattern.
RecallResult.total (and RememberBulkAcceptedResult.total) should carry a doc comment clarifying exactly what is being counted.
Actual Behavior
Timeout (memwal.js, inside recall()):
This value is not derived from any option in RecallOptions/RecallParams (types.d.ts), which only exposes limit, topK, namespace, and maxDistance — no timeoutMs field exists to override it.
total field (types.d.ts):
No doc comment on total, in contrast to nearly every other field in the same file (e.g. limit, maxDistance, and every field in ScoringWeights carry explicit /** ... */ comments).
Reproduction
Real-world evidence
Encountered directly during development: a recall() call against a namespace known to contain real, previously-confirmed blobs (verified separately via unique blob IDs returned at write time) intermittently returned total: 0, and separately returned inconsistent totals (4 vs. 8) across near-identical queries against the same namespace both fully explained once the default limit: 10 behavior was understood, but not documented anywhere in the type surface.
Suggested Fix
Add a timeoutMs option to RecallOptions, threaded through to the internal AbortController, defaulting to the current hardcoded 15000ms for backward compatibility.
Add a doc comment to RecallResult.total and RememberBulkAcceptedResult.total explicitly stating whether it reflects "items in this response" vs. "items matching in the namespace" — and if it is the former, consider renaming to returned or exposing a separate namespaceTotal for the latter, since total strongly implies the whole-namespace count to most readers.
(Evidence for this issue is a direct source-code citation plus a real-world friction log, both quoted exactly above.)