@stratasync/client 0.2.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.
@@ -0,0 +1,373 @@
1
+ import { createArchiveTransaction, createDeleteTransaction, createInsertTransaction, createTransactionBatch, createUnarchiveTransaction, createUpdateTransaction, isSyncIdGreaterThan, maxSyncId, ZERO_SYNC_ID, } from "@stratasync/core";
2
+ const MAX_RETRY_COUNT = 5;
3
+ /**
4
+ * Manages the outbox queue of pending transactions
5
+ */
6
+ export class OutboxManager {
7
+ storage;
8
+ transport;
9
+ clientId;
10
+ batchMutations;
11
+ batchDelay;
12
+ maxBatchSize;
13
+ onTransactionStateChange;
14
+ onTransactionRejected;
15
+ pendingBatch = [];
16
+ batchTimer = null;
17
+ processing = false;
18
+ processingPromise = null;
19
+ // oxlint-disable-next-line prefer-await-to-then -- fire-and-forget pattern
20
+ sendQueue = Promise.resolve();
21
+ lifecycleVersion = 0;
22
+ /**
23
+ * Tracks clientTxIds created by THIS runtime instance only.
24
+ * Used for echo suppression so cross-tab transactions (which share
25
+ * IndexedDB but not this in-memory set) are not incorrectly skipped.
26
+ */
27
+ localClientTxIds = new Set();
28
+ constructor(options) {
29
+ this.storage = options.storage;
30
+ this.transport = options.transport;
31
+ this.clientId = options.clientId;
32
+ this.batchMutations = options.batchMutations ?? true;
33
+ this.batchDelay = options.batchDelay ?? 50;
34
+ this.maxBatchSize = options.maxBatchSize ?? 100;
35
+ this.onTransactionStateChange = options.onTransactionStateChange;
36
+ this.onTransactionRejected = options.onTransactionRejected;
37
+ }
38
+ /**
39
+ * Queues an INSERT transaction
40
+ */
41
+ async insert(modelName, modelId, data) {
42
+ const tx = createInsertTransaction(this.clientId, modelName, modelId, data);
43
+ await this.queueTransaction(tx);
44
+ return tx;
45
+ }
46
+ /**
47
+ * Queues an UPDATE transaction
48
+ */
49
+ async update(modelName, modelId, changes, original) {
50
+ const tx = createUpdateTransaction(this.clientId, modelName, modelId, changes, original);
51
+ await this.queueTransaction(tx);
52
+ return tx;
53
+ }
54
+ /**
55
+ * Queues a DELETE transaction
56
+ */
57
+ async delete(modelName, modelId, original) {
58
+ const tx = createDeleteTransaction(this.clientId, modelName, modelId, original);
59
+ await this.queueTransaction(tx);
60
+ return tx;
61
+ }
62
+ /**
63
+ * Queues an ARCHIVE transaction
64
+ */
65
+ async archive(modelName, modelId, options = {}) {
66
+ const tx = createArchiveTransaction(this.clientId, modelName, modelId, options);
67
+ await this.queueTransaction(tx);
68
+ return tx;
69
+ }
70
+ /**
71
+ * Queues an UNARCHIVE transaction
72
+ */
73
+ async unarchive(modelName, modelId, options = {}) {
74
+ const tx = createUnarchiveTransaction(this.clientId, modelName, modelId, options);
75
+ await this.queueTransaction(tx);
76
+ return tx;
77
+ }
78
+ /**
79
+ * Queues a transaction for sending
80
+ */
81
+ async queueTransaction(tx) {
82
+ this.localClientTxIds.add(tx.clientTxId);
83
+ // Persist to storage first
84
+ await this.storage.addToOutbox(tx);
85
+ this.onTransactionStateChange?.(tx);
86
+ if (this.batchMutations) {
87
+ this.pendingBatch.push(tx);
88
+ this.scheduleBatchSend();
89
+ }
90
+ else {
91
+ await this.dispatchBatch([tx]);
92
+ }
93
+ }
94
+ /**
95
+ * Schedules sending the pending batch
96
+ */
97
+ scheduleBatchSend() {
98
+ if (this.batchTimer) {
99
+ clearTimeout(this.batchTimer);
100
+ }
101
+ // Send immediately if batch is full
102
+ if (this.pendingBatch.length >= this.maxBatchSize) {
103
+ this.flushBatch();
104
+ return;
105
+ }
106
+ this.batchTimer = setTimeout(() => {
107
+ this.flushBatch();
108
+ }, this.batchDelay);
109
+ }
110
+ /**
111
+ * Flushes the pending batch
112
+ */
113
+ flushBatch() {
114
+ if (this.batchTimer) {
115
+ clearTimeout(this.batchTimer);
116
+ this.batchTimer = null;
117
+ }
118
+ if (this.pendingBatch.length === 0) {
119
+ return;
120
+ }
121
+ const batch = this.pendingBatch;
122
+ this.pendingBatch = [];
123
+ // oxlint-disable-next-line prefer-await-to-then -- fire-and-forget pattern
124
+ this.dispatchBatch(batch).catch(() => {
125
+ // Errors are handled in sendBatch
126
+ });
127
+ }
128
+ dispatchBatch(transactions) {
129
+ const version = this.lifecycleVersion;
130
+ const previousQueue = this.sendQueue;
131
+ const sendPromise = (async () => {
132
+ await previousQueue;
133
+ await this.sendBatch(transactions, version);
134
+ })();
135
+ // oxlint-disable-next-line prefer-await-to-then -- fire-and-forget pattern
136
+ this.sendQueue = sendPromise.catch(() => {
137
+ /* noop */
138
+ });
139
+ return sendPromise;
140
+ }
141
+ isLifecycleCurrent(version) {
142
+ return version === this.lifecycleVersion;
143
+ }
144
+ waitForInflightSends() {
145
+ return this.sendQueue;
146
+ }
147
+ /**
148
+ * Sends a batch of transactions
149
+ */
150
+ async sendBatch(transactions, version) {
151
+ if (transactions.length === 0) {
152
+ return;
153
+ }
154
+ const markedSent = await this.markTransactionsSent(transactions, version);
155
+ if (!markedSent) {
156
+ return;
157
+ }
158
+ const batch = createTransactionBatch(transactions);
159
+ try {
160
+ const result = await this.transport.mutate(batch);
161
+ if (!this.isLifecycleCurrent(version)) {
162
+ return;
163
+ }
164
+ await this.handleMutateResult(transactions, result, version);
165
+ }
166
+ catch (error) {
167
+ await this.handleTransportFailure(transactions, error, version);
168
+ throw error;
169
+ }
170
+ }
171
+ async markTransactionsSent(transactions, version) {
172
+ for (const tx of transactions) {
173
+ if (!this.isLifecycleCurrent(version)) {
174
+ return false;
175
+ }
176
+ tx.state = "sent";
177
+ await this.storage.updateOutboxTransaction(tx.clientTxId, {
178
+ state: "sent",
179
+ });
180
+ if (!this.isLifecycleCurrent(version)) {
181
+ return false;
182
+ }
183
+ this.onTransactionStateChange?.(tx);
184
+ }
185
+ return true;
186
+ }
187
+ async handleTransportFailure(transactions, error, version) {
188
+ if (!this.isLifecycleCurrent(version)) {
189
+ throw error;
190
+ }
191
+ // Transport errors are retryable until the retry cap is reached.
192
+ for (const tx of transactions) {
193
+ const retryCount = tx.retryCount + 1;
194
+ const nextState = retryCount < MAX_RETRY_COUNT ? "queued" : "failed";
195
+ tx.state = nextState;
196
+ tx.lastError = error instanceof Error ? error.message : "Unknown error";
197
+ tx.retryCount = retryCount;
198
+ await this.storage.updateOutboxTransaction(tx.clientTxId, {
199
+ lastError: tx.lastError,
200
+ retryCount,
201
+ state: nextState,
202
+ });
203
+ if (!this.isLifecycleCurrent(version)) {
204
+ throw error;
205
+ }
206
+ this.onTransactionStateChange?.(tx);
207
+ }
208
+ }
209
+ /**
210
+ * Handles the result of a mutation batch
211
+ */
212
+ async handleMutateResult(transactions, result, version) {
213
+ const txMap = new Map(transactions.map((tx) => [tx.clientTxId, tx]));
214
+ let highestSyncId = result.lastSyncId ?? ZERO_SYNC_ID;
215
+ for (const txResult of result.results) {
216
+ if (txResult.syncId !== undefined) {
217
+ highestSyncId = maxSyncId(highestSyncId, txResult.syncId);
218
+ }
219
+ }
220
+ for (const txResult of result.results) {
221
+ if (!this.isLifecycleCurrent(version)) {
222
+ return;
223
+ }
224
+ const tx = txMap.get(txResult.clientTxId);
225
+ if (!tx) {
226
+ continue;
227
+ }
228
+ if (txResult.success) {
229
+ const syncIdNeededForCompletion = txResult.syncId ??
230
+ (highestSyncId === ZERO_SYNC_ID ? undefined : highestSyncId);
231
+ tx.state = "awaitingSync";
232
+ tx.syncIdNeededForCompletion = syncIdNeededForCompletion;
233
+ await this.storage.updateOutboxTransaction(tx.clientTxId, {
234
+ state: "awaitingSync",
235
+ syncIdNeededForCompletion,
236
+ });
237
+ }
238
+ else {
239
+ tx.state = "failed";
240
+ tx.lastError = txResult.error ?? "Unknown error";
241
+ tx.retryCount += 1;
242
+ await this.storage.updateOutboxTransaction(tx.clientTxId, {
243
+ lastError: tx.lastError,
244
+ retryCount: tx.retryCount,
245
+ state: "failed",
246
+ });
247
+ this.onTransactionRejected?.(tx);
248
+ }
249
+ if (!this.isLifecycleCurrent(version)) {
250
+ return;
251
+ }
252
+ this.onTransactionStateChange?.(tx);
253
+ }
254
+ }
255
+ /**
256
+ * Processes any pending transactions from storage (e.g., after reconnect)
257
+ */
258
+ async processPendingTransactions() {
259
+ if (this.processing) {
260
+ await this.processingPromise;
261
+ return;
262
+ }
263
+ this.processing = true;
264
+ this.processingPromise = this.doProcessPending();
265
+ try {
266
+ await this.processingPromise;
267
+ }
268
+ finally {
269
+ this.processing = false;
270
+ this.processingPromise = null;
271
+ }
272
+ }
273
+ async doProcessPending() {
274
+ await this.flushPendingBatchNow();
275
+ await this.waitForInflightSends();
276
+ const pending = await this.storage.getOutbox();
277
+ // Reset unconfirmed transport states back to queued so they can retry.
278
+ for (const tx of pending) {
279
+ if (tx.state === "sent" && tx.retryCount < MAX_RETRY_COUNT) {
280
+ tx.state = "queued";
281
+ await this.storage.updateOutboxTransaction(tx.clientTxId, {
282
+ state: "queued",
283
+ });
284
+ this.onTransactionStateChange?.(tx);
285
+ }
286
+ }
287
+ // Filter to only queued transactions
288
+ const queued = pending.filter((tx) => tx.state === "queued" && tx.retryCount < MAX_RETRY_COUNT);
289
+ if (queued.length === 0) {
290
+ return;
291
+ }
292
+ // Send in batches
293
+ for (let i = 0; i < queued.length; i += this.maxBatchSize) {
294
+ const batch = queued.slice(i, i + this.maxBatchSize);
295
+ await this.dispatchBatch(batch);
296
+ }
297
+ }
298
+ async flushPendingBatchNow() {
299
+ if (this.batchTimer) {
300
+ clearTimeout(this.batchTimer);
301
+ this.batchTimer = null;
302
+ }
303
+ if (this.pendingBatch.length === 0) {
304
+ return;
305
+ }
306
+ const batch = this.pendingBatch;
307
+ this.pendingBatch = [];
308
+ await this.dispatchBatch(batch);
309
+ }
310
+ /**
311
+ * Gets the count of pending transactions
312
+ */
313
+ async getPendingCount() {
314
+ const outbox = await this.storage.getOutbox();
315
+ return outbox.filter((tx) => tx.state === "queued" ||
316
+ tx.state === "sent" ||
317
+ tx.state === "awaitingSync").length;
318
+ }
319
+ /**
320
+ * Returns the set of clientTxIds created by this runtime instance.
321
+ */
322
+ getLocalClientTxIds() {
323
+ return this.localClientTxIds;
324
+ }
325
+ /**
326
+ * Completes any awaiting transactions up to the given sync ID
327
+ */
328
+ async completeUpToSyncId(lastSyncId) {
329
+ const outbox = await this.storage.getOutbox();
330
+ let completed = 0;
331
+ for (const tx of outbox) {
332
+ if (tx.state === "awaitingSync" &&
333
+ typeof tx.syncIdNeededForCompletion === "string" &&
334
+ !isSyncIdGreaterThan(tx.syncIdNeededForCompletion, lastSyncId)) {
335
+ await this.storage.removeFromOutbox(tx.clientTxId);
336
+ this.localClientTxIds.delete(tx.clientTxId);
337
+ tx.state = "completed";
338
+ completed += 1;
339
+ }
340
+ }
341
+ return completed;
342
+ }
343
+ /**
344
+ * Forces an immediate flush of pending batches
345
+ */
346
+ async flush() {
347
+ await this.flushPendingBatchNow();
348
+ await this.processingPromise;
349
+ await this.waitForInflightSends();
350
+ }
351
+ dispose() {
352
+ this.lifecycleVersion += 1;
353
+ if (this.batchTimer) {
354
+ clearTimeout(this.batchTimer);
355
+ this.batchTimer = null;
356
+ }
357
+ this.pendingBatch = [];
358
+ this.localClientTxIds.clear();
359
+ // oxlint-disable-next-line prefer-await-to-then -- fire-and-forget pattern
360
+ this.sendQueue = Promise.resolve();
361
+ }
362
+ /**
363
+ * Clears all pending transactions
364
+ */
365
+ async clear() {
366
+ this.dispose();
367
+ const outbox = await this.storage.getOutbox();
368
+ for (const tx of outbox) {
369
+ await this.storage.removeFromOutbox(tx.clientTxId);
370
+ }
371
+ }
372
+ }
373
+ //# sourceMappingURL=outbox-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-manager.js","sourceRoot":"","sources":["../src/outbox-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { IdentityMap } from "./identity-map.js";
2
+ import type { QueryOptions, QueryResult } from "./types.js";
3
+ /**
4
+ * Executes a query against an identity map
5
+ */
6
+ export declare const executeQuery: <T extends Record<string, unknown>>(map: IdentityMap<T>, options?: QueryOptions<T>) => QueryResult<T>;
7
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,KAAK,WAAW,CAAC,CAAC,CAAC,EACnB,UAAS,YAAY,CAAC,CAAC,CAAM,KAC5B,WAAW,CAAC,CAAC,CAsCf,CAAC"}
package/dist/query.js ADDED
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Executes a query against an identity map
3
+ */
4
+ export const executeQuery = (map, options = {}) => {
5
+ let results = map.values();
6
+ // Filter by predicate
7
+ if (options.where) {
8
+ results = results.filter(options.where);
9
+ }
10
+ // Filter archived unless explicitly included
11
+ if (!options.includeArchived) {
12
+ results = results.filter((item) => !item.archivedAt);
13
+ }
14
+ // Get total count before pagination
15
+ const totalCount = results.length;
16
+ // Sort results
17
+ if (options.orderBy) {
18
+ results = results.toSorted(options.orderBy);
19
+ }
20
+ // Apply offset
21
+ if (options.offset && options.offset > 0) {
22
+ results = results.slice(options.offset);
23
+ }
24
+ // Apply limit
25
+ let hasMore = false;
26
+ if (options.limit && options.limit > 0) {
27
+ hasMore = results.length > options.limit;
28
+ results = results.slice(0, options.limit);
29
+ }
30
+ return {
31
+ data: results,
32
+ hasMore,
33
+ totalCount,
34
+ };
35
+ };
36
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,GAAmB,EACnB,UAA2B,EAAE,EACb,EAAE;IAClB,IAAI,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;IAE3B,sBAAsB;IACtB,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,6CAA6C;IAC7C,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvD,CAAC;IAED,oCAAoC;IACpC,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAElC,eAAe;IACf,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED,eAAe;IACf,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,cAAc;IACd,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QACvC,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QACzC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO;QACL,IAAI,EAAE,OAAO;QACb,OAAO;QACP,UAAU;KACX,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,208 @@
1
+ import type { ConnectionState, SyncClientState, SyncId, Transaction } from "@stratasync/core";
2
+ import { ModelRegistry } from "@stratasync/core";
3
+ import type { IdentityMapRegistry } from "./identity-map.js";
4
+ import type { OutboxManager } from "./outbox-manager.js";
5
+ import type { StorageAdapter, SyncClientEvent, SyncClientOptions } from "./types.js";
6
+ /**
7
+ * Orchestrates the sync state machine
8
+ */
9
+ export declare class SyncOrchestrator {
10
+ private readonly storage;
11
+ private readonly transport;
12
+ private readonly identityMaps;
13
+ private outboxManager;
14
+ private readonly options;
15
+ private readonly registry;
16
+ private _state;
17
+ private _connectionState;
18
+ private readonly stateListeners;
19
+ private readonly connectionListeners;
20
+ private readonly schemaHash;
21
+ private clientId;
22
+ private lastSyncId;
23
+ private lastError;
24
+ private firstSyncId;
25
+ private groups;
26
+ private deltaSubscription;
27
+ private deltaPacketQueue;
28
+ private deltaReplayBarrier;
29
+ private stateUpdateLock;
30
+ private running;
31
+ private runToken;
32
+ private readonly emitEvent?;
33
+ private onTransactionConflict?;
34
+ /** Conflict rollbacks deferred until the identity map batch. */
35
+ private deferredConflictTxs;
36
+ constructor(options: SyncClientOptions, identityMaps: IdentityMapRegistry, emitEvent?: (event: SyncClientEvent) => void);
37
+ setOutboxManager(outboxManager: OutboxManager): void;
38
+ setConflictHandler(handler: (tx: Transaction) => void): void;
39
+ /**
40
+ * Gets the current sync state
41
+ */
42
+ get state(): SyncClientState;
43
+ /**
44
+ * Gets the current connection state
45
+ */
46
+ get connectionState(): ConnectionState;
47
+ /**
48
+ * Gets the client ID
49
+ */
50
+ getClientId(): string;
51
+ /**
52
+ * Gets the last sync ID
53
+ */
54
+ getLastSyncId(): SyncId;
55
+ /**
56
+ * Gets the first sync ID from the last full bootstrap
57
+ */
58
+ getFirstSyncId(): SyncId;
59
+ /**
60
+ * Gets the last error
61
+ */
62
+ getLastError(): Error | null;
63
+ /**
64
+ * Starts the sync orchestrator
65
+ */
66
+ start(): Promise<void>;
67
+ private openStorage;
68
+ private loadMetadata;
69
+ private configureGroups;
70
+ private bootstrapIfNeeded;
71
+ private shouldBootstrap;
72
+ private runBootstrapStrategy;
73
+ private applyPendingOutboxTransactions;
74
+ private processOutboxTransactions;
75
+ /**
76
+ * Best-effort catch-up for deltas created between bootstrap completion and
77
+ * subscription readiness.
78
+ */
79
+ private catchUpMissedDeltas;
80
+ private fetchAndApplyDeltaPages;
81
+ private fetchDeltaPage;
82
+ private static wait;
83
+ private isRunActive;
84
+ private shouldAbortBootstrap;
85
+ /**
86
+ * Stops the sync orchestrator
87
+ */
88
+ stop(): Promise<void>;
89
+ reset(): Promise<void>;
90
+ /**
91
+ * Forces an immediate sync
92
+ */
93
+ syncNow(): Promise<void>;
94
+ /**
95
+ * Subscribes to state changes
96
+ */
97
+ onStateChange(callback: (state: SyncClientState) => void): () => void;
98
+ /**
99
+ * Subscribes to connection state changes
100
+ */
101
+ onConnectionStateChange(callback: (state: ConnectionState) => void): () => void;
102
+ runWithStateLock<T>(operation: () => Promise<T>): Promise<T>;
103
+ /**
104
+ * Performs initial bootstrap
105
+ */
106
+ private bootstrap;
107
+ private readBootstrapStream;
108
+ private storeBootstrapRow;
109
+ private applyBootstrapMetadata;
110
+ private markBootstrapModelsPersisted;
111
+ /**
112
+ * Performs a local-only bootstrap using existing storage data.
113
+ */
114
+ private localBootstrap;
115
+ /**
116
+ * Checks whether any hydrated models exist in storage.
117
+ */
118
+ private hasLocalData;
119
+ /**
120
+ * Loads existing data from storage into identity maps
121
+ */
122
+ private hydrateIdentityMaps;
123
+ private areModelsPersisted;
124
+ private static areGroupsEqual;
125
+ /**
126
+ * Starts the delta subscription
127
+ */
128
+ private startDeltaSubscription;
129
+ private restartDeltaSubscription;
130
+ /**
131
+ * Processes the delta stream
132
+ */
133
+ private processDeltaStream;
134
+ private enqueueDeltaPacket;
135
+ private handleSyncError;
136
+ /**
137
+ * Applies a delta packet to local state.
138
+ *
139
+ * Identity map mutations are deferred and applied in a single batch at the
140
+ * end so that MobX observers never see an intermediate state where server
141
+ * data has been written but pending local (outbox) changes have not yet been
142
+ * re-applied.
143
+ */
144
+ private applyDeltaPacket;
145
+ private handleEmptyPacket;
146
+ /**
147
+ * Build set of own-action keys for transactions that this local runtime
148
+ * already applied optimistically and then saw confirmed by the server.
149
+ *
150
+ * Uses the instance-local set of clientTxIds (in-memory, not from shared
151
+ * storage) so that cross-tab transactions sharing the same IndexedDB are
152
+ * not incorrectly treated as own optimistic echoes.
153
+ */
154
+ private static buildOwnClientTxIds;
155
+ private getActiveOutboxTransactions;
156
+ /**
157
+ * Creates a delta target that writes to storage immediately but collects
158
+ * identity map operations for deferred application in a single batch.
159
+ */
160
+ private createDeferredDeltaTarget;
161
+ private collectDeferredDeltaOps;
162
+ private updateSyncMetadata;
163
+ private finishOutboxProcessing;
164
+ private static resolveModelChangeAction;
165
+ private emitModelChangeEvents;
166
+ private emitOutboxCount;
167
+ private rebasePendingTransactions;
168
+ private handleConflict;
169
+ private updatePendingOriginals;
170
+ private static buildActionsByKey;
171
+ private static shouldRebaseAction;
172
+ private static getUpdatedOriginal;
173
+ /**
174
+ * Re-applies pending outbox transactions to identity maps after a server sync.
175
+ * This intentionally differs from rollbackTransaction (which inverts) and
176
+ * applyDeltas (which writes to storage) — it re-applies forward to restore
177
+ * optimistic state on top of newly-synced server data.
178
+ */
179
+ private applyPendingTransactionsToIdentityMaps;
180
+ private removeConfirmedTransactions;
181
+ private removeRedundantCreateTransactions;
182
+ private handleCoverageActions;
183
+ private handleSyncGroupActions;
184
+ private bootstrapSyncGroups;
185
+ private removeSyncGroupData;
186
+ /**
187
+ * Handles connection state changes
188
+ */
189
+ private handleConnectionChange;
190
+ /**
191
+ * Sets the sync state
192
+ */
193
+ private setState;
194
+ /**
195
+ * Sets the connection state
196
+ */
197
+ private setConnectionState;
198
+ /**
199
+ * Gets the model registry
200
+ */
201
+ getRegistry(): ModelRegistry;
202
+ /**
203
+ * Gets the storage adapter
204
+ */
205
+ getStorage(): StorageAdapter;
206
+ private acquireDeltaReplayBarrier;
207
+ }
208
+ //# sourceMappingURL=sync-orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-orchestrator.d.ts","sourceRoot":"","sources":["../src/sync-orchestrator.ts"],"names":[],"mappings":"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"}