@abraca/dabra 1.0.10 → 1.0.11

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.
@@ -1703,14 +1703,17 @@ var AbracadabraWS = class extends EventEmitter {
1703
1703
  this.receivedOnOpenPayload = event;
1704
1704
  }
1705
1705
  attach(provider) {
1706
+ const existing = this.configuration.providerMap.get(provider.configuration.name);
1707
+ if (existing && existing !== provider) console.warn(`[AbracadabraWS] attach: overwriting provider for "${provider.configuration.name}". This may indicate a duplicate loadChild for the same document.`);
1706
1708
  this.configuration.providerMap.set(provider.configuration.name, provider);
1707
1709
  if (this.status === WebSocketStatus.Disconnected && this.shouldConnect) this.connect();
1708
1710
  if (this.receivedOnOpenPayload && this.status === WebSocketStatus.Connected) provider.onOpen(this.receivedOnOpenPayload);
1709
1711
  }
1710
1712
  detach(provider) {
1711
- if (this.configuration.providerMap.has(provider.configuration.name)) {
1712
- provider.send(CloseMessage, { documentName: provider.configuration.name });
1713
- this.configuration.providerMap.delete(provider.configuration.name);
1713
+ const name = provider.configuration.name;
1714
+ if (this.configuration.providerMap.get(name) === provider) {
1715
+ provider.send(CloseMessage, { documentName: name });
1716
+ this.configuration.providerMap.delete(name);
1714
1717
  }
1715
1718
  }
1716
1719
  setConfiguration(configuration = {}) {
@@ -3230,6 +3233,20 @@ var AbracadabraClient = class {
3230
3233
  if (this.cache) await this.cache.setPermissions(docId, res.permissions).catch(() => null);
3231
3234
  return res.permissions;
3232
3235
  }
3236
+ /** List effective permissions including inherited ones from ancestor documents. */
3237
+ async listEffectivePermissions(docId) {
3238
+ try {
3239
+ return await this.request("GET", `/docs/${encodeURIComponent(docId)}/effective-permissions`);
3240
+ } catch {
3241
+ return {
3242
+ permissions: (await this.listPermissions(docId)).map((p) => ({
3243
+ ...p,
3244
+ source: "direct"
3245
+ })),
3246
+ default_role: "viewer"
3247
+ };
3248
+ }
3249
+ }
3233
3250
  /** Grant or change a user's role on a document (requires Owner). */
3234
3251
  async setPermission(docId, opts) {
3235
3252
  await this.request("POST", `/docs/${encodeURIComponent(docId)}/permissions`, { body: opts });
@@ -7456,7 +7473,7 @@ var FileBlobStore = class extends EventEmitter {
7456
7473
  this.objectUrls = /* @__PURE__ */ new Map();
7457
7474
  this._flushing = false;
7458
7475
  this.origin = serverOrigin;
7459
- this.client = client;
7476
+ this.client = client ?? null;
7460
7477
  this._onlineHandler = () => {
7461
7478
  this.flushQueue().catch(() => null);
7462
7479
  };
@@ -7494,6 +7511,7 @@ var FileBlobStore = class extends EventEmitter {
7494
7511
  return url;
7495
7512
  }
7496
7513
  }
7514
+ if (!this.client) return null;
7497
7515
  let blob;
7498
7516
  try {
7499
7517
  blob = await this.client.getUpload(docId, uploadId);
@@ -7589,7 +7607,7 @@ var FileBlobStore = class extends EventEmitter {
7589
7607
  * Entries that fail are marked with status "error" and left in the queue.
7590
7608
  */
7591
7609
  async flushQueue() {
7592
- if (this._flushing) return;
7610
+ if (this._flushing || !this.client) return;
7593
7611
  this._flushing = true;
7594
7612
  try {
7595
7613
  const pending = (await this.getQueue()).filter((e) => e.status === "pending");