yrby-client 0.5.0 → 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 +236 -36
- package/dist/actioncable_provider.d.ts +18 -11
- package/dist/actioncable_provider.d.ts.map +1 -1
- package/dist/actioncable_provider.js +286 -178
- package/dist/actioncable_provider.js.map +1 -1
- package/dist/cjs/actioncable_provider.d.ts +18 -11
- package/dist/cjs/actioncable_provider.js +287 -179
- 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 +6 -6
- package/dist/cjs/y_protocol_session.js +96 -81
- 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 +6 -6
- package/dist/y_protocol_session.d.ts.map +1 -1
- package/dist/y_protocol_session.js +96 -81
- package/dist/y_protocol_session.js.map +1 -1
- package/package.json +29 -6
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
// the server's persistence/ack path.
|
|
10
10
|
//
|
|
11
11
|
// The constructor does not auto-connect: wire up your editor binding first, then
|
|
12
|
-
// call `connect()`. Watch the connection with `onStatusChange(({ status }) => ...)`
|
|
13
|
-
// or the `status`
|
|
12
|
+
// call `connect()`. Watch the connection with `onStatusChange(({ status, pending }) => ...)`
|
|
13
|
+
// or the `status` and `hasPending` getters. Editors that must not bind before the first sync
|
|
14
14
|
// can `await provider.whenSynced` after connect(). On `disconnect()`/`destroy()`,
|
|
15
15
|
// and on browser `pagehide`, the provider broadcasts a presence removal so peers
|
|
16
16
|
// drop our cursor right away instead of waiting for the awareness timeout.
|
|
@@ -24,68 +24,58 @@ export class ActionCableProvider {
|
|
|
24
24
|
channelParams;
|
|
25
25
|
awareness;
|
|
26
26
|
session;
|
|
27
|
-
#
|
|
27
|
+
#state = { phase: "disconnected" };
|
|
28
28
|
#onError;
|
|
29
|
-
|
|
30
|
-
#
|
|
29
|
+
// The last event sent to listeners. A refresh notifies them only when a field differs.
|
|
30
|
+
#last = { status: "disconnected", pending: false };
|
|
31
31
|
#statusListeners = new Set();
|
|
32
|
-
#
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
#resolveSynced;
|
|
33
|
+
#onDocUpdate = () => this.#refreshStatus(); // a local edit may have made the queue non-empty
|
|
34
|
+
#page = null;
|
|
35
|
+
/**
|
|
36
|
+
* Resolves once the document has first caught up with the server. Most
|
|
37
|
+
* editor bindings seed an empty document when they mount, so binding
|
|
38
|
+
* before the server's state arrives makes each client insert its own
|
|
39
|
+
* top-level node. Create the editor after this resolves:
|
|
40
|
+
*
|
|
41
|
+
* provider.connect();
|
|
42
|
+
* await provider.whenSynced;
|
|
43
|
+
* // now hand the doc to the editor binding
|
|
44
|
+
*
|
|
45
|
+
* It resolves on the first catch-up and remains resolved across later
|
|
46
|
+
* reconnects, even while `synced` is false during a re-handshake. Use
|
|
47
|
+
* `onStatusChange` to track the live connection. If the provider is
|
|
48
|
+
* destroyed before the first sync, it never resolves.
|
|
49
|
+
*/
|
|
50
|
+
whenSynced = new Promise((resolve) => { this.#resolveSynced = resolve; });
|
|
41
51
|
constructor(doc, consumer, channelName, channelParams = {}, opts = {}) {
|
|
42
52
|
this.doc = doc;
|
|
43
53
|
this.consumer = consumer;
|
|
44
54
|
this.channelName = channelName;
|
|
45
55
|
this.channelParams = channelParams;
|
|
46
|
-
|
|
47
|
-
this.#onError =
|
|
56
|
+
const onError = opts.onError ?? ((error, context) => console.warn(`[yrby] ${context}:`, error));
|
|
57
|
+
this.#onError = (error, context) => {
|
|
58
|
+
try {
|
|
59
|
+
onError(error, context);
|
|
60
|
+
}
|
|
61
|
+
catch (callbackError) {
|
|
62
|
+
console.warn("[yrby] onError callback failed:", callbackError, "while reporting:", error);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
this.awareness = new ProviderAwareness(doc, this.#onError);
|
|
48
66
|
this.session = new YProtocolSession(doc, {
|
|
49
67
|
awareness: this.awareness,
|
|
50
68
|
resendInterval: opts.resendInterval,
|
|
51
69
|
onError: this.#onError,
|
|
52
70
|
send: (frame, id) => this.#send(frame, id),
|
|
53
71
|
});
|
|
72
|
+
// Registered after the session's listener, so the queue already has the edit.
|
|
73
|
+
this.doc.on("update", this.#onDocUpdate);
|
|
54
74
|
}
|
|
55
75
|
/** True once the document has caught up with the server (received a SyncStep2). */
|
|
56
76
|
get synced() {
|
|
57
77
|
return this.session.synced;
|
|
58
78
|
}
|
|
59
|
-
/**
|
|
60
|
-
* Resolves once the document has first caught up with the server. Most
|
|
61
|
-
* editor bindings seed an empty document when they mount, so binding
|
|
62
|
-
* before the server's state arrives makes each client insert its own
|
|
63
|
-
* top-level node. Create the editor after this resolves:
|
|
64
|
-
*
|
|
65
|
-
* provider.connect();
|
|
66
|
-
* await provider.whenSynced;
|
|
67
|
-
* // now hand the doc to the editor binding
|
|
68
|
-
*
|
|
69
|
-
* Resolves immediately if the first catch-up has already happened, even
|
|
70
|
-
* while the transport is down (`synced` is false during a reconnect;
|
|
71
|
-
* whether the doc has ever synced does not change). It stays resolved
|
|
72
|
-
* across later reconnects; use `onStatusChange` to track the live
|
|
73
|
-
* connection. If the provider is destroyed before the first sync, the
|
|
74
|
-
* promise never settles.
|
|
75
|
-
*/
|
|
76
|
-
get whenSynced() {
|
|
77
|
-
this.#whenSynced ??= this.#everSynced
|
|
78
|
-
? Promise.resolve()
|
|
79
|
-
: new Promise((resolve) => {
|
|
80
|
-
const off = this.onStatusChange(({ status }) => {
|
|
81
|
-
if (status !== "synced")
|
|
82
|
-
return;
|
|
83
|
-
off();
|
|
84
|
-
resolve();
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
return this.#whenSynced;
|
|
88
|
-
}
|
|
89
79
|
/** True while there are unacknowledged local document updates in flight. */
|
|
90
80
|
get hasPending() {
|
|
91
81
|
return this.session.hasPending;
|
|
@@ -107,7 +97,7 @@ export class ActionCableProvider {
|
|
|
107
97
|
}
|
|
108
98
|
/** Current connection status. See {@link ProviderStatus}. */
|
|
109
99
|
get status() {
|
|
110
|
-
return this.#
|
|
100
|
+
return this.#computeStatus();
|
|
111
101
|
}
|
|
112
102
|
/** Subscribe to status changes. Returns an unsubscribe function. */
|
|
113
103
|
onStatusChange(listener) {
|
|
@@ -115,170 +105,288 @@ export class ActionCableProvider {
|
|
|
115
105
|
return () => this.#statusListeners.delete(listener);
|
|
116
106
|
}
|
|
117
107
|
connect() {
|
|
118
|
-
if (this.#
|
|
108
|
+
if (this.#destroying())
|
|
109
|
+
throw new Error("provider is destroyed");
|
|
110
|
+
if (this.#state.phase !== "disconnected")
|
|
119
111
|
return;
|
|
120
|
-
const
|
|
121
|
-
this.#
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
connected() {
|
|
152
|
-
provider.#connected = true;
|
|
153
|
-
provider.session.onConnect(); // handshake + replay the unacked tail
|
|
154
|
-
provider.#refreshStatus();
|
|
155
|
-
},
|
|
156
|
-
disconnected() {
|
|
157
|
-
provider.#connected = false;
|
|
158
|
-
provider.session.onDisconnect(); // pause retransmits, clear remote presence
|
|
159
|
-
provider.#refreshStatus(); // subscription still set -> "connecting" (retrying)
|
|
160
|
-
},
|
|
161
|
-
rejected() {
|
|
162
|
-
// The channel refused the subscription (auth, missing doc). Surface
|
|
163
|
-
// it and tear down — otherwise the provider sits at "connecting"
|
|
164
|
-
// forever, silently queueing edits. The app decides what's next.
|
|
165
|
-
provider.#onError(new Error("subscription rejected by the server"), "rejected");
|
|
166
|
-
provider.disconnect();
|
|
167
|
-
},
|
|
168
|
-
});
|
|
169
|
-
this.#installUnloadHandler();
|
|
170
|
-
this.#refreshStatus(); // -> "connecting"
|
|
171
|
-
}
|
|
172
|
-
disconnect() {
|
|
173
|
-
if (!this.#subscription)
|
|
112
|
+
const attempt = {};
|
|
113
|
+
this.#state = { phase: "subscribing", attempt };
|
|
114
|
+
// A consumer may invoke callbacks inside create(), before the subscription
|
|
115
|
+
// is installed, so on() defers those by one microtask.
|
|
116
|
+
const on = (callback) => (...args) => {
|
|
117
|
+
const run = () => { if (this.#active(attempt))
|
|
118
|
+
callback(...args); };
|
|
119
|
+
if (this.#state.phase === "subscribing")
|
|
120
|
+
queueMicrotask(run);
|
|
121
|
+
else
|
|
122
|
+
run();
|
|
123
|
+
};
|
|
124
|
+
let subscription;
|
|
125
|
+
try {
|
|
126
|
+
subscription = this.consumer.subscriptions.create({ channel: this.channelName, ...this.channelParams }, {
|
|
127
|
+
received: on((message) => this.#receive(message, attempt)),
|
|
128
|
+
connected: on(() => this.#connected()),
|
|
129
|
+
disconnected: on(() => this.#lost()),
|
|
130
|
+
rejected: on(() => this.#stop("reject")),
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
if (!this.#subscribing(attempt))
|
|
135
|
+
return;
|
|
136
|
+
this.#state = { phase: "disconnected" };
|
|
137
|
+
this.#refreshStatus();
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
// disconnect() or destroy() ran inside create().
|
|
141
|
+
if (!this.#subscribing(attempt)) {
|
|
142
|
+
this.#unsubscribe(subscription);
|
|
174
143
|
return;
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
this.session.removeLocalAwareness();
|
|
180
|
-
this.session.onDisconnect();
|
|
181
|
-
this.#connected = false;
|
|
182
|
-
this.#subscription = null;
|
|
183
|
-
this.#removeUnloadHandler();
|
|
184
|
-
// Universal teardown: both @rails/actioncable and @anycable/web subscriptions
|
|
185
|
-
// expose unsubscribe() (Rails' just calls consumer.subscriptions.remove(this)
|
|
186
|
-
// internally). @anycable has NO consumer.subscriptions.remove, so calling that
|
|
187
|
-
// would throw there.
|
|
188
|
-
queueMicrotask(() => sub.unsubscribe?.());
|
|
189
|
-
this.#refreshStatus(); // -> "disconnected"
|
|
144
|
+
}
|
|
145
|
+
this.#state = { phase: "connecting", attempt, subscription };
|
|
146
|
+
this.#watchPage();
|
|
147
|
+
this.#refreshStatus();
|
|
190
148
|
}
|
|
191
|
-
|
|
149
|
+
disconnect() { this.#stop("disconnect"); }
|
|
150
|
+
/**
|
|
151
|
+
* Resubscribes with updated channel params, such as a renewed grant. This
|
|
152
|
+
* replaces only the cable subscription and keeps the doc, the delivery
|
|
153
|
+
* queue, awareness, and this provider's ack route. Does nothing after
|
|
154
|
+
* destroy().
|
|
155
|
+
*/
|
|
156
|
+
renew(params) {
|
|
157
|
+
if (this.#destroying())
|
|
158
|
+
return;
|
|
159
|
+
Object.assign(this.channelParams, params);
|
|
192
160
|
this.disconnect();
|
|
193
|
-
this.
|
|
194
|
-
this.awareness.destroy(); // stops its reaper timer
|
|
195
|
-
this.#statusListeners.clear();
|
|
161
|
+
this.connect();
|
|
196
162
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
return "connecting";
|
|
202
|
-
return this.session.synced ? "synced" : "connected";
|
|
163
|
+
destroy() { this.#stop("destroy"); }
|
|
164
|
+
#destroying() {
|
|
165
|
+
const state = this.#state;
|
|
166
|
+
return state.phase === "destroyed" || (state.phase === "stopping" && state.reason === "destroy");
|
|
203
167
|
}
|
|
204
|
-
#
|
|
205
|
-
|
|
206
|
-
|
|
168
|
+
#subscribing(attempt) {
|
|
169
|
+
return this.#state.phase === "subscribing" && this.#state.attempt === attempt;
|
|
170
|
+
}
|
|
171
|
+
// Cable callbacks run only for a connecting or connected subscription.
|
|
172
|
+
#active(attempt) {
|
|
173
|
+
const state = this.#state;
|
|
174
|
+
return (state.phase === "connecting" || state.phase === "connected") && state.attempt === attempt;
|
|
175
|
+
}
|
|
176
|
+
// The cable callbacks below run only for the active attempt, which on() in
|
|
177
|
+
// connect() checks.
|
|
178
|
+
#connected() {
|
|
179
|
+
const state = this.#state;
|
|
180
|
+
if (state.phase !== "connecting")
|
|
181
|
+
return;
|
|
182
|
+
this.#state = { ...state, phase: "connected" };
|
|
183
|
+
this.session.resume();
|
|
184
|
+
this.#refreshStatus();
|
|
185
|
+
}
|
|
186
|
+
#lost() {
|
|
187
|
+
const state = this.#state;
|
|
188
|
+
if (state.phase !== "connecting" && state.phase !== "connected")
|
|
207
189
|
return;
|
|
208
|
-
this.#
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
for (const listener of this.#statusListeners)
|
|
212
|
-
listener({ status: next });
|
|
190
|
+
this.#state = { ...state, phase: "connecting" };
|
|
191
|
+
this.session.pause();
|
|
192
|
+
this.#refreshStatus();
|
|
213
193
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
194
|
+
#stop(reason) {
|
|
195
|
+
const state = this.#state;
|
|
196
|
+
if (state.phase === "destroyed")
|
|
197
|
+
return;
|
|
198
|
+
if (state.phase === "stopping") {
|
|
199
|
+
if (reason === "destroy")
|
|
200
|
+
state.reason = reason;
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (state.phase === "disconnected" && reason === "disconnect")
|
|
222
204
|
return;
|
|
223
|
-
|
|
224
|
-
|
|
205
|
+
let finalReason = reason;
|
|
206
|
+
if ("subscription" in state) {
|
|
207
|
+
const stopping = { ...state, phase: "stopping", reason };
|
|
208
|
+
this.#state = stopping;
|
|
209
|
+
this.#unwatchPage();
|
|
210
|
+
// From here the provider ignores the old subscription's callbacks, but the
|
|
211
|
+
// subscription can still send our presence removal before its deferred
|
|
212
|
+
// unsubscribe.
|
|
225
213
|
this.session.removeLocalAwareness();
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
if (
|
|
214
|
+
this.session.pause();
|
|
215
|
+
this.#unsubscribe(state.subscription);
|
|
216
|
+
if (this.#state !== stopping)
|
|
229
217
|
return;
|
|
230
|
-
|
|
231
|
-
|
|
218
|
+
finalReason = stopping.reason; // a destroy() during those calls upgrades it
|
|
219
|
+
}
|
|
220
|
+
const destroyed = finalReason === "destroy";
|
|
221
|
+
this.#state = { phase: destroyed ? "destroyed" : "disconnected" };
|
|
222
|
+
if (destroyed)
|
|
223
|
+
this.#destroyOwned();
|
|
224
|
+
else if (finalReason === "reject")
|
|
225
|
+
this.#onError(new Error("subscription rejected by the server"), "rejected");
|
|
226
|
+
this.#refreshStatus();
|
|
227
|
+
if (destroyed)
|
|
228
|
+
this.#statusListeners.clear();
|
|
229
|
+
}
|
|
230
|
+
#destroyOwned() {
|
|
231
|
+
this.session.destroy();
|
|
232
|
+
this.awareness.destroy();
|
|
233
|
+
this.doc.off("update", this.#onDocUpdate);
|
|
234
|
+
}
|
|
235
|
+
#unsubscribe(subscription) {
|
|
236
|
+
queueMicrotask(() => {
|
|
237
|
+
try {
|
|
238
|
+
subscription.unsubscribe?.();
|
|
232
239
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
240
|
+
catch (error) {
|
|
241
|
+
this.#onError(error, "unsubscribe");
|
|
242
|
+
}
|
|
243
|
+
});
|
|
237
244
|
}
|
|
238
|
-
#
|
|
239
|
-
if (
|
|
245
|
+
#receive(message, attempt) {
|
|
246
|
+
if (message && message.ack !== undefined) {
|
|
247
|
+
this.session.acknowledge(message.ack);
|
|
248
|
+
this.#refreshStatus();
|
|
240
249
|
return;
|
|
241
|
-
if (this.#onUnload) {
|
|
242
|
-
window.removeEventListener("pagehide", this.#onUnload);
|
|
243
|
-
this.#onUnload = null;
|
|
244
250
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
251
|
+
const awarenessPayload = message && message.awareness;
|
|
252
|
+
const payload = message && (awarenessPayload ?? message.update);
|
|
253
|
+
if (typeof payload !== "string")
|
|
254
|
+
return;
|
|
255
|
+
let frame;
|
|
256
|
+
try {
|
|
257
|
+
frame = fromBase64(payload);
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
this.#onError(error, "received");
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
if (awarenessPayload !== undefined && frame[0] !== MessageType.Awareness) {
|
|
264
|
+
this.#onError(new Error("awareness envelope carried a non-awareness frame"), "received");
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const reply = this.session.receive(frame);
|
|
268
|
+
// Applying the frame runs doc observers, which may have replaced the connection.
|
|
269
|
+
if (reply && this.#active(attempt))
|
|
270
|
+
this.#send(reply, undefined);
|
|
271
|
+
this.#refreshStatus();
|
|
272
|
+
}
|
|
273
|
+
#computeStatus() {
|
|
274
|
+
switch (this.#state.phase) {
|
|
275
|
+
case "subscribing":
|
|
276
|
+
case "connecting": return "connecting";
|
|
277
|
+
case "connected": return this.session.synced ? "synced" : "connected";
|
|
278
|
+
default: return "disconnected";
|
|
248
279
|
}
|
|
249
280
|
}
|
|
281
|
+
#refreshStatus() {
|
|
282
|
+
const status = this.#computeStatus();
|
|
283
|
+
const pending = this.hasPending;
|
|
284
|
+
if (status === this.#last.status && pending === this.#last.pending)
|
|
285
|
+
return;
|
|
286
|
+
const event = this.#last = { status, pending };
|
|
287
|
+
if (status === "synced")
|
|
288
|
+
this.#resolveSynced();
|
|
289
|
+
// A throwing listener is an application bug. Report it and continue so one
|
|
290
|
+
// bad listener can't stop the others or break the cable callback that
|
|
291
|
+
// triggered this refresh.
|
|
292
|
+
for (const listener of this.#statusListeners) {
|
|
293
|
+
if (this.#last !== event)
|
|
294
|
+
break; // a listener caused a newer transition
|
|
295
|
+
try {
|
|
296
|
+
listener({ status, pending });
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
this.#onError(error, "listener");
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// Handles presence across the page lifecycle. `pagehide` removes our cursor
|
|
304
|
+
// while the socket is still live, so peers drop it without waiting for the
|
|
305
|
+
// awareness timeout. A `pageshow` with `persisted` means the user came back
|
|
306
|
+
// through the bfcache, so we restore the cursor. Editor bindings set
|
|
307
|
+
// awareness only once at setup, so without this the user would return with
|
|
308
|
+
// no cursor.
|
|
309
|
+
#watchPage() {
|
|
310
|
+
if (typeof window === "undefined" || this.#page)
|
|
311
|
+
return;
|
|
312
|
+
let stashed = null;
|
|
313
|
+
const page = this.#page = {
|
|
314
|
+
hide: () => {
|
|
315
|
+
if (this.#page !== page)
|
|
316
|
+
return;
|
|
317
|
+
stashed = this.awareness.getLocalState();
|
|
318
|
+
this.session.removeLocalAwareness();
|
|
319
|
+
},
|
|
320
|
+
show: (event) => {
|
|
321
|
+
if (this.#page !== page || !event.persisted || !stashed)
|
|
322
|
+
return;
|
|
323
|
+
if (this.awareness.getLocalState() === null)
|
|
324
|
+
this.awareness.setLocalState(stashed);
|
|
325
|
+
stashed = null;
|
|
326
|
+
},
|
|
327
|
+
};
|
|
328
|
+
window.addEventListener("pagehide", this.#page.hide);
|
|
329
|
+
window.addEventListener("pageshow", this.#page.show);
|
|
330
|
+
}
|
|
331
|
+
#unwatchPage() {
|
|
332
|
+
if (!this.#page || typeof window === "undefined")
|
|
333
|
+
return;
|
|
334
|
+
const page = this.#page;
|
|
335
|
+
this.#page = null;
|
|
336
|
+
window.removeEventListener("pagehide", page.hide);
|
|
337
|
+
window.removeEventListener("pageshow", page.show);
|
|
338
|
+
}
|
|
250
339
|
// Send one raw protocol frame over the cable. Awareness frames are whispered
|
|
251
340
|
// when AnyCable exposes `subscription.whisper`; otherwise they fall back to a
|
|
252
341
|
// normal send. `id` (reliable doc updates) is tagged onto the envelope so the
|
|
253
342
|
// server can ack. A no-op while disconnected: reliable frames stay queued in
|
|
254
343
|
// the session and flush on the next connect().
|
|
255
344
|
#send(frame, id) {
|
|
256
|
-
const
|
|
257
|
-
if (!
|
|
345
|
+
const state = this.#state;
|
|
346
|
+
if (!("subscription" in state))
|
|
258
347
|
return;
|
|
259
|
-
const update = toBase64(frame);
|
|
260
348
|
const isAwareness = frame[0] === MessageType.Awareness;
|
|
349
|
+
if (state.phase === "stopping" && !isAwareness)
|
|
350
|
+
return;
|
|
351
|
+
const { subscription } = state;
|
|
352
|
+
const update = toBase64(frame);
|
|
261
353
|
// Route transport failures (sync throws, or @anycable/web's rejected
|
|
262
354
|
// promises) to onError instead of letting them escape into update
|
|
263
355
|
// handlers. A failed send is recoverable: reliable frames stay queued
|
|
264
|
-
// until acked, and awareness is best-effort anyway.
|
|
356
|
+
// until acked, and awareness is best-effort anyway. Failures from a
|
|
357
|
+
// subscription that has since been replaced go unreported.
|
|
358
|
+
const report = (error) => {
|
|
359
|
+
const current = this.#state;
|
|
360
|
+
if ("subscription" in current && current.subscription === subscription)
|
|
361
|
+
this.#onError(error, "send");
|
|
362
|
+
};
|
|
265
363
|
try {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
this.#observe(sub.send(payload));
|
|
364
|
+
const result = isAwareness && typeof subscription.whisper === "function"
|
|
365
|
+
? subscription.whisper({ awareness: update })
|
|
366
|
+
: subscription.send(id === undefined ? { update } : { update, id });
|
|
367
|
+
if (result instanceof Promise)
|
|
368
|
+
result.catch(report);
|
|
272
369
|
}
|
|
273
370
|
catch (error) {
|
|
274
|
-
|
|
371
|
+
report(error);
|
|
275
372
|
}
|
|
276
373
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
374
|
+
}
|
|
375
|
+
// Awareness runs application listeners during presence removal and destruction.
|
|
376
|
+
// A failing listener must not interrupt either one or leave the awareness timer
|
|
377
|
+
// running.
|
|
378
|
+
class ProviderAwareness extends Awareness {
|
|
379
|
+
onError;
|
|
380
|
+
constructor(doc, onError) {
|
|
381
|
+
super(doc);
|
|
382
|
+
this.onError = onError;
|
|
383
|
+
}
|
|
384
|
+
emit(...args) {
|
|
385
|
+
try {
|
|
386
|
+
super.emit(...args);
|
|
387
|
+
}
|
|
388
|
+
catch (error) {
|
|
389
|
+
this.onError(error, `awareness:${args[0]}`);
|
|
282
390
|
}
|
|
283
391
|
}
|
|
284
392
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actioncable_provider.js","sourceRoot":"","sources":["../src/actioncable_provider.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"actioncable_provider.js","sourceRoot":"","sources":["../src/actioncable_provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,9 +9,11 @@ import type { Doc } from "yjs";
|
|
|
9
9
|
* will retry shows as "connecting", not "disconnected".
|
|
10
10
|
*/
|
|
11
11
|
export type ProviderStatus = "connecting" | "connected" | "synced" | "disconnected";
|
|
12
|
-
/** Payload passed to onStatusChange listeners. */
|
|
12
|
+
/** Payload passed to onStatusChange listeners, which run when either field changes. */
|
|
13
13
|
export interface StatusEvent {
|
|
14
14
|
status: ProviderStatus;
|
|
15
|
+
/** True while local edits await the server's acknowledgment. */
|
|
16
|
+
pending: boolean;
|
|
15
17
|
}
|
|
16
18
|
/** The minimal slice of an ActionCable/AnyCable subscription this provider uses. */
|
|
17
19
|
export interface CableSubscription {
|
|
@@ -45,9 +47,6 @@ export declare class ActionCableProvider {
|
|
|
45
47
|
readonly channelParams: object;
|
|
46
48
|
readonly awareness: Awareness;
|
|
47
49
|
readonly session: YProtocolSession;
|
|
48
|
-
constructor(doc: Doc, consumer: CableConsumer, channelName: string, channelParams?: object, opts?: ActionCableProviderOptions);
|
|
49
|
-
/** True once the document has caught up with the server (received a SyncStep2). */
|
|
50
|
-
get synced(): boolean;
|
|
51
50
|
/**
|
|
52
51
|
* Resolves once the document has first caught up with the server. Most
|
|
53
52
|
* editor bindings seed an empty document when they mount, so binding
|
|
@@ -58,14 +57,15 @@ export declare class ActionCableProvider {
|
|
|
58
57
|
* await provider.whenSynced;
|
|
59
58
|
* // now hand the doc to the editor binding
|
|
60
59
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* connection. If the provider is destroyed before the first sync, the
|
|
66
|
-
* promise never settles.
|
|
60
|
+
* It resolves on the first catch-up and remains resolved across later
|
|
61
|
+
* reconnects, even while `synced` is false during a re-handshake. Use
|
|
62
|
+
* `onStatusChange` to track the live connection. If the provider is
|
|
63
|
+
* destroyed before the first sync, it never resolves.
|
|
67
64
|
*/
|
|
68
|
-
|
|
65
|
+
readonly whenSynced: Promise<void>;
|
|
66
|
+
constructor(doc: Doc, consumer: CableConsumer, channelName: string, channelParams?: object, opts?: ActionCableProviderOptions);
|
|
67
|
+
/** True once the document has caught up with the server (received a SyncStep2). */
|
|
68
|
+
get synced(): boolean;
|
|
69
69
|
/** True while there are unacknowledged local document updates in flight. */
|
|
70
70
|
get hasPending(): boolean;
|
|
71
71
|
/**
|
|
@@ -87,5 +87,12 @@ export declare class ActionCableProvider {
|
|
|
87
87
|
onStatusChange(listener: (event: StatusEvent) => void): () => void;
|
|
88
88
|
connect(): void;
|
|
89
89
|
disconnect(): void;
|
|
90
|
+
/**
|
|
91
|
+
* Resubscribes with updated channel params, such as a renewed grant. This
|
|
92
|
+
* replaces only the cable subscription and keeps the doc, the delivery
|
|
93
|
+
* queue, awareness, and this provider's ack route. Does nothing after
|
|
94
|
+
* destroy().
|
|
95
|
+
*/
|
|
96
|
+
renew(params: object): void;
|
|
90
97
|
destroy(): void;
|
|
91
98
|
}
|