@automerge/automerge-repo 2.0.0-alpha.7 → 2.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +8 -8
  2. package/dist/AutomergeUrl.d.ts +17 -5
  3. package/dist/AutomergeUrl.d.ts.map +1 -1
  4. package/dist/AutomergeUrl.js +71 -24
  5. package/dist/DocHandle.d.ts +68 -45
  6. package/dist/DocHandle.d.ts.map +1 -1
  7. package/dist/DocHandle.js +166 -69
  8. package/dist/FindProgress.d.ts +30 -0
  9. package/dist/FindProgress.d.ts.map +1 -0
  10. package/dist/FindProgress.js +1 -0
  11. package/dist/RemoteHeadsSubscriptions.d.ts +4 -5
  12. package/dist/RemoteHeadsSubscriptions.d.ts.map +1 -1
  13. package/dist/RemoteHeadsSubscriptions.js +4 -1
  14. package/dist/Repo.d.ts +46 -6
  15. package/dist/Repo.d.ts.map +1 -1
  16. package/dist/Repo.js +252 -67
  17. package/dist/helpers/abortable.d.ts +39 -0
  18. package/dist/helpers/abortable.d.ts.map +1 -0
  19. package/dist/helpers/abortable.js +45 -0
  20. package/dist/helpers/arraysAreEqual.d.ts.map +1 -1
  21. package/dist/helpers/bufferFromHex.d.ts +3 -0
  22. package/dist/helpers/bufferFromHex.d.ts.map +1 -0
  23. package/dist/helpers/bufferFromHex.js +13 -0
  24. package/dist/helpers/debounce.d.ts.map +1 -1
  25. package/dist/helpers/eventPromise.d.ts.map +1 -1
  26. package/dist/helpers/headsAreSame.d.ts +2 -2
  27. package/dist/helpers/headsAreSame.d.ts.map +1 -1
  28. package/dist/helpers/mergeArrays.d.ts +1 -1
  29. package/dist/helpers/mergeArrays.d.ts.map +1 -1
  30. package/dist/helpers/pause.d.ts.map +1 -1
  31. package/dist/helpers/tests/network-adapter-tests.d.ts.map +1 -1
  32. package/dist/helpers/tests/network-adapter-tests.js +13 -13
  33. package/dist/helpers/tests/storage-adapter-tests.d.ts +2 -2
  34. package/dist/helpers/tests/storage-adapter-tests.d.ts.map +1 -1
  35. package/dist/helpers/tests/storage-adapter-tests.js +25 -48
  36. package/dist/helpers/throttle.d.ts.map +1 -1
  37. package/dist/helpers/withTimeout.d.ts.map +1 -1
  38. package/dist/index.d.ts +2 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +1 -1
  41. package/dist/network/messages.d.ts.map +1 -1
  42. package/dist/storage/StorageSubsystem.d.ts +15 -1
  43. package/dist/storage/StorageSubsystem.d.ts.map +1 -1
  44. package/dist/storage/StorageSubsystem.js +50 -14
  45. package/dist/synchronizer/CollectionSynchronizer.d.ts +4 -3
  46. package/dist/synchronizer/CollectionSynchronizer.d.ts.map +1 -1
  47. package/dist/synchronizer/CollectionSynchronizer.js +34 -15
  48. package/dist/synchronizer/DocSynchronizer.d.ts +3 -2
  49. package/dist/synchronizer/DocSynchronizer.d.ts.map +1 -1
  50. package/dist/synchronizer/DocSynchronizer.js +51 -27
  51. package/dist/synchronizer/Synchronizer.d.ts +11 -0
  52. package/dist/synchronizer/Synchronizer.d.ts.map +1 -1
  53. package/dist/types.d.ts +4 -1
  54. package/dist/types.d.ts.map +1 -1
  55. package/fuzz/fuzz.ts +3 -3
  56. package/package.json +3 -4
  57. package/src/AutomergeUrl.ts +101 -26
  58. package/src/DocHandle.ts +235 -82
  59. package/src/FindProgress.ts +48 -0
  60. package/src/RemoteHeadsSubscriptions.ts +11 -9
  61. package/src/Repo.ts +364 -74
  62. package/src/helpers/abortable.ts +61 -0
  63. package/src/helpers/bufferFromHex.ts +14 -0
  64. package/src/helpers/headsAreSame.ts +2 -2
  65. package/src/helpers/tests/network-adapter-tests.ts +14 -13
  66. package/src/helpers/tests/storage-adapter-tests.ts +44 -86
  67. package/src/index.ts +7 -0
  68. package/src/storage/StorageSubsystem.ts +66 -16
  69. package/src/synchronizer/CollectionSynchronizer.ts +37 -16
  70. package/src/synchronizer/DocSynchronizer.ts +59 -32
  71. package/src/synchronizer/Synchronizer.ts +14 -0
  72. package/src/types.ts +4 -1
  73. package/test/AutomergeUrl.test.ts +130 -0
  74. package/test/CollectionSynchronizer.test.ts +4 -4
  75. package/test/DocHandle.test.ts +181 -38
  76. package/test/DocSynchronizer.test.ts +10 -3
  77. package/test/Repo.test.ts +376 -203
  78. package/test/StorageSubsystem.test.ts +80 -1
  79. package/test/remoteHeads.test.ts +27 -12
package/dist/DocHandle.js CHANGED
@@ -2,7 +2,7 @@ import * as A from "@automerge/automerge/slim/next";
2
2
  import debug from "debug";
3
3
  import { EventEmitter } from "eventemitter3";
4
4
  import { assertEvent, assign, createActor, setup, waitFor } from "xstate";
5
- import { stringifyAutomergeUrl } from "./AutomergeUrl.js";
5
+ import { decodeHeads, encodeHeads, stringifyAutomergeUrl, } from "./AutomergeUrl.js";
6
6
  import { encode } from "./helpers/cbor.js";
7
7
  import { headsAreSame } from "./helpers/headsAreSame.js";
8
8
  import { withTimeout } from "./helpers/withTimeout.js";
@@ -24,6 +24,8 @@ export class DocHandle extends EventEmitter {
24
24
  #log;
25
25
  /** The XState actor running our state machine. */
26
26
  #machine;
27
+ /** If set, this handle will only show the document at these heads */
28
+ #fixedHeads;
27
29
  /** The last known state of our document. */
28
30
  #prevDocState = A.init();
29
31
  /** How long to wait before giving up on a document. (Note that a document will be marked
@@ -31,6 +33,8 @@ export class DocHandle extends EventEmitter {
31
33
  #timeoutDelay = 60_000;
32
34
  /** A dictionary mapping each peer to the last heads we know they have. */
33
35
  #remoteHeads = {};
36
+ /** Cache for view handles, keyed by the stringified heads */
37
+ #viewCache = new Map();
34
38
  /** @hidden */
35
39
  constructor(documentId, options = {}) {
36
40
  super();
@@ -38,6 +42,9 @@ export class DocHandle extends EventEmitter {
38
42
  if ("timeoutDelay" in options && options.timeoutDelay) {
39
43
  this.#timeoutDelay = options.timeoutDelay;
40
44
  }
45
+ if ("heads" in options) {
46
+ this.#fixedHeads = options.heads;
47
+ }
41
48
  const doc = A.init();
42
49
  this.#log = debug(`automerge-repo:dochandle:${this.documentId.slice(0, 5)}`);
43
50
  const delay = this.#timeoutDelay;
@@ -59,9 +66,12 @@ export class DocHandle extends EventEmitter {
59
66
  this.emit("delete", { handle: this });
60
67
  return { doc: A.init() };
61
68
  }),
62
- onUnavailable: () => {
63
- this.emit("unavailable", { handle: this });
64
- },
69
+ onUnavailable: assign(() => {
70
+ return { doc: A.init() };
71
+ }),
72
+ onUnload: assign(() => {
73
+ return { doc: A.init() };
74
+ }),
65
75
  },
66
76
  }).createMachine({
67
77
  /** @xstate-layout N4IgpgJg5mDOIC5QAoC2BDAxgCwJYDswBKAYgFUAFAEQEEAVAUQG0AGAXUVAAcB7WXAC64e+TiAAeiAOwAOAKwA6ACxSAzKqks1ATjlTdAGhABPRAFolAJksKN2y1KtKAbFLla5AX09G0WPISkVAwAMgyMrBxIILz8QiJikggAjCzOijKqLEqqybJyLizaRqYIFpbJtro5Uo7J2o5S3r4YOATECrgQADZgJADCAEoM9MzsYrGCwqLRSeoyCtra8pa5adquySXmDjY5ac7JljLJeepKzSB+bYGdPX0AYgCSAHJUkRN8UwmziM7HCgqyVcUnqcmScmcMm2ZV2yiyzkOx1OalUFx8V1aAQ63R46AgBCgJGGAEUyAwAMp0D7RSbxGagJKHFgKOSWJTJGRSCosCpKaEmRCqbQKU5yXINeTaer6LwY67YogKXH4wkkKgAeX6AH1hjQqABNGncL70xKIJQ5RY5BHOJag6wwpRyEWImQVeT1aWrVSXBXtJUqgn4Ik0ADqNCedG1L3CYY1gwA0saYqbpuaEG4pKLksKpFDgcsCjDhTnxTKpTLdH6sQGFOgAO7oKYhl5gAQNngAJwA1iRY3R40ndSNDSm6enfpm5BkWAVkvy7bpuTCKq7ndZnfVeSwuTX-HWu2AAI4AVzgQhD6q12rILxoADVIyEaAAhMLjtM-RmIE4LVSQi4nLLDIGzOCWwLKA0cgyLBoFWNy+43B0R5nheaqajqepjuMtJfgyEh-FoixqMCoKqOyhzgYKCDOq6UIeuCSxHOoSGKgop74OgABuzbdOgABGvTXlho5GrhJpxJOP4pLulT6KoMhpJY2hzsWNF0QobqMV6LG+pc+A8BAcBiP6gSfFJ36EQgKksksKxrHamwwmY7gLKB85QjBzoAWxdZdL0FnfARST8ooLC7qoTnWBU4pyC5ViVMKBQaHUDQuM4fm3EGhJBWaU7-CysEAUp3LpEpWw0WYRw2LmqzgqciIsCxWUdI2zaXlAbYdt2PZ5dJ1n5jY2iJY1ikOIcMJHCyUWHC62hRZkUVNPKta3Kh56wJ1-VWUyzhFc64JWJCtQNBBzhQW4cHwbsrVKpxPF8YJgV4ZZIWIKkiKiiNSkqZYWjzCWaQ5hFh0AcCuR3QoR74qUknBRmzholpv3OkpRQNNRpTzaKTWKbIWR5FDxm9AIkA7e9skUYCWayLILBZGoLkUSKbIyIdpxHPoyTeN4QA */
@@ -71,6 +81,7 @@ export class DocHandle extends EventEmitter {
71
81
  context: { documentId, doc },
72
82
  on: {
73
83
  UPDATE: { actions: "onUpdate" },
84
+ UNLOAD: ".unloaded",
74
85
  DELETE: ".deleted",
75
86
  },
76
87
  states: {
@@ -98,6 +109,12 @@ export class DocHandle extends EventEmitter {
98
109
  on: { DOC_READY: "ready" },
99
110
  },
100
111
  ready: {},
112
+ unloaded: {
113
+ entry: "onUnload",
114
+ on: {
115
+ RELOAD: "loading",
116
+ },
117
+ },
101
118
  deleted: { entry: "onDelete", type: "final" },
102
119
  },
103
120
  });
@@ -113,7 +130,7 @@ export class DocHandle extends EventEmitter {
113
130
  });
114
131
  // Start the machine, and send a create or find event to get things going
115
132
  this.#machine.start();
116
- this.#machine.send({ type: BEGIN });
133
+ this.begin();
117
134
  }
118
135
  // PRIVATE
119
136
  /** Returns the current document, regardless of state */
@@ -140,7 +157,7 @@ export class DocHandle extends EventEmitter {
140
157
  #checkForChanges(before, after) {
141
158
  const beforeHeads = A.getHeads(before);
142
159
  const afterHeads = A.getHeads(after);
143
- const docChanged = !headsAreSame(afterHeads, beforeHeads);
160
+ const docChanged = !headsAreSame(encodeHeads(afterHeads), encodeHeads(beforeHeads));
144
161
  if (docChanged) {
145
162
  this.emit("heads-changed", { handle: this, doc: after });
146
163
  const patches = A.diff(after, beforeHeads, afterHeads);
@@ -163,7 +180,10 @@ export class DocHandle extends EventEmitter {
163
180
  /** Our documentId in Automerge URL form.
164
181
  */
165
182
  get url() {
166
- return stringifyAutomergeUrl({ documentId: this.documentId });
183
+ return stringifyAutomergeUrl({
184
+ documentId: this.documentId,
185
+ heads: this.#fixedHeads,
186
+ });
167
187
  }
168
188
  /**
169
189
  * @returns true if the document is ready for accessing or changes.
@@ -172,6 +192,13 @@ export class DocHandle extends EventEmitter {
172
192
  * peers. We do not currently have an equivalent `whenSynced()`.
173
193
  */
174
194
  isReady = () => this.inState(["ready"]);
195
+ /**
196
+ * @returns true if the document has been unloaded.
197
+ *
198
+ * Unloaded documents are freed from memory but not removed from local storage. It's not currently
199
+ * possible at runtime to reload an unloaded document.
200
+ */
201
+ isUnloaded = () => this.inState(["unloaded"]);
175
202
  /**
176
203
  * @returns true if the document has been marked as deleted.
177
204
  *
@@ -204,43 +231,26 @@ export class DocHandle extends EventEmitter {
204
231
  await withTimeout(this.#statePromise(awaitStates), this.#timeoutDelay);
205
232
  }
206
233
  /**
207
- * @returns the current state of this handle's Automerge document.
234
+ * Returns the current state of the Automerge document this handle manages.
235
+ *
236
+ * @returns the current document
237
+ * @throws on deleted and unavailable documents
208
238
  *
209
- * This is the recommended way to access a handle's document. Note that this waits for the handle
210
- * to be ready if necessary. If loading (or synchronization) fails, this will never resolve.
211
239
  */
212
- async doc(
213
- /** states to wait for, such as "LOADING". mostly for internal use. */
214
- awaitStates = ["ready", "unavailable"]) {
215
- try {
216
- // wait for the document to enter one of the desired states
217
- await this.#statePromise(awaitStates);
218
- }
219
- catch (error) {
220
- // if we timed out, return undefined
221
- return undefined;
240
+ doc() {
241
+ if (!this.isReady())
242
+ throw new Error("DocHandle is not ready");
243
+ if (this.#fixedHeads) {
244
+ return A.view(this.#doc, decodeHeads(this.#fixedHeads));
222
245
  }
223
- // Return the document
224
- return !this.isUnavailable() ? this.#doc : undefined;
246
+ return this.#doc;
225
247
  }
226
248
  /**
227
- * Synchronously returns the current state of the Automerge document this handle manages, or
228
- * undefined. Consider using `await handle.doc()` instead. Check `isReady()`, or use `whenReady()`
229
- * if you want to make sure loading is complete first.
230
- *
231
- * Not to be confused with the SyncState of the document, which describes the state of the
232
- * synchronization process.
233
249
  *
234
- * Note that `undefined` is not a valid Automerge document, so the return from this function is
235
- * unambigous.
236
- *
237
- * @returns the current document, or undefined if the document is not ready.
238
- */
250
+ * @deprecated */
239
251
  docSync() {
240
- if (!this.isReady())
241
- return undefined;
242
- else
243
- return this.#doc;
252
+ console.warn("docSync is deprecated. Use doc() instead. This function will be removed as part of the 2.0 release.");
253
+ return this.doc();
244
254
  }
245
255
  /**
246
256
  * Returns the current "heads" of the document, akin to a git commit.
@@ -248,15 +258,18 @@ export class DocHandle extends EventEmitter {
248
258
  * @returns the current document's heads, or undefined if the document is not ready
249
259
  */
250
260
  heads() {
251
- if (!this.isReady()) {
252
- return undefined;
261
+ if (!this.isReady())
262
+ throw new Error("DocHandle is not ready");
263
+ if (this.#fixedHeads) {
264
+ return this.#fixedHeads;
253
265
  }
254
- return A.getHeads(this.#doc);
266
+ return encodeHeads(A.getHeads(this.#doc));
267
+ }
268
+ begin() {
269
+ this.#machine.send({ type: BEGIN });
255
270
  }
256
271
  /**
257
- * Creates a fixed "view" of an automerge document at the given point in time represented
258
- * by the `heads` passed in. The return value is the same type as docSync() and will return
259
- * undefined if the object hasn't finished loading.
272
+ * Returns an array of all past "heads" for the document in topological order.
260
273
  *
261
274
  * @remarks
262
275
  * A point-in-time in an automerge document is an *array* of heads since there may be
@@ -265,46 +278,109 @@ export class DocHandle extends EventEmitter {
265
278
  * history views would be quite large under concurrency (every thing in each branch against each other).
266
279
  * There might be a clever way to think about this, but we haven't found it yet, so for now at least
267
280
  * we present a single traversable view which excludes concurrency.
268
- * @returns The individual heads for every change in the document.
281
+ * @returns UrlHeads[] - The individual heads for every change in the document. Each item is a tagged string[1].
269
282
  */
270
283
  history() {
271
284
  if (!this.isReady()) {
272
285
  return undefined;
273
286
  }
274
287
  // This just returns all the heads as individual strings.
275
- return A.topoHistoryTraversal(this.#doc).map(h => [h]);
288
+ return A.topoHistoryTraversal(this.#doc).map(h => encodeHeads([h]));
276
289
  }
277
290
  /**
278
291
  * Creates a fixed "view" of an automerge document at the given point in time represented
279
- * by the `heads` passed in. The return value is the same type as docSync() and will return
292
+ * by the `heads` passed in. The return value is the same type as doc() and will return
280
293
  * undefined if the object hasn't finished loading.
281
- * @returns
294
+ *
295
+ * @remarks
296
+ * Note that our Typescript types do not consider change over time and the current version
297
+ * of Automerge doesn't check types at runtime, so if you go back to an old set of heads
298
+ * that doesn't match the heads here, Typescript will not save you.
299
+ *
300
+ * @argument heads - The heads to view the document at. See history().
301
+ * @returns DocHandle<T> at the time of `heads`
282
302
  */
283
303
  view(heads) {
284
304
  if (!this.isReady()) {
285
- return undefined;
305
+ throw new Error(`DocHandle#${this.documentId} is not ready. Check \`handle.isReady()\` before calling view().`);
306
+ }
307
+ // Create a cache key from the heads
308
+ const cacheKey = JSON.stringify(heads);
309
+ // Check if we have a cached handle for these heads
310
+ const cachedHandle = this.#viewCache.get(cacheKey);
311
+ if (cachedHandle) {
312
+ return cachedHandle;
286
313
  }
287
- return A.view(this.#doc, heads);
314
+ // Create a new handle with the same documentId but fixed heads
315
+ const handle = new DocHandle(this.documentId, {
316
+ heads,
317
+ timeoutDelay: this.#timeoutDelay,
318
+ });
319
+ handle.update(() => A.clone(this.#doc));
320
+ handle.doneLoading();
321
+ // Store in cache
322
+ this.#viewCache.set(cacheKey, handle);
323
+ return handle;
288
324
  }
289
325
  /**
290
- * Creates a fixed "view" of an automerge document at the given point in time represented
291
- * by the `heads` passed in. The return value is the same type as docSync() and will return
292
- * undefined if the object hasn't finished loading.
326
+ * Returns a set of Patch operations that will move a materialized document from one state to another
327
+ * if applied.
293
328
  *
294
329
  * @remarks
295
- * We allow specifying both a from/to heads or just a single comparison point, in which case
296
- * the base will be the current document heads.
330
+ * We allow specifying either:
331
+ * - Two sets of heads to compare directly
332
+ * - A single set of heads to compare against our current heads
333
+ * - Another DocHandle to compare against (which must share history with this document)
297
334
  *
298
- * @returns Automerge patches that go from one document state to the other. Use view() to get the full state.
335
+ * @throws Error if the documents don't share history or if either document is not ready
336
+ * @returns Automerge patches that go from one document state to the other
299
337
  */
300
338
  diff(first, second) {
301
339
  if (!this.isReady()) {
302
- return undefined;
340
+ throw new Error(`DocHandle#${this.documentId} is not ready. Check \`handle.isReady()\` before calling diff().`);
303
341
  }
304
- // We allow only one set of heads to be specified, in which case we use the doc's heads
305
- const from = second ? first : this.heads() || []; // because we guard above this should always have useful data
342
+ const doc = this.#doc;
343
+ if (!doc)
344
+ throw new Error("Document not available");
345
+ // If first argument is a DocHandle
346
+ if (first instanceof DocHandle) {
347
+ if (!first.isReady()) {
348
+ throw new Error("Cannot diff against a handle that isn't ready");
349
+ }
350
+ const otherHeads = first.heads();
351
+ if (!otherHeads)
352
+ throw new Error("Other document's heads not available");
353
+ // Create a temporary merged doc to verify shared history and compute diff
354
+ const mergedDoc = A.merge(A.clone(doc), first.doc());
355
+ // Use the merged doc to compute the diff
356
+ return A.diff(mergedDoc, decodeHeads(this.heads()), decodeHeads(otherHeads));
357
+ }
358
+ // Otherwise treat as heads
359
+ const from = second ? first : (this.heads() || []);
306
360
  const to = second ? second : first;
307
- return A.diff(this.#doc, from, to);
361
+ return A.diff(doc, decodeHeads(from), decodeHeads(to));
362
+ }
363
+ /**
364
+ * `metadata(head?)` allows you to look at the metadata for a change
365
+ * this can be used to build history graphs to find commit messages and edit times.
366
+ * this interface.
367
+ *
368
+ * @remarks
369
+ * I'm really not convinced this is the right way to surface this information so
370
+ * I'm leaving this API "hidden".
371
+ *
372
+ * @hidden
373
+ */
374
+ metadata(change) {
375
+ if (!this.isReady()) {
376
+ return undefined;
377
+ }
378
+ if (!change) {
379
+ change = this.heads()[0];
380
+ }
381
+ // we return undefined instead of null by convention in this API
382
+ return (A.inspectChange(this.#doc, decodeHeads([change])[0]) ||
383
+ undefined);
308
384
  }
309
385
  /**
310
386
  * `update` is called any time we have a new document state; could be
@@ -324,7 +400,7 @@ export class DocHandle extends EventEmitter {
324
400
  this.#machine.send({ type: DOC_READY });
325
401
  }
326
402
  /**
327
- * Called by the repo either when a doc handle changes or we receive new remote heads.
403
+ * Called by the repo when a doc handle changes or we receive new remote heads.
328
404
  * @hidden
329
405
  */
330
406
  setRemoteHeads(storageId, heads) {
@@ -354,6 +430,9 @@ export class DocHandle extends EventEmitter {
354
430
  if (!this.isReady()) {
355
431
  throw new Error(`DocHandle#${this.documentId} is in ${this.state} and not ready. Check \`handle.isReady()\` before accessing the document.`);
356
432
  }
433
+ if (this.#fixedHeads) {
434
+ throw new Error(`DocHandle#${this.documentId} is in view-only mode at specific heads. Use clone() to create a new document from this state.`);
435
+ }
357
436
  this.#machine.send({
358
437
  type: UPDATE,
359
438
  payload: { callback: doc => A.change(doc, options, callback) },
@@ -368,13 +447,18 @@ export class DocHandle extends EventEmitter {
368
447
  if (!this.isReady()) {
369
448
  throw new Error(`DocHandle#${this.documentId} is not ready. Check \`handle.isReady()\` before accessing the document.`);
370
449
  }
450
+ if (this.#fixedHeads) {
451
+ throw new Error(`DocHandle#${this.documentId} is in view-only mode at specific heads. Use clone() to create a new document from this state.`);
452
+ }
371
453
  let resultHeads = undefined;
372
454
  this.#machine.send({
373
455
  type: UPDATE,
374
456
  payload: {
375
457
  callback: doc => {
376
- const result = A.changeAt(doc, heads, options, callback);
377
- resultHeads = result.newHeads || undefined;
458
+ const result = A.changeAt(doc, decodeHeads(heads), options, callback);
459
+ resultHeads = result.newHeads
460
+ ? encodeHeads(result.newHeads)
461
+ : undefined;
378
462
  return result.newDoc;
379
463
  },
380
464
  },
@@ -396,28 +480,37 @@ export class DocHandle extends EventEmitter {
396
480
  if (!this.isReady() || !otherHandle.isReady()) {
397
481
  throw new Error("Both handles must be ready to merge");
398
482
  }
399
- const mergingDoc = otherHandle.docSync();
400
- if (!mergingDoc) {
401
- throw new Error("The document to be merged in is falsy, aborting.");
483
+ if (this.#fixedHeads) {
484
+ throw new Error(`DocHandle#${this.documentId} is in view-only mode at specific heads. Use clone() to create a new document from this state.`);
402
485
  }
486
+ const mergingDoc = otherHandle.doc();
403
487
  this.update(doc => {
404
488
  return A.merge(doc, mergingDoc);
405
489
  });
406
490
  }
407
491
  /**
408
- * Used in testing to mark this document as unavailable.
492
+ * Updates the internal state machine to mark the document unavailable.
409
493
  * @hidden
410
494
  */
411
495
  unavailable() {
412
496
  this.#machine.send({ type: DOC_UNAVAILABLE });
413
497
  }
414
- /** Called by the repo when the document is not found in storage.
498
+ /**
499
+ * Called by the repo either when the document is not found in storage.
415
500
  * @hidden
416
501
  * */
417
502
  request() {
418
503
  if (this.#state === "loading")
419
504
  this.#machine.send({ type: REQUEST });
420
505
  }
506
+ /** Called by the repo to free memory used by the document. */
507
+ unload() {
508
+ this.#machine.send({ type: UNLOAD });
509
+ }
510
+ /** Called by the repo to reuse an unloaded handle. */
511
+ reload() {
512
+ this.#machine.send({ type: RELOAD });
513
+ }
421
514
  /** Called by the repo when the document is deleted. */
422
515
  delete() {
423
516
  this.#machine.send({ type: DELETE });
@@ -432,7 +525,7 @@ export class DocHandle extends EventEmitter {
432
525
  broadcast(message) {
433
526
  this.emit("ephemeral-message-outbound", {
434
527
  handle: this,
435
- data: encode(message),
528
+ data: new Uint8Array(encode(message)),
436
529
  });
437
530
  }
438
531
  metrics() {
@@ -453,16 +546,20 @@ export const HandleState = {
453
546
  REQUESTING: "requesting",
454
547
  /** The document is available */
455
548
  READY: "ready",
549
+ /** The document has been unloaded from the handle, to free memory usage */
550
+ UNLOADED: "unloaded",
456
551
  /** The document has been deleted from the repo */
457
552
  DELETED: "deleted",
458
553
  /** The document was not available in storage or from any connected peers */
459
554
  UNAVAILABLE: "unavailable",
460
555
  };
461
- export const { IDLE, LOADING, REQUESTING, READY, DELETED, UNAVAILABLE } = HandleState;
556
+ export const { IDLE, LOADING, REQUESTING, READY, UNLOADED, DELETED, UNAVAILABLE, } = HandleState;
462
557
  const BEGIN = "BEGIN";
463
558
  const REQUEST = "REQUEST";
464
559
  const DOC_READY = "DOC_READY";
465
560
  const UPDATE = "UPDATE";
561
+ const UNLOAD = "UNLOAD";
562
+ const RELOAD = "RELOAD";
466
563
  const DELETE = "DELETE";
467
564
  const TIMEOUT = "TIMEOUT";
468
565
  const DOC_UNAVAILABLE = "DOC_UNAVAILABLE";
@@ -0,0 +1,30 @@
1
+ import { DocHandle } from "./DocHandle.js";
2
+ export type FindProgressState = "loading" | "ready" | "failed" | "aborted" | "unavailable";
3
+ interface FindProgressBase<T> {
4
+ state: FindProgressState;
5
+ handle: DocHandle<T>;
6
+ }
7
+ interface FindProgressLoading<T> extends FindProgressBase<T> {
8
+ state: "loading";
9
+ progress: number;
10
+ }
11
+ interface FindProgressReady<T> extends FindProgressBase<T> {
12
+ state: "ready";
13
+ }
14
+ interface FindProgressFailed<T> extends FindProgressBase<T> {
15
+ state: "failed";
16
+ error: Error;
17
+ }
18
+ interface FindProgressUnavailable<T> extends FindProgressBase<T> {
19
+ state: "unavailable";
20
+ }
21
+ interface FindProgressAborted<T> extends FindProgressBase<T> {
22
+ state: "aborted";
23
+ }
24
+ export type FindProgress<T> = FindProgressLoading<T> | FindProgressReady<T> | FindProgressFailed<T> | FindProgressUnavailable<T> | FindProgressAborted<T>;
25
+ export type FindProgressWithMethods<T> = FindProgress<T> & {
26
+ next: () => Promise<FindProgressWithMethods<T>>;
27
+ untilReady: (allowableStates: string[]) => Promise<DocHandle<T>>;
28
+ };
29
+ export {};
30
+ //# sourceMappingURL=FindProgress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FindProgress.d.ts","sourceRoot":"","sources":["../src/FindProgress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,MAAM,MAAM,iBAAiB,GACzB,SAAS,GACT,OAAO,GACP,QAAQ,GACR,SAAS,GACT,aAAa,CAAA;AAEjB,UAAU,gBAAgB,CAAC,CAAC;IAC1B,KAAK,EAAE,iBAAiB,CAAA;IACxB,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;CACrB;AAED,UAAU,mBAAmB,CAAC,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IAC1D,KAAK,EAAE,SAAS,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,UAAU,iBAAiB,CAAC,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IACxD,KAAK,EAAE,OAAO,CAAA;CACf;AAED,UAAU,kBAAkB,CAAC,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IACzD,KAAK,EAAE,QAAQ,CAAA;IACf,KAAK,EAAE,KAAK,CAAA;CACb;AAED,UAAU,uBAAuB,CAAC,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IAC9D,KAAK,EAAE,aAAa,CAAA;CACrB;AAED,UAAU,mBAAmB,CAAC,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IAC1D,KAAK,EAAE,SAAS,CAAA;CACjB;AAED,MAAM,MAAM,YAAY,CAAC,CAAC,IACtB,mBAAmB,CAAC,CAAC,CAAC,GACtB,iBAAiB,CAAC,CAAC,CAAC,GACpB,kBAAkB,CAAC,CAAC,CAAC,GACrB,uBAAuB,CAAC,CAAC,CAAC,GAC1B,mBAAmB,CAAC,CAAC,CAAC,CAAA;AAE1B,MAAM,MAAM,uBAAuB,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG;IACzD,IAAI,EAAE,MAAM,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAA;IAE/C,UAAU,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;CACjE,CAAA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1,19 +1,18 @@
1
- import { next as A } from "@automerge/automerge/slim";
2
1
  import { EventEmitter } from "eventemitter3";
3
- import { DocumentId, PeerId } from "./types.js";
2
+ import { DocumentId, PeerId, UrlHeads } from "./types.js";
4
3
  import { RemoteHeadsChanged, RemoteSubscriptionControlMessage } from "./network/messages.js";
5
4
  import { StorageId } from "./index.js";
6
5
  export type RemoteHeadsSubscriptionEventPayload = {
7
6
  documentId: DocumentId;
8
7
  storageId: StorageId;
9
- remoteHeads: A.Heads;
8
+ remoteHeads: UrlHeads;
10
9
  timestamp: number;
11
10
  };
12
11
  export type NotifyRemoteHeadsPayload = {
13
12
  targetId: PeerId;
14
13
  documentId: DocumentId;
15
14
  storageId: StorageId;
16
- heads: A.Heads;
15
+ heads: UrlHeads;
17
16
  timestamp: number;
18
17
  };
19
18
  type RemoteHeadsSubscriptionEvents = {
@@ -33,7 +32,7 @@ export declare class RemoteHeadsSubscriptions extends EventEmitter<RemoteHeadsSu
33
32
  /** A peer we are not directly connected to has changed their heads */
34
33
  handleRemoteHeads(msg: RemoteHeadsChanged): void;
35
34
  /** A peer we are directly connected to has updated their heads */
36
- handleImmediateRemoteHeadsChanged(documentId: DocumentId, storageId: StorageId, heads: A.Heads): void;
35
+ handleImmediateRemoteHeadsChanged(documentId: DocumentId, storageId: StorageId, heads: UrlHeads): void;
37
36
  addGenerousPeer(peerId: PeerId): void;
38
37
  removePeer(peerId: PeerId): void;
39
38
  subscribePeerToDoc(peerId: PeerId, documentId: DocumentId): void;
@@ -1 +1 @@
1
- {"version":3,"file":"RemoteHeadsSubscriptions.d.ts","sourceRoot":"","sources":["../src/RemoteHeadsSubscriptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EACL,kBAAkB,EAClB,gCAAgC,EACjC,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAItC,MAAM,MAAM,mCAAmC,GAAG;IAChD,UAAU,EAAE,UAAU,CAAA;IACtB,SAAS,EAAE,SAAS,CAAA;IACpB,WAAW,EAAE,CAAC,CAAC,KAAK,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAGD,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,UAAU,CAAA;IACtB,SAAS,EAAE,SAAS,CAAA;IACpB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,KAAK,6BAA6B,GAAG;IACnC,sBAAsB,EAAE,CAAC,OAAO,EAAE,mCAAmC,KAAK,IAAI,CAAA;IAC9E,oBAAoB,EAAE,CAAC,OAAO,EAAE;QAC9B,KAAK,EAAE,MAAM,EAAE,CAAA;QACf,GAAG,CAAC,EAAE,SAAS,EAAE,CAAA;QACjB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAA;KACrB,KAAK,IAAI,CAAA;IACV,qBAAqB,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,IAAI,CAAA;CACnE,CAAA;AAED,qBAAa,wBAAyB,SAAQ,YAAY,CAAC,6BAA6B,CAAC;;IAcvF,kBAAkB,CAAC,OAAO,EAAE,SAAS,EAAE;IAkBvC,sBAAsB,CAAC,OAAO,EAAE,SAAS,EAAE;IAsB3C,oBAAoB,CAAC,OAAO,EAAE,gCAAgC;IA0E9D,sEAAsE;IACtE,iBAAiB,CAAC,GAAG,EAAE,kBAAkB;IAgDzC,kEAAkE;IAClE,iCAAiC,CAC/B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,CAAC,CAAC,KAAK;IAgChB,eAAe,CAAC,MAAM,EAAE,MAAM;IAwB9B,UAAU,CAAC,MAAM,EAAE,MAAM;IA2BzB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;CAoE1D"}
1
+ {"version":3,"file":"RemoteHeadsSubscriptions.d.ts","sourceRoot":"","sources":["../src/RemoteHeadsSubscriptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EACL,kBAAkB,EAClB,gCAAgC,EACjC,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAItC,MAAM,MAAM,mCAAmC,GAAG;IAChD,UAAU,EAAE,UAAU,CAAA;IACtB,SAAS,EAAE,SAAS,CAAA;IACpB,WAAW,EAAE,QAAQ,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAGD,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,UAAU,CAAA;IACtB,SAAS,EAAE,SAAS,CAAA;IACpB,KAAK,EAAE,QAAQ,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,KAAK,6BAA6B,GAAG;IACnC,sBAAsB,EAAE,CAAC,OAAO,EAAE,mCAAmC,KAAK,IAAI,CAAA;IAC9E,oBAAoB,EAAE,CAAC,OAAO,EAAE;QAC9B,KAAK,EAAE,MAAM,EAAE,CAAA;QACf,GAAG,CAAC,EAAE,SAAS,EAAE,CAAA;QACjB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAA;KACrB,KAAK,IAAI,CAAA;IACV,qBAAqB,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,IAAI,CAAA;CACnE,CAAA;AAED,qBAAa,wBAAyB,SAAQ,YAAY,CAAC,6BAA6B,CAAC;;IAcvF,kBAAkB,CAAC,OAAO,EAAE,SAAS,EAAE;IAkBvC,sBAAsB,CAAC,OAAO,EAAE,SAAS,EAAE;IAsB3C,oBAAoB,CAAC,OAAO,EAAE,gCAAgC;IA0E9D,sEAAsE;IACtE,iBAAiB,CAAC,GAAG,EAAE,kBAAkB;IAgDzC,kEAAkE;IAClE,iCAAiC,CAC/B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,QAAQ;IAgCjB,eAAe,CAAC,MAAM,EAAE,MAAM;IAwB9B,UAAU,CAAC,MAAM,EAAE,MAAM;IA2BzB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU;CAuE1D"}
@@ -270,7 +270,10 @@ export class RemoteHeadsSubscriptions extends EventEmitter {
270
270
  continue;
271
271
  }
272
272
  else {
273
- remote.set(storageId, { timestamp, heads });
273
+ remote.set(storageId, {
274
+ timestamp,
275
+ heads: heads,
276
+ });
274
277
  changedHeads.push({
275
278
  documentId,
276
279
  storageId: storageId,
package/dist/Repo.d.ts CHANGED
@@ -6,7 +6,20 @@ import { StorageAdapterInterface } from "./storage/StorageAdapterInterface.js";
6
6
  import { StorageSubsystem } from "./storage/StorageSubsystem.js";
7
7
  import { StorageId } from "./storage/types.js";
8
8
  import { CollectionSynchronizer } from "./synchronizer/CollectionSynchronizer.js";
9
- import type { AnyDocumentId, DocumentId, PeerId } from "./types.js";
9
+ import { DocSyncMetrics } from "./synchronizer/Synchronizer.js";
10
+ import type { AnyDocumentId, AutomergeUrl, DocumentId, PeerId } from "./types.js";
11
+ import { AbortOptions } from "./helpers/abortable.js";
12
+ import { FindProgress } from "./FindProgress.js";
13
+ export type FindProgressWithMethods<T> = FindProgress<T> & {
14
+ untilReady: (allowableStates: string[]) => Promise<DocHandle<T>>;
15
+ peek: () => FindProgress<T>;
16
+ subscribe: (callback: (progress: FindProgress<T>) => void) => () => void;
17
+ };
18
+ export type ProgressSignal<T> = {
19
+ peek: () => FindProgress<T>;
20
+ subscribe: (callback: (progress: FindProgress<T>) => void) => () => void;
21
+ untilReady: (allowableStates: string[]) => Promise<DocHandle<T>>;
22
+ };
10
23
  /** A Repo is a collection of documents with networking, syncing, and storage capabilities. */
11
24
  /** The `Repo` is the main entry point of this library
12
25
  *
@@ -32,7 +45,7 @@ export declare class Repo extends EventEmitter<RepoEvents> {
32
45
  /** maps peer id to to persistence information (storageId, isEphemeral), access by collection synchronizer */
33
46
  /** @hidden */
34
47
  peerMetadataByPeerId: Record<PeerId, PeerMetadata>;
35
- constructor({ storage, network, peerId, sharePolicy, isEphemeral, enableRemoteHeadsGossiping, }?: RepoConfig);
48
+ constructor({ storage, network, peerId, sharePolicy, isEphemeral, enableRemoteHeadsGossiping, denylist, }?: RepoConfig);
36
49
  /** Returns all the handles we have cached. */
37
50
  get handles(): Record<DocumentId, DocHandle<any>>;
38
51
  /** Returns a list of all connected peer ids */
@@ -56,17 +69,17 @@ export declare class Repo extends EventEmitter<RepoEvents> {
56
69
  * Any peers this `Repo` is connected to for whom `sharePolicy` returns `true` will
57
70
  * be notified of the newly created DocHandle.
58
71
  *
59
- * @throws if the cloned handle is not yet ready or if
60
- * `clonedHandle.docSync()` returns `undefined` (i.e. the handle is unavailable).
61
72
  */
62
73
  clone<T>(clonedHandle: DocHandle<T>): DocHandle<T>;
74
+ findWithProgress<T>(id: AnyDocumentId, options?: AbortOptions): FindProgressWithMethods<T> | FindProgress<T>;
75
+ find<T>(id: AnyDocumentId, options?: RepoFindOptions & AbortOptions): Promise<DocHandle<T>>;
63
76
  /**
64
77
  * Retrieves a document by id. It gets data from the local system, but also emits a `document`
65
78
  * event to advertise interest in the document.
66
79
  */
67
- find<T>(
80
+ findClassic<T>(
68
81
  /** The url or documentId of the handle to retrieve */
69
- id: AnyDocumentId): DocHandle<T>;
82
+ id: AnyDocumentId, options?: RepoFindOptions & AbortOptions): Promise<DocHandle<T>>;
70
83
  delete(
71
84
  /** The url or documentId of the handle to delete */
72
85
  id: AnyDocumentId): void;
@@ -92,6 +105,13 @@ export declare class Repo extends EventEmitter<RepoEvents> {
92
105
  * @returns Promise<void>
93
106
  */
94
107
  flush(documents?: DocumentId[]): Promise<void>;
108
+ /**
109
+ * Removes a DocHandle from the handleCache.
110
+ * @hidden this API is experimental and may change.
111
+ * @param documentId - documentId of the DocHandle to remove from handleCache, if present in cache.
112
+ * @returns Promise<void>
113
+ */
114
+ removeFromCache(documentId: DocumentId): Promise<void>;
95
115
  shutdown(): Promise<void>;
96
116
  metrics(): {
97
117
  documents: {
@@ -118,6 +138,12 @@ export interface RepoConfig {
118
138
  * Whether to enable the experimental remote heads gossiping feature
119
139
  */
120
140
  enableRemoteHeadsGossiping?: boolean;
141
+ /**
142
+ * A list of automerge URLs which should never be loaded regardless of what
143
+ * messages are received or what the share policy is. This is useful to avoid
144
+ * loading documents that are known to be too resource intensive.
145
+ */
146
+ denylist?: AutomergeUrl[];
121
147
  }
122
148
  /** A function that determines whether we should share a document with a peer
123
149
  *
@@ -135,6 +161,10 @@ export interface RepoEvents {
135
161
  "delete-document": (arg: DeleteDocumentPayload) => void;
136
162
  /** A document was marked as unavailable (we don't have it and none of our peers have it) */
137
163
  "unavailable-document": (arg: DeleteDocumentPayload) => void;
164
+ "doc-metrics": (arg: DocMetrics) => void;
165
+ }
166
+ export interface RepoFindOptions {
167
+ allowableStates?: string[];
138
168
  }
139
169
  export interface DocumentPayload {
140
170
  handle: DocHandle<any>;
@@ -142,4 +172,14 @@ export interface DocumentPayload {
142
172
  export interface DeleteDocumentPayload {
143
173
  documentId: DocumentId;
144
174
  }
175
+ export type DocMetrics = DocSyncMetrics | {
176
+ type: "doc-loaded";
177
+ documentId: DocumentId;
178
+ durationMillis: number;
179
+ numOps: number;
180
+ numChanges: number;
181
+ } | {
182
+ type: "doc-denied";
183
+ documentId: DocumentId;
184
+ };
145
185
  //# sourceMappingURL=Repo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../src/Repo.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../src/Repo.ts"],"names":[],"mappings":"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"}