braid-text 0.3.16 → 0.3.17
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/client/simpleton-sync.js +20 -10
- package/package.json +1 -1
- package/server.js +17 -10
package/client/simpleton-sync.js
CHANGED
|
@@ -199,11 +199,31 @@ function simpleton_client(url, {
|
|
|
199
199
|
client_state = apply_patches(client_state, patches)
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
+
// ── Advance version ─────────────────────────────────────────
|
|
203
|
+
// IMPORTANT: This must happen synchronously (before any await)
|
|
204
|
+
// to prevent the changed() accumulation loop from interleaving
|
|
205
|
+
// and capturing a stale client_version during a yield point.
|
|
206
|
+
client_version = update.version
|
|
207
|
+
|
|
208
|
+
// ── Notify listener ─────────────────────────────────────────
|
|
209
|
+
// IMPORTANT: No changed() / flush is called here.
|
|
210
|
+
// The JS does NOT send edits after receiving a server
|
|
211
|
+
// update. The PUT response handler's async accumulation
|
|
212
|
+
// loop handles flushing accumulated edits.
|
|
213
|
+
if (on_state) on_state(client_state)
|
|
214
|
+
|
|
202
215
|
// ── Digest verification ─────────────────────────────────────
|
|
203
216
|
// If the server sent a repr-digest, verify our state
|
|
204
217
|
// matches. On mismatch, THROW — this halts the
|
|
205
218
|
// subscription handler. The document is corrupted and
|
|
206
219
|
// continuing would compound the problem.
|
|
220
|
+
//
|
|
221
|
+
// This is placed after advancing client_version and calling
|
|
222
|
+
// on_state so that the await does not create a yield point
|
|
223
|
+
// between applying patches and advancing client_version.
|
|
224
|
+
// That yield point previously allowed the changed() PUT loop
|
|
225
|
+
// to interleave, capturing a stale client_version and causing
|
|
226
|
+
// edit loss.
|
|
207
227
|
if (update.extra_headers &&
|
|
208
228
|
update.extra_headers["repr-digest"] &&
|
|
209
229
|
update.extra_headers["repr-digest"].startsWith('sha-256=') &&
|
|
@@ -213,16 +233,6 @@ function simpleton_client(url, {
|
|
|
213
233
|
console.log('state: ' + client_state)
|
|
214
234
|
throw new Error('repr-digest mismatch')
|
|
215
235
|
}
|
|
216
|
-
|
|
217
|
-
// ── Advance version ─────────────────────────────────────────
|
|
218
|
-
client_version = update.version
|
|
219
|
-
|
|
220
|
-
// ── Notify listener ─────────────────────────────────────────
|
|
221
|
-
// IMPORTANT: No changed() / flush is called here.
|
|
222
|
-
// The JS does NOT send edits after receiving a server
|
|
223
|
-
// update. The PUT response handler's async accumulation
|
|
224
|
-
// loop handles flushing accumulated edits.
|
|
225
|
-
if (on_state) on_state(client_state)
|
|
226
236
|
}
|
|
227
237
|
|
|
228
238
|
// ── Public interface ────────────────────────────────────────────────
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -1023,16 +1023,10 @@ function create_braid_text() {
|
|
|
1023
1023
|
|
|
1024
1024
|
if (client.my_timeout) {
|
|
1025
1025
|
if (peer && client.peer === peer) {
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
set_timeout()
|
|
1031
|
-
} else {
|
|
1032
|
-
// hm.. it appears we got a correctly parented version,
|
|
1033
|
-
// which suggests that maybe we can stop the timeout early
|
|
1034
|
-
set_timeout(0)
|
|
1035
|
-
}
|
|
1026
|
+
// note: we don't add to client.my_unused_version_count,
|
|
1027
|
+
// because we're already in a timeout;
|
|
1028
|
+
// we'll just extend it here..
|
|
1029
|
+
set_timeout()
|
|
1036
1030
|
}
|
|
1037
1031
|
continue
|
|
1038
1032
|
}
|
|
@@ -1049,6 +1043,19 @@ function create_braid_text() {
|
|
|
1049
1043
|
|
|
1050
1044
|
x.parents = [version]
|
|
1051
1045
|
if (!v_eq(x.version, x.parents)) {
|
|
1046
|
+
// Note: this rebase will never trigger in the
|
|
1047
|
+
// presence of the timeout logic above, because
|
|
1048
|
+
// any version that would cause x.version to
|
|
1049
|
+
// differ from x.parents would have already
|
|
1050
|
+
// updated my_last_sent_version when forwarding
|
|
1051
|
+
// other peers' changes to this client, causing
|
|
1052
|
+
// a mismatch and triggering a timeout instead.
|
|
1053
|
+
//
|
|
1054
|
+
// However, this is the standard rebase path and
|
|
1055
|
+
// is left here for implementations that omit the
|
|
1056
|
+
// timeout optimization — without it, this branch
|
|
1057
|
+
// is needed to rebase the client's version when
|
|
1058
|
+
// concurrent edits have been merged.
|
|
1052
1059
|
if (braid_text.verbose) console.log("rebasing..")
|
|
1053
1060
|
x.patches = get_xf_patches(resource.doc, OpLog_remote_to_local(resource.doc, x.parents))
|
|
1054
1061
|
} else {
|