@automerge/automerge-repo 1.0.0-alpha.3 → 1.0.0-alpha.5

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 (61) hide show
  1. package/dist/DocCollection.d.ts +2 -1
  2. package/dist/DocCollection.d.ts.map +1 -1
  3. package/dist/DocCollection.js +3 -3
  4. package/dist/DocHandle.d.ts +8 -3
  5. package/dist/DocHandle.d.ts.map +1 -1
  6. package/dist/DocHandle.js +28 -6
  7. package/dist/DocUrl.d.ts +1 -1
  8. package/dist/DocUrl.d.ts.map +1 -1
  9. package/dist/Repo.d.ts.map +1 -1
  10. package/dist/Repo.js +25 -7
  11. package/dist/helpers/cbor.d.ts +4 -0
  12. package/dist/helpers/cbor.d.ts.map +1 -0
  13. package/dist/helpers/cbor.js +8 -0
  14. package/dist/helpers/eventPromise.d.ts +1 -1
  15. package/dist/helpers/eventPromise.d.ts.map +1 -1
  16. package/dist/helpers/headsAreSame.d.ts +0 -1
  17. package/dist/helpers/headsAreSame.d.ts.map +1 -1
  18. package/dist/index.d.ts +1 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +1 -0
  21. package/dist/network/NetworkAdapter.d.ts +4 -5
  22. package/dist/network/NetworkAdapter.d.ts.map +1 -1
  23. package/dist/network/NetworkAdapter.js +1 -1
  24. package/dist/network/NetworkSubsystem.d.ts +4 -4
  25. package/dist/network/NetworkSubsystem.d.ts.map +1 -1
  26. package/dist/network/NetworkSubsystem.js +28 -14
  27. package/dist/network/messages.d.ts +2 -2
  28. package/dist/network/messages.d.ts.map +1 -1
  29. package/dist/storage/StorageSubsystem.d.ts +1 -1
  30. package/dist/storage/StorageSubsystem.d.ts.map +1 -1
  31. package/dist/storage/StorageSubsystem.js +10 -4
  32. package/dist/synchronizer/DocSynchronizer.d.ts.map +1 -1
  33. package/dist/synchronizer/DocSynchronizer.js +11 -12
  34. package/dist/synchronizer/Synchronizer.d.ts +1 -1
  35. package/dist/synchronizer/Synchronizer.d.ts.map +1 -1
  36. package/dist/synchronizer/Synchronizer.js +1 -1
  37. package/fuzz/fuzz.ts +1 -1
  38. package/package.json +3 -3
  39. package/src/DocCollection.ts +4 -3
  40. package/src/DocHandle.ts +34 -4
  41. package/src/DocUrl.ts +1 -1
  42. package/src/Repo.ts +23 -7
  43. package/src/helpers/cbor.ts +10 -0
  44. package/src/helpers/eventPromise.ts +1 -1
  45. package/src/helpers/headsAreSame.ts +1 -1
  46. package/src/index.ts +2 -0
  47. package/src/network/NetworkAdapter.ts +4 -6
  48. package/src/network/NetworkSubsystem.ts +37 -19
  49. package/src/network/messages.ts +2 -2
  50. package/src/storage/StorageSubsystem.ts +11 -4
  51. package/src/synchronizer/DocSynchronizer.ts +14 -14
  52. package/src/synchronizer/Synchronizer.ts +1 -1
  53. package/test/CollectionSynchronizer.test.ts +1 -1
  54. package/test/DocCollection.test.ts +2 -2
  55. package/test/DocHandle.test.ts +5 -5
  56. package/test/Repo.test.ts +75 -13
  57. package/test/StorageSubsystem.test.ts +2 -3
  58. package/test/helpers/DummyNetworkAdapter.ts +13 -5
  59. package/test/helpers/DummyStorageAdapter.ts +1 -1
  60. package/test/helpers/generate-large-object.ts +13 -0
  61. package/tsconfig.json +2 -2
@@ -1,4 +1,4 @@
1
- import EventEmitter from "eventemitter3";
1
+ import { EventEmitter } from "eventemitter3";
2
2
  import { DocHandle } from "./DocHandle.js";
3
3
  import { DocumentId, AutomergeUrl } from "./types.js";
4
4
  import { type SharePolicy } from "./Repo.js";
@@ -37,6 +37,7 @@ interface DocCollectionEvents {
37
37
  }
38
38
  interface DocumentPayload {
39
39
  handle: DocHandle<any>;
40
+ isNew: boolean;
40
41
  }
41
42
  interface DeleteDocumentPayload {
42
43
  documentId: DocumentId;
@@ -1 +1 @@
1
- {"version":3,"file":"DocCollection.d.ts","sourceRoot":"","sources":["../src/DocCollection.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAyB,YAAY,EAAE,MAAM,YAAY,CAAA;AAC5E,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAS5C;;;KAGK;AACL,qBAAa,aAAc,SAAQ,YAAY,CAAC,mBAAmB,CAAC;;IAGlE,sDAAsD;IACtD,WAAW,EAAE,WAAW,CAAmB;;IAwB3C,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;IAwBf,MAAM;IACJ,6CAA6C;IAC7C,EAAE,EAAE,UAAU,GAAG,YAAY;CAchC;AAGD,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,CAAA;IACxC,iBAAiB,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,IAAI,CAAA;IACvD,sBAAsB,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,IAAI,CAAA;CAC7D;AAED,UAAU,eAAe;IACvB,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;CACvB;AAED,UAAU,qBAAqB;IAC7B,UAAU,EAAE,UAAU,CAAA;CACvB"}
1
+ {"version":3,"file":"DocCollection.d.ts","sourceRoot":"","sources":["../src/DocCollection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAyB,YAAY,EAAE,MAAM,YAAY,CAAA;AAC5E,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAS5C;;;KAGK;AACL,qBAAa,aAAc,SAAQ,YAAY,CAAC,mBAAmB,CAAC;;IAGlE,sDAAsD;IACtD,WAAW,EAAE,WAAW,CAAmB;;IAwB3C,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;IAwBf,MAAM;IACJ,6CAA6C;IAC7C,EAAE,EAAE,UAAU,GAAG,YAAY;CAchC;AAGD,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,CAAA;IACxC,iBAAiB,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,IAAI,CAAA;IACvD,sBAAsB,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,IAAI,CAAA;CAC7D;AAED,UAAU,eAAe;IACvB,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;IACtB,KAAK,EAAE,OAAO,CAAA;CACf;AAED,UAAU,qBAAqB;IAC7B,UAAU,EAAE,UAAU,CAAA;CACvB"}
@@ -1,4 +1,4 @@
1
- import EventEmitter from "eventemitter3";
1
+ import { EventEmitter } from "eventemitter3";
2
2
  import { DocHandle } from "./DocHandle.js";
3
3
  import { generateAutomergeUrl, isValidAutomergeUrl, parseAutomergeUrl, } from "./DocUrl.js";
4
4
  /**
@@ -55,7 +55,7 @@ export class DocCollection extends EventEmitter {
55
55
  // Generate a new UUID and store it in the buffer
56
56
  const { documentId } = parseAutomergeUrl(generateAutomergeUrl());
57
57
  const handle = this.#getHandle(documentId, true);
58
- this.emit("document", { handle });
58
+ this.emit("document", { handle, isNew: true });
59
59
  return handle;
60
60
  }
61
61
  /**
@@ -82,7 +82,7 @@ export class DocCollection extends EventEmitter {
82
82
  return this.#handleCache[documentId];
83
83
  }
84
84
  const handle = this.#getHandle(documentId, false);
85
- this.emit("document", { handle });
85
+ this.emit("document", { handle, isNew: false });
86
86
  return handle;
87
87
  }
88
88
  delete(
@@ -1,5 +1,5 @@
1
- import * as A from "@automerge/automerge";
2
- import EventEmitter from "eventemitter3";
1
+ import * as A from "@automerge/automerge/next";
2
+ import { EventEmitter } from "eventemitter3";
3
3
  import { StateValue } from "xstate";
4
4
  import type { DocumentId, PeerId, AutomergeUrl } from "./types.js";
5
5
  /** DocHandle is a wrapper around a single Automerge document that lets us listen for changes. */
@@ -59,6 +59,8 @@ export declare class DocHandle<T>//
59
59
  unavailable(): void;
60
60
  /** `request` is called by the repo when the document is not found in storage */
61
61
  request(): void;
62
+ awaitNetwork(): void;
63
+ networkReady(): void;
62
64
  /** `delete` is called by the repo when the document is deleted */
63
65
  delete(): void;
64
66
  /** `broadcast` sends an arbitrary ephemeral message out to all reachable peers who would receive sync messages from you
@@ -111,6 +113,7 @@ export interface DocHandleEvents<T> {
111
113
  export declare const HandleState: {
112
114
  readonly IDLE: "idle";
113
115
  readonly LOADING: "loading";
116
+ readonly AWAITING_NETWORK: "awaitingNetwork";
114
117
  readonly REQUESTING: "requesting";
115
118
  readonly READY: "ready";
116
119
  readonly FAILED: "failed";
@@ -123,11 +126,13 @@ export declare const Event: {
123
126
  readonly FIND: "FIND";
124
127
  readonly REQUEST: "REQUEST";
125
128
  readonly REQUEST_COMPLETE: "REQUEST_COMPLETE";
129
+ readonly AWAIT_NETWORK: "AWAIT_NETWORK";
130
+ readonly NETWORK_READY: "NETWORK_READY";
126
131
  readonly UPDATE: "UPDATE";
127
132
  readonly TIMEOUT: "TIMEOUT";
128
133
  readonly DELETE: "DELETE";
129
134
  readonly MARK_UNAVAILABLE: "MARK_UNAVAILABLE";
130
135
  };
131
- export declare const IDLE: "idle", LOADING: "loading", REQUESTING: "requesting", READY: "ready", FAILED: "failed", DELETED: "deleted", UNAVAILABLE: "unavailable";
136
+ export declare const IDLE: "idle", LOADING: "loading", AWAITING_NETWORK: "awaitingNetwork", REQUESTING: "requesting", READY: "ready", FAILED: "failed", DELETED: "deleted", UNAVAILABLE: "unavailable";
132
137
  export {};
133
138
  //# sourceMappingURL=DocHandle.d.ts.map
@@ -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
@@ -1,13 +1,13 @@
1
- import * as A from "@automerge/automerge";
1
+ import * as A from "@automerge/automerge/next";
2
2
  import debug from "debug";
3
- import EventEmitter from "eventemitter3";
3
+ 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
7
  import { pause } from "./helpers/pause.js";
8
8
  import { TimeoutError, withTimeout } from "./helpers/withTimeout.js";
9
9
  import { stringifyAutomergeUrl } from "./DocUrl.js";
10
- import { encode } from "cbor-x";
10
+ import { encode } from "./helpers/cbor.js";
11
11
  /** DocHandle is a wrapper around a single Automerge document that lets us listen for changes. */
12
12
  export class DocHandle//
13
13
  extends EventEmitter {
@@ -24,7 +24,11 @@ export class DocHandle//
24
24
  this.#timeoutDelay = timeoutDelay;
25
25
  this.#log = debug(`automerge-repo:dochandle:${this.documentId.slice(0, 5)}`);
26
26
  // initial doc
27
- const doc = A.init();
27
+ let doc = A.init();
28
+ // Make an empty change so that we have something to save to disk
29
+ if (isNew) {
30
+ doc = A.emptyChange(doc, {});
31
+ }
28
32
  /**
29
33
  * Internally we use a state machine to orchestrate document loading and/or syncing, in order to
30
34
  * avoid requesting data we already have, or surfacing intermediate values to the consumer.
@@ -59,6 +63,8 @@ export class DocHandle//
59
63
  UPDATE: { actions: "onUpdate", target: READY },
60
64
  // REQUEST is called by the Repo if the document is not found in storage
61
65
  REQUEST: { target: REQUESTING },
66
+ // AWAIT_NETWORK is called by the repo if the document is not found in storage but the network is not yet ready
67
+ AWAIT_NETWORK: { target: AWAITING_NETWORK },
62
68
  DELETE: { actions: "onDelete", target: DELETED },
63
69
  },
64
70
  after: [
@@ -68,6 +74,11 @@ export class DocHandle//
68
74
  },
69
75
  ],
70
76
  },
77
+ awaitingNetwork: {
78
+ on: {
79
+ NETWORK_READY: { target: REQUESTING },
80
+ },
81
+ },
71
82
  requesting: {
72
83
  on: {
73
84
  MARK_UNAVAILABLE: {
@@ -278,6 +289,14 @@ export class DocHandle//
278
289
  if (this.#state === LOADING)
279
290
  this.#machine.send(REQUEST);
280
291
  }
292
+ awaitNetwork() {
293
+ if (this.#state === LOADING)
294
+ this.#machine.send(AWAIT_NETWORK);
295
+ }
296
+ networkReady() {
297
+ if (this.#state === AWAITING_NETWORK)
298
+ this.#machine.send(NETWORK_READY);
299
+ }
281
300
  /** `delete` is called by the repo when the document is deleted */
282
301
  delete() {
283
302
  this.#machine.send(DELETE);
@@ -300,6 +319,7 @@ export class DocHandle//
300
319
  export const HandleState = {
301
320
  IDLE: "idle",
302
321
  LOADING: "loading",
322
+ AWAITING_NETWORK: "awaitingNetwork",
303
323
  REQUESTING: "requesting",
304
324
  READY: "ready",
305
325
  FAILED: "failed",
@@ -312,11 +332,13 @@ export const Event = {
312
332
  FIND: "FIND",
313
333
  REQUEST: "REQUEST",
314
334
  REQUEST_COMPLETE: "REQUEST_COMPLETE",
335
+ AWAIT_NETWORK: "AWAIT_NETWORK",
336
+ NETWORK_READY: "NETWORK_READY",
315
337
  UPDATE: "UPDATE",
316
338
  TIMEOUT: "TIMEOUT",
317
339
  DELETE: "DELETE",
318
340
  MARK_UNAVAILABLE: "MARK_UNAVAILABLE",
319
341
  };
320
342
  // CONSTANTS
321
- export const { IDLE, LOADING, REQUESTING, READY, FAILED, DELETED, UNAVAILABLE, } = HandleState;
322
- const { CREATE, FIND, REQUEST, UPDATE, TIMEOUT, DELETE, REQUEST_COMPLETE, MARK_UNAVAILABLE, } = Event;
343
+ export const { IDLE, LOADING, AWAITING_NETWORK, REQUESTING, READY, FAILED, DELETED, UNAVAILABLE, } = HandleState;
344
+ const { CREATE, FIND, REQUEST, UPDATE, TIMEOUT, DELETE, REQUEST_COMPLETE, MARK_UNAVAILABLE, AWAIT_NETWORK, NETWORK_READY, } = Event;
package/dist/DocUrl.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type AutomergeUrl, type BinaryDocumentId, type DocumentId } from "./types";
1
+ import { type AutomergeUrl, type BinaryDocumentId, type DocumentId } from "./types.js";
2
2
  export declare const urlPrefix = "automerge:";
3
3
  /**
4
4
  * given an Automerge URL, return a decoded DocumentId (and the encoded DocumentId)
@@ -1 +1 @@
1
- {"version":3,"file":"DocUrl.d.ts","sourceRoot":"","sources":["../src/DocUrl.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EAChB,MAAM,SAAS,CAAA;AAIhB,eAAO,MAAM,SAAS,eAAe,CAAA;AAErC;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,QAAS,YAAY;;;CAIlD,CAAA;AAED,UAAU,4BAA4B;IACpC,UAAU,EAAE,UAAU,GAAG,gBAAgB,CAAA;CAC1C;AAED;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,oBAE/B,4BAA4B,KAAG,YAQjC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,QAAS,MAAM,wBAK9C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,QAAO,YAGpC,CAAA;AAEJ,eAAO,MAAM,kBAAkB,UACtB,UAAU,KAChB,gBAAgB,GAAG,SACyC,CAAA;AAE/D,eAAO,MAAM,kBAAkB,UAAW,gBAAgB,KAAG,UACtB,CAAA"}
1
+ {"version":3,"file":"DocUrl.d.ts","sourceRoot":"","sources":["../src/DocUrl.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAA;AAInB,eAAO,MAAM,SAAS,eAAe,CAAA;AAErC;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,QAAS,YAAY;;;CAIlD,CAAA;AAED,UAAU,4BAA4B;IACpC,UAAU,EAAE,UAAU,GAAG,gBAAgB,CAAA;CAC1C;AAED;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,oBAE/B,4BAA4B,KAAG,YAQjC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,QAAS,MAAM,wBAK9C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,QAAO,YAGpC,CAAA;AAEJ,eAAO,MAAM,kBAAkB,UACtB,UAAU,KAChB,gBAAgB,GAAG,SACyC,CAAA;AAE/D,eAAO,MAAM,kBAAkB,UAAW,gBAAgB,KAAG,UACtB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../src/Repo.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,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,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAE/C,oFAAoF;AACpF,qBAAa,IAAK,SAAQ,aAAa;;IAGrC,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;gBAEvB,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,UAAU;CAiFlE;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,MAAM,MAAM,WAAW,GAAG,CACxB,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,UAAU,KACpB,OAAO,CAAC,OAAO,CAAC,CAAA"}
1
+ {"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../src/Repo.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,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,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAE/C,oFAAoF;AACpF,qBAAa,IAAK,SAAQ,aAAa;;IAGrC,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;gBAEvB,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,UAAU;CAiGlE;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,MAAM,MAAM,WAAW,GAAG,CACxB,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,UAAU,KACpB,OAAO,CAAC,OAAO,CAAC,CAAA"}
package/dist/Repo.js CHANGED
@@ -15,16 +15,22 @@ export class Repo extends DocCollection {
15
15
  // DOC COLLECTION
16
16
  // The `document` event is fired by the DocCollection any time we create a new document or look
17
17
  // up a document by ID. We listen for it in order to wire up storage and network synchronization.
18
- this.on("document", async ({ handle }) => {
18
+ this.on("document", async ({ handle, isNew }) => {
19
19
  if (storageSubsystem) {
20
20
  // Save when the document changes
21
21
  handle.on("heads-changed", async ({ handle, doc }) => {
22
22
  await storageSubsystem.saveDoc(handle.documentId, doc);
23
23
  });
24
- // Try to load from disk
25
- const loadedDoc = await storageSubsystem.loadDoc(handle.documentId);
26
- if (loadedDoc) {
27
- handle.update(() => loadedDoc);
24
+ if (isNew) {
25
+ // this is a new document, immediately save it
26
+ await storageSubsystem.saveDoc(handle.documentId, handle.docSync());
27
+ }
28
+ else {
29
+ // Try to load from disk
30
+ const loadedDoc = await storageSubsystem.loadDoc(handle.documentId);
31
+ if (loadedDoc) {
32
+ handle.update(() => loadedDoc);
33
+ }
28
34
  }
29
35
  }
30
36
  handle.on("unavailable", () => {
@@ -33,7 +39,17 @@ export class Repo extends DocCollection {
33
39
  documentId: handle.documentId,
34
40
  });
35
41
  });
36
- handle.request();
42
+ if (this.networkSubsystem.isReady()) {
43
+ handle.request();
44
+ }
45
+ else {
46
+ handle.awaitNetwork();
47
+ this.networkSubsystem.whenReady().then(() => {
48
+ handle.networkReady();
49
+ }).catch(err => {
50
+ this.#log("error waiting for network", { err });
51
+ });
52
+ }
37
53
  // Register the document with the synchronizer. This advertises our interest in the document.
38
54
  synchronizer.addDocument(handle.documentId);
39
55
  });
@@ -41,7 +57,9 @@ export class Repo extends DocCollection {
41
57
  // TODO Pass the delete on to the network
42
58
  // synchronizer.removeDocument(documentId)
43
59
  if (storageSubsystem) {
44
- storageSubsystem.remove(documentId);
60
+ storageSubsystem.remove(documentId).catch(err => {
61
+ this.#log("error deleting document", { documentId, err });
62
+ });
45
63
  }
46
64
  });
47
65
  // SYNCHRONIZER
@@ -0,0 +1,4 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ export declare function encode(obj: any): Buffer;
3
+ export declare function decode(buf: Buffer | Uint8Array): any;
4
+ //# sourceMappingURL=cbor.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,8 @@
1
+ import { Encoder, decode as cborXdecode } from "cbor-x";
2
+ export function encode(obj) {
3
+ let encoder = new Encoder({ tagUint8Array: false });
4
+ return encoder.encode(obj);
5
+ }
6
+ export function decode(buf) {
7
+ return cborXdecode(buf);
8
+ }
@@ -1,4 +1,4 @@
1
- import EventEmitter from "eventemitter3";
1
+ import { EventEmitter } from "eventemitter3";
2
2
  /** Returns a promise that resolves when the given event is emitted on the given emitter. */
3
3
  export declare const eventPromise: (emitter: EventEmitter, event: string) => Promise<any>;
4
4
  export declare const eventPromises: (emitters: EventEmitter[], event: string) => Promise<any[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"eventPromise.d.ts","sourceRoot":"","sources":["../../src/helpers/eventPromise.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AAExC,4FAA4F;AAC5F,eAAO,MAAM,YAAY,YAAa,YAAY,SAAS,MAAM,iBACE,CAAA;AAEnE,eAAO,MAAM,aAAa,aAAc,YAAY,EAAE,SAAS,MAAM,mBAGpE,CAAA"}
1
+ {"version":3,"file":"eventPromise.d.ts","sourceRoot":"","sources":["../../src/helpers/eventPromise.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,4FAA4F;AAC5F,eAAO,MAAM,YAAY,YAAa,YAAY,SAAS,MAAM,iBACE,CAAA;AAEnE,eAAO,MAAM,aAAa,aAAc,YAAY,EAAE,SAAS,MAAM,mBAGpE,CAAA"}
@@ -1,3 +1,2 @@
1
- import { Heads } from "@automerge/automerge";
2
1
  export declare const headsAreSame: (a: Heads, b: Heads) => boolean;
3
2
  //# sourceMappingURL=headsAreSame.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"headsAreSame.d.ts","sourceRoot":"","sources":["../../src/helpers/headsAreSame.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,sBAAsB,CAAA;AAG1C,eAAO,MAAM,YAAY,iCAExB,CAAA"}
1
+ {"version":3,"file":"headsAreSame.d.ts","sourceRoot":"","sources":["../../src/helpers/headsAreSame.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,iCAExB,CAAA"}
package/dist/index.d.ts CHANGED
@@ -11,4 +11,5 @@ export { StorageSubsystem } from "./storage/StorageSubsystem.js";
11
11
  export { CollectionSynchronizer } from "./synchronizer/CollectionSynchronizer.js";
12
12
  export { parseAutomergeUrl, isValidAutomergeUrl, stringifyAutomergeUrl as generateAutomergeUrl, } from "./DocUrl.js";
13
13
  export * from "./types.js";
14
+ export * as cbor from "./helpers/cbor.js";
14
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AACvD,YAAY,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EACV,WAAW,EACX,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,6BAA6B,CAAA;AAMpC,YAAY,EACV,OAAO,EACP,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,GACZ,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAA;AACjF,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,IAAI,oBAAoB,GAC9C,MAAM,aAAa,CAAA;AACpB,cAAc,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AACvD,YAAY,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EACV,WAAW,EACX,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,6BAA6B,CAAA;AAMpC,YAAY,EACV,OAAO,EACP,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,GACZ,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAA;AACjF,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,IAAI,oBAAoB,GAC9C,MAAM,aAAa,CAAA;AACpB,cAAc,YAAY,CAAA;AAE1B,OAAO,KAAK,IAAI,MAAM,mBAAmB,CAAA"}
package/dist/index.js CHANGED
@@ -8,3 +8,4 @@ export { StorageSubsystem } from "./storage/StorageSubsystem.js";
8
8
  export { CollectionSynchronizer } from "./synchronizer/CollectionSynchronizer.js";
9
9
  export { parseAutomergeUrl, isValidAutomergeUrl, stringifyAutomergeUrl as generateAutomergeUrl, } from "./DocUrl.js";
10
10
  export * from "./types.js";
11
+ export * as cbor from "./helpers/cbor.js";
@@ -1,15 +1,14 @@
1
- import EventEmitter from "eventemitter3";
1
+ import { EventEmitter } from "eventemitter3";
2
2
  import { PeerId } from "../types.js";
3
3
  import { Message } from "./messages.js";
4
4
  export declare abstract class NetworkAdapter extends EventEmitter<NetworkAdapterEvents> {
5
5
  peerId?: PeerId;
6
- abstract connect(url?: string): void;
6
+ abstract connect(peerId: PeerId): void;
7
7
  abstract send(message: Message): void;
8
- abstract join(): void;
9
- abstract leave(): void;
8
+ abstract disconnect(): void;
10
9
  }
11
10
  export interface NetworkAdapterEvents {
12
- open: (payload: OpenPayload) => void;
11
+ ready: (payload: OpenPayload) => void;
13
12
  close: () => void;
14
13
  "peer-candidate": (payload: PeerCandidatePayload) => void;
15
14
  "peer-disconnected": (payload: PeerDisconnectedPayload) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkAdapter.d.ts","sourceRoot":"","sources":["../../src/network/NetworkAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,8BAAsB,cAAe,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAEpC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAErC,QAAQ,CAAC,IAAI,IAAI,IAAI;IAErB,QAAQ,CAAC,KAAK,IAAI,IAAI;CACvB;AAID,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAA;IACpC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,gBAAgB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAA;IACzD,mBAAmB,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAA;IAC/D,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,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,8BAAsB,cAAe,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAEtC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAErC,QAAQ,CAAC,UAAU,IAAI,IAAI;CAC5B;AAID,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAA;IACrC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,gBAAgB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAA;IACzD,mBAAmB,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAA;IAC/D,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,4 +1,4 @@
1
- import EventEmitter from "eventemitter3";
1
+ import { EventEmitter } from "eventemitter3";
2
2
  export class NetworkAdapter extends EventEmitter {
3
3
  peerId; // hmmm, maybe not
4
4
  }
@@ -1,21 +1,21 @@
1
- import EventEmitter from "eventemitter3";
1
+ import { EventEmitter } from "eventemitter3";
2
2
  import { PeerId } from "../types.js";
3
3
  import { NetworkAdapter, PeerDisconnectedPayload } from "./NetworkAdapter.js";
4
4
  import { Message, MessageContents } from "./messages.js";
5
5
  export declare class NetworkSubsystem extends EventEmitter<NetworkSubsystemEvents> {
6
6
  #private;
7
- private adapters;
8
7
  peerId: PeerId;
9
8
  constructor(adapters: NetworkAdapter[], peerId?: PeerId);
10
9
  addNetworkAdapter(networkAdapter: NetworkAdapter): void;
11
10
  send(message: MessageContents): void;
12
- join(): void;
13
- leave(): void;
11
+ isReady: () => boolean;
12
+ whenReady: () => Promise<void>;
14
13
  }
15
14
  export interface NetworkSubsystemEvents {
16
15
  peer: (payload: PeerPayload) => void;
17
16
  "peer-disconnected": (payload: PeerDisconnectedPayload) => void;
18
17
  message: (payload: Message) => void;
18
+ ready: () => void;
19
19
  }
20
20
  export interface PeerPayload {
21
21
  peerId: PeerId;
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkSubsystem.d.ts","sourceRoot":"","sources":["../../src/network/NetworkSubsystem.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AACxC,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;;IAStE,OAAO,CAAC,QAAQ;IACT,MAAM;gBADL,QAAQ,EAAE,cAAc,EAAE,EAC3B,MAAM,SAAiB;IAOhC,iBAAiB,CAAC,cAAc,EAAE,cAAc;IA0DhD,IAAI,CAAC,OAAO,EAAE,eAAe;IA2B7B,IAAI;IAKJ,KAAK;CAIN;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;CACpC;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":"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,24 +1,31 @@
1
- import EventEmitter from "eventemitter3";
1
+ import { EventEmitter } from "eventemitter3";
2
2
  import { isEphemeralMessage, isValidMessage, } from "./messages.js";
3
3
  import debug from "debug";
4
4
  const getEphemeralMessageSource = (message) => `${message.senderId}:${message.sessionId}`;
5
5
  export class NetworkSubsystem extends EventEmitter {
6
- adapters;
7
6
  peerId;
8
7
  #log;
9
8
  #adaptersByPeer = {};
10
9
  #count = 0;
11
10
  #sessionId = Math.random().toString(36).slice(2);
12
11
  #ephemeralSessionCounts = {};
12
+ #readyAdapterCount = 0;
13
+ #adapters = [];
13
14
  constructor(adapters, peerId = randomPeerId()) {
14
15
  super();
15
- this.adapters = adapters;
16
16
  this.peerId = peerId;
17
17
  this.#log = debug(`automerge-repo:network:${this.peerId}`);
18
- this.adapters.forEach(a => this.addNetworkAdapter(a));
18
+ adapters.forEach(a => this.addNetworkAdapter(a));
19
19
  }
20
20
  addNetworkAdapter(networkAdapter) {
21
- networkAdapter.connect(this.peerId);
21
+ this.#adapters.push(networkAdapter);
22
+ networkAdapter.once("ready", () => {
23
+ this.#readyAdapterCount++;
24
+ this.#log("Adapters ready: ", this.#readyAdapterCount, "/", this.#adapters.length);
25
+ if (this.#readyAdapterCount === this.#adapters.length) {
26
+ this.emit("ready");
27
+ }
28
+ });
22
29
  networkAdapter.on("peer-candidate", ({ peerId }) => {
23
30
  this.#log(`peer candidate: ${peerId} `);
24
31
  // TODO: This is where authentication would happen
@@ -58,7 +65,7 @@ export class NetworkSubsystem extends EventEmitter {
58
65
  }
59
66
  });
60
67
  });
61
- networkAdapter.join();
68
+ networkAdapter.connect(this.peerId);
62
69
  }
63
70
  send(message) {
64
71
  const peer = this.#adaptersByPeer[message.targetId];
@@ -85,14 +92,21 @@ export class NetworkSubsystem extends EventEmitter {
85
92
  peer.send(outbound);
86
93
  }
87
94
  }
88
- join() {
89
- this.#log(`Joining network`);
90
- this.adapters.forEach(a => a.join());
91
- }
92
- leave() {
93
- this.#log(`Leaving network`);
94
- this.adapters.forEach(a => a.leave());
95
- }
95
+ isReady = () => {
96
+ return this.#readyAdapterCount === this.#adapters.length;
97
+ };
98
+ whenReady = async () => {
99
+ if (this.isReady()) {
100
+ return;
101
+ }
102
+ else {
103
+ return new Promise(resolve => {
104
+ this.once("ready", () => {
105
+ resolve();
106
+ });
107
+ });
108
+ }
109
+ };
96
110
  }
97
111
  function randomPeerId() {
98
112
  return `user-${Math.round(Math.random() * 100000)}`;
@@ -1,5 +1,5 @@
1
- import { SessionId } from "../EphemeralData";
2
- import { DocumentId, PeerId } from "../types";
1
+ import { SessionId } from "../EphemeralData.js";
2
+ import { DocumentId, PeerId } from "../types.js";
3
3
  export declare function isValidMessage(message: NetworkAdapterMessage): message is SyncMessage | EphemeralMessage | RequestMessage | DocumentUnavailableMessage;
4
4
  export declare function isDocumentUnavailableMessage(message: NetworkAdapterMessage): message is DocumentUnavailableMessage;
5
5
  export declare function isRequestMessage(message: NetworkAdapterMessage): message is RequestMessage;
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/network/messages.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAE7C,wBAAgB,cAAc,CAC5B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,IACN,WAAW,GACX,gBAAgB,GAChB,cAAc,GACd,0BAA0B,CAU7B;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,qBAAqB,GAC7B,OAAO,IAAI,0BAA0B,CAEvC;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,IAAI,cAAc,CAE3B;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,IAAI,WAAW,CAExB;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,qBAAqB,GAAG,eAAe,GAC/C,OAAO,IAAI,gBAAgB,GAAG,wBAAwB,CAExD;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,UAAU,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,UAAU,CAAA;CACvB;AAED,MAAM,MAAM,WAAW,GAAG,mBAAmB,GAAG,mBAAmB,CAAA;AAEnE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,SAAS,CAAA;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,UAAU,CAAA;IACtB,IAAI,EAAE,UAAU,CAAA;CACjB;AAED,MAAM,MAAM,gBAAgB,GAAG,wBAAwB,GACrD,wBAAwB,CAAA;AAE1B,MAAM,WAAW,kCAAkC;IACjD,IAAI,EAAE,iBAAiB,CAAA;IACvB,UAAU,EAAE,UAAU,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,GAC1D,kCAAkC,CAAA;AAEpC,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,SAAS,CAAA;IACf,IAAI,EAAE,UAAU,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,UAAU,CAAA;CACvB;AAED,MAAM,MAAM,cAAc,GAAG,mBAAmB,GAAG,sBAAsB,CAAA;AAEzE,MAAM,MAAM,eAAe,GACvB,mBAAmB,GACnB,wBAAwB,GACxB,sBAAsB,GACtB,kCAAkC,CAAA;AAEtC,MAAM,MAAM,OAAO,GACf,WAAW,GACX,gBAAgB,GAChB,cAAc,GACd,0BAA0B,CAAA;AAE9B,MAAM,MAAM,mBAAmB,GAC3B,WAAW,GACX,cAAc,GACd,0BAA0B,GAC1B,gBAAgB,CAAA;AAEpB,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,QAAQ,CAAA;CACf,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,SAAS,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,cAAc,GAAG,OAAO,CAAA"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/network/messages.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEhD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,IACN,WAAW,GACX,gBAAgB,GAChB,cAAc,GACd,0BAA0B,CAU7B;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,qBAAqB,GAC7B,OAAO,IAAI,0BAA0B,CAEvC;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,IAAI,cAAc,CAE3B;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,IAAI,WAAW,CAExB;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,qBAAqB,GAAG,eAAe,GAC/C,OAAO,IAAI,gBAAgB,GAAG,wBAAwB,CAExD;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,UAAU,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,UAAU,CAAA;CACvB;AAED,MAAM,MAAM,WAAW,GAAG,mBAAmB,GAAG,mBAAmB,CAAA;AAEnE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,SAAS,CAAA;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,UAAU,CAAA;IACtB,IAAI,EAAE,UAAU,CAAA;CACjB;AAED,MAAM,MAAM,gBAAgB,GAAG,wBAAwB,GACrD,wBAAwB,CAAA;AAE1B,MAAM,WAAW,kCAAkC;IACjD,IAAI,EAAE,iBAAiB,CAAA;IACvB,UAAU,EAAE,UAAU,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,GAC1D,kCAAkC,CAAA;AAEpC,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,SAAS,CAAA;IACf,IAAI,EAAE,UAAU,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,UAAU,CAAA;CACvB;AAED,MAAM,MAAM,cAAc,GAAG,mBAAmB,GAAG,sBAAsB,CAAA;AAEzE,MAAM,MAAM,eAAe,GACvB,mBAAmB,GACnB,wBAAwB,GACxB,sBAAsB,GACtB,kCAAkC,CAAA;AAEtC,MAAM,MAAM,OAAO,GACf,WAAW,GACX,gBAAgB,GAChB,cAAc,GACd,0BAA0B,CAAA;AAE9B,MAAM,MAAM,mBAAmB,GAC3B,WAAW,GACX,cAAc,GACd,0BAA0B,GAC1B,gBAAgB,CAAA;AAEpB,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,QAAQ,CAAA;CACf,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,SAAS,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,cAAc,GAAG,OAAO,CAAA"}
@@ -1,4 +1,4 @@
1
- import * as A from "@automerge/automerge";
1
+ import * as A from "@automerge/automerge/next";
2
2
  import { StorageAdapter } from "./StorageAdapter.js";
3
3
  import { type DocumentId } from "../types.js";
4
4
  export type ChunkType = "snapshot" | "incremental";
@@ -1 +1 @@
1
- {"version":3,"file":"StorageSubsystem.d.ts","sourceRoot":"","sources":["../../src/storage/StorageSubsystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,sBAAsB,CAAA;AACzC,OAAO,EAAE,cAAc,EAAc,MAAM,qBAAqB,CAAA;AAEhE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAa7C,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,aAAa,CAAA;AAelD,qBAAa,gBAAgB;;gBAMf,cAAc,EAAE,cAAc;IAqDpC,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IA0B/D,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAanE,MAAM,CAAC,UAAU,EAAE,UAAU;CAgCpC"}
1
+ {"version":3,"file":"StorageSubsystem.d.ts","sourceRoot":"","sources":["../../src/storage/StorageSubsystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,2BAA2B,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAc,MAAM,qBAAqB,CAAA;AAEhE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAa7C,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,aAAa,CAAA;AAelD,qBAAa,gBAAgB;;gBAQf,cAAc,EAAE,cAAc;IAuDpC,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IA0B/D,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAanE,MAAM,CAAC,UAAU,EAAE,UAAU;CAmCpC"}
@@ -1,4 +1,4 @@
1
- import * as A from "@automerge/automerge";
1
+ import * as A from "@automerge/automerge/next";
2
2
  import * as sha256 from "fast-sha256";
3
3
  import { mergeArrays } from "../helpers/mergeArrays.js";
4
4
  import debug from "debug";
@@ -11,7 +11,7 @@ function keyHash(binary) {
11
11
  }
12
12
  function headsHash(heads) {
13
13
  let encoder = new TextEncoder();
14
- let headsbinary = mergeArrays(heads.map(h => encoder.encode(h)));
14
+ let headsbinary = mergeArrays(heads.map((h) => encoder.encode(h)));
15
15
  return keyHash(headsbinary);
16
16
  }
17
17
  export class StorageSubsystem {
@@ -19,6 +19,7 @@ export class StorageSubsystem {
19
19
  #chunkInfos = new Map();
20
20
  #storedHeads = new Map();
21
21
  #log = debug(`automerge-repo:storage-subsystem`);
22
+ #snapshotting = false;
22
23
  constructor(storageAdapter) {
23
24
  this.#storageAdapter = storageAdapter;
24
25
  }
@@ -43,6 +44,7 @@ export class StorageSubsystem {
43
44
  }
44
45
  }
45
46
  async #saveTotal(documentId, doc, sourceChunks) {
47
+ this.#snapshotting = true;
46
48
  const binary = A.save(doc);
47
49
  const snapshotHash = headsHash(A.getHeads(doc));
48
50
  const key = [documentId, "snapshot", snapshotHash];
@@ -56,6 +58,7 @@ export class StorageSubsystem {
56
58
  const newChunkInfos = this.#chunkInfos.get(documentId)?.filter(c => !oldKeys.has(c.key)) ?? [];
57
59
  newChunkInfos.push({ key, type: "snapshot", size: binary.length });
58
60
  this.#chunkInfos.set(documentId, newChunkInfos);
61
+ this.#snapshotting = false;
59
62
  }
60
63
  async loadDoc(documentId) {
61
64
  const loaded = await this.#storageAdapter.loadRange([documentId]);
@@ -96,7 +99,7 @@ export class StorageSubsystem {
96
99
  this.#storedHeads.set(documentId, A.getHeads(doc));
97
100
  }
98
101
  async remove(documentId) {
99
- this.#storageAdapter.remove([documentId, "snapshot"]);
102
+ this.#storageAdapter.removeRange([documentId, "snapshot"]);
100
103
  this.#storageAdapter.removeRange([documentId, "incremental"]);
101
104
  }
102
105
  #shouldSave(documentId, doc) {
@@ -111,6 +114,9 @@ export class StorageSubsystem {
111
114
  return true;
112
115
  }
113
116
  #shouldCompact(sourceChunks) {
117
+ if (this.#snapshotting) {
118
+ return false;
119
+ }
114
120
  // compact if the incremental size is greater than the snapshot size
115
121
  let snapshotSize = 0;
116
122
  let incrementalSize = 0;
@@ -122,7 +128,7 @@ export class StorageSubsystem {
122
128
  incrementalSize += chunk.size;
123
129
  }
124
130
  }
125
- return incrementalSize > snapshotSize;
131
+ return incrementalSize >= snapshotSize;
126
132
  }
127
133
  }
128
134
  function chunkTypeFromKey(key) {
@@ -1 +1 @@
1
- {"version":3,"file":"DocSynchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/DocSynchronizer.ts"],"names":[],"mappings":"AACA,OAAO,EACL,SAAS,EAKV,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGhD,OAAO,EACL,gBAAgB,EAIhB,cAAc,EACd,mBAAmB,EACnB,WAAW,EACZ,MAAM,wBAAwB,CAAA;AAE/B,KAAK,kBAAkB,GAAG,SAAS,GAAG,KAAK,GAAG,aAAa,GAAG,OAAO,CAAA;AAGrE;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,YAAY;;IAiBnC,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC;IAoB1C,IAAI,UAAU,uCAEb;IAED,IAAI,UAAU,qCAEb;IAiHD,OAAO,CAAC,MAAM,EAAE,MAAM;IAItB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE;IA8B3B,OAAO,CAAC,MAAM,EAAE,MAAM;IAKtB,cAAc,CAAC,OAAO,EAAE,mBAAmB;IAkB3C,uBAAuB,CAAC,OAAO,EAAE,gBAAgB;IAuBjD,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc;CA2EzD"}
1
+ {"version":3,"file":"DocSynchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/DocSynchronizer.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,SAAS,EAKV,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGhD,OAAO,EACL,gBAAgB,EAIhB,cAAc,EACd,mBAAmB,EACnB,WAAW,EACZ,MAAM,wBAAwB,CAAA;AAE/B,KAAK,kBAAkB,GAAG,SAAS,GAAG,KAAK,GAAG,aAAa,GAAG,OAAO,CAAA;AAGrE;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,YAAY;;IAiBnC,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC;IAoB1C,IAAI,UAAU,uCAEb;IAED,IAAI,UAAU,qCAEb;IAiHD,OAAO,CAAC,MAAM,EAAE,MAAM;IAItB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE;IA6B3B,OAAO,CAAC,MAAM,EAAE,MAAM;IAKtB,cAAc,CAAC,OAAO,EAAE,mBAAmB;IAkB3C,uBAAuB,CAAC,OAAO,EAAE,gBAAgB;IAuBjD,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc;CA2EzD"}