@dxos/echo-pipeline 0.8.4-main.dedc0f3 → 0.8.4-main.e8ec1fe
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-I4JBIZSN.mjs → chunk-FR6GJ4S4.mjs} +341 -427
- package/dist/lib/browser/{chunk-I4JBIZSN.mjs.map → chunk-FR6GJ4S4.mjs.map} +2 -2
- package/dist/lib/browser/{chunk-MBMJB3V7.mjs → chunk-WJJXJTNS.mjs} +62 -4
- package/dist/lib/browser/chunk-WJJXJTNS.mjs.map +7 -0
- package/dist/lib/browser/filter/index.mjs +1 -1
- package/dist/lib/browser/index.mjs +797 -802
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +65 -106
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/{chunk-YOL7JY5W.mjs → chunk-JQCCVDLT.mjs} +341 -427
- package/dist/lib/node-esm/{chunk-YOL7JY5W.mjs.map → chunk-JQCCVDLT.mjs.map} +2 -2
- package/dist/lib/node-esm/{chunk-XJZTCD4G.mjs → chunk-LEQ77KAT.mjs} +62 -4
- package/dist/lib/node-esm/chunk-LEQ77KAT.mjs.map +7 -0
- package/dist/lib/node-esm/filter/index.mjs +1 -1
- package/dist/lib/node-esm/index.mjs +797 -802
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +65 -106
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
- package/dist/types/src/automerge/collection-synchronizer.d.ts +2 -1
- package/dist/types/src/automerge/collection-synchronizer.d.ts.map +1 -1
- package/dist/types/src/db-host/query-service.d.ts.map +1 -1
- package/dist/types/src/edge/echo-edge-replicator.d.ts.map +1 -1
- package/dist/types/src/filter/filter-match.d.ts +2 -2
- package/dist/types/src/filter/filter-match.d.ts.map +1 -1
- package/dist/types/src/query/errors.d.ts +14 -13
- package/dist/types/src/query/errors.d.ts.map +1 -1
- package/dist/types/src/query/query-executor.d.ts +9 -0
- package/dist/types/src/query/query-executor.d.ts.map +1 -1
- package/dist/types/src/query/query-planner.d.ts.map +1 -1
- package/dist/types/src/testing/test-data.d.ts.map +1 -1
- package/dist/types/src/testing/test-schema.d.ts +1 -1
- package/dist/types/src/testing/test-schema.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +37 -39
- package/src/automerge/automerge-host.ts +34 -21
- package/src/automerge/collection-synchronizer.test.ts +4 -3
- package/src/automerge/collection-synchronizer.ts +14 -9
- package/src/db-host/echo-host.ts +1 -1
- package/src/db-host/query-service.ts +2 -1
- package/src/edge/echo-edge-replicator.ts +30 -9
- package/src/filter/filter-match.test.ts +32 -12
- package/src/filter/filter-match.ts +88 -11
- package/src/query/errors.ts +2 -0
- package/src/query/query-executor.ts +121 -36
- package/src/query/query-planner.test.ts +90 -5
- package/src/query/query-planner.ts +48 -12
- package/src/testing/test-data.ts +1 -1
- package/src/testing/test-schema.ts +1 -1
- package/dist/lib/browser/chunk-MBMJB3V7.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XJZTCD4G.mjs.map +0 -7
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
filterMatchObject,
|
|
4
4
|
filterMatchObjectJSON,
|
|
5
5
|
filterMatchValue
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-WJJXJTNS.mjs";
|
|
7
7
|
import {
|
|
8
8
|
AuthExtension,
|
|
9
9
|
AuthStatus,
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
mapTimeframeToFeedIndexes,
|
|
27
27
|
startAfter,
|
|
28
28
|
valueEncoding
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-FR6GJ4S4.mjs";
|
|
30
30
|
import "./chunk-CGS2ULMK.mjs";
|
|
31
31
|
|
|
32
32
|
// src/db-host/data-service.ts
|
|
@@ -39,7 +39,6 @@ import { log as log7 } from "@dxos/log";
|
|
|
39
39
|
// src/automerge/automerge-host.ts
|
|
40
40
|
import { getBackend, getHeads, equals as headsEquals, isAutomerge, save } from "@automerge/automerge";
|
|
41
41
|
import { Repo, interpretAsDocumentId } from "@automerge/automerge-repo";
|
|
42
|
-
import { exportBundle } from "@automerge/automerge-repo-bundles";
|
|
43
42
|
import { DeferredTask, Event as Event2, asyncTimeout } from "@dxos/async";
|
|
44
43
|
import { Context, Resource as Resource3, cancelWithContext } from "@dxos/context";
|
|
45
44
|
import { DatabaseDirectory } from "@dxos/echo-protocol";
|
|
@@ -48,28 +47,17 @@ import { PublicKey } from "@dxos/keys";
|
|
|
48
47
|
import { log as log3 } from "@dxos/log";
|
|
49
48
|
import { objectPointerCodec } from "@dxos/protocols";
|
|
50
49
|
import { trace as trace2 } from "@dxos/tracing";
|
|
51
|
-
import { ComplexSet, bufferToArray, range } from "@dxos/util";
|
|
50
|
+
import { ComplexSet, bufferToArray, isNonNullable as isNonNullable2, range } from "@dxos/util";
|
|
52
51
|
|
|
53
52
|
// src/automerge/collection-synchronizer.ts
|
|
54
|
-
import { next as
|
|
53
|
+
import { next as A } from "@automerge/automerge";
|
|
54
|
+
import * as Array2 from "effect/Array";
|
|
55
|
+
import * as Record from "effect/Record";
|
|
55
56
|
import { Event, asyncReturn, scheduleTask, scheduleTaskInterval } from "@dxos/async";
|
|
56
57
|
import { Resource } from "@dxos/context";
|
|
57
58
|
import { log } from "@dxos/log";
|
|
58
59
|
import { trace } from "@dxos/tracing";
|
|
59
60
|
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
|
-
}
|
|
73
61
|
function _ts_decorate(decorators, target, key, desc) {
|
|
74
62
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
75
63
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -80,6 +68,22 @@ var __dxlog_file = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerg
|
|
|
80
68
|
var MIN_QUERY_INTERVAL = 5e3;
|
|
81
69
|
var POLL_INTERVAL = 3e4;
|
|
82
70
|
var CollectionSynchronizer = class extends Resource {
|
|
71
|
+
_sendCollectionState;
|
|
72
|
+
_queryCollectionState;
|
|
73
|
+
_shouldSyncCollection;
|
|
74
|
+
/**
|
|
75
|
+
* CollectionId -> State.
|
|
76
|
+
*/
|
|
77
|
+
_perCollectionStates = /* @__PURE__ */ new Map();
|
|
78
|
+
_activeCollections = /* @__PURE__ */ new Set();
|
|
79
|
+
_connectedPeers = /* @__PURE__ */ new Set();
|
|
80
|
+
remoteStateUpdated = new Event();
|
|
81
|
+
constructor(params) {
|
|
82
|
+
super();
|
|
83
|
+
this._sendCollectionState = params.sendCollectionState;
|
|
84
|
+
this._queryCollectionState = params.queryCollectionState;
|
|
85
|
+
this._shouldSyncCollection = params.shouldSyncCollection;
|
|
86
|
+
}
|
|
83
87
|
async _open(ctx) {
|
|
84
88
|
scheduleTaskInterval(this._ctx, async () => {
|
|
85
89
|
for (const collectionId of this._perCollectionStates.keys()) {
|
|
@@ -105,7 +109,7 @@ var CollectionSynchronizer = class extends Resource {
|
|
|
105
109
|
state
|
|
106
110
|
}, {
|
|
107
111
|
F: __dxlog_file,
|
|
108
|
-
L:
|
|
112
|
+
L: 78,
|
|
109
113
|
S: this,
|
|
110
114
|
C: (f, a) => f(...a)
|
|
111
115
|
});
|
|
@@ -124,7 +128,7 @@ var CollectionSynchronizer = class extends Resource {
|
|
|
124
128
|
collectionId
|
|
125
129
|
}, {
|
|
126
130
|
F: __dxlog_file,
|
|
127
|
-
L:
|
|
131
|
+
L: 92,
|
|
128
132
|
S: this,
|
|
129
133
|
C: (f, a) => f(...a)
|
|
130
134
|
});
|
|
@@ -207,7 +211,7 @@ var CollectionSynchronizer = class extends Resource {
|
|
|
207
211
|
state
|
|
208
212
|
}, {
|
|
209
213
|
F: __dxlog_file,
|
|
210
|
-
L:
|
|
214
|
+
L: 173,
|
|
211
215
|
S: this,
|
|
212
216
|
C: (f, a) => f(...a)
|
|
213
217
|
});
|
|
@@ -258,33 +262,28 @@ var CollectionSynchronizer = class extends Resource {
|
|
|
258
262
|
}
|
|
259
263
|
}
|
|
260
264
|
}
|
|
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
|
-
}
|
|
270
265
|
};
|
|
271
266
|
CollectionSynchronizer = _ts_decorate([
|
|
272
267
|
trace.resource()
|
|
273
268
|
], CollectionSynchronizer);
|
|
274
269
|
var diffCollectionState = (local, remote) => {
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
270
|
+
const localDocuments = Record.filter(local.documents, (heads) => heads.length > 0);
|
|
271
|
+
const remoteDocuments = Record.filter(remote.documents, (heads) => heads.length > 0);
|
|
272
|
+
const allDocuments = [
|
|
273
|
+
.../* @__PURE__ */ new Set([
|
|
274
|
+
...Record.keys(localDocuments),
|
|
275
|
+
...Record.keys(remoteDocuments)
|
|
276
|
+
])
|
|
277
|
+
];
|
|
279
278
|
const missingOnRemote = [];
|
|
280
279
|
const missingOnLocal = [];
|
|
281
280
|
const different = [];
|
|
282
281
|
for (const documentId of allDocuments) {
|
|
283
|
-
if (!
|
|
282
|
+
if (!localDocuments[documentId]) {
|
|
284
283
|
missingOnLocal.push(documentId);
|
|
285
|
-
} else if (!
|
|
284
|
+
} else if (!remoteDocuments[documentId]) {
|
|
286
285
|
missingOnRemote.push(documentId);
|
|
287
|
-
} else if (!
|
|
286
|
+
} else if (!A.equals(local.documents[documentId], remote.documents[documentId])) {
|
|
288
287
|
different.push(documentId);
|
|
289
288
|
}
|
|
290
289
|
}
|
|
@@ -299,7 +298,7 @@ var validateCollectionState = (state) => {
|
|
|
299
298
|
if (!isValidDocumentId(documentId)) {
|
|
300
299
|
throw new Error(`Invalid documentId: ${documentId}`);
|
|
301
300
|
}
|
|
302
|
-
if (
|
|
301
|
+
if (Array2.isArray(heads) && heads.some((head) => typeof head !== "string")) {
|
|
303
302
|
throw new Error(`Invalid heads: ${heads}`);
|
|
304
303
|
}
|
|
305
304
|
});
|
|
@@ -325,19 +324,6 @@ var isCollectionQueryMessage = (message) => message.type === MESSAGE_TYPE_COLLEC
|
|
|
325
324
|
var isCollectionStateMessage = (message) => message.type === MESSAGE_TYPE_COLLECTION_STATE;
|
|
326
325
|
|
|
327
326
|
// 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
|
-
}
|
|
341
327
|
function _ts_decorate2(decorators, target, key, desc) {
|
|
342
328
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
343
329
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -346,6 +332,18 @@ function _ts_decorate2(decorators, target, key, desc) {
|
|
|
346
332
|
}
|
|
347
333
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts";
|
|
348
334
|
var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
335
|
+
_params;
|
|
336
|
+
_replicators = /* @__PURE__ */ new Set();
|
|
337
|
+
/**
|
|
338
|
+
* Remote peer id -> connection.
|
|
339
|
+
*/
|
|
340
|
+
_connections = /* @__PURE__ */ new Map();
|
|
341
|
+
_lifecycleState = LifecycleState.CLOSED;
|
|
342
|
+
_connected = new Trigger();
|
|
343
|
+
_ready = new Trigger();
|
|
344
|
+
constructor(_params) {
|
|
345
|
+
super(), this._params = _params;
|
|
346
|
+
}
|
|
349
347
|
isReady() {
|
|
350
348
|
return this._lifecycleState === LifecycleState.OPEN;
|
|
351
349
|
}
|
|
@@ -675,12 +673,6 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
675
673
|
peerMetadata: createEchoPeerMetadata()
|
|
676
674
|
});
|
|
677
675
|
}
|
|
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
|
-
}
|
|
684
676
|
};
|
|
685
677
|
_ts_decorate2([
|
|
686
678
|
synchronized
|
|
@@ -702,20 +694,11 @@ var isEchoPeerMetadata = (metadata) => metadata?.dxos_peerSource === "EchoNetwor
|
|
|
702
694
|
|
|
703
695
|
// src/automerge/heads-store.ts
|
|
704
696
|
import { headsEncoding } from "@dxos/indexing";
|
|
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;
|
|
715
|
-
}
|
|
716
|
-
return obj;
|
|
717
|
-
}
|
|
718
697
|
var HeadsStore = class {
|
|
698
|
+
_db;
|
|
699
|
+
constructor({ db }) {
|
|
700
|
+
this._db = db;
|
|
701
|
+
}
|
|
719
702
|
setHeads(documentId, heads, batch) {
|
|
720
703
|
batch.put(documentId, heads, {
|
|
721
704
|
sublevel: this._db,
|
|
@@ -730,28 +713,15 @@ var HeadsStore = class {
|
|
|
730
713
|
valueEncoding: headsEncoding
|
|
731
714
|
});
|
|
732
715
|
}
|
|
733
|
-
constructor({ db }) {
|
|
734
|
-
_define_property3(this, "_db", void 0);
|
|
735
|
-
this._db = db;
|
|
736
|
-
}
|
|
737
716
|
};
|
|
738
717
|
|
|
739
718
|
// src/automerge/leveldb-storage-adapter.ts
|
|
740
719
|
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;
|
|
751
|
-
}
|
|
752
|
-
return obj;
|
|
753
|
-
}
|
|
754
720
|
var LevelDBStorageAdapter = class extends Resource2 {
|
|
721
|
+
_params;
|
|
722
|
+
constructor(_params) {
|
|
723
|
+
super(), this._params = _params;
|
|
724
|
+
}
|
|
755
725
|
async load(keyArray) {
|
|
756
726
|
try {
|
|
757
727
|
if (!this.isOpen) {
|
|
@@ -839,9 +809,6 @@ var LevelDBStorageAdapter = class extends Resource2 {
|
|
|
839
809
|
}
|
|
840
810
|
await batch.write();
|
|
841
811
|
}
|
|
842
|
-
constructor(_params) {
|
|
843
|
-
super(), _define_property4(this, "_params", void 0), this._params = _params;
|
|
844
|
-
}
|
|
845
812
|
};
|
|
846
813
|
var keyEncoder = {
|
|
847
814
|
encode: (key) => Buffer.from(key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-")),
|
|
@@ -855,19 +822,6 @@ var encodingOptions = {
|
|
|
855
822
|
var isLevelDbNotFoundError = (err) => err.code === "LEVEL_NOT_FOUND";
|
|
856
823
|
|
|
857
824
|
// 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
|
-
}
|
|
871
825
|
function _ts_decorate3(decorators, target, key, desc) {
|
|
872
826
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
873
827
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -885,6 +839,57 @@ var BUNDLE_SIZE = 100;
|
|
|
885
839
|
var BUNDLE_SYNC_CONCURRENCY = 2;
|
|
886
840
|
var BUNDLE_SYNC_THRESHOLD = 50;
|
|
887
841
|
var AutomergeHost = class extends Resource3 {
|
|
842
|
+
_db;
|
|
843
|
+
_indexMetadataStore;
|
|
844
|
+
_echoNetworkAdapter;
|
|
845
|
+
_collectionSynchronizer = new CollectionSynchronizer({
|
|
846
|
+
queryCollectionState: this._queryCollectionState.bind(this),
|
|
847
|
+
sendCollectionState: this._sendCollectionState.bind(this),
|
|
848
|
+
shouldSyncCollection: this._shouldSyncCollection.bind(this)
|
|
849
|
+
});
|
|
850
|
+
_repo;
|
|
851
|
+
_storage;
|
|
852
|
+
_headsStore;
|
|
853
|
+
_syncTask = void 0;
|
|
854
|
+
/**
|
|
855
|
+
* Cache of collections that would be synced on next sync task run.
|
|
856
|
+
*/
|
|
857
|
+
_collectionsToSync = new ComplexSet(({ collectionId, peerId }) => `${collectionId}|${peerId}`);
|
|
858
|
+
_peerId;
|
|
859
|
+
_peerIdProvider;
|
|
860
|
+
_getSpaceKeyByRootDocumentId;
|
|
861
|
+
collectionStateUpdated = new Event2();
|
|
862
|
+
/**
|
|
863
|
+
* Fired after a batch of documents was saved to disk.
|
|
864
|
+
*/
|
|
865
|
+
documentsSaved = new Event2();
|
|
866
|
+
_headsUpdates = /* @__PURE__ */ new Map();
|
|
867
|
+
_onHeadsChangedTask;
|
|
868
|
+
constructor({ db, indexMetadataStore, dataMonitor, peerIdProvider, getSpaceKeyByRootDocumentId }) {
|
|
869
|
+
super();
|
|
870
|
+
this._db = db;
|
|
871
|
+
this._storage = new LevelDBStorageAdapter({
|
|
872
|
+
db: db.sublevel("automerge"),
|
|
873
|
+
callbacks: {
|
|
874
|
+
beforeSave: async (params) => this._beforeSave(params),
|
|
875
|
+
afterSave: async (key) => this._afterSave(key)
|
|
876
|
+
},
|
|
877
|
+
monitor: dataMonitor
|
|
878
|
+
});
|
|
879
|
+
this._echoNetworkAdapter = new EchoNetworkAdapter({
|
|
880
|
+
getContainingSpaceForDocument: this._getContainingSpaceForDocument.bind(this),
|
|
881
|
+
isDocumentInRemoteCollection: this._isDocumentInRemoteCollection.bind(this),
|
|
882
|
+
onCollectionStateQueried: this._onCollectionStateQueried.bind(this),
|
|
883
|
+
onCollectionStateReceived: this._onCollectionStateReceived.bind(this),
|
|
884
|
+
monitor: dataMonitor
|
|
885
|
+
});
|
|
886
|
+
this._headsStore = new HeadsStore({
|
|
887
|
+
db: db.sublevel("heads")
|
|
888
|
+
});
|
|
889
|
+
this._indexMetadataStore = indexMetadataStore;
|
|
890
|
+
this._peerIdProvider = peerIdProvider;
|
|
891
|
+
this._getSpaceKeyByRootDocumentId = getSpaceKeyByRootDocumentId;
|
|
892
|
+
}
|
|
888
893
|
async _open() {
|
|
889
894
|
this._peerId = `host-${this._peerIdProvider?.() ?? PublicKey.random().toHex()}`;
|
|
890
895
|
this._onHeadsChangedTask = new DeferredTask(this._ctx, async () => {
|
|
@@ -934,7 +939,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
934
939
|
err
|
|
935
940
|
}, {
|
|
936
941
|
F: __dxlog_file3,
|
|
937
|
-
L:
|
|
942
|
+
L: 223,
|
|
938
943
|
S: this,
|
|
939
944
|
C: (f, a) => f(...a)
|
|
940
945
|
});
|
|
@@ -968,7 +973,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
968
973
|
async addReplicator(replicator) {
|
|
969
974
|
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
970
975
|
F: __dxlog_file3,
|
|
971
|
-
L:
|
|
976
|
+
L: 259,
|
|
972
977
|
S: this,
|
|
973
978
|
A: [
|
|
974
979
|
"this.isOpen",
|
|
@@ -980,7 +985,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
980
985
|
async removeReplicator(replicator) {
|
|
981
986
|
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
982
987
|
F: __dxlog_file3,
|
|
983
|
-
L:
|
|
988
|
+
L: 264,
|
|
984
989
|
S: this,
|
|
985
990
|
A: [
|
|
986
991
|
"this.isOpen",
|
|
@@ -995,7 +1000,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
995
1000
|
async loadDoc(ctx, documentId, opts) {
|
|
996
1001
|
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
997
1002
|
F: __dxlog_file3,
|
|
998
|
-
L:
|
|
1003
|
+
L: 272,
|
|
999
1004
|
S: this,
|
|
1000
1005
|
A: [
|
|
1001
1006
|
"this.isOpen",
|
|
@@ -1021,7 +1026,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1021
1026
|
async exportDoc(ctx, id) {
|
|
1022
1027
|
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1023
1028
|
F: __dxlog_file3,
|
|
1024
|
-
L:
|
|
1029
|
+
L: 295,
|
|
1025
1030
|
S: this,
|
|
1026
1031
|
A: [
|
|
1027
1032
|
"this.isOpen",
|
|
@@ -1040,7 +1045,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1040
1045
|
createDoc(initialValue, opts) {
|
|
1041
1046
|
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1042
1047
|
F: __dxlog_file3,
|
|
1043
|
-
L:
|
|
1048
|
+
L: 306,
|
|
1044
1049
|
S: this,
|
|
1045
1050
|
A: [
|
|
1046
1051
|
"this.isOpen",
|
|
@@ -1065,7 +1070,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1065
1070
|
async waitUntilHeadsReplicated(heads) {
|
|
1066
1071
|
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1067
1072
|
F: __dxlog_file3,
|
|
1068
|
-
L:
|
|
1073
|
+
L: 328,
|
|
1069
1074
|
S: this,
|
|
1070
1075
|
A: [
|
|
1071
1076
|
"this.isOpen",
|
|
@@ -1087,10 +1092,10 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1087
1092
|
return !(currentHeads !== null && headsEquals(currentHeads, targetHeads));
|
|
1088
1093
|
});
|
|
1089
1094
|
if (headsToWait.length > 0) {
|
|
1090
|
-
await Promise.all(headsToWait.map(async (entry
|
|
1095
|
+
await Promise.all(headsToWait.map(async (entry) => {
|
|
1091
1096
|
const handle = await this.loadDoc(Context.default(void 0, {
|
|
1092
1097
|
F: __dxlog_file3,
|
|
1093
|
-
L:
|
|
1098
|
+
L: 346
|
|
1094
1099
|
}), entry.documentId);
|
|
1095
1100
|
await waitForHeads(handle, entry.heads);
|
|
1096
1101
|
}));
|
|
@@ -1100,7 +1105,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1100
1105
|
async reIndexHeads(documentIds) {
|
|
1101
1106
|
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1102
1107
|
F: __dxlog_file3,
|
|
1103
|
-
L:
|
|
1108
|
+
L: 359,
|
|
1104
1109
|
S: this,
|
|
1105
1110
|
A: [
|
|
1106
1111
|
"this.isOpen",
|
|
@@ -1112,7 +1117,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1112
1117
|
documentId
|
|
1113
1118
|
}, {
|
|
1114
1119
|
F: __dxlog_file3,
|
|
1115
|
-
L:
|
|
1120
|
+
L: 361,
|
|
1116
1121
|
S: this,
|
|
1117
1122
|
C: (f, a) => f(...a)
|
|
1118
1123
|
});
|
|
@@ -1122,7 +1127,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1122
1127
|
documentId
|
|
1123
1128
|
}, {
|
|
1124
1129
|
F: __dxlog_file3,
|
|
1125
|
-
L:
|
|
1130
|
+
L: 364,
|
|
1126
1131
|
S: this,
|
|
1127
1132
|
C: (f, a) => f(...a)
|
|
1128
1133
|
});
|
|
@@ -1135,7 +1140,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1135
1140
|
}
|
|
1136
1141
|
log3("done re-indexing heads", void 0, {
|
|
1137
1142
|
F: __dxlog_file3,
|
|
1138
|
-
L:
|
|
1143
|
+
L: 373,
|
|
1139
1144
|
S: this,
|
|
1140
1145
|
C: (f, a) => f(...a)
|
|
1141
1146
|
});
|
|
@@ -1145,9 +1150,6 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1145
1150
|
// NOTE: If both peers return sharePolicy=false the replication will not happen
|
|
1146
1151
|
// https://github.com/automerge/automerge-repo/pull/292
|
|
1147
1152
|
async _sharePolicy(peerId, documentId) {
|
|
1148
|
-
if (peerId.startsWith("client-")) {
|
|
1149
|
-
return false;
|
|
1150
|
-
}
|
|
1151
1153
|
if (!documentId) {
|
|
1152
1154
|
return false;
|
|
1153
1155
|
}
|
|
@@ -1213,7 +1215,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1213
1215
|
this._headsUpdates.set(documentId, heads);
|
|
1214
1216
|
invariant2(this._onHeadsChangedTask, "onHeadsChangedTask is not initialized", {
|
|
1215
1217
|
F: __dxlog_file3,
|
|
1216
|
-
L:
|
|
1218
|
+
L: 445,
|
|
1217
1219
|
S: this,
|
|
1218
1220
|
A: [
|
|
1219
1221
|
"this._onHeadsChangedTask",
|
|
@@ -1257,11 +1259,12 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1257
1259
|
* Flush documents to disk.
|
|
1258
1260
|
*/
|
|
1259
1261
|
async flush({ documentIds } = {}) {
|
|
1260
|
-
const loadedDocuments = documentIds
|
|
1262
|
+
const loadedDocuments = (documentIds ?? Object.keys(this._repo.handles)).filter((documentId) => {
|
|
1261
1263
|
const handle = this._repo.handles[documentId];
|
|
1262
1264
|
return handle && handle.isReady();
|
|
1263
1265
|
});
|
|
1264
1266
|
await this._repo.flush(loadedDocuments);
|
|
1267
|
+
await this._onHeadsChangedTask?.runBlocking();
|
|
1265
1268
|
}
|
|
1266
1269
|
async getHeads(documentIds) {
|
|
1267
1270
|
const result = [];
|
|
@@ -1396,7 +1399,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1396
1399
|
amount: missingOnRemote.length
|
|
1397
1400
|
}, {
|
|
1398
1401
|
F: __dxlog_file3,
|
|
1399
|
-
L:
|
|
1402
|
+
L: 650,
|
|
1400
1403
|
S: this,
|
|
1401
1404
|
C: (f, a) => f(...a)
|
|
1402
1405
|
});
|
|
@@ -1409,7 +1412,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1409
1412
|
amount: missingOnRemote.length
|
|
1410
1413
|
}, {
|
|
1411
1414
|
F: __dxlog_file3,
|
|
1412
|
-
L:
|
|
1415
|
+
L: 654,
|
|
1413
1416
|
S: this,
|
|
1414
1417
|
C: (f, a) => f(...a)
|
|
1415
1418
|
});
|
|
@@ -1420,7 +1423,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1420
1423
|
amount: missingOnLocal.length
|
|
1421
1424
|
}, {
|
|
1422
1425
|
F: __dxlog_file3,
|
|
1423
|
-
L:
|
|
1426
|
+
L: 662,
|
|
1424
1427
|
S: this,
|
|
1425
1428
|
C: (f, a) => f(...a)
|
|
1426
1429
|
});
|
|
@@ -1433,7 +1436,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1433
1436
|
amount: missingOnLocal.length
|
|
1434
1437
|
}, {
|
|
1435
1438
|
F: __dxlog_file3,
|
|
1436
|
-
L:
|
|
1439
|
+
L: 666,
|
|
1437
1440
|
S: this,
|
|
1438
1441
|
C: (f, a) => f(...a)
|
|
1439
1442
|
});
|
|
@@ -1449,7 +1452,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1449
1452
|
count: toReplicateWithoutBatching.length
|
|
1450
1453
|
}, {
|
|
1451
1454
|
F: __dxlog_file3,
|
|
1452
|
-
L:
|
|
1455
|
+
L: 678,
|
|
1453
1456
|
S: this,
|
|
1454
1457
|
C: (f, a) => f(...a)
|
|
1455
1458
|
});
|
|
@@ -1477,7 +1480,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1477
1480
|
err
|
|
1478
1481
|
}, {
|
|
1479
1482
|
F: __dxlog_file3,
|
|
1480
|
-
L:
|
|
1483
|
+
L: 709,
|
|
1481
1484
|
S: this,
|
|
1482
1485
|
C: (f, a) => f(...a)
|
|
1483
1486
|
});
|
|
@@ -1493,13 +1496,38 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1493
1496
|
if (this._ctx.disposed) {
|
|
1494
1497
|
return;
|
|
1495
1498
|
}
|
|
1496
|
-
const
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1499
|
+
const docs = documentIds.map((documentId) => {
|
|
1500
|
+
const handle = this._repo.handles[documentId];
|
|
1501
|
+
if (!handle || !handle.isReady()) {
|
|
1502
|
+
log3.warn("document not ready, skipping", {
|
|
1503
|
+
documentId
|
|
1504
|
+
}, {
|
|
1505
|
+
F: __dxlog_file3,
|
|
1506
|
+
L: 727,
|
|
1507
|
+
S: this,
|
|
1508
|
+
C: (f, a) => f(...a)
|
|
1509
|
+
});
|
|
1510
|
+
return;
|
|
1511
|
+
}
|
|
1512
|
+
const doc = handle.doc();
|
|
1513
|
+
if (!doc) {
|
|
1514
|
+
log3.warn("document not available, skipping", {
|
|
1515
|
+
documentId
|
|
1516
|
+
}, {
|
|
1517
|
+
F: __dxlog_file3,
|
|
1518
|
+
L: 732,
|
|
1519
|
+
S: this,
|
|
1520
|
+
C: (f, a) => f(...a)
|
|
1521
|
+
});
|
|
1522
|
+
return;
|
|
1523
|
+
}
|
|
1524
|
+
return {
|
|
1525
|
+
documentId,
|
|
1526
|
+
data: save(doc),
|
|
1527
|
+
heads: getHeads(doc)
|
|
1528
|
+
};
|
|
1529
|
+
});
|
|
1530
|
+
await this._echoNetworkAdapter.pushBundle(peerId, docs.filter(isNonNullable2));
|
|
1503
1531
|
}
|
|
1504
1532
|
async _pullInBundles(peerId, documentIds) {
|
|
1505
1533
|
const documentsToPull = [
|
|
@@ -1520,7 +1548,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1520
1548
|
err
|
|
1521
1549
|
}, {
|
|
1522
1550
|
F: __dxlog_file3,
|
|
1523
|
-
L:
|
|
1551
|
+
L: 762,
|
|
1524
1552
|
S: this,
|
|
1525
1553
|
C: (f, a) => f(...a)
|
|
1526
1554
|
});
|
|
@@ -1558,9 +1586,12 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1558
1586
|
const collectionsChanged = /* @__PURE__ */ new Set();
|
|
1559
1587
|
for (const collectionId of this._collectionSynchronizer.getRegisteredCollectionIds()) {
|
|
1560
1588
|
const state = this._collectionSynchronizer.getLocalCollectionState(collectionId);
|
|
1589
|
+
if (!state) {
|
|
1590
|
+
continue;
|
|
1591
|
+
}
|
|
1561
1592
|
let newState;
|
|
1562
1593
|
for (const [documentId, heads] of docHeads) {
|
|
1563
|
-
if (state
|
|
1594
|
+
if (documentId in state.documents) {
|
|
1564
1595
|
if (!newState) {
|
|
1565
1596
|
newState = structuredClone(state);
|
|
1566
1597
|
}
|
|
@@ -1578,41 +1609,6 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1578
1609
|
});
|
|
1579
1610
|
}
|
|
1580
1611
|
}
|
|
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
1612
|
};
|
|
1617
1613
|
_ts_decorate3([
|
|
1618
1614
|
trace2.info()
|
|
@@ -1648,7 +1644,7 @@ var changeIsPresentInDoc = (doc, changeHash) => {
|
|
|
1648
1644
|
var decodeCollectionState = (state) => {
|
|
1649
1645
|
invariant2(typeof state === "object" && state !== null, "Invalid state", {
|
|
1650
1646
|
F: __dxlog_file3,
|
|
1651
|
-
L:
|
|
1647
|
+
L: 845,
|
|
1652
1648
|
S: void 0,
|
|
1653
1649
|
A: [
|
|
1654
1650
|
"typeof state === 'object' && state !== null",
|
|
@@ -1668,81 +1664,24 @@ import { log as log5 } from "@dxos/log";
|
|
|
1668
1664
|
import { ComplexSet as ComplexSet2, defaultMap as defaultMap2 } from "@dxos/util";
|
|
1669
1665
|
|
|
1670
1666
|
// src/automerge/mesh-echo-replicator-connection.ts
|
|
1671
|
-
import * as
|
|
1667
|
+
import * as A2 from "@automerge/automerge";
|
|
1672
1668
|
import { cbor } from "@automerge/automerge-repo";
|
|
1673
1669
|
import { Resource as Resource4 } from "@dxos/context";
|
|
1674
1670
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1675
1671
|
import { log as log4 } from "@dxos/log";
|
|
1676
1672
|
import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
|
|
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
1673
|
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator-connection.ts";
|
|
1691
1674
|
var DEFAULT_FACTORY = (params) => new AutomergeReplicator(...params);
|
|
1692
1675
|
var MeshReplicatorConnection = class extends Resource4 {
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
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
|
-
}
|
|
1676
|
+
_params;
|
|
1677
|
+
readable;
|
|
1678
|
+
writable;
|
|
1679
|
+
remoteDeviceKey = null;
|
|
1680
|
+
replicatorExtension;
|
|
1681
|
+
_remotePeerId = null;
|
|
1682
|
+
_isEnabled = false;
|
|
1744
1683
|
constructor(_params) {
|
|
1745
|
-
super(),
|
|
1684
|
+
super(), this._params = _params;
|
|
1746
1685
|
let readableStreamController;
|
|
1747
1686
|
this.readable = new ReadableStream({
|
|
1748
1687
|
start: (controller) => {
|
|
@@ -1806,10 +1745,61 @@ var MeshReplicatorConnection = class extends Resource4 {
|
|
|
1806
1745
|
}
|
|
1807
1746
|
]);
|
|
1808
1747
|
}
|
|
1748
|
+
_disconnectIfEnabled() {
|
|
1749
|
+
if (this._isEnabled) {
|
|
1750
|
+
this._params.onRemoteDisconnected();
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
get peerId() {
|
|
1754
|
+
invariant3(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1755
|
+
F: __dxlog_file4,
|
|
1756
|
+
L: 106,
|
|
1757
|
+
S: this,
|
|
1758
|
+
A: [
|
|
1759
|
+
"this._remotePeerId != null",
|
|
1760
|
+
"'Remote peer has not connected yet.'"
|
|
1761
|
+
]
|
|
1762
|
+
});
|
|
1763
|
+
return this._remotePeerId;
|
|
1764
|
+
}
|
|
1765
|
+
get isEnabled() {
|
|
1766
|
+
return this._isEnabled;
|
|
1767
|
+
}
|
|
1768
|
+
get bundleSyncEnabled() {
|
|
1769
|
+
return false;
|
|
1770
|
+
}
|
|
1771
|
+
async shouldAdvertise(params) {
|
|
1772
|
+
return this._params.shouldAdvertise(params);
|
|
1773
|
+
}
|
|
1774
|
+
shouldSyncCollection(params) {
|
|
1775
|
+
return this._params.shouldSyncCollection(params);
|
|
1776
|
+
}
|
|
1777
|
+
/**
|
|
1778
|
+
* Start exchanging messages with the remote peer.
|
|
1779
|
+
* Call after the remote peer has connected.
|
|
1780
|
+
*/
|
|
1781
|
+
enable() {
|
|
1782
|
+
invariant3(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1783
|
+
F: __dxlog_file4,
|
|
1784
|
+
L: 131,
|
|
1785
|
+
S: this,
|
|
1786
|
+
A: [
|
|
1787
|
+
"this._remotePeerId != null",
|
|
1788
|
+
"'Remote peer has not connected yet.'"
|
|
1789
|
+
]
|
|
1790
|
+
});
|
|
1791
|
+
this._isEnabled = true;
|
|
1792
|
+
}
|
|
1793
|
+
/**
|
|
1794
|
+
* Stop exchanging messages with the remote peer.
|
|
1795
|
+
*/
|
|
1796
|
+
disable() {
|
|
1797
|
+
this._isEnabled = false;
|
|
1798
|
+
}
|
|
1809
1799
|
};
|
|
1810
1800
|
var logSendSync = (message) => {
|
|
1811
1801
|
log4("sendSyncMessage", () => {
|
|
1812
|
-
const decodedSyncMessage = message.type === "sync" && message.data ?
|
|
1802
|
+
const decodedSyncMessage = message.type === "sync" && message.data ? A2.decodeSyncMessage(message.data) : void 0;
|
|
1813
1803
|
return {
|
|
1814
1804
|
sync: decodedSyncMessage && {
|
|
1815
1805
|
headsLength: decodedSyncMessage.heads.length,
|
|
@@ -1848,21 +1838,24 @@ var getSpaceIdFromCollectionId = (collectionId) => {
|
|
|
1848
1838
|
};
|
|
1849
1839
|
|
|
1850
1840
|
// 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;
|
|
1861
|
-
}
|
|
1862
|
-
return obj;
|
|
1863
|
-
}
|
|
1864
1841
|
var __dxlog_file6 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts";
|
|
1865
1842
|
var MeshEchoReplicator = class {
|
|
1843
|
+
/**
|
|
1844
|
+
* We might have multiple connections open with a peer (one per space), but there'll be only one enabled
|
|
1845
|
+
* connection at any given moment, because there's a single repo for all the spaces.
|
|
1846
|
+
* When a connection closes (space was closed) it gets removed from the list and the next connection
|
|
1847
|
+
* in the line gets enabled.
|
|
1848
|
+
*/
|
|
1849
|
+
_connectionsPerPeer = /* @__PURE__ */ new Map();
|
|
1850
|
+
/**
|
|
1851
|
+
* A set of all connections (enabled and disabled).
|
|
1852
|
+
*/
|
|
1853
|
+
_connections = /* @__PURE__ */ new Set();
|
|
1854
|
+
/**
|
|
1855
|
+
* spaceId -> deviceKey[]
|
|
1856
|
+
*/
|
|
1857
|
+
_authorizedDevices = /* @__PURE__ */ new Map();
|
|
1858
|
+
_context = null;
|
|
1866
1859
|
async connect(context) {
|
|
1867
1860
|
this._context = context;
|
|
1868
1861
|
}
|
|
@@ -2075,30 +2068,11 @@ var MeshEchoReplicator = class {
|
|
|
2075
2068
|
}
|
|
2076
2069
|
}
|
|
2077
2070
|
}
|
|
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
|
-
}
|
|
2084
2071
|
};
|
|
2085
2072
|
|
|
2086
2073
|
// src/automerge/echo-data-monitor.ts
|
|
2087
2074
|
import { trace as trace3 } from "@dxos/tracing";
|
|
2088
2075
|
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
|
-
}
|
|
2102
2076
|
function _ts_decorate4(decorators, target, key, desc) {
|
|
2103
2077
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2104
2078
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -2108,6 +2082,22 @@ function _ts_decorate4(decorators, target, key, desc) {
|
|
|
2108
2082
|
var PER_SECOND_RATE_AVG_WINDOW_SIZE = 5;
|
|
2109
2083
|
var DEFAULT_AVG_WINDOW_SIZE = 25;
|
|
2110
2084
|
var EchoDataMonitor = class {
|
|
2085
|
+
_params;
|
|
2086
|
+
_lastTick = 0;
|
|
2087
|
+
_activeCounters = createLocalCounters();
|
|
2088
|
+
_lastCompleteCounters;
|
|
2089
|
+
_localTimeSeries = createLocalTimeSeries();
|
|
2090
|
+
_storageAverages = createStorageAverages();
|
|
2091
|
+
_replicationAverages = createNetworkAverages();
|
|
2092
|
+
_sizeByMessage = {};
|
|
2093
|
+
_lastReceivedMessages = new CircularBuffer(100);
|
|
2094
|
+
_lastSentMessages = new CircularBuffer(100);
|
|
2095
|
+
_connectionsCount = 0;
|
|
2096
|
+
constructor(_params = {
|
|
2097
|
+
timeSeriesLength: 30
|
|
2098
|
+
}) {
|
|
2099
|
+
this._params = _params;
|
|
2100
|
+
}
|
|
2111
2101
|
tick(timeMs) {
|
|
2112
2102
|
this._advanceTimeWindow(timeMs - this._lastTick);
|
|
2113
2103
|
this._lastTick = timeMs;
|
|
@@ -2347,9 +2337,8 @@ var EchoDataMonitor = class {
|
|
|
2347
2337
|
messageCounts.failed++;
|
|
2348
2338
|
}
|
|
2349
2339
|
_getStatsForType(message) {
|
|
2350
|
-
|
|
2351
|
-
const
|
|
2352
|
-
const messageCounts = (_this__activeCounters_byType = this._activeCounters.byType)[_message_type1 = message.type] ?? (_this__activeCounters_byType[_message_type1] = createMessageCounter());
|
|
2340
|
+
const messageSize = this._sizeByMessage[message.type] ??= createSlidingWindow();
|
|
2341
|
+
const messageCounts = this._activeCounters.byType[message.type] ??= createMessageCounter();
|
|
2353
2342
|
return {
|
|
2354
2343
|
messageCounts,
|
|
2355
2344
|
messageSize
|
|
@@ -2358,48 +2347,21 @@ var EchoDataMonitor = class {
|
|
|
2358
2347
|
_computeMessageHistogram(groupKey) {
|
|
2359
2348
|
const result = {};
|
|
2360
2349
|
for (const receivedMessage of this._lastReceivedMessages) {
|
|
2361
|
-
|
|
2362
|
-
const counters = (_result = result)[_receivedMessage_groupKey = receivedMessage[groupKey]] ?? (_result[_receivedMessage_groupKey] = {
|
|
2350
|
+
const counters = result[receivedMessage[groupKey]] ??= {
|
|
2363
2351
|
received: 0,
|
|
2364
2352
|
sent: 0
|
|
2365
|
-
}
|
|
2353
|
+
};
|
|
2366
2354
|
counters.received++;
|
|
2367
2355
|
}
|
|
2368
2356
|
for (const receivedMessage of this._lastSentMessages) {
|
|
2369
|
-
|
|
2370
|
-
const counters = (_result1 = result)[_receivedMessage_groupKey1 = receivedMessage[groupKey]] ?? (_result1[_receivedMessage_groupKey1] = {
|
|
2357
|
+
const counters = result[receivedMessage[groupKey]] ??= {
|
|
2371
2358
|
received: 0,
|
|
2372
2359
|
sent: 0
|
|
2373
|
-
}
|
|
2360
|
+
};
|
|
2374
2361
|
counters.sent++;
|
|
2375
2362
|
}
|
|
2376
2363
|
return result;
|
|
2377
2364
|
}
|
|
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
|
-
}
|
|
2403
2365
|
};
|
|
2404
2366
|
EchoDataMonitor = _ts_decorate4([
|
|
2405
2367
|
trace3.resource()
|
|
@@ -2472,29 +2434,30 @@ var getByteCount = (message) => {
|
|
|
2472
2434
|
};
|
|
2473
2435
|
|
|
2474
2436
|
// src/db-host/documents-synchronizer.ts
|
|
2475
|
-
import { next as
|
|
2437
|
+
import { next as A3 } from "@automerge/automerge";
|
|
2476
2438
|
import { UpdateScheduler, sleep } from "@dxos/async";
|
|
2477
2439
|
import { LifecycleState as LifecycleState2, Resource as Resource5, cancelWithContext as cancelWithContext2 } from "@dxos/context";
|
|
2478
2440
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
2479
2441
|
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
2442
|
var __dxlog_file7 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/documents-synchronizer.ts";
|
|
2494
2443
|
var MAX_UPDATE_FREQ = 10;
|
|
2495
2444
|
var WRAP_AROUND_RETRY_LIMIT = 3;
|
|
2496
2445
|
var WRAP_AROUND_RETRY_INITIAL_DELAY = 100;
|
|
2497
2446
|
var DocumentsSynchronizer = class extends Resource5 {
|
|
2447
|
+
_params;
|
|
2448
|
+
_syncStates = /* @__PURE__ */ new Map();
|
|
2449
|
+
/**
|
|
2450
|
+
* Documents that have pending updates.
|
|
2451
|
+
* Used to batch updates.
|
|
2452
|
+
*/
|
|
2453
|
+
_pendingUpdates = /* @__PURE__ */ new Set();
|
|
2454
|
+
/**
|
|
2455
|
+
* Job that schedules if there are pending updates.
|
|
2456
|
+
*/
|
|
2457
|
+
_sendUpdatesJob = void 0;
|
|
2458
|
+
constructor(_params) {
|
|
2459
|
+
super(), this._params = _params;
|
|
2460
|
+
}
|
|
2498
2461
|
addDocuments(documentIds, retryCounter = 0, wrapAroundRetryDelay = WRAP_AROUND_RETRY_INITIAL_DELAY) {
|
|
2499
2462
|
if (retryCounter > WRAP_AROUND_RETRY_LIMIT) {
|
|
2500
2463
|
log6.warn("Failed to load document, retry limit reached", {
|
|
@@ -2613,11 +2576,11 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2613
2576
|
return;
|
|
2614
2577
|
}
|
|
2615
2578
|
const doc = handle.doc();
|
|
2616
|
-
const mutation = syncState.lastSentHead ?
|
|
2579
|
+
const mutation = syncState.lastSentHead ? A3.saveSince(doc, syncState.lastSentHead) : A3.save(doc);
|
|
2617
2580
|
if (mutation.length === 0) {
|
|
2618
2581
|
return;
|
|
2619
2582
|
}
|
|
2620
|
-
syncState.lastSentHead =
|
|
2583
|
+
syncState.lastSentHead = A3.getHeads(doc);
|
|
2621
2584
|
return mutation;
|
|
2622
2585
|
}
|
|
2623
2586
|
_writeMutation(documentId, mutation, isNew) {
|
|
@@ -2629,7 +2592,7 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2629
2592
|
docId: documentId
|
|
2630
2593
|
});
|
|
2631
2594
|
const syncState = this._startSync(newHandle);
|
|
2632
|
-
syncState.lastSentHead =
|
|
2595
|
+
syncState.lastSentHead = A3.getHeads(newHandle.doc());
|
|
2633
2596
|
} else {
|
|
2634
2597
|
const syncState = this._syncStates.get(documentId);
|
|
2635
2598
|
invariant6(syncState, "Sync state for document not found", {
|
|
@@ -2641,43 +2604,33 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2641
2604
|
"'Sync state for document not found'"
|
|
2642
2605
|
]
|
|
2643
2606
|
});
|
|
2644
|
-
const headsBefore =
|
|
2607
|
+
const headsBefore = A3.getHeads(syncState.handle.doc());
|
|
2645
2608
|
this._params.repo.import(mutation, {
|
|
2646
2609
|
docId: documentId
|
|
2647
2610
|
});
|
|
2648
|
-
if (
|
|
2649
|
-
syncState.lastSentHead =
|
|
2611
|
+
if (A3.equals(headsBefore, syncState.lastSentHead)) {
|
|
2612
|
+
syncState.lastSentHead = A3.getHeads(syncState.handle.doc());
|
|
2650
2613
|
}
|
|
2651
2614
|
}
|
|
2652
2615
|
}
|
|
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;
|
|
2662
|
-
}
|
|
2663
2616
|
};
|
|
2664
2617
|
|
|
2665
2618
|
// 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;
|
|
2676
|
-
}
|
|
2677
|
-
return obj;
|
|
2678
|
-
}
|
|
2679
2619
|
var __dxlog_file8 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/data-service.ts";
|
|
2680
2620
|
var DataServiceImpl = class {
|
|
2621
|
+
/**
|
|
2622
|
+
* Map of subscriptions.
|
|
2623
|
+
* subscriptionId -> DocumentsSynchronizer
|
|
2624
|
+
*/
|
|
2625
|
+
_subscriptions = /* @__PURE__ */ new Map();
|
|
2626
|
+
_automergeHost;
|
|
2627
|
+
_spaceStateManager;
|
|
2628
|
+
_updateIndexes;
|
|
2629
|
+
constructor(params) {
|
|
2630
|
+
this._automergeHost = params.automergeHost;
|
|
2631
|
+
this._spaceStateManager = params.spaceStateManager;
|
|
2632
|
+
this._updateIndexes = params.updateIndexes;
|
|
2633
|
+
}
|
|
2681
2634
|
subscribe(request) {
|
|
2682
2635
|
return new Stream(({ next, ready }) => {
|
|
2683
2636
|
const synchronizer = new DocumentsSynchronizer({
|
|
@@ -2798,15 +2751,6 @@ var DataServiceImpl = class {
|
|
|
2798
2751
|
scheduler.trigger();
|
|
2799
2752
|
});
|
|
2800
2753
|
}
|
|
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
|
-
}
|
|
2810
2754
|
};
|
|
2811
2755
|
|
|
2812
2756
|
// src/db-host/echo-host.ts
|
|
@@ -2819,7 +2763,7 @@ import { IndexKind } from "@dxos/protocols/proto/dxos/echo/indexing";
|
|
|
2819
2763
|
import { trace as trace5 } from "@dxos/tracing";
|
|
2820
2764
|
|
|
2821
2765
|
// src/db-host/documents-iterator.ts
|
|
2822
|
-
import * as
|
|
2766
|
+
import * as A4 from "@automerge/automerge";
|
|
2823
2767
|
import { Context as Context2 } from "@dxos/context";
|
|
2824
2768
|
import { DatabaseDirectory as DatabaseDirectory2, SpaceDocVersion } from "@dxos/echo-protocol";
|
|
2825
2769
|
import { invariant as invariant8 } from "@dxos/invariant";
|
|
@@ -2850,10 +2794,10 @@ var createSelectedDocumentsIterator = (automergeHost) => (
|
|
|
2850
2794
|
""
|
|
2851
2795
|
]
|
|
2852
2796
|
});
|
|
2853
|
-
const currentHeads =
|
|
2854
|
-
if (!
|
|
2797
|
+
const currentHeads = A4.getHeads(doc);
|
|
2798
|
+
if (!A4.equals(currentHeads, heads)) {
|
|
2855
2799
|
const begin = Date.now();
|
|
2856
|
-
doc =
|
|
2800
|
+
doc = A4.view(doc, heads);
|
|
2857
2801
|
const end = Date.now();
|
|
2858
2802
|
if (end - begin > LOG_VIEW_OPERATION_THRESHOLD) {
|
|
2859
2803
|
log8("Checking out document version is taking too long", {
|
|
@@ -2908,7 +2852,7 @@ var createSelectedDocumentsIterator = (automergeHost) => (
|
|
|
2908
2852
|
|
|
2909
2853
|
// src/db-host/query-service.ts
|
|
2910
2854
|
import { getHeads as getHeads3 } from "@automerge/automerge";
|
|
2911
|
-
import
|
|
2855
|
+
import * as Schema from "effect/Schema";
|
|
2912
2856
|
import { DeferredTask as DeferredTask2, scheduleMicroTask, synchronized as synchronized2 } from "@dxos/async";
|
|
2913
2857
|
import { Stream as Stream2 } from "@dxos/codec-protobuf/stream";
|
|
2914
2858
|
import { Context as Context4, Resource as Resource7 } from "@dxos/context";
|
|
@@ -2919,7 +2863,8 @@ import { objectPointerCodec as objectPointerCodec4 } from "@dxos/protocols";
|
|
|
2919
2863
|
import { trace as trace4 } from "@dxos/tracing";
|
|
2920
2864
|
|
|
2921
2865
|
// src/query/query-executor.ts
|
|
2922
|
-
import
|
|
2866
|
+
import * as Match from "effect/Match";
|
|
2867
|
+
import * as Predicate from "effect/Predicate";
|
|
2923
2868
|
import { Context as Context3, ContextDisposedError, LifecycleState as LifecycleState3, Resource as Resource6 } from "@dxos/context";
|
|
2924
2869
|
import { DatabaseDirectory as DatabaseDirectory3, ObjectStructure, isEncodedReference } from "@dxos/echo-protocol";
|
|
2925
2870
|
import { EscapedPropPath } from "@dxos/indexing";
|
|
@@ -2927,7 +2872,7 @@ import { invariant as invariant10 } from "@dxos/invariant";
|
|
|
2927
2872
|
import { DXN, PublicKey as PublicKey3 } from "@dxos/keys";
|
|
2928
2873
|
import { log as log9 } from "@dxos/log";
|
|
2929
2874
|
import { objectPointerCodec as objectPointerCodec3 } from "@dxos/protocols";
|
|
2930
|
-
import { getDeep, isNonNullable as
|
|
2875
|
+
import { getDeep, isNonNullable as isNonNullable3 } from "@dxos/util";
|
|
2931
2876
|
|
|
2932
2877
|
// src/query/query-planner.ts
|
|
2933
2878
|
import { Order } from "@dxos/echo";
|
|
@@ -2937,6 +2882,8 @@ import { invariant as invariant9 } from "@dxos/invariant";
|
|
|
2937
2882
|
import { BaseError } from "@dxos/errors";
|
|
2938
2883
|
var QueryError = class extends BaseError.extend("QUERY_ERROR") {
|
|
2939
2884
|
};
|
|
2885
|
+
var InvalidQueryError = class extends QueryError.extend("INVALID_QUERY") {
|
|
2886
|
+
};
|
|
2940
2887
|
|
|
2941
2888
|
// src/query/plan.ts
|
|
2942
2889
|
(function(QueryPlan2) {
|
|
@@ -2960,24 +2907,18 @@ var QueryError = class extends BaseError.extend("QUERY_ERROR") {
|
|
|
2960
2907
|
var QueryPlan;
|
|
2961
2908
|
|
|
2962
2909
|
// src/query/query-planner.ts
|
|
2963
|
-
function _define_property11(obj, key, value) {
|
|
2964
|
-
if (key in obj) {
|
|
2965
|
-
Object.defineProperty(obj, key, {
|
|
2966
|
-
value,
|
|
2967
|
-
enumerable: true,
|
|
2968
|
-
configurable: true,
|
|
2969
|
-
writable: true
|
|
2970
|
-
});
|
|
2971
|
-
} else {
|
|
2972
|
-
obj[key] = value;
|
|
2973
|
-
}
|
|
2974
|
-
return obj;
|
|
2975
|
-
}
|
|
2976
2910
|
var __dxlog_file10 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/query/query-planner.ts";
|
|
2977
2911
|
var DEFAULT_OPTIONS = {
|
|
2978
2912
|
defaultTextSearchKind: "full-text"
|
|
2979
2913
|
};
|
|
2980
2914
|
var QueryPlanner = class {
|
|
2915
|
+
_options;
|
|
2916
|
+
constructor(options) {
|
|
2917
|
+
this._options = {
|
|
2918
|
+
...DEFAULT_OPTIONS,
|
|
2919
|
+
...options
|
|
2920
|
+
};
|
|
2921
|
+
}
|
|
2981
2922
|
createPlan(query) {
|
|
2982
2923
|
let plan = this._generate(query, {
|
|
2983
2924
|
...DEFAULT_CONTEXT,
|
|
@@ -3011,7 +2952,8 @@ var QueryPlanner = class {
|
|
|
3011
2952
|
case "order":
|
|
3012
2953
|
return this._generateOrderClause(query, context);
|
|
3013
2954
|
default:
|
|
3014
|
-
throw new QueryError(
|
|
2955
|
+
throw new QueryError({
|
|
2956
|
+
message: `Unsupported query type: ${query.type}`,
|
|
3015
2957
|
context: {
|
|
3016
2958
|
query: context.originalQuery
|
|
3017
2959
|
}
|
|
@@ -3035,10 +2977,11 @@ var QueryPlanner = class {
|
|
|
3035
2977
|
}
|
|
3036
2978
|
// TODO(dmaretskyi): This can be rewritten as a function of (filter[]) -> (selection ? undefined, rest: filter[]) that recurses onto itself.
|
|
3037
2979
|
// TODO(dmaretskyi): If the tip of the query ast is a [select, ...filter] shape we can reorder the filters so the query is most efficient.
|
|
3038
|
-
_generateSelectionFromFilter(
|
|
3039
|
-
switch (
|
|
2980
|
+
_generateSelectionFromFilter(filter2, context) {
|
|
2981
|
+
switch (filter2.type) {
|
|
2982
|
+
// Props
|
|
3040
2983
|
case "object": {
|
|
3041
|
-
if (context.selectionInverted &&
|
|
2984
|
+
if (context.selectionInverted && filter2.id === void 0 && filter2.typename === null && Object.keys(filter2.props).length === 0) {
|
|
3042
2985
|
return QueryPlan.Plan.make([
|
|
3043
2986
|
{
|
|
3044
2987
|
_tag: "ClearWorkingSetStep"
|
|
@@ -3047,32 +2990,33 @@ var QueryPlanner = class {
|
|
|
3047
2990
|
]);
|
|
3048
2991
|
}
|
|
3049
2992
|
if (context.selectionInverted) {
|
|
3050
|
-
throw new QueryError(
|
|
2993
|
+
throw new QueryError({
|
|
2994
|
+
message: "Query too complex",
|
|
3051
2995
|
context: {
|
|
3052
2996
|
query: context.originalQuery
|
|
3053
2997
|
}
|
|
3054
2998
|
});
|
|
3055
2999
|
}
|
|
3056
|
-
if (
|
|
3000
|
+
if (filter2.id && filter2.id?.length > 0) {
|
|
3057
3001
|
return QueryPlan.Plan.make([
|
|
3058
3002
|
{
|
|
3059
3003
|
_tag: "SelectStep",
|
|
3060
3004
|
spaces: context.selectionSpaces,
|
|
3061
3005
|
selector: {
|
|
3062
3006
|
_tag: "IdSelector",
|
|
3063
|
-
objectIds:
|
|
3007
|
+
objectIds: filter2.id
|
|
3064
3008
|
}
|
|
3065
3009
|
},
|
|
3066
3010
|
...this._generateDeletedHandlingSteps(context),
|
|
3067
3011
|
{
|
|
3068
3012
|
_tag: "FilterStep",
|
|
3069
3013
|
filter: {
|
|
3070
|
-
...
|
|
3014
|
+
...filter2,
|
|
3071
3015
|
id: void 0
|
|
3072
3016
|
}
|
|
3073
3017
|
}
|
|
3074
3018
|
]);
|
|
3075
|
-
} else if (
|
|
3019
|
+
} else if (filter2.typename) {
|
|
3076
3020
|
return QueryPlan.Plan.make([
|
|
3077
3021
|
{
|
|
3078
3022
|
_tag: "SelectStep",
|
|
@@ -3080,17 +3024,17 @@ var QueryPlanner = class {
|
|
|
3080
3024
|
selector: {
|
|
3081
3025
|
_tag: "TypeSelector",
|
|
3082
3026
|
typename: [
|
|
3083
|
-
|
|
3027
|
+
filter2.typename
|
|
3084
3028
|
],
|
|
3085
3029
|
inverted: false
|
|
3086
3030
|
}
|
|
3087
3031
|
},
|
|
3088
3032
|
...this._generateDeletedHandlingSteps(context),
|
|
3033
|
+
// TODO(dmaretskyi): Normally we could skip filtering by typename here, but since the index does not separate schema versions, we need to do additional filter to only select the correct version.
|
|
3089
3034
|
{
|
|
3090
3035
|
_tag: "FilterStep",
|
|
3091
3036
|
filter: {
|
|
3092
|
-
...
|
|
3093
|
-
typename: null
|
|
3037
|
+
...filter2
|
|
3094
3038
|
}
|
|
3095
3039
|
}
|
|
3096
3040
|
]);
|
|
@@ -3107,12 +3051,32 @@ var QueryPlanner = class {
|
|
|
3107
3051
|
{
|
|
3108
3052
|
_tag: "FilterStep",
|
|
3109
3053
|
filter: {
|
|
3110
|
-
...
|
|
3054
|
+
...filter2
|
|
3111
3055
|
}
|
|
3112
3056
|
}
|
|
3113
3057
|
]);
|
|
3114
3058
|
}
|
|
3115
3059
|
}
|
|
3060
|
+
// Tag
|
|
3061
|
+
case "tag": {
|
|
3062
|
+
return QueryPlan.Plan.make([
|
|
3063
|
+
{
|
|
3064
|
+
_tag: "SelectStep",
|
|
3065
|
+
spaces: context.selectionSpaces,
|
|
3066
|
+
selector: {
|
|
3067
|
+
_tag: "WildcardSelector"
|
|
3068
|
+
}
|
|
3069
|
+
},
|
|
3070
|
+
...this._generateDeletedHandlingSteps(context),
|
|
3071
|
+
{
|
|
3072
|
+
_tag: "FilterStep",
|
|
3073
|
+
filter: {
|
|
3074
|
+
...filter2
|
|
3075
|
+
}
|
|
3076
|
+
}
|
|
3077
|
+
]);
|
|
3078
|
+
}
|
|
3079
|
+
// Text
|
|
3116
3080
|
case "text-search": {
|
|
3117
3081
|
return QueryPlan.Plan.make([
|
|
3118
3082
|
{
|
|
@@ -3120,55 +3084,61 @@ var QueryPlanner = class {
|
|
|
3120
3084
|
spaces: context.selectionSpaces,
|
|
3121
3085
|
selector: {
|
|
3122
3086
|
_tag: "TextSelector",
|
|
3123
|
-
text:
|
|
3124
|
-
searchKind:
|
|
3087
|
+
text: filter2.text,
|
|
3088
|
+
searchKind: filter2.searchKind ?? this._options.defaultTextSearchKind
|
|
3125
3089
|
}
|
|
3126
3090
|
},
|
|
3127
3091
|
...this._generateDeletedHandlingSteps(context)
|
|
3128
3092
|
]);
|
|
3129
3093
|
}
|
|
3094
|
+
// Compare
|
|
3130
3095
|
case "compare":
|
|
3131
|
-
throw new QueryError(
|
|
3096
|
+
throw new QueryError({
|
|
3097
|
+
message: "Query too complex",
|
|
3132
3098
|
context: {
|
|
3133
3099
|
query: context.originalQuery
|
|
3134
3100
|
}
|
|
3135
3101
|
});
|
|
3136
3102
|
case "in":
|
|
3137
|
-
throw new QueryError(
|
|
3103
|
+
throw new QueryError({
|
|
3104
|
+
message: "Query too complex",
|
|
3138
3105
|
context: {
|
|
3139
3106
|
query: context.originalQuery
|
|
3140
3107
|
}
|
|
3141
3108
|
});
|
|
3142
3109
|
case "range":
|
|
3143
|
-
throw new QueryError(
|
|
3110
|
+
throw new QueryError({
|
|
3111
|
+
message: "Query too complex",
|
|
3144
3112
|
context: {
|
|
3145
3113
|
query: context.originalQuery
|
|
3146
3114
|
}
|
|
3147
3115
|
});
|
|
3116
|
+
// Boolean
|
|
3148
3117
|
case "not":
|
|
3149
|
-
return this._generateSelectionFromFilter(
|
|
3118
|
+
return this._generateSelectionFromFilter(filter2.filter, {
|
|
3150
3119
|
...context,
|
|
3151
3120
|
selectionInverted: !context.selectionInverted
|
|
3152
3121
|
});
|
|
3153
3122
|
case "and":
|
|
3154
|
-
throw new QueryError(
|
|
3123
|
+
throw new QueryError({
|
|
3124
|
+
message: "Query too complex",
|
|
3155
3125
|
context: {
|
|
3156
3126
|
query: context.originalQuery
|
|
3157
3127
|
}
|
|
3158
3128
|
});
|
|
3159
3129
|
case "or":
|
|
3160
|
-
if (
|
|
3161
|
-
const typenames =
|
|
3162
|
-
invariant9(
|
|
3130
|
+
if (filter2.filters.every(isTrivialTypenameFilter)) {
|
|
3131
|
+
const typenames = filter2.filters.map((filter3) => {
|
|
3132
|
+
invariant9(filter3.type === "object" && filter3.typename !== null, void 0, {
|
|
3163
3133
|
F: __dxlog_file10,
|
|
3164
|
-
L:
|
|
3134
|
+
L: 225,
|
|
3165
3135
|
S: this,
|
|
3166
3136
|
A: [
|
|
3167
|
-
"
|
|
3137
|
+
"filter.type === 'object' && filter.typename !== null",
|
|
3168
3138
|
""
|
|
3169
3139
|
]
|
|
3170
3140
|
});
|
|
3171
|
-
return
|
|
3141
|
+
return filter3.typename;
|
|
3172
3142
|
});
|
|
3173
3143
|
return QueryPlan.Plan.make([
|
|
3174
3144
|
{
|
|
@@ -3180,17 +3150,25 @@ var QueryPlanner = class {
|
|
|
3180
3150
|
inverted: context.selectionInverted
|
|
3181
3151
|
}
|
|
3182
3152
|
},
|
|
3183
|
-
...this._generateDeletedHandlingSteps(context)
|
|
3153
|
+
...this._generateDeletedHandlingSteps(context),
|
|
3154
|
+
{
|
|
3155
|
+
_tag: "FilterStep",
|
|
3156
|
+
filter: {
|
|
3157
|
+
...filter2
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3184
3160
|
]);
|
|
3185
3161
|
} else {
|
|
3186
|
-
throw new QueryError(
|
|
3162
|
+
throw new QueryError({
|
|
3163
|
+
message: "Query too complex",
|
|
3187
3164
|
context: {
|
|
3188
3165
|
query: context.originalQuery
|
|
3189
3166
|
}
|
|
3190
3167
|
});
|
|
3191
3168
|
}
|
|
3192
3169
|
default:
|
|
3193
|
-
throw new QueryError(
|
|
3170
|
+
throw new QueryError({
|
|
3171
|
+
message: `Unsupported filter type: ${filter2.type}`,
|
|
3194
3172
|
context: {
|
|
3195
3173
|
query: context.originalQuery
|
|
3196
3174
|
}
|
|
@@ -3429,13 +3407,6 @@ var QueryPlanner = class {
|
|
|
3429
3407
|
}
|
|
3430
3408
|
]);
|
|
3431
3409
|
}
|
|
3432
|
-
constructor(options) {
|
|
3433
|
-
_define_property11(this, "_options", void 0);
|
|
3434
|
-
this._options = {
|
|
3435
|
-
...DEFAULT_OPTIONS,
|
|
3436
|
-
...options
|
|
3437
|
-
};
|
|
3438
|
-
}
|
|
3439
3410
|
};
|
|
3440
3411
|
var DEFAULT_CONTEXT = {
|
|
3441
3412
|
originalQuery: null,
|
|
@@ -3456,26 +3427,12 @@ var createRelationTraversalStep = (direction) => ({
|
|
|
3456
3427
|
direction
|
|
3457
3428
|
}
|
|
3458
3429
|
});
|
|
3459
|
-
var isTrivialTypenameFilter = (
|
|
3460
|
-
return
|
|
3430
|
+
var isTrivialTypenameFilter = (filter2) => {
|
|
3431
|
+
return filter2.type === "object" && filter2.typename !== null && Object.keys(filter2.props).length === 0 && (filter2.id === void 0 || filter2.id.length === 0) && (filter2.foreignKeys === void 0 || filter2.foreignKeys.length === 0);
|
|
3461
3432
|
};
|
|
3462
3433
|
|
|
3463
3434
|
// src/query/query-executor.ts
|
|
3464
|
-
function _define_property12(obj, key, value) {
|
|
3465
|
-
if (key in obj) {
|
|
3466
|
-
Object.defineProperty(obj, key, {
|
|
3467
|
-
value,
|
|
3468
|
-
enumerable: true,
|
|
3469
|
-
configurable: true,
|
|
3470
|
-
writable: true
|
|
3471
|
-
});
|
|
3472
|
-
} else {
|
|
3473
|
-
obj[key] = value;
|
|
3474
|
-
}
|
|
3475
|
-
return obj;
|
|
3476
|
-
}
|
|
3477
3435
|
var __dxlog_file11 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/query/query-executor.ts";
|
|
3478
|
-
var isNullable = Predicate.isNullable;
|
|
3479
3436
|
var ExecutionTrace = Object.freeze({
|
|
3480
3437
|
makeEmpty: () => ({
|
|
3481
3438
|
name: "Empty",
|
|
@@ -3483,11 +3440,57 @@ var ExecutionTrace = Object.freeze({
|
|
|
3483
3440
|
objectCount: 0,
|
|
3484
3441
|
documentsLoaded: 0,
|
|
3485
3442
|
indexHits: 0,
|
|
3443
|
+
beginTs: 0,
|
|
3444
|
+
endTs: 0,
|
|
3486
3445
|
indexQueryTime: 0,
|
|
3487
3446
|
documentLoadTime: 0,
|
|
3488
3447
|
executionTime: 0,
|
|
3489
3448
|
children: []
|
|
3490
3449
|
}),
|
|
3450
|
+
markEnd: (trace6) => {
|
|
3451
|
+
trace6.endTs = performance.now();
|
|
3452
|
+
trace6.executionTime = trace6.endTs - trace6.beginTs;
|
|
3453
|
+
},
|
|
3454
|
+
putOnPerformanceTimeline: (trace6) => {
|
|
3455
|
+
performance.measure(trace6.name, {
|
|
3456
|
+
start: trace6.beginTs,
|
|
3457
|
+
end: trace6.endTs,
|
|
3458
|
+
detail: {
|
|
3459
|
+
devtools: {
|
|
3460
|
+
dataType: "track-entry",
|
|
3461
|
+
track: "Query Execution",
|
|
3462
|
+
trackGroup: "ECHO",
|
|
3463
|
+
color: "tertiary-dark",
|
|
3464
|
+
properties: [
|
|
3465
|
+
[
|
|
3466
|
+
"objectCount",
|
|
3467
|
+
trace6.objectCount
|
|
3468
|
+
],
|
|
3469
|
+
[
|
|
3470
|
+
"documentsLoaded",
|
|
3471
|
+
trace6.documentsLoaded
|
|
3472
|
+
],
|
|
3473
|
+
[
|
|
3474
|
+
"index hits",
|
|
3475
|
+
trace6.indexHits
|
|
3476
|
+
],
|
|
3477
|
+
[
|
|
3478
|
+
"indexQueryTime",
|
|
3479
|
+
trace6.indexQueryTime
|
|
3480
|
+
],
|
|
3481
|
+
[
|
|
3482
|
+
"documentLoadTime",
|
|
3483
|
+
trace6.documentLoadTime
|
|
3484
|
+
]
|
|
3485
|
+
],
|
|
3486
|
+
tooltipText: trace6.details
|
|
3487
|
+
}
|
|
3488
|
+
}
|
|
3489
|
+
});
|
|
3490
|
+
for (const child of trace6.children) {
|
|
3491
|
+
ExecutionTrace.putOnPerformanceTimeline(child);
|
|
3492
|
+
}
|
|
3493
|
+
},
|
|
3491
3494
|
format: (trace6) => {
|
|
3492
3495
|
const go = (trace7, indent) => {
|
|
3493
3496
|
return [
|
|
@@ -3502,6 +3505,30 @@ var ExecutionTrace = Object.freeze({
|
|
|
3502
3505
|
});
|
|
3503
3506
|
var TRACE_QUERY_EXECUTION = false;
|
|
3504
3507
|
var QueryExecutor = class extends Resource6 {
|
|
3508
|
+
_indexer;
|
|
3509
|
+
_automergeHost;
|
|
3510
|
+
_spaceStateManager;
|
|
3511
|
+
/**
|
|
3512
|
+
* Id of this query.
|
|
3513
|
+
*/
|
|
3514
|
+
_id;
|
|
3515
|
+
_query;
|
|
3516
|
+
// TODO(dmaretskyi): Might be used in the future.
|
|
3517
|
+
_reactivity;
|
|
3518
|
+
_plan;
|
|
3519
|
+
_trace = ExecutionTrace.makeEmpty();
|
|
3520
|
+
_lastResultSet = [];
|
|
3521
|
+
constructor(options) {
|
|
3522
|
+
super();
|
|
3523
|
+
this._indexer = options.indexer;
|
|
3524
|
+
this._automergeHost = options.automergeHost;
|
|
3525
|
+
this._spaceStateManager = options.spaceStateManager;
|
|
3526
|
+
this._id = options.queryId;
|
|
3527
|
+
this._query = options.query;
|
|
3528
|
+
this._reactivity = options.reactivity;
|
|
3529
|
+
const queryPlanner = new QueryPlanner();
|
|
3530
|
+
this._plan = queryPlanner.createPlan(this._query);
|
|
3531
|
+
}
|
|
3505
3532
|
get query() {
|
|
3506
3533
|
return this._query;
|
|
3507
3534
|
}
|
|
@@ -3527,7 +3554,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3527
3554
|
async execQuery() {
|
|
3528
3555
|
invariant10(this._lifecycleState === LifecycleState3.OPEN, void 0, {
|
|
3529
3556
|
F: __dxlog_file11,
|
|
3530
|
-
L:
|
|
3557
|
+
L: 211,
|
|
3531
3558
|
S: this,
|
|
3532
3559
|
A: [
|
|
3533
3560
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -3562,7 +3589,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3562
3589
|
trace6.children.push(result.trace);
|
|
3563
3590
|
}
|
|
3564
3591
|
trace6.objectCount = workingSet.length;
|
|
3565
|
-
|
|
3592
|
+
ExecutionTrace.markEnd(trace6);
|
|
3566
3593
|
return {
|
|
3567
3594
|
workingSet,
|
|
3568
3595
|
trace: trace6
|
|
@@ -3606,7 +3633,8 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3606
3633
|
default:
|
|
3607
3634
|
throw new Error(`Unknown step type: ${step._tag}`);
|
|
3608
3635
|
}
|
|
3609
|
-
trace6.
|
|
3636
|
+
trace6.beginTs = begin;
|
|
3637
|
+
ExecutionTrace.markEnd(trace6);
|
|
3610
3638
|
return {
|
|
3611
3639
|
workingSet: newWorkingSet,
|
|
3612
3640
|
trace: trace6
|
|
@@ -3619,7 +3647,8 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3619
3647
|
const trace6 = {
|
|
3620
3648
|
...ExecutionTrace.makeEmpty(),
|
|
3621
3649
|
name: "Select",
|
|
3622
|
-
details: JSON.stringify(step.selector)
|
|
3650
|
+
details: JSON.stringify(step.selector),
|
|
3651
|
+
beginTs: performance.now()
|
|
3623
3652
|
};
|
|
3624
3653
|
switch (step.selector._tag) {
|
|
3625
3654
|
case "WildcardSelector": {
|
|
@@ -3640,7 +3669,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3640
3669
|
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
3641
3670
|
trace6.documentsLoaded += results.length;
|
|
3642
3671
|
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
3643
|
-
workingSet.push(...results.filter(
|
|
3672
|
+
workingSet.push(...results.filter(isNonNullable3).filter((item) => step.spaces.includes(item.spaceId)));
|
|
3644
3673
|
trace6.objectCount = workingSet.length;
|
|
3645
3674
|
break;
|
|
3646
3675
|
}
|
|
@@ -3650,7 +3679,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3650
3679
|
sourceSpaceId: step.spaces[0]
|
|
3651
3680
|
})));
|
|
3652
3681
|
trace6.documentLoadTime += performance.now() - beginLoad;
|
|
3653
|
-
workingSet.push(...items.filter(
|
|
3682
|
+
workingSet.push(...items.filter(isNonNullable3));
|
|
3654
3683
|
trace6.objectCount = workingSet.length;
|
|
3655
3684
|
break;
|
|
3656
3685
|
}
|
|
@@ -3672,7 +3701,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3672
3701
|
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
3673
3702
|
trace6.documentsLoaded += results.length;
|
|
3674
3703
|
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
3675
|
-
workingSet.push(...results.filter(
|
|
3704
|
+
workingSet.push(...results.filter(isNonNullable3).filter((item) => step.spaces.includes(item.spaceId)));
|
|
3676
3705
|
trace6.objectCount = workingSet.length;
|
|
3677
3706
|
break;
|
|
3678
3707
|
}
|
|
@@ -3697,7 +3726,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3697
3726
|
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
3698
3727
|
trace6.documentsLoaded += results.length;
|
|
3699
3728
|
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
3700
|
-
workingSet.push(...results.filter(
|
|
3729
|
+
workingSet.push(...results.filter(isNonNullable3).filter((item) => step.spaces.includes(item.spaceId)));
|
|
3701
3730
|
trace6.objectCount = workingSet.length;
|
|
3702
3731
|
break;
|
|
3703
3732
|
}
|
|
@@ -3767,20 +3796,20 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3767
3796
|
ref: ref2["/"]
|
|
3768
3797
|
}, {
|
|
3769
3798
|
F: __dxlog_file11,
|
|
3770
|
-
L:
|
|
3799
|
+
L: 477,
|
|
3771
3800
|
S: this,
|
|
3772
3801
|
C: (f, a) => f(...a)
|
|
3773
3802
|
});
|
|
3774
3803
|
return null;
|
|
3775
3804
|
}
|
|
3776
3805
|
});
|
|
3777
|
-
}).filter(
|
|
3806
|
+
}).filter(isNonNullable3);
|
|
3778
3807
|
const beginLoad = performance.now();
|
|
3779
3808
|
const items = await Promise.all(refs.map(({ ref, spaceId }) => this._loadFromDXN(ref, {
|
|
3780
3809
|
sourceSpaceId: spaceId
|
|
3781
3810
|
})));
|
|
3782
3811
|
trace6.documentLoadTime += performance.now() - beginLoad;
|
|
3783
|
-
newWorkingSet.push(...items.filter(
|
|
3812
|
+
newWorkingSet.push(...items.filter(isNonNullable3));
|
|
3784
3813
|
trace6.objectCount = newWorkingSet.length;
|
|
3785
3814
|
break;
|
|
3786
3815
|
}
|
|
@@ -3799,7 +3828,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3799
3828
|
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
3800
3829
|
trace6.documentsLoaded += results.length;
|
|
3801
3830
|
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
3802
|
-
newWorkingSet.push(...results.filter(
|
|
3831
|
+
newWorkingSet.push(...results.filter(isNonNullable3));
|
|
3803
3832
|
trace6.objectCount = newWorkingSet.length;
|
|
3804
3833
|
break;
|
|
3805
3834
|
}
|
|
@@ -3825,19 +3854,19 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3825
3854
|
ref: ref["/"]
|
|
3826
3855
|
}, {
|
|
3827
3856
|
F: __dxlog_file11,
|
|
3828
|
-
L:
|
|
3857
|
+
L: 540,
|
|
3829
3858
|
S: this,
|
|
3830
3859
|
C: (f, a) => f(...a)
|
|
3831
3860
|
});
|
|
3832
3861
|
return null;
|
|
3833
3862
|
}
|
|
3834
|
-
}).filter(
|
|
3863
|
+
}).filter(isNonNullable3);
|
|
3835
3864
|
const beginLoad = performance.now();
|
|
3836
3865
|
const items = await Promise.all(refs.map(({ ref, spaceId }) => this._loadFromDXN(ref, {
|
|
3837
3866
|
sourceSpaceId: spaceId
|
|
3838
3867
|
})));
|
|
3839
3868
|
trace6.documentLoadTime += performance.now() - beginLoad;
|
|
3840
|
-
newWorkingSet.push(...items.filter(
|
|
3869
|
+
newWorkingSet.push(...items.filter(isNonNullable3));
|
|
3841
3870
|
trace6.objectCount = newWorkingSet.length;
|
|
3842
3871
|
break;
|
|
3843
3872
|
}
|
|
@@ -3857,7 +3886,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3857
3886
|
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
3858
3887
|
trace6.documentsLoaded += results.length;
|
|
3859
3888
|
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
3860
|
-
newWorkingSet.push(...results.filter(
|
|
3889
|
+
newWorkingSet.push(...results.filter(isNonNullable3));
|
|
3861
3890
|
trace6.objectCount = newWorkingSet.length;
|
|
3862
3891
|
break;
|
|
3863
3892
|
}
|
|
@@ -3915,15 +3944,9 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3915
3944
|
};
|
|
3916
3945
|
}
|
|
3917
3946
|
async _execOrderStep(step, workingSet) {
|
|
3918
|
-
const compareItems = (a, b) => step.order.reduce((comparison, order) => {
|
|
3919
|
-
if (comparison !== 0) {
|
|
3920
|
-
return comparison;
|
|
3921
|
-
}
|
|
3922
|
-
return this._compareByOrder(a, b, order);
|
|
3923
|
-
}, 0);
|
|
3924
3947
|
const sortedWorkingSet = [
|
|
3925
3948
|
...workingSet
|
|
3926
|
-
].sort(
|
|
3949
|
+
].sort((a, b) => this._compareMultiOrder(a, b, step.order));
|
|
3927
3950
|
return {
|
|
3928
3951
|
workingSet: sortedWorkingSet,
|
|
3929
3952
|
trace: {
|
|
@@ -3934,64 +3957,69 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3934
3957
|
}
|
|
3935
3958
|
};
|
|
3936
3959
|
}
|
|
3960
|
+
_compareMultiOrder(a, b, orders) {
|
|
3961
|
+
if (orders.length === 0) {
|
|
3962
|
+
return 0;
|
|
3963
|
+
} else if (orders.length === 1) {
|
|
3964
|
+
return this._compareByOrder(a, b, orders[0]);
|
|
3965
|
+
}
|
|
3966
|
+
for (const order of orders) {
|
|
3967
|
+
const comparison = this._compareByOrder(a, b, order);
|
|
3968
|
+
if (comparison !== 0) {
|
|
3969
|
+
return comparison;
|
|
3970
|
+
}
|
|
3971
|
+
}
|
|
3972
|
+
return 0;
|
|
3973
|
+
}
|
|
3937
3974
|
_compareByOrder(a, b, order) {
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3975
|
+
switch (order.kind) {
|
|
3976
|
+
case "natural":
|
|
3977
|
+
return a.objectId.localeCompare(b.objectId);
|
|
3978
|
+
case "property": {
|
|
3979
|
+
const comparison = this._compareByProperty(a, b, order.property);
|
|
3980
|
+
return order.direction === "desc" ? -comparison : comparison;
|
|
3981
|
+
}
|
|
3982
|
+
default:
|
|
3983
|
+
return 0;
|
|
3984
|
+
}
|
|
3946
3985
|
}
|
|
3947
3986
|
_compareByProperty(a, b, property) {
|
|
3948
3987
|
const aValue = a.doc.data[property];
|
|
3949
3988
|
const bValue = b.doc.data[property];
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
}, ({ a: a2, b: b2 }) => a2 - b2),
|
|
3970
|
-
Match.when({
|
|
3971
|
-
a: Match.boolean,
|
|
3972
|
-
b: Match.boolean
|
|
3973
|
-
}, ({ a: a2, b: b2 }) => a2 === b2 ? 0 : a2 ? 1 : -1),
|
|
3974
|
-
Match.when({
|
|
3975
|
-
a: Match.defined,
|
|
3976
|
-
b: Match.defined
|
|
3977
|
-
}, ({ a: a2, b: b2 }) => String(a2).localeCompare(String(b2))),
|
|
3978
|
-
// TODO(wittjosiah): Why does Match.exhaustive fail here?
|
|
3979
|
-
Match.orElse(() => 0)
|
|
3980
|
-
)({
|
|
3981
|
-
a: aValue,
|
|
3982
|
-
b: bValue
|
|
3983
|
-
});
|
|
3989
|
+
if (aValue == null && bValue == null) {
|
|
3990
|
+
return 0;
|
|
3991
|
+
}
|
|
3992
|
+
if (aValue == null) {
|
|
3993
|
+
return 1;
|
|
3994
|
+
}
|
|
3995
|
+
if (bValue == null) {
|
|
3996
|
+
return -1;
|
|
3997
|
+
}
|
|
3998
|
+
if (typeof aValue === "string" && typeof bValue === "string") {
|
|
3999
|
+
return aValue.localeCompare(bValue);
|
|
4000
|
+
}
|
|
4001
|
+
if (typeof aValue === "number" && typeof bValue === "number") {
|
|
4002
|
+
return aValue - bValue;
|
|
4003
|
+
}
|
|
4004
|
+
if (typeof aValue === "boolean" && typeof bValue === "boolean") {
|
|
4005
|
+
return aValue === bValue ? 0 : aValue ? 1 : -1;
|
|
4006
|
+
}
|
|
4007
|
+
return String(aValue).localeCompare(String(bValue));
|
|
3984
4008
|
}
|
|
3985
4009
|
async _loadDocumentsAfterIndexQuery(indexHits) {
|
|
3986
4010
|
return Promise.all(indexHits.map(async (hit) => {
|
|
3987
4011
|
return this._loadFromIndexHit(hit);
|
|
3988
4012
|
}));
|
|
3989
4013
|
}
|
|
4014
|
+
/**
|
|
4015
|
+
* Space key hex -> SpaceId.
|
|
4016
|
+
*/
|
|
4017
|
+
_spaceIdCache = /* @__PURE__ */ new Map();
|
|
3990
4018
|
async _loadFromIndexHit(hit) {
|
|
3991
4019
|
const { objectId, documentId, spaceKey: spaceKeyInIndex } = objectPointerCodec3.decode(hit.id);
|
|
3992
4020
|
const handle = await this._automergeHost.loadDoc(Context3.default(void 0, {
|
|
3993
4021
|
F: __dxlog_file11,
|
|
3994
|
-
L:
|
|
4022
|
+
L: 738
|
|
3995
4023
|
}), documentId);
|
|
3996
4024
|
const doc = handle.doc();
|
|
3997
4025
|
if (!doc) {
|
|
@@ -4001,6 +4029,11 @@ var QueryExecutor = class extends Resource6 {
|
|
|
4001
4029
|
if (!spaceKey) {
|
|
4002
4030
|
return null;
|
|
4003
4031
|
}
|
|
4032
|
+
let spaceId = this._spaceIdCache.get(spaceKey);
|
|
4033
|
+
if (!spaceId) {
|
|
4034
|
+
spaceId = await createIdFromSpaceKey(PublicKey3.from(spaceKey));
|
|
4035
|
+
this._spaceIdCache.set(spaceKey, spaceId);
|
|
4036
|
+
}
|
|
4004
4037
|
const object = DatabaseDirectory3.getInlineObject(doc, objectId);
|
|
4005
4038
|
if (!object) {
|
|
4006
4039
|
return null;
|
|
@@ -4008,7 +4041,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
4008
4041
|
return {
|
|
4009
4042
|
objectId,
|
|
4010
4043
|
documentId,
|
|
4011
|
-
spaceId
|
|
4044
|
+
spaceId,
|
|
4012
4045
|
doc: object
|
|
4013
4046
|
};
|
|
4014
4047
|
}
|
|
@@ -4019,7 +4052,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
4019
4052
|
dxn
|
|
4020
4053
|
}, {
|
|
4021
4054
|
F: __dxlog_file11,
|
|
4022
|
-
L:
|
|
4055
|
+
L: 771,
|
|
4023
4056
|
S: this,
|
|
4024
4057
|
C: (f, a) => f(...a)
|
|
4025
4058
|
});
|
|
@@ -4032,7 +4065,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
4032
4065
|
spaceId
|
|
4033
4066
|
}, {
|
|
4034
4067
|
F: __dxlog_file11,
|
|
4035
|
-
L:
|
|
4068
|
+
L: 779,
|
|
4036
4069
|
S: this,
|
|
4037
4070
|
C: (f, a) => f(...a)
|
|
4038
4071
|
});
|
|
@@ -4044,7 +4077,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
4044
4077
|
spaceId
|
|
4045
4078
|
}, {
|
|
4046
4079
|
F: __dxlog_file11,
|
|
4047
|
-
L:
|
|
4080
|
+
L: 784,
|
|
4048
4081
|
S: this,
|
|
4049
4082
|
C: (f, a) => f(...a)
|
|
4050
4083
|
});
|
|
@@ -4065,7 +4098,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
4065
4098
|
}
|
|
4066
4099
|
const handle = await this._automergeHost.loadDoc(Context3.default(void 0, {
|
|
4067
4100
|
F: __dxlog_file11,
|
|
4068
|
-
L:
|
|
4101
|
+
L: 803
|
|
4069
4102
|
}), link);
|
|
4070
4103
|
const doc = handle.doc();
|
|
4071
4104
|
if (!doc) {
|
|
@@ -4082,37 +4115,9 @@ var QueryExecutor = class extends Resource6 {
|
|
|
4082
4115
|
doc: object
|
|
4083
4116
|
};
|
|
4084
4117
|
}
|
|
4085
|
-
constructor(options) {
|
|
4086
|
-
super(), _define_property12(this, "_indexer", void 0), _define_property12(this, "_automergeHost", void 0), _define_property12(this, "_spaceStateManager", void 0), /**
|
|
4087
|
-
* Id of this query.
|
|
4088
|
-
*/
|
|
4089
|
-
_define_property12(this, "_id", void 0), _define_property12(this, "_query", void 0), // TODO(dmaretskyi): Might be used in the future.
|
|
4090
|
-
_define_property12(this, "_reactivity", void 0), _define_property12(this, "_plan", void 0), _define_property12(this, "_trace", ExecutionTrace.makeEmpty()), _define_property12(this, "_lastResultSet", []);
|
|
4091
|
-
this._indexer = options.indexer;
|
|
4092
|
-
this._automergeHost = options.automergeHost;
|
|
4093
|
-
this._spaceStateManager = options.spaceStateManager;
|
|
4094
|
-
this._id = options.queryId;
|
|
4095
|
-
this._query = options.query;
|
|
4096
|
-
this._reactivity = options.reactivity;
|
|
4097
|
-
const queryPlanner = new QueryPlanner();
|
|
4098
|
-
this._plan = queryPlanner.createPlan(this._query);
|
|
4099
|
-
}
|
|
4100
4118
|
};
|
|
4101
4119
|
|
|
4102
4120
|
// src/db-host/query-service.ts
|
|
4103
|
-
function _define_property13(obj, key, value) {
|
|
4104
|
-
if (key in obj) {
|
|
4105
|
-
Object.defineProperty(obj, key, {
|
|
4106
|
-
value,
|
|
4107
|
-
enumerable: true,
|
|
4108
|
-
configurable: true,
|
|
4109
|
-
writable: true
|
|
4110
|
-
});
|
|
4111
|
-
} else {
|
|
4112
|
-
obj[key] = value;
|
|
4113
|
-
}
|
|
4114
|
-
return obj;
|
|
4115
|
-
}
|
|
4116
4121
|
function _ts_decorate5(decorators, target, key, desc) {
|
|
4117
4122
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4118
4123
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -4121,6 +4126,27 @@ function _ts_decorate5(decorators, target, key, desc) {
|
|
|
4121
4126
|
}
|
|
4122
4127
|
var __dxlog_file12 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/query-service.ts";
|
|
4123
4128
|
var QueryServiceImpl = class extends Resource7 {
|
|
4129
|
+
_params;
|
|
4130
|
+
// TODO(dmaretskyi): We need to implement query deduping. Idle composer has 80 queries with only 10 being unique.
|
|
4131
|
+
_queries = /* @__PURE__ */ new Set();
|
|
4132
|
+
_updateQueries;
|
|
4133
|
+
// TODO(burdon): OK for options, but not params. Pass separately and type readonly here.
|
|
4134
|
+
constructor(_params) {
|
|
4135
|
+
super(), this._params = _params;
|
|
4136
|
+
trace4.diagnostic({
|
|
4137
|
+
id: "active-queries",
|
|
4138
|
+
name: "Active Queries",
|
|
4139
|
+
fetch: () => {
|
|
4140
|
+
return Array.from(this._queries).map((query) => {
|
|
4141
|
+
return {
|
|
4142
|
+
query: JSON.stringify(query.executor.query),
|
|
4143
|
+
plan: JSON.stringify(query.executor.plan),
|
|
4144
|
+
trace: JSON.stringify(query.executor.trace)
|
|
4145
|
+
};
|
|
4146
|
+
});
|
|
4147
|
+
}
|
|
4148
|
+
});
|
|
4149
|
+
}
|
|
4124
4150
|
async _open() {
|
|
4125
4151
|
this._params.indexer.updated.on(this._ctx, () => this.invalidateQueries());
|
|
4126
4152
|
this._updateQueries = new DeferredTask2(this._ctx, this._executeQueries.bind(this));
|
|
@@ -4139,7 +4165,7 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
4139
4165
|
config: this._params.indexer.config
|
|
4140
4166
|
}, {
|
|
4141
4167
|
F: __dxlog_file12,
|
|
4142
|
-
L:
|
|
4168
|
+
L: 102,
|
|
4143
4169
|
S: this,
|
|
4144
4170
|
C: (f, a) => f(...a)
|
|
4145
4171
|
});
|
|
@@ -4161,7 +4187,7 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
4161
4187
|
async reindex() {
|
|
4162
4188
|
log10("Reindexing all documents...", void 0, {
|
|
4163
4189
|
F: __dxlog_file12,
|
|
4164
|
-
L:
|
|
4190
|
+
L: 121,
|
|
4165
4191
|
S: this,
|
|
4166
4192
|
C: (f, a) => f(...a)
|
|
4167
4193
|
});
|
|
@@ -4176,7 +4202,7 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
4176
4202
|
count: ids.size
|
|
4177
4203
|
}, {
|
|
4178
4204
|
F: __dxlog_file12,
|
|
4179
|
-
L:
|
|
4205
|
+
L: 129,
|
|
4180
4206
|
S: this,
|
|
4181
4207
|
C: (f, a) => f(...a)
|
|
4182
4208
|
});
|
|
@@ -4186,7 +4212,7 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
4186
4212
|
count: ids.size
|
|
4187
4213
|
}, {
|
|
4188
4214
|
F: __dxlog_file12,
|
|
4189
|
-
L:
|
|
4215
|
+
L: 133,
|
|
4190
4216
|
S: this,
|
|
4191
4217
|
C: (f, a) => f(...a)
|
|
4192
4218
|
});
|
|
@@ -4252,7 +4278,7 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
4252
4278
|
} catch (err) {
|
|
4253
4279
|
log10.catch(err, void 0, {
|
|
4254
4280
|
F: __dxlog_file12,
|
|
4255
|
-
L:
|
|
4281
|
+
L: 204,
|
|
4256
4282
|
S: this,
|
|
4257
4283
|
C: (f, a) => f(...a)
|
|
4258
4284
|
});
|
|
@@ -4263,28 +4289,11 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
4263
4289
|
duration: performance.now() - begin
|
|
4264
4290
|
}, {
|
|
4265
4291
|
F: __dxlog_file12,
|
|
4266
|
-
L:
|
|
4292
|
+
L: 208,
|
|
4267
4293
|
S: this,
|
|
4268
4294
|
C: (f, a) => f(...a)
|
|
4269
4295
|
});
|
|
4270
4296
|
}
|
|
4271
|
-
// TODO(burdon): OK for options, but not params. Pass separately and type readonly here.
|
|
4272
|
-
constructor(_params) {
|
|
4273
|
-
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();
|
|
4274
|
-
trace4.diagnostic({
|
|
4275
|
-
id: "active-queries",
|
|
4276
|
-
name: "Active Queries",
|
|
4277
|
-
fetch: () => {
|
|
4278
|
-
return Array.from(this._queries).map((query) => {
|
|
4279
|
-
return {
|
|
4280
|
-
query: JSON.stringify(query.executor.query),
|
|
4281
|
-
plan: JSON.stringify(query.executor.plan),
|
|
4282
|
-
trace: JSON.stringify(query.executor.trace)
|
|
4283
|
-
};
|
|
4284
|
-
});
|
|
4285
|
-
}
|
|
4286
|
-
});
|
|
4287
|
-
}
|
|
4288
4297
|
};
|
|
4289
4298
|
_ts_decorate5([
|
|
4290
4299
|
synchronized2
|
|
@@ -4331,7 +4340,7 @@ var createDocumentsIterator = (automergeHost) => (
|
|
|
4331
4340
|
}
|
|
4332
4341
|
const linkHandle = await automergeHost.loadDoc(Context4.default(void 0, {
|
|
4333
4342
|
F: __dxlog_file12,
|
|
4334
|
-
L:
|
|
4343
|
+
L: 248
|
|
4335
4344
|
}), urlString);
|
|
4336
4345
|
for await (const result of getObjectsFromHandle(linkHandle)) {
|
|
4337
4346
|
yield result;
|
|
@@ -4365,17 +4374,17 @@ import { DatabaseDirectory as DatabaseDirectory5, SpaceDocVersion as SpaceDocVer
|
|
|
4365
4374
|
import { invariant as invariant11 } from "@dxos/invariant";
|
|
4366
4375
|
|
|
4367
4376
|
// src/db-host/automerge-metrics.ts
|
|
4368
|
-
import * as
|
|
4377
|
+
import * as A5 from "@automerge/automerge";
|
|
4369
4378
|
import { log as log11 } from "@dxos/log";
|
|
4370
4379
|
var __dxlog_file13 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/automerge-metrics.ts";
|
|
4371
4380
|
var measureDocMetrics = (doc) => {
|
|
4372
|
-
const snapshot =
|
|
4381
|
+
const snapshot = A5.save(doc);
|
|
4373
4382
|
const start = Date.now();
|
|
4374
|
-
const temp =
|
|
4383
|
+
const temp = A5.load(snapshot);
|
|
4375
4384
|
const end = Date.now();
|
|
4376
|
-
|
|
4385
|
+
A5.free(temp);
|
|
4377
4386
|
const getAllChangesStart = Date.now();
|
|
4378
|
-
const mutationCount =
|
|
4387
|
+
const mutationCount = A5.getAllChanges(doc).length;
|
|
4379
4388
|
const getAllChangesEnd = Date.now();
|
|
4380
4389
|
if (getAllChangesEnd - getAllChangesStart > 300) {
|
|
4381
4390
|
log11.warn("getAllChanges took too long", {
|
|
@@ -4395,21 +4404,9 @@ var measureDocMetrics = (doc) => {
|
|
|
4395
4404
|
};
|
|
4396
4405
|
|
|
4397
4406
|
// src/db-host/database-root.ts
|
|
4398
|
-
function _define_property14(obj, key, value) {
|
|
4399
|
-
if (key in obj) {
|
|
4400
|
-
Object.defineProperty(obj, key, {
|
|
4401
|
-
value,
|
|
4402
|
-
enumerable: true,
|
|
4403
|
-
configurable: true,
|
|
4404
|
-
writable: true
|
|
4405
|
-
});
|
|
4406
|
-
} else {
|
|
4407
|
-
obj[key] = value;
|
|
4408
|
-
}
|
|
4409
|
-
return obj;
|
|
4410
|
-
}
|
|
4411
4407
|
var __dxlog_file14 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/database-root.ts";
|
|
4412
4408
|
var DatabaseRoot = class {
|
|
4409
|
+
_rootHandle;
|
|
4413
4410
|
static mapLinks(doc, mapping) {
|
|
4414
4411
|
doc.change((d) => {
|
|
4415
4412
|
if (!d.links) {
|
|
@@ -4423,6 +4420,9 @@ var DatabaseRoot = class {
|
|
|
4423
4420
|
}
|
|
4424
4421
|
});
|
|
4425
4422
|
}
|
|
4423
|
+
constructor(_rootHandle) {
|
|
4424
|
+
this._rootHandle = _rootHandle;
|
|
4425
|
+
}
|
|
4426
4426
|
get documentId() {
|
|
4427
4427
|
return this._rootHandle.documentId;
|
|
4428
4428
|
}
|
|
@@ -4486,28 +4486,16 @@ var DatabaseRoot = class {
|
|
|
4486
4486
|
}
|
|
4487
4487
|
return measureDocMetrics(doc);
|
|
4488
4488
|
}
|
|
4489
|
-
constructor(_rootHandle) {
|
|
4490
|
-
_define_property14(this, "_rootHandle", void 0);
|
|
4491
|
-
this._rootHandle = _rootHandle;
|
|
4492
|
-
}
|
|
4493
4489
|
};
|
|
4494
4490
|
|
|
4495
4491
|
// src/db-host/space-state-manager.ts
|
|
4496
|
-
function _define_property15(obj, key, value) {
|
|
4497
|
-
if (key in obj) {
|
|
4498
|
-
Object.defineProperty(obj, key, {
|
|
4499
|
-
value,
|
|
4500
|
-
enumerable: true,
|
|
4501
|
-
configurable: true,
|
|
4502
|
-
writable: true
|
|
4503
|
-
});
|
|
4504
|
-
} else {
|
|
4505
|
-
obj[key] = value;
|
|
4506
|
-
}
|
|
4507
|
-
return obj;
|
|
4508
|
-
}
|
|
4509
4492
|
var __dxlog_file15 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/space-state-manager.ts";
|
|
4510
4493
|
var SpaceStateManager = class extends Resource8 {
|
|
4494
|
+
_roots = /* @__PURE__ */ new Map();
|
|
4495
|
+
_rootBySpace = /* @__PURE__ */ new Map();
|
|
4496
|
+
_perRootContext = /* @__PURE__ */ new Map();
|
|
4497
|
+
_lastSpaceDocumentList = /* @__PURE__ */ new Map();
|
|
4498
|
+
spaceDocumentListUpdated = new Event3();
|
|
4511
4499
|
async _close(ctx) {
|
|
4512
4500
|
for (const [_, rootCtx] of this._perRootContext) {
|
|
4513
4501
|
await rootCtx.dispose();
|
|
@@ -4580,16 +4568,13 @@ var SpaceStateManager = class extends Resource8 {
|
|
|
4580
4568
|
documentListCheckScheduler.trigger();
|
|
4581
4569
|
return root;
|
|
4582
4570
|
}
|
|
4583
|
-
constructor(...args) {
|
|
4584
|
-
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());
|
|
4585
|
-
}
|
|
4586
4571
|
};
|
|
4587
4572
|
var SpaceDocumentListUpdatedEvent = class {
|
|
4573
|
+
spaceId;
|
|
4574
|
+
spaceRootId;
|
|
4575
|
+
previousRootId;
|
|
4576
|
+
documentIds;
|
|
4588
4577
|
constructor(spaceId, spaceRootId, previousRootId, documentIds) {
|
|
4589
|
-
_define_property15(this, "spaceId", void 0);
|
|
4590
|
-
_define_property15(this, "spaceRootId", void 0);
|
|
4591
|
-
_define_property15(this, "previousRootId", void 0);
|
|
4592
|
-
_define_property15(this, "documentIds", void 0);
|
|
4593
4578
|
this.spaceId = spaceId;
|
|
4594
4579
|
this.spaceRootId = spaceRootId;
|
|
4595
4580
|
this.previousRootId = previousRootId;
|
|
@@ -4598,19 +4583,6 @@ var SpaceDocumentListUpdatedEvent = class {
|
|
|
4598
4583
|
};
|
|
4599
4584
|
|
|
4600
4585
|
// src/db-host/echo-host.ts
|
|
4601
|
-
function _define_property16(obj, key, value) {
|
|
4602
|
-
if (key in obj) {
|
|
4603
|
-
Object.defineProperty(obj, key, {
|
|
4604
|
-
value,
|
|
4605
|
-
enumerable: true,
|
|
4606
|
-
configurable: true,
|
|
4607
|
-
writable: true
|
|
4608
|
-
});
|
|
4609
|
-
} else {
|
|
4610
|
-
obj[key] = value;
|
|
4611
|
-
}
|
|
4612
|
-
return obj;
|
|
4613
|
-
}
|
|
4614
4586
|
var __dxlog_file16 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/echo-host.ts";
|
|
4615
4587
|
var DEFAULT_INDEXING_CONFIG = {
|
|
4616
4588
|
// TODO(dmaretskyi): Disabled by default since embedding generation is expensive.
|
|
@@ -4618,6 +4590,111 @@ var DEFAULT_INDEXING_CONFIG = {
|
|
|
4618
4590
|
vector: false
|
|
4619
4591
|
};
|
|
4620
4592
|
var EchoHost = class extends Resource9 {
|
|
4593
|
+
_indexMetadataStore;
|
|
4594
|
+
_indexer;
|
|
4595
|
+
_automergeHost;
|
|
4596
|
+
_queryService;
|
|
4597
|
+
_dataService;
|
|
4598
|
+
_spaceStateManager = new SpaceStateManager();
|
|
4599
|
+
_echoDataMonitor;
|
|
4600
|
+
constructor({ kv, indexing = {}, peerIdProvider, getSpaceKeyByRootDocumentId }) {
|
|
4601
|
+
super();
|
|
4602
|
+
const indexingConfig = {
|
|
4603
|
+
...DEFAULT_INDEXING_CONFIG,
|
|
4604
|
+
...indexing
|
|
4605
|
+
};
|
|
4606
|
+
this._indexMetadataStore = new IndexMetadataStore({
|
|
4607
|
+
db: kv.sublevel("index-metadata")
|
|
4608
|
+
});
|
|
4609
|
+
this._echoDataMonitor = new EchoDataMonitor();
|
|
4610
|
+
this._automergeHost = new AutomergeHost({
|
|
4611
|
+
db: kv,
|
|
4612
|
+
dataMonitor: this._echoDataMonitor,
|
|
4613
|
+
indexMetadataStore: this._indexMetadataStore,
|
|
4614
|
+
peerIdProvider,
|
|
4615
|
+
getSpaceKeyByRootDocumentId
|
|
4616
|
+
});
|
|
4617
|
+
this._indexer = new Indexer({
|
|
4618
|
+
db: kv,
|
|
4619
|
+
indexStore: new IndexStore({
|
|
4620
|
+
db: kv.sublevel("index-storage")
|
|
4621
|
+
}),
|
|
4622
|
+
metadataStore: this._indexMetadataStore,
|
|
4623
|
+
loadDocuments: createSelectedDocumentsIterator(this._automergeHost),
|
|
4624
|
+
indexCooldownTime: false ? 0 : void 0
|
|
4625
|
+
});
|
|
4626
|
+
void this._indexer.setConfig({
|
|
4627
|
+
enabled: true,
|
|
4628
|
+
indexes: [
|
|
4629
|
+
//
|
|
4630
|
+
{
|
|
4631
|
+
kind: IndexKind.Kind.SCHEMA_MATCH
|
|
4632
|
+
},
|
|
4633
|
+
{
|
|
4634
|
+
kind: IndexKind.Kind.GRAPH
|
|
4635
|
+
},
|
|
4636
|
+
...indexingConfig.fullText ? [
|
|
4637
|
+
{
|
|
4638
|
+
kind: IndexKind.Kind.FULL_TEXT
|
|
4639
|
+
}
|
|
4640
|
+
] : [],
|
|
4641
|
+
...indexingConfig.vector ? [
|
|
4642
|
+
{
|
|
4643
|
+
kind: IndexKind.Kind.VECTOR
|
|
4644
|
+
}
|
|
4645
|
+
] : []
|
|
4646
|
+
]
|
|
4647
|
+
});
|
|
4648
|
+
this._queryService = new QueryServiceImpl({
|
|
4649
|
+
automergeHost: this._automergeHost,
|
|
4650
|
+
indexer: this._indexer,
|
|
4651
|
+
spaceStateManager: this._spaceStateManager
|
|
4652
|
+
});
|
|
4653
|
+
this._dataService = new DataServiceImpl({
|
|
4654
|
+
automergeHost: this._automergeHost,
|
|
4655
|
+
spaceStateManager: this._spaceStateManager,
|
|
4656
|
+
updateIndexes: async () => {
|
|
4657
|
+
await this._indexer.updateIndexes();
|
|
4658
|
+
}
|
|
4659
|
+
});
|
|
4660
|
+
trace5.diagnostic({
|
|
4661
|
+
id: "echo-stats",
|
|
4662
|
+
name: "Echo Stats",
|
|
4663
|
+
fetch: async () => {
|
|
4664
|
+
return {
|
|
4665
|
+
dataStats: this._echoDataMonitor.computeStats(),
|
|
4666
|
+
loadedDocsCount: this._automergeHost.loadedDocsCount
|
|
4667
|
+
};
|
|
4668
|
+
}
|
|
4669
|
+
});
|
|
4670
|
+
trace5.diagnostic({
|
|
4671
|
+
id: "database-roots",
|
|
4672
|
+
name: "Database Roots",
|
|
4673
|
+
fetch: async () => {
|
|
4674
|
+
return Array.from(this._spaceStateManager.roots.values()).map((root) => ({
|
|
4675
|
+
url: root.url,
|
|
4676
|
+
isLoaded: root.isLoaded,
|
|
4677
|
+
spaceKey: root.getSpaceKey(),
|
|
4678
|
+
inlineObjects: root.getInlineObjectCount(),
|
|
4679
|
+
linkedObjects: root.getLinkedObjectCount()
|
|
4680
|
+
}));
|
|
4681
|
+
}
|
|
4682
|
+
});
|
|
4683
|
+
trace5.diagnostic({
|
|
4684
|
+
id: "database-root-metrics",
|
|
4685
|
+
name: "Database Roots (with metrics)",
|
|
4686
|
+
fetch: async () => {
|
|
4687
|
+
return Array.from(this._spaceStateManager.roots.values()).map((root) => ({
|
|
4688
|
+
url: root.url,
|
|
4689
|
+
isLoaded: root.isLoaded,
|
|
4690
|
+
spaceKey: root.getSpaceKey(),
|
|
4691
|
+
inlineObjects: root.getInlineObjectCount(),
|
|
4692
|
+
linkedObjects: root.getLinkedObjectCount(),
|
|
4693
|
+
...root.measureMetrics() ?? {}
|
|
4694
|
+
}));
|
|
4695
|
+
}
|
|
4696
|
+
});
|
|
4697
|
+
}
|
|
4621
4698
|
get queryService() {
|
|
4622
4699
|
return this._queryService;
|
|
4623
4700
|
}
|
|
@@ -4658,7 +4735,7 @@ var EchoHost = class extends Resource9 {
|
|
|
4658
4735
|
* Flush all pending writes to the underlying storage.
|
|
4659
4736
|
*/
|
|
4660
4737
|
async flush() {
|
|
4661
|
-
await this._automergeHost.
|
|
4738
|
+
await this._automergeHost.flush();
|
|
4662
4739
|
}
|
|
4663
4740
|
/**
|
|
4664
4741
|
* Perform any pending index updates.
|
|
@@ -4742,107 +4819,10 @@ var EchoHost = class extends Resource9 {
|
|
|
4742
4819
|
async removeReplicator(replicator) {
|
|
4743
4820
|
await this._automergeHost.removeReplicator(replicator);
|
|
4744
4821
|
}
|
|
4745
|
-
constructor({ kv, indexing = {}, peerIdProvider, getSpaceKeyByRootDocumentId }) {
|
|
4746
|
-
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);
|
|
4747
|
-
const indexingConfig = {
|
|
4748
|
-
...DEFAULT_INDEXING_CONFIG,
|
|
4749
|
-
...indexing
|
|
4750
|
-
};
|
|
4751
|
-
this._indexMetadataStore = new IndexMetadataStore({
|
|
4752
|
-
db: kv.sublevel("index-metadata")
|
|
4753
|
-
});
|
|
4754
|
-
this._echoDataMonitor = new EchoDataMonitor();
|
|
4755
|
-
this._automergeHost = new AutomergeHost({
|
|
4756
|
-
db: kv,
|
|
4757
|
-
dataMonitor: this._echoDataMonitor,
|
|
4758
|
-
indexMetadataStore: this._indexMetadataStore,
|
|
4759
|
-
peerIdProvider,
|
|
4760
|
-
getSpaceKeyByRootDocumentId
|
|
4761
|
-
});
|
|
4762
|
-
this._indexer = new Indexer({
|
|
4763
|
-
db: kv,
|
|
4764
|
-
indexStore: new IndexStore({
|
|
4765
|
-
db: kv.sublevel("index-storage")
|
|
4766
|
-
}),
|
|
4767
|
-
metadataStore: this._indexMetadataStore,
|
|
4768
|
-
loadDocuments: createSelectedDocumentsIterator(this._automergeHost),
|
|
4769
|
-
indexCooldownTime: false ? 0 : void 0
|
|
4770
|
-
});
|
|
4771
|
-
void this._indexer.setConfig({
|
|
4772
|
-
enabled: true,
|
|
4773
|
-
indexes: [
|
|
4774
|
-
//
|
|
4775
|
-
{
|
|
4776
|
-
kind: IndexKind.Kind.SCHEMA_MATCH
|
|
4777
|
-
},
|
|
4778
|
-
{
|
|
4779
|
-
kind: IndexKind.Kind.GRAPH
|
|
4780
|
-
},
|
|
4781
|
-
...indexingConfig.fullText ? [
|
|
4782
|
-
{
|
|
4783
|
-
kind: IndexKind.Kind.FULL_TEXT
|
|
4784
|
-
}
|
|
4785
|
-
] : [],
|
|
4786
|
-
...indexingConfig.vector ? [
|
|
4787
|
-
{
|
|
4788
|
-
kind: IndexKind.Kind.VECTOR
|
|
4789
|
-
}
|
|
4790
|
-
] : []
|
|
4791
|
-
]
|
|
4792
|
-
});
|
|
4793
|
-
this._queryService = new QueryServiceImpl({
|
|
4794
|
-
automergeHost: this._automergeHost,
|
|
4795
|
-
indexer: this._indexer,
|
|
4796
|
-
spaceStateManager: this._spaceStateManager
|
|
4797
|
-
});
|
|
4798
|
-
this._dataService = new DataServiceImpl({
|
|
4799
|
-
automergeHost: this._automergeHost,
|
|
4800
|
-
spaceStateManager: this._spaceStateManager,
|
|
4801
|
-
updateIndexes: async () => {
|
|
4802
|
-
await this._indexer.updateIndexes();
|
|
4803
|
-
}
|
|
4804
|
-
});
|
|
4805
|
-
trace5.diagnostic({
|
|
4806
|
-
id: "echo-stats",
|
|
4807
|
-
name: "Echo Stats",
|
|
4808
|
-
fetch: async () => {
|
|
4809
|
-
return {
|
|
4810
|
-
dataStats: this._echoDataMonitor.computeStats(),
|
|
4811
|
-
loadedDocsCount: this._automergeHost.loadedDocsCount
|
|
4812
|
-
};
|
|
4813
|
-
}
|
|
4814
|
-
});
|
|
4815
|
-
trace5.diagnostic({
|
|
4816
|
-
id: "database-roots",
|
|
4817
|
-
name: "Database Roots",
|
|
4818
|
-
fetch: async () => {
|
|
4819
|
-
return Array.from(this._spaceStateManager.roots.values()).map((root) => ({
|
|
4820
|
-
url: root.url,
|
|
4821
|
-
isLoaded: root.isLoaded,
|
|
4822
|
-
spaceKey: root.getSpaceKey(),
|
|
4823
|
-
inlineObjects: root.getInlineObjectCount(),
|
|
4824
|
-
linkedObjects: root.getLinkedObjectCount()
|
|
4825
|
-
}));
|
|
4826
|
-
}
|
|
4827
|
-
});
|
|
4828
|
-
trace5.diagnostic({
|
|
4829
|
-
id: "database-root-metrics",
|
|
4830
|
-
name: "Database Roots (with metrics)",
|
|
4831
|
-
fetch: async () => {
|
|
4832
|
-
return Array.from(this._spaceStateManager.roots.values()).map((root) => ({
|
|
4833
|
-
url: root.url,
|
|
4834
|
-
isLoaded: root.isLoaded,
|
|
4835
|
-
spaceKey: root.getSpaceKey(),
|
|
4836
|
-
inlineObjects: root.getInlineObjectCount(),
|
|
4837
|
-
linkedObjects: root.getLinkedObjectCount(),
|
|
4838
|
-
...root.measureMetrics() ?? {}
|
|
4839
|
-
}));
|
|
4840
|
-
}
|
|
4841
|
-
});
|
|
4842
|
-
}
|
|
4843
4822
|
};
|
|
4844
4823
|
|
|
4845
4824
|
// src/edge/echo-edge-replicator.ts
|
|
4825
|
+
import * as Automerge from "@automerge/automerge";
|
|
4846
4826
|
import { cbor as cbor2 } from "@automerge/automerge-repo";
|
|
4847
4827
|
import { Mutex, scheduleMicroTask as scheduleMicroTask2, scheduleTask as scheduleTask2 } from "@dxos/async";
|
|
4848
4828
|
import { Context as Context6, Resource as Resource11 } from "@dxos/context";
|
|
@@ -4852,27 +4832,26 @@ import { log as log13 } from "@dxos/log";
|
|
|
4852
4832
|
import { DocumentCodec, EdgeService } from "@dxos/protocols";
|
|
4853
4833
|
import { buf } from "@dxos/protocols/buf";
|
|
4854
4834
|
import { MessageSchema as RouterMessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
4855
|
-
import { bufferToArray as bufferToArray2 } from "@dxos/util";
|
|
4835
|
+
import { bufferToArray as bufferToArray2, setDeep } from "@dxos/util";
|
|
4856
4836
|
|
|
4857
4837
|
// src/edge/inflight-request-limiter.ts
|
|
4858
4838
|
import { Trigger as Trigger2 } from "@dxos/async";
|
|
4859
4839
|
import { Resource as Resource10 } from "@dxos/context";
|
|
4860
4840
|
import { log as log12 } from "@dxos/log";
|
|
4861
|
-
function _define_property17(obj, key, value) {
|
|
4862
|
-
if (key in obj) {
|
|
4863
|
-
Object.defineProperty(obj, key, {
|
|
4864
|
-
value,
|
|
4865
|
-
enumerable: true,
|
|
4866
|
-
configurable: true,
|
|
4867
|
-
writable: true
|
|
4868
|
-
});
|
|
4869
|
-
} else {
|
|
4870
|
-
obj[key] = value;
|
|
4871
|
-
}
|
|
4872
|
-
return obj;
|
|
4873
|
-
}
|
|
4874
4841
|
var __dxlog_file17 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/edge/inflight-request-limiter.ts";
|
|
4875
4842
|
var InflightRequestLimiter = class extends Resource10 {
|
|
4843
|
+
_config;
|
|
4844
|
+
/**
|
|
4845
|
+
* Decrement when we receive a sync message, increment when we send one.
|
|
4846
|
+
* Can't exceed _config.maxInflightRequests.
|
|
4847
|
+
* Resets after timeout to avoid replicator being stuck.
|
|
4848
|
+
*/
|
|
4849
|
+
_inflightRequestBalance = 0;
|
|
4850
|
+
_requestBarrier = new Trigger2();
|
|
4851
|
+
_resetBalanceTimeout;
|
|
4852
|
+
constructor(_config) {
|
|
4853
|
+
super(), this._config = _config;
|
|
4854
|
+
}
|
|
4876
4855
|
async _open() {
|
|
4877
4856
|
this._inflightRequestBalance = 0;
|
|
4878
4857
|
this._requestBarrier.reset();
|
|
@@ -4915,30 +4894,9 @@ var InflightRequestLimiter = class extends Resource10 {
|
|
|
4915
4894
|
clearInterval(this._resetBalanceTimeout);
|
|
4916
4895
|
}
|
|
4917
4896
|
}
|
|
4918
|
-
constructor(_config) {
|
|
4919
|
-
super(), _define_property17(this, "_config", void 0), /**
|
|
4920
|
-
* Decrement when we receive a sync message, increment when we send one.
|
|
4921
|
-
* Can't exceed _config.maxInflightRequests.
|
|
4922
|
-
* Resets after timeout to avoid replicator being stuck.
|
|
4923
|
-
*/
|
|
4924
|
-
_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();
|
|
4925
|
-
}
|
|
4926
4897
|
};
|
|
4927
4898
|
|
|
4928
4899
|
// src/edge/echo-edge-replicator.ts
|
|
4929
|
-
function _define_property18(obj, key, value) {
|
|
4930
|
-
if (key in obj) {
|
|
4931
|
-
Object.defineProperty(obj, key, {
|
|
4932
|
-
value,
|
|
4933
|
-
enumerable: true,
|
|
4934
|
-
configurable: true,
|
|
4935
|
-
writable: true
|
|
4936
|
-
});
|
|
4937
|
-
} else {
|
|
4938
|
-
obj[key] = value;
|
|
4939
|
-
}
|
|
4940
|
-
return obj;
|
|
4941
|
-
}
|
|
4942
4900
|
function _ts_add_disposable_resource(env, value, async) {
|
|
4943
4901
|
if (value !== null && value !== void 0) {
|
|
4944
4902
|
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
@@ -5009,20 +4967,33 @@ var INITIAL_RESTART_DELAY = 500;
|
|
|
5009
4967
|
var RESTART_DELAY_JITTER = 250;
|
|
5010
4968
|
var MAX_RESTART_DELAY = 5e3;
|
|
5011
4969
|
var EchoEdgeReplicator = class {
|
|
4970
|
+
_edgeConnection;
|
|
4971
|
+
_edgeHttpClient;
|
|
4972
|
+
_mutex = new Mutex();
|
|
4973
|
+
_ctx = void 0;
|
|
4974
|
+
_context = null;
|
|
4975
|
+
_connectedSpaces = /* @__PURE__ */ new Set();
|
|
4976
|
+
_connections = /* @__PURE__ */ new Map();
|
|
4977
|
+
_sharePolicyEnabled = true;
|
|
4978
|
+
constructor({ edgeConnection, edgeHttpClient, disableSharePolicy }) {
|
|
4979
|
+
this._edgeConnection = edgeConnection;
|
|
4980
|
+
this._edgeHttpClient = edgeHttpClient;
|
|
4981
|
+
this._sharePolicyEnabled = !disableSharePolicy;
|
|
4982
|
+
}
|
|
5012
4983
|
async connect(context) {
|
|
5013
4984
|
log13("connecting...", {
|
|
5014
4985
|
peerId: context.peerId,
|
|
5015
4986
|
connectedSpaces: this._connectedSpaces.size
|
|
5016
4987
|
}, {
|
|
5017
4988
|
F: __dxlog_file18,
|
|
5018
|
-
L:
|
|
4989
|
+
L: 73,
|
|
5019
4990
|
S: this,
|
|
5020
4991
|
C: (f, a) => f(...a)
|
|
5021
4992
|
});
|
|
5022
4993
|
this._context = context;
|
|
5023
4994
|
this._ctx = Context6.default(void 0, {
|
|
5024
4995
|
F: __dxlog_file18,
|
|
5025
|
-
L:
|
|
4996
|
+
L: 75
|
|
5026
4997
|
});
|
|
5027
4998
|
this._ctx.onDispose(this._edgeConnection.onReconnected(() => {
|
|
5028
4999
|
this._ctx && scheduleMicroTask2(this._ctx, () => this._handleReconnect());
|
|
@@ -5121,7 +5092,7 @@ var EchoEdgeReplicator = class {
|
|
|
5121
5092
|
async _openConnection(spaceId, reconnects = 0) {
|
|
5122
5093
|
invariant14(this._context, void 0, {
|
|
5123
5094
|
F: __dxlog_file18,
|
|
5124
|
-
L:
|
|
5095
|
+
L: 136,
|
|
5125
5096
|
S: this,
|
|
5126
5097
|
A: [
|
|
5127
5098
|
"this._context",
|
|
@@ -5130,7 +5101,7 @@ var EchoEdgeReplicator = class {
|
|
|
5130
5101
|
});
|
|
5131
5102
|
invariant14(!this._connections.has(spaceId), void 0, {
|
|
5132
5103
|
F: __dxlog_file18,
|
|
5133
|
-
L:
|
|
5104
|
+
L: 137,
|
|
5134
5105
|
S: this,
|
|
5135
5106
|
A: [
|
|
5136
5107
|
"!this._connections.has(spaceId)",
|
|
@@ -5149,7 +5120,7 @@ var EchoEdgeReplicator = class {
|
|
|
5149
5120
|
spaceId
|
|
5150
5121
|
}, {
|
|
5151
5122
|
F: __dxlog_file18,
|
|
5152
|
-
L:
|
|
5123
|
+
L: 148,
|
|
5153
5124
|
S: this,
|
|
5154
5125
|
C: (f, a) => f(...a)
|
|
5155
5126
|
});
|
|
@@ -5160,7 +5131,7 @@ var EchoEdgeReplicator = class {
|
|
|
5160
5131
|
spaceId
|
|
5161
5132
|
}, {
|
|
5162
5133
|
F: __dxlog_file18,
|
|
5163
|
-
L:
|
|
5134
|
+
L: 152,
|
|
5164
5135
|
S: this,
|
|
5165
5136
|
C: (f, a) => f(...a)
|
|
5166
5137
|
});
|
|
@@ -5177,7 +5148,7 @@ var EchoEdgeReplicator = class {
|
|
|
5177
5148
|
restartDelay
|
|
5178
5149
|
}, {
|
|
5179
5150
|
F: __dxlog_file18,
|
|
5180
|
-
L:
|
|
5151
|
+
L: 163,
|
|
5181
5152
|
S: this,
|
|
5182
5153
|
C: (f, a) => f(...a)
|
|
5183
5154
|
});
|
|
@@ -5205,7 +5176,7 @@ var EchoEdgeReplicator = class {
|
|
|
5205
5176
|
restartDelay
|
|
5206
5177
|
}, {
|
|
5207
5178
|
F: __dxlog_file18,
|
|
5208
|
-
L:
|
|
5179
|
+
L: 180,
|
|
5209
5180
|
S: this,
|
|
5210
5181
|
C: (f, a) => f(...a)
|
|
5211
5182
|
});
|
|
@@ -5222,27 +5193,57 @@ var EchoEdgeReplicator = class {
|
|
|
5222
5193
|
this._connections.set(spaceId, connection);
|
|
5223
5194
|
await connection.open();
|
|
5224
5195
|
}
|
|
5225
|
-
constructor({ edgeConnection, edgeHttpClient, disableSharePolicy }) {
|
|
5226
|
-
_define_property18(this, "_edgeConnection", void 0);
|
|
5227
|
-
_define_property18(this, "_edgeHttpClient", void 0);
|
|
5228
|
-
_define_property18(this, "_mutex", new Mutex());
|
|
5229
|
-
_define_property18(this, "_ctx", void 0);
|
|
5230
|
-
_define_property18(this, "_context", null);
|
|
5231
|
-
_define_property18(this, "_connectedSpaces", /* @__PURE__ */ new Set());
|
|
5232
|
-
_define_property18(this, "_connections", /* @__PURE__ */ new Map());
|
|
5233
|
-
_define_property18(this, "_sharePolicyEnabled", true);
|
|
5234
|
-
this._edgeConnection = edgeConnection;
|
|
5235
|
-
this._edgeHttpClient = edgeHttpClient;
|
|
5236
|
-
this._sharePolicyEnabled = !disableSharePolicy;
|
|
5237
|
-
}
|
|
5238
5196
|
};
|
|
5239
5197
|
var MAX_INFLIGHT_REQUESTS = 5;
|
|
5240
5198
|
var MAX_RATE_LIMIT_WAIT_TIME_MS = 3e3;
|
|
5241
5199
|
var EdgeReplicatorConnection = class extends Resource11 {
|
|
5200
|
+
_connectionId = randomUUID();
|
|
5201
|
+
_edgeConnection;
|
|
5202
|
+
_edgeHttpClient;
|
|
5203
|
+
_remotePeerId = null;
|
|
5204
|
+
_targetServiceId;
|
|
5205
|
+
_spaceId;
|
|
5206
|
+
_context;
|
|
5207
|
+
_sharedPolicyEnabled;
|
|
5208
|
+
_onRemoteConnected;
|
|
5209
|
+
_onRemoteDisconnected;
|
|
5210
|
+
_onRestartRequested;
|
|
5211
|
+
_sequence = 0;
|
|
5212
|
+
_requestLimiter = new InflightRequestLimiter({
|
|
5213
|
+
maxInflightRequests: MAX_INFLIGHT_REQUESTS,
|
|
5214
|
+
resetBalanceTimeoutMs: MAX_RATE_LIMIT_WAIT_TIME_MS
|
|
5215
|
+
});
|
|
5216
|
+
_readableStreamController;
|
|
5217
|
+
readable;
|
|
5218
|
+
writable;
|
|
5219
|
+
constructor({ edgeConnection, edgeHttpClient, spaceId, context, sharedPolicyEnabled, onRemoteConnected, onRemoteDisconnected, onRestartRequested }) {
|
|
5220
|
+
super();
|
|
5221
|
+
this._edgeConnection = edgeConnection;
|
|
5222
|
+
this._edgeHttpClient = edgeHttpClient;
|
|
5223
|
+
this._spaceId = spaceId;
|
|
5224
|
+
this._context = context;
|
|
5225
|
+
this._remotePeerId = `${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}-${this._connectionId}`;
|
|
5226
|
+
this._targetServiceId = `${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}`;
|
|
5227
|
+
this._sharedPolicyEnabled = sharedPolicyEnabled;
|
|
5228
|
+
this._onRemoteConnected = onRemoteConnected;
|
|
5229
|
+
this._onRemoteDisconnected = onRemoteDisconnected;
|
|
5230
|
+
this._onRestartRequested = onRestartRequested;
|
|
5231
|
+
this.readable = new ReadableStream({
|
|
5232
|
+
start: (controller) => {
|
|
5233
|
+
this._readableStreamController = controller;
|
|
5234
|
+
}
|
|
5235
|
+
});
|
|
5236
|
+
this.writable = new WritableStream({
|
|
5237
|
+
write: async (message, controller) => {
|
|
5238
|
+
await this._requestLimiter.rateLimit(message);
|
|
5239
|
+
await this._sendMessage(message);
|
|
5240
|
+
}
|
|
5241
|
+
});
|
|
5242
|
+
}
|
|
5242
5243
|
async _open(ctx) {
|
|
5243
5244
|
log13("opening...", void 0, {
|
|
5244
5245
|
F: __dxlog_file18,
|
|
5245
|
-
L:
|
|
5246
|
+
L: 273,
|
|
5246
5247
|
S: this,
|
|
5247
5248
|
C: (f, a) => f(...a)
|
|
5248
5249
|
});
|
|
@@ -5257,7 +5258,7 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5257
5258
|
if (firstReconnect) {
|
|
5258
5259
|
log13.verbose("first reconnect skipped", void 0, {
|
|
5259
5260
|
F: __dxlog_file18,
|
|
5260
|
-
L:
|
|
5261
|
+
L: 288,
|
|
5261
5262
|
S: this,
|
|
5262
5263
|
C: (f, a) => f(...a)
|
|
5263
5264
|
});
|
|
@@ -5272,7 +5273,7 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5272
5273
|
async _close() {
|
|
5273
5274
|
log13("closing...", void 0, {
|
|
5274
5275
|
F: __dxlog_file18,
|
|
5275
|
-
L:
|
|
5276
|
+
L: 301,
|
|
5276
5277
|
S: this,
|
|
5277
5278
|
C: (f, a) => f(...a)
|
|
5278
5279
|
});
|
|
@@ -5283,7 +5284,7 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5283
5284
|
get peerId() {
|
|
5284
5285
|
invariant14(this._remotePeerId, "Not connected", {
|
|
5285
5286
|
F: __dxlog_file18,
|
|
5286
|
-
L:
|
|
5287
|
+
L: 310,
|
|
5287
5288
|
S: this,
|
|
5288
5289
|
A: [
|
|
5289
5290
|
"this._remotePeerId",
|
|
@@ -5308,7 +5309,7 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5308
5309
|
remoteId: this._remotePeerId
|
|
5309
5310
|
}, {
|
|
5310
5311
|
F: __dxlog_file18,
|
|
5311
|
-
L:
|
|
5312
|
+
L: 325,
|
|
5312
5313
|
S: this,
|
|
5313
5314
|
C: (f, a) => f(...a)
|
|
5314
5315
|
});
|
|
@@ -5329,12 +5330,11 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5329
5330
|
}
|
|
5330
5331
|
const payload = cbor2.decode(message.payload.value);
|
|
5331
5332
|
log13.verbose("received", {
|
|
5332
|
-
|
|
5333
|
-
documentId: payload.type === "sync" && payload.documentId,
|
|
5333
|
+
...getMessageInfo(payload),
|
|
5334
5334
|
remoteId: this._remotePeerId
|
|
5335
5335
|
}, {
|
|
5336
5336
|
F: __dxlog_file18,
|
|
5337
|
-
L:
|
|
5337
|
+
L: 354,
|
|
5338
5338
|
S: this,
|
|
5339
5339
|
C: (f, a) => f(...a)
|
|
5340
5340
|
});
|
|
@@ -5365,7 +5365,7 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5365
5365
|
]));
|
|
5366
5366
|
}
|
|
5367
5367
|
_processMessage(message) {
|
|
5368
|
-
if (
|
|
5368
|
+
if (isErrorMessage(message)) {
|
|
5369
5369
|
this._onRestartRequested();
|
|
5370
5370
|
return;
|
|
5371
5371
|
}
|
|
@@ -5374,13 +5374,20 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5374
5374
|
}
|
|
5375
5375
|
async _sendMessage(message) {
|
|
5376
5376
|
message.targetId = this._targetServiceId;
|
|
5377
|
+
setDeep(message, [
|
|
5378
|
+
"metadata",
|
|
5379
|
+
"dxos_sequence"
|
|
5380
|
+
], this._getSequence());
|
|
5381
|
+
setDeep(message, [
|
|
5382
|
+
"metadata",
|
|
5383
|
+
"dxos_connectionId"
|
|
5384
|
+
], this._connectionId);
|
|
5377
5385
|
log13.verbose("sending...", {
|
|
5378
|
-
|
|
5379
|
-
documentId: message.type === "sync" && message.documentId,
|
|
5386
|
+
...getMessageInfo(message),
|
|
5380
5387
|
remoteId: this._remotePeerId
|
|
5381
5388
|
}, {
|
|
5382
5389
|
F: __dxlog_file18,
|
|
5383
|
-
L:
|
|
5390
|
+
L: 407,
|
|
5384
5391
|
S: this,
|
|
5385
5392
|
C: (f, a) => f(...a)
|
|
5386
5393
|
});
|
|
@@ -5401,41 +5408,29 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5401
5408
|
err
|
|
5402
5409
|
}, {
|
|
5403
5410
|
F: __dxlog_file18,
|
|
5404
|
-
L:
|
|
5411
|
+
L: 426,
|
|
5405
5412
|
S: this,
|
|
5406
5413
|
C: (f, a) => f(...a)
|
|
5407
5414
|
});
|
|
5408
5415
|
}
|
|
5409
5416
|
}
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
maxInflightRequests: MAX_INFLIGHT_REQUESTS,
|
|
5413
|
-
resetBalanceTimeoutMs: MAX_RATE_LIMIT_WAIT_TIME_MS
|
|
5414
|
-
})), _define_property18(this, "_readableStreamController", void 0), _define_property18(this, "readable", void 0), _define_property18(this, "writable", void 0);
|
|
5415
|
-
this._edgeConnection = edgeConnection;
|
|
5416
|
-
this._edgeHttpClient = edgeHttpClient;
|
|
5417
|
-
this._spaceId = spaceId;
|
|
5418
|
-
this._context = context;
|
|
5419
|
-
this._remotePeerId = `${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}-${randomUUID()}`;
|
|
5420
|
-
this._targetServiceId = `${EdgeService.AUTOMERGE_REPLICATOR}:${spaceId}`;
|
|
5421
|
-
this._sharedPolicyEnabled = sharedPolicyEnabled;
|
|
5422
|
-
this._onRemoteConnected = onRemoteConnected;
|
|
5423
|
-
this._onRemoteDisconnected = onRemoteDisconnected;
|
|
5424
|
-
this._onRestartRequested = onRestartRequested;
|
|
5425
|
-
this.readable = new ReadableStream({
|
|
5426
|
-
start: (controller) => {
|
|
5427
|
-
this._readableStreamController = controller;
|
|
5428
|
-
}
|
|
5429
|
-
});
|
|
5430
|
-
this.writable = new WritableStream({
|
|
5431
|
-
write: async (message, controller) => {
|
|
5432
|
-
await this._requestLimiter.rateLimit(message);
|
|
5433
|
-
await this._sendMessage(message);
|
|
5434
|
-
}
|
|
5435
|
-
});
|
|
5417
|
+
_getSequence() {
|
|
5418
|
+
return this._sequence++;
|
|
5436
5419
|
}
|
|
5437
5420
|
};
|
|
5438
|
-
var
|
|
5421
|
+
var isErrorMessage = (message) => message.type === "error";
|
|
5422
|
+
var getMessageInfo = (msg) => {
|
|
5423
|
+
const { have, heads, need, changes } = msg.type === "sync" ? Automerge.decodeSyncMessage(msg.data) : {};
|
|
5424
|
+
return {
|
|
5425
|
+
type: msg.type,
|
|
5426
|
+
documentId: "documentId" in msg ? msg.documentId : void 0,
|
|
5427
|
+
have,
|
|
5428
|
+
heads,
|
|
5429
|
+
need,
|
|
5430
|
+
changes: changes?.length,
|
|
5431
|
+
sequence: msg.metadata?.dxos_sequence
|
|
5432
|
+
};
|
|
5433
|
+
};
|
|
5439
5434
|
|
|
5440
5435
|
// src/util.ts
|
|
5441
5436
|
import { ObjectStructure as ObjectStructure2, decodeReference } from "@dxos/echo-protocol";
|