yrby-client 0.4.3 → 0.6.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 +250 -36
- package/dist/actioncable_provider.d.ts +26 -1
- package/dist/actioncable_provider.d.ts.map +1 -1
- package/dist/actioncable_provider.js +295 -150
- package/dist/actioncable_provider.js.map +1 -1
- package/dist/cjs/actioncable_provider.d.ts +26 -1
- package/dist/cjs/actioncable_provider.js +296 -151
- package/dist/cjs/document_element.d.ts +24 -0
- package/dist/cjs/document_element.js +260 -0
- package/dist/cjs/document_session.d.ts +62 -0
- package/dist/cjs/document_session.js +335 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +4 -1
- package/dist/cjs/reliable_sync.d.ts +18 -31
- package/dist/cjs/reliable_sync.js +128 -98
- package/dist/cjs/turbo_adapter.d.ts +9 -0
- package/dist/cjs/turbo_adapter.js +81 -0
- package/dist/cjs/y_protocol_session.d.ts +7 -14
- package/dist/cjs/y_protocol_session.js +97 -92
- package/dist/document_element.d.ts +25 -0
- package/dist/document_element.d.ts.map +1 -0
- package/dist/document_element.js +225 -0
- package/dist/document_element.js.map +1 -0
- package/dist/document_session.d.ts +63 -0
- package/dist/document_session.d.ts.map +1 -0
- package/dist/document_session.js +296 -0
- package/dist/document_session.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/reliable_sync.d.ts +18 -31
- package/dist/reliable_sync.d.ts.map +1 -1
- package/dist/reliable_sync.js +128 -98
- package/dist/reliable_sync.js.map +1 -1
- package/dist/turbo_adapter.d.ts +10 -0
- package/dist/turbo_adapter.d.ts.map +1 -0
- package/dist/turbo_adapter.js +78 -0
- package/dist/turbo_adapter.js.map +1 -0
- package/dist/y_protocol_session.d.ts +7 -14
- package/dist/y_protocol_session.d.ts.map +1 -1
- package/dist/y_protocol_session.js +97 -92
- package/dist/y_protocol_session.js.map +1 -1
- package/package.json +29 -6
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
// Awareness); it works in raw Uint8Array frames and leaves the transport to the
|
|
5
5
|
// caller: base64, the { update, id } / { ack } envelope, and a socket.
|
|
6
6
|
//
|
|
7
|
-
// Call
|
|
8
|
-
//
|
|
9
|
-
// returns a reply to send, or null).
|
|
10
|
-
//
|
|
11
|
-
import {
|
|
7
|
+
// Call resume() when the transport connects, pause() when it drops,
|
|
8
|
+
// acknowledge(id) on an { ack } envelope, and receive(frame) for an inbound
|
|
9
|
+
// frame (it returns a reply to send, or null). The session sends local doc and
|
|
10
|
+
// awareness edits from their "update" events.
|
|
11
|
+
import { mergeUpdates, applyUpdate } from "yjs";
|
|
12
12
|
import * as encoding from "lib0/encoding";
|
|
13
13
|
import * as decoding from "lib0/decoding";
|
|
14
14
|
import { readSyncMessage, writeSyncStep1, writeUpdate, messageYjsSyncStep2 } from "y-protocols/sync";
|
|
@@ -22,12 +22,12 @@ export class YProtocolSession {
|
|
|
22
22
|
awareness;
|
|
23
23
|
#send;
|
|
24
24
|
#onError;
|
|
25
|
-
#
|
|
25
|
+
#state = { phase: "unsynced", cycle: {} };
|
|
26
26
|
#delivery;
|
|
27
27
|
#onDocUpdate;
|
|
28
28
|
#onAwarenessUpdate;
|
|
29
29
|
constructor(doc, opts) {
|
|
30
|
-
const { send, awareness = null, resendInterval, onError, setInterval:
|
|
30
|
+
const { send, awareness = null, resendInterval, onError, setInterval: setTimer, clearInterval: clearTimer } = opts ?? {};
|
|
31
31
|
if (!doc)
|
|
32
32
|
throw new TypeError("YProtocolSession requires a Y.Doc");
|
|
33
33
|
if (typeof send !== "function")
|
|
@@ -40,8 +40,8 @@ export class YProtocolSession {
|
|
|
40
40
|
merge: mergeUpdates,
|
|
41
41
|
send: (update, id) => this.#send(this.#frameUpdate(update), id),
|
|
42
42
|
resendInterval,
|
|
43
|
-
setInterval:
|
|
44
|
-
clearInterval:
|
|
43
|
+
setInterval: setTimer,
|
|
44
|
+
clearInterval: clearTimer,
|
|
45
45
|
});
|
|
46
46
|
this.#onDocUpdate = (update, origin) => {
|
|
47
47
|
if (origin === this)
|
|
@@ -52,10 +52,10 @@ export class YProtocolSession {
|
|
|
52
52
|
if (this.awareness) {
|
|
53
53
|
this.#onAwarenessUpdate = ({ added, updated, removed }, origin) => {
|
|
54
54
|
// Only broadcast our own presence changes. Updates applied from a peer,
|
|
55
|
-
// and our own remote-cleanup in
|
|
55
|
+
// and our own remote-cleanup in pause(), carry origin === this;
|
|
56
56
|
// re-sending those would echo presence and broadcast tombstones for
|
|
57
57
|
// other clients' cursors.
|
|
58
|
-
if (origin === this)
|
|
58
|
+
if (origin === this || this.#state.phase === "destroyed")
|
|
59
59
|
return;
|
|
60
60
|
const changed = added.concat(updated, removed);
|
|
61
61
|
this.#send(this.#frameAwareness(changed), undefined); // fire-and-forget
|
|
@@ -65,26 +65,35 @@ export class YProtocolSession {
|
|
|
65
65
|
}
|
|
66
66
|
/** True once we've received the server's SyncStep2 (the document is caught up). */
|
|
67
67
|
get synced() {
|
|
68
|
-
return this.#synced;
|
|
68
|
+
return this.#state.phase === "synced";
|
|
69
69
|
}
|
|
70
70
|
/** True while there are unacknowledged local document updates in flight. */
|
|
71
71
|
get hasPending() {
|
|
72
72
|
return this.#delivery.hasPending;
|
|
73
73
|
}
|
|
74
|
-
/**
|
|
75
|
-
|
|
74
|
+
/** Call when the transport is up. Sends the opening handshake, re-announces presence, and replays the unacked tail. */
|
|
75
|
+
resume() {
|
|
76
|
+
if (this.#state.phase === "destroyed")
|
|
77
|
+
return;
|
|
78
|
+
const cycle = {};
|
|
79
|
+
this.#state = { phase: "unsynced", cycle };
|
|
76
80
|
this.#send(this.#frameSyncStep1(), undefined);
|
|
81
|
+
if (!this.#current(cycle))
|
|
82
|
+
return;
|
|
77
83
|
if (this.awareness && this.awareness.getLocalState() !== null) {
|
|
78
84
|
this.#send(this.#frameAwareness([this.doc.clientID]), undefined);
|
|
79
85
|
}
|
|
80
|
-
this.#
|
|
86
|
+
if (this.#current(cycle))
|
|
87
|
+
this.#delivery.resume();
|
|
81
88
|
}
|
|
82
|
-
/**
|
|
83
|
-
|
|
84
|
-
this.#
|
|
85
|
-
|
|
89
|
+
/** Call when the transport is down. Keeps the queue, stops retransmits, and clears peers' presence. */
|
|
90
|
+
pause() {
|
|
91
|
+
if (this.#state.phase === "destroyed")
|
|
92
|
+
return;
|
|
93
|
+
this.#state = { phase: "unsynced", cycle: {} };
|
|
94
|
+
this.#delivery.pause();
|
|
86
95
|
if (this.awareness) {
|
|
87
|
-
const remote = [...this.awareness.getStates().keys()].filter(
|
|
96
|
+
const remote = [...this.awareness.getStates().keys()].filter(c => c !== this.doc.clientID);
|
|
88
97
|
if (remote.length)
|
|
89
98
|
removeAwarenessStates(this.awareness, remote, this);
|
|
90
99
|
}
|
|
@@ -96,23 +105,13 @@ export class YProtocolSession {
|
|
|
96
105
|
* waiting for the awareness timeout. A no-op when there's no local state.
|
|
97
106
|
*/
|
|
98
107
|
removeLocalAwareness() {
|
|
99
|
-
if (this.awareness && this.awareness.getLocalState() !== null) {
|
|
108
|
+
if (this.#state.phase !== "destroyed" && this.awareness && this.awareness.getLocalState() !== null) {
|
|
100
109
|
this.awareness.setLocalState(null); // fires "update" -> sends the removal frame
|
|
101
110
|
}
|
|
102
111
|
}
|
|
103
|
-
/**
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
* unhealable causal gap after repeated resyncs). The queue is pruned either
|
|
107
|
-
* way — retransmitting an unhealable update would loop forever — but a
|
|
108
|
-
* dropped settle is surfaced via onError ("ack-dropped") so the app can warn
|
|
109
|
-
* or reload instead of silently reporting synced over lost data.
|
|
110
|
-
*/
|
|
111
|
-
ack(id, dropped = false) {
|
|
112
|
-
this.#delivery.onAck(id);
|
|
113
|
-
if (dropped) {
|
|
114
|
-
this.#onError(new Error(`server dropped update ${id} as an unhealable causal gap; it was settled but NOT recorded`), "ack-dropped");
|
|
115
|
-
}
|
|
112
|
+
/** A reliable-delivery `{ ack: id }` envelope arrived. */
|
|
113
|
+
acknowledge(id) {
|
|
114
|
+
this.#delivery.acknowledge(id);
|
|
116
115
|
}
|
|
117
116
|
/**
|
|
118
117
|
* Apply an update without treating it as a local edit, so it isn't queued for
|
|
@@ -124,11 +123,12 @@ export class YProtocolSession {
|
|
|
124
123
|
* keystroke becomes an outbound frame), so a bare `Y.applyUpdate(doc, update)`
|
|
125
124
|
* would look like a local edit and get echoed back on the next connect. Going
|
|
126
125
|
* through here applies under the session's own origin, which the outbound
|
|
127
|
-
* filter skips. Safe to call before `
|
|
126
|
+
* filter skips. Safe to call before `resume()`: the state folds into the
|
|
128
127
|
* SyncStep1 handshake instead of being re-sent.
|
|
129
128
|
*/
|
|
130
129
|
applyRemoteUpdate(update) {
|
|
131
|
-
|
|
130
|
+
if (this.#state.phase !== "destroyed")
|
|
131
|
+
applyUpdate(this.doc, update, this);
|
|
132
132
|
}
|
|
133
133
|
/**
|
|
134
134
|
* Decode and apply one incoming binary protocol frame (document sync or
|
|
@@ -136,21 +136,27 @@ export class YProtocolSession {
|
|
|
136
136
|
* SyncStep1), or null if there's nothing to send.
|
|
137
137
|
*/
|
|
138
138
|
receive(frame) {
|
|
139
|
+
if (this.#state.phase === "destroyed")
|
|
140
|
+
return null;
|
|
141
|
+
const { cycle } = this.#state;
|
|
139
142
|
// A malformed/truncated frame must never take down the transport callback:
|
|
140
143
|
// decode + apply defensively, drop the frame on error, keep the session live.
|
|
141
144
|
try {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return null;
|
|
145
|
+
if (!validateFrame(frame))
|
|
146
|
+
return null; // a y-protocols type yrby doesn't use
|
|
145
147
|
const decoder = decoding.createDecoder(frame);
|
|
146
148
|
const encoder = encoding.createEncoder();
|
|
147
149
|
const type = decoding.readVarUint(decoder);
|
|
148
150
|
switch (type) {
|
|
149
151
|
case MessageType.Sync: {
|
|
150
152
|
encoding.writeVarUint(encoder, MessageType.Sync);
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
this.#
|
|
153
|
+
// y-protocols catches a failing update itself and reports it through this handler.
|
|
154
|
+
const report = (error) => { if (this.#current(cycle))
|
|
155
|
+
this.#onError(error, "receive"); };
|
|
156
|
+
const syncType = readSyncMessage(decoder, encoder, this.doc, this, report);
|
|
157
|
+
if (syncType === messageYjsSyncStep2 && this.#current(cycle)) {
|
|
158
|
+
this.#state = { phase: "synced", cycle };
|
|
159
|
+
}
|
|
154
160
|
break;
|
|
155
161
|
}
|
|
156
162
|
case MessageType.Awareness:
|
|
@@ -158,22 +164,29 @@ export class YProtocolSession {
|
|
|
158
164
|
applyAwarenessUpdate(this.awareness, decoding.readVarUint8Array(decoder), this);
|
|
159
165
|
break;
|
|
160
166
|
default:
|
|
161
|
-
return null; //
|
|
167
|
+
return null; // unreachable, since validateFrame accepts only the two types above
|
|
162
168
|
}
|
|
163
|
-
return encoding.length(encoder) > 1 ? encoding.toUint8Array(encoder) : null;
|
|
169
|
+
return this.#current(cycle) && encoding.length(encoder) > 1 ? encoding.toUint8Array(encoder) : null;
|
|
164
170
|
}
|
|
165
171
|
catch (error) {
|
|
166
|
-
this.#
|
|
172
|
+
if (this.#current(cycle))
|
|
173
|
+
this.#onError(error, "receive");
|
|
167
174
|
return null;
|
|
168
175
|
}
|
|
169
176
|
}
|
|
170
177
|
/** Detach doc/awareness listeners and stop retransmits. */
|
|
171
178
|
destroy() {
|
|
179
|
+
if (this.#state.phase === "destroyed")
|
|
180
|
+
return;
|
|
181
|
+
this.#state = { phase: "destroyed" };
|
|
172
182
|
this.doc.off("update", this.#onDocUpdate);
|
|
173
183
|
if (this.awareness && this.#onAwarenessUpdate)
|
|
174
184
|
this.awareness.off("update", this.#onAwarenessUpdate);
|
|
175
185
|
this.#delivery.destroy();
|
|
176
186
|
}
|
|
187
|
+
#current(cycle) {
|
|
188
|
+
return this.#state.phase !== "destroyed" && this.#state.cycle === cycle;
|
|
189
|
+
}
|
|
177
190
|
#frameSyncStep1() {
|
|
178
191
|
const e = encoding.createEncoder();
|
|
179
192
|
encoding.writeVarUint(e, MessageType.Sync);
|
|
@@ -192,53 +205,45 @@ export class YProtocolSession {
|
|
|
192
205
|
encoding.writeVarUint8Array(e, encodeAwarenessUpdate(this.awareness, clients));
|
|
193
206
|
return encoding.toUint8Array(e);
|
|
194
207
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
default:
|
|
233
|
-
return null; // a y-protocols type yrby doesn't speak: ignore
|
|
234
|
-
}
|
|
235
|
-
// This protocol is one message per frame. Anything left after a complete
|
|
236
|
-
// message is malformed (trailing garbage, or low-level packed messages whose
|
|
237
|
-
// tail we'd silently drop), so reject it before mutating local state.
|
|
238
|
-
if (decoding.hasContent(decoder)) {
|
|
239
|
-
throw new Error("frame has trailing bytes after a complete message");
|
|
240
|
-
}
|
|
241
|
-
return type;
|
|
208
|
+
}
|
|
209
|
+
// Checks a frame's structure before anything is applied, so a truncated or
|
|
210
|
+
// padded frame changes nothing. Returns false for a frame type yrby ignores
|
|
211
|
+
// (auth, query-awareness) and throws for a malformed one. Yjs checks the
|
|
212
|
+
// contents of an update itself when applying it.
|
|
213
|
+
function validateFrame(frame) {
|
|
214
|
+
const decoder = decoding.createDecoder(frame);
|
|
215
|
+
const type = decoding.readVarUint(decoder);
|
|
216
|
+
if (type === MessageType.Sync) {
|
|
217
|
+
// Every sync message is a subtype followed by one length-prefixed payload.
|
|
218
|
+
decoding.readVarUint(decoder);
|
|
219
|
+
decoding.readVarUint8Array(decoder);
|
|
220
|
+
}
|
|
221
|
+
else if (type === MessageType.Awareness) {
|
|
222
|
+
validateAwareness(decoding.readVarUint8Array(decoder));
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
// This protocol is one message per frame. Anything left after a complete
|
|
228
|
+
// message is malformed (trailing garbage, or low-level packed messages whose
|
|
229
|
+
// tail we'd silently drop).
|
|
230
|
+
if (decoding.hasContent(decoder))
|
|
231
|
+
throw new Error("frame has trailing bytes after a complete message");
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
// applyAwarenessUpdate mutates state entry by entry and notifies listeners
|
|
235
|
+
// only at the end, so a bad entry mid-payload would leave earlier entries
|
|
236
|
+
// applied with no event fired. Reading every entry first makes the real apply
|
|
237
|
+
// infallible and catches trailing bytes inside the payload.
|
|
238
|
+
function validateAwareness(payload) {
|
|
239
|
+
const decoder = decoding.createDecoder(payload);
|
|
240
|
+
const count = decoding.readVarUint(decoder);
|
|
241
|
+
for (let i = 0; i < count; i++) {
|
|
242
|
+
decoding.readVarUint(decoder); // clientID
|
|
243
|
+
decoding.readVarUint(decoder); // clock
|
|
244
|
+
JSON.parse(decoding.readVarString(decoder)); // state (null on removal)
|
|
242
245
|
}
|
|
246
|
+
if (decoding.hasContent(decoder))
|
|
247
|
+
throw new Error("awareness payload has trailing bytes");
|
|
243
248
|
}
|
|
244
249
|
//# sourceMappingURL=y_protocol_session.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"y_protocol_session.js","sourceRoot":"","sources":["../src/y_protocol_session.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,kFAAkF;AAClF,2EAA2E;AAC3E,gFAAgF;AAChF,uEAAuE;AACvE,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"y_protocol_session.js","sourceRoot":"","sources":["../src/y_protocol_session.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yrby-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "JavaScript client for the yrby y-websocket protocol: a ready-made ActionCable/AnyCable provider, a transport-agnostic protocol session (sync steps, encode/decode, awareness), and a reliable-delivery core (ack-tracked queue, sync-since-last-ack, retransmit + reconnect replay). Written in TypeScript with bundled types; ESM + CommonJS, usable from plain JS.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -36,6 +36,16 @@
|
|
|
36
36
|
"types": "./dist/cjs/base64.d.ts",
|
|
37
37
|
"default": "./dist/cjs/base64.js"
|
|
38
38
|
}
|
|
39
|
+
},
|
|
40
|
+
"./element": {
|
|
41
|
+
"import": {
|
|
42
|
+
"types": "./dist/document_element.d.ts",
|
|
43
|
+
"default": "./dist/document_element.js"
|
|
44
|
+
},
|
|
45
|
+
"require": {
|
|
46
|
+
"types": "./dist/cjs/document_element.d.ts",
|
|
47
|
+
"default": "./dist/cjs/document_element.js"
|
|
48
|
+
}
|
|
39
49
|
}
|
|
40
50
|
},
|
|
41
51
|
"files": [
|
|
@@ -47,7 +57,10 @@
|
|
|
47
57
|
"build": "npm run clean && tsc && tsc -p tsconfig.cjs.json && node -e \"require('fs').writeFileSync('dist/cjs/package.json', JSON.stringify({ type: 'commonjs' }) + '\\n')\"",
|
|
48
58
|
"typecheck": "tsc --noEmit",
|
|
49
59
|
"prepack": "npm run build",
|
|
50
|
-
"test": "npm run build && node --test"
|
|
60
|
+
"test": "npm run build && node --test --test-timeout=30000",
|
|
61
|
+
"test:browser": "node browser/run.mjs",
|
|
62
|
+
"test:browser:turbolinks": "node browser/run_turbolinks.mjs",
|
|
63
|
+
"test:browser:collaboration": "node browser/run_collaboration.mjs"
|
|
51
64
|
},
|
|
52
65
|
"license": "MIT",
|
|
53
66
|
"author": "JP Camara <jp@jpcamara.com>",
|
|
@@ -73,8 +86,9 @@
|
|
|
73
86
|
"access": "public"
|
|
74
87
|
},
|
|
75
88
|
"peerDependencies": {
|
|
76
|
-
"
|
|
77
|
-
"y-protocols": "^1.0.5"
|
|
89
|
+
"@rails/actioncable": ">= 7.1",
|
|
90
|
+
"y-protocols": "^1.0.5",
|
|
91
|
+
"yjs": "^13.6.0"
|
|
78
92
|
},
|
|
79
93
|
"peerDependenciesMeta": {
|
|
80
94
|
"yjs": {
|
|
@@ -82,14 +96,23 @@
|
|
|
82
96
|
},
|
|
83
97
|
"y-protocols": {
|
|
84
98
|
"optional": true
|
|
99
|
+
},
|
|
100
|
+
"@rails/actioncable": {
|
|
101
|
+
"optional": true
|
|
85
102
|
}
|
|
86
103
|
},
|
|
87
104
|
"dependencies": {
|
|
88
105
|
"lib0": "^0.2.117"
|
|
89
106
|
},
|
|
90
107
|
"devDependencies": {
|
|
91
|
-
"
|
|
108
|
+
"@anycable/web": "^1.1.1",
|
|
109
|
+
"@hotwired/turbo": "^8.0.23",
|
|
110
|
+
"@rails/actioncable": "^8.1.301",
|
|
111
|
+
"agent-browser": "^0.28.0",
|
|
112
|
+
"esbuild": "^0.25.12",
|
|
113
|
+
"turbolinks": "^5.2.0",
|
|
114
|
+
"typescript": "^5.6.0",
|
|
92
115
|
"y-protocols": "^1.0.5",
|
|
93
|
-
"
|
|
116
|
+
"yjs": "^13.6.0"
|
|
94
117
|
}
|
|
95
118
|
}
|