@automerge/automerge-repo 1.1.0-alpha.7 → 1.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 +5 -3
- 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 +21 -13
- package/dist/Repo.d.ts +22 -10
- package/dist/Repo.d.ts.map +1 -1
- package/dist/Repo.js +90 -76
- 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/tests/network-adapter-tests.d.ts +2 -2
- package/dist/helpers/tests/network-adapter-tests.d.ts.map +1 -1
- package/dist/helpers/tests/network-adapter-tests.js +16 -1
- package/dist/helpers/withTimeout.d.ts.map +1 -1
- package/dist/helpers/withTimeout.js +2 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/network/NetworkAdapter.d.ts +4 -34
- package/dist/network/NetworkAdapter.d.ts.map +1 -1
- package/dist/network/NetworkAdapter.js +2 -0
- package/dist/network/NetworkAdapterInterface.d.ts +61 -0
- package/dist/network/NetworkAdapterInterface.d.ts.map +1 -0
- package/dist/network/NetworkAdapterInterface.js +2 -0
- package/dist/network/NetworkSubsystem.d.ts +3 -3
- package/dist/network/NetworkSubsystem.d.ts.map +1 -1
- package/dist/network/NetworkSubsystem.js +7 -5
- 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/storage/StorageAdapter.d.ts +3 -1
- package/dist/storage/StorageAdapter.d.ts.map +1 -1
- package/dist/storage/StorageAdapter.js +1 -0
- package/dist/storage/StorageAdapterInterface.d.ts +30 -0
- package/dist/storage/StorageAdapterInterface.d.ts.map +1 -0
- package/dist/storage/StorageAdapterInterface.js +1 -0
- package/dist/storage/StorageSubsystem.d.ts +2 -2
- package/dist/storage/StorageSubsystem.d.ts.map +1 -1
- 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 +13 -9
- 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 +40 -19
- package/src/Repo.ts +123 -98
- package/src/helpers/pause.ts +3 -11
- package/src/helpers/tests/network-adapter-tests.ts +30 -4
- package/src/helpers/withTimeout.ts +2 -0
- package/src/index.ts +4 -2
- package/src/network/NetworkAdapter.ts +9 -45
- package/src/network/NetworkAdapterInterface.ts +77 -0
- package/src/network/NetworkSubsystem.ts +16 -14
- package/src/network/messages.ts +60 -63
- package/src/storage/StorageAdapter.ts +3 -1
- package/src/storage/StorageAdapterInterface.ts +34 -0
- package/src/storage/StorageSubsystem.ts +3 -3
- package/src/synchronizer/CollectionSynchronizer.ts +1 -0
- package/src/synchronizer/DocSynchronizer.ts +22 -18
- package/src/synchronizer/Synchronizer.ts +11 -3
- package/test/CollectionSynchronizer.test.ts +7 -5
- package/test/DocHandle.test.ts +35 -3
- package/test/RemoteHeadsSubscriptions.test.ts +49 -49
- package/test/Repo.test.ts +71 -2
- package/test/StorageSubsystem.test.ts +1 -1
- package/test/helpers/DummyNetworkAdapter.ts +37 -5
- 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/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,25 +1,17 @@
|
|
|
1
1
|
import { EventEmitter } from "eventemitter3";
|
|
2
|
+
import { NetworkAdapterEvents, PeerMetadata } from "../index.js";
|
|
2
3
|
import { PeerId } from "../types.js";
|
|
3
4
|
import { Message } from "./messages.js";
|
|
4
|
-
import {
|
|
5
|
-
/**
|
|
6
|
-
* Describes a peer intent to the system
|
|
7
|
-
* storageId: the key for syncState to decide what the other peer already has
|
|
8
|
-
* isEphemeral: to decide if we bother recording this peer's sync state
|
|
9
|
-
*
|
|
10
|
-
*/
|
|
11
|
-
export interface PeerMetadata {
|
|
12
|
-
storageId?: StorageId;
|
|
13
|
-
isEphemeral?: boolean;
|
|
14
|
-
}
|
|
5
|
+
import { NetworkAdapterInterface } from "./NetworkAdapterInterface.js";
|
|
15
6
|
/** An interface representing some way to connect to other peers
|
|
7
|
+
* @deprecated use {@link NetworkAdapterInterface}
|
|
16
8
|
*
|
|
17
9
|
* @remarks
|
|
18
10
|
* The {@link Repo} uses one or more `NetworkAdapter`s to connect to other peers.
|
|
19
11
|
* Because the network may take some time to be ready the {@link Repo} will wait
|
|
20
12
|
* until the adapter emits a `ready` event before it starts trying to use it
|
|
21
13
|
*/
|
|
22
|
-
export declare abstract class NetworkAdapter extends EventEmitter<NetworkAdapterEvents> {
|
|
14
|
+
export declare abstract class NetworkAdapter extends EventEmitter<NetworkAdapterEvents> implements NetworkAdapterInterface {
|
|
23
15
|
peerId?: PeerId;
|
|
24
16
|
peerMetadata?: PeerMetadata;
|
|
25
17
|
/** Called by the {@link Repo} to start the connection process
|
|
@@ -36,26 +28,4 @@ export declare abstract class NetworkAdapter extends EventEmitter<NetworkAdapter
|
|
|
36
28
|
/** Called by the {@link Repo} to disconnect from the network */
|
|
37
29
|
abstract disconnect(): void;
|
|
38
30
|
}
|
|
39
|
-
export interface NetworkAdapterEvents {
|
|
40
|
-
/** Emitted when the network is ready to be used */
|
|
41
|
-
ready: (payload: OpenPayload) => void;
|
|
42
|
-
/** Emitted when the network is closed */
|
|
43
|
-
close: () => void;
|
|
44
|
-
/** Emitted when the network adapter learns about a new peer */
|
|
45
|
-
"peer-candidate": (payload: PeerCandidatePayload) => void;
|
|
46
|
-
/** Emitted when the network adapter learns that a peer has disconnected */
|
|
47
|
-
"peer-disconnected": (payload: PeerDisconnectedPayload) => void;
|
|
48
|
-
/** Emitted when the network adapter receives a message from a peer */
|
|
49
|
-
message: (payload: Message) => void;
|
|
50
|
-
}
|
|
51
|
-
export interface OpenPayload {
|
|
52
|
-
network: NetworkAdapter;
|
|
53
|
-
}
|
|
54
|
-
export interface PeerCandidatePayload {
|
|
55
|
-
peerId: PeerId;
|
|
56
|
-
peerMetadata: PeerMetadata;
|
|
57
|
-
}
|
|
58
|
-
export interface PeerDisconnectedPayload {
|
|
59
|
-
peerId: PeerId;
|
|
60
|
-
}
|
|
61
31
|
//# sourceMappingURL=NetworkAdapter.d.ts.map
|
|
@@ -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,oBAAoB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AAEtE;;;;;;;GAOG;AACH,8BAAsB,cACpB,SAAQ,YAAY,CAAC,oBAAoB,CACzC,YAAW,uBAAuB;IAElC,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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
/* c8 ignore start */
|
|
1
2
|
import { EventEmitter } from "eventemitter3";
|
|
2
3
|
/** An interface representing some way to connect to other peers
|
|
4
|
+
* @deprecated use {@link NetworkAdapterInterface}
|
|
3
5
|
*
|
|
4
6
|
* @remarks
|
|
5
7
|
* The {@link Repo} uses one or more `NetworkAdapter`s to connect to other peers.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { EventEmitter } from "eventemitter3";
|
|
2
|
+
import { PeerId } from "../types.js";
|
|
3
|
+
import { Message } from "./messages.js";
|
|
4
|
+
import { StorageId } from "../storage/types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Describes a peer intent to the system
|
|
7
|
+
* storageId: the key for syncState to decide what the other peer already has
|
|
8
|
+
* isEphemeral: to decide if we bother recording this peer's sync state
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
export interface PeerMetadata {
|
|
12
|
+
storageId?: StorageId;
|
|
13
|
+
isEphemeral?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/** An interface representing some way to connect to other peers
|
|
16
|
+
*
|
|
17
|
+
* @remarks
|
|
18
|
+
* The {@link Repo} uses one or more `NetworkAdapter`s to connect to other peers.
|
|
19
|
+
* Because the network may take some time to be ready the {@link Repo} will wait
|
|
20
|
+
* until the adapter emits a `ready` event before it starts trying to use it
|
|
21
|
+
*/
|
|
22
|
+
export interface NetworkAdapterInterface extends EventEmitter<NetworkAdapterEvents> {
|
|
23
|
+
peerId?: PeerId;
|
|
24
|
+
peerMetadata?: PeerMetadata;
|
|
25
|
+
/** Called by the {@link Repo} to start the connection process
|
|
26
|
+
*
|
|
27
|
+
* @argument peerId - the peerId of this repo
|
|
28
|
+
* @argument peerMetadata - how this adapter should present itself to other peers
|
|
29
|
+
*/
|
|
30
|
+
connect(peerId: PeerId, peerMetadata?: PeerMetadata): void;
|
|
31
|
+
/** Called by the {@link Repo} to send a message to a peer
|
|
32
|
+
*
|
|
33
|
+
* @argument message - the message to send
|
|
34
|
+
*/
|
|
35
|
+
send(message: Message): void;
|
|
36
|
+
/** Called by the {@link Repo} to disconnect from the network */
|
|
37
|
+
disconnect(): void;
|
|
38
|
+
}
|
|
39
|
+
export interface NetworkAdapterEvents {
|
|
40
|
+
/** Emitted when the network is ready to be used */
|
|
41
|
+
ready: (payload: OpenPayload) => void;
|
|
42
|
+
/** Emitted when the network is closed */
|
|
43
|
+
close: () => void;
|
|
44
|
+
/** Emitted when the network adapter learns about a new peer */
|
|
45
|
+
"peer-candidate": (payload: PeerCandidatePayload) => void;
|
|
46
|
+
/** Emitted when the network adapter learns that a peer has disconnected */
|
|
47
|
+
"peer-disconnected": (payload: PeerDisconnectedPayload) => void;
|
|
48
|
+
/** Emitted when the network adapter receives a message from a peer */
|
|
49
|
+
message: (payload: Message) => void;
|
|
50
|
+
}
|
|
51
|
+
export interface OpenPayload {
|
|
52
|
+
network: NetworkAdapterInterface;
|
|
53
|
+
}
|
|
54
|
+
export interface PeerCandidatePayload {
|
|
55
|
+
peerId: PeerId;
|
|
56
|
+
peerMetadata: PeerMetadata;
|
|
57
|
+
}
|
|
58
|
+
export interface PeerDisconnectedPayload {
|
|
59
|
+
peerId: PeerId;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=NetworkAdapterInterface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NetworkAdapterInterface.d.ts","sourceRoot":"","sources":["../../src/network/NetworkAdapterInterface.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,MAAM,WAAW,uBAAwB,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IACjF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,YAAY,CAAA;IAE3B;;;;OAIG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,CAAA;IAE1D;;;OAGG;IACH,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IAE5B,gEAAgE;IAChE,UAAU,IAAI,IAAI,CAAA;CACnB;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,uBAAuB,CAAA;CACjC;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,13 +1,13 @@
|
|
|
1
1
|
import { EventEmitter } from "eventemitter3";
|
|
2
2
|
import { PeerId } from "../types.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { NetworkAdapterInterface, PeerDisconnectedPayload, PeerMetadata } from "./NetworkAdapterInterface.js";
|
|
4
4
|
import { MessageContents, RepoMessage } from "./messages.js";
|
|
5
5
|
export declare class NetworkSubsystem extends EventEmitter<NetworkSubsystemEvents> {
|
|
6
6
|
#private;
|
|
7
7
|
peerId: PeerId;
|
|
8
8
|
private peerMetadata;
|
|
9
|
-
constructor(adapters:
|
|
10
|
-
addNetworkAdapter(networkAdapter:
|
|
9
|
+
constructor(adapters: NetworkAdapterInterface[], peerId: PeerId, peerMetadata: Promise<PeerMetadata>);
|
|
10
|
+
addNetworkAdapter(networkAdapter: NetworkAdapterInterface): void;
|
|
11
11
|
send(message: MessageContents): void;
|
|
12
12
|
isReady: () => boolean;
|
|
13
13
|
whenReady: () => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NetworkSubsystem.d.ts","sourceRoot":"","sources":["../../src/network/NetworkSubsystem.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAa,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"NetworkSubsystem.d.ts","sourceRoot":"","sources":["../../src/network/NetworkSubsystem.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAa,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EACV,uBAAuB,EACvB,uBAAuB,EACvB,YAAY,EACb,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAEL,eAAe,EACf,WAAW,EAGZ,MAAM,eAAe,CAAA;AAOtB,qBAAa,gBAAiB,SAAQ,YAAY,CAAC,sBAAsB,CAAC;;IAY/D,MAAM;IACb,OAAO,CAAC,YAAY;gBAFpB,QAAQ,EAAE,uBAAuB,EAAE,EAC5B,MAAM,QAAiB,EACtB,YAAY,EAAE,OAAO,CAAC,YAAY,CAAC;IAO7C,iBAAiB,CAAC,cAAc,EAAE,uBAAuB;IA2EzD,IAAI,CAAC,OAAO,EAAE,eAAe;IAsC7B,OAAO,gBAEN;IAED,SAAS,sBAUR;CACF;AAQD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAA;IACpC,mBAAmB,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAA;IAC/D,OAAO,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAA;IACvC,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,YAAY,CAAA;CAC3B"}
|
|
@@ -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
|
}
|
|
@@ -67,9 +67,11 @@ export class NetworkSubsystem extends EventEmitter {
|
|
|
67
67
|
}
|
|
68
68
|
});
|
|
69
69
|
});
|
|
70
|
-
this.peerMetadata
|
|
70
|
+
this.peerMetadata
|
|
71
|
+
.then(peerMetadata => {
|
|
71
72
|
networkAdapter.connect(this.peerId, peerMetadata);
|
|
72
|
-
})
|
|
73
|
+
})
|
|
74
|
+
.catch(err => {
|
|
73
75
|
this.#log("error connecting to network", err);
|
|
74
76
|
});
|
|
75
77
|
}
|
|
@@ -107,7 +109,7 @@ export class NetworkSubsystem extends EventEmitter {
|
|
|
107
109
|
}
|
|
108
110
|
};
|
|
109
111
|
const outbound = prepareMessage(message);
|
|
110
|
-
this.#log("sending message", outbound);
|
|
112
|
+
this.#log("sending message %o", outbound);
|
|
111
113
|
peer.send(outbound);
|
|
112
114
|
}
|
|
113
115
|
isReady = () => {
|
|
@@ -1,56 +1,64 @@
|
|
|
1
1
|
import { SyncState } from "@automerge/automerge";
|
|
2
|
-
import { DocumentId, PeerId, SessionId } from "../types.js";
|
|
3
2
|
import { StorageId } from "../storage/types.js";
|
|
3
|
+
import { DocumentId, PeerId, SessionId } from "../types.js";
|
|
4
|
+
export type Message = {
|
|
5
|
+
type: string;
|
|
6
|
+
/** The peer ID of the sender of this message */
|
|
7
|
+
senderId: PeerId;
|
|
8
|
+
/** The peer ID of the recipient of this message */
|
|
9
|
+
targetId: PeerId;
|
|
10
|
+
data?: Uint8Array;
|
|
11
|
+
documentId?: DocumentId;
|
|
12
|
+
};
|
|
4
13
|
/**
|
|
5
14
|
* A sync message for a particular document
|
|
6
15
|
*/
|
|
7
16
|
export type SyncMessage = {
|
|
8
17
|
type: "sync";
|
|
9
|
-
/** The peer ID of the sender of this message */
|
|
10
18
|
senderId: PeerId;
|
|
11
|
-
/** The peer ID of the recipient of this message */
|
|
12
19
|
targetId: PeerId;
|
|
13
20
|
/** The automerge sync message */
|
|
14
21
|
data: Uint8Array;
|
|
15
22
|
/** The document ID of the document this message is for */
|
|
16
23
|
documentId: DocumentId;
|
|
17
24
|
};
|
|
18
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* An ephemeral message.
|
|
19
27
|
*
|
|
20
28
|
* @remarks
|
|
21
|
-
* Ephemeral messages are not persisted anywhere
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* number
|
|
26
|
-
* we have already seen.
|
|
29
|
+
* Ephemeral messages are not persisted anywhere. The data property can be used by the application
|
|
30
|
+
* as needed. The repo gossips these around.
|
|
31
|
+
*
|
|
32
|
+
* In order to avoid infinite loops of ephemeral messages, every message has (a) a session ID, which
|
|
33
|
+
* is a random number generated by the sender at startup time; and (b) a sequence number. The
|
|
34
|
+
* combination of these two things allows us to discard messages we have already seen.
|
|
27
35
|
* */
|
|
28
36
|
export type EphemeralMessage = {
|
|
29
37
|
type: "ephemeral";
|
|
30
|
-
/** The peer ID of the sender of this message */
|
|
31
38
|
senderId: PeerId;
|
|
32
|
-
/** The peer ID of the recipient of this message */
|
|
33
39
|
targetId: PeerId;
|
|
34
|
-
/** A sequence number which must be incremented for each message sent by this peer */
|
|
40
|
+
/** A sequence number which must be incremented for each message sent by this peer. */
|
|
35
41
|
count: number;
|
|
36
|
-
/** The ID of the session this message is part of. The sequence number for a given session always increases */
|
|
42
|
+
/** The ID of the session this message is part of. The sequence number for a given session always increases. */
|
|
37
43
|
sessionId: SessionId;
|
|
38
|
-
/** The document ID this message pertains to */
|
|
44
|
+
/** The document ID this message pertains to. */
|
|
39
45
|
documentId: DocumentId;
|
|
40
|
-
/** The actual data of the message */
|
|
46
|
+
/** The actual data of the message. */
|
|
41
47
|
data: Uint8Array;
|
|
42
48
|
};
|
|
43
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Sent by a {@link Repo} to indicate that it does not have the document and none of its connected
|
|
51
|
+
* peers do either.
|
|
52
|
+
*/
|
|
44
53
|
export type DocumentUnavailableMessage = {
|
|
45
54
|
type: "doc-unavailable";
|
|
46
|
-
/** The peer ID of the sender of this message */
|
|
47
55
|
senderId: PeerId;
|
|
48
|
-
/** The peer ID of the recipient of this message */
|
|
49
56
|
targetId: PeerId;
|
|
50
57
|
/** The document which the peer claims it doesn't have */
|
|
51
58
|
documentId: DocumentId;
|
|
52
59
|
};
|
|
53
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* Sent by a {@link Repo} to request a document from a peer.
|
|
54
62
|
*
|
|
55
63
|
* @remarks
|
|
56
64
|
* This is identical to a {@link SyncMessage} except that it is sent by a {@link Repo}
|
|
@@ -58,37 +66,35 @@ export type DocumentUnavailableMessage = {
|
|
|
58
66
|
* */
|
|
59
67
|
export type RequestMessage = {
|
|
60
68
|
type: "request";
|
|
61
|
-
/** The peer ID of the sender of this message */
|
|
62
69
|
senderId: PeerId;
|
|
63
|
-
/** The peer ID of the recipient of this message */
|
|
64
70
|
targetId: PeerId;
|
|
65
|
-
/** The
|
|
71
|
+
/** The automerge sync message */
|
|
66
72
|
data: Uint8Array;
|
|
67
|
-
/** The document ID this message
|
|
73
|
+
/** The document ID of the document this message is for */
|
|
68
74
|
documentId: DocumentId;
|
|
69
75
|
};
|
|
70
|
-
/**
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
/** The peer ID of the sender of this message */
|
|
74
|
-
senderId: PeerId;
|
|
75
|
-
/** The peer ID of the recipient of this message */
|
|
76
|
-
targetId: PeerId;
|
|
77
|
-
/** The payload of the auth message (up to the specific auth provider) */
|
|
78
|
-
payload: TPayload;
|
|
79
|
-
};
|
|
76
|
+
/**
|
|
77
|
+
* Sent by a {@link Repo} to add or remove storage IDs from a remote peer's subscription.
|
|
78
|
+
*/
|
|
80
79
|
export type RemoteSubscriptionControlMessage = {
|
|
81
80
|
type: "remote-subscription-change";
|
|
82
81
|
senderId: PeerId;
|
|
83
82
|
targetId: PeerId;
|
|
83
|
+
/** The storage IDs to add to the subscription */
|
|
84
84
|
add?: StorageId[];
|
|
85
|
+
/** The storage IDs to remove from the subscription */
|
|
85
86
|
remove?: StorageId[];
|
|
86
87
|
};
|
|
88
|
+
/**
|
|
89
|
+
* Sent by a {@link Repo} to indicate that the heads of a document have changed on a remote peer.
|
|
90
|
+
*/
|
|
87
91
|
export type RemoteHeadsChanged = {
|
|
88
92
|
type: "remote-heads-changed";
|
|
89
93
|
senderId: PeerId;
|
|
90
94
|
targetId: PeerId;
|
|
95
|
+
/** The document ID of the document that has changed */
|
|
91
96
|
documentId: DocumentId;
|
|
97
|
+
/** The document's new heads */
|
|
92
98
|
newHeads: {
|
|
93
99
|
[key: StorageId]: {
|
|
94
100
|
heads: string[];
|
|
@@ -98,13 +104,12 @@ export type RemoteHeadsChanged = {
|
|
|
98
104
|
};
|
|
99
105
|
/** These are message types that a {@link NetworkAdapter} surfaces to a {@link Repo}. */
|
|
100
106
|
export type RepoMessage = SyncMessage | EphemeralMessage | RequestMessage | DocumentUnavailableMessage | RemoteSubscriptionControlMessage | RemoteHeadsChanged;
|
|
107
|
+
/** These are message types that are handled by the {@link CollectionSynchronizer}.*/
|
|
101
108
|
export type DocMessage = SyncMessage | EphemeralMessage | RequestMessage | DocumentUnavailableMessage;
|
|
102
|
-
/** These are all the message types that a {@link NetworkAdapter} might see. */
|
|
103
|
-
export type Message = RepoMessage | AuthMessage;
|
|
104
109
|
/**
|
|
105
110
|
* The contents of a message, without the sender ID or other properties added by the {@link NetworkSubsystem})
|
|
106
111
|
*/
|
|
107
|
-
export type MessageContents<T extends Message =
|
|
112
|
+
export type MessageContents<T extends Message = RepoMessage> = T extends EphemeralMessage ? Omit<T, "senderId" | "count" | "sessionId"> : Omit<T, "senderId">;
|
|
108
113
|
/** Notify the repo that the sync state has changed */
|
|
109
114
|
export interface SyncStateMessage {
|
|
110
115
|
peerId: PeerId;
|
|
@@ -116,7 +121,7 @@ export interface OpenDocMessage {
|
|
|
116
121
|
peerId: PeerId;
|
|
117
122
|
documentId: DocumentId;
|
|
118
123
|
}
|
|
119
|
-
export declare const
|
|
124
|
+
export declare const isRepoMessage: (message: Message) => message is RepoMessage;
|
|
120
125
|
export declare const isDocumentUnavailableMessage: (msg: Message) => msg is DocumentUnavailableMessage;
|
|
121
126
|
export declare const isRequestMessage: (msg: Message) => msg is RequestMessage;
|
|
122
127
|
export declare const isSyncMessage: (msg: Message) => msg is SyncMessage;
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/network/messages.ts"],"names":[],"mappings":"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"}
|
package/dist/network/messages.js
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
// TYPE GUARDS
|
|
2
|
-
export const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
isDocumentUnavailableMessage(message) ||
|
|
9
|
-
isRemoteSubscriptionControlMessage(message) ||
|
|
10
|
-
isRemoteHeadsChanged(message));
|
|
2
|
+
export const isRepoMessage = (message) => isSyncMessage(message) ||
|
|
3
|
+
isEphemeralMessage(message) ||
|
|
4
|
+
isRequestMessage(message) ||
|
|
5
|
+
isDocumentUnavailableMessage(message) ||
|
|
6
|
+
isRemoteSubscriptionControlMessage(message) ||
|
|
7
|
+
isRemoteHeadsChanged(message);
|
|
11
8
|
// prettier-ignore
|
|
12
9
|
export const isDocumentUnavailableMessage = (msg) => msg.type === "doc-unavailable";
|
|
13
10
|
export const isRequestMessage = (msg) => msg.type === "request";
|
|
14
11
|
export const isSyncMessage = (msg) => msg.type === "sync";
|
|
15
12
|
export const isEphemeralMessage = (msg) => msg.type === "ephemeral";
|
|
13
|
+
// prettier-ignore
|
|
16
14
|
export const isRemoteSubscriptionControlMessage = (msg) => msg.type === "remote-subscription-change";
|
|
17
15
|
export const isRemoteHeadsChanged = (msg) => msg.type === "remote-heads-changed";
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import { StorageAdapterInterface } from "./StorageAdapterInterface.js";
|
|
1
2
|
import { StorageKey, Chunk } from "./types.js";
|
|
2
3
|
/** A storage adapter represents some way of storing binary data for a {@link Repo}
|
|
4
|
+
* @deprecated use {@link StorageAdapterInterface}
|
|
3
5
|
*
|
|
4
6
|
* @remarks
|
|
5
7
|
* `StorageAdapter`s provide a key/value storage interface. The keys are arrays of strings
|
|
6
8
|
* ({@link StorageKey}) and the values are binary blobs.
|
|
7
9
|
*/
|
|
8
|
-
export declare abstract class StorageAdapter {
|
|
10
|
+
export declare abstract class StorageAdapter implements StorageAdapterInterface {
|
|
9
11
|
/** Load the single value corresponding to `key` */
|
|
10
12
|
abstract load(key: StorageKey): Promise<Uint8Array | undefined>;
|
|
11
13
|
/** Save the value `data` to the key `key` */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageAdapter.d.ts","sourceRoot":"","sources":["../../src/storage/StorageAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAE9C
|
|
1
|
+
{"version":3,"file":"StorageAdapter.d.ts","sourceRoot":"","sources":["../../src/storage/StorageAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AACtE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAE9C;;;;;;GAMG;AACH,8BAAsB,cAAe,YAAW,uBAAuB;IACrE,mDAAmD;IACnD,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAE/D,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAE/D,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAE/C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,SAAS,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAE3D,8DAA8D;IAC9D,QAAQ,CAAC,WAAW,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAC3D"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { StorageKey, Chunk } from "./types.js";
|
|
2
|
+
/** A storage adapter represents some way of storing binary data for a {@link Repo}
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* `StorageAdapter`s provide a key/value storage interface. The keys are arrays of strings
|
|
6
|
+
* ({@link StorageKey}) and the values are binary blobs.
|
|
7
|
+
*/
|
|
8
|
+
export interface StorageAdapterInterface {
|
|
9
|
+
/** Load the single value corresponding to `key` */
|
|
10
|
+
load(key: StorageKey): Promise<Uint8Array | undefined>;
|
|
11
|
+
/** Save the value `data` to the key `key` */
|
|
12
|
+
save(key: StorageKey, data: Uint8Array): Promise<void>;
|
|
13
|
+
/** Remove the value corresponding to `key` */
|
|
14
|
+
remove(key: StorageKey): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Load all values with keys that start with `keyPrefix`.
|
|
17
|
+
*
|
|
18
|
+
* @remarks
|
|
19
|
+
* The `keyprefix` will match any key that starts with the given array. For example:
|
|
20
|
+
* - `[documentId, "incremental"]` will match all incremental saves
|
|
21
|
+
* - `[documentId]` will match all data for a given document.
|
|
22
|
+
*
|
|
23
|
+
* Be careful! `[documentId]` would also match something like `[documentId, "syncState"]`! We
|
|
24
|
+
* aren't using this yet but keep it in mind.)
|
|
25
|
+
*/
|
|
26
|
+
loadRange(keyPrefix: StorageKey): Promise<Chunk[]>;
|
|
27
|
+
/** Remove all values with keys that start with `keyPrefix` */
|
|
28
|
+
removeRange(keyPrefix: StorageKey): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=StorageAdapterInterface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StorageAdapterInterface.d.ts","sourceRoot":"","sources":["../../src/storage/StorageAdapterInterface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAE9C;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,mDAAmD;IACnD,IAAI,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAA;IAEtD,6CAA6C;IAC7C,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEtD,8CAA8C;IAC9C,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEtC;;;;;;;;;;OAUG;IACH,SAAS,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAAA;IAElD,8DAA8D;IAC9D,WAAW,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAClD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as A from "@automerge/automerge/next";
|
|
2
2
|
import { type DocumentId } from "../types.js";
|
|
3
|
-
import {
|
|
3
|
+
import { StorageAdapterInterface } from "./StorageAdapterInterface.js";
|
|
4
4
|
import { StorageId } from "./types.js";
|
|
5
5
|
/**
|
|
6
6
|
* The storage subsystem is responsible for saving and loading Automerge documents to and from
|
|
@@ -8,7 +8,7 @@ import { StorageId } from "./types.js";
|
|
|
8
8
|
*/
|
|
9
9
|
export declare class StorageSubsystem {
|
|
10
10
|
#private;
|
|
11
|
-
constructor(storageAdapter:
|
|
11
|
+
constructor(storageAdapter: StorageAdapterInterface);
|
|
12
12
|
id(): Promise<StorageId>;
|
|
13
13
|
/** Loads a value from storage. */
|
|
14
14
|
load(
|
|
@@ -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;AAC7C,OAAO,EAAE,
|
|
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;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AACtE,OAAO,EAAyB,SAAS,EAAE,MAAM,YAAY,CAAA;AAK7D;;;GAGG;AACH,qBAAa,gBAAgB;;gBAef,cAAc,EAAE,uBAAuB;IAI7C,EAAE,IAAI,OAAO,CAAC,SAAS,CAAC;IA2B9B,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,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC;IAM7B,aAAa,CACjB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,CAAC,CAAC,SAAS,GACrB,OAAO,CAAC,IAAI,CAAC;CA8CjB"}
|
|
@@ -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,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,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;IAqD9B;;;OAGG;IACG,cAAc,CAAC,OAAO,EAAE,UAAU;IAyBxC;;OAEG;IACH,WAAW,CAAC,UAAU,EAAE,UAAU;
|
|
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,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,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;IAqD9B;;;OAGG;IACG,cAAc,CAAC,OAAO,EAAE,UAAU;IAyBxC;;OAEG;IACH,WAAW,CAAC,UAAU,EAAE,UAAU;IAalC,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"}
|
|
@@ -1 +1 @@
|
|
|
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;AAGhD,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;
|
|
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;AAGhD,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;IAkID,OAAO,CAAC,MAAM,EAAE,MAAM;IAItB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE;IAmD3B,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"}
|
|
@@ -77,9 +77,11 @@ export class DocSynchronizer extends Synchronizer {
|
|
|
77
77
|
}
|
|
78
78
|
let pendingCallbacks = this.#pendingSyncStateCallbacks[peerId];
|
|
79
79
|
if (!pendingCallbacks) {
|
|
80
|
-
this.#onLoadSyncState(peerId)
|
|
80
|
+
this.#onLoadSyncState(peerId)
|
|
81
|
+
.then(syncState => {
|
|
81
82
|
this.#initSyncState(peerId, syncState ?? A.initSyncState());
|
|
82
|
-
})
|
|
83
|
+
})
|
|
84
|
+
.catch(err => {
|
|
83
85
|
this.#log(`Error loading sync state for ${peerId}: ${err}`);
|
|
84
86
|
});
|
|
85
87
|
pendingCallbacks = this.#pendingSyncStateCallbacks[peerId] = [];
|
|
@@ -150,7 +152,7 @@ export class DocSynchronizer extends Synchronizer {
|
|
|
150
152
|
return this.#peers.includes(peerId);
|
|
151
153
|
}
|
|
152
154
|
beginSync(peerIds) {
|
|
153
|
-
const
|
|
155
|
+
const noPeersWithDocument = peerIds.every((peerId) => this.#peerDocumentStatuses[peerId] in ["unavailable", "wants"]);
|
|
154
156
|
// At this point if we don't have anything in our storage, we need to use an empty doc to sync
|
|
155
157
|
// with; but we don't want to surface that state to the front end
|
|
156
158
|
const docPromise = this.#handle
|
|
@@ -160,7 +162,7 @@ export class DocSynchronizer extends Synchronizer {
|
|
|
160
162
|
this.#syncStarted = true;
|
|
161
163
|
this.#checkDocUnavailable();
|
|
162
164
|
const wasUnavailable = doc === undefined;
|
|
163
|
-
if (wasUnavailable &&
|
|
165
|
+
if (wasUnavailable && noPeersWithDocument) {
|
|
164
166
|
return;
|
|
165
167
|
}
|
|
166
168
|
// If the doc is unavailable we still need a blank document to generate
|
|
@@ -176,11 +178,13 @@ export class DocSynchronizer extends Synchronizer {
|
|
|
176
178
|
// TODO: cover that case with a test and remove this hack
|
|
177
179
|
const reparsedSyncState = A.decodeSyncState(A.encodeSyncState(syncState));
|
|
178
180
|
this.#setSyncState(peerId, reparsedSyncState);
|
|
179
|
-
docPromise
|
|
181
|
+
docPromise
|
|
182
|
+
.then(doc => {
|
|
180
183
|
if (doc) {
|
|
181
184
|
this.#sendSyncMessage(peerId, doc);
|
|
182
185
|
}
|
|
183
|
-
})
|
|
186
|
+
})
|
|
187
|
+
.catch(err => {
|
|
184
188
|
this.#log(`Error loading doc for ${peerId}: ${err}`);
|
|
185
189
|
});
|
|
186
190
|
});
|
|
@@ -235,9 +239,9 @@ export class DocSynchronizer extends Synchronizer {
|
|
|
235
239
|
return;
|
|
236
240
|
}
|
|
237
241
|
this.#processAllPendingSyncMessages();
|
|
238
|
-
this.#processSyncMessage(message
|
|
242
|
+
this.#processSyncMessage(message);
|
|
239
243
|
}
|
|
240
|
-
#processSyncMessage(message
|
|
244
|
+
#processSyncMessage(message) {
|
|
241
245
|
if (isRequestMessage(message)) {
|
|
242
246
|
this.#peerDocumentStatuses[message.senderId] = "wants";
|
|
243
247
|
}
|
|
@@ -278,7 +282,7 @@ export class DocSynchronizer extends Synchronizer {
|
|
|
278
282
|
}
|
|
279
283
|
#processAllPendingSyncMessages() {
|
|
280
284
|
for (const message of this.#pendingSyncMessages) {
|
|
281
|
-
this.#processSyncMessage(message.message
|
|
285
|
+
this.#processSyncMessage(message.message);
|
|
282
286
|
}
|
|
283
287
|
this.#pendingSyncMessages = [];
|
|
284
288
|
}
|