@remnic/core 9.3.654 → 9.3.655

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/dist/access-cli.js +23 -23
  2. package/dist/access-http.d.ts +4 -4
  3. package/dist/access-http.js +16 -16
  4. package/dist/access-mcp.d.ts +4 -4
  5. package/dist/access-mcp.js +15 -15
  6. package/dist/{access-service-C8A5hoXJ.d.ts → access-service-BEJvriUt.d.ts} +2 -2
  7. package/dist/access-service.d.ts +4 -4
  8. package/dist/access-service.js +14 -14
  9. package/dist/action-confidence.d.ts +1 -1
  10. package/dist/active-memory-bridge.d.ts +1 -1
  11. package/dist/active-recall.d.ts +1 -1
  12. package/dist/active-recall.js +1 -1
  13. package/dist/behavior-learner.d.ts +1 -1
  14. package/dist/behavior-signals.d.ts +1 -1
  15. package/dist/bootstrap.d.ts +3 -3
  16. package/dist/briefing.d.ts +1 -1
  17. package/dist/briefing.js +3 -3
  18. package/dist/buffer-surprise-report.d.ts +1 -1
  19. package/dist/buffer.d.ts +1 -1
  20. package/dist/calibration.d.ts +1 -1
  21. package/dist/causal-behavior.d.ts +1 -1
  22. package/dist/causal-consolidation.d.ts +1 -1
  23. package/dist/causal-consolidation.js +4 -4
  24. package/dist/{chunk-BP2EV6W5.js → chunk-2RCGZ67B.js} +4 -4
  25. package/dist/{chunk-FVRBLJP6.js → chunk-54LOUIBE.js} +2 -2
  26. package/dist/{chunk-LJCEWTG3.js → chunk-55ZMNKMQ.js} +8 -8
  27. package/dist/{chunk-7WEB3FLJ.js → chunk-5PLUC5OB.js} +2 -2
  28. package/dist/{chunk-OL2364SB.js → chunk-5QD3QD76.js} +854 -223
  29. package/dist/chunk-5QD3QD76.js.map +1 -0
  30. package/dist/{chunk-DBM2BD22.js → chunk-67G4T7KI.js} +3 -3
  31. package/dist/{chunk-JX2RINDR.js → chunk-6G5JEN55.js} +2 -2
  32. package/dist/{chunk-2DSTAWNZ.js → chunk-A3Y37UWI.js} +3 -3
  33. package/dist/{chunk-T2C6QJG2.js → chunk-BGKXTVNG.js} +2 -2
  34. package/dist/{chunk-JYN7QNTA.js → chunk-COVZLGMR.js} +17 -17
  35. package/dist/{chunk-JVRPJ7D4.js → chunk-EKQMQQ3U.js} +48 -12
  36. package/dist/chunk-EKQMQQ3U.js.map +1 -0
  37. package/dist/{chunk-JBHXMCYN.js → chunk-GRYAECRV.js} +2 -2
  38. package/dist/{chunk-RGPUQ66K.js → chunk-IQ53ZSXV.js} +2 -2
  39. package/dist/{chunk-YLZLPVKK.js → chunk-KOI765XP.js} +104 -1
  40. package/dist/chunk-KOI765XP.js.map +1 -0
  41. package/dist/{chunk-QW6JZO5P.js → chunk-KZZ4YAEC.js} +2 -2
  42. package/dist/{chunk-2DGQLOOM.js → chunk-M3VYPE2H.js} +1 -1
  43. package/dist/{chunk-2DGQLOOM.js.map → chunk-M3VYPE2H.js.map} +1 -1
  44. package/dist/{chunk-QKK64Z6M.js → chunk-NCSJKK23.js} +2 -2
  45. package/dist/{chunk-NCGWXCSW.js → chunk-NRBGRZW4.js} +2 -2
  46. package/dist/{chunk-GPW2E4LN.js → chunk-OKW6F5S5.js} +3 -3
  47. package/dist/{chunk-Y2RIIF6H.js → chunk-PTMJ2FH2.js} +2 -2
  48. package/dist/{chunk-JMQSYGXS.js → chunk-PVE7KSQP.js} +2 -2
  49. package/dist/{chunk-NAZWHTYV.js → chunk-QDVQ4AN2.js} +4 -4
  50. package/dist/{chunk-PYWNNF2I.js → chunk-QRSKPI62.js} +99 -66
  51. package/dist/chunk-QRSKPI62.js.map +1 -0
  52. package/dist/{chunk-YM3LR4LS.js → chunk-SSSXWIBP.js} +5 -5
  53. package/dist/{chunk-NE2JBMLN.js → chunk-TDZSSJV4.js} +1 -1
  54. package/dist/chunk-TDZSSJV4.js.map +1 -0
  55. package/dist/{chunk-6CVI6BP6.js → chunk-TEO46GMM.js} +2 -2
  56. package/dist/{chunk-K6X553JB.js → chunk-UCEABZZN.js} +2 -2
  57. package/dist/{chunk-ENV6RDTD.js → chunk-UCEDY5M7.js} +2 -2
  58. package/dist/{chunk-ZCORQM74.js → chunk-UYNFWZWG.js} +2 -2
  59. package/dist/{chunk-XWQ6ERUG.js → chunk-WDTUYOLS.js} +2 -2
  60. package/dist/{chunk-Z5MQI7K2.js → chunk-XOFXKASO.js} +2 -2
  61. package/dist/{chunk-3RACUBII.js → chunk-XRKQOQLY.js} +2 -2
  62. package/dist/{chunk-BJA6DQOC.js → chunk-YYN3LIYA.js} +5 -5
  63. package/dist/{cli-uQgvDFNE.d.ts → cli-BGahB_d3.d.ts} +3 -3
  64. package/dist/cli.d.ts +5 -5
  65. package/dist/cli.js +28 -28
  66. package/dist/compounding/engine.d.ts +1 -1
  67. package/dist/compounding/engine.js +3 -3
  68. package/dist/compounding/preference-consolidator.d.ts +1 -1
  69. package/dist/compression-optimizer.d.ts +1 -1
  70. package/dist/config.d.ts +1 -1
  71. package/dist/config.js +1 -1
  72. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  73. package/dist/connectors/codex-materialize-runner.js +3 -3
  74. package/dist/connectors/codex-materialize.d.ts +1 -1
  75. package/dist/connectors/index.d.ts +1 -1
  76. package/dist/connectors/index.js +3 -3
  77. package/dist/consolidation-provenance-check.d.ts +1 -1
  78. package/dist/consolidation-undo.d.ts +1 -1
  79. package/dist/contradiction/index.d.ts +1 -1
  80. package/dist/conversation-index/backend.d.ts +1 -1
  81. package/dist/conversation-index/chunker.d.ts +1 -1
  82. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  83. package/dist/conversation-index/indexer.d.ts +1 -1
  84. package/dist/conversation-index/search.d.ts +1 -1
  85. package/dist/day-summary.d.ts +1 -1
  86. package/dist/delinearize.d.ts +1 -1
  87. package/dist/direct-answer-wiring.d.ts +1 -1
  88. package/dist/direct-answer.d.ts +1 -1
  89. package/dist/embedding-fallback.d.ts +1 -1
  90. package/dist/enrichment/index.d.ts +1 -1
  91. package/dist/entity-retrieval.d.ts +1 -1
  92. package/dist/entity-retrieval.js +3 -3
  93. package/dist/entity-schema.d.ts +1 -1
  94. package/dist/explicit-capture.d.ts +3 -3
  95. package/dist/extraction-judge-telemetry.d.ts +1 -1
  96. package/dist/extraction-judge-training.d.ts +1 -1
  97. package/dist/extraction-judge.d.ts +1 -1
  98. package/dist/extraction.d.ts +1 -1
  99. package/dist/fallback-llm.d.ts +1 -1
  100. package/dist/identity-continuity.d.ts +1 -1
  101. package/dist/importance.d.ts +1 -1
  102. package/dist/index.d.ts +8 -8
  103. package/dist/index.js +33 -33
  104. package/dist/intent.d.ts +1 -1
  105. package/dist/lcm/engine.d.ts +1 -1
  106. package/dist/lcm/index.d.ts +1 -1
  107. package/dist/lcm/tools.d.ts +1 -1
  108. package/dist/lifecycle.d.ts +1 -1
  109. package/dist/live-connectors-runner.d.ts +1 -1
  110. package/dist/local-llm.d.ts +1 -1
  111. package/dist/maintenance/memory-governance.d.ts +1 -1
  112. package/dist/maintenance/memory-governance.js +3 -3
  113. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
  114. package/dist/maintenance/rebuild-memory-projection.js +4 -4
  115. package/dist/mcp-memory-inspector-app.d.ts +4 -4
  116. package/dist/memory-action-policy.d.ts +1 -1
  117. package/dist/memory-cache.d.ts +1 -1
  118. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  119. package/dist/memory-projection-store.d.ts +1 -1
  120. package/dist/memory-provenance.d.ts +1 -1
  121. package/dist/memory-worth-outcomes.d.ts +1 -1
  122. package/dist/models-json.d.ts +1 -1
  123. package/dist/namespaces/migrate.d.ts +1 -1
  124. package/dist/namespaces/migrate.js +11 -11
  125. package/dist/namespaces/principal.d.ts +1 -1
  126. package/dist/namespaces/search.d.ts +15 -4
  127. package/dist/namespaces/search.js +7 -7
  128. package/dist/namespaces/storage.d.ts +1 -1
  129. package/dist/namespaces/storage.js +3 -3
  130. package/dist/native-knowledge.d.ts +1 -1
  131. package/dist/operator-toolkit.d.ts +1 -1
  132. package/dist/operator-toolkit.js +14 -14
  133. package/dist/{orchestrator-B4Y4sWQH.d.ts → orchestrator-BgzZlWxH.d.ts} +11 -14
  134. package/dist/orchestrator.d.ts +3 -3
  135. package/dist/orchestrator.js +19 -19
  136. package/dist/patterns-cli.d.ts +1 -1
  137. package/dist/policy-runtime.d.ts +1 -1
  138. package/dist/qmd-recall-cache.d.ts +1 -1
  139. package/dist/qmd.d.ts +5 -1
  140. package/dist/qmd.js +2 -2
  141. package/dist/recall-disclosure-escalation.d.ts +1 -1
  142. package/dist/recall-explain-renderer.d.ts +1 -1
  143. package/dist/recall-explain-renderer.js +3 -3
  144. package/dist/recall-planner-llm.d.ts +1 -1
  145. package/dist/recall-state.d.ts +1 -1
  146. package/dist/recall-tag-filter.d.ts +1 -1
  147. package/dist/recall-xray-cli.d.ts +1 -1
  148. package/dist/recall-xray-cli.js +4 -4
  149. package/dist/recall-xray-renderer.d.ts +1 -1
  150. package/dist/recall-xray-renderer.js +3 -3
  151. package/dist/recall-xray.d.ts +1 -1
  152. package/dist/recall-xray.js +2 -2
  153. package/dist/resolve-auth-token.d.ts +1 -1
  154. package/dist/resume-bundles.js +2 -2
  155. package/dist/retrieval-agents.d.ts +1 -1
  156. package/dist/retrieval-tiers.d.ts +1 -1
  157. package/dist/routing/engine.d.ts +1 -1
  158. package/dist/routing/store.d.ts +1 -1
  159. package/dist/schemas.d.ts +22 -22
  160. package/dist/search/embed-helper.d.ts +1 -1
  161. package/dist/search/factory.d.ts +1 -1
  162. package/dist/search/factory.js +6 -6
  163. package/dist/search/index.d.ts +1 -1
  164. package/dist/search/index.js +6 -6
  165. package/dist/search/lancedb-backend.d.ts +1 -1
  166. package/dist/search/lancedb-backend.js +2 -2
  167. package/dist/search/meilisearch-backend.d.ts +1 -1
  168. package/dist/search/meilisearch-backend.js +2 -2
  169. package/dist/search/noop-backend.d.ts +1 -1
  170. package/dist/search/orama-backend.d.ts +1 -1
  171. package/dist/search/orama-backend.js +2 -2
  172. package/dist/search/port.d.ts +17 -1
  173. package/dist/search/port.js +1 -1
  174. package/dist/search/remote-backend.d.ts +1 -1
  175. package/dist/{semantic-consolidation-BKd0Pype.d.ts → semantic-consolidation-Z8d_uMq8.d.ts} +1 -1
  176. package/dist/semantic-consolidation.d.ts +2 -2
  177. package/dist/semantic-consolidation.js +4 -4
  178. package/dist/semantic-rule-promotion.js +3 -3
  179. package/dist/semantic-rule-verifier.d.ts +1 -1
  180. package/dist/semantic-rule-verifier.js +3 -3
  181. package/dist/session-observer-bands.d.ts +1 -1
  182. package/dist/session-observer-state.d.ts +1 -1
  183. package/dist/shared-context/manager.d.ts +1 -1
  184. package/dist/signal.d.ts +1 -1
  185. package/dist/storage.d.ts +1 -1
  186. package/dist/storage.js +2 -2
  187. package/dist/summarizer.d.ts +1 -1
  188. package/dist/summary-snapshot.d.ts +1 -1
  189. package/dist/temporal-supersession.d.ts +1 -1
  190. package/dist/temporal-validity.d.ts +1 -1
  191. package/dist/threading.d.ts +1 -1
  192. package/dist/tier-migration.d.ts +1 -1
  193. package/dist/tier-routing.d.ts +1 -1
  194. package/dist/topics.d.ts +1 -1
  195. package/dist/transcript.d.ts +1 -1
  196. package/dist/transfer/types.d.ts +12 -12
  197. package/dist/{types-BgChEr0M.d.ts → types-2OPlQWJG.d.ts} +12 -0
  198. package/dist/types.d.ts +1 -1
  199. package/dist/types.js +1 -1
  200. package/dist/utility-runtime.d.ts +1 -1
  201. package/dist/verified-recall.js +3 -3
  202. package/package.json +1 -1
  203. package/src/config.test.ts +69 -0
  204. package/src/config.ts +135 -0
  205. package/src/maintenance/namespace-planner.test.ts +1120 -0
  206. package/src/maintenance/namespace-planner.ts +893 -0
  207. package/src/namespaces/search.test.ts +130 -2
  208. package/src/namespaces/search.ts +71 -10
  209. package/src/orchestrator-flush.test.ts +464 -44
  210. package/src/orchestrator.ts +97 -66
  211. package/src/qmd-client.test.ts +59 -0
  212. package/src/qmd.ts +124 -84
  213. package/src/search/port.ts +16 -0
  214. package/src/types.ts +12 -0
  215. package/dist/chunk-JVRPJ7D4.js.map +0 -1
  216. package/dist/chunk-NE2JBMLN.js.map +0 -1
  217. package/dist/chunk-OL2364SB.js.map +0 -1
  218. package/dist/chunk-PYWNNF2I.js.map +0 -1
  219. package/dist/chunk-YLZLPVKK.js.map +0 -1
  220. /package/dist/{chunk-BP2EV6W5.js.map → chunk-2RCGZ67B.js.map} +0 -0
  221. /package/dist/{chunk-FVRBLJP6.js.map → chunk-54LOUIBE.js.map} +0 -0
  222. /package/dist/{chunk-LJCEWTG3.js.map → chunk-55ZMNKMQ.js.map} +0 -0
  223. /package/dist/{chunk-7WEB3FLJ.js.map → chunk-5PLUC5OB.js.map} +0 -0
  224. /package/dist/{chunk-DBM2BD22.js.map → chunk-67G4T7KI.js.map} +0 -0
  225. /package/dist/{chunk-JX2RINDR.js.map → chunk-6G5JEN55.js.map} +0 -0
  226. /package/dist/{chunk-2DSTAWNZ.js.map → chunk-A3Y37UWI.js.map} +0 -0
  227. /package/dist/{chunk-T2C6QJG2.js.map → chunk-BGKXTVNG.js.map} +0 -0
  228. /package/dist/{chunk-JYN7QNTA.js.map → chunk-COVZLGMR.js.map} +0 -0
  229. /package/dist/{chunk-JBHXMCYN.js.map → chunk-GRYAECRV.js.map} +0 -0
  230. /package/dist/{chunk-RGPUQ66K.js.map → chunk-IQ53ZSXV.js.map} +0 -0
  231. /package/dist/{chunk-QW6JZO5P.js.map → chunk-KZZ4YAEC.js.map} +0 -0
  232. /package/dist/{chunk-QKK64Z6M.js.map → chunk-NCSJKK23.js.map} +0 -0
  233. /package/dist/{chunk-NCGWXCSW.js.map → chunk-NRBGRZW4.js.map} +0 -0
  234. /package/dist/{chunk-GPW2E4LN.js.map → chunk-OKW6F5S5.js.map} +0 -0
  235. /package/dist/{chunk-Y2RIIF6H.js.map → chunk-PTMJ2FH2.js.map} +0 -0
  236. /package/dist/{chunk-JMQSYGXS.js.map → chunk-PVE7KSQP.js.map} +0 -0
  237. /package/dist/{chunk-NAZWHTYV.js.map → chunk-QDVQ4AN2.js.map} +0 -0
  238. /package/dist/{chunk-YM3LR4LS.js.map → chunk-SSSXWIBP.js.map} +0 -0
  239. /package/dist/{chunk-6CVI6BP6.js.map → chunk-TEO46GMM.js.map} +0 -0
  240. /package/dist/{chunk-K6X553JB.js.map → chunk-UCEABZZN.js.map} +0 -0
  241. /package/dist/{chunk-ENV6RDTD.js.map → chunk-UCEDY5M7.js.map} +0 -0
  242. /package/dist/{chunk-ZCORQM74.js.map → chunk-UYNFWZWG.js.map} +0 -0
  243. /package/dist/{chunk-XWQ6ERUG.js.map → chunk-WDTUYOLS.js.map} +0 -0
  244. /package/dist/{chunk-Z5MQI7K2.js.map → chunk-XOFXKASO.js.map} +0 -0
  245. /package/dist/{chunk-3RACUBII.js.map → chunk-XRKQOQLY.js.map} +0 -0
  246. /package/dist/{chunk-BJA6DQOC.js.map → chunk-YYN3LIYA.js.map} +0 -0
@@ -13,6 +13,12 @@ type CollectionState = "present" | "missing" | "unknown" | "skipped";
13
13
 
14
14
  class FakeBackend implements SearchBackend {
15
15
  updates = 0;
16
+ strictUpdates = 0;
17
+ strictCollectionUpdates: string[] = [];
18
+ embeds = 0;
19
+ collectionEmbeds: string[] = [];
20
+ strictEmbeds = 0;
21
+ strictCollectionEmbeds: string[] = [];
16
22
  disposed = 0;
17
23
  available = true;
18
24
  calls: Array<{
@@ -130,15 +136,35 @@ class FakeBackend implements SearchBackend {
130
136
  this.updates += 1;
131
137
  }
132
138
 
139
+ async updateStrict(): Promise<void> {
140
+ this.strictUpdates += 1;
141
+ }
142
+
133
143
  async updateCollection(): Promise<void> {}
134
144
 
145
+ async updateCollectionStrict(collection: string): Promise<void> {
146
+ this.strictCollectionUpdates.push(collection);
147
+ }
148
+
135
149
  updatesAllCollections(): boolean {
136
150
  return this.globalUpdate;
137
151
  }
138
152
 
139
- async embed(): Promise<void> {}
153
+ async embed(): Promise<void> {
154
+ this.embeds += 1;
155
+ }
156
+
157
+ async embedStrict(): Promise<void> {
158
+ this.strictEmbeds += 1;
159
+ }
140
160
 
141
- async embedCollection(): Promise<void> {}
161
+ async embedCollection(collection: string): Promise<void> {
162
+ this.collectionEmbeds.push(collection);
163
+ }
164
+
165
+ async embedCollectionStrict(collection: string): Promise<void> {
166
+ this.strictCollectionEmbeds.push(collection);
167
+ }
142
168
 
143
169
  async ensureCollection(
144
170
  _memoryDir?: string,
@@ -253,6 +279,108 @@ test("updateNamespaces still updates every namespace for scoped backends", async
253
279
  assert.equal(created.reduce((sum, backend) => sum + backend.updates, 0), 3);
254
280
  });
255
281
 
282
+ test("updateNamespaces uses strict global update when requested", async () => {
283
+ const created: FakeBackend[] = [];
284
+ const router = new NamespaceSearchRouter(
285
+ config(),
286
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
287
+ () => {
288
+ const backend = new FakeBackend(true);
289
+ created.push(backend);
290
+ return backend;
291
+ },
292
+ );
293
+
294
+ const updated = await router.updateNamespaces(
295
+ ["main", "shared", "main", "project"],
296
+ undefined,
297
+ { strict: true },
298
+ );
299
+
300
+ assert.equal(updated, 1);
301
+ assert.equal(created.reduce((sum, backend) => sum + backend.strictUpdates, 0), 1);
302
+ assert.equal(created.reduce((sum, backend) => sum + backend.updates, 0), 0);
303
+ });
304
+
305
+ test("updateNamespaces uses strict collection updates for scoped backends when requested", async () => {
306
+ const created: FakeBackend[] = [];
307
+ const router = new NamespaceSearchRouter(
308
+ config(),
309
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
310
+ () => {
311
+ const backend = new FakeBackend(false);
312
+ created.push(backend);
313
+ return backend;
314
+ },
315
+ );
316
+
317
+ const updated = await router.updateNamespaces(
318
+ ["main", "shared", "main", "project"],
319
+ undefined,
320
+ { strict: true },
321
+ );
322
+
323
+ assert.equal(updated, 3);
324
+ assert.equal(created.reduce((sum, backend) => sum + backend.strictCollectionUpdates.length, 0), 3);
325
+ assert.equal(created.reduce((sum, backend) => sum + backend.updates, 0), 0);
326
+ });
327
+
328
+ test("embedNamespaces uses strict collection embeds when requested", async () => {
329
+ const created: FakeBackend[] = [];
330
+ const router = new NamespaceSearchRouter(
331
+ config(),
332
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
333
+ () => {
334
+ const backend = new FakeBackend(false);
335
+ created.push(backend);
336
+ return backend;
337
+ },
338
+ );
339
+
340
+ await router.embedNamespaces(["main", "shared", "main", "project"], { strict: true });
341
+
342
+ assert.equal(created.reduce((sum, backend) => sum + backend.strictCollectionEmbeds.length, 0), 3);
343
+ assert.equal(created.reduce((sum, backend) => sum + backend.collectionEmbeds.length, 0), 0);
344
+ assert.equal(created.reduce((sum, backend) => sum + backend.embeds, 0), 0);
345
+ });
346
+
347
+ test("embedNamespaces propagates strict embed failures", async () => {
348
+ const router = new NamespaceSearchRouter(
349
+ config(),
350
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
351
+ () => {
352
+ const backend = new FakeBackend(false);
353
+ backend.embedCollectionStrict = async () => {
354
+ throw new Error("embed failed");
355
+ };
356
+ return backend;
357
+ },
358
+ );
359
+
360
+ await assert.rejects(
361
+ () => router.embedNamespaces(["main"], { strict: true }),
362
+ /embed failed/,
363
+ );
364
+ });
365
+
366
+ test("updateNamespacesDetailed reports only eligible namespaces", async () => {
367
+ const router = new NamespaceSearchRouter(
368
+ config(),
369
+ { storageFor: async (namespace: string) => ({ dir: `/tmp/remnic/${namespace}` }) },
370
+ (scopedConfig) => {
371
+ const backend = new FakeBackend(false, [], {
372
+ ensure: scopedConfig.memoryDir.endsWith("/missing") ? "missing" : "present",
373
+ });
374
+ return backend;
375
+ },
376
+ );
377
+
378
+ const result = await router.updateNamespacesDetailed(["main", "missing", "shared"]);
379
+
380
+ assert.equal(result.backendCount, 2);
381
+ assert.deepEqual(result.eligibleNamespaces.sort(), ["main", "shared"]);
382
+ });
383
+
256
384
  test("searchAcrossNamespaces preserves same path results from distinct namespaces", async () => {
257
385
  const router = new NamespaceSearchRouter(
258
386
  config(),
@@ -44,6 +44,11 @@ type NamespaceBackendRecord = {
44
44
  filtersNestedNamespaces: boolean;
45
45
  };
46
46
 
47
+ export interface NamespaceUpdateResult {
48
+ backendCount: number;
49
+ eligibleNamespaces: string[];
50
+ }
51
+
47
52
  export type CollectionState = "present" | "missing" | "unknown" | "skipped";
48
53
 
49
54
  export interface NamespaceSearchHealth {
@@ -161,37 +166,51 @@ export class NamespaceSearchRouter {
161
166
  async updateNamespaces(
162
167
  namespaces: string[],
163
168
  execution?: SearchExecutionOptions,
169
+ options?: { strict?: boolean },
164
170
  ): Promise<number> {
171
+ return (await this.updateNamespacesDetailed(namespaces, execution, options)).backendCount;
172
+ }
173
+
174
+ async updateNamespacesDetailed(
175
+ namespaces: string[],
176
+ execution?: SearchExecutionOptions,
177
+ options?: { strict?: boolean },
178
+ ): Promise<NamespaceUpdateResult> {
165
179
  const unique = Array.from(new Set(namespaces.map((value) => value.trim()).filter(Boolean)));
166
180
  const eligible = (await Promise.all(
167
181
  unique.map(async (namespace) => {
168
182
  const record = await this.backendRecordFor(namespace);
169
183
  return record.available && record.collectionState !== "missing"
170
- ? record
184
+ ? { namespace, record }
171
185
  : null;
172
186
  }),
173
- )).filter((record): record is NamespaceBackendRecord => record !== null);
187
+ )).filter((entry): entry is { namespace: string; record: NamespaceBackendRecord } => entry !== null);
174
188
 
175
- const globalRecord = eligible.find((record) => record.backend.updatesAllCollections?.() === true);
176
- const scopedRecords = globalRecord
177
- ? eligible.filter((record) => record.backend.updatesAllCollections?.() !== true)
189
+ const globalEntry = eligible.find(({ record }) => record.backend.updatesAllCollections?.() === true);
190
+ const scopedEntries = globalEntry
191
+ ? eligible.filter(({ record }) => record.backend.updatesAllCollections?.() !== true)
178
192
  : eligible;
179
193
 
180
194
  await Promise.all([
181
- globalRecord ? globalRecord.backend.update(execution) : Promise.resolve(),
182
- ...scopedRecords.map((record) => record.backend.update(execution)),
195
+ globalEntry
196
+ ? updateBackendRecord(globalEntry.record, execution, options)
197
+ : Promise.resolve(),
198
+ ...scopedEntries.map(({ record }) => updateBackendRecord(record, execution, options)),
183
199
  ]);
184
200
 
185
- return (globalRecord ? 1 : 0) + scopedRecords.length;
201
+ return {
202
+ backendCount: (globalEntry ? 1 : 0) + scopedEntries.length,
203
+ eligibleNamespaces: eligible.map(({ namespace }) => namespace),
204
+ };
186
205
  }
187
206
 
188
- async embedNamespaces(namespaces: string[]): Promise<void> {
207
+ async embedNamespaces(namespaces: string[], options?: { strict?: boolean }): Promise<void> {
189
208
  const unique = Array.from(new Set(namespaces.map((value) => value.trim()).filter(Boolean)));
190
209
  await Promise.all(
191
210
  unique.map(async (namespace) => {
192
211
  const record = await this.backendRecordFor(namespace);
193
212
  if (!record.available || record.collectionState === "missing") return;
194
- await record.backend.embed();
213
+ await embedBackendRecord(record, options);
195
214
  }),
196
215
  );
197
216
  }
@@ -442,6 +461,48 @@ function backendSearchLimit(
442
461
  );
443
462
  }
444
463
 
464
+ async function updateBackendRecord(
465
+ record: NamespaceBackendRecord,
466
+ execution?: SearchExecutionOptions,
467
+ options?: { strict?: boolean },
468
+ ): Promise<void> {
469
+ if (options?.strict === true) {
470
+ if (
471
+ record.backend.updatesAllCollections?.() === true &&
472
+ typeof record.backend.updateStrict === "function"
473
+ ) {
474
+ await record.backend.updateStrict(execution);
475
+ return;
476
+ }
477
+ if (typeof record.backend.updateCollectionStrict === "function") {
478
+ await record.backend.updateCollectionStrict(record.collection, execution);
479
+ return;
480
+ }
481
+ }
482
+ await record.backend.update(execution);
483
+ }
484
+
485
+ async function embedBackendRecord(
486
+ record: NamespaceBackendRecord,
487
+ options?: { strict?: boolean },
488
+ ): Promise<void> {
489
+ if (options?.strict === true) {
490
+ if (typeof record.backend.embedCollectionStrict === "function") {
491
+ await record.backend.embedCollectionStrict(record.collection);
492
+ return;
493
+ }
494
+ if (typeof record.backend.embedStrict === "function") {
495
+ await record.backend.embedStrict();
496
+ return;
497
+ }
498
+ }
499
+ if (typeof record.backend.embedCollection === "function") {
500
+ await record.backend.embedCollection(record.collection);
501
+ return;
502
+ }
503
+ await record.backend.embed();
504
+ }
505
+
445
506
  function daemonModeForBackend(backend: SearchBackend): boolean | null {
446
507
  return "isDaemonMode" in backend && typeof backend.isDaemonMode === "function"
447
508
  ? backend.isDaemonMode() === true