@abraca/dabra 1.6.0 → 1.8.1
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 +355 -8
- package/dist/abracadabra-provider.cjs.map +1 -1
- package/dist/abracadabra-provider.esm.js +354 -9
- package/dist/abracadabra-provider.esm.js.map +1 -1
- package/dist/index.d.ts +208 -4
- package/package.json +1 -1
- package/src/AbracadabraProvider.ts +10 -0
- package/src/AbracadabraWS.ts +10 -2
- package/src/ChatClient.ts +234 -0
- package/src/IdentityDoc.ts +11 -0
- package/src/NotificationsClient.ts +185 -0
- package/src/index.ts +16 -0
- package/src/types.ts +86 -0
- package/src/webrtc/DevicePairingChannel.ts +18 -6
|
@@ -2810,6 +2810,7 @@ var AbracadabraProvider = class AbracadabraProvider extends AbracadabraBaseProvi
|
|
|
2810
2810
|
this.childAccessTimes = /* @__PURE__ */ new Map();
|
|
2811
2811
|
this.pinnedChildren = /* @__PURE__ */ new Set();
|
|
2812
2812
|
this.boundHandleYSubdocsChange = this.handleYSubdocsChange.bind(this);
|
|
2813
|
+
this.hasCachedContent = false;
|
|
2813
2814
|
this._client = client;
|
|
2814
2815
|
this.abracadabraConfig = configuration;
|
|
2815
2816
|
this.subdocLoading = configuration.subdocLoading ?? "lazy";
|
|
@@ -2847,8 +2848,14 @@ var AbracadabraProvider = class AbracadabraProvider extends AbracadabraBaseProvi
|
|
|
2847
2848
|
async _initFromOfflineStore() {
|
|
2848
2849
|
if (!this.offlineStore) return;
|
|
2849
2850
|
const [snapshot, pending] = await Promise.all([this.offlineStore.getDocSnapshot().catch(() => null), this.offlineStore.getPendingUpdates().catch(() => [])]);
|
|
2850
|
-
if (snapshot)
|
|
2851
|
-
|
|
2851
|
+
if (snapshot) {
|
|
2852
|
+
Y.applyUpdate(this.document, snapshot, this.offlineStore);
|
|
2853
|
+
this.hasCachedContent = true;
|
|
2854
|
+
}
|
|
2855
|
+
for (const update of pending) {
|
|
2856
|
+
Y.applyUpdate(this.document, update, this.offlineStore);
|
|
2857
|
+
this.hasCachedContent = true;
|
|
2858
|
+
}
|
|
2852
2859
|
}
|
|
2853
2860
|
authenticatedHandler(scope) {
|
|
2854
2861
|
super.authenticatedHandler(scope);
|
|
@@ -13152,8 +13159,12 @@ var DevicePairingChannel = class DevicePairingChannel extends EventEmitter {
|
|
|
13152
13159
|
/**
|
|
13153
13160
|
* Approve the pending pairing request. Calls `client.addKey()` to
|
|
13154
13161
|
* register Device B's public key, then notifies Device B.
|
|
13162
|
+
*
|
|
13163
|
+
* @param client Authenticated REST client.
|
|
13164
|
+
* @param masterPublicKey Approver's account-level Ed25519 public key (base64url).
|
|
13165
|
+
* Sent to Device B so it can adopt the master's identity doc.
|
|
13155
13166
|
*/
|
|
13156
|
-
async approve(client) {
|
|
13167
|
+
async approve(client, masterPublicKey) {
|
|
13157
13168
|
if (this.role !== "approver") return {
|
|
13158
13169
|
success: false,
|
|
13159
13170
|
error: "Only the approver can approve"
|
|
@@ -13173,7 +13184,10 @@ var DevicePairingChannel = class DevicePairingChannel extends EventEmitter {
|
|
|
13173
13184
|
deviceName: req.deviceName,
|
|
13174
13185
|
x25519Key: req.x25519Key
|
|
13175
13186
|
});
|
|
13176
|
-
this.sendMessage({
|
|
13187
|
+
this.sendMessage({
|
|
13188
|
+
type: "pair-approved",
|
|
13189
|
+
masterPublicKey
|
|
13190
|
+
});
|
|
13177
13191
|
this._pendingRequest = null;
|
|
13178
13192
|
this.emit("pairingComplete", { success: true });
|
|
13179
13193
|
return { success: true };
|
|
@@ -13196,8 +13210,12 @@ var DevicePairingChannel = class DevicePairingChannel extends EventEmitter {
|
|
|
13196
13210
|
* Approve via server-side device invite. Creates a single-use invite code
|
|
13197
13211
|
* and sends it to Device B over the E2EE channel. Device B redeems it
|
|
13198
13212
|
* independently via HTTP — Device A can go offline after this.
|
|
13213
|
+
*
|
|
13214
|
+
* @param client Authenticated REST client.
|
|
13215
|
+
* @param masterPublicKey Approver's account-level Ed25519 public key (base64url).
|
|
13216
|
+
* Sent to Device B so it can adopt the master's identity doc.
|
|
13199
13217
|
*/
|
|
13200
|
-
async approveWithInvite(client) {
|
|
13218
|
+
async approveWithInvite(client, masterPublicKey) {
|
|
13201
13219
|
if (this.role !== "approver") return {
|
|
13202
13220
|
success: false,
|
|
13203
13221
|
error: "Only the approver can approve"
|
|
@@ -13214,7 +13232,8 @@ var DevicePairingChannel = class DevicePairingChannel extends EventEmitter {
|
|
|
13214
13232
|
const { code } = await client.createDeviceInvite();
|
|
13215
13233
|
this.sendMessage({
|
|
13216
13234
|
type: "pair-invite-code",
|
|
13217
|
-
code
|
|
13235
|
+
code,
|
|
13236
|
+
masterPublicKey
|
|
13218
13237
|
});
|
|
13219
13238
|
this._pendingRequest = null;
|
|
13220
13239
|
this.emit("pairingComplete", { success: true });
|
|
@@ -13385,7 +13404,7 @@ var DevicePairingChannel = class DevicePairingChannel extends EventEmitter {
|
|
|
13385
13404
|
break;
|
|
13386
13405
|
case "pair-approved":
|
|
13387
13406
|
if (this.role !== "requester") return;
|
|
13388
|
-
this.emit("approved");
|
|
13407
|
+
this.emit("approved", { masterPublicKey: msg.masterPublicKey });
|
|
13389
13408
|
this.emit("pairingComplete", { success: true });
|
|
13390
13409
|
break;
|
|
13391
13410
|
case "pair-rejected":
|
|
@@ -13398,7 +13417,7 @@ var DevicePairingChannel = class DevicePairingChannel extends EventEmitter {
|
|
|
13398
13417
|
break;
|
|
13399
13418
|
case "pair-invite-code":
|
|
13400
13419
|
if (this.role !== "requester") return;
|
|
13401
|
-
this.emit("inviteCode", msg.code);
|
|
13420
|
+
this.emit("inviteCode", msg.code, msg.masterPublicKey);
|
|
13402
13421
|
break;
|
|
13403
13422
|
}
|
|
13404
13423
|
}
|
|
@@ -13925,6 +13944,19 @@ var IdentityDocProvider = class extends EventEmitter {
|
|
|
13925
13944
|
return this.profileMap.size === 0 && this.serversMap.size === 0;
|
|
13926
13945
|
}
|
|
13927
13946
|
/**
|
|
13947
|
+
* Enable WebRTC P2P sync at runtime.
|
|
13948
|
+
* Use this for claimed/passkey users where E2EE identity derivation
|
|
13949
|
+
* was deferred to avoid biometric prompts on page load.
|
|
13950
|
+
*/
|
|
13951
|
+
enableWebRTC(webrtcConfig) {
|
|
13952
|
+
if (this._destroyed || this.webrtc) return;
|
|
13953
|
+
this.config = {
|
|
13954
|
+
...this.config,
|
|
13955
|
+
webrtc: webrtcConfig
|
|
13956
|
+
};
|
|
13957
|
+
this._connectWebRTC();
|
|
13958
|
+
}
|
|
13959
|
+
/**
|
|
13928
13960
|
* Update the sync server URL at runtime (e.g. when user changes their
|
|
13929
13961
|
* designated sync server in settings).
|
|
13930
13962
|
*/
|
|
@@ -14112,5 +14144,318 @@ var DeviceRegistrationService = class {
|
|
|
14112
14144
|
};
|
|
14113
14145
|
|
|
14114
14146
|
//#endregion
|
|
14115
|
-
|
|
14147
|
+
//#region packages/provider/src/ChatClient.ts
|
|
14148
|
+
const DEFAULT_TIMEOUT_MS$1 = 1e4;
|
|
14149
|
+
/**
|
|
14150
|
+
* Typed client for the Abracadabra chat feature.
|
|
14151
|
+
*
|
|
14152
|
+
* Wraps a connected provider (or base provider) and translates JSON envelopes
|
|
14153
|
+
* on the stateless channel into typed method calls and events.
|
|
14154
|
+
*
|
|
14155
|
+
* Events emitted:
|
|
14156
|
+
* - `message` → ChatMessage (new message broadcast)
|
|
14157
|
+
* - `typing` → ChatTypingEvent (typing indicator broadcast)
|
|
14158
|
+
* - `readReceipt` → ChatReadReceipt (mark_read broadcast)
|
|
14159
|
+
*/
|
|
14160
|
+
var ChatClient = class extends EventEmitter {
|
|
14161
|
+
constructor(provider, options) {
|
|
14162
|
+
super();
|
|
14163
|
+
this.pending = /* @__PURE__ */ new Map();
|
|
14164
|
+
this.provider = provider;
|
|
14165
|
+
this.responseTimeoutMs = options?.responseTimeoutMs ?? DEFAULT_TIMEOUT_MS$1;
|
|
14166
|
+
this.boundOnStateless = (data) => this.handleStateless(data.payload);
|
|
14167
|
+
this.provider.on("stateless", this.boundOnStateless);
|
|
14168
|
+
}
|
|
14169
|
+
/** Stop listening for chat messages. Does not disconnect the underlying provider. */
|
|
14170
|
+
destroy() {
|
|
14171
|
+
this.provider.off("stateless", this.boundOnStateless);
|
|
14172
|
+
for (const queue of this.pending.values()) for (const p of queue) {
|
|
14173
|
+
clearTimeout(p.timer);
|
|
14174
|
+
p.reject(/* @__PURE__ */ new Error("ChatClient destroyed"));
|
|
14175
|
+
}
|
|
14176
|
+
this.pending.clear();
|
|
14177
|
+
this.removeAllListeners();
|
|
14178
|
+
}
|
|
14179
|
+
/** Send a chat message on a channel. Fire-and-forget (the server broadcasts). */
|
|
14180
|
+
sendMessage(input) {
|
|
14181
|
+
this.provider.sendStateless(JSON.stringify({
|
|
14182
|
+
type: "chat:send",
|
|
14183
|
+
channel: input.channel,
|
|
14184
|
+
content: input.content,
|
|
14185
|
+
...input.sender_name !== void 0 ? { sender_name: input.sender_name } : {}
|
|
14186
|
+
}));
|
|
14187
|
+
}
|
|
14188
|
+
/** Fetch historical messages for a channel. Resolves with the server response. */
|
|
14189
|
+
getHistory(input) {
|
|
14190
|
+
const promise = this.enqueue("chat:history");
|
|
14191
|
+
this.provider.sendStateless(JSON.stringify({
|
|
14192
|
+
type: "chat:history",
|
|
14193
|
+
channel: input.channel,
|
|
14194
|
+
...input.before !== void 0 ? { before: input.before } : {},
|
|
14195
|
+
...input.limit !== void 0 ? { limit: input.limit } : {}
|
|
14196
|
+
}));
|
|
14197
|
+
return promise;
|
|
14198
|
+
}
|
|
14199
|
+
/** Broadcast a typing indicator on a channel. */
|
|
14200
|
+
sendTyping(channel) {
|
|
14201
|
+
this.provider.sendStateless(JSON.stringify({
|
|
14202
|
+
type: "chat:typing",
|
|
14203
|
+
channel
|
|
14204
|
+
}));
|
|
14205
|
+
}
|
|
14206
|
+
/** List the current user's channels (ordered by last activity). */
|
|
14207
|
+
listChannels() {
|
|
14208
|
+
const promise = this.enqueue("chat:channels");
|
|
14209
|
+
this.provider.sendStateless(JSON.stringify({ type: "chat:channels" }));
|
|
14210
|
+
return promise;
|
|
14211
|
+
}
|
|
14212
|
+
/** Mark a channel read up to `timestamp` (unix ms). */
|
|
14213
|
+
markRead(channel, timestamp) {
|
|
14214
|
+
this.provider.sendStateless(JSON.stringify({
|
|
14215
|
+
type: "chat:mark_read",
|
|
14216
|
+
channel,
|
|
14217
|
+
timestamp
|
|
14218
|
+
}));
|
|
14219
|
+
}
|
|
14220
|
+
/** Fetch per-user read cursors for a channel. */
|
|
14221
|
+
getReadCursors(channel) {
|
|
14222
|
+
const promise = this.enqueue("chat:read_cursors");
|
|
14223
|
+
this.provider.sendStateless(JSON.stringify({
|
|
14224
|
+
type: "chat:read_cursors",
|
|
14225
|
+
channel
|
|
14226
|
+
}));
|
|
14227
|
+
return promise;
|
|
14228
|
+
}
|
|
14229
|
+
onMessage(fn) {
|
|
14230
|
+
return this.on("message", fn);
|
|
14231
|
+
}
|
|
14232
|
+
onTyping(fn) {
|
|
14233
|
+
return this.on("typing", fn);
|
|
14234
|
+
}
|
|
14235
|
+
onReadReceipt(fn) {
|
|
14236
|
+
return this.on("readReceipt", fn);
|
|
14237
|
+
}
|
|
14238
|
+
enqueue(type) {
|
|
14239
|
+
return new Promise((resolve, reject) => {
|
|
14240
|
+
const entry = {
|
|
14241
|
+
resolve,
|
|
14242
|
+
reject,
|
|
14243
|
+
timer: setTimeout(() => {
|
|
14244
|
+
this.removePending(type, entry);
|
|
14245
|
+
reject(/* @__PURE__ */ new Error(`ChatClient: timeout waiting for ${type} response`));
|
|
14246
|
+
}, this.responseTimeoutMs)
|
|
14247
|
+
};
|
|
14248
|
+
const queue = this.pending.get(type) ?? [];
|
|
14249
|
+
queue.push(entry);
|
|
14250
|
+
this.pending.set(type, queue);
|
|
14251
|
+
});
|
|
14252
|
+
}
|
|
14253
|
+
removePending(type, entry) {
|
|
14254
|
+
const queue = this.pending.get(type);
|
|
14255
|
+
if (!queue) return;
|
|
14256
|
+
const idx = queue.indexOf(entry);
|
|
14257
|
+
if (idx >= 0) queue.splice(idx, 1);
|
|
14258
|
+
if (queue.length === 0) this.pending.delete(type);
|
|
14259
|
+
}
|
|
14260
|
+
resolveNext(type, value) {
|
|
14261
|
+
const queue = this.pending.get(type);
|
|
14262
|
+
if (!queue || queue.length === 0) return false;
|
|
14263
|
+
const next = queue.shift();
|
|
14264
|
+
if (queue.length === 0) this.pending.delete(type);
|
|
14265
|
+
clearTimeout(next.timer);
|
|
14266
|
+
next.resolve(value);
|
|
14267
|
+
return true;
|
|
14268
|
+
}
|
|
14269
|
+
handleStateless(payload) {
|
|
14270
|
+
let parsed;
|
|
14271
|
+
try {
|
|
14272
|
+
parsed = JSON.parse(payload);
|
|
14273
|
+
} catch {
|
|
14274
|
+
return;
|
|
14275
|
+
}
|
|
14276
|
+
const type = parsed?.type;
|
|
14277
|
+
if (typeof type !== "string" || !type.startsWith("chat:")) return;
|
|
14278
|
+
switch (type) {
|
|
14279
|
+
case "chat:message": {
|
|
14280
|
+
const { type: _t, ...rest } = parsed;
|
|
14281
|
+
this.emit("message", rest);
|
|
14282
|
+
break;
|
|
14283
|
+
}
|
|
14284
|
+
case "chat:history":
|
|
14285
|
+
this.resolveNext("chat:history", {
|
|
14286
|
+
channel: parsed.channel,
|
|
14287
|
+
messages: parsed.messages ?? []
|
|
14288
|
+
});
|
|
14289
|
+
break;
|
|
14290
|
+
case "chat:channels":
|
|
14291
|
+
this.resolveNext("chat:channels", { channels: parsed.channels ?? [] });
|
|
14292
|
+
break;
|
|
14293
|
+
case "chat:typing":
|
|
14294
|
+
this.emit("typing", {
|
|
14295
|
+
channel: parsed.channel,
|
|
14296
|
+
sender_id: parsed.sender_id,
|
|
14297
|
+
sender_name: parsed.sender_name ?? null
|
|
14298
|
+
});
|
|
14299
|
+
break;
|
|
14300
|
+
case "chat:read_receipt":
|
|
14301
|
+
this.emit("readReceipt", {
|
|
14302
|
+
channel: parsed.channel,
|
|
14303
|
+
user_id: parsed.user_id,
|
|
14304
|
+
last_read_at: parsed.last_read_at
|
|
14305
|
+
});
|
|
14306
|
+
break;
|
|
14307
|
+
case "chat:read_cursors":
|
|
14308
|
+
this.resolveNext("chat:read_cursors", {
|
|
14309
|
+
channel: parsed.channel,
|
|
14310
|
+
cursors: parsed.cursors ?? []
|
|
14311
|
+
});
|
|
14312
|
+
break;
|
|
14313
|
+
default: break;
|
|
14314
|
+
}
|
|
14315
|
+
}
|
|
14316
|
+
};
|
|
14317
|
+
|
|
14318
|
+
//#endregion
|
|
14319
|
+
//#region packages/provider/src/NotificationsClient.ts
|
|
14320
|
+
const DEFAULT_TIMEOUT_MS = 1e4;
|
|
14321
|
+
/**
|
|
14322
|
+
* Typed client for the Abracadabra notifications feature.
|
|
14323
|
+
*
|
|
14324
|
+
* Emits:
|
|
14325
|
+
* - `new` → NotificationRecord (incoming notify:new broadcast)
|
|
14326
|
+
* - `readUpdate` → NotificationReadUpdate (broadcast after mark_read / mark_all_read)
|
|
14327
|
+
*/
|
|
14328
|
+
var NotificationsClient = class extends EventEmitter {
|
|
14329
|
+
constructor(provider, options) {
|
|
14330
|
+
super();
|
|
14331
|
+
this.pending = /* @__PURE__ */ new Map();
|
|
14332
|
+
this.provider = provider;
|
|
14333
|
+
this.responseTimeoutMs = options?.responseTimeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
14334
|
+
this.boundOnStateless = (data) => this.handleStateless(data.payload);
|
|
14335
|
+
this.provider.on("stateless", this.boundOnStateless);
|
|
14336
|
+
}
|
|
14337
|
+
destroy() {
|
|
14338
|
+
this.provider.off("stateless", this.boundOnStateless);
|
|
14339
|
+
for (const queue of this.pending.values()) for (const p of queue) {
|
|
14340
|
+
clearTimeout(p.timer);
|
|
14341
|
+
p.reject(/* @__PURE__ */ new Error("NotificationsClient destroyed"));
|
|
14342
|
+
}
|
|
14343
|
+
this.pending.clear();
|
|
14344
|
+
this.removeAllListeners();
|
|
14345
|
+
}
|
|
14346
|
+
/**
|
|
14347
|
+
* Create a notification targeting a specific recipient. Requires elevated role
|
|
14348
|
+
* (service or admin); a `server:error` event with code `forbidden` is emitted
|
|
14349
|
+
* by the underlying provider if the caller lacks permission.
|
|
14350
|
+
*/
|
|
14351
|
+
create(input) {
|
|
14352
|
+
this.provider.sendStateless(JSON.stringify({
|
|
14353
|
+
type: "notify:create",
|
|
14354
|
+
recipient_id: input.recipient_id,
|
|
14355
|
+
...input.notification_type !== void 0 ? { notification_type: input.notification_type } : {},
|
|
14356
|
+
title: input.title,
|
|
14357
|
+
...input.body !== void 0 ? { body: input.body } : {},
|
|
14358
|
+
...input.icon !== void 0 ? { icon: input.icon } : {},
|
|
14359
|
+
...input.link !== void 0 ? { link: input.link } : {},
|
|
14360
|
+
...input.source_id !== void 0 ? { source_id: input.source_id } : {}
|
|
14361
|
+
}));
|
|
14362
|
+
}
|
|
14363
|
+
/** Fetch notification history for the current user. */
|
|
14364
|
+
fetch(input = {}) {
|
|
14365
|
+
const promise = this.enqueue("notify:history");
|
|
14366
|
+
this.provider.sendStateless(JSON.stringify({
|
|
14367
|
+
type: "notify:fetch",
|
|
14368
|
+
...input.before !== void 0 ? { before: input.before } : {},
|
|
14369
|
+
...input.limit !== void 0 ? { limit: input.limit } : {},
|
|
14370
|
+
...input.unread_only !== void 0 ? { unread_only: input.unread_only } : {}
|
|
14371
|
+
}));
|
|
14372
|
+
return promise;
|
|
14373
|
+
}
|
|
14374
|
+
/** Mark a single notification, or a batch, as read. */
|
|
14375
|
+
markRead(target) {
|
|
14376
|
+
const body = { type: "notify:mark_read" };
|
|
14377
|
+
if ("id" in target) body.id = target.id;
|
|
14378
|
+
else body.ids = target.ids;
|
|
14379
|
+
this.provider.sendStateless(JSON.stringify(body));
|
|
14380
|
+
}
|
|
14381
|
+
/** Mark every notification for the current user as read. */
|
|
14382
|
+
markAllRead() {
|
|
14383
|
+
this.provider.sendStateless(JSON.stringify({ type: "notify:mark_all_read" }));
|
|
14384
|
+
}
|
|
14385
|
+
/** Mark all notifications generated by the given source (e.g. a chat channel) as read. */
|
|
14386
|
+
markReadBySource(sourceId) {
|
|
14387
|
+
this.provider.sendStateless(JSON.stringify({
|
|
14388
|
+
type: "notify:mark_read_by_source",
|
|
14389
|
+
source_id: sourceId
|
|
14390
|
+
}));
|
|
14391
|
+
}
|
|
14392
|
+
onNew(fn) {
|
|
14393
|
+
return this.on("new", fn);
|
|
14394
|
+
}
|
|
14395
|
+
onReadUpdate(fn) {
|
|
14396
|
+
return this.on("readUpdate", fn);
|
|
14397
|
+
}
|
|
14398
|
+
enqueue(type) {
|
|
14399
|
+
return new Promise((resolve, reject) => {
|
|
14400
|
+
const entry = {
|
|
14401
|
+
resolve,
|
|
14402
|
+
reject,
|
|
14403
|
+
timer: setTimeout(() => {
|
|
14404
|
+
this.removePending(type, entry);
|
|
14405
|
+
reject(/* @__PURE__ */ new Error(`NotificationsClient: timeout waiting for ${type} response`));
|
|
14406
|
+
}, this.responseTimeoutMs)
|
|
14407
|
+
};
|
|
14408
|
+
const queue = this.pending.get(type) ?? [];
|
|
14409
|
+
queue.push(entry);
|
|
14410
|
+
this.pending.set(type, queue);
|
|
14411
|
+
});
|
|
14412
|
+
}
|
|
14413
|
+
removePending(type, entry) {
|
|
14414
|
+
const queue = this.pending.get(type);
|
|
14415
|
+
if (!queue) return;
|
|
14416
|
+
const idx = queue.indexOf(entry);
|
|
14417
|
+
if (idx >= 0) queue.splice(idx, 1);
|
|
14418
|
+
if (queue.length === 0) this.pending.delete(type);
|
|
14419
|
+
}
|
|
14420
|
+
resolveNext(type, value) {
|
|
14421
|
+
const queue = this.pending.get(type);
|
|
14422
|
+
if (!queue || queue.length === 0) return false;
|
|
14423
|
+
const next = queue.shift();
|
|
14424
|
+
if (queue.length === 0) this.pending.delete(type);
|
|
14425
|
+
clearTimeout(next.timer);
|
|
14426
|
+
next.resolve(value);
|
|
14427
|
+
return true;
|
|
14428
|
+
}
|
|
14429
|
+
handleStateless(payload) {
|
|
14430
|
+
let parsed;
|
|
14431
|
+
try {
|
|
14432
|
+
parsed = JSON.parse(payload);
|
|
14433
|
+
} catch {
|
|
14434
|
+
return;
|
|
14435
|
+
}
|
|
14436
|
+
const type = parsed?.type;
|
|
14437
|
+
if (typeof type !== "string" || !type.startsWith("notify:")) return;
|
|
14438
|
+
switch (type) {
|
|
14439
|
+
case "notify:new": {
|
|
14440
|
+
const { type: _t, ...rest } = parsed;
|
|
14441
|
+
this.emit("new", rest);
|
|
14442
|
+
break;
|
|
14443
|
+
}
|
|
14444
|
+
case "notify:history":
|
|
14445
|
+
this.resolveNext("notify:history", { notifications: parsed.notifications ?? [] });
|
|
14446
|
+
break;
|
|
14447
|
+
case "notify:read_update": {
|
|
14448
|
+
const update = { recipient_id: parsed.recipient_id };
|
|
14449
|
+
if (parsed.ids !== void 0) update.ids = parsed.ids;
|
|
14450
|
+
if (parsed.all !== void 0) update.all = parsed.all;
|
|
14451
|
+
this.emit("readUpdate", update);
|
|
14452
|
+
break;
|
|
14453
|
+
}
|
|
14454
|
+
default: break;
|
|
14455
|
+
}
|
|
14456
|
+
}
|
|
14457
|
+
};
|
|
14458
|
+
|
|
14459
|
+
//#endregion
|
|
14460
|
+
export { AbracadabraBaseProvider, AbracadabraClient, AbracadabraProvider, AbracadabraWS, AbracadabraWebRTC, AuthMessageType, AwarenessError, BackgroundSyncManager, BackgroundSyncPersistence, BroadcastChannelSync, CHANNEL_NAMES, ChatClient, ConnectionTimeout, CryptoIdentityKeystore, DEFAULT_FILE_CHUNK_SIZE, DEFAULT_ICE_SERVERS, DataChannelRouter, DevicePairingChannel, DeviceRegistrationService, DocKeyManager, DocumentCache, E2EAbracadabraProvider, E2EEChannel, E2EOfflineStore, EncryptedYMap, EncryptedYText, FileBlobStore, FileTransferChannel, FileTransferHandle, Forbidden, HocuspocusProvider, HocuspocusProviderWebsocket, IdentityDocProvider, KEY_EXCHANGE_CHANNEL, ManualSignaling, MessageTooBig, MessageType, NotificationsClient, OfflineStore, PeerConnection, ResetConnection, SearchIndex, SignalingSocket, SubdocMessage, Unauthorized, WebSocketStatus, WsReadyStates, YjsDataChannel, attachUpdatedAtObserver, awarenessStatesToArray, wordlist as bip39Wordlist, decryptField, deriveIdentityDocId, deriveSeedWrappingKey, encryptField, generateMnemonic, makeEncryptedYMap, makeEncryptedYText, mnemonicToEd25519Seed, mnemonicToKeyPair, readAuthMessage, unwrapSeed, validateMnemonic, wrapSeed, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest };
|
|
14116
14461
|
//# sourceMappingURL=abracadabra-provider.esm.js.map
|