@dxos/echo-pipeline 0.4.10-main.bf8d896 → 0.4.10-main.c16d37b
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/lib/browser/index.mjs +124 -146
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs.map +1 -1
- package/dist/lib/node/index.cjs +127 -147
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs.map +1 -1
- package/dist/types/src/automerge/automerge-host.d.ts +6 -13
- package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
- package/dist/types/src/automerge/automerge-repo.test.d.ts +2 -0
- package/dist/types/src/automerge/automerge-repo.test.d.ts.map +1 -0
- package/dist/types/src/automerge/index.d.ts +1 -0
- package/dist/types/src/automerge/index.d.ts.map +1 -1
- package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +11 -8
- package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -1
- package/dist/types/src/automerge/local-host-network-adapter.d.ts +8 -1
- package/dist/types/src/automerge/local-host-network-adapter.d.ts.map +1 -1
- package/dist/types/src/automerge/migrations.d.ts +2 -2
- package/dist/types/src/automerge/reference.d.ts +1 -1
- package/dist/types/src/automerge/reference.d.ts.map +1 -1
- package/dist/types/src/automerge/types.d.ts +4 -3
- package/dist/types/src/automerge/types.d.ts.map +1 -1
- package/dist/types/src/testing/level.d.ts +2 -2
- package/package.json +30 -30
- package/src/automerge/automerge-host.test.ts +4 -4
- package/src/automerge/automerge-host.ts +29 -100
- package/src/automerge/automerge-repo.test.ts +29 -0
- package/src/automerge/index.ts +1 -0
- package/src/automerge/level.test.ts +41 -2
- package/src/automerge/leveldb-storage-adapter.ts +36 -24
- package/src/automerge/local-host-network-adapter.ts +19 -13
- package/src/automerge/migrations.ts +2 -2
- package/src/automerge/reference.ts +1 -1
- package/src/automerge/storage-adapter.test.ts +4 -4
- package/src/automerge/types.ts +4 -3
- package/src/testing/level.ts +2 -2
|
@@ -25,41 +25,54 @@ import {
|
|
|
25
25
|
} from "./chunk-SYE4EK33.mjs";
|
|
26
26
|
|
|
27
27
|
// packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
|
|
28
|
-
import {
|
|
28
|
+
import { asyncTimeout } from "@dxos/async";
|
|
29
|
+
import { next as automerge } from "@dxos/automerge/automerge";
|
|
29
30
|
import { Repo } from "@dxos/automerge/automerge-repo";
|
|
30
31
|
import { Context } from "@dxos/context";
|
|
31
32
|
import { PublicKey } from "@dxos/keys";
|
|
32
|
-
import { log as
|
|
33
|
-
import { idCodec } from "@dxos/protocols";
|
|
33
|
+
import { log as log3 } from "@dxos/log";
|
|
34
34
|
import { trace } from "@dxos/tracing";
|
|
35
35
|
import { ComplexMap, ComplexSet, defaultMap, mapValues } from "@dxos/util";
|
|
36
36
|
|
|
37
37
|
// packages/core/echo/echo-pipeline/src/automerge/leveldb-storage-adapter.ts
|
|
38
|
-
|
|
38
|
+
import { LifecycleState, Resource } from "@dxos/context";
|
|
39
|
+
var LevelDBStorageAdapter = class extends Resource {
|
|
39
40
|
constructor(_params) {
|
|
41
|
+
super();
|
|
40
42
|
this._params = _params;
|
|
41
|
-
this._state = "opened";
|
|
42
43
|
}
|
|
43
44
|
async load(keyArray) {
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
try {
|
|
46
|
+
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
47
|
+
return void 0;
|
|
48
|
+
}
|
|
49
|
+
return await this._params.db.get(keyArray, {
|
|
50
|
+
...encodingOptions
|
|
51
|
+
});
|
|
52
|
+
} catch (err) {
|
|
53
|
+
if (isLevelDbNotFoundError(err)) {
|
|
54
|
+
return void 0;
|
|
55
|
+
}
|
|
56
|
+
throw err;
|
|
46
57
|
}
|
|
47
|
-
return this._params.db.get(keyArray, {
|
|
48
|
-
...encodingOptions
|
|
49
|
-
}).catch((err) => err.code === "LEVEL_NOT_FOUND" ? void 0 : Promise.reject(err));
|
|
50
58
|
}
|
|
51
59
|
async save(keyArray, binary) {
|
|
52
|
-
if (this.
|
|
60
|
+
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
53
61
|
return void 0;
|
|
54
62
|
}
|
|
55
|
-
|
|
56
|
-
await this._params.
|
|
63
|
+
const batch = this._params.db.batch();
|
|
64
|
+
await this._params.callbacks?.beforeSave?.({
|
|
65
|
+
path: keyArray,
|
|
66
|
+
batch
|
|
67
|
+
});
|
|
68
|
+
batch.put(keyArray, Buffer.from(binary), {
|
|
57
69
|
...encodingOptions
|
|
58
70
|
});
|
|
71
|
+
await batch.write();
|
|
59
72
|
await this._params.callbacks?.afterSave?.(keyArray);
|
|
60
73
|
}
|
|
61
74
|
async remove(keyArray) {
|
|
62
|
-
if (this.
|
|
75
|
+
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
63
76
|
return void 0;
|
|
64
77
|
}
|
|
65
78
|
await this._params.db.del(keyArray, {
|
|
@@ -67,7 +80,7 @@ var LevelDBStorageAdapter = class {
|
|
|
67
80
|
});
|
|
68
81
|
}
|
|
69
82
|
async loadRange(keyPrefix) {
|
|
70
|
-
if (this.
|
|
83
|
+
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
71
84
|
return [];
|
|
72
85
|
}
|
|
73
86
|
const result = [];
|
|
@@ -87,7 +100,7 @@ var LevelDBStorageAdapter = class {
|
|
|
87
100
|
return result;
|
|
88
101
|
}
|
|
89
102
|
async removeRange(keyPrefix) {
|
|
90
|
-
if (this.
|
|
103
|
+
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
91
104
|
return void 0;
|
|
92
105
|
}
|
|
93
106
|
const batch = this._params.db.batch();
|
|
@@ -105,9 +118,6 @@ var LevelDBStorageAdapter = class {
|
|
|
105
118
|
}
|
|
106
119
|
await batch.write();
|
|
107
120
|
}
|
|
108
|
-
close() {
|
|
109
|
-
this._state = "closed";
|
|
110
|
-
}
|
|
111
121
|
};
|
|
112
122
|
var keyEncoder = {
|
|
113
123
|
encode: (key) => Buffer.from(key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-")),
|
|
@@ -117,19 +127,20 @@ var encodingOptions = {
|
|
|
117
127
|
keyEncoding: keyEncoder,
|
|
118
128
|
valueEncoding: "buffer"
|
|
119
129
|
};
|
|
130
|
+
var isLevelDbNotFoundError = (err) => err.code === "LEVEL_NOT_FOUND";
|
|
120
131
|
|
|
121
132
|
// packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts
|
|
122
133
|
import { Trigger } from "@dxos/async";
|
|
123
134
|
import { NetworkAdapter, cbor } from "@dxos/automerge/automerge-repo";
|
|
124
135
|
import { Stream } from "@dxos/codec-protobuf";
|
|
125
136
|
import { invariant } from "@dxos/invariant";
|
|
126
|
-
import { log } from "@dxos/log";
|
|
127
137
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts";
|
|
128
138
|
var LocalHostNetworkAdapter = class extends NetworkAdapter {
|
|
129
139
|
constructor() {
|
|
130
140
|
super(...arguments);
|
|
131
141
|
this._peers = /* @__PURE__ */ new Map();
|
|
132
142
|
this._connected = new Trigger();
|
|
143
|
+
this._isConnected = false;
|
|
133
144
|
}
|
|
134
145
|
/**
|
|
135
146
|
* Emits `ready` event. That signals to `Repo` that it can start using the adapter.
|
|
@@ -139,15 +150,21 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
|
|
|
139
150
|
network: this
|
|
140
151
|
});
|
|
141
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Called by `Repo` to connect to the network.
|
|
155
|
+
*
|
|
156
|
+
* @param peerId Our peer Id.
|
|
157
|
+
*/
|
|
142
158
|
connect(peerId) {
|
|
143
159
|
this.peerId = peerId;
|
|
160
|
+
this._isConnected = true;
|
|
144
161
|
this._connected.wake();
|
|
145
162
|
}
|
|
146
163
|
send(message) {
|
|
147
164
|
const peer = this._peers.get(message.targetId);
|
|
148
165
|
invariant(peer, "Peer not found.", {
|
|
149
166
|
F: __dxlog_file,
|
|
150
|
-
L:
|
|
167
|
+
L: 51,
|
|
151
168
|
S: this,
|
|
152
169
|
A: [
|
|
153
170
|
"peer",
|
|
@@ -162,12 +179,17 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
|
|
|
162
179
|
}
|
|
163
180
|
disconnect() {
|
|
164
181
|
}
|
|
182
|
+
async whenConnected() {
|
|
183
|
+
await this._connected.wait({
|
|
184
|
+
timeout: 1e4
|
|
185
|
+
});
|
|
186
|
+
}
|
|
165
187
|
syncRepo({ id, syncMessage }) {
|
|
166
188
|
const peerId = this._getPeerId(id);
|
|
167
189
|
return new Stream(({ next, close }) => {
|
|
168
190
|
invariant(!this._peers.has(peerId), "Peer already connected.", {
|
|
169
191
|
F: __dxlog_file,
|
|
170
|
-
L:
|
|
192
|
+
L: 73,
|
|
171
193
|
S: this,
|
|
172
194
|
A: [
|
|
173
195
|
"!this._peers.has(peerId)",
|
|
@@ -189,35 +211,47 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
|
|
|
189
211
|
});
|
|
190
212
|
}
|
|
191
213
|
});
|
|
192
|
-
this.
|
|
193
|
-
timeout: 1e3
|
|
194
|
-
}).then(() => {
|
|
195
|
-
this.emit("peer-candidate", {
|
|
196
|
-
peerMetadata: {},
|
|
197
|
-
peerId
|
|
198
|
-
});
|
|
199
|
-
}).catch((err) => log.catch(err, void 0, {
|
|
214
|
+
invariant(this._isConnected, void 0, {
|
|
200
215
|
F: __dxlog_file,
|
|
201
|
-
L:
|
|
216
|
+
L: 90,
|
|
202
217
|
S: this,
|
|
203
|
-
|
|
204
|
-
|
|
218
|
+
A: [
|
|
219
|
+
"this._isConnected",
|
|
220
|
+
""
|
|
221
|
+
]
|
|
222
|
+
});
|
|
223
|
+
this.emit("peer-candidate", {
|
|
224
|
+
peerMetadata: {},
|
|
225
|
+
peerId
|
|
226
|
+
});
|
|
205
227
|
});
|
|
206
228
|
}
|
|
207
229
|
async sendSyncMessage({ id, syncMessage }) {
|
|
208
|
-
|
|
209
|
-
|
|
230
|
+
invariant(this._isConnected, void 0, {
|
|
231
|
+
F: __dxlog_file,
|
|
232
|
+
L: 99,
|
|
233
|
+
S: this,
|
|
234
|
+
A: [
|
|
235
|
+
"this._isConnected",
|
|
236
|
+
""
|
|
237
|
+
]
|
|
210
238
|
});
|
|
211
239
|
const message = cbor.decode(syncMessage);
|
|
212
240
|
this.emit("message", message);
|
|
213
241
|
}
|
|
214
242
|
async getHostInfo() {
|
|
215
|
-
|
|
216
|
-
|
|
243
|
+
invariant(this._isConnected, void 0, {
|
|
244
|
+
F: __dxlog_file,
|
|
245
|
+
L: 105,
|
|
246
|
+
S: this,
|
|
247
|
+
A: [
|
|
248
|
+
"this._isConnected",
|
|
249
|
+
""
|
|
250
|
+
]
|
|
217
251
|
});
|
|
218
252
|
invariant(this.peerId, "Peer id not set.", {
|
|
219
253
|
F: __dxlog_file,
|
|
220
|
-
L:
|
|
254
|
+
L: 106,
|
|
221
255
|
S: this,
|
|
222
256
|
A: [
|
|
223
257
|
"this.peerId",
|
|
@@ -237,7 +271,7 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
|
|
|
237
271
|
import { Trigger as Trigger2 } from "@dxos/async";
|
|
238
272
|
import { NetworkAdapter as NetworkAdapter2, cbor as cbor2 } from "@dxos/automerge/automerge-repo";
|
|
239
273
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
240
|
-
import { log
|
|
274
|
+
import { log } from "@dxos/log";
|
|
241
275
|
import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
|
|
242
276
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts";
|
|
243
277
|
var MeshNetworkAdapter = class extends NetworkAdapter2 {
|
|
@@ -272,7 +306,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter2 {
|
|
|
272
306
|
});
|
|
273
307
|
extension.sendSyncMessage({
|
|
274
308
|
payload: cbor2.encode(message)
|
|
275
|
-
}).catch((err) =>
|
|
309
|
+
}).catch((err) => log.catch(err, void 0, {
|
|
276
310
|
F: __dxlog_file2,
|
|
277
311
|
L: 39,
|
|
278
312
|
S: this,
|
|
@@ -297,7 +331,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter2 {
|
|
|
297
331
|
}, {
|
|
298
332
|
onStartReplication: async (info, remotePeerId) => {
|
|
299
333
|
await this._connected.wait();
|
|
300
|
-
|
|
334
|
+
log("onStartReplication", {
|
|
301
335
|
id: info.id,
|
|
302
336
|
thisPeerId: this.peerId,
|
|
303
337
|
remotePeerId: remotePeerId.toHex()
|
|
@@ -310,7 +344,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter2 {
|
|
|
310
344
|
if (!this._extensions.has(info.id)) {
|
|
311
345
|
peerInfo = info;
|
|
312
346
|
this._extensions.set(info.id, extension);
|
|
313
|
-
|
|
347
|
+
log("peer-candidate", {
|
|
314
348
|
id: info.id,
|
|
315
349
|
thisPeerId: this.peerId,
|
|
316
350
|
remotePeerId: remotePeerId.toHex()
|
|
@@ -352,7 +386,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter2 {
|
|
|
352
386
|
|
|
353
387
|
// packages/core/echo/echo-pipeline/src/automerge/migrations.ts
|
|
354
388
|
import { IndexedDBStorageAdapter } from "@dxos/automerge/automerge-repo-storage-indexeddb";
|
|
355
|
-
import { log as
|
|
389
|
+
import { log as log2 } from "@dxos/log";
|
|
356
390
|
import { StorageType } from "@dxos/random-access-storage";
|
|
357
391
|
|
|
358
392
|
// packages/core/echo/echo-pipeline/src/automerge/automerge-storage-adapter.ts
|
|
@@ -446,7 +480,7 @@ var levelMigration = async ({ db, directory }) => {
|
|
|
446
480
|
return;
|
|
447
481
|
}
|
|
448
482
|
const batch = db.batch();
|
|
449
|
-
|
|
483
|
+
log2.info("found chunks on old storage adapter", {
|
|
450
484
|
chunks: chunks.length
|
|
451
485
|
}, {
|
|
452
486
|
F: __dxlog_file3,
|
|
@@ -475,29 +509,27 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
475
509
|
}
|
|
476
510
|
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
|
|
477
511
|
var AutomergeHost = class {
|
|
478
|
-
constructor({ directory, db,
|
|
512
|
+
constructor({ directory, db, storageCallbacks }) {
|
|
479
513
|
this._ctx = new Context();
|
|
480
514
|
/**
|
|
481
515
|
* spaceKey -> deviceKey[]
|
|
482
516
|
*/
|
|
483
517
|
this._authorizedDevices = new ComplexMap(PublicKey.hash);
|
|
484
|
-
this._updatingMetadata = /* @__PURE__ */ new Map();
|
|
485
518
|
this._requestedDocs = /* @__PURE__ */ new Set();
|
|
486
519
|
this._directory = directory;
|
|
487
520
|
this._db = db;
|
|
488
|
-
this.
|
|
521
|
+
this._storageCallbacks = storageCallbacks;
|
|
489
522
|
}
|
|
490
523
|
async open() {
|
|
491
524
|
this._directory && await levelMigration({
|
|
492
|
-
db:
|
|
525
|
+
db: this._db,
|
|
493
526
|
directory: this._directory
|
|
494
527
|
});
|
|
495
528
|
this._storage = new LevelDBStorageAdapter({
|
|
496
|
-
db:
|
|
497
|
-
callbacks:
|
|
498
|
-
beforeSave: (params) => this._beforeSave(params)
|
|
499
|
-
}
|
|
529
|
+
db: this._db,
|
|
530
|
+
callbacks: this._storageCallbacks
|
|
500
531
|
});
|
|
532
|
+
await this._storage.open?.();
|
|
501
533
|
this._peerId = `host-${PublicKey.random().toHex()}`;
|
|
502
534
|
this._meshNetwork = new MeshNetworkAdapter();
|
|
503
535
|
this._clientNetwork = new LocalHostNetworkAdapter();
|
|
@@ -520,13 +552,13 @@ var AutomergeHost = class {
|
|
|
520
552
|
const doc = this._repo.handles[documentId]?.docSync();
|
|
521
553
|
if (!doc) {
|
|
522
554
|
const isRequested = this._requestedDocs.has(`automerge:${documentId}`);
|
|
523
|
-
|
|
555
|
+
log3("doc share policy check", {
|
|
524
556
|
peerId,
|
|
525
557
|
documentId,
|
|
526
558
|
isRequested
|
|
527
559
|
}, {
|
|
528
560
|
F: __dxlog_file4,
|
|
529
|
-
L:
|
|
561
|
+
L: 100,
|
|
530
562
|
S: this,
|
|
531
563
|
C: (f, a) => f(...a)
|
|
532
564
|
});
|
|
@@ -535,12 +567,12 @@ var AutomergeHost = class {
|
|
|
535
567
|
try {
|
|
536
568
|
const spaceKey = getSpaceKeyFromDoc(doc);
|
|
537
569
|
if (!spaceKey) {
|
|
538
|
-
|
|
570
|
+
log3("space key not found for share policy check", {
|
|
539
571
|
peerId,
|
|
540
572
|
documentId
|
|
541
573
|
}, {
|
|
542
574
|
F: __dxlog_file4,
|
|
543
|
-
L:
|
|
575
|
+
L: 107,
|
|
544
576
|
S: this,
|
|
545
577
|
C: (f, a) => f(...a)
|
|
546
578
|
});
|
|
@@ -549,12 +581,12 @@ var AutomergeHost = class {
|
|
|
549
581
|
const authorizedDevices = this._authorizedDevices.get(PublicKey.from(spaceKey));
|
|
550
582
|
const deviceKeyHex = this.repo.peerMetadataByPeerId[peerId]?.dxos_deviceKey;
|
|
551
583
|
if (!deviceKeyHex) {
|
|
552
|
-
|
|
584
|
+
log3("device key not found for share policy check", {
|
|
553
585
|
peerId,
|
|
554
586
|
documentId
|
|
555
587
|
}, {
|
|
556
588
|
F: __dxlog_file4,
|
|
557
|
-
L:
|
|
589
|
+
L: 116,
|
|
558
590
|
S: this,
|
|
559
591
|
C: (f, a) => f(...a)
|
|
560
592
|
});
|
|
@@ -562,7 +594,7 @@ var AutomergeHost = class {
|
|
|
562
594
|
}
|
|
563
595
|
const deviceKey = PublicKey.from(deviceKeyHex);
|
|
564
596
|
const isAuthorized = authorizedDevices?.has(deviceKey) ?? false;
|
|
565
|
-
|
|
597
|
+
log3("share policy check", {
|
|
566
598
|
localPeer: this._peerId,
|
|
567
599
|
remotePeer: peerId,
|
|
568
600
|
documentId,
|
|
@@ -571,15 +603,15 @@ var AutomergeHost = class {
|
|
|
571
603
|
isAuthorized
|
|
572
604
|
}, {
|
|
573
605
|
F: __dxlog_file4,
|
|
574
|
-
L:
|
|
606
|
+
L: 122,
|
|
575
607
|
S: this,
|
|
576
608
|
C: (f, a) => f(...a)
|
|
577
609
|
});
|
|
578
610
|
return isAuthorized;
|
|
579
611
|
} catch (err) {
|
|
580
|
-
|
|
612
|
+
log3.catch(err, void 0, {
|
|
581
613
|
F: __dxlog_file4,
|
|
582
|
-
L:
|
|
614
|
+
L: 132,
|
|
583
615
|
S: this,
|
|
584
616
|
C: (f, a) => f(...a)
|
|
585
617
|
});
|
|
@@ -589,66 +621,16 @@ var AutomergeHost = class {
|
|
|
589
621
|
});
|
|
590
622
|
this._clientNetwork.ready();
|
|
591
623
|
this._meshNetwork.ready();
|
|
592
|
-
|
|
593
|
-
const listener = ({ handle }) => this._onDocument(handle);
|
|
594
|
-
this._repo.on("document", listener);
|
|
595
|
-
this._ctx.onDispose(() => {
|
|
596
|
-
this._repo.off("document", listener);
|
|
597
|
-
Object.values(this._repo.handles).forEach((handle) => handle.off("change"));
|
|
598
|
-
});
|
|
599
|
-
}
|
|
624
|
+
await this._clientNetwork.whenConnected();
|
|
600
625
|
}
|
|
601
626
|
async close() {
|
|
602
|
-
this._storage.close?.();
|
|
627
|
+
await this._storage.close?.();
|
|
603
628
|
await this._clientNetwork.close();
|
|
604
629
|
await this._ctx.dispose();
|
|
605
630
|
}
|
|
606
631
|
get repo() {
|
|
607
632
|
return this._repo;
|
|
608
633
|
}
|
|
609
|
-
async _beforeSave(path) {
|
|
610
|
-
const id = path[0];
|
|
611
|
-
if (this._updatingMetadata.has(id)) {
|
|
612
|
-
return this._updatingMetadata.get(id);
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
_onDocument(handle) {
|
|
616
|
-
const listener = (event) => this._onUpdate(event);
|
|
617
|
-
handle.on("change", listener);
|
|
618
|
-
}
|
|
619
|
-
_onUpdate(event) {
|
|
620
|
-
if (this._metadata == null) {
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
623
|
-
const objectIds = getInlineChanges(event);
|
|
624
|
-
if (objectIds.length === 0) {
|
|
625
|
-
return;
|
|
626
|
-
}
|
|
627
|
-
const heads = getHeads(event.doc);
|
|
628
|
-
const lastAvailableHash = heads.join("");
|
|
629
|
-
if (!lastAvailableHash) {
|
|
630
|
-
return;
|
|
631
|
-
}
|
|
632
|
-
const encodedIds = objectIds.map((objectId) => idCodec.encode({
|
|
633
|
-
documentId: event.handle.documentId,
|
|
634
|
-
objectId
|
|
635
|
-
}));
|
|
636
|
-
const idToLastHash = new Map(encodedIds.map((id) => [
|
|
637
|
-
id,
|
|
638
|
-
lastAvailableHash
|
|
639
|
-
]));
|
|
640
|
-
const markingDirtyPromise = this._metadata.markDirty(idToLastHash).then(() => {
|
|
641
|
-
this._updatingMetadata.delete(event.handle.documentId);
|
|
642
|
-
}).catch((err) => {
|
|
643
|
-
this._ctx.disposed && log4.catch(err, void 0, {
|
|
644
|
-
F: __dxlog_file4,
|
|
645
|
-
L: 207,
|
|
646
|
-
S: this,
|
|
647
|
-
C: (f, a) => f(...a)
|
|
648
|
-
});
|
|
649
|
-
});
|
|
650
|
-
this._updatingMetadata.set(event.handle.documentId, markingDirtyPromise);
|
|
651
|
-
}
|
|
652
634
|
_automergeDocs() {
|
|
653
635
|
return mapValues(this._repo.handles, (handle) => ({
|
|
654
636
|
state: handle.state,
|
|
@@ -679,7 +661,19 @@ var AutomergeHost = class {
|
|
|
679
661
|
//
|
|
680
662
|
async flush({ documentIds }) {
|
|
681
663
|
await Promise.all(documentIds?.map((id) => this._repo.find(id).whenReady()) ?? []);
|
|
682
|
-
|
|
664
|
+
try {
|
|
665
|
+
await asyncTimeout(this._repo.flush(documentIds), 500);
|
|
666
|
+
} catch (err) {
|
|
667
|
+
log3.warn("flush error", {
|
|
668
|
+
documentIds,
|
|
669
|
+
err
|
|
670
|
+
}, {
|
|
671
|
+
F: __dxlog_file4,
|
|
672
|
+
L: 196,
|
|
673
|
+
S: this,
|
|
674
|
+
C: (f, a) => f(...a)
|
|
675
|
+
});
|
|
676
|
+
}
|
|
683
677
|
}
|
|
684
678
|
syncRepo(request) {
|
|
685
679
|
return this._clientNetwork.syncRepo(request);
|
|
@@ -697,12 +691,12 @@ var AutomergeHost = class {
|
|
|
697
691
|
return this._meshNetwork.createExtension();
|
|
698
692
|
}
|
|
699
693
|
authorizeDevice(spaceKey, deviceKey) {
|
|
700
|
-
|
|
694
|
+
log3("authorizeDevice", {
|
|
701
695
|
spaceKey,
|
|
702
696
|
deviceKey
|
|
703
697
|
}, {
|
|
704
698
|
F: __dxlog_file4,
|
|
705
|
-
L:
|
|
699
|
+
L: 221,
|
|
706
700
|
S: this,
|
|
707
701
|
C: (f, a) => f(...a)
|
|
708
702
|
});
|
|
@@ -725,24 +719,6 @@ _ts_decorate([
|
|
|
725
719
|
AutomergeHost = _ts_decorate([
|
|
726
720
|
trace.resource()
|
|
727
721
|
], AutomergeHost);
|
|
728
|
-
var getInlineChanges = (event) => {
|
|
729
|
-
const inlineChangedObjectIds = /* @__PURE__ */ new Set();
|
|
730
|
-
for (const { path } of event.patches) {
|
|
731
|
-
if (path.length < 2) {
|
|
732
|
-
continue;
|
|
733
|
-
}
|
|
734
|
-
switch (path[0]) {
|
|
735
|
-
case "objects":
|
|
736
|
-
if (path.length >= 2) {
|
|
737
|
-
inlineChangedObjectIds.add(path[1]);
|
|
738
|
-
}
|
|
739
|
-
break;
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
return [
|
|
743
|
-
...inlineChangedObjectIds
|
|
744
|
-
];
|
|
745
|
-
};
|
|
746
722
|
var getSpaceKeyFromDoc = (doc) => {
|
|
747
723
|
const rawSpaceKey = doc.access?.spaceKey ?? doc.experimental_spaceKey;
|
|
748
724
|
if (rawSpaceKey == null) {
|
|
@@ -756,7 +732,7 @@ import { Event } from "@dxos/async";
|
|
|
756
732
|
import { cancelWithContext } from "@dxos/context";
|
|
757
733
|
import { warnAfterTimeout } from "@dxos/debug";
|
|
758
734
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
759
|
-
import { log as
|
|
735
|
+
import { log as log4 } from "@dxos/log";
|
|
760
736
|
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
|
|
761
737
|
var AutomergeDocumentLoaderImpl = class {
|
|
762
738
|
constructor(_spaceKey, _repo) {
|
|
@@ -777,7 +753,7 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
777
753
|
return;
|
|
778
754
|
}
|
|
779
755
|
if (!spaceState.rootUrl) {
|
|
780
|
-
|
|
756
|
+
log4.error("Database opened with no rootUrl", {
|
|
781
757
|
spaceKey: this._spaceKey
|
|
782
758
|
}, {
|
|
783
759
|
F: __dxlog_file5,
|
|
@@ -830,7 +806,7 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
830
806
|
const documentUrl = (spaceRootDoc.links ?? {})[objectId];
|
|
831
807
|
if (documentUrl == null) {
|
|
832
808
|
this._objectsPendingDocumentLoad.add(objectId);
|
|
833
|
-
|
|
809
|
+
log4.info("loading delayed until object links are initialized", {
|
|
834
810
|
objectId
|
|
835
811
|
}, {
|
|
836
812
|
F: __dxlog_file5,
|
|
@@ -905,7 +881,7 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
905
881
|
};
|
|
906
882
|
const objectDocumentHandle = this._objectDocumentHandles.get(objectId);
|
|
907
883
|
if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {
|
|
908
|
-
|
|
884
|
+
log4.warn("object already inlined in a different document, ignoring the link", {
|
|
909
885
|
...logMeta,
|
|
910
886
|
actualDocumentUrl: objectDocumentHandle.url
|
|
911
887
|
}, {
|
|
@@ -917,7 +893,7 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
917
893
|
continue;
|
|
918
894
|
}
|
|
919
895
|
if (objectDocumentHandle?.url === automergeUrl) {
|
|
920
|
-
|
|
896
|
+
log4.warn("object document was already loaded", logMeta, {
|
|
921
897
|
F: __dxlog_file5,
|
|
922
898
|
L: 149,
|
|
923
899
|
S: this,
|
|
@@ -926,7 +902,7 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
926
902
|
continue;
|
|
927
903
|
}
|
|
928
904
|
const handle = this._repo.find(automergeUrl);
|
|
929
|
-
|
|
905
|
+
log4.debug("document loading triggered", logMeta, {
|
|
930
906
|
F: __dxlog_file5,
|
|
931
907
|
L: 153,
|
|
932
908
|
S: this,
|
|
@@ -946,7 +922,7 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
946
922
|
break;
|
|
947
923
|
} catch (err) {
|
|
948
924
|
if (`${err}`.includes("Timeout")) {
|
|
949
|
-
|
|
925
|
+
log4.info("wraparound", {
|
|
950
926
|
id: docHandle.documentId,
|
|
951
927
|
state: docHandle.state
|
|
952
928
|
}, {
|
|
@@ -991,7 +967,7 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
991
967
|
docUrl: handle.url
|
|
992
968
|
};
|
|
993
969
|
if (this.onObjectDocumentLoaded.listenerCount() === 0) {
|
|
994
|
-
|
|
970
|
+
log4.info("document loaded after all listeners were removed", logMeta, {
|
|
995
971
|
F: __dxlog_file5,
|
|
996
972
|
L: 205,
|
|
997
973
|
S: this,
|
|
@@ -1001,7 +977,7 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1001
977
|
}
|
|
1002
978
|
const objectDocHandle = this._objectDocumentHandles.get(objectId);
|
|
1003
979
|
if (objectDocHandle?.url !== handle.url) {
|
|
1004
|
-
|
|
980
|
+
log4.warn("object was rebound while a document was loading, discarding handle", logMeta, {
|
|
1005
981
|
F: __dxlog_file5,
|
|
1006
982
|
L: 210,
|
|
1007
983
|
S: this,
|
|
@@ -1015,7 +991,7 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1015
991
|
});
|
|
1016
992
|
} catch (err) {
|
|
1017
993
|
const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;
|
|
1018
|
-
|
|
994
|
+
log4.warn("failed to load a document", {
|
|
1019
995
|
objectId,
|
|
1020
996
|
automergeUrl: handle.url,
|
|
1021
997
|
retryLoading: shouldRetryLoading,
|
|
@@ -1034,7 +1010,7 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1034
1010
|
};
|
|
1035
1011
|
|
|
1036
1012
|
// packages/core/echo/echo-pipeline/src/automerge/reference.ts
|
|
1037
|
-
import { Reference } from "@dxos/echo-
|
|
1013
|
+
import { Reference } from "@dxos/echo-schema";
|
|
1038
1014
|
var REFERENCE_TYPE_TAG = "dxos.echo.model.document.Reference";
|
|
1039
1015
|
var encodeReference = (reference) => ({
|
|
1040
1016
|
"@type": REFERENCE_TYPE_TAG,
|
|
@@ -1052,6 +1028,7 @@ export {
|
|
|
1052
1028
|
AutomergeHost,
|
|
1053
1029
|
AutomergeStorageAdapter,
|
|
1054
1030
|
DataServiceImpl,
|
|
1031
|
+
LevelDBStorageAdapter,
|
|
1055
1032
|
LocalHostNetworkAdapter,
|
|
1056
1033
|
MOCK_AUTH_PROVIDER,
|
|
1057
1034
|
MOCK_AUTH_VERIFIER,
|
|
@@ -1070,6 +1047,7 @@ export {
|
|
|
1070
1047
|
createMappedFeedWriter,
|
|
1071
1048
|
decodeReference,
|
|
1072
1049
|
encodeReference,
|
|
1050
|
+
encodingOptions,
|
|
1073
1051
|
getSpaceKeyFromDoc,
|
|
1074
1052
|
hasInvitationExpired,
|
|
1075
1053
|
isEncodedReferenceObject,
|