@automerge/automerge-repo 1.0.17 → 1.0.19
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/DocHandle.d.ts +16 -3
- package/dist/DocHandle.d.ts.map +1 -1
- package/dist/DocHandle.js +20 -13
- package/dist/Repo.d.ts +2 -0
- package/dist/Repo.d.ts.map +1 -1
- package/dist/Repo.js +17 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/network/messages.d.ts +7 -0
- package/dist/network/messages.d.ts.map +1 -1
- package/dist/storage/StorageSubsystem.d.ts +3 -1
- package/dist/storage/StorageSubsystem.d.ts.map +1 -1
- package/dist/storage/StorageSubsystem.js +10 -0
- package/dist/storage/chunkTypeFromKey.d.ts +1 -2
- package/dist/storage/chunkTypeFromKey.d.ts.map +1 -1
- package/dist/synchronizer/CollectionSynchronizer.d.ts +2 -0
- package/dist/synchronizer/CollectionSynchronizer.d.ts.map +1 -1
- package/dist/synchronizer/CollectionSynchronizer.js +14 -1
- package/dist/synchronizer/DocSynchronizer.d.ts +6 -2
- package/dist/synchronizer/DocSynchronizer.d.ts.map +1 -1
- package/dist/synchronizer/DocSynchronizer.js +119 -76
- package/dist/synchronizer/Synchronizer.d.ts +2 -1
- package/dist/synchronizer/Synchronizer.d.ts.map +1 -1
- package/package.json +3 -5
- package/src/DocHandle.ts +32 -13
- package/src/Repo.ts +23 -6
- package/src/index.ts +1 -0
- package/src/network/messages.ts +8 -0
- package/src/storage/StorageSubsystem.ts +20 -2
- package/src/storage/chunkTypeFromKey.ts +1 -2
- package/src/synchronizer/CollectionSynchronizer.ts +19 -1
- package/src/synchronizer/DocSynchronizer.ts +168 -94
- package/src/synchronizer/Synchronizer.ts +6 -1
- package/test/DocHandle.test.ts +19 -2
- package/test/DocSynchronizer.test.ts +47 -16
- package/test/Repo.test.ts +159 -4
- package/test/StorageSubsystem.test.ts +30 -2
package/dist/DocHandle.d.ts
CHANGED
|
@@ -73,6 +73,12 @@ export declare class DocHandle<T>//
|
|
|
73
73
|
* @hidden
|
|
74
74
|
* */
|
|
75
75
|
update(callback: (doc: A.Doc<T>) => A.Doc<T>): void;
|
|
76
|
+
/** `setRemoteHeads` is called by the doc synchronizer
|
|
77
|
+
* @hidden
|
|
78
|
+
*/
|
|
79
|
+
setRemoteHeads(peerId: PeerId, heads: A.Heads): void;
|
|
80
|
+
/** Returns the heads of the peer */
|
|
81
|
+
getRemoteHeads(peerId: PeerId): A.Heads | undefined;
|
|
76
82
|
/** `change` is called by the repo when the document is changed locally */
|
|
77
83
|
change(callback: A.ChangeFn<T>, options?: A.ChangeOptions<T>): void;
|
|
78
84
|
/** Make a change as if the document were at `heads`
|
|
@@ -149,6 +155,14 @@ export interface DocHandleOutboundEphemeralMessagePayload<T> {
|
|
|
149
155
|
handle: DocHandle<T>;
|
|
150
156
|
data: Uint8Array;
|
|
151
157
|
}
|
|
158
|
+
export interface DocHandleRemoteHeadsPayload {
|
|
159
|
+
peerId: PeerId;
|
|
160
|
+
heads: A.Heads;
|
|
161
|
+
}
|
|
162
|
+
export interface DocHandleSyncStatePayload {
|
|
163
|
+
peerId: PeerId;
|
|
164
|
+
syncState: A.SyncState;
|
|
165
|
+
}
|
|
152
166
|
export interface DocHandleEvents<T> {
|
|
153
167
|
"heads-changed": (payload: DocHandleEncodedChangePayload<T>) => void;
|
|
154
168
|
change: (payload: DocHandleChangePayload<T>) => void;
|
|
@@ -156,6 +170,7 @@ export interface DocHandleEvents<T> {
|
|
|
156
170
|
unavailable: (payload: DocHandleDeletePayload<T>) => void;
|
|
157
171
|
"ephemeral-message": (payload: DocHandleEphemeralMessagePayload<T>) => void;
|
|
158
172
|
"ephemeral-message-outbound": (payload: DocHandleOutboundEphemeralMessagePayload<T>) => void;
|
|
173
|
+
"remote-heads": (payload: DocHandleRemoteHeadsPayload) => void;
|
|
159
174
|
}
|
|
160
175
|
/**
|
|
161
176
|
* The state of a document handle
|
|
@@ -173,8 +188,6 @@ export declare const HandleState: {
|
|
|
173
188
|
readonly REQUESTING: "requesting";
|
|
174
189
|
/** The document is available */
|
|
175
190
|
readonly READY: "ready";
|
|
176
|
-
/** We were unable to load or request the document for some reason */
|
|
177
|
-
readonly FAILED: "failed";
|
|
178
191
|
/** The document has been deleted from the repo */
|
|
179
192
|
readonly DELETED: "deleted";
|
|
180
193
|
/** The document was not available in storage or from any connected peers */
|
|
@@ -193,5 +206,5 @@ export declare const Event: {
|
|
|
193
206
|
readonly DELETE: "DELETE";
|
|
194
207
|
readonly MARK_UNAVAILABLE: "MARK_UNAVAILABLE";
|
|
195
208
|
};
|
|
196
|
-
export declare const IDLE: "idle", LOADING: "loading", AWAITING_NETWORK: "awaitingNetwork", REQUESTING: "requesting", READY: "ready",
|
|
209
|
+
export declare const IDLE: "idle", LOADING: "loading", AWAITING_NETWORK: "awaitingNetwork", REQUESTING: "requesting", READY: "ready", DELETED: "deleted", UNAVAILABLE: "unavailable";
|
|
197
210
|
//# sourceMappingURL=DocHandle.d.ts.map
|
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;AAElE;;;;;;;;;;;KAWK;AACL,qBAAa,SAAS,CAAC,CAAC,CAAE,EAAE;AAC1B,SAAQ,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;;
|
|
1
|
+
{"version":3,"file":"DocHandle.d.ts","sourceRoot":"","sources":["../src/DocHandle.ts"],"names":[],"mappings":"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"}
|
package/dist/DocHandle.js
CHANGED
|
@@ -25,6 +25,7 @@ export class DocHandle//
|
|
|
25
25
|
#log;
|
|
26
26
|
#machine;
|
|
27
27
|
#timeoutDelay;
|
|
28
|
+
#remoteHeads = {};
|
|
28
29
|
/** The URL of this document
|
|
29
30
|
*
|
|
30
31
|
* @remarks
|
|
@@ -49,9 +50,9 @@ export class DocHandle//
|
|
|
49
50
|
* Internally we use a state machine to orchestrate document loading and/or syncing, in order to
|
|
50
51
|
* avoid requesting data we already have, or surfacing intermediate values to the consumer.
|
|
51
52
|
*
|
|
52
|
-
* ┌─────────────────────┬─────────TIMEOUT
|
|
53
|
-
* ┌───┴─────┐ ┌───┴────────┐ │
|
|
54
|
-
* ┌───────┐ ┌──FIND──┤ loading ├─REQUEST──►│ requesting ├─UPDATE──┐
|
|
53
|
+
* ┌─────────────────────┬─────────TIMEOUT────►┌─────────────┐
|
|
54
|
+
* ┌───┴─────┐ ┌───┴────────┐ │ unavailable │
|
|
55
|
+
* ┌───────┐ ┌──FIND──┤ loading ├─REQUEST──►│ requesting ├─UPDATE──┐ └─────────────┘
|
|
55
56
|
* │ idle ├──┤ └───┬─────┘ └────────────┘ │
|
|
56
57
|
* └───────┘ │ │ └─►┌────────┐
|
|
57
58
|
* │ └───────LOAD───────────────────────────────►│ ready │
|
|
@@ -86,7 +87,7 @@ export class DocHandle//
|
|
|
86
87
|
after: [
|
|
87
88
|
{
|
|
88
89
|
delay: this.#timeoutDelay,
|
|
89
|
-
target:
|
|
90
|
+
target: UNAVAILABLE,
|
|
90
91
|
},
|
|
91
92
|
],
|
|
92
93
|
},
|
|
@@ -110,7 +111,7 @@ export class DocHandle//
|
|
|
110
111
|
after: [
|
|
111
112
|
{
|
|
112
113
|
delay: this.#timeoutDelay,
|
|
113
|
-
target:
|
|
114
|
+
target: UNAVAILABLE,
|
|
114
115
|
},
|
|
115
116
|
],
|
|
116
117
|
},
|
|
@@ -121,9 +122,6 @@ export class DocHandle//
|
|
|
121
122
|
DELETE: { actions: "onDelete", target: DELETED },
|
|
122
123
|
},
|
|
123
124
|
},
|
|
124
|
-
failed: {
|
|
125
|
-
type: "final",
|
|
126
|
-
},
|
|
127
125
|
deleted: {
|
|
128
126
|
type: "final",
|
|
129
127
|
},
|
|
@@ -197,7 +195,7 @@ export class DocHandle//
|
|
|
197
195
|
if (!Array.isArray(awaitStates))
|
|
198
196
|
awaitStates = [awaitStates];
|
|
199
197
|
return Promise.any(awaitStates.map(state => waitFor(this.#machine, s => s.matches(state), {
|
|
200
|
-
timeout: this.#timeoutDelay *
|
|
198
|
+
timeout: this.#timeoutDelay * 2, // use a longer delay here so as not to race with other delays
|
|
201
199
|
})));
|
|
202
200
|
}
|
|
203
201
|
// PUBLIC
|
|
@@ -242,7 +240,7 @@ export class DocHandle//
|
|
|
242
240
|
await this.#statePromise(awaitStates);
|
|
243
241
|
}
|
|
244
242
|
catch (error) {
|
|
245
|
-
// if we timed out (or the
|
|
243
|
+
// if we timed out (or have determined the document is currently unavailable), return undefined
|
|
246
244
|
return undefined;
|
|
247
245
|
}
|
|
248
246
|
// Return the document
|
|
@@ -272,6 +270,17 @@ export class DocHandle//
|
|
|
272
270
|
payload: { callback },
|
|
273
271
|
});
|
|
274
272
|
}
|
|
273
|
+
/** `setRemoteHeads` is called by the doc synchronizer
|
|
274
|
+
* @hidden
|
|
275
|
+
*/
|
|
276
|
+
setRemoteHeads(peerId, heads) {
|
|
277
|
+
this.#remoteHeads[peerId] = heads;
|
|
278
|
+
this.emit("remote-heads", { peerId, heads });
|
|
279
|
+
}
|
|
280
|
+
/** Returns the heads of the peer */
|
|
281
|
+
getRemoteHeads(peerId) {
|
|
282
|
+
return this.#remoteHeads[peerId];
|
|
283
|
+
}
|
|
275
284
|
/** `change` is called by the repo when the document is changed locally */
|
|
276
285
|
change(callback, options = {}) {
|
|
277
286
|
if (!this.isReady()) {
|
|
@@ -384,8 +393,6 @@ export const HandleState = {
|
|
|
384
393
|
REQUESTING: "requesting",
|
|
385
394
|
/** The document is available */
|
|
386
395
|
READY: "ready",
|
|
387
|
-
/** We were unable to load or request the document for some reason */
|
|
388
|
-
FAILED: "failed",
|
|
389
396
|
/** The document has been deleted from the repo */
|
|
390
397
|
DELETED: "deleted",
|
|
391
398
|
/** The document was not available in storage or from any connected peers */
|
|
@@ -405,5 +412,5 @@ export const Event = {
|
|
|
405
412
|
MARK_UNAVAILABLE: "MARK_UNAVAILABLE",
|
|
406
413
|
};
|
|
407
414
|
// CONSTANTS
|
|
408
|
-
export const { IDLE, LOADING, AWAITING_NETWORK, REQUESTING, READY,
|
|
415
|
+
export const { IDLE, LOADING, AWAITING_NETWORK, REQUESTING, READY, DELETED, UNAVAILABLE, } = HandleState;
|
|
409
416
|
const { CREATE, FIND, REQUEST, UPDATE, TIMEOUT, DELETE, REQUEST_COMPLETE, MARK_UNAVAILABLE, AWAIT_NETWORK, NETWORK_READY, } = Event;
|
package/dist/Repo.d.ts
CHANGED
|
@@ -28,6 +28,8 @@ export declare class Repo extends EventEmitter<RepoEvents> {
|
|
|
28
28
|
constructor({ storage, network, peerId, sharePolicy }: RepoConfig);
|
|
29
29
|
/** Returns all the handles we have cached. */
|
|
30
30
|
get handles(): Record<DocumentId, DocHandle<any>>;
|
|
31
|
+
/** Returns a list of all connected peer ids */
|
|
32
|
+
get peers(): PeerId[];
|
|
31
33
|
/**
|
|
32
34
|
* Creates a new document and returns a handle to it. The initial value of the document is
|
|
33
35
|
* an empty object `{}`. Its documentId is generated by the system. we emit a `document` event
|
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;AAEzE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAEhE,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;
|
|
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;AAEzE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAEhE,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAGnE,8FAA8F;AAC9F;;;;;;GAMG;AACH,qBAAa,IAAK,SAAQ,YAAY,CAAC,UAAU,CAAC;;IAGhD,cAAc;IACd,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,cAAc;IACd,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IAEnC,mDAAmD;IACnD,cAAc;IACd,gBAAgB,SAAM;IAMtB,sDAAsD;IACtD,cAAc;IACd,WAAW,EAAE,WAAW,CAAmB;gBAE/B,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,UAAU;IAuIjE,8CAA8C;IAC9C,IAAI,OAAO,uCAEV;IAED,+CAA+C;IAC/C,IAAI,KAAK,IAAI,MAAM,EAAE,CAEpB;IAED;;;;OAIG;IACH,MAAM,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC;IA0BzB;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;IAuBnC;;;OAGG;IACH,IAAI,CAAC,CAAC;IACJ,sDAAsD;IACtD,EAAE,EAAE,aAAa,GAChB,SAAS,CAAC,CAAC,CAAC;IAqBf,MAAM;IACJ,oDAAoD;IACpD,EAAE,EAAE,aAAa;CAUpB;AAED,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf,gDAAgD;IAChD,OAAO,CAAC,EAAE,cAAc,CAAA;IAExB,oDAAoD;IACpD,OAAO,EAAE,cAAc,EAAE,CAAA;IAEzB;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B;AAED;;;;;;;KAOK;AACL,MAAM,MAAM,WAAW,GAAG,CACxB,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,UAAU,KACpB,OAAO,CAAC,OAAO,CAAC,CAAA;AAGrB,MAAM,WAAW,UAAU;IACzB,+CAA+C;IAC/C,QAAQ,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,CAAA;IACxC,6BAA6B;IAC7B,iBAAiB,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,IAAI,CAAA;IACvD,4FAA4F;IAC5F,sBAAsB,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,IAAI,CAAA;CAC7D;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;IACtB,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,UAAU,CAAA;CACvB"}
|
package/dist/Repo.js
CHANGED
|
@@ -25,6 +25,7 @@ export class Repo extends EventEmitter {
|
|
|
25
25
|
/** @hidden */
|
|
26
26
|
saveDebounceRate = 100;
|
|
27
27
|
#handleCache = {};
|
|
28
|
+
#synchronizer;
|
|
28
29
|
/** By default, we share generously with all peers. */
|
|
29
30
|
/** @hidden */
|
|
30
31
|
sharePolicy = async () => true;
|
|
@@ -75,7 +76,7 @@ export class Repo extends EventEmitter {
|
|
|
75
76
|
});
|
|
76
77
|
}
|
|
77
78
|
// Register the document with the synchronizer. This advertises our interest in the document.
|
|
78
|
-
synchronizer.addDocument(handle.documentId);
|
|
79
|
+
this.#synchronizer.addDocument(handle.documentId);
|
|
79
80
|
});
|
|
80
81
|
this.on("delete-document", ({ documentId }) => {
|
|
81
82
|
// TODO Pass the delete on to the network
|
|
@@ -88,9 +89,9 @@ export class Repo extends EventEmitter {
|
|
|
88
89
|
});
|
|
89
90
|
// SYNCHRONIZER
|
|
90
91
|
// The synchronizer uses the network subsystem to keep documents in sync with peers.
|
|
91
|
-
|
|
92
|
+
this.#synchronizer = new CollectionSynchronizer(this);
|
|
92
93
|
// When the synchronizer emits messages, send them to peers
|
|
93
|
-
synchronizer.on("message", message => {
|
|
94
|
+
this.#synchronizer.on("message", message => {
|
|
94
95
|
this.#log(`sending ${message.type} message to ${message.targetId}`);
|
|
95
96
|
networkSubsystem.send(message);
|
|
96
97
|
});
|
|
@@ -105,16 +106,22 @@ export class Repo extends EventEmitter {
|
|
|
105
106
|
// When we get a new peer, register it with the synchronizer
|
|
106
107
|
networkSubsystem.on("peer", async ({ peerId }) => {
|
|
107
108
|
this.#log("peer connected", { peerId });
|
|
108
|
-
synchronizer.addPeer(peerId);
|
|
109
|
+
this.#synchronizer.addPeer(peerId);
|
|
109
110
|
});
|
|
110
111
|
// When a peer disconnects, remove it from the synchronizer
|
|
111
112
|
networkSubsystem.on("peer-disconnected", ({ peerId }) => {
|
|
112
|
-
synchronizer.removePeer(peerId);
|
|
113
|
+
this.#synchronizer.removePeer(peerId);
|
|
113
114
|
});
|
|
114
115
|
// Handle incoming messages
|
|
115
116
|
networkSubsystem.on("message", async (msg) => {
|
|
116
|
-
await synchronizer.receiveMessage(msg);
|
|
117
|
+
await this.#synchronizer.receiveMessage(msg);
|
|
117
118
|
});
|
|
119
|
+
if (storageSubsystem) {
|
|
120
|
+
const debouncedSaveSyncState = throttle(({ documentId, peerId, syncState }) => {
|
|
121
|
+
storageSubsystem.saveSyncState(documentId, peerId, syncState);
|
|
122
|
+
}, this.saveDebounceRate);
|
|
123
|
+
this.#synchronizer.on("sync-state", debouncedSaveSyncState);
|
|
124
|
+
}
|
|
118
125
|
}
|
|
119
126
|
/** Returns an existing handle if we have it; creates one otherwise. */
|
|
120
127
|
#getHandle(
|
|
@@ -136,6 +143,10 @@ export class Repo extends EventEmitter {
|
|
|
136
143
|
get handles() {
|
|
137
144
|
return this.#handleCache;
|
|
138
145
|
}
|
|
146
|
+
/** Returns a list of all connected peer ids */
|
|
147
|
+
get peers() {
|
|
148
|
+
return this.#synchronizer.peers;
|
|
149
|
+
}
|
|
139
150
|
/**
|
|
140
151
|
* Creates a new document and returns a handle to it. The initial value of the document is
|
|
141
152
|
* an empty object `{}`. Its documentId is generated by the system. we emit a `document` event
|
package/dist/index.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export { isValidRepoMessage } from "./network/messages.js";
|
|
|
33
33
|
export { StorageAdapter } from "./storage/StorageAdapter.js";
|
|
34
34
|
/** @hidden **/
|
|
35
35
|
export * as cbor from "./helpers/cbor.js";
|
|
36
|
-
export type { DocHandleChangePayload, DocHandleDeletePayload, DocHandleEncodedChangePayload, DocHandleEphemeralMessagePayload, DocHandleEvents, DocHandleOptions, DocHandleOutboundEphemeralMessagePayload, HandleState, } from "./DocHandle.js";
|
|
36
|
+
export type { DocHandleChangePayload, DocHandleDeletePayload, DocHandleEncodedChangePayload, DocHandleEphemeralMessagePayload, DocHandleRemoteHeadsPayload, DocHandleEvents, DocHandleOptions, DocHandleOutboundEphemeralMessagePayload, HandleState, } from "./DocHandle.js";
|
|
37
37
|
export type { DeleteDocumentPayload, DocumentPayload, RepoConfig, RepoEvents, SharePolicy, } from "./Repo.js";
|
|
38
38
|
export type { NetworkAdapterEvents, OpenPayload, PeerCandidatePayload, PeerDisconnectedPayload, } from "./network/NetworkAdapter.js";
|
|
39
39
|
export type { DocumentUnavailableMessage, EphemeralMessage, Message, RepoMessage, RequestMessage, SyncMessage, } from "./network/messages.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,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC1D,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,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,GACxB,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,GACX,MAAM,oBAAoB,CAAA;AAE3B,cAAc,YAAY,CAAA"}
|
|
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,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC1D,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,GACxB,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,GACX,MAAM,oBAAoB,CAAA;AAE3B,cAAc,YAAY,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SyncState } from "@automerge/automerge";
|
|
1
2
|
import { DocumentId, PeerId, SessionId } from "../types.js";
|
|
2
3
|
/**
|
|
3
4
|
* A sync message for a particular document
|
|
@@ -83,6 +84,12 @@ export type Message = RepoMessage | AuthMessage;
|
|
|
83
84
|
* The contents of a message, without the sender ID or other properties added by the {@link NetworkSubsystem})
|
|
84
85
|
*/
|
|
85
86
|
export type MessageContents<T extends Message = Message> = T extends EphemeralMessage ? Omit<T, "senderId" | "count" | "sessionId"> : Omit<T, "senderId">;
|
|
87
|
+
/** Notify the repo that the sync state has changed */
|
|
88
|
+
export interface SyncStateMessage {
|
|
89
|
+
peerId: PeerId;
|
|
90
|
+
documentId: DocumentId;
|
|
91
|
+
syncState: SyncState;
|
|
92
|
+
}
|
|
86
93
|
export declare const isValidRepoMessage: (message: Message) => message is RepoMessage;
|
|
87
94
|
export declare const isDocumentUnavailableMessage: (msg: Message) => msg is DocumentUnavailableMessage;
|
|
88
95
|
export declare const isRequestMessage: (msg: Message) => msg is RequestMessage;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/network/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE3D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAA;IAEZ,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAA;IAEhB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAA;IAEhB,iCAAiC;IACjC,IAAI,EAAE,UAAU,CAAA;IAEhB,0DAA0D;IAC1D,UAAU,EAAE,UAAU,CAAA;CACvB,CAAA;AAED;;;;;;;;;KASK;AACL,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,WAAW,CAAA;IAEjB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAA;IAEhB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAA;IAEhB,qFAAqF;IACrF,KAAK,EAAE,MAAM,CAAA;IAEb,8GAA8G;IAC9G,SAAS,EAAE,SAAS,CAAA;IAEpB,+CAA+C;IAC/C,UAAU,EAAE,UAAU,CAAA;IAEtB,qCAAqC;IACrC,IAAI,EAAE,UAAU,CAAA;CACjB,CAAA;AAED,uHAAuH;AACvH,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,iBAAiB,CAAA;IAEvB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAA;IAEhB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAA;IAEhB,yDAAyD;IACzD,UAAU,EAAE,UAAU,CAAA;CACvB,CAAA;AAED;;;;;KAKK;AACL,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,SAAS,CAAA;IAEf,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAA;IAEhB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAA;IAEhB,yCAAyC;IACzC,IAAI,EAAE,UAAU,CAAA;IAEhB,4CAA4C;IAC5C,UAAU,EAAE,UAAU,CAAA;CACvB,CAAA;AAED,sCAAsC;AACtC,MAAM,MAAM,WAAW,CAAC,QAAQ,GAAG,GAAG,IAAI;IACxC,IAAI,EAAE,MAAM,CAAA;IAEZ,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAA;IAEhB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAA;IAEhB,yEAAyE;IACzE,OAAO,EAAE,QAAQ,CAAA;CAClB,CAAA;AAED,wFAAwF;AACxF,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,gBAAgB,GAChB,cAAc,GACd,0BAA0B,CAAA;AAE9B,+EAA+E;AAC/E,MAAM,MAAM,OAAO,GAAG,WAAW,GAAG,WAAW,CAAA;AAE/C;;GAEG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,IACrD,CAAC,SAAS,gBAAgB,GACtB,IAAI,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,WAAW,CAAC,GAC3C,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/network/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE3D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAA;IAEZ,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAA;IAEhB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAA;IAEhB,iCAAiC;IACjC,IAAI,EAAE,UAAU,CAAA;IAEhB,0DAA0D;IAC1D,UAAU,EAAE,UAAU,CAAA;CACvB,CAAA;AAED;;;;;;;;;KASK;AACL,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,WAAW,CAAA;IAEjB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAA;IAEhB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAA;IAEhB,qFAAqF;IACrF,KAAK,EAAE,MAAM,CAAA;IAEb,8GAA8G;IAC9G,SAAS,EAAE,SAAS,CAAA;IAEpB,+CAA+C;IAC/C,UAAU,EAAE,UAAU,CAAA;IAEtB,qCAAqC;IACrC,IAAI,EAAE,UAAU,CAAA;CACjB,CAAA;AAED,uHAAuH;AACvH,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,iBAAiB,CAAA;IAEvB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAA;IAEhB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAA;IAEhB,yDAAyD;IACzD,UAAU,EAAE,UAAU,CAAA;CACvB,CAAA;AAED;;;;;KAKK;AACL,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,SAAS,CAAA;IAEf,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAA;IAEhB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAA;IAEhB,yCAAyC;IACzC,IAAI,EAAE,UAAU,CAAA;IAEhB,4CAA4C;IAC5C,UAAU,EAAE,UAAU,CAAA;CACvB,CAAA;AAED,sCAAsC;AACtC,MAAM,MAAM,WAAW,CAAC,QAAQ,GAAG,GAAG,IAAI;IACxC,IAAI,EAAE,MAAM,CAAA;IAEZ,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAA;IAEhB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAA;IAEhB,yEAAyE;IACzE,OAAO,EAAE,QAAQ,CAAA;CAClB,CAAA;AAED,wFAAwF;AACxF,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,gBAAgB,GAChB,cAAc,GACd,0BAA0B,CAAA;AAE9B,+EAA+E;AAC/E,MAAM,MAAM,OAAO,GAAG,WAAW,GAAG,WAAW,CAAA;AAE/C;;GAEG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,IACrD,CAAC,SAAS,gBAAgB,GACtB,IAAI,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,WAAW,CAAC,GAC3C,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;AAEzB,uDAAuD;AACvD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,UAAU,CAAA;IACtB,SAAS,EAAE,SAAS,CAAA;CACrB;AAID,eAAO,MAAM,kBAAkB,YAAa,OAAO,2BAOT,CAAA;AAG1C,eAAO,MAAM,4BAA4B,QAAS,OAAO,sCACzB,CAAA;AAEhC,eAAO,MAAM,gBAAgB,QAAS,OAAO,0BACrB,CAAA;AAExB,eAAO,MAAM,aAAa,QAAS,OAAO,uBACrB,CAAA;AAErB,eAAO,MAAM,kBAAkB,QAAS,OAAO,4BACrB,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as A from "@automerge/automerge/next";
|
|
2
|
-
import { type DocumentId } from "../types.js";
|
|
2
|
+
import { PeerId, type DocumentId } from "../types.js";
|
|
3
3
|
import { StorageAdapter } from "./StorageAdapter.js";
|
|
4
4
|
/**
|
|
5
5
|
* The storage subsystem is responsible for saving and loading Automerge documents to and from
|
|
@@ -44,5 +44,7 @@ export declare class StorageSubsystem {
|
|
|
44
44
|
* Removes the Automerge document with the given ID from storage
|
|
45
45
|
*/
|
|
46
46
|
removeDoc(documentId: DocumentId): Promise<void>;
|
|
47
|
+
loadSyncState(documentId: DocumentId, peerId: PeerId): Promise<A.SyncState | undefined>;
|
|
48
|
+
saveSyncState(documentId: DocumentId, peerId: PeerId, syncState: A.SyncState): Promise<void>;
|
|
47
49
|
}
|
|
48
50
|
//# sourceMappingURL=StorageSubsystem.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageSubsystem.d.ts","sourceRoot":"","sources":["../../src/storage/StorageSubsystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,2BAA2B,CAAA;AAI9C,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"StorageSubsystem.d.ts","sourceRoot":"","sources":["../../src/storage/StorageSubsystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,2BAA2B,CAAA;AAI9C,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAKpD;;;GAGG;AACH,qBAAa,gBAAgB;;gBAef,cAAc,EAAE,cAAc;IAc1C,kCAAkC;IAC5B,IAAI;IACR,iFAAiF;IACjF,SAAS,EAAE,MAAM;IAEjB,yFAAyF;IACzF,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAKlC,gCAAgC;IAC1B,IAAI;IACR,iFAAiF;IACjF,SAAS,EAAE,MAAM;IAEjB,yFAAyF;IACzF,GAAG,EAAE,MAAM;IAEX,sCAAsC;IACtC,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC;IAKhB,oCAAoC;IAC9B,MAAM;IACV,iFAAiF;IACjF,SAAS,EAAE,MAAM;IAEjB,2FAA2F;IAC3F,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,IAAI,CAAC;IAOhB;;OAEG;IACG,OAAO,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAmClE;;;;;;OAMG;IACG,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAazE;;OAEG;IACG,SAAS,CAAC,UAAU,EAAE,UAAU;IAkEhC,aAAa,CACjB,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC;IAM7B,aAAa,CACjB,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,CAAC,CAAC,SAAS,GACrB,OAAO,CAAC,IAAI,CAAC;CAyCjB"}
|
|
@@ -118,6 +118,7 @@ export class StorageSubsystem {
|
|
|
118
118
|
async removeDoc(documentId) {
|
|
119
119
|
await this.#storageAdapter.removeRange([documentId, "snapshot"]);
|
|
120
120
|
await this.#storageAdapter.removeRange([documentId, "incremental"]);
|
|
121
|
+
await this.#storageAdapter.removeRange([documentId, "sync-state"]);
|
|
121
122
|
}
|
|
122
123
|
/**
|
|
123
124
|
* Saves just the incremental changes since the last save.
|
|
@@ -162,6 +163,15 @@ export class StorageSubsystem {
|
|
|
162
163
|
this.#chunkInfos.set(documentId, newChunkInfos);
|
|
163
164
|
this.#compacting = false;
|
|
164
165
|
}
|
|
166
|
+
async loadSyncState(documentId, peerId) {
|
|
167
|
+
const key = [documentId, "sync-state", peerId];
|
|
168
|
+
const loaded = await this.#storageAdapter.load(key);
|
|
169
|
+
return loaded ? A.decodeSyncState(loaded) : undefined;
|
|
170
|
+
}
|
|
171
|
+
async saveSyncState(documentId, peerId, syncState) {
|
|
172
|
+
const key = [documentId, "sync-state", peerId];
|
|
173
|
+
await this.#storageAdapter.save(key, A.encodeSyncState(syncState));
|
|
174
|
+
}
|
|
165
175
|
/**
|
|
166
176
|
* Returns true if the document has changed since the last time it was saved.
|
|
167
177
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunkTypeFromKey.d.ts","sourceRoot":"","sources":["../../src/storage/chunkTypeFromKey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"chunkTypeFromKey.d.ts","sourceRoot":"","sources":["../../src/storage/chunkTypeFromKey.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEvD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,SAAS,GAAG,IAAI,CASlE"}
|
|
@@ -21,5 +21,7 @@ export declare class CollectionSynchronizer extends Synchronizer {
|
|
|
21
21
|
addPeer(peerId: PeerId): void;
|
|
22
22
|
/** Removes a peer and stops synchronizing with them */
|
|
23
23
|
removePeer(peerId: PeerId): void;
|
|
24
|
+
/** Returns a list of all connected peer ids */
|
|
25
|
+
get peers(): PeerId[];
|
|
24
26
|
}
|
|
25
27
|
//# sourceMappingURL=CollectionSynchronizer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CollectionSynchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/CollectionSynchronizer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAIhD,4FAA4F;AAC5F,qBAAa,sBAAuB,SAAQ,YAAY;;IAU1C,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"CollectionSynchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/CollectionSynchronizer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAIhD,4FAA4F;AAC5F,qBAAa,sBAAuB,SAAQ,YAAY;;IAU1C,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE,IAAI;IA8C9B;;;OAGG;IACG,cAAc,CAAC,OAAO,EAAE,WAAW;IAyBzC;;OAEG;IACH,WAAW,CAAC,UAAU,EAAE,UAAU;IAYlC,cAAc,CAAC,UAAU,EAAE,UAAU;IAIrC,2DAA2D;IAC3D,OAAO,CAAC,MAAM,EAAE,MAAM;IAgBtB,uDAAuD;IACvD,UAAU,CAAC,MAAM,EAAE,MAAM;IASzB,+CAA+C;IAC/C,IAAI,KAAK,IAAI,MAAM,EAAE,CAEpB;CACF"}
|
|
@@ -26,8 +26,17 @@ export class CollectionSynchronizer extends Synchronizer {
|
|
|
26
26
|
}
|
|
27
27
|
/** Creates a new docSynchronizer and sets it up to propagate messages */
|
|
28
28
|
#initDocSynchronizer(handle) {
|
|
29
|
-
const docSynchronizer = new DocSynchronizer(
|
|
29
|
+
const docSynchronizer = new DocSynchronizer({
|
|
30
|
+
handle,
|
|
31
|
+
onLoadSyncState: peerId => {
|
|
32
|
+
if (!this.repo.storageSubsystem) {
|
|
33
|
+
return Promise.resolve(undefined);
|
|
34
|
+
}
|
|
35
|
+
return this.repo.storageSubsystem.loadSyncState(handle.documentId, peerId);
|
|
36
|
+
},
|
|
37
|
+
});
|
|
30
38
|
docSynchronizer.on("message", event => this.emit("message", event));
|
|
39
|
+
docSynchronizer.on("sync-state", event => this.emit("sync-state", event));
|
|
31
40
|
return docSynchronizer;
|
|
32
41
|
}
|
|
33
42
|
/** returns an array of peerIds that we share this document generously with */
|
|
@@ -99,4 +108,8 @@ export class CollectionSynchronizer extends Synchronizer {
|
|
|
99
108
|
docSynchronizer.endSync(peerId);
|
|
100
109
|
}
|
|
101
110
|
}
|
|
111
|
+
/** Returns a list of all connected peer ids */
|
|
112
|
+
get peers() {
|
|
113
|
+
return Array.from(this.#peers);
|
|
114
|
+
}
|
|
102
115
|
}
|
|
@@ -1,17 +1,21 @@
|
|
|
1
|
+
import * as A from "@automerge/automerge/next";
|
|
1
2
|
import { DocHandle } from "../DocHandle.js";
|
|
2
3
|
import { EphemeralMessage, RepoMessage, RequestMessage, SyncMessage } from "../network/messages.js";
|
|
3
4
|
import { PeerId } from "../types.js";
|
|
4
5
|
import { Synchronizer } from "./Synchronizer.js";
|
|
5
6
|
type PeerDocumentStatus = "unknown" | "has" | "unavailable" | "wants";
|
|
7
|
+
interface DocSynchronizerConfig {
|
|
8
|
+
handle: DocHandle<unknown>;
|
|
9
|
+
onLoadSyncState?: (peerId: PeerId) => A.SyncState | undefined;
|
|
10
|
+
}
|
|
6
11
|
/**
|
|
7
12
|
* DocSynchronizer takes a handle to an Automerge document, and receives & dispatches sync messages
|
|
8
13
|
* to bring it inline with all other peers' versions.
|
|
9
14
|
*/
|
|
10
15
|
export declare class DocSynchronizer extends Synchronizer {
|
|
11
16
|
#private;
|
|
12
|
-
private handle;
|
|
13
17
|
syncDebounceRate: number;
|
|
14
|
-
constructor(handle:
|
|
18
|
+
constructor({ handle, onLoadSyncState }: DocSynchronizerConfig);
|
|
15
19
|
get peerStates(): Record<PeerId, PeerDocumentStatus>;
|
|
16
20
|
get documentId(): import("../types.js").DocumentId;
|
|
17
21
|
hasPeer(peerId: PeerId): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocSynchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/DocSynchronizer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DocSynchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/DocSynchronizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,2BAA2B,CAAA;AAG9C,OAAO,EACL,SAAS,EAKV,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAEL,gBAAgB,EAEhB,WAAW,EACX,cAAc,EACd,WAAW,EAEZ,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAIhD,KAAK,kBAAkB,GAAG,SAAS,GAAG,KAAK,GAAG,aAAa,GAAG,OAAO,CAAA;AAOrE,UAAU,qBAAqB;IAC7B,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;IAC1B,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,CAAC,CAAC,SAAS,GAAG,SAAS,CAAA;CAC9D;AAED;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,YAAY;;IAE/C,gBAAgB,SAAM;gBAsBV,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,qBAAqB;IAyB9D,IAAI,UAAU,uCAEb;IAED,IAAI,UAAU,qCAEb;IAqID,OAAO,CAAC,MAAM,EAAE,MAAM;IAItB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE;IA+C3B,OAAO,CAAC,MAAM,EAAE,MAAM;IAKtB,cAAc,CAAC,OAAO,EAAE,WAAW;IAkBnC,uBAAuB,CAAC,OAAO,EAAE,gBAAgB;IAuBjD,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc;CA8EzD"}
|