@abraca/dabra 1.0.20 → 1.0.22
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 +595 -5
- package/dist/abracadabra-provider.cjs.map +1 -1
- package/dist/abracadabra-provider.esm.js +593 -6
- package/dist/abracadabra-provider.esm.js.map +1 -1
- package/dist/index.d.ts +251 -1
- package/package.json +1 -1
- package/src/AbracadabraClient.ts +27 -0
- package/src/AbracadabraProvider.ts +10 -1
- package/src/IdentityDoc.ts +497 -0
- package/src/index.ts +7 -0
- package/src/types.ts +3 -0
- package/src/webrtc/AbracadabraWebRTC.ts +8 -4
- package/src/webrtc/DevicePairingChannel.ts +384 -0
- package/src/webrtc/index.ts +2 -0
package/dist/index.d.ts
CHANGED
|
@@ -315,8 +315,31 @@ declare class AbracadabraClient {
|
|
|
315
315
|
}): Promise<void>;
|
|
316
316
|
/** List all registered public keys for the current user. */
|
|
317
317
|
listKeys(): Promise<PublicKeyInfo[]>;
|
|
318
|
+
/** Rename a registered device key. */
|
|
319
|
+
renameKey(keyId: string, deviceName: string): Promise<void>;
|
|
318
320
|
/** Revoke a public key by its ID. */
|
|
319
321
|
revokeKey(keyId: string): Promise<void>;
|
|
322
|
+
/** Create a single-use device invite code for pairing a new device to this account. */
|
|
323
|
+
createDeviceInvite(opts?: {
|
|
324
|
+
expiresIn?: number;
|
|
325
|
+
}): Promise<{
|
|
326
|
+
code: string;
|
|
327
|
+
expiresAt: number;
|
|
328
|
+
}>;
|
|
329
|
+
/** Redeem a device invite code to register a new device key. Returns a JWT token. */
|
|
330
|
+
redeemDeviceInvite(opts: {
|
|
331
|
+
code: string;
|
|
332
|
+
publicKey: string;
|
|
333
|
+
x25519Key?: string;
|
|
334
|
+
deviceName?: string;
|
|
335
|
+
}): Promise<{
|
|
336
|
+
token: string;
|
|
337
|
+
user: {
|
|
338
|
+
id: string;
|
|
339
|
+
username: string;
|
|
340
|
+
publicKey: string;
|
|
341
|
+
};
|
|
342
|
+
}>;
|
|
320
343
|
/** Get encryption info for a document. */
|
|
321
344
|
getDocEncryption(docId: string): Promise<DocEncryptionInfo>;
|
|
322
345
|
/** Set the encryption mode for a document (no downgrade). */
|
|
@@ -598,6 +621,12 @@ interface AbracadabraProviderConfiguration extends Omit<AbracadabraBaseProviderC
|
|
|
598
621
|
keystore?: CryptoIdentityKeystore;
|
|
599
622
|
/** Shared WebSocket connection (use when multiplexing multiple root documents). */
|
|
600
623
|
websocketProvider?: AbracadabraWS;
|
|
624
|
+
/**
|
|
625
|
+
* When true, the IndexedDB offline store is NOT scoped by server origin.
|
|
626
|
+
* This allows a single document to be synced across multiple servers while
|
|
627
|
+
* sharing one local store. Used for the identity doc.
|
|
628
|
+
*/
|
|
629
|
+
serverAgnostic?: boolean;
|
|
601
630
|
}
|
|
602
631
|
/**
|
|
603
632
|
* AbracadabraProvider extends AbracadabraBaseProvider with:
|
|
@@ -1008,6 +1037,9 @@ interface PublicKeyInfo {
|
|
|
1008
1037
|
publicKey: string;
|
|
1009
1038
|
deviceName: string | null;
|
|
1010
1039
|
revoked: boolean;
|
|
1040
|
+
createdAt?: number | null;
|
|
1041
|
+
pairedBy?: string | null;
|
|
1042
|
+
pairedVia?: string | null;
|
|
1011
1043
|
}
|
|
1012
1044
|
interface PermissionEntry {
|
|
1013
1045
|
user_id: string;
|
|
@@ -2040,6 +2072,7 @@ declare class AbracadabraWebRTC extends EventEmitter {
|
|
|
2040
2072
|
broadcastFile(file: File | Blob, filename: string): Promise<FileTransferHandle[]>;
|
|
2041
2073
|
/**
|
|
2042
2074
|
* Send a custom string message to a specific peer via a data channel.
|
|
2075
|
+
* When E2EE is active, the message is encrypted through the router.
|
|
2043
2076
|
*/
|
|
2044
2077
|
sendCustomMessage(peerId: string, payload: string): void;
|
|
2045
2078
|
/**
|
|
@@ -2211,6 +2244,82 @@ declare class ManualSignaling extends EventEmitter {
|
|
|
2211
2244
|
destroy(): void;
|
|
2212
2245
|
}
|
|
2213
2246
|
//#endregion
|
|
2247
|
+
//#region packages/provider/src/webrtc/DevicePairingChannel.d.ts
|
|
2248
|
+
interface DevicePairingConfig {
|
|
2249
|
+
/** Server base URL (http/https). */
|
|
2250
|
+
serverUrl: string;
|
|
2251
|
+
/** JWT token or async token factory for signaling auth. */
|
|
2252
|
+
token: string | (() => string) | (() => Promise<string>);
|
|
2253
|
+
/** E2EE identity (Ed25519 public key + X25519 private key). */
|
|
2254
|
+
e2ee: E2EEIdentity;
|
|
2255
|
+
/** ICE servers. Defaults to Google STUN. */
|
|
2256
|
+
iceServers?: RTCIceServer[];
|
|
2257
|
+
/** WebSocket polyfill (for Node.js). */
|
|
2258
|
+
WebSocketPolyfill?: any;
|
|
2259
|
+
}
|
|
2260
|
+
interface PairingRequest {
|
|
2261
|
+
/** Device B's Ed25519 public key (base64url). */
|
|
2262
|
+
publicKey: string;
|
|
2263
|
+
/** Device B's X25519 public key (base64url). */
|
|
2264
|
+
x25519Key: string;
|
|
2265
|
+
/** Human-readable device label. */
|
|
2266
|
+
deviceName: string;
|
|
2267
|
+
}
|
|
2268
|
+
interface PairingResult {
|
|
2269
|
+
success: boolean;
|
|
2270
|
+
error?: string;
|
|
2271
|
+
}
|
|
2272
|
+
type PairingRole = "approver" | "requester";
|
|
2273
|
+
declare class DevicePairingChannel extends EventEmitter {
|
|
2274
|
+
private readonly config;
|
|
2275
|
+
private webrtc;
|
|
2276
|
+
private timeoutHandle;
|
|
2277
|
+
private _destroyed;
|
|
2278
|
+
private _pendingRequest;
|
|
2279
|
+
private _connectedPeerId;
|
|
2280
|
+
readonly role: PairingRole;
|
|
2281
|
+
readonly pairingCode: string;
|
|
2282
|
+
private constructor();
|
|
2283
|
+
/**
|
|
2284
|
+
* Create an approver session (Device A). Returns the channel and a
|
|
2285
|
+
* 6-character pairing code to share with Device B.
|
|
2286
|
+
*/
|
|
2287
|
+
static createApprover(config: DevicePairingConfig): {
|
|
2288
|
+
channel: DevicePairingChannel;
|
|
2289
|
+
pairingCode: string;
|
|
2290
|
+
};
|
|
2291
|
+
/**
|
|
2292
|
+
* Create a requester session (Device B). Joins with a pairing code
|
|
2293
|
+
* obtained from Device A.
|
|
2294
|
+
*/
|
|
2295
|
+
static createRequester(config: DevicePairingConfig, pairingCode: string): DevicePairingChannel;
|
|
2296
|
+
/**
|
|
2297
|
+
* Approve the pending pairing request. Calls `client.addKey()` to
|
|
2298
|
+
* register Device B's public key, then notifies Device B.
|
|
2299
|
+
*/
|
|
2300
|
+
approve(client: AbracadabraClient): Promise<PairingResult>;
|
|
2301
|
+
/**
|
|
2302
|
+
* Approve via server-side device invite. Creates a single-use invite code
|
|
2303
|
+
* and sends it to Device B over the E2EE channel. Device B redeems it
|
|
2304
|
+
* independently via HTTP — Device A can go offline after this.
|
|
2305
|
+
*/
|
|
2306
|
+
approveWithInvite(client: AbracadabraClient): Promise<PairingResult>;
|
|
2307
|
+
/**
|
|
2308
|
+
* Reject the pending pairing request.
|
|
2309
|
+
*/
|
|
2310
|
+
reject(reason?: string): void;
|
|
2311
|
+
/**
|
|
2312
|
+
* Send a pairing request to Device A. Call this after the "connected"
|
|
2313
|
+
* event fires.
|
|
2314
|
+
*/
|
|
2315
|
+
requestPairing(request: PairingRequest): void;
|
|
2316
|
+
get isDestroyed(): boolean;
|
|
2317
|
+
destroy(): void;
|
|
2318
|
+
private start;
|
|
2319
|
+
private sendMessage;
|
|
2320
|
+
private handleMessage;
|
|
2321
|
+
}
|
|
2322
|
+
//#endregion
|
|
2214
2323
|
//#region packages/provider/src/sync/BroadcastChannelSync.d.ts
|
|
2215
2324
|
declare class BroadcastChannelSync extends EventEmitter {
|
|
2216
2325
|
private readonly document;
|
|
@@ -2239,4 +2348,145 @@ declare class BroadcastChannelSync extends EventEmitter {
|
|
|
2239
2348
|
private handleAwarenessMessage;
|
|
2240
2349
|
}
|
|
2241
2350
|
//#endregion
|
|
2242
|
-
|
|
2351
|
+
//#region packages/provider/src/IdentityDoc.d.ts
|
|
2352
|
+
/**
|
|
2353
|
+
* Derives a deterministic UUID from an Ed25519 account-level public key.
|
|
2354
|
+
*
|
|
2355
|
+
* The result is a valid UUID v5-style string that any device sharing the
|
|
2356
|
+
* same identity can independently compute. The `abracadabra:identity:`
|
|
2357
|
+
* prefix prevents collisions with randomly generated doc UUIDs.
|
|
2358
|
+
*
|
|
2359
|
+
* @param publicKeyB64 Base64url-encoded Ed25519 public key (32 bytes).
|
|
2360
|
+
*/
|
|
2361
|
+
declare function deriveIdentityDocId(publicKeyB64: string): string;
|
|
2362
|
+
interface IdentityProfile {
|
|
2363
|
+
username?: string;
|
|
2364
|
+
displayName?: string;
|
|
2365
|
+
colorName?: string;
|
|
2366
|
+
neutralColorName?: string;
|
|
2367
|
+
locale?: string;
|
|
2368
|
+
avatarUrl?: string;
|
|
2369
|
+
}
|
|
2370
|
+
interface IdentityServerEntry {
|
|
2371
|
+
label: string;
|
|
2372
|
+
hubDocId?: string;
|
|
2373
|
+
entryDocId?: string;
|
|
2374
|
+
defaultRole?: string;
|
|
2375
|
+
spacesEnabled?: boolean;
|
|
2376
|
+
addedAt: number;
|
|
2377
|
+
}
|
|
2378
|
+
interface IdentitySpaceEntry {
|
|
2379
|
+
id: string;
|
|
2380
|
+
name: string;
|
|
2381
|
+
type: "local" | "remote";
|
|
2382
|
+
serverUrl: string | null;
|
|
2383
|
+
docId: string;
|
|
2384
|
+
remoteSpaceId?: string;
|
|
2385
|
+
visibility: "public" | "private" | "invite";
|
|
2386
|
+
isHub: boolean;
|
|
2387
|
+
order: number;
|
|
2388
|
+
lastSyncedAt?: number;
|
|
2389
|
+
createdAt: number;
|
|
2390
|
+
}
|
|
2391
|
+
interface IdentityDocConfiguration {
|
|
2392
|
+
/** Base64url-encoded Ed25519 account public key. */
|
|
2393
|
+
publicKey: string;
|
|
2394
|
+
/**
|
|
2395
|
+
* Trusted server URL for identity doc sync.
|
|
2396
|
+
* Only this server (plus the local server) will receive the identity doc.
|
|
2397
|
+
*/
|
|
2398
|
+
syncServerUrl?: string;
|
|
2399
|
+
/** Local Tauri server URL for on-device persistence. */
|
|
2400
|
+
localServerUrl?: string;
|
|
2401
|
+
/**
|
|
2402
|
+
* JWT token or async factory for authenticating with sync servers.
|
|
2403
|
+
* When using multiple servers, provide a factory that returns the correct
|
|
2404
|
+
* token for each.
|
|
2405
|
+
*/
|
|
2406
|
+
token?: string | (() => string) | (() => Promise<string>);
|
|
2407
|
+
/** Per-server token factories keyed by base URL. */
|
|
2408
|
+
tokens?: Record<string, string | (() => string) | (() => Promise<string>)>;
|
|
2409
|
+
/**
|
|
2410
|
+
* WebRTC configuration for P2P identity sync.
|
|
2411
|
+
* When provided, enables E2EE peer-to-peer sync using signaling from
|
|
2412
|
+
* any connected server.
|
|
2413
|
+
*/
|
|
2414
|
+
webrtc?: {
|
|
2415
|
+
/** Server URL to use for signaling (any connected server works). */signalingServerUrl: string; /** Token for the signaling server. */
|
|
2416
|
+
token: string | (() => string) | (() => Promise<string>); /** E2EE identity for the data channel. */
|
|
2417
|
+
e2ee?: E2EEIdentity; /** ICE servers. */
|
|
2418
|
+
iceServers?: RTCIceServer[];
|
|
2419
|
+
};
|
|
2420
|
+
/** Disable IndexedDB offline store. */
|
|
2421
|
+
disableOfflineStore?: boolean;
|
|
2422
|
+
/** Auto-connect on construction. Default: true. */
|
|
2423
|
+
autoConnect?: boolean;
|
|
2424
|
+
/** Additional provider config passed through to each AbracadabraProvider. */
|
|
2425
|
+
providerDefaults?: Partial<AbracadabraProviderConfiguration>;
|
|
2426
|
+
}
|
|
2427
|
+
/**
|
|
2428
|
+
* Manages a Y.Doc dedicated to user identity that syncs across trusted
|
|
2429
|
+
* targets only: a designated sync server, a local Tauri server, and/or
|
|
2430
|
+
* WebRTC P2P.
|
|
2431
|
+
*
|
|
2432
|
+
* The Y.Doc contains cross-device settings (profile, servers, spaces,
|
|
2433
|
+
* plugins, preferences). Each sync target gets its own
|
|
2434
|
+
* AbracadabraProvider sharing the same Y.Doc, with `serverAgnostic: true`
|
|
2435
|
+
* so they all use one IndexedDB store.
|
|
2436
|
+
*/
|
|
2437
|
+
declare class IdentityDocProvider extends EventEmitter {
|
|
2438
|
+
readonly docId: string;
|
|
2439
|
+
readonly document: Y.Doc;
|
|
2440
|
+
private providers;
|
|
2441
|
+
private websockets;
|
|
2442
|
+
private webrtc;
|
|
2443
|
+
private config;
|
|
2444
|
+
private _destroyed;
|
|
2445
|
+
constructor(configuration: IdentityDocConfiguration);
|
|
2446
|
+
connect(): void;
|
|
2447
|
+
private _connectToServer;
|
|
2448
|
+
private _connectWebRTC;
|
|
2449
|
+
get profileMap(): Y.Map<string>;
|
|
2450
|
+
get serversMap(): Y.Map<Y.Map<any>>;
|
|
2451
|
+
get spacesArray(): Y.Array<Y.Map<any>>;
|
|
2452
|
+
get pluginsMap(): Y.Map<any>;
|
|
2453
|
+
get preferencesMap(): Y.Map<any>;
|
|
2454
|
+
getProfile(): IdentityProfile;
|
|
2455
|
+
setProfile(profile: Partial<IdentityProfile>): void;
|
|
2456
|
+
getServer(url: string): IdentityServerEntry | undefined;
|
|
2457
|
+
setServer(url: string, entry: IdentityServerEntry): void;
|
|
2458
|
+
removeServer(url: string): void;
|
|
2459
|
+
getServers(): Map<string, IdentityServerEntry>;
|
|
2460
|
+
getSpaces(): IdentitySpaceEntry[];
|
|
2461
|
+
addSpace(space: IdentitySpaceEntry): void;
|
|
2462
|
+
removeSpace(spaceId: string): void;
|
|
2463
|
+
updateSpace(spaceId: string, updates: Partial<IdentitySpaceEntry>): void;
|
|
2464
|
+
getExternalPlugins(): Y.Array<Y.Map<any>>;
|
|
2465
|
+
getDisabledBuiltins(): Y.Array<string>;
|
|
2466
|
+
getPreference<T = any>(key: string): T | undefined;
|
|
2467
|
+
setPreference(key: string, value: any): void;
|
|
2468
|
+
/**
|
|
2469
|
+
* Observe deep changes on a specific top-level map.
|
|
2470
|
+
* Returns an unsubscribe function.
|
|
2471
|
+
*/
|
|
2472
|
+
observe(mapName: "profile" | "servers" | "plugins" | "preferences", callback: (events: Y.YEvent<any>[], transaction: Y.Transaction) => void): () => void;
|
|
2473
|
+
/**
|
|
2474
|
+
* Observe changes to the spaces array.
|
|
2475
|
+
* Returns an unsubscribe function.
|
|
2476
|
+
*/
|
|
2477
|
+
observeSpaces(callback: (event: Y.YArrayEvent<Y.Map<any>>, transaction: Y.Transaction) => void): () => void;
|
|
2478
|
+
/**
|
|
2479
|
+
* Returns true if the identity doc has no profile data yet (first use).
|
|
2480
|
+
* Call this to decide whether to run migration from localStorage.
|
|
2481
|
+
*/
|
|
2482
|
+
isEmpty(): boolean;
|
|
2483
|
+
/**
|
|
2484
|
+
* Update the sync server URL at runtime (e.g. when user changes their
|
|
2485
|
+
* designated sync server in settings).
|
|
2486
|
+
*/
|
|
2487
|
+
setSyncServer(url: string | null): void;
|
|
2488
|
+
getProvider(key: string): AbracadabraProvider | undefined;
|
|
2489
|
+
destroy(): void;
|
|
2490
|
+
}
|
|
2491
|
+
//#endregion
|
|
2492
|
+
export { AbracadabraBaseProvider, AbracadabraBaseProviderConfiguration, AbracadabraClient, AbracadabraClientConfig, AbracadabraOutgoingMessageArguments, AbracadabraProvider, AbracadabraProviderConfiguration, AbracadabraWS, AbracadabraWSConfiguration, AbracadabraWebRTC, type AbracadabraWebRTCConfiguration, AbracadabraWebSocketConn, AuthMessageType, AuthorizedScope, AwarenessError, BackgroundSyncManager, type BackgroundSyncManagerOptions, BackgroundSyncPersistence, BroadcastChannelSync, CHANNEL_NAMES, CloseEvent, CompleteAbracadabraBaseProviderConfiguration, CompleteAbracadabraWSConfiguration, CompleteHocuspocusProviderConfiguration, CompleteHocuspocusProviderWebsocketConfiguration, ConnectionTimeout, Constructable, ConstructableOutgoingMessage, CryptoIdentity, CryptoIdentityKeystore, DEFAULT_FILE_CHUNK_SIZE, DEFAULT_ICE_SERVERS, DataChannelRouter, DevicePairingChannel, type DevicePairingConfig, type DocEncryptionInfo, DocKeyManager, type DocSyncState, DocumentCache, type DocumentCacheOptions, DocumentMeta, E2EAbracadabraProvider, E2EEChannel, type E2EEIdentity, E2EOfflineStore, EffectivePermissionEntry, EffectivePermissionsResponse, EffectiveRole, EncryptedYMap, EncryptedYText, FileBlobStore, FileTransferChannel, FileTransferHandle, type FileTransferMeta, type FileTransferStatus, Forbidden, HealthStatus, HocusPocusWebSocket, HocuspocusProvider, HocuspocusProviderConfiguration, HocuspocusProviderWebsocket, HocuspocusProviderWebsocketConfiguration, HocuspocusWebSocket, type IdentityDocConfiguration, IdentityDocProvider, type IdentityProfile, type IdentityServerEntry, type IdentitySpaceEntry, InviteRow, KEY_EXCHANGE_CHANNEL, ManualSignaling, type ManualSignalingBlob, MessageTooBig, MessageType, OfflineStore, OutgoingMessageArguments, OutgoingMessageInterface, type PairingRequest, type PairingResult, PeerConnection, type PeerInfo, type PeerState, PendingSubdoc, PermissionEntry, PublicKeyInfo, ResetConnection, SearchIndex, SearchResult, ServerInfo, type SignalingIncoming, type SignalingOutgoing, SignalingSocket, SpaceMeta, StatesArray, SubdocMessage, SubdocRegisteredEvent, Unauthorized, UploadInfo, UploadMeta, UploadQueueEntry, UploadQueueStatus, UserProfile, WebSocketStatus, WsReadyStates, YjsDataChannel, attachUpdatedAtObserver, awarenessStatesToArray, decryptField, deriveIdentityDocId, encryptField, makeEncryptedYMap, makeEncryptedYText, onAuthenticatedParameters, onAuthenticationFailedParameters, onAwarenessChangeParameters, onAwarenessUpdateParameters, onCloseParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onStatelessParameters, onStatusParameters, onSubdocLoadedParameters, onSubdocRegisteredParameters, onSyncedParameters, onUnsyncedChangesParameters, readAuthMessage, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest };
|
package/package.json
CHANGED
package/src/AbracadabraClient.ts
CHANGED
|
@@ -195,11 +195,38 @@ export class AbracadabraClient {
|
|
|
195
195
|
return res.keys;
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
+
/** Rename a registered device key. */
|
|
199
|
+
async renameKey(keyId: string, deviceName: string): Promise<void> {
|
|
200
|
+
await this.request("PATCH", `/auth/keys/${encodeURIComponent(keyId)}`, { body: { deviceName } });
|
|
201
|
+
}
|
|
202
|
+
|
|
198
203
|
/** Revoke a public key by its ID. */
|
|
199
204
|
async revokeKey(keyId: string): Promise<void> {
|
|
200
205
|
await this.request("DELETE", `/auth/keys/${encodeURIComponent(keyId)}`);
|
|
201
206
|
}
|
|
202
207
|
|
|
208
|
+
// ── Device Invites ───────────────────────────────────────────────────────
|
|
209
|
+
|
|
210
|
+
/** Create a single-use device invite code for pairing a new device to this account. */
|
|
211
|
+
async createDeviceInvite(opts?: { expiresIn?: number }): Promise<{ code: string; expiresAt: number }> {
|
|
212
|
+
return this.request<{ code: string; expiresAt: number }>("POST", "/auth/device-invite", {
|
|
213
|
+
body: opts?.expiresIn != null ? { expiresIn: opts.expiresIn } : {},
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** Redeem a device invite code to register a new device key. Returns a JWT token. */
|
|
218
|
+
async redeemDeviceInvite(opts: {
|
|
219
|
+
code: string;
|
|
220
|
+
publicKey: string;
|
|
221
|
+
x25519Key?: string;
|
|
222
|
+
deviceName?: string;
|
|
223
|
+
}): Promise<{ token: string; user: { id: string; username: string; publicKey: string } }> {
|
|
224
|
+
return this.request("POST", "/auth/device-redeem", {
|
|
225
|
+
body: { code: opts.code, publicKey: opts.publicKey, x25519Key: opts.x25519Key, deviceName: opts.deviceName },
|
|
226
|
+
auth: false,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
203
230
|
// ── Encryption ───────────────────────────────────────────────────────────
|
|
204
231
|
|
|
205
232
|
/** Get encryption info for a document. */
|
|
@@ -66,6 +66,13 @@ export interface AbracadabraProviderConfiguration
|
|
|
66
66
|
|
|
67
67
|
/** Shared WebSocket connection (use when multiplexing multiple root documents). */
|
|
68
68
|
websocketProvider?: AbracadabraWS;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* When true, the IndexedDB offline store is NOT scoped by server origin.
|
|
72
|
+
* This allows a single document to be synced across multiple servers while
|
|
73
|
+
* sharing one local store. Used for the identity doc.
|
|
74
|
+
*/
|
|
75
|
+
serverAgnostic?: boolean;
|
|
69
76
|
}
|
|
70
77
|
|
|
71
78
|
/** Validate that a string is a UUID acceptable by the server's DocId parser. */
|
|
@@ -134,7 +141,9 @@ export class AbracadabraProvider extends AbracadabraBaseProvider {
|
|
|
134
141
|
this.abracadabraConfig = configuration;
|
|
135
142
|
this.subdocLoading = configuration.subdocLoading ?? "lazy";
|
|
136
143
|
|
|
137
|
-
const serverOrigin =
|
|
144
|
+
const serverOrigin = configuration.serverAgnostic
|
|
145
|
+
? undefined
|
|
146
|
+
: AbracadabraProvider.deriveServerOrigin(configuration, client);
|
|
138
147
|
this.offlineStore = configuration.disableOfflineStore
|
|
139
148
|
? null
|
|
140
149
|
: new OfflineStore(configuration.name, serverOrigin);
|