@dxos/echo-pipeline 0.8.3 → 0.8.4-main.1da679c
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-TQJTKNMS.mjs → chunk-KQYT6ADL.mjs} +109 -3
- package/dist/lib/browser/chunk-KQYT6ADL.mjs.map +7 -0
- package/dist/lib/browser/{chunk-35I6ERLG.mjs → chunk-XGG76KKU.mjs} +513 -350
- 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 +1371 -601
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +119 -56
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/{chunk-5BHLPT24.mjs → chunk-CHMJJ4DG.mjs} +513 -350
- package/dist/lib/node-esm/chunk-CHMJJ4DG.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-RVK35BS7.mjs → chunk-W4ACY3YC.mjs} +109 -3
- package/dist/lib/node-esm/chunk-W4ACY3YC.mjs.map +7 -0
- package/dist/lib/node-esm/filter/index.mjs +3 -1
- package/dist/lib/node-esm/index.mjs +1371 -601
- 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 +119 -56
- 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 +42 -38
- package/src/automerge/automerge-host.test.ts +18 -8
- package/src/automerge/automerge-host.ts +251 -65
- 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 +40 -7
- 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 +13 -14
- 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 +23 -3
- package/src/filter/filter-match.ts +148 -3
- 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 +66 -11
- package/src/query/query-planner.test.ts +146 -2
- package/src/query/query-planner.ts +52 -8
- 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-35I6ERLG.mjs.map +0 -7
- package/dist/lib/browser/chunk-TQJTKNMS.mjs.map +0 -7
- package/dist/lib/node/chunk-HOPOFWAL.cjs +0 -147
- package/dist/lib/node/chunk-HOPOFWAL.cjs.map +0 -7
- package/dist/lib/node/chunk-JXX6LF5U.cjs +0 -2084
- package/dist/lib/node/chunk-JXX6LF5U.cjs.map +0 -7
- package/dist/lib/node/chunk-Q7SFCCGT.cjs +0 -33
- package/dist/lib/node/chunk-Q7SFCCGT.cjs.map +0 -7
- package/dist/lib/node/filter/index.cjs +0 -32
- package/dist/lib/node/filter/index.cjs.map +0 -7
- package/dist/lib/node/index.cjs +0 -4699
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/lib/node/testing/index.cjs +0 -753
- package/dist/lib/node/testing/index.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-5BHLPT24.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-RVK35BS7.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-KQYT6ADL.mjs";
|
|
6
7
|
import {
|
|
7
8
|
AuthExtension,
|
|
8
9
|
AuthStatus,
|
|
@@ -25,27 +26,21 @@ 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
|
|
32
33
|
import { UpdateScheduler as UpdateScheduler2 } from "@dxos/async";
|
|
33
34
|
import { Stream } from "@dxos/codec-protobuf/stream";
|
|
34
35
|
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
|
-
//
|
|
39
|
-
import {
|
|
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
|
-
// packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
|
|
46
|
-
import { getBackend, getHeads, isAutomerge, equals as headsEquals, save } from "@automerge/automerge";
|
|
39
|
+
// src/automerge/automerge-host.ts
|
|
40
|
+
import { getBackend, getHeads, equals as headsEquals, isAutomerge, save } from "@automerge/automerge";
|
|
47
41
|
import { Repo, interpretAsDocumentId } from "@automerge/automerge-repo";
|
|
48
|
-
import {
|
|
42
|
+
import { exportBundle } from "@automerge/automerge-repo-bundles";
|
|
43
|
+
import { DeferredTask, Event as Event2, asyncTimeout } from "@dxos/async";
|
|
49
44
|
import { Context, Resource as Resource3, cancelWithContext } from "@dxos/context";
|
|
50
45
|
import { DatabaseDirectory } from "@dxos/echo-protocol";
|
|
51
46
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
@@ -53,38 +48,38 @@ import { PublicKey } from "@dxos/keys";
|
|
|
53
48
|
import { log as log3 } from "@dxos/log";
|
|
54
49
|
import { objectPointerCodec } from "@dxos/protocols";
|
|
55
50
|
import { trace as trace2 } from "@dxos/tracing";
|
|
56
|
-
import { bufferToArray } from "@dxos/util";
|
|
51
|
+
import { ComplexSet, bufferToArray, range } from "@dxos/util";
|
|
57
52
|
|
|
58
|
-
//
|
|
53
|
+
// src/automerge/collection-synchronizer.ts
|
|
59
54
|
import { next as am } from "@automerge/automerge";
|
|
60
|
-
import {
|
|
55
|
+
import { Event, asyncReturn, scheduleTask, scheduleTaskInterval } from "@dxos/async";
|
|
61
56
|
import { Resource } from "@dxos/context";
|
|
62
57
|
import { log } from "@dxos/log";
|
|
63
58
|
import { trace } from "@dxos/tracing";
|
|
64
59
|
import { defaultMap } from "@dxos/util";
|
|
60
|
+
function _define_property(obj, key, value) {
|
|
61
|
+
if (key in obj) {
|
|
62
|
+
Object.defineProperty(obj, key, {
|
|
63
|
+
value,
|
|
64
|
+
enumerable: true,
|
|
65
|
+
configurable: true,
|
|
66
|
+
writable: true
|
|
67
|
+
});
|
|
68
|
+
} else {
|
|
69
|
+
obj[key] = value;
|
|
70
|
+
}
|
|
71
|
+
return obj;
|
|
72
|
+
}
|
|
65
73
|
function _ts_decorate(decorators, target, key, desc) {
|
|
66
74
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
67
75
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
68
76
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
69
77
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
70
78
|
}
|
|
71
|
-
var __dxlog_file = "/
|
|
79
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/collection-synchronizer.ts";
|
|
72
80
|
var MIN_QUERY_INTERVAL = 5e3;
|
|
73
81
|
var POLL_INTERVAL = 3e4;
|
|
74
82
|
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
83
|
async _open(ctx) {
|
|
89
84
|
scheduleTaskInterval(this._ctx, async () => {
|
|
90
85
|
for (const collectionId of this._perCollectionStates.keys()) {
|
|
@@ -263,6 +258,15 @@ var CollectionSynchronizer = class extends Resource {
|
|
|
263
258
|
}
|
|
264
259
|
}
|
|
265
260
|
}
|
|
261
|
+
constructor(params) {
|
|
262
|
+
super(), _define_property(this, "_sendCollectionState", void 0), _define_property(this, "_queryCollectionState", void 0), _define_property(this, "_shouldSyncCollection", void 0), /**
|
|
263
|
+
* CollectionId -> State.
|
|
264
|
+
*/
|
|
265
|
+
_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());
|
|
266
|
+
this._sendCollectionState = params.sendCollectionState;
|
|
267
|
+
this._queryCollectionState = params.queryCollectionState;
|
|
268
|
+
this._shouldSyncCollection = params.shouldSyncCollection;
|
|
269
|
+
}
|
|
266
270
|
};
|
|
267
271
|
CollectionSynchronizer = _ts_decorate([
|
|
268
272
|
trace.resource()
|
|
@@ -276,9 +280,9 @@ var diffCollectionState = (local, remote) => {
|
|
|
276
280
|
const missingOnLocal = [];
|
|
277
281
|
const different = [];
|
|
278
282
|
for (const documentId of allDocuments) {
|
|
279
|
-
if (!local.documents[documentId]) {
|
|
283
|
+
if (!local.documents[documentId] || local.documents[documentId].length === 0) {
|
|
280
284
|
missingOnLocal.push(documentId);
|
|
281
|
-
} else if (!remote.documents[documentId]) {
|
|
285
|
+
} else if (!remote.documents[documentId] || remote.documents[documentId].length === 0) {
|
|
282
286
|
missingOnRemote.push(documentId);
|
|
283
287
|
} else if (!am.equals(local.documents[documentId], remote.documents[documentId])) {
|
|
284
288
|
different.push(documentId);
|
|
@@ -307,31 +311,41 @@ var getSpanName = (peerId) => {
|
|
|
307
311
|
return `collection-sync-${peerId}`;
|
|
308
312
|
};
|
|
309
313
|
|
|
310
|
-
//
|
|
314
|
+
// src/automerge/echo-network-adapter.ts
|
|
311
315
|
import { NetworkAdapter } from "@automerge/automerge-repo";
|
|
312
|
-
import {
|
|
316
|
+
import { Trigger, synchronized } from "@dxos/async";
|
|
313
317
|
import { LifecycleState } from "@dxos/context";
|
|
314
318
|
import { invariant } from "@dxos/invariant";
|
|
315
319
|
import { log as log2 } from "@dxos/log";
|
|
316
320
|
import { isNonNullable } from "@dxos/util";
|
|
317
321
|
|
|
318
|
-
//
|
|
322
|
+
// src/automerge/network-protocol.ts
|
|
319
323
|
import { MESSAGE_TYPE_COLLECTION_QUERY, MESSAGE_TYPE_COLLECTION_STATE } from "@dxos/protocols";
|
|
320
324
|
var isCollectionQueryMessage = (message) => message.type === MESSAGE_TYPE_COLLECTION_QUERY;
|
|
321
325
|
var isCollectionStateMessage = (message) => message.type === MESSAGE_TYPE_COLLECTION_STATE;
|
|
322
326
|
|
|
323
|
-
//
|
|
327
|
+
// src/automerge/echo-network-adapter.ts
|
|
328
|
+
function _define_property2(obj, key, value) {
|
|
329
|
+
if (key in obj) {
|
|
330
|
+
Object.defineProperty(obj, key, {
|
|
331
|
+
value,
|
|
332
|
+
enumerable: true,
|
|
333
|
+
configurable: true,
|
|
334
|
+
writable: true
|
|
335
|
+
});
|
|
336
|
+
} else {
|
|
337
|
+
obj[key] = value;
|
|
338
|
+
}
|
|
339
|
+
return obj;
|
|
340
|
+
}
|
|
324
341
|
function _ts_decorate2(decorators, target, key, desc) {
|
|
325
342
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
326
343
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
327
344
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
328
345
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
329
346
|
}
|
|
330
|
-
var __dxlog_file2 = "/
|
|
347
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts";
|
|
331
348
|
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
349
|
isReady() {
|
|
336
350
|
return this._lifecycleState === LifecycleState.OPEN;
|
|
337
351
|
}
|
|
@@ -380,7 +394,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
380
394
|
async addReplicator(replicator) {
|
|
381
395
|
invariant(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
382
396
|
F: __dxlog_file2,
|
|
383
|
-
L:
|
|
397
|
+
L: 137,
|
|
384
398
|
S: this,
|
|
385
399
|
A: [
|
|
386
400
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -389,7 +403,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
389
403
|
});
|
|
390
404
|
invariant(this.peerId, void 0, {
|
|
391
405
|
F: __dxlog_file2,
|
|
392
|
-
L:
|
|
406
|
+
L: 138,
|
|
393
407
|
S: this,
|
|
394
408
|
A: [
|
|
395
409
|
"this.peerId",
|
|
@@ -398,7 +412,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
398
412
|
});
|
|
399
413
|
invariant(!this._replicators.has(replicator), void 0, {
|
|
400
414
|
F: __dxlog_file2,
|
|
401
|
-
L:
|
|
415
|
+
L: 139,
|
|
402
416
|
S: this,
|
|
403
417
|
A: [
|
|
404
418
|
"!this._replicators.has(replicator)",
|
|
@@ -422,7 +436,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
422
436
|
async removeReplicator(replicator) {
|
|
423
437
|
invariant(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
424
438
|
F: __dxlog_file2,
|
|
425
|
-
L:
|
|
439
|
+
L: 158,
|
|
426
440
|
S: this,
|
|
427
441
|
A: [
|
|
428
442
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -431,7 +445,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
431
445
|
});
|
|
432
446
|
invariant(this._replicators.has(replicator), void 0, {
|
|
433
447
|
F: __dxlog_file2,
|
|
434
|
-
L:
|
|
448
|
+
L: 159,
|
|
435
449
|
S: this,
|
|
436
450
|
A: [
|
|
437
451
|
"this._replicators.has(replicator)",
|
|
@@ -482,6 +496,27 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
482
496
|
}) ? connection.connection.peerId : null;
|
|
483
497
|
}).filter(isNonNullable);
|
|
484
498
|
}
|
|
499
|
+
bundleSyncEnabledForPeer(peerId) {
|
|
500
|
+
const connection = this._connections.get(peerId);
|
|
501
|
+
if (!connection) {
|
|
502
|
+
return false;
|
|
503
|
+
}
|
|
504
|
+
return connection.connection.bundleSyncEnabled;
|
|
505
|
+
}
|
|
506
|
+
async pushBundle(peerId, bundle) {
|
|
507
|
+
const connection = this._connections.get(peerId);
|
|
508
|
+
if (!connection) {
|
|
509
|
+
throw new Error("Connection not found.");
|
|
510
|
+
}
|
|
511
|
+
return connection.connection.pushBundle(bundle);
|
|
512
|
+
}
|
|
513
|
+
async pullBundle(peerId, docHeads) {
|
|
514
|
+
const connection = this._connections.get(peerId);
|
|
515
|
+
if (!connection) {
|
|
516
|
+
throw new Error("Connection not found.");
|
|
517
|
+
}
|
|
518
|
+
return connection.connection.pullBundle(docHeads);
|
|
519
|
+
}
|
|
485
520
|
_send(message) {
|
|
486
521
|
const connectionEntry = this._connections.get(message.targetId);
|
|
487
522
|
if (!connectionEntry) {
|
|
@@ -494,7 +529,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
494
529
|
if (connectionEntry.isOpen) {
|
|
495
530
|
log2.catch(err, void 0, {
|
|
496
531
|
F: __dxlog_file2,
|
|
497
|
-
L:
|
|
532
|
+
L: 253,
|
|
498
533
|
S: this,
|
|
499
534
|
C: (f, a) => f(...a)
|
|
500
535
|
});
|
|
@@ -507,13 +542,13 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
507
542
|
peerId: connection.peerId
|
|
508
543
|
}, {
|
|
509
544
|
F: __dxlog_file2,
|
|
510
|
-
L:
|
|
545
|
+
L: 261,
|
|
511
546
|
S: this,
|
|
512
547
|
C: (f, a) => f(...a)
|
|
513
548
|
});
|
|
514
549
|
invariant(!this._connections.has(connection.peerId), void 0, {
|
|
515
550
|
F: __dxlog_file2,
|
|
516
|
-
L:
|
|
551
|
+
L: 262,
|
|
517
552
|
S: this,
|
|
518
553
|
A: [
|
|
519
554
|
"!this._connections.has(connection.peerId as PeerId)",
|
|
@@ -540,7 +575,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
540
575
|
if (connectionEntry.isOpen) {
|
|
541
576
|
log2.catch(err, void 0, {
|
|
542
577
|
F: __dxlog_file2,
|
|
543
|
-
L:
|
|
578
|
+
L: 286,
|
|
544
579
|
S: this,
|
|
545
580
|
C: (f, a) => f(...a)
|
|
546
581
|
});
|
|
@@ -551,7 +586,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
551
586
|
peerId: connection.peerId
|
|
552
587
|
}, {
|
|
553
588
|
F: __dxlog_file2,
|
|
554
|
-
L:
|
|
589
|
+
L: 291,
|
|
555
590
|
S: this,
|
|
556
591
|
C: (f, a) => f(...a)
|
|
557
592
|
});
|
|
@@ -573,14 +608,14 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
573
608
|
peerId: connection.peerId
|
|
574
609
|
}, {
|
|
575
610
|
F: __dxlog_file2,
|
|
576
|
-
L:
|
|
611
|
+
L: 308,
|
|
577
612
|
S: this,
|
|
578
613
|
C: (f, a) => f(...a)
|
|
579
614
|
});
|
|
580
615
|
const entry = this._connections.get(connection.peerId);
|
|
581
616
|
invariant(entry, void 0, {
|
|
582
617
|
F: __dxlog_file2,
|
|
583
|
-
L:
|
|
618
|
+
L: 310,
|
|
584
619
|
S: this,
|
|
585
620
|
A: [
|
|
586
621
|
"entry",
|
|
@@ -592,15 +627,15 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
592
627
|
peerId: connection.peerId
|
|
593
628
|
});
|
|
594
629
|
this._params.monitor?.recordPeerDisconnected(connection.peerId);
|
|
595
|
-
void entry.
|
|
630
|
+
void entry.writer.abort().catch((err) => log2.catch(err, void 0, {
|
|
596
631
|
F: __dxlog_file2,
|
|
597
|
-
L:
|
|
632
|
+
L: 316,
|
|
598
633
|
S: this,
|
|
599
634
|
C: (f, a) => f(...a)
|
|
600
635
|
}));
|
|
601
|
-
void entry.
|
|
636
|
+
void entry.reader.cancel().catch((err) => log2.catch(err, void 0, {
|
|
602
637
|
F: __dxlog_file2,
|
|
603
|
-
L:
|
|
638
|
+
L: 317,
|
|
604
639
|
S: this,
|
|
605
640
|
C: (f, a) => f(...a)
|
|
606
641
|
}));
|
|
@@ -615,14 +650,14 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
615
650
|
peerId: connection.peerId
|
|
616
651
|
}, {
|
|
617
652
|
F: __dxlog_file2,
|
|
618
|
-
L:
|
|
653
|
+
L: 327,
|
|
619
654
|
S: this,
|
|
620
655
|
C: (f, a) => f(...a)
|
|
621
656
|
});
|
|
622
657
|
const entry = this._connections.get(connection.peerId);
|
|
623
658
|
invariant(entry, void 0, {
|
|
624
659
|
F: __dxlog_file2,
|
|
625
|
-
L:
|
|
660
|
+
L: 329,
|
|
626
661
|
S: this,
|
|
627
662
|
A: [
|
|
628
663
|
"entry",
|
|
@@ -640,6 +675,12 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
640
675
|
peerMetadata: createEchoPeerMetadata()
|
|
641
676
|
});
|
|
642
677
|
}
|
|
678
|
+
constructor(_params) {
|
|
679
|
+
super(), _define_property2(this, "_params", void 0), _define_property2(this, "_replicators", void 0), /**
|
|
680
|
+
* Remote peer id -> connection.
|
|
681
|
+
*/
|
|
682
|
+
_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();
|
|
683
|
+
}
|
|
643
684
|
};
|
|
644
685
|
_ts_decorate2([
|
|
645
686
|
synchronized
|
|
@@ -659,12 +700,22 @@ var createEchoPeerMetadata = () => ({
|
|
|
659
700
|
});
|
|
660
701
|
var isEchoPeerMetadata = (metadata) => metadata?.dxos_peerSource === "EchoNetworkAdapter";
|
|
661
702
|
|
|
662
|
-
//
|
|
703
|
+
// src/automerge/heads-store.ts
|
|
663
704
|
import { headsEncoding } from "@dxos/indexing";
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
705
|
+
function _define_property3(obj, key, value) {
|
|
706
|
+
if (key in obj) {
|
|
707
|
+
Object.defineProperty(obj, key, {
|
|
708
|
+
value,
|
|
709
|
+
enumerable: true,
|
|
710
|
+
configurable: true,
|
|
711
|
+
writable: true
|
|
712
|
+
});
|
|
713
|
+
} else {
|
|
714
|
+
obj[key] = value;
|
|
667
715
|
}
|
|
716
|
+
return obj;
|
|
717
|
+
}
|
|
718
|
+
var HeadsStore = class {
|
|
668
719
|
setHeads(documentId, heads, batch) {
|
|
669
720
|
batch.put(documentId, heads, {
|
|
670
721
|
sublevel: this._db,
|
|
@@ -679,17 +730,31 @@ var HeadsStore = class {
|
|
|
679
730
|
valueEncoding: headsEncoding
|
|
680
731
|
});
|
|
681
732
|
}
|
|
733
|
+
constructor({ db }) {
|
|
734
|
+
_define_property3(this, "_db", void 0);
|
|
735
|
+
this._db = db;
|
|
736
|
+
}
|
|
682
737
|
};
|
|
683
738
|
|
|
684
|
-
//
|
|
685
|
-
import {
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
739
|
+
// src/automerge/leveldb-storage-adapter.ts
|
|
740
|
+
import { Resource as Resource2 } from "@dxos/context";
|
|
741
|
+
function _define_property4(obj, key, value) {
|
|
742
|
+
if (key in obj) {
|
|
743
|
+
Object.defineProperty(obj, key, {
|
|
744
|
+
value,
|
|
745
|
+
enumerable: true,
|
|
746
|
+
configurable: true,
|
|
747
|
+
writable: true
|
|
748
|
+
});
|
|
749
|
+
} else {
|
|
750
|
+
obj[key] = value;
|
|
689
751
|
}
|
|
752
|
+
return obj;
|
|
753
|
+
}
|
|
754
|
+
var LevelDBStorageAdapter = class extends Resource2 {
|
|
690
755
|
async load(keyArray) {
|
|
691
756
|
try {
|
|
692
|
-
if (this.
|
|
757
|
+
if (!this.isOpen) {
|
|
693
758
|
return void 0;
|
|
694
759
|
}
|
|
695
760
|
const startMs = Date.now();
|
|
@@ -707,7 +772,7 @@ var LevelDBStorageAdapter = class extends Resource2 {
|
|
|
707
772
|
}
|
|
708
773
|
}
|
|
709
774
|
async save(keyArray, binary) {
|
|
710
|
-
if (this.
|
|
775
|
+
if (!this.isOpen) {
|
|
711
776
|
return void 0;
|
|
712
777
|
}
|
|
713
778
|
const startMs = Date.now();
|
|
@@ -725,7 +790,7 @@ var LevelDBStorageAdapter = class extends Resource2 {
|
|
|
725
790
|
this._params.monitor?.recordStoreDuration(Date.now() - startMs);
|
|
726
791
|
}
|
|
727
792
|
async remove(keyArray) {
|
|
728
|
-
if (this.
|
|
793
|
+
if (!this.isOpen) {
|
|
729
794
|
return void 0;
|
|
730
795
|
}
|
|
731
796
|
await this._params.db.del(keyArray, {
|
|
@@ -733,7 +798,7 @@ var LevelDBStorageAdapter = class extends Resource2 {
|
|
|
733
798
|
});
|
|
734
799
|
}
|
|
735
800
|
async loadRange(keyPrefix) {
|
|
736
|
-
if (this.
|
|
801
|
+
if (!this.isOpen) {
|
|
737
802
|
return [];
|
|
738
803
|
}
|
|
739
804
|
const startMs = Date.now();
|
|
@@ -756,7 +821,7 @@ var LevelDBStorageAdapter = class extends Resource2 {
|
|
|
756
821
|
return result;
|
|
757
822
|
}
|
|
758
823
|
async removeRange(keyPrefix) {
|
|
759
|
-
if (this.
|
|
824
|
+
if (!this.isOpen) {
|
|
760
825
|
return void 0;
|
|
761
826
|
}
|
|
762
827
|
const batch = this._params.db.batch();
|
|
@@ -774,6 +839,9 @@ var LevelDBStorageAdapter = class extends Resource2 {
|
|
|
774
839
|
}
|
|
775
840
|
await batch.write();
|
|
776
841
|
}
|
|
842
|
+
constructor(_params) {
|
|
843
|
+
super(), _define_property4(this, "_params", void 0), this._params = _params;
|
|
844
|
+
}
|
|
777
845
|
};
|
|
778
846
|
var keyEncoder = {
|
|
779
847
|
encode: (key) => Buffer.from(key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-")),
|
|
@@ -786,58 +854,44 @@ var encodingOptions = {
|
|
|
786
854
|
};
|
|
787
855
|
var isLevelDbNotFoundError = (err) => err.code === "LEVEL_NOT_FOUND";
|
|
788
856
|
|
|
789
|
-
//
|
|
857
|
+
// src/automerge/automerge-host.ts
|
|
858
|
+
function _define_property5(obj, key, value) {
|
|
859
|
+
if (key in obj) {
|
|
860
|
+
Object.defineProperty(obj, key, {
|
|
861
|
+
value,
|
|
862
|
+
enumerable: true,
|
|
863
|
+
configurable: true,
|
|
864
|
+
writable: true
|
|
865
|
+
});
|
|
866
|
+
} else {
|
|
867
|
+
obj[key] = value;
|
|
868
|
+
}
|
|
869
|
+
return obj;
|
|
870
|
+
}
|
|
790
871
|
function _ts_decorate3(decorators, target, key, desc) {
|
|
791
872
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
792
873
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
793
874
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
794
875
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
795
876
|
}
|
|
796
|
-
var __dxlog_file3 = "/
|
|
877
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
|
|
797
878
|
var FIND_PARAMS = {
|
|
798
879
|
allowableStates: [
|
|
799
880
|
"ready",
|
|
800
881
|
"requesting"
|
|
801
882
|
]
|
|
802
883
|
};
|
|
884
|
+
var BUNDLE_SIZE = 100;
|
|
885
|
+
var BUNDLE_SYNC_CONCURRENCY = 2;
|
|
886
|
+
var BUNDLE_SYNC_THRESHOLD = 50;
|
|
803
887
|
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
888
|
async _open() {
|
|
840
889
|
this._peerId = `host-${this._peerIdProvider?.() ?? PublicKey.random().toHex()}`;
|
|
890
|
+
this._onHeadsChangedTask = new DeferredTask(this._ctx, async () => {
|
|
891
|
+
const docHeads = Array.from(this._headsUpdates.entries());
|
|
892
|
+
this._headsUpdates.clear();
|
|
893
|
+
this._onHeadsChanged(docHeads);
|
|
894
|
+
});
|
|
841
895
|
await this._storage.open?.();
|
|
842
896
|
this._repo = new Repo({
|
|
843
897
|
peerId: this._peerId,
|
|
@@ -865,6 +919,28 @@ var AutomergeHost = class extends Resource3 {
|
|
|
865
919
|
}
|
|
866
920
|
}
|
|
867
921
|
});
|
|
922
|
+
this._syncTask = new DeferredTask(this._ctx, async () => {
|
|
923
|
+
const collectionToSync = Array.from(this._collectionsToSync.values());
|
|
924
|
+
if (collectionToSync.length === 0) {
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
927
|
+
await Promise.all(collectionToSync.map(async ({ collectionId, peerId }) => {
|
|
928
|
+
try {
|
|
929
|
+
await this._handleCollectionSync(collectionId, peerId);
|
|
930
|
+
} catch (err) {
|
|
931
|
+
log3.error("failed to sync collection", {
|
|
932
|
+
collectionId,
|
|
933
|
+
peerId,
|
|
934
|
+
err
|
|
935
|
+
}, {
|
|
936
|
+
F: __dxlog_file3,
|
|
937
|
+
L: 224,
|
|
938
|
+
S: this,
|
|
939
|
+
C: (f, a) => f(...a)
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
}));
|
|
943
|
+
});
|
|
868
944
|
await this._echoNetworkAdapter.open();
|
|
869
945
|
await this._collectionSynchronizer.open();
|
|
870
946
|
await this._echoNetworkAdapter.open();
|
|
@@ -874,7 +950,8 @@ var AutomergeHost = class extends Resource3 {
|
|
|
874
950
|
await this._collectionSynchronizer.close();
|
|
875
951
|
await this._storage.close?.();
|
|
876
952
|
await this._echoNetworkAdapter.close();
|
|
877
|
-
|
|
953
|
+
this._syncTask = void 0;
|
|
954
|
+
this._onHeadsChangedTask = void 0;
|
|
878
955
|
}
|
|
879
956
|
/**
|
|
880
957
|
* @deprecated To be abstracted away.
|
|
@@ -889,15 +966,42 @@ var AutomergeHost = class extends Resource3 {
|
|
|
889
966
|
return Object.keys(this._repo.handles).length;
|
|
890
967
|
}
|
|
891
968
|
async addReplicator(replicator) {
|
|
969
|
+
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
970
|
+
F: __dxlog_file3,
|
|
971
|
+
L: 260,
|
|
972
|
+
S: this,
|
|
973
|
+
A: [
|
|
974
|
+
"this.isOpen",
|
|
975
|
+
"'AutomergeHost is not open'"
|
|
976
|
+
]
|
|
977
|
+
});
|
|
892
978
|
await this._echoNetworkAdapter.addReplicator(replicator);
|
|
893
979
|
}
|
|
894
980
|
async removeReplicator(replicator) {
|
|
981
|
+
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
982
|
+
F: __dxlog_file3,
|
|
983
|
+
L: 265,
|
|
984
|
+
S: this,
|
|
985
|
+
A: [
|
|
986
|
+
"this.isOpen",
|
|
987
|
+
"'AutomergeHost is not open'"
|
|
988
|
+
]
|
|
989
|
+
});
|
|
895
990
|
await this._echoNetworkAdapter.removeReplicator(replicator);
|
|
896
991
|
}
|
|
897
992
|
/**
|
|
898
993
|
* Loads the document handle from the repo and waits for it to be ready.
|
|
899
994
|
*/
|
|
900
995
|
async loadDoc(ctx, documentId, opts) {
|
|
996
|
+
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
997
|
+
F: __dxlog_file3,
|
|
998
|
+
L: 273,
|
|
999
|
+
S: this,
|
|
1000
|
+
A: [
|
|
1001
|
+
"this.isOpen",
|
|
1002
|
+
"'AutomergeHost is not open'"
|
|
1003
|
+
]
|
|
1004
|
+
});
|
|
901
1005
|
let handle;
|
|
902
1006
|
if (typeof documentId === "string") {
|
|
903
1007
|
handle = this._repo.handles[documentId];
|
|
@@ -915,6 +1019,15 @@ var AutomergeHost = class extends Resource3 {
|
|
|
915
1019
|
return handle;
|
|
916
1020
|
}
|
|
917
1021
|
async exportDoc(ctx, id) {
|
|
1022
|
+
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1023
|
+
F: __dxlog_file3,
|
|
1024
|
+
L: 296,
|
|
1025
|
+
S: this,
|
|
1026
|
+
A: [
|
|
1027
|
+
"this.isOpen",
|
|
1028
|
+
"'AutomergeHost is not open'"
|
|
1029
|
+
]
|
|
1030
|
+
});
|
|
918
1031
|
const documentId = interpretAsDocumentId(id);
|
|
919
1032
|
const chunks = await this._storage.loadRange([
|
|
920
1033
|
documentId
|
|
@@ -925,6 +1038,15 @@ var AutomergeHost = class extends Resource3 {
|
|
|
925
1038
|
* Create new persisted document.
|
|
926
1039
|
*/
|
|
927
1040
|
createDoc(initialValue, opts) {
|
|
1041
|
+
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1042
|
+
F: __dxlog_file3,
|
|
1043
|
+
L: 307,
|
|
1044
|
+
S: this,
|
|
1045
|
+
A: [
|
|
1046
|
+
"this.isOpen",
|
|
1047
|
+
"'AutomergeHost is not open'"
|
|
1048
|
+
]
|
|
1049
|
+
});
|
|
928
1050
|
if (opts?.preserveHistory) {
|
|
929
1051
|
if (initialValue instanceof Uint8Array) {
|
|
930
1052
|
return this._repo.import(initialValue);
|
|
@@ -941,6 +1063,15 @@ var AutomergeHost = class extends Resource3 {
|
|
|
941
1063
|
}
|
|
942
1064
|
}
|
|
943
1065
|
async waitUntilHeadsReplicated(heads) {
|
|
1066
|
+
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1067
|
+
F: __dxlog_file3,
|
|
1068
|
+
L: 329,
|
|
1069
|
+
S: this,
|
|
1070
|
+
A: [
|
|
1071
|
+
"this.isOpen",
|
|
1072
|
+
"'AutomergeHost is not open'"
|
|
1073
|
+
]
|
|
1074
|
+
});
|
|
944
1075
|
const entries = heads.entries;
|
|
945
1076
|
if (!entries?.length) {
|
|
946
1077
|
return;
|
|
@@ -959,7 +1090,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
959
1090
|
await Promise.all(headsToWait.map(async (entry, index) => {
|
|
960
1091
|
const handle = await this.loadDoc(Context.default(void 0, {
|
|
961
1092
|
F: __dxlog_file3,
|
|
962
|
-
L:
|
|
1093
|
+
L: 347
|
|
963
1094
|
}), entry.documentId);
|
|
964
1095
|
await waitForHeads(handle, entry.heads);
|
|
965
1096
|
}));
|
|
@@ -967,12 +1098,21 @@ var AutomergeHost = class extends Resource3 {
|
|
|
967
1098
|
await this._repo.flush(documentIds.filter((documentId) => this._repo.handles[documentId] && this._repo.handles[documentId].isReady()));
|
|
968
1099
|
}
|
|
969
1100
|
async reIndexHeads(documentIds) {
|
|
1101
|
+
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1102
|
+
F: __dxlog_file3,
|
|
1103
|
+
L: 360,
|
|
1104
|
+
S: this,
|
|
1105
|
+
A: [
|
|
1106
|
+
"this.isOpen",
|
|
1107
|
+
"'AutomergeHost is not open'"
|
|
1108
|
+
]
|
|
1109
|
+
});
|
|
970
1110
|
for (const documentId of documentIds) {
|
|
971
1111
|
log3("re-indexing heads for document", {
|
|
972
1112
|
documentId
|
|
973
1113
|
}, {
|
|
974
1114
|
F: __dxlog_file3,
|
|
975
|
-
L:
|
|
1115
|
+
L: 362,
|
|
976
1116
|
S: this,
|
|
977
1117
|
C: (f, a) => f(...a)
|
|
978
1118
|
});
|
|
@@ -982,7 +1122,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
982
1122
|
documentId
|
|
983
1123
|
}, {
|
|
984
1124
|
F: __dxlog_file3,
|
|
985
|
-
L:
|
|
1125
|
+
L: 365,
|
|
986
1126
|
S: this,
|
|
987
1127
|
C: (f, a) => f(...a)
|
|
988
1128
|
});
|
|
@@ -995,7 +1135,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
995
1135
|
}
|
|
996
1136
|
log3("done re-indexing heads", void 0, {
|
|
997
1137
|
F: __dxlog_file3,
|
|
998
|
-
L:
|
|
1138
|
+
L: 374,
|
|
999
1139
|
S: this,
|
|
1000
1140
|
C: (f, a) => f(...a)
|
|
1001
1141
|
});
|
|
@@ -1056,13 +1196,31 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1056
1196
|
* Called by AutomergeStorageAdapter after levelDB batch commit.
|
|
1057
1197
|
*/
|
|
1058
1198
|
async _afterSave(path) {
|
|
1199
|
+
if (!this.isOpen) {
|
|
1200
|
+
return void 0;
|
|
1201
|
+
}
|
|
1059
1202
|
this._indexMetadataStore.notifyMarkedDirty();
|
|
1060
1203
|
const documentId = path[0];
|
|
1061
|
-
const
|
|
1062
|
-
if (
|
|
1063
|
-
|
|
1064
|
-
|
|
1204
|
+
const handle = this._repo.handles[documentId];
|
|
1205
|
+
if (!handle || !handle.isReady()) {
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
1208
|
+
const document = handle.doc();
|
|
1209
|
+
if (!document) {
|
|
1210
|
+
return;
|
|
1065
1211
|
}
|
|
1212
|
+
const heads = getHeads(document);
|
|
1213
|
+
this._headsUpdates.set(documentId, heads);
|
|
1214
|
+
invariant2(this._onHeadsChangedTask, "onHeadsChangedTask is not initialized", {
|
|
1215
|
+
F: __dxlog_file3,
|
|
1216
|
+
L: 450,
|
|
1217
|
+
S: this,
|
|
1218
|
+
A: [
|
|
1219
|
+
"this._onHeadsChangedTask",
|
|
1220
|
+
"'onHeadsChangedTask is not initialized'"
|
|
1221
|
+
]
|
|
1222
|
+
});
|
|
1223
|
+
this._onHeadsChangedTask.schedule();
|
|
1066
1224
|
this.documentsSaved.emit();
|
|
1067
1225
|
}
|
|
1068
1226
|
_automergePeers() {
|
|
@@ -1155,8 +1313,17 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1155
1313
|
missingOnRemote: diff.missingOnRemote.length,
|
|
1156
1314
|
missingOnLocal: diff.missingOnLocal.length,
|
|
1157
1315
|
differentDocuments: diff.different.length,
|
|
1158
|
-
localDocumentCount: Object.
|
|
1159
|
-
remoteDocumentCount: Object.
|
|
1316
|
+
localDocumentCount: Object.entries(localState.documents).filter(([_, heads]) => heads.length > 0).length,
|
|
1317
|
+
remoteDocumentCount: Object.entries(state.documents).filter(([_, heads]) => heads.length > 0).length,
|
|
1318
|
+
totalDocumentCount: (/* @__PURE__ */ new Set([
|
|
1319
|
+
...Object.keys(localState.documents),
|
|
1320
|
+
...Object.keys(state.documents)
|
|
1321
|
+
])).size,
|
|
1322
|
+
unsyncedDocumentCount: (/* @__PURE__ */ new Set([
|
|
1323
|
+
...diff.missingOnLocal,
|
|
1324
|
+
...diff.missingOnRemote,
|
|
1325
|
+
...diff.different
|
|
1326
|
+
])).size
|
|
1160
1327
|
});
|
|
1161
1328
|
}
|
|
1162
1329
|
return result;
|
|
@@ -1173,6 +1340,14 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1173
1340
|
this._collectionSynchronizer.setLocalCollectionState(collectionId, {
|
|
1174
1341
|
documents
|
|
1175
1342
|
});
|
|
1343
|
+
const interestedPeers = this._echoNetworkAdapter.getPeersInterestedInCollection(collectionId);
|
|
1344
|
+
if (interestedPeers.length > 0) {
|
|
1345
|
+
for (const peerId of interestedPeers) {
|
|
1346
|
+
this._sendCollectionState(collectionId, peerId, {
|
|
1347
|
+
documents
|
|
1348
|
+
});
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1176
1351
|
}
|
|
1177
1352
|
async clearLocalCollectionState(collectionId) {
|
|
1178
1353
|
this._collectionSynchronizer.clearLocalCollectionState(collectionId);
|
|
@@ -1196,42 +1371,203 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1196
1371
|
this._collectionSynchronizer.onConnectionClosed(peerId);
|
|
1197
1372
|
}
|
|
1198
1373
|
_onRemoteCollectionStateUpdated(collectionId, peerId) {
|
|
1374
|
+
this._collectionsToSync.add({
|
|
1375
|
+
collectionId,
|
|
1376
|
+
peerId
|
|
1377
|
+
});
|
|
1378
|
+
this._syncTask?.schedule();
|
|
1379
|
+
}
|
|
1380
|
+
async _handleCollectionSync(collectionId, peerId) {
|
|
1199
1381
|
const localState = this._collectionSynchronizer.getLocalCollectionState(collectionId);
|
|
1200
1382
|
const remoteState = this._collectionSynchronizer.getRemoteCollectionStates(collectionId).get(peerId);
|
|
1201
1383
|
if (!localState || !remoteState) {
|
|
1202
1384
|
return;
|
|
1203
1385
|
}
|
|
1204
1386
|
const { different, missingOnLocal, missingOnRemote } = diffCollectionState(localState, remoteState);
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1387
|
+
if (different.length === 0 && missingOnLocal.length === 0 && missingOnRemote.length === 0) {
|
|
1388
|
+
return;
|
|
1389
|
+
}
|
|
1390
|
+
const toReplicateWithoutBatching = [
|
|
1208
1391
|
...different
|
|
1209
1392
|
];
|
|
1210
|
-
|
|
1393
|
+
const bundleSyncEnabled = this._echoNetworkAdapter.bundleSyncEnabledForPeer(peerId);
|
|
1394
|
+
if (bundleSyncEnabled && missingOnRemote.length >= BUNDLE_SYNC_THRESHOLD) {
|
|
1395
|
+
log3("pushing bundle", {
|
|
1396
|
+
amount: missingOnRemote.length
|
|
1397
|
+
}, {
|
|
1398
|
+
F: __dxlog_file3,
|
|
1399
|
+
L: 649,
|
|
1400
|
+
S: this,
|
|
1401
|
+
C: (f, a) => f(...a)
|
|
1402
|
+
});
|
|
1403
|
+
const { syncInteractively } = await this._pushInBundles(peerId, missingOnRemote);
|
|
1404
|
+
toReplicateWithoutBatching.push(...syncInteractively);
|
|
1405
|
+
} else {
|
|
1406
|
+
log3.verbose("failed to push bundle, replicating interactively", {
|
|
1407
|
+
collectionId,
|
|
1408
|
+
peerId,
|
|
1409
|
+
amount: missingOnRemote.length
|
|
1410
|
+
}, {
|
|
1411
|
+
F: __dxlog_file3,
|
|
1412
|
+
L: 653,
|
|
1413
|
+
S: this,
|
|
1414
|
+
C: (f, a) => f(...a)
|
|
1415
|
+
});
|
|
1416
|
+
toReplicateWithoutBatching.push(...missingOnRemote);
|
|
1417
|
+
}
|
|
1418
|
+
if (bundleSyncEnabled && missingOnLocal.length >= BUNDLE_SYNC_THRESHOLD) {
|
|
1419
|
+
log3("pulling bundle", {
|
|
1420
|
+
amount: missingOnLocal.length
|
|
1421
|
+
}, {
|
|
1422
|
+
F: __dxlog_file3,
|
|
1423
|
+
L: 661,
|
|
1424
|
+
S: this,
|
|
1425
|
+
C: (f, a) => f(...a)
|
|
1426
|
+
});
|
|
1427
|
+
const { syncInteractively } = await this._pullInBundles(peerId, missingOnLocal);
|
|
1428
|
+
toReplicateWithoutBatching.push(...syncInteractively);
|
|
1429
|
+
} else {
|
|
1430
|
+
log3.verbose("failed to pull bundle, replicating interactively", {
|
|
1431
|
+
collectionId,
|
|
1432
|
+
peerId,
|
|
1433
|
+
amount: missingOnLocal.length
|
|
1434
|
+
}, {
|
|
1435
|
+
F: __dxlog_file3,
|
|
1436
|
+
L: 665,
|
|
1437
|
+
S: this,
|
|
1438
|
+
C: (f, a) => f(...a)
|
|
1439
|
+
});
|
|
1440
|
+
toReplicateWithoutBatching.push(...missingOnLocal);
|
|
1441
|
+
}
|
|
1442
|
+
if (toReplicateWithoutBatching.length === 0) {
|
|
1211
1443
|
return;
|
|
1212
1444
|
}
|
|
1213
1445
|
log3("replicating documents after collection sync", {
|
|
1214
1446
|
collectionId,
|
|
1215
1447
|
peerId,
|
|
1216
|
-
|
|
1217
|
-
count:
|
|
1448
|
+
toReplicateWithoutBatching,
|
|
1449
|
+
count: toReplicateWithoutBatching.length
|
|
1218
1450
|
}, {
|
|
1219
1451
|
F: __dxlog_file3,
|
|
1220
|
-
L:
|
|
1452
|
+
L: 677,
|
|
1221
1453
|
S: this,
|
|
1222
1454
|
C: (f, a) => f(...a)
|
|
1223
1455
|
});
|
|
1224
|
-
for (const documentId of
|
|
1456
|
+
for (const documentId of toReplicateWithoutBatching) {
|
|
1225
1457
|
this._repo.findWithProgress(documentId);
|
|
1226
1458
|
}
|
|
1227
1459
|
}
|
|
1228
|
-
|
|
1460
|
+
// TODO(mykola): Add retries of batches https://gist.github.com/mykola-vrmchk/fde270259e9209fcbf1331e5abbf12cf
|
|
1461
|
+
// TODO(mykola): Use effect to retry batches.
|
|
1462
|
+
async _pushInBundles(peerId, documentIds) {
|
|
1463
|
+
const documentsToPush = [
|
|
1464
|
+
...documentIds
|
|
1465
|
+
];
|
|
1466
|
+
const syncInteractively = [];
|
|
1467
|
+
while (documentsToPush.length > 0) {
|
|
1468
|
+
await Promise.all(range(BUNDLE_SYNC_CONCURRENCY).map(async () => {
|
|
1469
|
+
const bundle = documentsToPush.splice(0, BUNDLE_SIZE);
|
|
1470
|
+
if (bundle.length === 0) {
|
|
1471
|
+
return;
|
|
1472
|
+
}
|
|
1473
|
+
await this._pushBundle(peerId, bundle).catch((err) => {
|
|
1474
|
+
log3.warn("failed to push bundle, replicating interactively", {
|
|
1475
|
+
peerId,
|
|
1476
|
+
bundle,
|
|
1477
|
+
err
|
|
1478
|
+
}, {
|
|
1479
|
+
F: __dxlog_file3,
|
|
1480
|
+
L: 708,
|
|
1481
|
+
S: this,
|
|
1482
|
+
C: (f, a) => f(...a)
|
|
1483
|
+
});
|
|
1484
|
+
syncInteractively.push(...bundle);
|
|
1485
|
+
});
|
|
1486
|
+
}));
|
|
1487
|
+
}
|
|
1488
|
+
return {
|
|
1489
|
+
syncInteractively
|
|
1490
|
+
};
|
|
1491
|
+
}
|
|
1492
|
+
async _pushBundle(peerId, documentIds) {
|
|
1493
|
+
if (this._ctx.disposed) {
|
|
1494
|
+
return;
|
|
1495
|
+
}
|
|
1496
|
+
const handles = documentIds.map((documentId) => this._repo.handles[documentId]);
|
|
1497
|
+
const bundle = exportBundle(this._repo, handles);
|
|
1498
|
+
await this._echoNetworkAdapter.pushBundle(peerId, Array.from(bundle.docs.entries()).map(([documentId, doc]) => ({
|
|
1499
|
+
documentId,
|
|
1500
|
+
data: doc.data,
|
|
1501
|
+
heads: doc.heads
|
|
1502
|
+
})));
|
|
1503
|
+
}
|
|
1504
|
+
async _pullInBundles(peerId, documentIds) {
|
|
1505
|
+
const documentsToPull = [
|
|
1506
|
+
...documentIds
|
|
1507
|
+
];
|
|
1508
|
+
const syncInteractively = [];
|
|
1509
|
+
const docsToImport = {};
|
|
1510
|
+
while (documentsToPull.length > 0) {
|
|
1511
|
+
await Promise.all(range(BUNDLE_SYNC_CONCURRENCY).map(async () => {
|
|
1512
|
+
const bundle = documentsToPull.splice(0, BUNDLE_SIZE);
|
|
1513
|
+
if (bundle.length === 0) {
|
|
1514
|
+
return;
|
|
1515
|
+
}
|
|
1516
|
+
const result = await this._pullBundle(peerId, bundle).catch((err) => {
|
|
1517
|
+
log3.warn("failed to pull bundle, replicating interactively", {
|
|
1518
|
+
peerId,
|
|
1519
|
+
bundle,
|
|
1520
|
+
err
|
|
1521
|
+
}, {
|
|
1522
|
+
F: __dxlog_file3,
|
|
1523
|
+
L: 752,
|
|
1524
|
+
S: this,
|
|
1525
|
+
C: (f, a) => f(...a)
|
|
1526
|
+
});
|
|
1527
|
+
syncInteractively.push(...bundle);
|
|
1528
|
+
});
|
|
1529
|
+
if (result) {
|
|
1530
|
+
Object.assign(docsToImport, result.docsToImport);
|
|
1531
|
+
}
|
|
1532
|
+
}));
|
|
1533
|
+
}
|
|
1534
|
+
for (const [documentId, data] of Object.entries(docsToImport)) {
|
|
1535
|
+
this._repo.import(data, {
|
|
1536
|
+
docId: documentId
|
|
1537
|
+
});
|
|
1538
|
+
}
|
|
1539
|
+
await this._repo.flush(Object.keys(docsToImport));
|
|
1540
|
+
return {
|
|
1541
|
+
syncInteractively
|
|
1542
|
+
};
|
|
1543
|
+
}
|
|
1544
|
+
async _pullBundle(peerId, documentIds) {
|
|
1545
|
+
if (this._ctx.disposed) {
|
|
1546
|
+
return;
|
|
1547
|
+
}
|
|
1548
|
+
const docHeads = Object.fromEntries(documentIds.map((documentId) => [
|
|
1549
|
+
documentId,
|
|
1550
|
+
[]
|
|
1551
|
+
]));
|
|
1552
|
+
const bundle = await this._echoNetworkAdapter.pullBundle(peerId, docHeads);
|
|
1553
|
+
return {
|
|
1554
|
+
docsToImport: bundle
|
|
1555
|
+
};
|
|
1556
|
+
}
|
|
1557
|
+
_onHeadsChanged(docHeads) {
|
|
1229
1558
|
const collectionsChanged = /* @__PURE__ */ new Set();
|
|
1230
1559
|
for (const collectionId of this._collectionSynchronizer.getRegisteredCollectionIds()) {
|
|
1231
1560
|
const state = this._collectionSynchronizer.getLocalCollectionState(collectionId);
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1561
|
+
let newState;
|
|
1562
|
+
for (const [documentId, heads] of docHeads) {
|
|
1563
|
+
if (state?.documents[documentId]) {
|
|
1564
|
+
if (!newState) {
|
|
1565
|
+
newState = structuredClone(state);
|
|
1566
|
+
}
|
|
1567
|
+
newState.documents[documentId] = heads;
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
if (newState) {
|
|
1235
1571
|
this._collectionSynchronizer.setLocalCollectionState(collectionId, newState);
|
|
1236
1572
|
collectionsChanged.add(collectionId);
|
|
1237
1573
|
}
|
|
@@ -1242,16 +1578,51 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1242
1578
|
});
|
|
1243
1579
|
}
|
|
1244
1580
|
}
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1581
|
+
constructor({ db, indexMetadataStore, dataMonitor, peerIdProvider, getSpaceKeyByRootDocumentId }) {
|
|
1582
|
+
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({
|
|
1583
|
+
queryCollectionState: this._queryCollectionState.bind(this),
|
|
1584
|
+
sendCollectionState: this._sendCollectionState.bind(this),
|
|
1585
|
+
shouldSyncCollection: this._shouldSyncCollection.bind(this)
|
|
1586
|
+
})), _define_property5(this, "_repo", void 0), _define_property5(this, "_storage", void 0), _define_property5(this, "_headsStore", void 0), _define_property5(this, "_syncTask", void 0), /**
|
|
1587
|
+
* Cache of collections that would be synced on next sync task run.
|
|
1588
|
+
*/
|
|
1589
|
+
_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()), /**
|
|
1590
|
+
* Fired after a batch of documents was saved to disk.
|
|
1591
|
+
*/
|
|
1592
|
+
_define_property5(this, "documentsSaved", new Event2()), _define_property5(this, "_headsUpdates", /* @__PURE__ */ new Map()), _define_property5(this, "_onHeadsChangedTask", void 0);
|
|
1593
|
+
this._db = db;
|
|
1594
|
+
this._storage = new LevelDBStorageAdapter({
|
|
1595
|
+
db: db.sublevel("automerge"),
|
|
1596
|
+
callbacks: {
|
|
1597
|
+
beforeSave: async (params) => this._beforeSave(params),
|
|
1598
|
+
afterSave: async (key) => this._afterSave(key)
|
|
1599
|
+
},
|
|
1600
|
+
monitor: dataMonitor
|
|
1601
|
+
});
|
|
1602
|
+
this._echoNetworkAdapter = new EchoNetworkAdapter({
|
|
1603
|
+
getContainingSpaceForDocument: this._getContainingSpaceForDocument.bind(this),
|
|
1604
|
+
isDocumentInRemoteCollection: this._isDocumentInRemoteCollection.bind(this),
|
|
1605
|
+
onCollectionStateQueried: this._onCollectionStateQueried.bind(this),
|
|
1606
|
+
onCollectionStateReceived: this._onCollectionStateReceived.bind(this),
|
|
1607
|
+
monitor: dataMonitor
|
|
1608
|
+
});
|
|
1609
|
+
this._headsStore = new HeadsStore({
|
|
1610
|
+
db: db.sublevel("heads")
|
|
1611
|
+
});
|
|
1612
|
+
this._indexMetadataStore = indexMetadataStore;
|
|
1613
|
+
this._peerIdProvider = peerIdProvider;
|
|
1614
|
+
this._getSpaceKeyByRootDocumentId = getSpaceKeyByRootDocumentId;
|
|
1615
|
+
}
|
|
1616
|
+
};
|
|
1617
|
+
_ts_decorate3([
|
|
1618
|
+
trace2.info()
|
|
1619
|
+
], AutomergeHost.prototype, "_peerId", void 0);
|
|
1620
|
+
_ts_decorate3([
|
|
1621
|
+
trace2.info({
|
|
1622
|
+
depth: null
|
|
1623
|
+
})
|
|
1624
|
+
], AutomergeHost.prototype, "_automergePeers", null);
|
|
1625
|
+
_ts_decorate3([
|
|
1255
1626
|
trace2.span({
|
|
1256
1627
|
showInBrowserTimeline: true
|
|
1257
1628
|
})
|
|
@@ -1277,7 +1648,7 @@ var changeIsPresentInDoc = (doc, changeHash) => {
|
|
|
1277
1648
|
var decodeCollectionState = (state) => {
|
|
1278
1649
|
invariant2(typeof state === "object" && state !== null, "Invalid state", {
|
|
1279
1650
|
F: __dxlog_file3,
|
|
1280
|
-
L:
|
|
1651
|
+
L: 832,
|
|
1281
1652
|
S: void 0,
|
|
1282
1653
|
A: [
|
|
1283
1654
|
"typeof state === 'object' && state !== null",
|
|
@@ -1290,24 +1661,88 @@ var encodeCollectionState = (state) => {
|
|
|
1290
1661
|
return state;
|
|
1291
1662
|
};
|
|
1292
1663
|
|
|
1293
|
-
//
|
|
1664
|
+
// src/automerge/mesh-echo-replicator.ts
|
|
1294
1665
|
import { invariant as invariant5 } from "@dxos/invariant";
|
|
1295
1666
|
import { PublicKey as PublicKey2 } from "@dxos/keys";
|
|
1296
1667
|
import { log as log5 } from "@dxos/log";
|
|
1297
|
-
import { ComplexSet, defaultMap as defaultMap2 } from "@dxos/util";
|
|
1668
|
+
import { ComplexSet as ComplexSet2, defaultMap as defaultMap2 } from "@dxos/util";
|
|
1298
1669
|
|
|
1299
|
-
//
|
|
1670
|
+
// src/automerge/mesh-echo-replicator-connection.ts
|
|
1300
1671
|
import * as A from "@automerge/automerge";
|
|
1301
1672
|
import { cbor } from "@automerge/automerge-repo";
|
|
1302
1673
|
import { Resource as Resource4 } from "@dxos/context";
|
|
1303
1674
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1304
1675
|
import { log as log4 } from "@dxos/log";
|
|
1305
1676
|
import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
|
|
1306
|
-
|
|
1677
|
+
function _define_property6(obj, key, value) {
|
|
1678
|
+
if (key in obj) {
|
|
1679
|
+
Object.defineProperty(obj, key, {
|
|
1680
|
+
value,
|
|
1681
|
+
enumerable: true,
|
|
1682
|
+
configurable: true,
|
|
1683
|
+
writable: true
|
|
1684
|
+
});
|
|
1685
|
+
} else {
|
|
1686
|
+
obj[key] = value;
|
|
1687
|
+
}
|
|
1688
|
+
return obj;
|
|
1689
|
+
}
|
|
1690
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator-connection.ts";
|
|
1307
1691
|
var DEFAULT_FACTORY = (params) => new AutomergeReplicator(...params);
|
|
1308
1692
|
var MeshReplicatorConnection = class extends Resource4 {
|
|
1693
|
+
_disconnectIfEnabled() {
|
|
1694
|
+
if (this._isEnabled) {
|
|
1695
|
+
this._params.onRemoteDisconnected();
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
get peerId() {
|
|
1699
|
+
invariant3(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1700
|
+
F: __dxlog_file4,
|
|
1701
|
+
L: 106,
|
|
1702
|
+
S: this,
|
|
1703
|
+
A: [
|
|
1704
|
+
"this._remotePeerId != null",
|
|
1705
|
+
"'Remote peer has not connected yet.'"
|
|
1706
|
+
]
|
|
1707
|
+
});
|
|
1708
|
+
return this._remotePeerId;
|
|
1709
|
+
}
|
|
1710
|
+
get isEnabled() {
|
|
1711
|
+
return this._isEnabled;
|
|
1712
|
+
}
|
|
1713
|
+
get bundleSyncEnabled() {
|
|
1714
|
+
return false;
|
|
1715
|
+
}
|
|
1716
|
+
async shouldAdvertise(params) {
|
|
1717
|
+
return this._params.shouldAdvertise(params);
|
|
1718
|
+
}
|
|
1719
|
+
shouldSyncCollection(params) {
|
|
1720
|
+
return this._params.shouldSyncCollection(params);
|
|
1721
|
+
}
|
|
1722
|
+
/**
|
|
1723
|
+
* Start exchanging messages with the remote peer.
|
|
1724
|
+
* Call after the remote peer has connected.
|
|
1725
|
+
*/
|
|
1726
|
+
enable() {
|
|
1727
|
+
invariant3(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1728
|
+
F: __dxlog_file4,
|
|
1729
|
+
L: 131,
|
|
1730
|
+
S: this,
|
|
1731
|
+
A: [
|
|
1732
|
+
"this._remotePeerId != null",
|
|
1733
|
+
"'Remote peer has not connected yet.'"
|
|
1734
|
+
]
|
|
1735
|
+
});
|
|
1736
|
+
this._isEnabled = true;
|
|
1737
|
+
}
|
|
1738
|
+
/**
|
|
1739
|
+
* Stop exchanging messages with the remote peer.
|
|
1740
|
+
*/
|
|
1741
|
+
disable() {
|
|
1742
|
+
this._isEnabled = false;
|
|
1743
|
+
}
|
|
1309
1744
|
constructor(_params) {
|
|
1310
|
-
super(), this._params = _params, this.remoteDeviceKey = null, this._remotePeerId = null, this._isEnabled = false;
|
|
1745
|
+
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
1746
|
let readableStreamController;
|
|
1312
1747
|
this.readable = new ReadableStream({
|
|
1313
1748
|
start: (controller) => {
|
|
@@ -1371,54 +1806,6 @@ var MeshReplicatorConnection = class extends Resource4 {
|
|
|
1371
1806
|
}
|
|
1372
1807
|
]);
|
|
1373
1808
|
}
|
|
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
1809
|
};
|
|
1423
1810
|
var logSendSync = (message) => {
|
|
1424
1811
|
log4("sendSyncMessage", () => {
|
|
@@ -1435,16 +1822,16 @@ var logSendSync = (message) => {
|
|
|
1435
1822
|
};
|
|
1436
1823
|
}, {
|
|
1437
1824
|
F: __dxlog_file4,
|
|
1438
|
-
L:
|
|
1825
|
+
L: 144,
|
|
1439
1826
|
S: void 0,
|
|
1440
1827
|
C: (f, a) => f(...a)
|
|
1441
1828
|
});
|
|
1442
1829
|
};
|
|
1443
1830
|
|
|
1444
|
-
//
|
|
1831
|
+
// src/automerge/space-collection.ts
|
|
1445
1832
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
1446
1833
|
import { SpaceId } from "@dxos/keys";
|
|
1447
|
-
var __dxlog_file5 = "/
|
|
1834
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/space-collection.ts";
|
|
1448
1835
|
var deriveCollectionIdFromSpaceId = (spaceId, rootDocumentId) => rootDocumentId ? `space:${spaceId}:${rootDocumentId}` : `space:${spaceId}`;
|
|
1449
1836
|
var getSpaceIdFromCollectionId = (collectionId) => {
|
|
1450
1837
|
const spaceId = collectionId.split(":")[1];
|
|
@@ -1460,27 +1847,22 @@ var getSpaceIdFromCollectionId = (collectionId) => {
|
|
|
1460
1847
|
return spaceId;
|
|
1461
1848
|
};
|
|
1462
1849
|
|
|
1463
|
-
//
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
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;
|
|
1850
|
+
// src/automerge/mesh-echo-replicator.ts
|
|
1851
|
+
function _define_property7(obj, key, value) {
|
|
1852
|
+
if (key in obj) {
|
|
1853
|
+
Object.defineProperty(obj, key, {
|
|
1854
|
+
value,
|
|
1855
|
+
enumerable: true,
|
|
1856
|
+
configurable: true,
|
|
1857
|
+
writable: true
|
|
1858
|
+
});
|
|
1859
|
+
} else {
|
|
1860
|
+
obj[key] = value;
|
|
1483
1861
|
}
|
|
1862
|
+
return obj;
|
|
1863
|
+
}
|
|
1864
|
+
var __dxlog_file6 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts";
|
|
1865
|
+
var MeshEchoReplicator = class {
|
|
1484
1866
|
async connect(context) {
|
|
1485
1867
|
this._context = context;
|
|
1486
1868
|
}
|
|
@@ -1500,7 +1882,7 @@ var MeshEchoReplicator = class {
|
|
|
1500
1882
|
createExtension(extensionFactory) {
|
|
1501
1883
|
invariant5(this._context, void 0, {
|
|
1502
1884
|
F: __dxlog_file6,
|
|
1503
|
-
L:
|
|
1885
|
+
L: 68,
|
|
1504
1886
|
S: this,
|
|
1505
1887
|
A: [
|
|
1506
1888
|
"this._context",
|
|
@@ -1515,13 +1897,13 @@ var MeshEchoReplicator = class {
|
|
|
1515
1897
|
peerId: connection.peerId
|
|
1516
1898
|
}, {
|
|
1517
1899
|
F: __dxlog_file6,
|
|
1518
|
-
L:
|
|
1900
|
+
L: 74,
|
|
1519
1901
|
S: this,
|
|
1520
1902
|
C: (f, a) => f(...a)
|
|
1521
1903
|
});
|
|
1522
1904
|
invariant5(this._context, void 0, {
|
|
1523
1905
|
F: __dxlog_file6,
|
|
1524
|
-
L:
|
|
1906
|
+
L: 75,
|
|
1525
1907
|
S: this,
|
|
1526
1908
|
A: [
|
|
1527
1909
|
"this._context",
|
|
@@ -1546,7 +1928,7 @@ var MeshEchoReplicator = class {
|
|
|
1546
1928
|
peerId: connection.peerId
|
|
1547
1929
|
}, {
|
|
1548
1930
|
F: __dxlog_file6,
|
|
1549
|
-
L:
|
|
1931
|
+
L: 89,
|
|
1550
1932
|
S: this,
|
|
1551
1933
|
C: (f, a) => f(...a)
|
|
1552
1934
|
});
|
|
@@ -1558,7 +1940,7 @@ var MeshEchoReplicator = class {
|
|
|
1558
1940
|
peerId: connection.peerId
|
|
1559
1941
|
}, {
|
|
1560
1942
|
F: __dxlog_file6,
|
|
1561
|
-
L:
|
|
1943
|
+
L: 97,
|
|
1562
1944
|
S: this,
|
|
1563
1945
|
C: (f, a) => f(...a)
|
|
1564
1946
|
});
|
|
@@ -1580,13 +1962,13 @@ var MeshEchoReplicator = class {
|
|
|
1580
1962
|
documentId: params.documentId
|
|
1581
1963
|
}, {
|
|
1582
1964
|
F: __dxlog_file6,
|
|
1583
|
-
L:
|
|
1965
|
+
L: 115,
|
|
1584
1966
|
S: this,
|
|
1585
1967
|
C: (f, a) => f(...a)
|
|
1586
1968
|
});
|
|
1587
1969
|
invariant5(this._context, void 0, {
|
|
1588
1970
|
F: __dxlog_file6,
|
|
1589
|
-
L:
|
|
1971
|
+
L: 116,
|
|
1590
1972
|
S: this,
|
|
1591
1973
|
A: [
|
|
1592
1974
|
"this._context",
|
|
@@ -1606,7 +1988,7 @@ var MeshEchoReplicator = class {
|
|
|
1606
1988
|
acceptDocument: remoteDocumentExists
|
|
1607
1989
|
}, {
|
|
1608
1990
|
F: __dxlog_file6,
|
|
1609
|
-
L:
|
|
1991
|
+
L: 124,
|
|
1610
1992
|
S: this,
|
|
1611
1993
|
C: (f, a) => f(...a)
|
|
1612
1994
|
});
|
|
@@ -1620,7 +2002,7 @@ var MeshEchoReplicator = class {
|
|
|
1620
2002
|
documentId: params.documentId
|
|
1621
2003
|
}, {
|
|
1622
2004
|
F: __dxlog_file6,
|
|
1623
|
-
L:
|
|
2005
|
+
L: 141,
|
|
1624
2006
|
S: this,
|
|
1625
2007
|
C: (f, a) => f(...a)
|
|
1626
2008
|
});
|
|
@@ -1636,7 +2018,7 @@ var MeshEchoReplicator = class {
|
|
|
1636
2018
|
isAuthorized
|
|
1637
2019
|
}, {
|
|
1638
2020
|
F: __dxlog_file6,
|
|
1639
|
-
L:
|
|
2021
|
+
L: 149,
|
|
1640
2022
|
S: this,
|
|
1641
2023
|
C: (f, a) => f(...a)
|
|
1642
2024
|
});
|
|
@@ -1644,7 +2026,7 @@ var MeshEchoReplicator = class {
|
|
|
1644
2026
|
} catch (err) {
|
|
1645
2027
|
log5.catch(err, void 0, {
|
|
1646
2028
|
F: __dxlog_file6,
|
|
1647
|
-
L:
|
|
2029
|
+
L: 159,
|
|
1648
2030
|
S: this,
|
|
1649
2031
|
C: (f, a) => f(...a)
|
|
1650
2032
|
});
|
|
@@ -1660,7 +2042,7 @@ var MeshEchoReplicator = class {
|
|
|
1660
2042
|
collectionId
|
|
1661
2043
|
}, {
|
|
1662
2044
|
F: __dxlog_file6,
|
|
1663
|
-
L:
|
|
2045
|
+
L: 169,
|
|
1664
2046
|
S: this,
|
|
1665
2047
|
C: (f, a) => f(...a)
|
|
1666
2048
|
});
|
|
@@ -1679,12 +2061,12 @@ var MeshEchoReplicator = class {
|
|
|
1679
2061
|
deviceKey
|
|
1680
2062
|
}, {
|
|
1681
2063
|
F: __dxlog_file6,
|
|
1682
|
-
L:
|
|
2064
|
+
L: 186,
|
|
1683
2065
|
S: this,
|
|
1684
2066
|
C: (f, a) => f(...a)
|
|
1685
2067
|
});
|
|
1686
2068
|
const spaceId = await createIdFromSpaceKey(spaceKey);
|
|
1687
|
-
defaultMap2(this._authorizedDevices, spaceId, () => new
|
|
2069
|
+
defaultMap2(this._authorizedDevices, spaceId, () => new ComplexSet2(PublicKey2.hash)).add(deviceKey);
|
|
1688
2070
|
for (const connection of this._connections) {
|
|
1689
2071
|
if (connection.isEnabled && connection.remoteDeviceKey && connection.remoteDeviceKey.equals(deviceKey)) {
|
|
1690
2072
|
if (this._connectionsPerPeer.has(connection.peerId)) {
|
|
@@ -1693,11 +2075,30 @@ var MeshEchoReplicator = class {
|
|
|
1693
2075
|
}
|
|
1694
2076
|
}
|
|
1695
2077
|
}
|
|
2078
|
+
constructor() {
|
|
2079
|
+
_define_property7(this, "_connectionsPerPeer", /* @__PURE__ */ new Map());
|
|
2080
|
+
_define_property7(this, "_connections", /* @__PURE__ */ new Set());
|
|
2081
|
+
_define_property7(this, "_authorizedDevices", /* @__PURE__ */ new Map());
|
|
2082
|
+
_define_property7(this, "_context", null);
|
|
2083
|
+
}
|
|
1696
2084
|
};
|
|
1697
2085
|
|
|
1698
|
-
//
|
|
2086
|
+
// src/automerge/echo-data-monitor.ts
|
|
1699
2087
|
import { trace as trace3 } from "@dxos/tracing";
|
|
1700
|
-
import { CircularBuffer,
|
|
2088
|
+
import { CircularBuffer, SlidingWindowSummary, mapValues } from "@dxos/util";
|
|
2089
|
+
function _define_property8(obj, key, value) {
|
|
2090
|
+
if (key in obj) {
|
|
2091
|
+
Object.defineProperty(obj, key, {
|
|
2092
|
+
value,
|
|
2093
|
+
enumerable: true,
|
|
2094
|
+
configurable: true,
|
|
2095
|
+
writable: true
|
|
2096
|
+
});
|
|
2097
|
+
} else {
|
|
2098
|
+
obj[key] = value;
|
|
2099
|
+
}
|
|
2100
|
+
return obj;
|
|
2101
|
+
}
|
|
1701
2102
|
function _ts_decorate4(decorators, target, key, desc) {
|
|
1702
2103
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1703
2104
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1707,20 +2108,6 @@ function _ts_decorate4(decorators, target, key, desc) {
|
|
|
1707
2108
|
var PER_SECOND_RATE_AVG_WINDOW_SIZE = 5;
|
|
1708
2109
|
var DEFAULT_AVG_WINDOW_SIZE = 25;
|
|
1709
2110
|
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
2111
|
tick(timeMs) {
|
|
1725
2112
|
this._advanceTimeWindow(timeMs - this._lastTick);
|
|
1726
2113
|
this._lastTick = timeMs;
|
|
@@ -1960,8 +2347,9 @@ var EchoDataMonitor = class {
|
|
|
1960
2347
|
messageCounts.failed++;
|
|
1961
2348
|
}
|
|
1962
2349
|
_getStatsForType(message) {
|
|
1963
|
-
|
|
1964
|
-
const
|
|
2350
|
+
var _this__sizeByMessage, _message_type, _this__activeCounters_byType, _message_type1;
|
|
2351
|
+
const messageSize = (_this__sizeByMessage = this._sizeByMessage)[_message_type = message.type] ?? (_this__sizeByMessage[_message_type] = createSlidingWindow());
|
|
2352
|
+
const messageCounts = (_this__activeCounters_byType = this._activeCounters.byType)[_message_type1 = message.type] ?? (_this__activeCounters_byType[_message_type1] = createMessageCounter());
|
|
1965
2353
|
return {
|
|
1966
2354
|
messageCounts,
|
|
1967
2355
|
messageSize
|
|
@@ -1970,21 +2358,48 @@ var EchoDataMonitor = class {
|
|
|
1970
2358
|
_computeMessageHistogram(groupKey) {
|
|
1971
2359
|
const result = {};
|
|
1972
2360
|
for (const receivedMessage of this._lastReceivedMessages) {
|
|
1973
|
-
|
|
2361
|
+
var _result, _receivedMessage_groupKey;
|
|
2362
|
+
const counters = (_result = result)[_receivedMessage_groupKey = receivedMessage[groupKey]] ?? (_result[_receivedMessage_groupKey] = {
|
|
1974
2363
|
received: 0,
|
|
1975
2364
|
sent: 0
|
|
1976
|
-
};
|
|
2365
|
+
});
|
|
1977
2366
|
counters.received++;
|
|
1978
2367
|
}
|
|
1979
2368
|
for (const receivedMessage of this._lastSentMessages) {
|
|
1980
|
-
|
|
2369
|
+
var _result1, _receivedMessage_groupKey1;
|
|
2370
|
+
const counters = (_result1 = result)[_receivedMessage_groupKey1 = receivedMessage[groupKey]] ?? (_result1[_receivedMessage_groupKey1] = {
|
|
1981
2371
|
received: 0,
|
|
1982
2372
|
sent: 0
|
|
1983
|
-
};
|
|
2373
|
+
});
|
|
1984
2374
|
counters.sent++;
|
|
1985
2375
|
}
|
|
1986
2376
|
return result;
|
|
1987
2377
|
}
|
|
2378
|
+
constructor(_params = {
|
|
2379
|
+
timeSeriesLength: 30
|
|
2380
|
+
}) {
|
|
2381
|
+
_define_property8(this, "_params", void 0);
|
|
2382
|
+
_define_property8(this, "_lastTick", void 0);
|
|
2383
|
+
_define_property8(this, "_activeCounters", void 0);
|
|
2384
|
+
_define_property8(this, "_lastCompleteCounters", void 0);
|
|
2385
|
+
_define_property8(this, "_localTimeSeries", void 0);
|
|
2386
|
+
_define_property8(this, "_storageAverages", void 0);
|
|
2387
|
+
_define_property8(this, "_replicationAverages", void 0);
|
|
2388
|
+
_define_property8(this, "_sizeByMessage", void 0);
|
|
2389
|
+
_define_property8(this, "_lastReceivedMessages", void 0);
|
|
2390
|
+
_define_property8(this, "_lastSentMessages", void 0);
|
|
2391
|
+
_define_property8(this, "_connectionsCount", void 0);
|
|
2392
|
+
this._params = _params;
|
|
2393
|
+
this._lastTick = 0;
|
|
2394
|
+
this._activeCounters = createLocalCounters();
|
|
2395
|
+
this._localTimeSeries = createLocalTimeSeries();
|
|
2396
|
+
this._storageAverages = createStorageAverages();
|
|
2397
|
+
this._replicationAverages = createNetworkAverages();
|
|
2398
|
+
this._sizeByMessage = {};
|
|
2399
|
+
this._lastReceivedMessages = new CircularBuffer(100);
|
|
2400
|
+
this._lastSentMessages = new CircularBuffer(100);
|
|
2401
|
+
this._connectionsCount = 0;
|
|
2402
|
+
}
|
|
1988
2403
|
};
|
|
1989
2404
|
EchoDataMonitor = _ts_decorate4([
|
|
1990
2405
|
trace3.resource()
|
|
@@ -2056,20 +2471,37 @@ var getByteCount = (message) => {
|
|
|
2056
2471
|
return message.type.length + message.senderId.length + message.targetId.length + (message.data?.byteLength ?? 0) + (message.documentId?.length ?? 0);
|
|
2057
2472
|
};
|
|
2058
2473
|
|
|
2059
|
-
//
|
|
2060
|
-
|
|
2474
|
+
// src/db-host/documents-synchronizer.ts
|
|
2475
|
+
import { next as A2 } from "@automerge/automerge";
|
|
2476
|
+
import { UpdateScheduler, sleep } from "@dxos/async";
|
|
2477
|
+
import { LifecycleState as LifecycleState2, Resource as Resource5, cancelWithContext as cancelWithContext2 } from "@dxos/context";
|
|
2478
|
+
import { invariant as invariant6 } from "@dxos/invariant";
|
|
2479
|
+
import { log as log6 } from "@dxos/log";
|
|
2480
|
+
function _define_property9(obj, key, value) {
|
|
2481
|
+
if (key in obj) {
|
|
2482
|
+
Object.defineProperty(obj, key, {
|
|
2483
|
+
value,
|
|
2484
|
+
enumerable: true,
|
|
2485
|
+
configurable: true,
|
|
2486
|
+
writable: true
|
|
2487
|
+
});
|
|
2488
|
+
} else {
|
|
2489
|
+
obj[key] = value;
|
|
2490
|
+
}
|
|
2491
|
+
return obj;
|
|
2492
|
+
}
|
|
2493
|
+
var __dxlog_file7 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/documents-synchronizer.ts";
|
|
2061
2494
|
var MAX_UPDATE_FREQ = 10;
|
|
2495
|
+
var WRAP_AROUND_RETRY_LIMIT = 3;
|
|
2496
|
+
var WRAP_AROUND_RETRY_INITIAL_DELAY = 100;
|
|
2062
2497
|
var DocumentsSynchronizer = class extends Resource5 {
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
}
|
|
2066
|
-
addDocuments(documentIds, retryCounter = 0) {
|
|
2067
|
-
if (retryCounter > 3) {
|
|
2498
|
+
addDocuments(documentIds, retryCounter = 0, wrapAroundRetryDelay = WRAP_AROUND_RETRY_INITIAL_DELAY) {
|
|
2499
|
+
if (retryCounter > WRAP_AROUND_RETRY_LIMIT) {
|
|
2068
2500
|
log6.warn("Failed to load document, retry limit reached", {
|
|
2069
2501
|
documentIds
|
|
2070
2502
|
}, {
|
|
2071
2503
|
F: __dxlog_file7,
|
|
2072
|
-
L:
|
|
2504
|
+
L: 57,
|
|
2073
2505
|
S: this,
|
|
2074
2506
|
C: (f, a) => f(...a)
|
|
2075
2507
|
});
|
|
@@ -2087,13 +2519,13 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2087
2519
|
error
|
|
2088
2520
|
}, {
|
|
2089
2521
|
F: __dxlog_file7,
|
|
2090
|
-
L:
|
|
2522
|
+
L: 71,
|
|
2091
2523
|
S: this,
|
|
2092
2524
|
C: (f, a) => f(...a)
|
|
2093
2525
|
});
|
|
2094
|
-
this.addDocuments([
|
|
2526
|
+
void cancelWithContext2(this._ctx, sleep(wrapAroundRetryDelay)).then(() => this.addDocuments([
|
|
2095
2527
|
documentId
|
|
2096
|
-
], retryCounter + 1);
|
|
2528
|
+
], retryCounter + 1, wrapAroundRetryDelay * 2));
|
|
2097
2529
|
});
|
|
2098
2530
|
}
|
|
2099
2531
|
}
|
|
@@ -2115,14 +2547,9 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2115
2547
|
}
|
|
2116
2548
|
async update(updates) {
|
|
2117
2549
|
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
|
-
}
|
|
2550
|
+
this._writeMutation(documentId, mutation, isNew);
|
|
2125
2551
|
}
|
|
2552
|
+
await this._params.repo.flush(updates.map(({ documentId }) => documentId));
|
|
2126
2553
|
}
|
|
2127
2554
|
_startSync(doc) {
|
|
2128
2555
|
if (this._syncStates.has(doc.documentId)) {
|
|
@@ -2130,7 +2557,7 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2130
2557
|
documentId: doc.documentId
|
|
2131
2558
|
}, {
|
|
2132
2559
|
F: __dxlog_file7,
|
|
2133
|
-
L:
|
|
2560
|
+
L: 108,
|
|
2134
2561
|
S: this,
|
|
2135
2562
|
C: (f, a) => f(...a)
|
|
2136
2563
|
});
|
|
@@ -2141,6 +2568,7 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2141
2568
|
};
|
|
2142
2569
|
this._subscribeForChanges(syncState);
|
|
2143
2570
|
this._syncStates.set(doc.documentId, syncState);
|
|
2571
|
+
return syncState;
|
|
2144
2572
|
}
|
|
2145
2573
|
_subscribeForChanges(syncState) {
|
|
2146
2574
|
const handler = () => {
|
|
@@ -2173,7 +2601,7 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2173
2601
|
const syncState = this._syncStates.get(documentId);
|
|
2174
2602
|
invariant6(syncState, "Sync state for document not found", {
|
|
2175
2603
|
F: __dxlog_file7,
|
|
2176
|
-
L:
|
|
2604
|
+
L: 150,
|
|
2177
2605
|
S: this,
|
|
2178
2606
|
A: [
|
|
2179
2607
|
"syncState",
|
|
@@ -2192,41 +2620,64 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2192
2620
|
syncState.lastSentHead = A2.getHeads(doc);
|
|
2193
2621
|
return mutation;
|
|
2194
2622
|
}
|
|
2195
|
-
_writeMutation(documentId, mutation) {
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
}
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2623
|
+
_writeMutation(documentId, mutation, isNew) {
|
|
2624
|
+
if (this._lifecycleState === LifecycleState2.CLOSED) {
|
|
2625
|
+
return;
|
|
2626
|
+
}
|
|
2627
|
+
if (isNew) {
|
|
2628
|
+
const newHandle = this._params.repo.import(mutation, {
|
|
2629
|
+
docId: documentId
|
|
2630
|
+
});
|
|
2631
|
+
const syncState = this._startSync(newHandle);
|
|
2632
|
+
syncState.lastSentHead = A2.getHeads(newHandle.doc());
|
|
2633
|
+
} else {
|
|
2634
|
+
const syncState = this._syncStates.get(documentId);
|
|
2635
|
+
invariant6(syncState, "Sync state for document not found", {
|
|
2636
|
+
F: __dxlog_file7,
|
|
2637
|
+
L: 174,
|
|
2638
|
+
S: this,
|
|
2639
|
+
A: [
|
|
2640
|
+
"syncState",
|
|
2641
|
+
"'Sync state for document not found'"
|
|
2642
|
+
]
|
|
2643
|
+
});
|
|
2644
|
+
const headsBefore = A2.getHeads(syncState.handle.doc());
|
|
2645
|
+
this._params.repo.import(mutation, {
|
|
2646
|
+
docId: documentId
|
|
2647
|
+
});
|
|
2209
2648
|
if (A2.equals(headsBefore, syncState.lastSentHead)) {
|
|
2210
|
-
syncState.lastSentHead = A2.getHeads(
|
|
2649
|
+
syncState.lastSentHead = A2.getHeads(syncState.handle.doc());
|
|
2211
2650
|
}
|
|
2212
|
-
|
|
2213
|
-
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
constructor(_params) {
|
|
2654
|
+
super(), _define_property9(this, "_params", void 0), _define_property9(this, "_syncStates", void 0), /**
|
|
2655
|
+
* Documents that have pending updates.
|
|
2656
|
+
* Used to batch updates.
|
|
2657
|
+
*/
|
|
2658
|
+
_define_property9(this, "_pendingUpdates", void 0), /**
|
|
2659
|
+
* Job that schedules if there are pending updates.
|
|
2660
|
+
*/
|
|
2661
|
+
_define_property9(this, "_sendUpdatesJob", void 0), this._params = _params, this._syncStates = /* @__PURE__ */ new Map(), this._pendingUpdates = /* @__PURE__ */ new Set(), this._sendUpdatesJob = void 0;
|
|
2214
2662
|
}
|
|
2215
2663
|
};
|
|
2216
2664
|
|
|
2217
|
-
//
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
this._updateIndexes = params.updateIndexes;
|
|
2665
|
+
// src/db-host/data-service.ts
|
|
2666
|
+
function _define_property10(obj, key, value) {
|
|
2667
|
+
if (key in obj) {
|
|
2668
|
+
Object.defineProperty(obj, key, {
|
|
2669
|
+
value,
|
|
2670
|
+
enumerable: true,
|
|
2671
|
+
configurable: true,
|
|
2672
|
+
writable: true
|
|
2673
|
+
});
|
|
2674
|
+
} else {
|
|
2675
|
+
obj[key] = value;
|
|
2229
2676
|
}
|
|
2677
|
+
return obj;
|
|
2678
|
+
}
|
|
2679
|
+
var __dxlog_file8 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/data-service.ts";
|
|
2680
|
+
var DataServiceImpl = class {
|
|
2230
2681
|
subscribe(request) {
|
|
2231
2682
|
return new Stream(({ next, ready }) => {
|
|
2232
2683
|
const synchronizer = new DocumentsSynchronizer({
|
|
@@ -2238,7 +2689,7 @@ var DataServiceImpl = class {
|
|
|
2238
2689
|
ready();
|
|
2239
2690
|
}).catch((err) => log7.catch(err, void 0, {
|
|
2240
2691
|
F: __dxlog_file8,
|
|
2241
|
-
L:
|
|
2692
|
+
L: 72,
|
|
2242
2693
|
S: this,
|
|
2243
2694
|
C: (f, a) => f(...a)
|
|
2244
2695
|
}));
|
|
@@ -2249,7 +2700,7 @@ var DataServiceImpl = class {
|
|
|
2249
2700
|
const synchronizer = this._subscriptions.get(request.subscriptionId);
|
|
2250
2701
|
invariant7(synchronizer, "Subscription not found", {
|
|
2251
2702
|
F: __dxlog_file8,
|
|
2252
|
-
L:
|
|
2703
|
+
L: 79,
|
|
2253
2704
|
S: this,
|
|
2254
2705
|
A: [
|
|
2255
2706
|
"synchronizer",
|
|
@@ -2270,7 +2721,7 @@ var DataServiceImpl = class {
|
|
|
2270
2721
|
const synchronizer = this._subscriptions.get(request.subscriptionId);
|
|
2271
2722
|
invariant7(synchronizer, "Subscription not found", {
|
|
2272
2723
|
F: __dxlog_file8,
|
|
2273
|
-
L:
|
|
2724
|
+
L: 94,
|
|
2274
2725
|
S: this,
|
|
2275
2726
|
A: [
|
|
2276
2727
|
"synchronizer",
|
|
@@ -2315,7 +2766,7 @@ var DataServiceImpl = class {
|
|
|
2315
2766
|
const spaceId = request.spaceId;
|
|
2316
2767
|
invariant7(SpaceId2.isValid(spaceId), void 0, {
|
|
2317
2768
|
F: __dxlog_file8,
|
|
2318
|
-
L:
|
|
2769
|
+
L: 134,
|
|
2319
2770
|
S: this,
|
|
2320
2771
|
A: [
|
|
2321
2772
|
"SpaceId.isValid(spaceId)",
|
|
@@ -2336,14 +2787,7 @@ var DataServiceImpl = class {
|
|
|
2336
2787
|
peers: []
|
|
2337
2788
|
};
|
|
2338
2789
|
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
|
-
}))
|
|
2790
|
+
peers: state.peers
|
|
2347
2791
|
});
|
|
2348
2792
|
});
|
|
2349
2793
|
this._automergeHost.collectionStateUpdated.on(ctx, (e) => {
|
|
@@ -2354,25 +2798,34 @@ var DataServiceImpl = class {
|
|
|
2354
2798
|
scheduler.trigger();
|
|
2355
2799
|
});
|
|
2356
2800
|
}
|
|
2801
|
+
constructor(params) {
|
|
2802
|
+
_define_property10(this, "_subscriptions", /* @__PURE__ */ new Map());
|
|
2803
|
+
_define_property10(this, "_automergeHost", void 0);
|
|
2804
|
+
_define_property10(this, "_spaceStateManager", void 0);
|
|
2805
|
+
_define_property10(this, "_updateIndexes", void 0);
|
|
2806
|
+
this._automergeHost = params.automergeHost;
|
|
2807
|
+
this._spaceStateManager = params.spaceStateManager;
|
|
2808
|
+
this._updateIndexes = params.updateIndexes;
|
|
2809
|
+
}
|
|
2357
2810
|
};
|
|
2358
2811
|
|
|
2359
|
-
//
|
|
2812
|
+
// src/db-host/echo-host.ts
|
|
2360
2813
|
import { LifecycleState as LifecycleState5, Resource as Resource9 } from "@dxos/context";
|
|
2361
2814
|
import { todo } from "@dxos/debug";
|
|
2362
|
-
import {
|
|
2815
|
+
import { SpaceDocVersion as SpaceDocVersion3, createIdFromSpaceKey as createIdFromSpaceKey2 } from "@dxos/echo-protocol";
|
|
2363
2816
|
import { IndexMetadataStore, IndexStore, Indexer } from "@dxos/indexing";
|
|
2364
2817
|
import { invariant as invariant13 } from "@dxos/invariant";
|
|
2365
2818
|
import { IndexKind } from "@dxos/protocols/proto/dxos/echo/indexing";
|
|
2366
2819
|
import { trace as trace5 } from "@dxos/tracing";
|
|
2367
2820
|
|
|
2368
|
-
//
|
|
2821
|
+
// src/db-host/documents-iterator.ts
|
|
2369
2822
|
import * as A3 from "@automerge/automerge";
|
|
2370
2823
|
import { Context as Context2 } from "@dxos/context";
|
|
2371
2824
|
import { DatabaseDirectory as DatabaseDirectory2, SpaceDocVersion } from "@dxos/echo-protocol";
|
|
2372
2825
|
import { invariant as invariant8 } from "@dxos/invariant";
|
|
2373
2826
|
import { log as log8 } from "@dxos/log";
|
|
2374
2827
|
import { ObjectPointerVersion, objectPointerCodec as objectPointerCodec2 } from "@dxos/protocols";
|
|
2375
|
-
var __dxlog_file9 = "/
|
|
2828
|
+
var __dxlog_file9 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/documents-iterator.ts";
|
|
2376
2829
|
var LOG_VIEW_OPERATION_THRESHOLD = 300;
|
|
2377
2830
|
var createSelectedDocumentsIterator = (automergeHost) => (
|
|
2378
2831
|
/**
|
|
@@ -2453,10 +2906,10 @@ var createSelectedDocumentsIterator = (automergeHost) => (
|
|
|
2453
2906
|
}
|
|
2454
2907
|
);
|
|
2455
2908
|
|
|
2456
|
-
//
|
|
2909
|
+
// src/db-host/query-service.ts
|
|
2457
2910
|
import { getHeads as getHeads3 } from "@automerge/automerge";
|
|
2458
2911
|
import { Schema } from "effect";
|
|
2459
|
-
import { DeferredTask, scheduleMicroTask, synchronized as synchronized2 } from "@dxos/async";
|
|
2912
|
+
import { DeferredTask as DeferredTask2, scheduleMicroTask, synchronized as synchronized2 } from "@dxos/async";
|
|
2460
2913
|
import { Stream as Stream2 } from "@dxos/codec-protobuf/stream";
|
|
2461
2914
|
import { Context as Context4, Resource as Resource7 } from "@dxos/context";
|
|
2462
2915
|
import { raise } from "@dxos/debug";
|
|
@@ -2465,10 +2918,10 @@ import { log as log10 } from "@dxos/log";
|
|
|
2465
2918
|
import { objectPointerCodec as objectPointerCodec4 } from "@dxos/protocols";
|
|
2466
2919
|
import { trace as trace4 } from "@dxos/tracing";
|
|
2467
2920
|
|
|
2468
|
-
//
|
|
2469
|
-
import { Match } from "effect";
|
|
2921
|
+
// src/query/query-executor.ts
|
|
2922
|
+
import { Match, Predicate } from "effect";
|
|
2470
2923
|
import { Context as Context3, ContextDisposedError, LifecycleState as LifecycleState3, Resource as Resource6 } from "@dxos/context";
|
|
2471
|
-
import { DatabaseDirectory as DatabaseDirectory3,
|
|
2924
|
+
import { DatabaseDirectory as DatabaseDirectory3, ObjectStructure, isEncodedReference } from "@dxos/echo-protocol";
|
|
2472
2925
|
import { EscapedPropPath } from "@dxos/indexing";
|
|
2473
2926
|
import { invariant as invariant10 } from "@dxos/invariant";
|
|
2474
2927
|
import { DXN, PublicKey as PublicKey3 } from "@dxos/keys";
|
|
@@ -2476,15 +2929,18 @@ import { log as log9 } from "@dxos/log";
|
|
|
2476
2929
|
import { objectPointerCodec as objectPointerCodec3 } from "@dxos/protocols";
|
|
2477
2930
|
import { getDeep, isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
2478
2931
|
|
|
2479
|
-
//
|
|
2932
|
+
// src/query/query-planner.ts
|
|
2933
|
+
import { Order } from "@dxos/echo";
|
|
2480
2934
|
import { invariant as invariant9 } from "@dxos/invariant";
|
|
2481
2935
|
|
|
2482
|
-
//
|
|
2936
|
+
// src/query/errors.ts
|
|
2483
2937
|
import { BaseError } from "@dxos/errors";
|
|
2484
2938
|
var QueryError = class extends BaseError.extend("QUERY_ERROR") {
|
|
2485
2939
|
};
|
|
2940
|
+
var InvalidQueryError = class extends QueryError.extend("INVALID_QUERY") {
|
|
2941
|
+
};
|
|
2486
2942
|
|
|
2487
|
-
//
|
|
2943
|
+
// src/query/plan.ts
|
|
2488
2944
|
(function(QueryPlan2) {
|
|
2489
2945
|
QueryPlan2.Plan = Object.freeze({
|
|
2490
2946
|
make: (steps) => ({
|
|
@@ -2505,18 +2961,25 @@ var QueryError = class extends BaseError.extend("QUERY_ERROR") {
|
|
|
2505
2961
|
})(QueryPlan || (QueryPlan = {}));
|
|
2506
2962
|
var QueryPlan;
|
|
2507
2963
|
|
|
2508
|
-
//
|
|
2509
|
-
|
|
2964
|
+
// src/query/query-planner.ts
|
|
2965
|
+
function _define_property11(obj, key, value) {
|
|
2966
|
+
if (key in obj) {
|
|
2967
|
+
Object.defineProperty(obj, key, {
|
|
2968
|
+
value,
|
|
2969
|
+
enumerable: true,
|
|
2970
|
+
configurable: true,
|
|
2971
|
+
writable: true
|
|
2972
|
+
});
|
|
2973
|
+
} else {
|
|
2974
|
+
obj[key] = value;
|
|
2975
|
+
}
|
|
2976
|
+
return obj;
|
|
2977
|
+
}
|
|
2978
|
+
var __dxlog_file10 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/query/query-planner.ts";
|
|
2510
2979
|
var DEFAULT_OPTIONS = {
|
|
2511
2980
|
defaultTextSearchKind: "full-text"
|
|
2512
2981
|
};
|
|
2513
2982
|
var QueryPlanner = class {
|
|
2514
|
-
constructor(options) {
|
|
2515
|
-
this._options = {
|
|
2516
|
-
...DEFAULT_OPTIONS,
|
|
2517
|
-
...options
|
|
2518
|
-
};
|
|
2519
|
-
}
|
|
2520
2983
|
createPlan(query) {
|
|
2521
2984
|
let plan = this._generate(query, {
|
|
2522
2985
|
...DEFAULT_CONTEXT,
|
|
@@ -2524,6 +2987,7 @@ var QueryPlanner = class {
|
|
|
2524
2987
|
});
|
|
2525
2988
|
plan = this._optimizeEmptyFilters(plan);
|
|
2526
2989
|
plan = this._optimizeSoloUnions(plan);
|
|
2990
|
+
plan = this._ensureOrderStep(plan);
|
|
2527
2991
|
return plan;
|
|
2528
2992
|
}
|
|
2529
2993
|
_generate(query, context) {
|
|
@@ -2546,8 +3010,11 @@ var QueryPlanner = class {
|
|
|
2546
3010
|
return this._generateUnionClause(query, context);
|
|
2547
3011
|
case "set-difference":
|
|
2548
3012
|
return this._generateSetDifferenceClause(query, context);
|
|
3013
|
+
case "order":
|
|
3014
|
+
return this._generateOrderClause(query, context);
|
|
2549
3015
|
default:
|
|
2550
|
-
throw new QueryError(
|
|
3016
|
+
throw new QueryError({
|
|
3017
|
+
message: `Unsupported query type: ${query.type}`,
|
|
2551
3018
|
context: {
|
|
2552
3019
|
query: context.originalQuery
|
|
2553
3020
|
}
|
|
@@ -2583,7 +3050,8 @@ var QueryPlanner = class {
|
|
|
2583
3050
|
]);
|
|
2584
3051
|
}
|
|
2585
3052
|
if (context.selectionInverted) {
|
|
2586
|
-
throw new QueryError(
|
|
3053
|
+
throw new QueryError({
|
|
3054
|
+
message: "Query too complex",
|
|
2587
3055
|
context: {
|
|
2588
3056
|
query: context.originalQuery
|
|
2589
3057
|
}
|
|
@@ -2664,19 +3132,22 @@ var QueryPlanner = class {
|
|
|
2664
3132
|
]);
|
|
2665
3133
|
}
|
|
2666
3134
|
case "compare":
|
|
2667
|
-
throw new QueryError(
|
|
3135
|
+
throw new QueryError({
|
|
3136
|
+
message: "Query too complex",
|
|
2668
3137
|
context: {
|
|
2669
3138
|
query: context.originalQuery
|
|
2670
3139
|
}
|
|
2671
3140
|
});
|
|
2672
3141
|
case "in":
|
|
2673
|
-
throw new QueryError(
|
|
3142
|
+
throw new QueryError({
|
|
3143
|
+
message: "Query too complex",
|
|
2674
3144
|
context: {
|
|
2675
3145
|
query: context.originalQuery
|
|
2676
3146
|
}
|
|
2677
3147
|
});
|
|
2678
3148
|
case "range":
|
|
2679
|
-
throw new QueryError(
|
|
3149
|
+
throw new QueryError({
|
|
3150
|
+
message: "Query too complex",
|
|
2680
3151
|
context: {
|
|
2681
3152
|
query: context.originalQuery
|
|
2682
3153
|
}
|
|
@@ -2687,7 +3158,8 @@ var QueryPlanner = class {
|
|
|
2687
3158
|
selectionInverted: !context.selectionInverted
|
|
2688
3159
|
});
|
|
2689
3160
|
case "and":
|
|
2690
|
-
throw new QueryError(
|
|
3161
|
+
throw new QueryError({
|
|
3162
|
+
message: "Query too complex",
|
|
2691
3163
|
context: {
|
|
2692
3164
|
query: context.originalQuery
|
|
2693
3165
|
}
|
|
@@ -2697,7 +3169,7 @@ var QueryPlanner = class {
|
|
|
2697
3169
|
const typenames = filter.filters.map((f) => {
|
|
2698
3170
|
invariant9(f.type === "object" && f.typename !== null, void 0, {
|
|
2699
3171
|
F: __dxlog_file10,
|
|
2700
|
-
L:
|
|
3172
|
+
L: 199,
|
|
2701
3173
|
S: this,
|
|
2702
3174
|
A: [
|
|
2703
3175
|
"f.type === 'object' && f.typename !== null",
|
|
@@ -2719,14 +3191,16 @@ var QueryPlanner = class {
|
|
|
2719
3191
|
...this._generateDeletedHandlingSteps(context)
|
|
2720
3192
|
]);
|
|
2721
3193
|
} else {
|
|
2722
|
-
throw new QueryError(
|
|
3194
|
+
throw new QueryError({
|
|
3195
|
+
message: "Query too complex",
|
|
2723
3196
|
context: {
|
|
2724
3197
|
query: context.originalQuery
|
|
2725
3198
|
}
|
|
2726
3199
|
});
|
|
2727
3200
|
}
|
|
2728
3201
|
default:
|
|
2729
|
-
throw new QueryError(
|
|
3202
|
+
throw new QueryError({
|
|
3203
|
+
message: `Unsupported filter type: ${filter.type}`,
|
|
2730
3204
|
context: {
|
|
2731
3205
|
query: context.originalQuery
|
|
2732
3206
|
}
|
|
@@ -2926,6 +3400,52 @@ var QueryPlanner = class {
|
|
|
2926
3400
|
_optimizeSoloUnions(plan) {
|
|
2927
3401
|
return plan;
|
|
2928
3402
|
}
|
|
3403
|
+
_generateOrderClause(query, context) {
|
|
3404
|
+
return QueryPlan.Plan.make([
|
|
3405
|
+
...this._generate(query.query, context).steps,
|
|
3406
|
+
{
|
|
3407
|
+
_tag: "OrderStep",
|
|
3408
|
+
order: query.order
|
|
3409
|
+
}
|
|
3410
|
+
]);
|
|
3411
|
+
}
|
|
3412
|
+
// After complete plan is built, inspect it from the end:
|
|
3413
|
+
// - Walk backwards until hitting an object set changer.
|
|
3414
|
+
// - If an order step is found, skip.
|
|
3415
|
+
// - Otherwise append natural order to the end.
|
|
3416
|
+
_ensureOrderStep(plan) {
|
|
3417
|
+
const OBJECT_SET_CHANGERS = /* @__PURE__ */ new Set([
|
|
3418
|
+
"SelectStep",
|
|
3419
|
+
"TraverseStep",
|
|
3420
|
+
"UnionStep",
|
|
3421
|
+
"SetDifferenceStep"
|
|
3422
|
+
]);
|
|
3423
|
+
for (let i = plan.steps.length - 1; i >= 0; i--) {
|
|
3424
|
+
const step = plan.steps[i];
|
|
3425
|
+
if (step._tag === "OrderStep") {
|
|
3426
|
+
return plan;
|
|
3427
|
+
}
|
|
3428
|
+
if (OBJECT_SET_CHANGERS.has(step._tag)) {
|
|
3429
|
+
break;
|
|
3430
|
+
}
|
|
3431
|
+
}
|
|
3432
|
+
return QueryPlan.Plan.make([
|
|
3433
|
+
...plan.steps,
|
|
3434
|
+
{
|
|
3435
|
+
_tag: "OrderStep",
|
|
3436
|
+
order: [
|
|
3437
|
+
Order.natural.ast
|
|
3438
|
+
]
|
|
3439
|
+
}
|
|
3440
|
+
]);
|
|
3441
|
+
}
|
|
3442
|
+
constructor(options) {
|
|
3443
|
+
_define_property11(this, "_options", void 0);
|
|
3444
|
+
this._options = {
|
|
3445
|
+
...DEFAULT_OPTIONS,
|
|
3446
|
+
...options
|
|
3447
|
+
};
|
|
3448
|
+
}
|
|
2929
3449
|
};
|
|
2930
3450
|
var DEFAULT_CONTEXT = {
|
|
2931
3451
|
originalQuery: null,
|
|
@@ -2950,8 +3470,22 @@ var isTrivialTypenameFilter = (filter) => {
|
|
|
2950
3470
|
return filter.type === "object" && filter.typename !== null && Object.keys(filter.props).length === 0 && (filter.id === void 0 || filter.id.length === 0) && (filter.foreignKeys === void 0 || filter.foreignKeys.length === 0);
|
|
2951
3471
|
};
|
|
2952
3472
|
|
|
2953
|
-
//
|
|
2954
|
-
|
|
3473
|
+
// src/query/query-executor.ts
|
|
3474
|
+
function _define_property12(obj, key, value) {
|
|
3475
|
+
if (key in obj) {
|
|
3476
|
+
Object.defineProperty(obj, key, {
|
|
3477
|
+
value,
|
|
3478
|
+
enumerable: true,
|
|
3479
|
+
configurable: true,
|
|
3480
|
+
writable: true
|
|
3481
|
+
});
|
|
3482
|
+
} else {
|
|
3483
|
+
obj[key] = value;
|
|
3484
|
+
}
|
|
3485
|
+
return obj;
|
|
3486
|
+
}
|
|
3487
|
+
var __dxlog_file11 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/query/query-executor.ts";
|
|
3488
|
+
var isNullable = Predicate.isNullable;
|
|
2955
3489
|
var ExecutionTrace = Object.freeze({
|
|
2956
3490
|
makeEmpty: () => ({
|
|
2957
3491
|
name: "Empty",
|
|
@@ -2978,19 +3512,6 @@ var ExecutionTrace = Object.freeze({
|
|
|
2978
3512
|
});
|
|
2979
3513
|
var TRACE_QUERY_EXECUTION = false;
|
|
2980
3514
|
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
3515
|
get query() {
|
|
2995
3516
|
return this._query;
|
|
2996
3517
|
}
|
|
@@ -3016,7 +3537,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3016
3537
|
async execQuery() {
|
|
3017
3538
|
invariant10(this._lifecycleState === LifecycleState3.OPEN, void 0, {
|
|
3018
3539
|
F: __dxlog_file11,
|
|
3019
|
-
L:
|
|
3540
|
+
L: 176,
|
|
3020
3541
|
S: this,
|
|
3021
3542
|
A: [
|
|
3022
3543
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -3089,6 +3610,9 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3089
3610
|
case "TraverseStep":
|
|
3090
3611
|
({ workingSet: newWorkingSet, trace: trace6 } = await this._execTraverseStep(step, workingSet));
|
|
3091
3612
|
break;
|
|
3613
|
+
case "OrderStep":
|
|
3614
|
+
({ workingSet: newWorkingSet, trace: trace6 } = await this._execOrderStep(step, workingSet));
|
|
3615
|
+
break;
|
|
3092
3616
|
default:
|
|
3093
3617
|
throw new Error(`Unknown step type: ${step._tag}`);
|
|
3094
3618
|
}
|
|
@@ -3212,17 +3736,6 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3212
3736
|
};
|
|
3213
3737
|
}
|
|
3214
3738
|
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
3739
|
const expected = step.mode === "only-deleted";
|
|
3227
3740
|
const result = workingSet.filter((item) => ObjectStructure.isDeleted(item.doc) === expected);
|
|
3228
3741
|
return {
|
|
@@ -3260,11 +3773,11 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3260
3773
|
spaceId: item.spaceId
|
|
3261
3774
|
} : null;
|
|
3262
3775
|
} catch {
|
|
3263
|
-
log9.warn("
|
|
3776
|
+
log9.warn("invalid reference", {
|
|
3264
3777
|
ref: ref2["/"]
|
|
3265
3778
|
}, {
|
|
3266
3779
|
F: __dxlog_file11,
|
|
3267
|
-
L:
|
|
3780
|
+
L: 432,
|
|
3268
3781
|
S: this,
|
|
3269
3782
|
C: (f, a) => f(...a)
|
|
3270
3783
|
});
|
|
@@ -3318,11 +3831,11 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3318
3831
|
spaceId: item.spaceId
|
|
3319
3832
|
};
|
|
3320
3833
|
} catch {
|
|
3321
|
-
log9.warn("
|
|
3834
|
+
log9.warn("invalid reference", {
|
|
3322
3835
|
ref: ref["/"]
|
|
3323
3836
|
}, {
|
|
3324
3837
|
F: __dxlog_file11,
|
|
3325
|
-
L:
|
|
3838
|
+
L: 495,
|
|
3326
3839
|
S: this,
|
|
3327
3840
|
C: (f, a) => f(...a)
|
|
3328
3841
|
});
|
|
@@ -3411,6 +3924,74 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3411
3924
|
trace: trace6
|
|
3412
3925
|
};
|
|
3413
3926
|
}
|
|
3927
|
+
async _execOrderStep(step, workingSet) {
|
|
3928
|
+
const compareItems = (a, b) => step.order.reduce((comparison, order) => {
|
|
3929
|
+
if (comparison !== 0) {
|
|
3930
|
+
return comparison;
|
|
3931
|
+
}
|
|
3932
|
+
return this._compareByOrder(a, b, order);
|
|
3933
|
+
}, 0);
|
|
3934
|
+
const sortedWorkingSet = [
|
|
3935
|
+
...workingSet
|
|
3936
|
+
].sort(compareItems);
|
|
3937
|
+
return {
|
|
3938
|
+
workingSet: sortedWorkingSet,
|
|
3939
|
+
trace: {
|
|
3940
|
+
...ExecutionTrace.makeEmpty(),
|
|
3941
|
+
name: "Order",
|
|
3942
|
+
details: JSON.stringify(step.order),
|
|
3943
|
+
objectCount: sortedWorkingSet.length
|
|
3944
|
+
}
|
|
3945
|
+
};
|
|
3946
|
+
}
|
|
3947
|
+
_compareByOrder(a, b, order) {
|
|
3948
|
+
return Match.type().pipe(Match.withReturnType(), Match.when({
|
|
3949
|
+
kind: "natural"
|
|
3950
|
+
}, () => a.objectId.localeCompare(b.objectId)), Match.when({
|
|
3951
|
+
kind: "property"
|
|
3952
|
+
}, ({ property, direction }) => {
|
|
3953
|
+
const comparison = this._compareByProperty(a, b, property);
|
|
3954
|
+
return direction === "desc" ? -comparison : comparison;
|
|
3955
|
+
}), Match.exhaustive)(order);
|
|
3956
|
+
}
|
|
3957
|
+
_compareByProperty(a, b, property) {
|
|
3958
|
+
const aValue = a.doc.data[property];
|
|
3959
|
+
const bValue = b.doc.data[property];
|
|
3960
|
+
return Match.type().pipe(
|
|
3961
|
+
Match.withReturnType(),
|
|
3962
|
+
Match.when({
|
|
3963
|
+
a: isNullable,
|
|
3964
|
+
b: isNullable
|
|
3965
|
+
}, () => 0),
|
|
3966
|
+
Match.when({
|
|
3967
|
+
a: isNullable
|
|
3968
|
+
}, () => 1),
|
|
3969
|
+
Match.when({
|
|
3970
|
+
b: isNullable
|
|
3971
|
+
}, () => -1),
|
|
3972
|
+
Match.when({
|
|
3973
|
+
a: Match.string,
|
|
3974
|
+
b: Match.string
|
|
3975
|
+
}, ({ a: a2, b: b2 }) => a2.localeCompare(b2)),
|
|
3976
|
+
Match.when({
|
|
3977
|
+
a: Match.number,
|
|
3978
|
+
b: Match.number
|
|
3979
|
+
}, ({ a: a2, b: b2 }) => a2 - b2),
|
|
3980
|
+
Match.when({
|
|
3981
|
+
a: Match.boolean,
|
|
3982
|
+
b: Match.boolean
|
|
3983
|
+
}, ({ a: a2, b: b2 }) => a2 === b2 ? 0 : a2 ? 1 : -1),
|
|
3984
|
+
Match.when({
|
|
3985
|
+
a: Match.defined,
|
|
3986
|
+
b: Match.defined
|
|
3987
|
+
}, ({ a: a2, b: b2 }) => String(a2).localeCompare(String(b2))),
|
|
3988
|
+
// TODO(wittjosiah): Why does Match.exhaustive fail here?
|
|
3989
|
+
Match.orElse(() => 0)
|
|
3990
|
+
)({
|
|
3991
|
+
a: aValue,
|
|
3992
|
+
b: bValue
|
|
3993
|
+
});
|
|
3994
|
+
}
|
|
3414
3995
|
async _loadDocumentsAfterIndexQuery(indexHits) {
|
|
3415
3996
|
return Promise.all(indexHits.map(async (hit) => {
|
|
3416
3997
|
return this._loadFromIndexHit(hit);
|
|
@@ -3420,7 +4001,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3420
4001
|
const { objectId, documentId, spaceKey: spaceKeyInIndex } = objectPointerCodec3.decode(hit.id);
|
|
3421
4002
|
const handle = await this._automergeHost.loadDoc(Context3.default(void 0, {
|
|
3422
4003
|
F: __dxlog_file11,
|
|
3423
|
-
L:
|
|
4004
|
+
L: 659
|
|
3424
4005
|
}), documentId);
|
|
3425
4006
|
const doc = handle.doc();
|
|
3426
4007
|
if (!doc) {
|
|
@@ -3448,7 +4029,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3448
4029
|
dxn
|
|
3449
4030
|
}, {
|
|
3450
4031
|
F: __dxlog_file11,
|
|
3451
|
-
L:
|
|
4032
|
+
L: 686,
|
|
3452
4033
|
S: this,
|
|
3453
4034
|
C: (f, a) => f(...a)
|
|
3454
4035
|
});
|
|
@@ -3461,7 +4042,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3461
4042
|
spaceId
|
|
3462
4043
|
}, {
|
|
3463
4044
|
F: __dxlog_file11,
|
|
3464
|
-
L:
|
|
4045
|
+
L: 694,
|
|
3465
4046
|
S: this,
|
|
3466
4047
|
C: (f, a) => f(...a)
|
|
3467
4048
|
});
|
|
@@ -3473,7 +4054,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3473
4054
|
spaceId
|
|
3474
4055
|
}, {
|
|
3475
4056
|
F: __dxlog_file11,
|
|
3476
|
-
L:
|
|
4057
|
+
L: 699,
|
|
3477
4058
|
S: this,
|
|
3478
4059
|
C: (f, a) => f(...a)
|
|
3479
4060
|
});
|
|
@@ -3494,7 +4075,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3494
4075
|
}
|
|
3495
4076
|
const handle = await this._automergeHost.loadDoc(Context3.default(void 0, {
|
|
3496
4077
|
F: __dxlog_file11,
|
|
3497
|
-
L:
|
|
4078
|
+
L: 718
|
|
3498
4079
|
}), link);
|
|
3499
4080
|
const doc = handle.doc();
|
|
3500
4081
|
if (!doc) {
|
|
@@ -3511,37 +4092,48 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3511
4092
|
doc: object
|
|
3512
4093
|
};
|
|
3513
4094
|
}
|
|
4095
|
+
constructor(options) {
|
|
4096
|
+
super(), _define_property12(this, "_indexer", void 0), _define_property12(this, "_automergeHost", void 0), _define_property12(this, "_spaceStateManager", void 0), /**
|
|
4097
|
+
* Id of this query.
|
|
4098
|
+
*/
|
|
4099
|
+
_define_property12(this, "_id", void 0), _define_property12(this, "_query", void 0), // TODO(dmaretskyi): Might be used in the future.
|
|
4100
|
+
_define_property12(this, "_reactivity", void 0), _define_property12(this, "_plan", void 0), _define_property12(this, "_trace", ExecutionTrace.makeEmpty()), _define_property12(this, "_lastResultSet", []);
|
|
4101
|
+
this._indexer = options.indexer;
|
|
4102
|
+
this._automergeHost = options.automergeHost;
|
|
4103
|
+
this._spaceStateManager = options.spaceStateManager;
|
|
4104
|
+
this._id = options.queryId;
|
|
4105
|
+
this._query = options.query;
|
|
4106
|
+
this._reactivity = options.reactivity;
|
|
4107
|
+
const queryPlanner = new QueryPlanner();
|
|
4108
|
+
this._plan = queryPlanner.createPlan(this._query);
|
|
4109
|
+
}
|
|
3514
4110
|
};
|
|
3515
4111
|
|
|
3516
|
-
//
|
|
4112
|
+
// src/db-host/query-service.ts
|
|
4113
|
+
function _define_property13(obj, key, value) {
|
|
4114
|
+
if (key in obj) {
|
|
4115
|
+
Object.defineProperty(obj, key, {
|
|
4116
|
+
value,
|
|
4117
|
+
enumerable: true,
|
|
4118
|
+
configurable: true,
|
|
4119
|
+
writable: true
|
|
4120
|
+
});
|
|
4121
|
+
} else {
|
|
4122
|
+
obj[key] = value;
|
|
4123
|
+
}
|
|
4124
|
+
return obj;
|
|
4125
|
+
}
|
|
3517
4126
|
function _ts_decorate5(decorators, target, key, desc) {
|
|
3518
4127
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3519
4128
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3520
4129
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
3521
4130
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3522
4131
|
}
|
|
3523
|
-
var __dxlog_file12 = "/
|
|
4132
|
+
var __dxlog_file12 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/query-service.ts";
|
|
3524
4133
|
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
4134
|
async _open() {
|
|
3543
4135
|
this._params.indexer.updated.on(this._ctx, () => this.invalidateQueries());
|
|
3544
|
-
this._updateQueries = new
|
|
4136
|
+
this._updateQueries = new DeferredTask2(this._ctx, this._executeQueries.bind(this));
|
|
3545
4137
|
}
|
|
3546
4138
|
async _close() {
|
|
3547
4139
|
await this._updateQueries.join();
|
|
@@ -3552,6 +4144,18 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
3552
4144
|
}
|
|
3553
4145
|
execQuery(request) {
|
|
3554
4146
|
return new Stream2(({ next, close, ctx }) => {
|
|
4147
|
+
if (this._params.indexer.config?.enabled !== true) {
|
|
4148
|
+
log10.error("indexer is disabled", {
|
|
4149
|
+
config: this._params.indexer.config
|
|
4150
|
+
}, {
|
|
4151
|
+
F: __dxlog_file12,
|
|
4152
|
+
L: 101,
|
|
4153
|
+
S: this,
|
|
4154
|
+
C: (f, a) => f(...a)
|
|
4155
|
+
});
|
|
4156
|
+
close();
|
|
4157
|
+
return;
|
|
4158
|
+
}
|
|
3555
4159
|
const queryEntry = this._createQuery(ctx, request, next, close, close);
|
|
3556
4160
|
scheduleMicroTask(ctx, async () => {
|
|
3557
4161
|
await queryEntry.executor.open();
|
|
@@ -3567,7 +4171,7 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
3567
4171
|
async reindex() {
|
|
3568
4172
|
log10("Reindexing all documents...", void 0, {
|
|
3569
4173
|
F: __dxlog_file12,
|
|
3570
|
-
L:
|
|
4174
|
+
L: 120,
|
|
3571
4175
|
S: this,
|
|
3572
4176
|
C: (f, a) => f(...a)
|
|
3573
4177
|
});
|
|
@@ -3582,7 +4186,7 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
3582
4186
|
count: ids.size
|
|
3583
4187
|
}, {
|
|
3584
4188
|
F: __dxlog_file12,
|
|
3585
|
-
L:
|
|
4189
|
+
L: 128,
|
|
3586
4190
|
S: this,
|
|
3587
4191
|
C: (f, a) => f(...a)
|
|
3588
4192
|
});
|
|
@@ -3592,7 +4196,7 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
3592
4196
|
count: ids.size
|
|
3593
4197
|
}, {
|
|
3594
4198
|
F: __dxlog_file12,
|
|
3595
|
-
L:
|
|
4199
|
+
L: 132,
|
|
3596
4200
|
S: this,
|
|
3597
4201
|
C: (f, a) => f(...a)
|
|
3598
4202
|
});
|
|
@@ -3658,7 +4262,7 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
3658
4262
|
} catch (err) {
|
|
3659
4263
|
log10.catch(err, void 0, {
|
|
3660
4264
|
F: __dxlog_file12,
|
|
3661
|
-
L:
|
|
4265
|
+
L: 203,
|
|
3662
4266
|
S: this,
|
|
3663
4267
|
C: (f, a) => f(...a)
|
|
3664
4268
|
});
|
|
@@ -3669,11 +4273,28 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
3669
4273
|
duration: performance.now() - begin
|
|
3670
4274
|
}, {
|
|
3671
4275
|
F: __dxlog_file12,
|
|
3672
|
-
L:
|
|
4276
|
+
L: 207,
|
|
3673
4277
|
S: this,
|
|
3674
4278
|
C: (f, a) => f(...a)
|
|
3675
4279
|
});
|
|
3676
4280
|
}
|
|
4281
|
+
// TODO(burdon): OK for options, but not params. Pass separately and type readonly here.
|
|
4282
|
+
constructor(_params) {
|
|
4283
|
+
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();
|
|
4284
|
+
trace4.diagnostic({
|
|
4285
|
+
id: "active-queries",
|
|
4286
|
+
name: "Active Queries",
|
|
4287
|
+
fetch: () => {
|
|
4288
|
+
return Array.from(this._queries).map((query) => {
|
|
4289
|
+
return {
|
|
4290
|
+
query: JSON.stringify(query.executor.query),
|
|
4291
|
+
plan: JSON.stringify(query.executor.plan),
|
|
4292
|
+
trace: JSON.stringify(query.executor.trace)
|
|
4293
|
+
};
|
|
4294
|
+
});
|
|
4295
|
+
}
|
|
4296
|
+
});
|
|
4297
|
+
}
|
|
3677
4298
|
};
|
|
3678
4299
|
_ts_decorate5([
|
|
3679
4300
|
synchronized2
|
|
@@ -3720,7 +4341,7 @@ var createDocumentsIterator = (automergeHost) => (
|
|
|
3720
4341
|
}
|
|
3721
4342
|
const linkHandle = await automergeHost.loadDoc(Context4.default(void 0, {
|
|
3722
4343
|
F: __dxlog_file12,
|
|
3723
|
-
L:
|
|
4344
|
+
L: 247
|
|
3724
4345
|
}), urlString);
|
|
3725
4346
|
for await (const result of getObjectsFromHandle(linkHandle)) {
|
|
3726
4347
|
yield result;
|
|
@@ -3741,22 +4362,22 @@ var createDocumentsIterator = (automergeHost) => (
|
|
|
3741
4362
|
}
|
|
3742
4363
|
);
|
|
3743
4364
|
|
|
3744
|
-
//
|
|
4365
|
+
// src/db-host/space-state-manager.ts
|
|
3745
4366
|
import { interpretAsDocumentId as interpretAsDocumentId3 } from "@automerge/automerge-repo";
|
|
3746
4367
|
import isEqual from "lodash.isequal";
|
|
3747
4368
|
import { Event as Event3, UpdateScheduler as UpdateScheduler3 } from "@dxos/async";
|
|
3748
|
-
import {
|
|
4369
|
+
import { Context as Context5, LifecycleState as LifecycleState4, Resource as Resource8 } from "@dxos/context";
|
|
3749
4370
|
import { invariant as invariant12 } from "@dxos/invariant";
|
|
3750
4371
|
|
|
3751
|
-
//
|
|
4372
|
+
// src/db-host/database-root.ts
|
|
3752
4373
|
import { interpretAsDocumentId as interpretAsDocumentId2 } from "@automerge/automerge-repo";
|
|
3753
4374
|
import { DatabaseDirectory as DatabaseDirectory5, SpaceDocVersion as SpaceDocVersion2 } from "@dxos/echo-protocol";
|
|
3754
4375
|
import { invariant as invariant11 } from "@dxos/invariant";
|
|
3755
4376
|
|
|
3756
|
-
//
|
|
4377
|
+
// src/db-host/automerge-metrics.ts
|
|
3757
4378
|
import * as A4 from "@automerge/automerge";
|
|
3758
4379
|
import { log as log11 } from "@dxos/log";
|
|
3759
|
-
var __dxlog_file13 = "/
|
|
4380
|
+
var __dxlog_file13 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/automerge-metrics.ts";
|
|
3760
4381
|
var measureDocMetrics = (doc) => {
|
|
3761
4382
|
const snapshot = A4.save(doc);
|
|
3762
4383
|
const start = Date.now();
|
|
@@ -3783,8 +4404,21 @@ var measureDocMetrics = (doc) => {
|
|
|
3783
4404
|
};
|
|
3784
4405
|
};
|
|
3785
4406
|
|
|
3786
|
-
//
|
|
3787
|
-
|
|
4407
|
+
// src/db-host/database-root.ts
|
|
4408
|
+
function _define_property14(obj, key, value) {
|
|
4409
|
+
if (key in obj) {
|
|
4410
|
+
Object.defineProperty(obj, key, {
|
|
4411
|
+
value,
|
|
4412
|
+
enumerable: true,
|
|
4413
|
+
configurable: true,
|
|
4414
|
+
writable: true
|
|
4415
|
+
});
|
|
4416
|
+
} else {
|
|
4417
|
+
obj[key] = value;
|
|
4418
|
+
}
|
|
4419
|
+
return obj;
|
|
4420
|
+
}
|
|
4421
|
+
var __dxlog_file14 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/database-root.ts";
|
|
3788
4422
|
var DatabaseRoot = class {
|
|
3789
4423
|
static mapLinks(doc, mapping) {
|
|
3790
4424
|
doc.change((d) => {
|
|
@@ -3799,9 +4433,6 @@ var DatabaseRoot = class {
|
|
|
3799
4433
|
}
|
|
3800
4434
|
});
|
|
3801
4435
|
}
|
|
3802
|
-
constructor(_rootHandle) {
|
|
3803
|
-
this._rootHandle = _rootHandle;
|
|
3804
|
-
}
|
|
3805
4436
|
get documentId() {
|
|
3806
4437
|
return this._rootHandle.documentId;
|
|
3807
4438
|
}
|
|
@@ -3865,19 +4496,28 @@ var DatabaseRoot = class {
|
|
|
3865
4496
|
}
|
|
3866
4497
|
return measureDocMetrics(doc);
|
|
3867
4498
|
}
|
|
4499
|
+
constructor(_rootHandle) {
|
|
4500
|
+
_define_property14(this, "_rootHandle", void 0);
|
|
4501
|
+
this._rootHandle = _rootHandle;
|
|
4502
|
+
}
|
|
3868
4503
|
};
|
|
3869
4504
|
|
|
3870
|
-
//
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
4505
|
+
// src/db-host/space-state-manager.ts
|
|
4506
|
+
function _define_property15(obj, key, value) {
|
|
4507
|
+
if (key in obj) {
|
|
4508
|
+
Object.defineProperty(obj, key, {
|
|
4509
|
+
value,
|
|
4510
|
+
enumerable: true,
|
|
4511
|
+
configurable: true,
|
|
4512
|
+
writable: true
|
|
4513
|
+
});
|
|
4514
|
+
} else {
|
|
4515
|
+
obj[key] = value;
|
|
3880
4516
|
}
|
|
4517
|
+
return obj;
|
|
4518
|
+
}
|
|
4519
|
+
var __dxlog_file15 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/space-state-manager.ts";
|
|
4520
|
+
var SpaceStateManager = class extends Resource8 {
|
|
3881
4521
|
async _close(ctx) {
|
|
3882
4522
|
for (const [_, rootCtx] of this._perRootContext) {
|
|
3883
4523
|
await rootCtx.dispose();
|
|
@@ -3950,9 +4590,16 @@ var SpaceStateManager = class extends Resource8 {
|
|
|
3950
4590
|
documentListCheckScheduler.trigger();
|
|
3951
4591
|
return root;
|
|
3952
4592
|
}
|
|
4593
|
+
constructor(...args) {
|
|
4594
|
+
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());
|
|
4595
|
+
}
|
|
3953
4596
|
};
|
|
3954
4597
|
var SpaceDocumentListUpdatedEvent = class {
|
|
3955
4598
|
constructor(spaceId, spaceRootId, previousRootId, documentIds) {
|
|
4599
|
+
_define_property15(this, "spaceId", void 0);
|
|
4600
|
+
_define_property15(this, "spaceRootId", void 0);
|
|
4601
|
+
_define_property15(this, "previousRootId", void 0);
|
|
4602
|
+
_define_property15(this, "documentIds", void 0);
|
|
3956
4603
|
this.spaceId = spaceId;
|
|
3957
4604
|
this.spaceRootId = spaceRootId;
|
|
3958
4605
|
this.previousRootId = previousRootId;
|
|
@@ -3960,113 +4607,27 @@ var SpaceDocumentListUpdatedEvent = class {
|
|
|
3960
4607
|
}
|
|
3961
4608
|
};
|
|
3962
4609
|
|
|
3963
|
-
//
|
|
3964
|
-
|
|
4610
|
+
// src/db-host/echo-host.ts
|
|
4611
|
+
function _define_property16(obj, key, value) {
|
|
4612
|
+
if (key in obj) {
|
|
4613
|
+
Object.defineProperty(obj, key, {
|
|
4614
|
+
value,
|
|
4615
|
+
enumerable: true,
|
|
4616
|
+
configurable: true,
|
|
4617
|
+
writable: true
|
|
4618
|
+
});
|
|
4619
|
+
} else {
|
|
4620
|
+
obj[key] = value;
|
|
4621
|
+
}
|
|
4622
|
+
return obj;
|
|
4623
|
+
}
|
|
4624
|
+
var __dxlog_file16 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/echo-host.ts";
|
|
3965
4625
|
var DEFAULT_INDEXING_CONFIG = {
|
|
3966
4626
|
// TODO(dmaretskyi): Disabled by default since embedding generation is expensive.
|
|
3967
4627
|
fullText: false,
|
|
3968
4628
|
vector: false
|
|
3969
4629
|
};
|
|
3970
4630
|
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
4631
|
get queryService() {
|
|
4071
4632
|
return this._queryService;
|
|
4072
4633
|
}
|
|
@@ -4091,7 +4652,6 @@ var EchoHost = class extends Resource9 {
|
|
|
4091
4652
|
if (e.previousRootId) {
|
|
4092
4653
|
void this._automergeHost.clearLocalCollectionState(deriveCollectionIdFromSpaceId(e.spaceId, e.previousRootId));
|
|
4093
4654
|
}
|
|
4094
|
-
void this._automergeHost.updateLocalCollectionState(deriveCollectionIdFromSpaceId(e.spaceId), e.documentIds);
|
|
4095
4655
|
void this._automergeHost.updateLocalCollectionState(deriveCollectionIdFromSpaceId(e.spaceId, e.spaceRootId), e.documentIds);
|
|
4096
4656
|
});
|
|
4097
4657
|
this._automergeHost.documentsSaved.on(this._ctx, () => {
|
|
@@ -4137,7 +4697,7 @@ var EchoHost = class extends Resource9 {
|
|
|
4137
4697
|
async createSpaceRoot(spaceKey) {
|
|
4138
4698
|
invariant13(this._lifecycleState === LifecycleState5.OPEN, void 0, {
|
|
4139
4699
|
F: __dxlog_file16,
|
|
4140
|
-
L:
|
|
4700
|
+
L: 254,
|
|
4141
4701
|
S: this,
|
|
4142
4702
|
A: [
|
|
4143
4703
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -4165,7 +4725,7 @@ var EchoHost = class extends Resource9 {
|
|
|
4165
4725
|
async openSpaceRoot(spaceId, automergeUrl) {
|
|
4166
4726
|
invariant13(this._lifecycleState === LifecycleState5.OPEN, void 0, {
|
|
4167
4727
|
F: __dxlog_file16,
|
|
4168
|
-
L:
|
|
4728
|
+
L: 273,
|
|
4169
4729
|
S: this,
|
|
4170
4730
|
A: [
|
|
4171
4731
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -4192,29 +4752,137 @@ var EchoHost = class extends Resource9 {
|
|
|
4192
4752
|
async removeReplicator(replicator) {
|
|
4193
4753
|
await this._automergeHost.removeReplicator(replicator);
|
|
4194
4754
|
}
|
|
4755
|
+
constructor({ kv, indexing = {}, peerIdProvider, getSpaceKeyByRootDocumentId }) {
|
|
4756
|
+
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);
|
|
4757
|
+
const indexingConfig = {
|
|
4758
|
+
...DEFAULT_INDEXING_CONFIG,
|
|
4759
|
+
...indexing
|
|
4760
|
+
};
|
|
4761
|
+
this._indexMetadataStore = new IndexMetadataStore({
|
|
4762
|
+
db: kv.sublevel("index-metadata")
|
|
4763
|
+
});
|
|
4764
|
+
this._echoDataMonitor = new EchoDataMonitor();
|
|
4765
|
+
this._automergeHost = new AutomergeHost({
|
|
4766
|
+
db: kv,
|
|
4767
|
+
dataMonitor: this._echoDataMonitor,
|
|
4768
|
+
indexMetadataStore: this._indexMetadataStore,
|
|
4769
|
+
peerIdProvider,
|
|
4770
|
+
getSpaceKeyByRootDocumentId
|
|
4771
|
+
});
|
|
4772
|
+
this._indexer = new Indexer({
|
|
4773
|
+
db: kv,
|
|
4774
|
+
indexStore: new IndexStore({
|
|
4775
|
+
db: kv.sublevel("index-storage")
|
|
4776
|
+
}),
|
|
4777
|
+
metadataStore: this._indexMetadataStore,
|
|
4778
|
+
loadDocuments: createSelectedDocumentsIterator(this._automergeHost),
|
|
4779
|
+
indexCooldownTime: false ? 0 : void 0
|
|
4780
|
+
});
|
|
4781
|
+
void this._indexer.setConfig({
|
|
4782
|
+
enabled: true,
|
|
4783
|
+
indexes: [
|
|
4784
|
+
//
|
|
4785
|
+
{
|
|
4786
|
+
kind: IndexKind.Kind.SCHEMA_MATCH
|
|
4787
|
+
},
|
|
4788
|
+
{
|
|
4789
|
+
kind: IndexKind.Kind.GRAPH
|
|
4790
|
+
},
|
|
4791
|
+
...indexingConfig.fullText ? [
|
|
4792
|
+
{
|
|
4793
|
+
kind: IndexKind.Kind.FULL_TEXT
|
|
4794
|
+
}
|
|
4795
|
+
] : [],
|
|
4796
|
+
...indexingConfig.vector ? [
|
|
4797
|
+
{
|
|
4798
|
+
kind: IndexKind.Kind.VECTOR
|
|
4799
|
+
}
|
|
4800
|
+
] : []
|
|
4801
|
+
]
|
|
4802
|
+
});
|
|
4803
|
+
this._queryService = new QueryServiceImpl({
|
|
4804
|
+
automergeHost: this._automergeHost,
|
|
4805
|
+
indexer: this._indexer,
|
|
4806
|
+
spaceStateManager: this._spaceStateManager
|
|
4807
|
+
});
|
|
4808
|
+
this._dataService = new DataServiceImpl({
|
|
4809
|
+
automergeHost: this._automergeHost,
|
|
4810
|
+
spaceStateManager: this._spaceStateManager,
|
|
4811
|
+
updateIndexes: async () => {
|
|
4812
|
+
await this._indexer.updateIndexes();
|
|
4813
|
+
}
|
|
4814
|
+
});
|
|
4815
|
+
trace5.diagnostic({
|
|
4816
|
+
id: "echo-stats",
|
|
4817
|
+
name: "Echo Stats",
|
|
4818
|
+
fetch: async () => {
|
|
4819
|
+
return {
|
|
4820
|
+
dataStats: this._echoDataMonitor.computeStats(),
|
|
4821
|
+
loadedDocsCount: this._automergeHost.loadedDocsCount
|
|
4822
|
+
};
|
|
4823
|
+
}
|
|
4824
|
+
});
|
|
4825
|
+
trace5.diagnostic({
|
|
4826
|
+
id: "database-roots",
|
|
4827
|
+
name: "Database Roots",
|
|
4828
|
+
fetch: async () => {
|
|
4829
|
+
return Array.from(this._spaceStateManager.roots.values()).map((root) => ({
|
|
4830
|
+
url: root.url,
|
|
4831
|
+
isLoaded: root.isLoaded,
|
|
4832
|
+
spaceKey: root.getSpaceKey(),
|
|
4833
|
+
inlineObjects: root.getInlineObjectCount(),
|
|
4834
|
+
linkedObjects: root.getLinkedObjectCount()
|
|
4835
|
+
}));
|
|
4836
|
+
}
|
|
4837
|
+
});
|
|
4838
|
+
trace5.diagnostic({
|
|
4839
|
+
id: "database-root-metrics",
|
|
4840
|
+
name: "Database Roots (with metrics)",
|
|
4841
|
+
fetch: async () => {
|
|
4842
|
+
return Array.from(this._spaceStateManager.roots.values()).map((root) => ({
|
|
4843
|
+
url: root.url,
|
|
4844
|
+
isLoaded: root.isLoaded,
|
|
4845
|
+
spaceKey: root.getSpaceKey(),
|
|
4846
|
+
inlineObjects: root.getInlineObjectCount(),
|
|
4847
|
+
linkedObjects: root.getLinkedObjectCount(),
|
|
4848
|
+
...root.measureMetrics() ?? {}
|
|
4849
|
+
}));
|
|
4850
|
+
}
|
|
4851
|
+
});
|
|
4852
|
+
}
|
|
4195
4853
|
};
|
|
4196
4854
|
|
|
4197
|
-
//
|
|
4855
|
+
// src/edge/echo-edge-replicator.ts
|
|
4198
4856
|
import { cbor as cbor2 } from "@automerge/automerge-repo";
|
|
4199
|
-
import { Mutex,
|
|
4857
|
+
import { Mutex, scheduleMicroTask as scheduleMicroTask2, scheduleTask as scheduleTask2 } from "@dxos/async";
|
|
4200
4858
|
import { Context as Context6, Resource as Resource11 } from "@dxos/context";
|
|
4201
4859
|
import { randomUUID } from "@dxos/crypto";
|
|
4202
4860
|
import { invariant as invariant14 } from "@dxos/invariant";
|
|
4203
4861
|
import { log as log13 } from "@dxos/log";
|
|
4204
|
-
import { EdgeService } from "@dxos/protocols";
|
|
4862
|
+
import { DocumentCodec, EdgeService } from "@dxos/protocols";
|
|
4205
4863
|
import { buf } from "@dxos/protocols/buf";
|
|
4206
4864
|
import { MessageSchema as RouterMessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
4207
4865
|
import { bufferToArray as bufferToArray2 } from "@dxos/util";
|
|
4208
4866
|
|
|
4209
|
-
//
|
|
4867
|
+
// src/edge/inflight-request-limiter.ts
|
|
4210
4868
|
import { Trigger as Trigger2 } from "@dxos/async";
|
|
4211
4869
|
import { Resource as Resource10 } from "@dxos/context";
|
|
4212
4870
|
import { log as log12 } from "@dxos/log";
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4871
|
+
function _define_property17(obj, key, value) {
|
|
4872
|
+
if (key in obj) {
|
|
4873
|
+
Object.defineProperty(obj, key, {
|
|
4874
|
+
value,
|
|
4875
|
+
enumerable: true,
|
|
4876
|
+
configurable: true,
|
|
4877
|
+
writable: true
|
|
4878
|
+
});
|
|
4879
|
+
} else {
|
|
4880
|
+
obj[key] = value;
|
|
4217
4881
|
}
|
|
4882
|
+
return obj;
|
|
4883
|
+
}
|
|
4884
|
+
var __dxlog_file17 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/edge/inflight-request-limiter.ts";
|
|
4885
|
+
var InflightRequestLimiter = class extends Resource10 {
|
|
4218
4886
|
async _open() {
|
|
4219
4887
|
this._inflightRequestBalance = 0;
|
|
4220
4888
|
this._requestBarrier.reset();
|
|
@@ -4257,9 +4925,30 @@ var InflightRequestLimiter = class extends Resource10 {
|
|
|
4257
4925
|
clearInterval(this._resetBalanceTimeout);
|
|
4258
4926
|
}
|
|
4259
4927
|
}
|
|
4928
|
+
constructor(_config) {
|
|
4929
|
+
super(), _define_property17(this, "_config", void 0), /**
|
|
4930
|
+
* Decrement when we receive a sync message, increment when we send one.
|
|
4931
|
+
* Can't exceed _config.maxInflightRequests.
|
|
4932
|
+
* Resets after timeout to avoid replicator being stuck.
|
|
4933
|
+
*/
|
|
4934
|
+
_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();
|
|
4935
|
+
}
|
|
4260
4936
|
};
|
|
4261
4937
|
|
|
4262
|
-
//
|
|
4938
|
+
// src/edge/echo-edge-replicator.ts
|
|
4939
|
+
function _define_property18(obj, key, value) {
|
|
4940
|
+
if (key in obj) {
|
|
4941
|
+
Object.defineProperty(obj, key, {
|
|
4942
|
+
value,
|
|
4943
|
+
enumerable: true,
|
|
4944
|
+
configurable: true,
|
|
4945
|
+
writable: true
|
|
4946
|
+
});
|
|
4947
|
+
} else {
|
|
4948
|
+
obj[key] = value;
|
|
4949
|
+
}
|
|
4950
|
+
return obj;
|
|
4951
|
+
}
|
|
4263
4952
|
function _ts_add_disposable_resource(env, value, async) {
|
|
4264
4953
|
if (value !== null && value !== void 0) {
|
|
4265
4954
|
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
@@ -4325,35 +5014,25 @@ function _ts_dispose_resources(env) {
|
|
|
4325
5014
|
return next();
|
|
4326
5015
|
})(env);
|
|
4327
5016
|
}
|
|
4328
|
-
var __dxlog_file18 = "/
|
|
5017
|
+
var __dxlog_file18 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/edge/echo-edge-replicator.ts";
|
|
4329
5018
|
var INITIAL_RESTART_DELAY = 500;
|
|
4330
5019
|
var RESTART_DELAY_JITTER = 250;
|
|
4331
5020
|
var MAX_RESTART_DELAY = 5e3;
|
|
4332
5021
|
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
5022
|
async connect(context) {
|
|
4344
5023
|
log13("connecting...", {
|
|
4345
5024
|
peerId: context.peerId,
|
|
4346
5025
|
connectedSpaces: this._connectedSpaces.size
|
|
4347
5026
|
}, {
|
|
4348
5027
|
F: __dxlog_file18,
|
|
4349
|
-
L:
|
|
5028
|
+
L: 72,
|
|
4350
5029
|
S: this,
|
|
4351
5030
|
C: (f, a) => f(...a)
|
|
4352
5031
|
});
|
|
4353
5032
|
this._context = context;
|
|
4354
5033
|
this._ctx = Context6.default(void 0, {
|
|
4355
5034
|
F: __dxlog_file18,
|
|
4356
|
-
L:
|
|
5035
|
+
L: 74
|
|
4357
5036
|
});
|
|
4358
5037
|
this._ctx.onDispose(this._edgeConnection.onReconnected(() => {
|
|
4359
5038
|
this._ctx && scheduleMicroTask2(this._ctx, () => this._handleReconnect());
|
|
@@ -4452,7 +5131,7 @@ var EchoEdgeReplicator = class {
|
|
|
4452
5131
|
async _openConnection(spaceId, reconnects = 0) {
|
|
4453
5132
|
invariant14(this._context, void 0, {
|
|
4454
5133
|
F: __dxlog_file18,
|
|
4455
|
-
L:
|
|
5134
|
+
L: 135,
|
|
4456
5135
|
S: this,
|
|
4457
5136
|
A: [
|
|
4458
5137
|
"this._context",
|
|
@@ -4461,7 +5140,7 @@ var EchoEdgeReplicator = class {
|
|
|
4461
5140
|
});
|
|
4462
5141
|
invariant14(!this._connections.has(spaceId), void 0, {
|
|
4463
5142
|
F: __dxlog_file18,
|
|
4464
|
-
L:
|
|
5143
|
+
L: 136,
|
|
4465
5144
|
S: this,
|
|
4466
5145
|
A: [
|
|
4467
5146
|
"!this._connections.has(spaceId)",
|
|
@@ -4470,14 +5149,31 @@ var EchoEdgeReplicator = class {
|
|
|
4470
5149
|
});
|
|
4471
5150
|
let restartScheduled = false;
|
|
4472
5151
|
const connection = new EdgeReplicatorConnection({
|
|
5152
|
+
edgeHttpClient: this._edgeHttpClient,
|
|
4473
5153
|
edgeConnection: this._edgeConnection,
|
|
4474
5154
|
spaceId,
|
|
4475
5155
|
context: this._context,
|
|
4476
5156
|
sharedPolicyEnabled: this._sharePolicyEnabled,
|
|
4477
5157
|
onRemoteConnected: async () => {
|
|
5158
|
+
log13.trace("dxos.echo.edge.replicator.onRemoteConnected", {
|
|
5159
|
+
spaceId
|
|
5160
|
+
}, {
|
|
5161
|
+
F: __dxlog_file18,
|
|
5162
|
+
L: 147,
|
|
5163
|
+
S: this,
|
|
5164
|
+
C: (f, a) => f(...a)
|
|
5165
|
+
});
|
|
4478
5166
|
this._context?.onConnectionOpen(connection);
|
|
4479
5167
|
},
|
|
4480
5168
|
onRemoteDisconnected: async () => {
|
|
5169
|
+
log13.trace("dxos.echo.edge.replicator.onRemoteDisconnected", {
|
|
5170
|
+
spaceId
|
|
5171
|
+
}, {
|
|
5172
|
+
F: __dxlog_file18,
|
|
5173
|
+
L: 151,
|
|
5174
|
+
S: this,
|
|
5175
|
+
C: (f, a) => f(...a)
|
|
5176
|
+
});
|
|
4481
5177
|
this._context?.onConnectionClosed(connection);
|
|
4482
5178
|
},
|
|
4483
5179
|
onRestartRequested: async () => {
|
|
@@ -4491,7 +5187,7 @@ var EchoEdgeReplicator = class {
|
|
|
4491
5187
|
restartDelay
|
|
4492
5188
|
}, {
|
|
4493
5189
|
F: __dxlog_file18,
|
|
4494
|
-
L:
|
|
5190
|
+
L: 162,
|
|
4495
5191
|
S: this,
|
|
4496
5192
|
C: (f, a) => f(...a)
|
|
4497
5193
|
});
|
|
@@ -4513,6 +5209,16 @@ var EchoEdgeReplicator = class {
|
|
|
4513
5209
|
if (ctx?.disposed) {
|
|
4514
5210
|
return;
|
|
4515
5211
|
}
|
|
5212
|
+
log13.trace("dxos.echo.edge.replicator.restart", {
|
|
5213
|
+
spaceId,
|
|
5214
|
+
reconnects,
|
|
5215
|
+
restartDelay
|
|
5216
|
+
}, {
|
|
5217
|
+
F: __dxlog_file18,
|
|
5218
|
+
L: 179,
|
|
5219
|
+
S: this,
|
|
5220
|
+
C: (f, a) => f(...a)
|
|
5221
|
+
});
|
|
4516
5222
|
await this._openConnection(spaceId, reconnects + 1);
|
|
4517
5223
|
} catch (e) {
|
|
4518
5224
|
env.error = e;
|
|
@@ -4526,42 +5232,27 @@ var EchoEdgeReplicator = class {
|
|
|
4526
5232
|
this._connections.set(spaceId, connection);
|
|
4527
5233
|
await connection.open();
|
|
4528
5234
|
}
|
|
5235
|
+
constructor({ edgeConnection, edgeHttpClient, disableSharePolicy }) {
|
|
5236
|
+
_define_property18(this, "_edgeConnection", void 0);
|
|
5237
|
+
_define_property18(this, "_edgeHttpClient", void 0);
|
|
5238
|
+
_define_property18(this, "_mutex", new Mutex());
|
|
5239
|
+
_define_property18(this, "_ctx", void 0);
|
|
5240
|
+
_define_property18(this, "_context", null);
|
|
5241
|
+
_define_property18(this, "_connectedSpaces", /* @__PURE__ */ new Set());
|
|
5242
|
+
_define_property18(this, "_connections", /* @__PURE__ */ new Map());
|
|
5243
|
+
_define_property18(this, "_sharePolicyEnabled", true);
|
|
5244
|
+
this._edgeConnection = edgeConnection;
|
|
5245
|
+
this._edgeHttpClient = edgeHttpClient;
|
|
5246
|
+
this._sharePolicyEnabled = !disableSharePolicy;
|
|
5247
|
+
}
|
|
4529
5248
|
};
|
|
4530
5249
|
var MAX_INFLIGHT_REQUESTS = 5;
|
|
4531
5250
|
var MAX_RATE_LIMIT_WAIT_TIME_MS = 3e3;
|
|
4532
5251
|
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
5252
|
async _open(ctx) {
|
|
4562
5253
|
log13("opening...", void 0, {
|
|
4563
5254
|
F: __dxlog_file18,
|
|
4564
|
-
L:
|
|
5255
|
+
L: 270,
|
|
4565
5256
|
S: this,
|
|
4566
5257
|
C: (f, a) => f(...a)
|
|
4567
5258
|
});
|
|
@@ -4569,12 +5260,29 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
4569
5260
|
this._ctx.onDispose(this._edgeConnection.onMessage((msg) => {
|
|
4570
5261
|
this._onMessage(msg);
|
|
4571
5262
|
}));
|
|
5263
|
+
let firstReconnect = true;
|
|
5264
|
+
this._ctx.onDispose(
|
|
5265
|
+
// NOTE: This will fire immediately if the connection is already open.
|
|
5266
|
+
this._edgeConnection.onReconnected(async () => {
|
|
5267
|
+
if (firstReconnect) {
|
|
5268
|
+
log13.verbose("first reconnect skipped", void 0, {
|
|
5269
|
+
F: __dxlog_file18,
|
|
5270
|
+
L: 285,
|
|
5271
|
+
S: this,
|
|
5272
|
+
C: (f, a) => f(...a)
|
|
5273
|
+
});
|
|
5274
|
+
firstReconnect = false;
|
|
5275
|
+
return;
|
|
5276
|
+
}
|
|
5277
|
+
this._onRestartRequested();
|
|
5278
|
+
})
|
|
5279
|
+
);
|
|
4572
5280
|
await this._onRemoteConnected();
|
|
4573
5281
|
}
|
|
4574
5282
|
async _close() {
|
|
4575
5283
|
log13("closing...", void 0, {
|
|
4576
5284
|
F: __dxlog_file18,
|
|
4577
|
-
L:
|
|
5285
|
+
L: 298,
|
|
4578
5286
|
S: this,
|
|
4579
5287
|
C: (f, a) => f(...a)
|
|
4580
5288
|
});
|
|
@@ -4585,7 +5293,7 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
4585
5293
|
get peerId() {
|
|
4586
5294
|
invariant14(this._remotePeerId, "Not connected", {
|
|
4587
5295
|
F: __dxlog_file18,
|
|
4588
|
-
L:
|
|
5296
|
+
L: 307,
|
|
4589
5297
|
S: this,
|
|
4590
5298
|
A: [
|
|
4591
5299
|
"this._remotePeerId",
|
|
@@ -4610,7 +5318,7 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
4610
5318
|
remoteId: this._remotePeerId
|
|
4611
5319
|
}, {
|
|
4612
5320
|
F: __dxlog_file18,
|
|
4613
|
-
L:
|
|
5321
|
+
L: 322,
|
|
4614
5322
|
S: this,
|
|
4615
5323
|
C: (f, a) => f(...a)
|
|
4616
5324
|
});
|
|
@@ -4636,13 +5344,36 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
4636
5344
|
remoteId: this._remotePeerId
|
|
4637
5345
|
}, {
|
|
4638
5346
|
F: __dxlog_file18,
|
|
4639
|
-
L:
|
|
5347
|
+
L: 351,
|
|
4640
5348
|
S: this,
|
|
4641
5349
|
C: (f, a) => f(...a)
|
|
4642
5350
|
});
|
|
4643
5351
|
payload.senderId = this._remotePeerId;
|
|
4644
5352
|
this._processMessage(payload);
|
|
4645
5353
|
}
|
|
5354
|
+
get bundleSyncEnabled() {
|
|
5355
|
+
return true;
|
|
5356
|
+
}
|
|
5357
|
+
async pushBundle(bundle) {
|
|
5358
|
+
const request = {
|
|
5359
|
+
bundle: bundle.map(({ documentId, data, heads }) => ({
|
|
5360
|
+
documentId,
|
|
5361
|
+
mutation: DocumentCodec.encode(data),
|
|
5362
|
+
heads
|
|
5363
|
+
}))
|
|
5364
|
+
};
|
|
5365
|
+
await this._edgeHttpClient.importBundle(this._spaceId, request);
|
|
5366
|
+
}
|
|
5367
|
+
async pullBundle(docHeads) {
|
|
5368
|
+
const request = {
|
|
5369
|
+
docHeads
|
|
5370
|
+
};
|
|
5371
|
+
const response = await this._edgeHttpClient.exportBundle(this._spaceId, request);
|
|
5372
|
+
return Object.fromEntries(response.bundle.map((doc) => [
|
|
5373
|
+
doc.documentId,
|
|
5374
|
+
DocumentCodec.decode(doc.mutation)
|
|
5375
|
+
]));
|
|
5376
|
+
}
|
|
4646
5377
|
_processMessage(message) {
|
|
4647
5378
|
if (isForbiddenErrorMessage(message)) {
|
|
4648
5379
|
this._onRestartRequested();
|
|
@@ -4659,27 +5390,65 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
4659
5390
|
remoteId: this._remotePeerId
|
|
4660
5391
|
}, {
|
|
4661
5392
|
F: __dxlog_file18,
|
|
4662
|
-
L:
|
|
5393
|
+
L: 401,
|
|
4663
5394
|
S: this,
|
|
4664
5395
|
C: (f, a) => f(...a)
|
|
4665
5396
|
});
|
|
4666
5397
|
const encoded = cbor2.encode(message);
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
5398
|
+
try {
|
|
5399
|
+
await this._edgeConnection.send(buf.create(RouterMessageSchema, {
|
|
5400
|
+
serviceId: this._targetServiceId,
|
|
5401
|
+
source: {
|
|
5402
|
+
identityKey: this._edgeConnection.identityKey,
|
|
5403
|
+
peerKey: this._edgeConnection.peerKey
|
|
5404
|
+
},
|
|
5405
|
+
payload: {
|
|
5406
|
+
value: bufferToArray2(encoded)
|
|
5407
|
+
}
|
|
5408
|
+
}));
|
|
5409
|
+
} catch (err) {
|
|
5410
|
+
log13.error("failed to send message", {
|
|
5411
|
+
err
|
|
5412
|
+
}, {
|
|
5413
|
+
F: __dxlog_file18,
|
|
5414
|
+
L: 421,
|
|
5415
|
+
S: this,
|
|
5416
|
+
C: (f, a) => f(...a)
|
|
5417
|
+
});
|
|
5418
|
+
}
|
|
5419
|
+
}
|
|
5420
|
+
constructor({ edgeConnection, edgeHttpClient, spaceId, context, sharedPolicyEnabled, onRemoteConnected, onRemoteDisconnected, onRestartRequested }) {
|
|
5421
|
+
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({
|
|
5422
|
+
maxInflightRequests: MAX_INFLIGHT_REQUESTS,
|
|
5423
|
+
resetBalanceTimeoutMs: MAX_RATE_LIMIT_WAIT_TIME_MS
|
|
5424
|
+
})), _define_property18(this, "_readableStreamController", void 0), _define_property18(this, "readable", void 0), _define_property18(this, "writable", void 0);
|
|
5425
|
+
this._edgeConnection = edgeConnection;
|
|
5426
|
+
this._edgeHttpClient = edgeHttpClient;
|
|
5427
|
+
this._spaceId = spaceId;
|
|
5428
|
+
this._context = context;
|
|
5429
|
+
this._remotePeerId = `${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}-${randomUUID()}`;
|
|
5430
|
+
this._targetServiceId = `${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}`;
|
|
5431
|
+
this._sharedPolicyEnabled = sharedPolicyEnabled;
|
|
5432
|
+
this._onRemoteConnected = onRemoteConnected;
|
|
5433
|
+
this._onRemoteDisconnected = onRemoteDisconnected;
|
|
5434
|
+
this._onRestartRequested = onRestartRequested;
|
|
5435
|
+
this.readable = new ReadableStream({
|
|
5436
|
+
start: (controller) => {
|
|
5437
|
+
this._readableStreamController = controller;
|
|
4675
5438
|
}
|
|
4676
|
-
})
|
|
5439
|
+
});
|
|
5440
|
+
this.writable = new WritableStream({
|
|
5441
|
+
write: async (message, controller) => {
|
|
5442
|
+
await this._requestLimiter.rateLimit(message);
|
|
5443
|
+
await this._sendMessage(message);
|
|
5444
|
+
}
|
|
5445
|
+
});
|
|
4677
5446
|
}
|
|
4678
5447
|
};
|
|
4679
5448
|
var isForbiddenErrorMessage = (message) => message.type === "error" && message.message === "Forbidden";
|
|
4680
5449
|
|
|
4681
|
-
//
|
|
4682
|
-
import {
|
|
5450
|
+
// src/util.ts
|
|
5451
|
+
import { ObjectStructure as ObjectStructure2, decodeReference } from "@dxos/echo-protocol";
|
|
4683
5452
|
var findInlineObjectOfType = (spaceDoc, typename) => {
|
|
4684
5453
|
for (const id in spaceDoc.objects ?? {}) {
|
|
4685
5454
|
const obj = spaceDoc.objects[id];
|
|
@@ -4731,6 +5500,7 @@ export {
|
|
|
4731
5500
|
diffCollectionState,
|
|
4732
5501
|
encodingOptions,
|
|
4733
5502
|
filterMatchObject,
|
|
5503
|
+
filterMatchObjectJSON,
|
|
4734
5504
|
filterMatchValue,
|
|
4735
5505
|
findInlineObjectOfType,
|
|
4736
5506
|
getSpaceIdFromCollectionId,
|