dropspace 0.0.0-stage → 0.1.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/README.md +17 -2
- package/dist/automerge/index.d.ts +108 -0
- package/dist/automerge/index.d.ts.map +1 -0
- package/dist/automerge/index.js +437 -0
- package/dist/automerge/index.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +372 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/channel.d.ts +153 -0
- package/dist/client/channel.d.ts.map +1 -0
- package/dist/client/channel.js +704 -0
- package/dist/client/channel.js.map +1 -0
- package/dist/client/client.d.ts +376 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +1421 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/events.d.ts +14 -0
- package/dist/client/events.d.ts.map +1 -0
- package/dist/client/events.js +71 -0
- package/dist/client/events.js.map +1 -0
- package/dist/client/identity.d.ts +89 -0
- package/dist/client/identity.d.ts.map +1 -0
- package/dist/client/identity.js +274 -0
- package/dist/client/identity.js.map +1 -0
- package/dist/client/index.d.ts +8 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +8 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/peer-connection.d.ts +190 -0
- package/dist/client/peer-connection.d.ts.map +1 -0
- package/dist/client/peer-connection.js +647 -0
- package/dist/client/peer-connection.js.map +1 -0
- package/dist/client/peer-selection.d.ts +70 -0
- package/dist/client/peer-selection.d.ts.map +1 -0
- package/dist/client/peer-selection.js +193 -0
- package/dist/client/peer-selection.js.map +1 -0
- package/dist/client/storage.d.ts +118 -0
- package/dist/client/storage.d.ts.map +1 -0
- package/dist/client/storage.js +463 -0
- package/dist/client/storage.js.map +1 -0
- package/dist/files/index.d.ts +140 -0
- package/dist/files/index.d.ts.map +1 -0
- package/dist/files/index.js +751 -0
- package/dist/files/index.js.map +1 -0
- package/dist/files/sha256.d.ts +24 -0
- package/dist/files/sha256.d.ts.map +1 -0
- package/dist/files/sha256.js +147 -0
- package/dist/files/sha256.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol/envelope.d.ts +61 -0
- package/dist/protocol/envelope.d.ts.map +1 -0
- package/dist/protocol/envelope.js +268 -0
- package/dist/protocol/envelope.js.map +1 -0
- package/dist/protocol/framing.d.ts +69 -0
- package/dist/protocol/framing.d.ts.map +1 -0
- package/dist/protocol/framing.js +145 -0
- package/dist/protocol/framing.js.map +1 -0
- package/dist/protocol/index.d.ts +3 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +3 -0
- package/dist/protocol/index.js.map +1 -0
- package/fixtures/envelopes.json +132 -0
- package/package.json +51 -4
package/README.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
-
#
|
|
1
|
+
# dropspace
|
|
2
|
+
|
|
3
|
+
End-to-end encrypted peer-to-peer rooms, resumable file transfers, and Automerge CRDT sync over WebRTC & WebSocket.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install dropspace
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Subpath Exports
|
|
12
|
+
|
|
13
|
+
- `dropspace` — Main entry (`DropspaceClient`, `createClient`, protocol types, and file transfer helpers)
|
|
14
|
+
- `dropspace/client` — Core E2EE client, identity, invites, WebRTC + WebSocket channels
|
|
15
|
+
- `dropspace/files` — Chunked resumable file transfer & SHA-256 verification
|
|
16
|
+
- `dropspace/automerge` — Automerge CRDT sync adapter
|
|
17
|
+
- `dropspace/protocol` — Wire framing & signaling envelope schemas
|
|
2
18
|
|
|
3
|
-
This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { next as Automerge } from "@automerge/automerge";
|
|
2
|
+
import { TypedEventEmitter, type DropspaceClient } from "../client/index.js";
|
|
3
|
+
export interface CrdtFileAttachmentRef {
|
|
4
|
+
fileId: string;
|
|
5
|
+
fileName: string;
|
|
6
|
+
mimeType: string;
|
|
7
|
+
byteLength: number;
|
|
8
|
+
sha256: string;
|
|
9
|
+
version: number;
|
|
10
|
+
}
|
|
11
|
+
export interface DropspaceNoteDoc {
|
|
12
|
+
title: string;
|
|
13
|
+
body: string;
|
|
14
|
+
updatedAt: number;
|
|
15
|
+
updatedBy: string;
|
|
16
|
+
attachments: CrdtFileAttachmentRef[];
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
}
|
|
19
|
+
export interface CrdtStorageAdapter {
|
|
20
|
+
loadDocument(documentId: string): Promise<Uint8Array | null>;
|
|
21
|
+
saveDocument(documentId: string, binary: Uint8Array): Promise<void>;
|
|
22
|
+
deleteDocument(documentId: string): Promise<void>;
|
|
23
|
+
listDocumentIds(): Promise<string[]>;
|
|
24
|
+
}
|
|
25
|
+
export declare class InMemoryCrdtStorageAdapter implements CrdtStorageAdapter {
|
|
26
|
+
private readonly store;
|
|
27
|
+
loadDocument(documentId: string): Promise<Uint8Array | null>;
|
|
28
|
+
saveDocument(documentId: string, binary: Uint8Array): Promise<void>;
|
|
29
|
+
deleteDocument(documentId: string): Promise<void>;
|
|
30
|
+
listDocumentIds(): Promise<string[]>;
|
|
31
|
+
}
|
|
32
|
+
export declare class IndexedDbCrdtStorageAdapter implements CrdtStorageAdapter {
|
|
33
|
+
private readonly dbName;
|
|
34
|
+
private readonly storeName;
|
|
35
|
+
constructor(dbName?: string, storeName?: string);
|
|
36
|
+
private openDb;
|
|
37
|
+
loadDocument(documentId: string): Promise<Uint8Array | null>;
|
|
38
|
+
saveDocument(documentId: string, binary: Uint8Array): Promise<void>;
|
|
39
|
+
deleteDocument(documentId: string): Promise<void>;
|
|
40
|
+
listDocumentIds(): Promise<string[]>;
|
|
41
|
+
}
|
|
42
|
+
export type DocumentSyncState = "idle" | "syncing" | "synced" | "offline_modified" | "access_denied";
|
|
43
|
+
export interface DocumentAccessPolicy {
|
|
44
|
+
/** Optional allowlist of peer deviceIds permitted to access this document */
|
|
45
|
+
allowedPeerDeviceIds?: Set<string>;
|
|
46
|
+
readOnlyPeerDeviceIds?: Set<string>;
|
|
47
|
+
}
|
|
48
|
+
export type DropspaceAutomergeEvents<T = DropspaceNoteDoc> = {
|
|
49
|
+
documentUpdated: {
|
|
50
|
+
documentId: string;
|
|
51
|
+
doc: Automerge.Doc<T>;
|
|
52
|
+
source: "local" | "remote";
|
|
53
|
+
peerDeviceId?: string;
|
|
54
|
+
};
|
|
55
|
+
documentSyncStatus: {
|
|
56
|
+
documentId: string;
|
|
57
|
+
peerDeviceId: string;
|
|
58
|
+
status: DocumentSyncState;
|
|
59
|
+
generation: number;
|
|
60
|
+
};
|
|
61
|
+
accessDenied: {
|
|
62
|
+
documentId: string;
|
|
63
|
+
peerDeviceId: string;
|
|
64
|
+
reason: string;
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
export interface DropspaceAutomergeSyncOptions {
|
|
68
|
+
client: DropspaceClient;
|
|
69
|
+
spaceId?: string;
|
|
70
|
+
storage?: CrdtStorageAdapter;
|
|
71
|
+
maxLoadedDocuments?: number;
|
|
72
|
+
maxDocumentBytes?: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Automerge CRDT synchronization and persistence engine over Dropspace channels (Section 16).
|
|
76
|
+
*
|
|
77
|
+
* Important CRDT Boundaries (Documented & Enforced):
|
|
78
|
+
* - Authorization & document access control are verified per peer before exchanging sync messages.
|
|
79
|
+
* - Binary files are prohibited inside CRDT documents; use `CrdtFileAttachmentRef` references.
|
|
80
|
+
* - Sync states (`Automerge.SyncState`) are scoped to `(peerDeviceId, generation)` and cleared on disconnect.
|
|
81
|
+
*/
|
|
82
|
+
export declare class DropspaceAutomergeManager<T extends Record<string, unknown> = DropspaceNoteDoc> {
|
|
83
|
+
private readonly options;
|
|
84
|
+
readonly events: TypedEventEmitter<DropspaceAutomergeEvents<T>>;
|
|
85
|
+
private readonly storage;
|
|
86
|
+
private readonly maxLoadedDocuments;
|
|
87
|
+
private readonly maxDocumentBytes;
|
|
88
|
+
private readonly documents;
|
|
89
|
+
private readonly docLocks;
|
|
90
|
+
private readonly unsubscribers;
|
|
91
|
+
constructor(options: DropspaceAutomergeSyncOptions);
|
|
92
|
+
openOrCreateDocument(documentId: string, initialValue?: T, policy?: DocumentAccessPolicy): Promise<Automerge.Doc<T>>;
|
|
93
|
+
getDocument(documentId: string): Automerge.Doc<T> | undefined;
|
|
94
|
+
hasDocumentContent(documentId: string): boolean;
|
|
95
|
+
updateTextField(documentId: string, field: keyof T & string, nextValue: string, message?: string): Promise<Automerge.Doc<T>>;
|
|
96
|
+
setDocumentAccessPolicy(documentId: string, policy: DocumentAccessPolicy): void;
|
|
97
|
+
unsubscribeDocument(documentId: string): void;
|
|
98
|
+
changeDocument(documentId: string, message: string, mutator: (draft: T) => void): Promise<Automerge.Doc<T>>;
|
|
99
|
+
private persistDoc;
|
|
100
|
+
private isPeerAuthorizedForDoc;
|
|
101
|
+
syncAllSubscribedWithPeer(peerDeviceId: string): Promise<void>;
|
|
102
|
+
syncDocumentWithPeer(documentId: string, peerDeviceId: string): Promise<void>;
|
|
103
|
+
private handleIncomingCrdtFrame;
|
|
104
|
+
private processIncomingCrdtFrame;
|
|
105
|
+
private prunePeerSyncStates;
|
|
106
|
+
close(): void;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/automerge/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
import { next as Automerge } from "@automerge/automerge";
|
|
2
|
+
import { WireFrameType } from "../protocol/index.js";
|
|
3
|
+
import { TypedEventEmitter } from "../client/index.js";
|
|
4
|
+
export class InMemoryCrdtStorageAdapter {
|
|
5
|
+
store = new Map();
|
|
6
|
+
async loadDocument(documentId) {
|
|
7
|
+
const data = this.store.get(documentId);
|
|
8
|
+
return data ? new Uint8Array(data) : null;
|
|
9
|
+
}
|
|
10
|
+
async saveDocument(documentId, binary) {
|
|
11
|
+
const copy = new Uint8Array(binary.byteLength);
|
|
12
|
+
copy.set(binary);
|
|
13
|
+
this.store.set(documentId, copy);
|
|
14
|
+
}
|
|
15
|
+
async deleteDocument(documentId) {
|
|
16
|
+
this.store.delete(documentId);
|
|
17
|
+
}
|
|
18
|
+
async listDocumentIds() {
|
|
19
|
+
return Array.from(this.store.keys());
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export class IndexedDbCrdtStorageAdapter {
|
|
23
|
+
dbName;
|
|
24
|
+
storeName;
|
|
25
|
+
constructor(dbName = "dropspace_crdt_v1", storeName = "automerge_docs") {
|
|
26
|
+
this.dbName = dbName;
|
|
27
|
+
this.storeName = storeName;
|
|
28
|
+
}
|
|
29
|
+
openDb() {
|
|
30
|
+
if (typeof globalThis.indexedDB === "undefined") {
|
|
31
|
+
return Promise.reject(new Error("IndexedDB is not available in this runtime"));
|
|
32
|
+
}
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
const req = globalThis.indexedDB.open(this.dbName, 1);
|
|
35
|
+
req.onupgradeneeded = () => {
|
|
36
|
+
const db = req.result;
|
|
37
|
+
if (!db.objectStoreNames.contains(this.storeName)) {
|
|
38
|
+
db.createObjectStore(this.storeName);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
req.onsuccess = () => resolve(req.result);
|
|
42
|
+
req.onerror = () => reject(req.error ?? new Error("Failed to open CRDT IndexedDB"));
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async loadDocument(documentId) {
|
|
46
|
+
const db = await this.openDb();
|
|
47
|
+
try {
|
|
48
|
+
return await new Promise((resolve, reject) => {
|
|
49
|
+
const tx = db.transaction(this.storeName, "readonly");
|
|
50
|
+
const req = tx.objectStore(this.storeName).get(documentId);
|
|
51
|
+
req.onsuccess = () => {
|
|
52
|
+
const res = req.result;
|
|
53
|
+
resolve(res ? new Uint8Array(res) : null);
|
|
54
|
+
};
|
|
55
|
+
req.onerror = () => reject(req.error);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
db.close();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async saveDocument(documentId, binary) {
|
|
63
|
+
const db = await this.openDb();
|
|
64
|
+
try {
|
|
65
|
+
await new Promise((resolve, reject) => {
|
|
66
|
+
const tx = db.transaction(this.storeName, "readwrite");
|
|
67
|
+
const req = tx.objectStore(this.storeName).put(new Uint8Array(binary), documentId);
|
|
68
|
+
req.onsuccess = () => resolve();
|
|
69
|
+
req.onerror = () => reject(req.error);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
db.close();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async deleteDocument(documentId) {
|
|
77
|
+
const db = await this.openDb();
|
|
78
|
+
try {
|
|
79
|
+
await new Promise((resolve, reject) => {
|
|
80
|
+
const tx = db.transaction(this.storeName, "readwrite");
|
|
81
|
+
const req = tx.objectStore(this.storeName).delete(documentId);
|
|
82
|
+
req.onsuccess = () => resolve();
|
|
83
|
+
req.onerror = () => reject(req.error);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
db.close();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async listDocumentIds() {
|
|
91
|
+
const db = await this.openDb();
|
|
92
|
+
try {
|
|
93
|
+
return await new Promise((resolve, reject) => {
|
|
94
|
+
const tx = db.transaction(this.storeName, "readonly");
|
|
95
|
+
const req = tx.objectStore(this.storeName).getAllKeys();
|
|
96
|
+
req.onsuccess = () => resolve(req.result ?? []);
|
|
97
|
+
req.onerror = () => reject(req.error);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
db.close();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function assertNoEmbeddedBinary(value, path = "doc") {
|
|
106
|
+
if (value instanceof Uint8Array ||
|
|
107
|
+
value instanceof ArrayBuffer ||
|
|
108
|
+
(typeof Blob !== "undefined" && value instanceof Blob)) {
|
|
109
|
+
throw new Error(`Binary data must not be embedded inside CRDT document at '${path}'. Store file metadata reference (CrdtFileAttachmentRef) instead.`);
|
|
110
|
+
}
|
|
111
|
+
if (Array.isArray(value)) {
|
|
112
|
+
for (let i = 0; i < value.length; i++) {
|
|
113
|
+
assertNoEmbeddedBinary(value[i], `${path}[${i}]`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
else if (typeof value === "object" && value !== null) {
|
|
117
|
+
for (const [k, v] of Object.entries(value)) {
|
|
118
|
+
assertNoEmbeddedBinary(v, `${path}.${k}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Automerge CRDT synchronization and persistence engine over Dropspace channels (Section 16).
|
|
124
|
+
*
|
|
125
|
+
* Important CRDT Boundaries (Documented & Enforced):
|
|
126
|
+
* - Authorization & document access control are verified per peer before exchanging sync messages.
|
|
127
|
+
* - Binary files are prohibited inside CRDT documents; use `CrdtFileAttachmentRef` references.
|
|
128
|
+
* - Sync states (`Automerge.SyncState`) are scoped to `(peerDeviceId, generation)` and cleared on disconnect.
|
|
129
|
+
*/
|
|
130
|
+
export class DropspaceAutomergeManager {
|
|
131
|
+
options;
|
|
132
|
+
events = new TypedEventEmitter();
|
|
133
|
+
storage;
|
|
134
|
+
maxLoadedDocuments;
|
|
135
|
+
maxDocumentBytes;
|
|
136
|
+
documents = new Map();
|
|
137
|
+
docLocks = new Map();
|
|
138
|
+
unsubscribers = [];
|
|
139
|
+
constructor(options) {
|
|
140
|
+
this.options = options;
|
|
141
|
+
this.storage = options.storage ?? new InMemoryCrdtStorageAdapter();
|
|
142
|
+
this.maxLoadedDocuments = options.maxLoadedDocuments ?? 64;
|
|
143
|
+
this.maxDocumentBytes = options.maxDocumentBytes ?? 2 * 1024 * 1024; // 2 MiB
|
|
144
|
+
this.unsubscribers.push(this.options.client.events.on("crdtFrame", ({ peerDeviceId, frame }) => {
|
|
145
|
+
void this.handleIncomingCrdtFrame(peerDeviceId, frame);
|
|
146
|
+
}));
|
|
147
|
+
this.unsubscribers.push(this.options.client.events.on("peerStateChange", (ev) => {
|
|
148
|
+
if (ev.state === "connected") {
|
|
149
|
+
// Reset all sync states for this peer on a fresh DataChannel open and initiate sync
|
|
150
|
+
this.prunePeerSyncStates(ev.peerDeviceId);
|
|
151
|
+
void this.syncAllSubscribedWithPeer(ev.peerDeviceId);
|
|
152
|
+
}
|
|
153
|
+
else if (ev.state === "closed" || ev.state === "failed" || ev.state === "reconnecting") {
|
|
154
|
+
this.prunePeerSyncStates(ev.peerDeviceId);
|
|
155
|
+
}
|
|
156
|
+
}));
|
|
157
|
+
this.unsubscribers.push(this.options.client.events.on("revocationNotice", (rev) => {
|
|
158
|
+
this.prunePeerSyncStates(rev.revokedDeviceId);
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
async openOrCreateDocument(documentId, initialValue, policy = {}) {
|
|
162
|
+
const existing = this.documents.get(documentId);
|
|
163
|
+
if (existing) {
|
|
164
|
+
existing.subscribed = true;
|
|
165
|
+
existing.policy = policy;
|
|
166
|
+
return existing.doc;
|
|
167
|
+
}
|
|
168
|
+
if (this.documents.size >= this.maxLoadedDocuments) {
|
|
169
|
+
throw new Error(`Maximum loaded CRDT documents limit (${this.maxLoadedDocuments}) exceeded`);
|
|
170
|
+
}
|
|
171
|
+
const persistedBytes = await this.storage.loadDocument(documentId);
|
|
172
|
+
let doc;
|
|
173
|
+
if (persistedBytes && persistedBytes.byteLength > 0) {
|
|
174
|
+
doc = Automerge.load(persistedBytes);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
doc = Automerge.init();
|
|
178
|
+
if (initialValue) {
|
|
179
|
+
assertNoEmbeddedBinary(initialValue);
|
|
180
|
+
doc = Automerge.change(doc, "Initialize document", (d) => {
|
|
181
|
+
for (const [k, v] of Object.entries(initialValue)) {
|
|
182
|
+
d[k] = v;
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
await this.persistDoc(documentId, doc);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const entry = {
|
|
189
|
+
documentId,
|
|
190
|
+
doc,
|
|
191
|
+
subscribed: true,
|
|
192
|
+
policy,
|
|
193
|
+
syncStates: new Map(),
|
|
194
|
+
};
|
|
195
|
+
this.documents.set(documentId, entry);
|
|
196
|
+
// Sync with any currently connected peers
|
|
197
|
+
for (const peer of this.options.client.devices.getPeers()) {
|
|
198
|
+
if (peer.deviceId !== this.options.client.getIdentity().deviceId) {
|
|
199
|
+
const sess = this.options.client.getPeerSession(peer.deviceId);
|
|
200
|
+
if (sess?.getState() === "connected") {
|
|
201
|
+
void this.syncDocumentWithPeer(documentId, peer.deviceId);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return doc;
|
|
206
|
+
}
|
|
207
|
+
getDocument(documentId) {
|
|
208
|
+
return this.documents.get(documentId)?.doc;
|
|
209
|
+
}
|
|
210
|
+
hasDocumentContent(documentId) {
|
|
211
|
+
const doc = this.documents.get(documentId)?.doc;
|
|
212
|
+
if (!doc)
|
|
213
|
+
return false;
|
|
214
|
+
return Automerge.getHeads(doc).length > 0;
|
|
215
|
+
}
|
|
216
|
+
async updateTextField(documentId, field, nextValue, message = `Update ${field}`) {
|
|
217
|
+
return this.changeDocument(documentId, message, (draft) => {
|
|
218
|
+
const current = draft[field];
|
|
219
|
+
if (typeof current === "string") {
|
|
220
|
+
Automerge.updateText(draft, [field], nextValue);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
draft[field] = nextValue;
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
setDocumentAccessPolicy(documentId, policy) {
|
|
228
|
+
const entry = this.documents.get(documentId);
|
|
229
|
+
if (entry) {
|
|
230
|
+
entry.policy = policy;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
unsubscribeDocument(documentId) {
|
|
234
|
+
const entry = this.documents.get(documentId);
|
|
235
|
+
if (entry) {
|
|
236
|
+
entry.subscribed = false;
|
|
237
|
+
entry.syncStates.clear();
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
async changeDocument(documentId, message, mutator) {
|
|
241
|
+
const entry = this.documents.get(documentId);
|
|
242
|
+
if (!entry) {
|
|
243
|
+
throw new Error(`Document '${documentId}' is not loaded`);
|
|
244
|
+
}
|
|
245
|
+
const nextDoc = Automerge.change(entry.doc, message, (draft) => {
|
|
246
|
+
mutator(draft);
|
|
247
|
+
assertNoEmbeddedBinary(draft);
|
|
248
|
+
});
|
|
249
|
+
await this.persistDoc(documentId, nextDoc);
|
|
250
|
+
entry.doc = nextDoc;
|
|
251
|
+
this.events.emit("documentUpdated", {
|
|
252
|
+
documentId,
|
|
253
|
+
doc: nextDoc,
|
|
254
|
+
source: "local",
|
|
255
|
+
});
|
|
256
|
+
// Push sync updates to all connected & authorized peers
|
|
257
|
+
const candidatePeerIds = this.options.spaceId
|
|
258
|
+
? this.options.client.devices.getPeers(this.options.spaceId).map((p) => p.deviceId)
|
|
259
|
+
: this.options.client.getConnectedPeerIds();
|
|
260
|
+
const myId = this.options.client.getIdentity().deviceId;
|
|
261
|
+
let sentToAnyPeer = false;
|
|
262
|
+
for (const peerDeviceId of candidatePeerIds) {
|
|
263
|
+
if (peerDeviceId === myId)
|
|
264
|
+
continue;
|
|
265
|
+
const sess = this.options.client.getPeerSession(peerDeviceId);
|
|
266
|
+
if (sess?.getState() === "connected" && this.isPeerAuthorizedForDoc(entry, peerDeviceId, false)) {
|
|
267
|
+
sentToAnyPeer = true;
|
|
268
|
+
void this.syncDocumentWithPeer(documentId, peerDeviceId);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
if (!sentToAnyPeer) {
|
|
272
|
+
this.events.emit("documentSyncStatus", {
|
|
273
|
+
documentId,
|
|
274
|
+
peerDeviceId: "local",
|
|
275
|
+
status: "offline_modified",
|
|
276
|
+
generation: 0,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
return nextDoc;
|
|
280
|
+
}
|
|
281
|
+
async persistDoc(documentId, doc) {
|
|
282
|
+
const saved = Automerge.save(doc);
|
|
283
|
+
if (saved.byteLength > this.maxDocumentBytes) {
|
|
284
|
+
throw new Error(`CRDT document '${documentId}' size (${saved.byteLength} bytes) exceeds maximum limit (${this.maxDocumentBytes} bytes)`);
|
|
285
|
+
}
|
|
286
|
+
await this.storage.saveDocument(documentId, saved);
|
|
287
|
+
}
|
|
288
|
+
isPeerAuthorizedForDoc(entry, peerDeviceId, isWriteFromPeer) {
|
|
289
|
+
if (entry.policy.allowedPeerDeviceIds &&
|
|
290
|
+
!entry.policy.allowedPeerDeviceIds.has(peerDeviceId)) {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
if (isWriteFromPeer &&
|
|
294
|
+
entry.policy.readOnlyPeerDeviceIds?.has(peerDeviceId)) {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
// Check client-level peer permissions in space / trusted peers
|
|
298
|
+
if (!this.options.client.hasPeerPermission(peerDeviceId, "crdt", this.options.spaceId)) {
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
async syncAllSubscribedWithPeer(peerDeviceId) {
|
|
304
|
+
for (const [docId, entry] of this.documents.entries()) {
|
|
305
|
+
if (entry.subscribed) {
|
|
306
|
+
await this.syncDocumentWithPeer(docId, peerDeviceId);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
async syncDocumentWithPeer(documentId, peerDeviceId) {
|
|
311
|
+
const entry = this.documents.get(documentId);
|
|
312
|
+
if (!entry || !entry.subscribed)
|
|
313
|
+
return;
|
|
314
|
+
const sess = this.options.client.getPeerSession(peerDeviceId);
|
|
315
|
+
if (!sess || sess.getState() !== "connected")
|
|
316
|
+
return;
|
|
317
|
+
if (!this.isPeerAuthorizedForDoc(entry, peerDeviceId, false)) {
|
|
318
|
+
this.events.emit("accessDenied", {
|
|
319
|
+
documentId,
|
|
320
|
+
peerDeviceId,
|
|
321
|
+
reason: "Peer is not authorized to sync this document",
|
|
322
|
+
});
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
const gen = sess.getGeneration();
|
|
326
|
+
const stateKey = `${peerDeviceId}:${gen}`;
|
|
327
|
+
const syncState = entry.syncStates.get(stateKey) ?? Automerge.initSyncState();
|
|
328
|
+
const [nextSyncState, syncMessage] = Automerge.generateSyncMessage(entry.doc, syncState);
|
|
329
|
+
entry.syncStates.set(stateKey, nextSyncState);
|
|
330
|
+
if (syncMessage) {
|
|
331
|
+
this.events.emit("documentSyncStatus", {
|
|
332
|
+
documentId,
|
|
333
|
+
peerDeviceId,
|
|
334
|
+
status: "syncing",
|
|
335
|
+
generation: gen,
|
|
336
|
+
});
|
|
337
|
+
await sess.multiplexer.sendRawWireFrame(WireFrameType.CRDT_SYNC, {
|
|
338
|
+
messageId: `crdt_${documentId}_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`,
|
|
339
|
+
channel: "crdt",
|
|
340
|
+
timestamp: Date.now(),
|
|
341
|
+
documentId,
|
|
342
|
+
}, syncMessage);
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
this.events.emit("documentSyncStatus", {
|
|
346
|
+
documentId,
|
|
347
|
+
peerDeviceId,
|
|
348
|
+
status: "synced",
|
|
349
|
+
generation: gen,
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
handleIncomingCrdtFrame(peerDeviceId, frame) {
|
|
354
|
+
const documentId = frame.header.documentId;
|
|
355
|
+
if (!documentId)
|
|
356
|
+
return Promise.resolve();
|
|
357
|
+
const prev = this.docLocks.get(documentId) ?? Promise.resolve();
|
|
358
|
+
const next = prev
|
|
359
|
+
.then(() => this.processIncomingCrdtFrame(peerDeviceId, documentId, frame))
|
|
360
|
+
.catch(() => { });
|
|
361
|
+
this.docLocks.set(documentId, next);
|
|
362
|
+
return next;
|
|
363
|
+
}
|
|
364
|
+
async processIncomingCrdtFrame(peerDeviceId, documentId, frame) {
|
|
365
|
+
const entry = this.documents.get(documentId);
|
|
366
|
+
if (!entry || !entry.subscribed)
|
|
367
|
+
return;
|
|
368
|
+
if (!this.isPeerAuthorizedForDoc(entry, peerDeviceId, true)) {
|
|
369
|
+
this.events.emit("accessDenied", {
|
|
370
|
+
documentId,
|
|
371
|
+
peerDeviceId,
|
|
372
|
+
reason: "Rejected incoming CRDT sync from unauthorized peer",
|
|
373
|
+
});
|
|
374
|
+
this.events.emit("documentSyncStatus", {
|
|
375
|
+
documentId,
|
|
376
|
+
peerDeviceId,
|
|
377
|
+
status: "access_denied",
|
|
378
|
+
generation: 0,
|
|
379
|
+
});
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
const sess = this.options.client.getPeerSession(peerDeviceId);
|
|
383
|
+
const gen = sess?.getGeneration() ?? 0;
|
|
384
|
+
const stateKey = `${peerDeviceId}:${gen}`;
|
|
385
|
+
const prevSyncState = entry.syncStates.get(stateKey) ?? Automerge.initSyncState();
|
|
386
|
+
const prevHeads = Automerge.getHeads(entry.doc).join(",");
|
|
387
|
+
let theirHeads = "";
|
|
388
|
+
try {
|
|
389
|
+
theirHeads = Automerge.decodeSyncMessage(frame.payload).heads.join(",");
|
|
390
|
+
}
|
|
391
|
+
catch {
|
|
392
|
+
theirHeads = "";
|
|
393
|
+
}
|
|
394
|
+
const [nextDoc, nextSyncState] = Automerge.receiveSyncMessage(entry.doc, prevSyncState, frame.payload);
|
|
395
|
+
entry.syncStates.set(stateKey, nextSyncState);
|
|
396
|
+
entry.doc = nextDoc;
|
|
397
|
+
const nextHeads = Automerge.getHeads(nextDoc).join(",");
|
|
398
|
+
if (nextHeads !== prevHeads) {
|
|
399
|
+
await this.persistDoc(documentId, nextDoc);
|
|
400
|
+
this.events.emit("documentUpdated", {
|
|
401
|
+
documentId,
|
|
402
|
+
doc: nextDoc,
|
|
403
|
+
source: "remote",
|
|
404
|
+
peerDeviceId,
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
// Continue the Automerge sync protocol exchange until both sides converge (generateSyncMessage returns null)
|
|
408
|
+
await this.syncDocumentWithPeer(documentId, peerDeviceId);
|
|
409
|
+
if (theirHeads && nextHeads === theirHeads) {
|
|
410
|
+
this.events.emit("documentSyncStatus", {
|
|
411
|
+
documentId,
|
|
412
|
+
peerDeviceId,
|
|
413
|
+
status: "synced",
|
|
414
|
+
generation: gen,
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
prunePeerSyncStates(peerDeviceId, keepGeneration) {
|
|
419
|
+
for (const entry of this.documents.values()) {
|
|
420
|
+
for (const key of Array.from(entry.syncStates.keys())) {
|
|
421
|
+
if (key.startsWith(`${peerDeviceId}:`)) {
|
|
422
|
+
if (keepGeneration === undefined || key !== `${peerDeviceId}:${keepGeneration}`) {
|
|
423
|
+
entry.syncStates.delete(key);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
close() {
|
|
430
|
+
for (const unsub of this.unsubscribers.splice(0)) {
|
|
431
|
+
unsub();
|
|
432
|
+
}
|
|
433
|
+
this.documents.clear();
|
|
434
|
+
this.events.removeAllListeners();
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/automerge/index.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|