@baukit/sync-client 0.1.2 → 0.2.1
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 +102 -12
- package/dist/conformance.d.ts +80 -0
- package/dist/conformance.d.ts.map +1 -0
- package/dist/conformance.js +251 -0
- package/dist/conformance.js.map +1 -0
- package/dist/error.d.ts +55 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +72 -1
- package/dist/error.js.map +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/push-batch.d.ts +11 -0
- package/dist/push-batch.d.ts.map +1 -1
- package/dist/push-batch.js +15 -0
- package/dist/push-batch.js.map +1 -1
- package/dist/store.d.ts +50 -10
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +95 -24
- package/dist/store.js.map +1 -1
- package/dist/transport.d.ts +33 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +91 -7
- package/dist/transport.js.map +1 -1
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -53,14 +53,20 @@ non-Expo consumers never import this subpath.
|
|
|
53
53
|
|
|
54
54
|
## Transport
|
|
55
55
|
|
|
56
|
-
The
|
|
57
|
-
|
|
56
|
+
The fetch-backed `SyncTransport` constructor wraps an injected `fetch` and auth header provider.
|
|
57
|
+
It classifies failures as follows:
|
|
58
58
|
|
|
59
|
-
- `SyncAuthError` for 401, never retryable
|
|
60
|
-
- `SyncPartitionMismatchError` when the body carries the configured partition-mismatch code
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
- `SyncAuthError` for 401, never retryable
|
|
60
|
+
- `SyncPartitionMismatchError` when the body carries the configured partition-mismatch code
|
|
61
|
+
- `SyncRateLimitError` for 429, always retryable and carrying `retryAt` plus the raw `retryAfter`
|
|
62
|
+
header
|
|
63
|
+
- `SyncNetworkError` when `fetch` or response-body reading fails, always retryable
|
|
64
|
+
- `SyncServerError` for other HTTP failures, retryable for 408 and 5xx
|
|
65
|
+
- `SyncPayloadCompatibilityError` when a successful response is not valid JSON, never retryable
|
|
66
|
+
|
|
67
|
+
`Retry-After` accepts integer delta seconds and HTTP dates. Missing, invalid, negative, and past
|
|
68
|
+
values use `now + retryAfterFallbackMs`. The default fallback is 60 seconds. Tests and products
|
|
69
|
+
with another policy can inject `now` and `retryAfterFallbackMs` in the fetch-backed constructor.
|
|
64
70
|
|
|
65
71
|
Auth headers resolve per attempt, so a token refreshed between retries is picked up. The
|
|
66
72
|
partition header is sent only when the caller passes a `partitionId`, and both its name and the
|
|
@@ -86,8 +92,8 @@ await transport.request('/api/v1/sync/push', {
|
|
|
86
92
|
|
|
87
93
|
This mode builds the relative path, query string, JSON body, and partition header, then delegates.
|
|
88
94
|
The request function owns decoding and errors, which keeps the product API client's existing auth
|
|
89
|
-
recovery intact.
|
|
90
|
-
|
|
95
|
+
recovery intact. Use the fetch-backed constructor when the product wants package-owned response
|
|
96
|
+
classification.
|
|
91
97
|
|
|
92
98
|
## Status store
|
|
93
99
|
|
|
@@ -99,13 +105,24 @@ wrong:
|
|
|
99
105
|
still reads `attention`;
|
|
100
106
|
- unsent work outranks a bare error, so a failed run with pending changes reads `pending`,
|
|
101
107
|
not `error`;
|
|
102
|
-
- the first run is the initial pull; later runs are settled activity
|
|
108
|
+
- the first run is the initial pull; later runs are settled activity;
|
|
109
|
+
- a failure updates `lastAttemptAt` without changing `lastSuccessAt` or clearing `pendingCount`.
|
|
110
|
+
|
|
111
|
+
Call `setSyncing(attemptAt)` when an attempt starts. `setIdle(successAt)` records a successful
|
|
112
|
+
attempt and clears work only after the product's success predicate passes. `setFailure` accepts
|
|
113
|
+
machine-readable metadata with one of these kinds: `auth`, `partition_mismatch`, `rate_limited`,
|
|
114
|
+
`network`, `server`, `payload_compatibility`, or `local_apply`. Product copy remains in the
|
|
115
|
+
separate `error` field.
|
|
116
|
+
|
|
117
|
+
Rate-limit metadata contains `retryAt`. Other retryable failures can pass `retryAt` in the
|
|
118
|
+
`SyncFailureUpdate` argument or call `setRetrying(retryAt)`. Snapshots expose both `retrying` and
|
|
119
|
+
`retryAt`, so a screen can distinguish scheduled retries and rate limits from an offline state.
|
|
103
120
|
|
|
104
121
|
`refreshRevision` increments whenever a run delivers a new authoritative snapshot.
|
|
105
122
|
`deriveLocalStoreReadiness` compares it against what a consumer has actually rendered, which is
|
|
106
123
|
how a cold start avoids flashing an empty state over data that is still arriving.
|
|
107
|
-
`deriveInitialSyncState` maps a snapshot onto
|
|
108
|
-
`
|
|
124
|
+
`deriveInitialSyncState` maps a snapshot onto `unknown`, `syncing`, `offline-cached`,
|
|
125
|
+
`sync-error-cached`, or `settled`. Only a first-run `network` failure maps to `offline-cached`.
|
|
109
126
|
|
|
110
127
|
The store is generic over its attention item and defaults to the existing
|
|
111
128
|
`{ entityType, entityId }` shape. This keeps one store API while allowing a product to retain the
|
|
@@ -127,7 +144,12 @@ For stores and screens that use API-style names, `toSnakeCaseSnapshot` returns a
|
|
|
127
144
|
```ts
|
|
128
145
|
const snapshot = toSnakeCaseSnapshot(status.getSnapshot());
|
|
129
146
|
|
|
147
|
+
snapshot.last_attempt_at;
|
|
148
|
+
snapshot.last_success_at;
|
|
130
149
|
snapshot.last_sync_at;
|
|
150
|
+
snapshot.failure;
|
|
151
|
+
snapshot.retrying;
|
|
152
|
+
snapshot.retry_at;
|
|
131
153
|
snapshot.pending_count;
|
|
132
154
|
snapshot.initial_pull_status;
|
|
133
155
|
snapshot.refresh_revision;
|
|
@@ -137,6 +159,29 @@ snapshot.security_block;
|
|
|
137
159
|
`status`, `error`, and `attention` keep their names. Attention items also keep their original
|
|
138
160
|
shape.
|
|
139
161
|
|
|
162
|
+
### Timestamp migration
|
|
163
|
+
|
|
164
|
+
`lastSyncAt` and `last_sync_at` are deprecated compatibility fields for one release cycle. They
|
|
165
|
+
are derived from `lastSuccessAt` and `last_success_at`. New code must not write or persist them as
|
|
166
|
+
attempt timestamps.
|
|
167
|
+
|
|
168
|
+
Replace `snapshot.lastSyncAt` with `snapshot.lastSuccessAt`. Replace `snapshot.last_sync_at` with
|
|
169
|
+
`snapshot.last_success_at`. Persist both attempt and success timestamps, then hydrate with an
|
|
170
|
+
object:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
status.hydrate({
|
|
174
|
+
lastAttemptAt: persisted.lastAttemptAt,
|
|
175
|
+
lastSuccessAt: persisted.lastSuccessAt,
|
|
176
|
+
attention: persisted.attention,
|
|
177
|
+
pendingCount: persisted.pendingCount,
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
The deprecated `hydrate(lastSyncAt, attention, pendingCount)` overload treats the old value as
|
|
182
|
+
both the last attempt and last success. Remove that overload call when the persisted schema has
|
|
183
|
+
both fields.
|
|
184
|
+
|
|
140
185
|
## Push batch ranking
|
|
141
186
|
|
|
142
187
|
`rankPushBatch` orders one push batch so a parent is never sent after its children.
|
|
@@ -163,3 +208,48 @@ missing. Held-back entities do not consume batch-size slots.
|
|
|
163
208
|
|
|
164
209
|
Entity names, the dependency order, and the hold-back predicate are all product inputs. Baukit
|
|
165
210
|
knows only that a rank exists.
|
|
211
|
+
|
|
212
|
+
## Payload validators
|
|
213
|
+
|
|
214
|
+
Call `validatePushOutcomeCoverage` before acknowledging any submitted change. Pass one key reader
|
|
215
|
+
for submitted entities and one for outcomes, then combine all accepted and rejected outcomes in
|
|
216
|
+
the second argument. The function throws `SyncPayloadCompatibilityError` if any submitted entity
|
|
217
|
+
has no outcome.
|
|
218
|
+
|
|
219
|
+
Call `validatePullPage(currentCursor, page, compare)` before following `hasMore`. Cursors are
|
|
220
|
+
opaque. The injected comparator defines their order. A regressing cursor, a non-finite comparison,
|
|
221
|
+
or `hasMore` without cursor progress throws `SyncPayloadCompatibilityError`.
|
|
222
|
+
|
|
223
|
+
`commitCursorAfterLocalTransaction` runs the supplied local transaction first. It invokes
|
|
224
|
+
`commitCursor` only after that promise resolves, and wraps local failures in `SyncLocalApplyError`.
|
|
225
|
+
This ordering prevents a failed local apply from skipping remote changes on the next pull.
|
|
226
|
+
|
|
227
|
+
## Conformance harness
|
|
228
|
+
|
|
229
|
+
`@baukit/sync-client/conformance` exports `createSyncConformanceTests`. It returns plain async test
|
|
230
|
+
cases and has no Vitest or Jest dependency. Register the returned cases with the runner already in
|
|
231
|
+
the product:
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
import { createSyncConformanceTests } from '@baukit/sync-client/conformance';
|
|
235
|
+
|
|
236
|
+
describe('product sync contract', () => {
|
|
237
|
+
for (const testCase of createSyncConformanceTests(productAdapter)) {
|
|
238
|
+
it(testCase.name, testCase.run);
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
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.
|
|
249
|
+
|
|
250
|
+
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.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export type SyncConformanceOperation = 'upsert' | 'delete';
|
|
2
|
+
export type SyncConformancePushFailure = 'network' | 'server';
|
|
3
|
+
export type SyncConformancePullFault = 'regress' | 'stall';
|
|
4
|
+
export interface SyncConformanceEntityRef {
|
|
5
|
+
entityType: string;
|
|
6
|
+
entityId: string;
|
|
7
|
+
}
|
|
8
|
+
export interface SyncConformanceChange extends SyncConformanceEntityRef {
|
|
9
|
+
changeId: string;
|
|
10
|
+
operation: SyncConformanceOperation;
|
|
11
|
+
value: string | null;
|
|
12
|
+
logicalTime: number;
|
|
13
|
+
dependsOn?: SyncConformanceEntityRef;
|
|
14
|
+
}
|
|
15
|
+
export interface SyncConformanceRow extends SyncConformanceEntityRef {
|
|
16
|
+
value: string | null;
|
|
17
|
+
logicalTime: number;
|
|
18
|
+
deleted: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface SyncConformanceRejection extends SyncConformanceEntityRef {
|
|
21
|
+
reason: string;
|
|
22
|
+
}
|
|
23
|
+
export interface SyncConformancePullPage<TChange, TCursor> {
|
|
24
|
+
changes: readonly TChange[];
|
|
25
|
+
nextCursor: TCursor;
|
|
26
|
+
hasMore: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface SyncConformancePushResult<TPending> {
|
|
29
|
+
acknowledged: readonly TPending[];
|
|
30
|
+
rejected: readonly SyncConformanceRejection[];
|
|
31
|
+
}
|
|
32
|
+
export interface SyncConformancePendingState {
|
|
33
|
+
pending: boolean;
|
|
34
|
+
pendingCount: number;
|
|
35
|
+
}
|
|
36
|
+
export interface SyncConformanceLocalApplyOptions {
|
|
37
|
+
failAfterChanges?: number;
|
|
38
|
+
}
|
|
39
|
+
export interface SyncConformanceScenario<TClient, TServer> {
|
|
40
|
+
clients: readonly [TClient, TClient];
|
|
41
|
+
server: TServer;
|
|
42
|
+
}
|
|
43
|
+
export interface SyncConformanceAdapter<TClient, TServer, TPending, TPushRequest, TPushResponse, TPullResponse, TRemoteChange, TCursor> {
|
|
44
|
+
createScenario(): Promise<SyncConformanceScenario<TClient, TServer>> | SyncConformanceScenario<TClient, TServer>;
|
|
45
|
+
disposeScenario?(scenario: SyncConformanceScenario<TClient, TServer>): Promise<void> | void;
|
|
46
|
+
outbox: {
|
|
47
|
+
enqueue(client: TClient, change: SyncConformanceChange): Promise<void> | void;
|
|
48
|
+
listPending(client: TClient): Promise<readonly TPending[]> | readonly TPending[];
|
|
49
|
+
markAcknowledged(client: TClient, pending: readonly TPending[]): Promise<void> | void;
|
|
50
|
+
recordRejected(client: TClient, rejected: readonly SyncConformanceRejection[]): Promise<void> | void;
|
|
51
|
+
listRejected(client: TClient): Promise<readonly SyncConformanceRejection[]> | readonly SyncConformanceRejection[];
|
|
52
|
+
};
|
|
53
|
+
local: {
|
|
54
|
+
readCursor(client: TClient): Promise<TCursor> | TCursor;
|
|
55
|
+
applyPullPage(client: TClient, page: SyncConformancePullPage<TRemoteChange, TCursor>, options?: SyncConformanceLocalApplyOptions): Promise<void> | void;
|
|
56
|
+
snapshot(client: TClient): Promise<readonly SyncConformanceRow[]> | readonly SyncConformanceRow[];
|
|
57
|
+
readPendingState(client: TClient): Promise<SyncConformancePendingState> | SyncConformancePendingState;
|
|
58
|
+
};
|
|
59
|
+
wire: {
|
|
60
|
+
encodePush(pending: readonly TPending[]): Promise<TPushRequest> | TPushRequest;
|
|
61
|
+
decodePush(response: TPushResponse, submitted: readonly TPending[]): Promise<SyncConformancePushResult<TPending>> | SyncConformancePushResult<TPending>;
|
|
62
|
+
decodePull(response: TPullResponse): Promise<SyncConformancePullPage<TRemoteChange, TCursor>> | SyncConformancePullPage<TRemoteChange, TCursor>;
|
|
63
|
+
compareCursors(left: TCursor, right: TCursor): number;
|
|
64
|
+
};
|
|
65
|
+
server: {
|
|
66
|
+
acceptPush(server: TServer, request: TPushRequest): Promise<TPushResponse>;
|
|
67
|
+
servePull(server: TServer, cursor: TCursor, pageSize: number): Promise<TPullResponse>;
|
|
68
|
+
seed(server: TServer, change: SyncConformanceChange): Promise<void> | void;
|
|
69
|
+
snapshot(server: TServer): Promise<readonly SyncConformanceRow[]> | readonly SyncConformanceRow[];
|
|
70
|
+
failNextPush(server: TServer, failure: SyncConformancePushFailure): Promise<void> | void;
|
|
71
|
+
omitNextPushOutcome(server: TServer): Promise<void> | void;
|
|
72
|
+
faultNextPull(server: TServer, fault: SyncConformancePullFault): Promise<void> | void;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export interface SyncConformanceTestCase {
|
|
76
|
+
readonly name: string;
|
|
77
|
+
readonly run: () => Promise<void>;
|
|
78
|
+
}
|
|
79
|
+
export declare function createSyncConformanceTests<TClient, TServer, TPending, TPushRequest, TPushResponse, TPullResponse, TRemoteChange, TCursor>(adapter: SyncConformanceAdapter<TClient, TServer, TPending, TPushRequest, TPushResponse, TPullResponse, TRemoteChange, TCursor>): readonly SyncConformanceTestCase[];
|
|
80
|
+
//# sourceMappingURL=conformance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conformance.d.ts","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { validatePullPage } from './transport.js';
|
|
2
|
+
const PAGE_SIZE = 2;
|
|
3
|
+
const parentChange = {
|
|
4
|
+
changeId: 'change-parent',
|
|
5
|
+
entityType: 'container',
|
|
6
|
+
entityId: 'parent',
|
|
7
|
+
operation: 'upsert',
|
|
8
|
+
value: 'parent value',
|
|
9
|
+
logicalTime: 10,
|
|
10
|
+
};
|
|
11
|
+
const childChange = {
|
|
12
|
+
changeId: 'change-child',
|
|
13
|
+
entityType: 'item',
|
|
14
|
+
entityId: 'child',
|
|
15
|
+
operation: 'upsert',
|
|
16
|
+
value: 'child value',
|
|
17
|
+
logicalTime: 11,
|
|
18
|
+
dependsOn: { entityType: 'container', entityId: 'parent' },
|
|
19
|
+
};
|
|
20
|
+
function change(changeId, entityId, logicalTime, value) {
|
|
21
|
+
return {
|
|
22
|
+
changeId,
|
|
23
|
+
entityType: 'record',
|
|
24
|
+
entityId,
|
|
25
|
+
operation: 'upsert',
|
|
26
|
+
value,
|
|
27
|
+
logicalTime,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function tombstone(changeId, entityId, logicalTime) {
|
|
31
|
+
return {
|
|
32
|
+
changeId,
|
|
33
|
+
entityType: 'record',
|
|
34
|
+
entityId,
|
|
35
|
+
operation: 'delete',
|
|
36
|
+
value: null,
|
|
37
|
+
logicalTime,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function fail(message) {
|
|
41
|
+
throw new Error(`Sync conformance failed: ${message}`);
|
|
42
|
+
}
|
|
43
|
+
function assert(condition, message) {
|
|
44
|
+
if (!condition)
|
|
45
|
+
fail(message);
|
|
46
|
+
}
|
|
47
|
+
function sortedRows(rows) {
|
|
48
|
+
return [...rows].sort((left, right) => left.entityType.localeCompare(right.entityType) ||
|
|
49
|
+
left.entityId.localeCompare(right.entityId));
|
|
50
|
+
}
|
|
51
|
+
function sameRows(left, right) {
|
|
52
|
+
return JSON.stringify(sortedRows(left)) === JSON.stringify(sortedRows(right));
|
|
53
|
+
}
|
|
54
|
+
async function expectFailure(run, message) {
|
|
55
|
+
try {
|
|
56
|
+
await run();
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
fail(message);
|
|
62
|
+
}
|
|
63
|
+
export function createSyncConformanceTests(adapter) {
|
|
64
|
+
async function inScenario(run) {
|
|
65
|
+
const scenario = await adapter.createScenario();
|
|
66
|
+
const [clientA, clientB] = scenario.clients;
|
|
67
|
+
try {
|
|
68
|
+
await run({ clientA, clientB, server: scenario.server });
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
await adapter.disposeScenario?.(scenario);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async function pending(client) {
|
|
75
|
+
return adapter.outbox.listPending(client);
|
|
76
|
+
}
|
|
77
|
+
async function assertPendingState(client, expectedCount) {
|
|
78
|
+
const actual = await pending(client);
|
|
79
|
+
const reported = await adapter.local.readPendingState(client);
|
|
80
|
+
assert(actual.length === expectedCount, `expected ${String(expectedCount)} pending changes`);
|
|
81
|
+
assert(reported.pendingCount === actual.length, 'reported pending count differs from the outbox');
|
|
82
|
+
assert(reported.pending === actual.length > 0, 'reported pending flag differs from the outbox');
|
|
83
|
+
}
|
|
84
|
+
async function push(client, server) {
|
|
85
|
+
const submitted = await pending(client);
|
|
86
|
+
if (submitted.length === 0)
|
|
87
|
+
return;
|
|
88
|
+
const request = await adapter.wire.encodePush(submitted);
|
|
89
|
+
const response = await adapter.server.acceptPush(server, request);
|
|
90
|
+
const outcome = await adapter.wire.decodePush(response, submitted);
|
|
91
|
+
await adapter.outbox.markAcknowledged(client, outcome.acknowledged);
|
|
92
|
+
await adapter.outbox.recordRejected(client, outcome.rejected);
|
|
93
|
+
}
|
|
94
|
+
async function pullPage(client, server, options) {
|
|
95
|
+
const cursor = (await adapter.local.readCursor(client));
|
|
96
|
+
const response = await adapter.server.servePull(server, cursor, PAGE_SIZE);
|
|
97
|
+
const page = await adapter.wire.decodePull(response);
|
|
98
|
+
validatePullPage(cursor, page, (left, right) => adapter.wire.compareCursors(left, right));
|
|
99
|
+
await adapter.local.applyPullPage(client, page, options);
|
|
100
|
+
return page.hasMore;
|
|
101
|
+
}
|
|
102
|
+
async function pullAll(client, server) {
|
|
103
|
+
let hasMore = true;
|
|
104
|
+
while (hasMore)
|
|
105
|
+
hasMore = await pullPage(client, server);
|
|
106
|
+
}
|
|
107
|
+
return [
|
|
108
|
+
{
|
|
109
|
+
name: 'replayed pushes create one server change',
|
|
110
|
+
run: () => inScenario(async ({ clientA, server }) => {
|
|
111
|
+
await adapter.outbox.enqueue(clientA, change('change-replay', 'replay', 10, 'once'));
|
|
112
|
+
const submitted = await pending(clientA);
|
|
113
|
+
const request = await adapter.wire.encodePush(submitted);
|
|
114
|
+
const first = await adapter.server.acceptPush(server, request);
|
|
115
|
+
const second = await adapter.server.acceptPush(server, request);
|
|
116
|
+
await adapter.wire.decodePush(first, submitted);
|
|
117
|
+
await adapter.wire.decodePush(second, submitted);
|
|
118
|
+
const rows = (await adapter.server.snapshot(server)).filter((row) => row.entityType === 'record' && row.entityId === 'replay');
|
|
119
|
+
assert(rows.length === 1, 'replay created a duplicate server row');
|
|
120
|
+
}),
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: 'an interrupted local transaction preserves data, cursor, and pending work',
|
|
124
|
+
run: () => inScenario(async ({ clientA, server }) => {
|
|
125
|
+
await adapter.outbox.enqueue(clientA, change('change-pending', 'pending', 30, 'local'));
|
|
126
|
+
await adapter.server.seed(server, change('seed-first', 'first', 10, 'remote first'));
|
|
127
|
+
await adapter.server.seed(server, change('seed-second', 'second', 20, 'remote second'));
|
|
128
|
+
const cursorBefore = await adapter.local.readCursor(clientA);
|
|
129
|
+
const rowsBefore = await adapter.local.snapshot(clientA);
|
|
130
|
+
await expectFailure(() => pullPage(clientA, server, { failAfterChanges: 1 }).then(() => undefined), 'local apply failure resolved successfully');
|
|
131
|
+
const cursorAfter = await adapter.local.readCursor(clientA);
|
|
132
|
+
const rowsAfter = await adapter.local.snapshot(clientA);
|
|
133
|
+
assert(adapter.wire.compareCursors(cursorAfter, cursorBefore) === 0, 'local apply failure advanced the cursor');
|
|
134
|
+
assert(sameRows(rowsAfter, rowsBefore), 'local apply failure committed part of the page');
|
|
135
|
+
await assertPendingState(clientA, 1);
|
|
136
|
+
}),
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: 'pull cursors advance monotonically across pages',
|
|
140
|
+
run: () => inScenario(async ({ clientA, server }) => {
|
|
141
|
+
await adapter.server.seed(server, change('seed-one', 'one', 10, 'one'));
|
|
142
|
+
await adapter.server.seed(server, change('seed-two', 'two', 20, 'two'));
|
|
143
|
+
await adapter.server.seed(server, change('seed-three', 'three', 30, 'three'));
|
|
144
|
+
const start = await adapter.local.readCursor(clientA);
|
|
145
|
+
await pullAll(clientA, server);
|
|
146
|
+
const end = await adapter.local.readCursor(clientA);
|
|
147
|
+
assert(adapter.wire.compareCursors(end, start) > 0, 'pull did not advance the cursor');
|
|
148
|
+
assert(sameRows(await adapter.local.snapshot(clientA), await adapter.server.snapshot(server)), 'paged pull skipped or duplicated server state');
|
|
149
|
+
}),
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: 'a regressing pull cursor is rejected before local apply',
|
|
153
|
+
run: () => inScenario(async ({ clientA, server }) => {
|
|
154
|
+
await adapter.server.seed(server, change('seed-regress', 'regress', 10, 'remote'));
|
|
155
|
+
await pullAll(clientA, server);
|
|
156
|
+
const cursor = await adapter.local.readCursor(clientA);
|
|
157
|
+
const rows = await adapter.local.snapshot(clientA);
|
|
158
|
+
await adapter.server.faultNextPull(server, 'regress');
|
|
159
|
+
await expectFailure(() => pullPage(clientA, server).then(() => undefined), 'regressing cursor was accepted');
|
|
160
|
+
assert(adapter.wire.compareCursors(await adapter.local.readCursor(clientA), cursor) === 0, 'regressing page changed the cursor');
|
|
161
|
+
assert(sameRows(await adapter.local.snapshot(clientA), rows), 'regressing page changed data');
|
|
162
|
+
}),
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
name: 'hasMore requires cursor progress',
|
|
166
|
+
run: () => inScenario(async ({ clientA, server }) => {
|
|
167
|
+
const cursor = await adapter.local.readCursor(clientA);
|
|
168
|
+
await adapter.server.faultNextPull(server, 'stall');
|
|
169
|
+
await expectFailure(() => pullPage(clientA, server).then(() => undefined), 'hasMore without cursor progress was accepted');
|
|
170
|
+
assert(adapter.wire.compareCursors(await adapter.local.readCursor(clientA), cursor) === 0, 'stalled page changed the cursor');
|
|
171
|
+
}),
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
name: 'partial push outcomes are rejected before acknowledgement',
|
|
175
|
+
run: () => inScenario(async ({ clientA, server }) => {
|
|
176
|
+
await adapter.outbox.enqueue(clientA, change('change-covered-a', 'covered-a', 10, 'a'));
|
|
177
|
+
await adapter.outbox.enqueue(clientA, change('change-covered-b', 'covered-b', 20, 'b'));
|
|
178
|
+
await adapter.server.omitNextPushOutcome(server);
|
|
179
|
+
await expectFailure(() => push(clientA, server), 'partial push outcomes were accepted');
|
|
180
|
+
await assertPendingState(clientA, 2);
|
|
181
|
+
}),
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: 'network failure keeps pending state truthful',
|
|
185
|
+
run: () => inScenario(async ({ clientA, server }) => {
|
|
186
|
+
await adapter.outbox.enqueue(clientA, change('change-network', 'network', 10, 'local'));
|
|
187
|
+
await adapter.server.failNextPush(server, 'network');
|
|
188
|
+
await expectFailure(() => push(clientA, server), 'network failure resolved successfully');
|
|
189
|
+
await assertPendingState(clientA, 1);
|
|
190
|
+
}),
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
name: 'server failure keeps pending state truthful',
|
|
194
|
+
run: () => inScenario(async ({ clientA, server }) => {
|
|
195
|
+
await adapter.outbox.enqueue(clientA, change('change-server', 'server', 10, 'local'));
|
|
196
|
+
await adapter.server.failNextPush(server, 'server');
|
|
197
|
+
await expectFailure(() => push(clientA, server), 'server failure resolved successfully');
|
|
198
|
+
await assertPendingState(clientA, 1);
|
|
199
|
+
}),
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
name: 'complete rejection outcomes are recorded without hidden pending work',
|
|
203
|
+
run: () => inScenario(async ({ clientA, server }) => {
|
|
204
|
+
await adapter.server.seed(server, change('seed-newer', 'rejected', 20, 'server'));
|
|
205
|
+
await adapter.outbox.enqueue(clientA, change('change-older', 'rejected', 10, 'local'));
|
|
206
|
+
await push(clientA, server);
|
|
207
|
+
await assertPendingState(clientA, 0);
|
|
208
|
+
const rejected = await adapter.outbox.listRejected(clientA);
|
|
209
|
+
assert(rejected.length === 1, 'actionable rejection was not recorded');
|
|
210
|
+
assert(rejected[0]?.entityId === 'rejected', 'wrong rejection was recorded');
|
|
211
|
+
}),
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
name: 'pushes referenced records before dependent records',
|
|
215
|
+
run: () => inScenario(async ({ clientA, server }) => {
|
|
216
|
+
await adapter.outbox.enqueue(clientA, childChange);
|
|
217
|
+
await adapter.outbox.enqueue(clientA, parentChange);
|
|
218
|
+
await push(clientA, server);
|
|
219
|
+
await assertPendingState(clientA, 0);
|
|
220
|
+
const rows = await adapter.server.snapshot(server);
|
|
221
|
+
assert(rows.some((row) => row.entityType === 'container' && row.entityId === 'parent'), 'referenced record did not reach the server');
|
|
222
|
+
assert(rows.some((row) => row.entityType === 'item' && row.entityId === 'child'), 'dependent record was rejected because push order was unsafe');
|
|
223
|
+
}),
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
name: 'two clients converge after alternating sync, including a tombstone',
|
|
227
|
+
run: () => inScenario(async ({ clientA, clientB, server }) => {
|
|
228
|
+
await adapter.outbox.enqueue(clientA, change('change-a', 'alpha', 10, 'from A'));
|
|
229
|
+
await adapter.outbox.enqueue(clientB, change('change-b', 'beta', 20, 'from B'));
|
|
230
|
+
await push(clientA, server);
|
|
231
|
+
await pullAll(clientB, server);
|
|
232
|
+
await push(clientB, server);
|
|
233
|
+
await pullAll(clientA, server);
|
|
234
|
+
await adapter.outbox.enqueue(clientB, tombstone('change-delete', 'alpha', 30));
|
|
235
|
+
await push(clientB, server);
|
|
236
|
+
await pullAll(clientA, server);
|
|
237
|
+
await pullAll(clientB, server);
|
|
238
|
+
const rowsA = await adapter.local.snapshot(clientA);
|
|
239
|
+
const rowsB = await adapter.local.snapshot(clientB);
|
|
240
|
+
const serverRows = await adapter.server.snapshot(server);
|
|
241
|
+
assert(sameRows(rowsA, rowsB), 'clients did not converge to the same state');
|
|
242
|
+
assert(sameRows(rowsA, serverRows), 'clients did not converge to server state');
|
|
243
|
+
const deleted = rowsA.find((row) => row.entityType === 'record' && row.entityId === 'alpha');
|
|
244
|
+
assert(deleted?.deleted === true, 'tombstone did not converge');
|
|
245
|
+
await assertPendingState(clientA, 0);
|
|
246
|
+
await assertPendingState(clientB, 0);
|
|
247
|
+
}),
|
|
248
|
+
},
|
|
249
|
+
];
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=conformance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conformance.js","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"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"}
|
package/dist/error.d.ts
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
/** Machine-readable failure metadata. Products own any message shown to users. */
|
|
2
|
+
export type SyncFailure = {
|
|
3
|
+
readonly kind: 'auth';
|
|
4
|
+
} | {
|
|
5
|
+
readonly kind: 'partition_mismatch';
|
|
6
|
+
} | {
|
|
7
|
+
readonly kind: 'rate_limited';
|
|
8
|
+
readonly retryAt: string;
|
|
9
|
+
} | {
|
|
10
|
+
readonly kind: 'network';
|
|
11
|
+
} | {
|
|
12
|
+
readonly kind: 'server';
|
|
13
|
+
} | {
|
|
14
|
+
readonly kind: 'payload_compatibility';
|
|
15
|
+
} | {
|
|
16
|
+
readonly kind: 'local_apply';
|
|
17
|
+
};
|
|
18
|
+
/** Snake-case projection of {@link SyncFailure}. */
|
|
19
|
+
export type SnakeCaseSyncFailure = Exclude<SyncFailure, {
|
|
20
|
+
readonly kind: 'rate_limited';
|
|
21
|
+
}> | {
|
|
22
|
+
readonly kind: 'rate_limited';
|
|
23
|
+
readonly retry_at: string;
|
|
24
|
+
};
|
|
1
25
|
/** A sync request failed. `retryable` decides whether a later attempt may win. */
|
|
2
26
|
export declare class SyncTransportError extends Error {
|
|
3
27
|
readonly retryable: boolean;
|
|
@@ -9,12 +33,42 @@ export declare class SyncAuthError extends SyncTransportError {
|
|
|
9
33
|
readonly kind = "auth";
|
|
10
34
|
constructor(message: string, cause?: unknown);
|
|
11
35
|
}
|
|
36
|
+
/** The request did not reach a usable HTTP response. */
|
|
37
|
+
export declare class SyncNetworkError extends SyncTransportError {
|
|
38
|
+
readonly kind = "network";
|
|
39
|
+
constructor(message: string, cause?: unknown);
|
|
40
|
+
}
|
|
41
|
+
/** The server returned an HTTP failure other than authentication or rate limiting. */
|
|
42
|
+
export declare class SyncServerError extends SyncTransportError {
|
|
43
|
+
readonly kind = "server";
|
|
44
|
+
constructor(message: string, retryable: boolean, cause?: unknown);
|
|
45
|
+
}
|
|
46
|
+
/** HTTP 429 with its raw `Retry-After` value and resolved retry time. */
|
|
47
|
+
export declare class SyncRateLimitError extends SyncTransportError {
|
|
48
|
+
readonly retryAt: string;
|
|
49
|
+
readonly retryAfter: string | null;
|
|
50
|
+
readonly kind = "rate_limited";
|
|
51
|
+
constructor(message: string, retryAt: string, retryAfter: string | null, cause?: unknown);
|
|
52
|
+
}
|
|
12
53
|
/**
|
|
13
54
|
* The server rejected the caller's local-data partition, so the local database
|
|
14
55
|
* belongs to an erased or replaced owner and must not be reused.
|
|
15
56
|
*/
|
|
16
57
|
export declare class SyncPartitionMismatchError extends SyncTransportError {
|
|
17
|
-
readonly kind = "
|
|
58
|
+
readonly kind = "partition_mismatch";
|
|
59
|
+
constructor(message: string, cause?: unknown);
|
|
60
|
+
}
|
|
61
|
+
/** A decoded response violates the sync payload contract. */
|
|
62
|
+
export declare class SyncPayloadCompatibilityError extends SyncTransportError {
|
|
63
|
+
readonly kind = "payload_compatibility";
|
|
64
|
+
constructor(message: string, cause?: unknown);
|
|
65
|
+
}
|
|
66
|
+
/** Remote data or a cursor could not be committed to local storage. */
|
|
67
|
+
export declare class SyncLocalApplyError extends Error {
|
|
68
|
+
readonly kind = "local_apply";
|
|
18
69
|
constructor(message: string, cause?: unknown);
|
|
19
70
|
}
|
|
71
|
+
/** Maps package errors onto store failure metadata. */
|
|
72
|
+
export declare function syncFailureFromError(error: unknown): SyncFailure;
|
|
73
|
+
export declare function toSnakeCaseFailure(failure: SyncFailure): SnakeCaseSyncFailure;
|
|
20
74
|
//# sourceMappingURL=error.d.ts.map
|
package/dist/error.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,qBAAa,kBAAmB,SAAQ,KAAK;IAGzC,QAAQ,CAAC,SAAS,EAAE,OAAO;aACT,KAAK,CAAC,EAAE,OAAO;gBAFjC,OAAO,EAAE,MAAM,EACN,SAAS,EAAE,OAAO,EACT,KAAK,CAAC,EAAE,OAAO,YAAA;CAKpC;AAED,4EAA4E;AAC5E,qBAAa,aAAc,SAAQ,kBAAkB;IACnD,QAAQ,CAAC,IAAI,UAAU;gBAEX,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAI7C;AAED;;;GAGG;AACH,qBAAa,0BAA2B,SAAQ,kBAAkB;IAChE,QAAQ,CAAC,IAAI,wBAAwB;gBAEzB,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAI7C"}
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAA;CAAE,GACvC;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAA;CAAE,GAC1C;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAErC,oDAAoD;AACpD,MAAM,MAAM,oBAAoB,GAC5B,OAAO,CAAC,WAAW,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAAE,CAAC,GACvD;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjE,kFAAkF;AAClF,qBAAa,kBAAmB,SAAQ,KAAK;IAGzC,QAAQ,CAAC,SAAS,EAAE,OAAO;aACT,KAAK,CAAC,EAAE,OAAO;gBAFjC,OAAO,EAAE,MAAM,EACN,SAAS,EAAE,OAAO,EACT,KAAK,CAAC,EAAE,OAAO,YAAA;CAKpC;AAED,4EAA4E;AAC5E,qBAAa,aAAc,SAAQ,kBAAkB;IACnD,QAAQ,CAAC,IAAI,UAAU;gBAEX,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAI7C;AAED,wDAAwD;AACxD,qBAAa,gBAAiB,SAAQ,kBAAkB;IACtD,QAAQ,CAAC,IAAI,aAAa;gBAEd,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAI7C;AAED,sFAAsF;AACtF,qBAAa,eAAgB,SAAQ,kBAAkB;IACrD,QAAQ,CAAC,IAAI,YAAY;gBAEb,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO;CAIjE;AAED,yEAAyE;AACzE,qBAAa,kBAAmB,SAAQ,kBAAkB;IAKtD,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IALpC,QAAQ,CAAC,IAAI,kBAAkB;gBAG7B,OAAO,EAAE,MAAM,EACN,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GAAG,IAAI,EAClC,KAAK,CAAC,EAAE,OAAO;CAKlB;AAED;;;GAGG;AACH,qBAAa,0BAA2B,SAAQ,kBAAkB;IAChE,QAAQ,CAAC,IAAI,wBAAwB;gBAEzB,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAI7C;AAED,6DAA6D;AAC7D,qBAAa,6BAA8B,SAAQ,kBAAkB;IACnE,QAAQ,CAAC,IAAI,2BAA2B;gBAE5B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAI7C;AAED,uEAAuE;AACvE,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,iBAAiB;gBAElB,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAI7C;AAED,uDAAuD;AACvD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAchE;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,oBAAoB,CAI7E"}
|