@automerge/automerge-repo 1.0.0-alpha.3 → 1.0.0-alpha.5
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/dist/DocCollection.d.ts +2 -1
- package/dist/DocCollection.d.ts.map +1 -1
- package/dist/DocCollection.js +3 -3
- package/dist/DocHandle.d.ts +8 -3
- package/dist/DocHandle.d.ts.map +1 -1
- package/dist/DocHandle.js +28 -6
- package/dist/DocUrl.d.ts +1 -1
- package/dist/DocUrl.d.ts.map +1 -1
- package/dist/Repo.d.ts.map +1 -1
- package/dist/Repo.js +25 -7
- package/dist/helpers/cbor.d.ts +4 -0
- package/dist/helpers/cbor.d.ts.map +1 -0
- package/dist/helpers/cbor.js +8 -0
- package/dist/helpers/eventPromise.d.ts +1 -1
- package/dist/helpers/eventPromise.d.ts.map +1 -1
- package/dist/helpers/headsAreSame.d.ts +0 -1
- package/dist/helpers/headsAreSame.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/network/NetworkAdapter.d.ts +4 -5
- package/dist/network/NetworkAdapter.d.ts.map +1 -1
- package/dist/network/NetworkAdapter.js +1 -1
- package/dist/network/NetworkSubsystem.d.ts +4 -4
- package/dist/network/NetworkSubsystem.d.ts.map +1 -1
- package/dist/network/NetworkSubsystem.js +28 -14
- package/dist/network/messages.d.ts +2 -2
- package/dist/network/messages.d.ts.map +1 -1
- package/dist/storage/StorageSubsystem.d.ts +1 -1
- package/dist/storage/StorageSubsystem.d.ts.map +1 -1
- package/dist/storage/StorageSubsystem.js +10 -4
- package/dist/synchronizer/DocSynchronizer.d.ts.map +1 -1
- package/dist/synchronizer/DocSynchronizer.js +11 -12
- package/dist/synchronizer/Synchronizer.d.ts +1 -1
- package/dist/synchronizer/Synchronizer.d.ts.map +1 -1
- package/dist/synchronizer/Synchronizer.js +1 -1
- package/fuzz/fuzz.ts +1 -1
- package/package.json +3 -3
- package/src/DocCollection.ts +4 -3
- package/src/DocHandle.ts +34 -4
- package/src/DocUrl.ts +1 -1
- package/src/Repo.ts +23 -7
- package/src/helpers/cbor.ts +10 -0
- package/src/helpers/eventPromise.ts +1 -1
- package/src/helpers/headsAreSame.ts +1 -1
- package/src/index.ts +2 -0
- package/src/network/NetworkAdapter.ts +4 -6
- package/src/network/NetworkSubsystem.ts +37 -19
- package/src/network/messages.ts +2 -2
- package/src/storage/StorageSubsystem.ts +11 -4
- package/src/synchronizer/DocSynchronizer.ts +14 -14
- package/src/synchronizer/Synchronizer.ts +1 -1
- package/test/CollectionSynchronizer.test.ts +1 -1
- package/test/DocCollection.test.ts +2 -2
- package/test/DocHandle.test.ts +5 -5
- package/test/Repo.test.ts +75 -13
- package/test/StorageSubsystem.test.ts +2 -3
- package/test/helpers/DummyNetworkAdapter.ts +13 -5
- package/test/helpers/DummyStorageAdapter.ts +1 -1
- package/test/helpers/generate-large-object.ts +13 -0
- package/tsconfig.json +2 -2
package/dist/DocCollection.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import EventEmitter from "eventemitter3";
|
|
1
|
+
import { EventEmitter } from "eventemitter3";
|
|
2
2
|
import { DocHandle } from "./DocHandle.js";
|
|
3
3
|
import { DocumentId, AutomergeUrl } from "./types.js";
|
|
4
4
|
import { type SharePolicy } from "./Repo.js";
|
|
@@ -37,6 +37,7 @@ interface DocCollectionEvents {
|
|
|
37
37
|
}
|
|
38
38
|
interface DocumentPayload {
|
|
39
39
|
handle: DocHandle<any>;
|
|
40
|
+
isNew: boolean;
|
|
40
41
|
}
|
|
41
42
|
interface DeleteDocumentPayload {
|
|
42
43
|
documentId: DocumentId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocCollection.d.ts","sourceRoot":"","sources":["../src/DocCollection.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"DocCollection.d.ts","sourceRoot":"","sources":["../src/DocCollection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAyB,YAAY,EAAE,MAAM,YAAY,CAAA;AAC5E,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAS5C;;;KAGK;AACL,qBAAa,aAAc,SAAQ,YAAY,CAAC,mBAAmB,CAAC;;IAGlE,sDAAsD;IACtD,WAAW,EAAE,WAAW,CAAmB;;IAwB3C,8CAA8C;IAC9C,IAAI,OAAO,uCAEV;IAED;;;;OAIG;IACH,MAAM,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC;IA0BzB;;;OAGG;IACH,IAAI,CAAC,CAAC;IACJ,+CAA+C;IAC/C,YAAY,EAAE,YAAY,GACzB,SAAS,CAAC,CAAC,CAAC;IAwBf,MAAM;IACJ,6CAA6C;IAC7C,EAAE,EAAE,UAAU,GAAG,YAAY;CAchC;AAGD,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,CAAA;IACxC,iBAAiB,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,IAAI,CAAA;IACvD,sBAAsB,EAAE,CAAC,GAAG,EAAE,qBAAqB,KAAK,IAAI,CAAA;CAC7D;AAED,UAAU,eAAe;IACvB,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;IACtB,KAAK,EAAE,OAAO,CAAA;CACf;AAED,UAAU,qBAAqB;IAC7B,UAAU,EAAE,UAAU,CAAA;CACvB"}
|
package/dist/DocCollection.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import EventEmitter from "eventemitter3";
|
|
1
|
+
import { EventEmitter } from "eventemitter3";
|
|
2
2
|
import { DocHandle } from "./DocHandle.js";
|
|
3
3
|
import { generateAutomergeUrl, isValidAutomergeUrl, parseAutomergeUrl, } from "./DocUrl.js";
|
|
4
4
|
/**
|
|
@@ -55,7 +55,7 @@ export class DocCollection extends EventEmitter {
|
|
|
55
55
|
// Generate a new UUID and store it in the buffer
|
|
56
56
|
const { documentId } = parseAutomergeUrl(generateAutomergeUrl());
|
|
57
57
|
const handle = this.#getHandle(documentId, true);
|
|
58
|
-
this.emit("document", { handle });
|
|
58
|
+
this.emit("document", { handle, isNew: true });
|
|
59
59
|
return handle;
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
@@ -82,7 +82,7 @@ export class DocCollection extends EventEmitter {
|
|
|
82
82
|
return this.#handleCache[documentId];
|
|
83
83
|
}
|
|
84
84
|
const handle = this.#getHandle(documentId, false);
|
|
85
|
-
this.emit("document", { handle });
|
|
85
|
+
this.emit("document", { handle, isNew: false });
|
|
86
86
|
return handle;
|
|
87
87
|
}
|
|
88
88
|
delete(
|
package/dist/DocHandle.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as A from "@automerge/automerge";
|
|
2
|
-
import EventEmitter from "eventemitter3";
|
|
1
|
+
import * as A from "@automerge/automerge/next";
|
|
2
|
+
import { EventEmitter } from "eventemitter3";
|
|
3
3
|
import { StateValue } from "xstate";
|
|
4
4
|
import type { DocumentId, PeerId, AutomergeUrl } from "./types.js";
|
|
5
5
|
/** DocHandle is a wrapper around a single Automerge document that lets us listen for changes. */
|
|
@@ -59,6 +59,8 @@ export declare class DocHandle<T>//
|
|
|
59
59
|
unavailable(): void;
|
|
60
60
|
/** `request` is called by the repo when the document is not found in storage */
|
|
61
61
|
request(): void;
|
|
62
|
+
awaitNetwork(): void;
|
|
63
|
+
networkReady(): void;
|
|
62
64
|
/** `delete` is called by the repo when the document is deleted */
|
|
63
65
|
delete(): void;
|
|
64
66
|
/** `broadcast` sends an arbitrary ephemeral message out to all reachable peers who would receive sync messages from you
|
|
@@ -111,6 +113,7 @@ export interface DocHandleEvents<T> {
|
|
|
111
113
|
export declare const HandleState: {
|
|
112
114
|
readonly IDLE: "idle";
|
|
113
115
|
readonly LOADING: "loading";
|
|
116
|
+
readonly AWAITING_NETWORK: "awaitingNetwork";
|
|
114
117
|
readonly REQUESTING: "requesting";
|
|
115
118
|
readonly READY: "ready";
|
|
116
119
|
readonly FAILED: "failed";
|
|
@@ -123,11 +126,13 @@ export declare const Event: {
|
|
|
123
126
|
readonly FIND: "FIND";
|
|
124
127
|
readonly REQUEST: "REQUEST";
|
|
125
128
|
readonly REQUEST_COMPLETE: "REQUEST_COMPLETE";
|
|
129
|
+
readonly AWAIT_NETWORK: "AWAIT_NETWORK";
|
|
130
|
+
readonly NETWORK_READY: "NETWORK_READY";
|
|
126
131
|
readonly UPDATE: "UPDATE";
|
|
127
132
|
readonly TIMEOUT: "TIMEOUT";
|
|
128
133
|
readonly DELETE: "DELETE";
|
|
129
134
|
readonly MARK_UNAVAILABLE: "MARK_UNAVAILABLE";
|
|
130
135
|
};
|
|
131
|
-
export declare const IDLE: "idle", LOADING: "loading", REQUESTING: "requesting", READY: "ready", FAILED: "failed", DELETED: "deleted", UNAVAILABLE: "unavailable";
|
|
136
|
+
export declare const IDLE: "idle", LOADING: "loading", AWAITING_NETWORK: "awaitingNetwork", REQUESTING: "requesting", READY: "ready", FAILED: "failed", DELETED: "deleted", UNAVAILABLE: "unavailable";
|
|
132
137
|
export {};
|
|
133
138
|
//# sourceMappingURL=DocHandle.d.ts.map
|
package/dist/DocHandle.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocHandle.d.ts","sourceRoot":"","sources":["../src/DocHandle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"DocHandle.d.ts","sourceRoot":"","sources":["../src/DocHandle.ts"],"names":[],"mappings":"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"}
|
package/dist/DocHandle.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import * as A from "@automerge/automerge";
|
|
1
|
+
import * as A from "@automerge/automerge/next";
|
|
2
2
|
import debug from "debug";
|
|
3
|
-
import EventEmitter from "eventemitter3";
|
|
3
|
+
import { EventEmitter } from "eventemitter3";
|
|
4
4
|
import { assign, createMachine, interpret, } from "xstate";
|
|
5
5
|
import { waitFor } from "xstate/lib/waitFor.js";
|
|
6
6
|
import { headsAreSame } from "./helpers/headsAreSame.js";
|
|
7
7
|
import { pause } from "./helpers/pause.js";
|
|
8
8
|
import { TimeoutError, withTimeout } from "./helpers/withTimeout.js";
|
|
9
9
|
import { stringifyAutomergeUrl } from "./DocUrl.js";
|
|
10
|
-
import { encode } from "cbor
|
|
10
|
+
import { encode } from "./helpers/cbor.js";
|
|
11
11
|
/** DocHandle is a wrapper around a single Automerge document that lets us listen for changes. */
|
|
12
12
|
export class DocHandle//
|
|
13
13
|
extends EventEmitter {
|
|
@@ -24,7 +24,11 @@ export class DocHandle//
|
|
|
24
24
|
this.#timeoutDelay = timeoutDelay;
|
|
25
25
|
this.#log = debug(`automerge-repo:dochandle:${this.documentId.slice(0, 5)}`);
|
|
26
26
|
// initial doc
|
|
27
|
-
|
|
27
|
+
let doc = A.init();
|
|
28
|
+
// Make an empty change so that we have something to save to disk
|
|
29
|
+
if (isNew) {
|
|
30
|
+
doc = A.emptyChange(doc, {});
|
|
31
|
+
}
|
|
28
32
|
/**
|
|
29
33
|
* Internally we use a state machine to orchestrate document loading and/or syncing, in order to
|
|
30
34
|
* avoid requesting data we already have, or surfacing intermediate values to the consumer.
|
|
@@ -59,6 +63,8 @@ export class DocHandle//
|
|
|
59
63
|
UPDATE: { actions: "onUpdate", target: READY },
|
|
60
64
|
// REQUEST is called by the Repo if the document is not found in storage
|
|
61
65
|
REQUEST: { target: REQUESTING },
|
|
66
|
+
// AWAIT_NETWORK is called by the repo if the document is not found in storage but the network is not yet ready
|
|
67
|
+
AWAIT_NETWORK: { target: AWAITING_NETWORK },
|
|
62
68
|
DELETE: { actions: "onDelete", target: DELETED },
|
|
63
69
|
},
|
|
64
70
|
after: [
|
|
@@ -68,6 +74,11 @@ export class DocHandle//
|
|
|
68
74
|
},
|
|
69
75
|
],
|
|
70
76
|
},
|
|
77
|
+
awaitingNetwork: {
|
|
78
|
+
on: {
|
|
79
|
+
NETWORK_READY: { target: REQUESTING },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
71
82
|
requesting: {
|
|
72
83
|
on: {
|
|
73
84
|
MARK_UNAVAILABLE: {
|
|
@@ -278,6 +289,14 @@ export class DocHandle//
|
|
|
278
289
|
if (this.#state === LOADING)
|
|
279
290
|
this.#machine.send(REQUEST);
|
|
280
291
|
}
|
|
292
|
+
awaitNetwork() {
|
|
293
|
+
if (this.#state === LOADING)
|
|
294
|
+
this.#machine.send(AWAIT_NETWORK);
|
|
295
|
+
}
|
|
296
|
+
networkReady() {
|
|
297
|
+
if (this.#state === AWAITING_NETWORK)
|
|
298
|
+
this.#machine.send(NETWORK_READY);
|
|
299
|
+
}
|
|
281
300
|
/** `delete` is called by the repo when the document is deleted */
|
|
282
301
|
delete() {
|
|
283
302
|
this.#machine.send(DELETE);
|
|
@@ -300,6 +319,7 @@ export class DocHandle//
|
|
|
300
319
|
export const HandleState = {
|
|
301
320
|
IDLE: "idle",
|
|
302
321
|
LOADING: "loading",
|
|
322
|
+
AWAITING_NETWORK: "awaitingNetwork",
|
|
303
323
|
REQUESTING: "requesting",
|
|
304
324
|
READY: "ready",
|
|
305
325
|
FAILED: "failed",
|
|
@@ -312,11 +332,13 @@ export const Event = {
|
|
|
312
332
|
FIND: "FIND",
|
|
313
333
|
REQUEST: "REQUEST",
|
|
314
334
|
REQUEST_COMPLETE: "REQUEST_COMPLETE",
|
|
335
|
+
AWAIT_NETWORK: "AWAIT_NETWORK",
|
|
336
|
+
NETWORK_READY: "NETWORK_READY",
|
|
315
337
|
UPDATE: "UPDATE",
|
|
316
338
|
TIMEOUT: "TIMEOUT",
|
|
317
339
|
DELETE: "DELETE",
|
|
318
340
|
MARK_UNAVAILABLE: "MARK_UNAVAILABLE",
|
|
319
341
|
};
|
|
320
342
|
// CONSTANTS
|
|
321
|
-
export const { IDLE, LOADING, REQUESTING, READY, FAILED, DELETED, UNAVAILABLE, } = HandleState;
|
|
322
|
-
const { CREATE, FIND, REQUEST, UPDATE, TIMEOUT, DELETE, REQUEST_COMPLETE, MARK_UNAVAILABLE, } = Event;
|
|
343
|
+
export const { IDLE, LOADING, AWAITING_NETWORK, REQUESTING, READY, FAILED, DELETED, UNAVAILABLE, } = HandleState;
|
|
344
|
+
const { CREATE, FIND, REQUEST, UPDATE, TIMEOUT, DELETE, REQUEST_COMPLETE, MARK_UNAVAILABLE, AWAIT_NETWORK, NETWORK_READY, } = Event;
|
package/dist/DocUrl.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AutomergeUrl, type BinaryDocumentId, type DocumentId } from "./types";
|
|
1
|
+
import { type AutomergeUrl, type BinaryDocumentId, type DocumentId } from "./types.js";
|
|
2
2
|
export declare const urlPrefix = "automerge:";
|
|
3
3
|
/**
|
|
4
4
|
* given an Automerge URL, return a decoded DocumentId (and the encoded DocumentId)
|
package/dist/DocUrl.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocUrl.d.ts","sourceRoot":"","sources":["../src/DocUrl.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EAChB,MAAM,
|
|
1
|
+
{"version":3,"file":"DocUrl.d.ts","sourceRoot":"","sources":["../src/DocUrl.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAA;AAInB,eAAO,MAAM,SAAS,eAAe,CAAA;AAErC;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,QAAS,YAAY;;;CAIlD,CAAA;AAED,UAAU,4BAA4B;IACpC,UAAU,EAAE,UAAU,GAAG,gBAAgB,CAAA;CAC1C;AAED;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,oBAE/B,4BAA4B,KAAG,YAQjC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,QAAS,MAAM,wBAK9C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,QAAO,YAGpC,CAAA;AAEJ,eAAO,MAAM,kBAAkB,UACtB,UAAU,KAChB,gBAAgB,GAAG,SACyC,CAAA;AAE/D,eAAO,MAAM,kBAAkB,UAAW,gBAAgB,KAAG,UACtB,CAAA"}
|
package/dist/Repo.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../src/Repo.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAEhE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAE/C,oFAAoF;AACpF,qBAAa,IAAK,SAAQ,aAAa;;IAGrC,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;gBAEvB,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,UAAU;
|
|
1
|
+
{"version":3,"file":"Repo.d.ts","sourceRoot":"","sources":["../src/Repo.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAEhE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAE/C,oFAAoF;AACpF,qBAAa,IAAK,SAAQ,aAAa;;IAGrC,gBAAgB,EAAE,gBAAgB,CAAA;IAClC,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;gBAEvB,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,UAAU;CAiGlE;AAED,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf,gDAAgD;IAChD,OAAO,CAAC,EAAE,cAAc,CAAA;IAExB,oDAAoD;IACpD,OAAO,EAAE,cAAc,EAAE,CAAA;IAEzB;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B;AAED,MAAM,MAAM,WAAW,GAAG,CACxB,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,UAAU,KACpB,OAAO,CAAC,OAAO,CAAC,CAAA"}
|
package/dist/Repo.js
CHANGED
|
@@ -15,16 +15,22 @@ export class Repo extends DocCollection {
|
|
|
15
15
|
// DOC COLLECTION
|
|
16
16
|
// The `document` event is fired by the DocCollection any time we create a new document or look
|
|
17
17
|
// up a document by ID. We listen for it in order to wire up storage and network synchronization.
|
|
18
|
-
this.on("document", async ({ handle }) => {
|
|
18
|
+
this.on("document", async ({ handle, isNew }) => {
|
|
19
19
|
if (storageSubsystem) {
|
|
20
20
|
// Save when the document changes
|
|
21
21
|
handle.on("heads-changed", async ({ handle, doc }) => {
|
|
22
22
|
await storageSubsystem.saveDoc(handle.documentId, doc);
|
|
23
23
|
});
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
if (isNew) {
|
|
25
|
+
// this is a new document, immediately save it
|
|
26
|
+
await storageSubsystem.saveDoc(handle.documentId, handle.docSync());
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
// Try to load from disk
|
|
30
|
+
const loadedDoc = await storageSubsystem.loadDoc(handle.documentId);
|
|
31
|
+
if (loadedDoc) {
|
|
32
|
+
handle.update(() => loadedDoc);
|
|
33
|
+
}
|
|
28
34
|
}
|
|
29
35
|
}
|
|
30
36
|
handle.on("unavailable", () => {
|
|
@@ -33,7 +39,17 @@ export class Repo extends DocCollection {
|
|
|
33
39
|
documentId: handle.documentId,
|
|
34
40
|
});
|
|
35
41
|
});
|
|
36
|
-
|
|
42
|
+
if (this.networkSubsystem.isReady()) {
|
|
43
|
+
handle.request();
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
handle.awaitNetwork();
|
|
47
|
+
this.networkSubsystem.whenReady().then(() => {
|
|
48
|
+
handle.networkReady();
|
|
49
|
+
}).catch(err => {
|
|
50
|
+
this.#log("error waiting for network", { err });
|
|
51
|
+
});
|
|
52
|
+
}
|
|
37
53
|
// Register the document with the synchronizer. This advertises our interest in the document.
|
|
38
54
|
synchronizer.addDocument(handle.documentId);
|
|
39
55
|
});
|
|
@@ -41,7 +57,9 @@ export class Repo extends DocCollection {
|
|
|
41
57
|
// TODO Pass the delete on to the network
|
|
42
58
|
// synchronizer.removeDocument(documentId)
|
|
43
59
|
if (storageSubsystem) {
|
|
44
|
-
storageSubsystem.remove(documentId)
|
|
60
|
+
storageSubsystem.remove(documentId).catch(err => {
|
|
61
|
+
this.#log("error deleting document", { documentId, err });
|
|
62
|
+
});
|
|
45
63
|
}
|
|
46
64
|
});
|
|
47
65
|
// SYNCHRONIZER
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cbor.d.ts","sourceRoot":"","sources":["../../src/helpers/cbor.ts"],"names":[],"mappings":";AAEA,wBAAgB,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAGvC;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,GAAG,CAEpD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import EventEmitter from "eventemitter3";
|
|
1
|
+
import { EventEmitter } from "eventemitter3";
|
|
2
2
|
/** Returns a promise that resolves when the given event is emitted on the given emitter. */
|
|
3
3
|
export declare const eventPromise: (emitter: EventEmitter, event: string) => Promise<any>;
|
|
4
4
|
export declare const eventPromises: (emitters: EventEmitter[], event: string) => Promise<any[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eventPromise.d.ts","sourceRoot":"","sources":["../../src/helpers/eventPromise.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"eventPromise.d.ts","sourceRoot":"","sources":["../../src/helpers/eventPromise.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,4FAA4F;AAC5F,eAAO,MAAM,YAAY,YAAa,YAAY,SAAS,MAAM,iBACE,CAAA;AAEnE,eAAO,MAAM,aAAa,aAAc,YAAY,EAAE,SAAS,MAAM,mBAGpE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headsAreSame.d.ts","sourceRoot":"","sources":["../../src/helpers/headsAreSame.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"headsAreSame.d.ts","sourceRoot":"","sources":["../../src/helpers/headsAreSame.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,iCAExB,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,4 +11,5 @@ export { StorageSubsystem } from "./storage/StorageSubsystem.js";
|
|
|
11
11
|
export { CollectionSynchronizer } from "./synchronizer/CollectionSynchronizer.js";
|
|
12
12
|
export { parseAutomergeUrl, isValidAutomergeUrl, stringifyAutomergeUrl as generateAutomergeUrl, } from "./DocUrl.js";
|
|
13
13
|
export * from "./types.js";
|
|
14
|
+
export * as cbor from "./helpers/cbor.js";
|
|
14
15
|
//# 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,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AACvD,YAAY,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EACV,WAAW,EACX,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,6BAA6B,CAAA;AAMpC,YAAY,EACV,OAAO,EACP,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,GACZ,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAA;AACjF,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,IAAI,oBAAoB,GAC9C,MAAM,aAAa,CAAA;AACpB,cAAc,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AACvD,YAAY,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,YAAY,EACV,WAAW,EACX,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,6BAA6B,CAAA;AAMpC,YAAY,EACV,OAAO,EACP,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,GACZ,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAA;AACjF,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,IAAI,oBAAoB,GAC9C,MAAM,aAAa,CAAA;AACpB,cAAc,YAAY,CAAA;AAE1B,OAAO,KAAK,IAAI,MAAM,mBAAmB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -8,3 +8,4 @@ export { StorageSubsystem } from "./storage/StorageSubsystem.js";
|
|
|
8
8
|
export { CollectionSynchronizer } from "./synchronizer/CollectionSynchronizer.js";
|
|
9
9
|
export { parseAutomergeUrl, isValidAutomergeUrl, stringifyAutomergeUrl as generateAutomergeUrl, } from "./DocUrl.js";
|
|
10
10
|
export * from "./types.js";
|
|
11
|
+
export * as cbor from "./helpers/cbor.js";
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import EventEmitter from "eventemitter3";
|
|
1
|
+
import { EventEmitter } from "eventemitter3";
|
|
2
2
|
import { PeerId } from "../types.js";
|
|
3
3
|
import { Message } from "./messages.js";
|
|
4
4
|
export declare abstract class NetworkAdapter extends EventEmitter<NetworkAdapterEvents> {
|
|
5
5
|
peerId?: PeerId;
|
|
6
|
-
abstract connect(
|
|
6
|
+
abstract connect(peerId: PeerId): void;
|
|
7
7
|
abstract send(message: Message): void;
|
|
8
|
-
abstract
|
|
9
|
-
abstract leave(): void;
|
|
8
|
+
abstract disconnect(): void;
|
|
10
9
|
}
|
|
11
10
|
export interface NetworkAdapterEvents {
|
|
12
|
-
|
|
11
|
+
ready: (payload: OpenPayload) => void;
|
|
13
12
|
close: () => void;
|
|
14
13
|
"peer-candidate": (payload: PeerCandidatePayload) => void;
|
|
15
14
|
"peer-disconnected": (payload: PeerDisconnectedPayload) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NetworkAdapter.d.ts","sourceRoot":"","sources":["../../src/network/NetworkAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"NetworkAdapter.d.ts","sourceRoot":"","sources":["../../src/network/NetworkAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,8BAAsB,cAAe,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAEtC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAErC,QAAQ,CAAC,UAAU,IAAI,IAAI;CAC5B;AAID,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAA;IACrC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,gBAAgB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAA;IACzD,mBAAmB,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAA;IAC/D,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CACpC;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,cAAc,CAAA;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAA;CACf"}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import EventEmitter from "eventemitter3";
|
|
1
|
+
import { EventEmitter } from "eventemitter3";
|
|
2
2
|
import { PeerId } from "../types.js";
|
|
3
3
|
import { NetworkAdapter, PeerDisconnectedPayload } from "./NetworkAdapter.js";
|
|
4
4
|
import { Message, MessageContents } from "./messages.js";
|
|
5
5
|
export declare class NetworkSubsystem extends EventEmitter<NetworkSubsystemEvents> {
|
|
6
6
|
#private;
|
|
7
|
-
private adapters;
|
|
8
7
|
peerId: PeerId;
|
|
9
8
|
constructor(adapters: NetworkAdapter[], peerId?: PeerId);
|
|
10
9
|
addNetworkAdapter(networkAdapter: NetworkAdapter): void;
|
|
11
10
|
send(message: MessageContents): void;
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
isReady: () => boolean;
|
|
12
|
+
whenReady: () => Promise<void>;
|
|
14
13
|
}
|
|
15
14
|
export interface NetworkSubsystemEvents {
|
|
16
15
|
peer: (payload: PeerPayload) => void;
|
|
17
16
|
"peer-disconnected": (payload: PeerDisconnectedPayload) => void;
|
|
18
17
|
message: (payload: Message) => void;
|
|
18
|
+
ready: () => void;
|
|
19
19
|
}
|
|
20
20
|
export interface PeerPayload {
|
|
21
21
|
peerId: PeerId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NetworkSubsystem.d.ts","sourceRoot":"","sources":["../../src/network/NetworkSubsystem.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"NetworkSubsystem.d.ts","sourceRoot":"","sources":["../../src/network/NetworkSubsystem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAE7E,OAAO,EAIL,OAAO,EACP,eAAe,EAChB,MAAM,eAAe,CAAA;AAUtB,qBAAa,gBAAiB,SAAQ,YAAY,CAAC,sBAAsB,CAAC;;IAUzB,MAAM;gBAAzC,QAAQ,EAAE,cAAc,EAAE,EAAS,MAAM,SAAiB;IAMtE,iBAAiB,CAAC,cAAc,EAAE,cAAc;IAsEhD,IAAI,CAAC,OAAO,EAAE,eAAe;IA2B7B,OAAO,gBAEN;IAED,SAAS,sBAUR;CACF;AAQD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAA;IACpC,mBAAmB,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAA;IAC/D,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IACnC,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;CACf"}
|
|
@@ -1,24 +1,31 @@
|
|
|
1
|
-
import EventEmitter from "eventemitter3";
|
|
1
|
+
import { EventEmitter } from "eventemitter3";
|
|
2
2
|
import { isEphemeralMessage, isValidMessage, } from "./messages.js";
|
|
3
3
|
import debug from "debug";
|
|
4
4
|
const getEphemeralMessageSource = (message) => `${message.senderId}:${message.sessionId}`;
|
|
5
5
|
export class NetworkSubsystem extends EventEmitter {
|
|
6
|
-
adapters;
|
|
7
6
|
peerId;
|
|
8
7
|
#log;
|
|
9
8
|
#adaptersByPeer = {};
|
|
10
9
|
#count = 0;
|
|
11
10
|
#sessionId = Math.random().toString(36).slice(2);
|
|
12
11
|
#ephemeralSessionCounts = {};
|
|
12
|
+
#readyAdapterCount = 0;
|
|
13
|
+
#adapters = [];
|
|
13
14
|
constructor(adapters, peerId = randomPeerId()) {
|
|
14
15
|
super();
|
|
15
|
-
this.adapters = adapters;
|
|
16
16
|
this.peerId = peerId;
|
|
17
17
|
this.#log = debug(`automerge-repo:network:${this.peerId}`);
|
|
18
|
-
|
|
18
|
+
adapters.forEach(a => this.addNetworkAdapter(a));
|
|
19
19
|
}
|
|
20
20
|
addNetworkAdapter(networkAdapter) {
|
|
21
|
-
|
|
21
|
+
this.#adapters.push(networkAdapter);
|
|
22
|
+
networkAdapter.once("ready", () => {
|
|
23
|
+
this.#readyAdapterCount++;
|
|
24
|
+
this.#log("Adapters ready: ", this.#readyAdapterCount, "/", this.#adapters.length);
|
|
25
|
+
if (this.#readyAdapterCount === this.#adapters.length) {
|
|
26
|
+
this.emit("ready");
|
|
27
|
+
}
|
|
28
|
+
});
|
|
22
29
|
networkAdapter.on("peer-candidate", ({ peerId }) => {
|
|
23
30
|
this.#log(`peer candidate: ${peerId} `);
|
|
24
31
|
// TODO: This is where authentication would happen
|
|
@@ -58,7 +65,7 @@ export class NetworkSubsystem extends EventEmitter {
|
|
|
58
65
|
}
|
|
59
66
|
});
|
|
60
67
|
});
|
|
61
|
-
networkAdapter.
|
|
68
|
+
networkAdapter.connect(this.peerId);
|
|
62
69
|
}
|
|
63
70
|
send(message) {
|
|
64
71
|
const peer = this.#adaptersByPeer[message.targetId];
|
|
@@ -85,14 +92,21 @@ export class NetworkSubsystem extends EventEmitter {
|
|
|
85
92
|
peer.send(outbound);
|
|
86
93
|
}
|
|
87
94
|
}
|
|
88
|
-
|
|
89
|
-
this.#
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
isReady = () => {
|
|
96
|
+
return this.#readyAdapterCount === this.#adapters.length;
|
|
97
|
+
};
|
|
98
|
+
whenReady = async () => {
|
|
99
|
+
if (this.isReady()) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
return new Promise(resolve => {
|
|
104
|
+
this.once("ready", () => {
|
|
105
|
+
resolve();
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
};
|
|
96
110
|
}
|
|
97
111
|
function randomPeerId() {
|
|
98
112
|
return `user-${Math.round(Math.random() * 100000)}`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SessionId } from "../EphemeralData";
|
|
2
|
-
import { DocumentId, PeerId } from "../types";
|
|
1
|
+
import { SessionId } from "../EphemeralData.js";
|
|
2
|
+
import { DocumentId, PeerId } from "../types.js";
|
|
3
3
|
export declare function isValidMessage(message: NetworkAdapterMessage): message is SyncMessage | EphemeralMessage | RequestMessage | DocumentUnavailableMessage;
|
|
4
4
|
export declare function isDocumentUnavailableMessage(message: NetworkAdapterMessage): message is DocumentUnavailableMessage;
|
|
5
5
|
export declare function isRequestMessage(message: NetworkAdapterMessage): message is RequestMessage;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/network/messages.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/network/messages.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEhD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,IACN,WAAW,GACX,gBAAgB,GAChB,cAAc,GACd,0BAA0B,CAU7B;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,qBAAqB,GAC7B,OAAO,IAAI,0BAA0B,CAEvC;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,IAAI,cAAc,CAE3B;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,IAAI,WAAW,CAExB;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,qBAAqB,GAAG,eAAe,GAC/C,OAAO,IAAI,gBAAgB,GAAG,wBAAwB,CAExD;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,UAAU,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,UAAU,CAAA;CACvB;AAED,MAAM,MAAM,WAAW,GAAG,mBAAmB,GAAG,mBAAmB,CAAA;AAEnE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,SAAS,CAAA;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,UAAU,CAAA;IACtB,IAAI,EAAE,UAAU,CAAA;CACjB;AAED,MAAM,MAAM,gBAAgB,GAAG,wBAAwB,GACrD,wBAAwB,CAAA;AAE1B,MAAM,WAAW,kCAAkC;IACjD,IAAI,EAAE,iBAAiB,CAAA;IACvB,UAAU,EAAE,UAAU,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,GAC1D,kCAAkC,CAAA;AAEpC,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,SAAS,CAAA;IACf,IAAI,EAAE,UAAU,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,UAAU,CAAA;CACvB;AAED,MAAM,MAAM,cAAc,GAAG,mBAAmB,GAAG,sBAAsB,CAAA;AAEzE,MAAM,MAAM,eAAe,GACvB,mBAAmB,GACnB,wBAAwB,GACxB,sBAAsB,GACtB,kCAAkC,CAAA;AAEtC,MAAM,MAAM,OAAO,GACf,WAAW,GACX,gBAAgB,GAChB,cAAc,GACd,0BAA0B,CAAA;AAE9B,MAAM,MAAM,mBAAmB,GAC3B,WAAW,GACX,cAAc,GACd,0BAA0B,GAC1B,gBAAgB,CAAA;AAEpB,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,QAAQ,CAAA;CACf,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,SAAS,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,cAAc,GAAG,OAAO,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageSubsystem.d.ts","sourceRoot":"","sources":["../../src/storage/StorageSubsystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"StorageSubsystem.d.ts","sourceRoot":"","sources":["../../src/storage/StorageSubsystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,2BAA2B,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAc,MAAM,qBAAqB,CAAA;AAEhE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAa7C,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,aAAa,CAAA;AAelD,qBAAa,gBAAgB;;gBAQf,cAAc,EAAE,cAAc;IAuDpC,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IA0B/D,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAanE,MAAM,CAAC,UAAU,EAAE,UAAU;CAmCpC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as A from "@automerge/automerge";
|
|
1
|
+
import * as A from "@automerge/automerge/next";
|
|
2
2
|
import * as sha256 from "fast-sha256";
|
|
3
3
|
import { mergeArrays } from "../helpers/mergeArrays.js";
|
|
4
4
|
import debug from "debug";
|
|
@@ -11,7 +11,7 @@ function keyHash(binary) {
|
|
|
11
11
|
}
|
|
12
12
|
function headsHash(heads) {
|
|
13
13
|
let encoder = new TextEncoder();
|
|
14
|
-
let headsbinary = mergeArrays(heads.map(h => encoder.encode(h)));
|
|
14
|
+
let headsbinary = mergeArrays(heads.map((h) => encoder.encode(h)));
|
|
15
15
|
return keyHash(headsbinary);
|
|
16
16
|
}
|
|
17
17
|
export class StorageSubsystem {
|
|
@@ -19,6 +19,7 @@ export class StorageSubsystem {
|
|
|
19
19
|
#chunkInfos = new Map();
|
|
20
20
|
#storedHeads = new Map();
|
|
21
21
|
#log = debug(`automerge-repo:storage-subsystem`);
|
|
22
|
+
#snapshotting = false;
|
|
22
23
|
constructor(storageAdapter) {
|
|
23
24
|
this.#storageAdapter = storageAdapter;
|
|
24
25
|
}
|
|
@@ -43,6 +44,7 @@ export class StorageSubsystem {
|
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
async #saveTotal(documentId, doc, sourceChunks) {
|
|
47
|
+
this.#snapshotting = true;
|
|
46
48
|
const binary = A.save(doc);
|
|
47
49
|
const snapshotHash = headsHash(A.getHeads(doc));
|
|
48
50
|
const key = [documentId, "snapshot", snapshotHash];
|
|
@@ -56,6 +58,7 @@ export class StorageSubsystem {
|
|
|
56
58
|
const newChunkInfos = this.#chunkInfos.get(documentId)?.filter(c => !oldKeys.has(c.key)) ?? [];
|
|
57
59
|
newChunkInfos.push({ key, type: "snapshot", size: binary.length });
|
|
58
60
|
this.#chunkInfos.set(documentId, newChunkInfos);
|
|
61
|
+
this.#snapshotting = false;
|
|
59
62
|
}
|
|
60
63
|
async loadDoc(documentId) {
|
|
61
64
|
const loaded = await this.#storageAdapter.loadRange([documentId]);
|
|
@@ -96,7 +99,7 @@ export class StorageSubsystem {
|
|
|
96
99
|
this.#storedHeads.set(documentId, A.getHeads(doc));
|
|
97
100
|
}
|
|
98
101
|
async remove(documentId) {
|
|
99
|
-
this.#storageAdapter.
|
|
102
|
+
this.#storageAdapter.removeRange([documentId, "snapshot"]);
|
|
100
103
|
this.#storageAdapter.removeRange([documentId, "incremental"]);
|
|
101
104
|
}
|
|
102
105
|
#shouldSave(documentId, doc) {
|
|
@@ -111,6 +114,9 @@ export class StorageSubsystem {
|
|
|
111
114
|
return true;
|
|
112
115
|
}
|
|
113
116
|
#shouldCompact(sourceChunks) {
|
|
117
|
+
if (this.#snapshotting) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
114
120
|
// compact if the incremental size is greater than the snapshot size
|
|
115
121
|
let snapshotSize = 0;
|
|
116
122
|
let incrementalSize = 0;
|
|
@@ -122,7 +128,7 @@ export class StorageSubsystem {
|
|
|
122
128
|
incrementalSize += chunk.size;
|
|
123
129
|
}
|
|
124
130
|
}
|
|
125
|
-
return incrementalSize
|
|
131
|
+
return incrementalSize >= snapshotSize;
|
|
126
132
|
}
|
|
127
133
|
}
|
|
128
134
|
function chunkTypeFromKey(key) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocSynchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/DocSynchronizer.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"DocSynchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/DocSynchronizer.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,SAAS,EAKV,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGhD,OAAO,EACL,gBAAgB,EAIhB,cAAc,EACd,mBAAmB,EACnB,WAAW,EACZ,MAAM,wBAAwB,CAAA;AAE/B,KAAK,kBAAkB,GAAG,SAAS,GAAG,KAAK,GAAG,aAAa,GAAG,OAAO,CAAA;AAGrE;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,YAAY;;IAiBnC,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC;IAoB1C,IAAI,UAAU,uCAEb;IAED,IAAI,UAAU,qCAEb;IAiHD,OAAO,CAAC,MAAM,EAAE,MAAM;IAItB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE;IA6B3B,OAAO,CAAC,MAAM,EAAE,MAAM;IAKtB,cAAc,CAAC,OAAO,EAAE,mBAAmB;IAkB3C,uBAAuB,CAAC,OAAO,EAAE,gBAAgB;IAuBjD,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc;CA2EzD"}
|