@automerge/automerge-repo 1.0.5 → 1.0.7

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.
Files changed (65) hide show
  1. package/.eslintrc +1 -1
  2. package/dist/DocHandle.d.ts +20 -7
  3. package/dist/DocHandle.d.ts.map +1 -1
  4. package/dist/DocHandle.js +27 -7
  5. package/dist/EphemeralData.d.ts +2 -2
  6. package/dist/EphemeralData.d.ts.map +1 -1
  7. package/dist/Repo.d.ts +16 -0
  8. package/dist/Repo.d.ts.map +1 -1
  9. package/dist/Repo.js +38 -10
  10. package/dist/helpers/cbor.d.ts +2 -2
  11. package/dist/helpers/cbor.d.ts.map +1 -1
  12. package/dist/helpers/cbor.js +1 -1
  13. package/dist/helpers/pause.d.ts.map +1 -1
  14. package/dist/helpers/pause.js +3 -1
  15. package/dist/helpers/tests/network-adapter-tests.d.ts.map +1 -1
  16. package/dist/helpers/tests/network-adapter-tests.js +2 -2
  17. package/dist/index.d.ts +11 -9
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +4 -4
  20. package/dist/network/NetworkAdapter.d.ts +3 -3
  21. package/dist/network/NetworkAdapter.d.ts.map +1 -1
  22. package/dist/network/NetworkSubsystem.d.ts +2 -2
  23. package/dist/network/NetworkSubsystem.d.ts.map +1 -1
  24. package/dist/network/NetworkSubsystem.js +30 -18
  25. package/dist/network/messages.d.ts +38 -68
  26. package/dist/network/messages.d.ts.map +1 -1
  27. package/dist/network/messages.js +13 -21
  28. package/dist/storage/StorageSubsystem.js +7 -7
  29. package/dist/synchronizer/CollectionSynchronizer.d.ts +3 -3
  30. package/dist/synchronizer/CollectionSynchronizer.d.ts.map +1 -1
  31. package/dist/synchronizer/CollectionSynchronizer.js +2 -2
  32. package/dist/synchronizer/DocSynchronizer.d.ts +3 -3
  33. package/dist/synchronizer/DocSynchronizer.d.ts.map +1 -1
  34. package/dist/synchronizer/DocSynchronizer.js +22 -29
  35. package/dist/synchronizer/Synchronizer.d.ts +2 -2
  36. package/dist/synchronizer/Synchronizer.d.ts.map +1 -1
  37. package/dist/types.d.ts +5 -1
  38. package/dist/types.d.ts.map +1 -1
  39. package/package.json +5 -13
  40. package/src/DocHandle.ts +38 -14
  41. package/src/EphemeralData.ts +2 -2
  42. package/src/Repo.ts +46 -12
  43. package/src/helpers/cbor.ts +4 -4
  44. package/src/helpers/pause.ts +7 -2
  45. package/src/helpers/tests/network-adapter-tests.ts +3 -3
  46. package/src/helpers/withTimeout.ts +2 -2
  47. package/src/index.ts +36 -29
  48. package/src/network/NetworkAdapter.ts +7 -3
  49. package/src/network/NetworkSubsystem.ts +31 -23
  50. package/src/network/messages.ts +88 -151
  51. package/src/storage/StorageSubsystem.ts +8 -8
  52. package/src/synchronizer/CollectionSynchronizer.ts +6 -15
  53. package/src/synchronizer/DocSynchronizer.ts +34 -48
  54. package/src/synchronizer/Synchronizer.ts +2 -2
  55. package/src/types.ts +8 -3
  56. package/test/CollectionSynchronizer.test.ts +58 -53
  57. package/test/DocHandle.test.ts +35 -36
  58. package/test/DocSynchronizer.test.ts +9 -8
  59. package/test/Network.test.ts +1 -0
  60. package/test/Repo.test.ts +273 -88
  61. package/test/StorageSubsystem.test.ts +6 -9
  62. package/test/tsconfig.json +8 -0
  63. package/test/types.ts +2 -0
  64. package/typedoc.json +3 -3
  65. package/.mocharc.json +0 -5
package/.eslintrc CHANGED
@@ -10,7 +10,7 @@
10
10
  ],
11
11
  "ignorePatterns": ["dist/**", "test/**", "node_modules/**"],
12
12
  "parser": "@typescript-eslint/parser",
13
- "plugins": ["@typescript-eslint", "mocha"],
13
+ "plugins": ["@typescript-eslint"],
14
14
  "parserOptions": {
15
15
  "project": "./tsconfig.json",
16
16
  "ecmaVersion": "latest",
@@ -80,6 +80,19 @@ export declare class DocHandle<T>//
80
80
  * @returns A set of heads representing the concurrent change that was made.
81
81
  */
82
82
  changeAt(heads: A.Heads, callback: A.ChangeFn<T>, options?: A.ChangeOptions<T>): string[] | undefined;
83
+ /** Merge another document into this document
84
+ *
85
+ * @param otherHandle - the handle of the document to merge into this one
86
+ *
87
+ * @remarks
88
+ * This is a convenience method for
89
+ * `handle.change(doc => A.merge(doc, otherHandle.docSync()))`. Any peers
90
+ * whom we are sharing changes with will be notified of the changes resulting
91
+ * from the merge.
92
+ *
93
+ * @throws if either document is not ready or if `otherHandle` is unavailable (`otherHandle.docSync() === undefined`)
94
+ */
95
+ merge(otherHandle: DocHandle<T>): void;
83
96
  unavailable(): void;
84
97
  /** `request` is called by the repo when the document is not found in storage
85
98
  * @hidden
@@ -97,7 +110,7 @@ export declare class DocHandle<T>//
97
110
  * a user could have multiple tabs open and would appear as multiple PeerIds.
98
111
  * every message source must have a unique PeerId.
99
112
  */
100
- broadcast(message: any): void;
113
+ broadcast(message: unknown): void;
101
114
  }
102
115
  /** @hidden */
103
116
  export interface DocHandleOptions {
@@ -127,13 +140,13 @@ export interface DocHandleChangePayload<T> {
127
140
  /** Information about the change */
128
141
  patchInfo: A.PatchInfo<T>;
129
142
  }
130
- export interface DocHandleEphemeralMessagePayload {
131
- handle: DocHandle<any>;
143
+ export interface DocHandleEphemeralMessagePayload<T> {
144
+ handle: DocHandle<T>;
132
145
  senderId: PeerId;
133
146
  message: unknown;
134
147
  }
135
- export interface DocHandleOutboundEphemeralMessagePayload {
136
- handle: DocHandle<any>;
148
+ export interface DocHandleOutboundEphemeralMessagePayload<T> {
149
+ handle: DocHandle<T>;
137
150
  data: Uint8Array;
138
151
  }
139
152
  export interface DocHandleEvents<T> {
@@ -141,8 +154,8 @@ export interface DocHandleEvents<T> {
141
154
  change: (payload: DocHandleChangePayload<T>) => void;
142
155
  delete: (payload: DocHandleDeletePayload<T>) => void;
143
156
  unavailable: (payload: DocHandleDeletePayload<T>) => void;
144
- "ephemeral-message": (payload: DocHandleEphemeralMessagePayload) => void;
145
- "ephemeral-message-outbound": (payload: DocHandleOutboundEphemeralMessagePayload) => void;
157
+ "ephemeral-message": (payload: DocHandleEphemeralMessagePayload<T>) => void;
158
+ "ephemeral-message-outbound": (payload: DocHandleOutboundEphemeralMessagePayload<T>) => void;
146
159
  }
147
160
  /**
148
161
  * The state of a document handle
@@ -1 +1 @@
1
- {"version":3,"file":"DocHandle.d.ts","sourceRoot":"","sources":["../src/DocHandle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DocHandle.d.ts","sourceRoot":"","sources":["../src/DocHandle.ts"],"names":[],"mappings":"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"}
package/dist/DocHandle.js CHANGED
@@ -4,8 +4,7 @@ import { EventEmitter } from "eventemitter3";
4
4
  import { assign, createMachine, interpret, } from "xstate";
5
5
  import { waitFor } from "xstate/lib/waitFor.js";
6
6
  import { headsAreSame } from "./helpers/headsAreSame.js";
7
- import { pause } from "./helpers/pause.js";
8
- import { TimeoutError, withTimeout } from "./helpers/withTimeout.js";
7
+ import { withTimeout } from "./helpers/withTimeout.js";
9
8
  import { stringifyAutomergeUrl } from "./DocUrl.js";
10
9
  import { encode } from "./helpers/cbor.js";
11
10
  /** DocHandle is a wrapper around a single Automerge document that lets us
@@ -238,16 +237,13 @@ export class DocHandle//
238
237
  * @param {awaitStates=[READY]} optional states to wait for, such as "LOADING". mostly for internal use.
239
238
  */
240
239
  async doc(awaitStates = [READY, UNAVAILABLE]) {
241
- await pause(); // yield one tick because reasons
242
240
  try {
243
241
  // wait for the document to enter one of the desired states
244
242
  await this.#statePromise(awaitStates);
245
243
  }
246
244
  catch (error) {
247
- if (error instanceof TimeoutError)
248
- throw new Error(`DocHandle: timed out loading ${this.documentId}`);
249
- else
250
- throw error;
245
+ // if we timed out (or the load has already failed), return undefined
246
+ return undefined;
251
247
  }
252
248
  // Return the document
253
249
  return !this.isUnavailable() ? this.#doc : undefined;
@@ -309,6 +305,30 @@ export class DocHandle//
309
305
  });
310
306
  return resultHeads;
311
307
  }
308
+ /** Merge another document into this document
309
+ *
310
+ * @param otherHandle - the handle of the document to merge into this one
311
+ *
312
+ * @remarks
313
+ * This is a convenience method for
314
+ * `handle.change(doc => A.merge(doc, otherHandle.docSync()))`. Any peers
315
+ * whom we are sharing changes with will be notified of the changes resulting
316
+ * from the merge.
317
+ *
318
+ * @throws if either document is not ready or if `otherHandle` is unavailable (`otherHandle.docSync() === undefined`)
319
+ */
320
+ merge(otherHandle) {
321
+ if (!this.isReady() || !otherHandle.isReady()) {
322
+ throw new Error("Both handles must be ready to merge");
323
+ }
324
+ const mergingDoc = otherHandle.docSync();
325
+ if (!mergingDoc) {
326
+ throw new Error("The document to be merged in is null, aborting.");
327
+ }
328
+ this.update(doc => {
329
+ return A.merge(doc, mergingDoc);
330
+ });
331
+ }
312
332
  unavailable() {
313
333
  this.#machine.send(MARK_UNAVAILABLE);
314
334
  }
@@ -1,5 +1,5 @@
1
1
  import { DocumentId, PeerId } from "./index.js";
2
- import { EphemeralMessageContents } from "./network/messages.js";
2
+ import { EphemeralMessage, MessageContents } from "./network/messages.js";
3
3
  /** A randomly generated string created when the {@link Repo} starts up */
4
4
  export type SessionId = string & {
5
5
  __SessionId: false;
@@ -14,7 +14,7 @@ export interface EphemeralDataPayload {
14
14
  };
15
15
  }
16
16
  export type EphemeralDataMessageEvents = {
17
- message: (event: EphemeralMessageContents) => void;
17
+ message: (event: MessageContents<EphemeralMessage>) => void;
18
18
  data: (event: EphemeralDataPayload) => void;
19
19
  };
20
20
  //# sourceMappingURL=EphemeralData.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EphemeralData.d.ts","sourceRoot":"","sources":["../src/EphemeralData.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAGhE,0EAA0E;AAC1E,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG;IAAE,WAAW,EAAE,KAAK,CAAA;CAAE,CAAA;AAEvD,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,UAAU,CAAA;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAA;CAChE;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,OAAO,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,CAAA;IAClD,IAAI,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAA;CAC5C,CAAA"}
1
+ {"version":3,"file":"EphemeralData.d.ts","sourceRoot":"","sources":["../src/EphemeralData.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAGzE,0EAA0E;AAC1E,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG;IAAE,WAAW,EAAE,KAAK,CAAA;CAAE,CAAA;AAEvD,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,UAAU,CAAA;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAA;CAChE;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,OAAO,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAA;IAC3D,IAAI,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAA;CAC5C,CAAA"}
package/dist/Repo.d.ts CHANGED
@@ -31,6 +31,22 @@ export declare class Repo extends EventEmitter<RepoEvents> {
31
31
  * to advertise interest in the document.
32
32
  */
33
33
  create<T>(): DocHandle<T>;
34
+ /** Create a new DocHandle by cloning the history of an existing DocHandle.
35
+ *
36
+ * @param clonedHandle - The handle to clone
37
+ *
38
+ * @remarks This is a wrapper around the `clone` function in the Automerge library.
39
+ * The new `DocHandle` will have a new URL but will share history with the original,
40
+ * which means that changes made to the cloned handle can be sensibly merged back
41
+ * into the original.
42
+ *
43
+ * Any peers this `Repo` is connected to for whom `sharePolicy` returns `true` will
44
+ * be notified of the newly created DocHandle.
45
+ *
46
+ * @throws if the cloned handle is not yet ready or if
47
+ * `clonedHandle.docSync()` returns `undefined` (i.e. the handle is unavailable).
48
+ */
49
+ clone<T>(clonedHandle: DocHandle<T>): DocHandle<T>;
34
50
  /**
35
51
  * Retrieves a document by id. It gets data from the local system, but also emits a `document`
36
52
  * event to advertise interest in the document.
@@ -1 +1 @@
1
- {"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../src/Repo.ts"],"names":[],"mappings":"AACA,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,EAAE,KAAK,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AASlE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAG5C,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;IAGnC,sDAAsD;IACtD,cAAc;IACd,WAAW,EAAE,WAAW,CAAmB;gBAE/B,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,UAAU;IAuHjE,8CAA8C;IAC9C,IAAI,OAAO,uCAEV;IAED;;;;OAIG;IACH,MAAM,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC;IA0BzB;;;OAGG;IACH,IAAI,CAAC,CAAC;IACJ,+CAA+C;IAC/C,YAAY,EAAE,YAAY,GACzB,SAAS,CAAC,CAAC,CAAC;IAgCf,MAAM;IACJ,6CAA6C;IAC7C,EAAE,EAAE,UAAU,GAAG,YAAY;CAchC;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"}
1
+ {"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../src/Repo.ts"],"names":[],"mappings":"AACA,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,EAAE,KAAK,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AASlE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAG5C,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;IAGnC,sDAAsD;IACtD,cAAc;IACd,WAAW,EAAE,WAAW,CAAmB;gBAE/B,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,UAAU;IAuHjE,8CAA8C;IAC9C,IAAI,OAAO,uCAEV;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,+CAA+C;IAC/C,YAAY,EAAE,YAAY,GACzB,SAAS,CAAC,CAAC,CAAC;IAgCf,MAAM;IACJ,6CAA6C;IAC7C,EAAE,EAAE,UAAU,GAAG,YAAY;CAUhC;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
@@ -5,6 +5,7 @@ import { CollectionSynchronizer } from "./synchronizer/CollectionSynchronizer.js
5
5
  import { parseAutomergeUrl, generateAutomergeUrl, isValidAutomergeUrl, parseLegacyUUID, } from "./DocUrl.js";
6
6
  import { DocHandle } from "./DocHandle.js";
7
7
  import { EventEmitter } from "eventemitter3";
8
+ import { next as Automerge } from "@automerge/automerge";
8
9
  /** A Repo is a collection of documents with networking, syncing, and storage capabilities. */
9
10
  /** The `Repo` is the main entry point of this library
10
11
  *
@@ -83,9 +84,9 @@ export class Repo extends EventEmitter {
83
84
  // SYNCHRONIZER
84
85
  // The synchronizer uses the network subsystem to keep documents in sync with peers.
85
86
  const synchronizer = new CollectionSynchronizer(this);
86
- // When the synchronizer emits sync messages, send them to peers
87
+ // When the synchronizer emits messages, send them to peers
87
88
  synchronizer.on("message", message => {
88
- this.#log(`sending sync message to ${message.targetId}`);
89
+ this.#log(`sending ${message.type} message to ${message.targetId}`);
89
90
  networkSubsystem.send(message);
90
91
  });
91
92
  // STORAGE
@@ -156,6 +157,37 @@ export class Repo extends EventEmitter {
156
157
  this.emit("document", { handle, isNew: true });
157
158
  return handle;
158
159
  }
160
+ /** Create a new DocHandle by cloning the history of an existing DocHandle.
161
+ *
162
+ * @param clonedHandle - The handle to clone
163
+ *
164
+ * @remarks This is a wrapper around the `clone` function in the Automerge library.
165
+ * The new `DocHandle` will have a new URL but will share history with the original,
166
+ * which means that changes made to the cloned handle can be sensibly merged back
167
+ * into the original.
168
+ *
169
+ * Any peers this `Repo` is connected to for whom `sharePolicy` returns `true` will
170
+ * be notified of the newly created DocHandle.
171
+ *
172
+ * @throws if the cloned handle is not yet ready or if
173
+ * `clonedHandle.docSync()` returns `undefined` (i.e. the handle is unavailable).
174
+ */
175
+ clone(clonedHandle) {
176
+ if (!clonedHandle.isReady()) {
177
+ throw new Error(`Cloned handle is not yet in ready state.
178
+ (Try await handle.waitForReady() first.)`);
179
+ }
180
+ const sourceDoc = clonedHandle.docSync();
181
+ if (!sourceDoc) {
182
+ throw new Error("Cloned handle doesn't have a document.");
183
+ }
184
+ const handle = this.create();
185
+ handle.update(() => {
186
+ // we replace the document with the new cloned one
187
+ return Automerge.clone(sourceDoc);
188
+ });
189
+ return handle;
190
+ }
159
191
  /**
160
192
  * Retrieves a document by id. It gets data from the local system, but also emits a `document`
161
193
  * event to advertise interest in the document.
@@ -164,7 +196,7 @@ export class Repo extends EventEmitter {
164
196
  /** The documentId of the handle to retrieve */
165
197
  automergeUrl) {
166
198
  if (!isValidAutomergeUrl(automergeUrl)) {
167
- let maybeAutomergeUrl = parseLegacyUUID(automergeUrl);
199
+ const maybeAutomergeUrl = parseLegacyUUID(automergeUrl);
168
200
  if (maybeAutomergeUrl) {
169
201
  console.warn("Legacy UUID document ID detected, converting to AutomergeUrl. This will be removed in a future version.");
170
202
  automergeUrl = maybeAutomergeUrl;
@@ -193,15 +225,11 @@ export class Repo extends EventEmitter {
193
225
  delete(
194
226
  /** The documentId of the handle to delete */
195
227
  id) {
196
- if (isValidAutomergeUrl(id)) {
197
- ;
198
- ({ documentId: id } = parseAutomergeUrl(id));
199
- }
228
+ if (isValidAutomergeUrl(id))
229
+ id = parseAutomergeUrl(id).documentId;
200
230
  const handle = this.#getHandle(id, false);
201
231
  handle.delete();
202
232
  delete this.#handleCache[id];
203
- this.emit("delete-document", {
204
- documentId: id,
205
- });
233
+ this.emit("delete-document", { documentId: id });
206
234
  }
207
235
  }
@@ -1,4 +1,4 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
- export declare function encode(obj: any): Buffer;
3
- export declare function decode(buf: Buffer | Uint8Array): any;
2
+ export declare function encode(obj: unknown): Buffer;
3
+ export declare function decode<T = unknown>(buf: Buffer | Uint8Array): T;
4
4
  //# sourceMappingURL=cbor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cbor.d.ts","sourceRoot":"","sources":["../../src/helpers/cbor.ts"],"names":[],"mappings":";AAEA,wBAAgB,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAGvC;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,GAAG,CAEpD"}
1
+ {"version":3,"file":"cbor.d.ts","sourceRoot":"","sources":["../../src/helpers/cbor.ts"],"names":[],"mappings":";AAEA,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAG3C;AAED,wBAAgB,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,CAAC,CAE/D"}
@@ -1,6 +1,6 @@
1
1
  import { Encoder, decode as cborXdecode } from "cbor-x";
2
2
  export function encode(obj) {
3
- let encoder = new Encoder({ tagUint8Array: false });
3
+ const encoder = new Encoder({ tagUint8Array: false });
4
4
  return encoder.encode(obj);
5
5
  }
6
6
  export function decode(buf) {
@@ -1 +1 @@
1
- {"version":3,"file":"pause.d.ts","sourceRoot":"","sources":["../../src/helpers/pause.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,+BAC4C,CAAA;AAE9D,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAKlF"}
1
+ {"version":3,"file":"pause.d.ts","sourceRoot":"","sources":["../../src/helpers/pause.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,+BAC4C,CAAA;AAE9D,wBAAgB,eAAe,CAAC,CAAC,EAC/B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,CAAC,CAAC,CAOZ"}
@@ -2,6 +2,8 @@ export const pause = (t = 0) => new Promise(resolve => setTimeout(() => resolve(
2
2
  export function rejectOnTimeout(promise, millis) {
3
3
  return Promise.race([
4
4
  promise,
5
- pause(millis).then(() => { throw new Error("timeout exceeded"); }),
5
+ pause(millis).then(() => {
6
+ throw new Error("timeout exceeded");
7
+ }),
6
8
  ]);
7
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"network-adapter-tests.d.ts","sourceRoot":"","sources":["../../../src/helpers/tests/network-adapter-tests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,cAAc,EAAc,MAAM,gBAAgB,CAAA;AAM9E;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CA8HrE;AAID,KAAK,OAAO,GAAG,cAAc,GAAG,cAAc,EAAE,CAAA;AAEhD,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC;IAClC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACrC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB,CAAC,CAAA"}
1
+ {"version":3,"file":"network-adapter-tests.d.ts","sourceRoot":"","sources":["../../../src/helpers/tests/network-adapter-tests.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAIlE;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CA8HrE;AAID,KAAK,OAAO,GAAG,cAAc,GAAG,cAAc,EAAE,CAAA;AAEhD,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC;IAClC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACrC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB,CAAC,CAAA"}
@@ -1,7 +1,7 @@
1
+ import assert from "assert";
2
+ import { describe, it } from "vitest";
1
3
  import { Repo } from "../../index.js";
2
4
  import { eventPromise, eventPromises } from "../eventPromise.js";
3
- import { assert } from "chai";
4
- import { describe, it } from "mocha";
5
5
  import { pause } from "../pause.js";
6
6
  /**
7
7
  * Runs a series of tests against a set of three peers, each represented by one or more instantiated
package/dist/index.d.ts CHANGED
@@ -25,16 +25,18 @@
25
25
  * const handle = repo.create
26
26
  * ```
27
27
  */
28
- export { DocHandle, type HandleState, type DocHandleOptions, type DocHandleEvents } from "./DocHandle.js";
29
- export type { DocHandleChangePayload, DocHandleDeletePayload, DocHandleEphemeralMessagePayload, DocHandleOutboundEphemeralMessagePayload, DocHandleEncodedChangePayload, } from "./DocHandle.js";
28
+ export { Repo } from "./Repo.js";
29
+ export { DocHandle } from "./DocHandle.js";
30
30
  export { NetworkAdapter } from "./network/NetworkAdapter.js";
31
- export type { OpenPayload, PeerCandidatePayload, PeerDisconnectedPayload, NetworkAdapterEvents, } from "./network/NetworkAdapter.js";
32
- export type { Message, ArriveMessage, WelcomeMessage, NetworkAdapterMessage, EphemeralMessage, RequestMessage, DocumentUnavailableMessage, SyncMessage, SessionId, } from "./network/messages.js";
33
- export { isValidMessage } from "./network/messages.js";
34
- export { Repo, type SharePolicy, type RepoConfig, type RepoEvents, type DeleteDocumentPayload, type DocumentPayload } from "./Repo.js";
35
- export { StorageAdapter, type StorageKey } from "./storage/StorageAdapter.js";
36
- export { parseAutomergeUrl, isValidAutomergeUrl, stringifyAutomergeUrl as generateAutomergeUrl, } from "./DocUrl.js";
37
- export * from "./types.js";
31
+ export { StorageAdapter } from "./storage/StorageAdapter.js";
32
+ export { isValidAutomergeUrl, parseAutomergeUrl, stringifyAutomergeUrl, } from "./DocUrl.js";
33
+ export { isValidRepoMessage } from "./network/messages.js";
38
34
  /** @hidden **/
39
35
  export * as cbor from "./helpers/cbor.js";
36
+ export type { DocHandleChangePayload, DocHandleDeletePayload, DocHandleEncodedChangePayload, DocHandleEphemeralMessagePayload, DocHandleEvents, DocHandleOptions, DocHandleOutboundEphemeralMessagePayload, HandleState, } from "./DocHandle.js";
37
+ export type { DeleteDocumentPayload, DocumentPayload, RepoConfig, RepoEvents, SharePolicy, } from "./Repo.js";
38
+ export type { NetworkAdapterEvents, OpenPayload, PeerCandidatePayload, PeerDisconnectedPayload, } from "./network/NetworkAdapter.js";
39
+ export type { ArriveMessage, DocumentUnavailableMessage, EphemeralMessage, Message, RepoMessage, RequestMessage, SyncMessage, WelcomeMessage, } from "./network/messages.js";
40
+ export type { StorageKey } from "./storage/StorageAdapter.js";
41
+ export * from "./types.js";
40
42
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACzG,YAAY,EACV,sBAAsB,EACtB,sBAAsB,EACtB,gCAAgC,EAChC,wCAAwC,EACxC,6BAA6B,GAC9B,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EACV,WAAW,EACX,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,6BAA6B,CAAA;AAMpC,YAAY,EACV,OAAO,EACP,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,cAAc,EACd,0BAA0B,EAC1B,WAAW,EACX,SAAS,GACV,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,qBAAqB,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAA;AACtI,OAAO,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAC7E,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,IAAI,oBAAoB,GAC9C,MAAM,aAAa,CAAA;AACpB,cAAc,YAAY,CAAA;AAE1B,eAAe;AACf,OAAO,KAAK,IAAI,MAAM,mBAAmB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAE1D,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;AACvB,YAAY,EACV,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,UAAU,EACV,WAAW,GACZ,MAAM,WAAW,CAAA;AAClB,YAAY,EACV,oBAAoB,EACpB,WAAW,EACX,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,6BAA6B,CAAA;AACpC,YAAY,EACV,aAAa,EACb,0BAA0B,EAC1B,gBAAgB,EAChB,OAAO,EACP,WAAW,EACX,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAC7D,cAAc,YAAY,CAAA"}
package/dist/index.js CHANGED
@@ -25,12 +25,12 @@
25
25
  * const handle = repo.create
26
26
  * ```
27
27
  */
28
+ export { Repo } from "./Repo.js";
28
29
  export { DocHandle } from "./DocHandle.js";
29
30
  export { NetworkAdapter } from "./network/NetworkAdapter.js";
30
- export { isValidMessage } from "./network/messages.js";
31
- export { Repo } from "./Repo.js";
32
31
  export { StorageAdapter } from "./storage/StorageAdapter.js";
33
- export { parseAutomergeUrl, isValidAutomergeUrl, stringifyAutomergeUrl as generateAutomergeUrl, } from "./DocUrl.js";
34
- export * from "./types.js";
32
+ export { isValidAutomergeUrl, parseAutomergeUrl, stringifyAutomergeUrl, } from "./DocUrl.js";
33
+ export { isValidRepoMessage } from "./network/messages.js";
35
34
  /** @hidden **/
36
35
  export * as cbor from "./helpers/cbor.js";
36
+ export * from "./types.js";
@@ -1,6 +1,6 @@
1
1
  import { EventEmitter } from "eventemitter3";
2
2
  import { PeerId } from "../types.js";
3
- import { Message } from "./messages.js";
3
+ import { RepoMessage } from "./messages.js";
4
4
  /** An interface representing some way to connect to other peers
5
5
  *
6
6
  * @remarks
@@ -19,7 +19,7 @@ export declare abstract class NetworkAdapter extends EventEmitter<NetworkAdapter
19
19
  *
20
20
  * @argument message - the message to send
21
21
  */
22
- abstract send(message: Message): void;
22
+ abstract send(message: RepoMessage): void;
23
23
  /** Called by the {@link Repo} to disconnect from the network */
24
24
  abstract disconnect(): void;
25
25
  }
@@ -33,7 +33,7 @@ export interface NetworkAdapterEvents {
33
33
  /** Emitted when the network adapter learns that a peer has disconnected */
34
34
  "peer-disconnected": (payload: PeerDisconnectedPayload) => void;
35
35
  /** Emitted when the network adapter receives a message from a peer */
36
- message: (payload: Message) => void;
36
+ message: (payload: RepoMessage) => void;
37
37
  }
38
38
  export interface OpenPayload {
39
39
  network: NetworkAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkAdapter.d.ts","sourceRoot":"","sources":["../../src/network/NetworkAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC;;;;;;GAMG;AACH,8BAAsB,cAAe,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAEtC;;;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;IACrC,yCAAyC;IACzC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,+DAA+D;IAC/D,gBAAgB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAA;IACzD,2EAA2E;IAC3E,mBAAmB,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAA;IAC/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;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAA;CACf"}
1
+ {"version":3,"file":"NetworkAdapter.d.ts","sourceRoot":"","sources":["../../src/network/NetworkAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE3C;;;;;;GAMG;AACH,8BAAsB,cAAe,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAEtC;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAEzC,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,WAAW,KAAK,IAAI,CAAA;CACxC;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,cAAc,CAAA;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAA;CACf"}
@@ -1,7 +1,7 @@
1
1
  import { EventEmitter } from "eventemitter3";
2
2
  import { PeerId } from "../types.js";
3
3
  import { NetworkAdapter, PeerDisconnectedPayload } from "./NetworkAdapter.js";
4
- import { Message, MessageContents } from "./messages.js";
4
+ import { RepoMessage, MessageContents } from "./messages.js";
5
5
  export declare class NetworkSubsystem extends EventEmitter<NetworkSubsystemEvents> {
6
6
  #private;
7
7
  peerId: PeerId;
@@ -14,7 +14,7 @@ export declare class NetworkSubsystem extends EventEmitter<NetworkSubsystemEvent
14
14
  export interface NetworkSubsystemEvents {
15
15
  peer: (payload: PeerPayload) => void;
16
16
  "peer-disconnected": (payload: PeerDisconnectedPayload) => void;
17
- message: (payload: Message) => void;
17
+ message: (payload: RepoMessage) => void;
18
18
  ready: () => void;
19
19
  }
20
20
  export interface PeerPayload {
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkSubsystem.d.ts","sourceRoot":"","sources":["../../src/network/NetworkSubsystem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAE7E,OAAO,EAIL,OAAO,EACP,eAAe,EAChB,MAAM,eAAe,CAAA;AAUtB,qBAAa,gBAAiB,SAAQ,YAAY,CAAC,sBAAsB,CAAC;;IAUzB,MAAM;gBAAzC,QAAQ,EAAE,cAAc,EAAE,EAAS,MAAM,SAAiB;IAMtE,iBAAiB,CAAC,cAAc,EAAE,cAAc;IAsEhD,IAAI,CAAC,OAAO,EAAE,eAAe;IA2B7B,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,OAAO,KAAK,IAAI,CAAA;IACnC,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;CACf"}
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,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAC7E,OAAO,EAEL,WAAW,EACX,eAAe,EAGhB,MAAM,eAAe,CAAA;AAOtB,qBAAa,gBAAiB,SAAQ,YAAY,CAAC,sBAAsB,CAAC;;IAUzB,MAAM;gBAAzC,QAAQ,EAAE,cAAc,EAAE,EAAS,MAAM,SAAiB;IAMtE,iBAAiB,CAAC,cAAc,EAAE,cAAc;IAsEhD,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;CACf"}
@@ -1,6 +1,6 @@
1
- import { EventEmitter } from "eventemitter3";
2
- import { isEphemeralMessage, isValidMessage, } from "./messages.js";
3
1
  import debug from "debug";
2
+ import { EventEmitter } from "eventemitter3";
3
+ import { isEphemeralMessage, isValidRepoMessage, } from "./messages.js";
4
4
  const getEphemeralMessageSource = (message) => `${message.senderId}:${message.sessionId}`;
5
5
  export class NetworkSubsystem extends EventEmitter {
6
6
  peerId;
@@ -41,7 +41,7 @@ export class NetworkSubsystem extends EventEmitter {
41
41
  this.emit("peer-disconnected", { peerId });
42
42
  });
43
43
  networkAdapter.on("message", msg => {
44
- if (!isValidMessage(msg)) {
44
+ if (!isValidRepoMessage(msg)) {
45
45
  this.#log(`invalid message: ${JSON.stringify(msg)}`);
46
46
  return;
47
47
  }
@@ -73,24 +73,36 @@ export class NetworkSubsystem extends EventEmitter {
73
73
  this.#log(`Tried to send message but peer not found: ${message.targetId}`);
74
74
  return;
75
75
  }
76
- this.#log(`Sending message to ${message.targetId}`);
77
- if (isEphemeralMessage(message)) {
78
- const outbound = "count" in message
79
- ? message
80
- : {
76
+ /** Messages come in without a senderId and other required information; this is where we make
77
+ * sure they have everything they need.
78
+ */
79
+ const prepareMessage = (message) => {
80
+ if (message.type === "ephemeral") {
81
+ if ("count" in message) {
82
+ // existing ephemeral message from another peer; pass on without changes
83
+ return message;
84
+ }
85
+ else {
86
+ // new ephemeral message from us; add our senderId as well as a counter and session id
87
+ return {
88
+ ...message,
89
+ count: ++this.#count,
90
+ sessionId: this.#sessionId,
91
+ senderId: this.peerId,
92
+ };
93
+ }
94
+ }
95
+ else {
96
+ // other message type; just add our senderId
97
+ return {
81
98
  ...message,
82
- count: ++this.#count,
83
- sessionId: this.#sessionId,
84
99
  senderId: this.peerId,
85
100
  };
86
- this.#log("Ephemeral message", outbound);
87
- peer.send(outbound);
88
- }
89
- else {
90
- const outbound = { ...message, senderId: this.peerId };
91
- this.#log("Sync message", outbound);
92
- peer.send(outbound);
93
- }
101
+ }
102
+ };
103
+ const outbound = prepareMessage(message);
104
+ this.#log("sending message", outbound);
105
+ peer.send(outbound);
94
106
  }
95
107
  isReady = () => {
96
108
  return this.#readyAdapterCount === this.#adapters.length;