@abraca/dabra 2.19.0 → 2.21.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 +41 -11
- package/dist/abracadabra-provider.cjs.map +1 -1
- package/dist/abracadabra-provider.esm.js +41 -11
- package/dist/abracadabra-provider.esm.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/package.json +2 -2
- package/src/AbracadabraBaseProvider.ts +11 -2
- package/src/AbracadabraProvider.ts +64 -2
- package/src/BackgroundSyncManager.ts +6 -4
- package/src/OfflineStore.ts +6 -3
|
@@ -2771,8 +2771,8 @@ var AbracadabraBaseProvider = class extends EventEmitter {
|
|
|
2771
2771
|
this.configuration.websocketProvider.on("destroy", this.configuration.onDestroy);
|
|
2772
2772
|
this.configuration.websocketProvider.on("destroy", this.forwardDestroy);
|
|
2773
2773
|
this.configuration.websocketProvider.on("rateLimited", this.forwardRateLimited);
|
|
2774
|
-
this.configuration.websocketProvider.attach(this);
|
|
2775
2774
|
this._isAttached = true;
|
|
2775
|
+
this.configuration.websocketProvider.attach(this);
|
|
2776
2776
|
}
|
|
2777
2777
|
permissionDeniedHandler(reason) {
|
|
2778
2778
|
this.emit("authenticationFailed", { reason });
|
|
@@ -2824,9 +2824,12 @@ function txPromise$2(store, request) {
|
|
|
2824
2824
|
var OfflineStore = class {
|
|
2825
2825
|
/**
|
|
2826
2826
|
* @param docId The document UUID.
|
|
2827
|
-
* @param serverOrigin
|
|
2828
|
-
*
|
|
2829
|
-
* per-server,
|
|
2827
|
+
* @param serverOrigin Host of the server, including a non-default port
|
|
2828
|
+
* (e.g. "abra.cou.sh", "localhost:3001"). When provided
|
|
2829
|
+
* the IndexedDB database is namespaced per-server,
|
|
2830
|
+
* preventing cross-server data contamination — the port
|
|
2831
|
+
* matters because two same-host servers sharing the
|
|
2832
|
+
* default root_doc_id would otherwise collide.
|
|
2830
2833
|
*/
|
|
2831
2834
|
constructor(docId, serverOrigin) {
|
|
2832
2835
|
this.db = null;
|
|
@@ -3033,6 +3036,7 @@ var AbracadabraProvider = class AbracadabraProvider extends AbracadabraBaseProvi
|
|
|
3033
3036
|
}
|
|
3034
3037
|
super(resolved);
|
|
3035
3038
|
this.effectiveRole = null;
|
|
3039
|
+
this._writeDropWarned = false;
|
|
3036
3040
|
this.childProviders = /* @__PURE__ */ new Map();
|
|
3037
3041
|
this.pendingLoads = /* @__PURE__ */ new Map();
|
|
3038
3042
|
this.childAccessTimes = /* @__PURE__ */ new Map();
|
|
@@ -3063,7 +3067,7 @@ var AbracadabraProvider = class AbracadabraProvider extends AbracadabraBaseProvi
|
|
|
3063
3067
|
static deriveServerOrigin(config, client) {
|
|
3064
3068
|
try {
|
|
3065
3069
|
const url = config.url ?? config.websocketProvider?.url ?? client?.wsUrl;
|
|
3066
|
-
if (url) return new URL(url).
|
|
3070
|
+
if (url) return new URL(url).host;
|
|
3067
3071
|
} catch {}
|
|
3068
3072
|
}
|
|
3069
3073
|
/**
|
|
@@ -3089,7 +3093,7 @@ var AbracadabraProvider = class AbracadabraProvider extends AbracadabraBaseProvi
|
|
|
3089
3093
|
}
|
|
3090
3094
|
authenticatedHandler(scope) {
|
|
3091
3095
|
super.authenticatedHandler(scope);
|
|
3092
|
-
|
|
3096
|
+
const roleMap = {
|
|
3093
3097
|
service: "service",
|
|
3094
3098
|
admin: "admin",
|
|
3095
3099
|
owner: "owner",
|
|
@@ -3098,8 +3102,16 @@ var AbracadabraProvider = class AbracadabraProvider extends AbracadabraBaseProvi
|
|
|
3098
3102
|
observer: "observer",
|
|
3099
3103
|
"read-write": "editor",
|
|
3100
3104
|
readonly: "viewer"
|
|
3101
|
-
}
|
|
3105
|
+
};
|
|
3106
|
+
const couldWrite = this.canWrite;
|
|
3107
|
+
this.effectiveRole = roleMap[scope] ?? "observer";
|
|
3102
3108
|
this.offlineStore?.savePermissionSnapshot(this.effectiveRole);
|
|
3109
|
+
if (this.canWrite) this._writeDropWarned = false;
|
|
3110
|
+
this.emit("roleChanged", {
|
|
3111
|
+
role: this.effectiveRole,
|
|
3112
|
+
canWrite: this.canWrite
|
|
3113
|
+
});
|
|
3114
|
+
if (!couldWrite && this.canWrite && this.isSynced) this.flushPendingUpdates().catch(() => null);
|
|
3103
3115
|
}
|
|
3104
3116
|
/**
|
|
3105
3117
|
* Override sendToken to send a pubkey-only identity declaration instead of a
|
|
@@ -3150,7 +3162,13 @@ var AbracadabraProvider = class AbracadabraProvider extends AbracadabraBaseProvi
|
|
|
3150
3162
|
async restorePermissionSnapshot() {
|
|
3151
3163
|
if (!this.offlineStore) return;
|
|
3152
3164
|
const role = await this.offlineStore.getPermissionSnapshot();
|
|
3153
|
-
if (role && !this.effectiveRole)
|
|
3165
|
+
if (role && !this.effectiveRole) {
|
|
3166
|
+
this.effectiveRole = role;
|
|
3167
|
+
this.emit("roleChanged", {
|
|
3168
|
+
role: this.effectiveRole,
|
|
3169
|
+
canWrite: this.canWrite
|
|
3170
|
+
});
|
|
3171
|
+
}
|
|
3154
3172
|
}
|
|
3155
3173
|
get canWrite() {
|
|
3156
3174
|
return this.effectiveRole != null && this.effectiveRole !== "viewer" && this.effectiveRole !== "observer";
|
|
@@ -3357,7 +3375,19 @@ var AbracadabraProvider = class AbracadabraProvider extends AbracadabraBaseProvi
|
|
|
3357
3375
|
if (origin === this) return;
|
|
3358
3376
|
if (this.offlineStore !== null && origin === this.offlineStore) return;
|
|
3359
3377
|
this.offlineStore?.persistUpdate(update).catch(() => null);
|
|
3360
|
-
if (!this.canWrite)
|
|
3378
|
+
if (!this.canWrite) {
|
|
3379
|
+
if (!this._writeDropWarned) {
|
|
3380
|
+
this._writeDropWarned = true;
|
|
3381
|
+
try {
|
|
3382
|
+
console.warn(`[abra:write-drop] dropping wire-send for doc "${this.configuration?.name}" — effectiveRole=${this.effectiveRole ?? "null"} (canWrite=false). Edits are persisted to IndexedDB only; the server will NOT receive them until this doc regains write access.`);
|
|
3383
|
+
} catch {}
|
|
3384
|
+
}
|
|
3385
|
+
this.emit("writeDropped", {
|
|
3386
|
+
name: this.configuration?.name,
|
|
3387
|
+
role: this.effectiveRole ?? null
|
|
3388
|
+
});
|
|
3389
|
+
return;
|
|
3390
|
+
}
|
|
3361
3391
|
super.documentUpdateHandler(update, origin);
|
|
3362
3392
|
}
|
|
3363
3393
|
/**
|
|
@@ -16066,7 +16096,7 @@ var BackgroundSyncManager = class extends EventEmitter {
|
|
|
16066
16096
|
};
|
|
16067
16097
|
let serverOrigin = "default";
|
|
16068
16098
|
try {
|
|
16069
|
-
serverOrigin = new URL(client.baseUrl ?? "").
|
|
16099
|
+
serverOrigin = new URL(client.baseUrl ?? "").host;
|
|
16070
16100
|
} catch {}
|
|
16071
16101
|
this.persistence = new BackgroundSyncPersistence(serverOrigin);
|
|
16072
16102
|
this.semaphore = new Semaphore(this.opts.concurrency);
|
|
@@ -16213,7 +16243,7 @@ var BackgroundSyncManager = class extends EventEmitter {
|
|
|
16213
16243
|
for (const docId of treeMap.keys()) docIds.add(docId);
|
|
16214
16244
|
let serverOrigin;
|
|
16215
16245
|
try {
|
|
16216
|
-
serverOrigin = new URL(this.client.baseUrl ?? "").
|
|
16246
|
+
serverOrigin = new URL(this.client.baseUrl ?? "").host;
|
|
16217
16247
|
} catch {}
|
|
16218
16248
|
const clearPromises = Array.from(docIds).map(async (docId) => {
|
|
16219
16249
|
try {
|