@nxgt/mongo-meilisearch 0.4.2 → 0.4.4

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 (41) hide show
  1. package/dist/index.d.ts +3 -3
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +95 -91
  4. package/dist/index.js.map +9 -9
  5. package/dist/{follow.d.ts → run/follow.d.ts} +2 -2
  6. package/dist/run/follow.d.ts.map +1 -0
  7. package/dist/{lease.d.ts → run/lease.d.ts} +2 -2
  8. package/dist/run/lease.d.ts.map +1 -0
  9. package/dist/{reindex.d.ts → run/reindex.d.ts} +2 -2
  10. package/dist/run/reindex.d.ts.map +1 -0
  11. package/dist/sync/batch.d.ts.map +1 -0
  12. package/dist/{context.d.ts → sync/context.d.ts} +1 -1
  13. package/dist/sync/context.d.ts.map +1 -0
  14. package/dist/sync/create-search-sync.d.ts.map +1 -0
  15. package/dist/sync/documents.d.ts.map +1 -0
  16. package/dist/sync/errors.d.ts.map +1 -0
  17. package/dist/sync/running.d.ts.map +1 -0
  18. package/dist/sync/start.d.ts.map +1 -0
  19. package/dist/sync/state.d.ts.map +1 -0
  20. package/dist/sync/types.d.ts.map +1 -0
  21. package/package.json +5 -5
  22. package/dist/batch.d.ts.map +0 -1
  23. package/dist/context.d.ts.map +0 -1
  24. package/dist/create-search-sync.d.ts.map +0 -1
  25. package/dist/documents.d.ts.map +0 -1
  26. package/dist/errors.d.ts.map +0 -1
  27. package/dist/follow.d.ts.map +0 -1
  28. package/dist/lease.d.ts.map +0 -1
  29. package/dist/reindex.d.ts.map +0 -1
  30. package/dist/running.d.ts.map +0 -1
  31. package/dist/start.d.ts.map +0 -1
  32. package/dist/state.d.ts.map +0 -1
  33. package/dist/types.d.ts.map +0 -1
  34. /package/dist/{batch.d.ts → sync/batch.d.ts} +0 -0
  35. /package/dist/{create-search-sync.d.ts → sync/create-search-sync.d.ts} +0 -0
  36. /package/dist/{documents.d.ts → sync/documents.d.ts} +0 -0
  37. /package/dist/{errors.d.ts → sync/errors.d.ts} +0 -0
  38. /package/dist/{running.d.ts → sync/running.d.ts} +0 -0
  39. /package/dist/{start.d.ts → sync/start.d.ts} +0 -0
  40. /package/dist/{state.d.ts → sync/state.d.ts} +0 -0
  41. /package/dist/{types.d.ts → sync/types.d.ts} +0 -0
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { createSearchSync } from './create-search-sync';
2
- export { SearchSyncError, type SearchSyncErrorCode, type SearchSyncErrorOptions, } from './errors';
3
- export type { ReindexReport, RunningSearchSync, SearchSync, SearchSyncOptions, SearchSyncState, ToIndexId, Transform, } from './types';
1
+ export { createSearchSync } from './sync/create-search-sync';
2
+ export { SearchSyncError, type SearchSyncErrorCode, type SearchSyncErrorOptions, } from './sync/errors';
3
+ export type { ReindexReport, RunningSearchSync, SearchSync, SearchSyncOptions, SearchSyncState, ToIndexId, Transform, } from './sync/types';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EACN,eAAe,EACf,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,GAC3B,MAAM,UAAU,CAAC;AAClB,YAAY,EACX,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,eAAe,EACf,SAAS,EACT,SAAS,GACT,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EACN,eAAe,EACf,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,GAC3B,MAAM,eAAe,CAAC;AACvB,YAAY,EACX,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,eAAe,EACf,SAAS,EACT,SAAS,GACT,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -1,49 +1,7 @@
1
- // src/context.ts
2
- var DEFAULT_STATE_COLLECTION = "nxgt_search_sync";
3
- function positive(option, value, fallback) {
4
- const resolved = value ?? fallback;
5
- if (!Number.isInteger(resolved) || resolved < 1) {
6
- throw new TypeError(`createSearchSync: ${option} must be a whole number above 0, not ${String(value)}`);
7
- }
8
- return resolved;
9
- }
10
- function createContext(options) {
11
- const { collection, index } = options;
12
- if (typeof options.transform !== "function") {
13
- throw new TypeError("createSearchSync: transform must be a function");
14
- }
15
- const name = options.name ?? `${collection.collectionName}:${index.uid}`;
16
- if (name === "") {
17
- throw new TypeError("createSearchSync: name must not be empty");
18
- }
19
- const flushIntervalMs = options.flushIntervalMs ?? 1000;
20
- if (!Number.isInteger(flushIntervalMs) || flushIntervalMs < 0) {
21
- throw new TypeError(`createSearchSync: flushIntervalMs must be a whole number of milliseconds, not ${String(options.flushIntervalMs)}`);
22
- }
23
- const stateCollection = options.stateCollection ?? DEFAULT_STATE_COLLECTION;
24
- return {
25
- name,
26
- collection,
27
- index,
28
- primaryKey: index.definition.primaryKey,
29
- state: collection.db.collection(stateCollection),
30
- leases: collection.db.collection(stateCollection),
31
- leaseMs: positive("leaseMs", options.leaseMs, 30000),
32
- batchSize: positive("batchSize", options.batchSize, 500),
33
- positionIntervalMs: positive("positionIntervalMs", options.positionIntervalMs, 60000),
34
- flushIntervalMs,
35
- pageSize: positive("pageSize", options.pageSize, 100),
36
- onHistoryLost: options.onHistoryLost ?? "reindex",
37
- transform: options.transform,
38
- toIndexId: options.toIndexId ?? String,
39
- follower: { running: false }
40
- };
41
- }
42
-
43
- // src/reindex.ts
1
+ // src/run/reindex.ts
44
2
  import { MeilisearchApiError } from "meilisearch";
45
3
 
46
- // src/batch.ts
4
+ // src/sync/batch.ts
47
5
  var WAIT = { wait: { timeout: 120000 } };
48
6
  function chunks(items, size) {
49
7
  const out = [];
@@ -75,11 +33,15 @@ async function send(ctx, entries) {
75
33
  await deleteIds(ctx, ids);
76
34
  }
77
35
 
78
- // src/errors.ts
36
+ // src/sync/errors.ts
79
37
  class SearchSyncError extends Error {
38
+ name = "SearchSyncError";
39
+ code;
40
+ sync;
41
+ holder;
42
+ expiresAt;
80
43
  constructor(message, options) {
81
44
  super(message, options.cause === undefined ? undefined : { cause: options.cause });
82
- this.name = "SearchSyncError";
83
45
  this.code = options.code;
84
46
  this.sync = options.sync;
85
47
  this.holder = options.holder;
@@ -97,7 +59,7 @@ function failed(sync, doing, error) {
97
59
  });
98
60
  }
99
61
 
100
- // src/documents.ts
62
+ // src/sync/documents.ts
101
63
  var keyOf = (id) => `${typeof id}:${String(id)}`;
102
64
  var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
103
65
  function describe(value) {
@@ -125,7 +87,44 @@ async function entryOf(ctx, mongoId, document) {
125
87
  return { kind: "upsert", key, document: indexed };
126
88
  }
127
89
 
128
- // src/lease.ts
90
+ // src/sync/running.ts
91
+ function checkIdle(ctx, doing) {
92
+ if (!ctx.follower.running)
93
+ return;
94
+ throw new SearchSyncError(`Search sync "${ctx.name}" is already following changes in this ` + `process: close it before you ${doing}.`, { code: "RUNNING", sync: ctx.name });
95
+ }
96
+
97
+ // src/sync/state.ts
98
+ async function readState(ctx) {
99
+ try {
100
+ return await ctx.state.findOne({ _id: ctx.name }) ?? undefined;
101
+ } catch (error) {
102
+ throw failed(ctx.name, "reading its resume point", error);
103
+ }
104
+ }
105
+ async function clearState(ctx) {
106
+ try {
107
+ await ctx.state.deleteOne({ _id: ctx.name });
108
+ } catch (error) {
109
+ throw failed(ctx.name, "forgetting its resume point", error);
110
+ }
111
+ }
112
+ async function saveState(ctx, resumeToken, reindexed) {
113
+ const now = new Date;
114
+ try {
115
+ await ctx.state.updateOne({ _id: ctx.name }, {
116
+ $set: {
117
+ resumeToken,
118
+ updatedAt: now,
119
+ ...reindexed ? { reindexedAt: now } : {}
120
+ }
121
+ }, { upsert: true });
122
+ } catch (error) {
123
+ throw failed(ctx.name, "recording its resume point", error);
124
+ }
125
+ }
126
+
127
+ // src/run/lease.ts
129
128
  import { hostname } from "node:os";
130
129
  import { ObjectId } from "mongodb";
131
130
  var idOf = (ctx) => ({ lease: ctx.name });
@@ -235,44 +234,7 @@ async function withLease(ctx, doing, fn) {
235
234
  }
236
235
  }
237
236
 
238
- // src/running.ts
239
- function checkIdle(ctx, doing) {
240
- if (!ctx.follower.running)
241
- return;
242
- throw new SearchSyncError(`Search sync "${ctx.name}" is already following changes in this ` + `process: close it before you ${doing}.`, { code: "RUNNING", sync: ctx.name });
243
- }
244
-
245
- // src/state.ts
246
- async function readState(ctx) {
247
- try {
248
- return await ctx.state.findOne({ _id: ctx.name }) ?? undefined;
249
- } catch (error) {
250
- throw failed(ctx.name, "reading its resume point", error);
251
- }
252
- }
253
- async function clearState(ctx) {
254
- try {
255
- await ctx.state.deleteOne({ _id: ctx.name });
256
- } catch (error) {
257
- throw failed(ctx.name, "forgetting its resume point", error);
258
- }
259
- }
260
- async function saveState(ctx, resumeToken, reindexed) {
261
- const now = new Date;
262
- try {
263
- await ctx.state.updateOne({ _id: ctx.name }, {
264
- $set: {
265
- resumeToken,
266
- updatedAt: now,
267
- ...reindexed ? { reindexedAt: now } : {}
268
- }
269
- }, { upsert: true });
270
- } catch (error) {
271
- throw failed(ctx.name, "recording its resume point", error);
272
- }
273
- }
274
-
275
- // src/reindex.ts
237
+ // src/run/reindex.ts
276
238
  async function currentToken(ctx) {
277
239
  const stream = ctx.collection.raw.watch([], { maxAwaitTimeMS: 1 });
278
240
  try {
@@ -293,7 +255,7 @@ async function sendAll(ctx, wanted, lease) {
293
255
  });
294
256
  const documents = [];
295
257
  for (const document of page.items) {
296
- const entry = await entryOf(ctx, document._id, document);
258
+ const entry = await entryOf(ctx, document["_id"], document);
297
259
  if (entry.kind === "delete") {
298
260
  skipped += 1;
299
261
  continue;
@@ -351,7 +313,49 @@ async function reindexHeld(ctx, lease) {
351
313
  }
352
314
  }
353
315
 
354
- // src/follow.ts
316
+ // src/sync/context.ts
317
+ var DEFAULT_STATE_COLLECTION = "nxgt_search_sync";
318
+ function positive(option, value, fallback) {
319
+ const resolved = value ?? fallback;
320
+ if (!Number.isInteger(resolved) || resolved < 1) {
321
+ throw new TypeError(`createSearchSync: ${option} must be a whole number above 0, not ${String(value)}`);
322
+ }
323
+ return resolved;
324
+ }
325
+ function createContext(options) {
326
+ const { collection, index } = options;
327
+ if (typeof options.transform !== "function") {
328
+ throw new TypeError("createSearchSync: transform must be a function");
329
+ }
330
+ const name = options.name ?? `${collection.collectionName}:${index.uid}`;
331
+ if (name === "") {
332
+ throw new TypeError("createSearchSync: name must not be empty");
333
+ }
334
+ const flushIntervalMs = options.flushIntervalMs ?? 1000;
335
+ if (!Number.isInteger(flushIntervalMs) || flushIntervalMs < 0) {
336
+ throw new TypeError(`createSearchSync: flushIntervalMs must be a whole number of milliseconds, not ${String(options.flushIntervalMs)}`);
337
+ }
338
+ const stateCollection = options.stateCollection ?? DEFAULT_STATE_COLLECTION;
339
+ return {
340
+ name,
341
+ collection,
342
+ index,
343
+ primaryKey: index.definition.primaryKey,
344
+ state: collection.db.collection(stateCollection),
345
+ leases: collection.db.collection(stateCollection),
346
+ leaseMs: positive("leaseMs", options.leaseMs, 30000),
347
+ batchSize: positive("batchSize", options.batchSize, 500),
348
+ positionIntervalMs: positive("positionIntervalMs", options.positionIntervalMs, 60000),
349
+ flushIntervalMs,
350
+ pageSize: positive("pageSize", options.pageSize, 100),
351
+ onHistoryLost: options.onHistoryLost ?? "reindex",
352
+ transform: options.transform,
353
+ toIndexId: options.toIndexId ?? String,
354
+ follower: { running: false }
355
+ };
356
+ }
357
+
358
+ // src/run/follow.ts
355
359
  var noop = () => {
356
360
  return;
357
361
  };
@@ -488,7 +492,7 @@ async function open(ctx, token, lease) {
488
492
  };
489
493
  }
490
494
 
491
- // src/start.ts
495
+ // src/sync/start.ts
492
496
  function historyLost(error) {
493
497
  const code = error?.serverCode;
494
498
  return code === 286 || code === 280;
@@ -537,7 +541,7 @@ async function startHeld(ctx, lease) {
537
541
  }
538
542
  }
539
543
 
540
- // src/create-search-sync.ts
544
+ // src/sync/create-search-sync.ts
541
545
  function createSearchSync(options) {
542
546
  const ctx = createContext(options);
543
547
  return {
@@ -552,5 +556,5 @@ export {
552
556
  createSearchSync
553
557
  };
554
558
 
555
- //# debugId=FCC6FD234D55BAD364756E2164756E21
559
+ //# debugId=E539F463F575811364756E2164756E21
556
560
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/context.ts", "../src/reindex.ts", "../src/batch.ts", "../src/errors.ts", "../src/documents.ts", "../src/lease.ts", "../src/running.ts", "../src/state.ts", "../src/follow.ts", "../src/start.ts", "../src/create-search-sync.ts"],
3
+ "sources": ["../src/run/reindex.ts", "../src/sync/batch.ts", "../src/sync/errors.ts", "../src/sync/documents.ts", "../src/sync/running.ts", "../src/sync/state.ts", "../src/run/lease.ts", "../src/sync/context.ts", "../src/run/follow.ts", "../src/sync/start.ts", "../src/sync/create-search-sync.ts"],
4
4
  "sourcesContent": [
5
- "import type { AnyIndexDefinition, TypedIndex } from '@nxgt/meilisearch';\nimport type { AnyCollectionDefinition, TypedCollection } from '@nxgt/mongo';\nimport type { Collection } from 'mongodb';\nimport type { LeaseDocument } from './lease';\nimport type { SearchSyncOptions, SearchSyncState } from './types';\n\n/** Loosely typed: this layer works on any documents; the public types are what callers see. */\nexport type Doc = Record<string, unknown>;\n\n/**\n * What a sync works from, resolved once. Data, and the caller's own two\n * functions as they were given.\n */\nexport interface SyncContext {\n\treadonly name: string;\n\treadonly collection: TypedCollection<AnyCollectionDefinition>;\n\treadonly index: TypedIndex<AnyIndexDefinition>;\n\treadonly primaryKey: string;\n\treadonly state: Collection<SearchSyncState>;\n\t/** The same collection, for the lease documents it also holds. */\n\treadonly leases: Collection<LeaseDocument>;\n\t/** How long a lease lasts unrenewed, in ms. */\n\treadonly leaseMs: number;\n\treadonly batchSize: number;\n\treadonly flushIntervalMs: number;\n\treadonly positionIntervalMs: number;\n\treadonly pageSize: number;\n\treadonly onHistoryLost: 'reindex' | 'fail';\n\treadonly transform: (document: Doc) => unknown;\n\treadonly toIndexId: (id: unknown) => unknown;\n\t/**\n\t * Whether this sync is following changes in this process. A reindex\n\t * beside its own follower would remove what the follower has just\n\t * indexed, and the follower would never send it again.\n\t */\n\treadonly follower: { running: boolean };\n}\n\nconst DEFAULT_STATE_COLLECTION = 'nxgt_search_sync';\n\nfunction positive(option: string, value: number | undefined, fallback: number) {\n\tconst resolved = value ?? fallback;\n\tif (!Number.isInteger(resolved) || resolved < 1) {\n\t\tthrow new TypeError(\n\t\t\t`createSearchSync: ${option} must be a whole number above 0, not ${String(value)}`,\n\t\t);\n\t}\n\treturn resolved;\n}\n\nexport function createContext(\n\toptions: SearchSyncOptions<AnyCollectionDefinition, AnyIndexDefinition>,\n): SyncContext {\n\tconst { collection, index } = options;\n\tif (typeof options.transform !== 'function') {\n\t\tthrow new TypeError('createSearchSync: transform must be a function');\n\t}\n\tconst name = options.name ?? `${collection.collectionName}:${index.uid}`;\n\tif (name === '') {\n\t\tthrow new TypeError('createSearchSync: name must not be empty');\n\t}\n\tconst flushIntervalMs = options.flushIntervalMs ?? 1000;\n\tif (!Number.isInteger(flushIntervalMs) || flushIntervalMs < 0) {\n\t\tthrow new TypeError(\n\t\t\t`createSearchSync: flushIntervalMs must be a whole number of milliseconds, not ${String(options.flushIntervalMs)}`,\n\t\t);\n\t}\n\tconst stateCollection = options.stateCollection ?? DEFAULT_STATE_COLLECTION;\n\treturn {\n\t\tname,\n\t\tcollection,\n\t\tindex,\n\t\tprimaryKey: index.definition.primaryKey as string,\n\t\tstate: collection.db.collection<SearchSyncState>(stateCollection),\n\t\tleases: collection.db.collection<LeaseDocument>(stateCollection),\n\t\tleaseMs: positive('leaseMs', options.leaseMs, 30_000),\n\t\tbatchSize: positive('batchSize', options.batchSize, 500),\n\t\tpositionIntervalMs: positive(\n\t\t\t'positionIntervalMs',\n\t\t\toptions.positionIntervalMs,\n\t\t\t60_000,\n\t\t),\n\t\tflushIntervalMs,\n\t\tpageSize: positive('pageSize', options.pageSize, 100),\n\t\tonHistoryLost: options.onHistoryLost ?? 'reindex',\n\t\ttransform: options.transform as (document: Doc) => unknown,\n\t\ttoIndexId: (options.toIndexId ?? String) as (id: unknown) => unknown,\n\t\tfollower: { running: false },\n\t};\n}\n",
6
- "import type { ResumeToken } from '@nxgt/mongo';\nimport { MeilisearchApiError } from 'meilisearch';\nimport { deleteIds, sendDocuments } from './batch';\nimport type { Doc, SyncContext } from './context';\nimport { entryOf, keyOf } from './documents';\nimport { failed } from './errors';\nimport { confirmLease, type HeldLease, leaseLost, withLease } from './lease';\nimport { checkIdle } from './running';\nimport { saveState } from './state';\nimport type { ReindexReport } from './types';\n\n/**\n * Where the collection's changes are now, without waiting for one: a new\n * stream's first read answers with its position. The server holds that read\n * for up to `maxAwaitTimeMS` — a second by default, measured.\n */\nasync function currentToken(ctx: SyncContext): Promise<ResumeToken> {\n\tconst stream = ctx.collection.raw.watch([], { maxAwaitTimeMS: 1 });\n\ttry {\n\t\tawait stream.tryNext();\n\t\treturn stream.resumeToken as unknown as ResumeToken;\n\t} finally {\n\t\tawait stream.close();\n\t}\n}\n\n/** Every live document through the transform, a page at a time. */\nasync function sendAll(\n\tctx: SyncContext,\n\twanted: Set<string>,\n\tlease: HeldLease,\n) {\n\tlet indexed = 0;\n\tlet skipped = 0;\n\tlet after: string | null | undefined;\n\tdo {\n\t\tconst page = await ctx.collection.paginateByCursor({\n\t\t\tafter,\n\t\t\tlimit: ctx.pageSize,\n\t\t});\n\t\tconst documents: Doc[] = [];\n\t\tfor (const document of page.items as Doc[]) {\n\t\t\tconst entry = await entryOf(ctx, document._id, document);\n\t\t\tif (entry.kind === 'delete') {\n\t\t\t\tskipped += 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\twanted.add(entry.key);\n\t\t\tdocuments.push(entry.document);\n\t\t}\n\t\tawait sendDocuments(ctx, documents);\n\t\tindexed += documents.length;\n\t\t// Found lost by a renewal: stop sending beside whoever holds it now.\n\t\tif (lease.lost) throw leaseLost(ctx);\n\t\tafter = page.nextCursor;\n\t} while (after);\n\treturn { indexed, skipped };\n}\n\nconst LIST_LIMIT = 1000;\n\n/** Nothing was ever written to it: an index that does not exist holds nothing. */\nconst missingIndex = (error: unknown) =>\n\terror instanceof MeilisearchApiError &&\n\terror.cause?.code === 'index_not_found';\n\n/** Takes out what the index holds and the collection no longer gives it. */\nasync function removeUnwanted(\n\tctx: SyncContext,\n\twanted: Set<string>,\n): Promise<number> {\n\tconst unwanted: unknown[] = [];\n\tfor (let offset = 0; ; offset += LIST_LIMIT) {\n\t\tconst page = await ctx.index.raw\n\t\t\t.getDocuments({ fields: [ctx.primaryKey], limit: LIST_LIMIT, offset })\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tif (missingIndex(error)) return undefined;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\tif (!page) return 0;\n\t\tfor (const document of page.results as Doc[]) {\n\t\t\tconst id = document[ctx.primaryKey];\n\t\t\tif (!wanted.has(keyOf(id))) unwanted.push(id);\n\t\t}\n\t\tif (offset + LIST_LIMIT >= page.total) break;\n\t}\n\tawait deleteIds(ctx, unwanted);\n\treturn unwanted.length;\n}\n\n/**\n * A reindex, holding the sync's lease for as long as it runs: a follower in\n * another process would otherwise have what it just indexed removed, and\n * never send it again.\n */\nexport async function reindex(ctx: SyncContext): Promise<ReindexReport> {\n\tcheckIdle(ctx, 'reindex');\n\treturn withLease(ctx, 'reindex', (lease) => reindexHeld(ctx, lease));\n}\n\n/**\n * A reindex by a caller that holds the lease. What removes documents and what\n * records a point each go only once the server confirms the lease is still\n * this one's: after another process took it over, either would undo what\n * that process just did.\n */\nexport async function reindexHeld(\n\tctx: SyncContext,\n\tlease: HeldLease,\n): Promise<ReindexReport> {\n\ttry {\n\t\t// Taken first: a change made while the documents are read is followed\n\t\t// again from here, so it cannot fall between the two.\n\t\tconst token = await currentToken(ctx);\n\t\tconst wanted = new Set<string>();\n\t\tconst { indexed, skipped } = await sendAll(ctx, wanted, lease);\n\t\tawait confirmLease(ctx, lease);\n\t\tconst removed = await removeUnwanted(ctx, wanted);\n\t\tawait confirmLease(ctx, lease);\n\t\tawait saveState(ctx, token, true);\n\t\treturn { indexed, skipped, removed };\n\t} catch (error) {\n\t\tthrow failed(ctx.name, 'reindexing', error);\n\t}\n}\n",
5
+ "import type { ResumeToken } from '@nxgt/mongo';\nimport { MeilisearchApiError } from 'meilisearch';\nimport { deleteIds, sendDocuments } from '../sync/batch';\nimport type { Doc, SyncContext } from '../sync/context';\nimport { entryOf, keyOf } from '../sync/documents';\nimport { failed } from '../sync/errors';\nimport { checkIdle } from '../sync/running';\nimport { saveState } from '../sync/state';\nimport type { ReindexReport } from '../sync/types';\nimport { confirmLease, type HeldLease, leaseLost, withLease } from './lease';\n\n/**\n * Where the collection's changes are now, without waiting for one: a new\n * stream's first read answers with its position. The server holds that read\n * for up to `maxAwaitTimeMS` — a second by default, measured.\n */\nasync function currentToken(ctx: SyncContext): Promise<ResumeToken> {\n\tconst stream = ctx.collection.raw.watch([], { maxAwaitTimeMS: 1 });\n\ttry {\n\t\tawait stream.tryNext();\n\t\treturn stream.resumeToken as unknown as ResumeToken;\n\t} finally {\n\t\tawait stream.close();\n\t}\n}\n\n/** Every live document through the transform, a page at a time. */\nasync function sendAll(\n\tctx: SyncContext,\n\twanted: Set<string>,\n\tlease: HeldLease,\n) {\n\tlet indexed = 0;\n\tlet skipped = 0;\n\tlet after: string | null | undefined;\n\tdo {\n\t\tconst page = await ctx.collection.paginateByCursor({\n\t\t\tafter,\n\t\t\tlimit: ctx.pageSize,\n\t\t});\n\t\tconst documents: Doc[] = [];\n\t\tfor (const document of page.items as Doc[]) {\n\t\t\tconst entry = await entryOf(ctx, document['_id'], document);\n\t\t\tif (entry.kind === 'delete') {\n\t\t\t\tskipped += 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\twanted.add(entry.key);\n\t\t\tdocuments.push(entry.document);\n\t\t}\n\t\tawait sendDocuments(ctx, documents);\n\t\tindexed += documents.length;\n\t\t// Found lost by a renewal: stop sending beside whoever holds it now.\n\t\tif (lease.lost) throw leaseLost(ctx);\n\t\tafter = page.nextCursor;\n\t} while (after);\n\treturn { indexed, skipped };\n}\n\nconst LIST_LIMIT = 1000;\n\n/** Nothing was ever written to it: an index that does not exist holds nothing. */\nconst missingIndex = (error: unknown) =>\n\terror instanceof MeilisearchApiError &&\n\terror.cause?.code === 'index_not_found';\n\n/** Takes out what the index holds and the collection no longer gives it. */\nasync function removeUnwanted(\n\tctx: SyncContext,\n\twanted: Set<string>,\n): Promise<number> {\n\tconst unwanted: unknown[] = [];\n\tfor (let offset = 0; ; offset += LIST_LIMIT) {\n\t\tconst page = await ctx.index.raw\n\t\t\t.getDocuments({ fields: [ctx.primaryKey], limit: LIST_LIMIT, offset })\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tif (missingIndex(error)) return undefined;\n\t\t\t\tthrow error;\n\t\t\t});\n\t\tif (!page) return 0;\n\t\tfor (const document of page.results as Doc[]) {\n\t\t\tconst id = document[ctx.primaryKey];\n\t\t\tif (!wanted.has(keyOf(id))) unwanted.push(id);\n\t\t}\n\t\tif (offset + LIST_LIMIT >= page.total) break;\n\t}\n\tawait deleteIds(ctx, unwanted);\n\treturn unwanted.length;\n}\n\n/**\n * A reindex, holding the sync's lease for as long as it runs: a follower in\n * another process would otherwise have what it just indexed removed, and\n * never send it again.\n */\nexport async function reindex(ctx: SyncContext): Promise<ReindexReport> {\n\tcheckIdle(ctx, 'reindex');\n\treturn withLease(ctx, 'reindex', (lease) => reindexHeld(ctx, lease));\n}\n\n/**\n * A reindex by a caller that holds the lease. What removes documents and what\n * records a point each go only once the server confirms the lease is still\n * this one's: after another process took it over, either would undo what\n * that process just did.\n */\nexport async function reindexHeld(\n\tctx: SyncContext,\n\tlease: HeldLease,\n): Promise<ReindexReport> {\n\ttry {\n\t\t// Taken first: a change made while the documents are read is followed\n\t\t// again from here, so it cannot fall between the two.\n\t\tconst token = await currentToken(ctx);\n\t\tconst wanted = new Set<string>();\n\t\tconst { indexed, skipped } = await sendAll(ctx, wanted, lease);\n\t\tawait confirmLease(ctx, lease);\n\t\tconst removed = await removeUnwanted(ctx, wanted);\n\t\tawait confirmLease(ctx, lease);\n\t\tawait saveState(ctx, token, true);\n\t\treturn { indexed, skipped, removed };\n\t} catch (error) {\n\t\tthrow failed(ctx.name, 'reindexing', error);\n\t}\n}\n",
7
6
  "import type { Doc, SyncContext } from './context';\nimport type { Entry } from './documents';\n\n/**\n * How long a write may take to be applied. Meilisearch's own default is\n * five seconds, which a batch on a large index outlasts.\n */\nconst WAIT = { wait: { timeout: 120_000 } } as const;\n\nfunction chunks<T>(items: readonly T[], size: number): T[][] {\n\tconst out: T[][] = [];\n\tfor (let i = 0; i < items.length; i += size) {\n\t\tout.push(items.slice(i, i + size));\n\t}\n\treturn out;\n}\n\n/** Adds documents, `batchSize` at a time, each batch applied before the next. */\nexport async function sendDocuments(\n\tctx: SyncContext,\n\tdocuments: readonly Doc[],\n): Promise<void> {\n\tfor (const batch of chunks(documents, ctx.batchSize)) {\n\t\tawait ctx.index.add(batch, WAIT);\n\t}\n}\n\n/** Deletes documents by id, `batchSize` at a time. */\nexport async function deleteIds(\n\tctx: SyncContext,\n\tids: readonly unknown[],\n): Promise<void> {\n\tfor (const batch of chunks(ids, ctx.batchSize)) {\n\t\tawait ctx.index.delete(batch, WAIT);\n\t}\n}\n\n/**\n * Applies entries: one per id, so adds and deletes touch different\n * documents and their order does not matter.\n */\nexport async function send(\n\tctx: SyncContext,\n\tentries: readonly Entry[],\n): Promise<void> {\n\tconst documents: Doc[] = [];\n\tconst ids: unknown[] = [];\n\tfor (const entry of entries) {\n\t\tif (entry.kind === 'upsert') documents.push(entry.document);\n\t\telse ids.push(entry.id);\n\t}\n\tawait sendDocuments(ctx, documents);\n\tawait deleteIds(ctx, ids);\n}\n",
8
7
  "/** What stopped a sync, as a string to switch on. */\nexport type SearchSyncErrorCode =\n\t/** The resume point is older than the server's change history. */\n\t| 'HISTORY_LOST'\n\t/** The transform gave a document whose primary key is not its index id. */\n\t| 'ID_MISMATCH'\n\t/** The transform gave something that is neither a document nor `null`. */\n\t| 'NOT_A_DOCUMENT'\n\t/**\n\t * This sync's name is taken: it is following changes in this process, or\n\t * another process holds its lease.\n\t */\n\t| 'RUNNING'\n\t/**\n\t * A running sync's lease was not renewed in time and is no longer its\n\t * own: it stopped rather than follow beside whoever took the name over.\n\t */\n\t| 'LEASE_LOST'\n\t/** Anything else: the cause says what. */\n\t| 'FAILED';\n\nexport interface SearchSyncErrorOptions {\n\tcode: SearchSyncErrorCode;\n\tsync: string;\n\tcause?: unknown;\n\t/** Who holds the lease, on a `RUNNING` the lease refused. */\n\tholder?: string | undefined;\n\t/** When that lease lapses unrenewed, on a `RUNNING` the lease refused. */\n\texpiresAt?: Date | undefined;\n}\n\n/** An error of a sync, with the sync's name and what caused it. */\nexport class SearchSyncError extends Error {\n\toverride name = 'SearchSyncError';\n\treadonly code: SearchSyncErrorCode;\n\t/** The sync's name. */\n\treadonly sync: string;\n\t/**\n\t * On a `RUNNING` the lease refused: who holds the name, as that process\n\t * described itself (`host:pid:<ObjectId>`). A label for a log, not a value\n\t * to parse. `undefined` on every other error, on the `RUNNING` of a sync\n\t * object that is already following in this process, and when the holder\n\t * let go before it could be read.\n\t */\n\treadonly holder: string | undefined;\n\t/**\n\t * On a `RUNNING` the lease refused: when the holder's lease lapses if it\n\t * stops renewing it, read from the lease document and so on the MongoDB\n\t * server's clock. A live holder renews it every third of `leaseMs`, so a\n\t * start at this time can still be refused, with a later one. `undefined`\n\t * whenever `holder` is.\n\t */\n\treadonly expiresAt: Date | undefined;\n\n\tconstructor(message: string, options: SearchSyncErrorOptions) {\n\t\tsuper(\n\t\t\tmessage,\n\t\t\toptions.cause === undefined ? undefined : { cause: options.cause },\n\t\t);\n\t\tthis.code = options.code;\n\t\tthis.sync = options.sync;\n\t\tthis.holder = options.holder;\n\t\tthis.expiresAt = options.expiresAt;\n\t}\n}\n\n/** `error` as a `SearchSyncError`, kept as it is when it already is one. */\nexport function failed(sync: string, doing: string, error: unknown) {\n\tif (error instanceof SearchSyncError) return error;\n\tconst reason = error instanceof Error ? error.message : String(error);\n\treturn new SearchSyncError(\n\t\t`Search sync \"${sync}\" failed ${doing}: ${reason}`,\n\t\t{\n\t\t\tcode: 'FAILED',\n\t\t\tsync,\n\t\t\tcause: error,\n\t\t},\n\t);\n}\n",
9
8
  "import type { Doc, SyncContext } from './context';\nimport { SearchSyncError } from './errors';\n\n/** One document's fate in the index: sent, or taken out. */\nexport type Entry =\n\t| { kind: 'upsert'; key: string; document: Doc }\n\t| { kind: 'delete'; key: string; id: unknown };\n\n/** An id as a key: `1` and `'1'` are different ids to Meilisearch. */\nexport const keyOf = (id: unknown) => `${typeof id}:${String(id)}`;\n\nconst isRecord = (value: unknown): value is Doc =>\n\ttypeof value === 'object' && value !== null && !Array.isArray(value);\n\n/** What a transform gave back, for a message: its shape, never its value. */\nfunction describe(value: unknown): string {\n\tif (Array.isArray(value)) return 'an array';\n\tif (value === undefined) return 'undefined';\n\treturn `a ${typeof value}`;\n}\n\n/**\n * What the index should hold for a document of the collection: what the\n * transform makes of it, or nothing when it is gone or kept out.\n */\nexport async function entryOf(\n\tctx: SyncContext,\n\tmongoId: unknown,\n\tdocument: Doc | undefined,\n): Promise<Entry> {\n\tconst id = ctx.toIndexId(mongoId);\n\tconst key = keyOf(id);\n\tif (!document) return { kind: 'delete', key, id };\n\tconst indexed = await ctx.transform(document);\n\tif (indexed === null) return { kind: 'delete', key, id };\n\tif (!isRecord(indexed)) {\n\t\t// A `SearchSyncError` with a code of its own, like the id mismatch\n\t\t// below it: a bare `TypeError` came back through `failed()` as\n\t\t// `FAILED`, the code that means \"anything else\", and named neither the\n\t\t// sync nor the document whose transform did it.\n\t\tthrow new SearchSyncError(\n\t\t\t`Search sync \"${ctx.name}\": transform gave ${describe(indexed)} for ` +\n\t\t\t\t`the document ${String(mongoId)}. It must give a document to ` +\n\t\t\t\t'index, or null to keep it out.',\n\t\t\t{ code: 'NOT_A_DOCUMENT', sync: ctx.name },\n\t\t);\n\t}\n\tconst given = indexed[ctx.primaryKey];\n\tif (keyOf(given) !== key) {\n\t\tthrow new SearchSyncError(\n\t\t\t`Search sync \"${ctx.name}\": transform gave \"${ctx.primaryKey}\" ` +\n\t\t\t\t`${JSON.stringify(given)} for the document ${String(mongoId)}, whose ` +\n\t\t\t\t`index id is ${JSON.stringify(id)}. A document under another id ` +\n\t\t\t\t'could never be taken out of the index again.',\n\t\t\t{ code: 'ID_MISMATCH', sync: ctx.name },\n\t\t);\n\t}\n\treturn { kind: 'upsert', key, document: indexed };\n}\n",
10
- "import { hostname } from 'node:os';\nimport { ObjectId } from 'mongodb';\nimport type { SyncContext } from './context';\nimport { failed, SearchSyncError } from './errors';\n\n/**\n * The lease on a sync's name: one document in the state collection, whose\n * `_id` is `{ lease: <name> }` — an object, so it can never be a sync's own\n * state, whose `_id` is the name itself.\n *\n * Taking it is one atomic write whose update decides — the server, not a\n * read before a write. Every time is the server's (`$$NOW`), so hosts whose\n * clocks disagree still agree on when a lease lapses.\n *\n * Renewal, release and the holder's name follow `@nxgt/mongo`'s migration\n * lock (`migrations/lock.ts`); taking it does not — see `take`.\n */\nexport interface LeaseDocument {\n\t_id: { lease: string };\n\tholder: string;\n\tacquiredAt: Date;\n\texpiresAt: Date;\n}\n\n/** A held lease: data, and whether a renewal found it gone. */\nexport interface HeldLease {\n\treadonly holder: string;\n\tlost: boolean;\n}\n\nconst idOf = (ctx: SyncContext) => ({ lease: ctx.name });\n\n/**\n * Inserts the lease, or takes over one that lapsed, in one atomic upsert.\n *\n * The filter is `_id` alone — the server allows no `$expr` in an upsert's\n * filter — and the decision is made by the update instead: a pipeline that\n * keeps the current holder's fields while its lease runs, and writes this\n * holder's when there is none or it lapsed. What comes back says who won.\n * It is a `findAndModify`, not an `aggregate`: `@nxgt/mongo`'s migration lock\n * takes its lock with `$documents`/`$merge`, which a failpoint or a monitor\n * aimed at the change stream's `aggregate` would also catch.\n */\nasync function take(ctx: SyncContext, holder: string): Promise<boolean> {\n\tconst free = {\n\t\t$or: [\n\t\t\t{ $eq: [{ $type: '$expiresAt' }, 'missing'] },\n\t\t\t{ $lte: ['$expiresAt', '$$NOW'] },\n\t\t],\n\t};\n\tconst pick = (mine: unknown, theirs: string) => ({\n\t\t$cond: [free, mine, theirs],\n\t});\n\ttry {\n\t\tconst after = await ctx.leases.findOneAndUpdate(\n\t\t\t{ _id: idOf(ctx) },\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\t$set: {\n\t\t\t\t\t\tholder: pick({ $literal: holder }, '$holder'),\n\t\t\t\t\t\tacquiredAt: pick('$$NOW', '$acquiredAt'),\n\t\t\t\t\t\texpiresAt: pick({ $add: ['$$NOW', ctx.leaseMs] }, '$expiresAt'),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\t{ upsert: true, returnDocument: 'after' },\n\t\t);\n\t\treturn after?.holder === holder;\n\t} catch (error) {\n\t\t// Two upserts racing to insert the same `_id`: the other one won.\n\t\tif ((error as { code?: number }).code === 11000) return false;\n\t\tthrow error;\n\t}\n}\n\n/**\n * Takes the lease, or throws `RUNNING` naming who holds it and until when —\n * in the message and as `holder` and `expiresAt`, so a standby can wait for\n * that moment rather than a fixed time. The same code a second `start` in\n * this process gets, since it means the same thing: this name is being\n * followed.\n */\nexport async function acquire(\n\tctx: SyncContext,\n\tdoing: string,\n): Promise<HeldLease> {\n\tconst holder = `${hostname()}:${process.pid}:${new ObjectId().toHexString()}`;\n\tlet current: LeaseDocument | null = null;\n\ttry {\n\t\t// Twice at most: a holder that let go between the take and the read\n\t\t// left the name free, and refusing it then would be wrong.\n\t\tfor (let attempt = 0; attempt < 2; attempt += 1) {\n\t\t\tif (await take(ctx, holder)) return { holder, lost: false };\n\t\t\tcurrent = await ctx.leases.findOne({ _id: idOf(ctx) });\n\t\t\tif (current) break;\n\t\t}\n\t} catch (error) {\n\t\tthrow failed(ctx.name, 'taking its lease', error);\n\t}\n\t// Each only when the document holds what it should; `expiresAt` only\n\t// beside a holder, as the error's own documentation promises.\n\tconst until =\n\t\tcurrent?.expiresAt instanceof Date ? current.expiresAt : undefined;\n\tconst theirs =\n\t\ttypeof current?.holder === 'string' ? current.holder : undefined;\n\tconst expiresAt = theirs === undefined ? undefined : until;\n\tthrow new SearchSyncError(\n\t\t`Search sync \"${ctx.name}\" is held by ${theirs ?? 'another process'} ` +\n\t\t\t`until ${until?.toISOString() ?? 'it lets go'}: ` +\n\t\t\t`wait for it to close, or for its lease to lapse, before you ${doing}.`,\n\t\t{\n\t\t\tcode: 'RUNNING',\n\t\t\tsync: ctx.name,\n\t\t\tholder: theirs,\n\t\t\texpiresAt,\n\t\t},\n\t);\n}\n\n/**\n * Pushes the lease's end back by `leaseMs`. A renewal that finds another\n * holder marks the lease lost; one that does not reach the server is tried\n * again at the next beat, and the lease lapses only if none reaches it for a\n * whole `leaseMs`.\n */\nexport async function renew(ctx: SyncContext, lease: HeldLease): Promise<void> {\n\ttry {\n\t\tconst result = await ctx.leases.updateOne(\n\t\t\t{ _id: idOf(ctx), holder: lease.holder },\n\t\t\t[{ $set: { expiresAt: { $add: ['$$NOW', ctx.leaseMs] } } }],\n\t\t);\n\t\tif (result.matchedCount === 0) lease.lost = true;\n\t} catch {\n\t\t// Tried again at the next beat.\n\t}\n}\n\n/**\n * Renews the lease now, and throws `LEASE_LOST` if it is someone else's: the\n * check before a step that must not run beside another holder.\n */\nexport async function confirmLease(\n\tctx: SyncContext,\n\tlease: HeldLease,\n): Promise<void> {\n\tlet result: { matchedCount: number };\n\ttry {\n\t\tresult = await ctx.leases.updateOne(\n\t\t\t{ _id: idOf(ctx), holder: lease.holder },\n\t\t\t[{ $set: { expiresAt: { $add: ['$$NOW', ctx.leaseMs] } } }],\n\t\t);\n\t} catch (error) {\n\t\t// Unlike a timed renewal, not tried again later: what comes next must\n\t\t// not run on a lease nobody could confirm.\n\t\tthrow failed(ctx.name, 'checking its lease', error);\n\t}\n\tif (result.matchedCount === 0) lease.lost = true;\n\tif (lease.lost) throw leaseLost(ctx);\n}\n\n/** Lets go of it, if it is still this holder's. One that fails lapses. */\nexport async function release(\n\tctx: SyncContext,\n\tlease: HeldLease,\n): Promise<void> {\n\tawait ctx.leases\n\t\t.deleteOne({ _id: idOf(ctx), holder: lease.holder })\n\t\t.catch(() => undefined);\n}\n\n/** The error a sync stops with once its lease is someone else's. */\nexport function leaseLost(ctx: SyncContext): SearchSyncError {\n\treturn new SearchSyncError(\n\t\t`Search sync \"${ctx.name}\" lost its lease: another process holds the ` +\n\t\t\t'name now, or the lease was removed (it lapses when not renewed ' +\n\t\t\t`within ${ctx.leaseMs} ms). It stopped rather than run beside it.`,\n\t\t{ code: 'LEASE_LOST', sync: ctx.name },\n\t);\n}\n\n/**\n * Renews the lease every third of `leaseMs`, and calls `onLost` once when a\n * renewal finds it someone else's. Gives back what stops the renewals.\n */\nexport function keepLease(\n\tctx: SyncContext,\n\tlease: HeldLease,\n\tonLost: () => void,\n): () => void {\n\tlet stopped = false;\n\tconst beat = setInterval(\n\t\t() => {\n\t\t\tvoid renew(ctx, lease).then(() => {\n\t\t\t\t// A renewal still in flight when it was stopped reports nothing.\n\t\t\t\tif (lease.lost && !stopped) {\n\t\t\t\t\tclearInterval(beat);\n\t\t\t\t\tonLost();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\tMath.max(1, Math.floor(ctx.leaseMs / 3)),\n\t);\n\treturn () => {\n\t\tstopped = true;\n\t\tclearInterval(beat);\n\t};\n}\n\n/**\n * Runs `fn` holding the lease, renewed every third of `leaseMs`. `fn` checks\n * it is still held where that matters (`confirmLease`).\n */\nexport async function withLease<T>(\n\tctx: SyncContext,\n\tdoing: string,\n\tfn: (lease: HeldLease) => Promise<T>,\n): Promise<T> {\n\tconst lease = await acquire(ctx, doing);\n\tconst stop = keepLease(ctx, lease, () => undefined);\n\ttry {\n\t\treturn await fn(lease);\n\t} finally {\n\t\tstop();\n\t\tawait release(ctx, lease);\n\t}\n}\n",
11
9
  "import type { SyncContext } from './context';\nimport { SearchSyncError } from './errors';\n\n/**\n * Refuses to do beside a running follower what would undo its work: a\n * reindex removes what the follower has just indexed, and the follower,\n * having handled that change, never sends it again.\n *\n * Its `RUNNING` carries no `holder` and no `expiresAt`: the lease is this\n * process's own and renewed for as long as it follows, so there is no time to\n * wait for — only a `close()` frees the name.\n */\nexport function checkIdle(ctx: SyncContext, doing: string): void {\n\tif (!ctx.follower.running) return;\n\tthrow new SearchSyncError(\n\t\t`Search sync \"${ctx.name}\" is already following changes in this ` +\n\t\t\t`process: close it before you ${doing}.`,\n\t\t{ code: 'RUNNING', sync: ctx.name },\n\t);\n}\n",
12
10
  "import type { ResumeToken } from '@nxgt/mongo';\nimport type { SyncContext } from './context';\nimport { failed } from './errors';\nimport type { SearchSyncState } from './types';\n\n/** What the sync has recorded, or `undefined` before its first reindex. */\nexport async function readState(\n\tctx: SyncContext,\n): Promise<SearchSyncState | undefined> {\n\ttry {\n\t\treturn (await ctx.state.findOne({ _id: ctx.name })) ?? undefined;\n\t} catch (error) {\n\t\tthrow failed(ctx.name, 'reading its resume point', error);\n\t}\n}\n\n/** Forgets everything recorded: the next `start` reindexes. */\nexport async function clearState(ctx: SyncContext): Promise<void> {\n\ttry {\n\t\tawait ctx.state.deleteOne({ _id: ctx.name });\n\t} catch (error) {\n\t\tthrow failed(ctx.name, 'forgetting its resume point', error);\n\t}\n}\n\n/** Moves the resume point, and says a reindex finished when one did. */\nexport async function saveState(\n\tctx: SyncContext,\n\tresumeToken: ResumeToken,\n\treindexed: boolean,\n): Promise<void> {\n\tconst now = new Date();\n\ttry {\n\t\tawait ctx.state.updateOne(\n\t\t\t{ _id: ctx.name },\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\tresumeToken,\n\t\t\t\t\tupdatedAt: now,\n\t\t\t\t\t...(reindexed ? { reindexedAt: now } : {}),\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ upsert: true },\n\t\t);\n\t} catch (error) {\n\t\tthrow failed(ctx.name, 'recording its resume point', error);\n\t}\n}\n",
13
- "import type {\n\tAnyCollectionDefinition,\n\tChangeOf,\n\tChangeSubscription,\n\tCloseReason,\n\tResumeToken,\n} from '@nxgt/mongo';\nimport { send } from './batch';\nimport type { Doc, SyncContext } from './context';\nimport { type Entry, entryOf } from './documents';\nimport { failed, type SearchSyncError } from './errors';\nimport { type HeldLease, keepLease, leaseLost, release } from './lease';\nimport { clearState, saveState } from './state';\nimport type { RunningSearchSync } from './types';\n\nconst noop = () => undefined;\n\n/** What a running sync holds between changes. */\ninterface Following {\n\treadonly pending: Map<string, Entry>;\n\t/** The token of the last change in `pending`. */\n\tlast: ResumeToken | undefined;\n\tsaved: ResumeToken;\n\t/** Changes whose handler has not queued them yet. */\n\tinFlight: number;\n\ttimer: ReturnType<typeof setTimeout> | undefined;\n\t/** Records where the stream is while nothing is being sent. */\n\tbeat: ReturnType<typeof setInterval> | undefined;\n\t/** Stops renewing the lease on the sync's name. */\n\tstopLease: () => void;\n\t/**\n\t * The stream was heard. Only then does `closed` let go of the lease: a\n\t * stream that never got ready leaves it to `start`, which may reindex and\n\t * open again on it after a lost history.\n\t */\n\theard: boolean;\n\t/** Flushes run one after the other. */\n\tchain: Promise<void>;\n\t/** The stream has stopped: what is queued no longer records anything. */\n\tdone: boolean;\n\tfailure: SearchSyncError | undefined;\n}\n\n/**\n * Sends what is pending, then records the token that covers it — or, with\n * nothing to send and no change being handled, where the stream is: a quiet\n * collection would otherwise keep a resume point until the server's history\n * no longer reaches it.\n */\nfunction flush(\n\tctx: SyncContext,\n\tf: Following,\n\tsubscription: ChangeSubscription,\n): Promise<void> {\n\tf.chain = f.chain.then(async () => {\n\t\tif (f.failure) throw f.failure;\n\t\tif (f.done) return;\n\t\tclearTimeout(f.timer);\n\t\tf.timer = undefined;\n\t\tconst entries = [...f.pending.values()];\n\t\tconst upTo = f.last;\n\t\tf.pending.clear();\n\t\ttry {\n\t\t\tif (entries.length > 0) await send(ctx, entries);\n\t\t\tconst idle = entries.length === 0 && f.inFlight === 0;\n\t\t\tconst at = upTo ?? (idle ? subscription.position : undefined);\n\t\t\tif (at && at !== f.saved) {\n\t\t\t\tawait saveState(ctx, at, false);\n\t\t\t\tf.saved = at;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tf.failure ??= failed(ctx.name, 'sending changes', error);\n\t\t\tthrow f.failure;\n\t\t}\n\t});\n\treturn f.chain;\n}\n\n/** A sync that has not heard anything yet, from `token`. */\nfunction following(token: ResumeToken): Following {\n\treturn {\n\t\tpending: new Map(),\n\t\tlast: undefined,\n\t\tsaved: token,\n\t\tinFlight: 0,\n\t\ttimer: undefined,\n\t\tbeat: undefined,\n\t\tstopLease: noop,\n\t\theard: false,\n\t\tchain: Promise.resolve(),\n\t\tdone: false,\n\t\tfailure: undefined,\n\t};\n}\n\n/** Stops everything a running sync does on its own. */\nfunction stopFollowing(ctx: SyncContext, f: Following): void {\n\tf.done = true;\n\tclearTimeout(f.timer);\n\tclearInterval(f.beat);\n\tf.stopLease();\n\tctx.follower.running = false;\n}\n\n/**\n * What `closed` settles to once the stream stops: the reason, or the failure\n * that stopped it — after the last queued flush, and with the lease let go.\n */\nfunction settle(\n\tctx: SyncContext,\n\tf: Following,\n\tsubscription: ChangeSubscription,\n\tlease: HeldLease,\n): Promise<CloseReason> {\n\tconst letGo = () => (f.heard ? release(ctx, lease) : Promise.resolve());\n\treturn subscription.closed.then(\n\t\tasync (reason) => {\n\t\t\tstopFollowing(ctx, f);\n\t\t\ttry {\n\t\t\t\t// A flush the timer or the beat had queued would otherwise record\n\t\t\t\t// a point after this.\n\t\t\t\tawait f.chain.catch(noop);\n\t\t\t\tif (f.failure) throw f.failure;\n\t\t\t\t// The collection is gone, and so is the point the stream stopped\n\t\t\t\t// at: what is recorded is older, and every later start would stop\n\t\t\t\t// here again. Forgetting it makes the next one reindex.\n\t\t\t\tif (reason === 'invalidated') await clearState(ctx);\n\t\t\t\treturn reason;\n\t\t\t} finally {\n\t\t\t\tawait letGo();\n\t\t\t}\n\t\t},\n\t\tasync (error: unknown) => {\n\t\t\tstopFollowing(ctx, f);\n\t\t\tawait letGo();\n\t\t\tthrow f.failure ?? failed(ctx.name, 'following changes', error);\n\t\t},\n\t);\n}\n\nexport async function open(\n\tctx: SyncContext,\n\ttoken: ResumeToken,\n\tlease: HeldLease,\n): Promise<RunningSearchSync> {\n\tconst f = following(token);\n\tconst handle = async (change: ChangeOf<AnyCollectionDefinition>) => {\n\t\tif (f.failure) throw f.failure;\n\t\tf.inFlight += 1;\n\t\tlet entry: Entry;\n\t\ttry {\n\t\t\tconst document =\n\t\t\t\tchange.type === 'delete' ? undefined : (change.document as Doc);\n\t\t\tentry = await entryOf(ctx, change.id, document);\n\t\t} catch (error) {\n\t\t\t// Kept, so `flush` and `close` report it as `closed` does.\n\t\t\tf.failure = failed(ctx.name, 'following changes', error);\n\t\t\tthrow f.failure;\n\t\t} finally {\n\t\t\tf.inFlight -= 1;\n\t\t}\n\t\tf.pending.set(entry.key, entry);\n\t\tf.last = change.resumeToken;\n\t\tif (f.pending.size >= ctx.batchSize) {\n\t\t\tawait flush(ctx, f, subscription);\n\t\t} else if (!f.timer) {\n\t\t\tf.timer = setTimeout(() => {\n\t\t\t\tflush(ctx, f, subscription).catch(() => subscription.close());\n\t\t\t}, ctx.flushIntervalMs);\n\t\t}\n\t};\n\tconst subscription = ctx.collection.onChange(handle, { startAfter: token });\n\tf.beat = setInterval(() => {\n\t\tflush(ctx, f, subscription).catch(() => subscription.close());\n\t}, ctx.positionIntervalMs);\n\t// A lease found gone means another process may be following this name:\n\t// stop at once, before anything else is sent or recorded beside it.\n\tf.stopLease = keepLease(ctx, lease, () => {\n\t\tif (f.failure) return;\n\t\tf.failure = leaseLost(ctx);\n\t\tvoid subscription.close();\n\t});\n\tconst closed = settle(ctx, f, subscription, lease);\n\ttry {\n\t\tawait subscription.ready;\n\t} catch (error) {\n\t\tstopFollowing(ctx, f);\n\t\tclosed.catch(noop);\n\t\tthrow error;\n\t}\n\tf.heard = true;\n\tctx.follower.running = true;\n\tconst close = async () => {\n\t\ttry {\n\t\t\tawait flush(ctx, f, subscription);\n\t\t} finally {\n\t\t\tawait subscription.close();\n\t\t\t// The lease is let go in `closed`'s handler: waited for, so a\n\t\t\t// `reindex` or a `start` right after this finds the name free. Not\n\t\t\t// from inside a change being handled, which `closed` waits for.\n\t\t\tif (f.inFlight === 0) await closed.then(noop, noop);\n\t\t}\n\t};\n\treturn {\n\t\tready: subscription.ready,\n\t\tclosed,\n\t\tflush: () => flush(ctx, f, subscription),\n\t\tclose,\n\t\t[Symbol.asyncDispose]: close,\n\t};\n}\n",
14
- "import type { ResumeToken } from '@nxgt/mongo';\nimport type { SyncContext } from './context';\nimport { failed, SearchSyncError } from './errors';\nimport { open } from './follow';\nimport {\n\tacquire,\n\tconfirmLease,\n\ttype HeldLease,\n\tkeepLease,\n\trelease,\n} from './lease';\nimport { reindexHeld } from './reindex';\nimport { checkIdle } from './running';\nimport { readState } from './state';\nimport type { RunningSearchSync } from './types';\n\n/** The server no longer has the history a token points into. */\nfunction historyLost(error: unknown): boolean {\n\tconst code = (error as { serverCode?: number } | undefined)?.serverCode;\n\treturn code === 286 || code === 280;\n}\n\n/**\n * Follows the collection from its recorded point — after a reindex when\n * nothing is recorded, or when the point is older than the server's history\n * and `onHistoryLost` allows it.\n */\nexport async function start(ctx: SyncContext): Promise<RunningSearchSync> {\n\tcheckIdle(ctx, 'start it twice');\n\t// Before anything else, the first reindex included: two processes\n\t// starting at once would otherwise both reindex, and both follow.\n\tconst lease = await acquire(ctx, 'start it');\n\t// Renewed while it reindexes, which can outlast `leaseMs`; the follower\n\t// renews it on its own once it is open.\n\tconst stop = keepLease(ctx, lease, () => undefined);\n\ttry {\n\t\tconst running = await startHeld(ctx, lease);\n\t\tstop();\n\t\treturn running;\n\t} catch (error) {\n\t\tstop();\n\t\tawait release(ctx, lease);\n\t\tthrow error;\n\t}\n}\n\n/** Opens the follower, once the server confirms the lease is still held. */\nasync function openHeld(\n\tctx: SyncContext,\n\ttoken: ResumeToken,\n\tlease: HeldLease,\n): Promise<RunningSearchSync> {\n\tawait confirmLease(ctx, lease);\n\treturn open(ctx, token, lease);\n}\n\nasync function startHeld(\n\tctx: SyncContext,\n\tlease: HeldLease,\n): Promise<RunningSearchSync> {\n\tlet state = await readState(ctx);\n\tif (!state) {\n\t\tawait reindexHeld(ctx, lease);\n\t\tstate = await readState(ctx);\n\t}\n\ttry {\n\t\treturn await openHeld(\n\t\t\tctx,\n\t\t\t(state as { resumeToken: ResumeToken }).resumeToken,\n\t\t\tlease,\n\t\t);\n\t} catch (error) {\n\t\tif (!historyLost(error)) throw failed(ctx.name, 'starting', error);\n\t\tif (ctx.onHistoryLost === 'fail') {\n\t\t\tthrow new SearchSyncError(\n\t\t\t\t`Search sync \"${ctx.name}\" was last at a point the server's change ` +\n\t\t\t\t\t'history no longer reaches. Reindex it, or start it with ' +\n\t\t\t\t\t\"onHistoryLost: 'reindex'.\",\n\t\t\t\t{ code: 'HISTORY_LOST', sync: ctx.name, cause: error },\n\t\t\t);\n\t\t}\n\t\tawait reindexHeld(ctx, lease);\n\t\tconst fresh = (await readState(ctx)) as { resumeToken: ResumeToken };\n\t\ttry {\n\t\t\treturn await openHeld(ctx, fresh.resumeToken, lease);\n\t\t} catch (again) {\n\t\t\tthrow failed(ctx.name, 'starting', again);\n\t\t}\n\t}\n}\n",
15
- "import type { AnyIndexDefinition } from '@nxgt/meilisearch';\nimport type { AnyCollectionDefinition } from '@nxgt/mongo';\nimport { createContext } from './context';\nimport { reindex } from './reindex';\nimport { start } from './start';\nimport { readState } from './state';\nimport type { SearchSync, SearchSyncOptions } from './types';\n\n/**\n * Keeps an index in step with a collection.\n *\n * ```ts\n * const usersSearch = createSearchSync({\n * \tcollection: getCollection(db, users),\n * \tindex: bindIndex(meili, userIndex),\n * \ttransform: (user) => (user.active ? { id: user.id, name: user.name } : null),\n * });\n * const running = await usersSearch.start(); // reindexes the first time\n * // …\n * await running.close();\n * ```\n *\n * Nothing is sent before `reindex` or `start`.\n */\nexport function createSearchSync<\n\tC extends AnyCollectionDefinition,\n\tI extends AnyIndexDefinition,\n>(options: SearchSyncOptions<C, I>): SearchSync {\n\t// The one place the caller's types are let go: a method taking `IdOf<C>`\n\t// is not one taking any id, so the widening cannot be implicit. Below\n\t// here, documents are records and ids are values.\n\tconst ctx = createContext(\n\t\toptions as unknown as SearchSyncOptions<\n\t\t\tAnyCollectionDefinition,\n\t\t\tAnyIndexDefinition\n\t\t>,\n\t);\n\treturn {\n\t\tname: ctx.name,\n\t\treindex: () => reindex(ctx),\n\t\tstart: () => start(ctx),\n\t\tstate: () => readState(ctx),\n\t};\n}\n"
11
+ "import { hostname } from 'node:os';\nimport { ObjectId } from 'mongodb';\nimport type { SyncContext } from '../sync/context';\nimport { failed, SearchSyncError } from '../sync/errors';\n\n/**\n * The lease on a sync's name: one document in the state collection, whose\n * `_id` is `{ lease: <name> }` — an object, so it can never be a sync's own\n * state, whose `_id` is the name itself.\n *\n * Taking it is one atomic write whose update decides — the server, not a\n * read before a write. Every time is the server's (`$$NOW`), so hosts whose\n * clocks disagree still agree on when a lease lapses.\n *\n * Renewal, release and the holder's name follow `@nxgt/mongo`'s migration\n * lock (`migrations/lock.ts`); taking it does not — see `take`.\n */\nexport interface LeaseDocument {\n\t_id: { lease: string };\n\tholder: string;\n\tacquiredAt: Date;\n\texpiresAt: Date;\n}\n\n/** A held lease: data, and whether a renewal found it gone. */\nexport interface HeldLease {\n\treadonly holder: string;\n\tlost: boolean;\n}\n\nconst idOf = (ctx: SyncContext) => ({ lease: ctx.name });\n\n/**\n * Inserts the lease, or takes over one that lapsed, in one atomic upsert.\n *\n * The filter is `_id` alone — the server allows no `$expr` in an upsert's\n * filter — and the decision is made by the update instead: a pipeline that\n * keeps the current holder's fields while its lease runs, and writes this\n * holder's when there is none or it lapsed. What comes back says who won.\n * It is a `findAndModify`, not an `aggregate`: `@nxgt/mongo`'s migration lock\n * takes its lock with `$documents`/`$merge`, which a failpoint or a monitor\n * aimed at the change stream's `aggregate` would also catch.\n */\nasync function take(ctx: SyncContext, holder: string): Promise<boolean> {\n\tconst free = {\n\t\t$or: [\n\t\t\t{ $eq: [{ $type: '$expiresAt' }, 'missing'] },\n\t\t\t{ $lte: ['$expiresAt', '$$NOW'] },\n\t\t],\n\t};\n\tconst pick = (mine: unknown, theirs: string) => ({\n\t\t$cond: [free, mine, theirs],\n\t});\n\ttry {\n\t\tconst after = await ctx.leases.findOneAndUpdate(\n\t\t\t{ _id: idOf(ctx) },\n\t\t\t[\n\t\t\t\t{\n\t\t\t\t\t$set: {\n\t\t\t\t\t\tholder: pick({ $literal: holder }, '$holder'),\n\t\t\t\t\t\tacquiredAt: pick('$$NOW', '$acquiredAt'),\n\t\t\t\t\t\texpiresAt: pick({ $add: ['$$NOW', ctx.leaseMs] }, '$expiresAt'),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\t{ upsert: true, returnDocument: 'after' },\n\t\t);\n\t\treturn after?.holder === holder;\n\t} catch (error) {\n\t\t// Two upserts racing to insert the same `_id`: the other one won.\n\t\tif ((error as { code?: number }).code === 11000) return false;\n\t\tthrow error;\n\t}\n}\n\n/**\n * Takes the lease, or throws `RUNNING` naming who holds it and until when —\n * in the message and as `holder` and `expiresAt`, so a standby can wait for\n * that moment rather than a fixed time. The same code a second `start` in\n * this process gets, since it means the same thing: this name is being\n * followed.\n */\nexport async function acquire(\n\tctx: SyncContext,\n\tdoing: string,\n): Promise<HeldLease> {\n\tconst holder = `${hostname()}:${process.pid}:${new ObjectId().toHexString()}`;\n\tlet current: LeaseDocument | null = null;\n\ttry {\n\t\t// Twice at most: a holder that let go between the take and the read\n\t\t// left the name free, and refusing it then would be wrong.\n\t\tfor (let attempt = 0; attempt < 2; attempt += 1) {\n\t\t\tif (await take(ctx, holder)) return { holder, lost: false };\n\t\t\tcurrent = await ctx.leases.findOne({ _id: idOf(ctx) });\n\t\t\tif (current) break;\n\t\t}\n\t} catch (error) {\n\t\tthrow failed(ctx.name, 'taking its lease', error);\n\t}\n\t// Each only when the document holds what it should; `expiresAt` only\n\t// beside a holder, as the error's own documentation promises.\n\tconst until =\n\t\tcurrent?.expiresAt instanceof Date ? current.expiresAt : undefined;\n\tconst theirs =\n\t\ttypeof current?.holder === 'string' ? current.holder : undefined;\n\tconst expiresAt = theirs === undefined ? undefined : until;\n\tthrow new SearchSyncError(\n\t\t`Search sync \"${ctx.name}\" is held by ${theirs ?? 'another process'} ` +\n\t\t\t`until ${until?.toISOString() ?? 'it lets go'}: ` +\n\t\t\t`wait for it to close, or for its lease to lapse, before you ${doing}.`,\n\t\t{\n\t\t\tcode: 'RUNNING',\n\t\t\tsync: ctx.name,\n\t\t\tholder: theirs,\n\t\t\texpiresAt,\n\t\t},\n\t);\n}\n\n/**\n * Pushes the lease's end back by `leaseMs`. A renewal that finds another\n * holder marks the lease lost; one that does not reach the server is tried\n * again at the next beat, and the lease lapses only if none reaches it for a\n * whole `leaseMs`.\n */\nexport async function renew(ctx: SyncContext, lease: HeldLease): Promise<void> {\n\ttry {\n\t\tconst result = await ctx.leases.updateOne(\n\t\t\t{ _id: idOf(ctx), holder: lease.holder },\n\t\t\t[{ $set: { expiresAt: { $add: ['$$NOW', ctx.leaseMs] } } }],\n\t\t);\n\t\tif (result.matchedCount === 0) lease.lost = true;\n\t} catch {\n\t\t// Tried again at the next beat.\n\t}\n}\n\n/**\n * Renews the lease now, and throws `LEASE_LOST` if it is someone else's: the\n * check before a step that must not run beside another holder.\n */\nexport async function confirmLease(\n\tctx: SyncContext,\n\tlease: HeldLease,\n): Promise<void> {\n\tlet result: { matchedCount: number };\n\ttry {\n\t\tresult = await ctx.leases.updateOne(\n\t\t\t{ _id: idOf(ctx), holder: lease.holder },\n\t\t\t[{ $set: { expiresAt: { $add: ['$$NOW', ctx.leaseMs] } } }],\n\t\t);\n\t} catch (error) {\n\t\t// Unlike a timed renewal, not tried again later: what comes next must\n\t\t// not run on a lease nobody could confirm.\n\t\tthrow failed(ctx.name, 'checking its lease', error);\n\t}\n\tif (result.matchedCount === 0) lease.lost = true;\n\tif (lease.lost) throw leaseLost(ctx);\n}\n\n/** Lets go of it, if it is still this holder's. One that fails lapses. */\nexport async function release(\n\tctx: SyncContext,\n\tlease: HeldLease,\n): Promise<void> {\n\tawait ctx.leases\n\t\t.deleteOne({ _id: idOf(ctx), holder: lease.holder })\n\t\t.catch(() => undefined);\n}\n\n/** The error a sync stops with once its lease is someone else's. */\nexport function leaseLost(ctx: SyncContext): SearchSyncError {\n\treturn new SearchSyncError(\n\t\t`Search sync \"${ctx.name}\" lost its lease: another process holds the ` +\n\t\t\t'name now, or the lease was removed (it lapses when not renewed ' +\n\t\t\t`within ${ctx.leaseMs} ms). It stopped rather than run beside it.`,\n\t\t{ code: 'LEASE_LOST', sync: ctx.name },\n\t);\n}\n\n/**\n * Renews the lease every third of `leaseMs`, and calls `onLost` once when a\n * renewal finds it someone else's. Gives back what stops the renewals.\n */\nexport function keepLease(\n\tctx: SyncContext,\n\tlease: HeldLease,\n\tonLost: () => void,\n): () => void {\n\tlet stopped = false;\n\tconst beat = setInterval(\n\t\t() => {\n\t\t\tvoid renew(ctx, lease).then(() => {\n\t\t\t\t// A renewal still in flight when it was stopped reports nothing.\n\t\t\t\tif (lease.lost && !stopped) {\n\t\t\t\t\tclearInterval(beat);\n\t\t\t\t\tonLost();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\tMath.max(1, Math.floor(ctx.leaseMs / 3)),\n\t);\n\treturn () => {\n\t\tstopped = true;\n\t\tclearInterval(beat);\n\t};\n}\n\n/**\n * Runs `fn` holding the lease, renewed every third of `leaseMs`. `fn` checks\n * it is still held where that matters (`confirmLease`).\n */\nexport async function withLease<T>(\n\tctx: SyncContext,\n\tdoing: string,\n\tfn: (lease: HeldLease) => Promise<T>,\n): Promise<T> {\n\tconst lease = await acquire(ctx, doing);\n\tconst stop = keepLease(ctx, lease, () => undefined);\n\ttry {\n\t\treturn await fn(lease);\n\t} finally {\n\t\tstop();\n\t\tawait release(ctx, lease);\n\t}\n}\n",
12
+ "import type { AnyIndexDefinition, TypedIndex } from '@nxgt/meilisearch';\nimport type { AnyCollectionDefinition, TypedCollection } from '@nxgt/mongo';\nimport type { Collection } from 'mongodb';\nimport type { LeaseDocument } from '../run/lease';\nimport type { SearchSyncOptions, SearchSyncState } from './types';\n\n/** Loosely typed: this layer works on any documents; the public types are what callers see. */\nexport type Doc = Record<string, unknown>;\n\n/**\n * What a sync works from, resolved once. Data, and the caller's own two\n * functions as they were given.\n */\nexport interface SyncContext {\n\treadonly name: string;\n\treadonly collection: TypedCollection<AnyCollectionDefinition>;\n\treadonly index: TypedIndex<AnyIndexDefinition>;\n\treadonly primaryKey: string;\n\treadonly state: Collection<SearchSyncState>;\n\t/** The same collection, for the lease documents it also holds. */\n\treadonly leases: Collection<LeaseDocument>;\n\t/** How long a lease lasts unrenewed, in ms. */\n\treadonly leaseMs: number;\n\treadonly batchSize: number;\n\treadonly flushIntervalMs: number;\n\treadonly positionIntervalMs: number;\n\treadonly pageSize: number;\n\treadonly onHistoryLost: 'reindex' | 'fail';\n\treadonly transform: (document: Doc) => unknown;\n\treadonly toIndexId: (id: unknown) => unknown;\n\t/**\n\t * Whether this sync is following changes in this process. A reindex\n\t * beside its own follower would remove what the follower has just\n\t * indexed, and the follower would never send it again.\n\t */\n\treadonly follower: { running: boolean };\n}\n\nconst DEFAULT_STATE_COLLECTION = 'nxgt_search_sync';\n\nfunction positive(option: string, value: number | undefined, fallback: number) {\n\tconst resolved = value ?? fallback;\n\tif (!Number.isInteger(resolved) || resolved < 1) {\n\t\tthrow new TypeError(\n\t\t\t`createSearchSync: ${option} must be a whole number above 0, not ${String(value)}`,\n\t\t);\n\t}\n\treturn resolved;\n}\n\nexport function createContext(\n\toptions: SearchSyncOptions<AnyCollectionDefinition, AnyIndexDefinition>,\n): SyncContext {\n\tconst { collection, index } = options;\n\tif (typeof options.transform !== 'function') {\n\t\tthrow new TypeError('createSearchSync: transform must be a function');\n\t}\n\tconst name = options.name ?? `${collection.collectionName}:${index.uid}`;\n\tif (name === '') {\n\t\tthrow new TypeError('createSearchSync: name must not be empty');\n\t}\n\tconst flushIntervalMs = options.flushIntervalMs ?? 1000;\n\tif (!Number.isInteger(flushIntervalMs) || flushIntervalMs < 0) {\n\t\tthrow new TypeError(\n\t\t\t`createSearchSync: flushIntervalMs must be a whole number of milliseconds, not ${String(options.flushIntervalMs)}`,\n\t\t);\n\t}\n\tconst stateCollection = options.stateCollection ?? DEFAULT_STATE_COLLECTION;\n\treturn {\n\t\tname,\n\t\tcollection,\n\t\tindex,\n\t\tprimaryKey: index.definition.primaryKey as string,\n\t\tstate: collection.db.collection<SearchSyncState>(stateCollection),\n\t\tleases: collection.db.collection<LeaseDocument>(stateCollection),\n\t\tleaseMs: positive('leaseMs', options.leaseMs, 30_000),\n\t\tbatchSize: positive('batchSize', options.batchSize, 500),\n\t\tpositionIntervalMs: positive(\n\t\t\t'positionIntervalMs',\n\t\t\toptions.positionIntervalMs,\n\t\t\t60_000,\n\t\t),\n\t\tflushIntervalMs,\n\t\tpageSize: positive('pageSize', options.pageSize, 100),\n\t\tonHistoryLost: options.onHistoryLost ?? 'reindex',\n\t\ttransform: options.transform as (document: Doc) => unknown,\n\t\ttoIndexId: (options.toIndexId ?? String) as (id: unknown) => unknown,\n\t\tfollower: { running: false },\n\t};\n}\n",
13
+ "import type {\n\tAnyCollectionDefinition,\n\tChangeOf,\n\tChangeSubscription,\n\tCloseReason,\n\tResumeToken,\n} from '@nxgt/mongo';\nimport { send } from '../sync/batch';\nimport type { Doc, SyncContext } from '../sync/context';\nimport { type Entry, entryOf } from '../sync/documents';\nimport { failed, type SearchSyncError } from '../sync/errors';\nimport { clearState, saveState } from '../sync/state';\nimport type { RunningSearchSync } from '../sync/types';\nimport { type HeldLease, keepLease, leaseLost, release } from './lease';\n\nconst noop = () => undefined;\n\n/** What a running sync holds between changes. */\ninterface Following {\n\treadonly pending: Map<string, Entry>;\n\t/** The token of the last change in `pending`. */\n\tlast: ResumeToken | undefined;\n\tsaved: ResumeToken;\n\t/** Changes whose handler has not queued them yet. */\n\tinFlight: number;\n\ttimer: ReturnType<typeof setTimeout> | undefined;\n\t/** Records where the stream is while nothing is being sent. */\n\tbeat: ReturnType<typeof setInterval> | undefined;\n\t/** Stops renewing the lease on the sync's name. */\n\tstopLease: () => void;\n\t/**\n\t * The stream was heard. Only then does `closed` let go of the lease: a\n\t * stream that never got ready leaves it to `start`, which may reindex and\n\t * open again on it after a lost history.\n\t */\n\theard: boolean;\n\t/** Flushes run one after the other. */\n\tchain: Promise<void>;\n\t/** The stream has stopped: what is queued no longer records anything. */\n\tdone: boolean;\n\tfailure: SearchSyncError | undefined;\n}\n\n/**\n * Sends what is pending, then records the token that covers it — or, with\n * nothing to send and no change being handled, where the stream is: a quiet\n * collection would otherwise keep a resume point until the server's history\n * no longer reaches it.\n */\nfunction flush(\n\tctx: SyncContext,\n\tf: Following,\n\tsubscription: ChangeSubscription,\n): Promise<void> {\n\tf.chain = f.chain.then(async () => {\n\t\tif (f.failure) throw f.failure;\n\t\tif (f.done) return;\n\t\tclearTimeout(f.timer);\n\t\tf.timer = undefined;\n\t\tconst entries = [...f.pending.values()];\n\t\tconst upTo = f.last;\n\t\tf.pending.clear();\n\t\ttry {\n\t\t\tif (entries.length > 0) await send(ctx, entries);\n\t\t\tconst idle = entries.length === 0 && f.inFlight === 0;\n\t\t\tconst at = upTo ?? (idle ? subscription.position : undefined);\n\t\t\tif (at && at !== f.saved) {\n\t\t\t\tawait saveState(ctx, at, false);\n\t\t\t\tf.saved = at;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tf.failure ??= failed(ctx.name, 'sending changes', error);\n\t\t\tthrow f.failure;\n\t\t}\n\t});\n\treturn f.chain;\n}\n\n/** A sync that has not heard anything yet, from `token`. */\nfunction following(token: ResumeToken): Following {\n\treturn {\n\t\tpending: new Map(),\n\t\tlast: undefined,\n\t\tsaved: token,\n\t\tinFlight: 0,\n\t\ttimer: undefined,\n\t\tbeat: undefined,\n\t\tstopLease: noop,\n\t\theard: false,\n\t\tchain: Promise.resolve(),\n\t\tdone: false,\n\t\tfailure: undefined,\n\t};\n}\n\n/** Stops everything a running sync does on its own. */\nfunction stopFollowing(ctx: SyncContext, f: Following): void {\n\tf.done = true;\n\tclearTimeout(f.timer);\n\tclearInterval(f.beat);\n\tf.stopLease();\n\tctx.follower.running = false;\n}\n\n/**\n * What `closed` settles to once the stream stops: the reason, or the failure\n * that stopped it — after the last queued flush, and with the lease let go.\n */\nfunction settle(\n\tctx: SyncContext,\n\tf: Following,\n\tsubscription: ChangeSubscription,\n\tlease: HeldLease,\n): Promise<CloseReason> {\n\tconst letGo = () => (f.heard ? release(ctx, lease) : Promise.resolve());\n\treturn subscription.closed.then(\n\t\tasync (reason) => {\n\t\t\tstopFollowing(ctx, f);\n\t\t\ttry {\n\t\t\t\t// A flush the timer or the beat had queued would otherwise record\n\t\t\t\t// a point after this.\n\t\t\t\tawait f.chain.catch(noop);\n\t\t\t\tif (f.failure) throw f.failure;\n\t\t\t\t// The collection is gone, and so is the point the stream stopped\n\t\t\t\t// at: what is recorded is older, and every later start would stop\n\t\t\t\t// here again. Forgetting it makes the next one reindex.\n\t\t\t\tif (reason === 'invalidated') await clearState(ctx);\n\t\t\t\treturn reason;\n\t\t\t} finally {\n\t\t\t\tawait letGo();\n\t\t\t}\n\t\t},\n\t\tasync (error: unknown) => {\n\t\t\tstopFollowing(ctx, f);\n\t\t\tawait letGo();\n\t\t\tthrow f.failure ?? failed(ctx.name, 'following changes', error);\n\t\t},\n\t);\n}\n\nexport async function open(\n\tctx: SyncContext,\n\ttoken: ResumeToken,\n\tlease: HeldLease,\n): Promise<RunningSearchSync> {\n\tconst f = following(token);\n\tconst handle = async (change: ChangeOf<AnyCollectionDefinition>) => {\n\t\tif (f.failure) throw f.failure;\n\t\tf.inFlight += 1;\n\t\tlet entry: Entry;\n\t\ttry {\n\t\t\tconst document =\n\t\t\t\tchange.type === 'delete' ? undefined : (change.document as Doc);\n\t\t\tentry = await entryOf(ctx, change.id, document);\n\t\t} catch (error) {\n\t\t\t// Kept, so `flush` and `close` report it as `closed` does.\n\t\t\tf.failure = failed(ctx.name, 'following changes', error);\n\t\t\tthrow f.failure;\n\t\t} finally {\n\t\t\tf.inFlight -= 1;\n\t\t}\n\t\tf.pending.set(entry.key, entry);\n\t\tf.last = change.resumeToken;\n\t\tif (f.pending.size >= ctx.batchSize) {\n\t\t\tawait flush(ctx, f, subscription);\n\t\t} else if (!f.timer) {\n\t\t\tf.timer = setTimeout(() => {\n\t\t\t\tflush(ctx, f, subscription).catch(() => subscription.close());\n\t\t\t}, ctx.flushIntervalMs);\n\t\t}\n\t};\n\tconst subscription = ctx.collection.onChange(handle, { startAfter: token });\n\tf.beat = setInterval(() => {\n\t\tflush(ctx, f, subscription).catch(() => subscription.close());\n\t}, ctx.positionIntervalMs);\n\t// A lease found gone means another process may be following this name:\n\t// stop at once, before anything else is sent or recorded beside it.\n\tf.stopLease = keepLease(ctx, lease, () => {\n\t\tif (f.failure) return;\n\t\tf.failure = leaseLost(ctx);\n\t\tvoid subscription.close();\n\t});\n\tconst closed = settle(ctx, f, subscription, lease);\n\ttry {\n\t\tawait subscription.ready;\n\t} catch (error) {\n\t\tstopFollowing(ctx, f);\n\t\tclosed.catch(noop);\n\t\tthrow error;\n\t}\n\tf.heard = true;\n\tctx.follower.running = true;\n\tconst close = async () => {\n\t\ttry {\n\t\t\tawait flush(ctx, f, subscription);\n\t\t} finally {\n\t\t\tawait subscription.close();\n\t\t\t// The lease is let go in `closed`'s handler: waited for, so a\n\t\t\t// `reindex` or a `start` right after this finds the name free. Not\n\t\t\t// from inside a change being handled, which `closed` waits for.\n\t\t\tif (f.inFlight === 0) await closed.then(noop, noop);\n\t\t}\n\t};\n\treturn {\n\t\tready: subscription.ready,\n\t\tclosed,\n\t\tflush: () => flush(ctx, f, subscription),\n\t\tclose,\n\t\t[Symbol.asyncDispose]: close,\n\t};\n}\n",
14
+ "import type { ResumeToken } from '@nxgt/mongo';\nimport { open } from '../run/follow';\nimport {\n\tacquire,\n\tconfirmLease,\n\ttype HeldLease,\n\tkeepLease,\n\trelease,\n} from '../run/lease';\nimport { reindexHeld } from '../run/reindex';\nimport type { SyncContext } from './context';\nimport { failed, SearchSyncError } from './errors';\nimport { checkIdle } from './running';\nimport { readState } from './state';\nimport type { RunningSearchSync } from './types';\n\n/** The server no longer has the history a token points into. */\nfunction historyLost(error: unknown): boolean {\n\tconst code = (error as { serverCode?: number } | undefined)?.serverCode;\n\treturn code === 286 || code === 280;\n}\n\n/**\n * Follows the collection from its recorded point — after a reindex when\n * nothing is recorded, or when the point is older than the server's history\n * and `onHistoryLost` allows it.\n */\nexport async function start(ctx: SyncContext): Promise<RunningSearchSync> {\n\tcheckIdle(ctx, 'start it twice');\n\t// Before anything else, the first reindex included: two processes\n\t// starting at once would otherwise both reindex, and both follow.\n\tconst lease = await acquire(ctx, 'start it');\n\t// Renewed while it reindexes, which can outlast `leaseMs`; the follower\n\t// renews it on its own once it is open.\n\tconst stop = keepLease(ctx, lease, () => undefined);\n\ttry {\n\t\tconst running = await startHeld(ctx, lease);\n\t\tstop();\n\t\treturn running;\n\t} catch (error) {\n\t\tstop();\n\t\tawait release(ctx, lease);\n\t\tthrow error;\n\t}\n}\n\n/** Opens the follower, once the server confirms the lease is still held. */\nasync function openHeld(\n\tctx: SyncContext,\n\ttoken: ResumeToken,\n\tlease: HeldLease,\n): Promise<RunningSearchSync> {\n\tawait confirmLease(ctx, lease);\n\treturn open(ctx, token, lease);\n}\n\nasync function startHeld(\n\tctx: SyncContext,\n\tlease: HeldLease,\n): Promise<RunningSearchSync> {\n\tlet state = await readState(ctx);\n\tif (!state) {\n\t\tawait reindexHeld(ctx, lease);\n\t\tstate = await readState(ctx);\n\t}\n\ttry {\n\t\treturn await openHeld(\n\t\t\tctx,\n\t\t\t(state as { resumeToken: ResumeToken }).resumeToken,\n\t\t\tlease,\n\t\t);\n\t} catch (error) {\n\t\tif (!historyLost(error)) throw failed(ctx.name, 'starting', error);\n\t\tif (ctx.onHistoryLost === 'fail') {\n\t\t\tthrow new SearchSyncError(\n\t\t\t\t`Search sync \"${ctx.name}\" was last at a point the server's change ` +\n\t\t\t\t\t'history no longer reaches. Reindex it, or start it with ' +\n\t\t\t\t\t\"onHistoryLost: 'reindex'.\",\n\t\t\t\t{ code: 'HISTORY_LOST', sync: ctx.name, cause: error },\n\t\t\t);\n\t\t}\n\t\tawait reindexHeld(ctx, lease);\n\t\tconst fresh = (await readState(ctx)) as { resumeToken: ResumeToken };\n\t\ttry {\n\t\t\treturn await openHeld(ctx, fresh.resumeToken, lease);\n\t\t} catch (again) {\n\t\t\tthrow failed(ctx.name, 'starting', again);\n\t\t}\n\t}\n}\n",
15
+ "import type { AnyIndexDefinition } from '@nxgt/meilisearch';\nimport type { AnyCollectionDefinition } from '@nxgt/mongo';\nimport { reindex } from '../run/reindex';\nimport { createContext } from './context';\nimport { start } from './start';\nimport { readState } from './state';\nimport type { SearchSync, SearchSyncOptions } from './types';\n\n/**\n * Keeps an index in step with a collection.\n *\n * ```ts\n * const usersSearch = createSearchSync({\n * \tcollection: getCollection(db, users),\n * \tindex: bindIndex(meili, userIndex),\n * \ttransform: (user) => (user.active ? { id: user.id, name: user.name } : null),\n * });\n * const running = await usersSearch.start(); // reindexes the first time\n * // …\n * await running.close();\n * ```\n *\n * Nothing is sent before `reindex` or `start`.\n */\nexport function createSearchSync<\n\tC extends AnyCollectionDefinition,\n\tI extends AnyIndexDefinition,\n>(options: SearchSyncOptions<C, I>): SearchSync {\n\t// The one place the caller's types are let go: a method taking `IdOf<C>`\n\t// is not one taking any id, so the widening cannot be implicit. Below\n\t// here, documents are records and ids are values.\n\tconst ctx = createContext(\n\t\toptions as unknown as SearchSyncOptions<\n\t\t\tAnyCollectionDefinition,\n\t\t\tAnyIndexDefinition\n\t\t>,\n\t);\n\treturn {\n\t\tname: ctx.name,\n\t\treindex: () => reindex(ctx),\n\t\tstart: () => start(ctx),\n\t\tstate: () => readState(ctx),\n\t};\n}\n"
16
16
  ],
17
- "mappings": ";AAsCA,IAAM,2BAA2B;AAEjC,SAAS,QAAQ,CAAC,QAAgB,OAA2B,UAAkB;AAAA,EAC9E,MAAM,WAAW,SAAS;AAAA,EAC1B,IAAI,CAAC,OAAO,UAAU,QAAQ,KAAK,WAAW,GAAG;AAAA,IAChD,MAAM,IAAI,UACT,qBAAqB,8CAA8C,OAAO,KAAK,GAChF;AAAA,EACD;AAAA,EACA,OAAO;AAAA;AAGD,SAAS,aAAa,CAC5B,SACc;AAAA,EACd,QAAQ,YAAY,UAAU;AAAA,EAC9B,IAAI,OAAO,QAAQ,cAAc,YAAY;AAAA,IAC5C,MAAM,IAAI,UAAU,gDAAgD;AAAA,EACrE;AAAA,EACA,MAAM,OAAO,QAAQ,QAAQ,GAAG,WAAW,kBAAkB,MAAM;AAAA,EACnE,IAAI,SAAS,IAAI;AAAA,IAChB,MAAM,IAAI,UAAU,0CAA0C;AAAA,EAC/D;AAAA,EACA,MAAM,kBAAkB,QAAQ,mBAAmB;AAAA,EACnD,IAAI,CAAC,OAAO,UAAU,eAAe,KAAK,kBAAkB,GAAG;AAAA,IAC9D,MAAM,IAAI,UACT,iFAAiF,OAAO,QAAQ,eAAe,GAChH;AAAA,EACD;AAAA,EACA,MAAM,kBAAkB,QAAQ,mBAAmB;AAAA,EACnD,OAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,MAAM,WAAW;AAAA,IAC7B,OAAO,WAAW,GAAG,WAA4B,eAAe;AAAA,IAChE,QAAQ,WAAW,GAAG,WAA0B,eAAe;AAAA,IAC/D,SAAS,SAAS,WAAW,QAAQ,SAAS,KAAM;AAAA,IACpD,WAAW,SAAS,aAAa,QAAQ,WAAW,GAAG;AAAA,IACvD,oBAAoB,SACnB,sBACA,QAAQ,oBACR,KACD;AAAA,IACA;AAAA,IACA,UAAU,SAAS,YAAY,QAAQ,UAAU,GAAG;AAAA,IACpD,eAAe,QAAQ,iBAAiB;AAAA,IACxC,WAAW,QAAQ;AAAA,IACnB,WAAY,QAAQ,aAAa;AAAA,IACjC,UAAU,EAAE,SAAS,MAAM;AAAA,EAC5B;AAAA;;;ACvFD;;;ACMA,IAAM,OAAO,EAAE,MAAM,EAAE,SAAS,OAAQ,EAAE;AAE1C,SAAS,MAAS,CAAC,OAAqB,MAAqB;AAAA,EAC5D,MAAM,MAAa,CAAC;AAAA,EACpB,SAAS,IAAI,EAAG,IAAI,MAAM,QAAQ,KAAK,MAAM;AAAA,IAC5C,IAAI,KAAK,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC;AAAA,EAClC;AAAA,EACA,OAAO;AAAA;AAIR,eAAsB,aAAa,CAClC,KACA,WACgB;AAAA,EAChB,WAAW,SAAS,OAAO,WAAW,IAAI,SAAS,GAAG;AAAA,IACrD,MAAM,IAAI,MAAM,IAAI,OAAO,IAAI;AAAA,EAChC;AAAA;AAID,eAAsB,SAAS,CAC9B,KACA,KACgB;AAAA,EAChB,WAAW,SAAS,OAAO,KAAK,IAAI,SAAS,GAAG;AAAA,IAC/C,MAAM,IAAI,MAAM,OAAO,OAAO,IAAI;AAAA,EACnC;AAAA;AAOD,eAAsB,IAAI,CACzB,KACA,SACgB;AAAA,EAChB,MAAM,YAAmB,CAAC;AAAA,EAC1B,MAAM,MAAiB,CAAC;AAAA,EACxB,WAAW,SAAS,SAAS;AAAA,IAC5B,IAAI,MAAM,SAAS;AAAA,MAAU,UAAU,KAAK,MAAM,QAAQ;AAAA,IACrD;AAAA,UAAI,KAAK,MAAM,EAAE;AAAA,EACvB;AAAA,EACA,MAAM,cAAc,KAAK,SAAS;AAAA,EAClC,MAAM,UAAU,KAAK,GAAG;AAAA;;;ACpBlB,MAAM,wBAAwB,MAAM;AAAA,EAsB1C,WAAW,CAAC,SAAiB,SAAiC;AAAA,IAC7D,MACC,SACA,QAAQ,UAAU,YAAY,YAAY,EAAE,OAAO,QAAQ,MAAM,CAClE;AAAA,IAzBQ,YAAO;AAAA,IA0Bf,KAAK,OAAO,QAAQ;AAAA,IACpB,KAAK,OAAO,QAAQ;AAAA,IACpB,KAAK,SAAS,QAAQ;AAAA,IACtB,KAAK,YAAY,QAAQ;AAAA;AAE3B;AAGO,SAAS,MAAM,CAAC,MAAc,OAAe,OAAgB;AAAA,EACnE,IAAI,iBAAiB;AAAA,IAAiB,OAAO;AAAA,EAC7C,MAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,EACpE,OAAO,IAAI,gBACV,gBAAgB,gBAAgB,UAAU,UAC1C;AAAA,IACC,MAAM;AAAA,IACN;AAAA,IACA,OAAO;AAAA,EACR,CACD;AAAA;;;ACpEM,IAAM,QAAQ,CAAC,OAAgB,GAAG,OAAO,MAAM,OAAO,EAAE;AAE/D,IAAM,WAAW,CAAC,UACjB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAGpE,SAAS,QAAQ,CAAC,OAAwB;AAAA,EACzC,IAAI,MAAM,QAAQ,KAAK;AAAA,IAAG,OAAO;AAAA,EACjC,IAAI,UAAU;AAAA,IAAW,OAAO;AAAA,EAChC,OAAO,KAAK,OAAO;AAAA;AAOpB,eAAsB,OAAO,CAC5B,KACA,SACA,UACiB;AAAA,EACjB,MAAM,KAAK,IAAI,UAAU,OAAO;AAAA,EAChC,MAAM,MAAM,MAAM,EAAE;AAAA,EACpB,IAAI,CAAC;AAAA,IAAU,OAAO,EAAE,MAAM,UAAU,KAAK,GAAG;AAAA,EAChD,MAAM,UAAU,MAAM,IAAI,UAAU,QAAQ;AAAA,EAC5C,IAAI,YAAY;AAAA,IAAM,OAAO,EAAE,MAAM,UAAU,KAAK,GAAG;AAAA,EACvD,IAAI,CAAC,SAAS,OAAO,GAAG;AAAA,IAKvB,MAAM,IAAI,gBACT,gBAAgB,IAAI,yBAAyB,SAAS,OAAO,WAC5D,gBAAgB,OAAO,OAAO,mCAC9B,kCACD,EAAE,MAAM,kBAAkB,MAAM,IAAI,KAAK,CAC1C;AAAA,EACD;AAAA,EACA,MAAM,QAAQ,QAAQ,IAAI;AAAA,EAC1B,IAAI,MAAM,KAAK,MAAM,KAAK;AAAA,IACzB,MAAM,IAAI,gBACT,gBAAgB,IAAI,0BAA0B,IAAI,iBACjD,GAAG,KAAK,UAAU,KAAK,sBAAsB,OAAO,OAAO,cAC3D,eAAe,KAAK,UAAU,EAAE,oCAChC,gDACD,EAAE,MAAM,eAAe,MAAM,IAAI,KAAK,CACvC;AAAA,EACD;AAAA,EACA,OAAO,EAAE,MAAM,UAAU,KAAK,UAAU,QAAQ;AAAA;;;ACzDjD;AACA;AA6BA,IAAM,OAAO,CAAC,SAAsB,EAAE,OAAO,IAAI,KAAK;AAatD,eAAe,IAAI,CAAC,KAAkB,QAAkC;AAAA,EACvE,MAAM,OAAO;AAAA,IACZ,KAAK;AAAA,MACJ,EAAE,KAAK,CAAC,EAAE,OAAO,aAAa,GAAG,SAAS,EAAE;AAAA,MAC5C,EAAE,MAAM,CAAC,cAAc,OAAO,EAAE;AAAA,IACjC;AAAA,EACD;AAAA,EACA,MAAM,OAAO,CAAC,MAAe,YAAoB;AAAA,IAChD,OAAO,CAAC,MAAM,MAAM,MAAM;AAAA,EAC3B;AAAA,EACA,IAAI;AAAA,IACH,MAAM,QAAQ,MAAM,IAAI,OAAO,iBAC9B,EAAE,KAAK,KAAK,GAAG,EAAE,GACjB;AAAA,MACC;AAAA,QACC,MAAM;AAAA,UACL,QAAQ,KAAK,EAAE,UAAU,OAAO,GAAG,SAAS;AAAA,UAC5C,YAAY,KAAK,SAAS,aAAa;AAAA,UACvC,WAAW,KAAK,EAAE,MAAM,CAAC,SAAS,IAAI,OAAO,EAAE,GAAG,YAAY;AAAA,QAC/D;AAAA,MACD;AAAA,IACD,GACA,EAAE,QAAQ,MAAM,gBAAgB,QAAQ,CACzC;AAAA,IACA,OAAO,OAAO,WAAW;AAAA,IACxB,OAAO,OAAO;AAAA,IAEf,IAAK,MAA4B,SAAS;AAAA,MAAO,OAAO;AAAA,IACxD,MAAM;AAAA;AAAA;AAWR,eAAsB,OAAO,CAC5B,KACA,OACqB;AAAA,EACrB,MAAM,SAAS,GAAG,SAAS,KAAK,QAAQ,OAAO,IAAI,SAAS,EAAE,YAAY;AAAA,EAC1E,IAAI,UAAgC;AAAA,EACpC,IAAI;AAAA,IAGH,SAAS,UAAU,EAAG,UAAU,GAAG,WAAW,GAAG;AAAA,MAChD,IAAI,MAAM,KAAK,KAAK,MAAM;AAAA,QAAG,OAAO,EAAE,QAAQ,MAAM,MAAM;AAAA,MAC1D,UAAU,MAAM,IAAI,OAAO,QAAQ,EAAE,KAAK,KAAK,GAAG,EAAE,CAAC;AAAA,MACrD,IAAI;AAAA,QAAS;AAAA,IACd;AAAA,IACC,OAAO,OAAO;AAAA,IACf,MAAM,OAAO,IAAI,MAAM,oBAAoB,KAAK;AAAA;AAAA,EAIjD,MAAM,QACL,SAAS,qBAAqB,OAAO,QAAQ,YAAY;AAAA,EAC1D,MAAM,SACL,OAAO,SAAS,WAAW,WAAW,QAAQ,SAAS;AAAA,EACxD,MAAM,YAAY,WAAW,YAAY,YAAY;AAAA,EACrD,MAAM,IAAI,gBACT,gBAAgB,IAAI,oBAAoB,UAAU,uBACjD,SAAS,OAAO,YAAY,KAAK,mBACjC,+DAA+D,UAChE;AAAA,IACC,MAAM;AAAA,IACN,MAAM,IAAI;AAAA,IACV,QAAQ;AAAA,IACR;AAAA,EACD,CACD;AAAA;AASD,eAAsB,KAAK,CAAC,KAAkB,OAAiC;AAAA,EAC9E,IAAI;AAAA,IACH,MAAM,SAAS,MAAM,IAAI,OAAO,UAC/B,EAAE,KAAK,KAAK,GAAG,GAAG,QAAQ,MAAM,OAAO,GACvC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,SAAS,IAAI,OAAO,EAAE,EAAE,EAAE,CAAC,CAC3D;AAAA,IACA,IAAI,OAAO,iBAAiB;AAAA,MAAG,MAAM,OAAO;AAAA,IAC3C,MAAM;AAAA;AAST,eAAsB,YAAY,CACjC,KACA,OACgB;AAAA,EAChB,IAAI;AAAA,EACJ,IAAI;AAAA,IACH,SAAS,MAAM,IAAI,OAAO,UACzB,EAAE,KAAK,KAAK,GAAG,GAAG,QAAQ,MAAM,OAAO,GACvC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,SAAS,IAAI,OAAO,EAAE,EAAE,EAAE,CAAC,CAC3D;AAAA,IACC,OAAO,OAAO;AAAA,IAGf,MAAM,OAAO,IAAI,MAAM,sBAAsB,KAAK;AAAA;AAAA,EAEnD,IAAI,OAAO,iBAAiB;AAAA,IAAG,MAAM,OAAO;AAAA,EAC5C,IAAI,MAAM;AAAA,IAAM,MAAM,UAAU,GAAG;AAAA;AAIpC,eAAsB,OAAO,CAC5B,KACA,OACgB;AAAA,EAChB,MAAM,IAAI,OACR,UAAU,EAAE,KAAK,KAAK,GAAG,GAAG,QAAQ,MAAM,OAAO,CAAC,EAClD,MAAM,MAAG;AAAA,IAAG;AAAA,GAAS;AAAA;AAIjB,SAAS,SAAS,CAAC,KAAmC;AAAA,EAC5D,OAAO,IAAI,gBACV,gBAAgB,IAAI,qDACnB,oEACA,UAAU,IAAI,sDACf,EAAE,MAAM,cAAc,MAAM,IAAI,KAAK,CACtC;AAAA;AAOM,SAAS,SAAS,CACxB,KACA,OACA,QACa;AAAA,EACb,IAAI,UAAU;AAAA,EACd,MAAM,OAAO,YACZ,MAAM;AAAA,IACA,MAAM,KAAK,KAAK,EAAE,KAAK,MAAM;AAAA,MAEjC,IAAI,MAAM,QAAQ,CAAC,SAAS;AAAA,QAC3B,cAAc,IAAI;AAAA,QAClB,OAAO;AAAA,MACR;AAAA,KACA;AAAA,KAEF,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,UAAU,CAAC,CAAC,CACxC;AAAA,EACA,OAAO,MAAM;AAAA,IACZ,UAAU;AAAA,IACV,cAAc,IAAI;AAAA;AAAA;AAQpB,eAAsB,SAAY,CACjC,KACA,OACA,IACa;AAAA,EACb,MAAM,QAAQ,MAAM,QAAQ,KAAK,KAAK;AAAA,EACtC,MAAM,OAAO,UAAU,KAAK,OAAO,MAAG;AAAA,IAAG;AAAA,GAAS;AAAA,EAClD,IAAI;AAAA,IACH,OAAO,MAAM,GAAG,KAAK;AAAA,YACpB;AAAA,IACD,KAAK;AAAA,IACL,MAAM,QAAQ,KAAK,KAAK;AAAA;AAAA;;;ACnNnB,SAAS,SAAS,CAAC,KAAkB,OAAqB;AAAA,EAChE,IAAI,CAAC,IAAI,SAAS;AAAA,IAAS;AAAA,EAC3B,MAAM,IAAI,gBACT,gBAAgB,IAAI,gDACnB,gCAAgC,UACjC,EAAE,MAAM,WAAW,MAAM,IAAI,KAAK,CACnC;AAAA;;;ACZD,eAAsB,SAAS,CAC9B,KACuC;AAAA,EACvC,IAAI;AAAA,IACH,OAAQ,MAAM,IAAI,MAAM,QAAQ,EAAE,KAAK,IAAI,KAAK,CAAC,KAAM;AAAA,IACtD,OAAO,OAAO;AAAA,IACf,MAAM,OAAO,IAAI,MAAM,4BAA4B,KAAK;AAAA;AAAA;AAK1D,eAAsB,UAAU,CAAC,KAAiC;AAAA,EACjE,IAAI;AAAA,IACH,MAAM,IAAI,MAAM,UAAU,EAAE,KAAK,IAAI,KAAK,CAAC;AAAA,IAC1C,OAAO,OAAO;AAAA,IACf,MAAM,OAAO,IAAI,MAAM,+BAA+B,KAAK;AAAA;AAAA;AAK7D,eAAsB,SAAS,CAC9B,KACA,aACA,WACgB;AAAA,EAChB,MAAM,MAAM,IAAI;AAAA,EAChB,IAAI;AAAA,IACH,MAAM,IAAI,MAAM,UACf,EAAE,KAAK,IAAI,KAAK,GAChB;AAAA,MACC,MAAM;AAAA,QACL;AAAA,QACA,WAAW;AAAA,WACP,YAAY,EAAE,aAAa,IAAI,IAAI,CAAC;AAAA,MACzC;AAAA,IACD,GACA,EAAE,QAAQ,KAAK,CAChB;AAAA,IACC,OAAO,OAAO;AAAA,IACf,MAAM,OAAO,IAAI,MAAM,8BAA8B,KAAK;AAAA;AAAA;;;AN7B5D,eAAe,YAAY,CAAC,KAAwC;AAAA,EACnE,MAAM,SAAS,IAAI,WAAW,IAAI,MAAM,CAAC,GAAG,EAAE,gBAAgB,EAAE,CAAC;AAAA,EACjE,IAAI;AAAA,IACH,MAAM,OAAO,QAAQ;AAAA,IACrB,OAAO,OAAO;AAAA,YACb;AAAA,IACD,MAAM,OAAO,MAAM;AAAA;AAAA;AAKrB,eAAe,OAAO,CACrB,KACA,QACA,OACC;AAAA,EACD,IAAI,UAAU;AAAA,EACd,IAAI,UAAU;AAAA,EACd,IAAI;AAAA,EACJ,GAAG;AAAA,IACF,MAAM,OAAO,MAAM,IAAI,WAAW,iBAAiB;AAAA,MAClD;AAAA,MACA,OAAO,IAAI;AAAA,IACZ,CAAC;AAAA,IACD,MAAM,YAAmB,CAAC;AAAA,IAC1B,WAAW,YAAY,KAAK,OAAgB;AAAA,MAC3C,MAAM,QAAQ,MAAM,QAAQ,KAAK,SAAS,KAAK,QAAQ;AAAA,MACvD,IAAI,MAAM,SAAS,UAAU;AAAA,QAC5B,WAAW;AAAA,QACX;AAAA,MACD;AAAA,MACA,OAAO,IAAI,MAAM,GAAG;AAAA,MACpB,UAAU,KAAK,MAAM,QAAQ;AAAA,IAC9B;AAAA,IACA,MAAM,cAAc,KAAK,SAAS;AAAA,IAClC,WAAW,UAAU;AAAA,IAErB,IAAI,MAAM;AAAA,MAAM,MAAM,UAAU,GAAG;AAAA,IACnC,QAAQ,KAAK;AAAA,EACd,SAAS;AAAA,EACT,OAAO,EAAE,SAAS,QAAQ;AAAA;AAG3B,IAAM,aAAa;AAGnB,IAAM,eAAe,CAAC,UACrB,iBAAiB,uBACjB,MAAM,OAAO,SAAS;AAGvB,eAAe,cAAc,CAC5B,KACA,QACkB;AAAA,EAClB,MAAM,WAAsB,CAAC;AAAA,EAC7B,SAAS,SAAS,IAAK,UAAU,YAAY;AAAA,IAC5C,MAAM,OAAO,MAAM,IAAI,MAAM,IAC3B,aAAa,EAAE,QAAQ,CAAC,IAAI,UAAU,GAAG,OAAO,YAAY,OAAO,CAAC,EACpE,MAAM,CAAC,UAAmB;AAAA,MAC1B,IAAI,aAAa,KAAK;AAAA,QAAG;AAAA,MACzB,MAAM;AAAA,KACN;AAAA,IACF,IAAI,CAAC;AAAA,MAAM,OAAO;AAAA,IAClB,WAAW,YAAY,KAAK,SAAkB;AAAA,MAC7C,MAAM,KAAK,SAAS,IAAI;AAAA,MACxB,IAAI,CAAC,OAAO,IAAI,MAAM,EAAE,CAAC;AAAA,QAAG,SAAS,KAAK,EAAE;AAAA,IAC7C;AAAA,IACA,IAAI,SAAS,cAAc,KAAK;AAAA,MAAO;AAAA,EACxC;AAAA,EACA,MAAM,UAAU,KAAK,QAAQ;AAAA,EAC7B,OAAO,SAAS;AAAA;AAQjB,eAAsB,OAAO,CAAC,KAA0C;AAAA,EACvE,UAAU,KAAK,SAAS;AAAA,EACxB,OAAO,UAAU,KAAK,WAAW,CAAC,UAAU,YAAY,KAAK,KAAK,CAAC;AAAA;AASpE,eAAsB,WAAW,CAChC,KACA,OACyB;AAAA,EACzB,IAAI;AAAA,IAGH,MAAM,QAAQ,MAAM,aAAa,GAAG;AAAA,IACpC,MAAM,SAAS,IAAI;AAAA,IACnB,QAAQ,SAAS,YAAY,MAAM,QAAQ,KAAK,QAAQ,KAAK;AAAA,IAC7D,MAAM,aAAa,KAAK,KAAK;AAAA,IAC7B,MAAM,UAAU,MAAM,eAAe,KAAK,MAAM;AAAA,IAChD,MAAM,aAAa,KAAK,KAAK;AAAA,IAC7B,MAAM,UAAU,KAAK,OAAO,IAAI;AAAA,IAChC,OAAO,EAAE,SAAS,SAAS,QAAQ;AAAA,IAClC,OAAO,OAAO;AAAA,IACf,MAAM,OAAO,IAAI,MAAM,cAAc,KAAK;AAAA;AAAA;;;AO3G5C,IAAM,OAAO,MAAG;AAAA,EAAG;AAAA;AAkCnB,SAAS,KAAK,CACb,KACA,GACA,cACgB;AAAA,EAChB,EAAE,QAAQ,EAAE,MAAM,KAAK,YAAY;AAAA,IAClC,IAAI,EAAE;AAAA,MAAS,MAAM,EAAE;AAAA,IACvB,IAAI,EAAE;AAAA,MAAM;AAAA,IACZ,aAAa,EAAE,KAAK;AAAA,IACpB,EAAE,QAAQ;AAAA,IACV,MAAM,UAAU,CAAC,GAAG,EAAE,QAAQ,OAAO,CAAC;AAAA,IACtC,MAAM,OAAO,EAAE;AAAA,IACf,EAAE,QAAQ,MAAM;AAAA,IAChB,IAAI;AAAA,MACH,IAAI,QAAQ,SAAS;AAAA,QAAG,MAAM,KAAK,KAAK,OAAO;AAAA,MAC/C,MAAM,OAAO,QAAQ,WAAW,KAAK,EAAE,aAAa;AAAA,MACpD,MAAM,KAAK,SAAS,OAAO,aAAa,WAAW;AAAA,MACnD,IAAI,MAAM,OAAO,EAAE,OAAO;AAAA,QACzB,MAAM,UAAU,KAAK,IAAI,KAAK;AAAA,QAC9B,EAAE,QAAQ;AAAA,MACX;AAAA,MACC,OAAO,OAAO;AAAA,MACf,EAAE,YAAY,OAAO,IAAI,MAAM,mBAAmB,KAAK;AAAA,MACvD,MAAM,EAAE;AAAA;AAAA,GAET;AAAA,EACD,OAAO,EAAE;AAAA;AAIV,SAAS,SAAS,CAAC,OAA+B;AAAA,EACjD,OAAO;AAAA,IACN,SAAS,IAAI;AAAA,IACb,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,OAAO;AAAA,IACP,MAAM;AAAA,IACN,WAAW;AAAA,IACX,OAAO;AAAA,IACP,OAAO,QAAQ,QAAQ;AAAA,IACvB,MAAM;AAAA,IACN,SAAS;AAAA,EACV;AAAA;AAID,SAAS,aAAa,CAAC,KAAkB,GAAoB;AAAA,EAC5D,EAAE,OAAO;AAAA,EACT,aAAa,EAAE,KAAK;AAAA,EACpB,cAAc,EAAE,IAAI;AAAA,EACpB,EAAE,UAAU;AAAA,EACZ,IAAI,SAAS,UAAU;AAAA;AAOxB,SAAS,MAAM,CACd,KACA,GACA,cACA,OACuB;AAAA,EACvB,MAAM,QAAQ,MAAO,EAAE,QAAQ,QAAQ,KAAK,KAAK,IAAI,QAAQ,QAAQ;AAAA,EACrE,OAAO,aAAa,OAAO,KAC1B,OAAO,WAAW;AAAA,IACjB,cAAc,KAAK,CAAC;AAAA,IACpB,IAAI;AAAA,MAGH,MAAM,EAAE,MAAM,MAAM,IAAI;AAAA,MACxB,IAAI,EAAE;AAAA,QAAS,MAAM,EAAE;AAAA,MAIvB,IAAI,WAAW;AAAA,QAAe,MAAM,WAAW,GAAG;AAAA,MAClD,OAAO;AAAA,cACN;AAAA,MACD,MAAM,MAAM;AAAA;AAAA,KAGd,OAAO,UAAmB;AAAA,IACzB,cAAc,KAAK,CAAC;AAAA,IACpB,MAAM,MAAM;AAAA,IACZ,MAAM,EAAE,WAAW,OAAO,IAAI,MAAM,qBAAqB,KAAK;AAAA,GAEhE;AAAA;AAGD,eAAsB,IAAI,CACzB,KACA,OACA,OAC6B;AAAA,EAC7B,MAAM,IAAI,UAAU,KAAK;AAAA,EACzB,MAAM,SAAS,OAAO,WAA8C;AAAA,IACnE,IAAI,EAAE;AAAA,MAAS,MAAM,EAAE;AAAA,IACvB,EAAE,YAAY;AAAA,IACd,IAAI;AAAA,IACJ,IAAI;AAAA,MACH,MAAM,WACL,OAAO,SAAS,WAAW,YAAa,OAAO;AAAA,MAChD,QAAQ,MAAM,QAAQ,KAAK,OAAO,IAAI,QAAQ;AAAA,MAC7C,OAAO,OAAO;AAAA,MAEf,EAAE,UAAU,OAAO,IAAI,MAAM,qBAAqB,KAAK;AAAA,MACvD,MAAM,EAAE;AAAA,cACP;AAAA,MACD,EAAE,YAAY;AAAA;AAAA,IAEf,EAAE,QAAQ,IAAI,MAAM,KAAK,KAAK;AAAA,IAC9B,EAAE,OAAO,OAAO;AAAA,IAChB,IAAI,EAAE,QAAQ,QAAQ,IAAI,WAAW;AAAA,MACpC,MAAM,MAAM,KAAK,GAAG,YAAY;AAAA,IACjC,EAAO,SAAI,CAAC,EAAE,OAAO;AAAA,MACpB,EAAE,QAAQ,WAAW,MAAM;AAAA,QAC1B,MAAM,KAAK,GAAG,YAAY,EAAE,MAAM,MAAM,aAAa,MAAM,CAAC;AAAA,SAC1D,IAAI,eAAe;AAAA,IACvB;AAAA;AAAA,EAED,MAAM,eAAe,IAAI,WAAW,SAAS,QAAQ,EAAE,YAAY,MAAM,CAAC;AAAA,EAC1E,EAAE,OAAO,YAAY,MAAM;AAAA,IAC1B,MAAM,KAAK,GAAG,YAAY,EAAE,MAAM,MAAM,aAAa,MAAM,CAAC;AAAA,KAC1D,IAAI,kBAAkB;AAAA,EAGzB,EAAE,YAAY,UAAU,KAAK,OAAO,MAAM;AAAA,IACzC,IAAI,EAAE;AAAA,MAAS;AAAA,IACf,EAAE,UAAU,UAAU,GAAG;AAAA,IACpB,aAAa,MAAM;AAAA,GACxB;AAAA,EACD,MAAM,SAAS,OAAO,KAAK,GAAG,cAAc,KAAK;AAAA,EACjD,IAAI;AAAA,IACH,MAAM,aAAa;AAAA,IAClB,OAAO,OAAO;AAAA,IACf,cAAc,KAAK,CAAC;AAAA,IACpB,OAAO,MAAM,IAAI;AAAA,IACjB,MAAM;AAAA;AAAA,EAEP,EAAE,QAAQ;AAAA,EACV,IAAI,SAAS,UAAU;AAAA,EACvB,MAAM,QAAQ,YAAY;AAAA,IACzB,IAAI;AAAA,MACH,MAAM,MAAM,KAAK,GAAG,YAAY;AAAA,cAC/B;AAAA,MACD,MAAM,aAAa,MAAM;AAAA,MAIzB,IAAI,EAAE,aAAa;AAAA,QAAG,MAAM,OAAO,KAAK,MAAM,IAAI;AAAA;AAAA;AAAA,EAGpD,OAAO;AAAA,IACN,OAAO,aAAa;AAAA,IACpB;AAAA,IACA,OAAO,MAAM,MAAM,KAAK,GAAG,YAAY;AAAA,IACvC;AAAA,KACC,OAAO,eAAe;AAAA,EACxB;AAAA;;;AChMD,SAAS,WAAW,CAAC,OAAyB;AAAA,EAC7C,MAAM,OAAQ,OAA+C;AAAA,EAC7D,OAAO,SAAS,OAAO,SAAS;AAAA;AAQjC,eAAsB,KAAK,CAAC,KAA8C;AAAA,EACzE,UAAU,KAAK,gBAAgB;AAAA,EAG/B,MAAM,QAAQ,MAAM,QAAQ,KAAK,UAAU;AAAA,EAG3C,MAAM,OAAO,UAAU,KAAK,OAAO,MAAG;AAAA,IAAG;AAAA,GAAS;AAAA,EAClD,IAAI;AAAA,IACH,MAAM,UAAU,MAAM,UAAU,KAAK,KAAK;AAAA,IAC1C,KAAK;AAAA,IACL,OAAO;AAAA,IACN,OAAO,OAAO;AAAA,IACf,KAAK;AAAA,IACL,MAAM,QAAQ,KAAK,KAAK;AAAA,IACxB,MAAM;AAAA;AAAA;AAKR,eAAe,QAAQ,CACtB,KACA,OACA,OAC6B;AAAA,EAC7B,MAAM,aAAa,KAAK,KAAK;AAAA,EAC7B,OAAO,KAAK,KAAK,OAAO,KAAK;AAAA;AAG9B,eAAe,SAAS,CACvB,KACA,OAC6B;AAAA,EAC7B,IAAI,QAAQ,MAAM,UAAU,GAAG;AAAA,EAC/B,IAAI,CAAC,OAAO;AAAA,IACX,MAAM,YAAY,KAAK,KAAK;AAAA,IAC5B,QAAQ,MAAM,UAAU,GAAG;AAAA,EAC5B;AAAA,EACA,IAAI;AAAA,IACH,OAAO,MAAM,SACZ,KACC,MAAuC,aACxC,KACD;AAAA,IACC,OAAO,OAAO;AAAA,IACf,IAAI,CAAC,YAAY,KAAK;AAAA,MAAG,MAAM,OAAO,IAAI,MAAM,YAAY,KAAK;AAAA,IACjE,IAAI,IAAI,kBAAkB,QAAQ;AAAA,MACjC,MAAM,IAAI,gBACT,gBAAgB,IAAI,mDACnB,6DACA,6BACD,EAAE,MAAM,gBAAgB,MAAM,IAAI,MAAM,OAAO,MAAM,CACtD;AAAA,IACD;AAAA,IACA,MAAM,YAAY,KAAK,KAAK;AAAA,IAC5B,MAAM,QAAS,MAAM,UAAU,GAAG;AAAA,IAClC,IAAI;AAAA,MACH,OAAO,MAAM,SAAS,KAAK,MAAM,aAAa,KAAK;AAAA,MAClD,OAAO,OAAO;AAAA,MACf,MAAM,OAAO,IAAI,MAAM,YAAY,KAAK;AAAA;AAAA;AAAA;;;AC9DpC,SAAS,gBAGf,CAAC,SAA8C;AAAA,EAI/C,MAAM,MAAM,cACX,OAID;AAAA,EACA,OAAO;AAAA,IACN,MAAM,IAAI;AAAA,IACV,SAAS,MAAM,QAAQ,GAAG;AAAA,IAC1B,OAAO,MAAM,MAAM,GAAG;AAAA,IACtB,OAAO,MAAM,UAAU,GAAG;AAAA,EAC3B;AAAA;",
18
- "debugId": "FCC6FD234D55BAD364756E2164756E21",
17
+ "mappings": "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",
18
+ "debugId": "E539F463F575811364756E2164756E21",
19
19
  "names": []
20
20
  }
@@ -1,6 +1,6 @@
1
1
  import type { ResumeToken } from '@nxgt/mongo';
2
- import type { SyncContext } from './context';
2
+ import type { SyncContext } from '../sync/context';
3
+ import type { RunningSearchSync } from '../sync/types';
3
4
  import { type HeldLease } from './lease';
4
- import type { RunningSearchSync } from './types';
5
5
  export declare function open(ctx: SyncContext, token: ResumeToken, lease: HeldLease): Promise<RunningSearchSync>;
6
6
  //# sourceMappingURL=follow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"follow.d.ts","sourceRoot":"","sources":["../../src/run/follow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAKX,WAAW,EACX,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAO,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAIxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,KAAK,SAAS,EAAiC,MAAM,SAAS,CAAC;AA+HxE,wBAAsB,IAAI,CACzB,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,SAAS,GACd,OAAO,CAAC,iBAAiB,CAAC,CAkE5B"}
@@ -1,5 +1,5 @@
1
- import type { SyncContext } from './context';
2
- import { SearchSyncError } from './errors';
1
+ import type { SyncContext } from '../sync/context';
2
+ import { SearchSyncError } from '../sync/errors';
3
3
  /**
4
4
  * The lease on a sync's name: one document in the state collection, whose
5
5
  * `_id` is `{ lease: <name> }` — an object, so it can never be a sync's own
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lease.d.ts","sourceRoot":"","sources":["../../src/run/lease.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAU,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEzD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,aAAa;IAC7B,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,IAAI,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;CAChB;AAED,+DAA+D;AAC/D,MAAM,WAAW,SAAS;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,OAAO,CAAC;CACd;AA+CD;;;;;;GAMG;AACH,wBAAsB,OAAO,CAC5B,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,SAAS,CAAC,CAgCpB;AAED;;;;;GAKG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAU7E;AAED;;;GAGG;AACH,wBAAsB,YAAY,CACjC,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,SAAS,GACd,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,0EAA0E;AAC1E,wBAAsB,OAAO,CAC5B,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,SAAS,GACd,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,oEAAoE;AACpE,wBAAgB,SAAS,CAAC,GAAG,EAAE,WAAW,GAAG,eAAe,CAO3D;AAED;;;GAGG;AACH,wBAAgB,SAAS,CACxB,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,MAAM,IAAI,GAChB,MAAM,IAAI,CAkBZ;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAChC,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,GAClC,OAAO,CAAC,CAAC,CAAC,CASZ"}
@@ -1,6 +1,6 @@
1
- import type { SyncContext } from './context';
1
+ import type { SyncContext } from '../sync/context';
2
+ import type { ReindexReport } from '../sync/types';
2
3
  import { type HeldLease } from './lease';
3
- import type { ReindexReport } from './types';
4
4
  /**
5
5
  * A reindex, holding the sync's lease for as long as it runs: a follower in
6
6
  * another process would otherwise have what it just indexed removed, and
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reindex.d.ts","sourceRoot":"","sources":["../../src/run/reindex.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAO,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAKxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAgB,KAAK,SAAS,EAAwB,MAAM,SAAS,CAAC;AAiF7E;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAGtE;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAChC,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,SAAS,GACd,OAAO,CAAC,aAAa,CAAC,CAexB"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../../src/sync/batch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAgBzC,iFAAiF;AACjF,wBAAsB,aAAa,CAClC,GAAG,EAAE,WAAW,EAChB,SAAS,EAAE,SAAS,GAAG,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,sDAAsD;AACtD,wBAAsB,SAAS,CAC9B,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,SAAS,OAAO,EAAE,GACrB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;GAGG;AACH,wBAAsB,IAAI,CACzB,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,SAAS,KAAK,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC,CASf"}
@@ -1,7 +1,7 @@
1
1
  import type { AnyIndexDefinition, TypedIndex } from '@nxgt/meilisearch';
2
2
  import type { AnyCollectionDefinition, TypedCollection } from '@nxgt/mongo';
3
3
  import type { Collection } from 'mongodb';
4
- import type { LeaseDocument } from './lease';
4
+ import type { LeaseDocument } from '../run/lease';
5
5
  import type { SearchSyncOptions, SearchSyncState } from './types';
6
6
  /** Loosely typed: this layer works on any documents; the public types are what callers see. */
7
7
  export type Doc = Record<string, unknown>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/sync/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAElE,+FAA+F;AAC/F,MAAM,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1C;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC,uBAAuB,CAAC,CAAC;IAC9D,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC;IAC5C,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC;IAC3C,+CAA+C;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,SAAS,GAAG,MAAM,CAAC;IAC3C,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,OAAO,CAAC;IAC/C,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,OAAO,KAAK,OAAO,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CACxC;AAcD,wBAAgB,aAAa,CAC5B,OAAO,EAAE,iBAAiB,CAAC,uBAAuB,EAAE,kBAAkB,CAAC,GACrE,WAAW,CAqCb"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-search-sync.d.ts","sourceRoot":"","sources":["../../src/sync/create-search-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAK3D,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE7D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC/B,CAAC,SAAS,uBAAuB,EACjC,CAAC,SAAS,kBAAkB,EAC3B,OAAO,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,UAAU,CAgB9C"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../src/sync/documents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGlD,4DAA4D;AAC5D,MAAM,MAAM,KAAK,GACd;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,OAAO,CAAA;CAAE,CAAC;AAEhD,sEAAsE;AACtE,eAAO,MAAM,KAAK,GAAI,IAAI,OAAO,WAAiC,CAAC;AAYnE;;;GAGG;AACH,wBAAsB,OAAO,CAC5B,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,GAAG,GAAG,SAAS,GACvB,OAAO,CAAC,KAAK,CAAC,CA6BhB"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/sync/errors.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,MAAM,MAAM,mBAAmB;AAC9B,kEAAkE;AAChE,cAAc;AAChB,2EAA2E;GACzE,aAAa;AACf,0EAA0E;GACxE,gBAAgB;AAClB;;;GAGG;GACD,SAAS;AACX;;;GAGG;GACD,YAAY;AACd,0CAA0C;GACxC,QAAQ,CAAC;AAEZ,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,0EAA0E;IAC1E,SAAS,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;CAC7B;AAED,mEAAmE;AACnE,qBAAa,eAAgB,SAAQ,KAAK;IAChC,IAAI,SAAqB;IAClC,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,uBAAuB;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,IAAI,GAAG,SAAS,CAAC;gBAEzB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB;CAU5D;AAED,4EAA4E;AAC5E,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,mBAWjE"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"running.d.ts","sourceRoot":"","sources":["../../src/sync/running.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG7C;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAO/D"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/sync/start.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAI7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAQjD;;;;GAIG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAiBxE"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/sync/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,2EAA2E;AAC3E,wBAAsB,SAAS,CAC9B,GAAG,EAAE,WAAW,GACd,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAMtC;AAED,+DAA+D;AAC/D,wBAAsB,UAAU,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAMhE;AAED,wEAAwE;AACxE,wBAAsB,SAAS,CAC9B,GAAG,EAAE,WAAW,EAChB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,OAAO,GAChB,OAAO,CAAC,IAAI,CAAC,CAiBf"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sync/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxgt/mongo-meilisearch",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "description": "Keeps a Meilisearch index in step with a MongoDB collection: a typed transform, a full reindex, and a change stream that resumes where it stopped",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -49,8 +49,8 @@
49
49
  ]
50
50
  },
51
51
  "devDependencies": {
52
- "@nxgt/meilisearch": "^0.6.0",
53
- "@nxgt/mongo": "^0.18.0",
52
+ "@nxgt/meilisearch": "^0.6.1",
53
+ "@nxgt/mongo": "^0.19.0",
54
54
  "@types/bun": "^1.4.0",
55
55
  "meilisearch": "0.62.0",
56
56
  "mongodb": "7.6.0",
@@ -58,8 +58,8 @@
58
58
  "zod": "4.6.5"
59
59
  },
60
60
  "peerDependencies": {
61
- "@nxgt/meilisearch": "^0.6.0",
62
- "@nxgt/mongo": "^0.18.0",
61
+ "@nxgt/meilisearch": "^0.6.1",
62
+ "@nxgt/mongo": "^0.19.0",
63
63
  "meilisearch": ">=0.62.0 <1",
64
64
  "mongodb": ">=7.0.0 <8",
65
65
  "typescript": "^6.0.3"
@@ -1 +0,0 @@
1
- {"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAgBzC,iFAAiF;AACjF,wBAAsB,aAAa,CAClC,GAAG,EAAE,WAAW,EAChB,SAAS,EAAE,SAAS,GAAG,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,sDAAsD;AACtD,wBAAsB,SAAS,CAC9B,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,SAAS,OAAO,EAAE,GACrB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;GAGG;AACH,wBAAsB,IAAI,CACzB,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,SAAS,KAAK,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC,CASf"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAElE,+FAA+F;AAC/F,MAAM,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1C;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC,uBAAuB,CAAC,CAAC;IAC9D,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC;IAC5C,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC;IAC3C,+CAA+C;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,SAAS,GAAG,MAAM,CAAC;IAC3C,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,OAAO,CAAC;IAC/C,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,OAAO,KAAK,OAAO,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CACxC;AAcD,wBAAgB,aAAa,CAC5B,OAAO,EAAE,iBAAiB,CAAC,uBAAuB,EAAE,kBAAkB,CAAC,GACrE,WAAW,CAqCb"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-search-sync.d.ts","sourceRoot":"","sources":["../src/create-search-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAK3D,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE7D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC/B,CAAC,SAAS,uBAAuB,EACjC,CAAC,SAAS,kBAAkB,EAC3B,OAAO,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,UAAU,CAgB9C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../src/documents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGlD,4DAA4D;AAC5D,MAAM,MAAM,KAAK,GACd;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,OAAO,CAAA;CAAE,CAAC;AAEhD,sEAAsE;AACtE,eAAO,MAAM,KAAK,GAAI,IAAI,OAAO,WAAiC,CAAC;AAYnE;;;GAGG;AACH,wBAAsB,OAAO,CAC5B,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,GAAG,GAAG,SAAS,GACvB,OAAO,CAAC,KAAK,CAAC,CA6BhB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,MAAM,MAAM,mBAAmB;AAC9B,kEAAkE;AAChE,cAAc;AAChB,2EAA2E;GACzE,aAAa;AACf,0EAA0E;GACxE,gBAAgB;AAClB;;;GAGG;GACD,SAAS;AACX;;;GAGG;GACD,YAAY;AACd,0CAA0C;GACxC,QAAQ,CAAC;AAEZ,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,0EAA0E;IAC1E,SAAS,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;CAC7B;AAED,mEAAmE;AACnE,qBAAa,eAAgB,SAAQ,KAAK;IAChC,IAAI,SAAqB;IAClC,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,uBAAuB;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,IAAI,GAAG,SAAS,CAAC;gBAEzB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB;CAU5D;AAED,4EAA4E;AAC5E,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,mBAWjE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"follow.d.ts","sourceRoot":"","sources":["../src/follow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAKX,WAAW,EACX,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAO,WAAW,EAAE,MAAM,WAAW,CAAC;AAGlD,OAAO,EAAE,KAAK,SAAS,EAAiC,MAAM,SAAS,CAAC;AAExE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AA+HjD,wBAAsB,IAAI,CACzB,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,SAAS,GACd,OAAO,CAAC,iBAAiB,CAAC,CAkE5B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"lease.d.ts","sourceRoot":"","sources":["../src/lease.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAU,eAAe,EAAE,MAAM,UAAU,CAAC;AAEnD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,aAAa;IAC7B,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,IAAI,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;CAChB;AAED,+DAA+D;AAC/D,MAAM,WAAW,SAAS;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,OAAO,CAAC;CACd;AA+CD;;;;;;GAMG;AACH,wBAAsB,OAAO,CAC5B,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,SAAS,CAAC,CAgCpB;AAED;;;;;GAKG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAU7E;AAED;;;GAGG;AACH,wBAAsB,YAAY,CACjC,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,SAAS,GACd,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,0EAA0E;AAC1E,wBAAsB,OAAO,CAC5B,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,SAAS,GACd,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,oEAAoE;AACpE,wBAAgB,SAAS,CAAC,GAAG,EAAE,WAAW,GAAG,eAAe,CAO3D;AAED;;;GAGG;AACH,wBAAgB,SAAS,CACxB,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,MAAM,IAAI,GAChB,MAAM,IAAI,CAkBZ;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAChC,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,GAClC,OAAO,CAAC,CAAC,CAAC,CASZ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"reindex.d.ts","sourceRoot":"","sources":["../src/reindex.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAO,WAAW,EAAE,MAAM,WAAW,CAAC;AAGlD,OAAO,EAAgB,KAAK,SAAS,EAAwB,MAAM,SAAS,CAAC;AAG7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAiF7C;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAGtE;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAChC,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,SAAS,GACd,OAAO,CAAC,aAAa,CAAC,CAexB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"running.d.ts","sourceRoot":"","sources":["../src/running.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG7C;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAO/D"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAa7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAQjD;;;;GAIG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAiBxE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,2EAA2E;AAC3E,wBAAsB,SAAS,CAC9B,GAAG,EAAE,WAAW,GACd,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAMtC;AAED,+DAA+D;AAC/D,wBAAsB,UAAU,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAMhE;AAED,wEAAwE;AACxE,wBAAsB,SAAS,CAC9B,GAAG,EAAE,WAAW,EAChB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,OAAO,GAChB,OAAO,CAAC,IAAI,CAAC,CAiBf"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes