@dxos/echo-pipeline 0.8.4-main.84f28bd → 0.8.4-main.a4bbb77
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-BVR7OOZK.mjs +251 -0
- package/dist/lib/browser/chunk-BVR7OOZK.mjs.map +7 -0
- package/dist/lib/browser/{chunk-GBFX5J5B.mjs → chunk-XGG76KKU.mjs} +487 -324
- package/dist/lib/browser/chunk-XGG76KKU.mjs.map +7 -0
- package/dist/lib/browser/filter/index.mjs +3 -1
- package/dist/lib/browser/index.mjs +1379 -562
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +107 -44
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/{chunk-FQFKWA3X.mjs → chunk-CHMJJ4DG.mjs} +487 -324
- package/dist/lib/node-esm/chunk-CHMJJ4DG.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-L3ZEKVDR.mjs +251 -0
- package/dist/lib/node-esm/chunk-L3ZEKVDR.mjs.map +7 -0
- package/dist/lib/node-esm/filter/index.mjs +3 -1
- package/dist/lib/node-esm/index.mjs +1379 -562
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +107 -44
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/automerge/automerge-host.d.ts +15 -28
- package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
- package/dist/types/src/automerge/collection-synchronizer.d.ts +1 -1
- package/dist/types/src/automerge/collection-synchronizer.d.ts.map +1 -1
- package/dist/types/src/automerge/echo-network-adapter.d.ts +8 -1
- package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
- package/dist/types/src/automerge/echo-replicator.d.ts +21 -2
- package/dist/types/src/automerge/echo-replicator.d.ts.map +1 -1
- package/dist/types/src/automerge/index.d.ts +1 -1
- package/dist/types/src/automerge/index.d.ts.map +1 -1
- package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +1 -1
- package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -1
- package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts +1 -0
- 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/common/codec.d.ts +1 -1
- package/dist/types/src/common/codec.d.ts.map +1 -1
- package/dist/types/src/db-host/data-service.d.ts +2 -2
- package/dist/types/src/db-host/data-service.d.ts.map +1 -1
- package/dist/types/src/db-host/database-root.d.ts.map +1 -1
- package/dist/types/src/db-host/documents-synchronizer.d.ts +2 -2
- package/dist/types/src/db-host/documents-synchronizer.d.ts.map +1 -1
- package/dist/types/src/db-host/echo-host.d.ts +2 -2
- package/dist/types/src/db-host/echo-host.d.ts.map +1 -1
- package/dist/types/src/db-host/query-service.d.ts +1 -1
- package/dist/types/src/db-host/query-service.d.ts.map +1 -1
- package/dist/types/src/db-host/space-state-manager.d.ts +1 -1
- package/dist/types/src/db-host/space-state-manager.d.ts.map +1 -1
- package/dist/types/src/edge/echo-edge-replicator.d.ts +4 -2
- package/dist/types/src/edge/echo-edge-replicator.d.ts.map +1 -1
- package/dist/types/src/filter/filter-match.d.ts +4 -1
- package/dist/types/src/filter/filter-match.d.ts.map +1 -1
- package/dist/types/src/metadata/metadata-store.d.ts +1 -1
- package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
- package/dist/types/src/pipeline/pipeline.d.ts +1 -1
- package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
- package/dist/types/src/query/errors.d.ts +24 -8
- package/dist/types/src/query/errors.d.ts.map +1 -1
- package/dist/types/src/query/plan.d.ts +8 -1
- package/dist/types/src/query/plan.d.ts.map +1 -1
- package/dist/types/src/query/query-executor.d.ts +4 -1
- package/dist/types/src/query/query-executor.d.ts.map +1 -1
- package/dist/types/src/query/query-planner.d.ts +2 -0
- package/dist/types/src/query/query-planner.d.ts.map +1 -1
- package/dist/types/src/space/admission-discovery-extension.d.ts.map +1 -1
- package/dist/types/src/space/control-pipeline.d.ts +1 -1
- package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
- package/dist/types/src/space/space-manager.d.ts +1 -1
- package/dist/types/src/space/space-manager.d.ts.map +1 -1
- package/dist/types/src/space/space-protocol.d.ts +1 -1
- package/dist/types/src/space/space-protocol.d.ts.map +1 -1
- package/dist/types/src/space/space.d.ts +1 -1
- package/dist/types/src/space/space.d.ts.map +1 -1
- package/dist/types/src/testing/test-agent-builder.d.ts +2 -2
- package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
- package/dist/types/src/testing/test-replicator.d.ts +1 -0
- package/dist/types/src/testing/test-replicator.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +1 -1
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +41 -38
- package/src/automerge/automerge-host.test.ts +18 -8
- package/src/automerge/automerge-host.ts +266 -70
- package/src/automerge/automerge-repo.test.ts +67 -16
- package/src/automerge/collection-synchronizer.test.ts +2 -2
- package/src/automerge/collection-synchronizer.ts +4 -4
- package/src/automerge/echo-data-monitor.ts +1 -1
- package/src/automerge/echo-network-adapter.test.ts +3 -3
- package/src/automerge/echo-network-adapter.ts +38 -6
- package/src/automerge/echo-replicator.ts +23 -2
- package/src/automerge/index.ts +1 -1
- package/src/automerge/leveldb-storage-adapter.ts +7 -7
- package/src/automerge/mesh-echo-replicator-connection.ts +4 -0
- package/src/automerge/mesh-echo-replicator.ts +2 -1
- package/src/automerge/storage-adapter.test.ts +1 -1
- package/src/common/space-id.ts +1 -1
- package/src/db-host/data-service.ts +9 -17
- package/src/db-host/database-root.ts +2 -2
- package/src/db-host/documents-synchronizer.test.ts +1 -1
- package/src/db-host/documents-synchronizer.ts +39 -26
- package/src/db-host/echo-host.ts +14 -15
- package/src/db-host/query-service.ts +8 -1
- package/src/db-host/space-state-manager.ts +2 -2
- package/src/edge/echo-edge-replicator.test.ts +5 -3
- package/src/edge/echo-edge-replicator.ts +75 -18
- package/src/filter/filter-match.test.ts +33 -13
- package/src/filter/filter-match.ts +177 -10
- package/src/metadata/metadata-store.ts +3 -3
- package/src/pipeline/pipeline-stress.test.ts +4 -2
- package/src/pipeline/pipeline.test.ts +3 -2
- package/src/pipeline/pipeline.ts +8 -5
- package/src/query/errors.ts +2 -0
- package/src/query/plan.ts +12 -1
- package/src/query/query-executor.ts +71 -11
- package/src/query/query-planner.test.ts +146 -2
- package/src/query/query-planner.ts +81 -11
- package/src/space/admission-discovery-extension.ts +2 -2
- package/src/space/control-pipeline.test.ts +4 -3
- package/src/space/control-pipeline.ts +9 -6
- package/src/space/space-manager.browser.test.ts +1 -1
- package/src/space/space-manager.ts +5 -4
- package/src/space/space-protocol.browser.test.ts +2 -2
- package/src/space/space-protocol.test.ts +3 -2
- package/src/space/space-protocol.ts +6 -3
- package/src/space/space.test.ts +1 -1
- package/src/space/space.ts +3 -2
- package/src/testing/test-agent-builder.ts +4 -3
- package/src/testing/test-replicator.ts +4 -0
- package/src/util.ts +1 -1
- package/dist/lib/browser/chunk-ANZAS5CC.mjs +0 -126
- package/dist/lib/browser/chunk-ANZAS5CC.mjs.map +0 -7
- package/dist/lib/browser/chunk-GBFX5J5B.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-2SAZ7CCF.mjs +0 -126
- package/dist/lib/node-esm/chunk-2SAZ7CCF.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-FQFKWA3X.mjs.map +0 -7
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import "@dxos/node-std/globals";
|
|
2
2
|
import {
|
|
3
3
|
filterMatchObject,
|
|
4
|
+
filterMatchObjectJSON,
|
|
4
5
|
filterMatchValue
|
|
5
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-BVR7OOZK.mjs";
|
|
6
7
|
import {
|
|
7
8
|
AuthExtension,
|
|
8
9
|
AuthStatus,
|
|
@@ -25,7 +26,7 @@ import {
|
|
|
25
26
|
mapTimeframeToFeedIndexes,
|
|
26
27
|
startAfter,
|
|
27
28
|
valueEncoding
|
|
28
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-XGG76KKU.mjs";
|
|
29
30
|
import "./chunk-CGS2ULMK.mjs";
|
|
30
31
|
|
|
31
32
|
// src/db-host/data-service.ts
|
|
@@ -35,17 +36,10 @@ import { invariant as invariant7 } from "@dxos/invariant";
|
|
|
35
36
|
import { SpaceId as SpaceId2 } from "@dxos/keys";
|
|
36
37
|
import { log as log7 } from "@dxos/log";
|
|
37
38
|
|
|
38
|
-
// src/db-host/documents-synchronizer.ts
|
|
39
|
-
import { next as A2 } from "@automerge/automerge";
|
|
40
|
-
import { UpdateScheduler } from "@dxos/async";
|
|
41
|
-
import { Resource as Resource5 } from "@dxos/context";
|
|
42
|
-
import { invariant as invariant6 } from "@dxos/invariant";
|
|
43
|
-
import { log as log6 } from "@dxos/log";
|
|
44
|
-
|
|
45
39
|
// src/automerge/automerge-host.ts
|
|
46
|
-
import { getBackend, getHeads,
|
|
40
|
+
import { getBackend, getHeads, equals as headsEquals, isAutomerge, save } from "@automerge/automerge";
|
|
47
41
|
import { Repo, interpretAsDocumentId } from "@automerge/automerge-repo";
|
|
48
|
-
import { Event as Event2, asyncTimeout } from "@dxos/async";
|
|
42
|
+
import { DeferredTask, Event as Event2, asyncTimeout } from "@dxos/async";
|
|
49
43
|
import { Context, Resource as Resource3, cancelWithContext } from "@dxos/context";
|
|
50
44
|
import { DatabaseDirectory } from "@dxos/echo-protocol";
|
|
51
45
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
@@ -53,15 +47,28 @@ import { PublicKey } from "@dxos/keys";
|
|
|
53
47
|
import { log as log3 } from "@dxos/log";
|
|
54
48
|
import { objectPointerCodec } from "@dxos/protocols";
|
|
55
49
|
import { trace as trace2 } from "@dxos/tracing";
|
|
56
|
-
import { bufferToArray } from "@dxos/util";
|
|
50
|
+
import { ComplexSet, bufferToArray, isNonNullable as isNonNullable2, range } from "@dxos/util";
|
|
57
51
|
|
|
58
52
|
// src/automerge/collection-synchronizer.ts
|
|
59
53
|
import { next as am } from "@automerge/automerge";
|
|
60
|
-
import {
|
|
54
|
+
import { Event, asyncReturn, scheduleTask, scheduleTaskInterval } from "@dxos/async";
|
|
61
55
|
import { Resource } from "@dxos/context";
|
|
62
56
|
import { log } from "@dxos/log";
|
|
63
57
|
import { trace } from "@dxos/tracing";
|
|
64
58
|
import { defaultMap } from "@dxos/util";
|
|
59
|
+
function _define_property(obj, key, value) {
|
|
60
|
+
if (key in obj) {
|
|
61
|
+
Object.defineProperty(obj, key, {
|
|
62
|
+
value,
|
|
63
|
+
enumerable: true,
|
|
64
|
+
configurable: true,
|
|
65
|
+
writable: true
|
|
66
|
+
});
|
|
67
|
+
} else {
|
|
68
|
+
obj[key] = value;
|
|
69
|
+
}
|
|
70
|
+
return obj;
|
|
71
|
+
}
|
|
65
72
|
function _ts_decorate(decorators, target, key, desc) {
|
|
66
73
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
67
74
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -72,19 +79,6 @@ var __dxlog_file = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerg
|
|
|
72
79
|
var MIN_QUERY_INTERVAL = 5e3;
|
|
73
80
|
var POLL_INTERVAL = 3e4;
|
|
74
81
|
var CollectionSynchronizer = class extends Resource {
|
|
75
|
-
constructor(params) {
|
|
76
|
-
super();
|
|
77
|
-
/**
|
|
78
|
-
* CollectionId -> State.
|
|
79
|
-
*/
|
|
80
|
-
this._perCollectionStates = /* @__PURE__ */ new Map();
|
|
81
|
-
this._activeCollections = /* @__PURE__ */ new Set();
|
|
82
|
-
this._connectedPeers = /* @__PURE__ */ new Set();
|
|
83
|
-
this.remoteStateUpdated = new Event();
|
|
84
|
-
this._sendCollectionState = params.sendCollectionState;
|
|
85
|
-
this._queryCollectionState = params.queryCollectionState;
|
|
86
|
-
this._shouldSyncCollection = params.shouldSyncCollection;
|
|
87
|
-
}
|
|
88
82
|
async _open(ctx) {
|
|
89
83
|
scheduleTaskInterval(this._ctx, async () => {
|
|
90
84
|
for (const collectionId of this._perCollectionStates.keys()) {
|
|
@@ -263,6 +257,15 @@ var CollectionSynchronizer = class extends Resource {
|
|
|
263
257
|
}
|
|
264
258
|
}
|
|
265
259
|
}
|
|
260
|
+
constructor(params) {
|
|
261
|
+
super(), _define_property(this, "_sendCollectionState", void 0), _define_property(this, "_queryCollectionState", void 0), _define_property(this, "_shouldSyncCollection", void 0), /**
|
|
262
|
+
* CollectionId -> State.
|
|
263
|
+
*/
|
|
264
|
+
_define_property(this, "_perCollectionStates", /* @__PURE__ */ new Map()), _define_property(this, "_activeCollections", /* @__PURE__ */ new Set()), _define_property(this, "_connectedPeers", /* @__PURE__ */ new Set()), _define_property(this, "remoteStateUpdated", new Event());
|
|
265
|
+
this._sendCollectionState = params.sendCollectionState;
|
|
266
|
+
this._queryCollectionState = params.queryCollectionState;
|
|
267
|
+
this._shouldSyncCollection = params.shouldSyncCollection;
|
|
268
|
+
}
|
|
266
269
|
};
|
|
267
270
|
CollectionSynchronizer = _ts_decorate([
|
|
268
271
|
trace.resource()
|
|
@@ -276,9 +279,9 @@ var diffCollectionState = (local, remote) => {
|
|
|
276
279
|
const missingOnLocal = [];
|
|
277
280
|
const different = [];
|
|
278
281
|
for (const documentId of allDocuments) {
|
|
279
|
-
if (!local.documents[documentId]) {
|
|
282
|
+
if (!local.documents[documentId] || local.documents[documentId].length === 0) {
|
|
280
283
|
missingOnLocal.push(documentId);
|
|
281
|
-
} else if (!remote.documents[documentId]) {
|
|
284
|
+
} else if (!remote.documents[documentId] || remote.documents[documentId].length === 0) {
|
|
282
285
|
missingOnRemote.push(documentId);
|
|
283
286
|
} else if (!am.equals(local.documents[documentId], remote.documents[documentId])) {
|
|
284
287
|
different.push(documentId);
|
|
@@ -309,7 +312,7 @@ var getSpanName = (peerId) => {
|
|
|
309
312
|
|
|
310
313
|
// src/automerge/echo-network-adapter.ts
|
|
311
314
|
import { NetworkAdapter } from "@automerge/automerge-repo";
|
|
312
|
-
import {
|
|
315
|
+
import { Trigger, synchronized } from "@dxos/async";
|
|
313
316
|
import { LifecycleState } from "@dxos/context";
|
|
314
317
|
import { invariant } from "@dxos/invariant";
|
|
315
318
|
import { log as log2 } from "@dxos/log";
|
|
@@ -321,6 +324,19 @@ var isCollectionQueryMessage = (message) => message.type === MESSAGE_TYPE_COLLEC
|
|
|
321
324
|
var isCollectionStateMessage = (message) => message.type === MESSAGE_TYPE_COLLECTION_STATE;
|
|
322
325
|
|
|
323
326
|
// src/automerge/echo-network-adapter.ts
|
|
327
|
+
function _define_property2(obj, key, value) {
|
|
328
|
+
if (key in obj) {
|
|
329
|
+
Object.defineProperty(obj, key, {
|
|
330
|
+
value,
|
|
331
|
+
enumerable: true,
|
|
332
|
+
configurable: true,
|
|
333
|
+
writable: true
|
|
334
|
+
});
|
|
335
|
+
} else {
|
|
336
|
+
obj[key] = value;
|
|
337
|
+
}
|
|
338
|
+
return obj;
|
|
339
|
+
}
|
|
324
340
|
function _ts_decorate2(decorators, target, key, desc) {
|
|
325
341
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
326
342
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -329,9 +345,6 @@ function _ts_decorate2(decorators, target, key, desc) {
|
|
|
329
345
|
}
|
|
330
346
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts";
|
|
331
347
|
var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
332
|
-
constructor(_params) {
|
|
333
|
-
super(), this._params = _params, this._replicators = /* @__PURE__ */ new Set(), this._connections = /* @__PURE__ */ new Map(), this._lifecycleState = LifecycleState.CLOSED, this._connected = new Trigger(), this._ready = new Trigger();
|
|
334
|
-
}
|
|
335
348
|
isReady() {
|
|
336
349
|
return this._lifecycleState === LifecycleState.OPEN;
|
|
337
350
|
}
|
|
@@ -380,7 +393,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
380
393
|
async addReplicator(replicator) {
|
|
381
394
|
invariant(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
382
395
|
F: __dxlog_file2,
|
|
383
|
-
L:
|
|
396
|
+
L: 137,
|
|
384
397
|
S: this,
|
|
385
398
|
A: [
|
|
386
399
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -389,7 +402,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
389
402
|
});
|
|
390
403
|
invariant(this.peerId, void 0, {
|
|
391
404
|
F: __dxlog_file2,
|
|
392
|
-
L:
|
|
405
|
+
L: 138,
|
|
393
406
|
S: this,
|
|
394
407
|
A: [
|
|
395
408
|
"this.peerId",
|
|
@@ -398,7 +411,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
398
411
|
});
|
|
399
412
|
invariant(!this._replicators.has(replicator), void 0, {
|
|
400
413
|
F: __dxlog_file2,
|
|
401
|
-
L:
|
|
414
|
+
L: 139,
|
|
402
415
|
S: this,
|
|
403
416
|
A: [
|
|
404
417
|
"!this._replicators.has(replicator)",
|
|
@@ -422,7 +435,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
422
435
|
async removeReplicator(replicator) {
|
|
423
436
|
invariant(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
424
437
|
F: __dxlog_file2,
|
|
425
|
-
L:
|
|
438
|
+
L: 158,
|
|
426
439
|
S: this,
|
|
427
440
|
A: [
|
|
428
441
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -431,7 +444,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
431
444
|
});
|
|
432
445
|
invariant(this._replicators.has(replicator), void 0, {
|
|
433
446
|
F: __dxlog_file2,
|
|
434
|
-
L:
|
|
447
|
+
L: 159,
|
|
435
448
|
S: this,
|
|
436
449
|
A: [
|
|
437
450
|
"this._replicators.has(replicator)",
|
|
@@ -482,6 +495,27 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
482
495
|
}) ? connection.connection.peerId : null;
|
|
483
496
|
}).filter(isNonNullable);
|
|
484
497
|
}
|
|
498
|
+
bundleSyncEnabledForPeer(peerId) {
|
|
499
|
+
const connection = this._connections.get(peerId);
|
|
500
|
+
if (!connection) {
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
return connection.connection.bundleSyncEnabled;
|
|
504
|
+
}
|
|
505
|
+
async pushBundle(peerId, bundle) {
|
|
506
|
+
const connection = this._connections.get(peerId);
|
|
507
|
+
if (!connection) {
|
|
508
|
+
throw new Error("Connection not found.");
|
|
509
|
+
}
|
|
510
|
+
return connection.connection.pushBundle(bundle);
|
|
511
|
+
}
|
|
512
|
+
async pullBundle(peerId, docHeads) {
|
|
513
|
+
const connection = this._connections.get(peerId);
|
|
514
|
+
if (!connection) {
|
|
515
|
+
throw new Error("Connection not found.");
|
|
516
|
+
}
|
|
517
|
+
return connection.connection.pullBundle(docHeads);
|
|
518
|
+
}
|
|
485
519
|
_send(message) {
|
|
486
520
|
const connectionEntry = this._connections.get(message.targetId);
|
|
487
521
|
if (!connectionEntry) {
|
|
@@ -494,7 +528,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
494
528
|
if (connectionEntry.isOpen) {
|
|
495
529
|
log2.catch(err, void 0, {
|
|
496
530
|
F: __dxlog_file2,
|
|
497
|
-
L:
|
|
531
|
+
L: 253,
|
|
498
532
|
S: this,
|
|
499
533
|
C: (f, a) => f(...a)
|
|
500
534
|
});
|
|
@@ -507,13 +541,13 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
507
541
|
peerId: connection.peerId
|
|
508
542
|
}, {
|
|
509
543
|
F: __dxlog_file2,
|
|
510
|
-
L:
|
|
544
|
+
L: 261,
|
|
511
545
|
S: this,
|
|
512
546
|
C: (f, a) => f(...a)
|
|
513
547
|
});
|
|
514
548
|
invariant(!this._connections.has(connection.peerId), void 0, {
|
|
515
549
|
F: __dxlog_file2,
|
|
516
|
-
L:
|
|
550
|
+
L: 262,
|
|
517
551
|
S: this,
|
|
518
552
|
A: [
|
|
519
553
|
"!this._connections.has(connection.peerId as PeerId)",
|
|
@@ -540,7 +574,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
540
574
|
if (connectionEntry.isOpen) {
|
|
541
575
|
log2.catch(err, void 0, {
|
|
542
576
|
F: __dxlog_file2,
|
|
543
|
-
L:
|
|
577
|
+
L: 286,
|
|
544
578
|
S: this,
|
|
545
579
|
C: (f, a) => f(...a)
|
|
546
580
|
});
|
|
@@ -551,7 +585,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
551
585
|
peerId: connection.peerId
|
|
552
586
|
}, {
|
|
553
587
|
F: __dxlog_file2,
|
|
554
|
-
L:
|
|
588
|
+
L: 291,
|
|
555
589
|
S: this,
|
|
556
590
|
C: (f, a) => f(...a)
|
|
557
591
|
});
|
|
@@ -573,14 +607,14 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
573
607
|
peerId: connection.peerId
|
|
574
608
|
}, {
|
|
575
609
|
F: __dxlog_file2,
|
|
576
|
-
L:
|
|
610
|
+
L: 308,
|
|
577
611
|
S: this,
|
|
578
612
|
C: (f, a) => f(...a)
|
|
579
613
|
});
|
|
580
614
|
const entry = this._connections.get(connection.peerId);
|
|
581
615
|
invariant(entry, void 0, {
|
|
582
616
|
F: __dxlog_file2,
|
|
583
|
-
L:
|
|
617
|
+
L: 310,
|
|
584
618
|
S: this,
|
|
585
619
|
A: [
|
|
586
620
|
"entry",
|
|
@@ -594,13 +628,13 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
594
628
|
this._params.monitor?.recordPeerDisconnected(connection.peerId);
|
|
595
629
|
void entry.writer.abort().catch((err) => log2.catch(err, void 0, {
|
|
596
630
|
F: __dxlog_file2,
|
|
597
|
-
L:
|
|
631
|
+
L: 316,
|
|
598
632
|
S: this,
|
|
599
633
|
C: (f, a) => f(...a)
|
|
600
634
|
}));
|
|
601
635
|
void entry.reader.cancel().catch((err) => log2.catch(err, void 0, {
|
|
602
636
|
F: __dxlog_file2,
|
|
603
|
-
L:
|
|
637
|
+
L: 317,
|
|
604
638
|
S: this,
|
|
605
639
|
C: (f, a) => f(...a)
|
|
606
640
|
}));
|
|
@@ -615,14 +649,14 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
615
649
|
peerId: connection.peerId
|
|
616
650
|
}, {
|
|
617
651
|
F: __dxlog_file2,
|
|
618
|
-
L:
|
|
652
|
+
L: 327,
|
|
619
653
|
S: this,
|
|
620
654
|
C: (f, a) => f(...a)
|
|
621
655
|
});
|
|
622
656
|
const entry = this._connections.get(connection.peerId);
|
|
623
657
|
invariant(entry, void 0, {
|
|
624
658
|
F: __dxlog_file2,
|
|
625
|
-
L:
|
|
659
|
+
L: 329,
|
|
626
660
|
S: this,
|
|
627
661
|
A: [
|
|
628
662
|
"entry",
|
|
@@ -640,6 +674,12 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
640
674
|
peerMetadata: createEchoPeerMetadata()
|
|
641
675
|
});
|
|
642
676
|
}
|
|
677
|
+
constructor(_params) {
|
|
678
|
+
super(), _define_property2(this, "_params", void 0), _define_property2(this, "_replicators", void 0), /**
|
|
679
|
+
* Remote peer id -> connection.
|
|
680
|
+
*/
|
|
681
|
+
_define_property2(this, "_connections", void 0), _define_property2(this, "_lifecycleState", void 0), _define_property2(this, "_connected", void 0), _define_property2(this, "_ready", void 0), this._params = _params, this._replicators = /* @__PURE__ */ new Set(), this._connections = /* @__PURE__ */ new Map(), this._lifecycleState = LifecycleState.CLOSED, this._connected = new Trigger(), this._ready = new Trigger();
|
|
682
|
+
}
|
|
643
683
|
};
|
|
644
684
|
_ts_decorate2([
|
|
645
685
|
synchronized
|
|
@@ -661,10 +701,20 @@ var isEchoPeerMetadata = (metadata) => metadata?.dxos_peerSource === "EchoNetwor
|
|
|
661
701
|
|
|
662
702
|
// src/automerge/heads-store.ts
|
|
663
703
|
import { headsEncoding } from "@dxos/indexing";
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
704
|
+
function _define_property3(obj, key, value) {
|
|
705
|
+
if (key in obj) {
|
|
706
|
+
Object.defineProperty(obj, key, {
|
|
707
|
+
value,
|
|
708
|
+
enumerable: true,
|
|
709
|
+
configurable: true,
|
|
710
|
+
writable: true
|
|
711
|
+
});
|
|
712
|
+
} else {
|
|
713
|
+
obj[key] = value;
|
|
667
714
|
}
|
|
715
|
+
return obj;
|
|
716
|
+
}
|
|
717
|
+
var HeadsStore = class {
|
|
668
718
|
setHeads(documentId, heads, batch) {
|
|
669
719
|
batch.put(documentId, heads, {
|
|
670
720
|
sublevel: this._db,
|
|
@@ -679,17 +729,31 @@ var HeadsStore = class {
|
|
|
679
729
|
valueEncoding: headsEncoding
|
|
680
730
|
});
|
|
681
731
|
}
|
|
732
|
+
constructor({ db }) {
|
|
733
|
+
_define_property3(this, "_db", void 0);
|
|
734
|
+
this._db = db;
|
|
735
|
+
}
|
|
682
736
|
};
|
|
683
737
|
|
|
684
738
|
// src/automerge/leveldb-storage-adapter.ts
|
|
685
|
-
import {
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
739
|
+
import { Resource as Resource2 } from "@dxos/context";
|
|
740
|
+
function _define_property4(obj, key, value) {
|
|
741
|
+
if (key in obj) {
|
|
742
|
+
Object.defineProperty(obj, key, {
|
|
743
|
+
value,
|
|
744
|
+
enumerable: true,
|
|
745
|
+
configurable: true,
|
|
746
|
+
writable: true
|
|
747
|
+
});
|
|
748
|
+
} else {
|
|
749
|
+
obj[key] = value;
|
|
689
750
|
}
|
|
751
|
+
return obj;
|
|
752
|
+
}
|
|
753
|
+
var LevelDBStorageAdapter = class extends Resource2 {
|
|
690
754
|
async load(keyArray) {
|
|
691
755
|
try {
|
|
692
|
-
if (this.
|
|
756
|
+
if (!this.isOpen) {
|
|
693
757
|
return void 0;
|
|
694
758
|
}
|
|
695
759
|
const startMs = Date.now();
|
|
@@ -707,7 +771,7 @@ var LevelDBStorageAdapter = class extends Resource2 {
|
|
|
707
771
|
}
|
|
708
772
|
}
|
|
709
773
|
async save(keyArray, binary) {
|
|
710
|
-
if (this.
|
|
774
|
+
if (!this.isOpen) {
|
|
711
775
|
return void 0;
|
|
712
776
|
}
|
|
713
777
|
const startMs = Date.now();
|
|
@@ -725,7 +789,7 @@ var LevelDBStorageAdapter = class extends Resource2 {
|
|
|
725
789
|
this._params.monitor?.recordStoreDuration(Date.now() - startMs);
|
|
726
790
|
}
|
|
727
791
|
async remove(keyArray) {
|
|
728
|
-
if (this.
|
|
792
|
+
if (!this.isOpen) {
|
|
729
793
|
return void 0;
|
|
730
794
|
}
|
|
731
795
|
await this._params.db.del(keyArray, {
|
|
@@ -733,7 +797,7 @@ var LevelDBStorageAdapter = class extends Resource2 {
|
|
|
733
797
|
});
|
|
734
798
|
}
|
|
735
799
|
async loadRange(keyPrefix) {
|
|
736
|
-
if (this.
|
|
800
|
+
if (!this.isOpen) {
|
|
737
801
|
return [];
|
|
738
802
|
}
|
|
739
803
|
const startMs = Date.now();
|
|
@@ -756,7 +820,7 @@ var LevelDBStorageAdapter = class extends Resource2 {
|
|
|
756
820
|
return result;
|
|
757
821
|
}
|
|
758
822
|
async removeRange(keyPrefix) {
|
|
759
|
-
if (this.
|
|
823
|
+
if (!this.isOpen) {
|
|
760
824
|
return void 0;
|
|
761
825
|
}
|
|
762
826
|
const batch = this._params.db.batch();
|
|
@@ -774,6 +838,9 @@ var LevelDBStorageAdapter = class extends Resource2 {
|
|
|
774
838
|
}
|
|
775
839
|
await batch.write();
|
|
776
840
|
}
|
|
841
|
+
constructor(_params) {
|
|
842
|
+
super(), _define_property4(this, "_params", void 0), this._params = _params;
|
|
843
|
+
}
|
|
777
844
|
};
|
|
778
845
|
var keyEncoder = {
|
|
779
846
|
encode: (key) => Buffer.from(key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-")),
|
|
@@ -787,6 +854,19 @@ var encodingOptions = {
|
|
|
787
854
|
var isLevelDbNotFoundError = (err) => err.code === "LEVEL_NOT_FOUND";
|
|
788
855
|
|
|
789
856
|
// src/automerge/automerge-host.ts
|
|
857
|
+
function _define_property5(obj, key, value) {
|
|
858
|
+
if (key in obj) {
|
|
859
|
+
Object.defineProperty(obj, key, {
|
|
860
|
+
value,
|
|
861
|
+
enumerable: true,
|
|
862
|
+
configurable: true,
|
|
863
|
+
writable: true
|
|
864
|
+
});
|
|
865
|
+
} else {
|
|
866
|
+
obj[key] = value;
|
|
867
|
+
}
|
|
868
|
+
return obj;
|
|
869
|
+
}
|
|
790
870
|
function _ts_decorate3(decorators, target, key, desc) {
|
|
791
871
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
792
872
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -800,44 +880,17 @@ var FIND_PARAMS = {
|
|
|
800
880
|
"requesting"
|
|
801
881
|
]
|
|
802
882
|
};
|
|
883
|
+
var BUNDLE_SIZE = 100;
|
|
884
|
+
var BUNDLE_SYNC_CONCURRENCY = 2;
|
|
885
|
+
var BUNDLE_SYNC_THRESHOLD = 50;
|
|
803
886
|
var AutomergeHost = class extends Resource3 {
|
|
804
|
-
constructor({ db, indexMetadataStore, dataMonitor, peerIdProvider, getSpaceKeyByRootDocumentId }) {
|
|
805
|
-
super();
|
|
806
|
-
this._collectionSynchronizer = new CollectionSynchronizer({
|
|
807
|
-
queryCollectionState: this._queryCollectionState.bind(this),
|
|
808
|
-
sendCollectionState: this._sendCollectionState.bind(this),
|
|
809
|
-
shouldSyncCollection: this._shouldSyncCollection.bind(this)
|
|
810
|
-
});
|
|
811
|
-
this.collectionStateUpdated = new Event2();
|
|
812
|
-
/**
|
|
813
|
-
* Fired after a batch of documents was saved to disk.
|
|
814
|
-
*/
|
|
815
|
-
this.documentsSaved = new Event2();
|
|
816
|
-
this._db = db;
|
|
817
|
-
this._storage = new LevelDBStorageAdapter({
|
|
818
|
-
db: db.sublevel("automerge"),
|
|
819
|
-
callbacks: {
|
|
820
|
-
beforeSave: async (params) => this._beforeSave(params),
|
|
821
|
-
afterSave: async (key) => this._afterSave(key)
|
|
822
|
-
},
|
|
823
|
-
monitor: dataMonitor
|
|
824
|
-
});
|
|
825
|
-
this._echoNetworkAdapter = new EchoNetworkAdapter({
|
|
826
|
-
getContainingSpaceForDocument: this._getContainingSpaceForDocument.bind(this),
|
|
827
|
-
isDocumentInRemoteCollection: this._isDocumentInRemoteCollection.bind(this),
|
|
828
|
-
onCollectionStateQueried: this._onCollectionStateQueried.bind(this),
|
|
829
|
-
onCollectionStateReceived: this._onCollectionStateReceived.bind(this),
|
|
830
|
-
monitor: dataMonitor
|
|
831
|
-
});
|
|
832
|
-
this._headsStore = new HeadsStore({
|
|
833
|
-
db: db.sublevel("heads")
|
|
834
|
-
});
|
|
835
|
-
this._indexMetadataStore = indexMetadataStore;
|
|
836
|
-
this._peerIdProvider = peerIdProvider;
|
|
837
|
-
this._getSpaceKeyByRootDocumentId = getSpaceKeyByRootDocumentId;
|
|
838
|
-
}
|
|
839
887
|
async _open() {
|
|
840
888
|
this._peerId = `host-${this._peerIdProvider?.() ?? PublicKey.random().toHex()}`;
|
|
889
|
+
this._onHeadsChangedTask = new DeferredTask(this._ctx, async () => {
|
|
890
|
+
const docHeads = Array.from(this._headsUpdates.entries());
|
|
891
|
+
this._headsUpdates.clear();
|
|
892
|
+
this._onHeadsChanged(docHeads);
|
|
893
|
+
});
|
|
841
894
|
await this._storage.open?.();
|
|
842
895
|
this._repo = new Repo({
|
|
843
896
|
peerId: this._peerId,
|
|
@@ -865,6 +918,28 @@ var AutomergeHost = class extends Resource3 {
|
|
|
865
918
|
}
|
|
866
919
|
}
|
|
867
920
|
});
|
|
921
|
+
this._syncTask = new DeferredTask(this._ctx, async () => {
|
|
922
|
+
const collectionToSync = Array.from(this._collectionsToSync.values());
|
|
923
|
+
if (collectionToSync.length === 0) {
|
|
924
|
+
return;
|
|
925
|
+
}
|
|
926
|
+
await Promise.all(collectionToSync.map(async ({ collectionId, peerId }) => {
|
|
927
|
+
try {
|
|
928
|
+
await this._handleCollectionSync(collectionId, peerId);
|
|
929
|
+
} catch (err) {
|
|
930
|
+
log3.error("failed to sync collection", {
|
|
931
|
+
collectionId,
|
|
932
|
+
peerId,
|
|
933
|
+
err
|
|
934
|
+
}, {
|
|
935
|
+
F: __dxlog_file3,
|
|
936
|
+
L: 223,
|
|
937
|
+
S: this,
|
|
938
|
+
C: (f, a) => f(...a)
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
}));
|
|
942
|
+
});
|
|
868
943
|
await this._echoNetworkAdapter.open();
|
|
869
944
|
await this._collectionSynchronizer.open();
|
|
870
945
|
await this._echoNetworkAdapter.open();
|
|
@@ -874,7 +949,8 @@ var AutomergeHost = class extends Resource3 {
|
|
|
874
949
|
await this._collectionSynchronizer.close();
|
|
875
950
|
await this._storage.close?.();
|
|
876
951
|
await this._echoNetworkAdapter.close();
|
|
877
|
-
|
|
952
|
+
this._syncTask = void 0;
|
|
953
|
+
this._onHeadsChangedTask = void 0;
|
|
878
954
|
}
|
|
879
955
|
/**
|
|
880
956
|
* @deprecated To be abstracted away.
|
|
@@ -889,15 +965,42 @@ var AutomergeHost = class extends Resource3 {
|
|
|
889
965
|
return Object.keys(this._repo.handles).length;
|
|
890
966
|
}
|
|
891
967
|
async addReplicator(replicator) {
|
|
968
|
+
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
969
|
+
F: __dxlog_file3,
|
|
970
|
+
L: 259,
|
|
971
|
+
S: this,
|
|
972
|
+
A: [
|
|
973
|
+
"this.isOpen",
|
|
974
|
+
"'AutomergeHost is not open'"
|
|
975
|
+
]
|
|
976
|
+
});
|
|
892
977
|
await this._echoNetworkAdapter.addReplicator(replicator);
|
|
893
978
|
}
|
|
894
979
|
async removeReplicator(replicator) {
|
|
980
|
+
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
981
|
+
F: __dxlog_file3,
|
|
982
|
+
L: 264,
|
|
983
|
+
S: this,
|
|
984
|
+
A: [
|
|
985
|
+
"this.isOpen",
|
|
986
|
+
"'AutomergeHost is not open'"
|
|
987
|
+
]
|
|
988
|
+
});
|
|
895
989
|
await this._echoNetworkAdapter.removeReplicator(replicator);
|
|
896
990
|
}
|
|
897
991
|
/**
|
|
898
992
|
* Loads the document handle from the repo and waits for it to be ready.
|
|
899
993
|
*/
|
|
900
994
|
async loadDoc(ctx, documentId, opts) {
|
|
995
|
+
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
996
|
+
F: __dxlog_file3,
|
|
997
|
+
L: 272,
|
|
998
|
+
S: this,
|
|
999
|
+
A: [
|
|
1000
|
+
"this.isOpen",
|
|
1001
|
+
"'AutomergeHost is not open'"
|
|
1002
|
+
]
|
|
1003
|
+
});
|
|
901
1004
|
let handle;
|
|
902
1005
|
if (typeof documentId === "string") {
|
|
903
1006
|
handle = this._repo.handles[documentId];
|
|
@@ -915,6 +1018,15 @@ var AutomergeHost = class extends Resource3 {
|
|
|
915
1018
|
return handle;
|
|
916
1019
|
}
|
|
917
1020
|
async exportDoc(ctx, id) {
|
|
1021
|
+
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1022
|
+
F: __dxlog_file3,
|
|
1023
|
+
L: 295,
|
|
1024
|
+
S: this,
|
|
1025
|
+
A: [
|
|
1026
|
+
"this.isOpen",
|
|
1027
|
+
"'AutomergeHost is not open'"
|
|
1028
|
+
]
|
|
1029
|
+
});
|
|
918
1030
|
const documentId = interpretAsDocumentId(id);
|
|
919
1031
|
const chunks = await this._storage.loadRange([
|
|
920
1032
|
documentId
|
|
@@ -925,6 +1037,15 @@ var AutomergeHost = class extends Resource3 {
|
|
|
925
1037
|
* Create new persisted document.
|
|
926
1038
|
*/
|
|
927
1039
|
createDoc(initialValue, opts) {
|
|
1040
|
+
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1041
|
+
F: __dxlog_file3,
|
|
1042
|
+
L: 306,
|
|
1043
|
+
S: this,
|
|
1044
|
+
A: [
|
|
1045
|
+
"this.isOpen",
|
|
1046
|
+
"'AutomergeHost is not open'"
|
|
1047
|
+
]
|
|
1048
|
+
});
|
|
928
1049
|
if (opts?.preserveHistory) {
|
|
929
1050
|
if (initialValue instanceof Uint8Array) {
|
|
930
1051
|
return this._repo.import(initialValue);
|
|
@@ -941,6 +1062,15 @@ var AutomergeHost = class extends Resource3 {
|
|
|
941
1062
|
}
|
|
942
1063
|
}
|
|
943
1064
|
async waitUntilHeadsReplicated(heads) {
|
|
1065
|
+
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1066
|
+
F: __dxlog_file3,
|
|
1067
|
+
L: 328,
|
|
1068
|
+
S: this,
|
|
1069
|
+
A: [
|
|
1070
|
+
"this.isOpen",
|
|
1071
|
+
"'AutomergeHost is not open'"
|
|
1072
|
+
]
|
|
1073
|
+
});
|
|
944
1074
|
const entries = heads.entries;
|
|
945
1075
|
if (!entries?.length) {
|
|
946
1076
|
return;
|
|
@@ -956,10 +1086,10 @@ var AutomergeHost = class extends Resource3 {
|
|
|
956
1086
|
return !(currentHeads !== null && headsEquals(currentHeads, targetHeads));
|
|
957
1087
|
});
|
|
958
1088
|
if (headsToWait.length > 0) {
|
|
959
|
-
await Promise.all(headsToWait.map(async (entry
|
|
1089
|
+
await Promise.all(headsToWait.map(async (entry) => {
|
|
960
1090
|
const handle = await this.loadDoc(Context.default(void 0, {
|
|
961
1091
|
F: __dxlog_file3,
|
|
962
|
-
L:
|
|
1092
|
+
L: 346
|
|
963
1093
|
}), entry.documentId);
|
|
964
1094
|
await waitForHeads(handle, entry.heads);
|
|
965
1095
|
}));
|
|
@@ -967,12 +1097,21 @@ var AutomergeHost = class extends Resource3 {
|
|
|
967
1097
|
await this._repo.flush(documentIds.filter((documentId) => this._repo.handles[documentId] && this._repo.handles[documentId].isReady()));
|
|
968
1098
|
}
|
|
969
1099
|
async reIndexHeads(documentIds) {
|
|
1100
|
+
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1101
|
+
F: __dxlog_file3,
|
|
1102
|
+
L: 359,
|
|
1103
|
+
S: this,
|
|
1104
|
+
A: [
|
|
1105
|
+
"this.isOpen",
|
|
1106
|
+
"'AutomergeHost is not open'"
|
|
1107
|
+
]
|
|
1108
|
+
});
|
|
970
1109
|
for (const documentId of documentIds) {
|
|
971
1110
|
log3("re-indexing heads for document", {
|
|
972
1111
|
documentId
|
|
973
1112
|
}, {
|
|
974
1113
|
F: __dxlog_file3,
|
|
975
|
-
L:
|
|
1114
|
+
L: 361,
|
|
976
1115
|
S: this,
|
|
977
1116
|
C: (f, a) => f(...a)
|
|
978
1117
|
});
|
|
@@ -982,7 +1121,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
982
1121
|
documentId
|
|
983
1122
|
}, {
|
|
984
1123
|
F: __dxlog_file3,
|
|
985
|
-
L:
|
|
1124
|
+
L: 364,
|
|
986
1125
|
S: this,
|
|
987
1126
|
C: (f, a) => f(...a)
|
|
988
1127
|
});
|
|
@@ -995,7 +1134,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
995
1134
|
}
|
|
996
1135
|
log3("done re-indexing heads", void 0, {
|
|
997
1136
|
F: __dxlog_file3,
|
|
998
|
-
L:
|
|
1137
|
+
L: 373,
|
|
999
1138
|
S: this,
|
|
1000
1139
|
C: (f, a) => f(...a)
|
|
1001
1140
|
});
|
|
@@ -1056,13 +1195,31 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1056
1195
|
* Called by AutomergeStorageAdapter after levelDB batch commit.
|
|
1057
1196
|
*/
|
|
1058
1197
|
async _afterSave(path) {
|
|
1198
|
+
if (!this.isOpen) {
|
|
1199
|
+
return void 0;
|
|
1200
|
+
}
|
|
1059
1201
|
this._indexMetadataStore.notifyMarkedDirty();
|
|
1060
1202
|
const documentId = path[0];
|
|
1061
|
-
const
|
|
1062
|
-
if (
|
|
1063
|
-
|
|
1064
|
-
|
|
1203
|
+
const handle = this._repo.handles[documentId];
|
|
1204
|
+
if (!handle || !handle.isReady()) {
|
|
1205
|
+
return;
|
|
1206
|
+
}
|
|
1207
|
+
const document = handle.doc();
|
|
1208
|
+
if (!document) {
|
|
1209
|
+
return;
|
|
1065
1210
|
}
|
|
1211
|
+
const heads = getHeads(document);
|
|
1212
|
+
this._headsUpdates.set(documentId, heads);
|
|
1213
|
+
invariant2(this._onHeadsChangedTask, "onHeadsChangedTask is not initialized", {
|
|
1214
|
+
F: __dxlog_file3,
|
|
1215
|
+
L: 449,
|
|
1216
|
+
S: this,
|
|
1217
|
+
A: [
|
|
1218
|
+
"this._onHeadsChangedTask",
|
|
1219
|
+
"'onHeadsChangedTask is not initialized'"
|
|
1220
|
+
]
|
|
1221
|
+
});
|
|
1222
|
+
this._onHeadsChangedTask.schedule();
|
|
1066
1223
|
this.documentsSaved.emit();
|
|
1067
1224
|
}
|
|
1068
1225
|
_automergePeers() {
|
|
@@ -1099,7 +1256,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1099
1256
|
* Flush documents to disk.
|
|
1100
1257
|
*/
|
|
1101
1258
|
async flush({ documentIds } = {}) {
|
|
1102
|
-
const loadedDocuments = documentIds
|
|
1259
|
+
const loadedDocuments = (documentIds ?? Object.keys(this._repo.handles)).filter((documentId) => {
|
|
1103
1260
|
const handle = this._repo.handles[documentId];
|
|
1104
1261
|
return handle && handle.isReady();
|
|
1105
1262
|
});
|
|
@@ -1155,8 +1312,17 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1155
1312
|
missingOnRemote: diff.missingOnRemote.length,
|
|
1156
1313
|
missingOnLocal: diff.missingOnLocal.length,
|
|
1157
1314
|
differentDocuments: diff.different.length,
|
|
1158
|
-
localDocumentCount: Object.
|
|
1159
|
-
remoteDocumentCount: Object.
|
|
1315
|
+
localDocumentCount: Object.entries(localState.documents).filter(([_, heads]) => heads.length > 0).length,
|
|
1316
|
+
remoteDocumentCount: Object.entries(state.documents).filter(([_, heads]) => heads.length > 0).length,
|
|
1317
|
+
totalDocumentCount: (/* @__PURE__ */ new Set([
|
|
1318
|
+
...Object.keys(localState.documents),
|
|
1319
|
+
...Object.keys(state.documents)
|
|
1320
|
+
])).size,
|
|
1321
|
+
unsyncedDocumentCount: (/* @__PURE__ */ new Set([
|
|
1322
|
+
...diff.missingOnLocal,
|
|
1323
|
+
...diff.missingOnRemote,
|
|
1324
|
+
...diff.different
|
|
1325
|
+
])).size
|
|
1160
1326
|
});
|
|
1161
1327
|
}
|
|
1162
1328
|
return result;
|
|
@@ -1173,6 +1339,14 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1173
1339
|
this._collectionSynchronizer.setLocalCollectionState(collectionId, {
|
|
1174
1340
|
documents
|
|
1175
1341
|
});
|
|
1342
|
+
const interestedPeers = this._echoNetworkAdapter.getPeersInterestedInCollection(collectionId);
|
|
1343
|
+
if (interestedPeers.length > 0) {
|
|
1344
|
+
for (const peerId of interestedPeers) {
|
|
1345
|
+
this._sendCollectionState(collectionId, peerId, {
|
|
1346
|
+
documents
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1176
1350
|
}
|
|
1177
1351
|
async clearLocalCollectionState(collectionId) {
|
|
1178
1352
|
this._collectionSynchronizer.clearLocalCollectionState(collectionId);
|
|
@@ -1196,52 +1370,273 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1196
1370
|
this._collectionSynchronizer.onConnectionClosed(peerId);
|
|
1197
1371
|
}
|
|
1198
1372
|
_onRemoteCollectionStateUpdated(collectionId, peerId) {
|
|
1373
|
+
this._collectionsToSync.add({
|
|
1374
|
+
collectionId,
|
|
1375
|
+
peerId
|
|
1376
|
+
});
|
|
1377
|
+
this._syncTask?.schedule();
|
|
1378
|
+
}
|
|
1379
|
+
async _handleCollectionSync(collectionId, peerId) {
|
|
1199
1380
|
const localState = this._collectionSynchronizer.getLocalCollectionState(collectionId);
|
|
1200
1381
|
const remoteState = this._collectionSynchronizer.getRemoteCollectionStates(collectionId).get(peerId);
|
|
1201
1382
|
if (!localState || !remoteState) {
|
|
1202
1383
|
return;
|
|
1203
1384
|
}
|
|
1204
1385
|
const { different, missingOnLocal, missingOnRemote } = diffCollectionState(localState, remoteState);
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1386
|
+
if (different.length === 0 && missingOnLocal.length === 0 && missingOnRemote.length === 0) {
|
|
1387
|
+
return;
|
|
1388
|
+
}
|
|
1389
|
+
const toReplicateWithoutBatching = [
|
|
1208
1390
|
...different
|
|
1209
1391
|
];
|
|
1210
|
-
|
|
1392
|
+
const bundleSyncEnabled = this._echoNetworkAdapter.bundleSyncEnabledForPeer(peerId);
|
|
1393
|
+
if (bundleSyncEnabled && missingOnRemote.length >= BUNDLE_SYNC_THRESHOLD) {
|
|
1394
|
+
log3("pushing bundle", {
|
|
1395
|
+
amount: missingOnRemote.length
|
|
1396
|
+
}, {
|
|
1397
|
+
F: __dxlog_file3,
|
|
1398
|
+
L: 650,
|
|
1399
|
+
S: this,
|
|
1400
|
+
C: (f, a) => f(...a)
|
|
1401
|
+
});
|
|
1402
|
+
const { syncInteractively } = await this._pushInBundles(peerId, missingOnRemote);
|
|
1403
|
+
toReplicateWithoutBatching.push(...syncInteractively);
|
|
1404
|
+
} else {
|
|
1405
|
+
log3.verbose("failed to push bundle, replicating interactively", {
|
|
1406
|
+
collectionId,
|
|
1407
|
+
peerId,
|
|
1408
|
+
amount: missingOnRemote.length
|
|
1409
|
+
}, {
|
|
1410
|
+
F: __dxlog_file3,
|
|
1411
|
+
L: 654,
|
|
1412
|
+
S: this,
|
|
1413
|
+
C: (f, a) => f(...a)
|
|
1414
|
+
});
|
|
1415
|
+
toReplicateWithoutBatching.push(...missingOnRemote);
|
|
1416
|
+
}
|
|
1417
|
+
if (bundleSyncEnabled && missingOnLocal.length >= BUNDLE_SYNC_THRESHOLD) {
|
|
1418
|
+
log3("pulling bundle", {
|
|
1419
|
+
amount: missingOnLocal.length
|
|
1420
|
+
}, {
|
|
1421
|
+
F: __dxlog_file3,
|
|
1422
|
+
L: 662,
|
|
1423
|
+
S: this,
|
|
1424
|
+
C: (f, a) => f(...a)
|
|
1425
|
+
});
|
|
1426
|
+
const { syncInteractively } = await this._pullInBundles(peerId, missingOnLocal);
|
|
1427
|
+
toReplicateWithoutBatching.push(...syncInteractively);
|
|
1428
|
+
} else {
|
|
1429
|
+
log3.verbose("failed to pull bundle, replicating interactively", {
|
|
1430
|
+
collectionId,
|
|
1431
|
+
peerId,
|
|
1432
|
+
amount: missingOnLocal.length
|
|
1433
|
+
}, {
|
|
1434
|
+
F: __dxlog_file3,
|
|
1435
|
+
L: 666,
|
|
1436
|
+
S: this,
|
|
1437
|
+
C: (f, a) => f(...a)
|
|
1438
|
+
});
|
|
1439
|
+
toReplicateWithoutBatching.push(...missingOnLocal);
|
|
1440
|
+
}
|
|
1441
|
+
if (toReplicateWithoutBatching.length === 0) {
|
|
1211
1442
|
return;
|
|
1212
1443
|
}
|
|
1213
1444
|
log3("replicating documents after collection sync", {
|
|
1214
1445
|
collectionId,
|
|
1215
1446
|
peerId,
|
|
1216
|
-
|
|
1217
|
-
count:
|
|
1447
|
+
toReplicateWithoutBatching,
|
|
1448
|
+
count: toReplicateWithoutBatching.length
|
|
1218
1449
|
}, {
|
|
1219
1450
|
F: __dxlog_file3,
|
|
1220
|
-
L:
|
|
1451
|
+
L: 678,
|
|
1221
1452
|
S: this,
|
|
1222
1453
|
C: (f, a) => f(...a)
|
|
1223
1454
|
});
|
|
1224
|
-
for (const documentId of
|
|
1455
|
+
for (const documentId of toReplicateWithoutBatching) {
|
|
1225
1456
|
this._repo.findWithProgress(documentId);
|
|
1226
1457
|
}
|
|
1227
1458
|
}
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1459
|
+
// TODO(mykola): Add retries of batches https://gist.github.com/mykola-vrmchk/fde270259e9209fcbf1331e5abbf12cf
|
|
1460
|
+
// TODO(mykola): Use effect to retry batches.
|
|
1461
|
+
async _pushInBundles(peerId, documentIds) {
|
|
1462
|
+
const documentsToPush = [
|
|
1463
|
+
...documentIds
|
|
1464
|
+
];
|
|
1465
|
+
const syncInteractively = [];
|
|
1466
|
+
while (documentsToPush.length > 0) {
|
|
1467
|
+
await Promise.all(range(BUNDLE_SYNC_CONCURRENCY).map(async () => {
|
|
1468
|
+
const bundle = documentsToPush.splice(0, BUNDLE_SIZE);
|
|
1469
|
+
if (bundle.length === 0) {
|
|
1470
|
+
return;
|
|
1471
|
+
}
|
|
1472
|
+
await this._pushBundle(peerId, bundle).catch((err) => {
|
|
1473
|
+
log3.warn("failed to push bundle, replicating interactively", {
|
|
1474
|
+
peerId,
|
|
1475
|
+
bundle,
|
|
1476
|
+
err
|
|
1477
|
+
}, {
|
|
1478
|
+
F: __dxlog_file3,
|
|
1479
|
+
L: 709,
|
|
1480
|
+
S: this,
|
|
1481
|
+
C: (f, a) => f(...a)
|
|
1482
|
+
});
|
|
1483
|
+
syncInteractively.push(...bundle);
|
|
1484
|
+
});
|
|
1485
|
+
}));
|
|
1486
|
+
}
|
|
1487
|
+
return {
|
|
1488
|
+
syncInteractively
|
|
1489
|
+
};
|
|
1490
|
+
}
|
|
1491
|
+
async _pushBundle(peerId, documentIds) {
|
|
1492
|
+
if (this._ctx.disposed) {
|
|
1493
|
+
return;
|
|
1494
|
+
}
|
|
1495
|
+
const docs = documentIds.map((documentId) => {
|
|
1496
|
+
const handle = this._repo.handles[documentId];
|
|
1497
|
+
if (!handle || !handle.isReady()) {
|
|
1498
|
+
log3.warn("document not ready, skipping", {
|
|
1499
|
+
documentId
|
|
1500
|
+
}, {
|
|
1501
|
+
F: __dxlog_file3,
|
|
1502
|
+
L: 727,
|
|
1503
|
+
S: this,
|
|
1504
|
+
C: (f, a) => f(...a)
|
|
1505
|
+
});
|
|
1506
|
+
return;
|
|
1507
|
+
}
|
|
1508
|
+
const doc = handle.doc();
|
|
1509
|
+
if (!doc) {
|
|
1510
|
+
log3.warn("document not available, skipping", {
|
|
1511
|
+
documentId
|
|
1512
|
+
}, {
|
|
1513
|
+
F: __dxlog_file3,
|
|
1514
|
+
L: 732,
|
|
1515
|
+
S: this,
|
|
1516
|
+
C: (f, a) => f(...a)
|
|
1517
|
+
});
|
|
1518
|
+
return;
|
|
1237
1519
|
}
|
|
1520
|
+
return {
|
|
1521
|
+
documentId,
|
|
1522
|
+
data: save(doc),
|
|
1523
|
+
heads: getHeads(doc)
|
|
1524
|
+
};
|
|
1525
|
+
});
|
|
1526
|
+
await this._echoNetworkAdapter.pushBundle(peerId, docs.filter(isNonNullable2));
|
|
1527
|
+
}
|
|
1528
|
+
async _pullInBundles(peerId, documentIds) {
|
|
1529
|
+
const documentsToPull = [
|
|
1530
|
+
...documentIds
|
|
1531
|
+
];
|
|
1532
|
+
const syncInteractively = [];
|
|
1533
|
+
const docsToImport = {};
|
|
1534
|
+
while (documentsToPull.length > 0) {
|
|
1535
|
+
await Promise.all(range(BUNDLE_SYNC_CONCURRENCY).map(async () => {
|
|
1536
|
+
const bundle = documentsToPull.splice(0, BUNDLE_SIZE);
|
|
1537
|
+
if (bundle.length === 0) {
|
|
1538
|
+
return;
|
|
1539
|
+
}
|
|
1540
|
+
const result = await this._pullBundle(peerId, bundle).catch((err) => {
|
|
1541
|
+
log3.warn("failed to pull bundle, replicating interactively", {
|
|
1542
|
+
peerId,
|
|
1543
|
+
bundle,
|
|
1544
|
+
err
|
|
1545
|
+
}, {
|
|
1546
|
+
F: __dxlog_file3,
|
|
1547
|
+
L: 762,
|
|
1548
|
+
S: this,
|
|
1549
|
+
C: (f, a) => f(...a)
|
|
1550
|
+
});
|
|
1551
|
+
syncInteractively.push(...bundle);
|
|
1552
|
+
});
|
|
1553
|
+
if (result) {
|
|
1554
|
+
Object.assign(docsToImport, result.docsToImport);
|
|
1555
|
+
}
|
|
1556
|
+
}));
|
|
1238
1557
|
}
|
|
1239
|
-
for (const
|
|
1240
|
-
this.
|
|
1241
|
-
|
|
1558
|
+
for (const [documentId, data] of Object.entries(docsToImport)) {
|
|
1559
|
+
this._repo.import(data, {
|
|
1560
|
+
docId: documentId
|
|
1242
1561
|
});
|
|
1243
1562
|
}
|
|
1244
|
-
|
|
1563
|
+
await this._repo.flush(Object.keys(docsToImport));
|
|
1564
|
+
return {
|
|
1565
|
+
syncInteractively
|
|
1566
|
+
};
|
|
1567
|
+
}
|
|
1568
|
+
async _pullBundle(peerId, documentIds) {
|
|
1569
|
+
if (this._ctx.disposed) {
|
|
1570
|
+
return;
|
|
1571
|
+
}
|
|
1572
|
+
const docHeads = Object.fromEntries(documentIds.map((documentId) => [
|
|
1573
|
+
documentId,
|
|
1574
|
+
[]
|
|
1575
|
+
]));
|
|
1576
|
+
const bundle = await this._echoNetworkAdapter.pullBundle(peerId, docHeads);
|
|
1577
|
+
return {
|
|
1578
|
+
docsToImport: bundle
|
|
1579
|
+
};
|
|
1580
|
+
}
|
|
1581
|
+
_onHeadsChanged(docHeads) {
|
|
1582
|
+
const collectionsChanged = /* @__PURE__ */ new Set();
|
|
1583
|
+
for (const collectionId of this._collectionSynchronizer.getRegisteredCollectionIds()) {
|
|
1584
|
+
const state = this._collectionSynchronizer.getLocalCollectionState(collectionId);
|
|
1585
|
+
let newState;
|
|
1586
|
+
for (const [documentId, heads] of docHeads) {
|
|
1587
|
+
if (state?.documents[documentId]) {
|
|
1588
|
+
if (!newState) {
|
|
1589
|
+
newState = structuredClone(state);
|
|
1590
|
+
}
|
|
1591
|
+
newState.documents[documentId] = heads;
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
if (newState) {
|
|
1595
|
+
this._collectionSynchronizer.setLocalCollectionState(collectionId, newState);
|
|
1596
|
+
collectionsChanged.add(collectionId);
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
for (const collectionId of collectionsChanged) {
|
|
1600
|
+
this.collectionStateUpdated.emit({
|
|
1601
|
+
collectionId
|
|
1602
|
+
});
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
constructor({ db, indexMetadataStore, dataMonitor, peerIdProvider, getSpaceKeyByRootDocumentId }) {
|
|
1606
|
+
super(), _define_property5(this, "_db", void 0), _define_property5(this, "_indexMetadataStore", void 0), _define_property5(this, "_echoNetworkAdapter", void 0), _define_property5(this, "_collectionSynchronizer", new CollectionSynchronizer({
|
|
1607
|
+
queryCollectionState: this._queryCollectionState.bind(this),
|
|
1608
|
+
sendCollectionState: this._sendCollectionState.bind(this),
|
|
1609
|
+
shouldSyncCollection: this._shouldSyncCollection.bind(this)
|
|
1610
|
+
})), _define_property5(this, "_repo", void 0), _define_property5(this, "_storage", void 0), _define_property5(this, "_headsStore", void 0), _define_property5(this, "_syncTask", void 0), /**
|
|
1611
|
+
* Cache of collections that would be synced on next sync task run.
|
|
1612
|
+
*/
|
|
1613
|
+
_define_property5(this, "_collectionsToSync", new ComplexSet(({ collectionId, peerId }) => `${collectionId}|${peerId}`)), _define_property5(this, "_peerId", void 0), _define_property5(this, "_peerIdProvider", void 0), _define_property5(this, "_getSpaceKeyByRootDocumentId", void 0), _define_property5(this, "collectionStateUpdated", new Event2()), /**
|
|
1614
|
+
* Fired after a batch of documents was saved to disk.
|
|
1615
|
+
*/
|
|
1616
|
+
_define_property5(this, "documentsSaved", new Event2()), _define_property5(this, "_headsUpdates", /* @__PURE__ */ new Map()), _define_property5(this, "_onHeadsChangedTask", void 0);
|
|
1617
|
+
this._db = db;
|
|
1618
|
+
this._storage = new LevelDBStorageAdapter({
|
|
1619
|
+
db: db.sublevel("automerge"),
|
|
1620
|
+
callbacks: {
|
|
1621
|
+
beforeSave: async (params) => this._beforeSave(params),
|
|
1622
|
+
afterSave: async (key) => this._afterSave(key)
|
|
1623
|
+
},
|
|
1624
|
+
monitor: dataMonitor
|
|
1625
|
+
});
|
|
1626
|
+
this._echoNetworkAdapter = new EchoNetworkAdapter({
|
|
1627
|
+
getContainingSpaceForDocument: this._getContainingSpaceForDocument.bind(this),
|
|
1628
|
+
isDocumentInRemoteCollection: this._isDocumentInRemoteCollection.bind(this),
|
|
1629
|
+
onCollectionStateQueried: this._onCollectionStateQueried.bind(this),
|
|
1630
|
+
onCollectionStateReceived: this._onCollectionStateReceived.bind(this),
|
|
1631
|
+
monitor: dataMonitor
|
|
1632
|
+
});
|
|
1633
|
+
this._headsStore = new HeadsStore({
|
|
1634
|
+
db: db.sublevel("heads")
|
|
1635
|
+
});
|
|
1636
|
+
this._indexMetadataStore = indexMetadataStore;
|
|
1637
|
+
this._peerIdProvider = peerIdProvider;
|
|
1638
|
+
this._getSpaceKeyByRootDocumentId = getSpaceKeyByRootDocumentId;
|
|
1639
|
+
}
|
|
1245
1640
|
};
|
|
1246
1641
|
_ts_decorate3([
|
|
1247
1642
|
trace2.info()
|
|
@@ -1277,7 +1672,7 @@ var changeIsPresentInDoc = (doc, changeHash) => {
|
|
|
1277
1672
|
var decodeCollectionState = (state) => {
|
|
1278
1673
|
invariant2(typeof state === "object" && state !== null, "Invalid state", {
|
|
1279
1674
|
F: __dxlog_file3,
|
|
1280
|
-
L:
|
|
1675
|
+
L: 842,
|
|
1281
1676
|
S: void 0,
|
|
1282
1677
|
A: [
|
|
1283
1678
|
"typeof state === 'object' && state !== null",
|
|
@@ -1294,7 +1689,7 @@ var encodeCollectionState = (state) => {
|
|
|
1294
1689
|
import { invariant as invariant5 } from "@dxos/invariant";
|
|
1295
1690
|
import { PublicKey as PublicKey2 } from "@dxos/keys";
|
|
1296
1691
|
import { log as log5 } from "@dxos/log";
|
|
1297
|
-
import { ComplexSet, defaultMap as defaultMap2 } from "@dxos/util";
|
|
1692
|
+
import { ComplexSet as ComplexSet2, defaultMap as defaultMap2 } from "@dxos/util";
|
|
1298
1693
|
|
|
1299
1694
|
// src/automerge/mesh-echo-replicator-connection.ts
|
|
1300
1695
|
import * as A from "@automerge/automerge";
|
|
@@ -1303,11 +1698,75 @@ import { Resource as Resource4 } from "@dxos/context";
|
|
|
1303
1698
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1304
1699
|
import { log as log4 } from "@dxos/log";
|
|
1305
1700
|
import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
|
|
1701
|
+
function _define_property6(obj, key, value) {
|
|
1702
|
+
if (key in obj) {
|
|
1703
|
+
Object.defineProperty(obj, key, {
|
|
1704
|
+
value,
|
|
1705
|
+
enumerable: true,
|
|
1706
|
+
configurable: true,
|
|
1707
|
+
writable: true
|
|
1708
|
+
});
|
|
1709
|
+
} else {
|
|
1710
|
+
obj[key] = value;
|
|
1711
|
+
}
|
|
1712
|
+
return obj;
|
|
1713
|
+
}
|
|
1306
1714
|
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator-connection.ts";
|
|
1307
1715
|
var DEFAULT_FACTORY = (params) => new AutomergeReplicator(...params);
|
|
1308
1716
|
var MeshReplicatorConnection = class extends Resource4 {
|
|
1717
|
+
_disconnectIfEnabled() {
|
|
1718
|
+
if (this._isEnabled) {
|
|
1719
|
+
this._params.onRemoteDisconnected();
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
get peerId() {
|
|
1723
|
+
invariant3(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1724
|
+
F: __dxlog_file4,
|
|
1725
|
+
L: 106,
|
|
1726
|
+
S: this,
|
|
1727
|
+
A: [
|
|
1728
|
+
"this._remotePeerId != null",
|
|
1729
|
+
"'Remote peer has not connected yet.'"
|
|
1730
|
+
]
|
|
1731
|
+
});
|
|
1732
|
+
return this._remotePeerId;
|
|
1733
|
+
}
|
|
1734
|
+
get isEnabled() {
|
|
1735
|
+
return this._isEnabled;
|
|
1736
|
+
}
|
|
1737
|
+
get bundleSyncEnabled() {
|
|
1738
|
+
return false;
|
|
1739
|
+
}
|
|
1740
|
+
async shouldAdvertise(params) {
|
|
1741
|
+
return this._params.shouldAdvertise(params);
|
|
1742
|
+
}
|
|
1743
|
+
shouldSyncCollection(params) {
|
|
1744
|
+
return this._params.shouldSyncCollection(params);
|
|
1745
|
+
}
|
|
1746
|
+
/**
|
|
1747
|
+
* Start exchanging messages with the remote peer.
|
|
1748
|
+
* Call after the remote peer has connected.
|
|
1749
|
+
*/
|
|
1750
|
+
enable() {
|
|
1751
|
+
invariant3(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1752
|
+
F: __dxlog_file4,
|
|
1753
|
+
L: 131,
|
|
1754
|
+
S: this,
|
|
1755
|
+
A: [
|
|
1756
|
+
"this._remotePeerId != null",
|
|
1757
|
+
"'Remote peer has not connected yet.'"
|
|
1758
|
+
]
|
|
1759
|
+
});
|
|
1760
|
+
this._isEnabled = true;
|
|
1761
|
+
}
|
|
1762
|
+
/**
|
|
1763
|
+
* Stop exchanging messages with the remote peer.
|
|
1764
|
+
*/
|
|
1765
|
+
disable() {
|
|
1766
|
+
this._isEnabled = false;
|
|
1767
|
+
}
|
|
1309
1768
|
constructor(_params) {
|
|
1310
|
-
super(), this._params = _params, this.remoteDeviceKey = null, this._remotePeerId = null, this._isEnabled = false;
|
|
1769
|
+
super(), _define_property6(this, "_params", void 0), _define_property6(this, "readable", void 0), _define_property6(this, "writable", void 0), _define_property6(this, "remoteDeviceKey", void 0), _define_property6(this, "replicatorExtension", void 0), _define_property6(this, "_remotePeerId", void 0), _define_property6(this, "_isEnabled", void 0), this._params = _params, this.remoteDeviceKey = null, this._remotePeerId = null, this._isEnabled = false;
|
|
1311
1770
|
let readableStreamController;
|
|
1312
1771
|
this.readable = new ReadableStream({
|
|
1313
1772
|
start: (controller) => {
|
|
@@ -1371,54 +1830,6 @@ var MeshReplicatorConnection = class extends Resource4 {
|
|
|
1371
1830
|
}
|
|
1372
1831
|
]);
|
|
1373
1832
|
}
|
|
1374
|
-
_disconnectIfEnabled() {
|
|
1375
|
-
if (this._isEnabled) {
|
|
1376
|
-
this._params.onRemoteDisconnected();
|
|
1377
|
-
}
|
|
1378
|
-
}
|
|
1379
|
-
get peerId() {
|
|
1380
|
-
invariant3(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1381
|
-
F: __dxlog_file4,
|
|
1382
|
-
L: 106,
|
|
1383
|
-
S: this,
|
|
1384
|
-
A: [
|
|
1385
|
-
"this._remotePeerId != null",
|
|
1386
|
-
"'Remote peer has not connected yet.'"
|
|
1387
|
-
]
|
|
1388
|
-
});
|
|
1389
|
-
return this._remotePeerId;
|
|
1390
|
-
}
|
|
1391
|
-
get isEnabled() {
|
|
1392
|
-
return this._isEnabled;
|
|
1393
|
-
}
|
|
1394
|
-
async shouldAdvertise(params) {
|
|
1395
|
-
return this._params.shouldAdvertise(params);
|
|
1396
|
-
}
|
|
1397
|
-
shouldSyncCollection(params) {
|
|
1398
|
-
return this._params.shouldSyncCollection(params);
|
|
1399
|
-
}
|
|
1400
|
-
/**
|
|
1401
|
-
* Start exchanging messages with the remote peer.
|
|
1402
|
-
* Call after the remote peer has connected.
|
|
1403
|
-
*/
|
|
1404
|
-
enable() {
|
|
1405
|
-
invariant3(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1406
|
-
F: __dxlog_file4,
|
|
1407
|
-
L: 127,
|
|
1408
|
-
S: this,
|
|
1409
|
-
A: [
|
|
1410
|
-
"this._remotePeerId != null",
|
|
1411
|
-
"'Remote peer has not connected yet.'"
|
|
1412
|
-
]
|
|
1413
|
-
});
|
|
1414
|
-
this._isEnabled = true;
|
|
1415
|
-
}
|
|
1416
|
-
/**
|
|
1417
|
-
* Stop exchanging messages with the remote peer.
|
|
1418
|
-
*/
|
|
1419
|
-
disable() {
|
|
1420
|
-
this._isEnabled = false;
|
|
1421
|
-
}
|
|
1422
1833
|
};
|
|
1423
1834
|
var logSendSync = (message) => {
|
|
1424
1835
|
log4("sendSyncMessage", () => {
|
|
@@ -1435,7 +1846,7 @@ var logSendSync = (message) => {
|
|
|
1435
1846
|
};
|
|
1436
1847
|
}, {
|
|
1437
1848
|
F: __dxlog_file4,
|
|
1438
|
-
L:
|
|
1849
|
+
L: 144,
|
|
1439
1850
|
S: void 0,
|
|
1440
1851
|
C: (f, a) => f(...a)
|
|
1441
1852
|
});
|
|
@@ -1461,26 +1872,21 @@ var getSpaceIdFromCollectionId = (collectionId) => {
|
|
|
1461
1872
|
};
|
|
1462
1873
|
|
|
1463
1874
|
// src/automerge/mesh-echo-replicator.ts
|
|
1875
|
+
function _define_property7(obj, key, value) {
|
|
1876
|
+
if (key in obj) {
|
|
1877
|
+
Object.defineProperty(obj, key, {
|
|
1878
|
+
value,
|
|
1879
|
+
enumerable: true,
|
|
1880
|
+
configurable: true,
|
|
1881
|
+
writable: true
|
|
1882
|
+
});
|
|
1883
|
+
} else {
|
|
1884
|
+
obj[key] = value;
|
|
1885
|
+
}
|
|
1886
|
+
return obj;
|
|
1887
|
+
}
|
|
1464
1888
|
var __dxlog_file6 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts";
|
|
1465
1889
|
var MeshEchoReplicator = class {
|
|
1466
|
-
constructor() {
|
|
1467
|
-
/**
|
|
1468
|
-
* We might have multiple connections open with a peer (one per space), but there'll be only one enabled
|
|
1469
|
-
* connection at any given moment, because there's a single repo for all the spaces.
|
|
1470
|
-
* When a connection closes (space was closed) it gets removed from the list and the next connection
|
|
1471
|
-
* in the line gets enabled.
|
|
1472
|
-
*/
|
|
1473
|
-
this._connectionsPerPeer = /* @__PURE__ */ new Map();
|
|
1474
|
-
/**
|
|
1475
|
-
* A set of all connections (enabled and disabled).
|
|
1476
|
-
*/
|
|
1477
|
-
this._connections = /* @__PURE__ */ new Set();
|
|
1478
|
-
/**
|
|
1479
|
-
* spaceId -> deviceKey[]
|
|
1480
|
-
*/
|
|
1481
|
-
this._authorizedDevices = /* @__PURE__ */ new Map();
|
|
1482
|
-
this._context = null;
|
|
1483
|
-
}
|
|
1484
1890
|
async connect(context) {
|
|
1485
1891
|
this._context = context;
|
|
1486
1892
|
}
|
|
@@ -1500,7 +1906,7 @@ var MeshEchoReplicator = class {
|
|
|
1500
1906
|
createExtension(extensionFactory) {
|
|
1501
1907
|
invariant5(this._context, void 0, {
|
|
1502
1908
|
F: __dxlog_file6,
|
|
1503
|
-
L:
|
|
1909
|
+
L: 68,
|
|
1504
1910
|
S: this,
|
|
1505
1911
|
A: [
|
|
1506
1912
|
"this._context",
|
|
@@ -1515,13 +1921,13 @@ var MeshEchoReplicator = class {
|
|
|
1515
1921
|
peerId: connection.peerId
|
|
1516
1922
|
}, {
|
|
1517
1923
|
F: __dxlog_file6,
|
|
1518
|
-
L:
|
|
1924
|
+
L: 74,
|
|
1519
1925
|
S: this,
|
|
1520
1926
|
C: (f, a) => f(...a)
|
|
1521
1927
|
});
|
|
1522
1928
|
invariant5(this._context, void 0, {
|
|
1523
1929
|
F: __dxlog_file6,
|
|
1524
|
-
L:
|
|
1930
|
+
L: 75,
|
|
1525
1931
|
S: this,
|
|
1526
1932
|
A: [
|
|
1527
1933
|
"this._context",
|
|
@@ -1546,7 +1952,7 @@ var MeshEchoReplicator = class {
|
|
|
1546
1952
|
peerId: connection.peerId
|
|
1547
1953
|
}, {
|
|
1548
1954
|
F: __dxlog_file6,
|
|
1549
|
-
L:
|
|
1955
|
+
L: 89,
|
|
1550
1956
|
S: this,
|
|
1551
1957
|
C: (f, a) => f(...a)
|
|
1552
1958
|
});
|
|
@@ -1558,7 +1964,7 @@ var MeshEchoReplicator = class {
|
|
|
1558
1964
|
peerId: connection.peerId
|
|
1559
1965
|
}, {
|
|
1560
1966
|
F: __dxlog_file6,
|
|
1561
|
-
L:
|
|
1967
|
+
L: 97,
|
|
1562
1968
|
S: this,
|
|
1563
1969
|
C: (f, a) => f(...a)
|
|
1564
1970
|
});
|
|
@@ -1580,13 +1986,13 @@ var MeshEchoReplicator = class {
|
|
|
1580
1986
|
documentId: params.documentId
|
|
1581
1987
|
}, {
|
|
1582
1988
|
F: __dxlog_file6,
|
|
1583
|
-
L:
|
|
1989
|
+
L: 115,
|
|
1584
1990
|
S: this,
|
|
1585
1991
|
C: (f, a) => f(...a)
|
|
1586
1992
|
});
|
|
1587
1993
|
invariant5(this._context, void 0, {
|
|
1588
1994
|
F: __dxlog_file6,
|
|
1589
|
-
L:
|
|
1995
|
+
L: 116,
|
|
1590
1996
|
S: this,
|
|
1591
1997
|
A: [
|
|
1592
1998
|
"this._context",
|
|
@@ -1606,7 +2012,7 @@ var MeshEchoReplicator = class {
|
|
|
1606
2012
|
acceptDocument: remoteDocumentExists
|
|
1607
2013
|
}, {
|
|
1608
2014
|
F: __dxlog_file6,
|
|
1609
|
-
L:
|
|
2015
|
+
L: 124,
|
|
1610
2016
|
S: this,
|
|
1611
2017
|
C: (f, a) => f(...a)
|
|
1612
2018
|
});
|
|
@@ -1620,7 +2026,7 @@ var MeshEchoReplicator = class {
|
|
|
1620
2026
|
documentId: params.documentId
|
|
1621
2027
|
}, {
|
|
1622
2028
|
F: __dxlog_file6,
|
|
1623
|
-
L:
|
|
2029
|
+
L: 141,
|
|
1624
2030
|
S: this,
|
|
1625
2031
|
C: (f, a) => f(...a)
|
|
1626
2032
|
});
|
|
@@ -1636,7 +2042,7 @@ var MeshEchoReplicator = class {
|
|
|
1636
2042
|
isAuthorized
|
|
1637
2043
|
}, {
|
|
1638
2044
|
F: __dxlog_file6,
|
|
1639
|
-
L:
|
|
2045
|
+
L: 149,
|
|
1640
2046
|
S: this,
|
|
1641
2047
|
C: (f, a) => f(...a)
|
|
1642
2048
|
});
|
|
@@ -1644,7 +2050,7 @@ var MeshEchoReplicator = class {
|
|
|
1644
2050
|
} catch (err) {
|
|
1645
2051
|
log5.catch(err, void 0, {
|
|
1646
2052
|
F: __dxlog_file6,
|
|
1647
|
-
L:
|
|
2053
|
+
L: 159,
|
|
1648
2054
|
S: this,
|
|
1649
2055
|
C: (f, a) => f(...a)
|
|
1650
2056
|
});
|
|
@@ -1660,7 +2066,7 @@ var MeshEchoReplicator = class {
|
|
|
1660
2066
|
collectionId
|
|
1661
2067
|
}, {
|
|
1662
2068
|
F: __dxlog_file6,
|
|
1663
|
-
L:
|
|
2069
|
+
L: 169,
|
|
1664
2070
|
S: this,
|
|
1665
2071
|
C: (f, a) => f(...a)
|
|
1666
2072
|
});
|
|
@@ -1679,12 +2085,12 @@ var MeshEchoReplicator = class {
|
|
|
1679
2085
|
deviceKey
|
|
1680
2086
|
}, {
|
|
1681
2087
|
F: __dxlog_file6,
|
|
1682
|
-
L:
|
|
2088
|
+
L: 186,
|
|
1683
2089
|
S: this,
|
|
1684
2090
|
C: (f, a) => f(...a)
|
|
1685
2091
|
});
|
|
1686
2092
|
const spaceId = await createIdFromSpaceKey(spaceKey);
|
|
1687
|
-
defaultMap2(this._authorizedDevices, spaceId, () => new
|
|
2093
|
+
defaultMap2(this._authorizedDevices, spaceId, () => new ComplexSet2(PublicKey2.hash)).add(deviceKey);
|
|
1688
2094
|
for (const connection of this._connections) {
|
|
1689
2095
|
if (connection.isEnabled && connection.remoteDeviceKey && connection.remoteDeviceKey.equals(deviceKey)) {
|
|
1690
2096
|
if (this._connectionsPerPeer.has(connection.peerId)) {
|
|
@@ -1693,11 +2099,30 @@ var MeshEchoReplicator = class {
|
|
|
1693
2099
|
}
|
|
1694
2100
|
}
|
|
1695
2101
|
}
|
|
2102
|
+
constructor() {
|
|
2103
|
+
_define_property7(this, "_connectionsPerPeer", /* @__PURE__ */ new Map());
|
|
2104
|
+
_define_property7(this, "_connections", /* @__PURE__ */ new Set());
|
|
2105
|
+
_define_property7(this, "_authorizedDevices", /* @__PURE__ */ new Map());
|
|
2106
|
+
_define_property7(this, "_context", null);
|
|
2107
|
+
}
|
|
1696
2108
|
};
|
|
1697
2109
|
|
|
1698
2110
|
// src/automerge/echo-data-monitor.ts
|
|
1699
2111
|
import { trace as trace3 } from "@dxos/tracing";
|
|
1700
|
-
import { CircularBuffer,
|
|
2112
|
+
import { CircularBuffer, SlidingWindowSummary, mapValues } from "@dxos/util";
|
|
2113
|
+
function _define_property8(obj, key, value) {
|
|
2114
|
+
if (key in obj) {
|
|
2115
|
+
Object.defineProperty(obj, key, {
|
|
2116
|
+
value,
|
|
2117
|
+
enumerable: true,
|
|
2118
|
+
configurable: true,
|
|
2119
|
+
writable: true
|
|
2120
|
+
});
|
|
2121
|
+
} else {
|
|
2122
|
+
obj[key] = value;
|
|
2123
|
+
}
|
|
2124
|
+
return obj;
|
|
2125
|
+
}
|
|
1701
2126
|
function _ts_decorate4(decorators, target, key, desc) {
|
|
1702
2127
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1703
2128
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1707,20 +2132,6 @@ function _ts_decorate4(decorators, target, key, desc) {
|
|
|
1707
2132
|
var PER_SECOND_RATE_AVG_WINDOW_SIZE = 5;
|
|
1708
2133
|
var DEFAULT_AVG_WINDOW_SIZE = 25;
|
|
1709
2134
|
var EchoDataMonitor = class {
|
|
1710
|
-
constructor(_params = {
|
|
1711
|
-
timeSeriesLength: 30
|
|
1712
|
-
}) {
|
|
1713
|
-
this._params = _params;
|
|
1714
|
-
this._lastTick = 0;
|
|
1715
|
-
this._activeCounters = createLocalCounters();
|
|
1716
|
-
this._localTimeSeries = createLocalTimeSeries();
|
|
1717
|
-
this._storageAverages = createStorageAverages();
|
|
1718
|
-
this._replicationAverages = createNetworkAverages();
|
|
1719
|
-
this._sizeByMessage = {};
|
|
1720
|
-
this._lastReceivedMessages = new CircularBuffer(100);
|
|
1721
|
-
this._lastSentMessages = new CircularBuffer(100);
|
|
1722
|
-
this._connectionsCount = 0;
|
|
1723
|
-
}
|
|
1724
2135
|
tick(timeMs) {
|
|
1725
2136
|
this._advanceTimeWindow(timeMs - this._lastTick);
|
|
1726
2137
|
this._lastTick = timeMs;
|
|
@@ -1960,8 +2371,9 @@ var EchoDataMonitor = class {
|
|
|
1960
2371
|
messageCounts.failed++;
|
|
1961
2372
|
}
|
|
1962
2373
|
_getStatsForType(message) {
|
|
1963
|
-
|
|
1964
|
-
const
|
|
2374
|
+
var _this__sizeByMessage, _message_type, _this__activeCounters_byType, _message_type1;
|
|
2375
|
+
const messageSize = (_this__sizeByMessage = this._sizeByMessage)[_message_type = message.type] ?? (_this__sizeByMessage[_message_type] = createSlidingWindow());
|
|
2376
|
+
const messageCounts = (_this__activeCounters_byType = this._activeCounters.byType)[_message_type1 = message.type] ?? (_this__activeCounters_byType[_message_type1] = createMessageCounter());
|
|
1965
2377
|
return {
|
|
1966
2378
|
messageCounts,
|
|
1967
2379
|
messageSize
|
|
@@ -1970,21 +2382,48 @@ var EchoDataMonitor = class {
|
|
|
1970
2382
|
_computeMessageHistogram(groupKey) {
|
|
1971
2383
|
const result = {};
|
|
1972
2384
|
for (const receivedMessage of this._lastReceivedMessages) {
|
|
1973
|
-
|
|
2385
|
+
var _result, _receivedMessage_groupKey;
|
|
2386
|
+
const counters = (_result = result)[_receivedMessage_groupKey = receivedMessage[groupKey]] ?? (_result[_receivedMessage_groupKey] = {
|
|
1974
2387
|
received: 0,
|
|
1975
2388
|
sent: 0
|
|
1976
|
-
};
|
|
2389
|
+
});
|
|
1977
2390
|
counters.received++;
|
|
1978
2391
|
}
|
|
1979
2392
|
for (const receivedMessage of this._lastSentMessages) {
|
|
1980
|
-
|
|
2393
|
+
var _result1, _receivedMessage_groupKey1;
|
|
2394
|
+
const counters = (_result1 = result)[_receivedMessage_groupKey1 = receivedMessage[groupKey]] ?? (_result1[_receivedMessage_groupKey1] = {
|
|
1981
2395
|
received: 0,
|
|
1982
2396
|
sent: 0
|
|
1983
|
-
};
|
|
2397
|
+
});
|
|
1984
2398
|
counters.sent++;
|
|
1985
2399
|
}
|
|
1986
2400
|
return result;
|
|
1987
2401
|
}
|
|
2402
|
+
constructor(_params = {
|
|
2403
|
+
timeSeriesLength: 30
|
|
2404
|
+
}) {
|
|
2405
|
+
_define_property8(this, "_params", void 0);
|
|
2406
|
+
_define_property8(this, "_lastTick", void 0);
|
|
2407
|
+
_define_property8(this, "_activeCounters", void 0);
|
|
2408
|
+
_define_property8(this, "_lastCompleteCounters", void 0);
|
|
2409
|
+
_define_property8(this, "_localTimeSeries", void 0);
|
|
2410
|
+
_define_property8(this, "_storageAverages", void 0);
|
|
2411
|
+
_define_property8(this, "_replicationAverages", void 0);
|
|
2412
|
+
_define_property8(this, "_sizeByMessage", void 0);
|
|
2413
|
+
_define_property8(this, "_lastReceivedMessages", void 0);
|
|
2414
|
+
_define_property8(this, "_lastSentMessages", void 0);
|
|
2415
|
+
_define_property8(this, "_connectionsCount", void 0);
|
|
2416
|
+
this._params = _params;
|
|
2417
|
+
this._lastTick = 0;
|
|
2418
|
+
this._activeCounters = createLocalCounters();
|
|
2419
|
+
this._localTimeSeries = createLocalTimeSeries();
|
|
2420
|
+
this._storageAverages = createStorageAverages();
|
|
2421
|
+
this._replicationAverages = createNetworkAverages();
|
|
2422
|
+
this._sizeByMessage = {};
|
|
2423
|
+
this._lastReceivedMessages = new CircularBuffer(100);
|
|
2424
|
+
this._lastSentMessages = new CircularBuffer(100);
|
|
2425
|
+
this._connectionsCount = 0;
|
|
2426
|
+
}
|
|
1988
2427
|
};
|
|
1989
2428
|
EchoDataMonitor = _ts_decorate4([
|
|
1990
2429
|
trace3.resource()
|
|
@@ -2057,19 +2496,36 @@ var getByteCount = (message) => {
|
|
|
2057
2496
|
};
|
|
2058
2497
|
|
|
2059
2498
|
// src/db-host/documents-synchronizer.ts
|
|
2499
|
+
import { next as A2 } from "@automerge/automerge";
|
|
2500
|
+
import { UpdateScheduler, sleep } from "@dxos/async";
|
|
2501
|
+
import { LifecycleState as LifecycleState2, Resource as Resource5, cancelWithContext as cancelWithContext2 } from "@dxos/context";
|
|
2502
|
+
import { invariant as invariant6 } from "@dxos/invariant";
|
|
2503
|
+
import { log as log6 } from "@dxos/log";
|
|
2504
|
+
function _define_property9(obj, key, value) {
|
|
2505
|
+
if (key in obj) {
|
|
2506
|
+
Object.defineProperty(obj, key, {
|
|
2507
|
+
value,
|
|
2508
|
+
enumerable: true,
|
|
2509
|
+
configurable: true,
|
|
2510
|
+
writable: true
|
|
2511
|
+
});
|
|
2512
|
+
} else {
|
|
2513
|
+
obj[key] = value;
|
|
2514
|
+
}
|
|
2515
|
+
return obj;
|
|
2516
|
+
}
|
|
2060
2517
|
var __dxlog_file7 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/documents-synchronizer.ts";
|
|
2061
2518
|
var MAX_UPDATE_FREQ = 10;
|
|
2519
|
+
var WRAP_AROUND_RETRY_LIMIT = 3;
|
|
2520
|
+
var WRAP_AROUND_RETRY_INITIAL_DELAY = 100;
|
|
2062
2521
|
var DocumentsSynchronizer = class extends Resource5 {
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
}
|
|
2066
|
-
addDocuments(documentIds, retryCounter = 0) {
|
|
2067
|
-
if (retryCounter > 3) {
|
|
2522
|
+
addDocuments(documentIds, retryCounter = 0, wrapAroundRetryDelay = WRAP_AROUND_RETRY_INITIAL_DELAY) {
|
|
2523
|
+
if (retryCounter > WRAP_AROUND_RETRY_LIMIT) {
|
|
2068
2524
|
log6.warn("Failed to load document, retry limit reached", {
|
|
2069
2525
|
documentIds
|
|
2070
2526
|
}, {
|
|
2071
2527
|
F: __dxlog_file7,
|
|
2072
|
-
L:
|
|
2528
|
+
L: 57,
|
|
2073
2529
|
S: this,
|
|
2074
2530
|
C: (f, a) => f(...a)
|
|
2075
2531
|
});
|
|
@@ -2087,13 +2543,13 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2087
2543
|
error
|
|
2088
2544
|
}, {
|
|
2089
2545
|
F: __dxlog_file7,
|
|
2090
|
-
L:
|
|
2546
|
+
L: 71,
|
|
2091
2547
|
S: this,
|
|
2092
2548
|
C: (f, a) => f(...a)
|
|
2093
2549
|
});
|
|
2094
|
-
this.addDocuments([
|
|
2550
|
+
void cancelWithContext2(this._ctx, sleep(wrapAroundRetryDelay)).then(() => this.addDocuments([
|
|
2095
2551
|
documentId
|
|
2096
|
-
], retryCounter + 1);
|
|
2552
|
+
], retryCounter + 1, wrapAroundRetryDelay * 2));
|
|
2097
2553
|
});
|
|
2098
2554
|
}
|
|
2099
2555
|
}
|
|
@@ -2115,14 +2571,9 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2115
2571
|
}
|
|
2116
2572
|
async update(updates) {
|
|
2117
2573
|
for (const { documentId, mutation, isNew } of updates) {
|
|
2118
|
-
|
|
2119
|
-
const doc = await this._params.repo.find(documentId, FIND_PARAMS);
|
|
2120
|
-
doc.update((doc2) => A2.loadIncremental(doc2, mutation));
|
|
2121
|
-
this._startSync(doc);
|
|
2122
|
-
} else {
|
|
2123
|
-
this._writeMutation(documentId, mutation);
|
|
2124
|
-
}
|
|
2574
|
+
this._writeMutation(documentId, mutation, isNew);
|
|
2125
2575
|
}
|
|
2576
|
+
await this._params.repo.flush(updates.map(({ documentId }) => documentId));
|
|
2126
2577
|
}
|
|
2127
2578
|
_startSync(doc) {
|
|
2128
2579
|
if (this._syncStates.has(doc.documentId)) {
|
|
@@ -2130,7 +2581,7 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2130
2581
|
documentId: doc.documentId
|
|
2131
2582
|
}, {
|
|
2132
2583
|
F: __dxlog_file7,
|
|
2133
|
-
L:
|
|
2584
|
+
L: 108,
|
|
2134
2585
|
S: this,
|
|
2135
2586
|
C: (f, a) => f(...a)
|
|
2136
2587
|
});
|
|
@@ -2141,6 +2592,7 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2141
2592
|
};
|
|
2142
2593
|
this._subscribeForChanges(syncState);
|
|
2143
2594
|
this._syncStates.set(doc.documentId, syncState);
|
|
2595
|
+
return syncState;
|
|
2144
2596
|
}
|
|
2145
2597
|
_subscribeForChanges(syncState) {
|
|
2146
2598
|
const handler = () => {
|
|
@@ -2173,7 +2625,7 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2173
2625
|
const syncState = this._syncStates.get(documentId);
|
|
2174
2626
|
invariant6(syncState, "Sync state for document not found", {
|
|
2175
2627
|
F: __dxlog_file7,
|
|
2176
|
-
L:
|
|
2628
|
+
L: 150,
|
|
2177
2629
|
S: this,
|
|
2178
2630
|
A: [
|
|
2179
2631
|
"syncState",
|
|
@@ -2192,41 +2644,64 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2192
2644
|
syncState.lastSentHead = A2.getHeads(doc);
|
|
2193
2645
|
return mutation;
|
|
2194
2646
|
}
|
|
2195
|
-
_writeMutation(documentId, mutation) {
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
}
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2647
|
+
_writeMutation(documentId, mutation, isNew) {
|
|
2648
|
+
if (this._lifecycleState === LifecycleState2.CLOSED) {
|
|
2649
|
+
return;
|
|
2650
|
+
}
|
|
2651
|
+
if (isNew) {
|
|
2652
|
+
const newHandle = this._params.repo.import(mutation, {
|
|
2653
|
+
docId: documentId
|
|
2654
|
+
});
|
|
2655
|
+
const syncState = this._startSync(newHandle);
|
|
2656
|
+
syncState.lastSentHead = A2.getHeads(newHandle.doc());
|
|
2657
|
+
} else {
|
|
2658
|
+
const syncState = this._syncStates.get(documentId);
|
|
2659
|
+
invariant6(syncState, "Sync state for document not found", {
|
|
2660
|
+
F: __dxlog_file7,
|
|
2661
|
+
L: 174,
|
|
2662
|
+
S: this,
|
|
2663
|
+
A: [
|
|
2664
|
+
"syncState",
|
|
2665
|
+
"'Sync state for document not found'"
|
|
2666
|
+
]
|
|
2667
|
+
});
|
|
2668
|
+
const headsBefore = A2.getHeads(syncState.handle.doc());
|
|
2669
|
+
this._params.repo.import(mutation, {
|
|
2670
|
+
docId: documentId
|
|
2671
|
+
});
|
|
2209
2672
|
if (A2.equals(headsBefore, syncState.lastSentHead)) {
|
|
2210
|
-
syncState.lastSentHead = A2.getHeads(
|
|
2673
|
+
syncState.lastSentHead = A2.getHeads(syncState.handle.doc());
|
|
2211
2674
|
}
|
|
2212
|
-
|
|
2213
|
-
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2677
|
+
constructor(_params) {
|
|
2678
|
+
super(), _define_property9(this, "_params", void 0), _define_property9(this, "_syncStates", void 0), /**
|
|
2679
|
+
* Documents that have pending updates.
|
|
2680
|
+
* Used to batch updates.
|
|
2681
|
+
*/
|
|
2682
|
+
_define_property9(this, "_pendingUpdates", void 0), /**
|
|
2683
|
+
* Job that schedules if there are pending updates.
|
|
2684
|
+
*/
|
|
2685
|
+
_define_property9(this, "_sendUpdatesJob", void 0), this._params = _params, this._syncStates = /* @__PURE__ */ new Map(), this._pendingUpdates = /* @__PURE__ */ new Set(), this._sendUpdatesJob = void 0;
|
|
2214
2686
|
}
|
|
2215
2687
|
};
|
|
2216
2688
|
|
|
2217
2689
|
// src/db-host/data-service.ts
|
|
2690
|
+
function _define_property10(obj, key, value) {
|
|
2691
|
+
if (key in obj) {
|
|
2692
|
+
Object.defineProperty(obj, key, {
|
|
2693
|
+
value,
|
|
2694
|
+
enumerable: true,
|
|
2695
|
+
configurable: true,
|
|
2696
|
+
writable: true
|
|
2697
|
+
});
|
|
2698
|
+
} else {
|
|
2699
|
+
obj[key] = value;
|
|
2700
|
+
}
|
|
2701
|
+
return obj;
|
|
2702
|
+
}
|
|
2218
2703
|
var __dxlog_file8 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/data-service.ts";
|
|
2219
2704
|
var DataServiceImpl = class {
|
|
2220
|
-
constructor(params) {
|
|
2221
|
-
/**
|
|
2222
|
-
* Map of subscriptions.
|
|
2223
|
-
* subscriptionId -> DocumentsSynchronizer
|
|
2224
|
-
*/
|
|
2225
|
-
this._subscriptions = /* @__PURE__ */ new Map();
|
|
2226
|
-
this._automergeHost = params.automergeHost;
|
|
2227
|
-
this._spaceStateManager = params.spaceStateManager;
|
|
2228
|
-
this._updateIndexes = params.updateIndexes;
|
|
2229
|
-
}
|
|
2230
2705
|
subscribe(request) {
|
|
2231
2706
|
return new Stream(({ next, ready }) => {
|
|
2232
2707
|
const synchronizer = new DocumentsSynchronizer({
|
|
@@ -2238,7 +2713,7 @@ var DataServiceImpl = class {
|
|
|
2238
2713
|
ready();
|
|
2239
2714
|
}).catch((err) => log7.catch(err, void 0, {
|
|
2240
2715
|
F: __dxlog_file8,
|
|
2241
|
-
L:
|
|
2716
|
+
L: 72,
|
|
2242
2717
|
S: this,
|
|
2243
2718
|
C: (f, a) => f(...a)
|
|
2244
2719
|
}));
|
|
@@ -2249,7 +2724,7 @@ var DataServiceImpl = class {
|
|
|
2249
2724
|
const synchronizer = this._subscriptions.get(request.subscriptionId);
|
|
2250
2725
|
invariant7(synchronizer, "Subscription not found", {
|
|
2251
2726
|
F: __dxlog_file8,
|
|
2252
|
-
L:
|
|
2727
|
+
L: 79,
|
|
2253
2728
|
S: this,
|
|
2254
2729
|
A: [
|
|
2255
2730
|
"synchronizer",
|
|
@@ -2270,7 +2745,7 @@ var DataServiceImpl = class {
|
|
|
2270
2745
|
const synchronizer = this._subscriptions.get(request.subscriptionId);
|
|
2271
2746
|
invariant7(synchronizer, "Subscription not found", {
|
|
2272
2747
|
F: __dxlog_file8,
|
|
2273
|
-
L:
|
|
2748
|
+
L: 94,
|
|
2274
2749
|
S: this,
|
|
2275
2750
|
A: [
|
|
2276
2751
|
"synchronizer",
|
|
@@ -2315,7 +2790,7 @@ var DataServiceImpl = class {
|
|
|
2315
2790
|
const spaceId = request.spaceId;
|
|
2316
2791
|
invariant7(SpaceId2.isValid(spaceId), void 0, {
|
|
2317
2792
|
F: __dxlog_file8,
|
|
2318
|
-
L:
|
|
2793
|
+
L: 134,
|
|
2319
2794
|
S: this,
|
|
2320
2795
|
A: [
|
|
2321
2796
|
"SpaceId.isValid(spaceId)",
|
|
@@ -2336,14 +2811,7 @@ var DataServiceImpl = class {
|
|
|
2336
2811
|
peers: []
|
|
2337
2812
|
};
|
|
2338
2813
|
next({
|
|
2339
|
-
peers: state.peers
|
|
2340
|
-
peerId: peer.peerId,
|
|
2341
|
-
missingOnRemote: peer.missingOnRemote,
|
|
2342
|
-
missingOnLocal: peer.missingOnLocal,
|
|
2343
|
-
differentDocuments: peer.differentDocuments,
|
|
2344
|
-
localDocumentCount: peer.localDocumentCount,
|
|
2345
|
-
remoteDocumentCount: peer.remoteDocumentCount
|
|
2346
|
-
}))
|
|
2814
|
+
peers: state.peers
|
|
2347
2815
|
});
|
|
2348
2816
|
});
|
|
2349
2817
|
this._automergeHost.collectionStateUpdated.on(ctx, (e) => {
|
|
@@ -2354,12 +2822,21 @@ var DataServiceImpl = class {
|
|
|
2354
2822
|
scheduler.trigger();
|
|
2355
2823
|
});
|
|
2356
2824
|
}
|
|
2825
|
+
constructor(params) {
|
|
2826
|
+
_define_property10(this, "_subscriptions", /* @__PURE__ */ new Map());
|
|
2827
|
+
_define_property10(this, "_automergeHost", void 0);
|
|
2828
|
+
_define_property10(this, "_spaceStateManager", void 0);
|
|
2829
|
+
_define_property10(this, "_updateIndexes", void 0);
|
|
2830
|
+
this._automergeHost = params.automergeHost;
|
|
2831
|
+
this._spaceStateManager = params.spaceStateManager;
|
|
2832
|
+
this._updateIndexes = params.updateIndexes;
|
|
2833
|
+
}
|
|
2357
2834
|
};
|
|
2358
2835
|
|
|
2359
2836
|
// src/db-host/echo-host.ts
|
|
2360
2837
|
import { LifecycleState as LifecycleState5, Resource as Resource9 } from "@dxos/context";
|
|
2361
2838
|
import { todo } from "@dxos/debug";
|
|
2362
|
-
import {
|
|
2839
|
+
import { SpaceDocVersion as SpaceDocVersion3, createIdFromSpaceKey as createIdFromSpaceKey2 } from "@dxos/echo-protocol";
|
|
2363
2840
|
import { IndexMetadataStore, IndexStore, Indexer } from "@dxos/indexing";
|
|
2364
2841
|
import { invariant as invariant13 } from "@dxos/invariant";
|
|
2365
2842
|
import { IndexKind } from "@dxos/protocols/proto/dxos/echo/indexing";
|
|
@@ -2456,7 +2933,7 @@ var createSelectedDocumentsIterator = (automergeHost) => (
|
|
|
2456
2933
|
// src/db-host/query-service.ts
|
|
2457
2934
|
import { getHeads as getHeads3 } from "@automerge/automerge";
|
|
2458
2935
|
import { Schema } from "effect";
|
|
2459
|
-
import { DeferredTask, scheduleMicroTask, synchronized as synchronized2 } from "@dxos/async";
|
|
2936
|
+
import { DeferredTask as DeferredTask2, scheduleMicroTask, synchronized as synchronized2 } from "@dxos/async";
|
|
2460
2937
|
import { Stream as Stream2 } from "@dxos/codec-protobuf/stream";
|
|
2461
2938
|
import { Context as Context4, Resource as Resource7 } from "@dxos/context";
|
|
2462
2939
|
import { raise } from "@dxos/debug";
|
|
@@ -2466,23 +2943,26 @@ import { objectPointerCodec as objectPointerCodec4 } from "@dxos/protocols";
|
|
|
2466
2943
|
import { trace as trace4 } from "@dxos/tracing";
|
|
2467
2944
|
|
|
2468
2945
|
// src/query/query-executor.ts
|
|
2469
|
-
import { Match } from "effect";
|
|
2946
|
+
import { Match, Predicate } from "effect";
|
|
2470
2947
|
import { Context as Context3, ContextDisposedError, LifecycleState as LifecycleState3, Resource as Resource6 } from "@dxos/context";
|
|
2471
|
-
import { DatabaseDirectory as DatabaseDirectory3,
|
|
2948
|
+
import { DatabaseDirectory as DatabaseDirectory3, ObjectStructure, isEncodedReference } from "@dxos/echo-protocol";
|
|
2472
2949
|
import { EscapedPropPath } from "@dxos/indexing";
|
|
2473
2950
|
import { invariant as invariant10 } from "@dxos/invariant";
|
|
2474
2951
|
import { DXN, PublicKey as PublicKey3 } from "@dxos/keys";
|
|
2475
2952
|
import { log as log9 } from "@dxos/log";
|
|
2476
2953
|
import { objectPointerCodec as objectPointerCodec3 } from "@dxos/protocols";
|
|
2477
|
-
import { getDeep, isNonNullable as
|
|
2954
|
+
import { getDeep, isNonNullable as isNonNullable3 } from "@dxos/util";
|
|
2478
2955
|
|
|
2479
2956
|
// src/query/query-planner.ts
|
|
2957
|
+
import { Order } from "@dxos/echo";
|
|
2480
2958
|
import { invariant as invariant9 } from "@dxos/invariant";
|
|
2481
2959
|
|
|
2482
2960
|
// src/query/errors.ts
|
|
2483
2961
|
import { BaseError } from "@dxos/errors";
|
|
2484
2962
|
var QueryError = class extends BaseError.extend("QUERY_ERROR") {
|
|
2485
2963
|
};
|
|
2964
|
+
var InvalidQueryError = class extends QueryError.extend("INVALID_QUERY") {
|
|
2965
|
+
};
|
|
2486
2966
|
|
|
2487
2967
|
// src/query/plan.ts
|
|
2488
2968
|
(function(QueryPlan2) {
|
|
@@ -2506,17 +2986,24 @@ var QueryError = class extends BaseError.extend("QUERY_ERROR") {
|
|
|
2506
2986
|
var QueryPlan;
|
|
2507
2987
|
|
|
2508
2988
|
// src/query/query-planner.ts
|
|
2989
|
+
function _define_property11(obj, key, value) {
|
|
2990
|
+
if (key in obj) {
|
|
2991
|
+
Object.defineProperty(obj, key, {
|
|
2992
|
+
value,
|
|
2993
|
+
enumerable: true,
|
|
2994
|
+
configurable: true,
|
|
2995
|
+
writable: true
|
|
2996
|
+
});
|
|
2997
|
+
} else {
|
|
2998
|
+
obj[key] = value;
|
|
2999
|
+
}
|
|
3000
|
+
return obj;
|
|
3001
|
+
}
|
|
2509
3002
|
var __dxlog_file10 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/query/query-planner.ts";
|
|
2510
3003
|
var DEFAULT_OPTIONS = {
|
|
2511
3004
|
defaultTextSearchKind: "full-text"
|
|
2512
3005
|
};
|
|
2513
3006
|
var QueryPlanner = class {
|
|
2514
|
-
constructor(options) {
|
|
2515
|
-
this._options = {
|
|
2516
|
-
...DEFAULT_OPTIONS,
|
|
2517
|
-
...options
|
|
2518
|
-
};
|
|
2519
|
-
}
|
|
2520
3007
|
createPlan(query) {
|
|
2521
3008
|
let plan = this._generate(query, {
|
|
2522
3009
|
...DEFAULT_CONTEXT,
|
|
@@ -2524,6 +3011,7 @@ var QueryPlanner = class {
|
|
|
2524
3011
|
});
|
|
2525
3012
|
plan = this._optimizeEmptyFilters(plan);
|
|
2526
3013
|
plan = this._optimizeSoloUnions(plan);
|
|
3014
|
+
plan = this._ensureOrderStep(plan);
|
|
2527
3015
|
return plan;
|
|
2528
3016
|
}
|
|
2529
3017
|
_generate(query, context) {
|
|
@@ -2546,8 +3034,11 @@ var QueryPlanner = class {
|
|
|
2546
3034
|
return this._generateUnionClause(query, context);
|
|
2547
3035
|
case "set-difference":
|
|
2548
3036
|
return this._generateSetDifferenceClause(query, context);
|
|
3037
|
+
case "order":
|
|
3038
|
+
return this._generateOrderClause(query, context);
|
|
2549
3039
|
default:
|
|
2550
|
-
throw new QueryError(
|
|
3040
|
+
throw new QueryError({
|
|
3041
|
+
message: `Unsupported query type: ${query.type}`,
|
|
2551
3042
|
context: {
|
|
2552
3043
|
query: context.originalQuery
|
|
2553
3044
|
}
|
|
@@ -2573,6 +3064,7 @@ var QueryPlanner = class {
|
|
|
2573
3064
|
// TODO(dmaretskyi): If the tip of the query ast is a [select, ...filter] shape we can reorder the filters so the query is most efficient.
|
|
2574
3065
|
_generateSelectionFromFilter(filter, context) {
|
|
2575
3066
|
switch (filter.type) {
|
|
3067
|
+
// Props
|
|
2576
3068
|
case "object": {
|
|
2577
3069
|
if (context.selectionInverted && filter.id === void 0 && filter.typename === null && Object.keys(filter.props).length === 0) {
|
|
2578
3070
|
return QueryPlan.Plan.make([
|
|
@@ -2583,7 +3075,8 @@ var QueryPlanner = class {
|
|
|
2583
3075
|
]);
|
|
2584
3076
|
}
|
|
2585
3077
|
if (context.selectionInverted) {
|
|
2586
|
-
throw new QueryError(
|
|
3078
|
+
throw new QueryError({
|
|
3079
|
+
message: "Query too complex",
|
|
2587
3080
|
context: {
|
|
2588
3081
|
query: context.originalQuery
|
|
2589
3082
|
}
|
|
@@ -2649,6 +3142,26 @@ var QueryPlanner = class {
|
|
|
2649
3142
|
]);
|
|
2650
3143
|
}
|
|
2651
3144
|
}
|
|
3145
|
+
// Tag
|
|
3146
|
+
case "tag": {
|
|
3147
|
+
return QueryPlan.Plan.make([
|
|
3148
|
+
{
|
|
3149
|
+
_tag: "SelectStep",
|
|
3150
|
+
spaces: context.selectionSpaces,
|
|
3151
|
+
selector: {
|
|
3152
|
+
_tag: "WildcardSelector"
|
|
3153
|
+
}
|
|
3154
|
+
},
|
|
3155
|
+
...this._generateDeletedHandlingSteps(context),
|
|
3156
|
+
{
|
|
3157
|
+
_tag: "FilterStep",
|
|
3158
|
+
filter: {
|
|
3159
|
+
...filter
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3162
|
+
]);
|
|
3163
|
+
}
|
|
3164
|
+
// Text
|
|
2652
3165
|
case "text-search": {
|
|
2653
3166
|
return QueryPlan.Plan.make([
|
|
2654
3167
|
{
|
|
@@ -2663,48 +3176,54 @@ var QueryPlanner = class {
|
|
|
2663
3176
|
...this._generateDeletedHandlingSteps(context)
|
|
2664
3177
|
]);
|
|
2665
3178
|
}
|
|
3179
|
+
// Compare
|
|
2666
3180
|
case "compare":
|
|
2667
|
-
throw new QueryError(
|
|
3181
|
+
throw new QueryError({
|
|
3182
|
+
message: "Query too complex",
|
|
2668
3183
|
context: {
|
|
2669
3184
|
query: context.originalQuery
|
|
2670
3185
|
}
|
|
2671
3186
|
});
|
|
2672
3187
|
case "in":
|
|
2673
|
-
throw new QueryError(
|
|
3188
|
+
throw new QueryError({
|
|
3189
|
+
message: "Query too complex",
|
|
2674
3190
|
context: {
|
|
2675
3191
|
query: context.originalQuery
|
|
2676
3192
|
}
|
|
2677
3193
|
});
|
|
2678
3194
|
case "range":
|
|
2679
|
-
throw new QueryError(
|
|
3195
|
+
throw new QueryError({
|
|
3196
|
+
message: "Query too complex",
|
|
2680
3197
|
context: {
|
|
2681
3198
|
query: context.originalQuery
|
|
2682
3199
|
}
|
|
2683
3200
|
});
|
|
3201
|
+
// Boolean
|
|
2684
3202
|
case "not":
|
|
2685
3203
|
return this._generateSelectionFromFilter(filter.filter, {
|
|
2686
3204
|
...context,
|
|
2687
3205
|
selectionInverted: !context.selectionInverted
|
|
2688
3206
|
});
|
|
2689
3207
|
case "and":
|
|
2690
|
-
throw new QueryError(
|
|
3208
|
+
throw new QueryError({
|
|
3209
|
+
message: "Query too complex",
|
|
2691
3210
|
context: {
|
|
2692
3211
|
query: context.originalQuery
|
|
2693
3212
|
}
|
|
2694
3213
|
});
|
|
2695
3214
|
case "or":
|
|
2696
3215
|
if (filter.filters.every(isTrivialTypenameFilter)) {
|
|
2697
|
-
const typenames = filter.filters.map((
|
|
2698
|
-
invariant9(
|
|
3216
|
+
const typenames = filter.filters.map((filter2) => {
|
|
3217
|
+
invariant9(filter2.type === "object" && filter2.typename !== null, void 0, {
|
|
2699
3218
|
F: __dxlog_file10,
|
|
2700
|
-
L:
|
|
3219
|
+
L: 224,
|
|
2701
3220
|
S: this,
|
|
2702
3221
|
A: [
|
|
2703
|
-
"
|
|
3222
|
+
"filter.type === 'object' && filter.typename !== null",
|
|
2704
3223
|
""
|
|
2705
3224
|
]
|
|
2706
3225
|
});
|
|
2707
|
-
return
|
|
3226
|
+
return filter2.typename;
|
|
2708
3227
|
});
|
|
2709
3228
|
return QueryPlan.Plan.make([
|
|
2710
3229
|
{
|
|
@@ -2719,14 +3238,16 @@ var QueryPlanner = class {
|
|
|
2719
3238
|
...this._generateDeletedHandlingSteps(context)
|
|
2720
3239
|
]);
|
|
2721
3240
|
} else {
|
|
2722
|
-
throw new QueryError(
|
|
3241
|
+
throw new QueryError({
|
|
3242
|
+
message: "Query too complex",
|
|
2723
3243
|
context: {
|
|
2724
3244
|
query: context.originalQuery
|
|
2725
3245
|
}
|
|
2726
3246
|
});
|
|
2727
3247
|
}
|
|
2728
3248
|
default:
|
|
2729
|
-
throw new QueryError(
|
|
3249
|
+
throw new QueryError({
|
|
3250
|
+
message: `Unsupported filter type: ${filter.type}`,
|
|
2730
3251
|
context: {
|
|
2731
3252
|
query: context.originalQuery
|
|
2732
3253
|
}
|
|
@@ -2926,6 +3447,52 @@ var QueryPlanner = class {
|
|
|
2926
3447
|
_optimizeSoloUnions(plan) {
|
|
2927
3448
|
return plan;
|
|
2928
3449
|
}
|
|
3450
|
+
_generateOrderClause(query, context) {
|
|
3451
|
+
return QueryPlan.Plan.make([
|
|
3452
|
+
...this._generate(query.query, context).steps,
|
|
3453
|
+
{
|
|
3454
|
+
_tag: "OrderStep",
|
|
3455
|
+
order: query.order
|
|
3456
|
+
}
|
|
3457
|
+
]);
|
|
3458
|
+
}
|
|
3459
|
+
// After complete plan is built, inspect it from the end:
|
|
3460
|
+
// - Walk backwards until hitting an object set changer.
|
|
3461
|
+
// - If an order step is found, skip.
|
|
3462
|
+
// - Otherwise append natural order to the end.
|
|
3463
|
+
_ensureOrderStep(plan) {
|
|
3464
|
+
const OBJECT_SET_CHANGERS = /* @__PURE__ */ new Set([
|
|
3465
|
+
"SelectStep",
|
|
3466
|
+
"TraverseStep",
|
|
3467
|
+
"UnionStep",
|
|
3468
|
+
"SetDifferenceStep"
|
|
3469
|
+
]);
|
|
3470
|
+
for (let i = plan.steps.length - 1; i >= 0; i--) {
|
|
3471
|
+
const step = plan.steps[i];
|
|
3472
|
+
if (step._tag === "OrderStep") {
|
|
3473
|
+
return plan;
|
|
3474
|
+
}
|
|
3475
|
+
if (OBJECT_SET_CHANGERS.has(step._tag)) {
|
|
3476
|
+
break;
|
|
3477
|
+
}
|
|
3478
|
+
}
|
|
3479
|
+
return QueryPlan.Plan.make([
|
|
3480
|
+
...plan.steps,
|
|
3481
|
+
{
|
|
3482
|
+
_tag: "OrderStep",
|
|
3483
|
+
order: [
|
|
3484
|
+
Order.natural.ast
|
|
3485
|
+
]
|
|
3486
|
+
}
|
|
3487
|
+
]);
|
|
3488
|
+
}
|
|
3489
|
+
constructor(options) {
|
|
3490
|
+
_define_property11(this, "_options", void 0);
|
|
3491
|
+
this._options = {
|
|
3492
|
+
...DEFAULT_OPTIONS,
|
|
3493
|
+
...options
|
|
3494
|
+
};
|
|
3495
|
+
}
|
|
2929
3496
|
};
|
|
2930
3497
|
var DEFAULT_CONTEXT = {
|
|
2931
3498
|
originalQuery: null,
|
|
@@ -2951,7 +3518,21 @@ var isTrivialTypenameFilter = (filter) => {
|
|
|
2951
3518
|
};
|
|
2952
3519
|
|
|
2953
3520
|
// src/query/query-executor.ts
|
|
3521
|
+
function _define_property12(obj, key, value) {
|
|
3522
|
+
if (key in obj) {
|
|
3523
|
+
Object.defineProperty(obj, key, {
|
|
3524
|
+
value,
|
|
3525
|
+
enumerable: true,
|
|
3526
|
+
configurable: true,
|
|
3527
|
+
writable: true
|
|
3528
|
+
});
|
|
3529
|
+
} else {
|
|
3530
|
+
obj[key] = value;
|
|
3531
|
+
}
|
|
3532
|
+
return obj;
|
|
3533
|
+
}
|
|
2954
3534
|
var __dxlog_file11 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/query/query-executor.ts";
|
|
3535
|
+
var isNullable = Predicate.isNullable;
|
|
2955
3536
|
var ExecutionTrace = Object.freeze({
|
|
2956
3537
|
makeEmpty: () => ({
|
|
2957
3538
|
name: "Empty",
|
|
@@ -2978,19 +3559,6 @@ var ExecutionTrace = Object.freeze({
|
|
|
2978
3559
|
});
|
|
2979
3560
|
var TRACE_QUERY_EXECUTION = false;
|
|
2980
3561
|
var QueryExecutor = class extends Resource6 {
|
|
2981
|
-
constructor(options) {
|
|
2982
|
-
super();
|
|
2983
|
-
this._trace = ExecutionTrace.makeEmpty();
|
|
2984
|
-
this._lastResultSet = [];
|
|
2985
|
-
this._indexer = options.indexer;
|
|
2986
|
-
this._automergeHost = options.automergeHost;
|
|
2987
|
-
this._spaceStateManager = options.spaceStateManager;
|
|
2988
|
-
this._id = options.queryId;
|
|
2989
|
-
this._query = options.query;
|
|
2990
|
-
this._reactivity = options.reactivity;
|
|
2991
|
-
const queryPlanner = new QueryPlanner();
|
|
2992
|
-
this._plan = queryPlanner.createPlan(this._query);
|
|
2993
|
-
}
|
|
2994
3562
|
get query() {
|
|
2995
3563
|
return this._query;
|
|
2996
3564
|
}
|
|
@@ -3016,7 +3584,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3016
3584
|
async execQuery() {
|
|
3017
3585
|
invariant10(this._lifecycleState === LifecycleState3.OPEN, void 0, {
|
|
3018
3586
|
F: __dxlog_file11,
|
|
3019
|
-
L:
|
|
3587
|
+
L: 176,
|
|
3020
3588
|
S: this,
|
|
3021
3589
|
A: [
|
|
3022
3590
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -3089,6 +3657,9 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3089
3657
|
case "TraverseStep":
|
|
3090
3658
|
({ workingSet: newWorkingSet, trace: trace6 } = await this._execTraverseStep(step, workingSet));
|
|
3091
3659
|
break;
|
|
3660
|
+
case "OrderStep":
|
|
3661
|
+
({ workingSet: newWorkingSet, trace: trace6 } = await this._execOrderStep(step, workingSet));
|
|
3662
|
+
break;
|
|
3092
3663
|
default:
|
|
3093
3664
|
throw new Error(`Unknown step type: ${step._tag}`);
|
|
3094
3665
|
}
|
|
@@ -3126,7 +3697,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3126
3697
|
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
3127
3698
|
trace6.documentsLoaded += results.length;
|
|
3128
3699
|
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
3129
|
-
workingSet.push(...results.filter(
|
|
3700
|
+
workingSet.push(...results.filter(isNonNullable3).filter((item) => step.spaces.includes(item.spaceId)));
|
|
3130
3701
|
trace6.objectCount = workingSet.length;
|
|
3131
3702
|
break;
|
|
3132
3703
|
}
|
|
@@ -3136,7 +3707,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3136
3707
|
sourceSpaceId: step.spaces[0]
|
|
3137
3708
|
})));
|
|
3138
3709
|
trace6.documentLoadTime += performance.now() - beginLoad;
|
|
3139
|
-
workingSet.push(...items.filter(
|
|
3710
|
+
workingSet.push(...items.filter(isNonNullable3));
|
|
3140
3711
|
trace6.objectCount = workingSet.length;
|
|
3141
3712
|
break;
|
|
3142
3713
|
}
|
|
@@ -3158,7 +3729,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3158
3729
|
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
3159
3730
|
trace6.documentsLoaded += results.length;
|
|
3160
3731
|
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
3161
|
-
workingSet.push(...results.filter(
|
|
3732
|
+
workingSet.push(...results.filter(isNonNullable3).filter((item) => step.spaces.includes(item.spaceId)));
|
|
3162
3733
|
trace6.objectCount = workingSet.length;
|
|
3163
3734
|
break;
|
|
3164
3735
|
}
|
|
@@ -3183,7 +3754,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3183
3754
|
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
3184
3755
|
trace6.documentsLoaded += results.length;
|
|
3185
3756
|
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
3186
|
-
workingSet.push(...results.filter(
|
|
3757
|
+
workingSet.push(...results.filter(isNonNullable3).filter((item) => step.spaces.includes(item.spaceId)));
|
|
3187
3758
|
trace6.objectCount = workingSet.length;
|
|
3188
3759
|
break;
|
|
3189
3760
|
}
|
|
@@ -3212,17 +3783,6 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3212
3783
|
};
|
|
3213
3784
|
}
|
|
3214
3785
|
async _execFilterDeletedStep(step, workingSet) {
|
|
3215
|
-
if (workingSet.length === 6) {
|
|
3216
|
-
log9.info("FilterDeletedStep", {
|
|
3217
|
-
step,
|
|
3218
|
-
workingSet
|
|
3219
|
-
}, {
|
|
3220
|
-
F: __dxlog_file11,
|
|
3221
|
-
L: 386,
|
|
3222
|
-
S: this,
|
|
3223
|
-
C: (f, a) => f(...a)
|
|
3224
|
-
});
|
|
3225
|
-
}
|
|
3226
3786
|
const expected = step.mode === "only-deleted";
|
|
3227
3787
|
const result = workingSet.filter((item) => ObjectStructure.isDeleted(item.doc) === expected);
|
|
3228
3788
|
return {
|
|
@@ -3260,24 +3820,24 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3260
3820
|
spaceId: item.spaceId
|
|
3261
3821
|
} : null;
|
|
3262
3822
|
} catch {
|
|
3263
|
-
log9.warn("
|
|
3823
|
+
log9.warn("invalid reference", {
|
|
3264
3824
|
ref: ref2["/"]
|
|
3265
3825
|
}, {
|
|
3266
3826
|
F: __dxlog_file11,
|
|
3267
|
-
L:
|
|
3827
|
+
L: 437,
|
|
3268
3828
|
S: this,
|
|
3269
3829
|
C: (f, a) => f(...a)
|
|
3270
3830
|
});
|
|
3271
3831
|
return null;
|
|
3272
3832
|
}
|
|
3273
3833
|
});
|
|
3274
|
-
}).filter(
|
|
3834
|
+
}).filter(isNonNullable3);
|
|
3275
3835
|
const beginLoad = performance.now();
|
|
3276
3836
|
const items = await Promise.all(refs.map(({ ref, spaceId }) => this._loadFromDXN(ref, {
|
|
3277
3837
|
sourceSpaceId: spaceId
|
|
3278
3838
|
})));
|
|
3279
3839
|
trace6.documentLoadTime += performance.now() - beginLoad;
|
|
3280
|
-
newWorkingSet.push(...items.filter(
|
|
3840
|
+
newWorkingSet.push(...items.filter(isNonNullable3));
|
|
3281
3841
|
trace6.objectCount = newWorkingSet.length;
|
|
3282
3842
|
break;
|
|
3283
3843
|
}
|
|
@@ -3296,7 +3856,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3296
3856
|
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
3297
3857
|
trace6.documentsLoaded += results.length;
|
|
3298
3858
|
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
3299
|
-
newWorkingSet.push(...results.filter(
|
|
3859
|
+
newWorkingSet.push(...results.filter(isNonNullable3));
|
|
3300
3860
|
trace6.objectCount = newWorkingSet.length;
|
|
3301
3861
|
break;
|
|
3302
3862
|
}
|
|
@@ -3318,23 +3878,23 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3318
3878
|
spaceId: item.spaceId
|
|
3319
3879
|
};
|
|
3320
3880
|
} catch {
|
|
3321
|
-
log9.warn("
|
|
3881
|
+
log9.warn("invalid reference", {
|
|
3322
3882
|
ref: ref["/"]
|
|
3323
3883
|
}, {
|
|
3324
3884
|
F: __dxlog_file11,
|
|
3325
|
-
L:
|
|
3885
|
+
L: 500,
|
|
3326
3886
|
S: this,
|
|
3327
3887
|
C: (f, a) => f(...a)
|
|
3328
3888
|
});
|
|
3329
3889
|
return null;
|
|
3330
3890
|
}
|
|
3331
|
-
}).filter(
|
|
3891
|
+
}).filter(isNonNullable3);
|
|
3332
3892
|
const beginLoad = performance.now();
|
|
3333
3893
|
const items = await Promise.all(refs.map(({ ref, spaceId }) => this._loadFromDXN(ref, {
|
|
3334
3894
|
sourceSpaceId: spaceId
|
|
3335
3895
|
})));
|
|
3336
3896
|
trace6.documentLoadTime += performance.now() - beginLoad;
|
|
3337
|
-
newWorkingSet.push(...items.filter(
|
|
3897
|
+
newWorkingSet.push(...items.filter(isNonNullable3));
|
|
3338
3898
|
trace6.objectCount = newWorkingSet.length;
|
|
3339
3899
|
break;
|
|
3340
3900
|
}
|
|
@@ -3354,7 +3914,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3354
3914
|
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
3355
3915
|
trace6.documentsLoaded += results.length;
|
|
3356
3916
|
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
3357
|
-
newWorkingSet.push(...results.filter(
|
|
3917
|
+
newWorkingSet.push(...results.filter(isNonNullable3));
|
|
3358
3918
|
trace6.objectCount = newWorkingSet.length;
|
|
3359
3919
|
break;
|
|
3360
3920
|
}
|
|
@@ -3411,6 +3971,74 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3411
3971
|
trace: trace6
|
|
3412
3972
|
};
|
|
3413
3973
|
}
|
|
3974
|
+
async _execOrderStep(step, workingSet) {
|
|
3975
|
+
const compareItems = (a, b) => step.order.reduce((comparison, order) => {
|
|
3976
|
+
if (comparison !== 0) {
|
|
3977
|
+
return comparison;
|
|
3978
|
+
}
|
|
3979
|
+
return this._compareByOrder(a, b, order);
|
|
3980
|
+
}, 0);
|
|
3981
|
+
const sortedWorkingSet = [
|
|
3982
|
+
...workingSet
|
|
3983
|
+
].sort(compareItems);
|
|
3984
|
+
return {
|
|
3985
|
+
workingSet: sortedWorkingSet,
|
|
3986
|
+
trace: {
|
|
3987
|
+
...ExecutionTrace.makeEmpty(),
|
|
3988
|
+
name: "Order",
|
|
3989
|
+
details: JSON.stringify(step.order),
|
|
3990
|
+
objectCount: sortedWorkingSet.length
|
|
3991
|
+
}
|
|
3992
|
+
};
|
|
3993
|
+
}
|
|
3994
|
+
_compareByOrder(a, b, order) {
|
|
3995
|
+
return Match.type().pipe(Match.withReturnType(), Match.when({
|
|
3996
|
+
kind: "natural"
|
|
3997
|
+
}, () => a.objectId.localeCompare(b.objectId)), Match.when({
|
|
3998
|
+
kind: "property"
|
|
3999
|
+
}, ({ property, direction }) => {
|
|
4000
|
+
const comparison = this._compareByProperty(a, b, property);
|
|
4001
|
+
return direction === "desc" ? -comparison : comparison;
|
|
4002
|
+
}), Match.exhaustive)(order);
|
|
4003
|
+
}
|
|
4004
|
+
_compareByProperty(a, b, property) {
|
|
4005
|
+
const aValue = a.doc.data[property];
|
|
4006
|
+
const bValue = b.doc.data[property];
|
|
4007
|
+
return Match.type().pipe(
|
|
4008
|
+
Match.withReturnType(),
|
|
4009
|
+
Match.when({
|
|
4010
|
+
a: isNullable,
|
|
4011
|
+
b: isNullable
|
|
4012
|
+
}, () => 0),
|
|
4013
|
+
Match.when({
|
|
4014
|
+
a: isNullable
|
|
4015
|
+
}, () => 1),
|
|
4016
|
+
Match.when({
|
|
4017
|
+
b: isNullable
|
|
4018
|
+
}, () => -1),
|
|
4019
|
+
Match.when({
|
|
4020
|
+
a: Match.string,
|
|
4021
|
+
b: Match.string
|
|
4022
|
+
}, ({ a: a2, b: b2 }) => a2.localeCompare(b2)),
|
|
4023
|
+
Match.when({
|
|
4024
|
+
a: Match.number,
|
|
4025
|
+
b: Match.number
|
|
4026
|
+
}, ({ a: a2, b: b2 }) => a2 - b2),
|
|
4027
|
+
Match.when({
|
|
4028
|
+
a: Match.boolean,
|
|
4029
|
+
b: Match.boolean
|
|
4030
|
+
}, ({ a: a2, b: b2 }) => a2 === b2 ? 0 : a2 ? 1 : -1),
|
|
4031
|
+
Match.when({
|
|
4032
|
+
a: Match.defined,
|
|
4033
|
+
b: Match.defined
|
|
4034
|
+
}, ({ a: a2, b: b2 }) => String(a2).localeCompare(String(b2))),
|
|
4035
|
+
// TODO(wittjosiah): Why does Match.exhaustive fail here?
|
|
4036
|
+
Match.orElse(() => 0)
|
|
4037
|
+
)({
|
|
4038
|
+
a: aValue,
|
|
4039
|
+
b: bValue
|
|
4040
|
+
});
|
|
4041
|
+
}
|
|
3414
4042
|
async _loadDocumentsAfterIndexQuery(indexHits) {
|
|
3415
4043
|
return Promise.all(indexHits.map(async (hit) => {
|
|
3416
4044
|
return this._loadFromIndexHit(hit);
|
|
@@ -3420,7 +4048,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3420
4048
|
const { objectId, documentId, spaceKey: spaceKeyInIndex } = objectPointerCodec3.decode(hit.id);
|
|
3421
4049
|
const handle = await this._automergeHost.loadDoc(Context3.default(void 0, {
|
|
3422
4050
|
F: __dxlog_file11,
|
|
3423
|
-
L:
|
|
4051
|
+
L: 664
|
|
3424
4052
|
}), documentId);
|
|
3425
4053
|
const doc = handle.doc();
|
|
3426
4054
|
if (!doc) {
|
|
@@ -3448,7 +4076,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3448
4076
|
dxn
|
|
3449
4077
|
}, {
|
|
3450
4078
|
F: __dxlog_file11,
|
|
3451
|
-
L:
|
|
4079
|
+
L: 691,
|
|
3452
4080
|
S: this,
|
|
3453
4081
|
C: (f, a) => f(...a)
|
|
3454
4082
|
});
|
|
@@ -3461,7 +4089,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3461
4089
|
spaceId
|
|
3462
4090
|
}, {
|
|
3463
4091
|
F: __dxlog_file11,
|
|
3464
|
-
L:
|
|
4092
|
+
L: 699,
|
|
3465
4093
|
S: this,
|
|
3466
4094
|
C: (f, a) => f(...a)
|
|
3467
4095
|
});
|
|
@@ -3473,7 +4101,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3473
4101
|
spaceId
|
|
3474
4102
|
}, {
|
|
3475
4103
|
F: __dxlog_file11,
|
|
3476
|
-
L:
|
|
4104
|
+
L: 704,
|
|
3477
4105
|
S: this,
|
|
3478
4106
|
C: (f, a) => f(...a)
|
|
3479
4107
|
});
|
|
@@ -3494,7 +4122,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3494
4122
|
}
|
|
3495
4123
|
const handle = await this._automergeHost.loadDoc(Context3.default(void 0, {
|
|
3496
4124
|
F: __dxlog_file11,
|
|
3497
|
-
L:
|
|
4125
|
+
L: 723
|
|
3498
4126
|
}), link);
|
|
3499
4127
|
const doc = handle.doc();
|
|
3500
4128
|
if (!doc) {
|
|
@@ -3511,9 +4139,37 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3511
4139
|
doc: object
|
|
3512
4140
|
};
|
|
3513
4141
|
}
|
|
4142
|
+
constructor(options) {
|
|
4143
|
+
super(), _define_property12(this, "_indexer", void 0), _define_property12(this, "_automergeHost", void 0), _define_property12(this, "_spaceStateManager", void 0), /**
|
|
4144
|
+
* Id of this query.
|
|
4145
|
+
*/
|
|
4146
|
+
_define_property12(this, "_id", void 0), _define_property12(this, "_query", void 0), // TODO(dmaretskyi): Might be used in the future.
|
|
4147
|
+
_define_property12(this, "_reactivity", void 0), _define_property12(this, "_plan", void 0), _define_property12(this, "_trace", ExecutionTrace.makeEmpty()), _define_property12(this, "_lastResultSet", []);
|
|
4148
|
+
this._indexer = options.indexer;
|
|
4149
|
+
this._automergeHost = options.automergeHost;
|
|
4150
|
+
this._spaceStateManager = options.spaceStateManager;
|
|
4151
|
+
this._id = options.queryId;
|
|
4152
|
+
this._query = options.query;
|
|
4153
|
+
this._reactivity = options.reactivity;
|
|
4154
|
+
const queryPlanner = new QueryPlanner();
|
|
4155
|
+
this._plan = queryPlanner.createPlan(this._query);
|
|
4156
|
+
}
|
|
3514
4157
|
};
|
|
3515
4158
|
|
|
3516
4159
|
// src/db-host/query-service.ts
|
|
4160
|
+
function _define_property13(obj, key, value) {
|
|
4161
|
+
if (key in obj) {
|
|
4162
|
+
Object.defineProperty(obj, key, {
|
|
4163
|
+
value,
|
|
4164
|
+
enumerable: true,
|
|
4165
|
+
configurable: true,
|
|
4166
|
+
writable: true
|
|
4167
|
+
});
|
|
4168
|
+
} else {
|
|
4169
|
+
obj[key] = value;
|
|
4170
|
+
}
|
|
4171
|
+
return obj;
|
|
4172
|
+
}
|
|
3517
4173
|
function _ts_decorate5(decorators, target, key, desc) {
|
|
3518
4174
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3519
4175
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -3522,26 +4178,9 @@ function _ts_decorate5(decorators, target, key, desc) {
|
|
|
3522
4178
|
}
|
|
3523
4179
|
var __dxlog_file12 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/query-service.ts";
|
|
3524
4180
|
var QueryServiceImpl = class extends Resource7 {
|
|
3525
|
-
// TODO(burdon): OK for options, but not params. Pass separately and type readonly here.
|
|
3526
|
-
constructor(_params) {
|
|
3527
|
-
super(), this._params = _params, this._queries = /* @__PURE__ */ new Set();
|
|
3528
|
-
trace4.diagnostic({
|
|
3529
|
-
id: "active-queries",
|
|
3530
|
-
name: "Active Queries",
|
|
3531
|
-
fetch: () => {
|
|
3532
|
-
return Array.from(this._queries).map((query) => {
|
|
3533
|
-
return {
|
|
3534
|
-
query: JSON.stringify(query.executor.query),
|
|
3535
|
-
plan: JSON.stringify(query.executor.plan),
|
|
3536
|
-
trace: JSON.stringify(query.executor.trace)
|
|
3537
|
-
};
|
|
3538
|
-
});
|
|
3539
|
-
}
|
|
3540
|
-
});
|
|
3541
|
-
}
|
|
3542
4181
|
async _open() {
|
|
3543
4182
|
this._params.indexer.updated.on(this._ctx, () => this.invalidateQueries());
|
|
3544
|
-
this._updateQueries = new
|
|
4183
|
+
this._updateQueries = new DeferredTask2(this._ctx, this._executeQueries.bind(this));
|
|
3545
4184
|
}
|
|
3546
4185
|
async _close() {
|
|
3547
4186
|
await this._updateQueries.join();
|
|
@@ -3552,6 +4191,18 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
3552
4191
|
}
|
|
3553
4192
|
execQuery(request) {
|
|
3554
4193
|
return new Stream2(({ next, close, ctx }) => {
|
|
4194
|
+
if (this._params.indexer.config?.enabled !== true) {
|
|
4195
|
+
log10.error("indexer is disabled", {
|
|
4196
|
+
config: this._params.indexer.config
|
|
4197
|
+
}, {
|
|
4198
|
+
F: __dxlog_file12,
|
|
4199
|
+
L: 101,
|
|
4200
|
+
S: this,
|
|
4201
|
+
C: (f, a) => f(...a)
|
|
4202
|
+
});
|
|
4203
|
+
close();
|
|
4204
|
+
return;
|
|
4205
|
+
}
|
|
3555
4206
|
const queryEntry = this._createQuery(ctx, request, next, close, close);
|
|
3556
4207
|
scheduleMicroTask(ctx, async () => {
|
|
3557
4208
|
await queryEntry.executor.open();
|
|
@@ -3567,7 +4218,7 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
3567
4218
|
async reindex() {
|
|
3568
4219
|
log10("Reindexing all documents...", void 0, {
|
|
3569
4220
|
F: __dxlog_file12,
|
|
3570
|
-
L:
|
|
4221
|
+
L: 120,
|
|
3571
4222
|
S: this,
|
|
3572
4223
|
C: (f, a) => f(...a)
|
|
3573
4224
|
});
|
|
@@ -3582,7 +4233,7 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
3582
4233
|
count: ids.size
|
|
3583
4234
|
}, {
|
|
3584
4235
|
F: __dxlog_file12,
|
|
3585
|
-
L:
|
|
4236
|
+
L: 128,
|
|
3586
4237
|
S: this,
|
|
3587
4238
|
C: (f, a) => f(...a)
|
|
3588
4239
|
});
|
|
@@ -3592,7 +4243,7 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
3592
4243
|
count: ids.size
|
|
3593
4244
|
}, {
|
|
3594
4245
|
F: __dxlog_file12,
|
|
3595
|
-
L:
|
|
4246
|
+
L: 132,
|
|
3596
4247
|
S: this,
|
|
3597
4248
|
C: (f, a) => f(...a)
|
|
3598
4249
|
});
|
|
@@ -3658,7 +4309,7 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
3658
4309
|
} catch (err) {
|
|
3659
4310
|
log10.catch(err, void 0, {
|
|
3660
4311
|
F: __dxlog_file12,
|
|
3661
|
-
L:
|
|
4312
|
+
L: 203,
|
|
3662
4313
|
S: this,
|
|
3663
4314
|
C: (f, a) => f(...a)
|
|
3664
4315
|
});
|
|
@@ -3669,11 +4320,28 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
3669
4320
|
duration: performance.now() - begin
|
|
3670
4321
|
}, {
|
|
3671
4322
|
F: __dxlog_file12,
|
|
3672
|
-
L:
|
|
4323
|
+
L: 207,
|
|
3673
4324
|
S: this,
|
|
3674
4325
|
C: (f, a) => f(...a)
|
|
3675
4326
|
});
|
|
3676
4327
|
}
|
|
4328
|
+
// TODO(burdon): OK for options, but not params. Pass separately and type readonly here.
|
|
4329
|
+
constructor(_params) {
|
|
4330
|
+
super(), _define_property13(this, "_params", void 0), _define_property13(this, "_queries", void 0), _define_property13(this, "_updateQueries", void 0), this._params = _params, this._queries = /* @__PURE__ */ new Set();
|
|
4331
|
+
trace4.diagnostic({
|
|
4332
|
+
id: "active-queries",
|
|
4333
|
+
name: "Active Queries",
|
|
4334
|
+
fetch: () => {
|
|
4335
|
+
return Array.from(this._queries).map((query) => {
|
|
4336
|
+
return {
|
|
4337
|
+
query: JSON.stringify(query.executor.query),
|
|
4338
|
+
plan: JSON.stringify(query.executor.plan),
|
|
4339
|
+
trace: JSON.stringify(query.executor.trace)
|
|
4340
|
+
};
|
|
4341
|
+
});
|
|
4342
|
+
}
|
|
4343
|
+
});
|
|
4344
|
+
}
|
|
3677
4345
|
};
|
|
3678
4346
|
_ts_decorate5([
|
|
3679
4347
|
synchronized2
|
|
@@ -3720,7 +4388,7 @@ var createDocumentsIterator = (automergeHost) => (
|
|
|
3720
4388
|
}
|
|
3721
4389
|
const linkHandle = await automergeHost.loadDoc(Context4.default(void 0, {
|
|
3722
4390
|
F: __dxlog_file12,
|
|
3723
|
-
L:
|
|
4391
|
+
L: 247
|
|
3724
4392
|
}), urlString);
|
|
3725
4393
|
for await (const result of getObjectsFromHandle(linkHandle)) {
|
|
3726
4394
|
yield result;
|
|
@@ -3745,7 +4413,7 @@ var createDocumentsIterator = (automergeHost) => (
|
|
|
3745
4413
|
import { interpretAsDocumentId as interpretAsDocumentId3 } from "@automerge/automerge-repo";
|
|
3746
4414
|
import isEqual from "lodash.isequal";
|
|
3747
4415
|
import { Event as Event3, UpdateScheduler as UpdateScheduler3 } from "@dxos/async";
|
|
3748
|
-
import {
|
|
4416
|
+
import { Context as Context5, LifecycleState as LifecycleState4, Resource as Resource8 } from "@dxos/context";
|
|
3749
4417
|
import { invariant as invariant12 } from "@dxos/invariant";
|
|
3750
4418
|
|
|
3751
4419
|
// src/db-host/database-root.ts
|
|
@@ -3784,6 +4452,19 @@ var measureDocMetrics = (doc) => {
|
|
|
3784
4452
|
};
|
|
3785
4453
|
|
|
3786
4454
|
// src/db-host/database-root.ts
|
|
4455
|
+
function _define_property14(obj, key, value) {
|
|
4456
|
+
if (key in obj) {
|
|
4457
|
+
Object.defineProperty(obj, key, {
|
|
4458
|
+
value,
|
|
4459
|
+
enumerable: true,
|
|
4460
|
+
configurable: true,
|
|
4461
|
+
writable: true
|
|
4462
|
+
});
|
|
4463
|
+
} else {
|
|
4464
|
+
obj[key] = value;
|
|
4465
|
+
}
|
|
4466
|
+
return obj;
|
|
4467
|
+
}
|
|
3787
4468
|
var __dxlog_file14 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/database-root.ts";
|
|
3788
4469
|
var DatabaseRoot = class {
|
|
3789
4470
|
static mapLinks(doc, mapping) {
|
|
@@ -3799,9 +4480,6 @@ var DatabaseRoot = class {
|
|
|
3799
4480
|
}
|
|
3800
4481
|
});
|
|
3801
4482
|
}
|
|
3802
|
-
constructor(_rootHandle) {
|
|
3803
|
-
this._rootHandle = _rootHandle;
|
|
3804
|
-
}
|
|
3805
4483
|
get documentId() {
|
|
3806
4484
|
return this._rootHandle.documentId;
|
|
3807
4485
|
}
|
|
@@ -3865,19 +4543,28 @@ var DatabaseRoot = class {
|
|
|
3865
4543
|
}
|
|
3866
4544
|
return measureDocMetrics(doc);
|
|
3867
4545
|
}
|
|
4546
|
+
constructor(_rootHandle) {
|
|
4547
|
+
_define_property14(this, "_rootHandle", void 0);
|
|
4548
|
+
this._rootHandle = _rootHandle;
|
|
4549
|
+
}
|
|
3868
4550
|
};
|
|
3869
4551
|
|
|
3870
4552
|
// src/db-host/space-state-manager.ts
|
|
4553
|
+
function _define_property15(obj, key, value) {
|
|
4554
|
+
if (key in obj) {
|
|
4555
|
+
Object.defineProperty(obj, key, {
|
|
4556
|
+
value,
|
|
4557
|
+
enumerable: true,
|
|
4558
|
+
configurable: true,
|
|
4559
|
+
writable: true
|
|
4560
|
+
});
|
|
4561
|
+
} else {
|
|
4562
|
+
obj[key] = value;
|
|
4563
|
+
}
|
|
4564
|
+
return obj;
|
|
4565
|
+
}
|
|
3871
4566
|
var __dxlog_file15 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/space-state-manager.ts";
|
|
3872
4567
|
var SpaceStateManager = class extends Resource8 {
|
|
3873
|
-
constructor() {
|
|
3874
|
-
super(...arguments);
|
|
3875
|
-
this._roots = /* @__PURE__ */ new Map();
|
|
3876
|
-
this._rootBySpace = /* @__PURE__ */ new Map();
|
|
3877
|
-
this._perRootContext = /* @__PURE__ */ new Map();
|
|
3878
|
-
this._lastSpaceDocumentList = /* @__PURE__ */ new Map();
|
|
3879
|
-
this.spaceDocumentListUpdated = new Event3();
|
|
3880
|
-
}
|
|
3881
4568
|
async _close(ctx) {
|
|
3882
4569
|
for (const [_, rootCtx] of this._perRootContext) {
|
|
3883
4570
|
await rootCtx.dispose();
|
|
@@ -3950,9 +4637,16 @@ var SpaceStateManager = class extends Resource8 {
|
|
|
3950
4637
|
documentListCheckScheduler.trigger();
|
|
3951
4638
|
return root;
|
|
3952
4639
|
}
|
|
4640
|
+
constructor(...args) {
|
|
4641
|
+
super(...args), _define_property15(this, "_roots", /* @__PURE__ */ new Map()), _define_property15(this, "_rootBySpace", /* @__PURE__ */ new Map()), _define_property15(this, "_perRootContext", /* @__PURE__ */ new Map()), _define_property15(this, "_lastSpaceDocumentList", /* @__PURE__ */ new Map()), _define_property15(this, "spaceDocumentListUpdated", new Event3());
|
|
4642
|
+
}
|
|
3953
4643
|
};
|
|
3954
4644
|
var SpaceDocumentListUpdatedEvent = class {
|
|
3955
4645
|
constructor(spaceId, spaceRootId, previousRootId, documentIds) {
|
|
4646
|
+
_define_property15(this, "spaceId", void 0);
|
|
4647
|
+
_define_property15(this, "spaceRootId", void 0);
|
|
4648
|
+
_define_property15(this, "previousRootId", void 0);
|
|
4649
|
+
_define_property15(this, "documentIds", void 0);
|
|
3956
4650
|
this.spaceId = spaceId;
|
|
3957
4651
|
this.spaceRootId = spaceRootId;
|
|
3958
4652
|
this.previousRootId = previousRootId;
|
|
@@ -3961,6 +4655,19 @@ var SpaceDocumentListUpdatedEvent = class {
|
|
|
3961
4655
|
};
|
|
3962
4656
|
|
|
3963
4657
|
// src/db-host/echo-host.ts
|
|
4658
|
+
function _define_property16(obj, key, value) {
|
|
4659
|
+
if (key in obj) {
|
|
4660
|
+
Object.defineProperty(obj, key, {
|
|
4661
|
+
value,
|
|
4662
|
+
enumerable: true,
|
|
4663
|
+
configurable: true,
|
|
4664
|
+
writable: true
|
|
4665
|
+
});
|
|
4666
|
+
} else {
|
|
4667
|
+
obj[key] = value;
|
|
4668
|
+
}
|
|
4669
|
+
return obj;
|
|
4670
|
+
}
|
|
3964
4671
|
var __dxlog_file16 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/echo-host.ts";
|
|
3965
4672
|
var DEFAULT_INDEXING_CONFIG = {
|
|
3966
4673
|
// TODO(dmaretskyi): Disabled by default since embedding generation is expensive.
|
|
@@ -3968,105 +4675,6 @@ var DEFAULT_INDEXING_CONFIG = {
|
|
|
3968
4675
|
vector: false
|
|
3969
4676
|
};
|
|
3970
4677
|
var EchoHost = class extends Resource9 {
|
|
3971
|
-
constructor({ kv, indexing = {}, peerIdProvider, getSpaceKeyByRootDocumentId }) {
|
|
3972
|
-
super();
|
|
3973
|
-
this._spaceStateManager = new SpaceStateManager();
|
|
3974
|
-
const indexingConfig = {
|
|
3975
|
-
...DEFAULT_INDEXING_CONFIG,
|
|
3976
|
-
...indexing
|
|
3977
|
-
};
|
|
3978
|
-
this._indexMetadataStore = new IndexMetadataStore({
|
|
3979
|
-
db: kv.sublevel("index-metadata")
|
|
3980
|
-
});
|
|
3981
|
-
this._echoDataMonitor = new EchoDataMonitor();
|
|
3982
|
-
this._automergeHost = new AutomergeHost({
|
|
3983
|
-
db: kv,
|
|
3984
|
-
dataMonitor: this._echoDataMonitor,
|
|
3985
|
-
indexMetadataStore: this._indexMetadataStore,
|
|
3986
|
-
peerIdProvider,
|
|
3987
|
-
getSpaceKeyByRootDocumentId
|
|
3988
|
-
});
|
|
3989
|
-
this._indexer = new Indexer({
|
|
3990
|
-
db: kv,
|
|
3991
|
-
indexStore: new IndexStore({
|
|
3992
|
-
db: kv.sublevel("index-storage")
|
|
3993
|
-
}),
|
|
3994
|
-
metadataStore: this._indexMetadataStore,
|
|
3995
|
-
loadDocuments: createSelectedDocumentsIterator(this._automergeHost),
|
|
3996
|
-
indexCooldownTime: false ? 0 : void 0
|
|
3997
|
-
});
|
|
3998
|
-
void this._indexer.setConfig({
|
|
3999
|
-
enabled: true,
|
|
4000
|
-
indexes: [
|
|
4001
|
-
//
|
|
4002
|
-
{
|
|
4003
|
-
kind: IndexKind.Kind.SCHEMA_MATCH
|
|
4004
|
-
},
|
|
4005
|
-
{
|
|
4006
|
-
kind: IndexKind.Kind.GRAPH
|
|
4007
|
-
},
|
|
4008
|
-
...indexingConfig.fullText ? [
|
|
4009
|
-
{
|
|
4010
|
-
kind: IndexKind.Kind.FULL_TEXT
|
|
4011
|
-
}
|
|
4012
|
-
] : [],
|
|
4013
|
-
...indexingConfig.vector ? [
|
|
4014
|
-
{
|
|
4015
|
-
kind: IndexKind.Kind.VECTOR
|
|
4016
|
-
}
|
|
4017
|
-
] : []
|
|
4018
|
-
]
|
|
4019
|
-
});
|
|
4020
|
-
this._queryService = new QueryServiceImpl({
|
|
4021
|
-
automergeHost: this._automergeHost,
|
|
4022
|
-
indexer: this._indexer,
|
|
4023
|
-
spaceStateManager: this._spaceStateManager
|
|
4024
|
-
});
|
|
4025
|
-
this._dataService = new DataServiceImpl({
|
|
4026
|
-
automergeHost: this._automergeHost,
|
|
4027
|
-
spaceStateManager: this._spaceStateManager,
|
|
4028
|
-
updateIndexes: async () => {
|
|
4029
|
-
await this._indexer.updateIndexes();
|
|
4030
|
-
}
|
|
4031
|
-
});
|
|
4032
|
-
trace5.diagnostic({
|
|
4033
|
-
id: "echo-stats",
|
|
4034
|
-
name: "Echo Stats",
|
|
4035
|
-
fetch: async () => {
|
|
4036
|
-
return {
|
|
4037
|
-
dataStats: this._echoDataMonitor.computeStats(),
|
|
4038
|
-
loadedDocsCount: this._automergeHost.loadedDocsCount
|
|
4039
|
-
};
|
|
4040
|
-
}
|
|
4041
|
-
});
|
|
4042
|
-
trace5.diagnostic({
|
|
4043
|
-
id: "database-roots",
|
|
4044
|
-
name: "Database Roots",
|
|
4045
|
-
fetch: async () => {
|
|
4046
|
-
return Array.from(this._spaceStateManager.roots.values()).map((root) => ({
|
|
4047
|
-
url: root.url,
|
|
4048
|
-
isLoaded: root.isLoaded,
|
|
4049
|
-
spaceKey: root.getSpaceKey(),
|
|
4050
|
-
inlineObjects: root.getInlineObjectCount(),
|
|
4051
|
-
linkedObjects: root.getLinkedObjectCount()
|
|
4052
|
-
}));
|
|
4053
|
-
}
|
|
4054
|
-
});
|
|
4055
|
-
trace5.diagnostic({
|
|
4056
|
-
id: "database-root-metrics",
|
|
4057
|
-
name: "Database Roots (with metrics)",
|
|
4058
|
-
fetch: async () => {
|
|
4059
|
-
return Array.from(this._spaceStateManager.roots.values()).map((root) => ({
|
|
4060
|
-
url: root.url,
|
|
4061
|
-
isLoaded: root.isLoaded,
|
|
4062
|
-
spaceKey: root.getSpaceKey(),
|
|
4063
|
-
inlineObjects: root.getInlineObjectCount(),
|
|
4064
|
-
linkedObjects: root.getLinkedObjectCount(),
|
|
4065
|
-
...root.measureMetrics() ?? {}
|
|
4066
|
-
}));
|
|
4067
|
-
}
|
|
4068
|
-
});
|
|
4069
|
-
}
|
|
4070
4678
|
get queryService() {
|
|
4071
4679
|
return this._queryService;
|
|
4072
4680
|
}
|
|
@@ -4091,7 +4699,6 @@ var EchoHost = class extends Resource9 {
|
|
|
4091
4699
|
if (e.previousRootId) {
|
|
4092
4700
|
void this._automergeHost.clearLocalCollectionState(deriveCollectionIdFromSpaceId(e.spaceId, e.previousRootId));
|
|
4093
4701
|
}
|
|
4094
|
-
void this._automergeHost.updateLocalCollectionState(deriveCollectionIdFromSpaceId(e.spaceId), e.documentIds);
|
|
4095
4702
|
void this._automergeHost.updateLocalCollectionState(deriveCollectionIdFromSpaceId(e.spaceId, e.spaceRootId), e.documentIds);
|
|
4096
4703
|
});
|
|
4097
4704
|
this._automergeHost.documentsSaved.on(this._ctx, () => {
|
|
@@ -4108,7 +4715,7 @@ var EchoHost = class extends Resource9 {
|
|
|
4108
4715
|
* Flush all pending writes to the underlying storage.
|
|
4109
4716
|
*/
|
|
4110
4717
|
async flush() {
|
|
4111
|
-
await this._automergeHost.
|
|
4718
|
+
await this._automergeHost.flush();
|
|
4112
4719
|
}
|
|
4113
4720
|
/**
|
|
4114
4721
|
* Perform any pending index updates.
|
|
@@ -4137,7 +4744,7 @@ var EchoHost = class extends Resource9 {
|
|
|
4137
4744
|
async createSpaceRoot(spaceKey) {
|
|
4138
4745
|
invariant13(this._lifecycleState === LifecycleState5.OPEN, void 0, {
|
|
4139
4746
|
F: __dxlog_file16,
|
|
4140
|
-
L:
|
|
4747
|
+
L: 254,
|
|
4141
4748
|
S: this,
|
|
4142
4749
|
A: [
|
|
4143
4750
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -4165,7 +4772,7 @@ var EchoHost = class extends Resource9 {
|
|
|
4165
4772
|
async openSpaceRoot(spaceId, automergeUrl) {
|
|
4166
4773
|
invariant13(this._lifecycleState === LifecycleState5.OPEN, void 0, {
|
|
4167
4774
|
F: __dxlog_file16,
|
|
4168
|
-
L:
|
|
4775
|
+
L: 273,
|
|
4169
4776
|
S: this,
|
|
4170
4777
|
A: [
|
|
4171
4778
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -4192,16 +4799,114 @@ var EchoHost = class extends Resource9 {
|
|
|
4192
4799
|
async removeReplicator(replicator) {
|
|
4193
4800
|
await this._automergeHost.removeReplicator(replicator);
|
|
4194
4801
|
}
|
|
4802
|
+
constructor({ kv, indexing = {}, peerIdProvider, getSpaceKeyByRootDocumentId }) {
|
|
4803
|
+
super(), _define_property16(this, "_indexMetadataStore", void 0), _define_property16(this, "_indexer", void 0), _define_property16(this, "_automergeHost", void 0), _define_property16(this, "_queryService", void 0), _define_property16(this, "_dataService", void 0), _define_property16(this, "_spaceStateManager", new SpaceStateManager()), _define_property16(this, "_echoDataMonitor", void 0);
|
|
4804
|
+
const indexingConfig = {
|
|
4805
|
+
...DEFAULT_INDEXING_CONFIG,
|
|
4806
|
+
...indexing
|
|
4807
|
+
};
|
|
4808
|
+
this._indexMetadataStore = new IndexMetadataStore({
|
|
4809
|
+
db: kv.sublevel("index-metadata")
|
|
4810
|
+
});
|
|
4811
|
+
this._echoDataMonitor = new EchoDataMonitor();
|
|
4812
|
+
this._automergeHost = new AutomergeHost({
|
|
4813
|
+
db: kv,
|
|
4814
|
+
dataMonitor: this._echoDataMonitor,
|
|
4815
|
+
indexMetadataStore: this._indexMetadataStore,
|
|
4816
|
+
peerIdProvider,
|
|
4817
|
+
getSpaceKeyByRootDocumentId
|
|
4818
|
+
});
|
|
4819
|
+
this._indexer = new Indexer({
|
|
4820
|
+
db: kv,
|
|
4821
|
+
indexStore: new IndexStore({
|
|
4822
|
+
db: kv.sublevel("index-storage")
|
|
4823
|
+
}),
|
|
4824
|
+
metadataStore: this._indexMetadataStore,
|
|
4825
|
+
loadDocuments: createSelectedDocumentsIterator(this._automergeHost),
|
|
4826
|
+
indexCooldownTime: false ? 0 : void 0
|
|
4827
|
+
});
|
|
4828
|
+
void this._indexer.setConfig({
|
|
4829
|
+
enabled: true,
|
|
4830
|
+
indexes: [
|
|
4831
|
+
//
|
|
4832
|
+
{
|
|
4833
|
+
kind: IndexKind.Kind.SCHEMA_MATCH
|
|
4834
|
+
},
|
|
4835
|
+
{
|
|
4836
|
+
kind: IndexKind.Kind.GRAPH
|
|
4837
|
+
},
|
|
4838
|
+
...indexingConfig.fullText ? [
|
|
4839
|
+
{
|
|
4840
|
+
kind: IndexKind.Kind.FULL_TEXT
|
|
4841
|
+
}
|
|
4842
|
+
] : [],
|
|
4843
|
+
...indexingConfig.vector ? [
|
|
4844
|
+
{
|
|
4845
|
+
kind: IndexKind.Kind.VECTOR
|
|
4846
|
+
}
|
|
4847
|
+
] : []
|
|
4848
|
+
]
|
|
4849
|
+
});
|
|
4850
|
+
this._queryService = new QueryServiceImpl({
|
|
4851
|
+
automergeHost: this._automergeHost,
|
|
4852
|
+
indexer: this._indexer,
|
|
4853
|
+
spaceStateManager: this._spaceStateManager
|
|
4854
|
+
});
|
|
4855
|
+
this._dataService = new DataServiceImpl({
|
|
4856
|
+
automergeHost: this._automergeHost,
|
|
4857
|
+
spaceStateManager: this._spaceStateManager,
|
|
4858
|
+
updateIndexes: async () => {
|
|
4859
|
+
await this._indexer.updateIndexes();
|
|
4860
|
+
}
|
|
4861
|
+
});
|
|
4862
|
+
trace5.diagnostic({
|
|
4863
|
+
id: "echo-stats",
|
|
4864
|
+
name: "Echo Stats",
|
|
4865
|
+
fetch: async () => {
|
|
4866
|
+
return {
|
|
4867
|
+
dataStats: this._echoDataMonitor.computeStats(),
|
|
4868
|
+
loadedDocsCount: this._automergeHost.loadedDocsCount
|
|
4869
|
+
};
|
|
4870
|
+
}
|
|
4871
|
+
});
|
|
4872
|
+
trace5.diagnostic({
|
|
4873
|
+
id: "database-roots",
|
|
4874
|
+
name: "Database Roots",
|
|
4875
|
+
fetch: async () => {
|
|
4876
|
+
return Array.from(this._spaceStateManager.roots.values()).map((root) => ({
|
|
4877
|
+
url: root.url,
|
|
4878
|
+
isLoaded: root.isLoaded,
|
|
4879
|
+
spaceKey: root.getSpaceKey(),
|
|
4880
|
+
inlineObjects: root.getInlineObjectCount(),
|
|
4881
|
+
linkedObjects: root.getLinkedObjectCount()
|
|
4882
|
+
}));
|
|
4883
|
+
}
|
|
4884
|
+
});
|
|
4885
|
+
trace5.diagnostic({
|
|
4886
|
+
id: "database-root-metrics",
|
|
4887
|
+
name: "Database Roots (with metrics)",
|
|
4888
|
+
fetch: async () => {
|
|
4889
|
+
return Array.from(this._spaceStateManager.roots.values()).map((root) => ({
|
|
4890
|
+
url: root.url,
|
|
4891
|
+
isLoaded: root.isLoaded,
|
|
4892
|
+
spaceKey: root.getSpaceKey(),
|
|
4893
|
+
inlineObjects: root.getInlineObjectCount(),
|
|
4894
|
+
linkedObjects: root.getLinkedObjectCount(),
|
|
4895
|
+
...root.measureMetrics() ?? {}
|
|
4896
|
+
}));
|
|
4897
|
+
}
|
|
4898
|
+
});
|
|
4899
|
+
}
|
|
4195
4900
|
};
|
|
4196
4901
|
|
|
4197
4902
|
// src/edge/echo-edge-replicator.ts
|
|
4198
4903
|
import { cbor as cbor2 } from "@automerge/automerge-repo";
|
|
4199
|
-
import { Mutex,
|
|
4904
|
+
import { Mutex, scheduleMicroTask as scheduleMicroTask2, scheduleTask as scheduleTask2 } from "@dxos/async";
|
|
4200
4905
|
import { Context as Context6, Resource as Resource11 } from "@dxos/context";
|
|
4201
4906
|
import { randomUUID } from "@dxos/crypto";
|
|
4202
4907
|
import { invariant as invariant14 } from "@dxos/invariant";
|
|
4203
4908
|
import { log as log13 } from "@dxos/log";
|
|
4204
|
-
import { EdgeService } from "@dxos/protocols";
|
|
4909
|
+
import { DocumentCodec, EdgeService } from "@dxos/protocols";
|
|
4205
4910
|
import { buf } from "@dxos/protocols/buf";
|
|
4206
4911
|
import { MessageSchema as RouterMessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
4207
4912
|
import { bufferToArray as bufferToArray2 } from "@dxos/util";
|
|
@@ -4210,11 +4915,21 @@ import { bufferToArray as bufferToArray2 } from "@dxos/util";
|
|
|
4210
4915
|
import { Trigger as Trigger2 } from "@dxos/async";
|
|
4211
4916
|
import { Resource as Resource10 } from "@dxos/context";
|
|
4212
4917
|
import { log as log12 } from "@dxos/log";
|
|
4918
|
+
function _define_property17(obj, key, value) {
|
|
4919
|
+
if (key in obj) {
|
|
4920
|
+
Object.defineProperty(obj, key, {
|
|
4921
|
+
value,
|
|
4922
|
+
enumerable: true,
|
|
4923
|
+
configurable: true,
|
|
4924
|
+
writable: true
|
|
4925
|
+
});
|
|
4926
|
+
} else {
|
|
4927
|
+
obj[key] = value;
|
|
4928
|
+
}
|
|
4929
|
+
return obj;
|
|
4930
|
+
}
|
|
4213
4931
|
var __dxlog_file17 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/edge/inflight-request-limiter.ts";
|
|
4214
4932
|
var InflightRequestLimiter = class extends Resource10 {
|
|
4215
|
-
constructor(_config) {
|
|
4216
|
-
super(), this._config = _config, this._inflightRequestBalance = 0, this._requestBarrier = new Trigger2();
|
|
4217
|
-
}
|
|
4218
4933
|
async _open() {
|
|
4219
4934
|
this._inflightRequestBalance = 0;
|
|
4220
4935
|
this._requestBarrier.reset();
|
|
@@ -4257,9 +4972,30 @@ var InflightRequestLimiter = class extends Resource10 {
|
|
|
4257
4972
|
clearInterval(this._resetBalanceTimeout);
|
|
4258
4973
|
}
|
|
4259
4974
|
}
|
|
4975
|
+
constructor(_config) {
|
|
4976
|
+
super(), _define_property17(this, "_config", void 0), /**
|
|
4977
|
+
* Decrement when we receive a sync message, increment when we send one.
|
|
4978
|
+
* Can't exceed _config.maxInflightRequests.
|
|
4979
|
+
* Resets after timeout to avoid replicator being stuck.
|
|
4980
|
+
*/
|
|
4981
|
+
_define_property17(this, "_inflightRequestBalance", void 0), _define_property17(this, "_requestBarrier", void 0), _define_property17(this, "_resetBalanceTimeout", void 0), this._config = _config, this._inflightRequestBalance = 0, this._requestBarrier = new Trigger2();
|
|
4982
|
+
}
|
|
4260
4983
|
};
|
|
4261
4984
|
|
|
4262
4985
|
// src/edge/echo-edge-replicator.ts
|
|
4986
|
+
function _define_property18(obj, key, value) {
|
|
4987
|
+
if (key in obj) {
|
|
4988
|
+
Object.defineProperty(obj, key, {
|
|
4989
|
+
value,
|
|
4990
|
+
enumerable: true,
|
|
4991
|
+
configurable: true,
|
|
4992
|
+
writable: true
|
|
4993
|
+
});
|
|
4994
|
+
} else {
|
|
4995
|
+
obj[key] = value;
|
|
4996
|
+
}
|
|
4997
|
+
return obj;
|
|
4998
|
+
}
|
|
4263
4999
|
function _ts_add_disposable_resource(env, value, async) {
|
|
4264
5000
|
if (value !== null && value !== void 0) {
|
|
4265
5001
|
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
@@ -4330,30 +5066,20 @@ var INITIAL_RESTART_DELAY = 500;
|
|
|
4330
5066
|
var RESTART_DELAY_JITTER = 250;
|
|
4331
5067
|
var MAX_RESTART_DELAY = 5e3;
|
|
4332
5068
|
var EchoEdgeReplicator = class {
|
|
4333
|
-
constructor({ edgeConnection, disableSharePolicy }) {
|
|
4334
|
-
this._mutex = new Mutex();
|
|
4335
|
-
this._ctx = void 0;
|
|
4336
|
-
this._context = null;
|
|
4337
|
-
this._connectedSpaces = /* @__PURE__ */ new Set();
|
|
4338
|
-
this._connections = /* @__PURE__ */ new Map();
|
|
4339
|
-
this._sharePolicyEnabled = true;
|
|
4340
|
-
this._edgeConnection = edgeConnection;
|
|
4341
|
-
this._sharePolicyEnabled = !disableSharePolicy;
|
|
4342
|
-
}
|
|
4343
5069
|
async connect(context) {
|
|
4344
5070
|
log13("connecting...", {
|
|
4345
5071
|
peerId: context.peerId,
|
|
4346
5072
|
connectedSpaces: this._connectedSpaces.size
|
|
4347
5073
|
}, {
|
|
4348
5074
|
F: __dxlog_file18,
|
|
4349
|
-
L:
|
|
5075
|
+
L: 72,
|
|
4350
5076
|
S: this,
|
|
4351
5077
|
C: (f, a) => f(...a)
|
|
4352
5078
|
});
|
|
4353
5079
|
this._context = context;
|
|
4354
5080
|
this._ctx = Context6.default(void 0, {
|
|
4355
5081
|
F: __dxlog_file18,
|
|
4356
|
-
L:
|
|
5082
|
+
L: 74
|
|
4357
5083
|
});
|
|
4358
5084
|
this._ctx.onDispose(this._edgeConnection.onReconnected(() => {
|
|
4359
5085
|
this._ctx && scheduleMicroTask2(this._ctx, () => this._handleReconnect());
|
|
@@ -4452,7 +5178,7 @@ var EchoEdgeReplicator = class {
|
|
|
4452
5178
|
async _openConnection(spaceId, reconnects = 0) {
|
|
4453
5179
|
invariant14(this._context, void 0, {
|
|
4454
5180
|
F: __dxlog_file18,
|
|
4455
|
-
L:
|
|
5181
|
+
L: 135,
|
|
4456
5182
|
S: this,
|
|
4457
5183
|
A: [
|
|
4458
5184
|
"this._context",
|
|
@@ -4461,7 +5187,7 @@ var EchoEdgeReplicator = class {
|
|
|
4461
5187
|
});
|
|
4462
5188
|
invariant14(!this._connections.has(spaceId), void 0, {
|
|
4463
5189
|
F: __dxlog_file18,
|
|
4464
|
-
L:
|
|
5190
|
+
L: 136,
|
|
4465
5191
|
S: this,
|
|
4466
5192
|
A: [
|
|
4467
5193
|
"!this._connections.has(spaceId)",
|
|
@@ -4470,14 +5196,31 @@ var EchoEdgeReplicator = class {
|
|
|
4470
5196
|
});
|
|
4471
5197
|
let restartScheduled = false;
|
|
4472
5198
|
const connection = new EdgeReplicatorConnection({
|
|
5199
|
+
edgeHttpClient: this._edgeHttpClient,
|
|
4473
5200
|
edgeConnection: this._edgeConnection,
|
|
4474
5201
|
spaceId,
|
|
4475
5202
|
context: this._context,
|
|
4476
5203
|
sharedPolicyEnabled: this._sharePolicyEnabled,
|
|
4477
5204
|
onRemoteConnected: async () => {
|
|
5205
|
+
log13.trace("dxos.echo.edge.replicator.onRemoteConnected", {
|
|
5206
|
+
spaceId
|
|
5207
|
+
}, {
|
|
5208
|
+
F: __dxlog_file18,
|
|
5209
|
+
L: 147,
|
|
5210
|
+
S: this,
|
|
5211
|
+
C: (f, a) => f(...a)
|
|
5212
|
+
});
|
|
4478
5213
|
this._context?.onConnectionOpen(connection);
|
|
4479
5214
|
},
|
|
4480
5215
|
onRemoteDisconnected: async () => {
|
|
5216
|
+
log13.trace("dxos.echo.edge.replicator.onRemoteDisconnected", {
|
|
5217
|
+
spaceId
|
|
5218
|
+
}, {
|
|
5219
|
+
F: __dxlog_file18,
|
|
5220
|
+
L: 151,
|
|
5221
|
+
S: this,
|
|
5222
|
+
C: (f, a) => f(...a)
|
|
5223
|
+
});
|
|
4481
5224
|
this._context?.onConnectionClosed(connection);
|
|
4482
5225
|
},
|
|
4483
5226
|
onRestartRequested: async () => {
|
|
@@ -4491,7 +5234,7 @@ var EchoEdgeReplicator = class {
|
|
|
4491
5234
|
restartDelay
|
|
4492
5235
|
}, {
|
|
4493
5236
|
F: __dxlog_file18,
|
|
4494
|
-
L:
|
|
5237
|
+
L: 162,
|
|
4495
5238
|
S: this,
|
|
4496
5239
|
C: (f, a) => f(...a)
|
|
4497
5240
|
});
|
|
@@ -4513,6 +5256,16 @@ var EchoEdgeReplicator = class {
|
|
|
4513
5256
|
if (ctx?.disposed) {
|
|
4514
5257
|
return;
|
|
4515
5258
|
}
|
|
5259
|
+
log13.trace("dxos.echo.edge.replicator.restart", {
|
|
5260
|
+
spaceId,
|
|
5261
|
+
reconnects,
|
|
5262
|
+
restartDelay
|
|
5263
|
+
}, {
|
|
5264
|
+
F: __dxlog_file18,
|
|
5265
|
+
L: 179,
|
|
5266
|
+
S: this,
|
|
5267
|
+
C: (f, a) => f(...a)
|
|
5268
|
+
});
|
|
4516
5269
|
await this._openConnection(spaceId, reconnects + 1);
|
|
4517
5270
|
} catch (e) {
|
|
4518
5271
|
env.error = e;
|
|
@@ -4526,42 +5279,27 @@ var EchoEdgeReplicator = class {
|
|
|
4526
5279
|
this._connections.set(spaceId, connection);
|
|
4527
5280
|
await connection.open();
|
|
4528
5281
|
}
|
|
5282
|
+
constructor({ edgeConnection, edgeHttpClient, disableSharePolicy }) {
|
|
5283
|
+
_define_property18(this, "_edgeConnection", void 0);
|
|
5284
|
+
_define_property18(this, "_edgeHttpClient", void 0);
|
|
5285
|
+
_define_property18(this, "_mutex", new Mutex());
|
|
5286
|
+
_define_property18(this, "_ctx", void 0);
|
|
5287
|
+
_define_property18(this, "_context", null);
|
|
5288
|
+
_define_property18(this, "_connectedSpaces", /* @__PURE__ */ new Set());
|
|
5289
|
+
_define_property18(this, "_connections", /* @__PURE__ */ new Map());
|
|
5290
|
+
_define_property18(this, "_sharePolicyEnabled", true);
|
|
5291
|
+
this._edgeConnection = edgeConnection;
|
|
5292
|
+
this._edgeHttpClient = edgeHttpClient;
|
|
5293
|
+
this._sharePolicyEnabled = !disableSharePolicy;
|
|
5294
|
+
}
|
|
4529
5295
|
};
|
|
4530
5296
|
var MAX_INFLIGHT_REQUESTS = 5;
|
|
4531
5297
|
var MAX_RATE_LIMIT_WAIT_TIME_MS = 3e3;
|
|
4532
5298
|
var EdgeReplicatorConnection = class extends Resource11 {
|
|
4533
|
-
constructor({ edgeConnection, spaceId, context, sharedPolicyEnabled, onRemoteConnected, onRemoteDisconnected, onRestartRequested }) {
|
|
4534
|
-
super();
|
|
4535
|
-
this._remotePeerId = null;
|
|
4536
|
-
this._requestLimiter = new InflightRequestLimiter({
|
|
4537
|
-
maxInflightRequests: MAX_INFLIGHT_REQUESTS,
|
|
4538
|
-
resetBalanceTimeoutMs: MAX_RATE_LIMIT_WAIT_TIME_MS
|
|
4539
|
-
});
|
|
4540
|
-
this._edgeConnection = edgeConnection;
|
|
4541
|
-
this._spaceId = spaceId;
|
|
4542
|
-
this._context = context;
|
|
4543
|
-
this._remotePeerId = `${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}-${randomUUID()}`;
|
|
4544
|
-
this._targetServiceId = `${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}`;
|
|
4545
|
-
this._sharedPolicyEnabled = sharedPolicyEnabled;
|
|
4546
|
-
this._onRemoteConnected = onRemoteConnected;
|
|
4547
|
-
this._onRemoteDisconnected = onRemoteDisconnected;
|
|
4548
|
-
this._onRestartRequested = onRestartRequested;
|
|
4549
|
-
this.readable = new ReadableStream({
|
|
4550
|
-
start: (controller) => {
|
|
4551
|
-
this._readableStreamController = controller;
|
|
4552
|
-
}
|
|
4553
|
-
});
|
|
4554
|
-
this.writable = new WritableStream({
|
|
4555
|
-
write: async (message, controller) => {
|
|
4556
|
-
await this._requestLimiter.rateLimit(message);
|
|
4557
|
-
await this._sendMessage(message);
|
|
4558
|
-
}
|
|
4559
|
-
});
|
|
4560
|
-
}
|
|
4561
5299
|
async _open(ctx) {
|
|
4562
5300
|
log13("opening...", void 0, {
|
|
4563
5301
|
F: __dxlog_file18,
|
|
4564
|
-
L:
|
|
5302
|
+
L: 270,
|
|
4565
5303
|
S: this,
|
|
4566
5304
|
C: (f, a) => f(...a)
|
|
4567
5305
|
});
|
|
@@ -4569,12 +5307,29 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
4569
5307
|
this._ctx.onDispose(this._edgeConnection.onMessage((msg) => {
|
|
4570
5308
|
this._onMessage(msg);
|
|
4571
5309
|
}));
|
|
5310
|
+
let firstReconnect = true;
|
|
5311
|
+
this._ctx.onDispose(
|
|
5312
|
+
// NOTE: This will fire immediately if the connection is already open.
|
|
5313
|
+
this._edgeConnection.onReconnected(async () => {
|
|
5314
|
+
if (firstReconnect) {
|
|
5315
|
+
log13.verbose("first reconnect skipped", void 0, {
|
|
5316
|
+
F: __dxlog_file18,
|
|
5317
|
+
L: 285,
|
|
5318
|
+
S: this,
|
|
5319
|
+
C: (f, a) => f(...a)
|
|
5320
|
+
});
|
|
5321
|
+
firstReconnect = false;
|
|
5322
|
+
return;
|
|
5323
|
+
}
|
|
5324
|
+
this._onRestartRequested();
|
|
5325
|
+
})
|
|
5326
|
+
);
|
|
4572
5327
|
await this._onRemoteConnected();
|
|
4573
5328
|
}
|
|
4574
5329
|
async _close() {
|
|
4575
5330
|
log13("closing...", void 0, {
|
|
4576
5331
|
F: __dxlog_file18,
|
|
4577
|
-
L:
|
|
5332
|
+
L: 298,
|
|
4578
5333
|
S: this,
|
|
4579
5334
|
C: (f, a) => f(...a)
|
|
4580
5335
|
});
|
|
@@ -4585,7 +5340,7 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
4585
5340
|
get peerId() {
|
|
4586
5341
|
invariant14(this._remotePeerId, "Not connected", {
|
|
4587
5342
|
F: __dxlog_file18,
|
|
4588
|
-
L:
|
|
5343
|
+
L: 307,
|
|
4589
5344
|
S: this,
|
|
4590
5345
|
A: [
|
|
4591
5346
|
"this._remotePeerId",
|
|
@@ -4610,7 +5365,7 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
4610
5365
|
remoteId: this._remotePeerId
|
|
4611
5366
|
}, {
|
|
4612
5367
|
F: __dxlog_file18,
|
|
4613
|
-
L:
|
|
5368
|
+
L: 322,
|
|
4614
5369
|
S: this,
|
|
4615
5370
|
C: (f, a) => f(...a)
|
|
4616
5371
|
});
|
|
@@ -4636,13 +5391,36 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
4636
5391
|
remoteId: this._remotePeerId
|
|
4637
5392
|
}, {
|
|
4638
5393
|
F: __dxlog_file18,
|
|
4639
|
-
L:
|
|
5394
|
+
L: 351,
|
|
4640
5395
|
S: this,
|
|
4641
5396
|
C: (f, a) => f(...a)
|
|
4642
5397
|
});
|
|
4643
5398
|
payload.senderId = this._remotePeerId;
|
|
4644
5399
|
this._processMessage(payload);
|
|
4645
5400
|
}
|
|
5401
|
+
get bundleSyncEnabled() {
|
|
5402
|
+
return true;
|
|
5403
|
+
}
|
|
5404
|
+
async pushBundle(bundle) {
|
|
5405
|
+
const request = {
|
|
5406
|
+
bundle: bundle.map(({ documentId, data, heads }) => ({
|
|
5407
|
+
documentId,
|
|
5408
|
+
mutation: DocumentCodec.encode(data),
|
|
5409
|
+
heads
|
|
5410
|
+
}))
|
|
5411
|
+
};
|
|
5412
|
+
await this._edgeHttpClient.importBundle(this._spaceId, request);
|
|
5413
|
+
}
|
|
5414
|
+
async pullBundle(docHeads) {
|
|
5415
|
+
const request = {
|
|
5416
|
+
docHeads
|
|
5417
|
+
};
|
|
5418
|
+
const response = await this._edgeHttpClient.exportBundle(this._spaceId, request);
|
|
5419
|
+
return Object.fromEntries(response.bundle.map((doc) => [
|
|
5420
|
+
doc.documentId,
|
|
5421
|
+
DocumentCodec.decode(doc.mutation)
|
|
5422
|
+
]));
|
|
5423
|
+
}
|
|
4646
5424
|
_processMessage(message) {
|
|
4647
5425
|
if (isForbiddenErrorMessage(message)) {
|
|
4648
5426
|
this._onRestartRequested();
|
|
@@ -4659,27 +5437,65 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
4659
5437
|
remoteId: this._remotePeerId
|
|
4660
5438
|
}, {
|
|
4661
5439
|
F: __dxlog_file18,
|
|
4662
|
-
L:
|
|
5440
|
+
L: 401,
|
|
4663
5441
|
S: this,
|
|
4664
5442
|
C: (f, a) => f(...a)
|
|
4665
5443
|
});
|
|
4666
5444
|
const encoded = cbor2.encode(message);
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
5445
|
+
try {
|
|
5446
|
+
await this._edgeConnection.send(buf.create(RouterMessageSchema, {
|
|
5447
|
+
serviceId: this._targetServiceId,
|
|
5448
|
+
source: {
|
|
5449
|
+
identityKey: this._edgeConnection.identityKey,
|
|
5450
|
+
peerKey: this._edgeConnection.peerKey
|
|
5451
|
+
},
|
|
5452
|
+
payload: {
|
|
5453
|
+
value: bufferToArray2(encoded)
|
|
5454
|
+
}
|
|
5455
|
+
}));
|
|
5456
|
+
} catch (err) {
|
|
5457
|
+
log13.error("failed to send message", {
|
|
5458
|
+
err
|
|
5459
|
+
}, {
|
|
5460
|
+
F: __dxlog_file18,
|
|
5461
|
+
L: 421,
|
|
5462
|
+
S: this,
|
|
5463
|
+
C: (f, a) => f(...a)
|
|
5464
|
+
});
|
|
5465
|
+
}
|
|
5466
|
+
}
|
|
5467
|
+
constructor({ edgeConnection, edgeHttpClient, spaceId, context, sharedPolicyEnabled, onRemoteConnected, onRemoteDisconnected, onRestartRequested }) {
|
|
5468
|
+
super(), _define_property18(this, "_edgeConnection", void 0), _define_property18(this, "_edgeHttpClient", void 0), _define_property18(this, "_remotePeerId", null), _define_property18(this, "_targetServiceId", void 0), _define_property18(this, "_spaceId", void 0), _define_property18(this, "_context", void 0), _define_property18(this, "_sharedPolicyEnabled", void 0), _define_property18(this, "_onRemoteConnected", void 0), _define_property18(this, "_onRemoteDisconnected", void 0), _define_property18(this, "_onRestartRequested", void 0), _define_property18(this, "_requestLimiter", new InflightRequestLimiter({
|
|
5469
|
+
maxInflightRequests: MAX_INFLIGHT_REQUESTS,
|
|
5470
|
+
resetBalanceTimeoutMs: MAX_RATE_LIMIT_WAIT_TIME_MS
|
|
5471
|
+
})), _define_property18(this, "_readableStreamController", void 0), _define_property18(this, "readable", void 0), _define_property18(this, "writable", void 0);
|
|
5472
|
+
this._edgeConnection = edgeConnection;
|
|
5473
|
+
this._edgeHttpClient = edgeHttpClient;
|
|
5474
|
+
this._spaceId = spaceId;
|
|
5475
|
+
this._context = context;
|
|
5476
|
+
this._remotePeerId = `${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}-${randomUUID()}`;
|
|
5477
|
+
this._targetServiceId = `${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}`;
|
|
5478
|
+
this._sharedPolicyEnabled = sharedPolicyEnabled;
|
|
5479
|
+
this._onRemoteConnected = onRemoteConnected;
|
|
5480
|
+
this._onRemoteDisconnected = onRemoteDisconnected;
|
|
5481
|
+
this._onRestartRequested = onRestartRequested;
|
|
5482
|
+
this.readable = new ReadableStream({
|
|
5483
|
+
start: (controller) => {
|
|
5484
|
+
this._readableStreamController = controller;
|
|
4675
5485
|
}
|
|
4676
|
-
})
|
|
5486
|
+
});
|
|
5487
|
+
this.writable = new WritableStream({
|
|
5488
|
+
write: async (message, controller) => {
|
|
5489
|
+
await this._requestLimiter.rateLimit(message);
|
|
5490
|
+
await this._sendMessage(message);
|
|
5491
|
+
}
|
|
5492
|
+
});
|
|
4677
5493
|
}
|
|
4678
5494
|
};
|
|
4679
5495
|
var isForbiddenErrorMessage = (message) => message.type === "error" && message.message === "Forbidden";
|
|
4680
5496
|
|
|
4681
5497
|
// src/util.ts
|
|
4682
|
-
import {
|
|
5498
|
+
import { ObjectStructure as ObjectStructure2, decodeReference } from "@dxos/echo-protocol";
|
|
4683
5499
|
var findInlineObjectOfType = (spaceDoc, typename) => {
|
|
4684
5500
|
for (const id in spaceDoc.objects ?? {}) {
|
|
4685
5501
|
const obj = spaceDoc.objects[id];
|
|
@@ -4731,6 +5547,7 @@ export {
|
|
|
4731
5547
|
diffCollectionState,
|
|
4732
5548
|
encodingOptions,
|
|
4733
5549
|
filterMatchObject,
|
|
5550
|
+
filterMatchObjectJSON,
|
|
4734
5551
|
filterMatchValue,
|
|
4735
5552
|
findInlineObjectOfType,
|
|
4736
5553
|
getSpaceIdFromCollectionId,
|