@dxos/echo-pipeline 0.4.10-main.3e35a2f → 0.4.10-main.3f5e2d2
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/{chunk-SYE4EK33.mjs → chunk-KMWJLYEQ.mjs} +52 -27
- package/dist/lib/browser/{chunk-SYE4EK33.mjs.map → chunk-KMWJLYEQ.mjs.map} +3 -3
- package/dist/lib/browser/index.mjs +192 -171
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +4 -2
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/{chunk-WCTX6RNS.cjs → chunk-YZA42CKA.cjs} +55 -30
- package/dist/lib/node/chunk-YZA42CKA.cjs.map +7 -0
- package/dist/lib/node/index.cjs +221 -198
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +14 -12
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/types/src/automerge/automerge-doc-loader.d.ts.map +1 -1
- package/dist/types/src/automerge/automerge-host.d.ts +7 -14
- 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/space/control-pipeline.d.ts +3 -1
- package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
- package/dist/types/src/space/space-manager.d.ts +3 -1
- package/dist/types/src/space/space-manager.d.ts.map +1 -1
- package/dist/types/src/space/space.d.ts +2 -1
- package/dist/types/src/space/space.d.ts.map +1 -1
- package/dist/types/src/testing/level.d.ts +2 -2
- package/dist/types/src/testing/level.d.ts.map +1 -1
- package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
- package/package.json +30 -30
- package/src/automerge/automerge-doc-loader.ts +3 -0
- package/src/automerge/automerge-host.test.ts +26 -17
- package/src/automerge/automerge-host.ts +59 -98
- package/src/automerge/automerge-repo.test.ts +61 -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/space/control-pipeline.ts +11 -1
- package/src/space/space-manager.ts +4 -0
- package/src/space/space.ts +11 -1
- package/src/testing/level.ts +3 -2
- package/src/testing/test-agent-builder.ts +1 -0
- package/dist/lib/node/chunk-WCTX6RNS.cjs.map +0 -7
|
@@ -22,44 +22,58 @@ import {
|
|
|
22
22
|
mapTimeframeToFeedIndexes,
|
|
23
23
|
startAfter,
|
|
24
24
|
valueEncoding
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-KMWJLYEQ.mjs";
|
|
26
26
|
|
|
27
27
|
// packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
|
|
28
|
-
import {
|
|
28
|
+
import { Event } from "@dxos/async";
|
|
29
|
+
import { next as automerge, getBackend } from "@dxos/automerge/automerge";
|
|
29
30
|
import { Repo } from "@dxos/automerge/automerge-repo";
|
|
30
31
|
import { Context } from "@dxos/context";
|
|
32
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
31
33
|
import { PublicKey } from "@dxos/keys";
|
|
32
|
-
import { log as
|
|
33
|
-
import { idCodec } from "@dxos/protocols";
|
|
34
|
+
import { log as log3 } from "@dxos/log";
|
|
34
35
|
import { trace } from "@dxos/tracing";
|
|
35
36
|
import { ComplexMap, ComplexSet, defaultMap, mapValues } from "@dxos/util";
|
|
36
37
|
|
|
37
38
|
// packages/core/echo/echo-pipeline/src/automerge/leveldb-storage-adapter.ts
|
|
38
|
-
|
|
39
|
+
import { LifecycleState, Resource } from "@dxos/context";
|
|
40
|
+
var LevelDBStorageAdapter = class extends Resource {
|
|
39
41
|
constructor(_params) {
|
|
42
|
+
super();
|
|
40
43
|
this._params = _params;
|
|
41
|
-
this._state = "opened";
|
|
42
44
|
}
|
|
43
45
|
async load(keyArray) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
try {
|
|
47
|
+
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
48
|
+
return void 0;
|
|
49
|
+
}
|
|
50
|
+
return await this._params.db.get(keyArray, {
|
|
51
|
+
...encodingOptions
|
|
52
|
+
});
|
|
53
|
+
} catch (err) {
|
|
54
|
+
if (isLevelDbNotFoundError(err)) {
|
|
55
|
+
return void 0;
|
|
56
|
+
}
|
|
57
|
+
throw err;
|
|
46
58
|
}
|
|
47
|
-
return this._params.db.get(keyArray, {
|
|
48
|
-
...encodingOptions
|
|
49
|
-
}).catch((err) => err.code === "LEVEL_NOT_FOUND" ? void 0 : Promise.reject(err));
|
|
50
59
|
}
|
|
51
60
|
async save(keyArray, binary) {
|
|
52
|
-
if (this.
|
|
61
|
+
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
53
62
|
return void 0;
|
|
54
63
|
}
|
|
55
|
-
|
|
56
|
-
await this._params.
|
|
64
|
+
const batch = this._params.db.batch();
|
|
65
|
+
await this._params.callbacks?.beforeSave?.({
|
|
66
|
+
path: keyArray,
|
|
67
|
+
batch
|
|
68
|
+
});
|
|
69
|
+
batch.put(keyArray, Buffer.from(binary), {
|
|
57
70
|
...encodingOptions
|
|
58
71
|
});
|
|
72
|
+
await batch.write();
|
|
59
73
|
await this._params.callbacks?.afterSave?.(keyArray);
|
|
60
74
|
}
|
|
61
75
|
async remove(keyArray) {
|
|
62
|
-
if (this.
|
|
76
|
+
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
63
77
|
return void 0;
|
|
64
78
|
}
|
|
65
79
|
await this._params.db.del(keyArray, {
|
|
@@ -67,7 +81,7 @@ var LevelDBStorageAdapter = class {
|
|
|
67
81
|
});
|
|
68
82
|
}
|
|
69
83
|
async loadRange(keyPrefix) {
|
|
70
|
-
if (this.
|
|
84
|
+
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
71
85
|
return [];
|
|
72
86
|
}
|
|
73
87
|
const result = [];
|
|
@@ -87,7 +101,7 @@ var LevelDBStorageAdapter = class {
|
|
|
87
101
|
return result;
|
|
88
102
|
}
|
|
89
103
|
async removeRange(keyPrefix) {
|
|
90
|
-
if (this.
|
|
104
|
+
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
91
105
|
return void 0;
|
|
92
106
|
}
|
|
93
107
|
const batch = this._params.db.batch();
|
|
@@ -105,9 +119,6 @@ var LevelDBStorageAdapter = class {
|
|
|
105
119
|
}
|
|
106
120
|
await batch.write();
|
|
107
121
|
}
|
|
108
|
-
close() {
|
|
109
|
-
this._state = "closed";
|
|
110
|
-
}
|
|
111
122
|
};
|
|
112
123
|
var keyEncoder = {
|
|
113
124
|
encode: (key) => Buffer.from(key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-")),
|
|
@@ -117,19 +128,20 @@ var encodingOptions = {
|
|
|
117
128
|
keyEncoding: keyEncoder,
|
|
118
129
|
valueEncoding: "buffer"
|
|
119
130
|
};
|
|
131
|
+
var isLevelDbNotFoundError = (err) => err.code === "LEVEL_NOT_FOUND";
|
|
120
132
|
|
|
121
133
|
// packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts
|
|
122
134
|
import { Trigger } from "@dxos/async";
|
|
123
135
|
import { NetworkAdapter, cbor } from "@dxos/automerge/automerge-repo";
|
|
124
136
|
import { Stream } from "@dxos/codec-protobuf";
|
|
125
137
|
import { invariant } from "@dxos/invariant";
|
|
126
|
-
import { log } from "@dxos/log";
|
|
127
138
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts";
|
|
128
139
|
var LocalHostNetworkAdapter = class extends NetworkAdapter {
|
|
129
140
|
constructor() {
|
|
130
141
|
super(...arguments);
|
|
131
142
|
this._peers = /* @__PURE__ */ new Map();
|
|
132
143
|
this._connected = new Trigger();
|
|
144
|
+
this._isConnected = false;
|
|
133
145
|
}
|
|
134
146
|
/**
|
|
135
147
|
* Emits `ready` event. That signals to `Repo` that it can start using the adapter.
|
|
@@ -139,15 +151,21 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
|
|
|
139
151
|
network: this
|
|
140
152
|
});
|
|
141
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Called by `Repo` to connect to the network.
|
|
156
|
+
*
|
|
157
|
+
* @param peerId Our peer Id.
|
|
158
|
+
*/
|
|
142
159
|
connect(peerId) {
|
|
143
160
|
this.peerId = peerId;
|
|
161
|
+
this._isConnected = true;
|
|
144
162
|
this._connected.wake();
|
|
145
163
|
}
|
|
146
164
|
send(message) {
|
|
147
165
|
const peer = this._peers.get(message.targetId);
|
|
148
166
|
invariant(peer, "Peer not found.", {
|
|
149
167
|
F: __dxlog_file,
|
|
150
|
-
L:
|
|
168
|
+
L: 51,
|
|
151
169
|
S: this,
|
|
152
170
|
A: [
|
|
153
171
|
"peer",
|
|
@@ -162,12 +180,17 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
|
|
|
162
180
|
}
|
|
163
181
|
disconnect() {
|
|
164
182
|
}
|
|
183
|
+
async whenConnected() {
|
|
184
|
+
await this._connected.wait({
|
|
185
|
+
timeout: 1e4
|
|
186
|
+
});
|
|
187
|
+
}
|
|
165
188
|
syncRepo({ id, syncMessage }) {
|
|
166
189
|
const peerId = this._getPeerId(id);
|
|
167
190
|
return new Stream(({ next, close }) => {
|
|
168
191
|
invariant(!this._peers.has(peerId), "Peer already connected.", {
|
|
169
192
|
F: __dxlog_file,
|
|
170
|
-
L:
|
|
193
|
+
L: 73,
|
|
171
194
|
S: this,
|
|
172
195
|
A: [
|
|
173
196
|
"!this._peers.has(peerId)",
|
|
@@ -189,35 +212,47 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
|
|
|
189
212
|
});
|
|
190
213
|
}
|
|
191
214
|
});
|
|
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, {
|
|
215
|
+
invariant(this._isConnected, void 0, {
|
|
200
216
|
F: __dxlog_file,
|
|
201
|
-
L:
|
|
217
|
+
L: 90,
|
|
202
218
|
S: this,
|
|
203
|
-
|
|
204
|
-
|
|
219
|
+
A: [
|
|
220
|
+
"this._isConnected",
|
|
221
|
+
""
|
|
222
|
+
]
|
|
223
|
+
});
|
|
224
|
+
this.emit("peer-candidate", {
|
|
225
|
+
peerMetadata: {},
|
|
226
|
+
peerId
|
|
227
|
+
});
|
|
205
228
|
});
|
|
206
229
|
}
|
|
207
230
|
async sendSyncMessage({ id, syncMessage }) {
|
|
208
|
-
|
|
209
|
-
|
|
231
|
+
invariant(this._isConnected, void 0, {
|
|
232
|
+
F: __dxlog_file,
|
|
233
|
+
L: 99,
|
|
234
|
+
S: this,
|
|
235
|
+
A: [
|
|
236
|
+
"this._isConnected",
|
|
237
|
+
""
|
|
238
|
+
]
|
|
210
239
|
});
|
|
211
240
|
const message = cbor.decode(syncMessage);
|
|
212
241
|
this.emit("message", message);
|
|
213
242
|
}
|
|
214
243
|
async getHostInfo() {
|
|
215
|
-
|
|
216
|
-
|
|
244
|
+
invariant(this._isConnected, void 0, {
|
|
245
|
+
F: __dxlog_file,
|
|
246
|
+
L: 105,
|
|
247
|
+
S: this,
|
|
248
|
+
A: [
|
|
249
|
+
"this._isConnected",
|
|
250
|
+
""
|
|
251
|
+
]
|
|
217
252
|
});
|
|
218
253
|
invariant(this.peerId, "Peer id not set.", {
|
|
219
254
|
F: __dxlog_file,
|
|
220
|
-
L:
|
|
255
|
+
L: 106,
|
|
221
256
|
S: this,
|
|
222
257
|
A: [
|
|
223
258
|
"this.peerId",
|
|
@@ -237,7 +272,7 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter {
|
|
|
237
272
|
import { Trigger as Trigger2 } from "@dxos/async";
|
|
238
273
|
import { NetworkAdapter as NetworkAdapter2, cbor as cbor2 } from "@dxos/automerge/automerge-repo";
|
|
239
274
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
240
|
-
import { log
|
|
275
|
+
import { log } from "@dxos/log";
|
|
241
276
|
import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
|
|
242
277
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts";
|
|
243
278
|
var MeshNetworkAdapter = class extends NetworkAdapter2 {
|
|
@@ -272,7 +307,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter2 {
|
|
|
272
307
|
});
|
|
273
308
|
extension.sendSyncMessage({
|
|
274
309
|
payload: cbor2.encode(message)
|
|
275
|
-
}).catch((err) =>
|
|
310
|
+
}).catch((err) => log.catch(err, void 0, {
|
|
276
311
|
F: __dxlog_file2,
|
|
277
312
|
L: 39,
|
|
278
313
|
S: this,
|
|
@@ -297,7 +332,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter2 {
|
|
|
297
332
|
}, {
|
|
298
333
|
onStartReplication: async (info, remotePeerId) => {
|
|
299
334
|
await this._connected.wait();
|
|
300
|
-
|
|
335
|
+
log("onStartReplication", {
|
|
301
336
|
id: info.id,
|
|
302
337
|
thisPeerId: this.peerId,
|
|
303
338
|
remotePeerId: remotePeerId.toHex()
|
|
@@ -310,7 +345,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter2 {
|
|
|
310
345
|
if (!this._extensions.has(info.id)) {
|
|
311
346
|
peerInfo = info;
|
|
312
347
|
this._extensions.set(info.id, extension);
|
|
313
|
-
|
|
348
|
+
log("peer-candidate", {
|
|
314
349
|
id: info.id,
|
|
315
350
|
thisPeerId: this.peerId,
|
|
316
351
|
remotePeerId: remotePeerId.toHex()
|
|
@@ -352,7 +387,7 @@ var MeshNetworkAdapter = class extends NetworkAdapter2 {
|
|
|
352
387
|
|
|
353
388
|
// packages/core/echo/echo-pipeline/src/automerge/migrations.ts
|
|
354
389
|
import { IndexedDBStorageAdapter } from "@dxos/automerge/automerge-repo-storage-indexeddb";
|
|
355
|
-
import { log as
|
|
390
|
+
import { log as log2 } from "@dxos/log";
|
|
356
391
|
import { StorageType } from "@dxos/random-access-storage";
|
|
357
392
|
|
|
358
393
|
// packages/core/echo/echo-pipeline/src/automerge/automerge-storage-adapter.ts
|
|
@@ -446,7 +481,7 @@ var levelMigration = async ({ db, directory }) => {
|
|
|
446
481
|
return;
|
|
447
482
|
}
|
|
448
483
|
const batch = db.batch();
|
|
449
|
-
|
|
484
|
+
log2.info("found chunks on old storage adapter", {
|
|
450
485
|
chunks: chunks.length
|
|
451
486
|
}, {
|
|
452
487
|
F: __dxlog_file3,
|
|
@@ -475,29 +510,27 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
475
510
|
}
|
|
476
511
|
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
|
|
477
512
|
var AutomergeHost = class {
|
|
478
|
-
constructor({ directory, db,
|
|
513
|
+
constructor({ directory, db, storageCallbacks }) {
|
|
479
514
|
this._ctx = new Context();
|
|
480
515
|
/**
|
|
481
516
|
* spaceKey -> deviceKey[]
|
|
482
517
|
*/
|
|
483
518
|
this._authorizedDevices = new ComplexMap(PublicKey.hash);
|
|
484
|
-
this._updatingMetadata = /* @__PURE__ */ new Map();
|
|
485
519
|
this._requestedDocs = /* @__PURE__ */ new Set();
|
|
486
520
|
this._directory = directory;
|
|
487
521
|
this._db = db;
|
|
488
|
-
this.
|
|
522
|
+
this._storageCallbacks = storageCallbacks;
|
|
489
523
|
}
|
|
490
524
|
async open() {
|
|
491
525
|
this._directory && await levelMigration({
|
|
492
|
-
db:
|
|
526
|
+
db: this._db,
|
|
493
527
|
directory: this._directory
|
|
494
528
|
});
|
|
495
529
|
this._storage = new LevelDBStorageAdapter({
|
|
496
|
-
db:
|
|
497
|
-
callbacks:
|
|
498
|
-
beforeSave: (params) => this._beforeSave(params)
|
|
499
|
-
}
|
|
530
|
+
db: this._db,
|
|
531
|
+
callbacks: this._storageCallbacks
|
|
500
532
|
});
|
|
533
|
+
await this._storage.open?.();
|
|
501
534
|
this._peerId = `host-${PublicKey.random().toHex()}`;
|
|
502
535
|
this._meshNetwork = new MeshNetworkAdapter();
|
|
503
536
|
this._clientNetwork = new LocalHostNetworkAdapter();
|
|
@@ -520,13 +553,13 @@ var AutomergeHost = class {
|
|
|
520
553
|
const doc = this._repo.handles[documentId]?.docSync();
|
|
521
554
|
if (!doc) {
|
|
522
555
|
const isRequested = this._requestedDocs.has(`automerge:${documentId}`);
|
|
523
|
-
|
|
556
|
+
log3("doc share policy check", {
|
|
524
557
|
peerId,
|
|
525
558
|
documentId,
|
|
526
559
|
isRequested
|
|
527
560
|
}, {
|
|
528
561
|
F: __dxlog_file4,
|
|
529
|
-
L:
|
|
562
|
+
L: 108,
|
|
530
563
|
S: this,
|
|
531
564
|
C: (f, a) => f(...a)
|
|
532
565
|
});
|
|
@@ -535,12 +568,12 @@ var AutomergeHost = class {
|
|
|
535
568
|
try {
|
|
536
569
|
const spaceKey = getSpaceKeyFromDoc(doc);
|
|
537
570
|
if (!spaceKey) {
|
|
538
|
-
|
|
571
|
+
log3("space key not found for share policy check", {
|
|
539
572
|
peerId,
|
|
540
573
|
documentId
|
|
541
574
|
}, {
|
|
542
575
|
F: __dxlog_file4,
|
|
543
|
-
L:
|
|
576
|
+
L: 115,
|
|
544
577
|
S: this,
|
|
545
578
|
C: (f, a) => f(...a)
|
|
546
579
|
});
|
|
@@ -549,12 +582,12 @@ var AutomergeHost = class {
|
|
|
549
582
|
const authorizedDevices = this._authorizedDevices.get(PublicKey.from(spaceKey));
|
|
550
583
|
const deviceKeyHex = this.repo.peerMetadataByPeerId[peerId]?.dxos_deviceKey;
|
|
551
584
|
if (!deviceKeyHex) {
|
|
552
|
-
|
|
585
|
+
log3("device key not found for share policy check", {
|
|
553
586
|
peerId,
|
|
554
587
|
documentId
|
|
555
588
|
}, {
|
|
556
589
|
F: __dxlog_file4,
|
|
557
|
-
L:
|
|
590
|
+
L: 124,
|
|
558
591
|
S: this,
|
|
559
592
|
C: (f, a) => f(...a)
|
|
560
593
|
});
|
|
@@ -562,7 +595,7 @@ var AutomergeHost = class {
|
|
|
562
595
|
}
|
|
563
596
|
const deviceKey = PublicKey.from(deviceKeyHex);
|
|
564
597
|
const isAuthorized = authorizedDevices?.has(deviceKey) ?? false;
|
|
565
|
-
|
|
598
|
+
log3("share policy check", {
|
|
566
599
|
localPeer: this._peerId,
|
|
567
600
|
remotePeer: peerId,
|
|
568
601
|
documentId,
|
|
@@ -571,15 +604,15 @@ var AutomergeHost = class {
|
|
|
571
604
|
isAuthorized
|
|
572
605
|
}, {
|
|
573
606
|
F: __dxlog_file4,
|
|
574
|
-
L:
|
|
607
|
+
L: 130,
|
|
575
608
|
S: this,
|
|
576
609
|
C: (f, a) => f(...a)
|
|
577
610
|
});
|
|
578
611
|
return isAuthorized;
|
|
579
612
|
} catch (err) {
|
|
580
|
-
|
|
613
|
+
log3.catch(err, void 0, {
|
|
581
614
|
F: __dxlog_file4,
|
|
582
|
-
L:
|
|
615
|
+
L: 140,
|
|
583
616
|
S: this,
|
|
584
617
|
C: (f, a) => f(...a)
|
|
585
618
|
});
|
|
@@ -589,66 +622,16 @@ var AutomergeHost = class {
|
|
|
589
622
|
});
|
|
590
623
|
this._clientNetwork.ready();
|
|
591
624
|
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
|
-
}
|
|
625
|
+
await this._clientNetwork.whenConnected();
|
|
600
626
|
}
|
|
601
627
|
async close() {
|
|
602
|
-
this._storage.close?.();
|
|
628
|
+
await this._storage.close?.();
|
|
603
629
|
await this._clientNetwork.close();
|
|
604
630
|
await this._ctx.dispose();
|
|
605
631
|
}
|
|
606
632
|
get repo() {
|
|
607
633
|
return this._repo;
|
|
608
634
|
}
|
|
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
635
|
_automergeDocs() {
|
|
653
636
|
return mapValues(this._repo.handles, (handle) => ({
|
|
654
637
|
state: handle.state,
|
|
@@ -677,9 +660,21 @@ var AutomergeHost = class {
|
|
|
677
660
|
//
|
|
678
661
|
// Methods for client-services.
|
|
679
662
|
//
|
|
680
|
-
async flush({
|
|
681
|
-
await Promise.all(
|
|
682
|
-
|
|
663
|
+
async flush({ states }) {
|
|
664
|
+
await Promise.all(states?.map(async ({ heads, documentId }) => {
|
|
665
|
+
invariant3(heads, "heads are required for flush", {
|
|
666
|
+
F: __dxlog_file4,
|
|
667
|
+
L: 200,
|
|
668
|
+
S: this,
|
|
669
|
+
A: [
|
|
670
|
+
"heads",
|
|
671
|
+
"'heads are required for flush'"
|
|
672
|
+
]
|
|
673
|
+
});
|
|
674
|
+
const handle = this.repo.handles[documentId] ?? this._repo.find(documentId);
|
|
675
|
+
await waitForHeads(handle, heads);
|
|
676
|
+
}) ?? []);
|
|
677
|
+
await this._repo.flush(states?.map(({ documentId }) => documentId));
|
|
683
678
|
}
|
|
684
679
|
syncRepo(request) {
|
|
685
680
|
return this._clientNetwork.syncRepo(request);
|
|
@@ -697,12 +692,12 @@ var AutomergeHost = class {
|
|
|
697
692
|
return this._meshNetwork.createExtension();
|
|
698
693
|
}
|
|
699
694
|
authorizeDevice(spaceKey, deviceKey) {
|
|
700
|
-
|
|
695
|
+
log3("authorizeDevice", {
|
|
701
696
|
spaceKey,
|
|
702
697
|
deviceKey
|
|
703
698
|
}, {
|
|
704
699
|
F: __dxlog_file4,
|
|
705
|
-
L:
|
|
700
|
+
L: 230,
|
|
706
701
|
S: this,
|
|
707
702
|
C: (f, a) => f(...a)
|
|
708
703
|
});
|
|
@@ -722,27 +717,14 @@ _ts_decorate([
|
|
|
722
717
|
depth: null
|
|
723
718
|
})
|
|
724
719
|
], AutomergeHost.prototype, "_automergePeers", null);
|
|
720
|
+
_ts_decorate([
|
|
721
|
+
trace.span({
|
|
722
|
+
showInBrowserTimeline: true
|
|
723
|
+
})
|
|
724
|
+
], AutomergeHost.prototype, "flush", null);
|
|
725
725
|
AutomergeHost = _ts_decorate([
|
|
726
726
|
trace.resource()
|
|
727
727
|
], 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
728
|
var getSpaceKeyFromDoc = (doc) => {
|
|
747
729
|
const rawSpaceKey = doc.access?.spaceKey ?? doc.experimental_spaceKey;
|
|
748
730
|
if (rawSpaceKey == null) {
|
|
@@ -750,13 +732,42 @@ var getSpaceKeyFromDoc = (doc) => {
|
|
|
750
732
|
}
|
|
751
733
|
return String(rawSpaceKey);
|
|
752
734
|
};
|
|
735
|
+
var waitForHeads = async (handle, heads) => {
|
|
736
|
+
await handle.whenReady();
|
|
737
|
+
const unavailableHeads = new Set(heads);
|
|
738
|
+
await Event.wrap(handle, "change").waitForCondition(() => {
|
|
739
|
+
for (const changeHash of unavailableHeads.values()) {
|
|
740
|
+
if (changeIsPresentInDoc(handle.docSync(), changeHash)) {
|
|
741
|
+
unavailableHeads.delete(changeHash);
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
if (unavailableHeads.size === 0) {
|
|
745
|
+
return true;
|
|
746
|
+
}
|
|
747
|
+
return false;
|
|
748
|
+
});
|
|
749
|
+
};
|
|
750
|
+
var changeIsPresentInDoc = (doc, changeHash) => {
|
|
751
|
+
return !!getBackend(doc).getChangeByHash(changeHash);
|
|
752
|
+
};
|
|
753
753
|
|
|
754
754
|
// packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts
|
|
755
|
-
import { Event } from "@dxos/async";
|
|
755
|
+
import { Event as Event2 } from "@dxos/async";
|
|
756
756
|
import { cancelWithContext } from "@dxos/context";
|
|
757
757
|
import { warnAfterTimeout } from "@dxos/debug";
|
|
758
|
-
import { invariant as
|
|
759
|
-
import { log as
|
|
758
|
+
import { invariant as invariant4 } from "@dxos/invariant";
|
|
759
|
+
import { log as log4 } from "@dxos/log";
|
|
760
|
+
import { trace as trace2 } from "@dxos/tracing";
|
|
761
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
762
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
763
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
764
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
765
|
+
else
|
|
766
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
767
|
+
if (d = decorators[i])
|
|
768
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
769
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
770
|
+
}
|
|
760
771
|
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
|
|
761
772
|
var AutomergeDocumentLoaderImpl = class {
|
|
762
773
|
constructor(_spaceKey, _repo) {
|
|
@@ -765,7 +776,7 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
765
776
|
this._spaceRootDocHandle = null;
|
|
766
777
|
this._objectDocumentHandles = /* @__PURE__ */ new Map();
|
|
767
778
|
this._objectsPendingDocumentLoad = /* @__PURE__ */ new Set();
|
|
768
|
-
this.onObjectDocumentLoaded = new
|
|
779
|
+
this.onObjectDocumentLoaded = new Event2();
|
|
769
780
|
}
|
|
770
781
|
getAllHandles() {
|
|
771
782
|
return [
|
|
@@ -777,11 +788,11 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
777
788
|
return;
|
|
778
789
|
}
|
|
779
790
|
if (!spaceState.rootUrl) {
|
|
780
|
-
|
|
791
|
+
log4.error("Database opened with no rootUrl", {
|
|
781
792
|
spaceKey: this._spaceKey
|
|
782
793
|
}, {
|
|
783
794
|
F: __dxlog_file5,
|
|
784
|
-
L:
|
|
795
|
+
L: 69,
|
|
785
796
|
S: this,
|
|
786
797
|
C: (f, a) => f(...a)
|
|
787
798
|
});
|
|
@@ -789,9 +800,9 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
789
800
|
} else {
|
|
790
801
|
const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);
|
|
791
802
|
const doc = existingDocHandle.docSync();
|
|
792
|
-
|
|
803
|
+
invariant4(doc, void 0, {
|
|
793
804
|
F: __dxlog_file5,
|
|
794
|
-
L:
|
|
805
|
+
L: 74,
|
|
795
806
|
S: this,
|
|
796
807
|
A: [
|
|
797
808
|
"doc",
|
|
@@ -805,9 +816,9 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
805
816
|
}
|
|
806
817
|
}
|
|
807
818
|
loadObjectDocument(objectId) {
|
|
808
|
-
|
|
819
|
+
invariant4(this._spaceRootDocHandle, void 0, {
|
|
809
820
|
F: __dxlog_file5,
|
|
810
|
-
L:
|
|
821
|
+
L: 83,
|
|
811
822
|
S: this,
|
|
812
823
|
A: [
|
|
813
824
|
"this._spaceRootDocHandle",
|
|
@@ -818,9 +829,9 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
818
829
|
return;
|
|
819
830
|
}
|
|
820
831
|
const spaceRootDoc = this._spaceRootDocHandle.docSync();
|
|
821
|
-
|
|
832
|
+
invariant4(spaceRootDoc, void 0, {
|
|
822
833
|
F: __dxlog_file5,
|
|
823
|
-
L:
|
|
834
|
+
L: 88,
|
|
824
835
|
S: this,
|
|
825
836
|
A: [
|
|
826
837
|
"spaceRootDoc",
|
|
@@ -830,11 +841,11 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
830
841
|
const documentUrl = (spaceRootDoc.links ?? {})[objectId];
|
|
831
842
|
if (documentUrl == null) {
|
|
832
843
|
this._objectsPendingDocumentLoad.add(objectId);
|
|
833
|
-
|
|
844
|
+
log4.info("loading delayed until object links are initialized", {
|
|
834
845
|
objectId
|
|
835
846
|
}, {
|
|
836
847
|
F: __dxlog_file5,
|
|
837
|
-
L:
|
|
848
|
+
L: 92,
|
|
838
849
|
S: this,
|
|
839
850
|
C: (f, a) => f(...a)
|
|
840
851
|
});
|
|
@@ -853,9 +864,9 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
853
864
|
linksAwaitingLoad.forEach(([objectId]) => this._objectsPendingDocumentLoad.delete(objectId));
|
|
854
865
|
}
|
|
855
866
|
getSpaceRootDocHandle() {
|
|
856
|
-
|
|
867
|
+
invariant4(this._spaceRootDocHandle, void 0, {
|
|
857
868
|
F: __dxlog_file5,
|
|
858
|
-
L:
|
|
869
|
+
L: 110,
|
|
859
870
|
S: this,
|
|
860
871
|
A: [
|
|
861
872
|
"this._spaceRootDocHandle",
|
|
@@ -865,9 +876,9 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
865
876
|
return this._spaceRootDocHandle;
|
|
866
877
|
}
|
|
867
878
|
createDocumentForObject(objectId) {
|
|
868
|
-
|
|
879
|
+
invariant4(this._spaceRootDocHandle, void 0, {
|
|
869
880
|
F: __dxlog_file5,
|
|
870
|
-
L:
|
|
881
|
+
L: 115,
|
|
871
882
|
S: this,
|
|
872
883
|
A: [
|
|
873
884
|
"this._spaceRootDocHandle",
|
|
@@ -905,30 +916,30 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
905
916
|
};
|
|
906
917
|
const objectDocumentHandle = this._objectDocumentHandles.get(objectId);
|
|
907
918
|
if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {
|
|
908
|
-
|
|
919
|
+
log4.warn("object already inlined in a different document, ignoring the link", {
|
|
909
920
|
...logMeta,
|
|
910
921
|
actualDocumentUrl: objectDocumentHandle.url
|
|
911
922
|
}, {
|
|
912
923
|
F: __dxlog_file5,
|
|
913
|
-
L:
|
|
924
|
+
L: 145,
|
|
914
925
|
S: this,
|
|
915
926
|
C: (f, a) => f(...a)
|
|
916
927
|
});
|
|
917
928
|
continue;
|
|
918
929
|
}
|
|
919
930
|
if (objectDocumentHandle?.url === automergeUrl) {
|
|
920
|
-
|
|
931
|
+
log4.warn("object document was already loaded", logMeta, {
|
|
921
932
|
F: __dxlog_file5,
|
|
922
|
-
L:
|
|
933
|
+
L: 152,
|
|
923
934
|
S: this,
|
|
924
935
|
C: (f, a) => f(...a)
|
|
925
936
|
});
|
|
926
937
|
continue;
|
|
927
938
|
}
|
|
928
939
|
const handle = this._repo.find(automergeUrl);
|
|
929
|
-
|
|
940
|
+
log4.debug("document loading triggered", logMeta, {
|
|
930
941
|
F: __dxlog_file5,
|
|
931
|
-
L:
|
|
942
|
+
L: 156,
|
|
932
943
|
S: this,
|
|
933
944
|
C: (f, a) => f(...a)
|
|
934
945
|
});
|
|
@@ -946,12 +957,12 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
946
957
|
break;
|
|
947
958
|
} catch (err) {
|
|
948
959
|
if (`${err}`.includes("Timeout")) {
|
|
949
|
-
|
|
960
|
+
log4.info("wraparound", {
|
|
950
961
|
id: docHandle.documentId,
|
|
951
962
|
state: docHandle.state
|
|
952
963
|
}, {
|
|
953
964
|
F: __dxlog_file5,
|
|
954
|
-
L:
|
|
965
|
+
L: 172,
|
|
955
966
|
S: this,
|
|
956
967
|
C: (f, a) => f(...a)
|
|
957
968
|
});
|
|
@@ -991,9 +1002,9 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
991
1002
|
docUrl: handle.url
|
|
992
1003
|
};
|
|
993
1004
|
if (this.onObjectDocumentLoaded.listenerCount() === 0) {
|
|
994
|
-
|
|
1005
|
+
log4.info("document loaded after all listeners were removed", logMeta, {
|
|
995
1006
|
F: __dxlog_file5,
|
|
996
|
-
L:
|
|
1007
|
+
L: 208,
|
|
997
1008
|
S: this,
|
|
998
1009
|
C: (f, a) => f(...a)
|
|
999
1010
|
});
|
|
@@ -1001,9 +1012,9 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1001
1012
|
}
|
|
1002
1013
|
const objectDocHandle = this._objectDocumentHandles.get(objectId);
|
|
1003
1014
|
if (objectDocHandle?.url !== handle.url) {
|
|
1004
|
-
|
|
1015
|
+
log4.warn("object was rebound while a document was loading, discarding handle", logMeta, {
|
|
1005
1016
|
F: __dxlog_file5,
|
|
1006
|
-
L:
|
|
1017
|
+
L: 213,
|
|
1007
1018
|
S: this,
|
|
1008
1019
|
C: (f, a) => f(...a)
|
|
1009
1020
|
});
|
|
@@ -1015,14 +1026,14 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1015
1026
|
});
|
|
1016
1027
|
} catch (err) {
|
|
1017
1028
|
const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;
|
|
1018
|
-
|
|
1029
|
+
log4.warn("failed to load a document", {
|
|
1019
1030
|
objectId,
|
|
1020
1031
|
automergeUrl: handle.url,
|
|
1021
1032
|
retryLoading: shouldRetryLoading,
|
|
1022
1033
|
err
|
|
1023
1034
|
}, {
|
|
1024
1035
|
F: __dxlog_file5,
|
|
1025
|
-
L:
|
|
1036
|
+
L: 219,
|
|
1026
1037
|
S: this,
|
|
1027
1038
|
C: (f, a) => f(...a)
|
|
1028
1039
|
});
|
|
@@ -1032,9 +1043,17 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1032
1043
|
}
|
|
1033
1044
|
}
|
|
1034
1045
|
};
|
|
1046
|
+
_ts_decorate2([
|
|
1047
|
+
trace2.span({
|
|
1048
|
+
showInBrowserTimeline: true
|
|
1049
|
+
})
|
|
1050
|
+
], AutomergeDocumentLoaderImpl.prototype, "loadSpaceRootDocHandle", null);
|
|
1051
|
+
AutomergeDocumentLoaderImpl = _ts_decorate2([
|
|
1052
|
+
trace2.resource()
|
|
1053
|
+
], AutomergeDocumentLoaderImpl);
|
|
1035
1054
|
|
|
1036
1055
|
// packages/core/echo/echo-pipeline/src/automerge/reference.ts
|
|
1037
|
-
import { Reference } from "@dxos/echo-
|
|
1056
|
+
import { Reference } from "@dxos/echo-schema";
|
|
1038
1057
|
var REFERENCE_TYPE_TAG = "dxos.echo.model.document.Reference";
|
|
1039
1058
|
var encodeReference = (reference) => ({
|
|
1040
1059
|
"@type": REFERENCE_TYPE_TAG,
|
|
@@ -1052,6 +1071,7 @@ export {
|
|
|
1052
1071
|
AutomergeHost,
|
|
1053
1072
|
AutomergeStorageAdapter,
|
|
1054
1073
|
DataServiceImpl,
|
|
1074
|
+
LevelDBStorageAdapter,
|
|
1055
1075
|
LocalHostNetworkAdapter,
|
|
1056
1076
|
MOCK_AUTH_PROVIDER,
|
|
1057
1077
|
MOCK_AUTH_VERIFIER,
|
|
@@ -1070,6 +1090,7 @@ export {
|
|
|
1070
1090
|
createMappedFeedWriter,
|
|
1071
1091
|
decodeReference,
|
|
1072
1092
|
encodeReference,
|
|
1093
|
+
encodingOptions,
|
|
1073
1094
|
getSpaceKeyFromDoc,
|
|
1074
1095
|
hasInvitationExpired,
|
|
1075
1096
|
isEncodedReferenceObject,
|