@automerge/automerge-repo 1.1.4 → 1.1.8

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 (37) hide show
  1. package/README.md +3 -22
  2. package/dist/DocHandle.d.ts +124 -100
  3. package/dist/DocHandle.d.ts.map +1 -1
  4. package/dist/DocHandle.js +239 -231
  5. package/dist/Repo.d.ts +10 -3
  6. package/dist/Repo.d.ts.map +1 -1
  7. package/dist/Repo.js +22 -1
  8. package/dist/helpers/arraysAreEqual.d.ts.map +1 -1
  9. package/dist/helpers/debounce.d.ts.map +1 -1
  10. package/dist/helpers/tests/network-adapter-tests.d.ts +1 -1
  11. package/dist/helpers/tests/network-adapter-tests.d.ts.map +1 -1
  12. package/dist/helpers/tests/network-adapter-tests.js +2 -2
  13. package/dist/helpers/tests/storage-adapter-tests.d.ts +7 -0
  14. package/dist/helpers/tests/storage-adapter-tests.d.ts.map +1 -0
  15. package/dist/helpers/tests/storage-adapter-tests.js +128 -0
  16. package/dist/helpers/throttle.d.ts.map +1 -1
  17. package/dist/helpers/withTimeout.d.ts.map +1 -1
  18. package/dist/index.d.ts +4 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +7 -0
  21. package/dist/synchronizer/DocSynchronizer.js +1 -1
  22. package/package.json +4 -4
  23. package/src/DocHandle.ts +325 -375
  24. package/src/Repo.ts +35 -8
  25. package/src/helpers/tests/network-adapter-tests.ts +4 -2
  26. package/src/helpers/tests/storage-adapter-tests.ts +193 -0
  27. package/src/index.ts +43 -0
  28. package/src/synchronizer/DocSynchronizer.ts +1 -1
  29. package/test/CollectionSynchronizer.test.ts +1 -3
  30. package/test/DocHandle.test.ts +19 -1
  31. package/test/DocSynchronizer.test.ts +1 -4
  32. package/test/DummyStorageAdapter.test.ts +11 -0
  33. package/test/Repo.test.ts +179 -53
  34. package/test/helpers/DummyNetworkAdapter.ts +20 -18
  35. package/test/helpers/DummyStorageAdapter.ts +5 -1
  36. package/test/remoteHeads.test.ts +1 -1
  37. package/tsconfig.json +1 -0
package/dist/Repo.d.ts CHANGED
@@ -29,7 +29,7 @@ export declare class Repo extends EventEmitter<RepoEvents> {
29
29
  /** maps peer id to to persistence information (storageId, isEphemeral), access by collection synchronizer */
30
30
  /** @hidden */
31
31
  peerMetadataByPeerId: Record<PeerId, PeerMetadata>;
32
- constructor({ storage, network, peerId, sharePolicy, isEphemeral, enableRemoteHeadsGossiping, }: RepoConfig);
32
+ constructor({ storage, network, peerId, sharePolicy, isEphemeral, enableRemoteHeadsGossiping, }?: RepoConfig);
33
33
  /** Returns all the handles we have cached. */
34
34
  get handles(): Record<DocumentId, DocHandle<any>>;
35
35
  /** Returns a list of all connected peer ids */
@@ -82,6 +82,13 @@ export declare class Repo extends EventEmitter<RepoEvents> {
82
82
  import<T>(binary: Uint8Array): DocHandle<T>;
83
83
  subscribeToRemotes: (remotes: StorageId[]) => void;
84
84
  storageId: () => Promise<StorageId | undefined>;
85
+ /**
86
+ * Writes Documents to a disk.
87
+ * @hidden this API is experimental and may change.
88
+ * @param documents - if provided, only writes the specified documents.
89
+ * @returns Promise<void>
90
+ */
91
+ flush(documents?: DocumentId[]): Promise<void>;
85
92
  }
86
93
  export interface RepoConfig {
87
94
  /** Our unique identifier */
@@ -91,8 +98,8 @@ export interface RepoConfig {
91
98
  isEphemeral?: boolean;
92
99
  /** A storage adapter can be provided, or not */
93
100
  storage?: StorageAdapterInterface;
94
- /** One or more network adapters must be provided */
95
- network: NetworkAdapterInterface[];
101
+ /** A list of network adapters (more can be added at runtime). */
102
+ network?: NetworkAdapterInterface[];
96
103
  /**
97
104
  * Normal peers typically share generously with everyone (meaning we sync all our documents with
98
105
  * all peers). A server only syncs documents that a peer explicitly requests by ID.
@@ -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
@@ -36,7 +36,7 @@ export class Repo extends EventEmitter {
36
36
  peerMetadataByPeerId = {};
37
37
  #remoteHeadsSubscriptions = new RemoteHeadsSubscriptions();
38
38
  #remoteHeadsGossipingEnabled = false;
39
- constructor({ storage, network, peerId, sharePolicy, isEphemeral = storage === undefined, enableRemoteHeadsGossiping = false, }) {
39
+ constructor({ storage, network = [], peerId, sharePolicy, isEphemeral = storage === undefined, enableRemoteHeadsGossiping = false, } = {}) {
40
40
  super();
41
41
  this.#remoteHeadsGossipingEnabled = enableRemoteHeadsGossiping;
42
42
  this.#log = debug(`automerge-repo:repo`);
@@ -383,4 +383,25 @@ export class Repo extends EventEmitter {
383
383
  return this.storageSubsystem.id();
384
384
  }
385
385
  };
386
+ /**
387
+ * Writes Documents to a disk.
388
+ * @hidden this API is experimental and may change.
389
+ * @param documents - if provided, only writes the specified documents.
390
+ * @returns Promise<void>
391
+ */
392
+ async flush(documents) {
393
+ if (!this.storageSubsystem) {
394
+ return;
395
+ }
396
+ const handles = documents
397
+ ? documents.map(id => this.#handleCache[id])
398
+ : Object.values(this.#handleCache);
399
+ await Promise.all(handles.map(async (handle) => {
400
+ const doc = handle.docSync();
401
+ if (!doc) {
402
+ return;
403
+ }
404
+ return this.storageSubsystem.saveDoc(handle.documentId, doc);
405
+ }));
406
+ }
386
407
  }
@@ -1 +1 @@
1
- {"version":3,"file":"arraysAreEqual.d.ts","sourceRoot":"","sources":["../../src/helpers/arraysAreEqual.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,gCACiD,CAAA"}
1
+ {"version":3,"file":"arraysAreEqual.d.ts","sourceRoot":"","sources":["../../src/helpers/arraysAreEqual.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,SAAU,CAAC,EAAE,KAAK,CAAC,EAAE,YAC4B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"debounce.d.ts","sourceRoot":"","sources":["../../src/helpers/debounce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,QAAQ,qEAEb,MAAM,qCASb,CAAA"}
1
+ {"version":3,"file":"debounce.d.ts","sourceRoot":"","sources":["../../src/helpers/debounce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,QAAQ,4DACf,CAAC,QACC,MAAM,eAGc,WAAW,CAAC,CAAC,SAMxC,CAAA"}
@@ -11,7 +11,7 @@ import type { NetworkAdapterInterface } from "../../network/NetworkAdapterInterf
11
11
  * - `teardown`: An optional function that will be called after the tests have run. This can be used
12
12
  * to clean up any resources that were created during the test.
13
13
  */
14
- export declare function runAdapterTests(_setup: SetupFn, title?: string): void;
14
+ export declare function runNetworkAdapterTests(_setup: SetupFn, title?: string): void;
15
15
  type Network = NetworkAdapterInterface | NetworkAdapterInterface[];
16
16
  export type SetupFn = () => Promise<{
17
17
  adapters: [Network, Network, Network];
@@ -1 +1 @@
1
- {"version":3,"file":"network-adapter-tests.d.ts","sourceRoot":"","sources":["../../../src/helpers/tests/network-adapter-tests.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAA;AAIvF;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAuJrE;AAID,KAAK,OAAO,GAAG,uBAAuB,GAAG,uBAAuB,EAAE,CAAA;AAElE,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC;IAClC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACrC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB,CAAC,CAAA"}
1
+ {"version":3,"file":"network-adapter-tests.d.ts","sourceRoot":"","sources":["../../../src/helpers/tests/network-adapter-tests.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAA;AAIvF;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAyJ5E;AAID,KAAK,OAAO,GAAG,uBAAuB,GAAG,uBAAuB,EAAE,CAAA;AAElE,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC;IAClC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACrC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB,CAAC,CAAA"}
@@ -15,7 +15,7 @@ import { pause } from "../pause.js";
15
15
  * - `teardown`: An optional function that will be called after the tests have run. This can be used
16
16
  * to clean up any resources that were created during the test.
17
17
  */
18
- export function runAdapterTests(_setup, title) {
18
+ export function runNetworkAdapterTests(_setup, title) {
19
19
  // Wrap the provided setup function
20
20
  const setup = async () => {
21
21
  const { adapters, teardown = NO_OP } = await _setup();
@@ -23,7 +23,7 @@ export function runAdapterTests(_setup, title) {
23
23
  const [a, b, c] = adapters.map(toArray);
24
24
  return { adapters: [a, b, c], teardown };
25
25
  };
26
- describe(`Adapter acceptance tests ${title ? `(${title})` : ""}`, () => {
26
+ describe(`Network adapter acceptance tests ${title ? `(${title})` : ""}`, () => {
27
27
  it("can sync 2 repos", async () => {
28
28
  const doTest = async (a, b) => {
29
29
  const aliceRepo = new Repo({ network: a, peerId: alice });
@@ -0,0 +1,7 @@
1
+ import type { StorageAdapterInterface } from "../../storage/StorageAdapterInterface.js";
2
+ export declare function runStorageAdapterTests(_setup: SetupFn, title?: string): void;
3
+ export type SetupFn = () => Promise<{
4
+ adapter: StorageAdapterInterface;
5
+ teardown?: () => void;
6
+ }>;
7
+ //# sourceMappingURL=storage-adapter-tests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-adapter-tests.d.ts","sourceRoot":"","sources":["../../../src/helpers/tests/storage-adapter-tests.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAA;AAQvF,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CA+K5E;AAID,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC;IAClC,OAAO,EAAE,uBAAuB,CAAA;IAChC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB,CAAC,CAAA"}
@@ -0,0 +1,128 @@
1
+ import { describe, expect, it } from "vitest";
2
+ const PAYLOAD_A = () => new Uint8Array([0, 1, 127, 99, 154, 235]);
3
+ const PAYLOAD_B = () => new Uint8Array([1, 76, 160, 53, 57, 10, 230]);
4
+ const PAYLOAD_C = () => new Uint8Array([2, 111, 74, 131, 236, 96, 142, 193]);
5
+ const LARGE_PAYLOAD = new Uint8Array(100000).map(() => Math.random() * 256);
6
+ export function runStorageAdapterTests(_setup, title) {
7
+ const setup = async () => {
8
+ const { adapter, teardown = NO_OP } = await _setup();
9
+ return { adapter, teardown };
10
+ };
11
+ describe(`Storage adapter acceptance tests ${title ? `(${title})` : ""}`, () => {
12
+ describe("load", () => {
13
+ it("should return undefined if there is no data", async () => {
14
+ const { adapter, teardown } = await setup();
15
+ const actual = await adapter.load(["AAAAA", "sync-state", "xxxxx"]);
16
+ expect(actual).toBeUndefined();
17
+ teardown();
18
+ });
19
+ });
20
+ describe("save and load", () => {
21
+ it("should return data that was saved", async () => {
22
+ const { adapter, teardown } = await setup();
23
+ await adapter.save(["storage-adapter-id"], PAYLOAD_A());
24
+ const actual = await adapter.load(["storage-adapter-id"]);
25
+ expect(actual).toStrictEqual(PAYLOAD_A());
26
+ teardown();
27
+ });
28
+ it("should work with composite keys", async () => {
29
+ const { adapter, teardown } = await setup();
30
+ await adapter.save(["AAAAA", "sync-state", "xxxxx"], PAYLOAD_A());
31
+ const actual = await adapter.load(["AAAAA", "sync-state", "xxxxx"]);
32
+ expect(actual).toStrictEqual(PAYLOAD_A());
33
+ teardown();
34
+ });
35
+ it("should work with a large payload", async () => {
36
+ const { adapter, teardown } = await setup();
37
+ await adapter.save(["AAAAA", "sync-state", "xxxxx"], LARGE_PAYLOAD);
38
+ const actual = await adapter.load(["AAAAA", "sync-state", "xxxxx"]);
39
+ expect(actual).toStrictEqual(LARGE_PAYLOAD);
40
+ teardown();
41
+ });
42
+ });
43
+ describe("loadRange", () => {
44
+ it("should return an empty array if there is no data", async () => {
45
+ const { adapter, teardown } = await setup();
46
+ expect(await adapter.loadRange(["AAAAA"])).toStrictEqual([]);
47
+ teardown();
48
+ });
49
+ });
50
+ describe("save and loadRange", () => {
51
+ it("should return all the data that matches the key", async () => {
52
+ const { adapter, teardown } = await setup();
53
+ await adapter.save(["AAAAA", "sync-state", "xxxxx"], PAYLOAD_A());
54
+ await adapter.save(["AAAAA", "snapshot", "yyyyy"], PAYLOAD_B());
55
+ await adapter.save(["AAAAA", "sync-state", "zzzzz"], PAYLOAD_C());
56
+ expect(await adapter.loadRange(["AAAAA"])).toStrictEqual(expect.arrayContaining([
57
+ { key: ["AAAAA", "sync-state", "xxxxx"], data: PAYLOAD_A() },
58
+ { key: ["AAAAA", "snapshot", "yyyyy"], data: PAYLOAD_B() },
59
+ { key: ["AAAAA", "sync-state", "zzzzz"], data: PAYLOAD_C() },
60
+ ]));
61
+ expect(await adapter.loadRange(["AAAAA", "sync-state"])).toStrictEqual(expect.arrayContaining([
62
+ { key: ["AAAAA", "sync-state", "xxxxx"], data: PAYLOAD_A() },
63
+ { key: ["AAAAA", "sync-state", "zzzzz"], data: PAYLOAD_C() },
64
+ ]));
65
+ teardown();
66
+ });
67
+ it("should only load values that match they key", async () => {
68
+ const { adapter, teardown } = await setup();
69
+ await adapter.save(["AAAAA", "sync-state", "xxxxx"], PAYLOAD_A());
70
+ await adapter.save(["BBBBB", "sync-state", "zzzzz"], PAYLOAD_C());
71
+ const actual = await adapter.loadRange(["AAAAA"]);
72
+ expect(actual).toStrictEqual(expect.arrayContaining([
73
+ { key: ["AAAAA", "sync-state", "xxxxx"], data: PAYLOAD_A() },
74
+ ]));
75
+ expect(actual).toStrictEqual(expect.not.arrayContaining([
76
+ { key: ["BBBBB", "sync-state", "zzzzz"], data: PAYLOAD_C() },
77
+ ]));
78
+ teardown();
79
+ });
80
+ });
81
+ describe("save and remove", () => {
82
+ it("after removing, should be empty", async () => {
83
+ const { adapter, teardown } = await setup();
84
+ await adapter.save(["AAAAA", "snapshot", "xxxxx"], PAYLOAD_A());
85
+ await adapter.remove(["AAAAA", "snapshot", "xxxxx"]);
86
+ expect(await adapter.loadRange(["AAAAA"])).toStrictEqual([]);
87
+ expect(await adapter.load(["AAAAA", "snapshot", "xxxxx"])).toBeUndefined();
88
+ teardown();
89
+ });
90
+ });
91
+ describe("save and save", () => {
92
+ it("should overwrite data saved with the same key", async () => {
93
+ const { adapter, teardown } = await setup();
94
+ await adapter.save(["AAAAA", "sync-state", "xxxxx"], PAYLOAD_A());
95
+ await adapter.save(["AAAAA", "sync-state", "xxxxx"], PAYLOAD_B());
96
+ expect(await adapter.loadRange(["AAAAA", "sync-state"])).toStrictEqual([
97
+ { key: ["AAAAA", "sync-state", "xxxxx"], data: PAYLOAD_B() },
98
+ ]);
99
+ teardown();
100
+ });
101
+ });
102
+ describe("removeRange", () => {
103
+ it("should remove a range of records", async () => {
104
+ const { adapter, teardown } = await setup();
105
+ await adapter.save(["AAAAA", "sync-state", "xxxxx"], PAYLOAD_A());
106
+ await adapter.save(["AAAAA", "snapshot", "yyyyy"], PAYLOAD_B());
107
+ await adapter.save(["AAAAA", "sync-state", "zzzzz"], PAYLOAD_C());
108
+ await adapter.removeRange(["AAAAA", "sync-state"]);
109
+ expect(await adapter.loadRange(["AAAAA"])).toStrictEqual([
110
+ { key: ["AAAAA", "snapshot", "yyyyy"], data: PAYLOAD_B() },
111
+ ]);
112
+ teardown();
113
+ });
114
+ it("should not remove records that don't match", async () => {
115
+ const { adapter, teardown } = await setup();
116
+ await adapter.save(["AAAAA", "sync-state", "xxxxx"], PAYLOAD_A());
117
+ await adapter.save(["BBBBB", "sync-state", "zzzzz"], PAYLOAD_B());
118
+ await adapter.removeRange(["AAAAA"]);
119
+ const actual = await adapter.loadRange(["BBBBB"]);
120
+ expect(actual).toStrictEqual([
121
+ { key: ["BBBBB", "sync-state", "zzzzz"], data: PAYLOAD_B() },
122
+ ]);
123
+ teardown();
124
+ });
125
+ });
126
+ });
127
+ }
128
+ const NO_OP = () => { };
@@ -1 +1 @@
1
- {"version":3,"file":"throttle.d.ts","sourceRoot":"","sources":["../../src/helpers/throttle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,eAAO,MAAM,QAAQ,sEAEZ,MAAM,qCAad,CAAA"}
1
+ {"version":3,"file":"throttle.d.ts","sourceRoot":"","sources":["../../src/helpers/throttle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,eAAO,MAAM,QAAQ,4DACf,CAAC,SACE,MAAM,eAKa,WAAW,CAAC,CAAC,SAQxC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"withTimeout.d.ts","sourceRoot":"","sources":["../../src/helpers/withTimeout.ts"],"names":[],"mappings":"AACA;;;GAGG;AACH,eAAO,MAAM,WAAW,8BAEnB,MAAM,eAcV,CAAA;AAED,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B"}
1
+ {"version":3,"file":"withTimeout.d.ts","sourceRoot":"","sources":["../../src/helpers/withTimeout.ts"],"names":[],"mappings":"AACA;;;GAGG;AACH,eAAO,MAAM,WAAW,eACb,QAAQ,CAAC,CAAC,KAChB,MAAM,KACR,QAAQ,CAAC,CAaX,CAAA;AAED,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B"}
package/dist/index.d.ts CHANGED
@@ -41,4 +41,8 @@ export type { NetworkAdapterEvents, OpenPayload, PeerCandidatePayload, PeerDisco
41
41
  export type { DocumentUnavailableMessage, EphemeralMessage, Message, RepoMessage, RequestMessage, SyncMessage, } from "./network/messages.js";
42
42
  export type { Chunk, ChunkInfo, ChunkType, StorageKey, StorageId, } from "./storage/types.js";
43
43
  export * from "./types.js";
44
+ export type { Counter, RawString, Cursor } from "@automerge/automerge/next";
45
+ export type { Doc, Heads, Patch, PatchCallback, Prop, ActorId, Change, ChangeFn, Mark, MarkSet, MarkRange, MarkValue, } from "@automerge/automerge/next";
46
+ export { getChanges, getAllChanges, applyChanges, view, getConflicts, } from "@automerge/automerge/next";
47
+ export { getCursor, getCursorPosition, splice, updateText, insertAt, deleteAt, mark, unmark, } from "@automerge/automerge/next";
44
48
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAA;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAA;AAEnF,eAAe;AACf,OAAO,KAAK,IAAI,MAAM,mBAAmB,CAAA;AAIzC,YAAY,EACV,sBAAsB,EACtB,sBAAsB,EACtB,6BAA6B,EAC7B,gCAAgC,EAChC,2BAA2B,EAC3B,eAAe,EACf,gBAAgB,EAChB,wCAAwC,EACxC,WAAW,GACZ,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EACV,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,UAAU,EACV,WAAW,GACZ,MAAM,WAAW,CAAA;AAElB,YAAY,EACV,oBAAoB,EACpB,WAAW,EACX,oBAAoB,EACpB,uBAAuB,EACvB,YAAY,GACb,MAAM,sCAAsC,CAAA;AAE7C,YAAY,EACV,0BAA0B,EAC1B,gBAAgB,EAChB,OAAO,EACP,WAAW,EACX,cAAc,EACd,WAAW,GACZ,MAAM,uBAAuB,CAAA;AAE9B,YAAY,EACV,KAAK,EACL,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,GACV,MAAM,oBAAoB,CAAA;AAE3B,cAAc,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAA;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAA;AAEnF,eAAe;AACf,OAAO,KAAK,IAAI,MAAM,mBAAmB,CAAA;AAIzC,YAAY,EACV,sBAAsB,EACtB,sBAAsB,EACtB,6BAA6B,EAC7B,gCAAgC,EAChC,2BAA2B,EAC3B,eAAe,EACf,gBAAgB,EAChB,wCAAwC,EACxC,WAAW,GACZ,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EACV,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,UAAU,EACV,WAAW,GACZ,MAAM,WAAW,CAAA;AAElB,YAAY,EACV,oBAAoB,EACpB,WAAW,EACX,oBAAoB,EACpB,uBAAuB,EACvB,YAAY,GACb,MAAM,sCAAsC,CAAA;AAE7C,YAAY,EACV,0BAA0B,EAC1B,gBAAgB,EAChB,OAAO,EACP,WAAW,EACX,cAAc,EACd,WAAW,GACZ,MAAM,uBAAuB,CAAA;AAE9B,YAAY,EACV,KAAK,EACL,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,GACV,MAAM,oBAAoB,CAAA;AAE3B,cAAc,YAAY,CAAA;AAG1B,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAG3E,YAAY,EACV,GAAG,EACH,KAAK,EACL,KAAK,EACL,aAAa,EACb,IAAI,EACJ,OAAO,EACP,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,SAAS,EACT,SAAS,GACV,MAAM,2BAA2B,CAAA;AAIlC,OAAO,EACL,UAAU,EACV,aAAa,EACb,YAAY,EACZ,IAAI,EACJ,YAAY,GACb,MAAM,2BAA2B,CAAA;AAKlC,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,MAAM,EACN,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,MAAM,GACP,MAAM,2BAA2B,CAAA"}
package/dist/index.js CHANGED
@@ -34,3 +34,10 @@ export { StorageAdapter } from "./storage/StorageAdapter.js";
34
34
  /** @hidden **/
35
35
  export * as cbor from "./helpers/cbor.js";
36
36
  export * from "./types.js";
37
+ // export a few utility functions that aren't in automerge-repo
38
+ // NB that these should probably all just be available via the dochandle
39
+ export { getChanges, getAllChanges, applyChanges, view, getConflicts, } from "@automerge/automerge/next";
40
+ // export type-specific utility functions
41
+ // these mostly can't be on the data-type in question because
42
+ // JS strings can't have methods added to them
43
+ export { getCursor, getCursorPosition, splice, updateText, insertAt, deleteAt, mark, unmark, } from "@automerge/automerge/next";
@@ -152,7 +152,7 @@ export class DocSynchronizer extends Synchronizer {
152
152
  return this.#peers.includes(peerId);
153
153
  }
154
154
  beginSync(peerIds) {
155
- const noPeersWithDocument = peerIds.every((peerId) => this.#peerDocumentStatuses[peerId] in ["unavailable", "wants"]);
155
+ const noPeersWithDocument = peerIds.every(peerId => this.#peerDocumentStatuses[peerId] in ["unavailable", "wants"]);
156
156
  // At this point if we don't have anything in our storage, we need to use an empty doc to sync
157
157
  // with; but we don't want to surface that state to the front end
158
158
  const docPromise = this.#handle
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automerge/automerge-repo",
3
- "version": "1.1.4",
3
+ "version": "1.1.8",
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>",
@@ -23,7 +23,7 @@
23
23
  "vite": "^5.0.8"
24
24
  },
25
25
  "dependencies": {
26
- "@automerge/automerge": "^2.1.9",
26
+ "@automerge/automerge": "^2.1.13",
27
27
  "bs58check": "^3.0.1",
28
28
  "cbor-x": "^1.3.0",
29
29
  "debug": "^4.3.4",
@@ -32,7 +32,7 @@
32
32
  "tiny-typed-emitter": "^2.1.0",
33
33
  "ts-node": "^10.9.1",
34
34
  "uuid": "^9.0.0",
35
- "xstate": "^4.37.0"
35
+ "xstate": "^5.9.1"
36
36
  },
37
37
  "watch": {
38
38
  "build": {
@@ -55,5 +55,5 @@
55
55
  "publishConfig": {
56
56
  "access": "public"
57
57
  },
58
- "gitHead": "e819a7ed6302ce34f372b119ea3e8bab052e3af6"
58
+ "gitHead": "fa2e5c0309458f244a81e49501dc882c5074f8ad"
59
59
  }