@procedures/store 0.0.0-stage → 0.1.0

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 (115) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +21 -0
  3. package/README.md +65 -2
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/errors.d.ts +16 -0
  6. package/dist/errors.d.ts.map +1 -0
  7. package/dist/errors.js +18 -0
  8. package/dist/errors.js.map +1 -0
  9. package/dist/index.d.ts +19 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +19 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/module.d.ts +15 -0
  14. package/dist/module.d.ts.map +1 -0
  15. package/dist/module.js +16 -0
  16. package/dist/module.js.map +1 -0
  17. package/dist/procedures.d.ts +13 -0
  18. package/dist/procedures.d.ts.map +1 -0
  19. package/dist/procedures.js +14 -0
  20. package/dist/procedures.js.map +1 -0
  21. package/dist/program-store/attach.d.ts +20 -0
  22. package/dist/program-store/attach.d.ts.map +1 -0
  23. package/dist/program-store/attach.js +36 -0
  24. package/dist/program-store/attach.js.map +1 -0
  25. package/dist/program-store/collection.d.ts +19 -0
  26. package/dist/program-store/collection.d.ts.map +1 -0
  27. package/dist/program-store/collection.js +34 -0
  28. package/dist/program-store/collection.js.map +1 -0
  29. package/dist/program-store/file.d.ts +29 -0
  30. package/dist/program-store/file.d.ts.map +1 -0
  31. package/dist/program-store/file.js +156 -0
  32. package/dist/program-store/file.js.map +1 -0
  33. package/dist/program-store/index.d.ts +11 -0
  34. package/dist/program-store/index.d.ts.map +1 -0
  35. package/dist/program-store/index.js +10 -0
  36. package/dist/program-store/index.js.map +1 -0
  37. package/dist/program-store/memory.d.ts +15 -0
  38. package/dist/program-store/memory.d.ts.map +1 -0
  39. package/dist/program-store/memory.js +25 -0
  40. package/dist/program-store/memory.js.map +1 -0
  41. package/dist/program-store/procedures.d.ts +23 -0
  42. package/dist/program-store/procedures.d.ts.map +1 -0
  43. package/dist/program-store/procedures.js +221 -0
  44. package/dist/program-store/procedures.js.map +1 -0
  45. package/dist/program-store/types.d.ts +50 -0
  46. package/dist/program-store/types.d.ts.map +1 -0
  47. package/dist/program-store/types.js +41 -0
  48. package/dist/program-store/types.js.map +1 -0
  49. package/dist/register.d.ts +8 -0
  50. package/dist/register.d.ts.map +1 -0
  51. package/dist/register.js +15 -0
  52. package/dist/register.js.map +1 -0
  53. package/dist/storage/adapter.d.ts +148 -0
  54. package/dist/storage/adapter.d.ts.map +1 -0
  55. package/dist/storage/adapter.js +214 -0
  56. package/dist/storage/adapter.js.map +1 -0
  57. package/dist/storage/api.d.ts +125 -0
  58. package/dist/storage/api.d.ts.map +1 -0
  59. package/dist/storage/api.js +220 -0
  60. package/dist/storage/api.js.map +1 -0
  61. package/dist/storage/factory.d.ts +134 -0
  62. package/dist/storage/factory.d.ts.map +1 -0
  63. package/dist/storage/factory.js +166 -0
  64. package/dist/storage/factory.js.map +1 -0
  65. package/dist/storage/hybrid.d.ts +193 -0
  66. package/dist/storage/hybrid.d.ts.map +1 -0
  67. package/dist/storage/hybrid.js +519 -0
  68. package/dist/storage/hybrid.js.map +1 -0
  69. package/dist/storage/index.d.ts +21 -0
  70. package/dist/storage/index.d.ts.map +1 -0
  71. package/dist/storage/index.js +20 -0
  72. package/dist/storage/index.js.map +1 -0
  73. package/dist/storage/procedures.d.ts +14 -0
  74. package/dist/storage/procedures.d.ts.map +1 -0
  75. package/dist/storage/procedures.js +98 -0
  76. package/dist/storage/procedures.js.map +1 -0
  77. package/dist/storage/serialization.d.ts +123 -0
  78. package/dist/storage/serialization.d.ts.map +1 -0
  79. package/dist/storage/serialization.js +216 -0
  80. package/dist/storage/serialization.js.map +1 -0
  81. package/dist/storage/synced-registry.d.ts +246 -0
  82. package/dist/storage/synced-registry.d.ts.map +1 -0
  83. package/dist/storage/synced-registry.js +575 -0
  84. package/dist/storage/synced-registry.js.map +1 -0
  85. package/dist/storage/types.d.ts +130 -0
  86. package/dist/storage/types.d.ts.map +1 -0
  87. package/dist/storage/types.js +8 -0
  88. package/dist/storage/types.js.map +1 -0
  89. package/dist/types.d.ts +7 -0
  90. package/dist/types.d.ts.map +1 -0
  91. package/dist/types.js +7 -0
  92. package/dist/types.js.map +1 -0
  93. package/package.json +79 -3
  94. package/src/errors.ts +20 -0
  95. package/src/index.ts +19 -0
  96. package/src/module.ts +18 -0
  97. package/src/procedures.ts +17 -0
  98. package/src/program-store/attach.ts +46 -0
  99. package/src/program-store/collection.ts +39 -0
  100. package/src/program-store/file.ts +157 -0
  101. package/src/program-store/index.ts +17 -0
  102. package/src/program-store/memory.ts +30 -0
  103. package/src/program-store/procedures.ts +344 -0
  104. package/src/program-store/types.ts +78 -0
  105. package/src/register.ts +18 -0
  106. package/src/storage/adapter.ts +273 -0
  107. package/src/storage/api.ts +335 -0
  108. package/src/storage/factory.ts +268 -0
  109. package/src/storage/hybrid.ts +676 -0
  110. package/src/storage/index.ts +61 -0
  111. package/src/storage/procedures.ts +146 -0
  112. package/src/storage/serialization.ts +283 -0
  113. package/src/storage/synced-registry.ts +698 -0
  114. package/src/storage/types.ts +180 -0
  115. package/src/types.ts +7 -0
@@ -0,0 +1,575 @@
1
+ /**
2
+ * Synced Procedure Registry
3
+ *
4
+ * Wraps ProcedureRegistry with storage synchronization capabilities.
5
+ * Enables procedure persistence and sync across backends.
6
+ */
7
+ import { ProcedureRegistry } from "@procedures/client";
8
+ import { pathToKey } from "@procedures/client";
9
+ import { ProcedureStorageAdapter } from "./adapter.js";
10
+ import { serializeProcedure, deserializeProcedure, getSerializedKey } from "./serialization.js";
11
+ // =============================================================================
12
+ // The store of a registry
13
+ // =============================================================================
14
+ const STORES = new WeakMap();
15
+ /**
16
+ * The synced registry that wraps a registry, if one does. The `procedure.store`, `load`,
17
+ * `sync` and `remote` procedures use it.
18
+ *
19
+ * @param registry - A procedure registry
20
+ * @returns The synced registry of the newest wrapper that is not closed, or undefined
21
+ */
22
+ export function getProcedureStore(registry) {
23
+ return STORES.get(registry);
24
+ }
25
+ // =============================================================================
26
+ // Synced Procedure Registry
27
+ // =============================================================================
28
+ /**
29
+ * Procedure registry with storage synchronization.
30
+ *
31
+ * Wraps an existing ProcedureRegistry and adds:
32
+ * - Automatic persistence on register (write-through/write-back)
33
+ * - Sync from storage on demand
34
+ * - Conflict resolution
35
+ * - Connection management for remote storage
36
+ *
37
+ * A pull compares the `storedAt` of each record with the one of the last sync, and a local
38
+ * change counter for each path. A change on one side only is not a conflict: the changed side
39
+ * wins. A change on both sides (or a path with no sync yet) is a conflict, and the
40
+ * `conflictResolution` option decides. A record with no handler never replaces a procedure
41
+ * that has one: the procedure keeps its handler and takes the record's metadata.
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * const registry = new SyncedProcedureRegistry(
46
+ * PROCEDURE_REGISTRY,
47
+ * storageAdapter,
48
+ * {
49
+ * writeStrategy: 'write-through',
50
+ * conflictResolution: 'remote',
51
+ * }
52
+ * );
53
+ *
54
+ * // Sync from storage on startup
55
+ * await registry.syncFromStorage();
56
+ *
57
+ * // Register with auto-persistence
58
+ * registry.register(myProcedure, { persist: true });
59
+ *
60
+ * // Manual sync
61
+ * const result = await registry.sync('both');
62
+ * ```
63
+ */
64
+ export class SyncedProcedureRegistry {
65
+ baseRegistry;
66
+ adapter;
67
+ options;
68
+ /** Pending changes for write-back strategy */
69
+ pendingChanges = new Map();
70
+ /** Pending deletes for write-back strategy (deep dive DATA-8: they were never deleted) */
71
+ pendingDeletes = new Map();
72
+ /** The handler reference of each path, for the stored records */
73
+ handlerRefs = new Map();
74
+ /** The `storedAt` of the record of each path at its last push or pull */
75
+ syncedAt = new Map();
76
+ /** A counter of local changes for each path, and its value at the last push or pull */
77
+ localVersion = new Map();
78
+ syncedVersion = new Map();
79
+ /** Write-through stores that have not finished */
80
+ inFlight = new Set();
81
+ /** Whether currently connected to remote storage */
82
+ connected = false;
83
+ /** Remote endpoint (if connected) */
84
+ endpoint;
85
+ /** Last sync timestamp */
86
+ lastSyncTime;
87
+ /** Whether currently syncing */
88
+ syncing = false;
89
+ /** Auto-sync interval handle */
90
+ syncIntervalHandle;
91
+ constructor(baseRegistry, storage, options = {}) {
92
+ this.baseRegistry = baseRegistry;
93
+ this.adapter = new ProcedureStorageAdapter(storage, {
94
+ handlerLoader: options.handlerLoader,
95
+ });
96
+ this.options = {
97
+ writeStrategy: options.writeStrategy ?? "write-through",
98
+ conflictResolution: options.conflictResolution ?? "local",
99
+ syncInterval: options.syncInterval ?? 0,
100
+ handlerLoader: options.handlerLoader,
101
+ syncOnInit: options.syncOnInit ?? false,
102
+ };
103
+ // The storage procedures of this registry find this wrapper
104
+ STORES.set(baseRegistry, this);
105
+ // Set up auto-sync if configured
106
+ if (this.options.syncInterval && this.options.syncInterval > 0) {
107
+ this.startAutoSync(this.options.syncInterval);
108
+ }
109
+ }
110
+ // ===========================================================================
111
+ // Registry Methods (delegated to base registry)
112
+ // ===========================================================================
113
+ /**
114
+ * Register a procedure with optional persistence.
115
+ *
116
+ * The record has the path where the procedure is registered: with a `pathPrefix`, the
117
+ * prefixed path. (Before, the record had the path without the prefix: deep dive CORE-8.)
118
+ *
119
+ * @param procedure - Procedure to register
120
+ * @param options - Registration options including persist flag
121
+ */
122
+ register(procedure, options) {
123
+ // Register in base registry
124
+ this.baseRegistry.register(procedure, options);
125
+ const path = options?.pathPrefix ? [...options.pathPrefix, ...procedure.path] : procedure.path;
126
+ const registered = this.baseRegistry.get(path) ?? { ...procedure, path };
127
+ const key = pathToKey(path);
128
+ if (options?.handlerRef) {
129
+ this.handlerRefs.set(key, options.handlerRef);
130
+ }
131
+ this.touch(key);
132
+ if (options?.persist === false) {
133
+ return;
134
+ }
135
+ this.pendingDeletes.delete(key);
136
+ if (this.options.writeStrategy === "write-through") {
137
+ // Write-through: persist now. flushWrites() waits for these writes.
138
+ this.track(this.storeRecords([registered]).catch((err) => {
139
+ console.error(`Failed to persist procedure ${key}:`, err);
140
+ }));
141
+ }
142
+ else {
143
+ // Write-back: queue for later sync
144
+ this.pendingChanges.set(key, registered);
145
+ }
146
+ }
147
+ /**
148
+ * Unregister a procedure. Its record is deleted from storage: now (write-through), or at the
149
+ * next flush (write-back).
150
+ *
151
+ * @param path - Procedure path
152
+ * @returns True if procedure was removed
153
+ */
154
+ unregister(path) {
155
+ const result = this.baseRegistry.unregister(path);
156
+ if (result) {
157
+ const key = pathToKey(path);
158
+ this.pendingChanges.delete(key);
159
+ this.touch(key);
160
+ if (this.options.writeStrategy === "write-through") {
161
+ this.track(this.adapter.remove(path).catch((err) => {
162
+ console.error(`Failed to remove procedure ${key} from storage:`, err);
163
+ }));
164
+ }
165
+ else {
166
+ this.pendingDeletes.set(key, path);
167
+ }
168
+ }
169
+ return result;
170
+ }
171
+ /**
172
+ * Get a procedure by path.
173
+ */
174
+ get(path) {
175
+ return this.baseRegistry.get(path);
176
+ }
177
+ /**
178
+ * Check if a procedure exists.
179
+ */
180
+ has(path) {
181
+ return this.baseRegistry.has(path);
182
+ }
183
+ /**
184
+ * Get all registered procedures.
185
+ */
186
+ getAll() {
187
+ return this.baseRegistry.getAll();
188
+ }
189
+ /**
190
+ * Get procedures by prefix.
191
+ */
192
+ getByPrefix(prefix) {
193
+ return this.baseRegistry.getByPrefix(prefix);
194
+ }
195
+ /**
196
+ * Get count of registered procedures.
197
+ */
198
+ get size() {
199
+ return this.baseRegistry.size;
200
+ }
201
+ // ===========================================================================
202
+ // Sync Operations
203
+ // ===========================================================================
204
+ /**
205
+ * Sync from storage to registry.
206
+ * Loads procedures from storage and merges with registry.
207
+ *
208
+ * @param filter - Pull only the records for which this function gives true (default: all)
209
+ * @returns Sync result with counts and conflicts
210
+ */
211
+ async syncFromStorage(filter) {
212
+ this.syncing = true;
213
+ const conflicts = [];
214
+ let pulled = 0;
215
+ try {
216
+ const records = (await this.adapter.getAllRaw()).filter((record) => !filter || filter(record));
217
+ for (const record of records) {
218
+ const key = getSerializedKey(record);
219
+ const remote = await deserializeProcedure(record, { handlerLoader: this.options.handlerLoader });
220
+ if (record.handlerRef) {
221
+ this.handlerRefs.set(key, record.handlerRef);
222
+ }
223
+ const existing = this.baseRegistry.get(record.path);
224
+ if (!existing) {
225
+ this.baseRegistry.register(remote, { override: false });
226
+ this.markSynced(key, record);
227
+ pulled++;
228
+ continue;
229
+ }
230
+ const known = this.syncedAt.get(key);
231
+ const remoteChanged = known === undefined || (record.storedAt ?? 0) !== known;
232
+ const localChanged = known === undefined || this.isDirty(key);
233
+ if (!remoteChanged) {
234
+ continue;
235
+ }
236
+ if (!localChanged) {
237
+ // Only the remote changed: it wins, and it is not a conflict
238
+ this.baseRegistry.register(this.keepHandler(existing, remote), { override: true });
239
+ this.markSynced(key, record);
240
+ pulled++;
241
+ continue;
242
+ }
243
+ const conflict = this.resolveConflict(record.path, existing, remote);
244
+ if (conflict) {
245
+ conflicts.push(conflict);
246
+ }
247
+ if (conflict?.resolution !== "local") {
248
+ this.markSynced(key, record);
249
+ }
250
+ else {
251
+ // The local version stays, and the next push stores it
252
+ this.syncedAt.set(key, record.storedAt ?? 0);
253
+ }
254
+ }
255
+ this.lastSyncTime = Date.now();
256
+ return {
257
+ pushed: 0,
258
+ pulled,
259
+ conflicts,
260
+ timestamp: this.lastSyncTime,
261
+ };
262
+ }
263
+ finally {
264
+ this.syncing = false;
265
+ }
266
+ }
267
+ /**
268
+ * Sync from registry to storage.
269
+ * Persists all registered procedures to storage, each with its handler reference.
270
+ *
271
+ * @returns Sync result
272
+ */
273
+ async syncToStorage() {
274
+ this.syncing = true;
275
+ try {
276
+ const procedures = this.baseRegistry.getAll();
277
+ await this.storeRecords(procedures);
278
+ await this.removeRecords([...this.pendingDeletes.values()]);
279
+ // Clear pending changes
280
+ this.pendingChanges.clear();
281
+ this.pendingDeletes.clear();
282
+ this.lastSyncTime = Date.now();
283
+ return {
284
+ pushed: procedures.length,
285
+ pulled: 0,
286
+ conflicts: [],
287
+ timestamp: this.lastSyncTime,
288
+ };
289
+ }
290
+ finally {
291
+ this.syncing = false;
292
+ }
293
+ }
294
+ /**
295
+ * Full bidirectional sync.
296
+ *
297
+ * @param direction - Sync direction (push/pull/both)
298
+ * @returns Sync result
299
+ */
300
+ async sync(direction = "both") {
301
+ const results = {
302
+ pushed: 0,
303
+ pulled: 0,
304
+ conflicts: [],
305
+ timestamp: Date.now(),
306
+ };
307
+ if (direction === "pull" || direction === "both") {
308
+ const pullResult = await this.syncFromStorage();
309
+ results.pulled = pullResult.pulled;
310
+ results.conflicts.push(...pullResult.conflicts);
311
+ }
312
+ if (direction === "push" || direction === "both") {
313
+ const pushResult = await this.syncToStorage();
314
+ results.pushed = pushResult.pushed;
315
+ }
316
+ this.lastSyncTime = results.timestamp;
317
+ return results;
318
+ }
319
+ /**
320
+ * Flush pending changes to storage: the queued writes and deletes of the write-back strategy.
321
+ *
322
+ * @returns The number of records written or deleted
323
+ */
324
+ async flushPending() {
325
+ await this.flushWrites();
326
+ const procedures = Array.from(this.pendingChanges.values());
327
+ const deletes = Array.from(this.pendingDeletes.values());
328
+ if (procedures.length === 0 && deletes.length === 0)
329
+ return 0;
330
+ if (procedures.length > 0) {
331
+ await this.storeRecords(procedures);
332
+ }
333
+ await this.removeRecords(deletes);
334
+ this.pendingChanges.clear();
335
+ this.pendingDeletes.clear();
336
+ return procedures.length + deletes.length;
337
+ }
338
+ /**
339
+ * Store the registered procedure at a path now, whatever the write strategy.
340
+ *
341
+ * @param path - Procedure path
342
+ * @param options - A handler reference for the record
343
+ * @returns The stored record, or undefined when no procedure is registered at the path
344
+ */
345
+ async storeProcedure(path, options = {}) {
346
+ const procedure = this.baseRegistry.get(path);
347
+ if (!procedure)
348
+ return undefined;
349
+ const key = pathToKey(path);
350
+ if (options.handlerRef) {
351
+ this.handlerRefs.set(key, options.handlerRef);
352
+ }
353
+ await this.storeRecords([procedure]);
354
+ this.pendingChanges.delete(key);
355
+ this.pendingDeletes.delete(key);
356
+ return this.adapter.getRaw(path);
357
+ }
358
+ /**
359
+ * Wait for the write-through writes that have started.
360
+ */
361
+ async flushWrites() {
362
+ while (this.inFlight.size > 0) {
363
+ await Promise.all([...this.inFlight]);
364
+ }
365
+ }
366
+ // ===========================================================================
367
+ // Connection Management
368
+ // ===========================================================================
369
+ /**
370
+ * Record a remote endpoint, and optionally pull from storage. This method does not change the
371
+ * storage: give the registry an `ApiStorage` for the endpoint when you make it.
372
+ *
373
+ * @param endpoint - Remote endpoint URL
374
+ * @param options - Connection options
375
+ */
376
+ async connect(endpoint, options) {
377
+ this.endpoint = endpoint;
378
+ this.connected = true;
379
+ if (options?.syncOnConnect ?? this.options.syncOnInit) {
380
+ await this.syncFromStorage();
381
+ }
382
+ }
383
+ /**
384
+ * Disconnect from remote storage.
385
+ */
386
+ disconnect() {
387
+ this.connected = false;
388
+ this.endpoint = undefined;
389
+ this.stopAutoSync();
390
+ }
391
+ /**
392
+ * Get current sync status.
393
+ */
394
+ getStatus() {
395
+ return {
396
+ connected: this.connected,
397
+ endpoint: this.endpoint,
398
+ lastSync: this.lastSyncTime,
399
+ pendingChanges: this.pendingChanges.size + this.pendingDeletes.size,
400
+ syncing: this.syncing,
401
+ };
402
+ }
403
+ // ===========================================================================
404
+ // Auto-Sync
405
+ // ===========================================================================
406
+ /**
407
+ * Start auto-sync at specified interval.
408
+ *
409
+ * @param intervalMs - Sync interval in milliseconds
410
+ */
411
+ startAutoSync(intervalMs) {
412
+ this.stopAutoSync();
413
+ const handle = setInterval(() => {
414
+ void this.sync("both").catch((err) => {
415
+ console.error("Auto-sync failed:", err);
416
+ });
417
+ }, intervalMs);
418
+ // Don't let the auto-sync timer keep the process alive. See BUGS-2026-07.md (M4).
419
+ handle.unref?.();
420
+ this.syncIntervalHandle = handle;
421
+ }
422
+ /**
423
+ * Stop auto-sync.
424
+ */
425
+ stopAutoSync() {
426
+ if (this.syncIntervalHandle) {
427
+ clearInterval(this.syncIntervalHandle);
428
+ this.syncIntervalHandle = undefined;
429
+ }
430
+ }
431
+ // ===========================================================================
432
+ // Conflict Resolution
433
+ // ===========================================================================
434
+ /**
435
+ * Resolve a conflict between local and remote procedures.
436
+ *
437
+ * @param path - Procedure path
438
+ * @param local - Local procedure
439
+ * @param remote - Remote procedure
440
+ * @returns Conflict info if not automatically resolved
441
+ */
442
+ resolveConflict(path, local, remote) {
443
+ switch (this.options.conflictResolution) {
444
+ case "local":
445
+ // Keep local, ignore remote
446
+ return {
447
+ path,
448
+ resolution: "local",
449
+ local: serializeProcedure(local),
450
+ remote: serializeProcedure(remote),
451
+ };
452
+ case "remote":
453
+ // Replace with remote, but never replace a handler with a stub (deep dive CORE-8)
454
+ this.baseRegistry.register(this.keepHandler(local, remote), { override: true });
455
+ return {
456
+ path,
457
+ resolution: "remote",
458
+ local: serializeProcedure(local),
459
+ remote: serializeProcedure(remote),
460
+ };
461
+ case "error":
462
+ // Throw error on conflict
463
+ throw new Error(`Sync conflict at ${pathToKey(path)}`);
464
+ case "merge": {
465
+ // Merge metadata, keep local handler
466
+ const merged = {
467
+ ...local,
468
+ metadata: { ...remote.metadata, ...local.metadata },
469
+ };
470
+ this.baseRegistry.register(merged, { override: true });
471
+ return {
472
+ path,
473
+ resolution: "merge",
474
+ local: serializeProcedure(local),
475
+ remote: serializeProcedure(remote),
476
+ };
477
+ }
478
+ default:
479
+ return undefined;
480
+ }
481
+ }
482
+ /**
483
+ * The remote version of a procedure. When the remote record gives no handler (a stub), the
484
+ * local handler and schemas stay, and the remote metadata applies.
485
+ */
486
+ keepHandler(local, remote) {
487
+ if (remote.handler || !local.handler) {
488
+ return remote;
489
+ }
490
+ const merged = { ...local, metadata: { ...remote.metadata } };
491
+ if (remote.streaming !== undefined) {
492
+ merged.streaming = remote.streaming;
493
+ }
494
+ return merged;
495
+ }
496
+ // ===========================================================================
497
+ // Change tracking
498
+ // ===========================================================================
499
+ /** Record a local change of a path. */
500
+ touch(key) {
501
+ this.localVersion.set(key, (this.localVersion.get(key) ?? 0) + 1);
502
+ }
503
+ /** True when the path changed locally since its last push or pull. */
504
+ isDirty(key) {
505
+ return (this.localVersion.get(key) ?? 0) !== (this.syncedVersion.get(key) ?? 0);
506
+ }
507
+ /** Record that storage and the registry agree on a path. */
508
+ markSynced(key, record, version = this.localVersion.get(key) ?? 0) {
509
+ this.syncedAt.set(key, record.storedAt ?? 0);
510
+ this.syncedVersion.set(key, version);
511
+ }
512
+ /** Store records for procedures, each with its handler reference, and mark them synced. */
513
+ async storeRecords(procedures) {
514
+ // The local versions at the start: a change during the write stays dirty
515
+ const versions = procedures.map((procedure) => this.localVersion.get(pathToKey(procedure.path)) ?? 0);
516
+ const records = await this.adapter.storeAll(procedures, (procedure) => {
517
+ const handlerRef = this.handlerRefs.get(pathToKey(procedure.path));
518
+ return handlerRef ? { handlerRef } : undefined;
519
+ });
520
+ records.forEach((record, index) => this.markSynced(getSerializedKey(record), record, versions[index]));
521
+ }
522
+ /** Delete records, and forget their sync state. */
523
+ async removeRecords(paths) {
524
+ if (paths.length === 0)
525
+ return;
526
+ await this.adapter.removeAll(paths);
527
+ for (const path of paths) {
528
+ const key = pathToKey(path);
529
+ this.syncedAt.delete(key);
530
+ this.syncedVersion.set(key, this.localVersion.get(key) ?? 0);
531
+ }
532
+ }
533
+ track(write) {
534
+ this.inFlight.add(write);
535
+ void write.finally(() => this.inFlight.delete(write));
536
+ }
537
+ // ===========================================================================
538
+ // Access to Underlying Components
539
+ // ===========================================================================
540
+ /**
541
+ * Get the base registry.
542
+ */
543
+ getBaseRegistry() {
544
+ return this.baseRegistry;
545
+ }
546
+ /**
547
+ * Get the storage adapter.
548
+ */
549
+ getAdapter() {
550
+ return this.adapter;
551
+ }
552
+ /**
553
+ * Get the handler loader.
554
+ */
555
+ getHandlerLoader() {
556
+ return this.options.handlerLoader;
557
+ }
558
+ // ===========================================================================
559
+ // Lifecycle
560
+ // ===========================================================================
561
+ /**
562
+ * Close the synced registry and cleanup resources.
563
+ */
564
+ async close() {
565
+ this.stopAutoSync();
566
+ // Flush pending changes before closing
567
+ await this.flushPending();
568
+ await this.adapter.close();
569
+ this.connected = false;
570
+ if (STORES.get(this.baseRegistry) === this) {
571
+ STORES.delete(this.baseRegistry);
572
+ }
573
+ }
574
+ }
575
+ //# sourceMappingURL=synced-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synced-registry.js","sourceRoot":"","sources":["../../src/storage/synced-registry.ts"],"names":[],"mappings":"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"}