@abraca/dabra 1.0.15 → 1.0.17
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 +72 -2
- package/dist/abracadabra-provider.cjs.map +1 -1
- package/dist/abracadabra-provider.esm.js +72 -2
- package/dist/abracadabra-provider.esm.js.map +1 -1
- package/dist/index.d.ts +54 -4
- package/package.json +1 -1
- package/src/AbracadabraClient.ts +32 -0
- package/src/AbracadabraProvider.ts +7 -2
- package/src/BackgroundSyncManager.ts +43 -0
- package/src/OfflineStore.ts +22 -0
- package/src/types.ts +16 -4
|
@@ -2696,6 +2696,22 @@ var OfflineStore = class {
|
|
|
2696
2696
|
const tx = db.transaction("meta", "readwrite");
|
|
2697
2697
|
await txPromise$2(tx.objectStore("meta"), tx.objectStore("meta").put(value, `meta:${key}`));
|
|
2698
2698
|
}
|
|
2699
|
+
/**
|
|
2700
|
+
* Clear all stored data (updates, snapshots, state vectors, subdoc queue).
|
|
2701
|
+
* The database itself is kept but emptied.
|
|
2702
|
+
*/
|
|
2703
|
+
async clearAll() {
|
|
2704
|
+
const db = await this.getDb();
|
|
2705
|
+
if (!db) return;
|
|
2706
|
+
const storeNames = Array.from(db.objectStoreNames);
|
|
2707
|
+
if (storeNames.length === 0) return;
|
|
2708
|
+
const tx = db.transaction(storeNames, "readwrite");
|
|
2709
|
+
await Promise.all(storeNames.map((name) => new Promise((resolve, reject) => {
|
|
2710
|
+
const req = tx.objectStore(name).clear();
|
|
2711
|
+
req.onsuccess = () => resolve();
|
|
2712
|
+
req.onerror = () => reject(req.error);
|
|
2713
|
+
})));
|
|
2714
|
+
}
|
|
2699
2715
|
destroy() {
|
|
2700
2716
|
this._destroyed = true;
|
|
2701
2717
|
this.db = null;
|
|
@@ -2819,9 +2835,10 @@ var AbracadabraProvider = class AbracadabraProvider extends AbracadabraBaseProvi
|
|
|
2819
2835
|
owner: "owner",
|
|
2820
2836
|
editor: "editor",
|
|
2821
2837
|
viewer: "viewer",
|
|
2838
|
+
observer: "observer",
|
|
2822
2839
|
"read-write": "editor",
|
|
2823
2840
|
readonly: "viewer"
|
|
2824
|
-
}[scope] ?? "
|
|
2841
|
+
}[scope] ?? "observer";
|
|
2825
2842
|
this.offlineStore?.savePermissionSnapshot(this.effectiveRole);
|
|
2826
2843
|
}
|
|
2827
2844
|
/**
|
|
@@ -2876,7 +2893,10 @@ var AbracadabraProvider = class AbracadabraProvider extends AbracadabraBaseProvi
|
|
|
2876
2893
|
if (role && !this.effectiveRole) this.effectiveRole = role;
|
|
2877
2894
|
}
|
|
2878
2895
|
get canWrite() {
|
|
2879
|
-
return this.effectiveRole != null && this.effectiveRole !== "viewer";
|
|
2896
|
+
return this.effectiveRole != null && this.effectiveRole !== "viewer" && this.effectiveRole !== "observer";
|
|
2897
|
+
}
|
|
2898
|
+
get canAwareness() {
|
|
2899
|
+
return this.effectiveRole != null && this.effectiveRole !== "observer";
|
|
2880
2900
|
}
|
|
2881
2901
|
/** The AbracadabraClient instance for REST API access, if configured. */
|
|
2882
2902
|
get client() {
|
|
@@ -3259,6 +3279,10 @@ var AbracadabraClient = class {
|
|
|
3259
3279
|
async createChild(docId, opts) {
|
|
3260
3280
|
return this.request("POST", `/docs/${encodeURIComponent(docId)}/children`, { body: opts ?? {} });
|
|
3261
3281
|
}
|
|
3282
|
+
/** Broadcast a stateless message to all connected clients on a document (requires manage permission). */
|
|
3283
|
+
async broadcast(docId, payload) {
|
|
3284
|
+
await this.request("POST", `/docs/${encodeURIComponent(docId)}/broadcast`, { body: { payload } });
|
|
3285
|
+
}
|
|
3262
3286
|
/** List all permissions for a document (requires read access). */
|
|
3263
3287
|
async listPermissions(docId) {
|
|
3264
3288
|
if (this.cache) {
|
|
@@ -3374,6 +3398,26 @@ var AbracadabraClient = class {
|
|
|
3374
3398
|
async deleteSpace(spaceId) {
|
|
3375
3399
|
await this.request("DELETE", `/spaces/${encodeURIComponent(spaceId)}`);
|
|
3376
3400
|
}
|
|
3401
|
+
/** List all users (requires elevated role: admin or service). */
|
|
3402
|
+
async adminListUsers() {
|
|
3403
|
+
return this.request("GET", "/admin/users");
|
|
3404
|
+
}
|
|
3405
|
+
/** Promote a user to admin (requires service role). */
|
|
3406
|
+
async adminPromote(userId) {
|
|
3407
|
+
await this.request("POST", `/admin/users/${encodeURIComponent(userId)}/admin`);
|
|
3408
|
+
}
|
|
3409
|
+
/** Demote an admin user back to regular (requires service role). */
|
|
3410
|
+
async adminDemote(userId) {
|
|
3411
|
+
await this.request("DELETE", `/admin/users/${encodeURIComponent(userId)}/admin`);
|
|
3412
|
+
}
|
|
3413
|
+
/** Sweep orphaned file blobs from storage (requires elevated role). */
|
|
3414
|
+
async adminStorageSweep() {
|
|
3415
|
+
return this.request("POST", "/admin/storage/sweep");
|
|
3416
|
+
}
|
|
3417
|
+
/** Repair blob ref-counts and sweep orphans (requires elevated role). */
|
|
3418
|
+
async adminStorageRepair() {
|
|
3419
|
+
return this.request("POST", "/admin/storage/repair");
|
|
3420
|
+
}
|
|
3377
3421
|
/** Health check — no auth required. */
|
|
3378
3422
|
async health() {
|
|
3379
3423
|
return this.request("GET", "/health", { auth: false });
|
|
@@ -8386,6 +8430,32 @@ var BackgroundSyncManager = class extends EventEmitter {
|
|
|
8386
8430
|
}, intervalMs);
|
|
8387
8431
|
return () => clearInterval(handle);
|
|
8388
8432
|
}
|
|
8433
|
+
/**
|
|
8434
|
+
* Clear all offline document data and sync state.
|
|
8435
|
+
* Opens each document's OfflineStore and clears its contents, then
|
|
8436
|
+
* resets the background sync persistence. After calling this, all
|
|
8437
|
+
* documents will need to be re-synced.
|
|
8438
|
+
*/
|
|
8439
|
+
async clearAllSyncedData() {
|
|
8440
|
+
const docIds = new Set(this.syncStates.keys());
|
|
8441
|
+
const treeMap = this.rootProvider.document.getMap("doc-tree");
|
|
8442
|
+
for (const docId of treeMap.keys()) docIds.add(docId);
|
|
8443
|
+
let serverOrigin;
|
|
8444
|
+
try {
|
|
8445
|
+
serverOrigin = new URL(this.client.baseUrl ?? "").hostname;
|
|
8446
|
+
} catch {}
|
|
8447
|
+
const clearPromises = Array.from(docIds).map(async (docId) => {
|
|
8448
|
+
try {
|
|
8449
|
+
const store = new OfflineStore(docId, serverOrigin);
|
|
8450
|
+
await store.clearAll();
|
|
8451
|
+
store.destroy();
|
|
8452
|
+
} catch {}
|
|
8453
|
+
});
|
|
8454
|
+
await Promise.all(clearPromises);
|
|
8455
|
+
for (const docId of docIds) await this.persistence.deleteState(docId).catch(() => null);
|
|
8456
|
+
this.syncStates.clear();
|
|
8457
|
+
this._initPromise = null;
|
|
8458
|
+
}
|
|
8389
8459
|
destroy() {
|
|
8390
8460
|
this._destroyed = true;
|
|
8391
8461
|
this.removeAllListeners();
|