@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.
- package/README.md +76 -0
- package/dist/client.d.ts +11 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +759 -0
- package/dist/client.js.map +1 -0
- package/dist/history-manager.d.ts +45 -0
- package/dist/history-manager.d.ts.map +1 -0
- package/dist/history-manager.js +266 -0
- package/dist/history-manager.js.map +1 -0
- package/dist/identity-map.d.ts +127 -0
- package/dist/identity-map.d.ts.map +1 -0
- package/dist/identity-map.js +295 -0
- package/dist/identity-map.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/outbox-manager.d.ts +122 -0
- package/dist/outbox-manager.d.ts.map +1 -0
- package/dist/outbox-manager.js +373 -0
- package/dist/outbox-manager.js.map +1 -0
- package/dist/query.d.ts +7 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +36 -0
- package/dist/query.js.map +1 -0
- package/dist/sync-orchestrator.d.ts +208 -0
- package/dist/sync-orchestrator.d.ts.map +1 -0
- package/dist/sync-orchestrator.js +1287 -0
- package/dist/sync-orchestrator.js.map +1 -0
- package/dist/types.d.ts +309 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +14 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +26 -0
- package/dist/utils.js.map +1 -0
- package/package.json +41 -0
|
@@ -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":"AAOA,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,EACtB,0BAA0B,EAC1B,uBAAuB,EACvB,mBAAmB,EACnB,SAAS,EACT,YAAY,GACb,MAAM,kBAAkB,CAAC;AAI1B,MAAM,eAAe,GAAG,CAAC,CAAC;AAwB1B;;GAEG;AACH,MAAM,OAAO,aAAa;IACP,OAAO,CAAiB;IACxB,SAAS,CAAmB;IAC5B,QAAQ,CAAS;IACjB,cAAc,CAAU;IACxB,UAAU,CAAS;IACnB,YAAY,CAAS;IACrB,wBAAwB,CAA6B;IACrD,qBAAqB,CAA6B;IAE3D,YAAY,GAAkB,EAAE,CAAC;IACjC,UAAU,GAAyC,IAAI,CAAC;IACxD,UAAU,GAAG,KAAK,CAAC;IACnB,iBAAiB,GAAyB,IAAI,CAAC;IACvD,2EAA2E;IACnE,SAAS,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7C,gBAAgB,GAAG,CAAC,CAAC;IAE7B;;;;OAIG;IACc,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;IAEtD,YAAY,OAA6B;QACvC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC;QACrD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;QAC3C,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,GAAG,CAAC;QAChD,IAAI,CAAC,wBAAwB,GAAG,OAAO,CAAC,wBAAwB,CAAC;QACjE,IAAI,CAAC,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAC7D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CACV,SAAiB,EACjB,OAAe,EACf,IAA6B;QAE7B,MAAM,EAAE,GAAG,uBAAuB,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC5E,MAAM,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAChC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CACV,SAAiB,EACjB,OAAe,EACf,OAAgC,EAChC,QAAiC;QAEjC,MAAM,EAAE,GAAG,uBAAuB,CAChC,IAAI,CAAC,QAAQ,EACb,SAAS,EACT,OAAO,EACP,OAAO,EACP,QAAQ,CACT,CAAC;QACF,MAAM,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAChC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CACV,SAAiB,EACjB,OAAe,EACf,QAAiC;QAEjC,MAAM,EAAE,GAAG,uBAAuB,CAChC,IAAI,CAAC,QAAQ,EACb,SAAS,EACT,OAAO,EACP,QAAQ,CACT,CAAC;QACF,MAAM,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAChC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CACX,SAAiB,EACjB,OAAe,EACf,UAAqC,EAAE;QAEvC,MAAM,EAAE,GAAG,wBAAwB,CACjC,IAAI,CAAC,QAAQ,EACb,SAAS,EACT,OAAO,EACP,OAAO,CACR,CAAC;QACF,MAAM,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAChC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS,CACb,SAAiB,EACjB,OAAe,EACf,UAAuC,EAAE;QAEzC,MAAM,EAAE,GAAG,0BAA0B,CACnC,IAAI,CAAC,QAAQ,EACb,SAAS,EACT,OAAO,EACP,OAAO,CACR,CAAC;QACF,MAAM,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAChC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,gBAAgB,CAAC,EAAe;QAC5C,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;QACzC,2BAA2B;QAC3B,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,wBAAwB,EAAE,CAAC,EAAE,CAAC,CAAC;QAEpC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC3B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,iBAAiB;QACvB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChC,CAAC;QAED,oCAAoC;QACpC,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAClD,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACtB,CAAC;IAED;;OAEG;IACK,UAAU;QAChB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC9B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QAED,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QAEvB,2EAA2E;QAC3E,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACnC,kCAAkC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,YAA2B;QAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC;QACtC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC;QACrC,MAAM,WAAW,GAAG,CAAC,KAAK,IAAI,EAAE;YAC9B,MAAM,aAAa,CAAC;YACpB,MAAM,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC9C,CAAC,CAAC,EAAE,CAAC;QACL,2EAA2E;QAC3E,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE;YACtC,UAAU;QACZ,CAAC,CAAC,CAAC;QACH,OAAO,WAAW,CAAC;IACrB,CAAC;IAEO,kBAAkB,CAAC,OAAe;QACxC,OAAO,OAAO,KAAK,IAAI,CAAC,gBAAgB,CAAC;IAC3C,CAAC;IAEO,oBAAoB;QAC1B,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,SAAS,CACrB,YAA2B,EAC3B,OAAe;QAEf,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC1E,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAC;QAEnD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAClD,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtC,OAAO;YACT,CAAC;YACD,MAAM,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,sBAAsB,CAAC,YAAY,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAChE,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAChC,YAA2B,EAC3B,OAAe;QAEf,KAAK,MAAM,EAAE,IAAI,YAAY,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtC,OAAO,KAAK,CAAC;YACf,CAAC;YACD,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC;YAClB,MAAM,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,CAAC,UAAU,EAAE;gBACxD,KAAK,EAAE,MAAM;aACd,CAAC,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtC,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,CAAC,wBAAwB,EAAE,CAAC,EAAE,CAAC,CAAC;QACtC,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAClC,YAA2B,EAC3B,KAAc,EACd,OAAe;QAEf,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;YACtC,MAAM,KAAK,CAAC;QACd,CAAC;QAED,iEAAiE;QACjE,KAAK,MAAM,EAAE,IAAI,YAAY,EAAE,CAAC;YAC9B,MAAM,UAAU,GAAG,EAAE,CAAC,UAAU,GAAG,CAAC,CAAC;YACrC,MAAM,SAAS,GACb,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAE,QAAkB,CAAC;YAChE,EAAE,CAAC,KAAK,GAAG,SAAS,CAAC;YACrB,EAAE,CAAC,SAAS,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YACxE,EAAE,CAAC,UAAU,GAAG,UAAU,CAAC;YAC3B,MAAM,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,CAAC,UAAU,EAAE;gBACxD,SAAS,EAAE,EAAE,CAAC,SAAS;gBACvB,UAAU;gBACV,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtC,MAAM,KAAK,CAAC;YACd,CAAC;YACD,IAAI,CAAC,wBAAwB,EAAE,CAAC,EAAE,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,kBAAkB,CAC9B,YAA2B,EAC3B,MAAoB,EACpB,OAAe;QAEf,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QACrE,IAAI,aAAa,GAAW,MAAM,CAAC,UAAU,IAAI,YAAY,CAAC;QAC9D,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACtC,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAClC,aAAa,GAAG,SAAS,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QAED,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtC,OAAO;YACT,CAAC;YACD,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YAC1C,IAAI,CAAC,EAAE,EAAE,CAAC;gBACR,SAAS;YACX,CAAC;YAED,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACrB,MAAM,yBAAyB,GAC7B,QAAQ,CAAC,MAAM;oBACf,CAAC,aAAa,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;gBAC/D,EAAE,CAAC,KAAK,GAAG,cAAc,CAAC;gBAC1B,EAAE,CAAC,yBAAyB,GAAG,yBAAyB,CAAC;gBACzD,MAAM,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,CAAC,UAAU,EAAE;oBACxD,KAAK,EAAE,cAAc;oBACrB,yBAAyB;iBAC1B,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,EAAE,CAAC,KAAK,GAAG,QAAQ,CAAC;gBACpB,EAAE,CAAC,SAAS,GAAG,QAAQ,CAAC,KAAK,IAAI,eAAe,CAAC;gBACjD,EAAE,CAAC,UAAU,IAAI,CAAC,CAAC;gBACnB,MAAM,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,CAAC,UAAU,EAAE;oBACxD,SAAS,EAAE,EAAE,CAAC,SAAS;oBACvB,UAAU,EAAE,EAAE,CAAC,UAAU;oBACzB,KAAK,EAAE,QAAQ;iBAChB,CAAC,CAAC;gBACH,IAAI,CAAC,qBAAqB,EAAE,CAAC,EAAE,CAAC,CAAC;YACnC,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtC,OAAO;YACT,CAAC;YACD,IAAI,CAAC,wBAAwB,EAAE,CAAC,EAAE,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,0BAA0B;QAC9B,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,IAAI,CAAC,iBAAiB,CAAC;YAC7B,OAAO;QACT,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAEjD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,iBAAiB,CAAC;QAC/B,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;YACxB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAChC,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,gBAAgB;QAC5B,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAClC,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAElC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QAE/C,uEAAuE;QACvE,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;YACzB,IAAI,EAAE,CAAC,KAAK,KAAK,MAAM,IAAI,EAAE,CAAC,UAAU,GAAG,eAAe,EAAE,CAAC;gBAC3D,EAAE,CAAC,KAAK,GAAG,QAAQ,CAAC;gBACpB,MAAM,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,CAAC,UAAU,EAAE;oBACxD,KAAK,EAAE,QAAQ;iBAChB,CAAC,CAAC;gBACH,IAAI,CAAC,wBAAwB,EAAE,CAAC,EAAE,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;QAED,qCAAqC;QACrC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAC3B,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,KAAK,QAAQ,IAAI,EAAE,CAAC,UAAU,GAAG,eAAe,CACjE,CAAC;QAEF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,kBAAkB;QAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;YACrD,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,oBAAoB;QAChC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC9B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QAED,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QAC9C,OAAO,MAAM,CAAC,MAAM,CAClB,CAAC,EAAE,EAAE,EAAE,CACL,EAAE,CAAC,KAAK,KAAK,QAAQ;YACrB,EAAE,CAAC,KAAK,KAAK,MAAM;YACnB,EAAE,CAAC,KAAK,KAAK,cAAc,CAC9B,CAAC,MAAM,CAAC;IACX,CAAC;IAED;;OAEG;IACH,mBAAmB;QACjB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,kBAAkB,CAAC,UAAkB;QACzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QAC9C,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;YACxB,IACE,EAAE,CAAC,KAAK,KAAK,cAAc;gBAC3B,OAAO,EAAE,CAAC,yBAAyB,KAAK,QAAQ;gBAChD,CAAC,mBAAmB,CAAC,EAAE,CAAC,yBAAyB,EAAE,UAAU,CAAC,EAC9D,CAAC;gBACD,MAAM,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;gBACnD,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;gBAC5C,EAAE,CAAC,KAAK,GAAG,WAAW,CAAC;gBACvB,SAAS,IAAI,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAClC,MAAM,IAAI,CAAC,iBAAiB,CAAC;QAC7B,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;IACpC,CAAC;IAED,OAAO;QACL,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAC;QAC3B,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC9B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;QAC9B,2EAA2E;QAC3E,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,OAAO,EAAE,CAAC;QAEf,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QAC9C,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;CACF"}
|
package/dist/query.d.ts
ADDED
|
@@ -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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"}
|