@automerge/automerge-repo 1.1.0-alpha.7 → 1.1.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/README.md +3 -1
- package/dist/AutomergeUrl.js +1 -1
- package/dist/DocHandle.d.ts +10 -4
- package/dist/DocHandle.d.ts.map +1 -1
- package/dist/DocHandle.js +17 -8
- package/dist/Repo.d.ts +18 -6
- package/dist/Repo.d.ts.map +1 -1
- package/dist/Repo.js +88 -72
- package/dist/helpers/pause.d.ts +0 -1
- package/dist/helpers/pause.d.ts.map +1 -1
- package/dist/helpers/pause.js +2 -8
- package/dist/helpers/withTimeout.d.ts.map +1 -1
- package/dist/helpers/withTimeout.js +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/network/NetworkAdapter.d.ts.map +1 -1
- package/dist/network/NetworkAdapter.js +1 -0
- package/dist/network/NetworkSubsystem.js +3 -3
- package/dist/network/messages.d.ts +43 -38
- package/dist/network/messages.d.ts.map +1 -1
- package/dist/network/messages.js +7 -9
- package/dist/synchronizer/CollectionSynchronizer.d.ts.map +1 -1
- package/dist/synchronizer/CollectionSynchronizer.js +1 -0
- package/dist/synchronizer/DocSynchronizer.d.ts.map +1 -1
- package/dist/synchronizer/DocSynchronizer.js +11 -7
- package/dist/synchronizer/Synchronizer.d.ts +11 -3
- package/dist/synchronizer/Synchronizer.d.ts.map +1 -1
- package/package.json +3 -4
- package/src/AutomergeUrl.ts +1 -1
- package/src/DocHandle.ts +34 -12
- package/src/Repo.ts +113 -84
- package/src/helpers/pause.ts +3 -11
- package/src/helpers/withTimeout.ts +2 -0
- package/src/index.ts +1 -1
- package/src/network/NetworkAdapter.ts +4 -2
- package/src/network/NetworkSubsystem.ts +3 -3
- package/src/network/messages.ts +60 -63
- package/src/synchronizer/CollectionSynchronizer.ts +1 -0
- package/src/synchronizer/DocSynchronizer.ts +19 -15
- package/src/synchronizer/Synchronizer.ts +11 -3
- package/test/CollectionSynchronizer.test.ts +7 -5
- package/test/DocHandle.test.ts +11 -2
- package/test/RemoteHeadsSubscriptions.test.ts +49 -49
- package/test/Repo.test.ts +39 -1
- package/test/StorageSubsystem.test.ts +1 -1
- package/test/helpers/collectMessages.ts +19 -0
- package/test/remoteHeads.test.ts +142 -119
- package/.eslintrc +0 -28
- package/test/helpers/waitForMessages.ts +0 -22
package/README.md
CHANGED
|
@@ -46,7 +46,9 @@ A `Repo` exposes these methods:
|
|
|
46
46
|
- `delete(docId: DocumentId)`
|
|
47
47
|
Deletes the local copy of a document from the local cache and local storage. _This does not currently delete the document from any other peers_.
|
|
48
48
|
- `import(binary: Uint8Array)`
|
|
49
|
-
Imports a document binary (from `Automerge.save(doc)`) into the repo, returning a new handle
|
|
49
|
+
Imports a document binary (from `export()` or `Automerge.save(doc)`) into the repo, returning a new handle
|
|
50
|
+
- `export(docId: DocumentId)`
|
|
51
|
+
Exports the document. Returns a Promise containing either the Uint8Array of the document or undefined if the document is currently unavailable. See the [Automerge binary format spec](https://automerge.org/automerge-binary-format-spec/) for more details on the shape of the Uint8Array.
|
|
50
52
|
- `.on("document", ({handle: DocHandle}) => void)`
|
|
51
53
|
Registers a callback to be fired each time a new document is loaded or created.
|
|
52
54
|
- `.on("delete-document", ({handle: DocHandle}) => void)`
|
package/dist/AutomergeUrl.js
CHANGED
|
@@ -4,7 +4,7 @@ export const urlPrefix = "automerge:";
|
|
|
4
4
|
/** Given an Automerge URL, returns the DocumentId in both base58check-encoded form and binary form */
|
|
5
5
|
export const parseAutomergeUrl = (url) => {
|
|
6
6
|
const regex = new RegExp(`^${urlPrefix}(\\w+)$`);
|
|
7
|
-
const [
|
|
7
|
+
const [, docMatch] = url.match(regex) || [];
|
|
8
8
|
const documentId = docMatch;
|
|
9
9
|
const binaryDocumentId = documentIdToBinary(documentId);
|
|
10
10
|
if (!binaryDocumentId)
|
package/dist/DocHandle.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export declare class DocHandle<T>//
|
|
|
26
26
|
*/
|
|
27
27
|
get url(): AutomergeUrl;
|
|
28
28
|
/** @hidden */
|
|
29
|
-
constructor(documentId: DocumentId,
|
|
29
|
+
constructor(documentId: DocumentId, options?: DocHandleOptions<T>);
|
|
30
30
|
/**
|
|
31
31
|
* Checks if the document is ready for accessing or changes.
|
|
32
32
|
* Note that for documents already stored locally this occurs before synchronization
|
|
@@ -120,10 +120,16 @@ export declare class DocHandle<T>//
|
|
|
120
120
|
broadcast(message: unknown): void;
|
|
121
121
|
}
|
|
122
122
|
/** @hidden */
|
|
123
|
-
export
|
|
124
|
-
|
|
123
|
+
export type DocHandleOptions<T> = {
|
|
124
|
+
/** If we know this is a new document (because we're creating it) this should be set to true. */
|
|
125
|
+
isNew: true;
|
|
126
|
+
/** The initial value of the document. */
|
|
127
|
+
initialValue?: T;
|
|
128
|
+
} | {
|
|
129
|
+
isNew?: false;
|
|
130
|
+
/** The number of milliseconds before we mark this document as unavailable if we don't have it and nobody shares it with us. */
|
|
125
131
|
timeoutDelay?: number;
|
|
126
|
-
}
|
|
132
|
+
};
|
|
127
133
|
export interface DocHandleMessagePayload {
|
|
128
134
|
destinationId: PeerId;
|
|
129
135
|
documentId: DocumentId;
|
package/dist/DocHandle.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocHandle.d.ts","sourceRoot":"","sources":["../src/DocHandle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,2BAA2B,CAAA;AAE9C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EASL,UAAU,EAEX,MAAM,QAAQ,CAAA;AAMf,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAE9C;;;;;;;;;;;KAWK;AACL,qBAAa,SAAS,CAAC,CAAC,CAAE,EAAE;AAC1B,SAAQ,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;;IAmB/B,UAAU,EAAE,UAAU;IAX/B;;;;OAIG;IACH,IAAI,GAAG,IAAI,YAAY,CAEtB;IAED,cAAc;gBAEL,UAAU,EAAE,UAAU,EAC7B,
|
|
1
|
+
{"version":3,"file":"DocHandle.d.ts","sourceRoot":"","sources":["../src/DocHandle.ts"],"names":[],"mappings":"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"}
|
package/dist/DocHandle.js
CHANGED
|
@@ -24,7 +24,7 @@ export class DocHandle//
|
|
|
24
24
|
documentId;
|
|
25
25
|
#log;
|
|
26
26
|
#machine;
|
|
27
|
-
#timeoutDelay;
|
|
27
|
+
#timeoutDelay = 60_000;
|
|
28
28
|
#remoteHeads = {};
|
|
29
29
|
/** The URL of this document
|
|
30
30
|
*
|
|
@@ -35,17 +35,26 @@ export class DocHandle//
|
|
|
35
35
|
return stringifyAutomergeUrl({ documentId: this.documentId });
|
|
36
36
|
}
|
|
37
37
|
/** @hidden */
|
|
38
|
-
constructor(documentId,
|
|
38
|
+
constructor(documentId, options = {}) {
|
|
39
39
|
super();
|
|
40
40
|
this.documentId = documentId;
|
|
41
|
-
this
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
this.documentId = documentId;
|
|
42
|
+
if ("timeoutDelay" in options && options.timeoutDelay) {
|
|
43
|
+
this.#timeoutDelay = options.timeoutDelay;
|
|
44
|
+
}
|
|
45
|
+
let doc;
|
|
46
|
+
const isNew = "isNew" in options && options.isNew;
|
|
46
47
|
if (isNew) {
|
|
47
|
-
|
|
48
|
+
// T should really be constrained to extend `Record<string, unknown>` (an automerge doc can't be
|
|
49
|
+
// e.g. a primitive, an array, etc. - it must be an object). But adding that constraint creates
|
|
50
|
+
// a bunch of other problems elsewhere so for now we'll just cast it here to make Automerge happy.
|
|
51
|
+
doc = A.from(options.initialValue);
|
|
52
|
+
doc = A.emptyChange(doc);
|
|
48
53
|
}
|
|
54
|
+
else {
|
|
55
|
+
doc = A.init();
|
|
56
|
+
}
|
|
57
|
+
this.#log = debug(`automerge-repo:dochandle:${this.documentId.slice(0, 5)}`);
|
|
49
58
|
/**
|
|
50
59
|
* Internally we use a state machine to orchestrate document loading and/or syncing, in order to
|
|
51
60
|
* avoid requesting data we already have, or surfacing intermediate values to the consumer.
|
package/dist/Repo.d.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { NetworkAdapter, type PeerMetadata } from "./network/NetworkAdapter.js";
|
|
|
4
4
|
import { NetworkSubsystem } from "./network/NetworkSubsystem.js";
|
|
5
5
|
import { StorageAdapter } from "./storage/StorageAdapter.js";
|
|
6
6
|
import { StorageSubsystem } from "./storage/StorageSubsystem.js";
|
|
7
|
-
import type { AnyDocumentId, DocumentId, PeerId } from "./types.js";
|
|
8
7
|
import { StorageId } from "./storage/types.js";
|
|
8
|
+
import type { AnyDocumentId, DocumentId, PeerId } from "./types.js";
|
|
9
9
|
/** A Repo is a collection of documents with networking, syncing, and storage capabilities. */
|
|
10
10
|
/** The `Repo` is the main entry point of this library
|
|
11
11
|
*
|
|
@@ -29,18 +29,18 @@ export declare class Repo extends EventEmitter<RepoEvents> {
|
|
|
29
29
|
/** maps peer id to to persistence information (storageId, isEphemeral), access by collection synchronizer */
|
|
30
30
|
/** @hidden */
|
|
31
31
|
peerMetadataByPeerId: Record<PeerId, PeerMetadata>;
|
|
32
|
-
constructor({ storage, network, peerId, sharePolicy, isEphemeral, }: RepoConfig);
|
|
32
|
+
constructor({ storage, network, peerId, sharePolicy, isEphemeral, enableRemoteHeadsGossiping, }: RepoConfig);
|
|
33
33
|
/** Returns all the handles we have cached. */
|
|
34
34
|
get handles(): Record<DocumentId, DocHandle<any>>;
|
|
35
35
|
/** Returns a list of all connected peer ids */
|
|
36
36
|
get peers(): PeerId[];
|
|
37
37
|
getStorageIdOfPeer(peerId: PeerId): StorageId | undefined;
|
|
38
38
|
/**
|
|
39
|
-
* Creates a new document and returns a handle to it. The initial value of the document is
|
|
40
|
-
*
|
|
41
|
-
* to advertise interest in the document.
|
|
39
|
+
* Creates a new document and returns a handle to it. The initial value of the document is an
|
|
40
|
+
* empty object `{}` unless an initial value is provided. Its documentId is generated by the
|
|
41
|
+
* system. we emit a `document` event to advertise interest in the document.
|
|
42
42
|
*/
|
|
43
|
-
create<T>(): DocHandle<T>;
|
|
43
|
+
create<T>(initialValue?: T): DocHandle<T>;
|
|
44
44
|
/** Create a new DocHandle by cloning the history of an existing DocHandle.
|
|
45
45
|
*
|
|
46
46
|
* @param clonedHandle - The handle to clone
|
|
@@ -67,6 +67,14 @@ export declare class Repo extends EventEmitter<RepoEvents> {
|
|
|
67
67
|
delete(
|
|
68
68
|
/** The url or documentId of the handle to delete */
|
|
69
69
|
id: AnyDocumentId): void;
|
|
70
|
+
/**
|
|
71
|
+
* Exports a document to a binary format.
|
|
72
|
+
* @param id - The url or documentId of the handle to export
|
|
73
|
+
*
|
|
74
|
+
* @returns Promise<Uint8Array | undefined> - A Promise containing the binary document,
|
|
75
|
+
* or undefined if the document is unavailable.
|
|
76
|
+
*/
|
|
77
|
+
export(id: AnyDocumentId): Promise<Uint8Array | undefined>;
|
|
70
78
|
/**
|
|
71
79
|
* Imports document binary into the repo.
|
|
72
80
|
* @param binary - The binary to import
|
|
@@ -90,6 +98,10 @@ export interface RepoConfig {
|
|
|
90
98
|
* all peers). A server only syncs documents that a peer explicitly requests by ID.
|
|
91
99
|
*/
|
|
92
100
|
sharePolicy?: SharePolicy;
|
|
101
|
+
/**
|
|
102
|
+
* Whether to enable the experimental remote heads gossiping feature
|
|
103
|
+
*/
|
|
104
|
+
enableRemoteHeadsGossiping?: boolean;
|
|
93
105
|
}
|
|
94
106
|
/** A function that determines whether we should share a document with a peer
|
|
95
107
|
*
|
package/dist/Repo.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../src/Repo.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAM5C,OAAO,EAAE,SAAS,EAAiC,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../src/Repo.ts"],"names":[],"mappings":"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"}
|
package/dist/Repo.js
CHANGED
|
@@ -3,12 +3,12 @@ import debug from "debug";
|
|
|
3
3
|
import { EventEmitter } from "eventemitter3";
|
|
4
4
|
import { generateAutomergeUrl, interpretAsDocumentId, parseAutomergeUrl, } from "./AutomergeUrl.js";
|
|
5
5
|
import { DocHandle } from "./DocHandle.js";
|
|
6
|
+
import { RemoteHeadsSubscriptions } from "./RemoteHeadsSubscriptions.js";
|
|
7
|
+
import { headsAreSame } from "./helpers/headsAreSame.js";
|
|
6
8
|
import { throttle } from "./helpers/throttle.js";
|
|
7
9
|
import { NetworkSubsystem } from "./network/NetworkSubsystem.js";
|
|
8
10
|
import { StorageSubsystem } from "./storage/StorageSubsystem.js";
|
|
9
11
|
import { CollectionSynchronizer } from "./synchronizer/CollectionSynchronizer.js";
|
|
10
|
-
import { RemoteHeadsSubscriptions } from "./RemoteHeadsSubscriptions.js";
|
|
11
|
-
import { headsAreSame } from "./helpers/headsAreSame.js";
|
|
12
12
|
/** A Repo is a collection of documents with networking, syncing, and storage capabilities. */
|
|
13
13
|
/** The `Repo` is the main entry point of this library
|
|
14
14
|
*
|
|
@@ -35,8 +35,10 @@ export class Repo extends EventEmitter {
|
|
|
35
35
|
/** @hidden */
|
|
36
36
|
peerMetadataByPeerId = {};
|
|
37
37
|
#remoteHeadsSubscriptions = new RemoteHeadsSubscriptions();
|
|
38
|
-
|
|
38
|
+
#remoteHeadsGossipingEnabled = false;
|
|
39
|
+
constructor({ storage, network, peerId, sharePolicy, isEphemeral = storage === undefined, enableRemoteHeadsGossiping = false, }) {
|
|
39
40
|
super();
|
|
41
|
+
this.#remoteHeadsGossipingEnabled = enableRemoteHeadsGossiping;
|
|
40
42
|
this.#log = debug(`automerge-repo:repo`);
|
|
41
43
|
this.sharePolicy = sharePolicy ?? this.sharePolicy;
|
|
42
44
|
// DOC COLLECTION
|
|
@@ -101,9 +103,11 @@ export class Repo extends EventEmitter {
|
|
|
101
103
|
this.#log(`sending ${message.type} message to ${message.targetId}`);
|
|
102
104
|
networkSubsystem.send(message);
|
|
103
105
|
});
|
|
104
|
-
this.#
|
|
105
|
-
this.#
|
|
106
|
-
|
|
106
|
+
if (this.#remoteHeadsGossipingEnabled) {
|
|
107
|
+
this.#synchronizer.on("open-doc", ({ peerId, documentId }) => {
|
|
108
|
+
this.#remoteHeadsSubscriptions.subscribePeerToDoc(peerId, documentId);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
107
111
|
// STORAGE
|
|
108
112
|
// The storage subsystem has access to some form of persistence, and deals with save and loading documents.
|
|
109
113
|
const storageSubsystem = storage ? new StorageSubsystem(storage) : undefined;
|
|
@@ -126,7 +130,7 @@ export class Repo extends EventEmitter {
|
|
|
126
130
|
}
|
|
127
131
|
this.sharePolicy(peerId)
|
|
128
132
|
.then(shouldShare => {
|
|
129
|
-
if (shouldShare) {
|
|
133
|
+
if (shouldShare && this.#remoteHeadsGossipingEnabled) {
|
|
130
134
|
this.#remoteHeadsSubscriptions.addGenerousPeer(peerId);
|
|
131
135
|
}
|
|
132
136
|
})
|
|
@@ -156,47 +160,53 @@ export class Repo extends EventEmitter {
|
|
|
156
160
|
(!heads || !headsAreSame(heads, message.syncState.theirHeads));
|
|
157
161
|
if (haveHeadsChanged) {
|
|
158
162
|
handle.setRemoteHeads(storageId, message.syncState.theirHeads);
|
|
159
|
-
if (storageId) {
|
|
163
|
+
if (storageId && this.#remoteHeadsGossipingEnabled) {
|
|
160
164
|
this.#remoteHeadsSubscriptions.handleImmediateRemoteHeadsChanged(message.documentId, storageId, message.syncState.theirHeads);
|
|
161
165
|
}
|
|
162
166
|
}
|
|
163
167
|
});
|
|
164
|
-
this.#
|
|
165
|
-
this.
|
|
166
|
-
type: "remote-heads-changed",
|
|
167
|
-
targetId: message.targetId,
|
|
168
|
-
documentId: message.documentId,
|
|
169
|
-
newHeads: {
|
|
170
|
-
[message.storageId]: {
|
|
171
|
-
heads: message.heads,
|
|
172
|
-
timestamp: message.timestamp,
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
this.#remoteHeadsSubscriptions.on("change-remote-subs", message => {
|
|
178
|
-
this.#log("change-remote-subs", message);
|
|
179
|
-
for (const peer of message.peers) {
|
|
168
|
+
if (this.#remoteHeadsGossipingEnabled) {
|
|
169
|
+
this.#remoteHeadsSubscriptions.on("notify-remote-heads", message => {
|
|
180
170
|
this.networkSubsystem.send({
|
|
181
|
-
type: "remote-
|
|
182
|
-
targetId:
|
|
183
|
-
|
|
184
|
-
|
|
171
|
+
type: "remote-heads-changed",
|
|
172
|
+
targetId: message.targetId,
|
|
173
|
+
documentId: message.documentId,
|
|
174
|
+
newHeads: {
|
|
175
|
+
[message.storageId]: {
|
|
176
|
+
heads: message.heads,
|
|
177
|
+
timestamp: message.timestamp,
|
|
178
|
+
},
|
|
179
|
+
},
|
|
185
180
|
});
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
181
|
+
});
|
|
182
|
+
this.#remoteHeadsSubscriptions.on("change-remote-subs", message => {
|
|
183
|
+
this.#log("change-remote-subs", message);
|
|
184
|
+
for (const peer of message.peers) {
|
|
185
|
+
this.networkSubsystem.send({
|
|
186
|
+
type: "remote-subscription-change",
|
|
187
|
+
targetId: peer,
|
|
188
|
+
add: message.add,
|
|
189
|
+
remove: message.remove,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
this.#remoteHeadsSubscriptions.on("remote-heads-changed", message => {
|
|
194
|
+
const handle = this.#handleCache[message.documentId];
|
|
195
|
+
handle.setRemoteHeads(message.storageId, message.remoteHeads);
|
|
196
|
+
});
|
|
197
|
+
}
|
|
192
198
|
}
|
|
193
199
|
#receiveMessage(message) {
|
|
194
200
|
switch (message.type) {
|
|
195
201
|
case "remote-subscription-change":
|
|
196
|
-
this.#
|
|
202
|
+
if (this.#remoteHeadsGossipingEnabled) {
|
|
203
|
+
this.#remoteHeadsSubscriptions.handleControlMessage(message);
|
|
204
|
+
}
|
|
197
205
|
break;
|
|
198
206
|
case "remote-heads-changed":
|
|
199
|
-
this.#
|
|
207
|
+
if (this.#remoteHeadsGossipingEnabled) {
|
|
208
|
+
this.#remoteHeadsSubscriptions.handleRemoteHeads(message);
|
|
209
|
+
}
|
|
200
210
|
break;
|
|
201
211
|
case "sync":
|
|
202
212
|
case "request":
|
|
@@ -209,38 +219,31 @@ export class Repo extends EventEmitter {
|
|
|
209
219
|
}
|
|
210
220
|
#throttledSaveSyncStateHandlers = {};
|
|
211
221
|
/** saves sync state throttled per storage id, if a peer doesn't have a storage id it's sync state is not persisted */
|
|
212
|
-
#saveSyncState(
|
|
222
|
+
#saveSyncState(payload) {
|
|
213
223
|
if (!this.storageSubsystem) {
|
|
214
224
|
return;
|
|
215
225
|
}
|
|
216
|
-
const { storageId, isEphemeral } = this.peerMetadataByPeerId[
|
|
226
|
+
const { storageId, isEphemeral } = this.peerMetadataByPeerId[payload.peerId] || {};
|
|
217
227
|
if (!storageId || isEphemeral) {
|
|
218
228
|
return;
|
|
219
229
|
}
|
|
220
230
|
let handler = this.#throttledSaveSyncStateHandlers[storageId];
|
|
221
231
|
if (!handler) {
|
|
222
232
|
handler = this.#throttledSaveSyncStateHandlers[storageId] = throttle(({ documentId, syncState }) => {
|
|
223
|
-
this.storageSubsystem.saveSyncState(documentId, storageId, syncState)
|
|
224
|
-
.catch(err => {
|
|
225
|
-
this.#log("error saving sync state", { err });
|
|
226
|
-
});
|
|
233
|
+
void this.storageSubsystem.saveSyncState(documentId, storageId, syncState);
|
|
227
234
|
}, this.saveDebounceRate);
|
|
228
235
|
}
|
|
229
|
-
handler(
|
|
236
|
+
handler(payload);
|
|
230
237
|
}
|
|
231
238
|
/** Returns an existing handle if we have it; creates one otherwise. */
|
|
232
|
-
#getHandle(
|
|
233
|
-
/** The documentId of the handle to look up or create */
|
|
234
|
-
documentId,
|
|
235
|
-
/** If we know we're creating a new document, specify this so we can have access to it immediately */
|
|
236
|
-
isNew) {
|
|
239
|
+
#getHandle({ documentId, isNew, initialValue, }) {
|
|
237
240
|
// If we have the handle cached, return it
|
|
238
241
|
if (this.#handleCache[documentId])
|
|
239
242
|
return this.#handleCache[documentId];
|
|
240
243
|
// If not, create a new handle, cache it, and return it
|
|
241
244
|
if (!documentId)
|
|
242
245
|
throw new Error(`Invalid documentId ${documentId}`);
|
|
243
|
-
const handle = new DocHandle(documentId, { isNew });
|
|
246
|
+
const handle = new DocHandle(documentId, { isNew, initialValue });
|
|
244
247
|
this.#handleCache[documentId] = handle;
|
|
245
248
|
return handle;
|
|
246
249
|
}
|
|
@@ -256,28 +259,18 @@ export class Repo extends EventEmitter {
|
|
|
256
259
|
return this.peerMetadataByPeerId[peerId]?.storageId;
|
|
257
260
|
}
|
|
258
261
|
/**
|
|
259
|
-
* Creates a new document and returns a handle to it. The initial value of the document is
|
|
260
|
-
*
|
|
261
|
-
* to advertise interest in the document.
|
|
262
|
+
* Creates a new document and returns a handle to it. The initial value of the document is an
|
|
263
|
+
* empty object `{}` unless an initial value is provided. Its documentId is generated by the
|
|
264
|
+
* system. we emit a `document` event to advertise interest in the document.
|
|
262
265
|
*/
|
|
263
|
-
create() {
|
|
264
|
-
// TODO:
|
|
265
|
-
// either
|
|
266
|
-
// - pass an initial value and do something like this to ensure that you get a valid initial value
|
|
267
|
-
// const myInitialValue = {
|
|
268
|
-
// tasks: [],
|
|
269
|
-
// filter: "all",
|
|
270
|
-
//
|
|
271
|
-
// const guaranteeInitialValue = (doc: any) => {
|
|
272
|
-
// if (!doc.tasks) doc.tasks = []
|
|
273
|
-
// if (!doc.filter) doc.filter = "all"
|
|
274
|
-
// return { ...myInitialValue, ...doc }
|
|
275
|
-
// }
|
|
276
|
-
// or
|
|
277
|
-
// - pass a "reify" function that takes a `<any>` and returns `<T>`
|
|
266
|
+
create(initialValue) {
|
|
278
267
|
// Generate a new UUID and store it in the buffer
|
|
279
268
|
const { documentId } = parseAutomergeUrl(generateAutomergeUrl());
|
|
280
|
-
const handle = this.#getHandle(
|
|
269
|
+
const handle = this.#getHandle({
|
|
270
|
+
documentId,
|
|
271
|
+
isNew: true,
|
|
272
|
+
initialValue,
|
|
273
|
+
});
|
|
281
274
|
this.emit("document", { handle, isNew: true });
|
|
282
275
|
return handle;
|
|
283
276
|
}
|
|
@@ -332,7 +325,10 @@ export class Repo extends EventEmitter {
|
|
|
332
325
|
}
|
|
333
326
|
return this.#handleCache[documentId];
|
|
334
327
|
}
|
|
335
|
-
const handle = this.#getHandle(
|
|
328
|
+
const handle = this.#getHandle({
|
|
329
|
+
documentId,
|
|
330
|
+
isNew: false,
|
|
331
|
+
});
|
|
336
332
|
this.emit("document", { handle, isNew: false });
|
|
337
333
|
return handle;
|
|
338
334
|
}
|
|
@@ -340,11 +336,26 @@ export class Repo extends EventEmitter {
|
|
|
340
336
|
/** The url or documentId of the handle to delete */
|
|
341
337
|
id) {
|
|
342
338
|
const documentId = interpretAsDocumentId(id);
|
|
343
|
-
const handle = this.#getHandle(documentId, false);
|
|
339
|
+
const handle = this.#getHandle({ documentId, isNew: false });
|
|
344
340
|
handle.delete();
|
|
345
341
|
delete this.#handleCache[documentId];
|
|
346
342
|
this.emit("delete-document", { documentId });
|
|
347
343
|
}
|
|
344
|
+
/**
|
|
345
|
+
* Exports a document to a binary format.
|
|
346
|
+
* @param id - The url or documentId of the handle to export
|
|
347
|
+
*
|
|
348
|
+
* @returns Promise<Uint8Array | undefined> - A Promise containing the binary document,
|
|
349
|
+
* or undefined if the document is unavailable.
|
|
350
|
+
*/
|
|
351
|
+
async export(id) {
|
|
352
|
+
const documentId = interpretAsDocumentId(id);
|
|
353
|
+
const handle = this.#getHandle({ documentId, isNew: false });
|
|
354
|
+
const doc = await handle.doc();
|
|
355
|
+
if (!doc)
|
|
356
|
+
return undefined;
|
|
357
|
+
return Automerge.save(doc);
|
|
358
|
+
}
|
|
348
359
|
/**
|
|
349
360
|
* Imports document binary into the repo.
|
|
350
361
|
* @param binary - The binary to import
|
|
@@ -358,8 +369,13 @@ export class Repo extends EventEmitter {
|
|
|
358
369
|
return handle;
|
|
359
370
|
}
|
|
360
371
|
subscribeToRemotes = (remotes) => {
|
|
361
|
-
this.#
|
|
362
|
-
|
|
372
|
+
if (this.#remoteHeadsGossipingEnabled) {
|
|
373
|
+
this.#log("subscribeToRemotes", { remotes });
|
|
374
|
+
this.#remoteHeadsSubscriptions.subscribeToRemotes(remotes);
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
this.#log("WARN: subscribeToRemotes called but remote heads gossiping is not enabled");
|
|
378
|
+
}
|
|
363
379
|
};
|
|
364
380
|
storageId = async () => {
|
|
365
381
|
if (!this.storageSubsystem) {
|
package/dist/helpers/pause.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pause.d.ts","sourceRoot":"","sources":["../../src/helpers/pause.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pause.d.ts","sourceRoot":"","sources":["../../src/helpers/pause.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,KAAK,+BAC4C,CAAA"}
|
package/dist/helpers/pause.js
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
+
/* c8 ignore start */
|
|
1
2
|
export const pause = (t = 0) => new Promise(resolve => setTimeout(() => resolve(), t));
|
|
2
|
-
|
|
3
|
-
return Promise.race([
|
|
4
|
-
promise,
|
|
5
|
-
pause(millis).then(() => {
|
|
6
|
-
throw new Error("timeout exceeded");
|
|
7
|
-
}),
|
|
8
|
-
]);
|
|
9
|
-
}
|
|
3
|
+
/* c8 ignore end */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"withTimeout.d.ts","sourceRoot":"","sources":["../../src/helpers/withTimeout.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"withTimeout.d.ts","sourceRoot":"","sources":["../../src/helpers/withTimeout.ts"],"names":[],"mappings":"AACA;;;GAGG;AACH,eAAO,MAAM,WAAW,8BAEnB,MAAM,eAcV,CAAA;AAED,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* c8 ignore start */
|
|
1
2
|
/**
|
|
2
3
|
* If `promise` is resolved before `t` ms elapse, the timeout is cleared and the result of the
|
|
3
4
|
* promise is returned. If the timeout ends first, a `TimeoutError` is thrown.
|
|
@@ -20,3 +21,4 @@ export class TimeoutError extends Error {
|
|
|
20
21
|
this.name = "TimeoutError";
|
|
21
22
|
}
|
|
22
23
|
}
|
|
24
|
+
/* c8 ignore end */
|
package/dist/index.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export { DocHandle } from "./DocHandle.js";
|
|
|
29
29
|
export { isValidAutomergeUrl, parseAutomergeUrl, stringifyAutomergeUrl, } from "./AutomergeUrl.js";
|
|
30
30
|
export { Repo } from "./Repo.js";
|
|
31
31
|
export { NetworkAdapter } from "./network/NetworkAdapter.js";
|
|
32
|
-
export {
|
|
32
|
+
export { isRepoMessage } from "./network/messages.js";
|
|
33
33
|
export { StorageAdapter } from "./storage/StorageAdapter.js";
|
|
34
34
|
/** @hidden **/
|
|
35
35
|
export * as cbor from "./helpers/cbor.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAE5D,eAAe;AACf,OAAO,KAAK,IAAI,MAAM,mBAAmB,CAAA;AAIzC,YAAY,EACV,sBAAsB,EACtB,sBAAsB,EACtB,6BAA6B,EAC7B,gCAAgC,EAChC,2BAA2B,EAC3B,eAAe,EACf,gBAAgB,EAChB,wCAAwC,EACxC,WAAW,GACZ,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EACV,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,UAAU,EACV,WAAW,GACZ,MAAM,WAAW,CAAA;AAElB,YAAY,EACV,oBAAoB,EACpB,WAAW,EACX,oBAAoB,EACpB,uBAAuB,EACvB,YAAY,GACb,MAAM,6BAA6B,CAAA;AAEpC,YAAY,EACV,0BAA0B,EAC1B,gBAAgB,EAChB,OAAO,EACP,WAAW,EACX,cAAc,EACd,WAAW,GACZ,MAAM,uBAAuB,CAAA;AAE9B,YAAY,EACV,KAAK,EACL,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,GACV,MAAM,oBAAoB,CAAA;AAE3B,cAAc,YAAY,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -29,7 +29,7 @@ export { DocHandle } from "./DocHandle.js";
|
|
|
29
29
|
export { isValidAutomergeUrl, parseAutomergeUrl, stringifyAutomergeUrl, } from "./AutomergeUrl.js";
|
|
30
30
|
export { Repo } from "./Repo.js";
|
|
31
31
|
export { NetworkAdapter } from "./network/NetworkAdapter.js";
|
|
32
|
-
export {
|
|
32
|
+
export { isRepoMessage } from "./network/messages.js";
|
|
33
33
|
export { StorageAdapter } from "./storage/StorageAdapter.js";
|
|
34
34
|
/** @hidden **/
|
|
35
35
|
export * as cbor from "./helpers/cbor.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NetworkAdapter.d.ts","sourceRoot":"","sources":["../../src/network/NetworkAdapter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"NetworkAdapter.d.ts","sourceRoot":"","sources":["../../src/network/NetworkAdapter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAE/C;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED;;;;;;GAMG;AACH,8BAAsB,cAAe,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,YAAY,CAAA;IAE3B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI;IAEnE;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAErC,gEAAgE;IAChE,QAAQ,CAAC,UAAU,IAAI,IAAI;CAC5B;AAID,MAAM,WAAW,oBAAoB;IACnC,mDAAmD;IACnD,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAA;IAErC,yCAAyC;IACzC,KAAK,EAAE,MAAM,IAAI,CAAA;IAEjB,+DAA+D;IAC/D,gBAAgB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAA;IAEzD,2EAA2E;IAC3E,mBAAmB,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAA;IAE/D,sEAAsE;IACtE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CACpC;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,cAAc,CAAA;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,YAAY,CAAA;CAC3B;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAA;CACf"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import debug from "debug";
|
|
2
2
|
import { EventEmitter } from "eventemitter3";
|
|
3
|
-
import { isEphemeralMessage,
|
|
3
|
+
import { isEphemeralMessage, isRepoMessage, } from "./messages.js";
|
|
4
4
|
const getEphemeralMessageSource = (message) => `${message.senderId}:${message.sessionId}`;
|
|
5
5
|
export class NetworkSubsystem extends EventEmitter {
|
|
6
6
|
peerId;
|
|
@@ -43,7 +43,7 @@ export class NetworkSubsystem extends EventEmitter {
|
|
|
43
43
|
this.emit("peer-disconnected", { peerId });
|
|
44
44
|
});
|
|
45
45
|
networkAdapter.on("message", msg => {
|
|
46
|
-
if (!
|
|
46
|
+
if (!isRepoMessage(msg)) {
|
|
47
47
|
this.#log(`invalid message: ${JSON.stringify(msg)}`);
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
@@ -107,7 +107,7 @@ export class NetworkSubsystem extends EventEmitter {
|
|
|
107
107
|
}
|
|
108
108
|
};
|
|
109
109
|
const outbound = prepareMessage(message);
|
|
110
|
-
this.#log("sending message", outbound);
|
|
110
|
+
this.#log("sending message %o", outbound);
|
|
111
111
|
peer.send(outbound);
|
|
112
112
|
}
|
|
113
113
|
isReady = () => {
|