@interop/was-react 0.20.1 → 0.21.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.
Files changed (94) hide show
  1. package/README.md +8 -2
  2. package/dist/dev/provisionDevGrants.js +1 -1
  3. package/dist/dev/provisionDevGrants.js.map +1 -1
  4. package/dist/index.d.ts +2 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +9 -2
  7. package/dist/index.js.map +1 -1
  8. package/dist/session/authStore.js +1 -1
  9. package/dist/session/authStore.js.map +1 -1
  10. package/dist/storage/adopt.d.ts.map +1 -1
  11. package/dist/storage/adopt.js +2 -1
  12. package/dist/storage/adopt.js.map +1 -1
  13. package/dist/{sync → storage}/docCipher.d.ts +3 -29
  14. package/dist/storage/docCipher.d.ts.map +1 -0
  15. package/dist/{sync → storage}/docCipher.js +0 -20
  16. package/dist/storage/docCipher.js.map +1 -0
  17. package/dist/storage/entityStore.d.ts.map +1 -1
  18. package/dist/storage/entityStore.js +2 -1
  19. package/dist/storage/entityStore.js.map +1 -1
  20. package/dist/storage/localStore.d.ts +1 -1
  21. package/dist/storage/localStore.d.ts.map +1 -1
  22. package/dist/storage/localStore.js +14 -2
  23. package/dist/storage/localStore.js.map +1 -1
  24. package/dist/storage/sharedCollectionReader.d.ts +1 -1
  25. package/dist/storage/sharedCollectionReader.d.ts.map +1 -1
  26. package/dist/storage/sharedCollectionReader.js +1 -1
  27. package/dist/storage/sharedCollectionReader.js.map +1 -1
  28. package/dist/storage/storageContext.d.ts +1 -2
  29. package/dist/storage/storageContext.d.ts.map +1 -1
  30. package/dist/storage/storageContext.js.map +1 -1
  31. package/dist/storage/storageManager.d.ts +1 -1
  32. package/dist/storage/storageManager.d.ts.map +1 -1
  33. package/dist/storage/syncController.d.ts +30 -19
  34. package/dist/storage/syncController.d.ts.map +1 -1
  35. package/dist/storage/syncController.js +84 -157
  36. package/dist/storage/syncController.js.map +1 -1
  37. package/dist/storage/syncStatusStore.d.ts +8 -7
  38. package/dist/storage/syncStatusStore.d.ts.map +1 -1
  39. package/dist/storage/syncStatusStore.js.map +1 -1
  40. package/dist/storage/wasRemoteStore.js +1 -1
  41. package/dist/storage/wasRemoteStore.js.map +1 -1
  42. package/dist/storage/wasSync.d.ts +1 -1
  43. package/dist/storage/wasSync.d.ts.map +1 -1
  44. package/dist/storage/wasSync.js +1 -1
  45. package/dist/storage/wasSync.js.map +1 -1
  46. package/dist/{sync → storage}/wasSyncPort.d.ts +14 -8
  47. package/dist/storage/wasSyncPort.d.ts.map +1 -0
  48. package/dist/storage/wasSyncPort.js.map +1 -0
  49. package/dist/storage/writerId.d.ts +7 -13
  50. package/dist/storage/writerId.d.ts.map +1 -1
  51. package/dist/storage/writerId.js +30 -46
  52. package/dist/storage/writerId.js.map +1 -1
  53. package/package.json +13 -10
  54. package/dist/sync/changesQuery.d.ts +0 -44
  55. package/dist/sync/changesQuery.d.ts.map +0 -1
  56. package/dist/sync/changesQuery.js +0 -54
  57. package/dist/sync/changesQuery.js.map +0 -1
  58. package/dist/sync/docCipher.d.ts.map +0 -1
  59. package/dist/sync/docCipher.js.map +0 -1
  60. package/dist/sync/feedMasterPort.d.ts +0 -38
  61. package/dist/sync/feedMasterPort.d.ts.map +0 -1
  62. package/dist/sync/feedMasterPort.js +0 -116
  63. package/dist/sync/feedMasterPort.js.map +0 -1
  64. package/dist/sync/index.d.ts +0 -23
  65. package/dist/sync/index.d.ts.map +0 -1
  66. package/dist/sync/index.js +0 -27
  67. package/dist/sync/index.js.map +0 -1
  68. package/dist/sync/lww.d.ts +0 -50
  69. package/dist/sync/lww.d.ts.map +0 -1
  70. package/dist/sync/lww.js +0 -69
  71. package/dist/sync/lww.js.map +0 -1
  72. package/dist/sync/lwwConflictHandler.d.ts +0 -83
  73. package/dist/sync/lwwConflictHandler.d.ts.map +0 -1
  74. package/dist/sync/lwwConflictHandler.js +0 -114
  75. package/dist/sync/lwwConflictHandler.js.map +0 -1
  76. package/dist/sync/pushWrites.d.ts +0 -76
  77. package/dist/sync/pushWrites.d.ts.map +0 -1
  78. package/dist/sync/pushWrites.js +0 -221
  79. package/dist/sync/pushWrites.js.map +0 -1
  80. package/dist/sync/syncedDocSchema.d.ts +0 -22
  81. package/dist/sync/syncedDocSchema.d.ts.map +0 -1
  82. package/dist/sync/syncedDocSchema.js +0 -29
  83. package/dist/sync/syncedDocSchema.js.map +0 -1
  84. package/dist/sync/types.d.ts +0 -319
  85. package/dist/sync/types.d.ts.map +0 -1
  86. package/dist/sync/types.js +0 -58
  87. package/dist/sync/types.js.map +0 -1
  88. package/dist/sync/wasReplication.d.ts +0 -47
  89. package/dist/sync/wasReplication.d.ts.map +0 -1
  90. package/dist/sync/wasReplication.js +0 -92
  91. package/dist/sync/wasReplication.js.map +0 -1
  92. package/dist/sync/wasSyncPort.d.ts.map +0 -1
  93. package/dist/sync/wasSyncPort.js.map +0 -1
  94. /package/dist/{sync → storage}/wasSyncPort.js +0 -0
@@ -1,221 +0,0 @@
1
- import { formatEtag } from '@interop/was-client/sync';
2
- import { bodiesEqual, copyOptionalBodyFields, WasSyncAuthError, WasSyncConflictError } from './types.js';
3
- /**
4
- * Maps a re-read master state into the RxDB conflict entry for one row, or --
5
- * when the re-read found the resource genuinely absent (`master === null`, a
6
- * delete/delete race) -- synthesizes the tombstone conflict entry from what we
7
- * know locally. Shared by the `412` assembler and the `/meta` 404 recovery, so
8
- * both report an absent master identically.
9
- *
10
- * @param options {object}
11
- * @param options.id {string}
12
- * @param options.master {MasterState | null}
13
- * @param options.fallbackUpdatedAt {string} used if the resource is now absent
14
- * @param options.fallbackVersion {number} used if the resource is now absent
15
- * @returns {WithDeleted<SyncedDoc>}
16
- */
17
- function masterOrTombstone({ id, master, fallbackUpdatedAt, fallbackVersion }) {
18
- if (master === null) {
19
- return {
20
- id,
21
- updatedAt: fallbackUpdatedAt,
22
- version: fallbackVersion,
23
- _deleted: true
24
- };
25
- }
26
- const conflict = {
27
- id,
28
- updatedAt: master.updatedAt,
29
- version: master.version,
30
- _deleted: master.deleted
31
- };
32
- copyOptionalBodyFields({ source: master, target: conflict });
33
- return conflict;
34
- }
35
- /**
36
- * Sends one local change to the remote Collection as up to two conditional
37
- * writes (content, then metadata). Returns the master-state conflict entry on a
38
- * `412` at either step, or the accepted writes' acked revisions on success
39
- * (`ack: null` when no response carried a revision). A conflict on the
40
- * metadata half still returns the content half's earned ack alongside the
41
- * conflict entry, so an accepted content version is never discarded.
42
- *
43
- * @param options {object}
44
- * @param options.port {WasSyncPort}
45
- * @param options.newDocumentState {WithDeleted<SyncedDoc>}
46
- * @param [options.assumedMasterState] {WithDeleted<SyncedDoc>}
47
- * @param [options.cache] {MasterReadCache} the push batch's shared
48
- * master-read memo
49
- * @returns {Promise<{ conflict: WithDeleted<SyncedDoc> | null,
50
- * ack: PushWriteAck | null }>}
51
- */
52
- async function pushRow({ port, newDocumentState, assumedMasterState, cache }) {
53
- const { id } = newDocumentState;
54
- const assumedVersion = assumedMasterState?.version;
55
- const isCreate = assumedMasterState === undefined;
56
- const ack = { id };
57
- const hasAck = () => ack.version !== undefined || ack.metaVersion !== undefined;
58
- const fallbackVersion = () => ack.version ?? assumedVersion ?? newDocumentState.version;
59
- // Re-reads this row's master. A row that has ALREADY written this batch
60
- // (a content write accepted before a `/meta` rejection) bypasses the batch
61
- // memo: a sibling's feed read may have paged past this resource before our
62
- // own write landed, and the conflict entry must carry the revision that write
63
- // produced. Rows that wrote nothing -- the ordinary content 412, the common
64
- // case -- are exactly what the memo is for.
65
- const readMaster = async () => hasAck()
66
- ? port.get({ id })
67
- : port.get({ id, ...(cache !== undefined && { cache }) });
68
- // Builds the conflict outcome from a re-read master (or from its absence, a
69
- // delete/delete race), PRESERVING any ack already earned: a content write
70
- // accepted before a `/meta` 412 must keep its acked `version` (and feed it to
71
- // the absent-master fallback), or the local row keeps the pre-write version
72
- // and every later conditional write sends a stale `If-Match`.
73
- const conflictOutcome = (master) => ({
74
- conflict: masterOrTombstone({
75
- id,
76
- master,
77
- fallbackUpdatedAt: newDocumentState.updatedAt,
78
- fallbackVersion: fallbackVersion()
79
- }),
80
- ack: hasAck() ? ack : null
81
- });
82
- // The 412 path: re-read the resource, then report its real master state.
83
- const conflictResult = async () => conflictOutcome(await readMaster());
84
- try {
85
- if (newDocumentState._deleted) {
86
- // Delete supersedes any metadata write: drop the content, tombstone wins.
87
- const ackedVersion = await port.deleteContent({
88
- id,
89
- ...(assumedVersion !== undefined && {
90
- ifMatch: formatEtag(assumedVersion)
91
- })
92
- });
93
- if (ackedVersion !== undefined) {
94
- ack.version = ackedVersion;
95
- }
96
- return { conflict: null, ack: ack.version !== undefined ? ack : null };
97
- }
98
- // Content half: write on create, or when the content body changed. For a
99
- // content-addressed collection the update case never fires (an immutable
100
- // body for a stable id), but it is handled for generality.
101
- const contentChanged = isCreate || !bodiesEqual(newDocumentState.data, assumedMasterState?.data);
102
- if (contentChanged) {
103
- const ackedVersion = await port.putContent({
104
- id,
105
- data: newDocumentState.data ?? null,
106
- ...(newDocumentState.epoch !== undefined && {
107
- epoch: newDocumentState.epoch
108
- }),
109
- ...(isCreate
110
- ? { ifNoneMatch: true }
111
- : assumedVersion !== undefined && {
112
- ifMatch: formatEtag(assumedVersion)
113
- })
114
- });
115
- if (ackedVersion !== undefined) {
116
- ack.version = ackedVersion;
117
- }
118
- }
119
- }
120
- catch (err) {
121
- if (err instanceof WasSyncConflictError) {
122
- return await conflictResult();
123
- }
124
- // Any non-conflict error (network, 5xx, auth) propagates so RxDB retries
125
- // the whole batch with backoff.
126
- throw err;
127
- }
128
- // Metadata half: write when the metadata changed -- including a CLEAR (the
129
- // new state carries no `custom` while the assumed master does; `putMeta`
130
- // with no `custom` writes the cleared state). On a create this runs after
131
- // the content write (the resource must exist first). Its own try/catch so a
132
- // rejection here can never discard an ack the content half already earned.
133
- const metadataChanged = !bodiesEqual(newDocumentState.custom, assumedMasterState?.custom);
134
- if (metadataChanged) {
135
- try {
136
- const assumedMetaVersion = assumedMasterState?.metaVersion;
137
- const ackedMetaVersion = await port.putMeta({
138
- id,
139
- ...(newDocumentState.custom !== undefined && {
140
- custom: newDocumentState.custom
141
- }),
142
- ...(assumedMetaVersion !== undefined
143
- ? { ifMatch: formatEtag(assumedMetaVersion) }
144
- : { ifNoneMatch: true })
145
- });
146
- if (ackedMetaVersion !== undefined) {
147
- ack.metaVersion = ackedMetaVersion;
148
- }
149
- }
150
- catch (err) {
151
- if (err instanceof WasSyncConflictError) {
152
- return await conflictResult();
153
- }
154
- // Corroborate before condemnation: under WAS 404-masking a `/meta` 404
155
- // is ambiguous -- expired access, or an ordinary race with a remote
156
- // delete (a PUT to the `/meta` of a nonexistent resource legitimately
157
- // 404s). An independent request decides: re-read the master off the
158
- // changes feed. A feed read that is itself denied rethrows its own auth
159
- // error (access genuinely expired, so the controller escalates); a feed
160
- // that answers with an absent/deleted master confirms the delete race,
161
- // and the row is resolved with that tombstone as the conflict entry
162
- // (the conflict handler reconciles it) instead of flipping the whole
163
- // session to "access expired" and wedging the batch in RxDB's retries.
164
- if (err instanceof WasSyncAuthError && err.status === 404) {
165
- const master = await readMaster();
166
- if (master === null || master.deleted) {
167
- return conflictOutcome(master);
168
- }
169
- // The resource is alive and readable while its `/meta` write 404s:
170
- // the write itself was rejected, so the auth signal stands.
171
- }
172
- throw err;
173
- }
174
- }
175
- return { conflict: null, ack: hasAck() ? ack : null };
176
- }
177
- /**
178
- * Builds the RxDB push handler that fans a batch of local changes out to
179
- * conditional WAS writes and returns the conflicting rows' master states.
180
- *
181
- * Rows are pushed concurrently; if any non-conflict error is thrown the whole
182
- * batch rejects (RxDB re-sends it later), matching RxDB's all-or-nothing retry.
183
- *
184
- * Each accepted write's acked server revision(s) are handed to
185
- * `onWriteAccepted` (when supplied) as soon as that row's writes settle, so the
186
- * caller can write the new `version` / `metaVersion` back into the local row
187
- * and keep subsequent conditional writes' `If-Match` in step with the server.
188
- *
189
- * Each batch gets one short-lived master-read memo, shared by its rows and
190
- * discarded with the batch (never held across batches, where it would go
191
- * stale). A conflict re-read walks the changes feed from its origin and so pages
192
- * past every other conflicting row's master on the way; without the memo a batch
193
- * with k conflicts would run k concurrent full-feed walks.
194
- *
195
- * @param port {WasSyncPort}
196
- * @param [onWriteAccepted] {(ack: PushWriteAck) => Promise<void>}
197
- * @returns {(rows: Array<{ newDocumentState: WithDeleted<SyncedDoc>,
198
- * assumedMasterState?: WithDeleted<SyncedDoc> }>) =>
199
- * Promise<WithDeleted<SyncedDoc>[]>}
200
- */
201
- export function createPushHandler(port, onWriteAccepted) {
202
- return async function push(rows) {
203
- const cache = { byId: new Map(), inFlight: null };
204
- const results = await Promise.all(rows.map(async (row) => {
205
- const result = await pushRow({
206
- port,
207
- newDocumentState: row.newDocumentState,
208
- assumedMasterState: row.assumedMasterState,
209
- cache
210
- });
211
- if (result.ack !== null && onWriteAccepted !== undefined) {
212
- await onWriteAccepted(result.ack);
213
- }
214
- return result;
215
- }));
216
- return results
217
- .map(result => result.conflict)
218
- .filter((conflict) => conflict !== null);
219
- };
220
- }
221
- //# sourceMappingURL=pushWrites.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pushWrites.js","sourceRoot":"","sources":["../../src/sync/pushWrites.ts"],"names":[],"mappings":"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"}
@@ -1,22 +0,0 @@
1
- /*!
2
- * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
- */
4
- /**
5
- * The single generic RxDB JSON schema reused across every synced collection.
6
- * One shape (`{ id, updatedAt, version, metaVersion?, data?, custom? }`) carries
7
- * both a content revision and an independently-versioned metadata sub-resource;
8
- * `_deleted` is added by RxDB via `deletedField`. `data` / `custom` are opaque
9
- * bodies (plaintext JSON, or an EDV envelope on an encrypted collection), so
10
- * they are typed as free-form objects.
11
- */
12
- import type { RxJsonSchema } from 'rxdb/plugins/core';
13
- import type { SyncedDoc } from './types.js';
14
- /**
15
- * Returns the synced-doc schema. `id` is the primary key (the WAS resourceId);
16
- * `updatedAt` is indexed because it is the change-feed sort field / checkpoint
17
- * component.
18
- *
19
- * @returns {RxJsonSchema<SyncedDoc>}
20
- */
21
- export declare function syncedDocSchema(): RxJsonSchema<SyncedDoc>;
22
- //# sourceMappingURL=syncedDocSchema.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"syncedDocSchema.d.ts","sourceRoot":"","sources":["../../src/sync/syncedDocSchema.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3C;;;;;;GAMG;AACH,wBAAgB,eAAe,IAAI,YAAY,CAAC,SAAS,CAAC,CAoBzD"}
@@ -1,29 +0,0 @@
1
- /**
2
- * Returns the synced-doc schema. `id` is the primary key (the WAS resourceId);
3
- * `updatedAt` is indexed because it is the change-feed sort field / checkpoint
4
- * component.
5
- *
6
- * @returns {RxJsonSchema<SyncedDoc>}
7
- */
8
- export function syncedDocSchema() {
9
- return {
10
- version: 0,
11
- primaryKey: 'id',
12
- type: 'object',
13
- properties: {
14
- id: { type: 'string', maxLength: 256 },
15
- updatedAt: { type: 'string', maxLength: 64 },
16
- version: { type: 'number' },
17
- metaVersion: { type: 'number' },
18
- // The opaque key-epoch id `data` was encrypted under (the `Key-Epoch`
19
- // content-push header), when known.
20
- epoch: { type: 'string', maxLength: 256 },
21
- // Opaque stored bodies -- content and metadata envelopes -- moved verbatim.
22
- data: { type: 'object', additionalProperties: true },
23
- custom: { type: 'object', additionalProperties: true }
24
- },
25
- required: ['id', 'updatedAt', 'version'],
26
- indexes: ['updatedAt']
27
- };
28
- }
29
- //# sourceMappingURL=syncedDocSchema.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"syncedDocSchema.js","sourceRoot":"","sources":["../../src/sync/syncedDocSchema.ts"],"names":[],"mappings":"AAcA;;;;;;GAMG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO;QACL,OAAO,EAAE,CAAC;QACV,UAAU,EAAE,IAAI;QAChB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE;YACtC,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE;YAC5C,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC3B,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC/B,sEAAsE;YACtE,oCAAoC;YACpC,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE;YACzC,4EAA4E;YAC5E,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,IAAI,EAAE;YACpD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,IAAI,EAAE;SACvD;QACD,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC;QACxC,OAAO,EAAE,CAAC,WAAW,CAAC;KACI,CAAA;AAC9B,CAAC"}
@@ -1,319 +0,0 @@
1
- /*!
2
- * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
- */
4
- /**
5
- * Shared types for the collection-agnostic WAS replication adapter.
6
- *
7
- * The adapter drives an RxDB `replicateRxCollection` state machine against a
8
- * remote WAS Collection's replication endpoints. It is deliberately free of any
9
- * React or app imports so it can stand alone; all WAS access is injected through
10
- * the {@link WasSyncPort} seam rather than importing `@interop/was-client`
11
- * directly.
12
- *
13
- * The wire contract follows the WAS `changes` feed and its V2 encrypted-metadata
14
- * profile: a synced document carries both a content revision (`version` /
15
- * `data`) and an independently-versioned metadata sub-resource (`metaVersion` /
16
- * `custom`). A metadata-only edit re-surfaces the resource with a bumped
17
- * `updatedAt` / `metaVersion` but unchanged `version` / `data`. The sync layer
18
- * moves both bodies opaquely: `data` is the stored content body (plaintext JSON,
19
- * or the EDV envelope on an encrypted collection) and `custom` is the stored
20
- * metadata body (an opaque envelope on an encrypted collection); encrypt/decrypt
21
- * stays a read/write-time concern above this layer.
22
- *
23
- * The two small helpers that travel with these shapes live here as well: the
24
- * opaque-body equality every routing decision is made on, and the optional-field
25
- * copy every wire-to-local mapping runs.
26
- */
27
- import type { Json } from '@interop/was-client';
28
- import type { MasterState as ClientMasterState, SyncCheckpoint as ClientSyncCheckpoint } from '@interop/was-client/sync';
29
- /**
30
- * The typed port signals, owned by `@interop/was-client` (its sync port raises
31
- * them) and re-exported here so the names this package's consumers already
32
- * import stay put -- and so an `instanceof` check anywhere in this package
33
- * matches the very class the port throws.
34
- *
35
- * `WasSyncConflictError` marks a conditional write rejected with `412
36
- * precondition-failed` (a lost-update conflict, or a create-if-absent whose
37
- * target already exists); the push handler catches exactly it to trigger the
38
- * re-read-and-report-conflict path. `WasSyncAuthError` marks a request refused
39
- * on authorization grounds -- `401`, `403`, or the `404` a WAS server masks a
40
- * failed capability invocation as, which on the sync paths (where the invoked
41
- * collection is known to exist) means the invocation was rejected. It keeps the
42
- * offending HTTP status on `status`, which the `/meta` push path reads to tell
43
- * a masked denial from an ordinary delete race.
44
- */
45
- export { WasSyncAuthError, WasSyncConflictError } from '@interop/was-client/sync';
46
- /**
47
- * A JSON value -- the opaque stored resource body the sync layer moves verbatim.
48
- * For a plaintext collection this is the user document; for an encrypted one it
49
- * is the EDV envelope. The adapter never inspects or transforms it. Re-exported
50
- * from `@interop/was-client`, which owns the wire model, so a body crosses the
51
- * port boundary without a cast.
52
- */
53
- export type { Json };
54
- /**
55
- * The optional half of a synced document, shared verbatim by every shape it
56
- * travels in ({@link WireDoc} on the feed, {@link SyncedDoc} locally,
57
- * {@link MasterState} on the conflict re-read): the independently-versioned
58
- * metadata revision and body, the content body, and the content body's
59
- * key-epoch stamp. Each is genuinely absent rather than `undefined` when the
60
- * server has nothing for it, so every mapping between the shapes copies them
61
- * conditionally -- see {@link copyOptionalBodyFields}.
62
- */
63
- export interface OptionalBodyFields {
64
- metaVersion?: number;
65
- data?: Json;
66
- custom?: Json;
67
- epoch?: string;
68
- }
69
- /**
70
- * Structural equality over two opaque bodies, by canonical-free JSON string.
71
- * Decides whether the content or the metadata half changed -- which endpoint(s)
72
- * a push writes, and whether two states compare equal for conflict resolution.
73
- * Content-addressed collections never mutate `data` for a given id, and a real
74
- * metadata edit re-encrypts to fresh bytes, so this coarse comparison suffices.
75
- *
76
- * @param left {Json | undefined}
77
- * @param right {Json | undefined}
78
- * @returns {boolean}
79
- */
80
- export declare function bodiesEqual(left: Json | undefined, right: Json | undefined): boolean;
81
- /**
82
- * Copies the {@link OptionalBodyFields} that are present on `source` onto
83
- * `target`, leaving an absent field absent (never writing an explicit
84
- * `undefined`, which would surface the key in a serialized body). The single
85
- * place every wire-to-local, feed-to-master, and master-to-conflict mapping
86
- * shares, so a new optional wire field is added once.
87
- *
88
- * @param options {object}
89
- * @param options.source {OptionalBodyFields}
90
- * @param options.target {OptionalBodyFields} mutated in place
91
- * @returns {void}
92
- */
93
- export declare function copyOptionalBodyFields({ source, target }: {
94
- source: OptionalBodyFields;
95
- target: OptionalBodyFields;
96
- }): void;
97
- /**
98
- * The keyset position in the change feed: the `{ id, updatedAt }` of the last
99
- * document a pull returned. Passed back verbatim to resume, and used as the
100
- * RxDB replication checkpoint. `id` is the total-order tiebreaker within a
101
- * single `updatedAt`. The client's own checkpoint type, aliased here so the
102
- * replication layer and the port agree by construction.
103
- */
104
- export type SyncCheckpoint = ClientSyncCheckpoint;
105
- /**
106
- * One document as it travels on the `changes` feed wire
107
- * (`POST /space/:s/:c/query`, profile `changes`). `id` is the WAS resourceId,
108
- * `version` is the content master revision (feeds the content push `If-Match`
109
- * ETag) and the user content body is nested under `data`; `metaVersion` is the
110
- * independent metadata revision (feeds the `/meta` push `If-Match` ETag) and the
111
- * user-writable metadata body is under `custom`. A tombstone carries
112
- * `_deleted: true` with no `data`. `metaVersion` / `custom` are present only
113
- * once metadata has been written for the resource.
114
- */
115
- export interface WireDoc {
116
- id: string;
117
- _deleted: boolean;
118
- updatedAt: string;
119
- version: number;
120
- metaVersion?: number;
121
- data?: Json;
122
- custom?: Json;
123
- /**
124
- * The opaque key-epoch id the content body was encrypted under (the
125
- * `key-epochs` feature), present when the server holds a stamp for the
126
- * resource. Moved verbatim; the sync layer never interprets it.
127
- */
128
- epoch?: string;
129
- }
130
- /**
131
- * The local RxDB document shape, shared across every synced collection. The
132
- * envelope fields are top-level (`id` primary key, `updatedAt` the checkpoint
133
- * sort field, `version` / `metaVersion` the server master revisions); the user
134
- * bodies stay nested (`data` for content, `custom` for metadata) to avoid field
135
- * collisions. `_deleted` is managed by RxDB via `deletedField` and so is not
136
- * part of this "clean" shape (handlers work with RxDB's `WithDeleted<SyncedDoc>`).
137
- */
138
- export interface SyncedDoc {
139
- id: string;
140
- updatedAt: string;
141
- version: number;
142
- metaVersion?: number;
143
- data?: Json;
144
- custom?: Json;
145
- /**
146
- * The opaque key-epoch id `data` was encrypted under, when known (stamped by
147
- * the encrypting cipher on a local write, or pulled off the feed). Sent as
148
- * the `Key-Epoch` header on the content push so the server's stamp stays
149
- * in step with the envelope.
150
- */
151
- epoch?: string;
152
- }
153
- /**
154
- * The current master state of a single resource, as read back for the 412
155
- * conflict path: the client's own `MasterState` (content `version` /
156
- * `updatedAt`, plus the optional `metaVersion` / `data` / `custom` /
157
- * `createdBy` / `epoch`) plus the `deleted` flag that distinguishes a tombstone
158
- * from a live resource. The flag is required here because this package resolves
159
- * the master from the changes feed, where a tombstone travels as a document
160
- * rather than as an absent read.
161
- */
162
- export interface MasterState extends ClientMasterState {
163
- deleted: boolean;
164
- }
165
- /**
166
- * The short-lived master-read memo the rows of ONE push batch share. A
167
- * resolving `get` implementation may answer from `byId` and MUST record every
168
- * master it resolved on the way there; a feed-walking implementation pages past
169
- * all of them anyway, so a batch of k conflicts costs one walk instead of k.
170
- *
171
- * `inFlight` is what makes that hold under concurrency: the batch's rows push in
172
- * parallel, so without it every row would start its own walk before the first
173
- * one finished and the memo would never be read. A `get` that must walk
174
- * publishes its walk here; a `get` that finds a walk already running awaits it
175
- * and re-checks `byId` first. It settles (never rejects) so one row's failed
176
- * read is not another row's, and is `null` whenever no walk is running.
177
- *
178
- * The whole object is created per batch invocation and dropped with it: a memo
179
- * held across batches would go stale.
180
- */
181
- export interface MasterReadCache {
182
- byId: Map<string, MasterState | null>;
183
- inFlight: Promise<void> | null;
184
- }
185
- /**
186
- * The write/query half of the injected WAS-access seam. An adapter (the app-side
187
- * `createWasSyncPort`) implements this over `@interop/was-client`; the core
188
- * module depends only on this interface, never on `was-client` itself. Every
189
- * method moves the stored body verbatim -- no codec, no key handling -- so the
190
- * same port works for plaintext and encrypted collections alike.
191
- *
192
- * `putContent` / `deleteContent` / `putMeta` MUST throw
193
- * {@link WasSyncConflictError} when the server rejects a conditional write with
194
- * `412 precondition-failed`, and let every other error propagate so RxDB's
195
- * retry/backoff handles it.
196
- *
197
- * The 412 conflict re-read (`get`) is deliberately NOT part of this base:
198
- * `createWasSyncPort` returns a `WasSyncBasePort`, and `withFeedMasterRead`
199
- * supplies a `get` that resolves the master state from the changes-feed body
200
- * (origin-independent) to produce a full {@link WasSyncPort}.
201
- */
202
- export interface WasSyncBasePort {
203
- /**
204
- * Pulls one page of the `changes` feed. Omit `checkpoint` for the first page.
205
- * Returns the page's `documents` and its resume `checkpoint`, or
206
- * `checkpoint: null` for an empty (no-change) page.
207
- *
208
- * @param options {object}
209
- * @param [options.checkpoint] {SyncCheckpoint} resume position
210
- * @param options.limit {number} requested batch size
211
- * @returns {Promise<{ documents: WireDoc[], checkpoint: SyncCheckpoint | null }>}
212
- */
213
- query(options: {
214
- checkpoint?: SyncCheckpoint;
215
- limit: number;
216
- }): Promise<{
217
- documents: WireDoc[];
218
- checkpoint: SyncCheckpoint | null;
219
- }>;
220
- /**
221
- * Conditionally writes the content body verbatim (`PUT /:id`). Pass
222
- * `ifNoneMatch: true` for a create-if-absent, or `ifMatch` (a quoted ETag over
223
- * the content `version`) for an update-if-unchanged. `epoch` is the opaque
224
- * key-epoch id the body was encrypted under, sent as the `Key-Epoch`
225
- * header (an absent epoch clears any prior stamp on the server, per the
226
- * `key-epochs` feature). Returns the new content `version` parsed from the
227
- * response ETag (the acked master revision), or `undefined` when the server
228
- * does not supply one.
229
- *
230
- * @param options {object}
231
- * @param options.id {string}
232
- * @param options.data {Json}
233
- * @param [options.ifMatch] {string}
234
- * @param [options.ifNoneMatch] {boolean}
235
- * @param [options.epoch] {string}
236
- * @returns {Promise<number | undefined>}
237
- */
238
- putContent(options: {
239
- id: string;
240
- data: Json;
241
- ifMatch?: string;
242
- ifNoneMatch?: boolean;
243
- epoch?: string;
244
- }): Promise<number | undefined>;
245
- /**
246
- * Conditionally deletes a resource (writes a tombstone; `DELETE /:id`). Pass
247
- * `ifMatch` (a quoted ETag over the content `version`) to delete only if
248
- * unchanged. Returns the tombstone `version` parsed from the response ETag
249
- * when the server supplies one (the reference server does not). MUST treat a
250
- * `404` as success (resolve `undefined`): the resource is already absent --
251
- * a row deleted locally before its first push, or deleted remotely first --
252
- * so the tombstone's goal state holds; rejecting would wedge the push batch
253
- * in RxDB's retry loop.
254
- *
255
- * @param options {object}
256
- * @param options.id {string}
257
- * @param [options.ifMatch] {string}
258
- * @returns {Promise<number | undefined>}
259
- */
260
- deleteContent(options: {
261
- id: string;
262
- ifMatch?: string;
263
- }): Promise<number | undefined>;
264
- /**
265
- * Conditionally writes the metadata body verbatim (`PUT /:id/meta`, body
266
- * `{ custom }`). An ABSENT `custom` writes the CLEARED state (a body with no
267
- * `custom` member -- the server's metadata replace clears every property the
268
- * body omits), so removing a resource's metadata replicates rather than being
269
- * skipped. Pass `ifNoneMatch: true` when the resource has no metadata yet, or
270
- * `ifMatch` (a quoted ETag over `metaVersion`) for an update-if-unchanged.
271
- * The resource must already exist (the server does not create a resource from
272
- * a `/meta` write). Returns the new `metaVersion` parsed from the response
273
- * ETag, or `undefined` when the server does not supply one.
274
- *
275
- * @param options {object}
276
- * @param [options.custom] {Json} absent = write the cleared state
277
- * @param options.id {string}
278
- * @param [options.ifMatch] {string}
279
- * @param [options.ifNoneMatch] {boolean}
280
- * @returns {Promise<number | undefined>}
281
- */
282
- putMeta(options: {
283
- id: string;
284
- custom?: Json;
285
- ifMatch?: string;
286
- ifNoneMatch?: boolean;
287
- }): Promise<number | undefined>;
288
- }
289
- /**
290
- * The full sync port the core consumes: a {@link WasSyncBasePort}'s write/query
291
- * methods plus the `get` used by the 412 conflict assembler. The push handler
292
- * and `createWasReplication` require this full port; build one by wrapping a
293
- * base port with `withFeedMasterRead`, which supplies `get`.
294
- */
295
- export interface WasSyncPort extends WasSyncBasePort {
296
- /**
297
- * Re-reads a single resource's current master state (content + metadata) for
298
- * the 412 conflict assembler. Returns `null` when the resource is genuinely
299
- * absent (a delete/delete race); throws a retryable error when the master
300
- * cannot be resolved (e.g. a feed re-read that exhausts its scan budget), so
301
- * the replication cycle retries rather than fabricating a false tombstone.
302
- *
303
- * `cache` is an OPTIONAL {@link MasterReadCache}, shared by the rows of one
304
- * push batch (see its own docs for the contract). A hit is no staler than a
305
- * read issued at the same moment, since the memo lives only for that batch. An
306
- * implementation that ignores it is fully conformant, and a caller that omits
307
- * it gets an uncached read.
308
- *
309
- * @param options {object}
310
- * @param options.id {string}
311
- * @param [options.cache] {MasterReadCache}
312
- * @returns {Promise<MasterState | null>}
313
- */
314
- get(options: {
315
- id: string;
316
- cache?: MasterReadCache;
317
- }): Promise<MasterState | null>;
318
- }
319
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sync/types.ts"],"names":[],"mappings":"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"}