@dxos/echo-pipeline 0.6.12 → 0.6.13-main.548ca8d
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-PESZVYAN.mjs +2050 -0
- package/dist/lib/browser/chunk-PESZVYAN.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +3463 -17
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +3 -4
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/{chunk-7HHYCGUR.cjs → chunk-6EZVIJNE.cjs} +89 -47
- package/dist/lib/node/chunk-6EZVIJNE.cjs.map +7 -0
- package/dist/lib/node/index.cjs +3440 -35
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +11 -12
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/lib/{browser/chunk-UKXIJW43.mjs → node-esm/chunk-4LW7MDPZ.mjs} +76 -36
- package/dist/lib/node-esm/chunk-4LW7MDPZ.mjs.map +7 -0
- package/dist/lib/{browser/chunk-MPWFDDQK.mjs → node-esm/index.mjs} +1702 -335
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/testing/index.mjs +551 -0
- package/dist/lib/node-esm/testing/index.mjs.map +7 -0
- package/dist/types/src/automerge/automerge-host.d.ts +24 -1
- package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
- package/dist/types/src/automerge/collection-synchronizer.d.ts +2 -0
- package/dist/types/src/automerge/collection-synchronizer.d.ts.map +1 -1
- package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
- package/dist/types/src/automerge/echo-replicator.d.ts +3 -3
- package/dist/types/src/automerge/echo-replicator.d.ts.map +1 -1
- package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts +3 -3
- package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts.map +1 -1
- package/dist/types/src/automerge/mesh-echo-replicator.d.ts.map +1 -1
- package/dist/types/src/automerge/space-collection.d.ts +3 -2
- package/dist/types/src/automerge/space-collection.d.ts.map +1 -1
- package/dist/types/src/db-host/automerge-metrics.d.ts +11 -0
- package/dist/types/src/db-host/automerge-metrics.d.ts.map +1 -0
- package/dist/types/src/db-host/data-service.d.ts +3 -2
- package/dist/types/src/db-host/data-service.d.ts.map +1 -1
- package/dist/types/src/db-host/database-root.d.ts +20 -0
- package/dist/types/src/db-host/database-root.d.ts.map +1 -0
- package/dist/types/src/db-host/documents-iterator.d.ts +7 -0
- package/dist/types/src/db-host/documents-iterator.d.ts.map +1 -0
- package/dist/types/src/db-host/echo-host.d.ts +73 -0
- package/dist/types/src/db-host/echo-host.d.ts.map +1 -0
- package/dist/types/src/db-host/index.d.ts +5 -0
- package/dist/types/src/db-host/index.d.ts.map +1 -1
- package/dist/types/src/db-host/migration.d.ts +8 -0
- package/dist/types/src/db-host/migration.d.ts.map +1 -0
- package/dist/types/src/db-host/query-service.d.ts +25 -0
- package/dist/types/src/db-host/query-service.d.ts.map +1 -0
- package/dist/types/src/db-host/query-state.d.ts +41 -0
- package/dist/types/src/db-host/query-state.d.ts.map +1 -0
- package/dist/types/src/db-host/space-state-manager.d.ts +23 -0
- package/dist/types/src/db-host/space-state-manager.d.ts.map +1 -0
- package/dist/types/src/edge/echo-edge-replicator.d.ts +23 -0
- package/dist/types/src/edge/echo-edge-replicator.d.ts.map +1 -0
- package/dist/types/src/edge/echo-edge-replicator.test.d.ts +2 -0
- package/dist/types/src/edge/echo-edge-replicator.test.d.ts.map +1 -0
- package/dist/types/src/edge/index.d.ts +2 -0
- package/dist/types/src/edge/index.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/metadata/metadata-store.d.ts +4 -1
- package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
- package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
- package/dist/types/src/testing/test-replicator.d.ts +4 -4
- package/dist/types/src/testing/test-replicator.d.ts.map +1 -1
- package/package.json +40 -50
- package/src/automerge/automerge-host.test.ts +8 -9
- package/src/automerge/automerge-host.ts +46 -7
- package/src/automerge/automerge-repo.test.ts +18 -16
- package/src/automerge/collection-synchronizer.test.ts +10 -5
- package/src/automerge/collection-synchronizer.ts +17 -6
- package/src/automerge/echo-data-monitor.test.ts +1 -3
- package/src/automerge/echo-network-adapter.test.ts +4 -3
- package/src/automerge/echo-network-adapter.ts +5 -4
- package/src/automerge/echo-replicator.ts +3 -3
- package/src/automerge/mesh-echo-replicator-connection.ts +10 -9
- package/src/automerge/mesh-echo-replicator.ts +2 -1
- package/src/automerge/space-collection.ts +3 -2
- package/src/automerge/storage-adapter.test.ts +2 -3
- package/src/db-host/automerge-metrics.ts +38 -0
- package/src/db-host/data-service.ts +29 -14
- package/src/db-host/database-root.ts +86 -0
- package/src/db-host/documents-iterator.ts +73 -0
- package/src/db-host/documents-synchronizer.test.ts +2 -2
- package/src/db-host/echo-host.ts +257 -0
- package/src/db-host/index.ts +6 -1
- package/src/db-host/migration.ts +57 -0
- package/src/db-host/query-service.ts +208 -0
- package/src/db-host/query-state.ts +200 -0
- package/src/db-host/space-state-manager.ts +90 -0
- package/src/edge/echo-edge-replicator.test.ts +96 -0
- package/src/edge/echo-edge-replicator.ts +337 -0
- package/src/edge/index.ts +5 -0
- package/src/index.ts +1 -0
- package/src/metadata/metadata-store.ts +20 -0
- package/src/pipeline/pipeline-stress.test.ts +44 -47
- package/src/pipeline/pipeline.test.ts +3 -4
- package/src/space/control-pipeline.test.ts +2 -3
- package/src/space/control-pipeline.ts +10 -1
- package/src/space/replication.browser.test.ts +2 -8
- package/src/space/space-manager.browser.test.ts +6 -5
- package/src/space/space-protocol.browser.test.ts +29 -34
- package/src/space/space-protocol.test.ts +29 -27
- package/src/space/space.test.ts +28 -11
- package/src/testing/test-agent-builder.ts +2 -2
- package/src/testing/test-replicator.ts +3 -3
- package/dist/lib/browser/chunk-MPWFDDQK.mjs.map +0 -7
- package/dist/lib/browser/chunk-UKXIJW43.mjs.map +0 -7
- package/dist/lib/browser/chunk-XPCF2V5U.mjs +0 -31
- package/dist/lib/browser/chunk-XPCF2V5U.mjs.map +0 -7
- package/dist/lib/browser/light.mjs +0 -32
- package/dist/lib/browser/light.mjs.map +0 -7
- package/dist/lib/node/chunk-5DH4KR2S.cjs +0 -2148
- package/dist/lib/node/chunk-5DH4KR2S.cjs.map +0 -7
- package/dist/lib/node/chunk-7HHYCGUR.cjs.map +0 -7
- package/dist/lib/node/chunk-DZVH7HDD.cjs +0 -43
- package/dist/lib/node/chunk-DZVH7HDD.cjs.map +0 -7
- package/dist/lib/node/light.cjs +0 -52
- package/dist/lib/node/light.cjs.map +0 -7
- package/dist/types/src/light.d.ts +0 -4
- package/dist/types/src/light.d.ts.map +0 -1
- package/src/light.ts +0 -7
|
@@ -1,8 +1,34 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
AuthExtension,
|
|
4
|
+
AuthStatus,
|
|
5
|
+
CredentialRetrieverExtension,
|
|
6
|
+
CredentialServerExtension,
|
|
7
|
+
MOCK_AUTH_PROVIDER,
|
|
8
|
+
MOCK_AUTH_VERIFIER,
|
|
9
|
+
MetadataStore,
|
|
10
|
+
Pipeline,
|
|
11
|
+
Space,
|
|
12
|
+
SpaceManager,
|
|
13
|
+
SpaceProtocol,
|
|
14
|
+
SpaceProtocolSession,
|
|
15
|
+
TimeframeClock,
|
|
16
|
+
codec,
|
|
17
|
+
createIdFromSpaceKey,
|
|
18
|
+
createMappedFeedWriter,
|
|
19
|
+
hasInvitationExpired,
|
|
20
|
+
mapFeedIndexesToTimeframe,
|
|
21
|
+
mapTimeframeToFeedIndexes,
|
|
22
|
+
startAfter,
|
|
23
|
+
valueEncoding
|
|
24
|
+
} from "./chunk-4LW7MDPZ.mjs";
|
|
25
|
+
|
|
26
|
+
// packages/core/echo/echo-pipeline/src/db-host/data-service.ts
|
|
27
|
+
import { UpdateScheduler as UpdateScheduler2 } from "@dxos/async";
|
|
28
|
+
import { Stream } from "@dxos/codec-protobuf/stream";
|
|
29
|
+
import { invariant as invariant7 } from "@dxos/invariant";
|
|
30
|
+
import { SpaceId as SpaceId2 } from "@dxos/keys";
|
|
31
|
+
import { log as log7 } from "@dxos/log";
|
|
6
32
|
|
|
7
33
|
// packages/core/echo/echo-pipeline/src/db-host/documents-synchronizer.ts
|
|
8
34
|
import { UpdateScheduler } from "@dxos/async";
|
|
@@ -170,11 +196,24 @@ var DocumentsSynchronizer = class extends Resource {
|
|
|
170
196
|
}
|
|
171
197
|
};
|
|
172
198
|
|
|
199
|
+
// packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
|
|
200
|
+
import { Event as Event2, asyncTimeout } from "@dxos/async";
|
|
201
|
+
import { getBackend, getHeads, isAutomerge, equals as headsEquals, save } from "@dxos/automerge/automerge";
|
|
202
|
+
import { Repo } from "@dxos/automerge/automerge-repo";
|
|
203
|
+
import { Context, Resource as Resource4, cancelWithContext } from "@dxos/context";
|
|
204
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
205
|
+
import { PublicKey } from "@dxos/keys";
|
|
206
|
+
import { log as log4 } from "@dxos/log";
|
|
207
|
+
import { objectPointerCodec } from "@dxos/protocols";
|
|
208
|
+
import { trace } from "@dxos/tracing";
|
|
209
|
+
|
|
173
210
|
// packages/core/echo/echo-pipeline/src/automerge/collection-synchronizer.ts
|
|
174
211
|
import { asyncReturn, Event, scheduleTask, scheduleTaskInterval } from "@dxos/async";
|
|
175
212
|
import { next as am } from "@dxos/automerge/automerge";
|
|
176
213
|
import { Resource as Resource2 } from "@dxos/context";
|
|
214
|
+
import { log as log2 } from "@dxos/log";
|
|
177
215
|
import { defaultMap } from "@dxos/util";
|
|
216
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/collection-synchronizer.ts";
|
|
178
217
|
var MIN_QUERY_INTERVAL = 5e3;
|
|
179
218
|
var POLL_INTERVAL = 3e4;
|
|
180
219
|
var CollectionSynchronizer = class extends Resource2 {
|
|
@@ -207,6 +246,15 @@ var CollectionSynchronizer = class extends Resource2 {
|
|
|
207
246
|
return this._getPerCollectionState(collectionId).localState;
|
|
208
247
|
}
|
|
209
248
|
setLocalCollectionState(collectionId, state) {
|
|
249
|
+
log2("setLocalCollectionState", {
|
|
250
|
+
collectionId,
|
|
251
|
+
state
|
|
252
|
+
}, {
|
|
253
|
+
F: __dxlog_file2,
|
|
254
|
+
L: 68,
|
|
255
|
+
S: this,
|
|
256
|
+
C: (f, a) => f(...a)
|
|
257
|
+
});
|
|
210
258
|
this._getPerCollectionState(collectionId).localState = state;
|
|
211
259
|
queueMicrotask(async () => {
|
|
212
260
|
if (!this._ctx.disposed) {
|
|
@@ -276,6 +324,16 @@ var CollectionSynchronizer = class extends Resource2 {
|
|
|
276
324
|
* Callback when a peer sends the state of a collection.
|
|
277
325
|
*/
|
|
278
326
|
onRemoteStateReceived(collectionId, peerId, state) {
|
|
327
|
+
log2("onRemoteStateReceived", {
|
|
328
|
+
collectionId,
|
|
329
|
+
peerId,
|
|
330
|
+
state
|
|
331
|
+
}, {
|
|
332
|
+
F: __dxlog_file2,
|
|
333
|
+
L: 148,
|
|
334
|
+
S: this,
|
|
335
|
+
C: (f, a) => f(...a)
|
|
336
|
+
});
|
|
279
337
|
validateCollectionState(state);
|
|
280
338
|
const perCollectionState = this._getPerCollectionState(collectionId);
|
|
281
339
|
perCollectionState.remoteStates.set(peerId, state);
|
|
@@ -307,13 +365,21 @@ var diffCollectionState = (local, remote) => {
|
|
|
307
365
|
...Object.keys(local.documents),
|
|
308
366
|
...Object.keys(remote.documents)
|
|
309
367
|
]);
|
|
368
|
+
const missingOnRemote = [];
|
|
369
|
+
const missingOnLocal = [];
|
|
310
370
|
const different = [];
|
|
311
371
|
for (const documentId of allDocuments) {
|
|
312
|
-
if (!local.documents[documentId]
|
|
372
|
+
if (!local.documents[documentId]) {
|
|
373
|
+
missingOnLocal.push(documentId);
|
|
374
|
+
} else if (!remote.documents[documentId]) {
|
|
375
|
+
missingOnRemote.push(documentId);
|
|
376
|
+
} else if (!am.equals(local.documents[documentId], remote.documents[documentId])) {
|
|
313
377
|
different.push(documentId);
|
|
314
378
|
}
|
|
315
379
|
}
|
|
316
380
|
return {
|
|
381
|
+
missingOnRemote,
|
|
382
|
+
missingOnLocal,
|
|
317
383
|
different
|
|
318
384
|
};
|
|
319
385
|
};
|
|
@@ -331,129 +397,12 @@ var isValidDocumentId = (documentId) => {
|
|
|
331
397
|
return typeof documentId === "string" && !documentId.includes(":");
|
|
332
398
|
};
|
|
333
399
|
|
|
334
|
-
// packages/core/echo/echo-pipeline/src/automerge/leveldb-storage-adapter.ts
|
|
335
|
-
import { LifecycleState, Resource as Resource3 } from "@dxos/context";
|
|
336
|
-
var LevelDBStorageAdapter = class extends Resource3 {
|
|
337
|
-
constructor(_params) {
|
|
338
|
-
super();
|
|
339
|
-
this._params = _params;
|
|
340
|
-
}
|
|
341
|
-
async load(keyArray) {
|
|
342
|
-
try {
|
|
343
|
-
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
344
|
-
return void 0;
|
|
345
|
-
}
|
|
346
|
-
const startMs = Date.now();
|
|
347
|
-
const chunk = await this._params.db.get(keyArray, {
|
|
348
|
-
...encodingOptions
|
|
349
|
-
});
|
|
350
|
-
this._params.monitor?.recordBytesLoaded(chunk.byteLength);
|
|
351
|
-
this._params.monitor?.recordLoadDuration(Date.now() - startMs);
|
|
352
|
-
return chunk;
|
|
353
|
-
} catch (err) {
|
|
354
|
-
if (isLevelDbNotFoundError(err)) {
|
|
355
|
-
return void 0;
|
|
356
|
-
}
|
|
357
|
-
throw err;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
async save(keyArray, binary) {
|
|
361
|
-
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
362
|
-
return void 0;
|
|
363
|
-
}
|
|
364
|
-
const startMs = Date.now();
|
|
365
|
-
const batch = this._params.db.batch();
|
|
366
|
-
await this._params.callbacks?.beforeSave?.({
|
|
367
|
-
path: keyArray,
|
|
368
|
-
batch
|
|
369
|
-
});
|
|
370
|
-
batch.put(keyArray, Buffer.from(binary), {
|
|
371
|
-
...encodingOptions
|
|
372
|
-
});
|
|
373
|
-
await batch.write();
|
|
374
|
-
this._params.monitor?.recordBytesStored(binary.byteLength);
|
|
375
|
-
await this._params.callbacks?.afterSave?.(keyArray);
|
|
376
|
-
this._params.monitor?.recordStoreDuration(Date.now() - startMs);
|
|
377
|
-
}
|
|
378
|
-
async remove(keyArray) {
|
|
379
|
-
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
380
|
-
return void 0;
|
|
381
|
-
}
|
|
382
|
-
await this._params.db.del(keyArray, {
|
|
383
|
-
...encodingOptions
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
async loadRange(keyPrefix) {
|
|
387
|
-
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
388
|
-
return [];
|
|
389
|
-
}
|
|
390
|
-
const startMs = Date.now();
|
|
391
|
-
const result = [];
|
|
392
|
-
for await (const [key, value] of this._params.db.iterator({
|
|
393
|
-
gte: keyPrefix,
|
|
394
|
-
lte: [
|
|
395
|
-
...keyPrefix,
|
|
396
|
-
"\uFFFF"
|
|
397
|
-
],
|
|
398
|
-
...encodingOptions
|
|
399
|
-
})) {
|
|
400
|
-
result.push({
|
|
401
|
-
key,
|
|
402
|
-
data: value
|
|
403
|
-
});
|
|
404
|
-
this._params.monitor?.recordBytesLoaded(value.byteLength);
|
|
405
|
-
}
|
|
406
|
-
this._params.monitor?.recordLoadDuration(Date.now() - startMs);
|
|
407
|
-
return result;
|
|
408
|
-
}
|
|
409
|
-
async removeRange(keyPrefix) {
|
|
410
|
-
if (this._lifecycleState !== LifecycleState.OPEN) {
|
|
411
|
-
return void 0;
|
|
412
|
-
}
|
|
413
|
-
const batch = this._params.db.batch();
|
|
414
|
-
for await (const [key] of this._params.db.iterator({
|
|
415
|
-
gte: keyPrefix,
|
|
416
|
-
lte: [
|
|
417
|
-
...keyPrefix,
|
|
418
|
-
"\uFFFF"
|
|
419
|
-
],
|
|
420
|
-
...encodingOptions
|
|
421
|
-
})) {
|
|
422
|
-
batch.del(key, {
|
|
423
|
-
...encodingOptions
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
await batch.write();
|
|
427
|
-
}
|
|
428
|
-
};
|
|
429
|
-
var keyEncoder = {
|
|
430
|
-
encode: (key) => Buffer.from(key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-")),
|
|
431
|
-
decode: (key) => Buffer.from(key).toString().split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%")),
|
|
432
|
-
format: "buffer"
|
|
433
|
-
};
|
|
434
|
-
var encodingOptions = {
|
|
435
|
-
keyEncoding: keyEncoder,
|
|
436
|
-
valueEncoding: "buffer"
|
|
437
|
-
};
|
|
438
|
-
var isLevelDbNotFoundError = (err) => err.code === "LEVEL_NOT_FOUND";
|
|
439
|
-
|
|
440
|
-
// packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
|
|
441
|
-
import { Event as Event2, asyncTimeout } from "@dxos/async";
|
|
442
|
-
import { getBackend, getHeads, isAutomerge, equals as headsEquals, save } from "@dxos/automerge/automerge";
|
|
443
|
-
import { Repo } from "@dxos/automerge/automerge-repo";
|
|
444
|
-
import { Context, Resource as Resource4, cancelWithContext } from "@dxos/context";
|
|
445
|
-
import { invariant as invariant3 } from "@dxos/invariant";
|
|
446
|
-
import { PublicKey } from "@dxos/keys";
|
|
447
|
-
import { log as log3 } from "@dxos/log";
|
|
448
|
-
import { objectPointerCodec } from "@dxos/protocols";
|
|
449
|
-
import { trace } from "@dxos/tracing";
|
|
450
|
-
|
|
451
400
|
// packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts
|
|
452
401
|
import { synchronized, Trigger } from "@dxos/async";
|
|
453
402
|
import { NetworkAdapter } from "@dxos/automerge/automerge-repo";
|
|
454
|
-
import { LifecycleState
|
|
403
|
+
import { LifecycleState } from "@dxos/context";
|
|
455
404
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
456
|
-
import { log as
|
|
405
|
+
import { log as log3 } from "@dxos/log";
|
|
457
406
|
import { nonNullable } from "@dxos/util";
|
|
458
407
|
|
|
459
408
|
// packages/core/echo/echo-pipeline/src/automerge/network-protocol.ts
|
|
@@ -468,14 +417,14 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
468
417
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
469
418
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
470
419
|
}
|
|
471
|
-
var
|
|
420
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts";
|
|
472
421
|
var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
473
422
|
constructor(_params) {
|
|
474
423
|
super();
|
|
475
424
|
this._params = _params;
|
|
476
425
|
this._replicators = /* @__PURE__ */ new Set();
|
|
477
426
|
this._connections = /* @__PURE__ */ new Map();
|
|
478
|
-
this._lifecycleState =
|
|
427
|
+
this._lifecycleState = LifecycleState.CLOSED;
|
|
479
428
|
this._connected = new Trigger();
|
|
480
429
|
}
|
|
481
430
|
connect(peerId, peerMetadata) {
|
|
@@ -489,13 +438,13 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
489
438
|
disconnect() {
|
|
490
439
|
}
|
|
491
440
|
async open() {
|
|
492
|
-
if (this._lifecycleState ===
|
|
441
|
+
if (this._lifecycleState === LifecycleState.OPEN) {
|
|
493
442
|
return;
|
|
494
443
|
}
|
|
495
|
-
this._lifecycleState =
|
|
496
|
-
|
|
497
|
-
F:
|
|
498
|
-
L:
|
|
444
|
+
this._lifecycleState = LifecycleState.OPEN;
|
|
445
|
+
log3("emit ready", void 0, {
|
|
446
|
+
F: __dxlog_file3,
|
|
447
|
+
L: 82,
|
|
499
448
|
S: this,
|
|
500
449
|
C: (f, a) => f(...a)
|
|
501
450
|
});
|
|
@@ -504,14 +453,14 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
504
453
|
});
|
|
505
454
|
}
|
|
506
455
|
async close() {
|
|
507
|
-
if (this._lifecycleState ===
|
|
456
|
+
if (this._lifecycleState === LifecycleState.CLOSED) {
|
|
508
457
|
return this;
|
|
509
458
|
}
|
|
510
459
|
for (const replicator of this._replicators) {
|
|
511
460
|
await replicator.disconnect();
|
|
512
461
|
}
|
|
513
462
|
this._replicators.clear();
|
|
514
|
-
this._lifecycleState =
|
|
463
|
+
this._lifecycleState = LifecycleState.CLOSED;
|
|
515
464
|
}
|
|
516
465
|
async whenConnected() {
|
|
517
466
|
await this._connected.wait({
|
|
@@ -519,9 +468,9 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
519
468
|
});
|
|
520
469
|
}
|
|
521
470
|
async addReplicator(replicator) {
|
|
522
|
-
invariant2(this._lifecycleState ===
|
|
523
|
-
F:
|
|
524
|
-
L:
|
|
471
|
+
invariant2(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
472
|
+
F: __dxlog_file3,
|
|
473
|
+
L: 108,
|
|
525
474
|
S: this,
|
|
526
475
|
A: [
|
|
527
476
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -529,8 +478,8 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
529
478
|
]
|
|
530
479
|
});
|
|
531
480
|
invariant2(this.peerId, void 0, {
|
|
532
|
-
F:
|
|
533
|
-
L:
|
|
481
|
+
F: __dxlog_file3,
|
|
482
|
+
L: 109,
|
|
534
483
|
S: this,
|
|
535
484
|
A: [
|
|
536
485
|
"this.peerId",
|
|
@@ -538,8 +487,8 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
538
487
|
]
|
|
539
488
|
});
|
|
540
489
|
invariant2(!this._replicators.has(replicator), void 0, {
|
|
541
|
-
F:
|
|
542
|
-
L:
|
|
490
|
+
F: __dxlog_file3,
|
|
491
|
+
L: 110,
|
|
543
492
|
S: this,
|
|
544
493
|
A: [
|
|
545
494
|
"!this._replicators.has(replicator)",
|
|
@@ -561,9 +510,9 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
561
510
|
});
|
|
562
511
|
}
|
|
563
512
|
async removeReplicator(replicator) {
|
|
564
|
-
invariant2(this._lifecycleState ===
|
|
565
|
-
F:
|
|
566
|
-
L:
|
|
513
|
+
invariant2(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
514
|
+
F: __dxlog_file3,
|
|
515
|
+
L: 129,
|
|
567
516
|
S: this,
|
|
568
517
|
A: [
|
|
569
518
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -571,8 +520,8 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
571
520
|
]
|
|
572
521
|
});
|
|
573
522
|
invariant2(this._replicators.has(replicator), void 0, {
|
|
574
|
-
F:
|
|
575
|
-
L:
|
|
523
|
+
F: __dxlog_file3,
|
|
524
|
+
L: 130,
|
|
576
525
|
S: this,
|
|
577
526
|
A: [
|
|
578
527
|
"this._replicators.has(replicator)",
|
|
@@ -626,9 +575,9 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
626
575
|
this._params.monitor?.recordMessageSent(message, durationMs);
|
|
627
576
|
}).catch((err) => {
|
|
628
577
|
if (connectionEntry.isOpen) {
|
|
629
|
-
|
|
630
|
-
F:
|
|
631
|
-
L:
|
|
578
|
+
log3.catch(err, void 0, {
|
|
579
|
+
F: __dxlog_file3,
|
|
580
|
+
L: 190,
|
|
632
581
|
S: this,
|
|
633
582
|
C: (f, a) => f(...a)
|
|
634
583
|
});
|
|
@@ -645,17 +594,17 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
645
594
|
}).filter(nonNullable);
|
|
646
595
|
}
|
|
647
596
|
_onConnectionOpen(connection) {
|
|
648
|
-
|
|
597
|
+
log3("Connection opened", {
|
|
649
598
|
peerId: connection.peerId
|
|
650
599
|
}, {
|
|
651
|
-
F:
|
|
652
|
-
L:
|
|
600
|
+
F: __dxlog_file3,
|
|
601
|
+
L: 208,
|
|
653
602
|
S: this,
|
|
654
603
|
C: (f, a) => f(...a)
|
|
655
604
|
});
|
|
656
605
|
invariant2(!this._connections.has(connection.peerId), void 0, {
|
|
657
|
-
F:
|
|
658
|
-
L:
|
|
606
|
+
F: __dxlog_file3,
|
|
607
|
+
L: 209,
|
|
659
608
|
S: this,
|
|
660
609
|
A: [
|
|
661
610
|
"!this._connections.has(connection.peerId as PeerId)",
|
|
@@ -682,20 +631,20 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
682
631
|
}
|
|
683
632
|
} catch (err) {
|
|
684
633
|
if (connectionEntry.isOpen) {
|
|
685
|
-
|
|
686
|
-
F:
|
|
687
|
-
L:
|
|
634
|
+
log3.catch(err, void 0, {
|
|
635
|
+
F: __dxlog_file3,
|
|
636
|
+
L: 228,
|
|
688
637
|
S: this,
|
|
689
638
|
C: (f, a) => f(...a)
|
|
690
639
|
});
|
|
691
640
|
}
|
|
692
641
|
}
|
|
693
642
|
});
|
|
694
|
-
|
|
643
|
+
log3("emit peer-candidate", {
|
|
695
644
|
peerId: connection.peerId
|
|
696
645
|
}, {
|
|
697
|
-
F:
|
|
698
|
-
L:
|
|
646
|
+
F: __dxlog_file3,
|
|
647
|
+
L: 233,
|
|
699
648
|
S: this,
|
|
700
649
|
C: (f, a) => f(...a)
|
|
701
650
|
});
|
|
@@ -717,18 +666,18 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
717
666
|
* TODO(y): replace with a proper API call when sharePolicy update becomes supported by automerge-repo
|
|
718
667
|
*/
|
|
719
668
|
_onConnectionAuthScopeChanged(connection) {
|
|
720
|
-
|
|
669
|
+
log3("Connection auth scope changed", {
|
|
721
670
|
peerId: connection.peerId
|
|
722
671
|
}, {
|
|
723
|
-
F:
|
|
724
|
-
L:
|
|
672
|
+
F: __dxlog_file3,
|
|
673
|
+
L: 254,
|
|
725
674
|
S: this,
|
|
726
675
|
C: (f, a) => f(...a)
|
|
727
676
|
});
|
|
728
677
|
const entry = this._connections.get(connection.peerId);
|
|
729
678
|
invariant2(entry, void 0, {
|
|
730
|
-
F:
|
|
731
|
-
L:
|
|
679
|
+
F: __dxlog_file3,
|
|
680
|
+
L: 256,
|
|
732
681
|
S: this,
|
|
733
682
|
A: [
|
|
734
683
|
"entry",
|
|
@@ -741,18 +690,18 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
741
690
|
this._emitPeerCandidate(connection);
|
|
742
691
|
}
|
|
743
692
|
_onConnectionClosed(connection) {
|
|
744
|
-
|
|
693
|
+
log3("Connection closed", {
|
|
745
694
|
peerId: connection.peerId
|
|
746
695
|
}, {
|
|
747
|
-
F:
|
|
748
|
-
L:
|
|
696
|
+
F: __dxlog_file3,
|
|
697
|
+
L: 262,
|
|
749
698
|
S: this,
|
|
750
699
|
C: (f, a) => f(...a)
|
|
751
700
|
});
|
|
752
701
|
const entry = this._connections.get(connection.peerId);
|
|
753
702
|
invariant2(entry, void 0, {
|
|
754
|
-
F:
|
|
755
|
-
L:
|
|
703
|
+
F: __dxlog_file3,
|
|
704
|
+
L: 264,
|
|
756
705
|
S: this,
|
|
757
706
|
A: [
|
|
758
707
|
"entry",
|
|
@@ -764,15 +713,15 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
764
713
|
peerId: connection.peerId
|
|
765
714
|
});
|
|
766
715
|
this._params.monitor?.recordPeerDisconnected(connection.peerId);
|
|
767
|
-
void entry.reader.cancel().catch((err) =>
|
|
768
|
-
F:
|
|
769
|
-
L:
|
|
716
|
+
void entry.reader.cancel().catch((err) => log3.catch(err, void 0, {
|
|
717
|
+
F: __dxlog_file3,
|
|
718
|
+
L: 270,
|
|
770
719
|
S: this,
|
|
771
720
|
C: (f, a) => f(...a)
|
|
772
721
|
}));
|
|
773
|
-
void entry.writer.abort().catch((err) =>
|
|
774
|
-
F:
|
|
775
|
-
L:
|
|
722
|
+
void entry.writer.abort().catch((err) => log3.catch(err, void 0, {
|
|
723
|
+
F: __dxlog_file3,
|
|
724
|
+
L: 271,
|
|
776
725
|
S: this,
|
|
777
726
|
C: (f, a) => f(...a)
|
|
778
727
|
}));
|
|
@@ -825,42 +774,149 @@ var HeadsStore = class {
|
|
|
825
774
|
}
|
|
826
775
|
};
|
|
827
776
|
|
|
828
|
-
// packages/core/echo/echo-pipeline/src/automerge/
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
833
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
834
|
-
}
|
|
835
|
-
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
|
|
836
|
-
var AutomergeHost = class extends Resource4 {
|
|
837
|
-
constructor({ db, indexMetadataStore, dataMonitor }) {
|
|
777
|
+
// packages/core/echo/echo-pipeline/src/automerge/leveldb-storage-adapter.ts
|
|
778
|
+
import { LifecycleState as LifecycleState2, Resource as Resource3 } from "@dxos/context";
|
|
779
|
+
var LevelDBStorageAdapter = class extends Resource3 {
|
|
780
|
+
constructor(_params) {
|
|
838
781
|
super();
|
|
839
|
-
this.
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
monitor
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
782
|
+
this._params = _params;
|
|
783
|
+
}
|
|
784
|
+
async load(keyArray) {
|
|
785
|
+
try {
|
|
786
|
+
if (this._lifecycleState !== LifecycleState2.OPEN) {
|
|
787
|
+
return void 0;
|
|
788
|
+
}
|
|
789
|
+
const startMs = Date.now();
|
|
790
|
+
const chunk = await this._params.db.get(keyArray, {
|
|
791
|
+
...encodingOptions
|
|
792
|
+
});
|
|
793
|
+
this._params.monitor?.recordBytesLoaded(chunk.byteLength);
|
|
794
|
+
this._params.monitor?.recordLoadDuration(Date.now() - startMs);
|
|
795
|
+
return chunk;
|
|
796
|
+
} catch (err) {
|
|
797
|
+
if (isLevelDbNotFoundError(err)) {
|
|
798
|
+
return void 0;
|
|
799
|
+
}
|
|
800
|
+
throw err;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
async save(keyArray, binary) {
|
|
804
|
+
if (this._lifecycleState !== LifecycleState2.OPEN) {
|
|
805
|
+
return void 0;
|
|
806
|
+
}
|
|
807
|
+
const startMs = Date.now();
|
|
808
|
+
const batch = this._params.db.batch();
|
|
809
|
+
await this._params.callbacks?.beforeSave?.({
|
|
810
|
+
path: keyArray,
|
|
811
|
+
batch
|
|
859
812
|
});
|
|
860
|
-
|
|
861
|
-
|
|
813
|
+
batch.put(keyArray, Buffer.from(binary), {
|
|
814
|
+
...encodingOptions
|
|
862
815
|
});
|
|
863
|
-
|
|
816
|
+
await batch.write();
|
|
817
|
+
this._params.monitor?.recordBytesStored(binary.byteLength);
|
|
818
|
+
await this._params.callbacks?.afterSave?.(keyArray);
|
|
819
|
+
this._params.monitor?.recordStoreDuration(Date.now() - startMs);
|
|
820
|
+
}
|
|
821
|
+
async remove(keyArray) {
|
|
822
|
+
if (this._lifecycleState !== LifecycleState2.OPEN) {
|
|
823
|
+
return void 0;
|
|
824
|
+
}
|
|
825
|
+
await this._params.db.del(keyArray, {
|
|
826
|
+
...encodingOptions
|
|
827
|
+
});
|
|
828
|
+
}
|
|
829
|
+
async loadRange(keyPrefix) {
|
|
830
|
+
if (this._lifecycleState !== LifecycleState2.OPEN) {
|
|
831
|
+
return [];
|
|
832
|
+
}
|
|
833
|
+
const startMs = Date.now();
|
|
834
|
+
const result = [];
|
|
835
|
+
for await (const [key, value] of this._params.db.iterator({
|
|
836
|
+
gte: keyPrefix,
|
|
837
|
+
lte: [
|
|
838
|
+
...keyPrefix,
|
|
839
|
+
"\uFFFF"
|
|
840
|
+
],
|
|
841
|
+
...encodingOptions
|
|
842
|
+
})) {
|
|
843
|
+
result.push({
|
|
844
|
+
key,
|
|
845
|
+
data: value
|
|
846
|
+
});
|
|
847
|
+
this._params.monitor?.recordBytesLoaded(value.byteLength);
|
|
848
|
+
}
|
|
849
|
+
this._params.monitor?.recordLoadDuration(Date.now() - startMs);
|
|
850
|
+
return result;
|
|
851
|
+
}
|
|
852
|
+
async removeRange(keyPrefix) {
|
|
853
|
+
if (this._lifecycleState !== LifecycleState2.OPEN) {
|
|
854
|
+
return void 0;
|
|
855
|
+
}
|
|
856
|
+
const batch = this._params.db.batch();
|
|
857
|
+
for await (const [key] of this._params.db.iterator({
|
|
858
|
+
gte: keyPrefix,
|
|
859
|
+
lte: [
|
|
860
|
+
...keyPrefix,
|
|
861
|
+
"\uFFFF"
|
|
862
|
+
],
|
|
863
|
+
...encodingOptions
|
|
864
|
+
})) {
|
|
865
|
+
batch.del(key, {
|
|
866
|
+
...encodingOptions
|
|
867
|
+
});
|
|
868
|
+
}
|
|
869
|
+
await batch.write();
|
|
870
|
+
}
|
|
871
|
+
};
|
|
872
|
+
var keyEncoder = {
|
|
873
|
+
encode: (key) => Buffer.from(key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-")),
|
|
874
|
+
decode: (key) => Buffer.from(key).toString().split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%")),
|
|
875
|
+
format: "buffer"
|
|
876
|
+
};
|
|
877
|
+
var encodingOptions = {
|
|
878
|
+
keyEncoding: keyEncoder,
|
|
879
|
+
valueEncoding: "buffer"
|
|
880
|
+
};
|
|
881
|
+
var isLevelDbNotFoundError = (err) => err.code === "LEVEL_NOT_FOUND";
|
|
882
|
+
|
|
883
|
+
// packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
|
|
884
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
885
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
886
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
887
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
888
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
889
|
+
}
|
|
890
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
|
|
891
|
+
var AutomergeHost = class extends Resource4 {
|
|
892
|
+
constructor({ db, indexMetadataStore, dataMonitor }) {
|
|
893
|
+
super();
|
|
894
|
+
this._collectionSynchronizer = new CollectionSynchronizer({
|
|
895
|
+
queryCollectionState: this._queryCollectionState.bind(this),
|
|
896
|
+
sendCollectionState: this._sendCollectionState.bind(this),
|
|
897
|
+
shouldSyncCollection: this._shouldSyncCollection.bind(this)
|
|
898
|
+
});
|
|
899
|
+
this.collectionStateUpdated = new Event2();
|
|
900
|
+
this._db = db;
|
|
901
|
+
this._storage = new LevelDBStorageAdapter({
|
|
902
|
+
db: db.sublevel("automerge"),
|
|
903
|
+
callbacks: {
|
|
904
|
+
beforeSave: async (params) => this._beforeSave(params),
|
|
905
|
+
afterSave: async (key) => this._afterSave(key)
|
|
906
|
+
},
|
|
907
|
+
monitor: dataMonitor
|
|
908
|
+
});
|
|
909
|
+
this._echoNetworkAdapter = new EchoNetworkAdapter({
|
|
910
|
+
getContainingSpaceForDocument: this._getContainingSpaceForDocument.bind(this),
|
|
911
|
+
isDocumentInRemoteCollection: this._isDocumentInRemoteCollection.bind(this),
|
|
912
|
+
onCollectionStateQueried: this._onCollectionStateQueried.bind(this),
|
|
913
|
+
onCollectionStateReceived: this._onCollectionStateReceived.bind(this),
|
|
914
|
+
monitor: dataMonitor
|
|
915
|
+
});
|
|
916
|
+
this._headsStore = new HeadsStore({
|
|
917
|
+
db: db.sublevel("heads")
|
|
918
|
+
});
|
|
919
|
+
this._indexMetadataStore = indexMetadataStore;
|
|
864
920
|
}
|
|
865
921
|
async _open() {
|
|
866
922
|
this._peerId = `host-${PublicKey.random().toHex()}`;
|
|
@@ -878,6 +934,9 @@ var AutomergeHost = class extends Resource4 {
|
|
|
878
934
|
Event2.wrap(this._echoNetworkAdapter, "peer-disconnected").on(this._ctx, (e) => this._onPeerDisconnected(e.peerId));
|
|
879
935
|
this._collectionSynchronizer.remoteStateUpdated.on(this._ctx, ({ collectionId, peerId }) => {
|
|
880
936
|
this._onRemoteCollectionStateUpdated(collectionId, peerId);
|
|
937
|
+
this.collectionStateUpdated.emit({
|
|
938
|
+
collectionId
|
|
939
|
+
});
|
|
881
940
|
});
|
|
882
941
|
await this._echoNetworkAdapter.open();
|
|
883
942
|
await this._collectionSynchronizer.open();
|
|
@@ -959,8 +1018,8 @@ var AutomergeHost = class extends Resource4 {
|
|
|
959
1018
|
if (headsToWait.length > 0) {
|
|
960
1019
|
await Promise.all(headsToWait.map(async (entry, index) => {
|
|
961
1020
|
const handle = await this.loadDoc(Context.default(void 0, {
|
|
962
|
-
F:
|
|
963
|
-
L:
|
|
1021
|
+
F: __dxlog_file4,
|
|
1022
|
+
L: 230
|
|
964
1023
|
}), entry.documentId);
|
|
965
1024
|
await waitForHeads(handle, entry.heads);
|
|
966
1025
|
}));
|
|
@@ -969,11 +1028,11 @@ var AutomergeHost = class extends Resource4 {
|
|
|
969
1028
|
}
|
|
970
1029
|
async reIndexHeads(documentIds) {
|
|
971
1030
|
for (const documentId of documentIds) {
|
|
972
|
-
|
|
1031
|
+
log4.info("re-indexing heads for document", {
|
|
973
1032
|
documentId
|
|
974
1033
|
}, {
|
|
975
|
-
F:
|
|
976
|
-
L:
|
|
1034
|
+
F: __dxlog_file4,
|
|
1035
|
+
L: 242,
|
|
977
1036
|
S: this,
|
|
978
1037
|
C: (f, a) => f(...a)
|
|
979
1038
|
});
|
|
@@ -985,11 +1044,11 @@ var AutomergeHost = class extends Resource4 {
|
|
|
985
1044
|
if (handle.inState([
|
|
986
1045
|
"requesting"
|
|
987
1046
|
])) {
|
|
988
|
-
|
|
1047
|
+
log4.warn("document is not available locally, skipping", {
|
|
989
1048
|
documentId
|
|
990
1049
|
}, {
|
|
991
|
-
F:
|
|
992
|
-
L:
|
|
1050
|
+
F: __dxlog_file4,
|
|
1051
|
+
L: 246,
|
|
993
1052
|
S: this,
|
|
994
1053
|
C: (f, a) => f(...a)
|
|
995
1054
|
});
|
|
@@ -997,8 +1056,8 @@ var AutomergeHost = class extends Resource4 {
|
|
|
997
1056
|
}
|
|
998
1057
|
const doc = handle.docSync();
|
|
999
1058
|
invariant3(doc, void 0, {
|
|
1000
|
-
F:
|
|
1001
|
-
L:
|
|
1059
|
+
F: __dxlog_file4,
|
|
1060
|
+
L: 251,
|
|
1002
1061
|
S: this,
|
|
1003
1062
|
A: [
|
|
1004
1063
|
"doc",
|
|
@@ -1010,9 +1069,9 @@ var AutomergeHost = class extends Resource4 {
|
|
|
1010
1069
|
this._headsStore.setHeads(documentId, heads, batch);
|
|
1011
1070
|
await batch.write();
|
|
1012
1071
|
}
|
|
1013
|
-
|
|
1014
|
-
F:
|
|
1015
|
-
L:
|
|
1072
|
+
log4.info("done re-indexing heads", void 0, {
|
|
1073
|
+
F: __dxlog_file4,
|
|
1074
|
+
L: 258,
|
|
1016
1075
|
S: this,
|
|
1017
1076
|
C: (f, a) => f(...a)
|
|
1018
1077
|
});
|
|
@@ -1109,7 +1168,8 @@ var AutomergeHost = class extends Resource4 {
|
|
|
1109
1168
|
* Flush documents to disk.
|
|
1110
1169
|
*/
|
|
1111
1170
|
async flush({ documentIds } = {}) {
|
|
1112
|
-
|
|
1171
|
+
const loadedDocuments = documentIds?.filter((documentId) => !!this._repo.handles[documentId]);
|
|
1172
|
+
await this._repo.flush(loadedDocuments);
|
|
1113
1173
|
}
|
|
1114
1174
|
async getHeads(documentIds) {
|
|
1115
1175
|
const result = [];
|
|
@@ -1158,7 +1218,11 @@ var AutomergeHost = class extends Resource4 {
|
|
|
1158
1218
|
const diff = diffCollectionState(localState, state);
|
|
1159
1219
|
result.peers.push({
|
|
1160
1220
|
peerId,
|
|
1161
|
-
|
|
1221
|
+
missingOnRemote: diff.missingOnRemote.length,
|
|
1222
|
+
missingOnLocal: diff.missingOnLocal.length,
|
|
1223
|
+
differentDocuments: diff.different.length,
|
|
1224
|
+
localDocumentCount: Object.keys(localState.documents).length,
|
|
1225
|
+
remoteDocumentCount: Object.keys(state.documents).length
|
|
1162
1226
|
});
|
|
1163
1227
|
}
|
|
1164
1228
|
return result;
|
|
@@ -1200,31 +1264,43 @@ var AutomergeHost = class extends Resource4 {
|
|
|
1200
1264
|
if (!localState || !remoteState) {
|
|
1201
1265
|
return;
|
|
1202
1266
|
}
|
|
1203
|
-
const { different } = diffCollectionState(localState, remoteState);
|
|
1204
|
-
|
|
1267
|
+
const { different, missingOnLocal, missingOnRemote } = diffCollectionState(localState, remoteState);
|
|
1268
|
+
const toReplicate = [
|
|
1269
|
+
...missingOnLocal,
|
|
1270
|
+
...missingOnRemote,
|
|
1271
|
+
...different
|
|
1272
|
+
];
|
|
1273
|
+
if (toReplicate.length === 0) {
|
|
1205
1274
|
return;
|
|
1206
1275
|
}
|
|
1207
|
-
|
|
1208
|
-
count:
|
|
1276
|
+
log4.info("replication documents after collection sync", {
|
|
1277
|
+
count: toReplicate.length
|
|
1209
1278
|
}, {
|
|
1210
|
-
F:
|
|
1211
|
-
L:
|
|
1279
|
+
F: __dxlog_file4,
|
|
1280
|
+
L: 486,
|
|
1212
1281
|
S: this,
|
|
1213
1282
|
C: (f, a) => f(...a)
|
|
1214
1283
|
});
|
|
1215
|
-
for (const documentId of
|
|
1284
|
+
for (const documentId of toReplicate) {
|
|
1216
1285
|
this._repo.find(documentId);
|
|
1217
1286
|
}
|
|
1218
1287
|
}
|
|
1219
1288
|
_onHeadsChanged(documentId, heads) {
|
|
1289
|
+
const collectionsChanged = /* @__PURE__ */ new Set();
|
|
1220
1290
|
for (const collectionId of this._collectionSynchronizer.getRegisteredCollectionIds()) {
|
|
1221
1291
|
const state = this._collectionSynchronizer.getLocalCollectionState(collectionId);
|
|
1222
1292
|
if (state?.documents[documentId]) {
|
|
1223
1293
|
const newState = structuredClone(state);
|
|
1224
1294
|
newState.documents[documentId] = heads;
|
|
1225
1295
|
this._collectionSynchronizer.setLocalCollectionState(collectionId, newState);
|
|
1296
|
+
collectionsChanged.add(collectionId);
|
|
1226
1297
|
}
|
|
1227
1298
|
}
|
|
1299
|
+
for (const collectionId of collectionsChanged) {
|
|
1300
|
+
this.collectionStateUpdated.emit({
|
|
1301
|
+
collectionId
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1228
1304
|
}
|
|
1229
1305
|
};
|
|
1230
1306
|
_ts_decorate2([
|
|
@@ -1267,8 +1343,8 @@ var changeIsPresentInDoc = (doc, changeHash) => {
|
|
|
1267
1343
|
};
|
|
1268
1344
|
var decodeCollectionState = (state) => {
|
|
1269
1345
|
invariant3(typeof state === "object" && state !== null, "Invalid state", {
|
|
1270
|
-
F:
|
|
1271
|
-
L:
|
|
1346
|
+
F: __dxlog_file4,
|
|
1347
|
+
L: 544,
|
|
1272
1348
|
S: void 0,
|
|
1273
1349
|
A: [
|
|
1274
1350
|
"typeof state === 'object' && state !== null",
|
|
@@ -1281,37 +1357,18 @@ var encodeCollectionState = (state) => {
|
|
|
1281
1357
|
return state;
|
|
1282
1358
|
};
|
|
1283
1359
|
|
|
1284
|
-
// packages/core/echo/echo-pipeline/src/automerge/space-collection.ts
|
|
1285
|
-
import { invariant as invariant4 } from "@dxos/invariant";
|
|
1286
|
-
import { SpaceId } from "@dxos/keys";
|
|
1287
|
-
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/space-collection.ts";
|
|
1288
|
-
var deriveCollectionIdFromSpaceId = (spaceId) => `space:${spaceId}`;
|
|
1289
|
-
var getSpaceIdFromCollectionId = (collectionId) => {
|
|
1290
|
-
const spaceId = collectionId.replace(/^space:/, "");
|
|
1291
|
-
invariant4(SpaceId.isValid(spaceId), void 0, {
|
|
1292
|
-
F: __dxlog_file4,
|
|
1293
|
-
L: 12,
|
|
1294
|
-
S: void 0,
|
|
1295
|
-
A: [
|
|
1296
|
-
"SpaceId.isValid(spaceId)",
|
|
1297
|
-
""
|
|
1298
|
-
]
|
|
1299
|
-
});
|
|
1300
|
-
return spaceId;
|
|
1301
|
-
};
|
|
1302
|
-
|
|
1303
1360
|
// packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts
|
|
1304
1361
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
1305
1362
|
import { PublicKey as PublicKey2 } from "@dxos/keys";
|
|
1306
|
-
import { log as
|
|
1363
|
+
import { log as log6 } from "@dxos/log";
|
|
1307
1364
|
import { ComplexSet, defaultMap as defaultMap2 } from "@dxos/util";
|
|
1308
1365
|
|
|
1309
1366
|
// packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator-connection.ts
|
|
1310
1367
|
import * as A2 from "@dxos/automerge/automerge";
|
|
1311
1368
|
import { cbor } from "@dxos/automerge/automerge-repo";
|
|
1312
1369
|
import { Resource as Resource5 } from "@dxos/context";
|
|
1313
|
-
import { invariant as
|
|
1314
|
-
import { log as
|
|
1370
|
+
import { invariant as invariant4 } from "@dxos/invariant";
|
|
1371
|
+
import { log as log5 } from "@dxos/log";
|
|
1315
1372
|
import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
|
|
1316
1373
|
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator-connection.ts";
|
|
1317
1374
|
var DEFAULT_FACTORY = (params) => new AutomergeReplicator(...params);
|
|
@@ -1331,9 +1388,9 @@ var MeshReplicatorConnection = class extends Resource5 {
|
|
|
1331
1388
|
});
|
|
1332
1389
|
this.writable = new WritableStream({
|
|
1333
1390
|
write: async (message, controller) => {
|
|
1334
|
-
|
|
1391
|
+
invariant4(this._isEnabled, "Writing to a disabled connection", {
|
|
1335
1392
|
F: __dxlog_file5,
|
|
1336
|
-
L:
|
|
1393
|
+
L: 50,
|
|
1337
1394
|
S: this,
|
|
1338
1395
|
A: [
|
|
1339
1396
|
"this._isEnabled",
|
|
@@ -1360,13 +1417,13 @@ var MeshReplicatorConnection = class extends Resource5 {
|
|
|
1360
1417
|
onStartReplication: async (info, remotePeerId) => {
|
|
1361
1418
|
this.remoteDeviceKey = remotePeerId;
|
|
1362
1419
|
this._remotePeerId = info.id;
|
|
1363
|
-
|
|
1420
|
+
log5("onStartReplication", {
|
|
1364
1421
|
id: info.id,
|
|
1365
1422
|
thisPeerId: this.peerId,
|
|
1366
1423
|
remotePeerId: remotePeerId.toHex()
|
|
1367
1424
|
}, {
|
|
1368
1425
|
F: __dxlog_file5,
|
|
1369
|
-
L:
|
|
1426
|
+
L: 85,
|
|
1370
1427
|
S: this,
|
|
1371
1428
|
C: (f, a) => f(...a)
|
|
1372
1429
|
});
|
|
@@ -1391,9 +1448,9 @@ var MeshReplicatorConnection = class extends Resource5 {
|
|
|
1391
1448
|
}
|
|
1392
1449
|
}
|
|
1393
1450
|
get peerId() {
|
|
1394
|
-
|
|
1451
|
+
invariant4(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1395
1452
|
F: __dxlog_file5,
|
|
1396
|
-
L:
|
|
1453
|
+
L: 111,
|
|
1397
1454
|
S: this,
|
|
1398
1455
|
A: [
|
|
1399
1456
|
"this._remotePeerId != null",
|
|
@@ -1413,9 +1470,9 @@ var MeshReplicatorConnection = class extends Resource5 {
|
|
|
1413
1470
|
* Call after the remote peer has connected.
|
|
1414
1471
|
*/
|
|
1415
1472
|
enable() {
|
|
1416
|
-
|
|
1473
|
+
invariant4(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1417
1474
|
F: __dxlog_file5,
|
|
1418
|
-
L:
|
|
1475
|
+
L: 128,
|
|
1419
1476
|
S: this,
|
|
1420
1477
|
A: [
|
|
1421
1478
|
"this._remotePeerId != null",
|
|
@@ -1432,7 +1489,7 @@ var MeshReplicatorConnection = class extends Resource5 {
|
|
|
1432
1489
|
}
|
|
1433
1490
|
};
|
|
1434
1491
|
var logSendSync = (message) => {
|
|
1435
|
-
|
|
1492
|
+
log5("sendSyncMessage", () => {
|
|
1436
1493
|
const decodedSyncMessage = message.type === "sync" && message.data ? A2.decodeSyncMessage(message.data) : void 0;
|
|
1437
1494
|
return {
|
|
1438
1495
|
sync: decodedSyncMessage && {
|
|
@@ -1446,14 +1503,33 @@ var logSendSync = (message) => {
|
|
|
1446
1503
|
};
|
|
1447
1504
|
}, {
|
|
1448
1505
|
F: __dxlog_file5,
|
|
1449
|
-
L:
|
|
1506
|
+
L: 141,
|
|
1450
1507
|
S: void 0,
|
|
1451
1508
|
C: (f, a) => f(...a)
|
|
1452
1509
|
});
|
|
1453
1510
|
};
|
|
1454
1511
|
|
|
1512
|
+
// packages/core/echo/echo-pipeline/src/automerge/space-collection.ts
|
|
1513
|
+
import { invariant as invariant5 } from "@dxos/invariant";
|
|
1514
|
+
import { SpaceId } from "@dxos/keys";
|
|
1515
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/space-collection.ts";
|
|
1516
|
+
var deriveCollectionIdFromSpaceId = (spaceId) => `space:${spaceId}`;
|
|
1517
|
+
var getSpaceIdFromCollectionId = (collectionId) => {
|
|
1518
|
+
const spaceId = collectionId.replace(/^space:/, "");
|
|
1519
|
+
invariant5(SpaceId.isValid(spaceId), void 0, {
|
|
1520
|
+
F: __dxlog_file6,
|
|
1521
|
+
L: 13,
|
|
1522
|
+
S: void 0,
|
|
1523
|
+
A: [
|
|
1524
|
+
"SpaceId.isValid(spaceId)",
|
|
1525
|
+
""
|
|
1526
|
+
]
|
|
1527
|
+
});
|
|
1528
|
+
return spaceId;
|
|
1529
|
+
};
|
|
1530
|
+
|
|
1455
1531
|
// packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts
|
|
1456
|
-
var
|
|
1532
|
+
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts";
|
|
1457
1533
|
var MeshEchoReplicator = class {
|
|
1458
1534
|
constructor() {
|
|
1459
1535
|
this._connections = /* @__PURE__ */ new Set();
|
|
@@ -1483,8 +1559,8 @@ var MeshEchoReplicator = class {
|
|
|
1483
1559
|
}
|
|
1484
1560
|
createExtension(extensionFactory) {
|
|
1485
1561
|
invariant6(this._context, void 0, {
|
|
1486
|
-
F:
|
|
1487
|
-
L:
|
|
1562
|
+
F: __dxlog_file7,
|
|
1563
|
+
L: 57,
|
|
1488
1564
|
S: this,
|
|
1489
1565
|
A: [
|
|
1490
1566
|
"this._context",
|
|
@@ -1495,17 +1571,17 @@ var MeshEchoReplicator = class {
|
|
|
1495
1571
|
ownPeerId: this._context.peerId,
|
|
1496
1572
|
replicatorFactory: extensionFactory,
|
|
1497
1573
|
onRemoteConnected: async () => {
|
|
1498
|
-
|
|
1574
|
+
log6("onRemoteConnected", {
|
|
1499
1575
|
peerId: connection.peerId
|
|
1500
1576
|
}, {
|
|
1501
|
-
F:
|
|
1502
|
-
L:
|
|
1577
|
+
F: __dxlog_file7,
|
|
1578
|
+
L: 63,
|
|
1503
1579
|
S: this,
|
|
1504
1580
|
C: (f, a) => f(...a)
|
|
1505
1581
|
});
|
|
1506
1582
|
invariant6(this._context, void 0, {
|
|
1507
|
-
F:
|
|
1508
|
-
L:
|
|
1583
|
+
F: __dxlog_file7,
|
|
1584
|
+
L: 64,
|
|
1509
1585
|
S: this,
|
|
1510
1586
|
A: [
|
|
1511
1587
|
"this._context",
|
|
@@ -1521,11 +1597,11 @@ var MeshEchoReplicator = class {
|
|
|
1521
1597
|
}
|
|
1522
1598
|
},
|
|
1523
1599
|
onRemoteDisconnected: async () => {
|
|
1524
|
-
|
|
1600
|
+
log6("onRemoteDisconnected", {
|
|
1525
1601
|
peerId: connection.peerId
|
|
1526
1602
|
}, {
|
|
1527
|
-
F:
|
|
1528
|
-
L:
|
|
1603
|
+
F: __dxlog_file7,
|
|
1604
|
+
L: 75,
|
|
1529
1605
|
S: this,
|
|
1530
1606
|
C: (f, a) => f(...a)
|
|
1531
1607
|
});
|
|
@@ -1535,18 +1611,18 @@ var MeshEchoReplicator = class {
|
|
|
1535
1611
|
this._connections.delete(connection);
|
|
1536
1612
|
},
|
|
1537
1613
|
shouldAdvertise: async (params) => {
|
|
1538
|
-
|
|
1614
|
+
log6("shouldAdvertise", {
|
|
1539
1615
|
peerId: connection.peerId,
|
|
1540
1616
|
documentId: params.documentId
|
|
1541
1617
|
}, {
|
|
1542
|
-
F:
|
|
1543
|
-
L:
|
|
1618
|
+
F: __dxlog_file7,
|
|
1619
|
+
L: 82,
|
|
1544
1620
|
S: this,
|
|
1545
1621
|
C: (f, a) => f(...a)
|
|
1546
1622
|
});
|
|
1547
1623
|
invariant6(this._context, void 0, {
|
|
1548
|
-
F:
|
|
1549
|
-
L:
|
|
1624
|
+
F: __dxlog_file7,
|
|
1625
|
+
L: 83,
|
|
1550
1626
|
S: this,
|
|
1551
1627
|
A: [
|
|
1552
1628
|
"this._context",
|
|
@@ -1560,13 +1636,13 @@ var MeshEchoReplicator = class {
|
|
|
1560
1636
|
documentId: params.documentId,
|
|
1561
1637
|
peerId: connection.peerId
|
|
1562
1638
|
});
|
|
1563
|
-
|
|
1639
|
+
log6("document not found locally for share policy check, accepting the remote document", {
|
|
1564
1640
|
peerId: connection.peerId,
|
|
1565
1641
|
documentId: params.documentId,
|
|
1566
1642
|
remoteDocumentExists
|
|
1567
1643
|
}, {
|
|
1568
|
-
F:
|
|
1569
|
-
L:
|
|
1644
|
+
F: __dxlog_file7,
|
|
1645
|
+
L: 91,
|
|
1570
1646
|
S: this,
|
|
1571
1647
|
C: (f, a) => f(...a)
|
|
1572
1648
|
});
|
|
@@ -1575,19 +1651,19 @@ var MeshEchoReplicator = class {
|
|
|
1575
1651
|
const spaceId = await createIdFromSpaceKey(spaceKey);
|
|
1576
1652
|
const authorizedDevices = this._authorizedDevices.get(spaceId);
|
|
1577
1653
|
if (!connection.remoteDeviceKey) {
|
|
1578
|
-
|
|
1654
|
+
log6("device key not found for share policy check", {
|
|
1579
1655
|
peerId: connection.peerId,
|
|
1580
1656
|
documentId: params.documentId
|
|
1581
1657
|
}, {
|
|
1582
|
-
F:
|
|
1583
|
-
L:
|
|
1658
|
+
F: __dxlog_file7,
|
|
1659
|
+
L: 107,
|
|
1584
1660
|
S: this,
|
|
1585
1661
|
C: (f, a) => f(...a)
|
|
1586
1662
|
});
|
|
1587
1663
|
return false;
|
|
1588
1664
|
}
|
|
1589
1665
|
const isAuthorized = authorizedDevices?.has(connection.remoteDeviceKey) ?? false;
|
|
1590
|
-
|
|
1666
|
+
log6("share policy check", {
|
|
1591
1667
|
localPeer: this._context.peerId,
|
|
1592
1668
|
remotePeer: connection.peerId,
|
|
1593
1669
|
documentId: params.documentId,
|
|
@@ -1595,16 +1671,16 @@ var MeshEchoReplicator = class {
|
|
|
1595
1671
|
spaceKey,
|
|
1596
1672
|
isAuthorized
|
|
1597
1673
|
}, {
|
|
1598
|
-
F:
|
|
1599
|
-
L:
|
|
1674
|
+
F: __dxlog_file7,
|
|
1675
|
+
L: 115,
|
|
1600
1676
|
S: this,
|
|
1601
1677
|
C: (f, a) => f(...a)
|
|
1602
1678
|
});
|
|
1603
1679
|
return isAuthorized;
|
|
1604
1680
|
} catch (err) {
|
|
1605
|
-
|
|
1606
|
-
F:
|
|
1607
|
-
L:
|
|
1681
|
+
log6.catch(err, void 0, {
|
|
1682
|
+
F: __dxlog_file7,
|
|
1683
|
+
L: 125,
|
|
1608
1684
|
S: this,
|
|
1609
1685
|
C: (f, a) => f(...a)
|
|
1610
1686
|
});
|
|
@@ -1615,12 +1691,12 @@ var MeshEchoReplicator = class {
|
|
|
1615
1691
|
const spaceId = getSpaceIdFromCollectionId(collectionId);
|
|
1616
1692
|
const authorizedDevices = this._authorizedDevices.get(spaceId);
|
|
1617
1693
|
if (!connection.remoteDeviceKey) {
|
|
1618
|
-
|
|
1694
|
+
log6("device key not found for collection sync check", {
|
|
1619
1695
|
peerId: connection.peerId,
|
|
1620
1696
|
collectionId
|
|
1621
1697
|
}, {
|
|
1622
|
-
F:
|
|
1623
|
-
L:
|
|
1698
|
+
F: __dxlog_file7,
|
|
1699
|
+
L: 135,
|
|
1624
1700
|
S: this,
|
|
1625
1701
|
C: (f, a) => f(...a)
|
|
1626
1702
|
});
|
|
@@ -1634,12 +1710,12 @@ var MeshEchoReplicator = class {
|
|
|
1634
1710
|
return connection.replicatorExtension;
|
|
1635
1711
|
}
|
|
1636
1712
|
async authorizeDevice(spaceKey, deviceKey) {
|
|
1637
|
-
|
|
1713
|
+
log6("authorizeDevice", {
|
|
1638
1714
|
spaceKey,
|
|
1639
1715
|
deviceKey
|
|
1640
1716
|
}, {
|
|
1641
|
-
F:
|
|
1642
|
-
L:
|
|
1717
|
+
F: __dxlog_file7,
|
|
1718
|
+
L: 152,
|
|
1643
1719
|
S: this,
|
|
1644
1720
|
C: (f, a) => f(...a)
|
|
1645
1721
|
});
|
|
@@ -2017,11 +2093,7 @@ var getByteCount = (message) => {
|
|
|
2017
2093
|
};
|
|
2018
2094
|
|
|
2019
2095
|
// packages/core/echo/echo-pipeline/src/db-host/data-service.ts
|
|
2020
|
-
|
|
2021
|
-
import { invariant as invariant7 } from "@dxos/invariant";
|
|
2022
|
-
import { SpaceId as SpaceId2 } from "@dxos/keys";
|
|
2023
|
-
import { log as log6 } from "@dxos/log";
|
|
2024
|
-
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/data-service.ts";
|
|
2096
|
+
var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/data-service.ts";
|
|
2025
2097
|
var DataServiceImpl = class {
|
|
2026
2098
|
constructor(params) {
|
|
2027
2099
|
/**
|
|
@@ -2041,9 +2113,9 @@ var DataServiceImpl = class {
|
|
|
2041
2113
|
synchronizer.open().then(() => {
|
|
2042
2114
|
this._subscriptions.set(request.subscriptionId, synchronizer);
|
|
2043
2115
|
ready();
|
|
2044
|
-
}).catch((err) =>
|
|
2045
|
-
F:
|
|
2046
|
-
L:
|
|
2116
|
+
}).catch((err) => log7.catch(err, void 0, {
|
|
2117
|
+
F: __dxlog_file8,
|
|
2118
|
+
L: 66,
|
|
2047
2119
|
S: this,
|
|
2048
2120
|
C: (f, a) => f(...a)
|
|
2049
2121
|
}));
|
|
@@ -2053,8 +2125,8 @@ var DataServiceImpl = class {
|
|
|
2053
2125
|
async updateSubscription(request) {
|
|
2054
2126
|
const synchronizer = this._subscriptions.get(request.subscriptionId);
|
|
2055
2127
|
invariant7(synchronizer, "Subscription not found", {
|
|
2056
|
-
F:
|
|
2057
|
-
L:
|
|
2128
|
+
F: __dxlog_file8,
|
|
2129
|
+
L: 73,
|
|
2058
2130
|
S: this,
|
|
2059
2131
|
A: [
|
|
2060
2132
|
"synchronizer",
|
|
@@ -2074,8 +2146,8 @@ var DataServiceImpl = class {
|
|
|
2074
2146
|
}
|
|
2075
2147
|
const synchronizer = this._subscriptions.get(request.subscriptionId);
|
|
2076
2148
|
invariant7(synchronizer, "Subscription not found", {
|
|
2077
|
-
F:
|
|
2078
|
-
L:
|
|
2149
|
+
F: __dxlog_file8,
|
|
2150
|
+
L: 88,
|
|
2079
2151
|
S: this,
|
|
2080
2152
|
A: [
|
|
2081
2153
|
"synchronizer",
|
|
@@ -2115,38 +2187,1333 @@ var DataServiceImpl = class {
|
|
|
2115
2187
|
async updateIndexes() {
|
|
2116
2188
|
await this._updateIndexes();
|
|
2117
2189
|
}
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2190
|
+
subscribeSpaceSyncState(request) {
|
|
2191
|
+
return new Stream(({ ctx, next, ready }) => {
|
|
2192
|
+
invariant7(SpaceId2.isValid(request.spaceId), void 0, {
|
|
2193
|
+
F: __dxlog_file8,
|
|
2194
|
+
L: 127,
|
|
2195
|
+
S: this,
|
|
2196
|
+
A: [
|
|
2197
|
+
"SpaceId.isValid(request.spaceId)",
|
|
2198
|
+
""
|
|
2199
|
+
]
|
|
2200
|
+
});
|
|
2201
|
+
const collectionId = deriveCollectionIdFromSpaceId(request.spaceId);
|
|
2202
|
+
const scheduler = new UpdateScheduler2(ctx, async () => {
|
|
2203
|
+
const state = await this._automergeHost.getCollectionSyncState(collectionId);
|
|
2204
|
+
next({
|
|
2205
|
+
peers: state.peers.map((peer) => ({
|
|
2206
|
+
peerId: peer.peerId,
|
|
2207
|
+
missingOnRemote: peer.missingOnRemote,
|
|
2208
|
+
missingOnLocal: peer.missingOnLocal,
|
|
2209
|
+
differentDocuments: peer.differentDocuments,
|
|
2210
|
+
localDocumentCount: peer.localDocumentCount,
|
|
2211
|
+
remoteDocumentCount: peer.remoteDocumentCount
|
|
2212
|
+
}))
|
|
2213
|
+
});
|
|
2214
|
+
});
|
|
2215
|
+
this._automergeHost.collectionStateUpdated.on(ctx, (e) => {
|
|
2216
|
+
if (e.collectionId === collectionId) {
|
|
2217
|
+
scheduler.trigger();
|
|
2218
|
+
}
|
|
2219
|
+
});
|
|
2220
|
+
scheduler.trigger();
|
|
2127
2221
|
});
|
|
2128
|
-
|
|
2129
|
-
|
|
2222
|
+
}
|
|
2223
|
+
};
|
|
2224
|
+
|
|
2225
|
+
// packages/core/echo/echo-pipeline/src/db-host/echo-host.ts
|
|
2226
|
+
import { LifecycleState as LifecycleState4, Resource as Resource9 } from "@dxos/context";
|
|
2227
|
+
import { todo } from "@dxos/debug";
|
|
2228
|
+
import { createIdFromSpaceKey as createIdFromSpaceKey3, SpaceDocVersion as SpaceDocVersion3 } from "@dxos/echo-protocol";
|
|
2229
|
+
import { IndexMetadataStore, IndexStore, Indexer } from "@dxos/indexing";
|
|
2230
|
+
import { invariant as invariant11 } from "@dxos/invariant";
|
|
2231
|
+
import { IndexKind } from "@dxos/protocols/proto/dxos/echo/indexing";
|
|
2232
|
+
import { trace as trace5 } from "@dxos/tracing";
|
|
2233
|
+
|
|
2234
|
+
// packages/core/echo/echo-pipeline/src/db-host/documents-iterator.ts
|
|
2235
|
+
import * as A3 from "@dxos/automerge/automerge";
|
|
2236
|
+
import { Context as Context2 } from "@dxos/context";
|
|
2237
|
+
import { SpaceDocVersion } from "@dxos/echo-protocol";
|
|
2238
|
+
import { invariant as invariant8 } from "@dxos/invariant";
|
|
2239
|
+
import { log as log8 } from "@dxos/log";
|
|
2240
|
+
import { ObjectPointerVersion, objectPointerCodec as objectPointerCodec2 } from "@dxos/protocols";
|
|
2241
|
+
var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/documents-iterator.ts";
|
|
2242
|
+
var LOG_VIEW_OPERATION_THRESHOLD = 300;
|
|
2243
|
+
var createSelectedDocumentsIterator = (automergeHost) => (
|
|
2244
|
+
/**
|
|
2245
|
+
* Get object data blobs from Automerge Repo by ids.
|
|
2246
|
+
*/
|
|
2247
|
+
// TODO(mykola): Unload automerge handles after usage.
|
|
2248
|
+
async function* loadDocuments(objects) {
|
|
2249
|
+
for (const [id, heads] of objects.entries()) {
|
|
2250
|
+
try {
|
|
2251
|
+
const { documentId, objectId } = objectPointerCodec2.decode(id);
|
|
2252
|
+
const handle = await automergeHost.loadDoc(Context2.default(void 0, {
|
|
2253
|
+
F: __dxlog_file9,
|
|
2254
|
+
L: 30
|
|
2255
|
+
}), documentId);
|
|
2256
|
+
let doc = handle.docSync();
|
|
2257
|
+
invariant8(doc, void 0, {
|
|
2258
|
+
F: __dxlog_file9,
|
|
2259
|
+
L: 33,
|
|
2260
|
+
S: this,
|
|
2261
|
+
A: [
|
|
2262
|
+
"doc",
|
|
2263
|
+
""
|
|
2264
|
+
]
|
|
2265
|
+
});
|
|
2266
|
+
const currentHeads = A3.getHeads(doc);
|
|
2267
|
+
if (!A3.equals(currentHeads, heads)) {
|
|
2268
|
+
const begin = Date.now();
|
|
2269
|
+
doc = A3.view(doc, heads);
|
|
2270
|
+
const end = Date.now();
|
|
2271
|
+
if (end - begin > LOG_VIEW_OPERATION_THRESHOLD) {
|
|
2272
|
+
log8.info("Checking out document version is taking too long", {
|
|
2273
|
+
duration: end - begin,
|
|
2274
|
+
requestedHeads: heads,
|
|
2275
|
+
originalHeads: currentHeads
|
|
2276
|
+
}, {
|
|
2277
|
+
F: __dxlog_file9,
|
|
2278
|
+
L: 44,
|
|
2279
|
+
S: this,
|
|
2280
|
+
C: (f, a) => f(...a)
|
|
2281
|
+
});
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
if (doc.version !== SpaceDocVersion.CURRENT) {
|
|
2285
|
+
continue;
|
|
2286
|
+
}
|
|
2287
|
+
if (!doc.objects?.[objectId]) {
|
|
2288
|
+
continue;
|
|
2289
|
+
}
|
|
2290
|
+
let newId = id;
|
|
2291
|
+
if (objectPointerCodec2.getVersion(id) === ObjectPointerVersion.V0) {
|
|
2292
|
+
const spaceKey = getSpaceKeyFromDoc(doc) ?? void 0;
|
|
2293
|
+
newId = objectPointerCodec2.encode({
|
|
2294
|
+
documentId,
|
|
2295
|
+
objectId,
|
|
2296
|
+
spaceKey
|
|
2297
|
+
});
|
|
2298
|
+
}
|
|
2299
|
+
yield [
|
|
2300
|
+
{
|
|
2301
|
+
id: newId,
|
|
2302
|
+
object: doc.objects[objectId],
|
|
2303
|
+
heads
|
|
2304
|
+
}
|
|
2305
|
+
];
|
|
2306
|
+
} catch (error) {
|
|
2307
|
+
log8.error("Error loading document", {
|
|
2308
|
+
heads,
|
|
2309
|
+
id,
|
|
2310
|
+
error
|
|
2311
|
+
}, {
|
|
2312
|
+
F: __dxlog_file9,
|
|
2313
|
+
L: 70,
|
|
2314
|
+
S: this,
|
|
2315
|
+
C: (f, a) => f(...a)
|
|
2316
|
+
});
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
);
|
|
2321
|
+
|
|
2322
|
+
// packages/core/echo/echo-pipeline/src/db-host/query-service.ts
|
|
2323
|
+
import { DeferredTask } from "@dxos/async";
|
|
2324
|
+
import { getHeads as getHeads3 } from "@dxos/automerge/automerge";
|
|
2325
|
+
import { Stream as Stream2 } from "@dxos/codec-protobuf";
|
|
2326
|
+
import { Context as Context4, Resource as Resource7 } from "@dxos/context";
|
|
2327
|
+
import { log as log9 } from "@dxos/log";
|
|
2328
|
+
import { objectPointerCodec as objectPointerCodec4 } from "@dxos/protocols";
|
|
2329
|
+
import { trace as trace4 } from "@dxos/tracing";
|
|
2330
|
+
|
|
2331
|
+
// packages/core/echo/echo-pipeline/src/db-host/query-state.ts
|
|
2332
|
+
import { Context as Context3, LifecycleState as LifecycleState3, Resource as Resource6 } from "@dxos/context";
|
|
2333
|
+
import { createIdFromSpaceKey as createIdFromSpaceKey2 } from "@dxos/echo-protocol";
|
|
2334
|
+
import { invariant as invariant9 } from "@dxos/invariant";
|
|
2335
|
+
import { PublicKey as PublicKey3 } from "@dxos/keys";
|
|
2336
|
+
import { objectPointerCodec as objectPointerCodec3 } from "@dxos/protocols";
|
|
2337
|
+
import { trace as trace3 } from "@dxos/tracing";
|
|
2338
|
+
import { nonNullable as nonNullable2 } from "@dxos/util";
|
|
2339
|
+
function _ts_decorate4(decorators, target, key, desc) {
|
|
2340
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2341
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2342
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2343
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2344
|
+
}
|
|
2345
|
+
var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/query-state.ts";
|
|
2346
|
+
var QueryState = class extends Resource6 {
|
|
2347
|
+
get active() {
|
|
2348
|
+
return this._lifecycleState === LifecycleState3.OPEN;
|
|
2349
|
+
}
|
|
2350
|
+
constructor(_params) {
|
|
2351
|
+
super();
|
|
2352
|
+
this._params = _params;
|
|
2353
|
+
this._results = [];
|
|
2354
|
+
this._firstRun = true;
|
|
2355
|
+
this.metrics = {
|
|
2356
|
+
objectsReturned: 0,
|
|
2357
|
+
objectsReturnedFromIndex: 0,
|
|
2358
|
+
documentsLoaded: 0,
|
|
2359
|
+
executionTime: 0,
|
|
2360
|
+
indexQueryTime: 0,
|
|
2361
|
+
documentLoadTime: 0
|
|
2362
|
+
};
|
|
2363
|
+
this.filter = _params.request.filter;
|
|
2364
|
+
}
|
|
2365
|
+
getResults() {
|
|
2366
|
+
return this._results;
|
|
2367
|
+
}
|
|
2368
|
+
// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/attributes-registry/db.md#generic-database-attributes
|
|
2369
|
+
async execQuery() {
|
|
2370
|
+
const filter = this._params.request.filter;
|
|
2371
|
+
const beginQuery = performance.now();
|
|
2372
|
+
const hits = filter.objectIds && filter.objectIds?.length > 0 ? [] : await this._params.indexer.execQuery(filterToIndexQuery(filter));
|
|
2373
|
+
if (this._firstRun) {
|
|
2374
|
+
this.metrics.indexQueryTime = performance.now() - beginQuery;
|
|
2375
|
+
}
|
|
2376
|
+
const beginFilter = performance.now();
|
|
2377
|
+
const results = (await Promise.all(hits.map(async (result) => {
|
|
2378
|
+
if (this._firstRun) {
|
|
2379
|
+
this.metrics.objectsReturnedFromIndex++;
|
|
2380
|
+
}
|
|
2381
|
+
const { objectId, documentId, spaceKey: spaceKeyInIndex } = objectPointerCodec3.decode(result.id);
|
|
2382
|
+
let spaceKey;
|
|
2383
|
+
if (spaceKeyInIndex !== void 0) {
|
|
2384
|
+
spaceKey = spaceKeyInIndex;
|
|
2385
|
+
} else {
|
|
2386
|
+
if (this._firstRun) {
|
|
2387
|
+
this.metrics.documentsLoaded++;
|
|
2388
|
+
}
|
|
2389
|
+
const handle = await this._params.automergeHost.loadDoc(Context3.default(void 0, {
|
|
2390
|
+
F: __dxlog_file10,
|
|
2391
|
+
L: 116
|
|
2392
|
+
}), documentId);
|
|
2393
|
+
if (this._ctx.disposed) {
|
|
2394
|
+
return;
|
|
2395
|
+
}
|
|
2396
|
+
spaceKey = getSpaceKeyFromDoc(handle.docSync());
|
|
2397
|
+
}
|
|
2398
|
+
if (!spaceKey) {
|
|
2399
|
+
return;
|
|
2400
|
+
}
|
|
2401
|
+
if (this._params.request.filter.options?.spaces?.length && !this._params.request.filter.options.spaces.some((key) => key.equals(spaceKey))) {
|
|
2402
|
+
return;
|
|
2403
|
+
}
|
|
2404
|
+
if (this._firstRun) {
|
|
2405
|
+
this.metrics.objectsReturned++;
|
|
2406
|
+
}
|
|
2407
|
+
return {
|
|
2408
|
+
id: objectId,
|
|
2409
|
+
documentId,
|
|
2410
|
+
spaceId: await createIdFromSpaceKey2(PublicKey3.from(spaceKey)),
|
|
2411
|
+
spaceKey: PublicKey3.from(spaceKey),
|
|
2412
|
+
rank: result.rank
|
|
2413
|
+
};
|
|
2414
|
+
}))).filter(nonNullable2);
|
|
2415
|
+
if (this._firstRun) {
|
|
2416
|
+
this.metrics.documentLoadTime = performance.now() - beginFilter;
|
|
2417
|
+
}
|
|
2418
|
+
if (this._ctx.disposed) {
|
|
2419
|
+
return {
|
|
2420
|
+
changed: false
|
|
2421
|
+
};
|
|
2422
|
+
}
|
|
2423
|
+
const areResultsUnchanged = !this._firstRun && this._results.length === results.length && this._results.every((oldResult) => results.some((result) => result.id === oldResult.id)) && results.every((result) => this._results.some((oldResult) => oldResult.id === result.id));
|
|
2424
|
+
if (this._firstRun) {
|
|
2425
|
+
this.metrics.executionTime = performance.now() - beginQuery;
|
|
2426
|
+
}
|
|
2427
|
+
this._firstRun = false;
|
|
2428
|
+
if (areResultsUnchanged) {
|
|
2429
|
+
return {
|
|
2430
|
+
changed: false
|
|
2431
|
+
};
|
|
2432
|
+
}
|
|
2433
|
+
this._results = results;
|
|
2434
|
+
return {
|
|
2435
|
+
changed: true
|
|
2436
|
+
};
|
|
2437
|
+
}
|
|
2438
|
+
};
|
|
2439
|
+
_ts_decorate4([
|
|
2440
|
+
trace3.info({
|
|
2441
|
+
depth: null
|
|
2442
|
+
})
|
|
2443
|
+
], QueryState.prototype, "filter", void 0);
|
|
2444
|
+
_ts_decorate4([
|
|
2445
|
+
trace3.info()
|
|
2446
|
+
], QueryState.prototype, "metrics", void 0);
|
|
2447
|
+
_ts_decorate4([
|
|
2448
|
+
trace3.info()
|
|
2449
|
+
], QueryState.prototype, "active", null);
|
|
2450
|
+
_ts_decorate4([
|
|
2451
|
+
trace3.span({
|
|
2452
|
+
showInBrowserTimeline: true,
|
|
2453
|
+
op: "db.query",
|
|
2454
|
+
attributes: {
|
|
2455
|
+
"db.system": "echo"
|
|
2456
|
+
}
|
|
2457
|
+
})
|
|
2458
|
+
], QueryState.prototype, "execQuery", null);
|
|
2459
|
+
QueryState = _ts_decorate4([
|
|
2460
|
+
trace3.resource()
|
|
2461
|
+
], QueryState);
|
|
2462
|
+
var filterToIndexQuery = (filter) => {
|
|
2463
|
+
invariant9(!(filter.type && (filter.or ?? []).length > 0), "Cannot mix type and or filters.", {
|
|
2464
|
+
F: __dxlog_file10,
|
|
2465
|
+
L: 181,
|
|
2466
|
+
S: void 0,
|
|
2467
|
+
A: [
|
|
2468
|
+
"!(filter.type && (filter.or ?? []).length > 0)",
|
|
2469
|
+
"'Cannot mix type and or filters.'"
|
|
2470
|
+
]
|
|
2471
|
+
});
|
|
2472
|
+
invariant9((filter.or ?? []).every((subFilter) => !(subFilter.type && (subFilter.or ?? []).length > 0)), "Cannot mix type and or filters.", {
|
|
2473
|
+
F: __dxlog_file10,
|
|
2474
|
+
L: 182,
|
|
2475
|
+
S: void 0,
|
|
2476
|
+
A: [
|
|
2477
|
+
"(filter.or ?? []).every((subFilter) => !(subFilter.type && (subFilter.or ?? []).length > 0))",
|
|
2478
|
+
"'Cannot mix type and or filters.'"
|
|
2479
|
+
]
|
|
2480
|
+
});
|
|
2481
|
+
if (filter.type || (filter.or ?? []).length > 0 && (filter.or ?? []).every((subFilter) => !subFilter.not && subFilter.type)) {
|
|
2482
|
+
return {
|
|
2483
|
+
typenames: filter.type?.objectId ? [
|
|
2484
|
+
filter.type.objectId
|
|
2485
|
+
] : (filter.or ?? []).map((f) => f.type?.objectId).filter(nonNullable2),
|
|
2486
|
+
inverted: filter.not
|
|
2487
|
+
};
|
|
2488
|
+
} else {
|
|
2130
2489
|
return {
|
|
2131
|
-
|
|
2132
|
-
peerId: peer.peerId,
|
|
2133
|
-
documentsToReconcile: peer.differentDocuments
|
|
2134
|
-
}))
|
|
2490
|
+
typenames: []
|
|
2135
2491
|
};
|
|
2136
2492
|
}
|
|
2137
2493
|
};
|
|
2138
2494
|
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2495
|
+
// packages/core/echo/echo-pipeline/src/db-host/query-service.ts
|
|
2496
|
+
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/query-service.ts";
|
|
2497
|
+
var QueryServiceImpl = class extends Resource7 {
|
|
2498
|
+
// TODO(burdon): OK for options, but not params. Pass separately and type readonly here.
|
|
2499
|
+
constructor(_params) {
|
|
2500
|
+
super();
|
|
2501
|
+
this._params = _params;
|
|
2502
|
+
this._queries = /* @__PURE__ */ new Set();
|
|
2503
|
+
this._updateQueries = new DeferredTask(this._ctx, async () => {
|
|
2504
|
+
await Promise.all(Array.from(this._queries).map(async (query) => {
|
|
2505
|
+
try {
|
|
2506
|
+
const { changed } = await query.state.execQuery();
|
|
2507
|
+
if (changed) {
|
|
2508
|
+
query.sendResults(query.state.getResults());
|
|
2509
|
+
}
|
|
2510
|
+
} catch (err) {
|
|
2511
|
+
log9.catch(err, void 0, {
|
|
2512
|
+
F: __dxlog_file11,
|
|
2513
|
+
L: 52,
|
|
2514
|
+
S: this,
|
|
2515
|
+
C: (f, a) => f(...a)
|
|
2516
|
+
});
|
|
2517
|
+
}
|
|
2518
|
+
}));
|
|
2519
|
+
});
|
|
2520
|
+
trace4.diagnostic({
|
|
2521
|
+
id: "active-queries",
|
|
2522
|
+
name: "Active Queries",
|
|
2523
|
+
fetch: () => {
|
|
2524
|
+
return Array.from(this._queries).map((query) => {
|
|
2525
|
+
return {
|
|
2526
|
+
filter: JSON.stringify(query.state.filter),
|
|
2527
|
+
metrics: query.state.metrics
|
|
2528
|
+
};
|
|
2529
|
+
});
|
|
2530
|
+
}
|
|
2531
|
+
});
|
|
2532
|
+
}
|
|
2533
|
+
async _open() {
|
|
2534
|
+
this._params.indexer.updated.on(this._ctx, () => this._updateQueries.schedule());
|
|
2535
|
+
}
|
|
2536
|
+
async _close() {
|
|
2537
|
+
await Promise.all(Array.from(this._queries).map((query) => query.close()));
|
|
2538
|
+
}
|
|
2539
|
+
async setConfig(config) {
|
|
2540
|
+
if (this._params.indexer.initialized) {
|
|
2541
|
+
log9.warn("Indexer already initialized.", void 0, {
|
|
2542
|
+
F: __dxlog_file11,
|
|
2543
|
+
L: 86,
|
|
2544
|
+
S: this,
|
|
2545
|
+
C: (f, a) => f(...a)
|
|
2546
|
+
});
|
|
2547
|
+
return;
|
|
2548
|
+
}
|
|
2549
|
+
this._params.indexer.setConfig(config);
|
|
2550
|
+
}
|
|
2551
|
+
execQuery(request) {
|
|
2552
|
+
return new Stream2(({ next, close, ctx }) => {
|
|
2553
|
+
const query = {
|
|
2554
|
+
state: new QueryState({
|
|
2555
|
+
indexer: this._params.indexer,
|
|
2556
|
+
automergeHost: this._params.automergeHost,
|
|
2557
|
+
request
|
|
2558
|
+
}),
|
|
2559
|
+
sendResults: (results) => {
|
|
2560
|
+
if (ctx.disposed) {
|
|
2561
|
+
return;
|
|
2562
|
+
}
|
|
2563
|
+
next({
|
|
2564
|
+
queryId: request.queryId,
|
|
2565
|
+
results
|
|
2566
|
+
});
|
|
2567
|
+
},
|
|
2568
|
+
close: async () => {
|
|
2569
|
+
close();
|
|
2570
|
+
await query.state.close();
|
|
2571
|
+
this._queries.delete(query);
|
|
2572
|
+
}
|
|
2573
|
+
};
|
|
2574
|
+
this._queries.add(query);
|
|
2575
|
+
queueMicrotask(async () => {
|
|
2576
|
+
await query.state.open();
|
|
2577
|
+
try {
|
|
2578
|
+
const { changed } = await query.state.execQuery();
|
|
2579
|
+
if (changed) {
|
|
2580
|
+
query.sendResults(query.state.getResults());
|
|
2581
|
+
}
|
|
2582
|
+
} catch (error) {
|
|
2583
|
+
log9.catch(error, void 0, {
|
|
2584
|
+
F: __dxlog_file11,
|
|
2585
|
+
L: 123,
|
|
2586
|
+
S: this,
|
|
2587
|
+
C: (f, a) => f(...a)
|
|
2588
|
+
});
|
|
2589
|
+
}
|
|
2590
|
+
});
|
|
2591
|
+
return query.close;
|
|
2592
|
+
});
|
|
2593
|
+
}
|
|
2594
|
+
/**
|
|
2595
|
+
* Re-index all loaded documents.
|
|
2596
|
+
*/
|
|
2597
|
+
async reindex() {
|
|
2598
|
+
log9.info("Reindexing all documents...", void 0, {
|
|
2599
|
+
F: __dxlog_file11,
|
|
2600
|
+
L: 135,
|
|
2601
|
+
S: this,
|
|
2602
|
+
C: (f, a) => f(...a)
|
|
2603
|
+
});
|
|
2604
|
+
const iterator = createDocumentsIterator(this._params.automergeHost);
|
|
2605
|
+
const ids = /* @__PURE__ */ new Map();
|
|
2606
|
+
for await (const documents of iterator()) {
|
|
2607
|
+
for (const { id, heads } of documents) {
|
|
2608
|
+
ids.set(id, heads);
|
|
2609
|
+
}
|
|
2610
|
+
if (ids.size % 100 === 0) {
|
|
2611
|
+
log9.info("Collected documents...", {
|
|
2612
|
+
count: ids.size
|
|
2613
|
+
}, {
|
|
2614
|
+
F: __dxlog_file11,
|
|
2615
|
+
L: 143,
|
|
2616
|
+
S: this,
|
|
2617
|
+
C: (f, a) => f(...a)
|
|
2618
|
+
});
|
|
2619
|
+
}
|
|
2620
|
+
}
|
|
2621
|
+
log9.info("Marking all documents as dirty...", {
|
|
2622
|
+
count: ids.size
|
|
2623
|
+
}, {
|
|
2624
|
+
F: __dxlog_file11,
|
|
2625
|
+
L: 147,
|
|
2626
|
+
S: this,
|
|
2627
|
+
C: (f, a) => f(...a)
|
|
2628
|
+
});
|
|
2629
|
+
await this._params.indexer.reindex(ids);
|
|
2630
|
+
}
|
|
2631
|
+
};
|
|
2632
|
+
var createDocumentsIterator = (automergeHost) => (
|
|
2633
|
+
/**
|
|
2634
|
+
* Recursively get all object data blobs from loaded documents from Automerge Repo.
|
|
2635
|
+
*/
|
|
2636
|
+
// TODO(mykola): Unload automerge handles after usage.
|
|
2637
|
+
async function* getAllDocuments() {
|
|
2638
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2639
|
+
async function* getObjectsFromHandle(handle) {
|
|
2640
|
+
if (visited.has(handle.documentId)) {
|
|
2641
|
+
return;
|
|
2642
|
+
}
|
|
2643
|
+
const doc = handle.docSync();
|
|
2644
|
+
const spaceKey = getSpaceKeyFromDoc(doc) ?? void 0;
|
|
2645
|
+
if (doc.objects) {
|
|
2646
|
+
yield Object.entries(doc.objects).map(([objectId, object]) => {
|
|
2647
|
+
return {
|
|
2648
|
+
id: objectPointerCodec4.encode({
|
|
2649
|
+
documentId: handle.documentId,
|
|
2650
|
+
objectId,
|
|
2651
|
+
spaceKey
|
|
2652
|
+
}),
|
|
2653
|
+
object,
|
|
2654
|
+
heads: getHeads3(doc)
|
|
2655
|
+
};
|
|
2656
|
+
});
|
|
2657
|
+
}
|
|
2658
|
+
if (doc.links) {
|
|
2659
|
+
for (const id of Object.values(doc.links)) {
|
|
2660
|
+
if (visited.has(id)) {
|
|
2661
|
+
continue;
|
|
2662
|
+
}
|
|
2663
|
+
const linkHandle = await automergeHost.loadDoc(Context4.default(void 0, {
|
|
2664
|
+
F: __dxlog_file11,
|
|
2665
|
+
L: 188
|
|
2666
|
+
}), id);
|
|
2667
|
+
for await (const result of getObjectsFromHandle(linkHandle)) {
|
|
2668
|
+
yield result;
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2671
|
+
}
|
|
2672
|
+
visited.add(handle.documentId);
|
|
2673
|
+
}
|
|
2674
|
+
for (const handle of Object.values(automergeHost.repo.handles)) {
|
|
2675
|
+
if (visited.has(handle.documentId)) {
|
|
2676
|
+
continue;
|
|
2677
|
+
}
|
|
2678
|
+
for await (const result of getObjectsFromHandle(handle)) {
|
|
2679
|
+
yield result;
|
|
2680
|
+
}
|
|
2681
|
+
visited.add(handle.documentId);
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2684
|
+
);
|
|
2685
|
+
|
|
2686
|
+
// packages/core/echo/echo-pipeline/src/db-host/space-state-manager.ts
|
|
2687
|
+
import isEqual from "lodash.isequal";
|
|
2688
|
+
import { Event as Event3, UpdateScheduler as UpdateScheduler3 } from "@dxos/async";
|
|
2689
|
+
import { interpretAsDocumentId } from "@dxos/automerge/automerge-repo";
|
|
2690
|
+
import { Resource as Resource8, Context as Context5 } from "@dxos/context";
|
|
2691
|
+
|
|
2692
|
+
// packages/core/echo/echo-pipeline/src/db-host/database-root.ts
|
|
2693
|
+
import { SpaceDocVersion as SpaceDocVersion2 } from "@dxos/echo-protocol";
|
|
2694
|
+
import { invariant as invariant10 } from "@dxos/invariant";
|
|
2695
|
+
|
|
2696
|
+
// packages/core/echo/echo-pipeline/src/db-host/automerge-metrics.ts
|
|
2697
|
+
import * as A4 from "@dxos/automerge/automerge";
|
|
2698
|
+
import { log as log10 } from "@dxos/log";
|
|
2699
|
+
var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/automerge-metrics.ts";
|
|
2700
|
+
var measureDocMetrics = (doc) => {
|
|
2701
|
+
const snapshot = A4.save(doc);
|
|
2702
|
+
const start = Date.now();
|
|
2703
|
+
const temp = A4.load(snapshot);
|
|
2704
|
+
const end = Date.now();
|
|
2705
|
+
A4.free(temp);
|
|
2706
|
+
const getAllChangesStart = Date.now();
|
|
2707
|
+
const mutationCount = A4.getAllChanges(doc).length;
|
|
2708
|
+
const getAllChangesEnd = Date.now();
|
|
2709
|
+
if (getAllChangesEnd - getAllChangesStart > 300) {
|
|
2710
|
+
log10.warn("getAllChanges took too long", {
|
|
2711
|
+
elapsed: getAllChangesEnd - getAllChangesStart
|
|
2712
|
+
}, {
|
|
2713
|
+
F: __dxlog_file12,
|
|
2714
|
+
L: 30,
|
|
2715
|
+
S: void 0,
|
|
2716
|
+
C: (f, a) => f(...a)
|
|
2717
|
+
});
|
|
2718
|
+
}
|
|
2719
|
+
return {
|
|
2720
|
+
compressedByteSize: snapshot.byteLength,
|
|
2721
|
+
loadTime: end - start,
|
|
2722
|
+
mutationCount
|
|
2723
|
+
};
|
|
2724
|
+
};
|
|
2725
|
+
|
|
2726
|
+
// packages/core/echo/echo-pipeline/src/db-host/database-root.ts
|
|
2727
|
+
var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/database-root.ts";
|
|
2728
|
+
var DatabaseRoot = class {
|
|
2729
|
+
constructor(_rootHandle) {
|
|
2730
|
+
this._rootHandle = _rootHandle;
|
|
2731
|
+
}
|
|
2732
|
+
get documentId() {
|
|
2733
|
+
return this._rootHandle.documentId;
|
|
2734
|
+
}
|
|
2735
|
+
get url() {
|
|
2736
|
+
return this._rootHandle.url;
|
|
2737
|
+
}
|
|
2738
|
+
get isLoaded() {
|
|
2739
|
+
return !!this._rootHandle.docSync();
|
|
2740
|
+
}
|
|
2741
|
+
get handle() {
|
|
2742
|
+
return this._rootHandle;
|
|
2743
|
+
}
|
|
2744
|
+
docSync() {
|
|
2745
|
+
return this._rootHandle.docSync();
|
|
2746
|
+
}
|
|
2747
|
+
getVersion() {
|
|
2748
|
+
const doc = this.docSync();
|
|
2749
|
+
if (!doc) {
|
|
2750
|
+
return null;
|
|
2751
|
+
}
|
|
2752
|
+
return doc.version ?? SpaceDocVersion2.LEGACY;
|
|
2753
|
+
}
|
|
2754
|
+
getSpaceKey() {
|
|
2755
|
+
const doc = this.docSync();
|
|
2756
|
+
if (!doc) {
|
|
2757
|
+
return null;
|
|
2758
|
+
}
|
|
2759
|
+
return getSpaceKeyFromDoc(doc);
|
|
2760
|
+
}
|
|
2761
|
+
getInlineObjectCount() {
|
|
2762
|
+
const doc = this.docSync();
|
|
2763
|
+
if (!doc) {
|
|
2764
|
+
return null;
|
|
2765
|
+
}
|
|
2766
|
+
return Object.keys(doc.objects ?? {}).length;
|
|
2767
|
+
}
|
|
2768
|
+
getLinkedObjectCount() {
|
|
2769
|
+
const doc = this.docSync();
|
|
2770
|
+
if (!doc) {
|
|
2771
|
+
return null;
|
|
2772
|
+
}
|
|
2773
|
+
return Object.keys(doc.links ?? {}).length;
|
|
2774
|
+
}
|
|
2775
|
+
getAllLinkedDocuments() {
|
|
2776
|
+
const doc = this.docSync();
|
|
2777
|
+
invariant10(doc, void 0, {
|
|
2778
|
+
F: __dxlog_file13,
|
|
2779
|
+
L: 74,
|
|
2780
|
+
S: this,
|
|
2781
|
+
A: [
|
|
2782
|
+
"doc",
|
|
2783
|
+
""
|
|
2784
|
+
]
|
|
2785
|
+
});
|
|
2786
|
+
return Object.values(doc.links ?? {});
|
|
2787
|
+
}
|
|
2788
|
+
measureMetrics() {
|
|
2789
|
+
const doc = this.docSync();
|
|
2790
|
+
if (!doc) {
|
|
2791
|
+
return null;
|
|
2792
|
+
}
|
|
2793
|
+
return measureDocMetrics(doc);
|
|
2794
|
+
}
|
|
2795
|
+
};
|
|
2796
|
+
|
|
2797
|
+
// packages/core/echo/echo-pipeline/src/db-host/space-state-manager.ts
|
|
2798
|
+
var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/space-state-manager.ts";
|
|
2799
|
+
var SpaceStateManager = class extends Resource8 {
|
|
2800
|
+
constructor() {
|
|
2801
|
+
super(...arguments);
|
|
2802
|
+
this._roots = /* @__PURE__ */ new Map();
|
|
2803
|
+
this._rootBySpace = /* @__PURE__ */ new Map();
|
|
2804
|
+
this._perRootContext = /* @__PURE__ */ new Map();
|
|
2805
|
+
this._lastSpaceDocumentList = /* @__PURE__ */ new Map();
|
|
2806
|
+
this.spaceDocumentListUpdated = new Event3();
|
|
2807
|
+
}
|
|
2808
|
+
async _close(ctx) {
|
|
2809
|
+
for (const [_, rootCtx] of this._perRootContext) {
|
|
2810
|
+
await rootCtx.dispose();
|
|
2811
|
+
}
|
|
2812
|
+
this._roots.clear();
|
|
2813
|
+
}
|
|
2814
|
+
get roots() {
|
|
2815
|
+
return this._roots;
|
|
2816
|
+
}
|
|
2817
|
+
getRootByDocumentId(documentId) {
|
|
2818
|
+
return this._roots.get(documentId);
|
|
2819
|
+
}
|
|
2820
|
+
async assignRootToSpace(spaceId, handle) {
|
|
2821
|
+
let root;
|
|
2822
|
+
if (this._roots.has(handle.documentId)) {
|
|
2823
|
+
root = this._roots.get(handle.documentId);
|
|
2824
|
+
} else {
|
|
2825
|
+
root = new DatabaseRoot(handle);
|
|
2826
|
+
this._roots.set(handle.documentId, root);
|
|
2827
|
+
}
|
|
2828
|
+
if (this._rootBySpace.get(spaceId) === root.handle.documentId) {
|
|
2829
|
+
return root;
|
|
2830
|
+
}
|
|
2831
|
+
const prevRootId = this._rootBySpace.get(spaceId);
|
|
2832
|
+
if (prevRootId) {
|
|
2833
|
+
void this._perRootContext.get(prevRootId)?.dispose();
|
|
2834
|
+
this._perRootContext.delete(prevRootId);
|
|
2835
|
+
}
|
|
2836
|
+
this._rootBySpace.set(spaceId, root.handle.documentId);
|
|
2837
|
+
const ctx = new Context5(void 0, {
|
|
2838
|
+
F: __dxlog_file14,
|
|
2839
|
+
L: 58
|
|
2840
|
+
});
|
|
2841
|
+
this._perRootContext.set(root.handle.documentId, ctx);
|
|
2842
|
+
await root.handle.whenReady();
|
|
2843
|
+
const documentListCheckScheduler = new UpdateScheduler3(ctx, async () => {
|
|
2844
|
+
const documentIds = [
|
|
2845
|
+
root.documentId,
|
|
2846
|
+
...root.getAllLinkedDocuments().map((url) => interpretAsDocumentId(url))
|
|
2847
|
+
];
|
|
2848
|
+
if (!isEqual(documentIds, this._lastSpaceDocumentList.get(spaceId))) {
|
|
2849
|
+
this._lastSpaceDocumentList.set(spaceId, documentIds);
|
|
2850
|
+
this.spaceDocumentListUpdated.emit(new SpaceDocumentListUpdatedEvent(spaceId, documentIds));
|
|
2851
|
+
}
|
|
2852
|
+
}, {
|
|
2853
|
+
maxFrequency: 50
|
|
2854
|
+
});
|
|
2855
|
+
const triggerCheckOnChange = () => documentListCheckScheduler.trigger();
|
|
2856
|
+
root.handle.addListener("change", triggerCheckOnChange);
|
|
2857
|
+
ctx.onDispose(() => root.handle.removeListener("change", triggerCheckOnChange));
|
|
2858
|
+
documentListCheckScheduler.trigger();
|
|
2859
|
+
return root;
|
|
2860
|
+
}
|
|
2861
|
+
};
|
|
2862
|
+
var SpaceDocumentListUpdatedEvent = class {
|
|
2863
|
+
constructor(spaceId, documentIds) {
|
|
2864
|
+
this.spaceId = spaceId;
|
|
2865
|
+
this.documentIds = documentIds;
|
|
2866
|
+
}
|
|
2867
|
+
};
|
|
2868
|
+
|
|
2869
|
+
// packages/core/echo/echo-pipeline/src/db-host/echo-host.ts
|
|
2870
|
+
var __dxlog_file15 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/echo-host.ts";
|
|
2871
|
+
var INDEXER_CONFIG = {
|
|
2872
|
+
enabled: true,
|
|
2873
|
+
indexes: [
|
|
2874
|
+
{
|
|
2875
|
+
kind: IndexKind.Kind.SCHEMA_MATCH
|
|
2876
|
+
}
|
|
2877
|
+
]
|
|
2878
|
+
};
|
|
2879
|
+
var EchoHost = class extends Resource9 {
|
|
2880
|
+
constructor({ kv }) {
|
|
2881
|
+
super();
|
|
2882
|
+
this._spaceStateManager = new SpaceStateManager();
|
|
2883
|
+
this._indexMetadataStore = new IndexMetadataStore({
|
|
2884
|
+
db: kv.sublevel("index-metadata")
|
|
2885
|
+
});
|
|
2886
|
+
this._echoDataMonitor = new EchoDataMonitor();
|
|
2887
|
+
this._automergeHost = new AutomergeHost({
|
|
2888
|
+
db: kv,
|
|
2889
|
+
dataMonitor: this._echoDataMonitor,
|
|
2890
|
+
indexMetadataStore: this._indexMetadataStore
|
|
2891
|
+
});
|
|
2892
|
+
this._indexer = new Indexer({
|
|
2893
|
+
db: kv,
|
|
2894
|
+
indexStore: new IndexStore({
|
|
2895
|
+
db: kv.sublevel("index-storage")
|
|
2896
|
+
}),
|
|
2897
|
+
metadataStore: this._indexMetadataStore,
|
|
2898
|
+
loadDocuments: createSelectedDocumentsIterator(this._automergeHost),
|
|
2899
|
+
indexCooldownTime: process.env.NODE_ENV === "test" ? 0 : void 0
|
|
2900
|
+
});
|
|
2901
|
+
this._indexer.setConfig(INDEXER_CONFIG);
|
|
2902
|
+
this._queryService = new QueryServiceImpl({
|
|
2903
|
+
automergeHost: this._automergeHost,
|
|
2904
|
+
indexer: this._indexer
|
|
2905
|
+
});
|
|
2906
|
+
this._dataService = new DataServiceImpl({
|
|
2907
|
+
automergeHost: this._automergeHost,
|
|
2908
|
+
updateIndexes: async () => {
|
|
2909
|
+
await this._indexer.updateIndexes();
|
|
2910
|
+
}
|
|
2911
|
+
});
|
|
2912
|
+
trace5.diagnostic({
|
|
2913
|
+
id: "echo-stats",
|
|
2914
|
+
name: "Echo Stats",
|
|
2915
|
+
fetch: async () => {
|
|
2916
|
+
return {
|
|
2917
|
+
dataStats: this._echoDataMonitor.computeStats(),
|
|
2918
|
+
loadedDocsCount: this._automergeHost.loadedDocsCount
|
|
2919
|
+
};
|
|
2920
|
+
}
|
|
2921
|
+
});
|
|
2922
|
+
trace5.diagnostic({
|
|
2923
|
+
id: "database-roots",
|
|
2924
|
+
name: "Database Roots",
|
|
2925
|
+
fetch: async () => {
|
|
2926
|
+
return Array.from(this._spaceStateManager.roots.values()).map((root) => ({
|
|
2927
|
+
url: root.url,
|
|
2928
|
+
isLoaded: root.isLoaded,
|
|
2929
|
+
spaceKey: root.getSpaceKey(),
|
|
2930
|
+
inlineObjects: root.getInlineObjectCount(),
|
|
2931
|
+
linkedObjects: root.getLinkedObjectCount()
|
|
2932
|
+
}));
|
|
2933
|
+
}
|
|
2934
|
+
});
|
|
2935
|
+
trace5.diagnostic({
|
|
2936
|
+
id: "database-root-metrics",
|
|
2937
|
+
name: "Database Roots (with metrics)",
|
|
2938
|
+
fetch: async () => {
|
|
2939
|
+
return Array.from(this._spaceStateManager.roots.values()).map((root) => ({
|
|
2940
|
+
url: root.url,
|
|
2941
|
+
isLoaded: root.isLoaded,
|
|
2942
|
+
spaceKey: root.getSpaceKey(),
|
|
2943
|
+
inlineObjects: root.getInlineObjectCount(),
|
|
2944
|
+
linkedObjects: root.getLinkedObjectCount(),
|
|
2945
|
+
...root.measureMetrics() ?? {}
|
|
2946
|
+
}));
|
|
2947
|
+
}
|
|
2948
|
+
});
|
|
2949
|
+
}
|
|
2950
|
+
get queryService() {
|
|
2951
|
+
return this._queryService;
|
|
2952
|
+
}
|
|
2953
|
+
get dataService() {
|
|
2954
|
+
return this._dataService;
|
|
2955
|
+
}
|
|
2956
|
+
/**
|
|
2957
|
+
* @deprecated To be abstracted away.
|
|
2958
|
+
*/
|
|
2959
|
+
get automergeRepo() {
|
|
2960
|
+
return this._automergeHost.repo;
|
|
2961
|
+
}
|
|
2962
|
+
get roots() {
|
|
2963
|
+
return this._spaceStateManager.roots;
|
|
2964
|
+
}
|
|
2965
|
+
async _open(ctx) {
|
|
2966
|
+
await this._automergeHost.open();
|
|
2967
|
+
await this._indexer.open(ctx);
|
|
2968
|
+
await this._queryService.open(ctx);
|
|
2969
|
+
await this._spaceStateManager.open(ctx);
|
|
2970
|
+
this._spaceStateManager.spaceDocumentListUpdated.on(this._ctx, (e) => {
|
|
2971
|
+
void this._automergeHost.updateLocalCollectionState(deriveCollectionIdFromSpaceId(e.spaceId), e.documentIds);
|
|
2972
|
+
});
|
|
2973
|
+
}
|
|
2974
|
+
async _close(ctx) {
|
|
2975
|
+
await this._spaceStateManager.close();
|
|
2976
|
+
await this._queryService.close(ctx);
|
|
2977
|
+
await this._indexer.close(ctx);
|
|
2978
|
+
await this._automergeHost.close();
|
|
2979
|
+
}
|
|
2980
|
+
/**
|
|
2981
|
+
* Flush all pending writes to the underlying storage.
|
|
2982
|
+
*/
|
|
2983
|
+
async flush() {
|
|
2984
|
+
await this._automergeHost.repo.flush();
|
|
2985
|
+
}
|
|
2986
|
+
/**
|
|
2987
|
+
* Perform any pending index updates.
|
|
2988
|
+
*/
|
|
2989
|
+
async updateIndexes() {
|
|
2990
|
+
await this._indexer.updateIndexes();
|
|
2991
|
+
}
|
|
2992
|
+
/**
|
|
2993
|
+
* Loads the document handle from the repo and waits for it to be ready.
|
|
2994
|
+
*/
|
|
2995
|
+
async loadDoc(ctx, documentId, opts) {
|
|
2996
|
+
return await this._automergeHost.loadDoc(ctx, documentId, opts);
|
|
2997
|
+
}
|
|
2998
|
+
/**
|
|
2999
|
+
* Create new persisted document.
|
|
3000
|
+
*/
|
|
3001
|
+
createDoc(initialValue, opts) {
|
|
3002
|
+
return this._automergeHost.createDoc(initialValue, opts);
|
|
3003
|
+
}
|
|
3004
|
+
/**
|
|
3005
|
+
* Create new space root.
|
|
3006
|
+
*/
|
|
3007
|
+
async createSpaceRoot(spaceKey) {
|
|
3008
|
+
invariant11(this._lifecycleState === LifecycleState4.OPEN, void 0, {
|
|
3009
|
+
F: __dxlog_file15,
|
|
3010
|
+
L: 206,
|
|
3011
|
+
S: this,
|
|
3012
|
+
A: [
|
|
3013
|
+
"this._lifecycleState === LifecycleState.OPEN",
|
|
3014
|
+
""
|
|
3015
|
+
]
|
|
3016
|
+
});
|
|
3017
|
+
const spaceId = await createIdFromSpaceKey3(spaceKey);
|
|
3018
|
+
const automergeRoot = this._automergeHost.createDoc({
|
|
3019
|
+
version: SpaceDocVersion3.CURRENT,
|
|
3020
|
+
access: {
|
|
3021
|
+
spaceKey: spaceKey.toHex()
|
|
3022
|
+
}
|
|
3023
|
+
});
|
|
3024
|
+
await this._automergeHost.flush({
|
|
3025
|
+
documentIds: [
|
|
3026
|
+
automergeRoot.documentId
|
|
3027
|
+
]
|
|
3028
|
+
});
|
|
3029
|
+
return await this.openSpaceRoot(spaceId, automergeRoot.url);
|
|
3030
|
+
}
|
|
3031
|
+
// TODO(dmaretskyi): Change to document id.
|
|
3032
|
+
async openSpaceRoot(spaceId, automergeUrl) {
|
|
3033
|
+
invariant11(this._lifecycleState === LifecycleState4.OPEN, void 0, {
|
|
3034
|
+
F: __dxlog_file15,
|
|
3035
|
+
L: 221,
|
|
3036
|
+
S: this,
|
|
3037
|
+
A: [
|
|
3038
|
+
"this._lifecycleState === LifecycleState.OPEN",
|
|
3039
|
+
""
|
|
3040
|
+
]
|
|
3041
|
+
});
|
|
3042
|
+
const handle = this._automergeHost.repo.find(automergeUrl);
|
|
3043
|
+
return this._spaceStateManager.assignRootToSpace(spaceId, handle);
|
|
3044
|
+
}
|
|
3045
|
+
// TODO(dmaretskyi): Change to document id.
|
|
3046
|
+
async closeSpaceRoot(automergeUrl) {
|
|
3047
|
+
todo();
|
|
3048
|
+
}
|
|
3049
|
+
/**
|
|
3050
|
+
* Install data replicator.
|
|
3051
|
+
*/
|
|
3052
|
+
async addReplicator(replicator) {
|
|
3053
|
+
await this._automergeHost.addReplicator(replicator);
|
|
3054
|
+
}
|
|
3055
|
+
/**
|
|
3056
|
+
* Remove data replicator.
|
|
3057
|
+
*/
|
|
3058
|
+
async removeReplicator(replicator) {
|
|
3059
|
+
await this._automergeHost.removeReplicator(replicator);
|
|
3060
|
+
}
|
|
3061
|
+
async getSpaceSyncState(spaceId) {
|
|
3062
|
+
const collectionId = deriveCollectionIdFromSpaceId(spaceId);
|
|
3063
|
+
return this._automergeHost.getCollectionSyncState(collectionId);
|
|
3064
|
+
}
|
|
3065
|
+
};
|
|
3066
|
+
|
|
3067
|
+
// packages/core/echo/echo-pipeline/src/db-host/migration.ts
|
|
3068
|
+
import { convertLegacyReference } from "@dxos/echo-protocol";
|
|
3069
|
+
import { decodeReference, encodeReference, isLegacyReference, LEGACY_TYPE_PROPERTIES, Reference, SpaceDocVersion as SpaceDocVersion4 } from "@dxos/echo-protocol";
|
|
3070
|
+
import { TYPE_PROPERTIES } from "@dxos/echo-schema";
|
|
3071
|
+
import { deepMapValuesAsync } from "@dxos/util";
|
|
3072
|
+
var convertLegacyReferences = async (doc) => {
|
|
3073
|
+
const newDoc = await deepMapValuesAsync(doc, async (value, recurse) => {
|
|
3074
|
+
if (isLegacyReference(value)) {
|
|
3075
|
+
return convertLegacyReference(value);
|
|
3076
|
+
}
|
|
3077
|
+
return recurse(value);
|
|
3078
|
+
});
|
|
3079
|
+
newDoc.version = SpaceDocVersion4.CURRENT;
|
|
3080
|
+
return newDoc;
|
|
3081
|
+
};
|
|
3082
|
+
var convertLegacySpaceRootDoc = async (root) => {
|
|
3083
|
+
const newDoc = await convertLegacyReferences(root);
|
|
3084
|
+
const properties = findInlineObjectOfType(newDoc, LEGACY_TYPE_PROPERTIES);
|
|
3085
|
+
if (properties) {
|
|
3086
|
+
const [_, obj] = properties;
|
|
3087
|
+
obj.system.type = encodeReference(Reference.fromLegacyTypename(TYPE_PROPERTIES));
|
|
3088
|
+
}
|
|
3089
|
+
return newDoc;
|
|
3090
|
+
};
|
|
3091
|
+
var findInlineObjectOfType = (spaceDoc, typename) => {
|
|
3092
|
+
for (const id in spaceDoc.objects ?? {}) {
|
|
3093
|
+
const obj = spaceDoc.objects[id];
|
|
3094
|
+
if (obj.system.type && decodeReference(obj.system.type).objectId === typename) {
|
|
3095
|
+
return [
|
|
3096
|
+
id,
|
|
3097
|
+
obj
|
|
3098
|
+
];
|
|
3099
|
+
}
|
|
3100
|
+
}
|
|
3101
|
+
return void 0;
|
|
3102
|
+
};
|
|
3103
|
+
|
|
3104
|
+
// packages/core/echo/echo-pipeline/src/edge/echo-edge-replicator.ts
|
|
3105
|
+
import { Mutex, scheduleTask as scheduleTask2 } from "@dxos/async";
|
|
3106
|
+
import * as A5 from "@dxos/automerge/automerge";
|
|
3107
|
+
import { cbor as cbor2 } from "@dxos/automerge/automerge-repo";
|
|
3108
|
+
import { Context as Context6, Resource as Resource10 } from "@dxos/context";
|
|
3109
|
+
import { randomUUID } from "@dxos/crypto";
|
|
3110
|
+
import { invariant as invariant12 } from "@dxos/invariant";
|
|
3111
|
+
import { log as log11 } from "@dxos/log";
|
|
3112
|
+
import { EdgeService } from "@dxos/protocols";
|
|
3113
|
+
import { buf } from "@dxos/protocols/buf";
|
|
3114
|
+
import { MessageSchema as RouterMessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
3115
|
+
import { bufferToArray } from "@dxos/util";
|
|
3116
|
+
function _using_ctx() {
|
|
3117
|
+
var _disposeSuppressedError = typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed) {
|
|
3118
|
+
var err = new Error();
|
|
3119
|
+
err.name = "SuppressedError";
|
|
3120
|
+
err.suppressed = suppressed;
|
|
3121
|
+
err.error = error;
|
|
3122
|
+
return err;
|
|
3123
|
+
}, empty = {}, stack = [];
|
|
3124
|
+
function using(isAwait, value) {
|
|
3125
|
+
if (value != null) {
|
|
3126
|
+
if (Object(value) !== value) {
|
|
3127
|
+
throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
|
|
3128
|
+
}
|
|
3129
|
+
if (isAwait) {
|
|
3130
|
+
var dispose = value[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")];
|
|
3131
|
+
}
|
|
3132
|
+
if (dispose == null) {
|
|
3133
|
+
dispose = value[Symbol.dispose || Symbol.for("Symbol.dispose")];
|
|
3134
|
+
}
|
|
3135
|
+
if (typeof dispose !== "function") {
|
|
3136
|
+
throw new TypeError(`Property [Symbol.dispose] is not a function.`);
|
|
3137
|
+
}
|
|
3138
|
+
stack.push({
|
|
3139
|
+
v: value,
|
|
3140
|
+
d: dispose,
|
|
3141
|
+
a: isAwait
|
|
3142
|
+
});
|
|
3143
|
+
} else if (isAwait) {
|
|
3144
|
+
stack.push({
|
|
3145
|
+
d: value,
|
|
3146
|
+
a: isAwait
|
|
3147
|
+
});
|
|
3148
|
+
}
|
|
3149
|
+
return value;
|
|
3150
|
+
}
|
|
3151
|
+
return {
|
|
3152
|
+
e: empty,
|
|
3153
|
+
u: using.bind(null, false),
|
|
3154
|
+
a: using.bind(null, true),
|
|
3155
|
+
d: function() {
|
|
3156
|
+
var error = this.e;
|
|
3157
|
+
function next() {
|
|
3158
|
+
while (resource = stack.pop()) {
|
|
3159
|
+
try {
|
|
3160
|
+
var resource, disposalResult = resource.d && resource.d.call(resource.v);
|
|
3161
|
+
if (resource.a) {
|
|
3162
|
+
return Promise.resolve(disposalResult).then(next, err);
|
|
3163
|
+
}
|
|
3164
|
+
} catch (e) {
|
|
3165
|
+
return err(e);
|
|
3166
|
+
}
|
|
3167
|
+
}
|
|
3168
|
+
if (error !== empty) throw error;
|
|
3169
|
+
}
|
|
3170
|
+
function err(e) {
|
|
3171
|
+
error = error !== empty ? new _disposeSuppressedError(error, e) : e;
|
|
3172
|
+
return next();
|
|
3173
|
+
}
|
|
3174
|
+
return next();
|
|
3175
|
+
}
|
|
3176
|
+
};
|
|
3177
|
+
}
|
|
3178
|
+
var __dxlog_file16 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/edge/echo-edge-replicator.ts";
|
|
3179
|
+
var RESTART_DELAY = 500;
|
|
3180
|
+
var EchoEdgeReplicator = class {
|
|
3181
|
+
constructor({ edgeConnection, disableSharePolicy }) {
|
|
3182
|
+
this._mutex = new Mutex();
|
|
3183
|
+
this._ctx = void 0;
|
|
3184
|
+
this._context = null;
|
|
3185
|
+
this._connectedSpaces = /* @__PURE__ */ new Set();
|
|
3186
|
+
this._connections = /* @__PURE__ */ new Map();
|
|
3187
|
+
this._sharePolicyEnabled = true;
|
|
3188
|
+
this._edgeConnection = edgeConnection;
|
|
3189
|
+
this._sharePolicyEnabled = !disableSharePolicy;
|
|
3190
|
+
}
|
|
3191
|
+
async connect(context) {
|
|
3192
|
+
log11.info("connect", {
|
|
3193
|
+
peerId: context.peerId,
|
|
3194
|
+
connectedSpaces: this._connectedSpaces.size
|
|
3195
|
+
}, {
|
|
3196
|
+
F: __dxlog_file16,
|
|
3197
|
+
L: 58,
|
|
3198
|
+
S: this,
|
|
3199
|
+
C: (f, a) => f(...a)
|
|
3200
|
+
});
|
|
3201
|
+
this._context = context;
|
|
3202
|
+
this._ctx = Context6.default(void 0, {
|
|
3203
|
+
F: __dxlog_file16,
|
|
3204
|
+
L: 61
|
|
3205
|
+
});
|
|
3206
|
+
this._edgeConnection.reconnect.on(this._ctx, async () => {
|
|
3207
|
+
try {
|
|
3208
|
+
var _usingCtx = _using_ctx();
|
|
3209
|
+
const _guard = _usingCtx.u(await this._mutex.acquire());
|
|
3210
|
+
const spaces = [
|
|
3211
|
+
...this._connectedSpaces
|
|
3212
|
+
];
|
|
3213
|
+
for (const connection of this._connections.values()) {
|
|
3214
|
+
await connection.close();
|
|
3215
|
+
}
|
|
3216
|
+
this._connections.clear();
|
|
3217
|
+
if (this._context !== null) {
|
|
3218
|
+
for (const spaceId of spaces) {
|
|
3219
|
+
await this._openConnection(spaceId);
|
|
3220
|
+
}
|
|
3221
|
+
}
|
|
3222
|
+
} catch (_) {
|
|
3223
|
+
_usingCtx.e = _;
|
|
3224
|
+
} finally {
|
|
3225
|
+
_usingCtx.d();
|
|
3226
|
+
}
|
|
3227
|
+
});
|
|
3228
|
+
for (const spaceId of this._connectedSpaces) {
|
|
3229
|
+
await this._openConnection(spaceId);
|
|
3230
|
+
}
|
|
3231
|
+
}
|
|
3232
|
+
async disconnect() {
|
|
3233
|
+
try {
|
|
3234
|
+
var _usingCtx = _using_ctx();
|
|
3235
|
+
const _guard = _usingCtx.u(await this._mutex.acquire());
|
|
3236
|
+
await this._ctx?.dispose();
|
|
3237
|
+
for (const connection of this._connections.values()) {
|
|
3238
|
+
await connection.close();
|
|
3239
|
+
}
|
|
3240
|
+
this._connections.clear();
|
|
3241
|
+
} catch (_) {
|
|
3242
|
+
_usingCtx.e = _;
|
|
3243
|
+
} finally {
|
|
3244
|
+
_usingCtx.d();
|
|
3245
|
+
}
|
|
3246
|
+
}
|
|
3247
|
+
async connectToSpace(spaceId) {
|
|
3248
|
+
try {
|
|
3249
|
+
var _usingCtx = _using_ctx();
|
|
3250
|
+
const _guard = _usingCtx.u(await this._mutex.acquire());
|
|
3251
|
+
this._connectedSpaces.add(spaceId);
|
|
3252
|
+
if (this._context !== null) {
|
|
3253
|
+
await this._openConnection(spaceId);
|
|
3254
|
+
}
|
|
3255
|
+
} catch (_) {
|
|
3256
|
+
_usingCtx.e = _;
|
|
3257
|
+
} finally {
|
|
3258
|
+
_usingCtx.d();
|
|
3259
|
+
}
|
|
3260
|
+
}
|
|
3261
|
+
async disconnectFromSpace(spaceId) {
|
|
3262
|
+
try {
|
|
3263
|
+
var _usingCtx = _using_ctx();
|
|
3264
|
+
const _guard = _usingCtx.u(await this._mutex.acquire());
|
|
3265
|
+
this._connectedSpaces.delete(spaceId);
|
|
3266
|
+
const connection = this._connections.get(spaceId);
|
|
3267
|
+
if (connection) {
|
|
3268
|
+
await connection.close();
|
|
3269
|
+
this._connections.delete(spaceId);
|
|
3270
|
+
}
|
|
3271
|
+
} catch (_) {
|
|
3272
|
+
_usingCtx.e = _;
|
|
3273
|
+
} finally {
|
|
3274
|
+
_usingCtx.d();
|
|
3275
|
+
}
|
|
3276
|
+
}
|
|
3277
|
+
async _openConnection(spaceId) {
|
|
3278
|
+
invariant12(this._context, void 0, {
|
|
3279
|
+
F: __dxlog_file16,
|
|
3280
|
+
L: 117,
|
|
3281
|
+
S: this,
|
|
3282
|
+
A: [
|
|
3283
|
+
"this._context",
|
|
3284
|
+
""
|
|
3285
|
+
]
|
|
3286
|
+
});
|
|
3287
|
+
invariant12(!this._connections.has(spaceId), void 0, {
|
|
3288
|
+
F: __dxlog_file16,
|
|
3289
|
+
L: 118,
|
|
3290
|
+
S: this,
|
|
3291
|
+
A: [
|
|
3292
|
+
"!this._connections.has(spaceId)",
|
|
3293
|
+
""
|
|
3294
|
+
]
|
|
3295
|
+
});
|
|
3296
|
+
const connection = new EdgeReplicatorConnection({
|
|
3297
|
+
edgeConnection: this._edgeConnection,
|
|
3298
|
+
ownPeerId: this._context.peerId,
|
|
3299
|
+
spaceId,
|
|
3300
|
+
context: this._context,
|
|
3301
|
+
sharedPolicyEnabled: this._sharePolicyEnabled,
|
|
3302
|
+
onRemoteConnected: async () => {
|
|
3303
|
+
this._context?.onConnectionOpen(connection);
|
|
3304
|
+
},
|
|
3305
|
+
onRemoteDisconnected: async () => {
|
|
3306
|
+
this._context?.onConnectionClosed(connection);
|
|
3307
|
+
},
|
|
3308
|
+
onRestartRequested: async () => {
|
|
3309
|
+
try {
|
|
3310
|
+
var _usingCtx = _using_ctx();
|
|
3311
|
+
const _guard = _usingCtx.u(await this._mutex.acquire());
|
|
3312
|
+
const ctx = this._ctx;
|
|
3313
|
+
await connection.close();
|
|
3314
|
+
this._connections.delete(spaceId);
|
|
3315
|
+
if (ctx?.disposed) {
|
|
3316
|
+
return;
|
|
3317
|
+
}
|
|
3318
|
+
await this._openConnection(spaceId);
|
|
3319
|
+
} catch (_) {
|
|
3320
|
+
_usingCtx.e = _;
|
|
3321
|
+
} finally {
|
|
3322
|
+
_usingCtx.d();
|
|
3323
|
+
}
|
|
3324
|
+
}
|
|
3325
|
+
});
|
|
3326
|
+
this._connections.set(spaceId, connection);
|
|
3327
|
+
await connection.open();
|
|
3328
|
+
}
|
|
3329
|
+
};
|
|
3330
|
+
var EdgeReplicatorConnection = class extends Resource10 {
|
|
3331
|
+
constructor({ edgeConnection, ownPeerId, spaceId, context, sharedPolicyEnabled, onRemoteConnected, onRemoteDisconnected, onRestartRequested }) {
|
|
3332
|
+
super();
|
|
3333
|
+
this._remotePeerId = null;
|
|
3334
|
+
this._restartScheduled = false;
|
|
3335
|
+
this._edgeConnection = edgeConnection;
|
|
3336
|
+
this._ownPeerId = ownPeerId;
|
|
3337
|
+
this._spaceId = spaceId;
|
|
3338
|
+
this._context = context;
|
|
3339
|
+
this._remotePeerId = `${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}-${randomUUID()}`;
|
|
3340
|
+
this._targetServiceId = `${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}`;
|
|
3341
|
+
this._sharedPolicyEnabled = sharedPolicyEnabled;
|
|
3342
|
+
this._onRemoteConnected = onRemoteConnected;
|
|
3343
|
+
this._onRemoteDisconnected = onRemoteDisconnected;
|
|
3344
|
+
this._onRestartRequested = onRestartRequested;
|
|
3345
|
+
this.readable = new ReadableStream({
|
|
3346
|
+
start: (controller) => {
|
|
3347
|
+
this._readableStreamController = controller;
|
|
3348
|
+
}
|
|
3349
|
+
});
|
|
3350
|
+
this.writable = new WritableStream({
|
|
3351
|
+
write: async (message, controller) => {
|
|
3352
|
+
await this._sendMessage(message);
|
|
3353
|
+
}
|
|
3354
|
+
});
|
|
3355
|
+
}
|
|
3356
|
+
async _open(ctx) {
|
|
3357
|
+
log11("open", void 0, {
|
|
3358
|
+
F: __dxlog_file16,
|
|
3359
|
+
L: 219,
|
|
3360
|
+
S: this,
|
|
3361
|
+
C: (f, a) => f(...a)
|
|
3362
|
+
});
|
|
3363
|
+
this._ctx.onDispose(this._edgeConnection.addListener((msg) => {
|
|
3364
|
+
this._onMessage(msg);
|
|
3365
|
+
}));
|
|
3366
|
+
await this._onRemoteConnected();
|
|
3367
|
+
}
|
|
3368
|
+
async _close() {
|
|
3369
|
+
log11("close", void 0, {
|
|
3370
|
+
F: __dxlog_file16,
|
|
3371
|
+
L: 231,
|
|
3372
|
+
S: this,
|
|
3373
|
+
C: (f, a) => f(...a)
|
|
3374
|
+
});
|
|
3375
|
+
this._readableStreamController.close();
|
|
3376
|
+
await this._onRemoteDisconnected();
|
|
3377
|
+
}
|
|
3378
|
+
get peerId() {
|
|
3379
|
+
invariant12(this._remotePeerId, "Not connected", {
|
|
3380
|
+
F: __dxlog_file16,
|
|
3381
|
+
L: 237,
|
|
3382
|
+
S: this,
|
|
3383
|
+
A: [
|
|
3384
|
+
"this._remotePeerId",
|
|
3385
|
+
"'Not connected'"
|
|
3386
|
+
]
|
|
3387
|
+
});
|
|
3388
|
+
return this._remotePeerId;
|
|
3389
|
+
}
|
|
3390
|
+
async shouldAdvertise(params) {
|
|
3391
|
+
if (!this._sharedPolicyEnabled) {
|
|
3392
|
+
return true;
|
|
3393
|
+
}
|
|
3394
|
+
const spaceId = await this._context.getContainingSpaceIdForDocument(params.documentId);
|
|
3395
|
+
if (!spaceId) {
|
|
3396
|
+
return true;
|
|
3397
|
+
}
|
|
3398
|
+
return spaceId === this._spaceId;
|
|
3399
|
+
}
|
|
3400
|
+
shouldSyncCollection(params) {
|
|
3401
|
+
if (!this._sharedPolicyEnabled) {
|
|
3402
|
+
return true;
|
|
3403
|
+
}
|
|
3404
|
+
const spaceId = getSpaceIdFromCollectionId(params.collectionId);
|
|
3405
|
+
return spaceId === this._spaceId;
|
|
3406
|
+
}
|
|
3407
|
+
_onMessage(message) {
|
|
3408
|
+
if (message.serviceId !== this._targetServiceId) {
|
|
3409
|
+
return;
|
|
3410
|
+
}
|
|
3411
|
+
const payload = cbor2.decode(message.payload.value);
|
|
3412
|
+
log11("recv", () => {
|
|
3413
|
+
const decodedData = payload.type === "sync" && payload.data ? A5.decodeSyncMessage(payload.data) : payload.type === "collection-state" ? payload.state : payload;
|
|
3414
|
+
return {
|
|
3415
|
+
from: message.serviceId,
|
|
3416
|
+
type: payload.type,
|
|
3417
|
+
decodedData
|
|
3418
|
+
};
|
|
3419
|
+
}, {
|
|
3420
|
+
F: __dxlog_file16,
|
|
3421
|
+
L: 268,
|
|
3422
|
+
S: this,
|
|
3423
|
+
C: (f, a) => f(...a)
|
|
3424
|
+
});
|
|
3425
|
+
payload.senderId = this._remotePeerId;
|
|
3426
|
+
this._processMessage(payload);
|
|
3427
|
+
}
|
|
3428
|
+
_processMessage(message) {
|
|
3429
|
+
if (isForbiddenErrorMessage(message)) {
|
|
3430
|
+
if (!this._restartScheduled) {
|
|
3431
|
+
log11.warn("Forbidden error received, replicator will restart the connection", {
|
|
3432
|
+
spaceId: this._spaceId,
|
|
3433
|
+
delayMs: RESTART_DELAY,
|
|
3434
|
+
remotePeerId: this._remotePeerId
|
|
3435
|
+
}, {
|
|
3436
|
+
F: __dxlog_file16,
|
|
3437
|
+
L: 288,
|
|
3438
|
+
S: this,
|
|
3439
|
+
C: (f, a) => f(...a)
|
|
3440
|
+
});
|
|
3441
|
+
this._restartScheduled = true;
|
|
3442
|
+
scheduleTask2(this._ctx, async () => {
|
|
3443
|
+
await this._onRestartRequested();
|
|
3444
|
+
}, RESTART_DELAY);
|
|
3445
|
+
}
|
|
3446
|
+
return;
|
|
3447
|
+
}
|
|
3448
|
+
this._readableStreamController.enqueue(message);
|
|
3449
|
+
}
|
|
3450
|
+
async _sendMessage(message) {
|
|
3451
|
+
message.targetId = this._targetServiceId;
|
|
3452
|
+
log11("send", {
|
|
3453
|
+
type: message.type,
|
|
3454
|
+
senderId: message.senderId,
|
|
3455
|
+
targetId: message.targetId,
|
|
3456
|
+
documentId: message.documentId
|
|
3457
|
+
}, {
|
|
3458
|
+
F: __dxlog_file16,
|
|
3459
|
+
L: 312,
|
|
3460
|
+
S: this,
|
|
3461
|
+
C: (f, a) => f(...a)
|
|
3462
|
+
});
|
|
3463
|
+
const encoded = cbor2.encode(message);
|
|
3464
|
+
await this._edgeConnection.send(buf.create(RouterMessageSchema, {
|
|
3465
|
+
serviceId: this._targetServiceId,
|
|
3466
|
+
source: {
|
|
3467
|
+
identityKey: this._edgeConnection.identityKey,
|
|
3468
|
+
peerKey: this._edgeConnection.peerKey
|
|
3469
|
+
},
|
|
3470
|
+
payload: {
|
|
3471
|
+
value: bufferToArray(encoded)
|
|
3472
|
+
}
|
|
3473
|
+
}));
|
|
3474
|
+
}
|
|
3475
|
+
};
|
|
3476
|
+
var isForbiddenErrorMessage = (message) => message.type === "error" && message.message === "Forbidden";
|
|
3477
|
+
export {
|
|
3478
|
+
AuthExtension,
|
|
3479
|
+
AuthStatus,
|
|
2144
3480
|
AutomergeHost,
|
|
2145
|
-
|
|
3481
|
+
CredentialRetrieverExtension,
|
|
3482
|
+
CredentialServerExtension,
|
|
3483
|
+
DataServiceImpl,
|
|
3484
|
+
DatabaseRoot,
|
|
3485
|
+
DocumentsSynchronizer,
|
|
3486
|
+
EchoDataMonitor,
|
|
3487
|
+
EchoEdgeReplicator,
|
|
3488
|
+
EchoHost,
|
|
3489
|
+
LevelDBStorageAdapter,
|
|
3490
|
+
MOCK_AUTH_PROVIDER,
|
|
3491
|
+
MOCK_AUTH_VERIFIER,
|
|
3492
|
+
MeshEchoReplicator,
|
|
3493
|
+
MetadataStore,
|
|
3494
|
+
Pipeline,
|
|
3495
|
+
QueryServiceImpl,
|
|
3496
|
+
QueryState,
|
|
3497
|
+
Space,
|
|
3498
|
+
SpaceManager,
|
|
3499
|
+
SpaceProtocol,
|
|
3500
|
+
SpaceProtocolSession,
|
|
3501
|
+
TimeframeClock,
|
|
3502
|
+
codec,
|
|
3503
|
+
convertLegacyReferences,
|
|
3504
|
+
convertLegacySpaceRootDoc,
|
|
3505
|
+
createIdFromSpaceKey,
|
|
3506
|
+
createMappedFeedWriter,
|
|
2146
3507
|
deriveCollectionIdFromSpaceId,
|
|
3508
|
+
diffCollectionState,
|
|
3509
|
+
encodingOptions,
|
|
3510
|
+
findInlineObjectOfType,
|
|
2147
3511
|
getSpaceIdFromCollectionId,
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
3512
|
+
getSpaceKeyFromDoc,
|
|
3513
|
+
hasInvitationExpired,
|
|
3514
|
+
mapFeedIndexesToTimeframe,
|
|
3515
|
+
mapTimeframeToFeedIndexes,
|
|
3516
|
+
startAfter,
|
|
3517
|
+
valueEncoding
|
|
2151
3518
|
};
|
|
2152
|
-
//# sourceMappingURL=
|
|
3519
|
+
//# sourceMappingURL=index.mjs.map
|