@dxos/echo-pipeline 0.8.4-main.ae835ea → 0.8.4-main.bc674ce
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-WJJXJTNS.mjs → chunk-FJPXA75J.mjs} +7 -12
- package/dist/lib/browser/chunk-FJPXA75J.mjs.map +7 -0
- package/dist/lib/browser/{chunk-FR6GJ4S4.mjs → chunk-WIQUYO7H.mjs} +39 -29
- package/dist/lib/browser/chunk-WIQUYO7H.mjs.map +7 -0
- package/dist/lib/browser/filter/index.mjs +1 -2
- package/dist/lib/browser/index.mjs +1933 -620
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +28 -201
- package/dist/lib/browser/testing/index.mjs.map +4 -4
- package/dist/lib/node-esm/{chunk-JQCCVDLT.mjs → chunk-7PL6UK4B.mjs} +39 -29
- package/dist/lib/node-esm/chunk-7PL6UK4B.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-LEQ77KAT.mjs → chunk-S5KGVQFZ.mjs} +7 -12
- package/dist/lib/node-esm/chunk-S5KGVQFZ.mjs.map +7 -0
- package/dist/lib/node-esm/filter/index.mjs +1 -2
- package/dist/lib/node-esm/index.mjs +1933 -620
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +28 -201
- package/dist/lib/node-esm/testing/index.mjs.map +4 -4
- package/dist/types/src/automerge/automerge-host.d.ts +36 -9
- package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
- package/dist/types/src/automerge/automerge-repo.test.d.ts +1 -1
- package/dist/types/src/automerge/automerge-repo.test.d.ts.map +1 -1
- package/dist/types/src/automerge/collection-synchronizer.d.ts +3 -2
- package/dist/types/src/automerge/collection-synchronizer.d.ts.map +1 -1
- package/dist/types/src/automerge/echo-network-adapter.d.ts +11 -6
- package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
- package/dist/types/src/automerge/echo-replicator.d.ts +9 -6
- package/dist/types/src/automerge/echo-replicator.d.ts.map +1 -1
- package/dist/types/src/automerge/heads-store.d.ts +9 -2
- package/dist/types/src/automerge/heads-store.d.ts.map +1 -1
- package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +4 -4
- package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -1
- package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts +7 -7
- package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts.map +1 -1
- package/dist/types/src/automerge/mesh-echo-replicator.d.ts.map +1 -1
- package/dist/types/src/db-host/automerge-data-source.d.ts +34 -0
- package/dist/types/src/db-host/automerge-data-source.d.ts.map +1 -0
- package/dist/types/src/db-host/automerge-data-source.test.d.ts +2 -0
- package/dist/types/src/db-host/automerge-data-source.test.d.ts.map +1 -0
- package/dist/types/src/db-host/data-service.d.ts +4 -3
- package/dist/types/src/db-host/data-service.d.ts.map +1 -1
- package/dist/types/src/db-host/documents-iterator.d.ts.map +1 -1
- package/dist/types/src/db-host/documents-synchronizer.d.ts +6 -5
- package/dist/types/src/db-host/documents-synchronizer.d.ts.map +1 -1
- package/dist/types/src/db-host/echo-host.d.ts +43 -11
- package/dist/types/src/db-host/echo-host.d.ts.map +1 -1
- package/dist/types/src/db-host/index.d.ts +1 -0
- package/dist/types/src/db-host/index.d.ts.map +1 -1
- package/dist/types/src/db-host/local-queue-service.d.ts +15 -0
- package/dist/types/src/db-host/local-queue-service.d.ts.map +1 -0
- package/dist/types/src/db-host/query-service.d.ts +7 -2
- package/dist/types/src/db-host/query-service.d.ts.map +1 -1
- package/dist/types/src/db-host/queue-data-source.d.ts +28 -0
- package/dist/types/src/db-host/queue-data-source.d.ts.map +1 -0
- package/dist/types/src/db-host/queue-service.test.d.ts +2 -0
- package/dist/types/src/db-host/queue-service.test.d.ts.map +1 -0
- package/dist/types/src/db-host/space-state-manager.d.ts +1 -0
- package/dist/types/src/db-host/space-state-manager.d.ts.map +1 -1
- package/dist/types/src/db-host/stub.d.ts +10 -0
- package/dist/types/src/db-host/stub.d.ts.map +1 -0
- package/dist/types/src/edge/echo-edge-replicator.d.ts +2 -2
- package/dist/types/src/edge/echo-edge-replicator.d.ts.map +1 -1
- package/dist/types/src/filter/filter-match.d.ts.map +1 -1
- package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
- package/dist/types/src/pipeline/pipeline.d.ts +2 -2
- package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
- package/dist/types/src/query/errors.d.ts +11 -15
- package/dist/types/src/query/errors.d.ts.map +1 -1
- package/dist/types/src/query/plan.d.ts +37 -3
- package/dist/types/src/query/plan.d.ts.map +1 -1
- package/dist/types/src/query/query-executor.d.ts +39 -3
- package/dist/types/src/query/query-executor.d.ts.map +1 -1
- package/dist/types/src/query/query-planner.d.ts +6 -0
- package/dist/types/src/query/query-planner.d.ts.map +1 -1
- package/dist/types/src/space/auth.d.ts +3 -3
- package/dist/types/src/space/auth.d.ts.map +1 -1
- package/dist/types/src/space/control-pipeline.d.ts +2 -2
- package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
- package/dist/types/src/space/space-manager.d.ts +6 -6
- package/dist/types/src/space/space-manager.d.ts.map +1 -1
- package/dist/types/src/space/space-protocol.d.ts +5 -5
- package/dist/types/src/space/space-protocol.d.ts.map +1 -1
- package/dist/types/src/space/space.d.ts +3 -3
- package/dist/types/src/space/space.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +0 -2
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/test-network-adapter.d.ts +1 -1
- package/dist/types/src/testing/test-network-adapter.d.ts.map +1 -1
- package/dist/types/src/testing/test-replicator.d.ts +6 -6
- package/dist/types/src/testing/test-replicator.d.ts.map +1 -1
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +48 -38
- package/src/automerge/automerge-host.test.ts +37 -14
- package/src/automerge/automerge-host.ts +130 -36
- package/src/automerge/automerge-repo.test.ts +147 -30
- package/src/automerge/collection-synchronizer.test.ts +16 -10
- package/src/automerge/collection-synchronizer.ts +41 -11
- package/src/automerge/echo-network-adapter.ts +23 -11
- package/src/automerge/echo-replicator.ts +10 -6
- package/src/automerge/heads-store.ts +14 -2
- package/src/automerge/leveldb-storage-adapter.ts +4 -4
- package/src/automerge/mesh-echo-replicator-connection.ts +7 -7
- package/src/automerge/mesh-echo-replicator.ts +2 -2
- package/src/db-host/automerge-data-source.test.ts +294 -0
- package/src/db-host/automerge-data-source.ts +144 -0
- package/src/db-host/data-service.ts +10 -3
- package/src/db-host/documents-iterator.ts +3 -1
- package/src/db-host/documents-synchronizer.test.ts +77 -13
- package/src/db-host/documents-synchronizer.ts +51 -50
- package/src/db-host/echo-host.ts +191 -28
- package/src/db-host/index.ts +1 -0
- package/src/db-host/local-queue-service.ts +127 -0
- package/src/db-host/query-service.ts +17 -4
- package/src/db-host/queue-data-source.ts +132 -0
- package/src/db-host/queue-service.test.ts +141 -0
- package/src/db-host/space-state-manager.ts +4 -0
- package/src/db-host/stub.ts +28 -0
- package/src/edge/echo-edge-replicator.ts +12 -8
- package/src/filter/filter-match.test.ts +31 -25
- package/src/filter/filter-match.ts +8 -14
- package/src/metadata/metadata-store.ts +5 -2
- package/src/pipeline/pipeline.ts +2 -2
- package/src/query/errors.ts +2 -2
- package/src/query/plan.ts +48 -3
- package/src/query/query-executor.ts +612 -131
- package/src/query/query-planner.test.ts +509 -35
- package/src/query/query-planner.ts +187 -13
- package/src/space/admission-discovery-extension.ts +1 -1
- package/src/space/auth.ts +6 -6
- package/src/space/control-pipeline.ts +2 -2
- package/src/space/space-manager.ts +6 -6
- package/src/space/space-protocol.ts +11 -11
- package/src/space/space.ts +3 -3
- package/src/testing/index.ts +0 -2
- package/src/testing/test-network-adapter.ts +16 -3
- package/src/testing/test-replicator.ts +8 -7
- package/src/util.ts +7 -3
- package/dist/lib/browser/chunk-CGS2ULMK.mjs +0 -11
- package/dist/lib/browser/chunk-CGS2ULMK.mjs.map +0 -7
- package/dist/lib/browser/chunk-FR6GJ4S4.mjs.map +0 -7
- package/dist/lib/browser/chunk-WJJXJTNS.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-JQCCVDLT.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-LEQ77KAT.mjs.map +0 -7
- package/dist/types/src/testing/test-data.d.ts +0 -18
- package/dist/types/src/testing/test-data.d.ts.map +0 -1
- package/dist/types/src/testing/test-schema.d.ts +0 -37
- package/dist/types/src/testing/test-schema.d.ts.map +0 -1
- package/src/testing/test-data.ts +0 -127
- package/src/testing/test-schema.ts +0 -53
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
filterMatchObject,
|
|
4
4
|
filterMatchObjectJSON,
|
|
5
5
|
filterMatchValue
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-FJPXA75J.mjs";
|
|
7
7
|
import {
|
|
8
8
|
AuthExtension,
|
|
9
9
|
AuthStatus,
|
|
@@ -26,28 +26,142 @@ import {
|
|
|
26
26
|
mapTimeframeToFeedIndexes,
|
|
27
27
|
startAfter,
|
|
28
28
|
valueEncoding
|
|
29
|
-
} from "./chunk-
|
|
30
|
-
|
|
29
|
+
} from "./chunk-WIQUYO7H.mjs";
|
|
30
|
+
|
|
31
|
+
// src/db-host/automerge-data-source.ts
|
|
32
|
+
import * as Effect from "effect/Effect";
|
|
33
|
+
import { Context } from "@dxos/context";
|
|
34
|
+
import { objectStructureToJson } from "@dxos/echo/internal";
|
|
35
|
+
import { DatabaseDirectory, SpaceDocVersion } from "@dxos/echo-protocol";
|
|
36
|
+
import { PublicKey } from "@dxos/keys";
|
|
37
|
+
import { log } from "@dxos/log";
|
|
38
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/automerge-data-source.ts";
|
|
39
|
+
var HEADS_DELIMITER = "|";
|
|
40
|
+
var headsCodec = {
|
|
41
|
+
/**
|
|
42
|
+
* Serialize automerge heads to a cursor string.
|
|
43
|
+
* Heads are sorted to ensure consistent comparison.
|
|
44
|
+
*/
|
|
45
|
+
encode: (heads) => [
|
|
46
|
+
...heads
|
|
47
|
+
].sort().join(HEADS_DELIMITER),
|
|
48
|
+
/**
|
|
49
|
+
* Deserialize a cursor string back to heads array.
|
|
50
|
+
*/
|
|
51
|
+
decode: (cursor) => cursor ? cursor.split(HEADS_DELIMITER) : []
|
|
52
|
+
};
|
|
53
|
+
var hasChanged = (cursor, currentHeads) => {
|
|
54
|
+
if (!cursor) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
return cursor !== headsCodec.encode(currentHeads);
|
|
58
|
+
};
|
|
59
|
+
var AutomergeDataSource = class {
|
|
60
|
+
sourceName = "automerge";
|
|
61
|
+
#automergeHost;
|
|
62
|
+
constructor(automergeHost) {
|
|
63
|
+
this.#automergeHost = automergeHost;
|
|
64
|
+
}
|
|
65
|
+
getChangedObjects(cursors, opts) {
|
|
66
|
+
return Effect.gen(this, function* () {
|
|
67
|
+
const cursorMap = /* @__PURE__ */ new Map();
|
|
68
|
+
for (const cursor of cursors) {
|
|
69
|
+
if (cursor.resourceId) {
|
|
70
|
+
cursorMap.set(cursor.resourceId, String(cursor.cursor));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const changedDocuments = yield* Effect.promise(async () => {
|
|
74
|
+
const result = [];
|
|
75
|
+
const limit = opts?.limit ?? Infinity;
|
|
76
|
+
for await (const { documentId, heads } of this.#automergeHost.listDocumentHeads()) {
|
|
77
|
+
const existingCursor = cursorMap.get(documentId);
|
|
78
|
+
if (hasChanged(existingCursor, heads)) {
|
|
79
|
+
result.push({
|
|
80
|
+
documentId,
|
|
81
|
+
heads
|
|
82
|
+
});
|
|
83
|
+
if (result.length >= limit) {
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
});
|
|
90
|
+
const objects = [];
|
|
91
|
+
const updatedCursors = [];
|
|
92
|
+
for (const { documentId, heads: docHeads } of changedDocuments) {
|
|
93
|
+
try {
|
|
94
|
+
const handle = yield* Effect.promise(() => this.#automergeHost.loadDoc(Context.default(void 0, {
|
|
95
|
+
F: __dxlog_file,
|
|
96
|
+
L: 97
|
|
97
|
+
}), documentId));
|
|
98
|
+
const doc = handle.doc();
|
|
99
|
+
if (!doc) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (doc.version !== SpaceDocVersion.CURRENT) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const spaceKeyHex = DatabaseDirectory.getSpaceKey(doc);
|
|
106
|
+
if (!spaceKeyHex) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const spaceKey = PublicKey.fromHex(spaceKeyHex);
|
|
110
|
+
const spaceId = yield* Effect.promise(() => createIdFromSpaceKey(spaceKey));
|
|
111
|
+
const docObjects = doc.objects ?? {};
|
|
112
|
+
for (const [objectId, structure] of Object.entries(docObjects)) {
|
|
113
|
+
objects.push({
|
|
114
|
+
spaceId,
|
|
115
|
+
documentId,
|
|
116
|
+
queueId: null,
|
|
117
|
+
recordId: null,
|
|
118
|
+
data: objectStructureToJson(objectId, structure)
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
updatedCursors.push({
|
|
122
|
+
spaceId,
|
|
123
|
+
resourceId: documentId,
|
|
124
|
+
cursor: headsCodec.encode(docHeads)
|
|
125
|
+
});
|
|
126
|
+
} catch (error) {
|
|
127
|
+
log.error("Error loading document for indexing", {
|
|
128
|
+
documentId,
|
|
129
|
+
error
|
|
130
|
+
}, {
|
|
131
|
+
F: __dxlog_file,
|
|
132
|
+
L: 137,
|
|
133
|
+
S: this,
|
|
134
|
+
C: (f, a) => f(...a)
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
objects,
|
|
140
|
+
cursors: updatedCursors
|
|
141
|
+
};
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
};
|
|
31
145
|
|
|
32
146
|
// src/db-host/data-service.ts
|
|
33
147
|
import { UpdateScheduler as UpdateScheduler2 } from "@dxos/async";
|
|
34
148
|
import { Stream } from "@dxos/codec-protobuf/stream";
|
|
35
149
|
import { invariant as invariant7 } from "@dxos/invariant";
|
|
36
150
|
import { SpaceId as SpaceId2 } from "@dxos/keys";
|
|
37
|
-
import { log as
|
|
151
|
+
import { log as log8 } from "@dxos/log";
|
|
38
152
|
|
|
39
153
|
// src/automerge/automerge-host.ts
|
|
40
154
|
import { getBackend, getHeads, equals as headsEquals, isAutomerge, save } from "@automerge/automerge";
|
|
41
155
|
import { Repo, interpretAsDocumentId } from "@automerge/automerge-repo";
|
|
42
|
-
import { DeferredTask, Event as
|
|
43
|
-
import { Context, Resource as Resource3, cancelWithContext } from "@dxos/context";
|
|
44
|
-
import { DatabaseDirectory } from "@dxos/echo-protocol";
|
|
156
|
+
import { DeferredTask, Event as Event3, asyncTimeout } from "@dxos/async";
|
|
157
|
+
import { Context as Context2, Resource as Resource3, cancelWithContext } from "@dxos/context";
|
|
158
|
+
import { DatabaseDirectory as DatabaseDirectory2 } from "@dxos/echo-protocol";
|
|
45
159
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
46
|
-
import { PublicKey } from "@dxos/keys";
|
|
47
|
-
import { log as
|
|
160
|
+
import { PublicKey as PublicKey2 } from "@dxos/keys";
|
|
161
|
+
import { log as log4 } from "@dxos/log";
|
|
48
162
|
import { objectPointerCodec } from "@dxos/protocols";
|
|
49
163
|
import { trace as trace2 } from "@dxos/tracing";
|
|
50
|
-
import { ComplexSet, bufferToArray, isNonNullable as isNonNullable2, range } from "@dxos/util";
|
|
164
|
+
import { ComplexSet, bufferToArray, defaultMap as defaultMap2, isNonNullable as isNonNullable2, range } from "@dxos/util";
|
|
51
165
|
|
|
52
166
|
// src/automerge/collection-synchronizer.ts
|
|
53
167
|
import { next as A } from "@automerge/automerge";
|
|
@@ -55,7 +169,7 @@ import * as Array2 from "effect/Array";
|
|
|
55
169
|
import * as Record from "effect/Record";
|
|
56
170
|
import { Event, asyncReturn, scheduleTask, scheduleTaskInterval } from "@dxos/async";
|
|
57
171
|
import { Resource } from "@dxos/context";
|
|
58
|
-
import { log } from "@dxos/log";
|
|
172
|
+
import { log as log2 } from "@dxos/log";
|
|
59
173
|
import { trace } from "@dxos/tracing";
|
|
60
174
|
import { defaultMap } from "@dxos/util";
|
|
61
175
|
function _ts_decorate(decorators, target, key, desc) {
|
|
@@ -64,9 +178,9 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
64
178
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
65
179
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
66
180
|
}
|
|
67
|
-
var
|
|
181
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/collection-synchronizer.ts";
|
|
68
182
|
var MIN_QUERY_INTERVAL = 5e3;
|
|
69
|
-
var POLL_INTERVAL =
|
|
183
|
+
var POLL_INTERVAL = 1e4;
|
|
70
184
|
var CollectionSynchronizer = class extends Resource {
|
|
71
185
|
_sendCollectionState;
|
|
72
186
|
_queryCollectionState;
|
|
@@ -104,16 +218,19 @@ var CollectionSynchronizer = class extends Resource {
|
|
|
104
218
|
}
|
|
105
219
|
setLocalCollectionState(collectionId, state) {
|
|
106
220
|
this._activeCollections.add(collectionId);
|
|
107
|
-
|
|
221
|
+
log2("setLocalCollectionState", {
|
|
108
222
|
collectionId,
|
|
109
223
|
state
|
|
110
224
|
}, {
|
|
111
|
-
F:
|
|
225
|
+
F: __dxlog_file2,
|
|
112
226
|
L: 78,
|
|
113
227
|
S: this,
|
|
114
228
|
C: (f, a) => f(...a)
|
|
115
229
|
});
|
|
116
230
|
this._getOrCreatePerCollectionState(collectionId).localState = state;
|
|
231
|
+
for (const peerId of this._connectedPeers) {
|
|
232
|
+
this._diffCollectionState(collectionId, peerId);
|
|
233
|
+
}
|
|
117
234
|
queueMicrotask(async () => {
|
|
118
235
|
if (!this._ctx.disposed && this._activeCollections.has(collectionId)) {
|
|
119
236
|
this._refreshInterestedPeers(collectionId);
|
|
@@ -124,11 +241,11 @@ var CollectionSynchronizer = class extends Resource {
|
|
|
124
241
|
clearLocalCollectionState(collectionId) {
|
|
125
242
|
this._activeCollections.delete(collectionId);
|
|
126
243
|
this._perCollectionStates.delete(collectionId);
|
|
127
|
-
|
|
244
|
+
log2("clearLocalCollectionState", {
|
|
128
245
|
collectionId
|
|
129
246
|
}, {
|
|
130
|
-
F:
|
|
131
|
-
L:
|
|
247
|
+
F: __dxlog_file2,
|
|
248
|
+
L: 96,
|
|
132
249
|
S: this,
|
|
133
250
|
C: (f, a) => f(...a)
|
|
134
251
|
});
|
|
@@ -158,6 +275,14 @@ var CollectionSynchronizer = class extends Resource {
|
|
|
158
275
|
* Callback when a connection to a peer is established.
|
|
159
276
|
*/
|
|
160
277
|
onConnectionOpen(peerId) {
|
|
278
|
+
log2("onConnectionOpen", {
|
|
279
|
+
peerId
|
|
280
|
+
}, {
|
|
281
|
+
F: __dxlog_file2,
|
|
282
|
+
L: 126,
|
|
283
|
+
S: this,
|
|
284
|
+
C: (f, a) => f(...a)
|
|
285
|
+
});
|
|
161
286
|
const spanId = getSpanName(peerId);
|
|
162
287
|
trace.spanStart({
|
|
163
288
|
id: spanId,
|
|
@@ -187,6 +312,14 @@ var CollectionSynchronizer = class extends Resource {
|
|
|
187
312
|
* Callback when a connection to a peer is closed.
|
|
188
313
|
*/
|
|
189
314
|
onConnectionClosed(peerId) {
|
|
315
|
+
log2("onConnectionClosed", {
|
|
316
|
+
peerId
|
|
317
|
+
}, {
|
|
318
|
+
F: __dxlog_file2,
|
|
319
|
+
L: 156,
|
|
320
|
+
S: this,
|
|
321
|
+
C: (f, a) => f(...a)
|
|
322
|
+
});
|
|
190
323
|
this._connectedPeers.delete(peerId);
|
|
191
324
|
for (const perCollectionState of this._perCollectionStates.values()) {
|
|
192
325
|
perCollectionState.remoteStates.delete(peerId);
|
|
@@ -205,22 +338,40 @@ var CollectionSynchronizer = class extends Resource {
|
|
|
205
338
|
* Callback when a peer sends the state of a collection.
|
|
206
339
|
*/
|
|
207
340
|
onRemoteStateReceived(collectionId, peerId, state) {
|
|
208
|
-
|
|
341
|
+
log2("onRemoteStateReceived", {
|
|
209
342
|
collectionId,
|
|
210
343
|
peerId,
|
|
211
344
|
state
|
|
212
345
|
}, {
|
|
213
|
-
F:
|
|
214
|
-
L:
|
|
346
|
+
F: __dxlog_file2,
|
|
347
|
+
L: 180,
|
|
215
348
|
S: this,
|
|
216
349
|
C: (f, a) => f(...a)
|
|
217
350
|
});
|
|
218
351
|
validateCollectionState(state);
|
|
219
352
|
const perCollectionState = this._getOrCreatePerCollectionState(collectionId);
|
|
220
|
-
|
|
353
|
+
perCollectionState.remoteStates.set(peerId, state);
|
|
354
|
+
this._diffCollectionState(collectionId, peerId);
|
|
355
|
+
}
|
|
356
|
+
_diffCollectionState(collectionId, peerId) {
|
|
357
|
+
const perCollectionState = this._getOrCreatePerCollectionState(collectionId);
|
|
358
|
+
const remoteState = perCollectionState.remoteStates.get(peerId);
|
|
359
|
+
if (!remoteState) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
log2("diffCollectionState", {
|
|
363
|
+
collectionId,
|
|
364
|
+
peerId
|
|
365
|
+
}, {
|
|
366
|
+
F: __dxlog_file2,
|
|
367
|
+
L: 194,
|
|
368
|
+
S: this,
|
|
369
|
+
C: (f, a) => f(...a)
|
|
370
|
+
});
|
|
371
|
+
const localState = perCollectionState.localState ?? {
|
|
221
372
|
documents: {}
|
|
222
373
|
};
|
|
223
|
-
const diff = diffCollectionState(
|
|
374
|
+
const diff = diffCollectionState(localState, remoteState);
|
|
224
375
|
const spanId = getSpanName(peerId);
|
|
225
376
|
if (diff.different.length === 0) {
|
|
226
377
|
trace.spanEnd(spanId);
|
|
@@ -236,8 +387,25 @@ var CollectionSynchronizer = class extends Resource {
|
|
|
236
387
|
}
|
|
237
388
|
});
|
|
238
389
|
}
|
|
239
|
-
|
|
240
|
-
|
|
390
|
+
log2("diff", {
|
|
391
|
+
localState: localState.documents,
|
|
392
|
+
remoteState: remoteState.documents,
|
|
393
|
+
missingOnLocal: diff.missingOnLocal,
|
|
394
|
+
missingOnRemote: diff.missingOnRemote,
|
|
395
|
+
different: diff.different
|
|
396
|
+
}, {
|
|
397
|
+
F: __dxlog_file2,
|
|
398
|
+
L: 210,
|
|
399
|
+
S: this,
|
|
400
|
+
C: (f, a) => f(...a)
|
|
401
|
+
});
|
|
402
|
+
if (diff.missingOnLocal.length > 0 || diff.different.length > 0 || diff.missingOnRemote.length > 0) {
|
|
403
|
+
log2("emit remote state update", void 0, {
|
|
404
|
+
F: __dxlog_file2,
|
|
405
|
+
L: 218,
|
|
406
|
+
S: this,
|
|
407
|
+
C: (f, a) => f(...a)
|
|
408
|
+
});
|
|
241
409
|
this.remoteStateUpdated.emit({
|
|
242
410
|
peerId,
|
|
243
411
|
collectionId,
|
|
@@ -312,10 +480,10 @@ var getSpanName = (peerId) => {
|
|
|
312
480
|
|
|
313
481
|
// src/automerge/echo-network-adapter.ts
|
|
314
482
|
import { NetworkAdapter } from "@automerge/automerge-repo";
|
|
315
|
-
import { Trigger, synchronized } from "@dxos/async";
|
|
483
|
+
import { Event as Event2, Trigger, synchronized } from "@dxos/async";
|
|
316
484
|
import { LifecycleState } from "@dxos/context";
|
|
317
485
|
import { invariant } from "@dxos/invariant";
|
|
318
|
-
import { log as
|
|
486
|
+
import { log as log3 } from "@dxos/log";
|
|
319
487
|
import { isNonNullable } from "@dxos/util";
|
|
320
488
|
|
|
321
489
|
// src/automerge/network-protocol.ts
|
|
@@ -330,7 +498,7 @@ function _ts_decorate2(decorators, target, key, desc) {
|
|
|
330
498
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
331
499
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
332
500
|
}
|
|
333
|
-
var
|
|
501
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts";
|
|
334
502
|
var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
335
503
|
_params;
|
|
336
504
|
_replicators = /* @__PURE__ */ new Set();
|
|
@@ -341,6 +509,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
341
509
|
_lifecycleState = LifecycleState.CLOSED;
|
|
342
510
|
_connected = new Trigger();
|
|
343
511
|
_ready = new Trigger();
|
|
512
|
+
documentRequested = new Event2();
|
|
344
513
|
constructor(_params) {
|
|
345
514
|
super(), this._params = _params;
|
|
346
515
|
}
|
|
@@ -391,8 +560,8 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
391
560
|
}
|
|
392
561
|
async addReplicator(replicator) {
|
|
393
562
|
invariant(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
394
|
-
F:
|
|
395
|
-
L:
|
|
563
|
+
F: __dxlog_file3,
|
|
564
|
+
L: 140,
|
|
396
565
|
S: this,
|
|
397
566
|
A: [
|
|
398
567
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -400,8 +569,8 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
400
569
|
]
|
|
401
570
|
});
|
|
402
571
|
invariant(this.peerId, void 0, {
|
|
403
|
-
F:
|
|
404
|
-
L:
|
|
572
|
+
F: __dxlog_file3,
|
|
573
|
+
L: 141,
|
|
405
574
|
S: this,
|
|
406
575
|
A: [
|
|
407
576
|
"this.peerId",
|
|
@@ -409,8 +578,8 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
409
578
|
]
|
|
410
579
|
});
|
|
411
580
|
invariant(!this._replicators.has(replicator), void 0, {
|
|
412
|
-
F:
|
|
413
|
-
L:
|
|
581
|
+
F: __dxlog_file3,
|
|
582
|
+
L: 142,
|
|
414
583
|
S: this,
|
|
415
584
|
A: [
|
|
416
585
|
"!this._replicators.has(replicator)",
|
|
@@ -433,8 +602,8 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
433
602
|
}
|
|
434
603
|
async removeReplicator(replicator) {
|
|
435
604
|
invariant(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
436
|
-
F:
|
|
437
|
-
L:
|
|
605
|
+
F: __dxlog_file3,
|
|
606
|
+
L: 161,
|
|
438
607
|
S: this,
|
|
439
608
|
A: [
|
|
440
609
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -442,8 +611,8 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
442
611
|
]
|
|
443
612
|
});
|
|
444
613
|
invariant(this._replicators.has(replicator), void 0, {
|
|
445
|
-
F:
|
|
446
|
-
L:
|
|
614
|
+
F: __dxlog_file3,
|
|
615
|
+
L: 162,
|
|
447
616
|
S: this,
|
|
448
617
|
A: [
|
|
449
618
|
"this._replicators.has(replicator)",
|
|
@@ -525,9 +694,9 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
525
694
|
this._params.monitor?.recordMessageSent(message, Date.now() - start);
|
|
526
695
|
}).catch((err) => {
|
|
527
696
|
if (connectionEntry.isOpen) {
|
|
528
|
-
|
|
529
|
-
F:
|
|
530
|
-
L:
|
|
697
|
+
log3.catch(err, void 0, {
|
|
698
|
+
F: __dxlog_file3,
|
|
699
|
+
L: 256,
|
|
531
700
|
S: this,
|
|
532
701
|
C: (f, a) => f(...a)
|
|
533
702
|
});
|
|
@@ -536,17 +705,17 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
536
705
|
});
|
|
537
706
|
}
|
|
538
707
|
_onConnectionOpen(connection) {
|
|
539
|
-
|
|
708
|
+
log3("connection opened", {
|
|
540
709
|
peerId: connection.peerId
|
|
541
710
|
}, {
|
|
542
|
-
F:
|
|
543
|
-
L:
|
|
711
|
+
F: __dxlog_file3,
|
|
712
|
+
L: 264,
|
|
544
713
|
S: this,
|
|
545
714
|
C: (f, a) => f(...a)
|
|
546
715
|
});
|
|
547
716
|
invariant(!this._connections.has(connection.peerId), void 0, {
|
|
548
|
-
F:
|
|
549
|
-
L:
|
|
717
|
+
F: __dxlog_file3,
|
|
718
|
+
L: 265,
|
|
550
719
|
S: this,
|
|
551
720
|
A: [
|
|
552
721
|
"!this._connections.has(connection.peerId as PeerId)",
|
|
@@ -557,7 +726,8 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
557
726
|
isOpen: true,
|
|
558
727
|
connection,
|
|
559
728
|
reader: connection.readable.getReader(),
|
|
560
|
-
writer: connection.writable.getWriter()
|
|
729
|
+
writer: connection.writable.getWriter(),
|
|
730
|
+
requestedDocuments: /* @__PURE__ */ new Set()
|
|
561
731
|
};
|
|
562
732
|
this._connections.set(connection.peerId, connectionEntry);
|
|
563
733
|
queueMicrotask(async () => {
|
|
@@ -567,31 +737,38 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
567
737
|
if (done) {
|
|
568
738
|
break;
|
|
569
739
|
}
|
|
570
|
-
this._onMessage(value);
|
|
740
|
+
this._onMessage(connectionEntry, value);
|
|
571
741
|
}
|
|
572
742
|
} catch (err) {
|
|
573
743
|
if (connectionEntry.isOpen) {
|
|
574
|
-
|
|
575
|
-
F:
|
|
576
|
-
L:
|
|
744
|
+
log3.catch(err, void 0, {
|
|
745
|
+
F: __dxlog_file3,
|
|
746
|
+
L: 290,
|
|
577
747
|
S: this,
|
|
578
748
|
C: (f, a) => f(...a)
|
|
579
749
|
});
|
|
580
750
|
}
|
|
581
751
|
}
|
|
582
752
|
});
|
|
583
|
-
|
|
753
|
+
log3("emit peer-candidate", {
|
|
584
754
|
peerId: connection.peerId
|
|
585
755
|
}, {
|
|
586
|
-
F:
|
|
587
|
-
L:
|
|
756
|
+
F: __dxlog_file3,
|
|
757
|
+
L: 295,
|
|
588
758
|
S: this,
|
|
589
759
|
C: (f, a) => f(...a)
|
|
590
760
|
});
|
|
591
761
|
this._emitPeerCandidate(connection);
|
|
592
762
|
this._params.monitor?.recordPeerConnected(connection.peerId);
|
|
593
763
|
}
|
|
594
|
-
_onMessage(message) {
|
|
764
|
+
_onMessage(connectionEntry, message) {
|
|
765
|
+
const amMessage = message;
|
|
766
|
+
if (amMessage.type === "request") {
|
|
767
|
+
this.documentRequested.emit({
|
|
768
|
+
documentId: amMessage.documentId,
|
|
769
|
+
peerId: connectionEntry.connection.peerId
|
|
770
|
+
});
|
|
771
|
+
}
|
|
595
772
|
if (isCollectionQueryMessage(message)) {
|
|
596
773
|
this._params.onCollectionStateQueried(message.collectionId, message.senderId);
|
|
597
774
|
} else if (isCollectionStateMessage(message)) {
|
|
@@ -602,18 +779,18 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
602
779
|
this._params.monitor?.recordMessageReceived(message);
|
|
603
780
|
}
|
|
604
781
|
_onConnectionClosed(connection) {
|
|
605
|
-
|
|
782
|
+
log3("connection closed", {
|
|
606
783
|
peerId: connection.peerId
|
|
607
784
|
}, {
|
|
608
|
-
F:
|
|
609
|
-
L:
|
|
785
|
+
F: __dxlog_file3,
|
|
786
|
+
L: 320,
|
|
610
787
|
S: this,
|
|
611
788
|
C: (f, a) => f(...a)
|
|
612
789
|
});
|
|
613
790
|
const entry = this._connections.get(connection.peerId);
|
|
614
791
|
invariant(entry, void 0, {
|
|
615
|
-
F:
|
|
616
|
-
L:
|
|
792
|
+
F: __dxlog_file3,
|
|
793
|
+
L: 322,
|
|
617
794
|
S: this,
|
|
618
795
|
A: [
|
|
619
796
|
"entry",
|
|
@@ -625,15 +802,15 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
625
802
|
peerId: connection.peerId
|
|
626
803
|
});
|
|
627
804
|
this._params.monitor?.recordPeerDisconnected(connection.peerId);
|
|
628
|
-
void entry.writer.abort().catch((err) =>
|
|
629
|
-
F:
|
|
630
|
-
L:
|
|
805
|
+
void entry.writer.abort().catch((err) => log3.catch(err, void 0, {
|
|
806
|
+
F: __dxlog_file3,
|
|
807
|
+
L: 328,
|
|
631
808
|
S: this,
|
|
632
809
|
C: (f, a) => f(...a)
|
|
633
810
|
}));
|
|
634
|
-
void entry.reader.cancel().catch((err) =>
|
|
635
|
-
F:
|
|
636
|
-
L:
|
|
811
|
+
void entry.reader.cancel().catch((err) => log3.catch(err, void 0, {
|
|
812
|
+
F: __dxlog_file3,
|
|
813
|
+
L: 329,
|
|
637
814
|
S: this,
|
|
638
815
|
C: (f, a) => f(...a)
|
|
639
816
|
}));
|
|
@@ -644,18 +821,18 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
644
821
|
* TODO(y): replace with a proper API call when sharePolicy update becomes supported by automerge-repo
|
|
645
822
|
*/
|
|
646
823
|
_onConnectionAuthScopeChanged(connection) {
|
|
647
|
-
|
|
824
|
+
log3("Connection auth scope changed", {
|
|
648
825
|
peerId: connection.peerId
|
|
649
826
|
}, {
|
|
650
|
-
F:
|
|
651
|
-
L:
|
|
827
|
+
F: __dxlog_file3,
|
|
828
|
+
L: 339,
|
|
652
829
|
S: this,
|
|
653
830
|
C: (f, a) => f(...a)
|
|
654
831
|
});
|
|
655
832
|
const entry = this._connections.get(connection.peerId);
|
|
656
833
|
invariant(entry, void 0, {
|
|
657
|
-
F:
|
|
658
|
-
L:
|
|
834
|
+
F: __dxlog_file3,
|
|
835
|
+
L: 341,
|
|
659
836
|
S: this,
|
|
660
837
|
A: [
|
|
661
838
|
"entry",
|
|
@@ -713,6 +890,20 @@ var HeadsStore = class {
|
|
|
713
890
|
valueEncoding: headsEncoding
|
|
714
891
|
});
|
|
715
892
|
}
|
|
893
|
+
/**
|
|
894
|
+
* Iterate over all document IDs and their heads.
|
|
895
|
+
*/
|
|
896
|
+
async *iterateAll() {
|
|
897
|
+
for await (const [documentId, heads] of this._db.iterator({
|
|
898
|
+
keyEncoding: "utf8",
|
|
899
|
+
valueEncoding: headsEncoding
|
|
900
|
+
})) {
|
|
901
|
+
yield {
|
|
902
|
+
documentId,
|
|
903
|
+
heads
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
}
|
|
716
907
|
};
|
|
717
908
|
|
|
718
909
|
// src/automerge/leveldb-storage-adapter.ts
|
|
@@ -828,7 +1019,7 @@ function _ts_decorate3(decorators, target, key, desc) {
|
|
|
828
1019
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
829
1020
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
830
1021
|
}
|
|
831
|
-
var
|
|
1022
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
|
|
832
1023
|
var FIND_PARAMS = {
|
|
833
1024
|
allowableStates: [
|
|
834
1025
|
"ready",
|
|
@@ -838,6 +1029,7 @@ var FIND_PARAMS = {
|
|
|
838
1029
|
var BUNDLE_SIZE = 100;
|
|
839
1030
|
var BUNDLE_SYNC_CONCURRENCY = 2;
|
|
840
1031
|
var BUNDLE_SYNC_THRESHOLD = 50;
|
|
1032
|
+
var OPTIMIZED_SHARE_POLICY = true;
|
|
841
1033
|
var AutomergeHost = class extends Resource3 {
|
|
842
1034
|
_db;
|
|
843
1035
|
_indexMetadataStore;
|
|
@@ -858,13 +1050,30 @@ var AutomergeHost = class extends Resource3 {
|
|
|
858
1050
|
_peerId;
|
|
859
1051
|
_peerIdProvider;
|
|
860
1052
|
_getSpaceKeyByRootDocumentId;
|
|
861
|
-
collectionStateUpdated = new
|
|
1053
|
+
collectionStateUpdated = new Event3();
|
|
862
1054
|
/**
|
|
863
1055
|
* Fired after a batch of documents was saved to disk.
|
|
864
1056
|
*/
|
|
865
|
-
documentsSaved = new
|
|
1057
|
+
documentsSaved = new Event3();
|
|
866
1058
|
_headsUpdates = /* @__PURE__ */ new Map();
|
|
867
1059
|
_onHeadsChangedTask;
|
|
1060
|
+
/**
|
|
1061
|
+
* Documents created in this session.
|
|
1062
|
+
*/
|
|
1063
|
+
_createdDocuments = /* @__PURE__ */ new Set();
|
|
1064
|
+
/**
|
|
1065
|
+
* Documents that need to be synced based on the result of collection-sync.
|
|
1066
|
+
*/
|
|
1067
|
+
_documentsToSync = /* @__PURE__ */ new Set();
|
|
1068
|
+
/**
|
|
1069
|
+
* Documents that are not avaiale locally that should be requested.
|
|
1070
|
+
*/
|
|
1071
|
+
_documentsToRequest = /* @__PURE__ */ new Set();
|
|
1072
|
+
/**
|
|
1073
|
+
* Documents requested by remote peers.
|
|
1074
|
+
*/
|
|
1075
|
+
_documentsRequested = /* @__PURE__ */ new Map();
|
|
1076
|
+
_sharePolicyChangedTask;
|
|
868
1077
|
constructor({ db, indexMetadataStore, dataMonitor, peerIdProvider, getSpaceKeyByRootDocumentId }) {
|
|
869
1078
|
super();
|
|
870
1079
|
this._db = db;
|
|
@@ -883,6 +1092,10 @@ var AutomergeHost = class extends Resource3 {
|
|
|
883
1092
|
onCollectionStateReceived: this._onCollectionStateReceived.bind(this),
|
|
884
1093
|
monitor: dataMonitor
|
|
885
1094
|
});
|
|
1095
|
+
this._echoNetworkAdapter.documentRequested.on(({ peerId, documentId }) => {
|
|
1096
|
+
defaultMap2(this._documentsRequested, peerId, () => /* @__PURE__ */ new Set()).add(documentId);
|
|
1097
|
+
this._sharePolicyChangedTask.schedule();
|
|
1098
|
+
});
|
|
886
1099
|
this._headsStore = new HeadsStore({
|
|
887
1100
|
db: db.sublevel("heads")
|
|
888
1101
|
});
|
|
@@ -891,7 +1104,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
891
1104
|
this._getSpaceKeyByRootDocumentId = getSpaceKeyByRootDocumentId;
|
|
892
1105
|
}
|
|
893
1106
|
async _open() {
|
|
894
|
-
this._peerId = `host-${this._peerIdProvider?.() ??
|
|
1107
|
+
this._peerId = `host-${this._peerIdProvider?.() ?? PublicKey2.random().toHex()}`;
|
|
895
1108
|
this._onHeadsChangedTask = new DeferredTask(this._ctx, async () => {
|
|
896
1109
|
const docHeads = Array.from(this._headsUpdates.entries());
|
|
897
1110
|
this._headsUpdates.clear();
|
|
@@ -900,7 +1113,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
900
1113
|
await this._storage.open?.();
|
|
901
1114
|
this._repo = new Repo({
|
|
902
1115
|
peerId: this._peerId,
|
|
903
|
-
|
|
1116
|
+
shareConfig: this._shareConfig,
|
|
904
1117
|
storage: this._storage,
|
|
905
1118
|
network: [
|
|
906
1119
|
// Upstream swarm.
|
|
@@ -908,8 +1121,8 @@ var AutomergeHost = class extends Resource3 {
|
|
|
908
1121
|
]
|
|
909
1122
|
});
|
|
910
1123
|
let updatingAuthScope = false;
|
|
911
|
-
|
|
912
|
-
|
|
1124
|
+
Event3.wrap(this._echoNetworkAdapter, "peer-candidate").on(this._ctx, (e) => !updatingAuthScope && this._onPeerConnected(e.peerId));
|
|
1125
|
+
Event3.wrap(this._echoNetworkAdapter, "peer-disconnected").on(this._ctx, (e) => !updatingAuthScope && this._onPeerDisconnected(e.peerId));
|
|
913
1126
|
this._collectionSynchronizer.remoteStateUpdated.on(this._ctx, ({ collectionId, peerId, newDocsAppeared }) => {
|
|
914
1127
|
this._onRemoteCollectionStateUpdated(collectionId, peerId);
|
|
915
1128
|
this.collectionStateUpdated.emit({
|
|
@@ -933,19 +1146,28 @@ var AutomergeHost = class extends Resource3 {
|
|
|
933
1146
|
try {
|
|
934
1147
|
await this._handleCollectionSync(collectionId, peerId);
|
|
935
1148
|
} catch (err) {
|
|
936
|
-
|
|
1149
|
+
log4.error("failed to sync collection", {
|
|
937
1150
|
collectionId,
|
|
938
1151
|
peerId,
|
|
939
1152
|
err
|
|
940
1153
|
}, {
|
|
941
|
-
F:
|
|
942
|
-
L:
|
|
1154
|
+
F: __dxlog_file4,
|
|
1155
|
+
L: 263,
|
|
943
1156
|
S: this,
|
|
944
1157
|
C: (f, a) => f(...a)
|
|
945
1158
|
});
|
|
946
1159
|
}
|
|
947
1160
|
}));
|
|
948
1161
|
});
|
|
1162
|
+
this._sharePolicyChangedTask = new DeferredTask(this._ctx, async () => {
|
|
1163
|
+
log4("share policy changed", void 0, {
|
|
1164
|
+
F: __dxlog_file4,
|
|
1165
|
+
L: 270,
|
|
1166
|
+
S: this,
|
|
1167
|
+
C: (f, a) => f(...a)
|
|
1168
|
+
});
|
|
1169
|
+
this._repo.shareConfigChanged();
|
|
1170
|
+
});
|
|
949
1171
|
await this._echoNetworkAdapter.open();
|
|
950
1172
|
await this._collectionSynchronizer.open();
|
|
951
1173
|
await this._echoNetworkAdapter.open();
|
|
@@ -957,12 +1179,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
957
1179
|
await this._echoNetworkAdapter.close();
|
|
958
1180
|
this._syncTask = void 0;
|
|
959
1181
|
this._onHeadsChangedTask = void 0;
|
|
960
|
-
|
|
961
|
-
/**
|
|
962
|
-
* @deprecated To be abstracted away.
|
|
963
|
-
*/
|
|
964
|
-
get repo() {
|
|
965
|
-
return this._repo;
|
|
1182
|
+
this._sharePolicyChangedTask = void 0;
|
|
966
1183
|
}
|
|
967
1184
|
get peerId() {
|
|
968
1185
|
return this._peerId;
|
|
@@ -970,10 +1187,13 @@ var AutomergeHost = class extends Resource3 {
|
|
|
970
1187
|
get loadedDocsCount() {
|
|
971
1188
|
return Object.keys(this._repo.handles).length;
|
|
972
1189
|
}
|
|
1190
|
+
get handles() {
|
|
1191
|
+
return this._repo.handles;
|
|
1192
|
+
}
|
|
973
1193
|
async addReplicator(replicator) {
|
|
974
1194
|
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
975
|
-
F:
|
|
976
|
-
L:
|
|
1195
|
+
F: __dxlog_file4,
|
|
1196
|
+
L: 302,
|
|
977
1197
|
S: this,
|
|
978
1198
|
A: [
|
|
979
1199
|
"this.isOpen",
|
|
@@ -984,8 +1204,8 @@ var AutomergeHost = class extends Resource3 {
|
|
|
984
1204
|
}
|
|
985
1205
|
async removeReplicator(replicator) {
|
|
986
1206
|
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
987
|
-
F:
|
|
988
|
-
L:
|
|
1207
|
+
F: __dxlog_file4,
|
|
1208
|
+
L: 307,
|
|
989
1209
|
S: this,
|
|
990
1210
|
A: [
|
|
991
1211
|
"this.isOpen",
|
|
@@ -999,8 +1219,8 @@ var AutomergeHost = class extends Resource3 {
|
|
|
999
1219
|
*/
|
|
1000
1220
|
async loadDoc(ctx, documentId, opts) {
|
|
1001
1221
|
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1002
|
-
F:
|
|
1003
|
-
L:
|
|
1222
|
+
F: __dxlog_file4,
|
|
1223
|
+
L: 315,
|
|
1004
1224
|
S: this,
|
|
1005
1225
|
A: [
|
|
1006
1226
|
"this.isOpen",
|
|
@@ -1012,7 +1232,34 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1012
1232
|
handle = this._repo.handles[documentId];
|
|
1013
1233
|
}
|
|
1014
1234
|
if (!handle) {
|
|
1015
|
-
|
|
1235
|
+
if (!opts?.fetchFromNetwork) {
|
|
1236
|
+
handle = await this._repo.find(documentId, FIND_PARAMS);
|
|
1237
|
+
} else {
|
|
1238
|
+
try {
|
|
1239
|
+
handle = await this._repo.find(documentId, {
|
|
1240
|
+
allowableStates: [
|
|
1241
|
+
"ready",
|
|
1242
|
+
"requesting",
|
|
1243
|
+
"unavailable"
|
|
1244
|
+
]
|
|
1245
|
+
});
|
|
1246
|
+
if (handle.state === "requesting" || handle.state === "unavailable") {
|
|
1247
|
+
this._documentsToRequest.add(handle.documentId);
|
|
1248
|
+
this._sharePolicyChangedTask.schedule();
|
|
1249
|
+
}
|
|
1250
|
+
} catch (err) {
|
|
1251
|
+
log4.error("failed to load document", {
|
|
1252
|
+
documentId,
|
|
1253
|
+
err
|
|
1254
|
+
}, {
|
|
1255
|
+
F: __dxlog_file4,
|
|
1256
|
+
L: 334,
|
|
1257
|
+
S: this,
|
|
1258
|
+
C: (f, a) => f(...a)
|
|
1259
|
+
});
|
|
1260
|
+
throw err;
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1016
1263
|
}
|
|
1017
1264
|
if (!handle.isReady()) {
|
|
1018
1265
|
if (!opts?.timeout) {
|
|
@@ -1025,8 +1272,8 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1025
1272
|
}
|
|
1026
1273
|
async exportDoc(ctx, id) {
|
|
1027
1274
|
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1028
|
-
F:
|
|
1029
|
-
L:
|
|
1275
|
+
F: __dxlog_file4,
|
|
1276
|
+
L: 353,
|
|
1030
1277
|
S: this,
|
|
1031
1278
|
A: [
|
|
1032
1279
|
"this.isOpen",
|
|
@@ -1042,10 +1289,10 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1042
1289
|
/**
|
|
1043
1290
|
* Create new persisted document.
|
|
1044
1291
|
*/
|
|
1045
|
-
createDoc(initialValue, opts) {
|
|
1292
|
+
async createDoc(initialValue, opts) {
|
|
1046
1293
|
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1047
|
-
F:
|
|
1048
|
-
L:
|
|
1294
|
+
F: __dxlog_file4,
|
|
1295
|
+
L: 364,
|
|
1049
1296
|
S: this,
|
|
1050
1297
|
A: [
|
|
1051
1298
|
"this.isOpen",
|
|
@@ -1054,23 +1301,36 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1054
1301
|
});
|
|
1055
1302
|
if (opts?.preserveHistory) {
|
|
1056
1303
|
if (initialValue instanceof Uint8Array) {
|
|
1057
|
-
return this._repo.import(initialValue
|
|
1304
|
+
return this._repo.import(initialValue, {
|
|
1305
|
+
docId: opts?.documentId
|
|
1306
|
+
});
|
|
1058
1307
|
}
|
|
1059
1308
|
if (!isAutomerge(initialValue)) {
|
|
1060
1309
|
throw new TypeError("Initial value must be an Automerge document");
|
|
1061
1310
|
}
|
|
1062
|
-
|
|
1311
|
+
const handle = this._repo.import(save(initialValue), {
|
|
1312
|
+
docId: opts?.documentId
|
|
1313
|
+
});
|
|
1314
|
+
this._createdDocuments.add(handle.documentId);
|
|
1315
|
+
this._sharePolicyChangedTask.schedule();
|
|
1316
|
+
return handle;
|
|
1063
1317
|
} else {
|
|
1064
1318
|
if (initialValue instanceof Uint8Array) {
|
|
1065
1319
|
throw new Error("Cannot create document from Uint8Array without preserving history");
|
|
1066
1320
|
}
|
|
1067
|
-
|
|
1321
|
+
if (opts?.documentId) {
|
|
1322
|
+
throw new Error("Cannot prefil document id when not importing an existing doc");
|
|
1323
|
+
}
|
|
1324
|
+
const handle = await this._repo.create2(initialValue);
|
|
1325
|
+
this._createdDocuments.add(handle.documentId);
|
|
1326
|
+
this._sharePolicyChangedTask.schedule();
|
|
1327
|
+
return handle;
|
|
1068
1328
|
}
|
|
1069
1329
|
}
|
|
1070
1330
|
async waitUntilHeadsReplicated(heads) {
|
|
1071
1331
|
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1072
|
-
F:
|
|
1073
|
-
L:
|
|
1332
|
+
F: __dxlog_file4,
|
|
1333
|
+
L: 395,
|
|
1074
1334
|
S: this,
|
|
1075
1335
|
A: [
|
|
1076
1336
|
"this.isOpen",
|
|
@@ -1093,9 +1353,9 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1093
1353
|
});
|
|
1094
1354
|
if (headsToWait.length > 0) {
|
|
1095
1355
|
await Promise.all(headsToWait.map(async (entry) => {
|
|
1096
|
-
const handle = await this.loadDoc(
|
|
1097
|
-
F:
|
|
1098
|
-
L:
|
|
1356
|
+
const handle = await this.loadDoc(Context2.default(void 0, {
|
|
1357
|
+
F: __dxlog_file4,
|
|
1358
|
+
L: 413
|
|
1099
1359
|
}), entry.documentId);
|
|
1100
1360
|
await waitForHeads(handle, entry.heads);
|
|
1101
1361
|
}));
|
|
@@ -1104,8 +1364,8 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1104
1364
|
}
|
|
1105
1365
|
async reIndexHeads(documentIds) {
|
|
1106
1366
|
invariant2(this.isOpen, "AutomergeHost is not open", {
|
|
1107
|
-
F:
|
|
1108
|
-
L:
|
|
1367
|
+
F: __dxlog_file4,
|
|
1368
|
+
L: 426,
|
|
1109
1369
|
S: this,
|
|
1110
1370
|
A: [
|
|
1111
1371
|
"this.isOpen",
|
|
@@ -1113,21 +1373,21 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1113
1373
|
]
|
|
1114
1374
|
});
|
|
1115
1375
|
for (const documentId of documentIds) {
|
|
1116
|
-
|
|
1376
|
+
log4("re-indexing heads for document", {
|
|
1117
1377
|
documentId
|
|
1118
1378
|
}, {
|
|
1119
|
-
F:
|
|
1120
|
-
L:
|
|
1379
|
+
F: __dxlog_file4,
|
|
1380
|
+
L: 428,
|
|
1121
1381
|
S: this,
|
|
1122
1382
|
C: (f, a) => f(...a)
|
|
1123
1383
|
});
|
|
1124
1384
|
const handle = await this._repo.find(documentId, FIND_PARAMS);
|
|
1125
1385
|
if (!handle.isReady()) {
|
|
1126
|
-
|
|
1386
|
+
log4.warn("document is not available locally, skipping", {
|
|
1127
1387
|
documentId
|
|
1128
1388
|
}, {
|
|
1129
|
-
F:
|
|
1130
|
-
L:
|
|
1389
|
+
F: __dxlog_file4,
|
|
1390
|
+
L: 431,
|
|
1131
1391
|
S: this,
|
|
1132
1392
|
C: (f, a) => f(...a)
|
|
1133
1393
|
});
|
|
@@ -1138,29 +1398,40 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1138
1398
|
this._headsStore.setHeads(documentId, heads, batch);
|
|
1139
1399
|
await batch.write();
|
|
1140
1400
|
}
|
|
1141
|
-
|
|
1142
|
-
F:
|
|
1143
|
-
L:
|
|
1401
|
+
log4("done re-indexing heads", void 0, {
|
|
1402
|
+
F: __dxlog_file4,
|
|
1403
|
+
L: 440,
|
|
1144
1404
|
S: this,
|
|
1145
1405
|
C: (f, a) => f(...a)
|
|
1146
1406
|
});
|
|
1147
1407
|
}
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1408
|
+
_shareConfig = {
|
|
1409
|
+
access: async (peerId, documentId) => {
|
|
1410
|
+
return true;
|
|
1411
|
+
},
|
|
1412
|
+
// TODO(dmaretskyi): Share based on HALO permissions and space affinity.
|
|
1413
|
+
// Hosts, running in the worker, don't share documents unless requested by other peers.
|
|
1414
|
+
// NOTE: If both peers return sharePolicy=false the replication will not happen
|
|
1415
|
+
// https://github.com/automerge/automerge-repo/pull/292
|
|
1416
|
+
// Called for all loaded documents so they could be advertised to the sync server.
|
|
1417
|
+
announce: async (peerId, documentId) => {
|
|
1418
|
+
if (!documentId) {
|
|
1419
|
+
return false;
|
|
1420
|
+
}
|
|
1421
|
+
if (OPTIMIZED_SHARE_POLICY) {
|
|
1422
|
+
if (!this._createdDocuments.has(documentId) && !this._documentsToSync.has(documentId) && !this._documentsToRequest.has(documentId)) {
|
|
1423
|
+
return false;
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
const peerMetadata = this._repo.peerMetadataByPeerId[peerId];
|
|
1427
|
+
if (isEchoPeerMetadata(peerMetadata)) {
|
|
1428
|
+
return this._echoNetworkAdapter.shouldAdvertise(peerId, {
|
|
1429
|
+
documentId
|
|
1430
|
+
});
|
|
1431
|
+
}
|
|
1154
1432
|
return false;
|
|
1155
1433
|
}
|
|
1156
|
-
|
|
1157
|
-
if (isEchoPeerMetadata(peerMetadata)) {
|
|
1158
|
-
return this._echoNetworkAdapter.shouldAdvertise(peerId, {
|
|
1159
|
-
documentId
|
|
1160
|
-
});
|
|
1161
|
-
}
|
|
1162
|
-
return false;
|
|
1163
|
-
}
|
|
1434
|
+
};
|
|
1164
1435
|
async _beforeSave({ path, batch }) {
|
|
1165
1436
|
const handle = this._repo.handles[path[0]];
|
|
1166
1437
|
if (!handle || !handle.isReady()) {
|
|
@@ -1172,7 +1443,7 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1172
1443
|
}
|
|
1173
1444
|
const heads = getHeads(doc);
|
|
1174
1445
|
this._headsStore.setHeads(handle.documentId, heads, batch);
|
|
1175
|
-
const spaceKey =
|
|
1446
|
+
const spaceKey = DatabaseDirectory2.getSpaceKey(doc) ?? void 0;
|
|
1176
1447
|
const objectIds = Object.keys(doc.objects ?? {});
|
|
1177
1448
|
const encodedIds = objectIds.map((objectId) => objectPointerCodec.encode({
|
|
1178
1449
|
documentId: handle.documentId,
|
|
@@ -1214,8 +1485,8 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1214
1485
|
const heads = getHeads(document);
|
|
1215
1486
|
this._headsUpdates.set(documentId, heads);
|
|
1216
1487
|
invariant2(this._onHeadsChangedTask, "onHeadsChangedTask is not initialized", {
|
|
1217
|
-
F:
|
|
1218
|
-
L:
|
|
1488
|
+
F: __dxlog_file4,
|
|
1489
|
+
L: 530,
|
|
1219
1490
|
S: this,
|
|
1220
1491
|
A: [
|
|
1221
1492
|
"this._onHeadsChangedTask",
|
|
@@ -1244,9 +1515,9 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1244
1515
|
await handle.whenReady();
|
|
1245
1516
|
}
|
|
1246
1517
|
if (handle && handle.isReady() && handle.doc()) {
|
|
1247
|
-
const spaceKeyHex =
|
|
1518
|
+
const spaceKeyHex = DatabaseDirectory2.getSpaceKey(handle.doc());
|
|
1248
1519
|
if (spaceKeyHex) {
|
|
1249
|
-
return
|
|
1520
|
+
return PublicKey2.from(spaceKeyHex);
|
|
1250
1521
|
}
|
|
1251
1522
|
}
|
|
1252
1523
|
const rootDocSpaceKey = this._getSpaceKeyByRootDocumentId?.(documentId);
|
|
@@ -1288,6 +1559,12 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1288
1559
|
}
|
|
1289
1560
|
return result;
|
|
1290
1561
|
}
|
|
1562
|
+
/**
|
|
1563
|
+
* Iterate over all document heads stored on disk.
|
|
1564
|
+
*/
|
|
1565
|
+
listDocumentHeads() {
|
|
1566
|
+
return this._headsStore.iterateAll();
|
|
1567
|
+
}
|
|
1291
1568
|
//
|
|
1292
1569
|
// Collection sync.
|
|
1293
1570
|
//
|
|
@@ -1395,48 +1672,48 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1395
1672
|
];
|
|
1396
1673
|
const bundleSyncEnabled = this._echoNetworkAdapter.bundleSyncEnabledForPeer(peerId);
|
|
1397
1674
|
if (bundleSyncEnabled && missingOnRemote.length >= BUNDLE_SYNC_THRESHOLD) {
|
|
1398
|
-
|
|
1675
|
+
log4("pushing bundle", {
|
|
1399
1676
|
amount: missingOnRemote.length
|
|
1400
1677
|
}, {
|
|
1401
|
-
F:
|
|
1402
|
-
L:
|
|
1678
|
+
F: __dxlog_file4,
|
|
1679
|
+
L: 742,
|
|
1403
1680
|
S: this,
|
|
1404
1681
|
C: (f, a) => f(...a)
|
|
1405
1682
|
});
|
|
1406
1683
|
const { syncInteractively } = await this._pushInBundles(peerId, missingOnRemote);
|
|
1407
1684
|
toReplicateWithoutBatching.push(...syncInteractively);
|
|
1408
1685
|
} else {
|
|
1409
|
-
|
|
1686
|
+
log4.verbose("failed to push bundle, replicating interactively", {
|
|
1410
1687
|
collectionId,
|
|
1411
1688
|
peerId,
|
|
1412
1689
|
amount: missingOnRemote.length
|
|
1413
1690
|
}, {
|
|
1414
|
-
F:
|
|
1415
|
-
L:
|
|
1691
|
+
F: __dxlog_file4,
|
|
1692
|
+
L: 746,
|
|
1416
1693
|
S: this,
|
|
1417
1694
|
C: (f, a) => f(...a)
|
|
1418
1695
|
});
|
|
1419
1696
|
toReplicateWithoutBatching.push(...missingOnRemote);
|
|
1420
1697
|
}
|
|
1421
1698
|
if (bundleSyncEnabled && missingOnLocal.length >= BUNDLE_SYNC_THRESHOLD) {
|
|
1422
|
-
|
|
1699
|
+
log4("pulling bundle", {
|
|
1423
1700
|
amount: missingOnLocal.length
|
|
1424
1701
|
}, {
|
|
1425
|
-
F:
|
|
1426
|
-
L:
|
|
1702
|
+
F: __dxlog_file4,
|
|
1703
|
+
L: 754,
|
|
1427
1704
|
S: this,
|
|
1428
1705
|
C: (f, a) => f(...a)
|
|
1429
1706
|
});
|
|
1430
1707
|
const { syncInteractively } = await this._pullInBundles(peerId, missingOnLocal);
|
|
1431
1708
|
toReplicateWithoutBatching.push(...syncInteractively);
|
|
1432
1709
|
} else {
|
|
1433
|
-
|
|
1710
|
+
log4.verbose("failed to pull bundle, replicating interactively", {
|
|
1434
1711
|
collectionId,
|
|
1435
1712
|
peerId,
|
|
1436
1713
|
amount: missingOnLocal.length
|
|
1437
1714
|
}, {
|
|
1438
|
-
F:
|
|
1439
|
-
L:
|
|
1715
|
+
F: __dxlog_file4,
|
|
1716
|
+
L: 758,
|
|
1440
1717
|
S: this,
|
|
1441
1718
|
C: (f, a) => f(...a)
|
|
1442
1719
|
});
|
|
@@ -1445,23 +1722,24 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1445
1722
|
if (toReplicateWithoutBatching.length === 0) {
|
|
1446
1723
|
return;
|
|
1447
1724
|
}
|
|
1448
|
-
|
|
1725
|
+
log4("replicating documents after collection sync", {
|
|
1449
1726
|
collectionId,
|
|
1450
1727
|
peerId,
|
|
1451
1728
|
toReplicateWithoutBatching,
|
|
1452
1729
|
count: toReplicateWithoutBatching.length
|
|
1453
1730
|
}, {
|
|
1454
|
-
F:
|
|
1455
|
-
L:
|
|
1731
|
+
F: __dxlog_file4,
|
|
1732
|
+
L: 770,
|
|
1456
1733
|
S: this,
|
|
1457
1734
|
C: (f, a) => f(...a)
|
|
1458
1735
|
});
|
|
1459
1736
|
for (const documentId of toReplicateWithoutBatching) {
|
|
1737
|
+
this._documentsToSync.add(documentId);
|
|
1460
1738
|
this._repo.findWithProgress(documentId);
|
|
1461
1739
|
}
|
|
1740
|
+
this._sharePolicyChangedTask.schedule();
|
|
1462
1741
|
}
|
|
1463
1742
|
// TODO(mykola): Add retries of batches https://gist.github.com/mykola-vrmchk/fde270259e9209fcbf1331e5abbf12cf
|
|
1464
|
-
// TODO(mykola): Use effect to retry batches.
|
|
1465
1743
|
async _pushInBundles(peerId, documentIds) {
|
|
1466
1744
|
const documentsToPush = [
|
|
1467
1745
|
...documentIds
|
|
@@ -1474,13 +1752,13 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1474
1752
|
return;
|
|
1475
1753
|
}
|
|
1476
1754
|
await this._pushBundle(peerId, bundle).catch((err) => {
|
|
1477
|
-
|
|
1755
|
+
log4.warn("failed to push bundle, replicating interactively", {
|
|
1478
1756
|
peerId,
|
|
1479
1757
|
bundle,
|
|
1480
1758
|
err
|
|
1481
1759
|
}, {
|
|
1482
|
-
F:
|
|
1483
|
-
L:
|
|
1760
|
+
F: __dxlog_file4,
|
|
1761
|
+
L: 803,
|
|
1484
1762
|
S: this,
|
|
1485
1763
|
C: (f, a) => f(...a)
|
|
1486
1764
|
});
|
|
@@ -1499,11 +1777,11 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1499
1777
|
const docs = documentIds.map((documentId) => {
|
|
1500
1778
|
const handle = this._repo.handles[documentId];
|
|
1501
1779
|
if (!handle || !handle.isReady()) {
|
|
1502
|
-
|
|
1780
|
+
log4.warn("document not ready, skipping", {
|
|
1503
1781
|
documentId
|
|
1504
1782
|
}, {
|
|
1505
|
-
F:
|
|
1506
|
-
L:
|
|
1783
|
+
F: __dxlog_file4,
|
|
1784
|
+
L: 821,
|
|
1507
1785
|
S: this,
|
|
1508
1786
|
C: (f, a) => f(...a)
|
|
1509
1787
|
});
|
|
@@ -1511,11 +1789,11 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1511
1789
|
}
|
|
1512
1790
|
const doc = handle.doc();
|
|
1513
1791
|
if (!doc) {
|
|
1514
|
-
|
|
1792
|
+
log4.warn("document not available, skipping", {
|
|
1515
1793
|
documentId
|
|
1516
1794
|
}, {
|
|
1517
|
-
F:
|
|
1518
|
-
L:
|
|
1795
|
+
F: __dxlog_file4,
|
|
1796
|
+
L: 826,
|
|
1519
1797
|
S: this,
|
|
1520
1798
|
C: (f, a) => f(...a)
|
|
1521
1799
|
});
|
|
@@ -1542,13 +1820,13 @@ var AutomergeHost = class extends Resource3 {
|
|
|
1542
1820
|
return;
|
|
1543
1821
|
}
|
|
1544
1822
|
const result = await this._pullBundle(peerId, bundle).catch((err) => {
|
|
1545
|
-
|
|
1823
|
+
log4.warn("failed to pull bundle, replicating interactively", {
|
|
1546
1824
|
peerId,
|
|
1547
1825
|
bundle,
|
|
1548
1826
|
err
|
|
1549
1827
|
}, {
|
|
1550
|
-
F:
|
|
1551
|
-
L:
|
|
1828
|
+
F: __dxlog_file4,
|
|
1829
|
+
L: 856,
|
|
1552
1830
|
S: this,
|
|
1553
1831
|
C: (f, a) => f(...a)
|
|
1554
1832
|
});
|
|
@@ -1629,7 +1907,7 @@ AutomergeHost = _ts_decorate3([
|
|
|
1629
1907
|
var waitForHeads = async (handle, heads) => {
|
|
1630
1908
|
const unavailableHeads = new Set(heads);
|
|
1631
1909
|
await handle.whenReady();
|
|
1632
|
-
await
|
|
1910
|
+
await Event3.wrap(handle, "change").waitForCondition(() => {
|
|
1633
1911
|
for (const changeHash of unavailableHeads.values()) {
|
|
1634
1912
|
if (changeIsPresentInDoc(handle.doc(), changeHash)) {
|
|
1635
1913
|
unavailableHeads.delete(changeHash);
|
|
@@ -1643,8 +1921,8 @@ var changeIsPresentInDoc = (doc, changeHash) => {
|
|
|
1643
1921
|
};
|
|
1644
1922
|
var decodeCollectionState = (state) => {
|
|
1645
1923
|
invariant2(typeof state === "object" && state !== null, "Invalid state", {
|
|
1646
|
-
F:
|
|
1647
|
-
L:
|
|
1924
|
+
F: __dxlog_file4,
|
|
1925
|
+
L: 939,
|
|
1648
1926
|
S: void 0,
|
|
1649
1927
|
A: [
|
|
1650
1928
|
"typeof state === 'object' && state !== null",
|
|
@@ -1659,18 +1937,18 @@ var encodeCollectionState = (state) => {
|
|
|
1659
1937
|
|
|
1660
1938
|
// src/automerge/mesh-echo-replicator.ts
|
|
1661
1939
|
import { invariant as invariant5 } from "@dxos/invariant";
|
|
1662
|
-
import { PublicKey as
|
|
1663
|
-
import { log as
|
|
1664
|
-
import { ComplexSet as ComplexSet2, defaultMap as
|
|
1940
|
+
import { PublicKey as PublicKey3 } from "@dxos/keys";
|
|
1941
|
+
import { log as log6 } from "@dxos/log";
|
|
1942
|
+
import { ComplexSet as ComplexSet2, defaultMap as defaultMap3 } from "@dxos/util";
|
|
1665
1943
|
|
|
1666
1944
|
// src/automerge/mesh-echo-replicator-connection.ts
|
|
1667
1945
|
import * as A2 from "@automerge/automerge";
|
|
1668
1946
|
import { cbor } from "@automerge/automerge-repo";
|
|
1669
1947
|
import { Resource as Resource4 } from "@dxos/context";
|
|
1670
1948
|
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1671
|
-
import { log as
|
|
1949
|
+
import { log as log5 } from "@dxos/log";
|
|
1672
1950
|
import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
|
|
1673
|
-
var
|
|
1951
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator-connection.ts";
|
|
1674
1952
|
var DEFAULT_FACTORY = (params) => new AutomergeReplicator(...params);
|
|
1675
1953
|
var MeshReplicatorConnection = class extends Resource4 {
|
|
1676
1954
|
_params;
|
|
@@ -1692,7 +1970,7 @@ var MeshReplicatorConnection = class extends Resource4 {
|
|
|
1692
1970
|
this.writable = new WritableStream({
|
|
1693
1971
|
write: async (message, controller) => {
|
|
1694
1972
|
invariant3(this._isEnabled, "Writing to a disabled connection", {
|
|
1695
|
-
F:
|
|
1973
|
+
F: __dxlog_file5,
|
|
1696
1974
|
L: 51,
|
|
1697
1975
|
S: this,
|
|
1698
1976
|
A: [
|
|
@@ -1720,12 +1998,12 @@ var MeshReplicatorConnection = class extends Resource4 {
|
|
|
1720
1998
|
onStartReplication: async (info, remotePeerId) => {
|
|
1721
1999
|
this.remoteDeviceKey = remotePeerId;
|
|
1722
2000
|
this._remotePeerId = info.id;
|
|
1723
|
-
|
|
2001
|
+
log5("onStartReplication", {
|
|
1724
2002
|
id: info.id,
|
|
1725
2003
|
thisPeerId: this.peerId,
|
|
1726
2004
|
remotePeerId: remotePeerId.toHex()
|
|
1727
2005
|
}, {
|
|
1728
|
-
F:
|
|
2006
|
+
F: __dxlog_file5,
|
|
1729
2007
|
L: 80,
|
|
1730
2008
|
S: this,
|
|
1731
2009
|
C: (f, a) => f(...a)
|
|
@@ -1752,7 +2030,7 @@ var MeshReplicatorConnection = class extends Resource4 {
|
|
|
1752
2030
|
}
|
|
1753
2031
|
get peerId() {
|
|
1754
2032
|
invariant3(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1755
|
-
F:
|
|
2033
|
+
F: __dxlog_file5,
|
|
1756
2034
|
L: 106,
|
|
1757
2035
|
S: this,
|
|
1758
2036
|
A: [
|
|
@@ -1780,7 +2058,7 @@ var MeshReplicatorConnection = class extends Resource4 {
|
|
|
1780
2058
|
*/
|
|
1781
2059
|
enable() {
|
|
1782
2060
|
invariant3(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1783
|
-
F:
|
|
2061
|
+
F: __dxlog_file5,
|
|
1784
2062
|
L: 131,
|
|
1785
2063
|
S: this,
|
|
1786
2064
|
A: [
|
|
@@ -1798,7 +2076,7 @@ var MeshReplicatorConnection = class extends Resource4 {
|
|
|
1798
2076
|
}
|
|
1799
2077
|
};
|
|
1800
2078
|
var logSendSync = (message) => {
|
|
1801
|
-
|
|
2079
|
+
log5("sendSyncMessage", () => {
|
|
1802
2080
|
const decodedSyncMessage = message.type === "sync" && message.data ? A2.decodeSyncMessage(message.data) : void 0;
|
|
1803
2081
|
return {
|
|
1804
2082
|
sync: decodedSyncMessage && {
|
|
@@ -1811,7 +2089,7 @@ var logSendSync = (message) => {
|
|
|
1811
2089
|
to: message.targetId
|
|
1812
2090
|
};
|
|
1813
2091
|
}, {
|
|
1814
|
-
F:
|
|
2092
|
+
F: __dxlog_file5,
|
|
1815
2093
|
L: 144,
|
|
1816
2094
|
S: void 0,
|
|
1817
2095
|
C: (f, a) => f(...a)
|
|
@@ -1821,12 +2099,12 @@ var logSendSync = (message) => {
|
|
|
1821
2099
|
// src/automerge/space-collection.ts
|
|
1822
2100
|
import { invariant as invariant4 } from "@dxos/invariant";
|
|
1823
2101
|
import { SpaceId } from "@dxos/keys";
|
|
1824
|
-
var
|
|
2102
|
+
var __dxlog_file6 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/space-collection.ts";
|
|
1825
2103
|
var deriveCollectionIdFromSpaceId = (spaceId, rootDocumentId) => rootDocumentId ? `space:${spaceId}:${rootDocumentId}` : `space:${spaceId}`;
|
|
1826
2104
|
var getSpaceIdFromCollectionId = (collectionId) => {
|
|
1827
2105
|
const spaceId = collectionId.split(":")[1];
|
|
1828
2106
|
invariant4(SpaceId.isValid(spaceId), void 0, {
|
|
1829
|
-
F:
|
|
2107
|
+
F: __dxlog_file6,
|
|
1830
2108
|
L: 16,
|
|
1831
2109
|
S: void 0,
|
|
1832
2110
|
A: [
|
|
@@ -1838,7 +2116,7 @@ var getSpaceIdFromCollectionId = (collectionId) => {
|
|
|
1838
2116
|
};
|
|
1839
2117
|
|
|
1840
2118
|
// src/automerge/mesh-echo-replicator.ts
|
|
1841
|
-
var
|
|
2119
|
+
var __dxlog_file7 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts";
|
|
1842
2120
|
var MeshEchoReplicator = class {
|
|
1843
2121
|
/**
|
|
1844
2122
|
* We might have multiple connections open with a peer (one per space), but there'll be only one enabled
|
|
@@ -1874,7 +2152,7 @@ var MeshEchoReplicator = class {
|
|
|
1874
2152
|
}
|
|
1875
2153
|
createExtension(extensionFactory) {
|
|
1876
2154
|
invariant5(this._context, void 0, {
|
|
1877
|
-
F:
|
|
2155
|
+
F: __dxlog_file7,
|
|
1878
2156
|
L: 68,
|
|
1879
2157
|
S: this,
|
|
1880
2158
|
A: [
|
|
@@ -1886,16 +2164,16 @@ var MeshEchoReplicator = class {
|
|
|
1886
2164
|
ownPeerId: this._context.peerId,
|
|
1887
2165
|
replicatorFactory: extensionFactory,
|
|
1888
2166
|
onRemoteConnected: async () => {
|
|
1889
|
-
|
|
2167
|
+
log6("onRemoteConnected", {
|
|
1890
2168
|
peerId: connection.peerId
|
|
1891
2169
|
}, {
|
|
1892
|
-
F:
|
|
2170
|
+
F: __dxlog_file7,
|
|
1893
2171
|
L: 74,
|
|
1894
2172
|
S: this,
|
|
1895
2173
|
C: (f, a) => f(...a)
|
|
1896
2174
|
});
|
|
1897
2175
|
invariant5(this._context, void 0, {
|
|
1898
|
-
F:
|
|
2176
|
+
F: __dxlog_file7,
|
|
1899
2177
|
L: 75,
|
|
1900
2178
|
S: this,
|
|
1901
2179
|
A: [
|
|
@@ -1917,10 +2195,10 @@ var MeshEchoReplicator = class {
|
|
|
1917
2195
|
}
|
|
1918
2196
|
},
|
|
1919
2197
|
onRemoteDisconnected: async () => {
|
|
1920
|
-
|
|
2198
|
+
log6("onRemoteDisconnected", {
|
|
1921
2199
|
peerId: connection.peerId
|
|
1922
2200
|
}, {
|
|
1923
|
-
F:
|
|
2201
|
+
F: __dxlog_file7,
|
|
1924
2202
|
L: 89,
|
|
1925
2203
|
S: this,
|
|
1926
2204
|
C: (f, a) => f(...a)
|
|
@@ -1929,10 +2207,10 @@ var MeshEchoReplicator = class {
|
|
|
1929
2207
|
const existingConnections = this._connectionsPerPeer.get(connection.peerId) ?? [];
|
|
1930
2208
|
const index = existingConnections.indexOf(connection);
|
|
1931
2209
|
if (index < 0) {
|
|
1932
|
-
|
|
2210
|
+
log6.warn("disconnected connection not found", {
|
|
1933
2211
|
peerId: connection.peerId
|
|
1934
2212
|
}, {
|
|
1935
|
-
F:
|
|
2213
|
+
F: __dxlog_file7,
|
|
1936
2214
|
L: 97,
|
|
1937
2215
|
S: this,
|
|
1938
2216
|
C: (f, a) => f(...a)
|
|
@@ -1950,17 +2228,17 @@ var MeshEchoReplicator = class {
|
|
|
1950
2228
|
}
|
|
1951
2229
|
},
|
|
1952
2230
|
shouldAdvertise: async (params) => {
|
|
1953
|
-
|
|
2231
|
+
log6("shouldAdvertise", {
|
|
1954
2232
|
peerId: connection.peerId,
|
|
1955
2233
|
documentId: params.documentId
|
|
1956
2234
|
}, {
|
|
1957
|
-
F:
|
|
2235
|
+
F: __dxlog_file7,
|
|
1958
2236
|
L: 115,
|
|
1959
2237
|
S: this,
|
|
1960
2238
|
C: (f, a) => f(...a)
|
|
1961
2239
|
});
|
|
1962
2240
|
invariant5(this._context, void 0, {
|
|
1963
|
-
F:
|
|
2241
|
+
F: __dxlog_file7,
|
|
1964
2242
|
L: 116,
|
|
1965
2243
|
S: this,
|
|
1966
2244
|
A: [
|
|
@@ -1975,12 +2253,12 @@ var MeshEchoReplicator = class {
|
|
|
1975
2253
|
documentId: params.documentId,
|
|
1976
2254
|
peerId: connection.peerId
|
|
1977
2255
|
});
|
|
1978
|
-
|
|
2256
|
+
log6("document not found locally for share policy check", {
|
|
1979
2257
|
peerId: connection.peerId,
|
|
1980
2258
|
documentId: params.documentId,
|
|
1981
2259
|
acceptDocument: remoteDocumentExists
|
|
1982
2260
|
}, {
|
|
1983
|
-
F:
|
|
2261
|
+
F: __dxlog_file7,
|
|
1984
2262
|
L: 124,
|
|
1985
2263
|
S: this,
|
|
1986
2264
|
C: (f, a) => f(...a)
|
|
@@ -1990,11 +2268,11 @@ var MeshEchoReplicator = class {
|
|
|
1990
2268
|
const spaceId = await createIdFromSpaceKey(spaceKey);
|
|
1991
2269
|
const authorizedDevices = this._authorizedDevices.get(spaceId);
|
|
1992
2270
|
if (!connection.remoteDeviceKey) {
|
|
1993
|
-
|
|
2271
|
+
log6("device key not found for share policy check", {
|
|
1994
2272
|
peerId: connection.peerId,
|
|
1995
2273
|
documentId: params.documentId
|
|
1996
2274
|
}, {
|
|
1997
|
-
F:
|
|
2275
|
+
F: __dxlog_file7,
|
|
1998
2276
|
L: 141,
|
|
1999
2277
|
S: this,
|
|
2000
2278
|
C: (f, a) => f(...a)
|
|
@@ -2002,7 +2280,7 @@ var MeshEchoReplicator = class {
|
|
|
2002
2280
|
return false;
|
|
2003
2281
|
}
|
|
2004
2282
|
const isAuthorized = authorizedDevices?.has(connection.remoteDeviceKey) ?? false;
|
|
2005
|
-
|
|
2283
|
+
log6("share policy check", {
|
|
2006
2284
|
localPeer: this._context.peerId,
|
|
2007
2285
|
remotePeer: connection.peerId,
|
|
2008
2286
|
documentId: params.documentId,
|
|
@@ -2010,15 +2288,15 @@ var MeshEchoReplicator = class {
|
|
|
2010
2288
|
spaceKey,
|
|
2011
2289
|
isAuthorized
|
|
2012
2290
|
}, {
|
|
2013
|
-
F:
|
|
2291
|
+
F: __dxlog_file7,
|
|
2014
2292
|
L: 149,
|
|
2015
2293
|
S: this,
|
|
2016
2294
|
C: (f, a) => f(...a)
|
|
2017
2295
|
});
|
|
2018
2296
|
return isAuthorized;
|
|
2019
2297
|
} catch (err) {
|
|
2020
|
-
|
|
2021
|
-
F:
|
|
2298
|
+
log6.catch(err, void 0, {
|
|
2299
|
+
F: __dxlog_file7,
|
|
2022
2300
|
L: 159,
|
|
2023
2301
|
S: this,
|
|
2024
2302
|
C: (f, a) => f(...a)
|
|
@@ -2030,11 +2308,11 @@ var MeshEchoReplicator = class {
|
|
|
2030
2308
|
const spaceId = getSpaceIdFromCollectionId(collectionId);
|
|
2031
2309
|
const authorizedDevices = this._authorizedDevices.get(spaceId);
|
|
2032
2310
|
if (!connection.remoteDeviceKey) {
|
|
2033
|
-
|
|
2311
|
+
log6("device key not found for collection sync check", {
|
|
2034
2312
|
peerId: connection.peerId,
|
|
2035
2313
|
collectionId
|
|
2036
2314
|
}, {
|
|
2037
|
-
F:
|
|
2315
|
+
F: __dxlog_file7,
|
|
2038
2316
|
L: 169,
|
|
2039
2317
|
S: this,
|
|
2040
2318
|
C: (f, a) => f(...a)
|
|
@@ -2049,17 +2327,17 @@ var MeshEchoReplicator = class {
|
|
|
2049
2327
|
return connection.replicatorExtension;
|
|
2050
2328
|
}
|
|
2051
2329
|
async authorizeDevice(spaceKey, deviceKey) {
|
|
2052
|
-
|
|
2330
|
+
log6("authorizeDevice", {
|
|
2053
2331
|
spaceKey,
|
|
2054
2332
|
deviceKey
|
|
2055
2333
|
}, {
|
|
2056
|
-
F:
|
|
2334
|
+
F: __dxlog_file7,
|
|
2057
2335
|
L: 186,
|
|
2058
2336
|
S: this,
|
|
2059
2337
|
C: (f, a) => f(...a)
|
|
2060
2338
|
});
|
|
2061
2339
|
const spaceId = await createIdFromSpaceKey(spaceKey);
|
|
2062
|
-
|
|
2340
|
+
defaultMap3(this._authorizedDevices, spaceId, () => new ComplexSet2(PublicKey3.hash)).add(deviceKey);
|
|
2063
2341
|
for (const connection of this._connections) {
|
|
2064
2342
|
if (connection.isEnabled && connection.remoteDeviceKey && connection.remoteDeviceKey.equals(deviceKey)) {
|
|
2065
2343
|
if (this._connectionsPerPeer.has(connection.peerId)) {
|
|
@@ -2435,11 +2713,12 @@ var getByteCount = (message) => {
|
|
|
2435
2713
|
|
|
2436
2714
|
// src/db-host/documents-synchronizer.ts
|
|
2437
2715
|
import { next as A3 } from "@automerge/automerge";
|
|
2438
|
-
import { UpdateScheduler
|
|
2439
|
-
import {
|
|
2716
|
+
import { UpdateScheduler } from "@dxos/async";
|
|
2717
|
+
import { Context as Context3, LifecycleState as LifecycleState2, Resource as Resource5 } from "@dxos/context";
|
|
2440
2718
|
import { invariant as invariant6 } from "@dxos/invariant";
|
|
2441
|
-
import { log as
|
|
2442
|
-
|
|
2719
|
+
import { log as log7 } from "@dxos/log";
|
|
2720
|
+
import { retry } from "@dxos/util";
|
|
2721
|
+
var __dxlog_file8 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/documents-synchronizer.ts";
|
|
2443
2722
|
var MAX_UPDATE_FREQ = 10;
|
|
2444
2723
|
var WRAP_AROUND_RETRY_LIMIT = 3;
|
|
2445
2724
|
var WRAP_AROUND_RETRY_INITIAL_DELAY = 100;
|
|
@@ -2458,39 +2737,53 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2458
2737
|
constructor(_params) {
|
|
2459
2738
|
super(), this._params = _params;
|
|
2460
2739
|
}
|
|
2461
|
-
addDocuments(documentIds
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2740
|
+
async addDocuments(documentIds) {
|
|
2741
|
+
await Promise.all(documentIds.map(async (documentId) => {
|
|
2742
|
+
try {
|
|
2743
|
+
await retry({
|
|
2744
|
+
count: WRAP_AROUND_RETRY_LIMIT,
|
|
2745
|
+
delayMs: WRAP_AROUND_RETRY_INITIAL_DELAY,
|
|
2746
|
+
exponent: 2
|
|
2747
|
+
}, async () => {
|
|
2748
|
+
try {
|
|
2749
|
+
log7("loading document", {
|
|
2750
|
+
documentId
|
|
2751
|
+
}, {
|
|
2752
|
+
F: __dxlog_file8,
|
|
2753
|
+
L: 62,
|
|
2754
|
+
S: this,
|
|
2755
|
+
C: (f, a) => f(...a)
|
|
2756
|
+
});
|
|
2757
|
+
const doc = await this._params.automergeHost.loadDoc(Context3.default(void 0, {
|
|
2758
|
+
F: __dxlog_file8,
|
|
2759
|
+
L: 64
|
|
2760
|
+
}), documentId, {
|
|
2761
|
+
fetchFromNetwork: true
|
|
2762
|
+
});
|
|
2763
|
+
this._startSync(doc);
|
|
2764
|
+
this._pendingUpdates.add(doc.documentId);
|
|
2765
|
+
this._sendUpdatesJob.trigger();
|
|
2766
|
+
} catch (err) {
|
|
2767
|
+
log7.warn("failed to load document", {
|
|
2768
|
+
err
|
|
2769
|
+
}, {
|
|
2770
|
+
F: __dxlog_file8,
|
|
2771
|
+
L: 72,
|
|
2772
|
+
S: this,
|
|
2773
|
+
C: (f, a) => f(...a)
|
|
2774
|
+
});
|
|
2775
|
+
throw err;
|
|
2776
|
+
}
|
|
2777
|
+
});
|
|
2778
|
+
} catch (err) {
|
|
2779
|
+
log7.catch(err, void 0, {
|
|
2780
|
+
F: __dxlog_file8,
|
|
2781
|
+
L: 78,
|
|
2486
2782
|
S: this,
|
|
2487
2783
|
C: (f, a) => f(...a)
|
|
2488
2784
|
});
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
], retryCounter + 1, wrapAroundRetryDelay * 2));
|
|
2492
|
-
});
|
|
2493
|
-
}
|
|
2785
|
+
}
|
|
2786
|
+
}));
|
|
2494
2787
|
}
|
|
2495
2788
|
removeDocuments(documentIds) {
|
|
2496
2789
|
for (const documentId of documentIds) {
|
|
@@ -2509,18 +2802,20 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2509
2802
|
this._syncStates.clear();
|
|
2510
2803
|
}
|
|
2511
2804
|
async update(updates) {
|
|
2512
|
-
for (const { documentId, mutation
|
|
2513
|
-
this._writeMutation(documentId, mutation
|
|
2805
|
+
for (const { documentId, mutation } of updates) {
|
|
2806
|
+
await this._writeMutation(documentId, mutation);
|
|
2514
2807
|
}
|
|
2515
|
-
await this._params.
|
|
2808
|
+
await this._params.automergeHost.flush({
|
|
2809
|
+
documentIds: updates.map(({ documentId }) => documentId)
|
|
2810
|
+
});
|
|
2516
2811
|
}
|
|
2517
2812
|
_startSync(doc) {
|
|
2518
2813
|
if (this._syncStates.has(doc.documentId)) {
|
|
2519
|
-
|
|
2814
|
+
log7("Document already being synced", {
|
|
2520
2815
|
documentId: doc.documentId
|
|
2521
2816
|
}, {
|
|
2522
|
-
F:
|
|
2523
|
-
L:
|
|
2817
|
+
F: __dxlog_file8,
|
|
2818
|
+
L: 113,
|
|
2524
2819
|
S: this,
|
|
2525
2820
|
C: (f, a) => f(...a)
|
|
2526
2821
|
});
|
|
@@ -2563,8 +2858,8 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2563
2858
|
_getPendingChanges(documentId) {
|
|
2564
2859
|
const syncState = this._syncStates.get(documentId);
|
|
2565
2860
|
invariant6(syncState, "Sync state for document not found", {
|
|
2566
|
-
F:
|
|
2567
|
-
L:
|
|
2861
|
+
F: __dxlog_file8,
|
|
2862
|
+
L: 155,
|
|
2568
2863
|
S: this,
|
|
2569
2864
|
A: [
|
|
2570
2865
|
"syncState",
|
|
@@ -2583,40 +2878,41 @@ var DocumentsSynchronizer = class extends Resource5 {
|
|
|
2583
2878
|
syncState.lastSentHead = A3.getHeads(doc);
|
|
2584
2879
|
return mutation;
|
|
2585
2880
|
}
|
|
2586
|
-
_writeMutation(documentId, mutation
|
|
2881
|
+
async _writeMutation(documentId, mutation) {
|
|
2587
2882
|
if (this._lifecycleState === LifecycleState2.CLOSED) {
|
|
2588
2883
|
return;
|
|
2589
2884
|
}
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2885
|
+
log7("write mutation", {
|
|
2886
|
+
documentId
|
|
2887
|
+
}, {
|
|
2888
|
+
F: __dxlog_file8,
|
|
2889
|
+
L: 173,
|
|
2890
|
+
S: this,
|
|
2891
|
+
C: (f, a) => f(...a)
|
|
2892
|
+
});
|
|
2893
|
+
const syncState = this._syncStates.get(documentId);
|
|
2894
|
+
invariant6(syncState, "Sync state for document not found", {
|
|
2895
|
+
F: __dxlog_file8,
|
|
2896
|
+
L: 176,
|
|
2897
|
+
S: this,
|
|
2898
|
+
A: [
|
|
2899
|
+
"syncState",
|
|
2900
|
+
"'Sync state for document not found'"
|
|
2901
|
+
]
|
|
2902
|
+
});
|
|
2903
|
+
const headsBefore = A3.getHeads(syncState.handle.doc());
|
|
2904
|
+
await this._params.automergeHost.createDoc(mutation, {
|
|
2905
|
+
documentId,
|
|
2906
|
+
preserveHistory: true
|
|
2907
|
+
});
|
|
2908
|
+
if (A3.equals(headsBefore, syncState.lastSentHead)) {
|
|
2909
|
+
syncState.lastSentHead = A3.getHeads(syncState.handle.doc());
|
|
2614
2910
|
}
|
|
2615
2911
|
}
|
|
2616
2912
|
};
|
|
2617
2913
|
|
|
2618
2914
|
// src/db-host/data-service.ts
|
|
2619
|
-
var
|
|
2915
|
+
var __dxlog_file9 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/data-service.ts";
|
|
2620
2916
|
var DataServiceImpl = class {
|
|
2621
2917
|
/**
|
|
2622
2918
|
* Map of subscriptions.
|
|
@@ -2634,15 +2930,15 @@ var DataServiceImpl = class {
|
|
|
2634
2930
|
subscribe(request) {
|
|
2635
2931
|
return new Stream(({ next, ready }) => {
|
|
2636
2932
|
const synchronizer = new DocumentsSynchronizer({
|
|
2637
|
-
|
|
2933
|
+
automergeHost: this._automergeHost,
|
|
2638
2934
|
sendUpdates: (updates) => next(updates)
|
|
2639
2935
|
});
|
|
2640
2936
|
synchronizer.open().then(() => {
|
|
2641
2937
|
this._subscriptions.set(request.subscriptionId, synchronizer);
|
|
2642
2938
|
ready();
|
|
2643
|
-
}).catch((err) =>
|
|
2644
|
-
F:
|
|
2645
|
-
L:
|
|
2939
|
+
}).catch((err) => log8.catch(err, void 0, {
|
|
2940
|
+
F: __dxlog_file9,
|
|
2941
|
+
L: 74,
|
|
2646
2942
|
S: this,
|
|
2647
2943
|
C: (f, a) => f(...a)
|
|
2648
2944
|
}));
|
|
@@ -2652,8 +2948,8 @@ var DataServiceImpl = class {
|
|
|
2652
2948
|
async updateSubscription(request) {
|
|
2653
2949
|
const synchronizer = this._subscriptions.get(request.subscriptionId);
|
|
2654
2950
|
invariant7(synchronizer, "Subscription not found", {
|
|
2655
|
-
F:
|
|
2656
|
-
L:
|
|
2951
|
+
F: __dxlog_file9,
|
|
2952
|
+
L: 81,
|
|
2657
2953
|
S: this,
|
|
2658
2954
|
A: [
|
|
2659
2955
|
"synchronizer",
|
|
@@ -2667,14 +2963,20 @@ var DataServiceImpl = class {
|
|
|
2667
2963
|
await synchronizer.removeDocuments(request.removeIds);
|
|
2668
2964
|
}
|
|
2669
2965
|
}
|
|
2966
|
+
async createDocument(request) {
|
|
2967
|
+
const handle = await this._automergeHost.createDoc(request.initialValue);
|
|
2968
|
+
return {
|
|
2969
|
+
documentId: handle.documentId
|
|
2970
|
+
};
|
|
2971
|
+
}
|
|
2670
2972
|
async update(request) {
|
|
2671
2973
|
if (!request.updates) {
|
|
2672
2974
|
return;
|
|
2673
2975
|
}
|
|
2674
2976
|
const synchronizer = this._subscriptions.get(request.subscriptionId);
|
|
2675
2977
|
invariant7(synchronizer, "Subscription not found", {
|
|
2676
|
-
F:
|
|
2677
|
-
L:
|
|
2978
|
+
F: __dxlog_file9,
|
|
2979
|
+
L: 101,
|
|
2678
2980
|
S: this,
|
|
2679
2981
|
A: [
|
|
2680
2982
|
"synchronizer",
|
|
@@ -2718,8 +3020,8 @@ var DataServiceImpl = class {
|
|
|
2718
3020
|
return new Stream(({ ctx, next, ready }) => {
|
|
2719
3021
|
const spaceId = request.spaceId;
|
|
2720
3022
|
invariant7(SpaceId2.isValid(spaceId), void 0, {
|
|
2721
|
-
F:
|
|
2722
|
-
L:
|
|
3023
|
+
F: __dxlog_file9,
|
|
3024
|
+
L: 141,
|
|
2723
3025
|
S: this,
|
|
2724
3026
|
A: [
|
|
2725
3027
|
"SpaceId.isValid(spaceId)",
|
|
@@ -2754,22 +3056,27 @@ var DataServiceImpl = class {
|
|
|
2754
3056
|
};
|
|
2755
3057
|
|
|
2756
3058
|
// src/db-host/echo-host.ts
|
|
2757
|
-
import {
|
|
3059
|
+
import { DeferredTask as DeferredTask3, sleep } from "@dxos/async";
|
|
3060
|
+
import { Context as Context8, LifecycleState as LifecycleState5, Resource as Resource9 } from "@dxos/context";
|
|
2758
3061
|
import { todo } from "@dxos/debug";
|
|
2759
|
-
import { SpaceDocVersion as
|
|
3062
|
+
import { SpaceDocVersion as SpaceDocVersion4, createIdFromSpaceKey as createIdFromSpaceKey2 } from "@dxos/echo-protocol";
|
|
3063
|
+
import { RuntimeProvider as RuntimeProvider3 } from "@dxos/effect";
|
|
3064
|
+
import { FeedStore } from "@dxos/feed";
|
|
3065
|
+
import { IndexEngine } from "@dxos/index-core";
|
|
2760
3066
|
import { IndexMetadataStore, IndexStore, Indexer } from "@dxos/indexing";
|
|
2761
|
-
import { invariant as
|
|
3067
|
+
import { invariant as invariant14 } from "@dxos/invariant";
|
|
3068
|
+
import { log as log14 } from "@dxos/log";
|
|
2762
3069
|
import { IndexKind } from "@dxos/protocols/proto/dxos/echo/indexing";
|
|
2763
3070
|
import { trace as trace5 } from "@dxos/tracing";
|
|
2764
3071
|
|
|
2765
3072
|
// src/db-host/documents-iterator.ts
|
|
2766
3073
|
import * as A4 from "@automerge/automerge";
|
|
2767
|
-
import { Context as
|
|
2768
|
-
import { DatabaseDirectory as
|
|
3074
|
+
import { Context as Context4 } from "@dxos/context";
|
|
3075
|
+
import { DatabaseDirectory as DatabaseDirectory3, SpaceDocVersion as SpaceDocVersion2 } from "@dxos/echo-protocol";
|
|
2769
3076
|
import { invariant as invariant8 } from "@dxos/invariant";
|
|
2770
|
-
import { log as
|
|
3077
|
+
import { log as log9 } from "@dxos/log";
|
|
2771
3078
|
import { ObjectPointerVersion, objectPointerCodec as objectPointerCodec2 } from "@dxos/protocols";
|
|
2772
|
-
var
|
|
3079
|
+
var __dxlog_file10 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/documents-iterator.ts";
|
|
2773
3080
|
var LOG_VIEW_OPERATION_THRESHOLD = 300;
|
|
2774
3081
|
var createSelectedDocumentsIterator = (automergeHost) => (
|
|
2775
3082
|
/**
|
|
@@ -2780,14 +3087,16 @@ var createSelectedDocumentsIterator = (automergeHost) => (
|
|
|
2780
3087
|
for (const [id, heads] of objects.entries()) {
|
|
2781
3088
|
try {
|
|
2782
3089
|
const { documentId, objectId } = objectPointerCodec2.decode(id);
|
|
2783
|
-
const handle = await automergeHost.loadDoc(
|
|
2784
|
-
F:
|
|
3090
|
+
const handle = await automergeHost.loadDoc(Context4.default(void 0, {
|
|
3091
|
+
F: __dxlog_file10,
|
|
2785
3092
|
L: 31
|
|
2786
|
-
}), documentId
|
|
3093
|
+
}), documentId, {
|
|
3094
|
+
fetchFromNetwork: true
|
|
3095
|
+
});
|
|
2787
3096
|
let doc = handle.doc();
|
|
2788
3097
|
invariant8(doc, void 0, {
|
|
2789
|
-
F:
|
|
2790
|
-
L:
|
|
3098
|
+
F: __dxlog_file10,
|
|
3099
|
+
L: 36,
|
|
2791
3100
|
S: this,
|
|
2792
3101
|
A: [
|
|
2793
3102
|
"doc",
|
|
@@ -2800,19 +3109,19 @@ var createSelectedDocumentsIterator = (automergeHost) => (
|
|
|
2800
3109
|
doc = A4.view(doc, heads);
|
|
2801
3110
|
const end = Date.now();
|
|
2802
3111
|
if (end - begin > LOG_VIEW_OPERATION_THRESHOLD) {
|
|
2803
|
-
|
|
3112
|
+
log9("Checking out document version is taking too long", {
|
|
2804
3113
|
duration: end - begin,
|
|
2805
3114
|
requestedHeads: heads,
|
|
2806
3115
|
originalHeads: currentHeads
|
|
2807
3116
|
}, {
|
|
2808
|
-
F:
|
|
2809
|
-
L:
|
|
3117
|
+
F: __dxlog_file10,
|
|
3118
|
+
L: 47,
|
|
2810
3119
|
S: this,
|
|
2811
3120
|
C: (f, a) => f(...a)
|
|
2812
3121
|
});
|
|
2813
3122
|
}
|
|
2814
3123
|
}
|
|
2815
|
-
if (doc.version !==
|
|
3124
|
+
if (doc.version !== SpaceDocVersion2.CURRENT) {
|
|
2816
3125
|
continue;
|
|
2817
3126
|
}
|
|
2818
3127
|
if (!doc.objects?.[objectId]) {
|
|
@@ -2820,7 +3129,7 @@ var createSelectedDocumentsIterator = (automergeHost) => (
|
|
|
2820
3129
|
}
|
|
2821
3130
|
let newId = id;
|
|
2822
3131
|
if (objectPointerCodec2.getVersion(id) === ObjectPointerVersion.V0) {
|
|
2823
|
-
const spaceKey =
|
|
3132
|
+
const spaceKey = DatabaseDirectory3.getSpaceKey(doc) ?? void 0;
|
|
2824
3133
|
newId = objectPointerCodec2.encode({
|
|
2825
3134
|
documentId,
|
|
2826
3135
|
objectId,
|
|
@@ -2835,13 +3144,13 @@ var createSelectedDocumentsIterator = (automergeHost) => (
|
|
|
2835
3144
|
}
|
|
2836
3145
|
];
|
|
2837
3146
|
} catch (error) {
|
|
2838
|
-
|
|
3147
|
+
log9.error("Error loading document", {
|
|
2839
3148
|
heads,
|
|
2840
3149
|
id,
|
|
2841
3150
|
error
|
|
2842
3151
|
}, {
|
|
2843
|
-
F:
|
|
2844
|
-
L:
|
|
3152
|
+
F: __dxlog_file10,
|
|
3153
|
+
L: 73,
|
|
2845
3154
|
S: this,
|
|
2846
3155
|
C: (f, a) => f(...a)
|
|
2847
3156
|
});
|
|
@@ -2850,39 +3159,148 @@ var createSelectedDocumentsIterator = (automergeHost) => (
|
|
|
2850
3159
|
}
|
|
2851
3160
|
);
|
|
2852
3161
|
|
|
3162
|
+
// src/db-host/local-queue-service.ts
|
|
3163
|
+
import * as Effect2 from "effect/Effect";
|
|
3164
|
+
import * as Function from "effect/Function";
|
|
3165
|
+
import { ATTR_META } from "@dxos/echo/internal";
|
|
3166
|
+
import { RuntimeProvider } from "@dxos/effect";
|
|
3167
|
+
import { invariant as invariant9 } from "@dxos/invariant";
|
|
3168
|
+
import { KEY_QUEUE_POSITION } from "@dxos/protocols";
|
|
3169
|
+
var __dxlog_file11 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/local-queue-service.ts";
|
|
3170
|
+
var LocalQueueServiceImpl = class {
|
|
3171
|
+
#runtime;
|
|
3172
|
+
#feedStore;
|
|
3173
|
+
constructor(runtime, feedStore) {
|
|
3174
|
+
this.#runtime = runtime;
|
|
3175
|
+
this.#feedStore = feedStore;
|
|
3176
|
+
}
|
|
3177
|
+
queryQueue(request) {
|
|
3178
|
+
const { query } = request;
|
|
3179
|
+
invariant9(query, "query is required", {
|
|
3180
|
+
F: __dxlog_file11,
|
|
3181
|
+
L: 37,
|
|
3182
|
+
S: this,
|
|
3183
|
+
A: [
|
|
3184
|
+
"query",
|
|
3185
|
+
"'query is required'"
|
|
3186
|
+
]
|
|
3187
|
+
});
|
|
3188
|
+
const { spaceId, queueIds } = query;
|
|
3189
|
+
return RuntimeProvider.runPromise(this.#runtime)(Effect2.gen(this, function* () {
|
|
3190
|
+
const cursor = query.after ? parseInt(query.after) : -1;
|
|
3191
|
+
const result = yield* this.#feedStore.query({
|
|
3192
|
+
requestId: crypto.randomUUID(),
|
|
3193
|
+
spaceId,
|
|
3194
|
+
query: {
|
|
3195
|
+
feedIds: queueIds ?? []
|
|
3196
|
+
},
|
|
3197
|
+
position: cursor,
|
|
3198
|
+
limit: query.limit
|
|
3199
|
+
});
|
|
3200
|
+
const objects = result.blocks.map((block) => {
|
|
3201
|
+
const data = JSON.parse(new TextDecoder().decode(block.data));
|
|
3202
|
+
if (block.position !== null) {
|
|
3203
|
+
setQueuePosition(data, block.position);
|
|
3204
|
+
}
|
|
3205
|
+
return data;
|
|
3206
|
+
});
|
|
3207
|
+
const lastBlock = result.blocks[result.blocks.length - 1];
|
|
3208
|
+
const nextCursor = lastBlock && lastBlock.position != null ? String(lastBlock.position) : null;
|
|
3209
|
+
return Function.identity({
|
|
3210
|
+
objects,
|
|
3211
|
+
// TODO(dmaretskyi): This is wrong, fix later - cursors should come directly from the feed.
|
|
3212
|
+
nextCursor: nextCursor?.toString() ?? "",
|
|
3213
|
+
prevCursor: ""
|
|
3214
|
+
});
|
|
3215
|
+
}));
|
|
3216
|
+
}
|
|
3217
|
+
insertIntoQueue(request) {
|
|
3218
|
+
const { subspaceTag, spaceId, queueId, objects } = request;
|
|
3219
|
+
return RuntimeProvider.runPromise(this.#runtime)(Effect2.gen(this, function* () {
|
|
3220
|
+
const messages = objects.map((obj) => {
|
|
3221
|
+
const data = structuredClone(obj);
|
|
3222
|
+
if (data[ATTR_META]?.keys?.find((key) => key.source === KEY_QUEUE_POSITION)) {
|
|
3223
|
+
data[ATTR_META].keys = data[ATTR_META].keys.filter((key) => key.source !== KEY_QUEUE_POSITION);
|
|
3224
|
+
}
|
|
3225
|
+
return {
|
|
3226
|
+
spaceId,
|
|
3227
|
+
feedId: queueId,
|
|
3228
|
+
feedNamespace: subspaceTag,
|
|
3229
|
+
data: new TextEncoder().encode(JSON.stringify(obj))
|
|
3230
|
+
};
|
|
3231
|
+
});
|
|
3232
|
+
yield* this.#feedStore.appendLocal(messages);
|
|
3233
|
+
}));
|
|
3234
|
+
}
|
|
3235
|
+
deleteFromQueue(request) {
|
|
3236
|
+
const { subspaceTag, spaceId, queueId, objectIds } = request;
|
|
3237
|
+
return RuntimeProvider.runPromise(this.#runtime)(Effect2.gen(this, function* () {
|
|
3238
|
+
const messages = objectIds.map((id) => ({
|
|
3239
|
+
spaceId,
|
|
3240
|
+
feedId: queueId,
|
|
3241
|
+
feedNamespace: subspaceTag,
|
|
3242
|
+
data: new TextEncoder().encode(JSON.stringify({
|
|
3243
|
+
id,
|
|
3244
|
+
"@deleted": true
|
|
3245
|
+
}))
|
|
3246
|
+
}));
|
|
3247
|
+
yield* this.#feedStore.appendLocal(messages);
|
|
3248
|
+
}));
|
|
3249
|
+
}
|
|
3250
|
+
};
|
|
3251
|
+
var setQueuePosition = (obj, position) => {
|
|
3252
|
+
obj[ATTR_META] ??= {
|
|
3253
|
+
keys: []
|
|
3254
|
+
};
|
|
3255
|
+
obj[ATTR_META].keys ??= [];
|
|
3256
|
+
for (let i = 0; i < obj[ATTR_META].keys.length; i++) {
|
|
3257
|
+
const key = obj[ATTR_META].keys[i];
|
|
3258
|
+
if (key.source === KEY_QUEUE_POSITION) {
|
|
3259
|
+
obj[ATTR_META].keys.splice(i, 1);
|
|
3260
|
+
i--;
|
|
3261
|
+
}
|
|
3262
|
+
}
|
|
3263
|
+
obj[ATTR_META].keys.push({
|
|
3264
|
+
source: KEY_QUEUE_POSITION,
|
|
3265
|
+
id: position.toString()
|
|
3266
|
+
});
|
|
3267
|
+
};
|
|
3268
|
+
|
|
2853
3269
|
// src/db-host/query-service.ts
|
|
2854
3270
|
import { getHeads as getHeads3 } from "@automerge/automerge";
|
|
2855
3271
|
import * as Schema from "effect/Schema";
|
|
2856
3272
|
import { DeferredTask as DeferredTask2, scheduleMicroTask, synchronized as synchronized2 } from "@dxos/async";
|
|
2857
3273
|
import { Stream as Stream2 } from "@dxos/codec-protobuf/stream";
|
|
2858
|
-
import { Context as
|
|
3274
|
+
import { Context as Context6, Resource as Resource7 } from "@dxos/context";
|
|
2859
3275
|
import { raise } from "@dxos/debug";
|
|
2860
|
-
import { DatabaseDirectory as
|
|
2861
|
-
import { log as
|
|
3276
|
+
import { DatabaseDirectory as DatabaseDirectory5, QueryAST } from "@dxos/echo-protocol";
|
|
3277
|
+
import { log as log11 } from "@dxos/log";
|
|
2862
3278
|
import { objectPointerCodec as objectPointerCodec4 } from "@dxos/protocols";
|
|
2863
3279
|
import { trace as trace4 } from "@dxos/tracing";
|
|
2864
3280
|
|
|
2865
3281
|
// src/query/query-executor.ts
|
|
2866
3282
|
import * as Match from "effect/Match";
|
|
2867
|
-
import * as
|
|
2868
|
-
import { Context as
|
|
2869
|
-
import {
|
|
3283
|
+
import * as Runtime from "effect/Runtime";
|
|
3284
|
+
import { Context as Context5, ContextDisposedError, LifecycleState as LifecycleState3, Resource as Resource6 } from "@dxos/context";
|
|
3285
|
+
import { ATTR_RELATION_SOURCE, ATTR_RELATION_TARGET } from "@dxos/echo/internal";
|
|
3286
|
+
import { DatabaseDirectory as DatabaseDirectory4, ObjectStructure, isEncodedReference } from "@dxos/echo-protocol";
|
|
3287
|
+
import { runAndForwardErrors, unwrapExit } from "@dxos/effect";
|
|
2870
3288
|
import { EscapedPropPath } from "@dxos/indexing";
|
|
2871
|
-
import { invariant as
|
|
2872
|
-
import { DXN, PublicKey as
|
|
2873
|
-
import { log as
|
|
3289
|
+
import { invariant as invariant11 } from "@dxos/invariant";
|
|
3290
|
+
import { DXN, PublicKey as PublicKey4 } from "@dxos/keys";
|
|
3291
|
+
import { log as log10 } from "@dxos/log";
|
|
2874
3292
|
import { objectPointerCodec as objectPointerCodec3 } from "@dxos/protocols";
|
|
2875
3293
|
import { getDeep, isNonNullable as isNonNullable3 } from "@dxos/util";
|
|
2876
3294
|
|
|
2877
3295
|
// src/query/query-planner.ts
|
|
2878
3296
|
import { Order } from "@dxos/echo";
|
|
2879
|
-
import { invariant as
|
|
3297
|
+
import { invariant as invariant10 } from "@dxos/invariant";
|
|
2880
3298
|
|
|
2881
3299
|
// src/query/errors.ts
|
|
2882
3300
|
import { BaseError } from "@dxos/errors";
|
|
2883
|
-
var QueryError = class extends BaseError.extend("
|
|
3301
|
+
var QueryError = class extends BaseError.extend("QueryError") {
|
|
2884
3302
|
};
|
|
2885
|
-
var InvalidQueryError = class extends QueryError.extend("
|
|
3303
|
+
var InvalidQueryError = class extends QueryError.extend("InvalidQueryError") {
|
|
2886
3304
|
};
|
|
2887
3305
|
|
|
2888
3306
|
// src/query/plan.ts
|
|
@@ -2907,7 +3325,7 @@ var InvalidQueryError = class extends QueryError.extend("INVALID_QUERY") {
|
|
|
2907
3325
|
var QueryPlan;
|
|
2908
3326
|
|
|
2909
3327
|
// src/query/query-planner.ts
|
|
2910
|
-
var
|
|
3328
|
+
var __dxlog_file12 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/query/query-planner.ts";
|
|
2911
3329
|
var DEFAULT_OPTIONS = {
|
|
2912
3330
|
defaultTextSearchKind: "full-text"
|
|
2913
3331
|
};
|
|
@@ -2927,6 +3345,7 @@ var QueryPlanner = class {
|
|
|
2927
3345
|
plan = this._optimizeEmptyFilters(plan);
|
|
2928
3346
|
plan = this._optimizeSoloUnions(plan);
|
|
2929
3347
|
plan = this._ensureOrderStep(plan);
|
|
3348
|
+
plan = this._optimizeLimits(plan);
|
|
2930
3349
|
return plan;
|
|
2931
3350
|
}
|
|
2932
3351
|
_generate(query, context) {
|
|
@@ -2951,6 +3370,8 @@ var QueryPlanner = class {
|
|
|
2951
3370
|
return this._generateSetDifferenceClause(query, context);
|
|
2952
3371
|
case "order":
|
|
2953
3372
|
return this._generateOrderClause(query, context);
|
|
3373
|
+
case "limit":
|
|
3374
|
+
return this._generateLimitClause(query, context);
|
|
2954
3375
|
default:
|
|
2955
3376
|
throw new QueryError({
|
|
2956
3377
|
message: `Unsupported query type: ${query.type}`,
|
|
@@ -2967,6 +3388,12 @@ var QueryPlanner = class {
|
|
|
2967
3388
|
if (query.options.spaceIds) {
|
|
2968
3389
|
newContext.selectionSpaces = query.options.spaceIds;
|
|
2969
3390
|
}
|
|
3391
|
+
if (query.options.allQueuesFromSpaces !== void 0) {
|
|
3392
|
+
newContext.selectionAllQueuesFromSpaces = query.options.allQueuesFromSpaces;
|
|
3393
|
+
}
|
|
3394
|
+
if (query.options.queues) {
|
|
3395
|
+
newContext.selectionQueues = query.options.queues;
|
|
3396
|
+
}
|
|
2970
3397
|
if (query.options.deleted) {
|
|
2971
3398
|
newContext.deletedHandling = query.options.deleted;
|
|
2972
3399
|
}
|
|
@@ -3002,6 +3429,8 @@ var QueryPlanner = class {
|
|
|
3002
3429
|
{
|
|
3003
3430
|
_tag: "SelectStep",
|
|
3004
3431
|
spaces: context.selectionSpaces,
|
|
3432
|
+
allQueuesFromSpaces: context.selectionAllQueuesFromSpaces,
|
|
3433
|
+
queues: context.selectionQueues,
|
|
3005
3434
|
selector: {
|
|
3006
3435
|
_tag: "IdSelector",
|
|
3007
3436
|
objectIds: filter2.id
|
|
@@ -3021,6 +3450,8 @@ var QueryPlanner = class {
|
|
|
3021
3450
|
{
|
|
3022
3451
|
_tag: "SelectStep",
|
|
3023
3452
|
spaces: context.selectionSpaces,
|
|
3453
|
+
allQueuesFromSpaces: context.selectionAllQueuesFromSpaces,
|
|
3454
|
+
queues: context.selectionQueues,
|
|
3024
3455
|
selector: {
|
|
3025
3456
|
_tag: "TypeSelector",
|
|
3026
3457
|
typename: [
|
|
@@ -3030,11 +3461,11 @@ var QueryPlanner = class {
|
|
|
3030
3461
|
}
|
|
3031
3462
|
},
|
|
3032
3463
|
...this._generateDeletedHandlingSteps(context),
|
|
3464
|
+
// 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.
|
|
3033
3465
|
{
|
|
3034
3466
|
_tag: "FilterStep",
|
|
3035
3467
|
filter: {
|
|
3036
|
-
...filter2
|
|
3037
|
-
typename: null
|
|
3468
|
+
...filter2
|
|
3038
3469
|
}
|
|
3039
3470
|
}
|
|
3040
3471
|
]);
|
|
@@ -3043,6 +3474,8 @@ var QueryPlanner = class {
|
|
|
3043
3474
|
{
|
|
3044
3475
|
_tag: "SelectStep",
|
|
3045
3476
|
spaces: context.selectionSpaces,
|
|
3477
|
+
allQueuesFromSpaces: context.selectionAllQueuesFromSpaces,
|
|
3478
|
+
queues: context.selectionQueues,
|
|
3046
3479
|
selector: {
|
|
3047
3480
|
_tag: "WildcardSelector"
|
|
3048
3481
|
}
|
|
@@ -3063,6 +3496,8 @@ var QueryPlanner = class {
|
|
|
3063
3496
|
{
|
|
3064
3497
|
_tag: "SelectStep",
|
|
3065
3498
|
spaces: context.selectionSpaces,
|
|
3499
|
+
allQueuesFromSpaces: context.selectionAllQueuesFromSpaces,
|
|
3500
|
+
queues: context.selectionQueues,
|
|
3066
3501
|
selector: {
|
|
3067
3502
|
_tag: "WildcardSelector"
|
|
3068
3503
|
}
|
|
@@ -3082,10 +3517,13 @@ var QueryPlanner = class {
|
|
|
3082
3517
|
{
|
|
3083
3518
|
_tag: "SelectStep",
|
|
3084
3519
|
spaces: context.selectionSpaces,
|
|
3520
|
+
allQueuesFromSpaces: context.selectionAllQueuesFromSpaces,
|
|
3521
|
+
queues: context.selectionQueues,
|
|
3085
3522
|
selector: {
|
|
3086
3523
|
_tag: "TextSelector",
|
|
3087
3524
|
text: filter2.text,
|
|
3088
|
-
searchKind: filter2.searchKind ?? this._options.defaultTextSearchKind
|
|
3525
|
+
searchKind: filter2.searchKind ?? this._options.defaultTextSearchKind,
|
|
3526
|
+
typename: null
|
|
3089
3527
|
}
|
|
3090
3528
|
},
|
|
3091
3529
|
...this._generateDeletedHandlingSteps(context)
|
|
@@ -3129,9 +3567,9 @@ var QueryPlanner = class {
|
|
|
3129
3567
|
case "or":
|
|
3130
3568
|
if (filter2.filters.every(isTrivialTypenameFilter)) {
|
|
3131
3569
|
const typenames = filter2.filters.map((filter3) => {
|
|
3132
|
-
|
|
3133
|
-
F:
|
|
3134
|
-
L:
|
|
3570
|
+
invariant10(filter3.type === "object" && filter3.typename !== null, void 0, {
|
|
3571
|
+
F: __dxlog_file12,
|
|
3572
|
+
L: 245,
|
|
3135
3573
|
S: this,
|
|
3136
3574
|
A: [
|
|
3137
3575
|
"filter.type === 'object' && filter.typename !== null",
|
|
@@ -3144,13 +3582,21 @@ var QueryPlanner = class {
|
|
|
3144
3582
|
{
|
|
3145
3583
|
_tag: "SelectStep",
|
|
3146
3584
|
spaces: context.selectionSpaces,
|
|
3585
|
+
allQueuesFromSpaces: context.selectionAllQueuesFromSpaces,
|
|
3586
|
+
queues: context.selectionQueues,
|
|
3147
3587
|
selector: {
|
|
3148
3588
|
_tag: "TypeSelector",
|
|
3149
3589
|
typename: typenames,
|
|
3150
3590
|
inverted: context.selectionInverted
|
|
3151
3591
|
}
|
|
3152
3592
|
},
|
|
3153
|
-
...this._generateDeletedHandlingSteps(context)
|
|
3593
|
+
...this._generateDeletedHandlingSteps(context),
|
|
3594
|
+
{
|
|
3595
|
+
_tag: "FilterStep",
|
|
3596
|
+
filter: {
|
|
3597
|
+
...filter2
|
|
3598
|
+
}
|
|
3599
|
+
}
|
|
3154
3600
|
]);
|
|
3155
3601
|
} else {
|
|
3156
3602
|
throw new QueryError({
|
|
@@ -3228,7 +3674,7 @@ var QueryPlanner = class {
|
|
|
3228
3674
|
traversal: {
|
|
3229
3675
|
_tag: "ReferenceTraversal",
|
|
3230
3676
|
direction: "incoming",
|
|
3231
|
-
property: query.property
|
|
3677
|
+
property: query.property ?? null
|
|
3232
3678
|
}
|
|
3233
3679
|
},
|
|
3234
3680
|
...this._generateDeletedHandlingSteps(context),
|
|
@@ -3371,40 +3817,156 @@ var QueryPlanner = class {
|
|
|
3371
3817
|
}
|
|
3372
3818
|
]);
|
|
3373
3819
|
}
|
|
3820
|
+
_generateLimitClause(query, context) {
|
|
3821
|
+
return QueryPlan.Plan.make([
|
|
3822
|
+
...this._generate(query.query, context).steps,
|
|
3823
|
+
{
|
|
3824
|
+
_tag: "LimitStep",
|
|
3825
|
+
limit: query.limit
|
|
3826
|
+
}
|
|
3827
|
+
]);
|
|
3828
|
+
}
|
|
3374
3829
|
// After complete plan is built, inspect it from the end:
|
|
3375
3830
|
// - Walk backwards until hitting an object set changer.
|
|
3376
3831
|
// - If an order step is found, skip.
|
|
3377
|
-
// - Otherwise
|
|
3832
|
+
// - Otherwise insert natural order before any limit steps (since limit should be applied after ordering).
|
|
3833
|
+
// This method is recursive and also processes sub-plans in unions and set differences.
|
|
3378
3834
|
_ensureOrderStep(plan) {
|
|
3835
|
+
const processedSteps = plan.steps.map((step) => {
|
|
3836
|
+
if (step._tag === "UnionStep") {
|
|
3837
|
+
return {
|
|
3838
|
+
_tag: "UnionStep",
|
|
3839
|
+
plans: step.plans.map((subPlan) => this._ensureOrderStep(subPlan))
|
|
3840
|
+
};
|
|
3841
|
+
} else if (step._tag === "SetDifferenceStep") {
|
|
3842
|
+
return {
|
|
3843
|
+
_tag: "SetDifferenceStep",
|
|
3844
|
+
source: this._ensureOrderStep(step.source),
|
|
3845
|
+
exclude: this._ensureOrderStep(step.exclude)
|
|
3846
|
+
};
|
|
3847
|
+
}
|
|
3848
|
+
return step;
|
|
3849
|
+
});
|
|
3850
|
+
const processedPlan = QueryPlan.Plan.make(processedSteps);
|
|
3379
3851
|
const OBJECT_SET_CHANGERS = /* @__PURE__ */ new Set([
|
|
3380
3852
|
"SelectStep",
|
|
3381
3853
|
"TraverseStep",
|
|
3382
3854
|
"UnionStep",
|
|
3383
3855
|
"SetDifferenceStep"
|
|
3384
3856
|
]);
|
|
3385
|
-
for (let i =
|
|
3386
|
-
const step =
|
|
3857
|
+
for (let i = processedPlan.steps.length - 1; i >= 0; i--) {
|
|
3858
|
+
const step = processedPlan.steps[i];
|
|
3387
3859
|
if (step._tag === "OrderStep") {
|
|
3388
|
-
return
|
|
3860
|
+
return processedPlan;
|
|
3389
3861
|
}
|
|
3390
3862
|
if (OBJECT_SET_CHANGERS.has(step._tag)) {
|
|
3391
3863
|
break;
|
|
3392
3864
|
}
|
|
3393
3865
|
}
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
{
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3866
|
+
let insertIndex = processedPlan.steps.length;
|
|
3867
|
+
for (let i = processedPlan.steps.length - 1; i >= 0; i--) {
|
|
3868
|
+
if (processedPlan.steps[i]._tag === "LimitStep") {
|
|
3869
|
+
insertIndex = i;
|
|
3870
|
+
} else {
|
|
3871
|
+
break;
|
|
3872
|
+
}
|
|
3873
|
+
}
|
|
3874
|
+
const newSteps = [
|
|
3875
|
+
...processedPlan.steps
|
|
3876
|
+
];
|
|
3877
|
+
newSteps.splice(insertIndex, 0, {
|
|
3878
|
+
_tag: "OrderStep",
|
|
3879
|
+
order: [
|
|
3880
|
+
Order.natural.ast
|
|
3881
|
+
]
|
|
3882
|
+
});
|
|
3883
|
+
return QueryPlan.Plan.make(newSteps);
|
|
3884
|
+
}
|
|
3885
|
+
/**
|
|
3886
|
+
* Propagates limits from LimitStep to SelectStep and OrderStep when possible.
|
|
3887
|
+
* Limits can only be propagated if there are no unions or traversals between the LimitStep and SelectStep/OrderStep.
|
|
3888
|
+
*/
|
|
3889
|
+
_optimizeLimits(plan) {
|
|
3890
|
+
const processedSteps = plan.steps.map((step) => {
|
|
3891
|
+
if (step._tag === "UnionStep") {
|
|
3892
|
+
return {
|
|
3893
|
+
_tag: "UnionStep",
|
|
3894
|
+
plans: step.plans.map((subPlan) => this._optimizeLimits(subPlan))
|
|
3895
|
+
};
|
|
3896
|
+
} else if (step._tag === "SetDifferenceStep") {
|
|
3897
|
+
return {
|
|
3898
|
+
_tag: "SetDifferenceStep",
|
|
3899
|
+
source: this._optimizeLimits(step.source),
|
|
3900
|
+
exclude: this._optimizeLimits(step.exclude)
|
|
3901
|
+
};
|
|
3902
|
+
}
|
|
3903
|
+
return step;
|
|
3904
|
+
});
|
|
3905
|
+
let limitStepIndex = -1;
|
|
3906
|
+
let limitValue;
|
|
3907
|
+
for (let i = processedSteps.length - 1; i >= 0; i--) {
|
|
3908
|
+
const step = processedSteps[i];
|
|
3909
|
+
if (step._tag === "LimitStep") {
|
|
3910
|
+
limitStepIndex = i;
|
|
3911
|
+
limitValue = step.limit;
|
|
3912
|
+
break;
|
|
3913
|
+
}
|
|
3914
|
+
if (step._tag !== "OrderStep") {
|
|
3915
|
+
break;
|
|
3401
3916
|
}
|
|
3917
|
+
}
|
|
3918
|
+
if (limitStepIndex === -1 || limitValue === void 0) {
|
|
3919
|
+
return QueryPlan.Plan.make(processedSteps);
|
|
3920
|
+
}
|
|
3921
|
+
const BLOCKERS = /* @__PURE__ */ new Set([
|
|
3922
|
+
"UnionStep",
|
|
3923
|
+
"TraverseStep",
|
|
3924
|
+
"SetDifferenceStep"
|
|
3402
3925
|
]);
|
|
3926
|
+
let selectStepIndex = -1;
|
|
3927
|
+
let orderStepIndex = -1;
|
|
3928
|
+
for (let i = 0; i < limitStepIndex; i++) {
|
|
3929
|
+
const step = processedSteps[i];
|
|
3930
|
+
if (step._tag === "SelectStep") {
|
|
3931
|
+
selectStepIndex = i;
|
|
3932
|
+
}
|
|
3933
|
+
if (step._tag === "OrderStep") {
|
|
3934
|
+
orderStepIndex = i;
|
|
3935
|
+
}
|
|
3936
|
+
if (BLOCKERS.has(step._tag)) {
|
|
3937
|
+
selectStepIndex = -1;
|
|
3938
|
+
orderStepIndex = -1;
|
|
3939
|
+
}
|
|
3940
|
+
}
|
|
3941
|
+
if (selectStepIndex === -1 && orderStepIndex === -1) {
|
|
3942
|
+
return QueryPlan.Plan.make(processedSteps);
|
|
3943
|
+
}
|
|
3944
|
+
const newSteps = [
|
|
3945
|
+
...processedSteps
|
|
3946
|
+
];
|
|
3947
|
+
if (selectStepIndex !== -1) {
|
|
3948
|
+
const selectStep = newSteps[selectStepIndex];
|
|
3949
|
+
newSteps[selectStepIndex] = {
|
|
3950
|
+
...selectStep,
|
|
3951
|
+
limit: limitValue
|
|
3952
|
+
};
|
|
3953
|
+
}
|
|
3954
|
+
if (orderStepIndex !== -1) {
|
|
3955
|
+
const orderStep = newSteps[orderStepIndex];
|
|
3956
|
+
newSteps[orderStepIndex] = {
|
|
3957
|
+
...orderStep,
|
|
3958
|
+
limit: limitValue
|
|
3959
|
+
};
|
|
3960
|
+
}
|
|
3961
|
+
newSteps.splice(limitStepIndex, 1);
|
|
3962
|
+
return QueryPlan.Plan.make(newSteps);
|
|
3403
3963
|
}
|
|
3404
3964
|
};
|
|
3405
3965
|
var DEFAULT_CONTEXT = {
|
|
3406
3966
|
originalQuery: null,
|
|
3407
3967
|
selectionSpaces: [],
|
|
3968
|
+
selectionAllQueuesFromSpaces: false,
|
|
3969
|
+
selectionQueues: [],
|
|
3408
3970
|
deletedHandling: "exclude",
|
|
3409
3971
|
selectionInverted: false
|
|
3410
3972
|
};
|
|
@@ -3426,7 +3988,45 @@ var isTrivialTypenameFilter = (filter2) => {
|
|
|
3426
3988
|
};
|
|
3427
3989
|
|
|
3428
3990
|
// src/query/query-executor.ts
|
|
3429
|
-
var
|
|
3991
|
+
var __dxlog_file13 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/query/query-executor.ts";
|
|
3992
|
+
var QueryItem = Object.freeze({
|
|
3993
|
+
isDeleted: (item) => {
|
|
3994
|
+
if (item.doc) {
|
|
3995
|
+
return ObjectStructure.isDeleted(item.doc);
|
|
3996
|
+
} else if (item.data) {
|
|
3997
|
+
return item.data["@deleted"] === true;
|
|
3998
|
+
} else {
|
|
3999
|
+
throw new Error("Invalid query item");
|
|
4000
|
+
}
|
|
4001
|
+
},
|
|
4002
|
+
getProperty: (item, property) => {
|
|
4003
|
+
if (item.doc) {
|
|
4004
|
+
return getDeep(item.doc.data, property);
|
|
4005
|
+
} else if (item.data) {
|
|
4006
|
+
return getDeep(item.data, property);
|
|
4007
|
+
} else {
|
|
4008
|
+
throw new Error("Invalid query item");
|
|
4009
|
+
}
|
|
4010
|
+
},
|
|
4011
|
+
getRelationSource: (item) => {
|
|
4012
|
+
if (item.doc) {
|
|
4013
|
+
return ObjectStructure.getRelationSource(item.doc)?.["/"];
|
|
4014
|
+
} else if (item.data) {
|
|
4015
|
+
return item.data[ATTR_RELATION_SOURCE];
|
|
4016
|
+
} else {
|
|
4017
|
+
throw new Error("Invalid query item");
|
|
4018
|
+
}
|
|
4019
|
+
},
|
|
4020
|
+
getRelationTarget: (item) => {
|
|
4021
|
+
if (item.doc) {
|
|
4022
|
+
return ObjectStructure.getRelationTarget(item.doc)?.["/"];
|
|
4023
|
+
} else if (item.data) {
|
|
4024
|
+
return item.data[ATTR_RELATION_TARGET];
|
|
4025
|
+
} else {
|
|
4026
|
+
throw new Error("Invalid query item");
|
|
4027
|
+
}
|
|
4028
|
+
}
|
|
4029
|
+
});
|
|
3430
4030
|
var ExecutionTrace = Object.freeze({
|
|
3431
4031
|
makeEmpty: () => ({
|
|
3432
4032
|
name: "Empty",
|
|
@@ -3498,8 +4098,10 @@ var ExecutionTrace = Object.freeze({
|
|
|
3498
4098
|
}
|
|
3499
4099
|
});
|
|
3500
4100
|
var TRACE_QUERY_EXECUTION = false;
|
|
3501
|
-
var QueryExecutor = class extends Resource6 {
|
|
4101
|
+
var QueryExecutor = class _QueryExecutor extends Resource6 {
|
|
3502
4102
|
_indexer;
|
|
4103
|
+
_indexer2;
|
|
4104
|
+
_runtime;
|
|
3503
4105
|
_automergeHost;
|
|
3504
4106
|
_spaceStateManager;
|
|
3505
4107
|
/**
|
|
@@ -3515,6 +4117,8 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3515
4117
|
constructor(options) {
|
|
3516
4118
|
super();
|
|
3517
4119
|
this._indexer = options.indexer;
|
|
4120
|
+
this._indexer2 = options.indexer2;
|
|
4121
|
+
this._runtime = options.runtime;
|
|
3518
4122
|
this._automergeHost = options.automergeHost;
|
|
3519
4123
|
this._spaceStateManager = options.spaceStateManager;
|
|
3520
4124
|
this._id = options.queryId;
|
|
@@ -3532,23 +4136,21 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3532
4136
|
get trace() {
|
|
3533
4137
|
return this._trace;
|
|
3534
4138
|
}
|
|
3535
|
-
async _open(ctx) {
|
|
3536
|
-
}
|
|
3537
|
-
async _close(ctx) {
|
|
3538
|
-
}
|
|
3539
4139
|
getResults() {
|
|
3540
4140
|
return this._lastResultSet.map((item) => ({
|
|
3541
4141
|
id: item.objectId,
|
|
3542
|
-
documentId: item.documentId,
|
|
4142
|
+
documentId: item.documentId ?? void 0,
|
|
4143
|
+
queueId: item.queueId ?? void 0,
|
|
4144
|
+
queueNamespace: item.queueNamespace ?? void 0,
|
|
3543
4145
|
spaceId: item.spaceId,
|
|
3544
|
-
|
|
3545
|
-
|
|
4146
|
+
rank: item.rank,
|
|
4147
|
+
documentJson: item.doc ? JSON.stringify(item.doc) : item.data ? JSON.stringify(item.data) : void 0
|
|
3546
4148
|
}));
|
|
3547
4149
|
}
|
|
3548
4150
|
async execQuery() {
|
|
3549
|
-
|
|
3550
|
-
F:
|
|
3551
|
-
L:
|
|
4151
|
+
invariant11(this._lifecycleState === LifecycleState3.OPEN, void 0, {
|
|
4152
|
+
F: __dxlog_file13,
|
|
4153
|
+
L: 285,
|
|
3552
4154
|
S: this,
|
|
3553
4155
|
A: [
|
|
3554
4156
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -3573,7 +4175,6 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3573
4175
|
}
|
|
3574
4176
|
async _execPlan(plan, workingSet) {
|
|
3575
4177
|
const trace6 = ExecutionTrace.makeEmpty();
|
|
3576
|
-
const begin = performance.now();
|
|
3577
4178
|
for (const step of plan.steps) {
|
|
3578
4179
|
if (this._ctx.disposed) {
|
|
3579
4180
|
throw new ContextDisposedError();
|
|
@@ -3624,6 +4225,9 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3624
4225
|
case "OrderStep":
|
|
3625
4226
|
({ workingSet: newWorkingSet, trace: trace6 } = await this._execOrderStep(step, workingSet));
|
|
3626
4227
|
break;
|
|
4228
|
+
case "LimitStep":
|
|
4229
|
+
({ workingSet: newWorkingSet, trace: trace6 } = await this._execLimitStep(step, workingSet));
|
|
4230
|
+
break;
|
|
3627
4231
|
default:
|
|
3628
4232
|
throw new Error(`Unknown step type: ${step._tag}`);
|
|
3629
4233
|
}
|
|
@@ -3646,24 +4250,42 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3646
4250
|
};
|
|
3647
4251
|
switch (step.selector._tag) {
|
|
3648
4252
|
case "WildcardSelector": {
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
4253
|
+
if (this._supportsSqlIndexing()) {
|
|
4254
|
+
const beginIndexQuery = performance.now();
|
|
4255
|
+
const metas = await this._queryAllFromSqlIndex(step.spaces);
|
|
4256
|
+
trace6.indexHits = metas.length;
|
|
4257
|
+
trace6.indexQueryTime += performance.now() - beginIndexQuery;
|
|
4258
|
+
if (this._ctx.disposed) {
|
|
4259
|
+
return {
|
|
4260
|
+
workingSet,
|
|
4261
|
+
trace: trace6
|
|
4262
|
+
};
|
|
4263
|
+
}
|
|
4264
|
+
const documentLoadStart = performance.now();
|
|
4265
|
+
const results = await this._loadDocumentsAfterSqlQuery(metas);
|
|
4266
|
+
trace6.documentsLoaded += results.length;
|
|
4267
|
+
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
4268
|
+
workingSet.push(...results.filter(isNonNullable3));
|
|
4269
|
+
} else {
|
|
4270
|
+
const beginIndexQuery = performance.now();
|
|
4271
|
+
const indexHits = await this._indexer.execQuery({
|
|
4272
|
+
typenames: [],
|
|
4273
|
+
inverted: false
|
|
4274
|
+
});
|
|
4275
|
+
trace6.indexHits = +indexHits.length;
|
|
4276
|
+
trace6.indexQueryTime += performance.now() - beginIndexQuery;
|
|
4277
|
+
if (this._ctx.disposed) {
|
|
4278
|
+
return {
|
|
4279
|
+
workingSet,
|
|
4280
|
+
trace: trace6
|
|
4281
|
+
};
|
|
4282
|
+
}
|
|
4283
|
+
const documentLoadStart = performance.now();
|
|
4284
|
+
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
4285
|
+
trace6.documentsLoaded += results.length;
|
|
4286
|
+
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
4287
|
+
workingSet.push(...results.filter(isNonNullable3).filter((item) => step.spaces.includes(item.spaceId)));
|
|
3661
4288
|
}
|
|
3662
|
-
const documentLoadStart = performance.now();
|
|
3663
|
-
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
3664
|
-
trace6.documentsLoaded += results.length;
|
|
3665
|
-
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
3666
|
-
workingSet.push(...results.filter(isNonNullable3).filter((item) => step.spaces.includes(item.spaceId)));
|
|
3667
4289
|
trace6.objectCount = workingSet.length;
|
|
3668
4290
|
break;
|
|
3669
4291
|
}
|
|
@@ -3678,66 +4300,182 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3678
4300
|
break;
|
|
3679
4301
|
}
|
|
3680
4302
|
case "TypeSelector": {
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
4303
|
+
if (this._supportsSqlIndexing()) {
|
|
4304
|
+
const beginIndexQuery = performance.now();
|
|
4305
|
+
const metas = await this._queryTypesFromSqlIndex(step.spaces, step.selector.typename, step.selector.inverted);
|
|
4306
|
+
trace6.indexHits = metas.length;
|
|
4307
|
+
trace6.indexQueryTime += performance.now() - beginIndexQuery;
|
|
4308
|
+
if (this._ctx.disposed) {
|
|
4309
|
+
return {
|
|
4310
|
+
workingSet,
|
|
4311
|
+
trace: trace6
|
|
4312
|
+
};
|
|
4313
|
+
}
|
|
4314
|
+
const documentLoadStart = performance.now();
|
|
4315
|
+
const results = await this._loadDocumentsAfterSqlQuery(metas);
|
|
4316
|
+
trace6.documentsLoaded += results.length;
|
|
4317
|
+
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
4318
|
+
workingSet.push(...results.filter(isNonNullable3));
|
|
4319
|
+
} else {
|
|
4320
|
+
const beginIndexQuery = performance.now();
|
|
4321
|
+
const indexHits = await this._indexer.execQuery({
|
|
4322
|
+
typenames: step.selector.typename,
|
|
4323
|
+
inverted: step.selector.inverted
|
|
4324
|
+
});
|
|
4325
|
+
trace6.indexHits = +indexHits.length;
|
|
4326
|
+
trace6.indexQueryTime += performance.now() - beginIndexQuery;
|
|
4327
|
+
if (this._ctx.disposed) {
|
|
4328
|
+
return {
|
|
4329
|
+
workingSet,
|
|
4330
|
+
trace: trace6
|
|
4331
|
+
};
|
|
4332
|
+
}
|
|
4333
|
+
const documentLoadStart = performance.now();
|
|
4334
|
+
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
4335
|
+
trace6.documentsLoaded += results.length;
|
|
4336
|
+
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
4337
|
+
workingSet.push(...results.filter(isNonNullable3).filter((item) => step.spaces.includes(item.spaceId)));
|
|
3693
4338
|
}
|
|
3694
|
-
const documentLoadStart = performance.now();
|
|
3695
|
-
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
3696
|
-
trace6.documentsLoaded += results.length;
|
|
3697
|
-
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
3698
|
-
workingSet.push(...results.filter(isNonNullable3).filter((item) => step.spaces.includes(item.spaceId)));
|
|
3699
4339
|
trace6.objectCount = workingSet.length;
|
|
3700
4340
|
break;
|
|
3701
4341
|
}
|
|
3702
4342
|
case "TextSelector": {
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
4343
|
+
if (step.selector.searchKind === "full-text" && this._supportsSqlIndexing()) {
|
|
4344
|
+
const beginIndexQuery = performance.now();
|
|
4345
|
+
invariant11(this._indexer2, "SQL indexer is required.", {
|
|
4346
|
+
F: __dxlog_file13,
|
|
4347
|
+
L: 492,
|
|
4348
|
+
S: this,
|
|
4349
|
+
A: [
|
|
4350
|
+
"this._indexer2",
|
|
4351
|
+
"'SQL indexer is required.'"
|
|
4352
|
+
]
|
|
4353
|
+
});
|
|
4354
|
+
invariant11(step.spaces.length <= 1, "Multiple spaces are not supported for full-text search", {
|
|
4355
|
+
F: __dxlog_file13,
|
|
4356
|
+
L: 493,
|
|
4357
|
+
S: this,
|
|
4358
|
+
A: [
|
|
4359
|
+
"step.spaces.length <= 1",
|
|
4360
|
+
"'Multiple spaces are not supported for full-text search'"
|
|
4361
|
+
]
|
|
4362
|
+
});
|
|
4363
|
+
const queueIds = step.queues.length > 0 ? step.queues.map((dxnStr) => DXN.parse(dxnStr).asQueueDXN()?.queueId).filter(Boolean) : null;
|
|
4364
|
+
const textResults = await this._runInRuntime(this._indexer2.queryText({
|
|
3707
4365
|
query: step.selector.text,
|
|
3708
|
-
|
|
4366
|
+
spaceId: step.spaces,
|
|
4367
|
+
includeAllQueues: step.allQueuesFromSpaces,
|
|
4368
|
+
queueIds
|
|
4369
|
+
}));
|
|
4370
|
+
trace6.indexHits = textResults.length;
|
|
4371
|
+
trace6.indexQueryTime += performance.now() - beginIndexQuery;
|
|
4372
|
+
if (this._ctx.disposed) {
|
|
4373
|
+
return {
|
|
4374
|
+
workingSet,
|
|
4375
|
+
trace: trace6
|
|
4376
|
+
};
|
|
3709
4377
|
}
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
4378
|
+
const documentLoadStart = performance.now();
|
|
4379
|
+
const queueResults = textResults.filter((r) => r.queueId);
|
|
4380
|
+
const spaceResults = textResults.filter((r) => !r.queueId);
|
|
4381
|
+
const rankMap = new Map(textResults.map((r) => [
|
|
4382
|
+
r.recordId,
|
|
4383
|
+
r.rank
|
|
4384
|
+
]));
|
|
4385
|
+
let queueItems = [];
|
|
4386
|
+
if (queueResults.length > 0) {
|
|
4387
|
+
const snapshots = await this._runInRuntime(this._indexer2.querySnapshotsJSON(queueResults.map((r) => r.recordId)));
|
|
4388
|
+
const snapshotMap = new Map(snapshots.map((s) => [
|
|
4389
|
+
s.recordId,
|
|
4390
|
+
s.snapshot
|
|
4391
|
+
]));
|
|
4392
|
+
queueItems = queueResults.map((result) => {
|
|
4393
|
+
const snapshot = snapshotMap.get(result.recordId);
|
|
4394
|
+
if (!snapshot || typeof snapshot !== "object") {
|
|
4395
|
+
return null;
|
|
4396
|
+
}
|
|
4397
|
+
return {
|
|
4398
|
+
objectId: result.objectId,
|
|
4399
|
+
spaceId: result.spaceId,
|
|
4400
|
+
queueId: result.queueId,
|
|
4401
|
+
queueNamespace: "data",
|
|
4402
|
+
documentId: null,
|
|
4403
|
+
doc: null,
|
|
4404
|
+
data: snapshot,
|
|
4405
|
+
rank: rankMap.get(result.recordId) ?? 1
|
|
4406
|
+
};
|
|
4407
|
+
}).filter(isNonNullable3);
|
|
4408
|
+
}
|
|
4409
|
+
const spaceItems = await Promise.all(spaceResults.map(async (result) => {
|
|
4410
|
+
const dxn = DXN.fromLocalObjectId(result.objectId);
|
|
4411
|
+
const item = await this._loadFromDXN(dxn, {
|
|
4412
|
+
sourceSpaceId: result.spaceId
|
|
4413
|
+
});
|
|
4414
|
+
if (item) {
|
|
4415
|
+
item.rank = rankMap.get(result.recordId) ?? 1;
|
|
4416
|
+
}
|
|
4417
|
+
return item;
|
|
4418
|
+
}));
|
|
4419
|
+
const items = [
|
|
4420
|
+
...queueItems,
|
|
4421
|
+
...spaceItems.filter(isNonNullable3)
|
|
4422
|
+
];
|
|
4423
|
+
trace6.documentsLoaded += items.length;
|
|
4424
|
+
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
4425
|
+
workingSet.push(...items.filter((item) => step.spaces.includes(item.spaceId)));
|
|
4426
|
+
trace6.objectCount = workingSet.length;
|
|
4427
|
+
} else {
|
|
4428
|
+
const beginIndexQuery = performance.now();
|
|
4429
|
+
const indexHits = await this._indexer.execQuery({
|
|
4430
|
+
typenames: [],
|
|
4431
|
+
text: {
|
|
4432
|
+
query: step.selector.text,
|
|
4433
|
+
kind: Match.type().pipe(Match.withReturnType(), Match.when("full-text", () => "text"), Match.when("vector", () => "vector"), Match.orElseAbsurd)(step.selector.searchKind)
|
|
4434
|
+
}
|
|
4435
|
+
});
|
|
4436
|
+
trace6.indexHits = +indexHits.length;
|
|
4437
|
+
trace6.indexQueryTime += performance.now() - beginIndexQuery;
|
|
4438
|
+
if (this._ctx.disposed) {
|
|
4439
|
+
return {
|
|
4440
|
+
workingSet,
|
|
4441
|
+
trace: trace6
|
|
4442
|
+
};
|
|
4443
|
+
}
|
|
4444
|
+
const documentLoadStart = performance.now();
|
|
4445
|
+
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
4446
|
+
trace6.documentsLoaded += results.length;
|
|
4447
|
+
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
4448
|
+
workingSet.push(...results.filter(isNonNullable3).filter((item) => step.spaces.includes(item.spaceId)));
|
|
4449
|
+
trace6.objectCount = workingSet.length;
|
|
3718
4450
|
}
|
|
3719
|
-
const documentLoadStart = performance.now();
|
|
3720
|
-
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
3721
|
-
trace6.documentsLoaded += results.length;
|
|
3722
|
-
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
3723
|
-
workingSet.push(...results.filter(isNonNullable3).filter((item) => step.spaces.includes(item.spaceId)));
|
|
3724
|
-
trace6.objectCount = workingSet.length;
|
|
3725
4451
|
break;
|
|
3726
4452
|
}
|
|
3727
4453
|
default:
|
|
3728
4454
|
throw new Error(`Unknown selector type: ${step.selector._tag}`);
|
|
3729
4455
|
}
|
|
4456
|
+
if (step.limit !== void 0 && workingSet.length > step.limit) {
|
|
4457
|
+
workingSet = workingSet.slice(0, step.limit);
|
|
4458
|
+
trace6.objectCount = workingSet.length;
|
|
4459
|
+
}
|
|
3730
4460
|
return {
|
|
3731
4461
|
workingSet,
|
|
3732
4462
|
trace: trace6
|
|
3733
4463
|
};
|
|
3734
4464
|
}
|
|
3735
4465
|
async _execFilterStep(step, workingSet) {
|
|
3736
|
-
const result = workingSet.filter((item) =>
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
4466
|
+
const result = workingSet.filter((item) => {
|
|
4467
|
+
if (item.doc) {
|
|
4468
|
+
return filterMatchObject(step.filter, {
|
|
4469
|
+
id: item.objectId,
|
|
4470
|
+
spaceId: item.spaceId,
|
|
4471
|
+
doc: item.doc
|
|
4472
|
+
});
|
|
4473
|
+
} else if (item.data) {
|
|
4474
|
+
return filterMatchObjectJSON(step.filter, item.data);
|
|
4475
|
+
} else {
|
|
4476
|
+
return false;
|
|
4477
|
+
}
|
|
4478
|
+
});
|
|
3741
4479
|
return {
|
|
3742
4480
|
workingSet: result,
|
|
3743
4481
|
trace: {
|
|
@@ -3750,7 +4488,7 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3750
4488
|
}
|
|
3751
4489
|
async _execFilterDeletedStep(step, workingSet) {
|
|
3752
4490
|
const expected = step.mode === "only-deleted";
|
|
3753
|
-
const result = workingSet.filter((item) =>
|
|
4491
|
+
const result = workingSet.filter((item) => QueryItem.isDeleted(item) === expected);
|
|
3754
4492
|
return {
|
|
3755
4493
|
workingSet: result,
|
|
3756
4494
|
trace: {
|
|
@@ -3773,9 +4511,18 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3773
4511
|
case "ReferenceTraversal": {
|
|
3774
4512
|
switch (step.traversal.direction) {
|
|
3775
4513
|
case "outgoing": {
|
|
4514
|
+
invariant11(step.traversal.property !== null, "Outgoing reference traversal requires a property", {
|
|
4515
|
+
F: __dxlog_file13,
|
|
4516
|
+
L: 674,
|
|
4517
|
+
S: this,
|
|
4518
|
+
A: [
|
|
4519
|
+
"step.traversal.property !== null",
|
|
4520
|
+
"'Outgoing reference traversal requires a property'"
|
|
4521
|
+
]
|
|
4522
|
+
});
|
|
3776
4523
|
const property = EscapedPropPath.unescape(step.traversal.property);
|
|
3777
4524
|
const refs = workingSet.flatMap((item) => {
|
|
3778
|
-
const ref =
|
|
4525
|
+
const ref = QueryItem.getProperty(item, property);
|
|
3779
4526
|
const refs2 = Array.isArray(ref) ? ref : [
|
|
3780
4527
|
ref
|
|
3781
4528
|
];
|
|
@@ -3786,11 +4533,11 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3786
4533
|
spaceId: item.spaceId
|
|
3787
4534
|
} : null;
|
|
3788
4535
|
} catch {
|
|
3789
|
-
|
|
4536
|
+
log10.warn("invalid reference", {
|
|
3790
4537
|
ref: ref2["/"]
|
|
3791
4538
|
}, {
|
|
3792
|
-
F:
|
|
3793
|
-
L:
|
|
4539
|
+
F: __dxlog_file13,
|
|
4540
|
+
L: 690,
|
|
3794
4541
|
S: this,
|
|
3795
4542
|
C: (f, a) => f(...a)
|
|
3796
4543
|
});
|
|
@@ -3808,22 +4555,35 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3808
4555
|
break;
|
|
3809
4556
|
}
|
|
3810
4557
|
case "incoming": {
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
4558
|
+
if (this._supportsSqlIndexing()) {
|
|
4559
|
+
const beginIndexQuery = performance.now();
|
|
4560
|
+
const metas = await this._queryIncomingReferencesFromSqlIndex(workingSet, step.traversal.property);
|
|
4561
|
+
trace6.indexHits += metas.length;
|
|
4562
|
+
trace6.indexQueryTime += performance.now() - beginIndexQuery;
|
|
4563
|
+
const documentLoadStart = performance.now();
|
|
4564
|
+
const results = await this._loadDocumentsAfterSqlQuery(metas);
|
|
4565
|
+
trace6.documentsLoaded += results.length;
|
|
4566
|
+
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
4567
|
+
newWorkingSet.push(...results.filter(isNonNullable3));
|
|
4568
|
+
trace6.objectCount = newWorkingSet.length;
|
|
4569
|
+
} else {
|
|
4570
|
+
const indexHits = await this._indexer.execQuery({
|
|
4571
|
+
typenames: [],
|
|
4572
|
+
inverted: false,
|
|
4573
|
+
graph: {
|
|
4574
|
+
kind: "inbound-reference",
|
|
4575
|
+
property: step.traversal.property,
|
|
4576
|
+
anchors: workingSet.map((item) => item.objectId)
|
|
4577
|
+
}
|
|
4578
|
+
});
|
|
4579
|
+
trace6.indexHits += indexHits.length;
|
|
4580
|
+
const documentLoadStart = performance.now();
|
|
4581
|
+
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
4582
|
+
trace6.documentsLoaded += results.length;
|
|
4583
|
+
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
4584
|
+
newWorkingSet.push(...results.filter(isNonNullable3));
|
|
4585
|
+
trace6.objectCount = newWorkingSet.length;
|
|
4586
|
+
}
|
|
3827
4587
|
break;
|
|
3828
4588
|
}
|
|
3829
4589
|
}
|
|
@@ -3834,21 +4594,18 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3834
4594
|
case "relation-to-source":
|
|
3835
4595
|
case "relation-to-target": {
|
|
3836
4596
|
const refs = workingSet.map((item) => {
|
|
3837
|
-
const
|
|
3838
|
-
if (!isEncodedReference(ref)) {
|
|
3839
|
-
return null;
|
|
3840
|
-
}
|
|
4597
|
+
const dxn = step.traversal.direction === "relation-to-source" ? QueryItem.getRelationSource(item) : QueryItem.getRelationTarget(item);
|
|
3841
4598
|
try {
|
|
3842
4599
|
return {
|
|
3843
|
-
ref: DXN.parse(
|
|
4600
|
+
ref: DXN.parse(dxn),
|
|
3844
4601
|
spaceId: item.spaceId
|
|
3845
4602
|
};
|
|
3846
4603
|
} catch {
|
|
3847
|
-
|
|
3848
|
-
ref:
|
|
4604
|
+
log10.warn("invalid reference", {
|
|
4605
|
+
ref: dxn
|
|
3849
4606
|
}, {
|
|
3850
|
-
F:
|
|
3851
|
-
L:
|
|
4607
|
+
F: __dxlog_file13,
|
|
4608
|
+
L: 764,
|
|
3852
4609
|
S: this,
|
|
3853
4610
|
C: (f, a) => f(...a)
|
|
3854
4611
|
});
|
|
@@ -3866,22 +4623,35 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3866
4623
|
}
|
|
3867
4624
|
case "source-to-relation":
|
|
3868
4625
|
case "target-to-relation": {
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
4626
|
+
if (this._supportsSqlIndexing()) {
|
|
4627
|
+
const beginIndexQuery = performance.now();
|
|
4628
|
+
const metas = await this._queryRelationsFromSqlIndex(workingSet, step.traversal.direction === "source-to-relation" ? "source" : "target");
|
|
4629
|
+
trace6.indexHits += metas.length;
|
|
4630
|
+
trace6.indexQueryTime += performance.now() - beginIndexQuery;
|
|
4631
|
+
const documentLoadStart = performance.now();
|
|
4632
|
+
const results = await this._loadDocumentsAfterSqlQuery(metas);
|
|
4633
|
+
trace6.documentsLoaded += results.length;
|
|
4634
|
+
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
4635
|
+
newWorkingSet.push(...results.filter(isNonNullable3));
|
|
4636
|
+
trace6.objectCount = newWorkingSet.length;
|
|
4637
|
+
} else {
|
|
4638
|
+
const indexHits = await this._indexer.execQuery({
|
|
4639
|
+
typenames: [],
|
|
4640
|
+
inverted: false,
|
|
4641
|
+
graph: {
|
|
4642
|
+
kind: step.traversal.direction === "source-to-relation" ? "relation-source" : "relation-target",
|
|
4643
|
+
anchors: workingSet.map((item) => item.objectId),
|
|
4644
|
+
property: null
|
|
4645
|
+
}
|
|
4646
|
+
});
|
|
4647
|
+
trace6.indexHits += indexHits.length;
|
|
4648
|
+
const documentLoadStart = performance.now();
|
|
4649
|
+
const results = await this._loadDocumentsAfterIndexQuery(indexHits);
|
|
4650
|
+
trace6.documentsLoaded += results.length;
|
|
4651
|
+
trace6.documentLoadTime += performance.now() - documentLoadStart;
|
|
4652
|
+
newWorkingSet.push(...results.filter(isNonNullable3));
|
|
4653
|
+
trace6.objectCount = newWorkingSet.length;
|
|
4654
|
+
}
|
|
3885
4655
|
break;
|
|
3886
4656
|
}
|
|
3887
4657
|
}
|
|
@@ -3938,19 +4708,39 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3938
4708
|
};
|
|
3939
4709
|
}
|
|
3940
4710
|
async _execOrderStep(step, workingSet) {
|
|
3941
|
-
|
|
4711
|
+
let sortedWorkingSet = [
|
|
3942
4712
|
...workingSet
|
|
3943
4713
|
].sort((a, b) => this._compareMultiOrder(a, b, step.order));
|
|
4714
|
+
if (step.limit !== void 0 && sortedWorkingSet.length > step.limit) {
|
|
4715
|
+
sortedWorkingSet = sortedWorkingSet.slice(0, step.limit);
|
|
4716
|
+
}
|
|
3944
4717
|
return {
|
|
3945
4718
|
workingSet: sortedWorkingSet,
|
|
3946
4719
|
trace: {
|
|
3947
4720
|
...ExecutionTrace.makeEmpty(),
|
|
3948
4721
|
name: "Order",
|
|
3949
|
-
details: JSON.stringify(
|
|
4722
|
+
details: JSON.stringify({
|
|
4723
|
+
order: step.order,
|
|
4724
|
+
limit: step.limit
|
|
4725
|
+
}),
|
|
3950
4726
|
objectCount: sortedWorkingSet.length
|
|
3951
4727
|
}
|
|
3952
4728
|
};
|
|
3953
4729
|
}
|
|
4730
|
+
async _execLimitStep(step, workingSet) {
|
|
4731
|
+
const limitedWorkingSet = workingSet.slice(0, step.limit);
|
|
4732
|
+
return {
|
|
4733
|
+
workingSet: limitedWorkingSet,
|
|
4734
|
+
trace: {
|
|
4735
|
+
...ExecutionTrace.makeEmpty(),
|
|
4736
|
+
name: "Limit",
|
|
4737
|
+
details: JSON.stringify({
|
|
4738
|
+
limit: step.limit
|
|
4739
|
+
}),
|
|
4740
|
+
objectCount: limitedWorkingSet.length
|
|
4741
|
+
}
|
|
4742
|
+
};
|
|
4743
|
+
}
|
|
3954
4744
|
_compareMultiOrder(a, b, orders) {
|
|
3955
4745
|
if (orders.length === 0) {
|
|
3956
4746
|
return 0;
|
|
@@ -3973,13 +4763,21 @@ var QueryExecutor = class extends Resource6 {
|
|
|
3973
4763
|
const comparison = this._compareByProperty(a, b, order.property);
|
|
3974
4764
|
return order.direction === "desc" ? -comparison : comparison;
|
|
3975
4765
|
}
|
|
4766
|
+
case "rank": {
|
|
4767
|
+
const comparison = a.rank - b.rank;
|
|
4768
|
+
return order.direction === "desc" ? -comparison : comparison;
|
|
4769
|
+
}
|
|
3976
4770
|
default:
|
|
3977
4771
|
return 0;
|
|
3978
4772
|
}
|
|
3979
4773
|
}
|
|
3980
4774
|
_compareByProperty(a, b, property) {
|
|
3981
|
-
const aValue = a
|
|
3982
|
-
|
|
4775
|
+
const aValue = QueryItem.getProperty(a, [
|
|
4776
|
+
property
|
|
4777
|
+
]);
|
|
4778
|
+
const bValue = QueryItem.getProperty(b, [
|
|
4779
|
+
property
|
|
4780
|
+
]);
|
|
3983
4781
|
if (aValue == null && bValue == null) {
|
|
3984
4782
|
return 0;
|
|
3985
4783
|
}
|
|
@@ -4005,30 +4803,242 @@ var QueryExecutor = class extends Resource6 {
|
|
|
4005
4803
|
return this._loadFromIndexHit(hit);
|
|
4006
4804
|
}));
|
|
4007
4805
|
}
|
|
4806
|
+
_supportsSqlIndexing() {
|
|
4807
|
+
return !!this._indexer2 && !!this._runtime;
|
|
4808
|
+
}
|
|
4809
|
+
async _runInRuntime(effect) {
|
|
4810
|
+
const runtimeProvider = this._runtime;
|
|
4811
|
+
invariant11(runtimeProvider, "SQL runtime is required.", {
|
|
4812
|
+
F: __dxlog_file13,
|
|
4813
|
+
L: 1002,
|
|
4814
|
+
S: this,
|
|
4815
|
+
A: [
|
|
4816
|
+
"runtimeProvider",
|
|
4817
|
+
"'SQL runtime is required.'"
|
|
4818
|
+
]
|
|
4819
|
+
});
|
|
4820
|
+
const runtime = await runAndForwardErrors(runtimeProvider);
|
|
4821
|
+
return await unwrapExit(await effect.pipe(Runtime.runPromiseExit(runtime)));
|
|
4822
|
+
}
|
|
4823
|
+
async _queryAllFromSqlIndex(spaceIds) {
|
|
4824
|
+
invariant11(this._indexer2, "SQL indexer is required.", {
|
|
4825
|
+
F: __dxlog_file13,
|
|
4826
|
+
L: 1008,
|
|
4827
|
+
S: this,
|
|
4828
|
+
A: [
|
|
4829
|
+
"this._indexer2",
|
|
4830
|
+
"'SQL indexer is required.'"
|
|
4831
|
+
]
|
|
4832
|
+
});
|
|
4833
|
+
return await this._runInRuntime(this._indexer2.queryAll({
|
|
4834
|
+
spaceIds
|
|
4835
|
+
}));
|
|
4836
|
+
}
|
|
4837
|
+
async _queryTypesFromSqlIndex(spaceIds, typeDxns, inverted) {
|
|
4838
|
+
invariant11(this._indexer2, "SQL indexer is required.", {
|
|
4839
|
+
F: __dxlog_file13,
|
|
4840
|
+
L: 1017,
|
|
4841
|
+
S: this,
|
|
4842
|
+
A: [
|
|
4843
|
+
"this._indexer2",
|
|
4844
|
+
"'SQL indexer is required.'"
|
|
4845
|
+
]
|
|
4846
|
+
});
|
|
4847
|
+
return await this._runInRuntime(this._indexer2.queryTypes({
|
|
4848
|
+
spaceIds,
|
|
4849
|
+
typeDxns,
|
|
4850
|
+
inverted
|
|
4851
|
+
}));
|
|
4852
|
+
}
|
|
4853
|
+
async _queryIncomingReferencesFromSqlIndex(workingSet, property) {
|
|
4854
|
+
const anchorDxns = workingSet.map((item) => DXN.fromLocalObjectId(item.objectId).toString());
|
|
4855
|
+
invariant11(this._indexer2, "SQL indexer is required.", {
|
|
4856
|
+
F: __dxlog_file13,
|
|
4857
|
+
L: 1026,
|
|
4858
|
+
S: this,
|
|
4859
|
+
A: [
|
|
4860
|
+
"this._indexer2",
|
|
4861
|
+
"'SQL indexer is required.'"
|
|
4862
|
+
]
|
|
4863
|
+
});
|
|
4864
|
+
const rows = (await Promise.all(anchorDxns.map((targetDxn) => this._runInRuntime(this._indexer2.queryReverseRef({
|
|
4865
|
+
targetDxn
|
|
4866
|
+
}))))).flat();
|
|
4867
|
+
const recordIds = rows.filter((row) => {
|
|
4868
|
+
if (property === null) {
|
|
4869
|
+
return true;
|
|
4870
|
+
}
|
|
4871
|
+
const queryPath = EscapedPropPath.unescape(property);
|
|
4872
|
+
const rowPath = EscapedPropPath.unescape(row.propPath);
|
|
4873
|
+
return _QueryExecutor._matchesReferencePropertyPath(rowPath, queryPath);
|
|
4874
|
+
}).map((row) => row.recordId);
|
|
4875
|
+
const uniqueRecordIds = Array.from(new Set(recordIds));
|
|
4876
|
+
return await this._runInRuntime(this._indexer2.lookupByRecordIds(uniqueRecordIds));
|
|
4877
|
+
}
|
|
4878
|
+
/**
|
|
4879
|
+
* Matches a reverse-reference row path against a query property path.
|
|
4880
|
+
* Allows numeric segments in the row path (array indices) that are not present in the query.
|
|
4881
|
+
*
|
|
4882
|
+
* Examples:
|
|
4883
|
+
* - query: ['assignee'] matches row: ['assignee'] and ['assignee', '0'].
|
|
4884
|
+
* - query: ['items', 'assignee'] matches row: ['items', '0', 'assignee'].
|
|
4885
|
+
* - query: ['a', 'b'] does NOT match row: ['a'].
|
|
4886
|
+
* - query: ['a'] does NOT match row: ['a', 'b'].
|
|
4887
|
+
*/
|
|
4888
|
+
static _matchesReferencePropertyPath(rowPath, queryPath) {
|
|
4889
|
+
const isNumericSegment = (segment) => /^[0-9]+$/.test(segment);
|
|
4890
|
+
let i = 0;
|
|
4891
|
+
let j = 0;
|
|
4892
|
+
while (i < queryPath.length && j < rowPath.length) {
|
|
4893
|
+
if (rowPath[j] === queryPath[i]) {
|
|
4894
|
+
i++;
|
|
4895
|
+
j++;
|
|
4896
|
+
continue;
|
|
4897
|
+
}
|
|
4898
|
+
if (isNumericSegment(rowPath[j])) {
|
|
4899
|
+
j++;
|
|
4900
|
+
continue;
|
|
4901
|
+
}
|
|
4902
|
+
return false;
|
|
4903
|
+
}
|
|
4904
|
+
if (i !== queryPath.length) {
|
|
4905
|
+
return false;
|
|
4906
|
+
}
|
|
4907
|
+
for (; j < rowPath.length; j++) {
|
|
4908
|
+
if (!isNumericSegment(rowPath[j])) {
|
|
4909
|
+
return false;
|
|
4910
|
+
}
|
|
4911
|
+
}
|
|
4912
|
+
return true;
|
|
4913
|
+
}
|
|
4914
|
+
async _queryRelationsFromSqlIndex(workingSet, endpoint) {
|
|
4915
|
+
invariant11(this._indexer2, "SQL indexer is required.", {
|
|
4916
|
+
F: __dxlog_file13,
|
|
4917
|
+
L: 1100,
|
|
4918
|
+
S: this,
|
|
4919
|
+
A: [
|
|
4920
|
+
"this._indexer2",
|
|
4921
|
+
"'SQL indexer is required.'"
|
|
4922
|
+
]
|
|
4923
|
+
});
|
|
4924
|
+
const anchorDxns = workingSet.map((item) => DXN.fromLocalObjectId(item.objectId).toString());
|
|
4925
|
+
return await this._runInRuntime(this._indexer2.queryRelations({
|
|
4926
|
+
endpoint,
|
|
4927
|
+
anchorDxns
|
|
4928
|
+
}));
|
|
4929
|
+
}
|
|
4930
|
+
async _loadDocumentsAfterSqlQuery(metas) {
|
|
4931
|
+
const snapshotMap = await this._loadQueueSnapshotMap(metas);
|
|
4932
|
+
return await Promise.all(metas.map(async (meta) => {
|
|
4933
|
+
if (meta.documentId) {
|
|
4934
|
+
return this._loadFromAutomerge(meta);
|
|
4935
|
+
}
|
|
4936
|
+
if (meta.queueId) {
|
|
4937
|
+
return this._loadFromQueue(meta, snapshotMap);
|
|
4938
|
+
}
|
|
4939
|
+
return null;
|
|
4940
|
+
}));
|
|
4941
|
+
}
|
|
4942
|
+
async _loadQueueSnapshotMap(metas) {
|
|
4943
|
+
const queueMetas = metas.filter((meta) => !meta.documentId && !!meta.queueId);
|
|
4944
|
+
if (queueMetas.length === 0) {
|
|
4945
|
+
return /* @__PURE__ */ new Map();
|
|
4946
|
+
}
|
|
4947
|
+
invariant11(this._indexer2, "SQL indexer is required.", {
|
|
4948
|
+
F: __dxlog_file13,
|
|
4949
|
+
L: 1130,
|
|
4950
|
+
S: this,
|
|
4951
|
+
A: [
|
|
4952
|
+
"this._indexer2",
|
|
4953
|
+
"'SQL indexer is required.'"
|
|
4954
|
+
]
|
|
4955
|
+
});
|
|
4956
|
+
const snapshots = await this._runInRuntime(this._indexer2.querySnapshotsJSON(queueMetas.map((meta) => meta.recordId)));
|
|
4957
|
+
return new Map(snapshots.map((s) => [
|
|
4958
|
+
s.recordId,
|
|
4959
|
+
s.snapshot
|
|
4960
|
+
]));
|
|
4961
|
+
}
|
|
4962
|
+
/**
|
|
4963
|
+
* Loads a queue-backed object from an indexed snapshot (by `recordId`).
|
|
4964
|
+
* Returns `null` when the snapshot is missing or is not a JSON object.
|
|
4965
|
+
*/
|
|
4966
|
+
_loadFromQueue(meta, snapshotMap) {
|
|
4967
|
+
const snapshot = snapshotMap.get(meta.recordId);
|
|
4968
|
+
if (!snapshot || typeof snapshot !== "object") {
|
|
4969
|
+
return null;
|
|
4970
|
+
}
|
|
4971
|
+
return {
|
|
4972
|
+
objectId: meta.objectId,
|
|
4973
|
+
spaceId: meta.spaceId,
|
|
4974
|
+
queueId: meta.queueId,
|
|
4975
|
+
queueNamespace: "data",
|
|
4976
|
+
documentId: null,
|
|
4977
|
+
doc: null,
|
|
4978
|
+
data: snapshot,
|
|
4979
|
+
rank: 1
|
|
4980
|
+
};
|
|
4981
|
+
}
|
|
4982
|
+
/**
|
|
4983
|
+
* Loads a document-backed object from an Automerge `DatabaseDirectory`.
|
|
4984
|
+
* Returns `null` if the document can't be loaded, the inline object isn't present, or if the meta does not have a
|
|
4985
|
+
* document id (e.g. queue-backed objects).
|
|
4986
|
+
*/
|
|
4987
|
+
async _loadFromAutomerge(meta) {
|
|
4988
|
+
if (!meta.documentId) {
|
|
4989
|
+
return null;
|
|
4990
|
+
}
|
|
4991
|
+
const handle = await this._automergeHost.loadDoc(Context5.default(void 0, {
|
|
4992
|
+
F: __dxlog_file13,
|
|
4993
|
+
L: 1169
|
|
4994
|
+
}), meta.documentId, {
|
|
4995
|
+
fetchFromNetwork: true
|
|
4996
|
+
});
|
|
4997
|
+
const doc = handle.doc();
|
|
4998
|
+
if (!doc) {
|
|
4999
|
+
return null;
|
|
5000
|
+
}
|
|
5001
|
+
const object = DatabaseDirectory4.getInlineObject(doc, meta.objectId);
|
|
5002
|
+
if (!object) {
|
|
5003
|
+
return null;
|
|
5004
|
+
}
|
|
5005
|
+
return {
|
|
5006
|
+
objectId: meta.objectId,
|
|
5007
|
+
documentId: meta.documentId,
|
|
5008
|
+
spaceId: meta.spaceId,
|
|
5009
|
+
queueId: null,
|
|
5010
|
+
queueNamespace: null,
|
|
5011
|
+
doc: object,
|
|
5012
|
+
data: null,
|
|
5013
|
+
rank: 1
|
|
5014
|
+
};
|
|
5015
|
+
}
|
|
4008
5016
|
/**
|
|
4009
5017
|
* Space key hex -> SpaceId.
|
|
4010
5018
|
*/
|
|
4011
5019
|
_spaceIdCache = /* @__PURE__ */ new Map();
|
|
4012
5020
|
async _loadFromIndexHit(hit) {
|
|
4013
5021
|
const { objectId, documentId, spaceKey: spaceKeyInIndex } = objectPointerCodec3.decode(hit.id);
|
|
4014
|
-
const handle = await this._automergeHost.loadDoc(
|
|
4015
|
-
F:
|
|
4016
|
-
L:
|
|
4017
|
-
}), documentId
|
|
5022
|
+
const handle = await this._automergeHost.loadDoc(Context5.default(void 0, {
|
|
5023
|
+
F: __dxlog_file13,
|
|
5024
|
+
L: 1203
|
|
5025
|
+
}), documentId, {
|
|
5026
|
+
fetchFromNetwork: true
|
|
5027
|
+
});
|
|
4018
5028
|
const doc = handle.doc();
|
|
4019
5029
|
if (!doc) {
|
|
4020
5030
|
return null;
|
|
4021
5031
|
}
|
|
4022
|
-
const spaceKey = spaceKeyInIndex ??
|
|
5032
|
+
const spaceKey = spaceKeyInIndex ?? DatabaseDirectory4.getSpaceKey(doc);
|
|
4023
5033
|
if (!spaceKey) {
|
|
4024
5034
|
return null;
|
|
4025
5035
|
}
|
|
4026
5036
|
let spaceId = this._spaceIdCache.get(spaceKey);
|
|
4027
5037
|
if (!spaceId) {
|
|
4028
|
-
spaceId = await createIdFromSpaceKey(
|
|
5038
|
+
spaceId = await createIdFromSpaceKey(PublicKey4.from(spaceKey));
|
|
4029
5039
|
this._spaceIdCache.set(spaceKey, spaceId);
|
|
4030
5040
|
}
|
|
4031
|
-
const object =
|
|
5041
|
+
const object = DatabaseDirectory4.getInlineObject(doc, objectId);
|
|
4032
5042
|
if (!object) {
|
|
4033
5043
|
return null;
|
|
4034
5044
|
}
|
|
@@ -4036,17 +5046,21 @@ var QueryExecutor = class extends Resource6 {
|
|
|
4036
5046
|
objectId,
|
|
4037
5047
|
documentId,
|
|
4038
5048
|
spaceId,
|
|
4039
|
-
|
|
5049
|
+
queueId: null,
|
|
5050
|
+
queueNamespace: null,
|
|
5051
|
+
data: null,
|
|
5052
|
+
doc: object,
|
|
5053
|
+
rank: hit.rank
|
|
4040
5054
|
};
|
|
4041
5055
|
}
|
|
4042
5056
|
async _loadFromDXN(dxn, { sourceSpaceId }) {
|
|
4043
5057
|
const echoDxn = dxn.asEchoDXN();
|
|
4044
5058
|
if (!echoDxn) {
|
|
4045
|
-
|
|
5059
|
+
log10.warn("unable to resolve DXN", {
|
|
4046
5060
|
dxn
|
|
4047
5061
|
}, {
|
|
4048
|
-
F:
|
|
4049
|
-
L:
|
|
5062
|
+
F: __dxlog_file13,
|
|
5063
|
+
L: 1242,
|
|
4050
5064
|
S: this,
|
|
4051
5065
|
C: (f, a) => f(...a)
|
|
4052
5066
|
});
|
|
@@ -4055,11 +5069,11 @@ var QueryExecutor = class extends Resource6 {
|
|
|
4055
5069
|
const spaceId = echoDxn.spaceId ?? sourceSpaceId;
|
|
4056
5070
|
const spaceRoot = this._spaceStateManager.getRootBySpaceId(spaceId);
|
|
4057
5071
|
if (!spaceRoot) {
|
|
4058
|
-
|
|
5072
|
+
log10.warn("no space state found for", {
|
|
4059
5073
|
spaceId
|
|
4060
5074
|
}, {
|
|
4061
|
-
F:
|
|
4062
|
-
L:
|
|
5075
|
+
F: __dxlog_file13,
|
|
5076
|
+
L: 1250,
|
|
4063
5077
|
S: this,
|
|
4064
5078
|
C: (f, a) => f(...a)
|
|
4065
5079
|
});
|
|
@@ -4067,38 +5081,44 @@ var QueryExecutor = class extends Resource6 {
|
|
|
4067
5081
|
}
|
|
4068
5082
|
const dbDirectory = spaceRoot.doc();
|
|
4069
5083
|
if (!dbDirectory) {
|
|
4070
|
-
|
|
5084
|
+
log10.warn("no space state found for", {
|
|
4071
5085
|
spaceId
|
|
4072
5086
|
}, {
|
|
4073
|
-
F:
|
|
4074
|
-
L:
|
|
5087
|
+
F: __dxlog_file13,
|
|
5088
|
+
L: 1255,
|
|
4075
5089
|
S: this,
|
|
4076
5090
|
C: (f, a) => f(...a)
|
|
4077
5091
|
});
|
|
4078
5092
|
return null;
|
|
4079
5093
|
}
|
|
4080
|
-
const inlineObject =
|
|
5094
|
+
const inlineObject = DatabaseDirectory4.getInlineObject(dbDirectory, echoDxn.echoId);
|
|
4081
5095
|
if (inlineObject) {
|
|
4082
5096
|
return {
|
|
4083
5097
|
objectId: echoDxn.echoId,
|
|
4084
5098
|
documentId: spaceRoot.documentId,
|
|
4085
5099
|
spaceId,
|
|
4086
|
-
|
|
5100
|
+
queueId: null,
|
|
5101
|
+
queueNamespace: null,
|
|
5102
|
+
data: null,
|
|
5103
|
+
doc: inlineObject,
|
|
5104
|
+
rank: 1
|
|
4087
5105
|
};
|
|
4088
5106
|
}
|
|
4089
|
-
const link =
|
|
5107
|
+
const link = DatabaseDirectory4.getLink(dbDirectory, echoDxn.echoId);
|
|
4090
5108
|
if (!link) {
|
|
4091
5109
|
return null;
|
|
4092
5110
|
}
|
|
4093
|
-
const handle = await this._automergeHost.loadDoc(
|
|
4094
|
-
F:
|
|
4095
|
-
L:
|
|
4096
|
-
}), link
|
|
5111
|
+
const handle = await this._automergeHost.loadDoc(Context5.default(void 0, {
|
|
5112
|
+
F: __dxlog_file13,
|
|
5113
|
+
L: 1278
|
|
5114
|
+
}), link, {
|
|
5115
|
+
fetchFromNetwork: true
|
|
5116
|
+
});
|
|
4097
5117
|
const doc = handle.doc();
|
|
4098
5118
|
if (!doc) {
|
|
4099
5119
|
return null;
|
|
4100
5120
|
}
|
|
4101
|
-
const object =
|
|
5121
|
+
const object = DatabaseDirectory4.getInlineObject(doc, echoDxn.echoId);
|
|
4102
5122
|
if (!object) {
|
|
4103
5123
|
return null;
|
|
4104
5124
|
}
|
|
@@ -4106,7 +5126,11 @@ var QueryExecutor = class extends Resource6 {
|
|
|
4106
5126
|
objectId: echoDxn.echoId,
|
|
4107
5127
|
documentId: handle.documentId,
|
|
4108
5128
|
spaceId,
|
|
4109
|
-
|
|
5129
|
+
queueId: null,
|
|
5130
|
+
queueNamespace: null,
|
|
5131
|
+
data: null,
|
|
5132
|
+
doc: object,
|
|
5133
|
+
rank: 1
|
|
4110
5134
|
};
|
|
4111
5135
|
}
|
|
4112
5136
|
};
|
|
@@ -4118,7 +5142,7 @@ function _ts_decorate5(decorators, target, key, desc) {
|
|
|
4118
5142
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
4119
5143
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4120
5144
|
}
|
|
4121
|
-
var
|
|
5145
|
+
var __dxlog_file14 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/query-service.ts";
|
|
4122
5146
|
var QueryServiceImpl = class extends Resource7 {
|
|
4123
5147
|
_params;
|
|
4124
5148
|
// TODO(dmaretskyi): We need to implement query deduping. Idle composer has 80 queries with only 10 being unique.
|
|
@@ -4155,11 +5179,11 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
4155
5179
|
execQuery(request) {
|
|
4156
5180
|
return new Stream2(({ next, close, ctx }) => {
|
|
4157
5181
|
if (this._params.indexer.config?.enabled !== true) {
|
|
4158
|
-
|
|
5182
|
+
log11.error("indexer is disabled", {
|
|
4159
5183
|
config: this._params.indexer.config
|
|
4160
5184
|
}, {
|
|
4161
|
-
F:
|
|
4162
|
-
L:
|
|
5185
|
+
F: __dxlog_file14,
|
|
5186
|
+
L: 107,
|
|
4163
5187
|
S: this,
|
|
4164
5188
|
C: (f, a) => f(...a)
|
|
4165
5189
|
});
|
|
@@ -4179,9 +5203,9 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
4179
5203
|
* Re-index all loaded documents.
|
|
4180
5204
|
*/
|
|
4181
5205
|
async reindex() {
|
|
4182
|
-
|
|
4183
|
-
F:
|
|
4184
|
-
L:
|
|
5206
|
+
log11("Reindexing all documents...", void 0, {
|
|
5207
|
+
F: __dxlog_file14,
|
|
5208
|
+
L: 126,
|
|
4185
5209
|
S: this,
|
|
4186
5210
|
C: (f, a) => f(...a)
|
|
4187
5211
|
});
|
|
@@ -4192,21 +5216,21 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
4192
5216
|
ids.set(id, heads);
|
|
4193
5217
|
}
|
|
4194
5218
|
if (ids.size % 100 === 0) {
|
|
4195
|
-
|
|
5219
|
+
log11("Collected documents...", {
|
|
4196
5220
|
count: ids.size
|
|
4197
5221
|
}, {
|
|
4198
|
-
F:
|
|
4199
|
-
L:
|
|
5222
|
+
F: __dxlog_file14,
|
|
5223
|
+
L: 134,
|
|
4200
5224
|
S: this,
|
|
4201
5225
|
C: (f, a) => f(...a)
|
|
4202
5226
|
});
|
|
4203
5227
|
}
|
|
4204
5228
|
}
|
|
4205
|
-
|
|
5229
|
+
log11("Marking all documents as dirty...", {
|
|
4206
5230
|
count: ids.size
|
|
4207
5231
|
}, {
|
|
4208
|
-
F:
|
|
4209
|
-
L:
|
|
5232
|
+
F: __dxlog_file14,
|
|
5233
|
+
L: 138,
|
|
4210
5234
|
S: this,
|
|
4211
5235
|
C: (f, a) => f(...a)
|
|
4212
5236
|
});
|
|
@@ -4226,6 +5250,8 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
4226
5250
|
const queryEntry = {
|
|
4227
5251
|
executor: new QueryExecutor({
|
|
4228
5252
|
indexer: this._params.indexer,
|
|
5253
|
+
indexer2: this._params.indexer2,
|
|
5254
|
+
runtime: this._params.runtime,
|
|
4229
5255
|
automergeHost: this._params.automergeHost,
|
|
4230
5256
|
queryId: request.queryId ?? raise(new Error("query id required")),
|
|
4231
5257
|
query: parsedQuery,
|
|
@@ -4270,20 +5296,20 @@ var QueryServiceImpl = class extends Resource7 {
|
|
|
4270
5296
|
query.sendResults(query.executor.getResults());
|
|
4271
5297
|
}
|
|
4272
5298
|
} catch (err) {
|
|
4273
|
-
|
|
4274
|
-
F:
|
|
4275
|
-
L:
|
|
5299
|
+
log11.catch(err, void 0, {
|
|
5300
|
+
F: __dxlog_file14,
|
|
5301
|
+
L: 211,
|
|
4276
5302
|
S: this,
|
|
4277
5303
|
C: (f, a) => f(...a)
|
|
4278
5304
|
});
|
|
4279
5305
|
}
|
|
4280
5306
|
}));
|
|
4281
|
-
|
|
5307
|
+
log11.verbose("executed queries", {
|
|
4282
5308
|
count,
|
|
4283
5309
|
duration: performance.now() - begin
|
|
4284
5310
|
}, {
|
|
4285
|
-
F:
|
|
4286
|
-
L:
|
|
5311
|
+
F: __dxlog_file14,
|
|
5312
|
+
L: 215,
|
|
4287
5313
|
S: this,
|
|
4288
5314
|
C: (f, a) => f(...a)
|
|
4289
5315
|
});
|
|
@@ -4312,7 +5338,7 @@ var createDocumentsIterator = (automergeHost) => (
|
|
|
4312
5338
|
return;
|
|
4313
5339
|
}
|
|
4314
5340
|
const doc = handle.doc();
|
|
4315
|
-
const spaceKey =
|
|
5341
|
+
const spaceKey = DatabaseDirectory5.getSpaceKey(doc) ?? void 0;
|
|
4316
5342
|
if (doc.objects) {
|
|
4317
5343
|
yield Object.entries(doc.objects).map(([objectId, object]) => {
|
|
4318
5344
|
return {
|
|
@@ -4332,10 +5358,12 @@ var createDocumentsIterator = (automergeHost) => (
|
|
|
4332
5358
|
if (visited.has(urlString)) {
|
|
4333
5359
|
continue;
|
|
4334
5360
|
}
|
|
4335
|
-
const linkHandle = await automergeHost.loadDoc(
|
|
4336
|
-
F:
|
|
4337
|
-
L:
|
|
4338
|
-
}), urlString
|
|
5361
|
+
const linkHandle = await automergeHost.loadDoc(Context6.default(void 0, {
|
|
5362
|
+
F: __dxlog_file14,
|
|
5363
|
+
L: 256
|
|
5364
|
+
}), urlString, {
|
|
5365
|
+
fetchFromNetwork: true
|
|
5366
|
+
});
|
|
4339
5367
|
for await (const result of getObjectsFromHandle(linkHandle)) {
|
|
4340
5368
|
yield result;
|
|
4341
5369
|
}
|
|
@@ -4343,7 +5371,7 @@ var createDocumentsIterator = (automergeHost) => (
|
|
|
4343
5371
|
}
|
|
4344
5372
|
visited.add(handle.documentId);
|
|
4345
5373
|
}
|
|
4346
|
-
for (const handle of Object.values(automergeHost.
|
|
5374
|
+
for (const handle of Object.values(automergeHost.handles)) {
|
|
4347
5375
|
if (visited.has(handle.documentId)) {
|
|
4348
5376
|
continue;
|
|
4349
5377
|
}
|
|
@@ -4355,22 +5383,127 @@ var createDocumentsIterator = (automergeHost) => (
|
|
|
4355
5383
|
}
|
|
4356
5384
|
);
|
|
4357
5385
|
|
|
5386
|
+
// src/db-host/queue-data-source.ts
|
|
5387
|
+
import * as Effect3 from "effect/Effect";
|
|
5388
|
+
import { RuntimeProvider as RuntimeProvider2 } from "@dxos/effect";
|
|
5389
|
+
import { FeedCursor } from "@dxos/feed";
|
|
5390
|
+
import { failedInvariant } from "@dxos/invariant";
|
|
5391
|
+
import { log as log12 } from "@dxos/log";
|
|
5392
|
+
var __dxlog_file15 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/queue-data-source.ts";
|
|
5393
|
+
var QueueDataSource = class {
|
|
5394
|
+
sourceName = "queue";
|
|
5395
|
+
_feedStore;
|
|
5396
|
+
_runtime;
|
|
5397
|
+
_getSpaceIds;
|
|
5398
|
+
constructor(options) {
|
|
5399
|
+
this._feedStore = options.feedStore;
|
|
5400
|
+
this._runtime = options.runtime;
|
|
5401
|
+
this._getSpaceIds = options.getSpaceIds;
|
|
5402
|
+
}
|
|
5403
|
+
getChangedObjects(cursors, opts) {
|
|
5404
|
+
return Effect3.gen(this, function* () {
|
|
5405
|
+
const objects = [];
|
|
5406
|
+
const updatedCursors = [];
|
|
5407
|
+
const existingSpaceIds = new Set(cursors.map((c) => c.spaceId).filter(Boolean));
|
|
5408
|
+
const allSpaceIds = this._getSpaceIds();
|
|
5409
|
+
const augmentedCursors = [
|
|
5410
|
+
...cursors
|
|
5411
|
+
];
|
|
5412
|
+
for (const spaceId of allSpaceIds) {
|
|
5413
|
+
if (!existingSpaceIds.has(spaceId)) {
|
|
5414
|
+
augmentedCursors.push({
|
|
5415
|
+
spaceId,
|
|
5416
|
+
resourceId: null,
|
|
5417
|
+
cursor: ""
|
|
5418
|
+
});
|
|
5419
|
+
}
|
|
5420
|
+
}
|
|
5421
|
+
let remainingLimit = opts?.limit ?? Infinity;
|
|
5422
|
+
for (const cursor of augmentedCursors) {
|
|
5423
|
+
if (remainingLimit <= 0) {
|
|
5424
|
+
updatedCursors.push(cursor);
|
|
5425
|
+
continue;
|
|
5426
|
+
}
|
|
5427
|
+
if (!cursor.spaceId) {
|
|
5428
|
+
updatedCursors.push(cursor);
|
|
5429
|
+
continue;
|
|
5430
|
+
}
|
|
5431
|
+
const currentCursor = typeof cursor.cursor === "string" && cursor.cursor !== "" ? FeedCursor.make(cursor.cursor) : void 0;
|
|
5432
|
+
try {
|
|
5433
|
+
const result = yield* this._feedStore.query({
|
|
5434
|
+
spaceId: cursor.spaceId,
|
|
5435
|
+
cursor: currentCursor,
|
|
5436
|
+
query: {
|
|
5437
|
+
// Query all feeds in data namespace
|
|
5438
|
+
feedNamespace: "data"
|
|
5439
|
+
},
|
|
5440
|
+
limit: remainingLimit
|
|
5441
|
+
});
|
|
5442
|
+
for (const block of result.blocks) {
|
|
5443
|
+
try {
|
|
5444
|
+
const dataString = new TextDecoder().decode(block.data);
|
|
5445
|
+
const data = JSON.parse(dataString);
|
|
5446
|
+
objects.push({
|
|
5447
|
+
spaceId: cursor.spaceId,
|
|
5448
|
+
queueId: block.feedId ?? failedInvariant(),
|
|
5449
|
+
documentId: null,
|
|
5450
|
+
recordId: null,
|
|
5451
|
+
data
|
|
5452
|
+
});
|
|
5453
|
+
} catch (err) {
|
|
5454
|
+
log12.warn("Failed to parse block data for indexing", {
|
|
5455
|
+
spaceId: cursor.spaceId,
|
|
5456
|
+
err
|
|
5457
|
+
}, {
|
|
5458
|
+
F: __dxlog_file15,
|
|
5459
|
+
L: 114,
|
|
5460
|
+
S: this,
|
|
5461
|
+
C: (f, a) => f(...a)
|
|
5462
|
+
});
|
|
5463
|
+
}
|
|
5464
|
+
}
|
|
5465
|
+
remainingLimit -= result.blocks.length;
|
|
5466
|
+
updatedCursors.push({
|
|
5467
|
+
spaceId: cursor.spaceId,
|
|
5468
|
+
resourceId: null,
|
|
5469
|
+
cursor: result.nextCursor
|
|
5470
|
+
});
|
|
5471
|
+
} catch (error) {
|
|
5472
|
+
log12.error("Error querying queue for indexing", {
|
|
5473
|
+
spaceId: cursor.spaceId,
|
|
5474
|
+
error
|
|
5475
|
+
}, {
|
|
5476
|
+
F: __dxlog_file15,
|
|
5477
|
+
L: 125,
|
|
5478
|
+
S: this,
|
|
5479
|
+
C: (f, a) => f(...a)
|
|
5480
|
+
});
|
|
5481
|
+
}
|
|
5482
|
+
}
|
|
5483
|
+
return {
|
|
5484
|
+
objects,
|
|
5485
|
+
cursors: updatedCursors
|
|
5486
|
+
};
|
|
5487
|
+
}).pipe(RuntimeProvider2.provide(this._runtime), Effect3.withSpan("QueueDataSource.getChangedObjects"), Effect3.orDie);
|
|
5488
|
+
}
|
|
5489
|
+
};
|
|
5490
|
+
|
|
4358
5491
|
// src/db-host/space-state-manager.ts
|
|
4359
5492
|
import { interpretAsDocumentId as interpretAsDocumentId3 } from "@automerge/automerge-repo";
|
|
4360
5493
|
import isEqual from "lodash.isequal";
|
|
4361
|
-
import { Event as
|
|
4362
|
-
import { Context as
|
|
4363
|
-
import { invariant as
|
|
5494
|
+
import { Event as Event4, UpdateScheduler as UpdateScheduler3 } from "@dxos/async";
|
|
5495
|
+
import { Context as Context7, LifecycleState as LifecycleState4, Resource as Resource8 } from "@dxos/context";
|
|
5496
|
+
import { invariant as invariant13 } from "@dxos/invariant";
|
|
4364
5497
|
|
|
4365
5498
|
// src/db-host/database-root.ts
|
|
4366
5499
|
import { interpretAsDocumentId as interpretAsDocumentId2 } from "@automerge/automerge-repo";
|
|
4367
|
-
import { DatabaseDirectory as
|
|
4368
|
-
import { invariant as
|
|
5500
|
+
import { DatabaseDirectory as DatabaseDirectory6, SpaceDocVersion as SpaceDocVersion3 } from "@dxos/echo-protocol";
|
|
5501
|
+
import { invariant as invariant12 } from "@dxos/invariant";
|
|
4369
5502
|
|
|
4370
5503
|
// src/db-host/automerge-metrics.ts
|
|
4371
5504
|
import * as A5 from "@automerge/automerge";
|
|
4372
|
-
import { log as
|
|
4373
|
-
var
|
|
5505
|
+
import { log as log13 } from "@dxos/log";
|
|
5506
|
+
var __dxlog_file16 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/automerge-metrics.ts";
|
|
4374
5507
|
var measureDocMetrics = (doc) => {
|
|
4375
5508
|
const snapshot = A5.save(doc);
|
|
4376
5509
|
const start = Date.now();
|
|
@@ -4381,10 +5514,10 @@ var measureDocMetrics = (doc) => {
|
|
|
4381
5514
|
const mutationCount = A5.getAllChanges(doc).length;
|
|
4382
5515
|
const getAllChangesEnd = Date.now();
|
|
4383
5516
|
if (getAllChangesEnd - getAllChangesStart > 300) {
|
|
4384
|
-
|
|
5517
|
+
log13.warn("getAllChanges took too long", {
|
|
4385
5518
|
elapsed: getAllChangesEnd - getAllChangesStart
|
|
4386
5519
|
}, {
|
|
4387
|
-
F:
|
|
5520
|
+
F: __dxlog_file16,
|
|
4388
5521
|
L: 31,
|
|
4389
5522
|
S: void 0,
|
|
4390
5523
|
C: (f, a) => f(...a)
|
|
@@ -4398,7 +5531,7 @@ var measureDocMetrics = (doc) => {
|
|
|
4398
5531
|
};
|
|
4399
5532
|
|
|
4400
5533
|
// src/db-host/database-root.ts
|
|
4401
|
-
var
|
|
5534
|
+
var __dxlog_file17 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/database-root.ts";
|
|
4402
5535
|
var DatabaseRoot = class {
|
|
4403
5536
|
_rootHandle;
|
|
4404
5537
|
static mapLinks(doc, mapping) {
|
|
@@ -4437,14 +5570,14 @@ var DatabaseRoot = class {
|
|
|
4437
5570
|
if (!doc) {
|
|
4438
5571
|
return null;
|
|
4439
5572
|
}
|
|
4440
|
-
return doc.version ??
|
|
5573
|
+
return doc.version ?? SpaceDocVersion3.LEGACY;
|
|
4441
5574
|
}
|
|
4442
5575
|
getSpaceKey() {
|
|
4443
5576
|
const doc = this.doc();
|
|
4444
5577
|
if (!doc) {
|
|
4445
5578
|
return null;
|
|
4446
5579
|
}
|
|
4447
|
-
return
|
|
5580
|
+
return DatabaseDirectory6.getSpaceKey(doc);
|
|
4448
5581
|
}
|
|
4449
5582
|
getInlineObjectCount() {
|
|
4450
5583
|
const doc = this.doc();
|
|
@@ -4462,8 +5595,8 @@ var DatabaseRoot = class {
|
|
|
4462
5595
|
}
|
|
4463
5596
|
getAllLinkedDocuments() {
|
|
4464
5597
|
const doc = this.doc();
|
|
4465
|
-
|
|
4466
|
-
F:
|
|
5598
|
+
invariant12(doc, void 0, {
|
|
5599
|
+
F: __dxlog_file17,
|
|
4467
5600
|
L: 88,
|
|
4468
5601
|
S: this,
|
|
4469
5602
|
A: [
|
|
@@ -4483,13 +5616,13 @@ var DatabaseRoot = class {
|
|
|
4483
5616
|
};
|
|
4484
5617
|
|
|
4485
5618
|
// src/db-host/space-state-manager.ts
|
|
4486
|
-
var
|
|
5619
|
+
var __dxlog_file18 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/space-state-manager.ts";
|
|
4487
5620
|
var SpaceStateManager = class extends Resource8 {
|
|
4488
5621
|
_roots = /* @__PURE__ */ new Map();
|
|
4489
5622
|
_rootBySpace = /* @__PURE__ */ new Map();
|
|
4490
5623
|
_perRootContext = /* @__PURE__ */ new Map();
|
|
4491
5624
|
_lastSpaceDocumentList = /* @__PURE__ */ new Map();
|
|
4492
|
-
spaceDocumentListUpdated = new
|
|
5625
|
+
spaceDocumentListUpdated = new Event4();
|
|
4493
5626
|
async _close(ctx) {
|
|
4494
5627
|
for (const [_, rootCtx] of this._perRootContext) {
|
|
4495
5628
|
await rootCtx.dispose();
|
|
@@ -4499,6 +5632,9 @@ var SpaceStateManager = class extends Resource8 {
|
|
|
4499
5632
|
get roots() {
|
|
4500
5633
|
return this._roots;
|
|
4501
5634
|
}
|
|
5635
|
+
get spaceIds() {
|
|
5636
|
+
return Array.from(this._rootBySpace.keys());
|
|
5637
|
+
}
|
|
4502
5638
|
getRootByDocumentId(documentId) {
|
|
4503
5639
|
return this._roots.get(documentId);
|
|
4504
5640
|
}
|
|
@@ -4506,9 +5642,9 @@ var SpaceStateManager = class extends Resource8 {
|
|
|
4506
5642
|
return this._rootBySpace.get(spaceId);
|
|
4507
5643
|
}
|
|
4508
5644
|
getRootBySpaceId(spaceId) {
|
|
4509
|
-
|
|
4510
|
-
F:
|
|
4511
|
-
L:
|
|
5645
|
+
invariant13(this._lifecycleState === LifecycleState4.OPEN, void 0, {
|
|
5646
|
+
F: __dxlog_file18,
|
|
5647
|
+
L: 48,
|
|
4512
5648
|
S: this,
|
|
4513
5649
|
A: [
|
|
4514
5650
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -4538,9 +5674,9 @@ var SpaceStateManager = class extends Resource8 {
|
|
|
4538
5674
|
this._perRootContext.delete(prevRootId);
|
|
4539
5675
|
}
|
|
4540
5676
|
this._rootBySpace.set(spaceId, root.handle.documentId);
|
|
4541
|
-
const ctx = new
|
|
4542
|
-
F:
|
|
4543
|
-
L:
|
|
5677
|
+
const ctx = new Context7(void 0, {
|
|
5678
|
+
F: __dxlog_file18,
|
|
5679
|
+
L: 76
|
|
4544
5680
|
});
|
|
4545
5681
|
this._perRootContext.set(root.handle.documentId, ctx);
|
|
4546
5682
|
await root.handle.whenReady();
|
|
@@ -4576,11 +5712,24 @@ var SpaceDocumentListUpdatedEvent = class {
|
|
|
4576
5712
|
}
|
|
4577
5713
|
};
|
|
4578
5714
|
|
|
5715
|
+
// src/db-host/stub.ts
|
|
5716
|
+
var QueueServiceStub = class {
|
|
5717
|
+
queryQueue(request) {
|
|
5718
|
+
throw new Error("Not available.");
|
|
5719
|
+
}
|
|
5720
|
+
insertIntoQueue(request) {
|
|
5721
|
+
throw new Error("Not available.");
|
|
5722
|
+
}
|
|
5723
|
+
deleteFromQueue(request) {
|
|
5724
|
+
throw new Error("Not available.");
|
|
5725
|
+
}
|
|
5726
|
+
};
|
|
5727
|
+
|
|
4579
5728
|
// src/db-host/echo-host.ts
|
|
4580
|
-
var
|
|
5729
|
+
var __dxlog_file19 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/echo-host.ts";
|
|
4581
5730
|
var DEFAULT_INDEXING_CONFIG = {
|
|
4582
|
-
// TODO(
|
|
4583
|
-
|
|
5731
|
+
// TODO(mykola): Enable by default when SQLite indexer is stable.
|
|
5732
|
+
sqlIndex: false,
|
|
4584
5733
|
vector: false
|
|
4585
5734
|
};
|
|
4586
5735
|
var EchoHost = class extends Resource9 {
|
|
@@ -4591,9 +5740,18 @@ var EchoHost = class extends Resource9 {
|
|
|
4591
5740
|
_dataService;
|
|
4592
5741
|
_spaceStateManager = new SpaceStateManager();
|
|
4593
5742
|
_echoDataMonitor;
|
|
4594
|
-
|
|
5743
|
+
_automergeDataSource;
|
|
5744
|
+
_indexer2;
|
|
5745
|
+
_indexConfig;
|
|
5746
|
+
_runtime;
|
|
5747
|
+
_feedStore;
|
|
5748
|
+
_queueDataSource;
|
|
5749
|
+
_updateIndexes;
|
|
5750
|
+
_queuesService;
|
|
5751
|
+
_indexesUpToDate = false;
|
|
5752
|
+
constructor({ kv, localQueues, indexing = {}, peerIdProvider, getSpaceKeyByRootDocumentId, runtime, assignQueuePositions = false }) {
|
|
4595
5753
|
super();
|
|
4596
|
-
|
|
5754
|
+
this._indexConfig = {
|
|
4597
5755
|
...DEFAULT_INDEXING_CONFIG,
|
|
4598
5756
|
...indexing
|
|
4599
5757
|
};
|
|
@@ -4608,6 +5766,22 @@ var EchoHost = class extends Resource9 {
|
|
|
4608
5766
|
peerIdProvider,
|
|
4609
5767
|
getSpaceKeyByRootDocumentId
|
|
4610
5768
|
});
|
|
5769
|
+
this._runtime = runtime;
|
|
5770
|
+
this._automergeDataSource = new AutomergeDataSource(this._automergeHost);
|
|
5771
|
+
if (localQueues) {
|
|
5772
|
+
this._feedStore = new FeedStore({
|
|
5773
|
+
assignPositions: assignQueuePositions,
|
|
5774
|
+
localActorId: crypto.randomUUID()
|
|
5775
|
+
});
|
|
5776
|
+
this._queueDataSource = new QueueDataSource({
|
|
5777
|
+
feedStore: this._feedStore,
|
|
5778
|
+
runtime: this._runtime,
|
|
5779
|
+
getSpaceIds: () => this._spaceStateManager.spaceIds
|
|
5780
|
+
});
|
|
5781
|
+
this._queuesService = new LocalQueueServiceImpl(runtime, this._feedStore);
|
|
5782
|
+
} else {
|
|
5783
|
+
this._queuesService = new QueueServiceStub();
|
|
5784
|
+
}
|
|
4611
5785
|
this._indexer = new Indexer({
|
|
4612
5786
|
db: kv,
|
|
4613
5787
|
indexStore: new IndexStore({
|
|
@@ -4627,21 +5801,19 @@ var EchoHost = class extends Resource9 {
|
|
|
4627
5801
|
{
|
|
4628
5802
|
kind: IndexKind.Kind.GRAPH
|
|
4629
5803
|
},
|
|
4630
|
-
...
|
|
4631
|
-
{
|
|
4632
|
-
kind: IndexKind.Kind.FULL_TEXT
|
|
4633
|
-
}
|
|
4634
|
-
] : [],
|
|
4635
|
-
...indexingConfig.vector ? [
|
|
5804
|
+
...this._indexConfig.vector ? [
|
|
4636
5805
|
{
|
|
4637
5806
|
kind: IndexKind.Kind.VECTOR
|
|
4638
5807
|
}
|
|
4639
5808
|
] : []
|
|
4640
5809
|
]
|
|
4641
5810
|
});
|
|
5811
|
+
this._indexer2 = new IndexEngine();
|
|
4642
5812
|
this._queryService = new QueryServiceImpl({
|
|
4643
5813
|
automergeHost: this._automergeHost,
|
|
4644
5814
|
indexer: this._indexer,
|
|
5815
|
+
indexer2: this._indexConfig.sqlIndex ? this._indexer2 : void 0,
|
|
5816
|
+
runtime: this._indexConfig.sqlIndex ? this._runtime : void 0,
|
|
4645
5817
|
spaceStateManager: this._spaceStateManager
|
|
4646
5818
|
});
|
|
4647
5819
|
this._dataService = new DataServiceImpl({
|
|
@@ -4649,6 +5821,11 @@ var EchoHost = class extends Resource9 {
|
|
|
4649
5821
|
spaceStateManager: this._spaceStateManager,
|
|
4650
5822
|
updateIndexes: async () => {
|
|
4651
5823
|
await this._indexer.updateIndexes();
|
|
5824
|
+
if (this._indexConfig.sqlIndex) {
|
|
5825
|
+
do {
|
|
5826
|
+
await this._updateIndexes.runBlocking();
|
|
5827
|
+
} while (!this._indexesUpToDate);
|
|
5828
|
+
}
|
|
4652
5829
|
}
|
|
4653
5830
|
});
|
|
4654
5831
|
trace5.diagnostic({
|
|
@@ -4695,20 +5872,36 @@ var EchoHost = class extends Resource9 {
|
|
|
4695
5872
|
get dataService() {
|
|
4696
5873
|
return this._dataService;
|
|
4697
5874
|
}
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
*/
|
|
4701
|
-
get automergeRepo() {
|
|
4702
|
-
return this._automergeHost.repo;
|
|
5875
|
+
get queuesService() {
|
|
5876
|
+
return this._queuesService;
|
|
4703
5877
|
}
|
|
4704
5878
|
get roots() {
|
|
4705
5879
|
return this._spaceStateManager.roots;
|
|
4706
5880
|
}
|
|
5881
|
+
/**
|
|
5882
|
+
* New index-core indexer for text and other queries.
|
|
5883
|
+
*/
|
|
5884
|
+
get indexer2() {
|
|
5885
|
+
return this._indexer2;
|
|
5886
|
+
}
|
|
4707
5887
|
async _open(ctx) {
|
|
4708
5888
|
await this._automergeHost.open();
|
|
4709
5889
|
await this._indexer.open(ctx);
|
|
4710
5890
|
await this._queryService.open(ctx);
|
|
4711
5891
|
await this._spaceStateManager.open(ctx);
|
|
5892
|
+
if (this._feedStore) {
|
|
5893
|
+
await RuntimeProvider3.runPromise(this._runtime)(this._feedStore.migrate());
|
|
5894
|
+
this._feedStore.onNewBlocks.on(this._ctx, () => {
|
|
5895
|
+
this._queryService.invalidateQueries();
|
|
5896
|
+
if (this._indexConfig.sqlIndex) {
|
|
5897
|
+
this._updateIndexes.schedule();
|
|
5898
|
+
}
|
|
5899
|
+
});
|
|
5900
|
+
}
|
|
5901
|
+
if (this._indexConfig.sqlIndex) {
|
|
5902
|
+
await RuntimeProvider3.runPromise(this._runtime)(this._indexer2.migrate());
|
|
5903
|
+
this._updateIndexes = new DeferredTask3(this._ctx, this._runUpdateIndexes);
|
|
5904
|
+
}
|
|
4712
5905
|
this._spaceStateManager.spaceDocumentListUpdated.on(this._ctx, (e) => {
|
|
4713
5906
|
if (e.previousRootId) {
|
|
4714
5907
|
void this._automergeHost.clearLocalCollectionState(deriveCollectionIdFromSpaceId(e.spaceId, e.previousRootId));
|
|
@@ -4717,7 +5910,13 @@ var EchoHost = class extends Resource9 {
|
|
|
4717
5910
|
});
|
|
4718
5911
|
this._automergeHost.documentsSaved.on(this._ctx, () => {
|
|
4719
5912
|
this._queryService.invalidateQueries();
|
|
5913
|
+
if (this._indexConfig.sqlIndex) {
|
|
5914
|
+
this._updateIndexes.schedule();
|
|
5915
|
+
}
|
|
4720
5916
|
});
|
|
5917
|
+
if (this._indexConfig.sqlIndex) {
|
|
5918
|
+
this._updateIndexes.schedule();
|
|
5919
|
+
}
|
|
4721
5920
|
}
|
|
4722
5921
|
async _close(ctx) {
|
|
4723
5922
|
await this._queryService.close(ctx);
|
|
@@ -4749,16 +5948,16 @@ var EchoHost = class extends Resource9 {
|
|
|
4749
5948
|
/**
|
|
4750
5949
|
* Create new persisted document.
|
|
4751
5950
|
*/
|
|
4752
|
-
createDoc(initialValue, opts) {
|
|
5951
|
+
async createDoc(initialValue, opts) {
|
|
4753
5952
|
return this._automergeHost.createDoc(initialValue, opts);
|
|
4754
5953
|
}
|
|
4755
5954
|
/**
|
|
4756
5955
|
* Create new space root.
|
|
4757
5956
|
*/
|
|
4758
5957
|
async createSpaceRoot(spaceKey) {
|
|
4759
|
-
|
|
4760
|
-
F:
|
|
4761
|
-
L:
|
|
5958
|
+
invariant14(this._lifecycleState === LifecycleState5.OPEN, void 0, {
|
|
5959
|
+
F: __dxlog_file19,
|
|
5960
|
+
L: 342,
|
|
4762
5961
|
S: this,
|
|
4763
5962
|
A: [
|
|
4764
5963
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -4766,8 +5965,8 @@ var EchoHost = class extends Resource9 {
|
|
|
4766
5965
|
]
|
|
4767
5966
|
});
|
|
4768
5967
|
const spaceId = await createIdFromSpaceKey2(spaceKey);
|
|
4769
|
-
const automergeRoot = this._automergeHost.createDoc({
|
|
4770
|
-
version:
|
|
5968
|
+
const automergeRoot = await this._automergeHost.createDoc({
|
|
5969
|
+
version: SpaceDocVersion4.CURRENT,
|
|
4771
5970
|
access: {
|
|
4772
5971
|
spaceKey: spaceKey.toHex()
|
|
4773
5972
|
},
|
|
@@ -4784,21 +5983,26 @@ var EchoHost = class extends Resource9 {
|
|
|
4784
5983
|
}
|
|
4785
5984
|
// TODO(dmaretskyi): Change to document id.
|
|
4786
5985
|
async openSpaceRoot(spaceId, automergeUrl) {
|
|
4787
|
-
|
|
4788
|
-
F:
|
|
4789
|
-
L:
|
|
5986
|
+
invariant14(this._lifecycleState === LifecycleState5.OPEN, void 0, {
|
|
5987
|
+
F: __dxlog_file19,
|
|
5988
|
+
L: 361,
|
|
4790
5989
|
S: this,
|
|
4791
5990
|
A: [
|
|
4792
5991
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
4793
5992
|
""
|
|
4794
5993
|
]
|
|
4795
5994
|
});
|
|
4796
|
-
const handle = await this._automergeHost.
|
|
5995
|
+
const handle = await this._automergeHost.loadDoc(Context8.default(void 0, {
|
|
5996
|
+
F: __dxlog_file19,
|
|
5997
|
+
L: 362
|
|
5998
|
+
}), automergeUrl, {
|
|
5999
|
+
fetchFromNetwork: true
|
|
6000
|
+
});
|
|
4797
6001
|
await handle.whenReady();
|
|
4798
6002
|
return this._spaceStateManager.assignRootToSpace(spaceId, handle);
|
|
4799
6003
|
}
|
|
4800
6004
|
// TODO(dmaretskyi): Change to document id.
|
|
4801
|
-
async closeSpaceRoot(
|
|
6005
|
+
async closeSpaceRoot(_automergeUrl) {
|
|
4802
6006
|
todo();
|
|
4803
6007
|
}
|
|
4804
6008
|
/**
|
|
@@ -4813,16 +6017,102 @@ var EchoHost = class extends Resource9 {
|
|
|
4813
6017
|
async removeReplicator(replicator) {
|
|
4814
6018
|
await this._automergeHost.removeReplicator(replicator);
|
|
4815
6019
|
}
|
|
6020
|
+
/**
|
|
6021
|
+
* Run collection sync for the given space.
|
|
6022
|
+
* Does not wait for the sync to complete.
|
|
6023
|
+
*/
|
|
6024
|
+
async runCollectionSync(spaceId) {
|
|
6025
|
+
const root = this._spaceStateManager.getRootBySpaceId(spaceId);
|
|
6026
|
+
if (!root) {
|
|
6027
|
+
throw new Error(`Space not found: ${spaceId}`);
|
|
6028
|
+
}
|
|
6029
|
+
this._automergeHost.refreshCollection(deriveCollectionIdFromSpaceId(spaceId, root.documentId));
|
|
6030
|
+
}
|
|
6031
|
+
_runUpdateIndexes = async () => {
|
|
6032
|
+
if (!this._indexer2) {
|
|
6033
|
+
return;
|
|
6034
|
+
}
|
|
6035
|
+
let totalUpdated = 0;
|
|
6036
|
+
let totalDone = true;
|
|
6037
|
+
{
|
|
6038
|
+
performance.mark("indexer2.update.automerge:start");
|
|
6039
|
+
const { updated, done } = await this._indexer2.update(this._automergeDataSource, {
|
|
6040
|
+
spaceId: null,
|
|
6041
|
+
limit: 50
|
|
6042
|
+
}).pipe(RuntimeProvider3.runPromise(this._runtime));
|
|
6043
|
+
totalUpdated += updated;
|
|
6044
|
+
totalDone &&= done;
|
|
6045
|
+
performance.measure("Index Automerge", {
|
|
6046
|
+
start: "indexer2.update.automerge:start",
|
|
6047
|
+
detail: {
|
|
6048
|
+
devtools: {
|
|
6049
|
+
dataType: "track-entry",
|
|
6050
|
+
track: "Indexing",
|
|
6051
|
+
trackGroup: "ECHO",
|
|
6052
|
+
color: "tertiary-dark",
|
|
6053
|
+
properties: [
|
|
6054
|
+
[
|
|
6055
|
+
"count",
|
|
6056
|
+
updated
|
|
6057
|
+
]
|
|
6058
|
+
]
|
|
6059
|
+
}
|
|
6060
|
+
}
|
|
6061
|
+
});
|
|
6062
|
+
}
|
|
6063
|
+
if (this._queueDataSource) {
|
|
6064
|
+
performance.mark("indexer2.update.queue:start");
|
|
6065
|
+
const { updated, done } = await this._indexer2.update(this._queueDataSource, {
|
|
6066
|
+
spaceId: null,
|
|
6067
|
+
limit: 50
|
|
6068
|
+
}).pipe(RuntimeProvider3.runPromise(this._runtime));
|
|
6069
|
+
totalUpdated += updated;
|
|
6070
|
+
totalDone &&= done;
|
|
6071
|
+
performance.measure("Index Queues", {
|
|
6072
|
+
start: "indexer2.update.queue:start",
|
|
6073
|
+
detail: {
|
|
6074
|
+
devtools: {
|
|
6075
|
+
dataType: "track-entry",
|
|
6076
|
+
track: "Indexing",
|
|
6077
|
+
trackGroup: "ECHO",
|
|
6078
|
+
color: "tertiary-dark",
|
|
6079
|
+
properties: [
|
|
6080
|
+
[
|
|
6081
|
+
"count",
|
|
6082
|
+
updated
|
|
6083
|
+
]
|
|
6084
|
+
]
|
|
6085
|
+
}
|
|
6086
|
+
}
|
|
6087
|
+
});
|
|
6088
|
+
}
|
|
6089
|
+
log14.verbose("indexer2 update completed", {
|
|
6090
|
+
updated: totalUpdated,
|
|
6091
|
+
done: totalDone
|
|
6092
|
+
}, {
|
|
6093
|
+
F: __dxlog_file19,
|
|
6094
|
+
L: 452,
|
|
6095
|
+
S: this,
|
|
6096
|
+
C: (f, a) => f(...a)
|
|
6097
|
+
});
|
|
6098
|
+
await sleep(1);
|
|
6099
|
+
if (!totalDone) {
|
|
6100
|
+
this._indexesUpToDate = false;
|
|
6101
|
+
this._updateIndexes.schedule();
|
|
6102
|
+
} else {
|
|
6103
|
+
this._indexesUpToDate = true;
|
|
6104
|
+
}
|
|
6105
|
+
};
|
|
4816
6106
|
};
|
|
4817
6107
|
|
|
4818
6108
|
// src/edge/echo-edge-replicator.ts
|
|
4819
6109
|
import * as Automerge from "@automerge/automerge";
|
|
4820
6110
|
import { cbor as cbor2 } from "@automerge/automerge-repo";
|
|
4821
6111
|
import { Mutex, scheduleMicroTask as scheduleMicroTask2, scheduleTask as scheduleTask2 } from "@dxos/async";
|
|
4822
|
-
import { Context as
|
|
6112
|
+
import { Context as Context9, Resource as Resource11 } from "@dxos/context";
|
|
4823
6113
|
import { randomUUID } from "@dxos/crypto";
|
|
4824
|
-
import { invariant as
|
|
4825
|
-
import { log as
|
|
6114
|
+
import { invariant as invariant15 } from "@dxos/invariant";
|
|
6115
|
+
import { log as log16 } from "@dxos/log";
|
|
4826
6116
|
import { DocumentCodec, EdgeService } from "@dxos/protocols";
|
|
4827
6117
|
import { buf } from "@dxos/protocols/buf";
|
|
4828
6118
|
import { MessageSchema as RouterMessageSchema } from "@dxos/protocols/buf/dxos/edge/messenger_pb";
|
|
@@ -4831,8 +6121,8 @@ import { bufferToArray as bufferToArray2, setDeep } from "@dxos/util";
|
|
|
4831
6121
|
// src/edge/inflight-request-limiter.ts
|
|
4832
6122
|
import { Trigger as Trigger2 } from "@dxos/async";
|
|
4833
6123
|
import { Resource as Resource10 } from "@dxos/context";
|
|
4834
|
-
import { log as
|
|
4835
|
-
var
|
|
6124
|
+
import { log as log15 } from "@dxos/log";
|
|
6125
|
+
var __dxlog_file20 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/edge/inflight-request-limiter.ts";
|
|
4836
6126
|
var InflightRequestLimiter = class extends Resource10 {
|
|
4837
6127
|
_config;
|
|
4838
6128
|
/**
|
|
@@ -4867,8 +6157,8 @@ var InflightRequestLimiter = class extends Resource10 {
|
|
|
4867
6157
|
if (this._inflightRequestBalance === this._config.maxInflightRequests) {
|
|
4868
6158
|
this._requestBarrier.reset();
|
|
4869
6159
|
this._resetBalanceTimeout = setTimeout(() => {
|
|
4870
|
-
|
|
4871
|
-
F:
|
|
6160
|
+
log15.warn("Request balance has not changed during specified timeout, resetting request limiter.", void 0, {
|
|
6161
|
+
F: __dxlog_file20,
|
|
4872
6162
|
L: 52,
|
|
4873
6163
|
S: this,
|
|
4874
6164
|
C: (f, a) => f(...a)
|
|
@@ -4956,7 +6246,7 @@ function _ts_dispose_resources(env) {
|
|
|
4956
6246
|
return next();
|
|
4957
6247
|
})(env);
|
|
4958
6248
|
}
|
|
4959
|
-
var
|
|
6249
|
+
var __dxlog_file21 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/edge/echo-edge-replicator.ts";
|
|
4960
6250
|
var INITIAL_RESTART_DELAY = 500;
|
|
4961
6251
|
var RESTART_DELAY_JITTER = 250;
|
|
4962
6252
|
var MAX_RESTART_DELAY = 5e3;
|
|
@@ -4975,19 +6265,19 @@ var EchoEdgeReplicator = class {
|
|
|
4975
6265
|
this._sharePolicyEnabled = !disableSharePolicy;
|
|
4976
6266
|
}
|
|
4977
6267
|
async connect(context) {
|
|
4978
|
-
|
|
6268
|
+
log16("connecting...", {
|
|
4979
6269
|
peerId: context.peerId,
|
|
4980
6270
|
connectedSpaces: this._connectedSpaces.size
|
|
4981
6271
|
}, {
|
|
4982
|
-
F:
|
|
4983
|
-
L:
|
|
6272
|
+
F: __dxlog_file21,
|
|
6273
|
+
L: 74,
|
|
4984
6274
|
S: this,
|
|
4985
6275
|
C: (f, a) => f(...a)
|
|
4986
6276
|
});
|
|
4987
6277
|
this._context = context;
|
|
4988
|
-
this._ctx =
|
|
4989
|
-
F:
|
|
4990
|
-
L:
|
|
6278
|
+
this._ctx = Context9.default(void 0, {
|
|
6279
|
+
F: __dxlog_file21,
|
|
6280
|
+
L: 76
|
|
4991
6281
|
});
|
|
4992
6282
|
this._ctx.onDispose(this._edgeConnection.onReconnected(() => {
|
|
4993
6283
|
this._ctx && scheduleMicroTask2(this._ctx, () => this._handleReconnect());
|
|
@@ -5047,6 +6337,14 @@ var EchoEdgeReplicator = class {
|
|
|
5047
6337
|
hasError: false
|
|
5048
6338
|
};
|
|
5049
6339
|
try {
|
|
6340
|
+
log16("connectToSpace", {
|
|
6341
|
+
spaceId
|
|
6342
|
+
}, {
|
|
6343
|
+
F: __dxlog_file21,
|
|
6344
|
+
L: 111,
|
|
6345
|
+
S: this,
|
|
6346
|
+
C: (f, a) => f(...a)
|
|
6347
|
+
});
|
|
5050
6348
|
const _guard = _ts_add_disposable_resource(env, await this._mutex.acquire(), false);
|
|
5051
6349
|
if (this._connectedSpaces.has(spaceId)) {
|
|
5052
6350
|
return;
|
|
@@ -5084,18 +6382,18 @@ var EchoEdgeReplicator = class {
|
|
|
5084
6382
|
}
|
|
5085
6383
|
}
|
|
5086
6384
|
async _openConnection(spaceId, reconnects = 0) {
|
|
5087
|
-
|
|
5088
|
-
F:
|
|
5089
|
-
L:
|
|
6385
|
+
invariant15(this._context, void 0, {
|
|
6386
|
+
F: __dxlog_file21,
|
|
6387
|
+
L: 138,
|
|
5090
6388
|
S: this,
|
|
5091
6389
|
A: [
|
|
5092
6390
|
"this._context",
|
|
5093
6391
|
""
|
|
5094
6392
|
]
|
|
5095
6393
|
});
|
|
5096
|
-
|
|
5097
|
-
F:
|
|
5098
|
-
L:
|
|
6394
|
+
invariant15(!this._connections.has(spaceId), void 0, {
|
|
6395
|
+
F: __dxlog_file21,
|
|
6396
|
+
L: 139,
|
|
5099
6397
|
S: this,
|
|
5100
6398
|
A: [
|
|
5101
6399
|
"!this._connections.has(spaceId)",
|
|
@@ -5110,22 +6408,22 @@ var EchoEdgeReplicator = class {
|
|
|
5110
6408
|
context: this._context,
|
|
5111
6409
|
sharedPolicyEnabled: this._sharePolicyEnabled,
|
|
5112
6410
|
onRemoteConnected: async () => {
|
|
5113
|
-
|
|
6411
|
+
log16.trace("dxos.echo.edge.replicator.onRemoteConnected", {
|
|
5114
6412
|
spaceId
|
|
5115
6413
|
}, {
|
|
5116
|
-
F:
|
|
5117
|
-
L:
|
|
6414
|
+
F: __dxlog_file21,
|
|
6415
|
+
L: 150,
|
|
5118
6416
|
S: this,
|
|
5119
6417
|
C: (f, a) => f(...a)
|
|
5120
6418
|
});
|
|
5121
6419
|
this._context?.onConnectionOpen(connection);
|
|
5122
6420
|
},
|
|
5123
6421
|
onRemoteDisconnected: async () => {
|
|
5124
|
-
|
|
6422
|
+
log16.trace("dxos.echo.edge.replicator.onRemoteDisconnected", {
|
|
5125
6423
|
spaceId
|
|
5126
6424
|
}, {
|
|
5127
|
-
F:
|
|
5128
|
-
L:
|
|
6425
|
+
F: __dxlog_file21,
|
|
6426
|
+
L: 154,
|
|
5129
6427
|
S: this,
|
|
5130
6428
|
C: (f, a) => f(...a)
|
|
5131
6429
|
});
|
|
@@ -5136,13 +6434,13 @@ var EchoEdgeReplicator = class {
|
|
|
5136
6434
|
return;
|
|
5137
6435
|
}
|
|
5138
6436
|
const restartDelay = Math.min(MAX_RESTART_DELAY, INITIAL_RESTART_DELAY * reconnects) + Math.random() * RESTART_DELAY_JITTER;
|
|
5139
|
-
|
|
6437
|
+
log16("connection restart scheduled", {
|
|
5140
6438
|
spaceId,
|
|
5141
6439
|
reconnects,
|
|
5142
6440
|
restartDelay
|
|
5143
6441
|
}, {
|
|
5144
|
-
F:
|
|
5145
|
-
L:
|
|
6442
|
+
F: __dxlog_file21,
|
|
6443
|
+
L: 165,
|
|
5146
6444
|
S: this,
|
|
5147
6445
|
C: (f, a) => f(...a)
|
|
5148
6446
|
});
|
|
@@ -5164,13 +6462,13 @@ var EchoEdgeReplicator = class {
|
|
|
5164
6462
|
if (ctx?.disposed) {
|
|
5165
6463
|
return;
|
|
5166
6464
|
}
|
|
5167
|
-
|
|
6465
|
+
log16.trace("dxos.echo.edge.replicator.restart", {
|
|
5168
6466
|
spaceId,
|
|
5169
6467
|
reconnects,
|
|
5170
6468
|
restartDelay
|
|
5171
6469
|
}, {
|
|
5172
|
-
F:
|
|
5173
|
-
L:
|
|
6470
|
+
F: __dxlog_file21,
|
|
6471
|
+
L: 182,
|
|
5174
6472
|
S: this,
|
|
5175
6473
|
C: (f, a) => f(...a)
|
|
5176
6474
|
});
|
|
@@ -5235,9 +6533,9 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5235
6533
|
});
|
|
5236
6534
|
}
|
|
5237
6535
|
async _open(ctx) {
|
|
5238
|
-
|
|
5239
|
-
F:
|
|
5240
|
-
L:
|
|
6536
|
+
log16("opening...", void 0, {
|
|
6537
|
+
F: __dxlog_file21,
|
|
6538
|
+
L: 275,
|
|
5241
6539
|
S: this,
|
|
5242
6540
|
C: (f, a) => f(...a)
|
|
5243
6541
|
});
|
|
@@ -5250,9 +6548,9 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5250
6548
|
// NOTE: This will fire immediately if the connection is already open.
|
|
5251
6549
|
this._edgeConnection.onReconnected(async () => {
|
|
5252
6550
|
if (firstReconnect) {
|
|
5253
|
-
|
|
5254
|
-
F:
|
|
5255
|
-
L:
|
|
6551
|
+
log16.verbose("first reconnect skipped", void 0, {
|
|
6552
|
+
F: __dxlog_file21,
|
|
6553
|
+
L: 290,
|
|
5256
6554
|
S: this,
|
|
5257
6555
|
C: (f, a) => f(...a)
|
|
5258
6556
|
});
|
|
@@ -5265,9 +6563,9 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5265
6563
|
await this._onRemoteConnected();
|
|
5266
6564
|
}
|
|
5267
6565
|
async _close() {
|
|
5268
|
-
|
|
5269
|
-
F:
|
|
5270
|
-
L:
|
|
6566
|
+
log16("closing...", void 0, {
|
|
6567
|
+
F: __dxlog_file21,
|
|
6568
|
+
L: 303,
|
|
5271
6569
|
S: this,
|
|
5272
6570
|
C: (f, a) => f(...a)
|
|
5273
6571
|
});
|
|
@@ -5276,9 +6574,9 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5276
6574
|
await this._onRemoteDisconnected();
|
|
5277
6575
|
}
|
|
5278
6576
|
get peerId() {
|
|
5279
|
-
|
|
5280
|
-
F:
|
|
5281
|
-
L:
|
|
6577
|
+
invariant15(this._remotePeerId, "Not connected", {
|
|
6578
|
+
F: __dxlog_file21,
|
|
6579
|
+
L: 312,
|
|
5282
6580
|
S: this,
|
|
5283
6581
|
A: [
|
|
5284
6582
|
"this._remotePeerId",
|
|
@@ -5297,13 +6595,13 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5297
6595
|
documentId: params.documentId,
|
|
5298
6596
|
peerId: this._remotePeerId
|
|
5299
6597
|
});
|
|
5300
|
-
|
|
6598
|
+
log16.verbose("document not found locally for share policy check", {
|
|
5301
6599
|
documentId: params.documentId,
|
|
5302
6600
|
acceptDocument: remoteDocumentExists,
|
|
5303
6601
|
remoteId: this._remotePeerId
|
|
5304
6602
|
}, {
|
|
5305
|
-
F:
|
|
5306
|
-
L:
|
|
6603
|
+
F: __dxlog_file21,
|
|
6604
|
+
L: 327,
|
|
5307
6605
|
S: this,
|
|
5308
6606
|
C: (f, a) => f(...a)
|
|
5309
6607
|
});
|
|
@@ -5323,12 +6621,12 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5323
6621
|
return;
|
|
5324
6622
|
}
|
|
5325
6623
|
const payload = cbor2.decode(message.payload.value);
|
|
5326
|
-
|
|
6624
|
+
log16.verbose("received", {
|
|
5327
6625
|
...getMessageInfo(payload),
|
|
5328
6626
|
remoteId: this._remotePeerId
|
|
5329
6627
|
}, {
|
|
5330
|
-
F:
|
|
5331
|
-
L:
|
|
6628
|
+
F: __dxlog_file21,
|
|
6629
|
+
L: 356,
|
|
5332
6630
|
S: this,
|
|
5333
6631
|
C: (f, a) => f(...a)
|
|
5334
6632
|
});
|
|
@@ -5360,6 +6658,14 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5360
6658
|
}
|
|
5361
6659
|
_processMessage(message) {
|
|
5362
6660
|
if (isErrorMessage(message)) {
|
|
6661
|
+
log16.verbose("stream error", {
|
|
6662
|
+
error: message.message
|
|
6663
|
+
}, {
|
|
6664
|
+
F: __dxlog_file21,
|
|
6665
|
+
L: 392,
|
|
6666
|
+
S: this,
|
|
6667
|
+
C: (f, a) => f(...a)
|
|
6668
|
+
});
|
|
5363
6669
|
this._onRestartRequested();
|
|
5364
6670
|
return;
|
|
5365
6671
|
}
|
|
@@ -5376,12 +6682,12 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5376
6682
|
"metadata",
|
|
5377
6683
|
"dxos_connectionId"
|
|
5378
6684
|
], this._connectionId);
|
|
5379
|
-
|
|
6685
|
+
log16.verbose("sending...", {
|
|
5380
6686
|
...getMessageInfo(message),
|
|
5381
6687
|
remoteId: this._remotePeerId
|
|
5382
6688
|
}, {
|
|
5383
|
-
F:
|
|
5384
|
-
L:
|
|
6689
|
+
F: __dxlog_file21,
|
|
6690
|
+
L: 410,
|
|
5385
6691
|
S: this,
|
|
5386
6692
|
C: (f, a) => f(...a)
|
|
5387
6693
|
});
|
|
@@ -5398,11 +6704,11 @@ var EdgeReplicatorConnection = class extends Resource11 {
|
|
|
5398
6704
|
}
|
|
5399
6705
|
}));
|
|
5400
6706
|
} catch (err) {
|
|
5401
|
-
|
|
6707
|
+
log16.error("failed to send message", {
|
|
5402
6708
|
err
|
|
5403
6709
|
}, {
|
|
5404
|
-
F:
|
|
5405
|
-
L:
|
|
6710
|
+
F: __dxlog_file21,
|
|
6711
|
+
L: 429,
|
|
5406
6712
|
S: this,
|
|
5407
6713
|
C: (f, a) => f(...a)
|
|
5408
6714
|
});
|
|
@@ -5418,6 +6724,7 @@ var getMessageInfo = (msg) => {
|
|
|
5418
6724
|
return {
|
|
5419
6725
|
type: msg.type,
|
|
5420
6726
|
documentId: "documentId" in msg ? msg.documentId : void 0,
|
|
6727
|
+
collectionId: "collectionId" in msg ? msg.collectionId : void 0,
|
|
5421
6728
|
have,
|
|
5422
6729
|
heads,
|
|
5423
6730
|
need,
|
|
@@ -5427,16 +6734,20 @@ var getMessageInfo = (msg) => {
|
|
|
5427
6734
|
};
|
|
5428
6735
|
|
|
5429
6736
|
// src/util.ts
|
|
5430
|
-
import { ObjectStructure as ObjectStructure2
|
|
6737
|
+
import { EncodedReference, ObjectStructure as ObjectStructure2 } from "@dxos/echo-protocol";
|
|
5431
6738
|
var findInlineObjectOfType = (spaceDoc, typename) => {
|
|
5432
6739
|
for (const id in spaceDoc.objects ?? {}) {
|
|
5433
6740
|
const obj = spaceDoc.objects[id];
|
|
5434
6741
|
const objType = ObjectStructure2.getTypeReference(obj);
|
|
5435
|
-
if (objType
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
6742
|
+
if (objType) {
|
|
6743
|
+
const typeDXN = EncodedReference.toDXN(objType);
|
|
6744
|
+
const typeDXNInfo = typeDXN.asTypeDXN();
|
|
6745
|
+
if (typeDXNInfo?.type === typename) {
|
|
6746
|
+
return [
|
|
6747
|
+
id,
|
|
6748
|
+
obj
|
|
6749
|
+
];
|
|
6750
|
+
}
|
|
5440
6751
|
}
|
|
5441
6752
|
}
|
|
5442
6753
|
return void 0;
|
|
@@ -5444,6 +6755,7 @@ var findInlineObjectOfType = (spaceDoc, typename) => {
|
|
|
5444
6755
|
export {
|
|
5445
6756
|
AuthExtension,
|
|
5446
6757
|
AuthStatus,
|
|
6758
|
+
AutomergeDataSource,
|
|
5447
6759
|
AutomergeHost,
|
|
5448
6760
|
CredentialRetrieverExtension,
|
|
5449
6761
|
CredentialServerExtension,
|
|
@@ -5484,6 +6796,7 @@ export {
|
|
|
5484
6796
|
findInlineObjectOfType,
|
|
5485
6797
|
getSpaceIdFromCollectionId,
|
|
5486
6798
|
hasInvitationExpired,
|
|
6799
|
+
headsCodec,
|
|
5487
6800
|
mapFeedIndexesToTimeframe,
|
|
5488
6801
|
mapTimeframeToFeedIndexes,
|
|
5489
6802
|
startAfter,
|