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
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
// Holds a document for the application, independently of editors and page
|
|
2
|
+
// navigation.
|
|
3
|
+
//
|
|
4
|
+
// A session remains open while an editor is attached or the server has not yet
|
|
5
|
+
// acknowledged some of its edits, and it closes itself when neither is true.
|
|
6
|
+
// When the server rejects the subscription, the session tries the descriptor's
|
|
7
|
+
// refresh URL once if it has one. If there is no URL, the refresh fails, or the
|
|
8
|
+
// server rejects the new grant, the session blocks. Blocking releases its
|
|
9
|
+
// editors and keeps its queued work in memory until the application calls
|
|
10
|
+
// retry() or discard().
|
|
11
|
+
import * as Y from "yjs";
|
|
12
|
+
import { uuidv4 } from "lib0/random";
|
|
13
|
+
import { ActionCableProvider } from "./actioncable_provider.js";
|
|
14
|
+
// Each phase sets the state apps see, whether a new lease connects right away,
|
|
15
|
+
// and which transitions are allowed. A new lease does not connect while the
|
|
16
|
+
// session is blocked or waiting for a refreshed grant. Transitions that aren't
|
|
17
|
+
// listed are ignored.
|
|
18
|
+
const PHASES = {
|
|
19
|
+
open: { state: "open", connects: true, on: { refresh: "refreshing", block: "blocked", close: "closed" } },
|
|
20
|
+
refreshing: { state: "open", connects: false, on: { renew: "renewed", block: "blocked", close: "closed" } },
|
|
21
|
+
renewed: { state: "open", connects: true, on: { accept: "open", block: "blocked", close: "closed" } },
|
|
22
|
+
blocked: { state: "blocked", connects: false, on: { retry: "open", close: "closed" } },
|
|
23
|
+
closed: { state: "closed", connects: false, on: {} },
|
|
24
|
+
};
|
|
25
|
+
// Without a limit, a refresh request that never returns would leave the
|
|
26
|
+
// session offline and stuck with its editors attached. After this long, the
|
|
27
|
+
// session blocks.
|
|
28
|
+
const REFRESH_TIMEOUT_MS = 15_000;
|
|
29
|
+
const DEFAULT_CHANNEL = "Y::DocumentChannel";
|
|
30
|
+
const stores = new WeakMap();
|
|
31
|
+
/** The identity of the document a descriptor names. Matching keys share a session. */
|
|
32
|
+
export function documentKey(descriptor) {
|
|
33
|
+
return JSON.stringify([descriptor.channel || DEFAULT_CHANNEL, descriptor.grant, descriptor.name]);
|
|
34
|
+
}
|
|
35
|
+
// Only the factory may create a store for a consumer.
|
|
36
|
+
const storeToken = Symbol("storeToken");
|
|
37
|
+
// Not exported, so only the store can acquire leases.
|
|
38
|
+
const attachLease = Symbol("attachLease");
|
|
39
|
+
// Not exported, so only a session can publish store changes.
|
|
40
|
+
const notifyStoreChange = Symbol("notifyStoreChange");
|
|
41
|
+
/** Holds one consumer's sessions and emits "change" with the session in `detail`. */
|
|
42
|
+
export class DocumentSessionStore extends EventTarget {
|
|
43
|
+
consumer;
|
|
44
|
+
static for(consumer) {
|
|
45
|
+
let store = stores.get(consumer);
|
|
46
|
+
if (!store)
|
|
47
|
+
stores.set(consumer, store = new DocumentSessionStore(consumer, storeToken));
|
|
48
|
+
return store;
|
|
49
|
+
}
|
|
50
|
+
#sessions = new Map();
|
|
51
|
+
constructor(consumer, token) {
|
|
52
|
+
super();
|
|
53
|
+
this.consumer = consumer;
|
|
54
|
+
if (token !== storeToken)
|
|
55
|
+
throw new Error("Use DocumentSessionStore.for(consumer)");
|
|
56
|
+
}
|
|
57
|
+
get sessions() { return [...this.#sessions.values()]; }
|
|
58
|
+
/** Acquire a lease on this document session, creating it on first use. */
|
|
59
|
+
acquire(input) {
|
|
60
|
+
if (!input.grant || !input.name)
|
|
61
|
+
throw new Error("A document requires a grant and name");
|
|
62
|
+
// The refresh URL is not part of the identity. Matching tuples share a
|
|
63
|
+
// session, which renews with the URL from the first acquisition.
|
|
64
|
+
const descriptor = Object.freeze({
|
|
65
|
+
channel: input.channel || DEFAULT_CHANNEL,
|
|
66
|
+
grant: input.grant,
|
|
67
|
+
name: input.name,
|
|
68
|
+
...(input.refresh ? { refresh: input.refresh } : {}),
|
|
69
|
+
});
|
|
70
|
+
const key = documentKey(descriptor);
|
|
71
|
+
let session = this.#sessions.get(key);
|
|
72
|
+
if (!session) {
|
|
73
|
+
session = new DocumentSession(this, descriptor, () => { this.#sessions.delete(key); });
|
|
74
|
+
this.#sessions.set(key, session);
|
|
75
|
+
}
|
|
76
|
+
return session[attachLease]();
|
|
77
|
+
}
|
|
78
|
+
[notifyStoreChange](session) {
|
|
79
|
+
this.dispatchEvent(new CustomEvent("change", { detail: session }));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** A caller's hold on a session. Release it when you're done with the session. */
|
|
83
|
+
export class DocumentLease {
|
|
84
|
+
session;
|
|
85
|
+
#controller = new AbortController();
|
|
86
|
+
#onRelease;
|
|
87
|
+
constructor(session, onRelease) {
|
|
88
|
+
this.session = session;
|
|
89
|
+
this.#onRelease = onRelease;
|
|
90
|
+
}
|
|
91
|
+
/** Aborts when the lease ends, including when the session blocks or is discarded. */
|
|
92
|
+
get signal() { return this.#controller.signal; }
|
|
93
|
+
setPresence(state) {
|
|
94
|
+
if (!this.signal.aborted)
|
|
95
|
+
this.session.provider.awareness.setLocalState(state);
|
|
96
|
+
}
|
|
97
|
+
/** Runs editor cleanup synchronously, before the final check for pending work. */
|
|
98
|
+
release() {
|
|
99
|
+
if (this.signal.aborted)
|
|
100
|
+
return;
|
|
101
|
+
this.#controller.abort();
|
|
102
|
+
this.#onRelease();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Application commands (acquire, retry, discard) take effect immediately.
|
|
106
|
+
// Provider callbacks and lease releases record what happened and request a
|
|
107
|
+
// settle, which runs after the current call stack finishes. Settle releases a
|
|
108
|
+
// blocked session's leases, closes a session nobody needs, and notifies store
|
|
109
|
+
// observers once.
|
|
110
|
+
export class DocumentSession {
|
|
111
|
+
store;
|
|
112
|
+
descriptor;
|
|
113
|
+
remove;
|
|
114
|
+
doc = new Y.Doc();
|
|
115
|
+
provider;
|
|
116
|
+
#lifecycle = { phase: "open" };
|
|
117
|
+
#leases = new Set();
|
|
118
|
+
// Leases held when the session blocked. Settle releases these and keeps any
|
|
119
|
+
// lease acquired while blocked for retry().
|
|
120
|
+
#retiring;
|
|
121
|
+
#error;
|
|
122
|
+
#dirty = false; // true until store observers are notified of the latest change
|
|
123
|
+
#settleQueued = false;
|
|
124
|
+
/** Create and hold sessions through DocumentSessionStore.acquire. */
|
|
125
|
+
constructor(store, descriptor, remove) {
|
|
126
|
+
this.store = store;
|
|
127
|
+
this.descriptor = descriptor;
|
|
128
|
+
this.remove = remove;
|
|
129
|
+
// The session uses one provider for its whole life. The provider queues
|
|
130
|
+
// edits while offline, so blocking and retrying only need to disconnect and
|
|
131
|
+
// connect.
|
|
132
|
+
this.provider = new ActionCableProvider(this.doc, store.consumer, descriptor.channel, {
|
|
133
|
+
grant: descriptor.grant,
|
|
134
|
+
name: descriptor.name,
|
|
135
|
+
// Ack sequence numbers are per session, not per record.
|
|
136
|
+
session_id: uuidv4(),
|
|
137
|
+
}, {
|
|
138
|
+
onError: (error, context) => {
|
|
139
|
+
if (context === "rejected")
|
|
140
|
+
this.#rejected(error);
|
|
141
|
+
else if (this.state !== "closed") {
|
|
142
|
+
this.#error = error;
|
|
143
|
+
this.#changed();
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
this.provider.awareness.setLocalState(null); // no cursor until an editor sets one
|
|
148
|
+
this.provider.onStatusChange(({ status }) => {
|
|
149
|
+
if (this.state !== "open")
|
|
150
|
+
return;
|
|
151
|
+
// The server accepted the subscription, so a renewed grant is valid.
|
|
152
|
+
if (status === "connected" || status === "synced")
|
|
153
|
+
this.#transition("accept");
|
|
154
|
+
this.#changed();
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
get error() { return this.#error; }
|
|
158
|
+
get hasPending() { return this.provider.hasPending; }
|
|
159
|
+
get whenSynced() { return this.provider.whenSynced; }
|
|
160
|
+
get state() { return PHASES[this.#lifecycle.phase].state; }
|
|
161
|
+
[attachLease]() {
|
|
162
|
+
if (this.state === "closed")
|
|
163
|
+
throw new Error("Cannot acquire a closed document session");
|
|
164
|
+
const lease = new DocumentLease(this, () => this.#release(lease));
|
|
165
|
+
this.#leases.add(lease);
|
|
166
|
+
this.#changed();
|
|
167
|
+
if (PHASES[this.#lifecycle.phase].connects)
|
|
168
|
+
this.#connect();
|
|
169
|
+
return lease;
|
|
170
|
+
}
|
|
171
|
+
#release(lease) {
|
|
172
|
+
if (!this.#leases.delete(lease))
|
|
173
|
+
return;
|
|
174
|
+
this.#changed();
|
|
175
|
+
if (!this.#leases.size)
|
|
176
|
+
this.provider.awareness.setLocalState(null);
|
|
177
|
+
}
|
|
178
|
+
/** Reconnects with this session's current grant, which is the original one or the last one a refresh returned. */
|
|
179
|
+
retry() {
|
|
180
|
+
if (this.#transition("retry"))
|
|
181
|
+
this.#connect();
|
|
182
|
+
}
|
|
183
|
+
/** Closes the session and drops pending work. The application calls this explicitly, because an ordinary detach keeps pending work. */
|
|
184
|
+
discard() { this.#close(); }
|
|
185
|
+
#changed() {
|
|
186
|
+
this.#dirty = true;
|
|
187
|
+
if (this.#settleQueued)
|
|
188
|
+
return;
|
|
189
|
+
this.#settleQueued = true;
|
|
190
|
+
queueMicrotask(() => this.#settle());
|
|
191
|
+
}
|
|
192
|
+
#settle() {
|
|
193
|
+
this.#settleQueued = false;
|
|
194
|
+
// If editor cleanup retries or blocks during #enforce, #changed queues
|
|
195
|
+
// another settle to handle it.
|
|
196
|
+
this.#enforce();
|
|
197
|
+
if (!this.#dirty)
|
|
198
|
+
return;
|
|
199
|
+
this.#dirty = false;
|
|
200
|
+
this.store[notifyStoreChange](this);
|
|
201
|
+
}
|
|
202
|
+
#enforce() {
|
|
203
|
+
if (this.state === "closed")
|
|
204
|
+
return;
|
|
205
|
+
if (this.state === "blocked") {
|
|
206
|
+
const retiring = this.#retiring;
|
|
207
|
+
this.#retiring = undefined;
|
|
208
|
+
// Leave the queue alone until retry() or discard().
|
|
209
|
+
for (const lease of retiring ?? [])
|
|
210
|
+
lease.release();
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (!this.#needed())
|
|
214
|
+
this.#close();
|
|
215
|
+
}
|
|
216
|
+
// Connect with the current grant, or resubscribe with a renewed one. The
|
|
217
|
+
// provider defers its own callbacks, so a failure here only blocks.
|
|
218
|
+
#connect(grant) {
|
|
219
|
+
try {
|
|
220
|
+
if (grant === undefined)
|
|
221
|
+
this.provider.connect();
|
|
222
|
+
else
|
|
223
|
+
this.provider.renew({ grant });
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
this.#transition("block", error);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
#needed() { return this.#leases.size > 0 || this.provider.hasPending; }
|
|
230
|
+
// The only method that changes the phase. It doesn't call out to other code,
|
|
231
|
+
// and #settle acts on the result.
|
|
232
|
+
#transition(event, error) {
|
|
233
|
+
const phase = PHASES[this.#lifecycle.phase].on[event];
|
|
234
|
+
if (!phase)
|
|
235
|
+
return false;
|
|
236
|
+
this.#lifecycle = { phase };
|
|
237
|
+
this.#retiring = phase === "blocked" ? [...this.#leases] : undefined;
|
|
238
|
+
if (event === "retry")
|
|
239
|
+
this.#error = undefined;
|
|
240
|
+
else if (event === "block")
|
|
241
|
+
this.#error = error;
|
|
242
|
+
this.#changed();
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
#close() {
|
|
246
|
+
if (!this.#transition("close"))
|
|
247
|
+
return;
|
|
248
|
+
// Leave the store first so editor cleanup below can acquire a new session.
|
|
249
|
+
this.remove();
|
|
250
|
+
for (const lease of [...this.#leases])
|
|
251
|
+
lease.release();
|
|
252
|
+
this.provider.destroy();
|
|
253
|
+
this.doc.destroy();
|
|
254
|
+
}
|
|
255
|
+
// Try the refresh URL once per rejection. Block if the server rejects again
|
|
256
|
+
// while refreshing or rejects the renewed grant.
|
|
257
|
+
#rejected(error) {
|
|
258
|
+
const url = this.descriptor.refresh;
|
|
259
|
+
if (url && this.#transition("refresh"))
|
|
260
|
+
void this.#refresh(url, this.#lifecycle);
|
|
261
|
+
else
|
|
262
|
+
this.#transition("block", error);
|
|
263
|
+
}
|
|
264
|
+
async #refresh(url, attempt) {
|
|
265
|
+
let grant;
|
|
266
|
+
try {
|
|
267
|
+
grant = await fetchGrant(url);
|
|
268
|
+
}
|
|
269
|
+
catch (error) {
|
|
270
|
+
if (this.#lifecycle === attempt)
|
|
271
|
+
this.#transition("block", error);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
// A retry, discard, or block during the request takes precedence over it.
|
|
275
|
+
if (this.#lifecycle !== attempt)
|
|
276
|
+
return;
|
|
277
|
+
if (this.#transition("renew"))
|
|
278
|
+
this.#connect(grant);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
/** Ask the application for a new grant. Resolves to the grant or throws. */
|
|
282
|
+
async function fetchGrant(url) {
|
|
283
|
+
const response = await fetch(url, {
|
|
284
|
+
credentials: "same-origin",
|
|
285
|
+
headers: { Accept: "application/json" },
|
|
286
|
+
signal: AbortSignal.timeout(REFRESH_TIMEOUT_MS),
|
|
287
|
+
});
|
|
288
|
+
if (!response.ok)
|
|
289
|
+
throw new Error(`grant refresh failed: ${response.status}`);
|
|
290
|
+
const body = await response.json();
|
|
291
|
+
const grant = body?.grant;
|
|
292
|
+
if (typeof grant !== "string" || !grant)
|
|
293
|
+
throw new Error("grant refresh returned no grant");
|
|
294
|
+
return grant;
|
|
295
|
+
}
|
|
296
|
+
//# sourceMappingURL=document_session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document_session.js","sourceRoot":"","sources":["../src/document_session.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,4 +5,6 @@ export type { YProtocolSessionOptions } from "./y_protocol_session.js";
|
|
|
5
5
|
export { ActionCableProvider } from "./actioncable_provider.js";
|
|
6
6
|
export type { ActionCableProviderOptions, ProviderStatus, StatusEvent, CableConsumer, CableSubscription, } from "./actioncable_provider.js";
|
|
7
7
|
export { toBase64, fromBase64 } from "./base64.js";
|
|
8
|
+
export { DocumentSessionStore } from "./document_session.js";
|
|
9
|
+
export type { DocumentSession, DocumentLease, DocumentDescriptor, DocumentSessionState } from "./document_session.js";
|
|
8
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAI3E,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACxE,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAIvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,YAAY,EACV,0BAA0B,EAC1B,cAAc,EACd,WAAW,EACX,aAAa,EACb,iBAAiB,GAClB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAI3E,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACxE,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAIvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,YAAY,EACV,0BAA0B,EAC1B,cAAc,EACd,WAAW,EACX,aAAa,EACb,iBAAiB,GAClB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -8,4 +8,6 @@ export { YProtocolSession, MessageType } from "./y_protocol_session.js";
|
|
|
8
8
|
export { ActionCableProvider } from "./actioncable_provider.js";
|
|
9
9
|
// Optional base64 helpers for transports that carry frames as strings.
|
|
10
10
|
export { toBase64, fromBase64 } from "./base64.js";
|
|
11
|
+
// Document sessions, leased by editors or held by headless workflows.
|
|
12
|
+
export { DocumentSessionStore } from "./document_session.js";
|
|
11
13
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,6DAA6D;AAC7D,6CAA6C;AAC7C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGxE,6DAA6D;AAC7D,iEAAiE;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAShE,uEAAuE;AACvE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,6DAA6D;AAC7D,6CAA6C;AAC7C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGxE,6DAA6D;AAC7D,iEAAiE;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAShE,uEAAuE;AACvE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEnD,sEAAsE;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/reliable_sync.d.ts
CHANGED
|
@@ -14,46 +14,33 @@ export interface ReliableSyncOptions {
|
|
|
14
14
|
setInterval?: (handler: () => void, ms: number) => TimerHandle;
|
|
15
15
|
clearInterval?: (handle: TimerHandle) => void;
|
|
16
16
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
/** One queued update and the sequence number an ack must reach to remove it. */
|
|
18
|
+
export interface Pending {
|
|
19
|
+
readonly seq: number;
|
|
20
|
+
readonly update: Uint8Array;
|
|
20
21
|
}
|
|
21
22
|
export declare class ReliableSync {
|
|
22
23
|
#private;
|
|
23
|
-
/** Unacked local updates, in order. */
|
|
24
|
-
pending: Pending[];
|
|
25
24
|
constructor(opts: ReliableSyncOptions);
|
|
25
|
+
/** A snapshot of unacknowledged local updates, oldest first. Editing it does not change the queue. */
|
|
26
|
+
get pending(): readonly Pending[];
|
|
26
27
|
/** True while there are unacknowledged local updates. */
|
|
27
28
|
get hasPending(): boolean;
|
|
28
|
-
/**
|
|
29
|
-
* Record a local document update. It is queued and the unacked tail is
|
|
30
|
-
* flushed; the update remains retained until the server acknowledges it.
|
|
31
|
-
*/
|
|
29
|
+
/** Queue a local update and, while connected, send the tail. Ignored after destroy(). */
|
|
32
30
|
enqueue(update: Uint8Array): void;
|
|
33
31
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*/
|
|
38
|
-
flush(): void;
|
|
39
|
-
/**
|
|
40
|
-
* Confirm delivery up to `id`: prune every queued update with seq <= id.
|
|
41
|
-
* Acks arrive over the wire, so validate before pruning. A malformed value
|
|
42
|
-
* (NaN/string/negative) or an impossible future id must not silently drop the
|
|
43
|
-
* queue; invalid acks are ignored.
|
|
44
|
-
*/
|
|
45
|
-
onAck(id: number): void;
|
|
46
|
-
/** Transport (re)connected: replay the unacked tail and resume retransmits. */
|
|
47
|
-
onConnect(): void;
|
|
48
|
-
/** Transport dropped: keep the queue (for reconnect replay), pause the timer. */
|
|
49
|
-
onDisconnect(): void;
|
|
50
|
-
/**
|
|
51
|
-
* One retransmit tick. Exposed for deterministic testing; normally driven by
|
|
52
|
-
* the internal timer.
|
|
32
|
+
* Confirm delivery through `id`, removing every queued update with
|
|
33
|
+
* seq <= id. Acks come off the wire, so ignore a malformed value or an id
|
|
34
|
+
* beyond anything sent.
|
|
53
35
|
*/
|
|
54
|
-
|
|
55
|
-
/**
|
|
36
|
+
acknowledge(id: number): void;
|
|
37
|
+
/** Call when the transport is up. Replays the tail and keeps retransmitting until it is acknowledged. */
|
|
38
|
+
resume(): void;
|
|
39
|
+
/** Call when the transport is down. Keeps the queue and stops retransmitting. */
|
|
40
|
+
pause(): void;
|
|
41
|
+
/** Send the tail again if anything is unacknowledged. The internal timer calls this, and a host with its own scheduler can too. */
|
|
42
|
+
retransmit(): void;
|
|
43
|
+
/** Stop the timer and drop the queue. Later enqueues are ignored. */
|
|
56
44
|
destroy(): void;
|
|
57
45
|
}
|
|
58
|
-
export {};
|
|
59
46
|
//# sourceMappingURL=reliable_sync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reliable_sync.d.ts","sourceRoot":"","sources":["../src/reliable_sync.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reliable_sync.d.ts","sourceRoot":"","sources":["../src/reliable_sync.ts"],"names":[],"mappings":"AAmBA,oEAAoE;AACpE,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC;AAElC,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,IAAI,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,gFAAgF;IAChF,KAAK,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,UAAU,CAAC;IAC7C,2EAA2E;IAC3E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,WAAW,CAAC;IAC/D,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;CAC/C;AAED,gFAAgF;AAChF,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC7B;AASD,qBAAa,YAAY;;gBAkBX,IAAI,EAAE,mBAAmB;IAgBrC,sGAAsG;IACtG,IAAI,OAAO,IAAI,SAAS,OAAO,EAAE,CAEhC;IAED,yDAAyD;IACzD,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,yFAAyF;IACzF,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAOjC;;;;OAIG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAQ7B,yGAAyG;IACzG,MAAM,IAAI,IAAI;IAQd,iFAAiF;IACjF,KAAK,IAAI,IAAI;IAOb,mIAAmI;IACnI,UAAU,IAAI,IAAI;IAIlB,qEAAqE;IACrE,OAAO,IAAI,IAAI;CAwDhB"}
|