@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.
- package/README.md +3 -22
- package/dist/DocHandle.d.ts +124 -100
- package/dist/DocHandle.d.ts.map +1 -1
- package/dist/DocHandle.js +239 -231
- package/dist/Repo.d.ts +10 -3
- package/dist/Repo.d.ts.map +1 -1
- package/dist/Repo.js +22 -1
- package/dist/helpers/arraysAreEqual.d.ts.map +1 -1
- package/dist/helpers/debounce.d.ts.map +1 -1
- package/dist/helpers/tests/network-adapter-tests.d.ts +1 -1
- package/dist/helpers/tests/network-adapter-tests.d.ts.map +1 -1
- package/dist/helpers/tests/network-adapter-tests.js +2 -2
- package/dist/helpers/tests/storage-adapter-tests.d.ts +7 -0
- package/dist/helpers/tests/storage-adapter-tests.d.ts.map +1 -0
- package/dist/helpers/tests/storage-adapter-tests.js +128 -0
- package/dist/helpers/throttle.d.ts.map +1 -1
- package/dist/helpers/withTimeout.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/synchronizer/DocSynchronizer.js +1 -1
- package/package.json +4 -4
- package/src/DocHandle.ts +325 -375
- package/src/Repo.ts +35 -8
- package/src/helpers/tests/network-adapter-tests.ts +4 -2
- package/src/helpers/tests/storage-adapter-tests.ts +193 -0
- package/src/index.ts +43 -0
- package/src/synchronizer/DocSynchronizer.ts +1 -1
- package/test/CollectionSynchronizer.test.ts +1 -3
- package/test/DocHandle.test.ts +19 -1
- package/test/DocSynchronizer.test.ts +1 -4
- package/test/DummyStorageAdapter.test.ts +11 -0
- package/test/Repo.test.ts +179 -53
- package/test/helpers/DummyNetworkAdapter.ts +20 -18
- package/test/helpers/DummyStorageAdapter.ts +5 -1
- package/test/remoteHeads.test.ts +1 -1
- 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, }
|
|
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
|
-
/**
|
|
95
|
-
network
|
|
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.
|
package/dist/Repo.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../src/Repo.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAM5C,OAAO,EAAE,SAAS,EAAiC,MAAM,gBAAgB,CAAA;AAIzE,OAAO,
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
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(`
|
|
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,
|
|
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,
|
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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(
|
|
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.
|
|
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.
|
|
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": "^
|
|
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": "
|
|
58
|
+
"gitHead": "fa2e5c0309458f244a81e49501dc882c5074f8ad"
|
|
59
59
|
}
|