@automerge/automerge-repo 1.0.0-alpha.2 → 1.0.0-alpha.4

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 (80) hide show
  1. package/dist/DocCollection.d.ts +4 -2
  2. package/dist/DocCollection.d.ts.map +1 -1
  3. package/dist/DocCollection.js +20 -11
  4. package/dist/DocHandle.d.ts +34 -6
  5. package/dist/DocHandle.d.ts.map +1 -1
  6. package/dist/DocHandle.js +69 -9
  7. package/dist/DocUrl.d.ts +4 -4
  8. package/dist/DocUrl.d.ts.map +1 -1
  9. package/dist/DocUrl.js +9 -9
  10. package/dist/EphemeralData.d.ts +8 -16
  11. package/dist/EphemeralData.d.ts.map +1 -1
  12. package/dist/EphemeralData.js +1 -28
  13. package/dist/Repo.d.ts +0 -2
  14. package/dist/Repo.d.ts.map +1 -1
  15. package/dist/Repo.js +37 -39
  16. package/dist/helpers/cbor.d.ts +4 -0
  17. package/dist/helpers/cbor.d.ts.map +1 -0
  18. package/dist/helpers/cbor.js +8 -0
  19. package/dist/helpers/eventPromise.d.ts +1 -1
  20. package/dist/helpers/eventPromise.d.ts.map +1 -1
  21. package/dist/helpers/headsAreSame.d.ts +0 -1
  22. package/dist/helpers/headsAreSame.d.ts.map +1 -1
  23. package/dist/helpers/tests/network-adapter-tests.d.ts.map +1 -1
  24. package/dist/helpers/tests/network-adapter-tests.js +15 -13
  25. package/dist/index.d.ts +3 -1
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +1 -0
  28. package/dist/network/NetworkAdapter.d.ts +6 -15
  29. package/dist/network/NetworkAdapter.d.ts.map +1 -1
  30. package/dist/network/NetworkAdapter.js +1 -1
  31. package/dist/network/NetworkSubsystem.d.ts +9 -6
  32. package/dist/network/NetworkSubsystem.d.ts.map +1 -1
  33. package/dist/network/NetworkSubsystem.js +69 -32
  34. package/dist/network/messages.d.ts +57 -0
  35. package/dist/network/messages.d.ts.map +1 -0
  36. package/dist/network/messages.js +21 -0
  37. package/dist/storage/StorageSubsystem.d.ts +1 -1
  38. package/dist/storage/StorageSubsystem.d.ts.map +1 -1
  39. package/dist/storage/StorageSubsystem.js +2 -2
  40. package/dist/synchronizer/CollectionSynchronizer.d.ts +3 -2
  41. package/dist/synchronizer/CollectionSynchronizer.d.ts.map +1 -1
  42. package/dist/synchronizer/CollectionSynchronizer.js +19 -13
  43. package/dist/synchronizer/DocSynchronizer.d.ts +9 -3
  44. package/dist/synchronizer/DocSynchronizer.d.ts.map +1 -1
  45. package/dist/synchronizer/DocSynchronizer.js +149 -34
  46. package/dist/synchronizer/Synchronizer.d.ts +4 -5
  47. package/dist/synchronizer/Synchronizer.d.ts.map +1 -1
  48. package/dist/synchronizer/Synchronizer.js +1 -1
  49. package/dist/types.d.ts +1 -3
  50. package/dist/types.d.ts.map +1 -1
  51. package/fuzz/fuzz.ts +5 -5
  52. package/package.json +3 -3
  53. package/src/DocCollection.ts +23 -12
  54. package/src/DocHandle.ts +120 -13
  55. package/src/DocUrl.ts +10 -10
  56. package/src/EphemeralData.ts +6 -36
  57. package/src/Repo.ts +37 -55
  58. package/src/helpers/cbor.ts +10 -0
  59. package/src/helpers/eventPromise.ts +1 -1
  60. package/src/helpers/headsAreSame.ts +1 -1
  61. package/src/helpers/tests/network-adapter-tests.ts +18 -14
  62. package/src/index.ts +14 -2
  63. package/src/network/NetworkAdapter.ts +6 -22
  64. package/src/network/NetworkSubsystem.ts +94 -44
  65. package/src/network/messages.ts +123 -0
  66. package/src/storage/StorageSubsystem.ts +2 -2
  67. package/src/synchronizer/CollectionSynchronizer.ts +38 -19
  68. package/src/synchronizer/DocSynchronizer.ts +201 -43
  69. package/src/synchronizer/Synchronizer.ts +4 -9
  70. package/src/types.ts +4 -1
  71. package/test/CollectionSynchronizer.test.ts +6 -7
  72. package/test/DocCollection.test.ts +2 -2
  73. package/test/DocHandle.test.ts +32 -17
  74. package/test/DocSynchronizer.test.ts +85 -9
  75. package/test/Repo.test.ts +267 -63
  76. package/test/StorageSubsystem.test.ts +4 -5
  77. package/test/helpers/DummyNetworkAdapter.ts +12 -3
  78. package/test/helpers/DummyStorageAdapter.ts +1 -1
  79. package/tsconfig.json +4 -3
  80. package/test/EphemeralData.test.ts +0 -44
@@ -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";
@@ -33,12 +33,14 @@ export declare class DocCollection extends EventEmitter<DocCollectionEvents> {
33
33
  interface DocCollectionEvents {
34
34
  document: (arg: DocumentPayload) => void;
35
35
  "delete-document": (arg: DeleteDocumentPayload) => void;
36
+ "unavailable-document": (arg: DeleteDocumentPayload) => void;
36
37
  }
37
38
  interface DocumentPayload {
38
39
  handle: DocHandle<any>;
40
+ isNew: boolean;
39
41
  }
40
42
  interface DeleteDocumentPayload {
41
- encodedDocumentId: DocumentId;
43
+ documentId: DocumentId;
42
44
  }
43
45
  export {};
44
46
  //# sourceMappingURL=DocCollection.d.ts.map
@@ -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;IAef,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;CACxD;AAED,UAAU,eAAe;IACvB,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;CACvB;AAED,UAAU,qBAAqB;IAC7B,iBAAiB,EAAE,UAAU,CAAA;CAC9B"}
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
  /**
@@ -53,9 +53,9 @@ export class DocCollection extends EventEmitter {
53
53
  // or
54
54
  // - pass a "reify" function that takes a `<any>` and returns `<T>`
55
55
  // Generate a new UUID and store it in the buffer
56
- const { encodedDocumentId } = parseAutomergeUrl(generateAutomergeUrl());
57
- const handle = this.#getHandle(encodedDocumentId, true);
58
- this.emit("document", { handle });
56
+ const { documentId } = parseAutomergeUrl(generateAutomergeUrl());
57
+ const handle = this.#getHandle(documentId, true);
58
+ this.emit("document", { handle, isNew: true });
59
59
  return handle;
60
60
  }
61
61
  /**
@@ -68,12 +68,21 @@ export class DocCollection extends EventEmitter {
68
68
  if (!isValidAutomergeUrl(automergeUrl)) {
69
69
  throw new Error(`Invalid AutomergeUrl: '${automergeUrl}'`);
70
70
  }
71
- const { encodedDocumentId } = parseAutomergeUrl(automergeUrl);
71
+ const { documentId } = parseAutomergeUrl(automergeUrl);
72
72
  // If we have the handle cached, return it
73
- if (this.#handleCache[encodedDocumentId])
74
- return this.#handleCache[encodedDocumentId];
75
- const handle = this.#getHandle(encodedDocumentId, false);
76
- this.emit("document", { handle });
73
+ if (this.#handleCache[documentId]) {
74
+ if (this.#handleCache[documentId].isUnavailable()) {
75
+ // this ensures that the event fires after the handle has been returned
76
+ setTimeout(() => {
77
+ this.#handleCache[documentId].emit("unavailable", {
78
+ handle: this.#handleCache[documentId],
79
+ });
80
+ });
81
+ }
82
+ return this.#handleCache[documentId];
83
+ }
84
+ const handle = this.#getHandle(documentId, false);
85
+ this.emit("document", { handle, isNew: false });
77
86
  return handle;
78
87
  }
79
88
  delete(
@@ -81,13 +90,13 @@ export class DocCollection extends EventEmitter {
81
90
  id) {
82
91
  if (isValidAutomergeUrl(id)) {
83
92
  ;
84
- ({ encodedDocumentId: id } = parseAutomergeUrl(id));
93
+ ({ documentId: id } = parseAutomergeUrl(id));
85
94
  }
86
95
  const handle = this.#getHandle(id, false);
87
96
  handle.delete();
88
97
  delete this.#handleCache[id];
89
98
  this.emit("delete-document", {
90
- encodedDocumentId: id,
99
+ documentId: id,
91
100
  });
92
101
  }
93
102
  }
@@ -1,7 +1,7 @@
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
- import type { ChannelId, DocumentId, PeerId, AutomergeUrl } from "./types.js";
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. */
6
6
  export declare class DocHandle<T>//
7
7
  extends EventEmitter<DocHandleEvents<T>> {
@@ -22,6 +22,7 @@ export declare class DocHandle<T>//
22
22
  * @returns true if the document has been marked as deleted
23
23
  */
24
24
  isDeleted: () => boolean;
25
+ isUnavailable: () => boolean;
25
26
  inState: (states: HandleState[]) => boolean;
26
27
  get state(): StateValue;
27
28
  /**
@@ -38,7 +39,7 @@ export declare class DocHandle<T>//
38
39
  *
39
40
  * @param {awaitStates=[READY]} optional states to wait for, such as "LOADING". mostly for internal use.
40
41
  */
41
- doc(awaitStates?: HandleState[]): Promise<A.Doc<T>>;
42
+ doc(awaitStates?: HandleState[]): Promise<A.Doc<T> | undefined>;
42
43
  /**
43
44
  * Returns the current state of the Automerge document this handle manages, or undefined.
44
45
  * Useful in a synchronous context. Consider using `await handle.doc()` instead, check `isReady()`,
@@ -55,10 +56,20 @@ export declare class DocHandle<T>//
55
56
  /** `change` is called by the repo when the document is changed locally */
56
57
  change(callback: A.ChangeFn<T>, options?: A.ChangeOptions<T>): void;
57
58
  changeAt(heads: A.Heads, callback: A.ChangeFn<T>, options?: A.ChangeOptions<T>): void;
59
+ unavailable(): void;
58
60
  /** `request` is called by the repo when the document is not found in storage */
59
61
  request(): void;
62
+ awaitNetwork(): void;
63
+ networkReady(): void;
60
64
  /** `delete` is called by the repo when the document is deleted */
61
65
  delete(): void;
66
+ /** `broadcast` sends an arbitrary ephemeral message out to all reachable peers who would receive sync messages from you
67
+ * it has no guarantee of delivery, and is not persisted to the underlying automerge doc in any way.
68
+ * messages will have a sending PeerId but this is *not* a useful user identifier.
69
+ * a user could have multiple tabs open and would appear as multiple PeerIds.
70
+ * every message source must have a unique PeerId.
71
+ */
72
+ broadcast(message: any): void;
62
73
  }
63
74
  interface DocHandleOptions {
64
75
  isNew?: boolean;
@@ -66,7 +77,7 @@ interface DocHandleOptions {
66
77
  }
67
78
  export interface DocHandleMessagePayload {
68
79
  destinationId: PeerId;
69
- channelId: ChannelId;
80
+ documentId: DocumentId;
70
81
  data: Uint8Array;
71
82
  }
72
83
  export interface DocHandleEncodedChangePayload<T> {
@@ -82,18 +93,32 @@ export interface DocHandleChangePayload<T> {
82
93
  patches: A.Patch[];
83
94
  patchInfo: A.PatchInfo<T>;
84
95
  }
96
+ export interface DocHandleEphemeralMessagePayload {
97
+ handle: DocHandle<any>;
98
+ senderId: PeerId;
99
+ message: unknown;
100
+ }
101
+ export interface DocHandleOutboundEphemeralMessagePayload {
102
+ handle: DocHandle<any>;
103
+ data: Uint8Array;
104
+ }
85
105
  export interface DocHandleEvents<T> {
86
106
  "heads-changed": (payload: DocHandleEncodedChangePayload<T>) => void;
87
107
  change: (payload: DocHandleChangePayload<T>) => void;
88
108
  delete: (payload: DocHandleDeletePayload<T>) => void;
109
+ unavailable: (payload: DocHandleDeletePayload<T>) => void;
110
+ "ephemeral-message": (payload: DocHandleEphemeralMessagePayload) => void;
111
+ "ephemeral-message-outbound": (payload: DocHandleOutboundEphemeralMessagePayload) => void;
89
112
  }
90
113
  export declare const HandleState: {
91
114
  readonly IDLE: "idle";
92
115
  readonly LOADING: "loading";
116
+ readonly AWAITING_NETWORK: "awaitingNetwork";
93
117
  readonly REQUESTING: "requesting";
94
118
  readonly READY: "ready";
95
119
  readonly FAILED: "failed";
96
120
  readonly DELETED: "deleted";
121
+ readonly UNAVAILABLE: "unavailable";
97
122
  };
98
123
  export type HandleState = (typeof HandleState)[keyof typeof HandleState];
99
124
  export declare const Event: {
@@ -101,10 +126,13 @@ export declare const Event: {
101
126
  readonly FIND: "FIND";
102
127
  readonly REQUEST: "REQUEST";
103
128
  readonly REQUEST_COMPLETE: "REQUEST_COMPLETE";
129
+ readonly AWAIT_NETWORK: "AWAIT_NETWORK";
130
+ readonly NETWORK_READY: "NETWORK_READY";
104
131
  readonly UPDATE: "UPDATE";
105
132
  readonly TIMEOUT: "TIMEOUT";
106
133
  readonly DELETE: "DELETE";
134
+ readonly MARK_UNAVAILABLE: "MARK_UNAVAILABLE";
107
135
  };
108
- export declare const IDLE: "idle", LOADING: "loading", REQUESTING: "requesting", READY: "ready", FAILED: "failed", DELETED: "deleted";
136
+ export declare const IDLE: "idle", LOADING: "loading", AWAITING_NETWORK: "awaitingNetwork", REQUESTING: "requesting", READY: "ready", FAILED: "failed", DELETED: "deleted", UNAVAILABLE: "unavailable";
109
137
  export {};
110
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,12 +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 "./helpers/cbor.js";
10
11
  /** DocHandle is a wrapper around a single Automerge document that lets us listen for changes. */
11
12
  export class DocHandle//
12
13
  extends EventEmitter {
@@ -23,7 +24,11 @@ export class DocHandle//
23
24
  this.#timeoutDelay = timeoutDelay;
24
25
  this.#log = debug(`automerge-repo:dochandle:${this.documentId.slice(0, 5)}`);
25
26
  // initial doc
26
- 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
+ }
27
32
  /**
28
33
  * Internally we use a state machine to orchestrate document loading and/or syncing, in order to
29
34
  * avoid requesting data we already have, or surfacing intermediate values to the consumer.
@@ -58,6 +63,8 @@ export class DocHandle//
58
63
  UPDATE: { actions: "onUpdate", target: READY },
59
64
  // REQUEST is called by the Repo if the document is not found in storage
60
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 },
61
68
  DELETE: { actions: "onDelete", target: DELETED },
62
69
  },
63
70
  after: [
@@ -67,8 +74,17 @@ export class DocHandle//
67
74
  },
68
75
  ],
69
76
  },
77
+ awaitingNetwork: {
78
+ on: {
79
+ NETWORK_READY: { target: REQUESTING },
80
+ }
81
+ },
70
82
  requesting: {
71
83
  on: {
84
+ MARK_UNAVAILABLE: {
85
+ target: UNAVAILABLE,
86
+ actions: "onUnavailable",
87
+ },
72
88
  // UPDATE is called by the Repo when we receive changes from the network
73
89
  UPDATE: { actions: "onUpdate" },
74
90
  // REQUEST_COMPLETE is called from `onUpdate` when the doc has been fully loaded from the network
@@ -95,6 +111,14 @@ export class DocHandle//
95
111
  deleted: {
96
112
  type: "final",
97
113
  },
114
+ unavailable: {
115
+ on: {
116
+ UPDATE: { actions: "onUpdate" },
117
+ // REQUEST_COMPLETE is called from `onUpdate` when the doc has been fully loaded from the network
118
+ REQUEST_COMPLETE: { target: READY },
119
+ DELETE: { actions: "onDelete", target: DELETED },
120
+ },
121
+ },
98
122
  },
99
123
  }, {
100
124
  actions: {
@@ -109,13 +133,20 @@ export class DocHandle//
109
133
  this.emit("delete", { handle: this });
110
134
  return { doc: undefined };
111
135
  }),
136
+ onUnavailable: assign(context => {
137
+ const { doc } = context;
138
+ this.emit("unavailable", { handle: this });
139
+ return { doc };
140
+ }),
112
141
  },
113
142
  }))
114
143
  .onTransition(({ value: state, history, context }, event) => {
115
144
  const oldDoc = history?.context?.doc;
116
145
  const newDoc = context.doc;
117
- console.log(`${event} → ${state}`, newDoc);
118
- const docChanged = newDoc && oldDoc && !headsAreSame(A.getHeads(newDoc), A.getHeads(oldDoc));
146
+ this.#log(`${history?.value}: ${event.type} → ${state}`, newDoc);
147
+ const docChanged = newDoc &&
148
+ oldDoc &&
149
+ !headsAreSame(A.getHeads(newDoc), A.getHeads(oldDoc));
119
150
  if (docChanged) {
120
151
  this.emit("heads-changed", { handle: this, doc: newDoc });
121
152
  const patches = A.diff(newDoc, A.getHeads(oldDoc), A.getHeads(newDoc));
@@ -167,6 +198,7 @@ export class DocHandle//
167
198
  * @returns true if the document has been marked as deleted
168
199
  */
169
200
  isDeleted = () => this.inState([HandleState.DELETED]);
201
+ isUnavailable = () => this.inState([HandleState.UNAVAILABLE]);
170
202
  inState = (states) => states.some(this.#machine?.getSnapshot().matches);
171
203
  get state() {
172
204
  return this.#machine?.getSnapshot().value;
@@ -187,7 +219,7 @@ export class DocHandle//
187
219
  *
188
220
  * @param {awaitStates=[READY]} optional states to wait for, such as "LOADING". mostly for internal use.
189
221
  */
190
- async doc(awaitStates = [READY]) {
222
+ async doc(awaitStates = [READY, UNAVAILABLE]) {
191
223
  await pause(); // yield one tick because reasons
192
224
  try {
193
225
  // wait for the document to enter one of the desired states
@@ -200,7 +232,7 @@ export class DocHandle//
200
232
  throw error;
201
233
  }
202
234
  // Return the document
203
- return this.#doc;
235
+ return !this.isUnavailable() ? this.#doc : undefined;
204
236
  }
205
237
  /**
206
238
  * Returns the current state of the Automerge document this handle manages, or undefined.
@@ -249,25 +281,50 @@ export class DocHandle//
249
281
  },
250
282
  });
251
283
  }
284
+ unavailable() {
285
+ this.#machine.send(MARK_UNAVAILABLE);
286
+ }
252
287
  /** `request` is called by the repo when the document is not found in storage */
253
288
  request() {
254
289
  if (this.#state === LOADING)
255
290
  this.#machine.send(REQUEST);
256
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
+ }
257
300
  /** `delete` is called by the repo when the document is deleted */
258
301
  delete() {
259
302
  this.#machine.send(DELETE);
260
303
  }
304
+ /** `broadcast` sends an arbitrary ephemeral message out to all reachable peers who would receive sync messages from you
305
+ * it has no guarantee of delivery, and is not persisted to the underlying automerge doc in any way.
306
+ * messages will have a sending PeerId but this is *not* a useful user identifier.
307
+ * a user could have multiple tabs open and would appear as multiple PeerIds.
308
+ * every message source must have a unique PeerId.
309
+ */
310
+ broadcast(message) {
311
+ this.emit("ephemeral-message-outbound", {
312
+ handle: this,
313
+ data: encode(message),
314
+ });
315
+ }
261
316
  }
262
317
  // STATE MACHINE TYPES
263
318
  // state
264
319
  export const HandleState = {
265
320
  IDLE: "idle",
266
321
  LOADING: "loading",
322
+ AWAITING_NETWORK: "awaitingNetwork",
267
323
  REQUESTING: "requesting",
268
324
  READY: "ready",
269
325
  FAILED: "failed",
270
326
  DELETED: "deleted",
327
+ UNAVAILABLE: "unavailable",
271
328
  };
272
329
  // events
273
330
  export const Event = {
@@ -275,10 +332,13 @@ export const Event = {
275
332
  FIND: "FIND",
276
333
  REQUEST: "REQUEST",
277
334
  REQUEST_COMPLETE: "REQUEST_COMPLETE",
335
+ AWAIT_NETWORK: "AWAIT_NETWORK",
336
+ NETWORK_READY: "NETWORK_READY",
278
337
  UPDATE: "UPDATE",
279
338
  TIMEOUT: "TIMEOUT",
280
339
  DELETE: "DELETE",
340
+ MARK_UNAVAILABLE: "MARK_UNAVAILABLE",
281
341
  };
282
342
  // CONSTANTS
283
- export const { IDLE, LOADING, REQUESTING, READY, FAILED, DELETED } = HandleState;
284
- const { CREATE, FIND, REQUEST, UPDATE, TIMEOUT, DELETE, REQUEST_COMPLETE } = 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,14 +1,14 @@
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)
5
5
  *
6
6
  * @param url
7
- * @returns { documentId: Uint8Array(16), encodedDocumentId: bs58check.encode(documentId) }
7
+ * @returns { binaryDocumentId: BinaryDocumentId, documentId: DocumentId }
8
8
  */
9
9
  export declare const parseAutomergeUrl: (url: AutomergeUrl) => {
10
10
  binaryDocumentId: BinaryDocumentId;
11
- encodedDocumentId: DocumentId;
11
+ documentId: DocumentId;
12
12
  };
13
13
  interface StringifyAutomergeUrlOptions {
14
14
  documentId: DocumentId | BinaryDocumentId;
@@ -17,7 +17,7 @@ interface StringifyAutomergeUrlOptions {
17
17
  * Given a documentId in either canonical form, return an Automerge URL
18
18
  * Throws on invalid input.
19
19
  * Note: this is an object because we anticipate adding fields in the future.
20
- * @param { documentId: EncodedDocumentId | DocumentId }
20
+ * @param { documentId: BinaryDocumentId | DocumentId }
21
21
  * @returns AutomergeUrl
22
22
  */
23
23
  export declare const stringifyAutomergeUrl: ({ documentId, }: StringifyAutomergeUrlOptions) => AutomergeUrl;
@@ -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"}
package/dist/DocUrl.js CHANGED
@@ -5,19 +5,19 @@ export const urlPrefix = "automerge:";
5
5
  * given an Automerge URL, return a decoded DocumentId (and the encoded DocumentId)
6
6
  *
7
7
  * @param url
8
- * @returns { documentId: Uint8Array(16), encodedDocumentId: bs58check.encode(documentId) }
8
+ * @returns { binaryDocumentId: BinaryDocumentId, documentId: DocumentId }
9
9
  */
10
10
  export const parseAutomergeUrl = (url) => {
11
- const { binaryDocumentId: binaryDocumentId, encodedDocumentId } = parts(url);
11
+ const { binaryDocumentId, documentId } = parts(url);
12
12
  if (!binaryDocumentId)
13
13
  throw new Error("Invalid document URL: " + url);
14
- return { binaryDocumentId, encodedDocumentId };
14
+ return { binaryDocumentId, documentId };
15
15
  };
16
16
  /**
17
17
  * Given a documentId in either canonical form, return an Automerge URL
18
18
  * Throws on invalid input.
19
19
  * Note: this is an object because we anticipate adding fields in the future.
20
- * @param { documentId: EncodedDocumentId | DocumentId }
20
+ * @param { documentId: BinaryDocumentId | DocumentId }
21
21
  * @returns AutomergeUrl
22
22
  */
23
23
  export const stringifyAutomergeUrl = ({ documentId, }) => {
@@ -56,12 +56,12 @@ export const binaryToDocumentId = (docId) => bs58check.encode(docId);
56
56
  * eventually this could include things like heads, so we use this structure
57
57
  * we return both a binary & string-encoded version of the document ID
58
58
  * @param str
59
- * @returns { binaryDocumentId, encodedDocumentId }
59
+ * @returns { binaryDocumentId, documentId }
60
60
  */
61
61
  const parts = (str) => {
62
62
  const regex = new RegExp(`^${urlPrefix}(\\w+)$`);
63
- const [m, docMatch] = str.match(regex) || [];
64
- const encodedDocumentId = docMatch;
65
- const binaryDocumentId = documentIdToBinary(encodedDocumentId);
66
- return { binaryDocumentId, encodedDocumentId };
63
+ const [_, docMatch] = str.match(regex) || [];
64
+ const documentId = docMatch;
65
+ const binaryDocumentId = documentIdToBinary(documentId);
66
+ return { binaryDocumentId, documentId };
67
67
  };
@@ -1,27 +1,19 @@
1
- import EventEmitter from "eventemitter3";
2
- import { ChannelId, PeerId } from "./index.js";
3
- import { MessagePayload } from "./network/NetworkAdapter.js";
4
- /**
5
- * EphemeralData provides a mechanism to broadcast short-lived data — cursor positions, presence,
6
- * heartbeats, etc. — that is useful in the moment but not worth persisting.
7
- */
8
- export declare class EphemeralData extends EventEmitter<EphemeralDataMessageEvents> {
9
- /** Broadcast an ephemeral message */
10
- broadcast(channelId: ChannelId, message: unknown): void;
11
- /** Receive an ephemeral message */
12
- receive(senderId: PeerId, grossChannelId: ChannelId, message: Uint8Array): void;
13
- }
1
+ import { DocumentId, PeerId } from "./index.js";
2
+ import { EphemeralMessageContents } from "./network/messages.js";
3
+ export type SessionId = string & {
4
+ __SessionId: false;
5
+ };
14
6
  export interface EphemeralDataPayload {
15
- channelId: ChannelId;
7
+ documentId: DocumentId;
16
8
  peerId: PeerId;
17
9
  data: {
18
10
  peerId: PeerId;
19
- channelId: ChannelId;
11
+ documentId: DocumentId;
20
12
  data: unknown;
21
13
  };
22
14
  }
23
15
  export type EphemeralDataMessageEvents = {
24
- message: (event: MessagePayload) => void;
16
+ message: (event: EphemeralMessageContents) => void;
25
17
  data: (event: EphemeralDataPayload) => void;
26
18
  };
27
19
  //# sourceMappingURL=EphemeralData.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EphemeralData.d.ts","sourceRoot":"","sources":["../src/EphemeralData.ts"],"names":[],"mappings":"AACA,OAAO,YAAY,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAE5D;;;GAGG;AACH,qBAAa,aAAc,SAAQ,YAAY,CAAC,0BAA0B,CAAC;IACzE,qCAAqC;IACrC,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO;IAWhD,mCAAmC;IACnC,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU;CASzE;AAID,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,SAAS,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,SAAS,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAA;CAC9D;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAA;IACxC,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,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAGhE,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,28 +1 @@
1
- import { decode, encode } from "cbor-x";
2
- import EventEmitter from "eventemitter3";
3
- /**
4
- * EphemeralData provides a mechanism to broadcast short-lived data — cursor positions, presence,
5
- * heartbeats, etc. — that is useful in the moment but not worth persisting.
6
- */
7
- export class EphemeralData extends EventEmitter {
8
- /** Broadcast an ephemeral message */
9
- broadcast(channelId, message) {
10
- const messageBytes = encode(message);
11
- this.emit("message", {
12
- targetId: "*",
13
- channelId: ("m/" + channelId),
14
- message: messageBytes,
15
- broadcast: true,
16
- });
17
- }
18
- /** Receive an ephemeral message */
19
- receive(senderId, grossChannelId, message) {
20
- const data = decode(message);
21
- const channelId = grossChannelId.slice(2);
22
- this.emit("data", {
23
- peerId: senderId,
24
- channelId,
25
- data,
26
- });
27
- }
28
- }
1
+ export {};
package/dist/Repo.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { DocCollection } from "./DocCollection.js";
2
- import { EphemeralData } from "./EphemeralData.js";
3
2
  import { NetworkAdapter } from "./network/NetworkAdapter.js";
4
3
  import { NetworkSubsystem } from "./network/NetworkSubsystem.js";
5
4
  import { StorageAdapter } from "./storage/StorageAdapter.js";
@@ -10,7 +9,6 @@ export declare class Repo extends DocCollection {
10
9
  #private;
11
10
  networkSubsystem: NetworkSubsystem;
12
11
  storageSubsystem?: StorageSubsystem;
13
- ephemeralData: EphemeralData;
14
12
  constructor({ storage, network, peerId, sharePolicy }: RepoConfig);
15
13
  }
16
14
  export interface RepoConfig {
@@ -1 +1 @@
1
- {"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../src/Repo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,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;AAI/C,oFAAoF;AACpF,qBAAa,IAAK,SAAQ,aAAa;;IAGrC,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,aAAa,EAAE,aAAa,CAAA;gBAEhB,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,UAAU;CAgHlE;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"}