@abraca/dabra 0.1.5 → 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.
@@ -2116,6 +2116,10 @@ var SubdocMessage = class extends OutgoingMessage {
2116
2116
 
2117
2117
  //#endregion
2118
2118
  //#region packages/provider/src/AbracadabraProvider.ts
2119
+ /** Validate that a string is a UUID acceptable by the server's DocId parser. */
2120
+ function isValidDocId(id) {
2121
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id);
2122
+ }
2119
2123
  /**
2120
2124
  * AbracadabraProvider extends HocuspocusProvider with:
2121
2125
  *
@@ -2142,6 +2146,7 @@ var AbracadabraProvider = class AbracadabraProvider extends HocuspocusProvider {
2142
2146
  super(resolved);
2143
2147
  this.effectiveRole = null;
2144
2148
  this.childProviders = /* @__PURE__ */ new Map();
2149
+ this.pendingLoads = /* @__PURE__ */ new Map();
2145
2150
  this.boundHandleYSubdocsChange = this.handleYSubdocsChange.bind(this);
2146
2151
  this._client = client;
2147
2152
  this.abracadabraConfig = configuration;
@@ -2251,7 +2256,10 @@ var AbracadabraProvider = class AbracadabraProvider extends HocuspocusProvider {
2251
2256
  * We intercept additions to register them with the Abracadabra server.
2252
2257
  */
2253
2258
  handleYSubdocsChange({ added, removed }) {
2254
- for (const subdoc of added) this.registerSubdoc(subdoc);
2259
+ for (const subdoc of added) {
2260
+ if (!isValidDocId(subdoc.guid)) continue;
2261
+ this.registerSubdoc(subdoc);
2262
+ }
2255
2263
  for (const subdoc of removed) this.unloadChild(subdoc.guid);
2256
2264
  }
2257
2265
  /**
@@ -2272,17 +2280,35 @@ var AbracadabraProvider = class AbracadabraProvider extends HocuspocusProvider {
2272
2280
  }
2273
2281
  /**
2274
2282
  * Create (or return cached) a child AbracadabraProvider for a given
2275
- * child document id. The child shares the parent's WebSocket connection.
2283
+ * child document id. Each child opens its own WebSocket connection because
2284
+ * the server is document-scoped (one WebSocket ↔ one document).
2276
2285
  */
2277
2286
  async loadChild(childId) {
2287
+ if (!isValidDocId(childId)) throw new Error(`loadChild: "${childId}" is not a valid document ID (must be a UUID). If this node was created with an older version of the app, delete it and recreate it.`);
2278
2288
  if (this.childProviders.has(childId)) return this.childProviders.get(childId);
2289
+ if (this.pendingLoads.has(childId)) return this.pendingLoads.get(childId);
2290
+ const load = this._doLoadChild(childId);
2291
+ this.pendingLoads.set(childId, load);
2292
+ load.finally(() => this.pendingLoads.delete(childId));
2293
+ return load;
2294
+ }
2295
+ async _doLoadChild(childId) {
2279
2296
  const childDoc = new yjs.Doc({ guid: childId });
2280
- const parentWsp = this.configuration.websocketProvider;
2297
+ await new Promise((resolve) => {
2298
+ const onRegistered = ({ childId: cid }) => {
2299
+ if (cid === childId) {
2300
+ this.off("subdocRegistered", onRegistered);
2301
+ resolve();
2302
+ }
2303
+ };
2304
+ this.on("subdocRegistered", onRegistered);
2305
+ this.registerSubdoc(childDoc);
2306
+ setTimeout(resolve, 3e3);
2307
+ });
2281
2308
  const childProvider = new AbracadabraProvider({
2282
2309
  name: childId,
2283
2310
  document: childDoc,
2284
- url: parentWsp.configuration.url,
2285
- WebSocketPolyfill: parentWsp.configuration.WebSocketPolyfill,
2311
+ url: this.abracadabraConfig.url ?? this.configuration.websocketProvider?.url,
2286
2312
  token: this.configuration.token,
2287
2313
  subdocLoading: this.subdocLoading,
2288
2314
  disableOfflineStore: this.abracadabraConfig.disableOfflineStore,