@baukit/sync-client 0.2.0 → 0.3.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 CHANGED
@@ -1,16 +1,59 @@
1
1
  # `@baukit/sync-client`
2
2
 
3
- `@baukit/sync-client` holds the four client-side pieces every offline-capable product rebuilds
4
- around a sync loop: when to run, how to send a request, how to report status, and what order to
5
- push a batch in. It does not define a sync protocol. Endpoint paths, payloads, conflict rules, and
6
- the sync engine itself stay product-owned, as
3
+ `@baukit/sync-client` holds client-side mechanics that offline-capable products rebuild around a
4
+ sync loop: scheduling, transport, status, push ordering, and hybrid logical timestamps. It does
5
+ not define a sync protocol. Endpoint paths, payloads, conflict rules, and the sync engine itself
6
+ stay product-owned, as
7
7
  [the offline readiness contract](../../../docs/platform/offline-readiness-contract.md) says they
8
8
  must.
9
9
 
10
10
  The root entry has no runtime dependencies and no React. Timers, foreground state, connectivity,
11
11
  and `fetch` all arrive by injection, so the same code runs under Node, a browser, and React Native.
12
12
  The optional `@baukit/sync-client/expo` entry imports `react-native` and `expo-network`; neither is
13
- loaded by the root entry.
13
+ loaded by the root entry. The `@baukit/sync-client/browser` entry reads browser globals only when
14
+ `createBrowserSyncEnvironment` is called, so importing it under Node is safe.
15
+
16
+ ## Hybrid logical clock
17
+
18
+ Import the clock from the root package or `@baukit/sync-client/hlc`. It uses the same integer
19
+ encoding as `baukit_sync::hlc`, so Rust and TypeScript can compare stored timestamps directly.
20
+
21
+ ```ts
22
+ import { HybridLogicalClock } from '@baukit/sync-client/hlc';
23
+
24
+ const clock = await HybridLogicalClock.open('device-a', metadataStore, Date.now);
25
+ const localTimestamp = await clock.now();
26
+ const afterRemote = await clock.observe(remoteTimestamp);
27
+ const state = clock.snapshot();
28
+ ```
29
+
30
+ The encoding is `wallTimeMs * 1000 + counter + 1`. The added one reserves zero as invalid. Use
31
+ `encodeHybridLogicalTimestamp`, `decodeHybridLogicalTimestamp`, and
32
+ `compareHybridLogicalTimestamps` when no stateful clock is needed. Comparison returns `null` if
33
+ either input is invalid.
34
+
35
+ JavaScript can represent integers exactly only through `Number.MAX_SAFE_INTEGER`,
36
+ `9_007_199_254_740_991`. The last valid HLC value decodes to wall time `9_007_199_254_740` and
37
+ counter `990`. Calls beyond that point reject with `HybridLogicalClockError` code
38
+ `exceeds_safe_integer` and leave committed state unchanged. Within the normal range, counter 1,000
39
+ moves the wall component forward by one millisecond and resets the counter to zero.
40
+
41
+ The device ID and physical clock are caller inputs. The module does not generate device IDs or
42
+ choose a storage system. Pass no store for an in-memory clock, or implement `HlcStorage` for product
43
+ persistence. A stored state is restored only when its device ID matches and its components form a
44
+ valid encoded timestamp. Missing, corrupt, and foreign state reset to zero. Storage read and write
45
+ failures reject unchanged.
46
+
47
+ When storage is present, `now` and `observe` run in call order. A later call waits for the prior
48
+ write to finish. Failed writes do not update the snapshot and do not stop the queue. `snapshot`
49
+ therefore reports the last state committed to storage.
50
+
51
+ ### Clock migration
52
+
53
+ Redemut can replace its local HLC import with `@baukit/sync-client/hlc`. The existing
54
+ `open(deviceId, storage, physicalClock)` call and `hlc-state` record remain compatible. No stored
55
+ timestamp or state rewrite is needed. Redemut keeps its IndexedDB and SQLite adapters, device ID
56
+ creation, merge rules, server compare-and-swap, and cursor protocol.
14
57
 
15
58
  ## Scheduler
16
59
 
@@ -34,6 +77,41 @@ interval while backgrounded and ignores connectivity events there.
34
77
  A failing run reaches `onError` and does not stop scheduling. Backoff between attempts belongs to
35
78
  the product's engine, inside `run()`, where it can see which failures are retryable.
36
79
 
80
+ If the engine waits inside its own retry delay, pass `onRecoverySignal` to the scheduler and wake
81
+ that delay there. The scheduler calls it with `active` before a foreground-triggered run and with
82
+ `online` before an online-triggered run. Online recovery is reported even while the scheduler is
83
+ backgrounded, although the scheduler still waits for foreground before starting another run.
84
+ Retry wake-up belongs in this scheduler option, not in a decorated environment, because the
85
+ environment does not know whether an engine has a retry delay.
86
+
87
+ ```ts
88
+ const scheduler = new SyncScheduler(() => engine.retryNow(), environment, {
89
+ onRecoverySignal: () => engine.wakeRetryDelay(),
90
+ });
91
+ ```
92
+
93
+ ### Browser environment
94
+
95
+ Browser products can import an environment that maps document visibility, online events, and
96
+ intervals to the scheduler contract:
97
+
98
+ ```ts
99
+ import { SyncScheduler } from '@baukit/sync-client';
100
+ import { createBrowserSyncEnvironment } from '@baukit/sync-client/browser';
101
+
102
+ const scheduler = new SyncScheduler(() => engine.retryNow(), createBrowserSyncEnvironment(), {
103
+ onRecoverySignal: () => engine.wakeRetryDelay(),
104
+ });
105
+ ```
106
+
107
+ `isActive` is true only while `document.visibilityState` is `visible`. A visibility change reports
108
+ the new active state, and an `online` event reports a connectivity wake signal. Each returned
109
+ cleanup function may be called more than once and removes its listener once.
110
+
111
+ Tests and non-browser hosts can inject `{ document, window, timers }`. Calling the factory without
112
+ injections outside a browser throws a specific missing-document or missing-window error. Importing
113
+ the entry never reads either global. The browser entry has no React, Dexie, or sync-engine import.
114
+
37
115
  ### Expo environment
38
116
 
39
117
  Expo products can use the supplied environment instead of repeating AppState and network wiring:
@@ -241,15 +319,71 @@ describe('product sync contract', () => {
241
319
  ```
242
320
 
243
321
  The adapter supplies two isolated clients and one fake server per case. It also supplies callbacks
244
- for outbox enqueue, listing, acknowledgement, and rejection storage; atomic pull application and
245
- cursor storage; pending-state reporting; wire encoding and decoding; and fake-server push, pull,
246
- seeding, snapshots, and fault injection. Canonical fixture changes contain opaque entity names,
247
- values, logical times, dependencies, and tombstones. The adapter maps them to the product's schema
248
- and payloads.
322
+ for outbox enqueue, listing, and stable pending IDs; atomic submitted-batch settlement; atomic pull
323
+ application and cursor storage; pending-state reporting; wire encoding and decoding; and
324
+ fake-server push, pull, seeding, snapshots, and fault injection. Canonical fixture changes contain
325
+ opaque entity names, values, logical times, dependencies, and tombstones. The adapter maps them to
326
+ the product's schema and payloads.
249
327
 
250
328
  The cases cover replay, transaction rollback, paged cursor progress, stalled and regressing
251
- cursors, complete push outcomes, pending state after network, server, and local failures,
252
- actionable rejections, dependency-safe push order, and two-client convergence with a tombstone.
253
- `wire.decodePush` must call `validatePushOutcomeCoverage` before returning acknowledged rows. The
254
- local apply callback must commit the page and cursor in one transaction. Its injected failure must
255
- roll both back.
329
+ cursors, complete push outcomes, late accepted and rejected responses, stale pulls over pending
330
+ writes, pending state after failures, dependency-safe push order, and two-client convergence with
331
+ a tombstone. When `fullResync` is present, five more cases cover monotonic purge horizons, cursor
332
+ zero, parent and child cleanup, pull-only rows, pending edits, rejection records, reset rollback,
333
+ reset deferral, and the repeated-stale stop condition. `wire.decodePush` must call
334
+ `validatePushOutcomeCoverage` before returning acknowledged rows. It returns decoded
335
+ `rejectedRows` when a rejection contains an authoritative server row.
336
+
337
+ `local.applySubmittedBatchOutcome` receives the exact `submitted` rows, the raw push `response`,
338
+ the decoded acknowledged rows and rejections, and any decoded rejected server rows. In one storage
339
+ transaction it must settle only pending IDs covered by that submission, record actionable
340
+ rejections, apply safe rejected rows, and perform any accepted-revision stamping. A newer pending
341
+ row for the same entity blocks an older response from replacing its local payload. Revision
342
+ stamping is product policy. The harness does not require last-writer-wins or a particular revision
343
+ type, but a stamp from an older submission must not replace the payload of a newer local write.
344
+
345
+ The pull callback must keep a pending local row when an older or equal remote revision arrives,
346
+ while committing the page cursor in the same transaction. Its injected failure must roll back both
347
+ the staged row and cursor.
348
+
349
+ ### Tombstone-horizon conformance
350
+
351
+ Adapters for products with finite tombstone retention set the optional `fullResync` field. Products
352
+ without it receive the original case set and need no adapter change.
353
+
354
+ `zeroCursor` is the product's explicit full-rebuild cursor. `decodeStaleCursor` maps the product's
355
+ wire error onto `{ code: 'resync_required', horizon }`. The product response must keep the code and
356
+ horizon field stable. For the HTTP 409 envelope, the source value is
357
+ `error.details.horizon_revision`.
358
+
359
+ `isResetSafe` is the production policy hook. `setResetSafe` lets the isolated test client enter a
360
+ safe or unsafe state. `reset` clears server-backed rows and writes `zeroCursor` in one transaction,
361
+ while keeping pending mutations, rejection records, and their repairable rows. It must honor
362
+ `failAfterRows` inside that transaction so the rollback case can inspect the unchanged database.
363
+ `readResetCount` lets the suite prove that an immediate second stale response does not start a
364
+ loop.
365
+
366
+ The fake-server callbacks stay test-only. `purgeTombstones` removes the requested fixture rows and
367
+ returns the owner's current horizon. `rejectNextZeroCursor` injects a protocol violation for the
368
+ stop-condition case. Entity registration, deletion SQL, retention periods, and foreign-key order
369
+ remain in the product.
370
+
371
+ After reset, the suite submits retained pending work and pulls from zero. The full snapshot must
372
+ not overwrite a newer pending edit. It must remove server-backed parent, child, and pull-only rows
373
+ whose tombstones are no longer available.
374
+
375
+ ### Tombstone-horizon migration
376
+
377
+ Existing adapters can omit `fullResync`; their types and cases are unchanged. A product that
378
+ enables finite tombstone retention should add the callbacks as one unit. Keep its current cursor
379
+ type and HTTP envelope, decode the horizon into `SyncConformanceStaleCursor`, and replace any split
380
+ "clear rows, then set cursor" path with one local transaction before enabling these cases.
381
+
382
+ ### Conformance adapter migration
383
+
384
+ Existing adapter objects still type-check because `applySubmittedBatchOutcome` and `pendingId` are
385
+ optional, and the old `markAcknowledged` and `recordRejected` callbacks remain in the interface.
386
+ The expanded suite stops with a conformance error until the two new callbacks are present.
387
+ Implement atomic settlement with the same transaction used by the production sync path, return
388
+ rejected server rows from `decodePush`, then remove split settlement calls from the product engine.
389
+ Do not emulate the new callback by calling the two old callbacks in sequence.
@@ -0,0 +1,23 @@
1
+ import type { SyncSchedulerEnvironment, SyncSchedulerTimer } from './scheduler.js';
2
+ export interface BrowserSyncDocument {
3
+ readonly visibilityState: string;
4
+ addEventListener(type: 'visibilitychange', listener: () => void): void;
5
+ removeEventListener(type: 'visibilitychange', listener: () => void): void;
6
+ }
7
+ export interface BrowserSyncWindow {
8
+ addEventListener(type: 'online', listener: () => void): void;
9
+ removeEventListener(type: 'online', listener: () => void): void;
10
+ setInterval(callback: () => void, milliseconds: number): number;
11
+ clearInterval(handle: number): void;
12
+ }
13
+ export interface BrowserSyncTimers {
14
+ setInterval(callback: () => void, milliseconds: number): SyncSchedulerTimer;
15
+ clearInterval(handle: SyncSchedulerTimer): void;
16
+ }
17
+ export interface BrowserSyncEnvironmentOptions {
18
+ document?: BrowserSyncDocument;
19
+ window?: BrowserSyncWindow;
20
+ timers?: BrowserSyncTimers;
21
+ }
22
+ export declare function createBrowserSyncEnvironment(options?: BrowserSyncEnvironmentOptions): SyncSchedulerEnvironment;
23
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEnF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACvE,mBAAmB,CAAC,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CAC3E;AAED,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC7D,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAChE,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;IAChE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,YAAY,EAAE,MAAM,GAAG,kBAAkB,CAAC;IAC5E,aAAa,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACjD;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AA6BD,wBAAgB,4BAA4B,CAC1C,OAAO,GAAE,6BAAkC,GAC1C,wBAAwB,CAmC1B"}
@@ -0,0 +1,60 @@
1
+ function resolveDocument(document) {
2
+ const globalDocument = globalThis.document;
3
+ const resolved = document ?? globalDocument;
4
+ if (resolved === undefined) {
5
+ throw new Error('Browser sync environment requires a document');
6
+ }
7
+ return resolved;
8
+ }
9
+ function resolveWindow(window) {
10
+ const globalWindow = globalThis.window;
11
+ const resolved = window ?? globalWindow;
12
+ if (resolved === undefined) {
13
+ throw new Error('Browser sync environment requires a window');
14
+ }
15
+ return resolved;
16
+ }
17
+ function once(cleanup) {
18
+ let active = true;
19
+ return () => {
20
+ if (!active)
21
+ return;
22
+ active = false;
23
+ cleanup();
24
+ };
25
+ }
26
+ export function createBrowserSyncEnvironment(options = {}) {
27
+ const browserDocument = resolveDocument(options.document);
28
+ const browserWindow = resolveWindow(options.window);
29
+ const timers = options.timers ?? {
30
+ setInterval: (callback, milliseconds) => browserWindow.setInterval(callback, milliseconds),
31
+ clearInterval: (handle) => {
32
+ browserWindow.clearInterval(handle);
33
+ },
34
+ };
35
+ return {
36
+ isActive: () => browserDocument.visibilityState === 'visible',
37
+ subscribeActive(listener) {
38
+ const onVisibilityChange = () => {
39
+ listener(browserDocument.visibilityState === 'visible');
40
+ };
41
+ browserDocument.addEventListener('visibilitychange', onVisibilityChange);
42
+ return once(() => {
43
+ browserDocument.removeEventListener('visibilitychange', onVisibilityChange);
44
+ });
45
+ },
46
+ subscribeOnline(listener) {
47
+ browserWindow.addEventListener('online', listener);
48
+ return once(() => {
49
+ browserWindow.removeEventListener('online', listener);
50
+ });
51
+ },
52
+ setInterval(callback, milliseconds) {
53
+ return timers.setInterval(callback, milliseconds);
54
+ },
55
+ clearInterval(handle) {
56
+ timers.clearInterval(handle);
57
+ },
58
+ };
59
+ }
60
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AA0BA,SAAS,eAAe,CAAC,QAAyC;IAChE,MAAM,cAAc,GAAG,UAAU,CAAC,QAA2C,CAAC;IAC9E,MAAM,QAAQ,GAAG,QAAQ,IAAI,cAAc,CAAC;IAC5C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,aAAa,CAAC,MAAqC;IAC1D,MAAM,YAAY,GAAG,UAAU,CAAC,MAAkD,CAAC;IACnF,MAAM,QAAQ,GAAG,MAAM,IAAI,YAAY,CAAC;IACxC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,IAAI,CAAC,OAAmB;IAC/B,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,OAAO,GAAG,EAAE;QACV,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,GAAG,KAAK,CAAC;QACf,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,UAAyC,EAAE;IAE3C,MAAM,eAAe,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,MAAM,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,MAAM,GAAsB,OAAO,CAAC,MAAM,IAAI;QAClD,WAAW,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,CACtC,aAAa,CAAC,WAAW,CAAC,QAAQ,EAAE,YAAY,CAAkC;QACpF,aAAa,EAAE,CAAC,MAAM,EAAE,EAAE;YACxB,aAAa,CAAC,aAAa,CAAC,MAA2B,CAAC,CAAC;QAC3D,CAAC;KACF,CAAC;IAEF,OAAO;QACL,QAAQ,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,eAAe,KAAK,SAAS;QAC7D,eAAe,CAAC,QAAQ;YACtB,MAAM,kBAAkB,GAAG,GAAG,EAAE;gBAC9B,QAAQ,CAAC,eAAe,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC;YAC1D,CAAC,CAAC;YACF,eAAe,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC;YACzE,OAAO,IAAI,CAAC,GAAG,EAAE;gBACf,eAAe,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC;YAC9E,CAAC,CAAC,CAAC;QACL,CAAC;QACD,eAAe,CAAC,QAAQ;YACtB,aAAa,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACnD,OAAO,IAAI,CAAC,GAAG,EAAE;gBACf,aAAa,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACxD,CAAC,CAAC,CAAC;QACL,CAAC;QACD,WAAW,CAAC,QAAQ,EAAE,YAAY;YAChC,OAAO,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QACpD,CAAC;QACD,aAAa,CAAC,MAAM;YAClB,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -25,9 +25,14 @@ export interface SyncConformancePullPage<TChange, TCursor> {
25
25
  nextCursor: TCursor;
26
26
  hasMore: boolean;
27
27
  }
28
- export interface SyncConformancePushResult<TPending> {
28
+ export interface SyncConformancePushResult<TPending, TRemoteChange = never> {
29
29
  acknowledged: readonly TPending[];
30
30
  rejected: readonly SyncConformanceRejection[];
31
+ rejectedRows?: readonly TRemoteChange[];
32
+ }
33
+ export interface SyncConformanceSubmittedBatchOutcome<TPending, TPushResponse, TRemoteChange> extends SyncConformancePushResult<TPending, TRemoteChange> {
34
+ submitted: readonly TPending[];
35
+ response: TPushResponse;
31
36
  }
32
37
  export interface SyncConformancePendingState {
33
38
  pending: boolean;
@@ -36,6 +41,23 @@ export interface SyncConformancePendingState {
36
41
  export interface SyncConformanceLocalApplyOptions {
37
42
  failAfterChanges?: number;
38
43
  }
44
+ export interface SyncConformanceStaleCursor<TCursor> {
45
+ code: 'resync_required';
46
+ horizon: TCursor;
47
+ }
48
+ export interface SyncConformanceFullResyncOptions {
49
+ failAfterRows?: number;
50
+ }
51
+ export interface SyncConformanceFullResyncCallbacks<TClient, TServer, TCursor> {
52
+ zeroCursor: TCursor;
53
+ decodeStaleCursor(error: unknown): SyncConformanceStaleCursor<TCursor> | null;
54
+ isResetSafe(client: TClient, stale: SyncConformanceStaleCursor<TCursor>): Promise<boolean> | boolean;
55
+ setResetSafe(client: TClient, safe: boolean): Promise<void> | void;
56
+ reset(client: TClient, stale: SyncConformanceStaleCursor<TCursor>, options?: SyncConformanceFullResyncOptions): Promise<void> | void;
57
+ readResetCount(client: TClient): Promise<number> | number;
58
+ purgeTombstones(server: TServer, rows: readonly SyncConformanceEntityRef[]): Promise<TCursor> | TCursor;
59
+ rejectNextZeroCursor(server: TServer, horizon: TCursor): Promise<void> | void;
60
+ }
39
61
  export interface SyncConformanceScenario<TClient, TServer> {
40
62
  clients: readonly [TClient, TClient];
41
63
  server: TServer;
@@ -46,6 +68,7 @@ export interface SyncConformanceAdapter<TClient, TServer, TPending, TPushRequest
46
68
  outbox: {
47
69
  enqueue(client: TClient, change: SyncConformanceChange): Promise<void> | void;
48
70
  listPending(client: TClient): Promise<readonly TPending[]> | readonly TPending[];
71
+ pendingId?(pending: TPending): string;
49
72
  markAcknowledged(client: TClient, pending: readonly TPending[]): Promise<void> | void;
50
73
  recordRejected(client: TClient, rejected: readonly SyncConformanceRejection[]): Promise<void> | void;
51
74
  listRejected(client: TClient): Promise<readonly SyncConformanceRejection[]> | readonly SyncConformanceRejection[];
@@ -55,10 +78,11 @@ export interface SyncConformanceAdapter<TClient, TServer, TPending, TPushRequest
55
78
  applyPullPage(client: TClient, page: SyncConformancePullPage<TRemoteChange, TCursor>, options?: SyncConformanceLocalApplyOptions): Promise<void> | void;
56
79
  snapshot(client: TClient): Promise<readonly SyncConformanceRow[]> | readonly SyncConformanceRow[];
57
80
  readPendingState(client: TClient): Promise<SyncConformancePendingState> | SyncConformancePendingState;
81
+ applySubmittedBatchOutcome?(client: TClient, outcome: SyncConformanceSubmittedBatchOutcome<TPending, TPushResponse, TRemoteChange>): Promise<void> | void;
58
82
  };
59
83
  wire: {
60
84
  encodePush(pending: readonly TPending[]): Promise<TPushRequest> | TPushRequest;
61
- decodePush(response: TPushResponse, submitted: readonly TPending[]): Promise<SyncConformancePushResult<TPending>> | SyncConformancePushResult<TPending>;
85
+ decodePush(response: TPushResponse, submitted: readonly TPending[]): Promise<SyncConformancePushResult<TPending, TRemoteChange>> | SyncConformancePushResult<TPending, TRemoteChange>;
62
86
  decodePull(response: TPullResponse): Promise<SyncConformancePullPage<TRemoteChange, TCursor>> | SyncConformancePullPage<TRemoteChange, TCursor>;
63
87
  compareCursors(left: TCursor, right: TCursor): number;
64
88
  };
@@ -71,6 +95,7 @@ export interface SyncConformanceAdapter<TClient, TServer, TPending, TPushRequest
71
95
  omitNextPushOutcome(server: TServer): Promise<void> | void;
72
96
  faultNextPull(server: TServer, fault: SyncConformancePullFault): Promise<void> | void;
73
97
  };
98
+ fullResync?: SyncConformanceFullResyncCallbacks<TClient, TServer, TCursor>;
74
99
  }
75
100
  export interface SyncConformanceTestCase {
76
101
  readonly name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"conformance.d.ts","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"conformance.d.ts","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"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"}
@@ -77,19 +77,33 @@ export function createSyncConformanceTests(adapter) {
77
77
  async function assertPendingState(client, expectedCount) {
78
78
  const actual = await pending(client);
79
79
  const reported = await adapter.local.readPendingState(client);
80
- assert(actual.length === expectedCount, `expected ${String(expectedCount)} pending changes`);
80
+ assert(actual.length === expectedCount, `expected ${String(expectedCount)} pending changes, received ${String(actual.length)}`);
81
81
  assert(reported.pendingCount === actual.length, 'reported pending count differs from the outbox');
82
82
  assert(reported.pending === actual.length > 0, 'reported pending flag differs from the outbox');
83
83
  }
84
- async function push(client, server) {
84
+ async function submit(client, server) {
85
85
  const submitted = await pending(client);
86
- if (submitted.length === 0)
87
- return;
86
+ assert(submitted.length > 0, 'cannot submit an empty pending batch');
88
87
  const request = await adapter.wire.encodePush(submitted);
89
88
  const response = await adapter.server.acceptPush(server, request);
90
89
  const outcome = await adapter.wire.decodePush(response, submitted);
91
- await adapter.outbox.markAcknowledged(client, outcome.acknowledged);
92
- await adapter.outbox.recordRejected(client, outcome.rejected);
90
+ return { submitted, response, outcome };
91
+ }
92
+ async function applySubmittedBatchOutcome(client, submission) {
93
+ if (adapter.local.applySubmittedBatchOutcome === undefined) {
94
+ fail('adapter must implement local.applySubmittedBatchOutcome for submitted outcomes');
95
+ }
96
+ await adapter.local.applySubmittedBatchOutcome(client, {
97
+ submitted: submission.submitted,
98
+ response: submission.response,
99
+ ...submission.outcome,
100
+ });
101
+ }
102
+ async function push(client, server) {
103
+ const submitted = await pending(client);
104
+ if (submitted.length === 0)
105
+ return;
106
+ await applySubmittedBatchOutcome(client, await submit(client, server));
93
107
  }
94
108
  async function pullPage(client, server, options) {
95
109
  const cursor = (await adapter.local.readCursor(client));
@@ -104,7 +118,31 @@ export function createSyncConformanceTests(adapter) {
104
118
  while (hasMore)
105
119
  hasMore = await pullPage(client, server);
106
120
  }
107
- return [
121
+ async function expectStalePull(client, server, fullResync) {
122
+ const cursor = await adapter.local.readCursor(client);
123
+ try {
124
+ await adapter.server.servePull(server, cursor, PAGE_SIZE);
125
+ }
126
+ catch (error) {
127
+ const stale = fullResync.decodeStaleCursor(error);
128
+ if (stale === null)
129
+ throw error;
130
+ assert(adapter.wire.compareCursors(stale.horizon, cursor) > 0, 'stale cursor response did not contain a newer purge horizon');
131
+ return stale;
132
+ }
133
+ fail('stale cursor returned a pull page');
134
+ }
135
+ async function recoverFromStaleCursor(client, server, fullResync) {
136
+ const stale = await expectStalePull(client, server, fullResync);
137
+ if (!(await fullResync.isResetSafe(client, stale)))
138
+ return 'deferred';
139
+ await fullResync.reset(client, stale);
140
+ assert(adapter.wire.compareCursors(await adapter.local.readCursor(client), fullResync.zeroCursor) ===
141
+ 0, 'full-resync reset did not store cursor zero');
142
+ await pullAll(client, server);
143
+ return 'completed';
144
+ }
145
+ const tests = [
108
146
  {
109
147
  name: 'replayed pushes create one server change',
110
148
  run: () => inScenario(async ({ clientA, server }) => {
@@ -180,6 +218,65 @@ export function createSyncConformanceTests(adapter) {
180
218
  await assertPendingState(clientA, 2);
181
219
  }),
182
220
  },
221
+ {
222
+ name: 'an older accepted submission settles only its exact pending rows',
223
+ run: () => inScenario(async ({ clientA, server }) => {
224
+ await adapter.outbox.enqueue(clientA, change('change-overlap-a', 'overlap', 10, 'A'));
225
+ const submissionA = await submit(clientA, server);
226
+ await adapter.outbox.enqueue(clientA, change('change-overlap-b', 'overlap', 30, 'B'));
227
+ await submit(clientA, server);
228
+ await applySubmittedBatchOutcome(clientA, submissionA);
229
+ const remaining = await pending(clientA);
230
+ assert(remaining.length === 1, 'accepted submission removed a newer pending row');
231
+ if (adapter.outbox.pendingId === undefined) {
232
+ fail('adapter must implement outbox.pendingId for overlapping outcomes');
233
+ }
234
+ assert(remaining[0] !== undefined &&
235
+ adapter.outbox.pendingId(remaining[0]) === 'change-overlap-b', 'accepted submission settled the wrong pending ID');
236
+ const rows = await adapter.local.snapshot(clientA);
237
+ const visible = rows.find((row) => row.entityType === 'record' && row.entityId === 'overlap');
238
+ assert(visible?.value === 'B', 'accepted submission replaced the newer local value');
239
+ await assertPendingState(clientA, 1);
240
+ }),
241
+ },
242
+ {
243
+ name: 'an older rejected submission cannot replace a newer pending value',
244
+ run: () => inScenario(async ({ clientA, server }) => {
245
+ await adapter.server.seed(server, change('seed-overlap', 'overlap', 20, 'server'));
246
+ await adapter.outbox.enqueue(clientA, change('change-overlap-a', 'overlap', 10, 'A'));
247
+ const submissionA = await submit(clientA, server);
248
+ await adapter.outbox.enqueue(clientA, change('change-overlap-b', 'overlap', 30, 'B'));
249
+ await submit(clientA, server);
250
+ await applySubmittedBatchOutcome(clientA, submissionA);
251
+ const remaining = await pending(clientA);
252
+ assert(remaining.length === 1, 'rejected submission removed a newer pending row');
253
+ if (adapter.outbox.pendingId === undefined) {
254
+ fail('adapter must implement outbox.pendingId for overlapping outcomes');
255
+ }
256
+ assert(remaining[0] !== undefined &&
257
+ adapter.outbox.pendingId(remaining[0]) === 'change-overlap-b', 'rejected submission settled the wrong pending ID');
258
+ const rows = await adapter.local.snapshot(clientA);
259
+ const visible = rows.find((row) => row.entityType === 'record' && row.entityId === 'overlap');
260
+ assert(visible?.value === 'B', 'rejected server row replaced the newer local value');
261
+ assert((await adapter.outbox.listRejected(clientA)).length === 1, 'rejected submission did not record its rejection');
262
+ await assertPendingState(clientA, 1);
263
+ }),
264
+ },
265
+ {
266
+ name: 'a stale pull commits its cursor without replacing a pending local value',
267
+ run: () => inScenario(async ({ clientA, server }) => {
268
+ await adapter.server.seed(server, change('seed-stale-pull', 'stale-pull', 20, 'server'));
269
+ await adapter.outbox.enqueue(clientA, change('change-stale-pull', 'stale-pull', 20, 'local'));
270
+ const cursorBefore = await adapter.local.readCursor(clientA);
271
+ await pullPage(clientA, server);
272
+ const cursorAfter = await adapter.local.readCursor(clientA);
273
+ assert(adapter.wire.compareCursors(cursorAfter, cursorBefore) > 0, 'stale pull did not commit its cursor');
274
+ const rows = await adapter.local.snapshot(clientA);
275
+ const visible = rows.find((row) => row.entityType === 'record' && row.entityId === 'stale-pull');
276
+ assert(visible?.value === 'local', 'stale pull replaced the pending local value');
277
+ await assertPendingState(clientA, 1);
278
+ }),
279
+ },
183
280
  {
184
281
  name: 'network failure keeps pending state truthful',
185
282
  run: () => inScenario(async ({ clientA, server }) => {
@@ -247,5 +344,109 @@ export function createSyncConformanceTests(adapter) {
247
344
  }),
248
345
  },
249
346
  ];
347
+ const fullResync = adapter.fullResync;
348
+ if (fullResync === undefined)
349
+ return tests;
350
+ tests.push({
351
+ name: 'purge horizons are monotonic and cursor zero requests a full rebuild',
352
+ run: () => inScenario(async ({ clientA, server }) => {
353
+ const first = change('horizon-first', 'horizon-first', 10, 'first');
354
+ const second = change('horizon-second', 'horizon-second', 20, 'second');
355
+ await adapter.server.seed(server, first);
356
+ await adapter.server.seed(server, second);
357
+ await pullAll(clientA, server);
358
+ const oldCursor = await adapter.local.readCursor(clientA);
359
+ const firstHorizon = await fullResync.purgeTombstones(server, [first]);
360
+ const secondHorizon = await fullResync.purgeTombstones(server, [second]);
361
+ assert(adapter.wire.compareCursors(firstHorizon, oldCursor) > 0, 'first purge did not advance the owner horizon past the old cursor');
362
+ assert(adapter.wire.compareCursors(secondHorizon, firstHorizon) >= 0, 'owner purge horizon regressed');
363
+ const stale = await expectStalePull(clientA, server, fullResync);
364
+ assert(adapter.wire.compareCursors(stale.horizon, secondHorizon) === 0, 'stale cursor response did not contain the current owner horizon');
365
+ const response = await adapter.server.servePull(server, fullResync.zeroCursor, PAGE_SIZE);
366
+ const page = await adapter.wire.decodePull(response);
367
+ validatePullPage(fullResync.zeroCursor, page, (left, right) => adapter.wire.compareCursors(left, right));
368
+ }),
369
+ }, {
370
+ name: 'full resync clears parent, child, and pull-only rows but preserves repair work',
371
+ run: () => inScenario(async ({ clientA, server }) => {
372
+ const pullOnly = change('pull-only-seed', 'pull-only', 12, 'server only');
373
+ const pendingRemote = change('pending-seed', 'pending-edit', 20, 'server value');
374
+ const rejectedRemote = change('rejected-seed', 'rejected-edit', 50, 'server value');
375
+ await adapter.server.seed(server, parentChange);
376
+ await adapter.server.seed(server, childChange);
377
+ await adapter.server.seed(server, pullOnly);
378
+ await adapter.server.seed(server, pendingRemote);
379
+ await adapter.server.seed(server, rejectedRemote);
380
+ await pullAll(clientA, server);
381
+ await adapter.outbox.enqueue(clientA, change('rejected-local', 'rejected-edit', 40, 'rejected value'));
382
+ await push(clientA, server);
383
+ await adapter.outbox.enqueue(clientA, change('pending-local', 'pending-edit', 60, 'pending value'));
384
+ await fullResync.purgeTombstones(server, [childChange, parentChange, pullOnly]);
385
+ const stale = await expectStalePull(clientA, server, fullResync);
386
+ await fullResync.reset(clientA, stale);
387
+ assert(adapter.wire.compareCursors(await adapter.local.readCursor(clientA), fullResync.zeroCursor) === 0, 'reset did not atomically store cursor zero');
388
+ await assertPendingState(clientA, 1);
389
+ assert((await adapter.outbox.listRejected(clientA)).length === 1, 'reset removed an explicit rejection record');
390
+ const resetRows = await adapter.local.snapshot(clientA);
391
+ assert(!resetRows.some((row) => row.entityType === 'container' && row.entityId === 'parent'), 'reset retained a server-backed parent');
392
+ assert(!resetRows.some((row) => row.entityType === 'item' && row.entityId === 'child'), 'reset retained a server-backed child');
393
+ assert(!resetRows.some((row) => row.entityType === 'record' && row.entityId === 'pull-only'), 'reset retained a pull-only row');
394
+ assert(resetRows.some((row) => row.entityId === 'pending-edit' && row.value === 'pending value'), 'reset removed the row for a pending local edit');
395
+ assert(resetRows.some((row) => row.entityId === 'rejected-edit'), 'reset removed the row attached to an explicit rejection');
396
+ await push(clientA, server);
397
+ await pullAll(clientA, server);
398
+ await assertPendingState(clientA, 0);
399
+ assert((await adapter.outbox.listRejected(clientA)).length === 1, 'full rebuild removed an unresolved rejection');
400
+ }),
401
+ }, {
402
+ name: 'an interrupted full-resync reset rolls back rows and cursor',
403
+ run: () => inScenario(async ({ clientA, server }) => {
404
+ const first = change('reset-first', 'reset-first', 10, 'first');
405
+ const second = change('reset-second', 'reset-second', 20, 'second');
406
+ await adapter.server.seed(server, first);
407
+ await adapter.server.seed(server, second);
408
+ await pullAll(clientA, server);
409
+ await adapter.outbox.enqueue(clientA, change('reset-pending', 'pending', 30, 'local'));
410
+ await fullResync.purgeTombstones(server, [first, second]);
411
+ const stale = await expectStalePull(clientA, server, fullResync);
412
+ const cursorBefore = await adapter.local.readCursor(clientA);
413
+ const rowsBefore = await adapter.local.snapshot(clientA);
414
+ await expectFailure(() => Promise.resolve(fullResync.reset(clientA, stale, { failAfterRows: 1 })), 'injected full-resync reset failure resolved successfully');
415
+ assert(adapter.wire.compareCursors(await adapter.local.readCursor(clientA), cursorBefore) ===
416
+ 0, 'failed full-resync reset changed the cursor');
417
+ assert(sameRows(await adapter.local.snapshot(clientA), rowsBefore), 'failed full-resync reset committed a partial row deletion');
418
+ await assertPendingState(clientA, 1);
419
+ }),
420
+ }, {
421
+ name: 'the product safety hook can defer a disruptive reset',
422
+ run: () => inScenario(async ({ clientA, server }) => {
423
+ const remote = change('defer-seed', 'defer', 10, 'remote');
424
+ await adapter.server.seed(server, remote);
425
+ await pullAll(clientA, server);
426
+ await fullResync.purgeTombstones(server, [remote]);
427
+ await fullResync.setResetSafe(clientA, false);
428
+ const cursorBefore = await adapter.local.readCursor(clientA);
429
+ const rowsBefore = await adapter.local.snapshot(clientA);
430
+ const result = await recoverFromStaleCursor(clientA, server, fullResync);
431
+ assert(result === 'deferred', 'unsafe reset was not deferred');
432
+ assert((await fullResync.readResetCount(clientA)) === 0, 'deferred reset ran anyway');
433
+ assert(adapter.wire.compareCursors(await adapter.local.readCursor(clientA), cursorBefore) ===
434
+ 0, 'deferred reset changed the cursor');
435
+ assert(sameRows(await adapter.local.snapshot(clientA), rowsBefore), 'deferred reset changed local rows');
436
+ }),
437
+ }, {
438
+ name: 'a second stale cursor after reset stops without another reset',
439
+ run: () => inScenario(async ({ clientA, server }) => {
440
+ const remote = change('repeat-stale-seed', 'repeat-stale', 10, 'remote');
441
+ await adapter.server.seed(server, remote);
442
+ await pullAll(clientA, server);
443
+ const horizon = await fullResync.purgeTombstones(server, [remote]);
444
+ await fullResync.rejectNextZeroCursor(server, horizon);
445
+ await expectFailure(() => recoverFromStaleCursor(clientA, server, fullResync).then(() => undefined), 'second stale cursor restarted full resync');
446
+ assert((await fullResync.readResetCount(clientA)) === 1, 'second stale cursor caused another reset');
447
+ assert(adapter.wire.compareCursors(await adapter.local.readCursor(clientA), fullResync.zeroCursor) === 0, 'failed full rebuild did not leave the explicit rebuild cursor');
448
+ }),
449
+ });
450
+ return tests;
250
451
  }
251
452
  //# sourceMappingURL=conformance.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"conformance.js","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"conformance.js","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"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"}
package/dist/hlc.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ /** Number of logical counter values available in one physical millisecond. */
2
+ export declare const HLC_COUNTERS_PER_MILLISECOND = 1000;
3
+ /** Largest encoded timestamp JavaScript can represent exactly. */
4
+ export declare const MAX_HLC_TIMESTAMP: number;
5
+ /** Key passed to an injected HLC store. */
6
+ export declare const HLC_STORAGE_KEY = "hlc-state";
7
+ /** Serializable state needed to restore a hybrid logical clock. */
8
+ export type HybridLogicalClockState = Readonly<{
9
+ wallTimeMs: number;
10
+ counter: number;
11
+ deviceId: string;
12
+ } & Record<string, string | number>>;
13
+ /** Async persistence supplied by a product storage adapter. */
14
+ export interface HlcStorage {
15
+ get(key: string): Promise<unknown>;
16
+ set(key: string, value: HybridLogicalClockState): Promise<void>;
17
+ }
18
+ /** Physical clock supplied by the host, usually `Date.now`. */
19
+ export type HlcPhysicalClock = () => number;
20
+ /** Stable validation and exhaustion error codes. */
21
+ export type HybridLogicalClockErrorCode = 'invalid_component' | 'invalid_timestamp' | 'exceeds_safe_integer' | 'invalid_physical_clock' | 'empty_device_id';
22
+ /** Invalid HLC input or exhausted JavaScript-safe timestamp space. */
23
+ export declare class HybridLogicalClockError extends Error {
24
+ readonly code: HybridLogicalClockErrorCode;
25
+ constructor(code: HybridLogicalClockErrorCode, message: string);
26
+ }
27
+ /** Encodes physical milliseconds and a logical counter into one timestamp. */
28
+ export declare function encodeHybridLogicalTimestamp(wallTimeMs: number, counter: number): number;
29
+ /** Decodes a positive JavaScript-safe timestamp into physical and logical parts. */
30
+ export declare function decodeHybridLogicalTimestamp(timestamp: number): Readonly<{
31
+ wallTimeMs: number;
32
+ counter: number;
33
+ }>;
34
+ /** Compares two valid encoded timestamps, or returns `null` for invalid input. */
35
+ export declare function compareHybridLogicalTimestamps(left: number, right: number): -1 | 0 | 1 | null;
36
+ /** Hybrid logical clock with injected time and optional persistence. */
37
+ export declare class HybridLogicalClock {
38
+ #private;
39
+ private constructor();
40
+ /** Opens a clock from optional injected storage. Invalid stored state resets to zero. */
41
+ static open(deviceId: string, storage?: HlcStorage, physicalClock?: HlcPhysicalClock): Promise<HybridLogicalClock>;
42
+ /** Returns the next local timestamp after committing its state. */
43
+ now(): Promise<number>;
44
+ /** Observes a remote timestamp and returns a committed timestamp ordered after it. */
45
+ observe(remoteTimestamp: number): Promise<number>;
46
+ /** Returns an immutable copy of the last committed state. */
47
+ snapshot(): HybridLogicalClockState;
48
+ }
49
+ //# sourceMappingURL=hlc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hlc.d.ts","sourceRoot":"","sources":["../src/hlc.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,eAAO,MAAM,4BAA4B,OAAQ,CAAC;AAElD,kEAAkE;AAClE,eAAO,MAAM,iBAAiB,QAA0B,CAAC;AAEzD,2CAA2C;AAC3C,eAAO,MAAM,eAAe,cAAc,CAAC;AAE3C,mEAAmE;AACnE,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAC5C;IACE,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CACpC,CAAC;AAEF,+DAA+D;AAC/D,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjE;AAED,+DAA+D;AAC/D,MAAM,MAAM,gBAAgB,GAAG,MAAM,MAAM,CAAC;AAE5C,oDAAoD;AACpD,MAAM,MAAM,2BAA2B,GACnC,mBAAmB,GACnB,mBAAmB,GACnB,sBAAsB,GACtB,wBAAwB,GACxB,iBAAiB,CAAC;AAEtB,sEAAsE;AACtE,qBAAa,uBAAwB,SAAQ,KAAK;IAE9C,QAAQ,CAAC,IAAI,EAAE,2BAA2B;gBAAjC,IAAI,EAAE,2BAA2B,EAC1C,OAAO,EAAE,MAAM;CAKlB;AAED,8EAA8E;AAC9E,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAsBxF;AAED,oFAAoF;AACpF,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAaD;AAED,kFAAkF;AAClF,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAK7F;AAED,wEAAwE;AACxE,qBAAa,kBAAkB;;IAO7B,OAAO;IAYP,yFAAyF;WACrE,IAAI,CACtB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,UAAU,EACpB,aAAa,GAAE,gBAA2B,GACzC,OAAO,CAAC,kBAAkB,CAAC;IAO9B,mEAAmE;IAC5D,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;IAS7B,sFAAsF;IAC/E,OAAO,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBxD,6DAA6D;IACtD,QAAQ,IAAI,uBAAuB;CA2B3C"}
package/dist/hlc.js ADDED
@@ -0,0 +1,170 @@
1
+ /** Number of logical counter values available in one physical millisecond. */
2
+ export const HLC_COUNTERS_PER_MILLISECOND = 1_000;
3
+ /** Largest encoded timestamp JavaScript can represent exactly. */
4
+ export const MAX_HLC_TIMESTAMP = Number.MAX_SAFE_INTEGER;
5
+ /** Key passed to an injected HLC store. */
6
+ export const HLC_STORAGE_KEY = 'hlc-state';
7
+ /** Invalid HLC input or exhausted JavaScript-safe timestamp space. */
8
+ export class HybridLogicalClockError extends Error {
9
+ code;
10
+ constructor(code, message) {
11
+ super(message);
12
+ this.code = code;
13
+ this.name = 'HybridLogicalClockError';
14
+ }
15
+ }
16
+ /** Encodes physical milliseconds and a logical counter into one timestamp. */
17
+ export function encodeHybridLogicalTimestamp(wallTimeMs, counter) {
18
+ if (!Number.isSafeInteger(wallTimeMs) ||
19
+ wallTimeMs < 0 ||
20
+ !Number.isInteger(counter) ||
21
+ counter < 0 ||
22
+ counter >= HLC_COUNTERS_PER_MILLISECOND) {
23
+ throw new HybridLogicalClockError('invalid_component', 'Invalid hybrid logical timestamp component');
24
+ }
25
+ const encoded = wallTimeMs * HLC_COUNTERS_PER_MILLISECOND + counter + 1;
26
+ if (!Number.isSafeInteger(encoded) || encoded < 1) {
27
+ throw new HybridLogicalClockError('exceeds_safe_integer', 'Hybrid logical timestamp exceeds safe integer range');
28
+ }
29
+ return encoded;
30
+ }
31
+ /** Decodes a positive JavaScript-safe timestamp into physical and logical parts. */
32
+ export function decodeHybridLogicalTimestamp(timestamp) {
33
+ if (!isEncodedTimestamp(timestamp)) {
34
+ throw new HybridLogicalClockError('invalid_timestamp', 'Invalid encoded hybrid logical timestamp');
35
+ }
36
+ const zeroBased = timestamp - 1;
37
+ return Object.freeze({
38
+ wallTimeMs: Math.floor(zeroBased / HLC_COUNTERS_PER_MILLISECOND),
39
+ counter: zeroBased % HLC_COUNTERS_PER_MILLISECOND,
40
+ });
41
+ }
42
+ /** Compares two valid encoded timestamps, or returns `null` for invalid input. */
43
+ export function compareHybridLogicalTimestamps(left, right) {
44
+ if (!isEncodedTimestamp(left) || !isEncodedTimestamp(right))
45
+ return null;
46
+ if (left < right)
47
+ return -1;
48
+ if (left > right)
49
+ return 1;
50
+ return 0;
51
+ }
52
+ /** Hybrid logical clock with injected time and optional persistence. */
53
+ export class HybridLogicalClock {
54
+ #deviceId;
55
+ #physicalClock;
56
+ #storage;
57
+ #state;
58
+ #queue = Promise.resolve();
59
+ constructor(deviceId, physicalClock, storage, state) {
60
+ this.#deviceId = deviceId;
61
+ this.#physicalClock = physicalClock;
62
+ this.#storage = storage;
63
+ this.#state = state;
64
+ }
65
+ /** Opens a clock from optional injected storage. Invalid stored state resets to zero. */
66
+ static async open(deviceId, storage, physicalClock = Date.now) {
67
+ validateDeviceId(deviceId);
68
+ const persisted = storage ? parseState(await storage.get(HLC_STORAGE_KEY), deviceId) : null;
69
+ const state = persisted ?? freezeState({ wallTimeMs: 0, counter: 0, deviceId });
70
+ return new HybridLogicalClock(deviceId, physicalClock, storage, state);
71
+ }
72
+ /** Returns the next local timestamp after committing its state. */
73
+ now() {
74
+ return this.#serialized(async () => {
75
+ const physical = readPhysicalTime(this.#physicalClock);
76
+ const wallTimeMs = Math.max(physical, this.#state.wallTimeMs);
77
+ const counter = physical > this.#state.wallTimeMs ? 0 : this.#state.counter + 1;
78
+ return this.#advance(wallTimeMs, counter);
79
+ });
80
+ }
81
+ /** Observes a remote timestamp and returns a committed timestamp ordered after it. */
82
+ observe(remoteTimestamp) {
83
+ return this.#serialized(async () => {
84
+ const remote = decodeHybridLogicalTimestamp(remoteTimestamp);
85
+ const physical = readPhysicalTime(this.#physicalClock);
86
+ const wallTimeMs = Math.max(physical, this.#state.wallTimeMs, remote.wallTimeMs);
87
+ let counter;
88
+ if (wallTimeMs === this.#state.wallTimeMs && wallTimeMs === remote.wallTimeMs) {
89
+ counter = Math.max(this.#state.counter, remote.counter) + 1;
90
+ }
91
+ else if (wallTimeMs === this.#state.wallTimeMs) {
92
+ counter = this.#state.counter + 1;
93
+ }
94
+ else if (wallTimeMs === remote.wallTimeMs) {
95
+ counter = remote.counter + 1;
96
+ }
97
+ else {
98
+ counter = 0;
99
+ }
100
+ return this.#advance(wallTimeMs, counter);
101
+ });
102
+ }
103
+ /** Returns an immutable copy of the last committed state. */
104
+ snapshot() {
105
+ return freezeState(this.#state);
106
+ }
107
+ async #advance(wallTimeMs, counter) {
108
+ if (counter >= HLC_COUNTERS_PER_MILLISECOND) {
109
+ wallTimeMs += 1;
110
+ counter = 0;
111
+ }
112
+ const timestamp = encodeHybridLogicalTimestamp(wallTimeMs, counter);
113
+ const nextState = freezeState({ wallTimeMs, counter, deviceId: this.#deviceId });
114
+ if (this.#storage)
115
+ await this.#storage.set(HLC_STORAGE_KEY, nextState);
116
+ this.#state = nextState;
117
+ return timestamp;
118
+ }
119
+ #serialized(operation) {
120
+ if (!this.#storage)
121
+ return operation();
122
+ const result = this.#queue.then(operation, operation);
123
+ this.#queue = result.then(() => undefined, () => undefined);
124
+ return result;
125
+ }
126
+ }
127
+ function isEncodedTimestamp(timestamp) {
128
+ return Number.isSafeInteger(timestamp) && timestamp >= 1;
129
+ }
130
+ function parseState(value, deviceId) {
131
+ if (typeof value !== 'object' || value === null)
132
+ return null;
133
+ if (!('wallTimeMs' in value) || !('counter' in value) || !('deviceId' in value))
134
+ return null;
135
+ const candidate = value;
136
+ if (typeof candidate.wallTimeMs !== 'number' ||
137
+ typeof candidate.counter !== 'number' ||
138
+ candidate.deviceId !== deviceId) {
139
+ return null;
140
+ }
141
+ try {
142
+ encodeHybridLogicalTimestamp(candidate.wallTimeMs, candidate.counter);
143
+ }
144
+ catch (error) {
145
+ if (error instanceof HybridLogicalClockError)
146
+ return null;
147
+ throw error;
148
+ }
149
+ return freezeState({
150
+ wallTimeMs: candidate.wallTimeMs,
151
+ counter: candidate.counter,
152
+ deviceId,
153
+ });
154
+ }
155
+ function readPhysicalTime(clock) {
156
+ const value = Math.floor(clock());
157
+ if (!Number.isSafeInteger(value) || value < 0) {
158
+ throw new HybridLogicalClockError('invalid_physical_clock', 'Physical clock must return a non-negative safe integer');
159
+ }
160
+ return value;
161
+ }
162
+ function validateDeviceId(deviceId) {
163
+ if (deviceId.trim().length === 0) {
164
+ throw new HybridLogicalClockError('empty_device_id', 'HLC device id must not be empty');
165
+ }
166
+ }
167
+ function freezeState(state) {
168
+ return Object.freeze({ ...state });
169
+ }
170
+ //# sourceMappingURL=hlc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hlc.js","sourceRoot":"","sources":["../src/hlc.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  export { SyncAuthError, SyncLocalApplyError, SyncNetworkError, SyncPartitionMismatchError, SyncPayloadCompatibilityError, SyncRateLimitError, SyncServerError, SyncTransportError, syncFailureFromError, toSnakeCaseFailure, } from './error.js';
2
2
  export type { SnakeCaseSyncFailure, SyncFailure } from './error.js';
3
+ export { compareHybridLogicalTimestamps, decodeHybridLogicalTimestamp, encodeHybridLogicalTimestamp, HybridLogicalClock, HybridLogicalClockError, HLC_COUNTERS_PER_MILLISECOND, HLC_STORAGE_KEY, MAX_HLC_TIMESTAMP, } from './hlc.js';
4
+ export type { HlcPhysicalClock, HlcStorage, HybridLogicalClockErrorCode, HybridLogicalClockState, } from './hlc.js';
3
5
  export { dependencyRankByOrder, rankPushBatch, validatePushOutcomeCoverage } from './push-batch.js';
4
6
  export type { PushCandidate, PushOutcomeCoverageOptions, RankedPushItem, RankPushBatchOptions, } from './push-batch.js';
5
7
  export { SyncScheduler } from './scheduler.js';
6
- export type { SyncSchedulerEnvironment, SyncSchedulerOptions, SyncSchedulerTimer, } from './scheduler.js';
8
+ export type { SyncSchedulerEnvironment, SyncSchedulerOptions, SyncSchedulerRecoverySignal, SyncSchedulerTimer, } from './scheduler.js';
7
9
  export { deriveInitialSyncState, deriveLocalStoreReadiness, SyncStatusStore, toSnakeCaseSnapshot, } from './store.js';
8
10
  export type { InitialPullStatus, InitialSyncState, LocalStoreReadiness, LocalStoreReadinessInput, SnakeCaseSyncStatusSnapshot, SyncAttentionItem, SyncFailureUpdate, SyncStatus, SyncStatusHydration, SyncStatusSink, SyncStatusSnapshot, SyncStatusStoreOptions, } from './store.js';
9
11
  export { commitCursorAfterLocalTransaction, DEFAULT_RETRY_AFTER_FALLBACK_MS, parseRetryAfter, SyncTransport, validatePullPage, } from './transport.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,0BAA0B,EAC1B,6BAA6B,EAC7B,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AACpG,YAAY,EACV,aAAa,EACb,0BAA0B,EAC1B,cAAc,EACd,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EACV,wBAAwB,EACxB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EACf,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,wBAAwB,EACxB,2BAA2B,EAC3B,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iCAAiC,EACjC,+BAA+B,EAC/B,eAAe,EACf,aAAa,EACb,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,EAChB,oBAAoB,EACpB,SAAS,EACT,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,mCAAmC,EACnC,kBAAkB,EAClB,eAAe,EACf,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,0BAA0B,EAC1B,6BAA6B,EAC7B,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EACL,8BAA8B,EAC9B,4BAA4B,EAC5B,4BAA4B,EAC5B,kBAAkB,EAClB,uBAAuB,EACvB,4BAA4B,EAC5B,eAAe,EACf,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,gBAAgB,EAChB,UAAU,EACV,2BAA2B,EAC3B,uBAAuB,GACxB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AACpG,YAAY,EACV,aAAa,EACb,0BAA0B,EAC1B,cAAc,EACd,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EACV,wBAAwB,EACxB,oBAAoB,EACpB,2BAA2B,EAC3B,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EACf,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,wBAAwB,EACxB,2BAA2B,EAC3B,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iCAAiC,EACjC,+BAA+B,EAC/B,eAAe,EACf,aAAa,EACb,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,EAChB,oBAAoB,EACpB,SAAS,EACT,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,mCAAmC,EACnC,kBAAkB,EAClB,eAAe,EACf,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { SyncAuthError, SyncLocalApplyError, SyncNetworkError, SyncPartitionMismatchError, SyncPayloadCompatibilityError, SyncRateLimitError, SyncServerError, SyncTransportError, syncFailureFromError, toSnakeCaseFailure, } from './error.js';
2
+ export { compareHybridLogicalTimestamps, decodeHybridLogicalTimestamp, encodeHybridLogicalTimestamp, HybridLogicalClock, HybridLogicalClockError, HLC_COUNTERS_PER_MILLISECOND, HLC_STORAGE_KEY, MAX_HLC_TIMESTAMP, } from './hlc.js';
2
3
  export { dependencyRankByOrder, rankPushBatch, validatePushOutcomeCoverage } from './push-batch.js';
3
4
  export { SyncScheduler } from './scheduler.js';
4
5
  export { deriveInitialSyncState, deriveLocalStoreReadiness, SyncStatusStore, toSnakeCaseSnapshot, } from './store.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,0BAA0B,EAC1B,6BAA6B,EAC7B,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAOpG,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAM/C,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EACf,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAepB,OAAO,EACL,iCAAiC,EACjC,+BAA+B,EAC/B,eAAe,EACf,aAAa,EACb,gBAAgB,GACjB,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,0BAA0B,EAC1B,6BAA6B,EAC7B,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,8BAA8B,EAC9B,4BAA4B,EAC5B,4BAA4B,EAC5B,kBAAkB,EAClB,uBAAuB,EACvB,4BAA4B,EAC5B,eAAe,EACf,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAOlB,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAOpG,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAO/C,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EACf,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAepB,OAAO,EACL,iCAAiC,EACjC,+BAA+B,EAC/B,eAAe,EACf,aAAa,EACb,gBAAgB,GACjB,MAAM,gBAAgB,CAAC"}
@@ -19,7 +19,9 @@ export type SyncSchedulerTimer = {
19
19
  export interface SyncSchedulerOptions {
20
20
  intervalMs?: number;
21
21
  onError?: (error: unknown) => void;
22
+ onRecoverySignal?: (signal: SyncSchedulerRecoverySignal) => void;
22
23
  }
24
+ export type SyncSchedulerRecoverySignal = 'active' | 'online';
23
25
  /**
24
26
  * Runs one opaque sync callback at most once at a time.
25
27
  *
@@ -32,6 +34,7 @@ export declare class SyncScheduler {
32
34
  private readonly environment;
33
35
  private readonly intervalMs;
34
36
  private readonly onError;
37
+ private readonly onRecoverySignal;
35
38
  private active;
36
39
  private started;
37
40
  private inFlight;
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,IAAI,OAAO,CAAC;IACpB,eAAe,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACjE,eAAe,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IAClD,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,YAAY,EAAE,MAAM,GAAG,kBAAkB,CAAC;IAC5E,aAAa,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACjD;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG,MAAM,CAAC;AAEpF,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC;AAQD;;;;;;GAMG;AACH,qBAAa,aAAa;IAWtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAX9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,aAAa,CAAsB;gBAGxB,GAAG,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAC3B,WAAW,EAAE,wBAAwB,EACtD,OAAO,GAAE,oBAAyB;IAMpC,KAAK,IAAI,IAAI;IA0Bb,IAAI,IAAI,IAAI;IAUZ,6CAA6C;IAC7C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAexB,gEAAgE;IAChE,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;YAQlB,eAAe;IAa7B,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,YAAY;CAOrB"}
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,IAAI,OAAO,CAAC;IACpB,eAAe,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACjE,eAAe,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IAClD,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,YAAY,EAAE,MAAM,GAAG,kBAAkB,CAAC;IAC5E,aAAa,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACjD;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG,MAAM,CAAC;AAEpF,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,2BAA2B,KAAK,IAAI,CAAC;CAClE;AAED,MAAM,MAAM,2BAA2B,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAQ9D;;;;;;GAMG;AACH,qBAAa,aAAa;IAYtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAZ9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAgD;IACjF,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,aAAa,CAAsB;gBAGxB,GAAG,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAC3B,WAAW,EAAE,wBAAwB,EACtD,OAAO,GAAE,oBAAyB;IAOpC,KAAK,IAAI,IAAI;IA4Bb,IAAI,IAAI,IAAI;IAUZ,6CAA6C;IAC7C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAexB,gEAAgE;IAChE,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;YAQlB,eAAe;IAa7B,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,YAAY;CAOrB"}
package/dist/scheduler.js CHANGED
@@ -14,6 +14,7 @@ export class SyncScheduler {
14
14
  environment;
15
15
  intervalMs;
16
16
  onError;
17
+ onRecoverySignal;
17
18
  active = false;
18
19
  started = false;
19
20
  inFlight = null;
@@ -25,6 +26,7 @@ export class SyncScheduler {
25
26
  this.environment = environment;
26
27
  this.intervalMs = options.intervalMs ?? DEFAULT_INTERVAL_MS;
27
28
  this.onError = options.onError ?? noop;
29
+ this.onRecoverySignal = options.onRecoverySignal ?? noop;
28
30
  }
29
31
  start() {
30
32
  if (this.started) {
@@ -37,10 +39,12 @@ export class SyncScheduler {
37
39
  this.active = active;
38
40
  this.refreshInterval();
39
41
  if (active) {
42
+ this.onRecoverySignal('active');
40
43
  void this.trigger();
41
44
  }
42
45
  }),
43
46
  this.environment.subscribeOnline(() => {
47
+ this.onRecoverySignal('online');
44
48
  if (this.active) {
45
49
  void this.trigger();
46
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAuBA,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAE1C,SAAS,IAAI;IACX,OAAO;AACT,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,aAAa;IAWL;IACA;IAXF,UAAU,CAAS;IACnB,OAAO,CAA2B;IAC3C,MAAM,GAAG,KAAK,CAAC;IACf,OAAO,GAAG,KAAK,CAAC;IAChB,QAAQ,GAAyB,IAAI,CAAC;IACtC,cAAc,GAAG,KAAK,CAAC;IACvB,QAAQ,GAA8B,IAAI,CAAC;IAC3C,aAAa,GAAmB,EAAE,CAAC;IAE3C,YACmB,GAA2B,EAC3B,WAAqC,EACtD,UAAgC,EAAE;QAFjB,QAAG,GAAH,GAAG,CAAwB;QAC3B,gBAAW,GAAX,WAAW,CAA0B;QAGtD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,mBAAmB,CAAC;QAC5D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;IACzC,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;QAC1C,IAAI,CAAC,aAAa,GAAG;YACnB,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,MAAM,EAAE,EAAE;gBAC1C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;gBACrB,IAAI,CAAC,eAAe,EAAE,CAAC;gBACvB,IAAI,MAAM,EAAE,CAAC;oBACX,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;gBACtB,CAAC;YACH,CAAC,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,GAAG,EAAE;gBACpC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBAChB,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;gBACtB,CAAC;YACH,CAAC,CAAC;SACH,CAAC;QACF,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;IAED,IAAI;QACF,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE;YACzC,WAAW,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;IAC1B,CAAC;IAED,6CAA6C;IAC7C,OAAO;QACL,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,QAAQ,CAAC;QACvB,CAAC;QACD,MAAM,IAAI,GAAkB,OAAO,CAAC,OAAO,EAAE;aAC1C,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;aAClC,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;gBAC3B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;YACvB,CAAC;QACH,CAAC,CAAC,CAAC;QACL,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gEAAgE;IAChE,eAAe;QACb,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,OAAO,IAAI,CAAC,QAAQ,CAAC;QACvB,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,IAAI,KAAK,GAAG,IAAI,CAAC;QACjB,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;YACnB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;YACD,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC;QAC9B,CAAC;IACH,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,GAAG,EAAE;YAChD,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;QACtB,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACtB,CAAC;IAEO,YAAY;QAClB,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC3B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;CACF"}
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@baukit/sync-client",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Client-side scheduling, transport, status reporting, and ordering for offline-capable sync loops.",
5
5
  "license": "MIT",
6
6
  "author": "Patrick Koss",
@@ -26,10 +26,18 @@
26
26
  "types": "./dist/index.d.ts",
27
27
  "import": "./dist/index.js"
28
28
  },
29
+ "./hlc": {
30
+ "types": "./dist/hlc.d.ts",
31
+ "import": "./dist/hlc.js"
32
+ },
29
33
  "./expo": {
30
34
  "types": "./dist/expo.d.ts",
31
35
  "import": "./dist/expo.js"
32
36
  },
37
+ "./browser": {
38
+ "types": "./dist/browser.d.ts",
39
+ "import": "./dist/browser.js"
40
+ },
33
41
  "./conformance": {
34
42
  "types": "./dist/conformance.d.ts",
35
43
  "import": "./dist/conformance.js"
@@ -40,13 +48,6 @@
40
48
  "README.md",
41
49
  "LICENSE"
42
50
  ],
43
- "scripts": {
44
- "build": "tsc -p tsconfig.json",
45
- "prepare": "pnpm run build",
46
- "test": "tsc -p tsconfig.exports.json && vitest run --config ../../vitest.config.ts",
47
- "lint": "eslint src --max-warnings=0",
48
- "format:check": "prettier --check src type-tests package.json tsconfig*.json"
49
- },
50
51
  "devDependencies": {
51
52
  "expo-network": "57.0.1",
52
53
  "react-native": "0.86.2",
@@ -64,5 +65,11 @@
64
65
  "react-native": {
65
66
  "optional": true
66
67
  }
68
+ },
69
+ "scripts": {
70
+ "build": "tsc -p tsconfig.json",
71
+ "test": "tsc -p tsconfig.exports.json && vitest run --config ../../vitest.config.ts",
72
+ "lint": "eslint src --max-warnings=0",
73
+ "format:check": "prettier --check src type-tests package.json tsconfig*.json"
67
74
  }
68
- }
75
+ }