@automerge/automerge-repo 2.0.0-alpha.22 → 2.0.0-alpha.23
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 -2
- package/dist/DocHandle.d.ts +0 -9
- package/dist/DocHandle.d.ts.map +1 -1
- package/dist/DocHandle.js +1 -21
- package/dist/synchronizer/DocSynchronizer.d.ts.map +1 -1
- package/dist/synchronizer/DocSynchronizer.js +31 -23
- package/package.json +3 -4
- package/src/DocHandle.ts +1 -22
- package/src/synchronizer/DocSynchronizer.ts +36 -27
- package/test/DocHandle.test.ts +0 -2
- package/test/Repo.test.ts +0 -8
package/README.md
CHANGED
|
@@ -232,14 +232,14 @@ Now import it and add it to your list of network adapters:
|
|
|
232
232
|
|
|
233
233
|
```ts
|
|
234
234
|
// main.tsx
|
|
235
|
-
import {
|
|
235
|
+
import { WebSocketClientAdapter } from "@automerge/automerge-repo-network-websocket" // <-- add this line
|
|
236
236
|
|
|
237
237
|
// ...
|
|
238
238
|
|
|
239
239
|
const repo = new Repo({
|
|
240
240
|
network: [
|
|
241
241
|
new BroadcastChannelNetworkAdapter(),
|
|
242
|
-
new
|
|
242
|
+
new WebSocketClientAdapter("ws://localhost:3030"), // <-- add this line
|
|
243
243
|
],
|
|
244
244
|
storage: new IndexedDBStorageAdapter(),
|
|
245
245
|
})
|
|
@@ -261,3 +261,4 @@ With gratitude for contributions by:
|
|
|
261
261
|
- Jeremy Rose
|
|
262
262
|
- Alex Currie-Clark
|
|
263
263
|
- Dylan Mackenzie
|
|
264
|
+
- Maciek Sakrejda
|
package/dist/DocHandle.d.ts
CHANGED
|
@@ -64,15 +64,6 @@ export declare class DocHandle<T> extends EventEmitter<DocHandleEvents<T>> {
|
|
|
64
64
|
* checking `inState()`.
|
|
65
65
|
*/
|
|
66
66
|
whenReady(awaitStates?: HandleState[]): Promise<void>;
|
|
67
|
-
/**
|
|
68
|
-
* @returns the current state of this handle's Automerge document.
|
|
69
|
-
*
|
|
70
|
-
* This is the recommended way to access a handle's document. Note that this waits for the handle
|
|
71
|
-
* to be ready if necessary. If loading (or synchronization) fails, this will never resolve.
|
|
72
|
-
*/
|
|
73
|
-
legacyAsyncDoc(
|
|
74
|
-
/** states to wait for, such as "LOADING". mostly for internal use. */
|
|
75
|
-
awaitStates?: HandleState[]): Promise<A.Doc<T> | undefined>;
|
|
76
67
|
/**
|
|
77
68
|
* Returns the current state of the Automerge document this handle manages.
|
|
78
69
|
*
|
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,gCAAgC,CAAA;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAU5C,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAE9C;;;;;;;;;;;;GAYG;AACH,qBAAa,SAAS,CAAC,CAAC,CAAE,SAAQ,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;;IAqBvD,UAAU,EAAE,UAAU;IAF/B,cAAc;gBAEL,UAAU,EAAE,UAAU,EAC7B,OAAO,GAAE,gBAAgB,CAAC,CAAC,CAAM;IAqKnC;OACG;IACH,IAAI,GAAG,IAAI,YAAY,CAKtB;IAED;;;;;OAKG;IACH,OAAO,gBAAgC;IAEvC;;;;;OAKG;IACH,UAAU,gBAAmC;IAE7C;;;;;OAKG;IACH,SAAS,gBAAkC;IAE3C;;;;OAIG;IACH,aAAa,gBAAsC;IAEnD;;OAEG;IACH,OAAO,WAAY,WAAW,EAAE,aAC0B;IAE1D,cAAc;IACd,IAAI,KAAK,yFAER;IAED;;;;;;OAMG;IACG,SAAS,CAAC,WAAW,GAAE,WAAW,EAAc;IAItD
|
|
1
|
+
{"version":3,"file":"DocHandle.d.ts","sourceRoot":"","sources":["../src/DocHandle.ts"],"names":[],"mappings":"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"}
|
package/dist/DocHandle.js
CHANGED
|
@@ -228,26 +228,6 @@ export class DocHandle extends EventEmitter {
|
|
|
228
228
|
async whenReady(awaitStates = ["ready"]) {
|
|
229
229
|
await withTimeout(this.#statePromise(awaitStates), this.#timeoutDelay);
|
|
230
230
|
}
|
|
231
|
-
/**
|
|
232
|
-
* @returns the current state of this handle's Automerge document.
|
|
233
|
-
*
|
|
234
|
-
* This is the recommended way to access a handle's document. Note that this waits for the handle
|
|
235
|
-
* to be ready if necessary. If loading (or synchronization) fails, this will never resolve.
|
|
236
|
-
*/
|
|
237
|
-
async legacyAsyncDoc(
|
|
238
|
-
/** states to wait for, such as "LOADING". mostly for internal use. */
|
|
239
|
-
awaitStates = ["ready", "unavailable"]) {
|
|
240
|
-
try {
|
|
241
|
-
// wait for the document to enter one of the desired states
|
|
242
|
-
await this.#statePromise(awaitStates);
|
|
243
|
-
}
|
|
244
|
-
catch (error) {
|
|
245
|
-
// if we timed out, return undefined
|
|
246
|
-
return undefined;
|
|
247
|
-
}
|
|
248
|
-
// Return the document
|
|
249
|
-
return !this.isUnavailable() ? this.#doc : undefined;
|
|
250
|
-
}
|
|
251
231
|
/**
|
|
252
232
|
* Returns the current state of the Automerge document this handle manages.
|
|
253
233
|
*
|
|
@@ -533,7 +513,7 @@ export class DocHandle extends EventEmitter {
|
|
|
533
513
|
broadcast(message) {
|
|
534
514
|
this.emit("ephemeral-message-outbound", {
|
|
535
515
|
handle: this,
|
|
536
|
-
data: encode(message),
|
|
516
|
+
data: new Uint8Array(encode(message)),
|
|
537
517
|
});
|
|
538
518
|
}
|
|
539
519
|
metrics() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocSynchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/DocSynchronizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gCAAgC,CAAA;AAGnD,OAAO,EACL,SAAS,EAKV,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAEL,gBAAgB,EAEhB,WAAW,EACX,cAAc,EACd,WAAW,EAEZ,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGhD,KAAK,kBAAkB,GAAG,SAAS,GAAG,KAAK,GAAG,aAAa,GAAG,OAAO,CAAA;AAOrE,UAAU,qBAAqB;IAC7B,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC,CAAA;CACvE;AAED;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,YAAY;;IAE/C,gBAAgB,SAAM;gBAyBV,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,qBAAqB;
|
|
1
|
+
{"version":3,"file":"DocSynchronizer.d.ts","sourceRoot":"","sources":["../../src/synchronizer/DocSynchronizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gCAAgC,CAAA;AAGnD,OAAO,EACL,SAAS,EAKV,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAEL,gBAAgB,EAEhB,WAAW,EACX,cAAc,EACd,WAAW,EAEZ,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGhD,KAAK,kBAAkB,GAAG,SAAS,GAAG,KAAK,GAAG,aAAa,GAAG,OAAO,CAAA;AAOrE,UAAU,qBAAqB;IAC7B,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC,CAAA;CACvE;AAED;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,YAAY;;IAE/C,gBAAgB,SAAM;gBAyBV,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,qBAAqB;IAyBtE,IAAI,UAAU,uCAEb;IAED,IAAI,UAAU,qCAEb;IAqID,OAAO,CAAC,MAAM,EAAE,MAAM;IAIhB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE;IA8DjC,OAAO,CAAC,MAAM,EAAE,MAAM;IAKtB,cAAc,CAAC,OAAO,EAAE,WAAW;IAkBnC,uBAAuB,CAAC,OAAO,EAAE,gBAAgB;IAuBjD,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc;IAwFxD,OAAO,IAAI;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE;CAM7E"}
|
|
@@ -37,7 +37,6 @@ export class DocSynchronizer extends Synchronizer {
|
|
|
37
37
|
handle.on("ephemeral-message-outbound", payload => this.#broadcastToPeers(payload));
|
|
38
38
|
// Process pending sync messages immediately after the handle becomes ready.
|
|
39
39
|
void (async () => {
|
|
40
|
-
await handle.whenReady([READY, REQUESTING]);
|
|
41
40
|
this.#processAllPendingSyncMessages();
|
|
42
41
|
})();
|
|
43
42
|
}
|
|
@@ -49,10 +48,14 @@ export class DocSynchronizer extends Synchronizer {
|
|
|
49
48
|
}
|
|
50
49
|
/// PRIVATE
|
|
51
50
|
async #syncWithPeers() {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
try {
|
|
52
|
+
await this.#handle.whenReady();
|
|
53
|
+
const doc = this.#handle.doc(); // XXX THIS ONE IS WEIRD
|
|
54
|
+
this.#peers.forEach(peerId => this.#sendSyncMessage(peerId, doc));
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
console.log("sync with peers threw an exception");
|
|
58
|
+
}
|
|
56
59
|
}
|
|
57
60
|
async #broadcastToPeers({ data, }) {
|
|
58
61
|
this.#log(`broadcastToPeers`, this.#peers);
|
|
@@ -155,22 +158,16 @@ export class DocSynchronizer extends Synchronizer {
|
|
|
155
158
|
return this.#peers.includes(peerId);
|
|
156
159
|
}
|
|
157
160
|
async beginSync(peerIds) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
161
|
+
void this.#handle
|
|
162
|
+
.whenReady([READY, REQUESTING, UNAVAILABLE])
|
|
163
|
+
.then(() => {
|
|
164
|
+
this.#syncStarted = true;
|
|
165
|
+
this.#checkDocUnavailable();
|
|
166
|
+
})
|
|
167
|
+
.catch(e => {
|
|
168
|
+
console.log("caught whenready", e);
|
|
165
169
|
this.#syncStarted = true;
|
|
166
170
|
this.#checkDocUnavailable();
|
|
167
|
-
const wasUnavailable = doc === undefined;
|
|
168
|
-
if (wasUnavailable && noPeersWithDocument) {
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
// If the doc is unavailable we still need a blank document to generate
|
|
172
|
-
// the sync message from
|
|
173
|
-
return doc ?? A.init();
|
|
174
171
|
});
|
|
175
172
|
const peersWithDocument = this.#peers.some(peerId => {
|
|
176
173
|
return this.#peerDocumentStatuses[peerId] == "has";
|
|
@@ -186,11 +183,22 @@ export class DocSynchronizer extends Synchronizer {
|
|
|
186
183
|
// TODO: cover that case with a test and remove this hack
|
|
187
184
|
const reparsedSyncState = A.decodeSyncState(A.encodeSyncState(syncState));
|
|
188
185
|
this.#setSyncState(peerId, reparsedSyncState);
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
186
|
+
// At this point if we don't have anything in our storage, we need to use an empty doc to sync
|
|
187
|
+
// with; but we don't want to surface that state to the front end
|
|
188
|
+
this.#handle
|
|
189
|
+
.whenReady([READY, REQUESTING, UNAVAILABLE])
|
|
190
|
+
.then(() => {
|
|
191
|
+
const doc = this.#handle.isReady()
|
|
192
|
+
? this.#handle.doc()
|
|
193
|
+
: A.init();
|
|
194
|
+
const noPeersWithDocument = peerIds.every(peerId => this.#peerDocumentStatuses[peerId] in ["unavailable", "wants"]);
|
|
195
|
+
const wasUnavailable = doc === undefined;
|
|
196
|
+
if (wasUnavailable && noPeersWithDocument) {
|
|
197
|
+
return;
|
|
193
198
|
}
|
|
199
|
+
// If the doc is unavailable we still need a blank document to generate
|
|
200
|
+
// the sync message from
|
|
201
|
+
this.#sendSyncMessage(peerId, doc ?? A.init());
|
|
194
202
|
})
|
|
195
203
|
.catch(err => {
|
|
196
204
|
this.#log(`Error loading doc for ${peerId}: ${err}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automerge/automerge-repo",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.23",
|
|
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>",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"http-server": "^14.1.0",
|
|
23
|
+
"ts-node": "^10.9.2",
|
|
23
24
|
"vite": "^5.0.8"
|
|
24
25
|
},
|
|
25
26
|
"dependencies": {
|
|
@@ -29,8 +30,6 @@
|
|
|
29
30
|
"debug": "^4.3.4",
|
|
30
31
|
"eventemitter3": "^5.0.1",
|
|
31
32
|
"fast-sha256": "^1.3.0",
|
|
32
|
-
"tiny-typed-emitter": "^2.1.0",
|
|
33
|
-
"ts-node": "^10.9.1",
|
|
34
33
|
"uuid": "^9.0.0",
|
|
35
34
|
"xstate": "^5.9.1"
|
|
36
35
|
},
|
|
@@ -60,5 +59,5 @@
|
|
|
60
59
|
"publishConfig": {
|
|
61
60
|
"access": "public"
|
|
62
61
|
},
|
|
63
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "82a9bed7cc6a92940f3aa68167f6990123dda58e"
|
|
64
63
|
}
|
package/src/DocHandle.ts
CHANGED
|
@@ -275,27 +275,6 @@ export class DocHandle<T> extends EventEmitter<DocHandleEvents<T>> {
|
|
|
275
275
|
await withTimeout(this.#statePromise(awaitStates), this.#timeoutDelay)
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
-
/**
|
|
279
|
-
* @returns the current state of this handle's Automerge document.
|
|
280
|
-
*
|
|
281
|
-
* This is the recommended way to access a handle's document. Note that this waits for the handle
|
|
282
|
-
* to be ready if necessary. If loading (or synchronization) fails, this will never resolve.
|
|
283
|
-
*/
|
|
284
|
-
async legacyAsyncDoc(
|
|
285
|
-
/** states to wait for, such as "LOADING". mostly for internal use. */
|
|
286
|
-
awaitStates: HandleState[] = ["ready", "unavailable"]
|
|
287
|
-
) {
|
|
288
|
-
try {
|
|
289
|
-
// wait for the document to enter one of the desired states
|
|
290
|
-
await this.#statePromise(awaitStates)
|
|
291
|
-
} catch (error) {
|
|
292
|
-
// if we timed out, return undefined
|
|
293
|
-
return undefined
|
|
294
|
-
}
|
|
295
|
-
// Return the document
|
|
296
|
-
return !this.isUnavailable() ? this.#doc : undefined
|
|
297
|
-
}
|
|
298
|
-
|
|
299
278
|
/**
|
|
300
279
|
* Returns the current state of the Automerge document this handle manages.
|
|
301
280
|
*
|
|
@@ -635,7 +614,7 @@ export class DocHandle<T> extends EventEmitter<DocHandleEvents<T>> {
|
|
|
635
614
|
broadcast(message: unknown) {
|
|
636
615
|
this.emit("ephemeral-message-outbound", {
|
|
637
616
|
handle: this,
|
|
638
|
-
data: encode(message),
|
|
617
|
+
data: new Uint8Array(encode(message)),
|
|
639
618
|
})
|
|
640
619
|
}
|
|
641
620
|
|
|
@@ -86,7 +86,6 @@ export class DocSynchronizer extends Synchronizer {
|
|
|
86
86
|
|
|
87
87
|
// Process pending sync messages immediately after the handle becomes ready.
|
|
88
88
|
void (async () => {
|
|
89
|
-
await handle.whenReady([READY, REQUESTING])
|
|
90
89
|
this.#processAllPendingSyncMessages()
|
|
91
90
|
})()
|
|
92
91
|
}
|
|
@@ -102,9 +101,13 @@ export class DocSynchronizer extends Synchronizer {
|
|
|
102
101
|
/// PRIVATE
|
|
103
102
|
|
|
104
103
|
async #syncWithPeers() {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
try {
|
|
105
|
+
await this.#handle.whenReady()
|
|
106
|
+
const doc = this.#handle.doc() // XXX THIS ONE IS WEIRD
|
|
107
|
+
this.#peers.forEach(peerId => this.#sendSyncMessage(peerId, doc))
|
|
108
|
+
} catch (e) {
|
|
109
|
+
console.log("sync with peers threw an exception")
|
|
110
|
+
}
|
|
108
111
|
}
|
|
109
112
|
|
|
110
113
|
async #broadcastToPeers({
|
|
@@ -231,27 +234,16 @@ export class DocSynchronizer extends Synchronizer {
|
|
|
231
234
|
}
|
|
232
235
|
|
|
233
236
|
async beginSync(peerIds: PeerId[]) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
.then(doc => {
|
|
243
|
-
// we register out peers first, then say that sync has started
|
|
237
|
+
void this.#handle
|
|
238
|
+
.whenReady([READY, REQUESTING, UNAVAILABLE])
|
|
239
|
+
.then(() => {
|
|
240
|
+
this.#syncStarted = true
|
|
241
|
+
this.#checkDocUnavailable()
|
|
242
|
+
})
|
|
243
|
+
.catch(e => {
|
|
244
|
+
console.log("caught whenready", e)
|
|
244
245
|
this.#syncStarted = true
|
|
245
246
|
this.#checkDocUnavailable()
|
|
246
|
-
|
|
247
|
-
const wasUnavailable = doc === undefined
|
|
248
|
-
if (wasUnavailable && noPeersWithDocument) {
|
|
249
|
-
return
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// If the doc is unavailable we still need a blank document to generate
|
|
253
|
-
// the sync message from
|
|
254
|
-
return doc ?? A.init<unknown>()
|
|
255
247
|
})
|
|
256
248
|
|
|
257
249
|
const peersWithDocument = this.#peers.some(peerId => {
|
|
@@ -273,11 +265,28 @@ export class DocSynchronizer extends Synchronizer {
|
|
|
273
265
|
)
|
|
274
266
|
this.#setSyncState(peerId, reparsedSyncState)
|
|
275
267
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
268
|
+
// At this point if we don't have anything in our storage, we need to use an empty doc to sync
|
|
269
|
+
// with; but we don't want to surface that state to the front end
|
|
270
|
+
this.#handle
|
|
271
|
+
.whenReady([READY, REQUESTING, UNAVAILABLE])
|
|
272
|
+
.then(() => {
|
|
273
|
+
const doc = this.#handle.isReady()
|
|
274
|
+
? this.#handle.doc()
|
|
275
|
+
: A.init<unknown>()
|
|
276
|
+
|
|
277
|
+
const noPeersWithDocument = peerIds.every(
|
|
278
|
+
peerId =>
|
|
279
|
+
this.#peerDocumentStatuses[peerId] in ["unavailable", "wants"]
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
const wasUnavailable = doc === undefined
|
|
283
|
+
if (wasUnavailable && noPeersWithDocument) {
|
|
284
|
+
return
|
|
280
285
|
}
|
|
286
|
+
|
|
287
|
+
// If the doc is unavailable we still need a blank document to generate
|
|
288
|
+
// the sync message from
|
|
289
|
+
this.#sendSyncMessage(peerId, doc ?? A.init<unknown>())
|
|
281
290
|
})
|
|
282
291
|
.catch(err => {
|
|
283
292
|
this.#log(`Error loading doc for ${peerId}: ${err}`)
|
package/test/DocHandle.test.ts
CHANGED
package/test/Repo.test.ts
CHANGED
|
@@ -255,7 +255,6 @@ describe("Repo", () => {
|
|
|
255
255
|
await repo.flush()
|
|
256
256
|
|
|
257
257
|
const bobHandle = await repo2.find<TestDoc>(handle.url)
|
|
258
|
-
await bobHandle.whenReady()
|
|
259
258
|
assert.deepEqual(bobHandle.doc(), { foo: "saved" })
|
|
260
259
|
})
|
|
261
260
|
|
|
@@ -306,7 +305,6 @@ describe("Repo", () => {
|
|
|
306
305
|
d.foo = "bar"
|
|
307
306
|
})
|
|
308
307
|
assert.equal(handle.isReady(), true)
|
|
309
|
-
await handle.whenReady()
|
|
310
308
|
|
|
311
309
|
await pause()
|
|
312
310
|
repo.delete(handle.url)
|
|
@@ -1063,11 +1061,6 @@ describe("Repo", () => {
|
|
|
1063
1061
|
: // tails, pick a random doc
|
|
1064
1062
|
(getRandomItem(docs) as DocHandle<TestDoc>)
|
|
1065
1063
|
|
|
1066
|
-
// make sure the doc is ready
|
|
1067
|
-
if (!doc.isReady()) {
|
|
1068
|
-
await doc.whenReady()
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
1064
|
// make a random change to it
|
|
1072
1065
|
doc.change(d => {
|
|
1073
1066
|
d.foo = Math.random().toString()
|
|
@@ -1240,7 +1233,6 @@ describe("Repo", () => {
|
|
|
1240
1233
|
})
|
|
1241
1234
|
|
|
1242
1235
|
const charlieHandle = await charlieRepo.find<TestDoc>(handle.url)
|
|
1243
|
-
await charlieHandle.whenReady()
|
|
1244
1236
|
|
|
1245
1237
|
// make a change on charlie
|
|
1246
1238
|
charlieHandle.change(d => {
|