velocious 1.0.663 → 1.0.665
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 +2 -2
- package/build/background-jobs/client.js +36 -6
- package/build/configuration-types.js +3 -3
- package/build/database/query/alter-table-base.js +11 -1
- package/build/src/background-jobs/client.d.ts.map +1 -1
- package/build/src/background-jobs/client.js +35 -6
- package/build/src/configuration-types.d.ts +8 -4
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +4 -4
- package/build/src/database/query/alter-table-base.d.ts.map +1 -1
- package/build/src/database/query/alter-table-base.js +12 -2
- package/build/src/sync/sync-api-client.d.ts +36 -10
- package/build/src/sync/sync-api-client.d.ts.map +1 -1
- package/build/src/sync/sync-api-client.js +58 -14
- package/build/src/sync/sync-client-types.d.ts +41 -2
- package/build/src/sync/sync-client-types.d.ts.map +1 -1
- package/build/src/sync/sync-client-types.js +20 -3
- package/build/src/sync/sync-client.d.ts +112 -3
- package/build/src/sync/sync-client.d.ts.map +1 -1
- package/build/src/sync/sync-client.js +306 -60
- package/build/src/sync/sync-publisher-types.d.ts +36 -3
- package/build/src/sync/sync-publisher-types.d.ts.map +1 -1
- package/build/src/sync/sync-publisher-types.js +16 -2
- package/build/src/sync/sync-publisher.d.ts +22 -3
- package/build/src/sync/sync-publisher.d.ts.map +1 -1
- package/build/src/sync/sync-publisher.js +134 -13
- package/build/src/sync/sync-realtime-bridge.d.ts +11 -5
- package/build/src/sync/sync-realtime-bridge.d.ts.map +1 -1
- package/build/src/sync/sync-realtime-bridge.js +37 -13
- package/build/src/sync/sync-scope-store.d.ts +32 -0
- package/build/src/sync/sync-scope-store.d.ts.map +1 -1
- package/build/src/sync/sync-scope-store.js +74 -4
- package/build/sync/sync-api-client.js +58 -13
- package/build/sync/sync-client-types.js +22 -2
- package/build/sync/sync-client.js +333 -63
- package/build/sync/sync-publisher-types.js +17 -1
- package/build/sync/sync-publisher.js +156 -15
- package/build/sync/sync-realtime-bridge.js +37 -12
- package/build/sync/sync-scope-store.js +79 -3
- package/package.json +1 -1
- package/src/background-jobs/client.js +36 -6
- package/src/configuration-types.js +3 -3
- package/src/database/query/alter-table-base.js +11 -1
- package/src/sync/sync-api-client.js +58 -13
- package/src/sync/sync-client-types.js +22 -2
- package/src/sync/sync-client.js +333 -63
- package/src/sync/sync-publisher-types.js +17 -1
- package/src/sync/sync-publisher.js +156 -15
- package/src/sync/sync-realtime-bridge.js +37 -12
- package/src/sync/sync-scope-store.js +79 -3
|
@@ -71,16 +71,19 @@ export default class SyncApiClient {
|
|
|
71
71
|
* @param {string} args.authenticationToken - Authentication token.
|
|
72
72
|
* @param {number} [args.batchSize] - Batch size.
|
|
73
73
|
* @param {import("./sync-client-types.js").SyncClientConflictTrackingConfig} args.conflictTracking - Tracking configuration.
|
|
74
|
-
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}) => Promise<SyncReplayResponse>} args.postReplay - Transport boundary.
|
|
74
|
+
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}, options?: {signal?: AbortSignal}) => Promise<SyncReplayResponse>} args.postReplay - Transport boundary.
|
|
75
75
|
* @param {(identity: string) => number} args.remoteGeneration - Current remote generation.
|
|
76
76
|
* @param {string} args.resourceType - Resource whose log records should drain.
|
|
77
|
+
* @param {AbortSignal} [args.signal] - Lifecycle cancellation signal.
|
|
77
78
|
* @returns {Promise<void>} Resolves when no ready intent remains.
|
|
78
79
|
*/
|
|
79
|
-
static async replayConflictTrackedSyncs({authenticationToken, batchSize, conflictTracking, postReplay, remoteGeneration, resourceType}) {
|
|
80
|
+
static async replayConflictTrackedSyncs({authenticationToken, batchSize, conflictTracking, postReplay, remoteGeneration, resourceType, signal}) {
|
|
80
81
|
const maxBatchSize = this.normalizedBatchSize(batchSize)
|
|
81
82
|
|
|
82
83
|
while (true) {
|
|
84
|
+
throwIfSyncAborted(signal)
|
|
83
85
|
const records = await conflictTracking.mutationLog.records()
|
|
86
|
+
throwIfSyncAborted(signal)
|
|
84
87
|
const statuses = new Map(records.map((record) => [record.mutation.clientMutationId, record.status]))
|
|
85
88
|
const pending = records.filter((record) => record.status === "pending" && record.mutation.model === resourceType)
|
|
86
89
|
const ready = pending.filter((record) => record.dependencies.every((dependency) => statuses.get(dependency.clientMutationId) === "synced"))
|
|
@@ -92,13 +95,15 @@ export default class SyncApiClient {
|
|
|
92
95
|
const response = await postReplay({
|
|
93
96
|
authenticationToken,
|
|
94
97
|
syncs: groups.map((group) => this.conflictReplayPayload(group))
|
|
95
|
-
})
|
|
98
|
+
}, {signal})
|
|
96
99
|
|
|
100
|
+
throwIfSyncAborted(signal)
|
|
97
101
|
this.ensureSuccessfulResponse(response)
|
|
98
102
|
|
|
99
103
|
const responsesById = new Map((response.syncs || []).map((result) => [String(result.id), result]))
|
|
100
104
|
|
|
101
105
|
for (const group of groups) {
|
|
106
|
+
throwIfSyncAborted(signal)
|
|
102
107
|
const result = responsesById.get(group[0].mutation.clientMutationId)
|
|
103
108
|
|
|
104
109
|
if (!result) throw new Error(`Sync response missing result for mutation ${group[0].mutation.clientMutationId}`)
|
|
@@ -108,6 +113,7 @@ export default class SyncApiClient {
|
|
|
108
113
|
|
|
109
114
|
for (const record of group) {
|
|
110
115
|
await applySyncReplayResultToLocalMutationLog({mutationLog: conflictTracking.mutationLog, record, result: /** @type {Record<string, ReturnType<typeof JSON.parse>>} */ (result)})
|
|
116
|
+
throwIfSyncAborted(signal)
|
|
111
117
|
}
|
|
112
118
|
|
|
113
119
|
if (["successful", "duplicate"].includes(result.syncState) && result.serverVersion !== undefined) {
|
|
@@ -115,6 +121,7 @@ export default class SyncApiClient {
|
|
|
115
121
|
|
|
116
122
|
if (remoteGeneration(identity) === generations.get(group[0].mutation.clientMutationId)) {
|
|
117
123
|
await this.rebaseConflictSuccessor({conflictTracking, predecessor: group[group.length - 1], serverVersion: result.serverVersion})
|
|
124
|
+
throwIfSyncAborted(signal)
|
|
118
125
|
}
|
|
119
126
|
}
|
|
120
127
|
}
|
|
@@ -261,6 +268,7 @@ export default class SyncApiClient {
|
|
|
261
268
|
* @param {(payload: SyncChangesRequest) => Promise<SyncChangesResponse>} args.postChanges - Posts one changes request.
|
|
262
269
|
* @param {Record<string, SyncResourceConfig>} args.resources - Resource policies.
|
|
263
270
|
* @param {(progress: import("./sync-api-client-types.js").SyncPullProgress) => void} [args.onProgress] - Progress callback.
|
|
271
|
+
* @param {AbortSignal} [args.signal] - Lifecycle cancellation signal.
|
|
264
272
|
* @returns {Promise<SyncChangesResult>} Pull result.
|
|
265
273
|
*/
|
|
266
274
|
static async pullChangesWithCursor(args) {
|
|
@@ -271,7 +279,8 @@ export default class SyncApiClient {
|
|
|
271
279
|
saveCursor: async (cursor) => await this.saveSyncCursor({cursor, cursorKey: args.cursorKey, cursorModel: args.cursorModel}),
|
|
272
280
|
postChanges: args.postChanges,
|
|
273
281
|
applySync: this.resourceApplier(args.resources),
|
|
274
|
-
onProgress: args.onProgress
|
|
282
|
+
onProgress: args.onProgress,
|
|
283
|
+
signal: args.signal
|
|
275
284
|
})
|
|
276
285
|
}
|
|
277
286
|
|
|
@@ -309,12 +318,14 @@ export default class SyncApiClient {
|
|
|
309
318
|
* @param {number} [args.batchSize] - Max syncs per request. Defaults to 100.
|
|
310
319
|
* @param {() => Promise<SyncCursor | string | null | undefined>} args.loadCursor - Loads the persisted local cursor.
|
|
311
320
|
* @param {(cursor: SyncCursor) => Promise<void>} args.saveCursor - Persists the final acknowledged cursor.
|
|
312
|
-
* @param {(payload: SyncChangesRequest) => Promise<SyncChangesResponse>} args.postChanges - Posts one changes request.
|
|
321
|
+
* @param {(payload: SyncChangesRequest, options?: {signal?: AbortSignal}) => Promise<SyncChangesResponse>} args.postChanges - Posts one changes request.
|
|
313
322
|
* @param {(sync: SyncChangeEnvelope) => Promise<SyncChangeApplyResult>} args.applySync - Applies one normalized sync row locally.
|
|
314
323
|
* @param {(progress: import("./sync-api-client-types.js").SyncPullProgress) => void} [args.onProgress] - Progress callback invoked per applied page (and once for an empty pull) with the applied counts and the stable server total.
|
|
324
|
+
* @param {AbortSignal} [args.signal] - Lifecycle cancellation signal.
|
|
315
325
|
* @returns {Promise<SyncChangesResult>} Pull result.
|
|
316
326
|
*/
|
|
317
327
|
static async pullChanges(args) {
|
|
328
|
+
throwIfSyncAborted(args.signal)
|
|
318
329
|
let afterCursor = this.syncCursorFromPayload(await args.loadCursor())
|
|
319
330
|
let upToCursor = null
|
|
320
331
|
let pages = 0
|
|
@@ -326,7 +337,9 @@ export default class SyncApiClient {
|
|
|
326
337
|
const batchSize = this.normalizedBatchSize(args.batchSize)
|
|
327
338
|
|
|
328
339
|
while (true) {
|
|
340
|
+
throwIfSyncAborted(args.signal)
|
|
329
341
|
const changesResponse = await this.changesPage({...args, afterCursor, batchSize, upToCursor})
|
|
342
|
+
throwIfSyncAborted(args.signal)
|
|
330
343
|
const syncs = changesResponse.syncs
|
|
331
344
|
|
|
332
345
|
if (!upToCursor) upToCursor = changesResponse.upToCursor
|
|
@@ -341,6 +354,7 @@ export default class SyncApiClient {
|
|
|
341
354
|
if (syncs.length === 0) {
|
|
342
355
|
// Report the terminal progress once for an entirely empty pull so consumers observe
|
|
343
356
|
// total 0; a pull that already applied pages reported its final counts on its last page.
|
|
357
|
+
throwIfSyncAborted(args.signal)
|
|
344
358
|
if (pages === 0 && args.onProgress) args.onProgress({pages, syncedCount, total})
|
|
345
359
|
|
|
346
360
|
break
|
|
@@ -354,7 +368,9 @@ export default class SyncApiClient {
|
|
|
354
368
|
// waiting for the rest of the pull.
|
|
355
369
|
await recordChanges.batch(async () => {
|
|
356
370
|
for (const sync of syncs) {
|
|
371
|
+
throwIfSyncAborted(args.signal)
|
|
357
372
|
const applyResult = await args.applySync(sync)
|
|
373
|
+
throwIfSyncAborted(args.signal)
|
|
358
374
|
const resourceType = applyResult.resourceType ?? sync.resourceType()
|
|
359
375
|
|
|
360
376
|
changed ||= applyResult.changed === true
|
|
@@ -369,11 +385,14 @@ export default class SyncApiClient {
|
|
|
369
385
|
|
|
370
386
|
afterCursor = changesResponse.nextCursor
|
|
371
387
|
|
|
388
|
+
throwIfSyncAborted(args.signal)
|
|
372
389
|
if (args.onProgress) args.onProgress({pages, syncedCount, total})
|
|
373
390
|
if (syncs.length < batchSize) break
|
|
374
391
|
}
|
|
375
392
|
|
|
393
|
+
throwIfSyncAborted(args.signal)
|
|
376
394
|
if (afterCursor) await args.saveCursor(afterCursor)
|
|
395
|
+
throwIfSyncAborted(args.signal)
|
|
377
396
|
|
|
378
397
|
return {changed, pages, resourceChanged, resourceCounts, syncedCount, total}
|
|
379
398
|
}
|
|
@@ -384,18 +403,21 @@ export default class SyncApiClient {
|
|
|
384
403
|
* @param {SyncCursor} args.afterCursor - Last acknowledged cursor.
|
|
385
404
|
* @param {string} args.authenticationToken - Auth token.
|
|
386
405
|
* @param {number} args.batchSize - Page size.
|
|
387
|
-
* @param {(payload: SyncChangesRequest) => Promise<SyncChangesResponse>} args.postChanges - Changes poster.
|
|
406
|
+
* @param {(payload: SyncChangesRequest, options?: {signal?: AbortSignal}) => Promise<SyncChangesResponse>} args.postChanges - Changes poster.
|
|
407
|
+
* @param {AbortSignal} [args.signal] - Lifecycle cancellation signal.
|
|
388
408
|
* @param {SyncCursor} args.upToCursor - Snapshot upper-bound cursor.
|
|
389
409
|
* @returns {Promise<{nextCursor: SyncCursor, syncs: SyncChangeEnvelope[], total: number | null, upToCursor: SyncCursor}>} Normalized changes page.
|
|
390
410
|
*/
|
|
391
|
-
static async changesPage({afterCursor, authenticationToken, batchSize, postChanges, upToCursor}) {
|
|
411
|
+
static async changesPage({afterCursor, authenticationToken, batchSize, postChanges, signal, upToCursor}) {
|
|
412
|
+
throwIfSyncAborted(signal)
|
|
392
413
|
const response = await postChanges({
|
|
393
414
|
authenticationToken,
|
|
394
415
|
limit: batchSize,
|
|
395
416
|
...this.cursorPayload("after", afterCursor),
|
|
396
417
|
...this.cursorPayload("upTo", upToCursor)
|
|
397
|
-
})
|
|
418
|
+
}, {signal})
|
|
398
419
|
|
|
420
|
+
throwIfSyncAborted(signal)
|
|
399
421
|
this.ensureSuccessfulChangesResponse(response)
|
|
400
422
|
|
|
401
423
|
const syncs = /** @type {unknown[]} */ (response.syncs)
|
|
@@ -578,7 +600,8 @@ export default class SyncApiClient {
|
|
|
578
600
|
* @param {string} args.authenticationToken - Auth token to send with replay requests.
|
|
579
601
|
* @param {number} [args.batchSize] - Max syncs per request.
|
|
580
602
|
* @param {ReturnType<typeof JSON.parse>} args.syncModel - Local Sync model class.
|
|
581
|
-
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}) => Promise<SyncReplayResponse>} args.postReplay - Replay poster.
|
|
603
|
+
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}, options?: {signal?: AbortSignal}) => Promise<SyncReplayResponse>} args.postReplay - Replay poster.
|
|
604
|
+
* @param {AbortSignal} [args.signal] - Lifecycle cancellation signal.
|
|
582
605
|
* @returns {Promise<void>}
|
|
583
606
|
*/
|
|
584
607
|
static async replayLocalSyncs(args) {
|
|
@@ -602,6 +625,7 @@ export default class SyncApiClient {
|
|
|
602
625
|
},
|
|
603
626
|
pendingSyncs: async () => await args.syncModel.preload({resource: true}).where({state: "pending"}).order("created_at").toArray(),
|
|
604
627
|
postReplay: args.postReplay,
|
|
628
|
+
signal: args.signal,
|
|
605
629
|
syncId: (sync) => (/** @type {{id: () => string | number | null | undefined}} */ (sync)).id(),
|
|
606
630
|
syncPayload: (sync) => {
|
|
607
631
|
postedSnapshotsBySyncId.set(String((/** @type {{id: () => string | number | null | undefined}} */ (sync)).id()), this.localSyncReplaySnapshot(sync))
|
|
@@ -810,15 +834,19 @@ export default class SyncApiClient {
|
|
|
810
834
|
* @param {() => Promise<Array<unknown>>} args.pendingSyncs - Loads pending local sync rows in replay order.
|
|
811
835
|
* @param {(sync: unknown) => string | number | null | undefined} args.syncId - Returns the local sync id.
|
|
812
836
|
* @param {(sync: unknown) => Record<string, ReturnType<typeof JSON.parse>>} args.syncPayload - Builds the API sync envelope.
|
|
813
|
-
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}) => Promise<SyncReplayResponse>} args.postReplay - Posts one replay request.
|
|
837
|
+
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}, options?: {signal?: AbortSignal}) => Promise<SyncReplayResponse>} args.postReplay - Posts one replay request.
|
|
814
838
|
* @param {(sync: unknown, response: SyncReplayItem) => Promise<void>} args.markSuccessful - Marks one sync as successful locally.
|
|
839
|
+
* @param {AbortSignal} [args.signal] - Lifecycle cancellation signal.
|
|
815
840
|
* @returns {Promise<void>} Resolves after all batches are replayed.
|
|
816
841
|
*/
|
|
817
842
|
static async replayPending(args) {
|
|
843
|
+
throwIfSyncAborted(args.signal)
|
|
818
844
|
const pendingSyncs = await args.pendingSyncs()
|
|
845
|
+
throwIfSyncAborted(args.signal)
|
|
819
846
|
const batchSize = this.normalizedBatchSize(args.batchSize)
|
|
820
847
|
|
|
821
848
|
for (let offset = 0; offset < pendingSyncs.length; offset += batchSize) {
|
|
849
|
+
throwIfSyncAborted(args.signal)
|
|
822
850
|
await this.replayBatch({...args, pendingSyncs: pendingSyncs.slice(offset, offset + batchSize)})
|
|
823
851
|
}
|
|
824
852
|
}
|
|
@@ -830,14 +858,16 @@ export default class SyncApiClient {
|
|
|
830
858
|
* @param {Array<unknown>} args.pendingSyncs - Batch syncs.
|
|
831
859
|
* @param {(sync: unknown) => string | number | null | undefined} args.syncId - Sync id getter.
|
|
832
860
|
* @param {(sync: unknown) => Record<string, ReturnType<typeof JSON.parse>>} args.syncPayload - Payload builder.
|
|
833
|
-
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}) => Promise<SyncReplayResponse>} args.postReplay - Replay poster.
|
|
861
|
+
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}, options?: {signal?: AbortSignal}) => Promise<SyncReplayResponse>} args.postReplay - Replay poster.
|
|
834
862
|
* @param {(sync: unknown, response: SyncReplayItem) => Promise<void>} args.markSuccessful - Success hook.
|
|
863
|
+
* @param {AbortSignal} [args.signal] - Lifecycle cancellation signal.
|
|
835
864
|
* @returns {Promise<void>} Resolves after the batch is acknowledged.
|
|
836
865
|
*/
|
|
837
866
|
static async replayBatch(args) {
|
|
838
|
-
const {authenticationToken, markSuccessful, pendingSyncs, postReplay, syncId, syncPayload} = args
|
|
867
|
+
const {authenticationToken, markSuccessful, pendingSyncs, postReplay, signal, syncId, syncPayload} = args
|
|
839
868
|
|
|
840
869
|
if (pendingSyncs.length === 0) return
|
|
870
|
+
throwIfSyncAborted(signal)
|
|
841
871
|
|
|
842
872
|
const syncsById = new Map()
|
|
843
873
|
|
|
@@ -850,11 +880,13 @@ export default class SyncApiClient {
|
|
|
850
880
|
const response = await postReplay({
|
|
851
881
|
authenticationToken,
|
|
852
882
|
syncs: pendingSyncs.map((sync) => syncPayload(sync))
|
|
853
|
-
})
|
|
883
|
+
}, {signal})
|
|
854
884
|
|
|
885
|
+
throwIfSyncAborted(signal)
|
|
855
886
|
this.ensureSuccessfulResponse(response)
|
|
856
887
|
|
|
857
888
|
for (const syncResponse of response.syncs || []) {
|
|
889
|
+
throwIfSyncAborted(signal)
|
|
858
890
|
const sync = syncsById.get(String(syncResponse.id))
|
|
859
891
|
|
|
860
892
|
if (!sync) continue
|
|
@@ -863,6 +895,7 @@ export default class SyncApiClient {
|
|
|
863
895
|
}
|
|
864
896
|
|
|
865
897
|
await markSuccessful(sync, syncResponse)
|
|
898
|
+
throwIfSyncAborted(signal)
|
|
866
899
|
}
|
|
867
900
|
}
|
|
868
901
|
|
|
@@ -887,3 +920,15 @@ export default class SyncApiClient {
|
|
|
887
920
|
return Math.floor(batchSize)
|
|
888
921
|
}
|
|
889
922
|
}
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* Throws the exact abort reason at lifecycle boundaries so callers can
|
|
926
|
+
* distinguish an expected cooperative stop from transport or apply failures.
|
|
927
|
+
* @param {AbortSignal | undefined} signal - Lifecycle signal.
|
|
928
|
+
* @returns {void}
|
|
929
|
+
*/
|
|
930
|
+
function throwIfSyncAborted(signal) {
|
|
931
|
+
if (!signal?.aborted) return
|
|
932
|
+
|
|
933
|
+
throw signal.reason instanceof Error ? signal.reason : new Error("Sync operation aborted")
|
|
934
|
+
}
|
|
@@ -97,6 +97,26 @@
|
|
|
97
97
|
* @property {import("../tenants/tenant-handle.js").default} [tenantHandle] - Immutable tenant handle binding every local sync state transition.
|
|
98
98
|
*/
|
|
99
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Local cleanup hook that runs transactionally with selected scope resets.
|
|
102
|
+
* @typedef {(args: {connection: import("../database/drivers/base.js").default | null, scopes: SerializedSyncScope[]}) => Promise<void> | void} SyncClientScopeCleanup
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Options for stopping and resetting a sync client lifecycle.
|
|
107
|
+
* @typedef {object} SyncClientStopOptions
|
|
108
|
+
* @property {SyncClientScopeCleanup} [cleanup] - App-owned local-row purge run atomically with resetScopes.
|
|
109
|
+
* @property {SerializedSyncScope[]} [resetScopes] - Selected scope rows to deactivate and restart from a null cursor.
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Options for atomically replacing the external identity read by sync.client.
|
|
114
|
+
* @typedef {SyncClientStopOptions & {
|
|
115
|
+
* replace: () => Promise<void> | void,
|
|
116
|
+
* subscribeUserScope?: boolean
|
|
117
|
+
* }} SyncClientReplaceIdentityOptions
|
|
118
|
+
*/
|
|
119
|
+
|
|
100
120
|
/**
|
|
101
121
|
* Internal derived sync client configuration built by the SyncClient
|
|
102
122
|
* constructor — not an app-facing API.
|
|
@@ -107,8 +127,8 @@
|
|
|
107
127
|
* @property {() => boolean | Promise<boolean>} [isOnline] - Connectivity gate for pulls and replays. Defaults to always online.
|
|
108
128
|
* @property {(args: {scope: SerializedSyncScope}) => string | null | Promise<string | null>} [legacyCursor] - Seeds a newly declared scope's cursor (e.g. from a pre-scope cursor store) so devices don't re-pull everything.
|
|
109
129
|
* @property {(error: Error) => void} [onError] - Reports background replay/pull failures. Defaults to rethrowing.
|
|
110
|
-
* @property {(payload: import("./sync-api-client-types.js").SyncChangesRequest & {scope: SerializedSyncScope}) => Promise<import("./sync-api-client-types.js").SyncChangesResponse>} postChanges - Posts one changes request.
|
|
111
|
-
* @property {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}) => Promise<import("./sync-api-client-types.js").SyncReplayResponse>} postReplay - Posts one replay request.
|
|
130
|
+
* @property {(payload: import("./sync-api-client-types.js").SyncChangesRequest & {scope: SerializedSyncScope}, options?: {signal?: AbortSignal}) => Promise<import("./sync-api-client-types.js").SyncChangesResponse>} postChanges - Posts one changes request.
|
|
131
|
+
* @property {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}, options?: {signal?: AbortSignal}) => Promise<import("./sync-api-client-types.js").SyncReplayResponse>} postReplay - Posts one replay request.
|
|
112
132
|
* @property {import("../configuration-types.js").VelociousSyncClientRealtimeConfiguration} [realtime] - Realtime push configuration consumed by `subscribeRealtime(...)`.
|
|
113
133
|
* @property {import("../remote-request-context.js").RemoteRequestContext} requestContext - Immutable scalar context captured for this client.
|
|
114
134
|
* @property {Record<string, SyncClientResourceConfig>} resources - Derived resource policies keyed by resource/model name.
|