@abraca/dabra 1.3.3 → 1.5.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/index.d.ts CHANGED
@@ -528,6 +528,23 @@ declare class AbracadabraClient {
528
528
  refCountsRepaired: number;
529
529
  blobsSwept: number;
530
530
  }>;
531
+ /** List snapshot metadata for a document. */
532
+ listSnapshots(docId: string, opts?: {
533
+ limit?: number;
534
+ offset?: number;
535
+ }): Promise<SnapshotMeta[]>;
536
+ /** Fetch a single snapshot including its base64-encoded data blob. */
537
+ getSnapshot(docId: string, version: number): Promise<SnapshotData>;
538
+ /** Create a manual snapshot of the current document state. */
539
+ createSnapshot(docId: string, opts?: {
540
+ label?: string;
541
+ }): Promise<SnapshotCreateResult>;
542
+ /** Delete a specific snapshot version. Requires manage permission. */
543
+ deleteSnapshot(docId: string, version: number): Promise<void>;
544
+ /** Restore a snapshot by merging it forward into the current document state. */
545
+ restoreSnapshot(docId: string, version: number): Promise<SnapshotRestoreResult>;
546
+ /** Fork a snapshot into a new document. */
547
+ forkSnapshot(docId: string, version: number): Promise<SnapshotForkResult>;
531
548
  /** Health check — no auth required. */
532
549
  health(): Promise<HealthStatus>;
533
550
  /**
@@ -1202,6 +1219,33 @@ interface EffectivePermissionsResponse {
1202
1219
  permissions: EffectivePermissionEntry[];
1203
1220
  default_role: string;
1204
1221
  }
1222
+ interface SnapshotMeta {
1223
+ version: number;
1224
+ size_bytes: number;
1225
+ trigger: string;
1226
+ label?: string | null;
1227
+ created_by?: string | null;
1228
+ created_at: number;
1229
+ }
1230
+ interface SnapshotData extends SnapshotMeta {
1231
+ data: string;
1232
+ }
1233
+ interface SnapshotCreateResult {
1234
+ version: number;
1235
+ size_bytes: number;
1236
+ label?: string | null;
1237
+ }
1238
+ interface SnapshotRestoreResult {
1239
+ restored_from: number;
1240
+ diff_bytes: number;
1241
+ }
1242
+ interface SnapshotForkResult {
1243
+ doc_id: string;
1244
+ forked_from: {
1245
+ doc_id: string;
1246
+ version: number;
1247
+ };
1248
+ }
1205
1249
  interface HealthStatus {
1206
1250
  status: string;
1207
1251
  version: string;
@@ -2816,4 +2860,4 @@ declare function wrapSeed(seed: Uint8Array, wrappingKeyBytes: Uint8Array): Promi
2816
2860
  */
2817
2861
  declare function unwrapSeed(ciphertext: ArrayBuffer, iv: Uint8Array, wrappingKeyBytes: Uint8Array): Promise<Uint8Array>;
2818
2862
  //#endregion
2819
- 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, DeviceRegistrationService, type DeviceServerStatus, type DeviceTier, 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 IdentityDeviceEntry, 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, wordlist as bip39Wordlist, decryptField, deriveIdentityDocId, deriveSeedWrappingKey, encryptField, generateMnemonic, makeEncryptedYMap, makeEncryptedYText, mnemonicToEd25519Seed, mnemonicToKeyPair, onAuthenticatedParameters, onAuthenticationFailedParameters, onAwarenessChangeParameters, onAwarenessUpdateParameters, onCloseParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onStatelessParameters, onStatusParameters, onSubdocLoadedParameters, onSubdocRegisteredParameters, onSyncedParameters, onUnsyncedChangesParameters, readAuthMessage, unwrapSeed, validateMnemonic, wrapSeed, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest };
2863
+ 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, DeviceRegistrationService, type DeviceServerStatus, type DeviceTier, 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 IdentityDeviceEntry, 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, SnapshotCreateResult, SnapshotData, SnapshotForkResult, SnapshotMeta, SnapshotRestoreResult, SpaceMeta, StatesArray, SubdocMessage, SubdocRegisteredEvent, Unauthorized, UploadInfo, UploadMeta, UploadQueueEntry, UploadQueueStatus, UserProfile, WebSocketStatus, WsReadyStates, YjsDataChannel, attachUpdatedAtObserver, awarenessStatesToArray, wordlist as bip39Wordlist, decryptField, deriveIdentityDocId, deriveSeedWrappingKey, encryptField, generateMnemonic, makeEncryptedYMap, makeEncryptedYText, mnemonicToEd25519Seed, mnemonicToKeyPair, onAuthenticatedParameters, onAuthenticationFailedParameters, onAwarenessChangeParameters, onAwarenessUpdateParameters, onCloseParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onStatelessParameters, onStatusParameters, onSubdocLoadedParameters, onSubdocRegisteredParameters, onSyncedParameters, onUnsyncedChangesParameters, readAuthMessage, unwrapSeed, validateMnemonic, wrapSeed, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abraca/dabra",
3
- "version": "1.3.3",
3
+ "version": "1.5.0",
4
4
  "description": "abracadabra provider",
5
5
  "keywords": [
6
6
  "abracadabra",
@@ -10,6 +10,11 @@ import type {
10
10
  ServerInfo,
11
11
  InviteRow,
12
12
  SpaceMeta,
13
+ SnapshotMeta,
14
+ SnapshotData,
15
+ SnapshotCreateResult,
16
+ SnapshotRestoreResult,
17
+ SnapshotForkResult,
13
18
  } from "./types.ts";
14
19
  import type { DocEncryptionInfo } from "./types.ts";
15
20
  import type { DocumentCache } from "./DocumentCache.ts";
@@ -699,6 +704,56 @@ export class AbracadabraClient {
699
704
  return this.request("POST", "/admin/storage/repair");
700
705
  }
701
706
 
707
+ // ── Snapshots ────────────────────────────────────────────────────────────
708
+
709
+ /** List snapshot metadata for a document. */
710
+ async listSnapshots(docId: string, opts?: { limit?: number; offset?: number }): Promise<SnapshotMeta[]> {
711
+ const params = new URLSearchParams();
712
+ if (opts?.limit != null) params.set("limit", String(opts.limit));
713
+ if (opts?.offset != null) params.set("offset", String(opts.offset));
714
+ const qs = params.toString();
715
+ const res = await this.request<{ snapshots: SnapshotMeta[] }>(
716
+ "GET", `/docs/${encodeURIComponent(docId)}/snapshots${qs ? `?${qs}` : ""}`,
717
+ );
718
+ return res.snapshots;
719
+ }
720
+
721
+ /** Fetch a single snapshot including its base64-encoded data blob. */
722
+ async getSnapshot(docId: string, version: number): Promise<SnapshotData> {
723
+ return this.request<SnapshotData>(
724
+ "GET", `/docs/${encodeURIComponent(docId)}/snapshots/${version}`,
725
+ );
726
+ }
727
+
728
+ /** Create a manual snapshot of the current document state. */
729
+ async createSnapshot(docId: string, opts?: { label?: string }): Promise<SnapshotCreateResult> {
730
+ return this.request<SnapshotCreateResult>(
731
+ "POST", `/docs/${encodeURIComponent(docId)}/snapshots`,
732
+ { body: opts ?? {} },
733
+ );
734
+ }
735
+
736
+ /** Delete a specific snapshot version. Requires manage permission. */
737
+ async deleteSnapshot(docId: string, version: number): Promise<void> {
738
+ await this.request("DELETE", `/docs/${encodeURIComponent(docId)}/snapshots/${version}`);
739
+ }
740
+
741
+ /** Restore a snapshot by merging it forward into the current document state. */
742
+ async restoreSnapshot(docId: string, version: number): Promise<SnapshotRestoreResult> {
743
+ return this.request<SnapshotRestoreResult>(
744
+ "POST", `/docs/${encodeURIComponent(docId)}/snapshots/${version}/restore`,
745
+ { body: {} },
746
+ );
747
+ }
748
+
749
+ /** Fork a snapshot into a new document. */
750
+ async forkSnapshot(docId: string, version: number): Promise<SnapshotForkResult> {
751
+ return this.request<SnapshotForkResult>(
752
+ "POST", `/docs/${encodeURIComponent(docId)}/snapshots/${version}/fork`,
753
+ { body: {} },
754
+ );
755
+ }
756
+
702
757
  // ── System ───────────────────────────────────────────────────────────────
703
758
 
704
759
  /** Health check — no auth required. */
@@ -40,9 +40,12 @@ export function attachUpdatedAtObserver(
40
40
  if (offlineStore !== null && origin === offlineStore) return;
41
41
 
42
42
  // Update the root tree entry (no-op if the entry doesn't exist).
43
- const entry = treeMap.get(childDocId);
44
- if (!entry) return;
43
+ const raw = treeMap.get(childDocId);
44
+ if (!raw) return;
45
45
 
46
+ // Guard: if the entry is a nested Y.Map (possible after Yrs
47
+ // document compaction), convert to plain object so spread works.
48
+ const entry = raw instanceof Y.Map ? (raw as any).toJSON() : raw;
46
49
  treeMap.set(childDocId, { ...entry, updatedAt: Date.now() });
47
50
  }
48
51
 
package/src/types.ts CHANGED
@@ -226,6 +226,37 @@ export interface EffectivePermissionsResponse {
226
226
  default_role: string;
227
227
  }
228
228
 
229
+ // ── Snapshots ────────────────────────────────────────────────────────────────
230
+
231
+ export interface SnapshotMeta {
232
+ version: number;
233
+ size_bytes: number;
234
+ trigger: string;
235
+ label?: string | null;
236
+ created_by?: string | null;
237
+ created_at: number;
238
+ }
239
+
240
+ export interface SnapshotData extends SnapshotMeta {
241
+ data: string;
242
+ }
243
+
244
+ export interface SnapshotCreateResult {
245
+ version: number;
246
+ size_bytes: number;
247
+ label?: string | null;
248
+ }
249
+
250
+ export interface SnapshotRestoreResult {
251
+ restored_from: number;
252
+ diff_bytes: number;
253
+ }
254
+
255
+ export interface SnapshotForkResult {
256
+ doc_id: string;
257
+ forked_from: { doc_id: string; version: number };
258
+ }
259
+
229
260
  export interface HealthStatus {
230
261
  status: string;
231
262
  version: string;