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

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.
@@ -1 +1 @@
1
- {"version":3,"file":"AutomergeUrl.d.ts","sourceRoot":"","sources":["../src/AutomergeUrl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,QAAQ,EACT,MAAM,YAAY,CAAA;AASnB,OAAO,KAAK,EAAE,KAAK,IAAI,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAExE,eAAO,MAAM,SAAS,eAAe,CAAA;AAErC,UAAU,kBAAkB;IAC1B,2BAA2B;IAC3B,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,8BAA8B;IAC9B,UAAU,EAAE,UAAU,CAAA;IACtB,mDAAmD;IACnD,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,sGAAsG;AACtG,eAAO,MAAM,iBAAiB,GAAI,KAAK,YAAY,KAAG,kBAsBrD,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAChC,KAAK,UAAU,GAAG,UAAU,GAAG,gBAAgB,KAC9C,YAgCF,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,eAAe,GAAI,KAAK,YAAY,KAAG,MAAM,EAAE,GAAG,SAG9D,CAAA;AAED,eAAO,MAAM,2BAA2B,GAAI,IAAI,aAAa,6BAO9C,CAAA;AAEf;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,KAAK,OAAO,KAAG,GAAG,IAAI,YAsBzD,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,KAAK,OAAO,KAAG,GAAG,IAAI,UASvD,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,KAAK,OAAO,KAAG,GAAG,IAAI,gBACH,CAAA;AAE/C;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAAO,YAGvC,CAAA;AAED,eAAO,MAAM,kBAAkB,GAAI,OAAO,UAAU,KACjB,gBAAgB,GAAG,SAAS,CAAA;AAE/D,eAAO,MAAM,kBAAkB,GAAI,OAAO,gBAAgB,KAC7B,UAAU,CAAA;AAEvC,eAAO,MAAM,WAAW,GAAI,OAAO,cAAc,KAAG,QACsB,CAAA;AAE1E,eAAO,MAAM,WAAW,GAAI,OAAO,QAAQ,KAAG,cACgC,CAAA;AAE9E,eAAO,MAAM,eAAe,GAAI,KAAK,MAAM,6BAI1C,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,GAAI,IAAI,aAAa,eAqBtD,CAAA;AAID,KAAK,UAAU,GAAG;IAChB,UAAU,EAAE,UAAU,GAAG,gBAAgB,CAAA;IACzC,KAAK,CAAC,EAAE,QAAQ,CAAA;CACjB,CAAA"}
1
+ {"version":3,"file":"AutomergeUrl.d.ts","sourceRoot":"","sources":["../src/AutomergeUrl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,QAAQ,EACT,MAAM,YAAY,CAAA;AASnB,OAAO,KAAK,EAAE,KAAK,IAAI,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAExE,eAAO,MAAM,SAAS,eAAe,CAAA;AAErC,UAAU,kBAAkB;IAC1B,2BAA2B;IAC3B,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,8BAA8B;IAC9B,UAAU,EAAE,UAAU,CAAA;IACtB,mDAAmD;IACnD,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,sGAAsG;AACtG,eAAO,MAAM,iBAAiB,GAAI,KAAK,YAAY,KAAG,kBAsBrD,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAChC,KAAK,UAAU,GAAG,UAAU,GAAG,gBAAgB,KAC9C,YAgCF,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,eAAe,GAAI,KAAK,YAAY,KAAG,MAAM,EAAE,GAAG,SAG9D,CAAA;AAED,eAAO,MAAM,2BAA2B,GAAI,IAAI,aAAa,6BAO9C,CAAA;AAEf;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,KAAK,OAAO,KAAG,GAAG,IAAI,YAsBzD,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,KAAK,OAAO,KAAG,GAAG,IAAI,UAKvD,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,KAAK,OAAO,KAAG,GAAG,IAAI,gBACH,CAAA;AAE/C;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAAO,YAGvC,CAAA;AAED,eAAO,MAAM,kBAAkB,GAAI,OAAO,UAAU,KACjB,gBAAgB,GAAG,SAAS,CAAA;AAE/D,eAAO,MAAM,kBAAkB,GAAI,OAAO,gBAAgB,KAC7B,UAAU,CAAA;AAEvC,eAAO,MAAM,WAAW,GAAI,OAAO,cAAc,KAAG,QACsB,CAAA;AAE1E,eAAO,MAAM,WAAW,GAAI,OAAO,QAAQ,KAAG,cACgC,CAAA;AAE9E,eAAO,MAAM,eAAe,GAAI,KAAK,MAAM,6BAI1C,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,GAAI,IAAI,aAAa,eAqBtD,CAAA;AAID,KAAK,UAAU,GAAG;IAChB,UAAU,EAAE,UAAU,GAAG,gBAAgB,CAAA;IACzC,KAAK,CAAC,EAAE,QAAQ,CAAA;CACjB,CAAA"}
@@ -103,11 +103,7 @@ export const isValidDocumentId = (str) => {
103
103
  return false;
104
104
  // try to decode from base58
105
105
  const binaryDocumentID = documentIdToBinary(str);
106
- if (binaryDocumentID === undefined)
107
- return false; // invalid base58check encoding
108
- // confirm that the document ID is a valid UUID
109
- const documentId = Uuid.stringify(binaryDocumentID);
110
- return Uuid.validate(documentId);
106
+ return binaryDocumentID !== undefined;
111
107
  };
112
108
  export const isValidUuid = (str) => typeof str === "string" && Uuid.validate(str);
113
109
  /**
package/dist/Repo.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Heads } from "@automerge/automerge/slim";
1
2
  import { EventEmitter } from "eventemitter3";
2
3
  import { DocHandle } from "./DocHandle.js";
3
4
  import { NetworkAdapterInterface, type PeerMetadata } from "./network/NetworkAdapterInterface.js";
@@ -39,7 +40,7 @@ export declare class Repo extends EventEmitter<RepoEvents> {
39
40
  /** maps peer id to to persistence information (storageId, isEphemeral), access by collection synchronizer */
40
41
  /** @hidden */
41
42
  peerMetadataByPeerId: Record<PeerId, PeerMetadata>;
42
- constructor({ storage, network, peerId, sharePolicy, shareConfig, isEphemeral, enableRemoteHeadsGossiping, denylist, saveDebounceRate, }?: RepoConfig);
43
+ constructor({ storage, network, peerId, sharePolicy, shareConfig, isEphemeral, enableRemoteHeadsGossiping, denylist, saveDebounceRate, idFactory, }?: RepoConfig);
43
44
  /** Returns all the handles we have cached. */
44
45
  get handles(): Record<DocumentId, DocHandle<any>>;
45
46
  /** Returns a list of all connected peer ids */
@@ -60,6 +61,18 @@ export declare class Repo extends EventEmitter<RepoEvents> {
60
61
  * system. we emit a `document` event to advertise interest in the document.
61
62
  */
62
63
  create<T>(initialValue?: T): DocHandle<T>;
64
+ /**
65
+ * Creates a new document and returns a handle to it. The initial value of the
66
+ * document is an empty object `{}` unless an initial value is provided. The
67
+ * main difference between this and Repo.create is that if an `idGenerator`
68
+ * was provided at repo construction, that idGenerator will be used to
69
+ * generate the document ID of the document returned by this method.
70
+ *
71
+ * This is a hidden, experimental API which is subject to change or removal without notice.
72
+ * @hidden
73
+ * @experimental
74
+ */
75
+ create2<T>(initialValue?: T): Promise<DocHandle<T>>;
63
76
  /** Create a new DocHandle by cloning the history of an existing DocHandle.
64
77
  *
65
78
  * @param clonedHandle - The handle to clone
@@ -149,13 +162,16 @@ export interface RepoConfig {
149
162
  /**
150
163
  * Normal peers typically share generously with everyone (meaning we sync all our documents with
151
164
  * all peers). A server only syncs documents that a peer explicitly requests by ID.
152
- * @deprecated Use `shareConfig` instead
153
165
  */
154
166
  sharePolicy?: SharePolicy;
155
167
  /**
156
168
  * Whether to share documents with other peers. By default we announce new
157
169
  * documents to everyone and allow everyone access to documents, see the
158
170
  * documentation for {@link ShareConfig} to override this
171
+ *
172
+ * Note that this is currently an experimental API and will very likely change
173
+ * without a major release.
174
+ * @experimental
159
175
  */
160
176
  shareConfig?: ShareConfig;
161
177
  /**
@@ -172,6 +188,10 @@ export interface RepoConfig {
172
188
  * The debounce rate in milliseconds for saving documents. Defaults to 100ms.
173
189
  */
174
190
  saveDebounceRate?: number;
191
+ /**
192
+ * @hidden
193
+ */
194
+ idFactory?: (initialHeads: Heads) => Promise<Uint8Array>;
175
195
  }
176
196
  /** A function that determines whether we should share a document with a peer
177
197
  *
@@ -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":"AAAA,OAAO,EAAqB,KAAK,EAAE,MAAM,2BAA2B,CAAA;AAEpE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAS5C,OAAO,EAEL,SAAS,EAKV,MAAM,gBAAgB,CAAA;AAIvB,OAAO,EACL,uBAAuB,EACvB,KAAK,YAAY,EAClB,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAEhE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAA;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAA;AACjF,OAAO,EACL,cAAc,EAEf,MAAM,gCAAgC,CAAA;AACvC,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EAEZ,UAAU,EACV,MAAM,EACP,MAAM,YAAY,CAAA;AACnB,OAAO,EAAa,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD,MAAM,MAAM,uBAAuB,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG;IACzD,UAAU,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;IAChE,IAAI,EAAE,MAAM,YAAY,CAAC,CAAC,CAAC,CAAA;IAC3B,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,MAAM,IAAI,CAAA;CACzE,CAAA;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,IAAI,EAAE,MAAM,YAAY,CAAC,CAAC,CAAC,CAAA;IAC3B,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,MAAM,IAAI,CAAA;IACxE,UAAU,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;CACjE,CAAA;AAMD,8FAA8F;AAC9F;;;;;;GAMG;AACH,qBAAa,IAAK,SAAQ,YAAY,CAAC,UAAU,CAAC;;IAGhD,cAAc;IACd,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,cAAc;IACd,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IAUnC,cAAc;IACd,YAAY,EAAE,sBAAsB,CAAA;IAOpC,8GAA8G;IAC9G,cAAc;IACd,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAK;gBAW3C,EACV,OAAO,EACP,OAAY,EACZ,MAAuB,EACvB,WAAW,EACX,WAAW,EACX,WAAmC,EACnC,0BAAkC,EAClC,QAAa,EACb,gBAAsB,EACtB,SAAS,GACV,GAAE,UAAe;IAmSlB,8CAA8C;IAC9C,IAAI,OAAO,uCAEV;IAED,+CAA+C;IAC/C,IAAI,KAAK,IAAI,MAAM,EAAE,CAEpB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,cAAc;IACd,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED,cAAc;IACd,IAAI,WAAW,CAAC,MAAM,EAAE,WAAW,EAElC;IAED,cAAc;IACd,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED,cAAc;IACd,IAAI,WAAW,CAAC,MAAM,EAAE,WAAW,EAElC;IAED,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAIzD;;;;OAIG;IACH,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAwBzC;;;;;;;;;;OAUG;IACG,OAAO,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IA8BzD;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;IAmBnC,gBAAgB,CAAC,CAAC,EAChB,EAAE,EAAE,aAAa,EACjB,OAAO,GAAE,YAAiB,GACzB,uBAAuB,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;IAgKzC,IAAI,CAAC,CAAC,EACV,EAAE,EAAE,aAAa,EACjB,OAAO,GAAE,eAAe,GAAG,YAAiB,GAC3C,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IA0ExB;;;OAGG;IACG,WAAW,CAAC,CAAC;IACjB,sDAAsD;IACtD,EAAE,EAAE,aAAa,EACjB,OAAO,GAAE,eAAe,GAAG,YAAiB,GAC3C,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAmBxB,MAAM;IACJ,oDAAoD;IACpD,EAAE,EAAE,aAAa;IAanB;;;;;;OAMG;IACG,MAAM,CAAC,EAAE,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAQhE;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC,CAAC;IAoB1E,kBAAkB,GAAI,SAAS,SAAS,EAAE,UASzC;IAED,SAAS,QAAa,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAMnD;IAED;;;;;OAKG;IACG,KAAK,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAcpD;;;;;OAKG;IACG,eAAe,CAAC,UAAU,EAAE,UAAU;IA8B5C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAOzB,OAAO,IAAI;QAAE,SAAS,EAAE;YAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;SAAE,CAAA;KAAE;CAGjD;AAED,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;8DAC0D;IAC1D,WAAW,CAAC,EAAE,OAAO,CAAA;IAErB,gDAAgD;IAChD,OAAO,CAAC,EAAE,uBAAuB,CAAA;IAEjC,iEAAiE;IACjE,OAAO,CAAC,EAAE,uBAAuB,EAAE,CAAA;IAEnC;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;IAEzB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;IAEzB;;OAEG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAA;IAEpC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAA;IAEzB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAIzB;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,KAAK,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;CACzD;AAED;;;;;;;KAOK;AACL,MAAM,MAAM,WAAW,GAAG,CACxB,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,UAAU,KACpB,OAAO,CAAC,OAAO,CAAC,CAAA;AAErB;;KAEK;AACL,MAAM,MAAM,WAAW,GAAG;IACxB;;;;;;;;;OASG;IACH,QAAQ,EAAE,WAAW,CAAA;IACrB;;OAEG;IACH,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC5D,CAAA;AAGD,MAAM,WAAW,UAAU;IACzB,+CAA+C;IAC/C,QAAQ,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,CAAA;IACxC,6BAA6B;IAC7B,iBAAiB,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,IAAI,CAAA;IACvD,4FAA4F;IAC5F,sBAAsB,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,IAAI,CAAA;IAC5D,aAAa,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAA;CACzC;AAED,MAAM,WAAW,eAAe;IAC9B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,UAAU,CAAA;CACvB;AAED,MAAM,MAAM,UAAU,GAClB,cAAc,GACd;IACE,IAAI,EAAE,YAAY,CAAA;IAClB,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"}
package/dist/Repo.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { next as Automerge } from "@automerge/automerge/slim";
2
2
  import debug from "debug";
3
3
  import { EventEmitter } from "eventemitter3";
4
- import { encodeHeads, generateAutomergeUrl, interpretAsDocumentId, isValidAutomergeUrl, parseAutomergeUrl, } from "./AutomergeUrl.js";
4
+ import { binaryToDocumentId, encodeHeads, generateAutomergeUrl, interpretAsDocumentId, isValidAutomergeUrl, parseAutomergeUrl, } from "./AutomergeUrl.js";
5
5
  import { DELETED, DocHandle, READY, UNAVAILABLE, UNLOADED, } from "./DocHandle.js";
6
6
  import { RemoteHeadsSubscriptions } from "./RemoteHeadsSubscriptions.js";
7
7
  import { headsAreSame } from "./helpers/headsAreSame.js";
@@ -45,10 +45,12 @@ export class Repo extends EventEmitter {
45
45
  #remoteHeadsGossipingEnabled = false;
46
46
  #progressCache = {};
47
47
  #saveFns = {};
48
- constructor({ storage, network = [], peerId = randomPeerId(), sharePolicy, shareConfig, isEphemeral = storage === undefined, enableRemoteHeadsGossiping = false, denylist = [], saveDebounceRate = 100, } = {}) {
48
+ #idFactory;
49
+ constructor({ storage, network = [], peerId = randomPeerId(), sharePolicy, shareConfig, isEphemeral = storage === undefined, enableRemoteHeadsGossiping = false, denylist = [], saveDebounceRate = 100, idFactory, } = {}) {
49
50
  super();
50
51
  this.#remoteHeadsGossipingEnabled = enableRemoteHeadsGossiping;
51
52
  this.#log = debug(`automerge-repo:repo`);
53
+ this.#idFactory = idFactory || null;
52
54
  // Handle legacy sharePolicy
53
55
  if (sharePolicy != null && shareConfig != null) {
54
56
  throw new Error("cannot provide both sharePolicy and shareConfig at once");
@@ -300,6 +302,13 @@ export class Repo extends EventEmitter {
300
302
  * system. we emit a `document` event to advertise interest in the document.
301
303
  */
302
304
  create(initialValue) {
305
+ let initialDoc;
306
+ if (initialValue) {
307
+ initialDoc = Automerge.from(initialValue);
308
+ }
309
+ else {
310
+ initialDoc = Automerge.emptyChange(Automerge.init());
311
+ }
303
312
  // Generate a new UUID and store it in the buffer
304
313
  const { documentId } = parseAutomergeUrl(generateAutomergeUrl());
305
314
  const handle = this.#getHandle({
@@ -307,14 +316,45 @@ export class Repo extends EventEmitter {
307
316
  });
308
317
  this.#registerHandleWithSubsystems(handle);
309
318
  handle.update(() => {
310
- let nextDoc;
311
- if (initialValue) {
312
- nextDoc = Automerge.from(initialValue);
313
- }
314
- else {
315
- nextDoc = Automerge.emptyChange(Automerge.init());
316
- }
317
- return nextDoc;
319
+ return initialDoc;
320
+ });
321
+ handle.doneLoading();
322
+ return handle;
323
+ }
324
+ /**
325
+ * Creates a new document and returns a handle to it. The initial value of the
326
+ * document is an empty object `{}` unless an initial value is provided. The
327
+ * main difference between this and Repo.create is that if an `idGenerator`
328
+ * was provided at repo construction, that idGenerator will be used to
329
+ * generate the document ID of the document returned by this method.
330
+ *
331
+ * This is a hidden, experimental API which is subject to change or removal without notice.
332
+ * @hidden
333
+ * @experimental
334
+ */
335
+ async create2(initialValue) {
336
+ // Note that the reason this method is hidden and experimental is because it is async,
337
+ // and it is async because we want to be able to call the #idGenerator, which is async.
338
+ // This is all really in service of wiring up keyhive and we probably need to find a
339
+ // nicer way to achieve this.
340
+ let initialDoc;
341
+ if (initialValue) {
342
+ initialDoc = Automerge.from(initialValue);
343
+ }
344
+ else {
345
+ initialDoc = Automerge.emptyChange(Automerge.init());
346
+ }
347
+ let { documentId } = parseAutomergeUrl(generateAutomergeUrl());
348
+ if (this.#idFactory) {
349
+ const rawDocId = await this.#idFactory(Automerge.getHeads(initialDoc));
350
+ documentId = binaryToDocumentId(rawDocId);
351
+ }
352
+ const handle = this.#getHandle({
353
+ documentId,
354
+ });
355
+ this.#registerHandleWithSubsystems(handle);
356
+ handle.update(() => {
357
+ return initialDoc;
318
358
  });
319
359
  handle.doneLoading();
320
360
  return handle;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automerge/automerge-repo",
3
- "version": "2.4.0-alpha.0",
3
+ "version": "2.4.0-alpha.2",
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": "d6d7dfd5c4af335ff3db876db053733efada83df"
62
+ "gitHead": "f963f3a1a36292ac0ea417c1c17d180fd8e78ac5"
63
63
  }
@@ -141,11 +141,7 @@ export const isValidDocumentId = (str: unknown): str is DocumentId => {
141
141
  if (typeof str !== "string") return false
142
142
  // try to decode from base58
143
143
  const binaryDocumentID = documentIdToBinary(str as DocumentId)
144
- if (binaryDocumentID === undefined) return false // invalid base58check encoding
145
-
146
- // confirm that the document ID is a valid UUID
147
- const documentId = Uuid.stringify(binaryDocumentID)
148
- return Uuid.validate(documentId)
144
+ return binaryDocumentID !== undefined
149
145
  }
150
146
 
151
147
  export const isValidUuid = (str: unknown): str is LegacyDocumentId =>
package/src/Repo.ts CHANGED
@@ -1,7 +1,8 @@
1
- import { next as Automerge } from "@automerge/automerge/slim"
1
+ import { next as Automerge, Heads } from "@automerge/automerge/slim"
2
2
  import debug from "debug"
3
3
  import { EventEmitter } from "eventemitter3"
4
4
  import {
5
+ binaryToDocumentId,
5
6
  encodeHeads,
6
7
  generateAutomergeUrl,
7
8
  interpretAsDocumentId,
@@ -36,6 +37,7 @@ import {
36
37
  import type {
37
38
  AnyDocumentId,
38
39
  AutomergeUrl,
40
+ BinaryDocumentId,
39
41
  DocumentId,
40
42
  PeerId,
41
43
  } from "./types.js"
@@ -101,6 +103,7 @@ export class Repo extends EventEmitter<RepoEvents> {
101
103
  DocumentId,
102
104
  (payload: DocHandleEncodedChangePayload<any>) => void
103
105
  > = {}
106
+ #idFactory: ((initialHeads: Heads) => Promise<Uint8Array>) | null
104
107
 
105
108
  constructor({
106
109
  storage,
@@ -112,11 +115,13 @@ export class Repo extends EventEmitter<RepoEvents> {
112
115
  enableRemoteHeadsGossiping = false,
113
116
  denylist = [],
114
117
  saveDebounceRate = 100,
118
+ idFactory,
115
119
  }: RepoConfig = {}) {
116
120
  super()
117
121
  this.#remoteHeadsGossipingEnabled = enableRemoteHeadsGossiping
118
122
  this.#log = debug(`automerge-repo:repo`)
119
123
 
124
+ this.#idFactory = idFactory || null
120
125
  // Handle legacy sharePolicy
121
126
  if (sharePolicy != null && shareConfig != null) {
122
127
  throw new Error("cannot provide both sharePolicy and shareConfig at once")
@@ -446,6 +451,13 @@ export class Repo extends EventEmitter<RepoEvents> {
446
451
  * system. we emit a `document` event to advertise interest in the document.
447
452
  */
448
453
  create<T>(initialValue?: T): DocHandle<T> {
454
+ let initialDoc: Automerge.Doc<T>
455
+ if (initialValue) {
456
+ initialDoc = Automerge.from(initialValue)
457
+ } else {
458
+ initialDoc = Automerge.emptyChange(Automerge.init())
459
+ }
460
+
449
461
  // Generate a new UUID and store it in the buffer
450
462
  const { documentId } = parseAutomergeUrl(generateAutomergeUrl())
451
463
  const handle = this.#getHandle<T>({
@@ -455,19 +467,54 @@ export class Repo extends EventEmitter<RepoEvents> {
455
467
  this.#registerHandleWithSubsystems(handle)
456
468
 
457
469
  handle.update(() => {
458
- let nextDoc: Automerge.Doc<T>
459
- if (initialValue) {
460
- nextDoc = Automerge.from(initialValue)
461
- } else {
462
- nextDoc = Automerge.emptyChange(Automerge.init())
463
- }
464
- return nextDoc
470
+ return initialDoc
465
471
  })
466
472
 
467
473
  handle.doneLoading()
468
474
  return handle
469
475
  }
470
476
 
477
+ /**
478
+ * Creates a new document and returns a handle to it. The initial value of the
479
+ * document is an empty object `{}` unless an initial value is provided. The
480
+ * main difference between this and Repo.create is that if an `idGenerator`
481
+ * was provided at repo construction, that idGenerator will be used to
482
+ * generate the document ID of the document returned by this method.
483
+ *
484
+ * This is a hidden, experimental API which is subject to change or removal without notice.
485
+ * @hidden
486
+ * @experimental
487
+ */
488
+ async create2<T>(initialValue?: T): Promise<DocHandle<T>> {
489
+ // Note that the reason this method is hidden and experimental is because it is async,
490
+ // and it is async because we want to be able to call the #idGenerator, which is async.
491
+ // This is all really in service of wiring up keyhive and we probably need to find a
492
+ // nicer way to achieve this.
493
+ let initialDoc: Automerge.Doc<T>
494
+ if (initialValue) {
495
+ initialDoc = Automerge.from(initialValue)
496
+ } else {
497
+ initialDoc = Automerge.emptyChange(Automerge.init())
498
+ }
499
+
500
+ let { documentId } = parseAutomergeUrl(generateAutomergeUrl())
501
+ if (this.#idFactory) {
502
+ const rawDocId = await this.#idFactory(Automerge.getHeads(initialDoc))
503
+ documentId = binaryToDocumentId(rawDocId as BinaryDocumentId)
504
+ }
505
+ const handle = this.#getHandle<T>({
506
+ documentId,
507
+ }) as DocHandle<T>
508
+
509
+ this.#registerHandleWithSubsystems(handle)
510
+
511
+ handle.update(() => {
512
+ return initialDoc
513
+ })
514
+
515
+ handle.doneLoading()
516
+ return handle
517
+ }
471
518
  /** Create a new DocHandle by cloning the history of an existing DocHandle.
472
519
  *
473
520
  * @param clonedHandle - The handle to clone
@@ -937,7 +984,6 @@ export interface RepoConfig {
937
984
  /**
938
985
  * Normal peers typically share generously with everyone (meaning we sync all our documents with
939
986
  * all peers). A server only syncs documents that a peer explicitly requests by ID.
940
- * @deprecated Use `shareConfig` instead
941
987
  */
942
988
  sharePolicy?: SharePolicy
943
989
 
@@ -945,6 +991,10 @@ export interface RepoConfig {
945
991
  * Whether to share documents with other peers. By default we announce new
946
992
  * documents to everyone and allow everyone access to documents, see the
947
993
  * documentation for {@link ShareConfig} to override this
994
+ *
995
+ * Note that this is currently an experimental API and will very likely change
996
+ * without a major release.
997
+ * @experimental
948
998
  */
949
999
  shareConfig?: ShareConfig
950
1000
 
@@ -964,6 +1014,13 @@ export interface RepoConfig {
964
1014
  * The debounce rate in milliseconds for saving documents. Defaults to 100ms.
965
1015
  */
966
1016
  saveDebounceRate?: number
1017
+
1018
+ // This is hidden for now because it's an experimental API, mostly here in order
1019
+ // for keyhive to be able to control the ID generation
1020
+ /**
1021
+ * @hidden
1022
+ */
1023
+ idFactory?: (initialHeads: Heads) => Promise<Uint8Array>
967
1024
  }
968
1025
 
969
1026
  /** A function that determines whether we should share a document with a peer
@@ -2,6 +2,7 @@ import assert from "assert"
2
2
  import bs58check from "bs58check"
3
3
  import { describe, it } from "vitest"
4
4
  import {
5
+ binaryToDocumentId,
5
6
  generateAutomergeUrl,
6
7
  getHeadsFromUrl,
7
8
  isValidAutomergeUrl,
@@ -14,6 +15,7 @@ import type {
14
15
  BinaryDocumentId,
15
16
  DocumentId,
16
17
  } from "../src/types.js"
18
+ import { interpretAsDocumentId } from "../src/AutomergeUrl.js"
17
19
 
18
20
  const goodUrl = "automerge:4NMNnkMhL8jXrdJ9jamS58PAVdXu" as AutomergeUrl
19
21
  const badChecksumUrl = "automerge:badbadbad" as AutomergeUrl
@@ -94,15 +96,18 @@ describe("AutomergeUrl", () => {
94
96
  assert(isValidAutomergeUrl(url) === false)
95
97
  })
96
98
 
97
- it("should return false for a documentId that is not a valid UUID ", () => {
98
- const url = stringifyAutomergeUrl({ documentId: badUuidDocumentId })
99
- assert(isValidAutomergeUrl(url) === false)
100
- })
101
-
102
99
  it("should return false for a documentId that is just some random type", () => {
103
100
  assert(isValidAutomergeUrl({ foo: "bar" } as unknown) === false)
104
101
  })
105
102
  })
103
+
104
+ it("should allow arbitrary uint8array ids", () => {
105
+ const raw = new Uint8Array("custom-id".split("").map(c => c.charCodeAt(0)))
106
+ const documentId = binaryToDocumentId(raw as BinaryDocumentId)
107
+ const url = stringifyAutomergeUrl({ documentId })
108
+ const interpreted = interpretAsDocumentId(url)
109
+ assert.deepStrictEqual(interpreted, documentId)
110
+ })
106
111
  })
107
112
 
108
113
  describe("AutomergeUrl with heads", () => {
package/test/Repo.test.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { next as A } from "@automerge/automerge"
1
+ import { next as A, Heads } from "@automerge/automerge"
2
2
  import { MessageChannelNetworkAdapter } from "../../automerge-repo-network-messagechannel/src/index.js"
3
3
  import assert from "assert"
4
4
  import * as Uuid from "uuid"
@@ -2027,6 +2027,50 @@ describe("Repo.find() abort behavior", () => {
2027
2027
  controller.abort()
2028
2028
  expect(handle.url).toBe(url)
2029
2029
  })
2030
+
2031
+ describe("creating a document with a custom ID factory", () => {
2032
+ it("creates a document with the custom ID", async () => {
2033
+ const id = new Uint8Array("custom-id".split("").map(c => c.charCodeAt(0)))
2034
+ const repo = new Repo({
2035
+ idFactory: () => id,
2036
+ })
2037
+ const handle = await repo.create2()
2038
+ expect(handle.documentId).toBe("9HUp4wuzRMx9MRvN4x")
2039
+ })
2040
+
2041
+ it("passes the heads of the document to the callback", async () => {
2042
+ const id = new Uint8Array("custom-id".split("").map(c => c.charCodeAt(0)))
2043
+ let calledHeads: Heads | null = null
2044
+ const repo = new Repo({
2045
+ idFactory: (heads: Heads) => {
2046
+ calledHeads = heads
2047
+ return id
2048
+ },
2049
+ })
2050
+ const handle = await repo.create2()
2051
+ const actualHeads = A.getHeads(handle.doc())
2052
+ assert.deepStrictEqual(actualHeads, calledHeads)
2053
+ })
2054
+
2055
+ it("allows syncing documents with a custom ID", async () => {
2056
+ const [aliceToBob, bobToAlice] = DummyNetworkAdapter.createConnectedPair()
2057
+ const alice = new Repo({
2058
+ peerId: "alice" as PeerId,
2059
+ idFactory: () =>
2060
+ new Uint8Array("custom-id".split("").map(c => c.charCodeAt(0))),
2061
+ network: [aliceToBob],
2062
+ })
2063
+ const bob = new Repo({ peerId: "bob" as PeerId, network: [bobToAlice] })
2064
+ aliceToBob.peerCandidate("bob" as PeerId)
2065
+ bobToAlice.peerCandidate("alice" as PeerId)
2066
+
2067
+ await pause(50)
2068
+
2069
+ const handle = await alice.create2({ foo: "bar" })
2070
+ const bobHandle = await bob.find(handle.url)
2071
+ assert.deepStrictEqual(bobHandle.doc(), { foo: "bar" })
2072
+ })
2073
+ })
2030
2074
  })
2031
2075
 
2032
2076
  const warn = console.warn