@dabble/patches 0.8.6 → 0.8.7
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/dist/client/LWWInMemoryStore.d.ts +8 -2
- package/dist/client/LWWInMemoryStore.js +11 -8
- package/dist/client/LWWIndexedDBStore.d.ts +8 -2
- package/dist/client/LWWIndexedDBStore.js +5 -14
- package/dist/client/OTInMemoryStore.js +2 -1
- package/dist/client/OTIndexedDBStore.js +1 -2
- package/dist/net/PatchesSync.js +1 -1
- package/package.json +1 -1
|
@@ -31,7 +31,7 @@ declare class LWWInMemoryStore implements LWWClientStore {
|
|
|
31
31
|
listDocs(includeDeleted?: boolean): Promise<TrackedDoc[]>;
|
|
32
32
|
/**
|
|
33
33
|
* Saves the current document state to storage.
|
|
34
|
-
* Clears
|
|
34
|
+
* Clears committed fields (subsumed by the snapshot) but preserves pending ops.
|
|
35
35
|
*/
|
|
36
36
|
saveDoc(docId: string, docState: PatchesState): Promise<void>;
|
|
37
37
|
/**
|
|
@@ -71,7 +71,13 @@ declare class LWWInMemoryStore implements LWWClientStore {
|
|
|
71
71
|
*/
|
|
72
72
|
saveSendingChange(docId: string, change: Change): Promise<void>;
|
|
73
73
|
/**
|
|
74
|
-
*
|
|
74
|
+
* Move sending ops to committed, then clear the sending slot.
|
|
75
|
+
* committedRev is NOT updated here — applyServerChanges owns that using the
|
|
76
|
+
* server's actual rev. Updating it here would bump the rev above the server's
|
|
77
|
+
* real value for noop changes (where the server doesn't create a new rev).
|
|
78
|
+
*
|
|
79
|
+
* Call this BEFORE applyServerChanges so that server corrections (which run
|
|
80
|
+
* after) overwrite any stale ops for fields the server won via LWW.
|
|
75
81
|
*/
|
|
76
82
|
confirmSendingChange(docId: string): Promise<void>;
|
|
77
83
|
/**
|
|
@@ -51,14 +51,15 @@ class LWWInMemoryStore {
|
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
53
|
* Saves the current document state to storage.
|
|
54
|
-
* Clears
|
|
54
|
+
* Clears committed fields (subsumed by the snapshot) but preserves pending ops.
|
|
55
55
|
*/
|
|
56
56
|
async saveDoc(docId, docState) {
|
|
57
|
+
const existing = this.docs.get(docId);
|
|
57
58
|
this.docs.set(docId, {
|
|
58
59
|
snapshot: { state: docState.state, rev: docState.rev },
|
|
59
60
|
committedFields: /* @__PURE__ */ new Map(),
|
|
60
|
-
pendingOps: /* @__PURE__ */ new Map(),
|
|
61
|
-
sendingChange: null,
|
|
61
|
+
pendingOps: existing?.pendingOps ?? /* @__PURE__ */ new Map(),
|
|
62
|
+
sendingChange: existing?.sendingChange ?? null,
|
|
62
63
|
committedRev: docState.rev
|
|
63
64
|
});
|
|
64
65
|
}
|
|
@@ -150,7 +151,13 @@ class LWWInMemoryStore {
|
|
|
150
151
|
buf.pendingOps.clear();
|
|
151
152
|
}
|
|
152
153
|
/**
|
|
153
|
-
*
|
|
154
|
+
* Move sending ops to committed, then clear the sending slot.
|
|
155
|
+
* committedRev is NOT updated here — applyServerChanges owns that using the
|
|
156
|
+
* server's actual rev. Updating it here would bump the rev above the server's
|
|
157
|
+
* real value for noop changes (where the server doesn't create a new rev).
|
|
158
|
+
*
|
|
159
|
+
* Call this BEFORE applyServerChanges so that server corrections (which run
|
|
160
|
+
* after) overwrite any stale ops for fields the server won via LWW.
|
|
154
161
|
*/
|
|
155
162
|
async confirmSendingChange(docId) {
|
|
156
163
|
const buf = this.docs.get(docId);
|
|
@@ -158,10 +165,6 @@ class LWWInMemoryStore {
|
|
|
158
165
|
for (const op of buf.sendingChange.ops) {
|
|
159
166
|
buf.committedFields.set(op.path, op.value);
|
|
160
167
|
}
|
|
161
|
-
const changeRev = buf.sendingChange.rev;
|
|
162
|
-
if (changeRev !== void 0 && changeRev > buf.committedRev) {
|
|
163
|
-
buf.committedRev = changeRev;
|
|
164
|
-
}
|
|
165
168
|
buf.sendingChange = null;
|
|
166
169
|
}
|
|
167
170
|
/**
|
|
@@ -73,7 +73,7 @@ declare class LWWIndexedDBStore implements LWWClientStore {
|
|
|
73
73
|
getDoc(docId: string): Promise<PatchesSnapshot | undefined>;
|
|
74
74
|
/**
|
|
75
75
|
* Saves the current document state to storage.
|
|
76
|
-
* Clears
|
|
76
|
+
* Clears committed fields (subsumed by the snapshot) but preserves pending ops.
|
|
77
77
|
*/
|
|
78
78
|
saveDoc(docId: string, docState: PatchesState): Promise<void>;
|
|
79
79
|
/**
|
|
@@ -101,7 +101,13 @@ declare class LWWIndexedDBStore implements LWWClientStore {
|
|
|
101
101
|
*/
|
|
102
102
|
saveSendingChange(docId: string, change: Change): Promise<void>;
|
|
103
103
|
/**
|
|
104
|
-
*
|
|
104
|
+
* Move sending ops to committed, then clear the sending slot.
|
|
105
|
+
* committedRev is NOT updated here — applyServerChanges owns that using the
|
|
106
|
+
* server's actual rev. Updating it here would bump the rev above the server's
|
|
107
|
+
* real value for noop changes (where the server doesn't create a new rev).
|
|
108
|
+
*
|
|
109
|
+
* Call this BEFORE applyServerChanges so that server corrections (which run
|
|
110
|
+
* after) overwrite any stale ops for fields the server won via LWW.
|
|
105
111
|
*/
|
|
106
112
|
confirmSendingChange(docId: string): Promise<void>;
|
|
107
113
|
/**
|
|
@@ -122,17 +122,15 @@ class LWWIndexedDBStore {
|
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
124
|
async saveDoc(docId, docState) {
|
|
125
|
-
const [tx, snapshots, committedOps,
|
|
126
|
-
["snapshots", "committedOps", "
|
|
125
|
+
const [tx, snapshots, committedOps, docsStore] = await this.db.transaction(
|
|
126
|
+
["snapshots", "committedOps", "docs"],
|
|
127
127
|
"readwrite"
|
|
128
128
|
);
|
|
129
129
|
const { rev, state } = docState;
|
|
130
130
|
await Promise.all([
|
|
131
131
|
docsStore.put({ docId, committedRev: rev, algorithm: "lww" }),
|
|
132
132
|
snapshots.put({ docId, state, rev }),
|
|
133
|
-
this.deleteFieldsForDoc(committedOps, docId)
|
|
134
|
-
this.deleteFieldsForDoc(pendingOps, docId),
|
|
135
|
-
sendingChanges.delete(docId)
|
|
133
|
+
this.deleteFieldsForDoc(committedOps, docId)
|
|
136
134
|
]);
|
|
137
135
|
await tx.complete();
|
|
138
136
|
}
|
|
@@ -233,8 +231,8 @@ class LWWIndexedDBStore {
|
|
|
233
231
|
await tx.complete();
|
|
234
232
|
}
|
|
235
233
|
async confirmSendingChange(docId) {
|
|
236
|
-
const [tx, sendingChanges, committedOps
|
|
237
|
-
["sendingChanges", "committedOps"
|
|
234
|
+
const [tx, sendingChanges, committedOps] = await this.db.transaction(
|
|
235
|
+
["sendingChanges", "committedOps"],
|
|
238
236
|
"readwrite"
|
|
239
237
|
);
|
|
240
238
|
const sending = await sendingChanges.get(docId);
|
|
@@ -243,13 +241,6 @@ class LWWIndexedDBStore {
|
|
|
243
241
|
return;
|
|
244
242
|
}
|
|
245
243
|
await Promise.all(sending.change.ops.map((op) => committedOps.put({ ...op, docId })));
|
|
246
|
-
const changeRev = sending.change.rev;
|
|
247
|
-
if (changeRev !== void 0) {
|
|
248
|
-
const docMeta = await docsStore.get(docId) ?? { docId, committedRev: 0, algorithm: "lww" };
|
|
249
|
-
if (changeRev > docMeta.committedRev) {
|
|
250
|
-
await docsStore.put({ ...docMeta, committedRev: changeRev });
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
244
|
await sendingChanges.delete(docId);
|
|
254
245
|
await tx.complete();
|
|
255
246
|
}
|
|
@@ -31,10 +31,11 @@ class OTInMemoryStore {
|
|
|
31
31
|
}
|
|
32
32
|
// ─── Writes ────────────────────────────────────────────────────────────
|
|
33
33
|
async saveDoc(docId, snapshot) {
|
|
34
|
+
const existing = this.docs.get(docId);
|
|
34
35
|
this.docs.set(docId, {
|
|
35
36
|
snapshot,
|
|
36
37
|
committed: [],
|
|
37
|
-
pending: []
|
|
38
|
+
pending: existing?.pending ?? []
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
41
|
async savePendingChanges(docId, changes) {
|
|
@@ -119,8 +119,7 @@ class OTIndexedDBStore {
|
|
|
119
119
|
await Promise.all([
|
|
120
120
|
docsStore.put({ docId, committedRev: rev, algorithm: "ot" }),
|
|
121
121
|
snapshots.put({ docId, state, rev }),
|
|
122
|
-
committedChanges.delete([docId, 0], [docId, Infinity])
|
|
123
|
-
pendingChanges.delete([docId, 0], [docId, Infinity])
|
|
122
|
+
committedChanges.delete([docId, 0], [docId, Infinity])
|
|
124
123
|
]);
|
|
125
124
|
await tx.complete();
|
|
126
125
|
}
|
package/dist/net/PatchesSync.js
CHANGED
|
@@ -318,8 +318,8 @@ class PatchesSync extends (_a = ReadonlyStoreClass, _syncDoc_dec = [serialGate],
|
|
|
318
318
|
openDoc.import({ ...snapshot, changes: [] });
|
|
319
319
|
}
|
|
320
320
|
} else {
|
|
321
|
-
await this._applyServerChangesToDoc(docId, committed);
|
|
322
321
|
await algorithm.confirmSent(docId, changeBatch);
|
|
322
|
+
await this._applyServerChangesToDoc(docId, committed);
|
|
323
323
|
}
|
|
324
324
|
pending = await algorithm.getPendingToSend(docId) ?? [];
|
|
325
325
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dabble/patches",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
4
4
|
"description": "Immutable JSON Patch implementation based on RFC 6902 supporting operational transformation and last-writer-wins",
|
|
5
5
|
"author": "Jacob Wright <jacwright@gmail.com>",
|
|
6
6
|
"bugs": {
|