@web_of_trust/adapter-automerge 0.1.2

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/README.md ADDED
@@ -0,0 +1,143 @@
1
+ # @web_of_trust/adapter-automerge
2
+
3
+ Alternative CRDT adapter for Web of Trust — Rust compiled to WebAssembly.
4
+
5
+ Implements the `ReplicationAdapter` and personal document interfaces from `@web_of_trust/core` using [Automerge](https://automerge.org). Available as a drop-in alternative to `@web_of_trust/adapter-yjs`. The Yjs adapter is the default; use this one when Automerge semantics or tooling are specifically required.
6
+
7
+ > **Note:** Automerge's Rust→WASM runtime (1.7 MB) blocks the main thread on mobile devices. Measured: ~6.4 s initialisation on Android vs ~85 ms for Yjs. Only use this adapter on desktop-only deployments or when you need Automerge's specific merge semantics.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ pnpm add @web_of_trust/adapter-automerge
13
+ ```
14
+
15
+ Requires `@web_of_trust/core` as a peer dependency.
16
+
17
+ ## Key Features
18
+
19
+ - **AutomergeReplicationAdapter** — encrypted shared spaces using `automerge-repo` `DocHandle`s
20
+ - **PersonalDocManager** — personal data stored in an Automerge document with `Automerge.save()` snapshots
21
+ - **CompactionService** — two-phase compaction with yield points to reduce UI freeze on WASM-constrained devices
22
+ - **PersonalNetworkAdapter** — multi-device sync for the personal document via the Relay
23
+ - **SyncOnlyStorageAdapter** — stores automerge-repo sync states without the full document binary
24
+
25
+ ## API Overview
26
+
27
+ ### Personal Document
28
+
29
+ ```typescript
30
+ import {
31
+ initPersonalDoc,
32
+ getPersonalDoc,
33
+ changePersonalDoc,
34
+ onPersonalDocChange,
35
+ flushPersonalDoc,
36
+ } from '@web_of_trust/adapter-automerge'
37
+
38
+ // Initialise (loads snapshot from CompactStore / Vault)
39
+ await initPersonalDoc({ identity, compactStore, vaultClient })
40
+
41
+ // Read
42
+ const doc = getPersonalDoc()
43
+ const contact = doc.contacts['did:key:z6Mk...']
44
+
45
+ // Mutate
46
+ changePersonalDoc((doc) => {
47
+ doc.profile.name = 'Alice'
48
+ })
49
+
50
+ // Subscribe to changes
51
+ const unsub = onPersonalDocChange(() => {
52
+ const latest = getPersonalDoc()
53
+ })
54
+
55
+ // Persist immediately (normally automatic)
56
+ await flushPersonalDoc()
57
+ ```
58
+
59
+ ### Replication Adapter (Shared Spaces)
60
+
61
+ ```typescript
62
+ import { AutomergeReplicationAdapter } from '@web_of_trust/adapter-automerge'
63
+
64
+ const replication = new AutomergeReplicationAdapter({
65
+ identity, // WotIdentity
66
+ messaging, // MessagingAdapter
67
+ groupKeyService, // GroupKeyService
68
+ metadataStorage, // SpaceMetadataStorage (optional)
69
+ compactStore, // CompactStore (optional, IDB-backed)
70
+ vaultUrl, // string (optional)
71
+ })
72
+
73
+ // Open a space
74
+ const handle = await replication.openSpace<{ notes: string }>(spaceInfo)
75
+
76
+ // Read
77
+ const doc = handle.getDoc()
78
+
79
+ // Mutate
80
+ await handle.transact((doc) => {
81
+ doc.notes = 'Hello from Alice'
82
+ })
83
+
84
+ // React to remote updates
85
+ handle.onRemoteUpdate(() => {
86
+ console.log('Remote change:', handle.getDoc())
87
+ })
88
+
89
+ handle.close()
90
+ ```
91
+
92
+ ### Compaction Service
93
+
94
+ The `CompactionService` strips Automerge history to keep snapshots small. It runs in the background with `yield` points to avoid long WASM freezes:
95
+
96
+ ```typescript
97
+ import { CompactionService } from '@web_of_trust/adapter-automerge'
98
+
99
+ const compaction = new CompactionService()
100
+ const compact = await compaction.compact(automergeDoc)
101
+ // compact is a fresh Automerge.Doc with history stripped
102
+ ```
103
+
104
+ ## How to Run
105
+
106
+ ```bash
107
+ # Build (watch mode during development)
108
+ pnpm dev
109
+
110
+ # Build once
111
+ pnpm build
112
+
113
+ # Run tests
114
+ pnpm test
115
+
116
+ # Run tests in watch mode
117
+ pnpm test:watch
118
+ ```
119
+
120
+ ## CRDT Switch
121
+
122
+ ```bash
123
+ # Use Automerge in the demo app
124
+ VITE_CRDT=automerge pnpm dev:demo
125
+
126
+ # Default is Yjs (no variable needed)
127
+ pnpm dev:demo
128
+ ```
129
+
130
+ Vite config must mark `@automerge/automerge` as external to avoid bundling the WASM twice:
131
+
132
+ ```typescript
133
+ // vite.config.ts
134
+ build: {
135
+ rollupOptions: {
136
+ external: ['@automerge/automerge'],
137
+ },
138
+ }
139
+ ```
140
+
141
+ ## Main Repo
142
+
143
+ [github.com/antontranelis/web-of-trust](https://github.com/antontranelis/web-of-trust)
@@ -0,0 +1,23 @@
1
+ import { OutboxStore, OutboxEntry, MessageEnvelope, Subscribable } from '@web_of_trust/core';
2
+ import { PersonalDoc } from './PersonalDocManager';
3
+ export interface PersonalDocFunctions {
4
+ getPersonalDoc: () => PersonalDoc;
5
+ changePersonalDoc: (fn: (doc: PersonalDoc) => void, options?: {
6
+ background?: boolean;
7
+ }) => PersonalDoc;
8
+ onPersonalDocChange: (callback: () => void) => () => void;
9
+ }
10
+ export declare class AutomergeOutboxStore implements OutboxStore {
11
+ private getPersonalDoc;
12
+ private changePersonalDoc;
13
+ private onPersonalDocChange;
14
+ constructor(fns?: PersonalDocFunctions);
15
+ enqueue(envelope: MessageEnvelope): Promise<void>;
16
+ dequeue(envelopeId: string): Promise<void>;
17
+ getPending(): Promise<OutboxEntry[]>;
18
+ has(envelopeId: string): Promise<boolean>;
19
+ incrementRetry(envelopeId: string): Promise<void>;
20
+ count(): Promise<number>;
21
+ watchPendingCount(): Subscribable<number>;
22
+ }
23
+ //# sourceMappingURL=AutomergeOutboxStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutomergeOutboxStore.d.ts","sourceRoot":"","sources":["../src/AutomergeOutboxStore.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACZ,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAMtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAEvD,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,MAAM,WAAW,CAAA;IACjC,iBAAiB,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,EAAE,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,WAAW,CAAA;IACtG,mBAAmB,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;CAC1D;AAED,qBAAa,oBAAqB,YAAW,WAAW;IACtD,OAAO,CAAC,cAAc,CAAmB;IACzC,OAAO,CAAC,iBAAiB,CAAqF;IAC9G,OAAO,CAAC,mBAAmB,CAAsC;gBAErD,GAAG,CAAC,EAAE,oBAAoB;IAMhC,OAAO,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAajD,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1C,UAAU,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAWpC,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKzC,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjD,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAK9B,iBAAiB,IAAI,YAAY,CAAC,MAAM,CAAC;CAsB1C"}
@@ -0,0 +1,132 @@
1
+ import { DocumentId, AutomergeUrl, StorageAdapterInterface, DocHandle } from '@automerge/automerge-repo';
2
+ import { ReplicationAdapter, SpaceHandle, TransactOptions, Subscribable, MessagingAdapter, SpaceInfo, SpaceMemberChange, ReplicationState, GroupKeyService, SpaceMetadataStorage, WotIdentity, VaultPushScheduler } from '@web_of_trust/core';
3
+ interface SpaceState {
4
+ info: SpaceInfo;
5
+ documentId: DocumentId;
6
+ documentUrl: AutomergeUrl;
7
+ handles: Set<AutomergeSpaceHandle<any>>;
8
+ memberEncryptionKeys: Map<string, Uint8Array>;
9
+ }
10
+ /** Duck-typed interface for CompactStorageManager / InMemoryCompactStore */
11
+ export interface CompactStore {
12
+ save(docId: string, binary: Uint8Array): Promise<void>;
13
+ load(docId: string): Promise<Uint8Array | null>;
14
+ delete(docId: string): Promise<void>;
15
+ }
16
+ export interface AutomergeReplicationAdapterConfig {
17
+ identity: WotIdentity;
18
+ messaging: MessagingAdapter;
19
+ groupKeyService: GroupKeyService;
20
+ /** New: automerge-repo metadata storage (no docBinary) */
21
+ metadataStorage?: SpaceMetadataStorage;
22
+ /** Optional: automerge-repo StorageAdapter for doc persistence (e.g. IndexedDB) */
23
+ repoStorage?: StorageAdapterInterface;
24
+ /** Optional: CompactStore for single-snapshot-per-doc persistence */
25
+ compactStore?: CompactStore;
26
+ /** Optional: vault URL for persistent encrypted doc storage */
27
+ vaultUrl?: string;
28
+ /** Optional: only restore spaces matching this filter (e.g. by appTag) */
29
+ spaceFilter?: (info: SpaceInfo) => boolean;
30
+ }
31
+ declare class AutomergeSpaceHandle<T> implements SpaceHandle<T> {
32
+ readonly id: string;
33
+ private spaceState;
34
+ private docHandle;
35
+ private vaultScheduler;
36
+ private compactScheduler;
37
+ private remoteUpdateCallbacks;
38
+ private closed;
39
+ private localChanging;
40
+ private unsubChange?;
41
+ constructor(spaceState: SpaceState, docHandle: DocHandle<T>, vaultScheduler: VaultPushScheduler | null, compactScheduler: VaultPushScheduler | null);
42
+ info(): SpaceInfo;
43
+ getDoc(): T;
44
+ getMeta(): import('@web_of_trust/core').SpaceDocMeta;
45
+ transact(fn: (doc: T) => void, options?: TransactOptions): void;
46
+ onRemoteUpdate(callback: () => void): () => void;
47
+ _notifyRemoteUpdate(): void;
48
+ close(): void;
49
+ }
50
+ export declare class AutomergeReplicationAdapter implements ReplicationAdapter {
51
+ private identity;
52
+ private messaging;
53
+ private groupKeyService;
54
+ private metadataStorage;
55
+ private repoStorage;
56
+ private compactStore;
57
+ private vault;
58
+ private spaces;
59
+ private state;
60
+ private memberChangeCallbacks;
61
+ private spacesSubscribers;
62
+ private unsubscribeMessaging;
63
+ /** Local seq counter per doc — avoids a getDocInfo HTTP call (and its 404) on first push */
64
+ private vaultSeqs;
65
+ /** VaultPushScheduler per space — handles immediate/debounced vault pushes */
66
+ private vaultSchedulers;
67
+ /** VaultPushScheduler per space for CompactStore (2s debounce) */
68
+ private compactSchedulers;
69
+ /** Optional filter to restrict which spaces are restored (e.g. by appTag) */
70
+ private spaceFilter;
71
+ private repo;
72
+ private networkAdapter;
73
+ constructor(config: AutomergeReplicationAdapterConfig);
74
+ /** Sign an envelope with our identity and send it */
75
+ private _signAndSend;
76
+ start(): Promise<void>;
77
+ /**
78
+ * Restore spaces from metadata storage.
79
+ * Called on start() and can be called again after remote sync
80
+ * delivers new space metadata (e.g. multi-device sync).
81
+ * Only loads spaces that aren't already known.
82
+ */
83
+ restoreSpacesFromMetadata(): Promise<void>;
84
+ /**
85
+ * Try to restore a space doc from the vault.
86
+ * Returns true if doc was successfully imported from vault.
87
+ */
88
+ private _restoreFromVault;
89
+ /**
90
+ * Try to restore a space doc from the CompactStore.
91
+ * Returns true if doc was successfully imported.
92
+ */
93
+ private _restoreFromCompactStore;
94
+ /**
95
+ * Save a snapshot to the CompactStore.
96
+ * Two-phase: save with history immediately (fast), then compact in Worker.
97
+ */
98
+ private _saveToCompactStore;
99
+ private _pushSnapshotToVault;
100
+ /**
101
+ * Background wait for a space doc that isn't locally available yet.
102
+ * The doc may arrive via sync from another device.
103
+ */
104
+ private _waitForDoc;
105
+ stop(): Promise<void>;
106
+ getState(): ReplicationState;
107
+ createSpace<T>(type: 'personal' | 'shared', initialDoc: T, meta?: {
108
+ name?: string;
109
+ description?: string;
110
+ appTag?: string;
111
+ }): Promise<SpaceInfo>;
112
+ getSpaces(): Promise<SpaceInfo[]>;
113
+ watchSpaces(): Subscribable<SpaceInfo[]>;
114
+ private _getSpacesSnapshot;
115
+ private _notifySpacesSubscribers;
116
+ getSpace(spaceId: string): Promise<SpaceInfo | null>;
117
+ openSpace<T>(spaceId: string): Promise<SpaceHandle<T>>;
118
+ addMember(spaceId: string, memberDid: string, memberEncryptionPublicKey: Uint8Array): Promise<void>;
119
+ removeMember(spaceId: string, memberDid: string): Promise<void>;
120
+ onMemberChange(callback: (change: SpaceMemberChange) => void): () => void;
121
+ leaveSpace(_spaceId: string): Promise<void>;
122
+ updateSpace(_spaceId: string, _meta: import('@web_of_trust/core').SpaceDocMeta): Promise<void>;
123
+ getKeyGeneration(spaceId: string): number;
124
+ requestSync(_spaceId: string): Promise<void>;
125
+ _persistSpaceMetadata(space: SpaceState): Promise<void>;
126
+ private handleMessage;
127
+ private handleSpaceInvite;
128
+ private handleKeyRotation;
129
+ private handleMemberUpdate;
130
+ }
131
+ export {};
132
+ //# sourceMappingURL=AutomergeReplicationAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutomergeReplicationAdapter.d.ts","sourceRoot":"","sources":["../src/AutomergeReplicationAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { SpaceMetadataStorage, PersistedSpaceMetadata, PersistedGroupKey } from '@web_of_trust/core';
2
+ import { PersonalDoc } from './PersonalDocManager';
3
+ export interface SpaceMetadataDocFunctions {
4
+ getPersonalDoc: () => PersonalDoc;
5
+ changePersonalDoc: (fn: (doc: PersonalDoc) => void, options?: {
6
+ background?: boolean;
7
+ }) => PersonalDoc;
8
+ }
9
+ export declare class AutomergeSpaceMetadataStorage implements SpaceMetadataStorage {
10
+ private getPersonalDoc;
11
+ private changePersonalDoc;
12
+ constructor(fns?: SpaceMetadataDocFunctions);
13
+ saveSpaceMetadata(meta: PersistedSpaceMetadata): Promise<void>;
14
+ loadSpaceMetadata(spaceId: string): Promise<PersistedSpaceMetadata | null>;
15
+ loadAllSpaceMetadata(): Promise<PersistedSpaceMetadata[]>;
16
+ deleteSpaceMetadata(spaceId: string): Promise<void>;
17
+ saveGroupKey(key: PersistedGroupKey): Promise<void>;
18
+ loadGroupKeys(spaceId: string): Promise<PersistedGroupKey[]>;
19
+ deleteGroupKeys(spaceId: string): Promise<void>;
20
+ clearAll(): Promise<void>;
21
+ private deserialize;
22
+ }
23
+ //# sourceMappingURL=AutomergeSpaceMetadataStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutomergeSpaceMetadataStorage.d.ts","sourceRoot":"","sources":["../src/AutomergeSpaceMetadataStorage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EAClB,MAAM,oBAAoB,CAAA;AAK3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAEvD,MAAM,WAAW,yBAAyB;IACxC,cAAc,EAAE,MAAM,WAAW,CAAA;IACjC,iBAAiB,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,EAAE,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,WAAW,CAAA;CACvG;AAMD,qBAAa,6BAA8B,YAAW,oBAAoB;IACxE,OAAO,CAAC,cAAc,CAAmB;IACzC,OAAO,CAAC,iBAAiB,CAAqF;gBAElG,GAAG,CAAC,EAAE,yBAAyB;IAKrC,iBAAiB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB9D,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;IAO1E,oBAAoB,IAAI,OAAO,CAAC,sBAAsB,EAAE,CAAC;IAKzD,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMnD,YAAY,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAWnD,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAW5D,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ/C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAW/B,OAAO,CAAC,WAAW;CAyBpB"}
@@ -0,0 +1,28 @@
1
+ export interface CompactionRequest {
2
+ id: string;
3
+ binary: Uint8Array;
4
+ }
5
+ export interface CompactionResponse {
6
+ id: string;
7
+ compacted?: Uint8Array;
8
+ error?: string;
9
+ }
10
+ export declare class CompactionService {
11
+ private static instance;
12
+ private constructor();
13
+ static getInstance(): CompactionService;
14
+ /**
15
+ * Compact an Automerge document binary (strip change history).
16
+ * Yields to the browser between steps to keep the UI responsive.
17
+ *
18
+ * @param binary - Automerge.save() output (includes history)
19
+ * @returns Compacted binary (history-free)
20
+ */
21
+ compact(binary: Uint8Array): Promise<Uint8Array>;
22
+ /**
23
+ * Whether the service is using a Web Worker (true) or main-thread with yielding (false).
24
+ */
25
+ get isUsingWorker(): boolean;
26
+ destroy(): void;
27
+ }
28
+ //# sourceMappingURL=CompactionService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompactionService.d.ts","sourceRoot":"","sources":["../src/CompactionService.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,UAAU,CAAA;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,CAAC,EAAE,UAAU,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAiC;IAExD,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,iBAAiB;IAOvC;;;;;;OAMG;IACG,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAiBtD;;OAEG;IACH,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,OAAO,IAAI,IAAI;CAGhB"}
@@ -0,0 +1,62 @@
1
+ import { NetworkAdapter, PeerId, DocumentId, Message, PeerMetadata } from '@automerge/automerge-repo';
2
+ import { MessagingAdapter, GroupKeyService } from '@web_of_trust/core';
3
+ /**
4
+ * EncryptedMessagingNetworkAdapter — Bridge between automerge-repo and our MessagingAdapter.
5
+ *
6
+ * Responsibilities:
7
+ * - Translates automerge-repo sync messages to/from encrypted MessageEnvelopes
8
+ * - Routes messages through our existing MessagingAdapter (WebSocket relay)
9
+ * - Encrypts outgoing sync data with per-space AES-256-GCM group keys
10
+ * - Decrypts incoming sync data using GroupKeyService
11
+ * - Maps DocumentId -> SpaceId for key lookup
12
+ * - Maps PeerId = DID for routing
13
+ */
14
+ export declare class EncryptedMessagingNetworkAdapter extends NetworkAdapter {
15
+ private messaging;
16
+ private identity;
17
+ private groupKeyService;
18
+ private ready;
19
+ private readyResolve?;
20
+ private readyPromise;
21
+ private unsubMessage?;
22
+ /** Track message IDs we sent, so we can ignore our own echoes from the relay */
23
+ private sentMessageIds;
24
+ /** Phantom peerId used for multi-device self-sync */
25
+ private selfPeerId;
26
+ private docToSpace;
27
+ private spacePeers;
28
+ constructor(messaging: MessagingAdapter, identity: {
29
+ getDid(): string;
30
+ sign(data: string): Promise<string>;
31
+ }, groupKeyService: GroupKeyService);
32
+ isReady(): boolean;
33
+ whenReady(): Promise<void>;
34
+ connect(peerId: PeerId, peerMetadata?: PeerMetadata): void;
35
+ send(message: Message): void;
36
+ disconnect(): void;
37
+ /**
38
+ * Register a document -> space mapping.
39
+ * Needed so we can look up the right group key when sending/receiving.
40
+ */
41
+ registerDocument(documentId: DocumentId, spaceId: string): void;
42
+ /**
43
+ * Unregister a document mapping.
44
+ */
45
+ unregisterDocument(documentId: DocumentId): void;
46
+ /**
47
+ * Register a peer (DID) as a member of a space.
48
+ * Emits peer-candidate so automerge-repo starts syncing with this peer.
49
+ */
50
+ registerSpacePeer(spaceId: string, memberDid: string): void;
51
+ /**
52
+ * Register a phantom peer representing "self on another device".
53
+ * Uses a different peerId so automerge-repo doesn't skip it as self,
54
+ * but send() routes messages to our own DID (relay delivers to other devices).
55
+ */
56
+ registerSelfPeer(spaceId: string): void;
57
+ /**
58
+ * Unregister a peer from a space.
59
+ */
60
+ unregisterSpacePeer(spaceId: string, memberDid: string): void;
61
+ }
62
+ //# sourceMappingURL=EncryptedMessagingNetworkAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EncryptedMessagingNetworkAdapter.d.ts","sourceRoot":"","sources":["../src/EncryptedMessagingNetworkAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AACnE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAIzD;;;;;;;;;;GAUG;AACH,qBAAa,gCAAiC,SAAQ,cAAc;IAClE,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,QAAQ,CAA2D;IAC3E,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,YAAY,CAAC,CAAY;IACjC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,YAAY,CAAC,CAAY;IACjC,gFAAgF;IAChF,OAAO,CAAC,cAAc,CAAoB;IAC1C,qDAAqD;IACrD,OAAO,CAAC,UAAU,CAAsB;IAGxC,OAAO,CAAC,UAAU,CAAgC;IAGlD,OAAO,CAAC,UAAU,CAAiC;gBAGjD,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE;QAAE,MAAM,IAAI,MAAM,CAAC;QAAC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;KAAE,EACnE,eAAe,EAAE,eAAe;IAalC,OAAO,IAAI,OAAO;IAIlB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAI1B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI;IAiF1D,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAiE5B,UAAU,IAAI,IAAI;IASlB;;;OAGG;IACH,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAI/D;;OAEG;IACH,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAIhD;;;OAGG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAiB3D;;;;OAIG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAOvC;;OAEG;IACH,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;CAa9D"}
@@ -0,0 +1,21 @@
1
+ import { StorageAdapterInterface } from '@automerge/automerge-repo';
2
+ type StorageKey = string[];
3
+ type Chunk = {
4
+ key: StorageKey;
5
+ data: Uint8Array;
6
+ };
7
+ /**
8
+ * In-memory implementation of automerge-repo's StorageAdapterInterface.
9
+ * Used for testing — persists documents across Repo restarts within the same process.
10
+ */
11
+ export declare class InMemoryRepoStorageAdapter implements StorageAdapterInterface {
12
+ private data;
13
+ private keyToString;
14
+ load(key: StorageKey): Promise<Uint8Array | undefined>;
15
+ save(key: StorageKey, binary: Uint8Array): Promise<void>;
16
+ remove(key: StorageKey): Promise<void>;
17
+ loadRange(keyPrefix: StorageKey): Promise<Chunk[]>;
18
+ removeRange(keyPrefix: string[]): Promise<void>;
19
+ }
20
+ export {};
21
+ //# sourceMappingURL=InMemoryRepoStorageAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InMemoryRepoStorageAdapter.d.ts","sourceRoot":"","sources":["../src/InMemoryRepoStorageAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAA;AAExE,KAAK,UAAU,GAAG,MAAM,EAAE,CAAA;AAC1B,KAAK,KAAK,GAAG;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CAAA;AAElD;;;GAGG;AACH,qBAAa,0BAA2B,YAAW,uBAAuB;IACxE,OAAO,CAAC,IAAI,CAAgC;IAE5C,OAAO,CAAC,WAAW;IAIb,IAAI,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAItD,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxD,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAItC,SAAS,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAWlD,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAQtD"}
@@ -0,0 +1,166 @@
1
+ import { WotIdentity, MessagingAdapter } from '@web_of_trust/core';
2
+ export interface OutboxEntryDoc {
3
+ envelopeJson: string;
4
+ createdAt: string;
5
+ retryCount: number;
6
+ }
7
+ export interface PublishStateDoc {
8
+ profileDirty: boolean;
9
+ verificationsDirty: boolean;
10
+ attestationsDirty: boolean;
11
+ }
12
+ export interface CachedGraphEntryDoc {
13
+ did: string;
14
+ name: string | null;
15
+ bio: string | null;
16
+ avatar: string | null;
17
+ encryptionPublicKey: string | null;
18
+ verificationCount: number;
19
+ attestationCount: number;
20
+ verifierDidsJson: string | null;
21
+ fetchedAt: string;
22
+ }
23
+ export interface CachedGraphVerificationDoc {
24
+ subjectDid: string;
25
+ verificationId: string;
26
+ fromDid: string;
27
+ toDid: string;
28
+ timestamp: string;
29
+ proofJson: string;
30
+ locationJson: string | null;
31
+ }
32
+ export interface CachedGraphAttestationDoc {
33
+ subjectDid: string;
34
+ attestationId: string;
35
+ fromDid: string;
36
+ toDid: string;
37
+ claim: string;
38
+ tagsJson: string | null;
39
+ context: string | null;
40
+ attestationCreatedAt: string;
41
+ proofJson: string;
42
+ }
43
+ export interface SpaceMetadataDoc {
44
+ info: {
45
+ id: string;
46
+ type: string;
47
+ name: string | null;
48
+ description: string | null;
49
+ appTag?: string;
50
+ members: string[];
51
+ createdAt: string;
52
+ };
53
+ documentId: string;
54
+ documentUrl: string;
55
+ /** memberEncryptionKeys stored as Record<did, number[]> for serialization */
56
+ memberEncryptionKeys: Record<string, number[]>;
57
+ }
58
+ export interface GroupKeyDoc {
59
+ spaceId: string;
60
+ generation: number;
61
+ key: number[];
62
+ }
63
+ export interface ContactDoc {
64
+ did: string;
65
+ publicKey: string;
66
+ name: string | null;
67
+ avatar: string | null;
68
+ bio: string | null;
69
+ status: string;
70
+ verifiedAt: string | null;
71
+ createdAt: string;
72
+ updatedAt: string;
73
+ }
74
+ export interface VerificationDoc {
75
+ id: string;
76
+ fromDid: string;
77
+ toDid: string;
78
+ timestamp: string;
79
+ proofJson: string;
80
+ locationJson: string | null;
81
+ }
82
+ export interface AttestationDoc {
83
+ id: string;
84
+ attestationId: string | null;
85
+ fromDid: string;
86
+ toDid: string;
87
+ claim: string;
88
+ tagsJson: string | null;
89
+ context: string | null;
90
+ createdAt: string;
91
+ proofJson: string;
92
+ }
93
+ export interface AttestationMetadataDoc {
94
+ attestationId: string;
95
+ accepted: boolean;
96
+ acceptedAt: string | null;
97
+ deliveryStatus: string | null;
98
+ }
99
+ export interface ProfileDoc {
100
+ did: string;
101
+ name: string | null;
102
+ bio: string | null;
103
+ avatar: string | null;
104
+ offersJson: string | null;
105
+ needsJson: string | null;
106
+ createdAt: string;
107
+ updatedAt: string;
108
+ }
109
+ export interface PersonalDoc {
110
+ profile: ProfileDoc | null;
111
+ contacts: Record<string, ContactDoc>;
112
+ verifications: Record<string, VerificationDoc>;
113
+ attestations: Record<string, AttestationDoc>;
114
+ attestationMetadata: Record<string, AttestationMetadataDoc>;
115
+ outbox: Record<string, OutboxEntryDoc>;
116
+ spaces: Record<string, SpaceMetadataDoc>;
117
+ groupKeys: Record<string, GroupKeyDoc>;
118
+ }
119
+ /**
120
+ * Initialize the personal document as an Automerge doc with multi-device sync.
121
+ *
122
+ * - Derives deterministic doc ID from mnemonic
123
+ * - Creates Automerge Repo with IndexedDB persistence + PersonalNetworkAdapter
124
+ * - Migrates data from old plain-object IndexedDB if present
125
+ * - Starts encrypted sync to other devices via wot-relay
126
+ */
127
+ export declare function initPersonalDoc(identity: WotIdentity, messaging?: MessagingAdapter, vaultUrl?: string): Promise<PersonalDoc>;
128
+ /**
129
+ * Get the current personal document. Throws if not initialized.
130
+ */
131
+ export declare function getPersonalDoc(): PersonalDoc;
132
+ /**
133
+ * Check if the personal doc is initialized.
134
+ */
135
+ export declare function isPersonalDocInitialized(): boolean;
136
+ /**
137
+ * Apply a change to the personal document.
138
+ * Uses Automerge's change() for CRDT operations.
139
+ * Notifies all listeners after the change.
140
+ *
141
+ * @param options.background - If true, debounce persistence instead of pushing immediately.
142
+ * Use for background updates (cache, contact sync) that don't need instant persistence.
143
+ */
144
+ export declare function changePersonalDoc(fn: (doc: PersonalDoc) => void, options?: {
145
+ background?: boolean;
146
+ }): PersonalDoc;
147
+ /**
148
+ * Subscribe to changes on the personal document.
149
+ * Returns an unsubscribe function.
150
+ * Fires on both local changes and remote sync updates.
151
+ */
152
+ export declare function onPersonalDocChange(callback: () => void): () => void;
153
+ /**
154
+ * Force-flush the personal doc to CompactStore and Vault immediately.
155
+ */
156
+ export declare function flushPersonalDoc(): Promise<void>;
157
+ /**
158
+ * Reset the personal document — shut down repo and clear data.
159
+ */
160
+ export declare function resetPersonalDoc(): Promise<void>;
161
+ /**
162
+ * Delete the personal doc database entirely.
163
+ * Used on identity switch (stronger than resetPersonalDoc).
164
+ */
165
+ export declare function deletePersonalDocDB(): Promise<void>;
166
+ //# sourceMappingURL=PersonalDocManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PersonalDocManager.d.ts","sourceRoot":"","sources":["../src/PersonalDocManager.ts"],"names":[],"mappings":"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"}