@abraca/dabra 0.4.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/dist/abracadabra-provider.cjs +10 -18
- package/dist/abracadabra-provider.cjs.map +1 -1
- package/dist/abracadabra-provider.esm.js +10 -18
- package/dist/abracadabra-provider.esm.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/AbracadabraProvider.ts +13 -26
- package/src/OfflineStore.ts +11 -5
package/dist/index.d.ts
CHANGED
|
@@ -933,6 +933,7 @@ declare class OfflineStore {
|
|
|
933
933
|
* per-server, preventing cross-server data contamination.
|
|
934
934
|
*/
|
|
935
935
|
constructor(docId: string, serverOrigin?: string);
|
|
936
|
+
private dbPromise;
|
|
936
937
|
private getDb;
|
|
937
938
|
persistUpdate(update: Uint8Array): Promise<void>;
|
|
938
939
|
getPendingUpdates(): Promise<Uint8Array[]>;
|
package/package.json
CHANGED
|
@@ -188,12 +188,16 @@ export class AbracadabraProvider extends HocuspocusProvider {
|
|
|
188
188
|
private async _initFromOfflineStore(): Promise<void> {
|
|
189
189
|
if (!this.offlineStore) return;
|
|
190
190
|
|
|
191
|
-
|
|
191
|
+
// Fetch snapshot and pending updates in parallel — each call opens the
|
|
192
|
+
// IDB database, so running them concurrently roughly halves the latency.
|
|
193
|
+
const [snapshot, pending] = await Promise.all([
|
|
194
|
+
this.offlineStore.getDocSnapshot().catch(() => null),
|
|
195
|
+
this.offlineStore.getPendingUpdates().catch(() => []),
|
|
196
|
+
]);
|
|
197
|
+
|
|
192
198
|
if (snapshot) {
|
|
193
199
|
Y.applyUpdate(this.document, snapshot, this.offlineStore);
|
|
194
200
|
}
|
|
195
|
-
|
|
196
|
-
const pending = await this.offlineStore.getPendingUpdates().catch(() => []);
|
|
197
201
|
for (const update of pending) {
|
|
198
202
|
Y.applyUpdate(this.document, update, this.offlineStore);
|
|
199
203
|
}
|
|
@@ -417,29 +421,12 @@ export class AbracadabraProvider extends HocuspocusProvider {
|
|
|
417
421
|
private async _doLoadChild(childId: string): Promise<AbracadabraProvider> {
|
|
418
422
|
const childDoc = new Y.Doc({ guid: childId });
|
|
419
423
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
const onRegistered = ({ childId: cid }: onSubdocRegisteredParameters) => {
|
|
427
|
-
if (cid === childId) {
|
|
428
|
-
this.off("subdocRegistered", onRegistered);
|
|
429
|
-
resolve();
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
|
-
this.on("subdocRegistered", onRegistered);
|
|
433
|
-
this.registerSubdoc(childDoc);
|
|
434
|
-
// Fallback: don't block forever if the server is slow or the
|
|
435
|
-
// doc was already registered in a previous session.
|
|
436
|
-
setTimeout(resolve, 3000);
|
|
437
|
-
});
|
|
438
|
-
} else {
|
|
439
|
-
// Offline: queue the registration for replay on reconnect and proceed
|
|
440
|
-
// immediately so the child provider can populate from its local store.
|
|
441
|
-
this.registerSubdoc(childDoc);
|
|
442
|
-
}
|
|
424
|
+
// Fire-and-forget: tell the server this child belongs to the parent.
|
|
425
|
+
// The child provider's own WebSocket handshake (TCP + TLS + auth) is
|
|
426
|
+
// slow enough that the server will have processed the registration
|
|
427
|
+
// before the child's first SyncStep1 arrives. In the rare race the
|
|
428
|
+
// child's built-in reconnect logic retries automatically.
|
|
429
|
+
this.registerSubdoc(childDoc);
|
|
443
430
|
|
|
444
431
|
// Each child gets its own WebSocket connection. Omitting
|
|
445
432
|
// websocketProvider lets HocuspocusProvider create one automatically
|
package/src/OfflineStore.ts
CHANGED
|
@@ -77,12 +77,18 @@ export class OfflineStore {
|
|
|
77
77
|
this.storeKey = serverOrigin ? `${serverOrigin}/${docId}` : docId;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
private
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
private dbPromise: Promise<IDBDatabase | null> | null = null;
|
|
81
|
+
|
|
82
|
+
private getDb(): Promise<IDBDatabase | null> {
|
|
83
|
+
if (!idbAvailable()) return Promise.resolve(null);
|
|
84
|
+
if (!this.dbPromise) {
|
|
85
|
+
// Cache the promise so concurrent callers share a single open operation.
|
|
86
|
+
this.dbPromise = openDb(this.storeKey).catch(() => null).then(db => {
|
|
87
|
+
this.db = db;
|
|
88
|
+
return db;
|
|
89
|
+
});
|
|
84
90
|
}
|
|
85
|
-
return this.
|
|
91
|
+
return this.dbPromise;
|
|
86
92
|
}
|
|
87
93
|
|
|
88
94
|
// ── Pending (unsynced) updates ────────────────────────────────────────────
|