@abraca/dabra 0.1.6 → 0.1.7

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/index.d.ts CHANGED
@@ -311,6 +311,7 @@ declare class AbracadabraProvider extends HocuspocusProvider {
311
311
  private _client;
312
312
  private offlineStore;
313
313
  private childProviders;
314
+ private pendingLoads;
314
315
  private subdocLoading;
315
316
  private abracadabraConfig;
316
317
  private readonly boundHandleYSubdocsChange;
@@ -353,6 +354,7 @@ declare class AbracadabraProvider extends HocuspocusProvider {
353
354
  * the server is document-scoped (one WebSocket ↔ one document).
354
355
  */
355
356
  loadChild(childId: string): Promise<AbracadabraProvider>;
357
+ private _doLoadChild;
356
358
  private unloadChild;
357
359
  /** Return all currently-loaded child providers. */
358
360
  get children(): Map<string, AbracadabraProvider>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abraca/dabra",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "abracadabra provider",
5
5
  "keywords": [
6
6
  "abracadabra",
@@ -61,6 +61,11 @@ export interface AbracadabraProviderConfiguration
61
61
  websocketProvider?: HocuspocusProviderWebsocket;
62
62
  }
63
63
 
64
+ /** Validate that a string is a UUID acceptable by the server's DocId parser. */
65
+ function isValidDocId(id: string): boolean {
66
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id);
67
+ }
68
+
64
69
  /**
65
70
  * AbracadabraProvider extends HocuspocusProvider with:
66
71
  *
@@ -82,6 +87,7 @@ export class AbracadabraProvider extends HocuspocusProvider {
82
87
  private _client: AbracadabraClient | null;
83
88
  private offlineStore: OfflineStore | null;
84
89
  private childProviders = new Map<string, AbracadabraProvider>();
90
+ private pendingLoads = new Map<string, Promise<AbracadabraProvider>>();
85
91
  private subdocLoading: "lazy" | "eager";
86
92
 
87
93
  private abracadabraConfig: AbracadabraProviderConfiguration;
@@ -281,6 +287,7 @@ export class AbracadabraProvider extends HocuspocusProvider {
281
287
  loaded: Set<Y.Doc>;
282
288
  }) {
283
289
  for (const subdoc of added) {
290
+ if (!isValidDocId(subdoc.guid)) continue;
284
291
  this.registerSubdoc(subdoc);
285
292
  }
286
293
  for (const subdoc of removed) {
@@ -315,11 +322,33 @@ export class AbracadabraProvider extends HocuspocusProvider {
315
322
  * child document id. Each child opens its own WebSocket connection because
316
323
  * the server is document-scoped (one WebSocket ↔ one document).
317
324
  */
318
- async loadChild(childId: string): Promise<AbracadabraProvider> {
325
+ loadChild(childId: string): Promise<AbracadabraProvider> {
326
+ if (!isValidDocId(childId)) {
327
+ return Promise.reject(
328
+ new Error(
329
+ `loadChild: "${childId}" is not a valid document ID (must be a UUID). ` +
330
+ `If this node was created with an older version of the app, delete it and recreate it.`,
331
+ ),
332
+ );
333
+ }
334
+
319
335
  if (this.childProviders.has(childId)) {
320
- return this.childProviders.get(childId)!;
336
+ return Promise.resolve(this.childProviders.get(childId)!);
321
337
  }
322
338
 
339
+ // Deduplicate concurrent calls: return the same Promise so both callers
340
+ // get the exact same AbracadabraProvider instance.
341
+ if (this.pendingLoads.has(childId)) {
342
+ return this.pendingLoads.get(childId)!;
343
+ }
344
+
345
+ const load = this._doLoadChild(childId);
346
+ this.pendingLoads.set(childId, load);
347
+ load.finally(() => this.pendingLoads.delete(childId));
348
+ return load;
349
+ }
350
+
351
+ private async _doLoadChild(childId: string): Promise<AbracadabraProvider> {
323
352
  const childDoc = new Y.Doc({ guid: childId });
324
353
 
325
354
  // Notify the server that this child belongs to the parent document and
@@ -346,7 +375,7 @@ export class AbracadabraProvider extends HocuspocusProvider {
346
375
  const childProvider = new AbracadabraProvider({
347
376
  name: childId,
348
377
  document: childDoc,
349
- url: this.abracadabraConfig.url,
378
+ url: this.abracadabraConfig.url ?? this.configuration.websocketProvider?.url,
350
379
  token: this.configuration.token,
351
380
  subdocLoading: this.subdocLoading,
352
381
  disableOfflineStore: this.abracadabraConfig.disableOfflineStore,