@automerge/automerge-repo 2.4.0 → 2.5.0-alpha.0

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.
@@ -2,6 +2,7 @@ import { next as A } from "@automerge/automerge/slim";
2
2
  import { EventEmitter } from "eventemitter3";
3
3
  import type { AutomergeUrl, DocumentId, PeerId, UrlHeads } from "./types.js";
4
4
  import { StorageId } from "./storage/types.js";
5
+ import { AbortOptions } from "./helpers/abortable.js";
5
6
  /**
6
7
  * A DocHandle is a wrapper around a single Automerge document that lets us listen for changes and
7
8
  * notify the network and storage of new changes.
@@ -57,13 +58,17 @@ export declare class DocHandle<T> extends EventEmitter<DocHandleEvents<T>> {
57
58
  /** @hidden */
58
59
  get state(): "idle" | "loading" | "requesting" | "ready" | "unavailable" | "unloaded" | "deleted";
59
60
  /**
60
- * @returns a promise that resolves when the document is in one of the given states (if no states
61
- * are passed, when the document is ready)
61
+ * Returns promise that resolves when document is in one of the given states (default is 'ready' state)
62
62
  *
63
63
  * Use this to block until the document handle has finished loading. The async equivalent to
64
64
  * checking `inState()`.
65
+ *
66
+ * @param awaitStates - HandleState or HandleStates to wait for
67
+ * @param signal - Optional AbortSignal to cancel the waiting operation
68
+ * @returns a promise that resolves when the document is in one of the given states (if no states
69
+ * are passed, when the document is ready)
65
70
  */
66
- whenReady(awaitStates?: HandleState[]): Promise<void>;
71
+ whenReady(awaitStates?: HandleState[], options?: AbortOptions): Promise<void>;
67
72
  /**
68
73
  * Returns the current state of the Automerge document this handle manages.
69
74
  *
@@ -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":"AAAA,OAAO,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,2BAA2B,CAAA;AAErD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAU5C,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAEL,YAAY,EAEb,MAAM,wBAAwB,CAAA;AAE/B;;;;;;;;;;;;GAYG;AACH,qBAAa,SAAS,CAAC,CAAC,CAAE,SAAQ,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;;IAwBvD,UAAU,EAAE,UAAU;IAF/B,cAAc;gBAEL,UAAU,EAAE,UAAU,EAC7B,OAAO,GAAE,gBAAgB,CAAC,CAAC,CAAM;IA8MnC;OACG;IACH,IAAI,GAAG,IAAI,YAAY,CAKtB;IAED;;;;;OAKG;IACH,OAAO,gBAAgC;IAEvC;;;;;OAKG;IACH,UAAU,gBAAmC;IAE7C;;;;;OAKG;IACH,SAAS,gBAAkC;IAE3C;;;;OAIG;IACH,aAAa,gBAAsC;IAEnD;;OAEG;IACH,OAAO,GAAI,QAAQ,WAAW,EAAE,aAC0B;IAE1D,cAAc;IACd,IAAI,KAAK,yFAER;IAED;;;;;;;;;;OAUG;IACG,SAAS,CACb,WAAW,GAAE,WAAW,EAAc,EACtC,OAAO,CAAC,EAAE,YAAY;IAoBxB;;;;;;OAMG;IACH,GAAG;IAQH;;qBAEiB;IACjB,OAAO;IAOP;;;;OAIG;IACH,KAAK,IAAI,QAAQ;IAQjB,KAAK;IAIL;;;;;;;;;;;OAWG;IACH,OAAO,IAAI,QAAQ,EAAE,GAAG,SAAS;IAWjC;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC;IA8BnC;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,EAAE;IAkClE;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,aAAa,GAAG,SAAS;IAetD;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAI5C;;;;OAIG;IACH,WAAW;IAIX;;;OAGG;IACH,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ;IASpD;;;OAGG;IACH,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS;IAI1D,gFAAgF;IAChF,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS;IAIvD;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAM;IAehE;;;;OAIG;IACH,QAAQ,CACN,KAAK,EAAE,QAAQ,EACf,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EACvB,OAAO,GAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAM,GAC/B,QAAQ,GAAG,SAAS;IAuBvB;;;;;;;;;OASG;IACH,UAAU;IAIV;;;;;;;OAOG;IACH,KAAK;IACH,wDAAwD;IACxD,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;IAiB3B;;;OAGG;IACH,WAAW;IAIX;;;SAGK;IACL,OAAO;IAIP,8DAA8D;IAC9D,MAAM;IAIN,sDAAsD;IACtD,MAAM;IAIN,uDAAuD;IACvD,MAAM;IAIN;;;;;;OAMG;IACH,SAAS,CAAC,OAAO,EAAE,OAAO;IAO1B,OAAO,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;CAGlD;AAID,MAAM,MAAM,QAAQ,GAAG;IACrB,SAAS,EAAE,QAAQ,CAAA;IACnB,iBAAiB,EAAE,MAAM,CAAA;CAC1B,CAAA;AAED,cAAc;AACd,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAE1B;IACE,gGAAgG;IAChG,KAAK,EAAE,IAAI,CAAA;IAEX,yCAAyC;IACzC,YAAY,CAAC,EAAE,CAAC,CAAA;CACjB,GAED;IACE,KAAK,CAAC,EAAE,KAAK,CAAA;IAGb,KAAK,CAAC,EAAE,QAAQ,CAAA;IAEhB,+HAA+H;IAC/H,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAIL,2EAA2E;AAC3E,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,eAAe,EAAE,CAAC,OAAO,EAAE,6BAA6B,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IACpE,MAAM,EAAE,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IACpD,MAAM,EAAE,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IACpD,mBAAmB,EAAE,CAAC,OAAO,EAAE,gCAAgC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;IAC3E,4BAA4B,EAAE,CAC5B,OAAO,EAAE,wCAAwC,CAAC,CAAC,CAAC,KACjD,IAAI,CAAA;IACT,cAAc,EAAE,CAAC,OAAO,EAAE,2BAA2B,KAAK,IAAI,CAAA;CAC/D;AAED,sDAAsD;AACtD,MAAM,WAAW,6BAA6B,CAAC,CAAC;IAC9C,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACpB,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;CACd;AAED,6CAA6C;AAC7C,MAAM,WAAW,sBAAsB,CAAC,CAAC;IACvC,8BAA8B;IAC9B,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACpB,iDAAiD;IACjD,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IACb,wDAAwD;IACxD,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,CAAA;IAClB,mCAAmC;IACnC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;CAC1B;AAED,4CAA4C;AAC5C,MAAM,WAAW,sBAAsB,CAAC,CAAC;IACvC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;CACrB;AAED,6DAA6D;AAC7D,MAAM,WAAW,2BAA2B,CAAC,CAAC;IAC5C,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;CACrB;AAED,qEAAqE;AACrE,MAAM,WAAW,gCAAgC,CAAC,CAAC;IACjD,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,kEAAkE;AAClE,MAAM,WAAW,wCAAwC,CAAC,CAAC;IACzD,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACpB,IAAI,EAAE,UAAU,CAAA;CACjB;AAED,8DAA8D;AAC9D,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,SAAS,CAAA;IACpB,KAAK,EAAE,QAAQ,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB;AAMD;;GAEG;AACH,eAAO,MAAM,WAAW;IACtB,kEAAkE;;IAElE,mDAAmD;;IAEnD,6EAA6E;;IAE7E,gCAAgC;;IAEhC,2EAA2E;;IAE3E,kDAAkD;;IAElD,4EAA4E;;CAEpE,CAAA;AACV,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,CAAA;AAExE,eAAO,MACL,IAAI,UACJ,OAAO,aACP,UAAU,gBACV,KAAK,WACL,QAAQ,cACR,OAAO,aACP,WAAW,eACE,CAAA"}
package/dist/DocHandle.js CHANGED
@@ -6,6 +6,7 @@ import { decodeHeads, encodeHeads, stringifyAutomergeUrl, } from "./AutomergeUrl
6
6
  import { encode } from "./helpers/cbor.js";
7
7
  import { headsAreSame } from "./helpers/headsAreSame.js";
8
8
  import { withTimeout } from "./helpers/withTimeout.js";
9
+ import { AbortError, isAbortErrorLike, } from "./helpers/abortable.js";
9
10
  /**
10
11
  * A DocHandle is a wrapper around a single Automerge document that lets us listen for changes and
11
12
  * notify the network and storage of new changes.
@@ -141,14 +142,19 @@ export class DocHandle extends EventEmitter {
141
142
  get #state() {
142
143
  return this.#machine?.getSnapshot().value;
143
144
  }
144
- /** Returns a promise that resolves when the docHandle is in one of the given states */
145
- #statePromise(awaitStates) {
145
+ /**
146
+ * Returns a promise that resolves when the docHandle is in one of the given states
147
+ *
148
+ * @param awaitStates - HandleState or HandleStates to wait for
149
+ * @param signal - Optional AbortSignal to cancel the waiting operation
150
+ */
151
+ #statePromise(awaitStates, options) {
146
152
  const awaitStatesArray = Array.isArray(awaitStates)
147
153
  ? awaitStates
148
154
  : [awaitStates];
149
155
  return waitFor(this.#machine, s => awaitStatesArray.some(state => s.matches(state)),
150
156
  // use a longer delay here so as not to race with other delays
151
- { timeout: this.#timeoutDelay * 2 });
157
+ { timeout: this.#timeoutDelay * 2, ...options });
152
158
  }
153
159
  /**
154
160
  * Update the document with whatever the result of callback is
@@ -254,17 +260,24 @@ export class DocHandle extends EventEmitter {
254
260
  return this.#machine.getSnapshot().value;
255
261
  }
256
262
  /**
257
- * @returns a promise that resolves when the document is in one of the given states (if no states
258
- * are passed, when the document is ready)
263
+ * Returns promise that resolves when document is in one of the given states (default is 'ready' state)
259
264
  *
260
265
  * Use this to block until the document handle has finished loading. The async equivalent to
261
266
  * checking `inState()`.
267
+ *
268
+ * @param awaitStates - HandleState or HandleStates to wait for
269
+ * @param signal - Optional AbortSignal to cancel the waiting operation
270
+ * @returns a promise that resolves when the document is in one of the given states (if no states
271
+ * are passed, when the document is ready)
262
272
  */
263
- async whenReady(awaitStates = ["ready"]) {
273
+ async whenReady(awaitStates = ["ready"], options) {
264
274
  try {
265
- await withTimeout(this.#statePromise(awaitStates), this.#timeoutDelay);
275
+ await withTimeout(this.#statePromise(awaitStates, options), this.#timeoutDelay);
266
276
  }
267
277
  catch (error) {
278
+ if (isAbortErrorLike(error)) {
279
+ throw new AbortError(); //throw new error for stack trace
280
+ }
268
281
  console.log(`error waiting for ${this.documentId} to be in one of states: ${awaitStates.join(", ")}`);
269
282
  throw error;
270
283
  }
package/dist/Repo.d.ts CHANGED
@@ -241,6 +241,15 @@ export interface DeleteDocumentPayload {
241
241
  documentId: DocumentId;
242
242
  }
243
243
  export type DocMetrics = DocSyncMetrics | {
244
+ type: "doc-compacted";
245
+ documentId: DocumentId;
246
+ durationMillis: number;
247
+ } | {
248
+ type: "doc-saved";
249
+ documentId: DocumentId;
250
+ durationMillis: number;
251
+ sinceHeads: Array<string>;
252
+ } | {
244
253
  type: "doc-loaded";
245
254
  documentId: DocumentId;
246
255
  durationMillis: number;
@@ -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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"}
package/dist/Repo.js CHANGED
@@ -92,6 +92,8 @@ export class Repo extends EventEmitter {
92
92
  const storageSubsystem = storage ? new StorageSubsystem(storage) : undefined;
93
93
  if (storageSubsystem) {
94
94
  storageSubsystem.on("document-loaded", event => this.emit("doc-metrics", { type: "doc-loaded", ...event }));
95
+ storageSubsystem.on("doc-compacted", event => this.emit("doc-metrics", { type: "doc-compacted", ...event }));
96
+ storageSubsystem.on("doc-saved", event => this.emit("doc-metrics", { type: "doc-saved", ...event }));
95
97
  }
96
98
  this.storageSubsystem = storageSubsystem;
97
99
  this.#saveDebounceRate = saveDebounceRate;
@@ -13,6 +13,13 @@
13
13
  export declare class AbortError extends DOMException {
14
14
  constructor(message?: string);
15
15
  }
16
+ /**
17
+ * Detects if candidate `Error` is an `AbortError` or AbortError-like.
18
+ * @remarks
19
+ * - This method detects if an error is AbortError-like (for which there could be many implementations)
20
+ * - AbortController spec defines AbortError as DOMException or Error with `name === 'AbortError'`.
21
+ */
22
+ export declare const isAbortErrorLike: (candidate: unknown) => boolean;
16
23
  /**
17
24
  * Wraps a Promise and causes it to reject when the signal is aborted.
18
25
  *
@@ -1 +1 @@
1
- {"version":3,"file":"abortable.d.ts","sourceRoot":"","sources":["../../src/helpers/abortable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,qBAAa,UAAW,SAAQ,YAAY;gBAC9B,OAAO,CAAC,EAAE,MAAM;CAG7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,SAAS,CAAC,CAAC,EACzB,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EACb,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,OAAO,CAAC,CAAC,CAAC,CAsBZ;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB"}
1
+ {"version":3,"file":"abortable.d.ts","sourceRoot":"","sources":["../../src/helpers/abortable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,qBAAa,UAAW,SAAQ,YAAY;gBAC9B,OAAO,CAAC,EAAE,MAAM;CAG7B;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAI,WAAW,OAAO,KAAG,OAQrD,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,SAAS,CAAC,CAAC,EACzB,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EACb,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,OAAO,CAAC,CAAC,CAAC,CAsBZ;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB"}
@@ -15,6 +15,19 @@ export class AbortError extends DOMException {
15
15
  super(message ?? "Operation aborted", "AbortError");
16
16
  }
17
17
  }
18
+ /**
19
+ * Detects if candidate `Error` is an `AbortError` or AbortError-like.
20
+ * @remarks
21
+ * - This method detects if an error is AbortError-like (for which there could be many implementations)
22
+ * - AbortController spec defines AbortError as DOMException or Error with `name === 'AbortError'`.
23
+ */
24
+ export const isAbortErrorLike = (candidate) => {
25
+ return (candidate instanceof AbortError ||
26
+ ((candidate instanceof Error ||
27
+ //In some JS environments, DOMException is not defined, and sometimes when defined, it does not extend Error; hence extra checks
28
+ (DOMException && candidate instanceof DOMException)) &&
29
+ candidate.name === "AbortError"));
30
+ };
18
31
  /**
19
32
  * Wraps a Promise and causes it to reject when the signal is aborted.
20
33
  *
@@ -10,6 +10,15 @@ type StorageSubsystemEvents = {
10
10
  numOps: number;
11
11
  numChanges: number;
12
12
  }) => void;
13
+ "doc-compacted": (arg: {
14
+ documentId: DocumentId;
15
+ durationMillis: number;
16
+ }) => void;
17
+ "doc-saved": (arg: {
18
+ documentId: DocumentId;
19
+ durationMillis: number;
20
+ sinceHeads: A.Heads;
21
+ }) => void;
13
22
  };
14
23
  /**
15
24
  * The storage subsystem is responsible for saving and loading Automerge documents to and from
@@ -1 +1 @@
1
- {"version":3,"file":"StorageSubsystem.d.ts","sourceRoot":"","sources":["../../src/storage/StorageSubsystem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,2BAA2B,CAAA;AAIrD,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AACtE,OAAO,EAAyB,SAAS,EAAE,MAAM,YAAY,CAAA;AAG7D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAG5C,KAAK,sBAAsB,GAAG;IAC5B,iBAAiB,EAAE,CAAC,GAAG,EAAE;QACvB,UAAU,EAAE,UAAU,CAAA;QACtB,cAAc,EAAE,MAAM,CAAA;QACtB,MAAM,EAAE,MAAM,CAAA;QACd,UAAU,EAAE,MAAM,CAAA;KACnB,KAAK,IAAI,CAAA;CACX,CAAA;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,YAAY,CAAC,sBAAsB,CAAC;;gBAe5D,cAAc,EAAE,uBAAuB;IAK7C,EAAE,IAAI,OAAO,CAAC,SAAS,CAAC;IA2B9B,kCAAkC;IAC5B,IAAI;IACR,iFAAiF;IACjF,SAAS,EAAE,MAAM;IAEjB,yFAAyF;IACzF,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAKlC,gCAAgC;IAC1B,IAAI;IACR,iFAAiF;IACjF,SAAS,EAAE,MAAM;IAEjB,yFAAyF;IACzF,GAAG,EAAE,MAAM;IAEX,sCAAsC;IACtC,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC;IAKhB,oCAAoC;IAC9B,MAAM;IACV,iFAAiF;IACjF,SAAS,EAAE,MAAM;IAEjB,2FAA2F;IAC3F,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,IAAI,CAAC;IAOhB;;OAEG;IACG,WAAW,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAgDrE;;OAEG;IACG,OAAO,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAqBlE;;;;;;OAMG;IACG,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAezE;;OAEG;IACG,SAAS,CAAC,UAAU,EAAE,UAAU;IAkEhC,aAAa,CACjB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC;IAW7B,aAAa,CACjB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,CAAC,CAAC,SAAS,GACrB,OAAO,CAAC,IAAI,CAAC;CA8CjB"}
1
+ {"version":3,"file":"StorageSubsystem.d.ts","sourceRoot":"","sources":["../../src/storage/StorageSubsystem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,2BAA2B,CAAA;AAIrD,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AACtE,OAAO,EAAyB,SAAS,EAAE,MAAM,YAAY,CAAA;AAG7D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAG5C,KAAK,sBAAsB,GAAG;IAC5B,iBAAiB,EAAE,CAAC,GAAG,EAAE;QACvB,UAAU,EAAE,UAAU,CAAA;QACtB,cAAc,EAAE,MAAM,CAAA;QACtB,MAAM,EAAE,MAAM,CAAA;QACd,UAAU,EAAE,MAAM,CAAA;KACnB,KAAK,IAAI,CAAA;IACV,eAAe,EAAE,CAAC,GAAG,EAAE;QACrB,UAAU,EAAE,UAAU,CAAA;QACtB,cAAc,EAAE,MAAM,CAAA;KACvB,KAAK,IAAI,CAAA;IACV,WAAW,EAAE,CAAC,GAAG,EAAE;QACjB,UAAU,EAAE,UAAU,CAAA;QACtB,cAAc,EAAE,MAAM,CAAA;QACtB,UAAU,EAAE,CAAC,CAAC,KAAK,CAAA;KACpB,KAAK,IAAI,CAAA;CACX,CAAA;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,YAAY,CAAC,sBAAsB,CAAC;;gBAe5D,cAAc,EAAE,uBAAuB;IAK7C,EAAE,IAAI,OAAO,CAAC,SAAS,CAAC;IA2B9B,kCAAkC;IAC5B,IAAI;IACR,iFAAiF;IACjF,SAAS,EAAE,MAAM;IAEjB,yFAAyF;IACzF,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAKlC,gCAAgC;IAC1B,IAAI;IACR,iFAAiF;IACjF,SAAS,EAAE,MAAM;IAEjB,yFAAyF;IACzF,GAAG,EAAE,MAAM;IAEX,sCAAsC;IACtC,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC;IAKhB,oCAAoC;IAC9B,MAAM;IACV,iFAAiF;IACjF,SAAS,EAAE,MAAM;IAEjB,2FAA2F;IAC3F,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,IAAI,CAAC;IAOhB;;OAEG;IACG,WAAW,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAgDrE;;OAEG;IACG,OAAO,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAqBlE;;;;;;OAMG;IACG,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAezE;;OAEG;IACG,SAAS,CAAC,UAAU,EAAE,UAAU;IAgFhC,aAAa,CACjB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC;IAW7B,aAAa,CACjB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,CAAC,CAAC,SAAS,GACrB,OAAO,CAAC,IAAI,CAAC;CA8CjB"}
@@ -173,7 +173,16 @@ export class StorageSubsystem extends EventEmitter {
173
173
  * Saves just the incremental changes since the last save.
174
174
  */
175
175
  async #saveIncremental(documentId, doc) {
176
- const binary = A.saveSince(doc, this.#storedHeads.get(documentId) ?? []);
176
+ const sinceHeads = this.#storedHeads.get(documentId) ?? [];
177
+ const start = performance.now();
178
+ const binary = A.saveSince(doc, sinceHeads);
179
+ const end = performance.now();
180
+ console.log("emitting saved");
181
+ this.emit("doc-saved", {
182
+ documentId,
183
+ durationMillis: end - start,
184
+ sinceHeads,
185
+ });
177
186
  if (binary && binary.length > 0) {
178
187
  const key = [documentId, "incremental", keyHash(binary)];
179
188
  this.#log(`Saving incremental ${key} for document ${documentId}`);
@@ -197,7 +206,10 @@ export class StorageSubsystem extends EventEmitter {
197
206
  */
198
207
  async #saveTotal(documentId, doc, sourceChunks) {
199
208
  this.#compacting = true;
209
+ const start = performance.now();
200
210
  const binary = A.save(doc);
211
+ const end = performance.now();
212
+ this.emit("doc-compacted", { documentId, durationMillis: end - start });
201
213
  const snapshotHash = headsHash(A.getHeads(doc));
202
214
  const key = [documentId, "snapshot", snapshotHash];
203
215
  const oldKeys = new Set(sourceChunks.map(c => c.key).filter(k => k[2] !== snapshotHash));
@@ -1 +1 @@
1
- {"version":3,"file":"DocSynchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/DocSynchronizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,2BAA2B,CAAA;AAGrD,OAAO,EACL,SAAS,EAKV,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAEL,gBAAgB,EAEhB,WAAW,EACX,cAAc,EACd,WAAW,EAEZ,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGhD,KAAK,kBAAkB,GAAG,SAAS,GAAG,KAAK,GAAG,aAAa,GAAG,OAAO,CAAA;AAOrE,UAAU,qBAAqB;IAC7B,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC,CAAA;CACvE;AAED;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,YAAY;;IAE/C,gBAAgB,SAAM;gBAyBV,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,qBAAqB;IAyBtE,IAAI,UAAU,uCAEb;IAED,IAAI,UAAU,qCAEb;IAqID,OAAO,CAAC,MAAM,EAAE,MAAM;IAIhB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE;IA8DjC,OAAO,CAAC,MAAM,EAAE,MAAM;IAOtB,cAAc,CAAC,OAAO,EAAE,WAAW;IAkBnC,uBAAuB,CAAC,OAAO,EAAE,gBAAgB;IAuBjD,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc;IA2FxD,OAAO,IAAI;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE;CAM7E"}
1
+ {"version":3,"file":"DocSynchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/DocSynchronizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,2BAA2B,CAAA;AAGrD,OAAO,EACL,SAAS,EAKV,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAEL,gBAAgB,EAEhB,WAAW,EACX,cAAc,EACd,WAAW,EAEZ,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGhD,KAAK,kBAAkB,GAAG,SAAS,GAAG,KAAK,GAAG,aAAa,GAAG,OAAO,CAAA;AAOrE,UAAU,qBAAqB;IAC7B,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC,CAAA;CACvE;AAED;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,YAAY;;IAE/C,gBAAgB,SAAM;gBAyBV,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,qBAAqB;IAyBtE,IAAI,UAAU,uCAEb;IAED,IAAI,UAAU,qCAEb;IA6ID,OAAO,CAAC,MAAM,EAAE,MAAM;IAIhB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE;IA8DjC,OAAO,CAAC,MAAM,EAAE,MAAM;IAOtB,cAAc,CAAC,OAAO,EAAE,WAAW;IAkBnC,uBAAuB,CAAC,OAAO,EAAE,gBAAgB;IAuBjD,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc;IA2FxD,OAAO,IAAI;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE;CAM7E"}
@@ -121,7 +121,14 @@ export class DocSynchronizer extends Synchronizer {
121
121
  #sendSyncMessage(peerId, doc) {
122
122
  this.#log(`sendSyncMessage ->${peerId}`);
123
123
  this.#withSyncState(peerId, syncState => {
124
+ const start = performance.now();
124
125
  const [newSyncState, message] = A.generateSyncMessage(doc, syncState);
126
+ const end = performance.now();
127
+ this.emit("metrics", {
128
+ type: "generate-sync-message",
129
+ documentId: this.#handle.documentId,
130
+ durationMillis: end - start,
131
+ });
125
132
  if (message) {
126
133
  this.#setSyncState(peerId, newSyncState);
127
134
  const isNew = A.getHeads(doc).length === 0;
@@ -23,6 +23,10 @@ export type DocSyncMetrics = {
23
23
  durationMillis: number;
24
24
  numOps: number;
25
25
  numChanges: number;
26
+ } | {
27
+ type: "generate-sync-message";
28
+ documentId: DocumentId;
29
+ durationMillis: number;
26
30
  } | {
27
31
  type: "doc-denied";
28
32
  documentId: DocumentId;
@@ -1 +1 @@
1
- {"version":3,"file":"Synchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/Synchronizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EACL,eAAe,EACf,cAAc,EACd,WAAW,EACZ,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAEhD,8BAAsB,YAAa,SAAQ,YAAY,CAAC,kBAAkB,CAAC;IACzE,QAAQ,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;CACpD;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAA;IAC3C,YAAY,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAA;IACjD,UAAU,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAA;IACzC,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAA;CACvC;AAED,uDAAuD;AACvD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,UAAU,CAAA;IACtB,SAAS,EAAE,SAAS,CAAA;CACrB;AAED,MAAM,MAAM,cAAc,GACtB;IACE,IAAI,EAAE,sBAAsB,CAAA;IAC5B,UAAU,EAAE,UAAU,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;CACnB,GACD;IACE,IAAI,EAAE,YAAY,CAAA;IAClB,UAAU,EAAE,UAAU,CAAA;CACvB,CAAA"}
1
+ {"version":3,"file":"Synchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/Synchronizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EACL,eAAe,EACf,cAAc,EACd,WAAW,EACZ,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAEhD,8BAAsB,YAAa,SAAQ,YAAY,CAAC,kBAAkB,CAAC;IACzE,QAAQ,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;CACpD;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAA;IAC3C,YAAY,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAA;IACjD,UAAU,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAA;IACzC,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAA;CACvC;AAED,uDAAuD;AACvD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,UAAU,CAAA;IACtB,SAAS,EAAE,SAAS,CAAA;CACrB;AAED,MAAM,MAAM,cAAc,GACtB;IACE,IAAI,EAAE,sBAAsB,CAAA;IAC5B,UAAU,EAAE,UAAU,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;CACnB,GACD;IACE,IAAI,EAAE,uBAAuB,CAAA;IAC7B,UAAU,EAAE,UAAU,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;CACvB,GACD;IACE,IAAI,EAAE,YAAY,CAAA;IAClB,UAAU,EAAE,UAAU,CAAA;CACvB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automerge/automerge-repo",
3
- "version": "2.4.0",
3
+ "version": "2.5.0-alpha.0",
4
4
  "description": "A repository object to manage a collection of automerge documents",
5
5
  "repository": "https://github.com/automerge/automerge-repo/tree/master/packages/automerge-repo",
6
6
  "author": "Peter van Hardenberg <pvh@pvh.ca>",
@@ -59,5 +59,5 @@
59
59
  "publishConfig": {
60
60
  "access": "public"
61
61
  },
62
- "gitHead": "586290a804e12206362cf41c87e309bd0fb22d69"
62
+ "gitHead": "6d94459eecf708f9c508be7e22c2035abffc03a4"
63
63
  }
package/src/DocHandle.ts CHANGED
@@ -12,6 +12,11 @@ import { headsAreSame } from "./helpers/headsAreSame.js"
12
12
  import { withTimeout } from "./helpers/withTimeout.js"
13
13
  import type { AutomergeUrl, DocumentId, PeerId, UrlHeads } from "./types.js"
14
14
  import { StorageId } from "./storage/types.js"
15
+ import {
16
+ AbortError,
17
+ AbortOptions,
18
+ isAbortErrorLike,
19
+ } from "./helpers/abortable.js"
15
20
 
16
21
  /**
17
22
  * A DocHandle is a wrapper around a single Automerge document that lets us listen for changes and
@@ -170,8 +175,16 @@ export class DocHandle<T> extends EventEmitter<DocHandleEvents<T>> {
170
175
  return this.#machine?.getSnapshot().value
171
176
  }
172
177
 
173
- /** Returns a promise that resolves when the docHandle is in one of the given states */
174
- #statePromise(awaitStates: HandleState | HandleState[]) {
178
+ /**
179
+ * Returns a promise that resolves when the docHandle is in one of the given states
180
+ *
181
+ * @param awaitStates - HandleState or HandleStates to wait for
182
+ * @param signal - Optional AbortSignal to cancel the waiting operation
183
+ */
184
+ #statePromise(
185
+ awaitStates: HandleState | HandleState[],
186
+ options?: AbortOptions
187
+ ) {
175
188
  const awaitStatesArray = Array.isArray(awaitStates)
176
189
  ? awaitStates
177
190
  : [awaitStates]
@@ -179,7 +192,7 @@ export class DocHandle<T> extends EventEmitter<DocHandleEvents<T>> {
179
192
  this.#machine,
180
193
  s => awaitStatesArray.some(state => s.matches(state)),
181
194
  // use a longer delay here so as not to race with other delays
182
- { timeout: this.#timeoutDelay * 2 }
195
+ { timeout: this.#timeoutDelay * 2, ...options }
183
196
  )
184
197
  }
185
198
 
@@ -301,16 +314,29 @@ export class DocHandle<T> extends EventEmitter<DocHandleEvents<T>> {
301
314
  }
302
315
 
303
316
  /**
304
- * @returns a promise that resolves when the document is in one of the given states (if no states
305
- * are passed, when the document is ready)
317
+ * Returns promise that resolves when document is in one of the given states (default is 'ready' state)
306
318
  *
307
319
  * Use this to block until the document handle has finished loading. The async equivalent to
308
320
  * checking `inState()`.
321
+ *
322
+ * @param awaitStates - HandleState or HandleStates to wait for
323
+ * @param signal - Optional AbortSignal to cancel the waiting operation
324
+ * @returns a promise that resolves when the document is in one of the given states (if no states
325
+ * are passed, when the document is ready)
309
326
  */
310
- async whenReady(awaitStates: HandleState[] = ["ready"]) {
327
+ async whenReady(
328
+ awaitStates: HandleState[] = ["ready"],
329
+ options?: AbortOptions
330
+ ) {
311
331
  try {
312
- await withTimeout(this.#statePromise(awaitStates), this.#timeoutDelay)
332
+ await withTimeout(
333
+ this.#statePromise(awaitStates, options),
334
+ this.#timeoutDelay
335
+ )
313
336
  } catch (error) {
337
+ if (isAbortErrorLike(error)) {
338
+ throw new AbortError() //throw new error for stack trace
339
+ }
314
340
  console.log(
315
341
  `error waiting for ${
316
342
  this.documentId
package/src/Repo.ts CHANGED
@@ -172,6 +172,12 @@ export class Repo extends EventEmitter<RepoEvents> {
172
172
  storageSubsystem.on("document-loaded", event =>
173
173
  this.emit("doc-metrics", { type: "doc-loaded", ...event })
174
174
  )
175
+ storageSubsystem.on("doc-compacted", event =>
176
+ this.emit("doc-metrics", { type: "doc-compacted", ...event })
177
+ )
178
+ storageSubsystem.on("doc-saved", event =>
179
+ this.emit("doc-metrics", { type: "doc-saved", ...event })
180
+ )
175
181
  }
176
182
 
177
183
  this.storageSubsystem = storageSubsystem
@@ -1088,6 +1094,17 @@ export interface DeleteDocumentPayload {
1088
1094
 
1089
1095
  export type DocMetrics =
1090
1096
  | DocSyncMetrics
1097
+ | {
1098
+ type: "doc-compacted"
1099
+ documentId: DocumentId
1100
+ durationMillis: number
1101
+ }
1102
+ | {
1103
+ type: "doc-saved"
1104
+ documentId: DocumentId
1105
+ durationMillis: number
1106
+ sinceHeads: Array<string>
1107
+ }
1091
1108
  | {
1092
1109
  type: "doc-loaded"
1093
1110
  documentId: DocumentId
@@ -16,6 +16,22 @@ export class AbortError extends DOMException {
16
16
  }
17
17
  }
18
18
 
19
+ /**
20
+ * Detects if candidate `Error` is an `AbortError` or AbortError-like.
21
+ * @remarks
22
+ * - This method detects if an error is AbortError-like (for which there could be many implementations)
23
+ * - AbortController spec defines AbortError as DOMException or Error with `name === 'AbortError'`.
24
+ */
25
+ export const isAbortErrorLike = (candidate: unknown): boolean => {
26
+ return (
27
+ candidate instanceof AbortError ||
28
+ ((candidate instanceof Error ||
29
+ //In some JS environments, DOMException is not defined, and sometimes when defined, it does not extend Error; hence extra checks
30
+ (DOMException && candidate instanceof DOMException)) &&
31
+ candidate.name === "AbortError")
32
+ )
33
+ }
34
+
19
35
  /**
20
36
  * Wraps a Promise and causes it to reject when the signal is aborted.
21
37
  *
@@ -17,6 +17,15 @@ type StorageSubsystemEvents = {
17
17
  numOps: number
18
18
  numChanges: number
19
19
  }) => void
20
+ "doc-compacted": (arg: {
21
+ documentId: DocumentId
22
+ durationMillis: number
23
+ }) => void
24
+ "doc-saved": (arg: {
25
+ documentId: DocumentId
26
+ durationMillis: number
27
+ sinceHeads: A.Heads
28
+ }) => void
20
29
  }
21
30
 
22
31
  /**
@@ -224,7 +233,17 @@ export class StorageSubsystem extends EventEmitter<StorageSubsystemEvents> {
224
233
  documentId: DocumentId,
225
234
  doc: A.Doc<unknown>
226
235
  ): Promise<void> {
227
- const binary = A.saveSince(doc, this.#storedHeads.get(documentId) ?? [])
236
+ const sinceHeads = this.#storedHeads.get(documentId) ?? []
237
+ const start = performance.now()
238
+ const binary = A.saveSince(doc, sinceHeads)
239
+ const end = performance.now()
240
+ console.log("emitting saved")
241
+ this.emit("doc-saved", {
242
+ documentId,
243
+ durationMillis: end - start,
244
+ sinceHeads,
245
+ })
246
+
228
247
  if (binary && binary.length > 0) {
229
248
  const key = [documentId, "incremental", keyHash(binary)]
230
249
  this.#log(`Saving incremental ${key} for document ${documentId}`)
@@ -253,7 +272,11 @@ export class StorageSubsystem extends EventEmitter<StorageSubsystemEvents> {
253
272
  ): Promise<void> {
254
273
  this.#compacting = true
255
274
 
275
+ const start = performance.now()
256
276
  const binary = A.save(doc)
277
+ const end = performance.now()
278
+ this.emit("doc-compacted", { documentId, durationMillis: end - start })
279
+
257
280
  const snapshotHash = headsHash(A.getHeads(doc))
258
281
  const key = [documentId, "snapshot", snapshotHash]
259
282
  const oldKeys = new Set(
@@ -191,7 +191,15 @@ export class DocSynchronizer extends Synchronizer {
191
191
  this.#log(`sendSyncMessage ->${peerId}`)
192
192
 
193
193
  this.#withSyncState(peerId, syncState => {
194
+ const start = performance.now()
194
195
  const [newSyncState, message] = A.generateSyncMessage(doc, syncState)
196
+ const end = performance.now()
197
+ this.emit("metrics", {
198
+ type: "generate-sync-message",
199
+ documentId: this.#handle.documentId,
200
+ durationMillis: end - start,
201
+ })
202
+
195
203
  if (message) {
196
204
  this.#setSyncState(peerId, newSyncState)
197
205
  const isNew = A.getHeads(doc).length === 0
@@ -33,6 +33,11 @@ export type DocSyncMetrics =
33
33
  numOps: number
34
34
  numChanges: number
35
35
  }
36
+ | {
37
+ type: "generate-sync-message"
38
+ documentId: DocumentId
39
+ durationMillis: number
40
+ }
36
41
  | {
37
42
  type: "doc-denied"
38
43
  documentId: DocumentId
package/test/Repo.test.ts CHANGED
@@ -11,7 +11,12 @@ import {
11
11
  generateAutomergeUrl,
12
12
  stringifyAutomergeUrl,
13
13
  } from "../src/AutomergeUrl.js"
14
- import { FindProgressWithMethods, Repo, ShareConfig } from "../src/Repo.js"
14
+ import {
15
+ DocMetrics,
16
+ FindProgressWithMethods,
17
+ Repo,
18
+ ShareConfig,
19
+ } from "../src/Repo.js"
15
20
  import { eventPromise } from "../src/helpers/eventPromise.js"
16
21
  import { pause } from "../src/helpers/pause.js"
17
22
  import {
@@ -2039,7 +2044,7 @@ describe("Repo.find() abort behavior", () => {
2039
2044
  it("creates a document with the custom ID", async () => {
2040
2045
  const id = new Uint8Array("custom-id".split("").map(c => c.charCodeAt(0)))
2041
2046
  const repo = new Repo({
2042
- idFactory: () => id,
2047
+ idFactory: async () => id,
2043
2048
  })
2044
2049
  const handle = await repo.create2()
2045
2050
  expect(handle.documentId).toBe("9HUp4wuzRMx9MRvN4x")
@@ -2049,7 +2054,7 @@ describe("Repo.find() abort behavior", () => {
2049
2054
  const id = new Uint8Array("custom-id".split("").map(c => c.charCodeAt(0)))
2050
2055
  let calledHeads: Heads | null = null
2051
2056
  const repo = new Repo({
2052
- idFactory: (heads: Heads) => {
2057
+ idFactory: async (heads: Heads) => {
2053
2058
  calledHeads = heads
2054
2059
  return id
2055
2060
  },
@@ -2063,7 +2068,7 @@ describe("Repo.find() abort behavior", () => {
2063
2068
  const [aliceToBob, bobToAlice] = DummyNetworkAdapter.createConnectedPair()
2064
2069
  const alice = new Repo({
2065
2070
  peerId: "alice" as PeerId,
2066
- idFactory: () =>
2071
+ idFactory: async () =>
2067
2072
  new Uint8Array("custom-id".split("").map(c => c.charCodeAt(0))),
2068
2073
  network: [aliceToBob],
2069
2074
  })
@@ -2078,6 +2083,166 @@ describe("Repo.find() abort behavior", () => {
2078
2083
  assert.deepStrictEqual(bobHandle.doc(), { foo: "bar" })
2079
2084
  })
2080
2085
  })
2086
+
2087
+ describe("emitted metrics", () => {
2088
+ async function setup(): Promise<{ alice: Repo; bob: Repo }> {
2089
+ const [aliceToBob, bobToAlice] = DummyNetworkAdapter.createConnectedPair()
2090
+ const alice = new Repo({
2091
+ peerId: "alice" as PeerId,
2092
+ network: [aliceToBob],
2093
+ })
2094
+ const bob = new Repo({ peerId: "bob" as PeerId, network: [bobToAlice] })
2095
+ aliceToBob.peerCandidate("bob" as PeerId)
2096
+ bobToAlice.peerCandidate("alice" as PeerId)
2097
+
2098
+ await pause(50)
2099
+
2100
+ return { alice, bob }
2101
+ }
2102
+
2103
+ it("should emit events for receive sync message", async () => {
2104
+ const { alice, bob } = await setup()
2105
+
2106
+ const bobEvents: DocMetrics[] = []
2107
+ bob.on("doc-metrics", e => {
2108
+ if (e.type === "receive-sync-message") {
2109
+ bobEvents.push(e)
2110
+ }
2111
+ })
2112
+
2113
+ const handle = await alice.create2({ foo: "bar" })
2114
+ const bobHandle = await bob.find(handle.url)
2115
+
2116
+ assert.notEqual(bobEvents.length, 0)
2117
+ assert(
2118
+ bobEvents.every(
2119
+ e =>
2120
+ e.type === "receive-sync-message" &&
2121
+ e.documentId == handle.documentId &&
2122
+ e.durationMillis > 0
2123
+ )
2124
+ )
2125
+
2126
+ await Promise.all([bob.shutdown(), alice.shutdown()])
2127
+ })
2128
+
2129
+ it("should emit events for generate sync message", async () => {
2130
+ const { alice, bob } = await setup()
2131
+
2132
+ const bobEvents: DocMetrics[] = []
2133
+ bob.on("doc-metrics", e => {
2134
+ if (e.type === "generate-sync-message") {
2135
+ bobEvents.push(e)
2136
+ }
2137
+ })
2138
+
2139
+ const handle = await alice.create2({ foo: "bar" })
2140
+ const bobHandle = await bob.find(handle.url)
2141
+
2142
+ assert.notEqual(bobEvents.length, 0)
2143
+ assert(
2144
+ bobEvents.every(
2145
+ e =>
2146
+ e.type === "generate-sync-message" &&
2147
+ e.documentId == handle.documentId &&
2148
+ e.durationMillis > 0
2149
+ )
2150
+ )
2151
+
2152
+ await Promise.all([bob.shutdown(), alice.shutdown()])
2153
+ })
2154
+
2155
+ it("should emit events on compaction", async () => {
2156
+ const bob = new Repo({ storage: new DummyStorageAdapter() })
2157
+ // Create a doc and change it enough times to trigger compaction
2158
+ const doc = bob.create({ foo: "bar" })
2159
+
2160
+ const events: DocMetrics[] = []
2161
+ bob.on("doc-metrics", e => {
2162
+ if (e.type === "doc-compacted") {
2163
+ events.push(e)
2164
+ }
2165
+ })
2166
+
2167
+ for (let i = 0; i < 1000; i++) {
2168
+ doc.change(d => {
2169
+ A.splice(d, ["foo"], 0, 1, `${i}`)
2170
+ })
2171
+ }
2172
+
2173
+ await pause(50)
2174
+
2175
+ assert.notEqual(events.length, 0)
2176
+ assert(
2177
+ events.every(
2178
+ e =>
2179
+ e.type === "doc-compacted" &&
2180
+ e.documentId == doc.documentId &&
2181
+ e.durationMillis > 0
2182
+ )
2183
+ )
2184
+
2185
+ await bob.shutdown()
2186
+ })
2187
+
2188
+ it("should emit events on save since", async () => {
2189
+ const bob = new Repo({
2190
+ storage: new DummyStorageAdapter(),
2191
+ saveDebounceRate: 10,
2192
+ })
2193
+
2194
+ const events: DocMetrics[] = []
2195
+ bob.on("doc-metrics", e => {
2196
+ console.log("event: ", e)
2197
+ if (e.type === "doc-saved") {
2198
+ events.push(e)
2199
+ }
2200
+ })
2201
+
2202
+ const doc = bob.create({ foo: "bar" })
2203
+
2204
+ // We have to save, then pause, then save again in order to trigger the
2205
+ // initial compaction and then get to the point where the save actually
2206
+ // triggers incremental saves rather than compactions. This is because the
2207
+ // logic in the storage adapter is designed to initially compact on every
2208
+ // change and only start incremental saves as the document gets a little
2209
+ // larger.
2210
+
2211
+ // First create enough changes to get past the "always compact" threshold
2212
+ for (let i = 0; i < 1000; i++) {
2213
+ doc.change(d => {
2214
+ A.splice(d, ["foo"], 0, 1, `${i}`)
2215
+ })
2216
+ }
2217
+
2218
+ // Wait for the debounced save routine to finish
2219
+ await pause(20)
2220
+
2221
+ // Now trigger some changes which will cause incremental saves
2222
+ for (let i = 0; i < 10; i++) {
2223
+ doc.change(d => {
2224
+ A.splice(d, ["foo"], 0, 1, `${i}`)
2225
+ })
2226
+ }
2227
+
2228
+ // Wait for the debounced save routine again
2229
+ await pause(20)
2230
+
2231
+ // Now actually test the events we got
2232
+ assert.notEqual(events.length, 0)
2233
+ assert(
2234
+ events.every(
2235
+ e =>
2236
+ e.type === "doc-saved" &&
2237
+ e.documentId == doc.documentId &&
2238
+ e.durationMillis > 0 &&
2239
+ A.hasHeads(doc.doc(), e.sinceHeads)
2240
+ )
2241
+ )
2242
+
2243
+ await bob.shutdown()
2244
+ })
2245
+ })
2081
2246
  })
2082
2247
 
2083
2248
  const warn = console.warn