@dxos/echo-pipeline 0.3.8-next.f4e0086 → 0.3.9-main.03b62b6
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-KD6OVLI6.mjs → chunk-CLHJJVQE.mjs} +253 -49
- package/dist/lib/browser/chunk-CLHJJVQE.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +3 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +7 -2
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/chunk-XWUUSV4Y.cjs +2931 -0
- package/dist/lib/node/chunk-XWUUSV4Y.cjs.map +7 -0
- package/dist/lib/node/index.cjs +30 -2727
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +93 -2798
- package/dist/lib/node/testing/index.cjs.map +4 -4
- package/dist/types/src/automerge/automerge-host.d.ts +15 -0
- package/dist/types/src/automerge/automerge-host.d.ts.map +1 -0
- package/dist/types/src/automerge/automerge-host.test.d.ts +2 -0
- package/dist/types/src/automerge/automerge-host.test.d.ts.map +1 -0
- package/dist/types/src/automerge/index.d.ts +2 -0
- package/dist/types/src/automerge/index.d.ts.map +1 -0
- package/dist/types/src/db-host/data-service-host.d.ts +3 -1
- package/dist/types/src/db-host/data-service-host.d.ts.map +1 -1
- package/dist/types/src/db-host/data-service.d.ts +6 -2
- package/dist/types/src/db-host/data-service.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/space/data-pipeline.d.ts +4 -0
- package/dist/types/src/space/data-pipeline.d.ts.map +1 -1
- package/dist/types/src/space/space-protocol.d.ts +2 -1
- package/dist/types/src/space/space-protocol.d.ts.map +1 -1
- package/dist/types/src/testing/util.d.ts.map +1 -1
- package/package.json +52 -35
- package/src/automerge/automerge-host.test.ts +42 -0
- package/src/automerge/automerge-host.ts +212 -0
- package/src/automerge/index.ts +5 -0
- package/src/db-host/data-service-host.ts +15 -1
- package/src/db-host/data-service.ts +15 -1
- package/src/index.ts +1 -0
- package/src/space/data-pipeline.ts +49 -2
- package/src/space/space-protocol.ts +6 -3
- package/src/testing/util.ts +4 -1
- package/src/tests/database.test.ts +4 -1
- package/dist/lib/browser/chunk-KD6OVLI6.mjs.map +0 -7
- package/testing.d.ts +0 -11
- package/testing.js +0 -5
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,17 +15,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
|
|
30
|
-
// packages/core/echo/echo-pipeline/src/testing/index.ts
|
|
31
19
|
var testing_exports = {};
|
|
32
20
|
__export(testing_exports, {
|
|
33
21
|
DatabaseTestBuilder: () => DatabaseTestBuilder,
|
|
@@ -42,2735 +30,60 @@ __export(testing_exports, {
|
|
|
42
30
|
testLocalDatabase: () => testLocalDatabase
|
|
43
31
|
});
|
|
44
32
|
module.exports = __toCommonJS(testing_exports);
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
var
|
|
48
|
-
var
|
|
49
|
-
var
|
|
50
|
-
var
|
|
51
|
-
var
|
|
52
|
-
var import_model_factory = require("@dxos/model-factory");
|
|
53
|
-
var import_network_manager2 = require("@dxos/network-manager");
|
|
54
|
-
var import_credentials6 = require("@dxos/protocols/proto/dxos/halo/credentials");
|
|
55
|
-
var import_random_access_storage = require("@dxos/random-access-storage");
|
|
56
|
-
var import_teleport_extension_gossip = require("@dxos/teleport-extension-gossip");
|
|
57
|
-
var import_teleport_extension_object_sync2 = require("@dxos/teleport-extension-object-sync");
|
|
58
|
-
var import_util10 = require("@dxos/util");
|
|
59
|
-
|
|
60
|
-
// packages/core/echo/echo-pipeline/src/testing/test-feed-builder.ts
|
|
61
|
-
var import_testing = require("@dxos/feed-store/testing");
|
|
62
|
-
|
|
63
|
-
// packages/core/echo/echo-pipeline/src/common/codec.ts
|
|
64
|
-
var import_hypercore = require("@dxos/hypercore");
|
|
65
|
-
var import_protocols = require("@dxos/protocols");
|
|
66
|
-
var codec = import_protocols.schema.getCodecForType("dxos.echo.feed.FeedMessage");
|
|
67
|
-
var valueEncoding = (0, import_hypercore.createCodecEncoding)(codec);
|
|
68
|
-
|
|
69
|
-
// packages/core/echo/echo-pipeline/src/common/feeds.ts
|
|
70
|
-
var import_invariant = require("@dxos/invariant");
|
|
71
|
-
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/common/feeds.ts";
|
|
72
|
-
var createMappedFeedWriter = (mapper, writer) => {
|
|
73
|
-
(0, import_invariant.invariant)(mapper, void 0, {
|
|
74
|
-
F: __dxlog_file,
|
|
75
|
-
L: 16,
|
|
76
|
-
S: void 0,
|
|
77
|
-
A: [
|
|
78
|
-
"mapper",
|
|
79
|
-
""
|
|
80
|
-
]
|
|
81
|
-
});
|
|
82
|
-
(0, import_invariant.invariant)(writer, void 0, {
|
|
83
|
-
F: __dxlog_file,
|
|
84
|
-
L: 17,
|
|
85
|
-
S: void 0,
|
|
86
|
-
A: [
|
|
87
|
-
"writer",
|
|
88
|
-
""
|
|
89
|
-
]
|
|
90
|
-
});
|
|
91
|
-
return {
|
|
92
|
-
write: async (data, options) => await writer.write(await mapper(data), options)
|
|
93
|
-
};
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
// packages/core/echo/echo-pipeline/src/testing/test-feed-builder.ts
|
|
97
|
-
var TestFeedBuilder = class extends import_testing.TestBuilder {
|
|
98
|
-
constructor() {
|
|
99
|
-
super({
|
|
100
|
-
valueEncoding
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
// packages/core/echo/echo-pipeline/src/db-host/data-service-host.ts
|
|
106
|
-
var import_async = require("@dxos/async");
|
|
107
|
-
var import_codec_protobuf = require("@dxos/codec-protobuf");
|
|
108
|
-
var import_context = require("@dxos/context");
|
|
109
|
-
var import_echo_db = require("@dxos/echo-db");
|
|
110
|
-
var import_invariant2 = require("@dxos/invariant");
|
|
111
|
-
var import_log = require("@dxos/log");
|
|
112
|
-
var import_service = require("@dxos/protocols/proto/dxos/echo/service");
|
|
113
|
-
var import_util = require("@dxos/util");
|
|
114
|
-
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/data-service-host.ts";
|
|
115
|
-
var MUTATION_LIMIT_PER_OBJECT = 10;
|
|
116
|
-
var DataServiceHost = class {
|
|
117
|
-
constructor(_itemManager, _itemDemuxer, _flush, _writeStream, _opts = {}) {
|
|
118
|
-
this._itemManager = _itemManager;
|
|
119
|
-
this._itemDemuxer = _itemDemuxer;
|
|
120
|
-
this._flush = _flush;
|
|
121
|
-
this._writeStream = _writeStream;
|
|
122
|
-
this._opts = _opts;
|
|
123
|
-
this._ctx = new import_context.Context();
|
|
124
|
-
this._clientTagMap = new import_util.ComplexMap(([feedKey, seq]) => `${feedKey.toHex()}:${seq}`);
|
|
125
|
-
}
|
|
126
|
-
async open() {
|
|
127
|
-
}
|
|
128
|
-
async close() {
|
|
129
|
-
await this._ctx.dispose();
|
|
130
|
-
}
|
|
131
|
-
get _deferEvents() {
|
|
132
|
-
return this._opts.deferEvents ?? true;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Real-time subscription to data objects in a space.
|
|
136
|
-
*/
|
|
137
|
-
subscribe() {
|
|
138
|
-
return new import_codec_protobuf.Stream(({ next, close, ctx }) => {
|
|
139
|
-
ctx.onDispose(this._ctx.onDispose(close));
|
|
140
|
-
const objects = Array.from(this._itemManager.entities.values()).map((entity) => entity.createSnapshot());
|
|
141
|
-
next({
|
|
142
|
-
batch: {
|
|
143
|
-
objects
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
const updateScheduler = new import_async.UpdateScheduler(ctx, async () => {
|
|
147
|
-
flushPendingUpdate();
|
|
148
|
-
}, {
|
|
149
|
-
maxFrequency: 10
|
|
150
|
-
});
|
|
151
|
-
const pendingUpdates = [];
|
|
152
|
-
const mutationsPerObject = /* @__PURE__ */ new Map();
|
|
153
|
-
const clearPendingUpdates = () => {
|
|
154
|
-
pendingUpdates.length = 0;
|
|
155
|
-
mutationsPerObject.clear();
|
|
156
|
-
};
|
|
157
|
-
const flushPendingUpdate = () => {
|
|
158
|
-
const stagedEvents = [];
|
|
159
|
-
const objectsWithSnapshots = /* @__PURE__ */ new Set();
|
|
160
|
-
for (const [id, count] of mutationsPerObject) {
|
|
161
|
-
if (count >= MUTATION_LIMIT_PER_OBJECT) {
|
|
162
|
-
objectsWithSnapshots.add(id);
|
|
163
|
-
const entity = this._itemManager.entities.get(id);
|
|
164
|
-
if (entity) {
|
|
165
|
-
stagedEvents.push(entity.createSnapshot());
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
for (const obj of pendingUpdates) {
|
|
170
|
-
if (!objectsWithSnapshots.has(obj.objectId)) {
|
|
171
|
-
stagedEvents.push(obj);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
next({
|
|
175
|
-
batch: {
|
|
176
|
-
objects: stagedEvents
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
clearPendingUpdates();
|
|
180
|
-
};
|
|
181
|
-
this._itemDemuxer.snapshot.on(ctx, (snapshot) => {
|
|
182
|
-
clearPendingUpdates();
|
|
183
|
-
next({
|
|
184
|
-
action: import_service.EchoEvent.DatabaseAction.RESET,
|
|
185
|
-
batch: {
|
|
186
|
-
objects: snapshot.items
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
|
-
this._itemDemuxer.mutation.on(ctx, (message) => {
|
|
191
|
-
const { batch, meta } = message;
|
|
192
|
-
(0, import_invariant2.invariant)(!meta.clientTag, "Unexpected client tag in mutation message", {
|
|
193
|
-
F: __dxlog_file2,
|
|
194
|
-
L: 131,
|
|
195
|
-
S: this,
|
|
196
|
-
A: [
|
|
197
|
-
"!(meta as any).clientTag",
|
|
198
|
-
"'Unexpected client tag in mutation message'"
|
|
199
|
-
]
|
|
200
|
-
});
|
|
201
|
-
(0, import_log.log)("message", {
|
|
202
|
-
batch: batch.objects?.length,
|
|
203
|
-
meta
|
|
204
|
-
}, {
|
|
205
|
-
F: __dxlog_file2,
|
|
206
|
-
L: 132,
|
|
207
|
-
S: this,
|
|
208
|
-
C: (f, a) => f(...a)
|
|
209
|
-
});
|
|
210
|
-
const clientTag = this._clientTagMap.get([
|
|
211
|
-
message.meta.feedKey,
|
|
212
|
-
message.meta.seq
|
|
213
|
-
]);
|
|
214
|
-
batch.objects?.forEach((object) => {
|
|
215
|
-
(0, import_echo_db.setMetadataOnObject)(object, {
|
|
216
|
-
...meta
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
if (clientTag) {
|
|
220
|
-
flushPendingUpdate();
|
|
221
|
-
(0, import_echo_db.tagMutationsInBatch)(batch, clientTag, 0);
|
|
222
|
-
next({
|
|
223
|
-
clientTag,
|
|
224
|
-
feedKey: message.meta.feedKey,
|
|
225
|
-
seq: message.meta.seq,
|
|
226
|
-
batch
|
|
227
|
-
});
|
|
228
|
-
} else {
|
|
229
|
-
for (const obj of batch.objects ?? []) {
|
|
230
|
-
const newCount = (mutationsPerObject.get(obj.objectId) ?? 0) + 1;
|
|
231
|
-
mutationsPerObject.set(obj.objectId, newCount);
|
|
232
|
-
}
|
|
233
|
-
for (const obj of batch.objects ?? []) {
|
|
234
|
-
if ((mutationsPerObject.get(obj.objectId) ?? 0) < MUTATION_LIMIT_PER_OBJECT) {
|
|
235
|
-
pendingUpdates.push(obj);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
if (this._deferEvents) {
|
|
239
|
-
updateScheduler.trigger();
|
|
240
|
-
} else {
|
|
241
|
-
flushPendingUpdate();
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
async write(request) {
|
|
248
|
-
(0, import_invariant2.invariant)(!this._ctx.disposed, "Cannot write to closed DataServiceHost", {
|
|
249
|
-
F: __dxlog_file2,
|
|
250
|
-
L: 177,
|
|
251
|
-
S: this,
|
|
252
|
-
A: [
|
|
253
|
-
"!this._ctx.disposed",
|
|
254
|
-
"'Cannot write to closed DataServiceHost'"
|
|
255
|
-
]
|
|
256
|
-
});
|
|
257
|
-
(0, import_invariant2.invariant)(this._writeStream, "Cannot write mutations in readonly mode", {
|
|
258
|
-
F: __dxlog_file2,
|
|
259
|
-
L: 178,
|
|
260
|
-
S: this,
|
|
261
|
-
A: [
|
|
262
|
-
"this._writeStream",
|
|
263
|
-
"'Cannot write mutations in readonly mode'"
|
|
264
|
-
]
|
|
265
|
-
});
|
|
266
|
-
(0, import_log.log)("write", {
|
|
267
|
-
clientTag: request.clientTag,
|
|
268
|
-
objectCount: request.batch.objects?.length ?? 0
|
|
269
|
-
}, {
|
|
270
|
-
F: __dxlog_file2,
|
|
271
|
-
L: 180,
|
|
272
|
-
S: this,
|
|
273
|
-
C: (f, a) => f(...a)
|
|
274
|
-
});
|
|
275
|
-
const message = createDataMessage(request.batch);
|
|
276
|
-
const receipt = await this._writeStream.write(message, {
|
|
277
|
-
afterWrite: async (receipt2) => {
|
|
278
|
-
if (request.clientTag) {
|
|
279
|
-
(0, import_log.log)("tag", {
|
|
280
|
-
clientTag: request.clientTag,
|
|
281
|
-
feedKey: receipt2.feedKey,
|
|
282
|
-
seq: receipt2.seq
|
|
283
|
-
}, {
|
|
284
|
-
F: __dxlog_file2,
|
|
285
|
-
L: 189,
|
|
286
|
-
S: this,
|
|
287
|
-
C: (f, a) => f(...a)
|
|
288
|
-
});
|
|
289
|
-
this._clientTagMap.set([
|
|
290
|
-
receipt2.feedKey,
|
|
291
|
-
receipt2.seq
|
|
292
|
-
], request.clientTag);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
return receipt;
|
|
297
|
-
}
|
|
298
|
-
async flush() {
|
|
299
|
-
await this._flush();
|
|
300
|
-
}
|
|
301
|
-
};
|
|
302
|
-
var createDataMessage = (batch) => ({
|
|
303
|
-
batch: {
|
|
304
|
-
objects: batch.objects?.map((object) => ({
|
|
305
|
-
...object,
|
|
306
|
-
mutations: object.mutations?.map((mutation) => ({
|
|
307
|
-
...mutation,
|
|
308
|
-
meta: void 0
|
|
309
|
-
})),
|
|
310
|
-
meta: void 0
|
|
311
|
-
}))
|
|
312
|
-
}
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
// packages/core/echo/echo-pipeline/src/db-host/database-host.ts
|
|
316
|
-
var import_echo_db2 = require("@dxos/echo-db");
|
|
317
|
-
var DatabaseHost = class {
|
|
318
|
-
constructor(_outboundStream, _flush) {
|
|
319
|
-
this._outboundStream = _outboundStream;
|
|
320
|
-
this._flush = _flush;
|
|
321
|
-
}
|
|
322
|
-
get isReadOnly() {
|
|
323
|
-
return !!this._outboundStream;
|
|
324
|
-
}
|
|
325
|
-
get echoProcessor() {
|
|
326
|
-
return this._echoProcessor;
|
|
327
|
-
}
|
|
328
|
-
async open(itemManager, modelFactory) {
|
|
329
|
-
this._itemManager = itemManager;
|
|
330
|
-
this._itemManager._debugLabel = "host";
|
|
331
|
-
this._itemDemuxer = new import_echo_db2.ItemDemuxer(itemManager, modelFactory);
|
|
332
|
-
this._echoProcessor = this._itemDemuxer.open();
|
|
333
|
-
}
|
|
334
|
-
async close() {
|
|
335
|
-
}
|
|
336
|
-
getWriteStream() {
|
|
337
|
-
return this._outboundStream;
|
|
338
|
-
}
|
|
339
|
-
createSnapshot() {
|
|
340
|
-
return this._itemDemuxer.createSnapshot();
|
|
341
|
-
}
|
|
342
|
-
createDataServiceHost(opts = {}) {
|
|
343
|
-
return new DataServiceHost(this._itemManager, this._itemDemuxer, this._flush, this._outboundStream ?? void 0, opts);
|
|
344
|
-
}
|
|
345
|
-
};
|
|
346
|
-
|
|
347
|
-
// packages/core/echo/echo-pipeline/src/db-host/snapshot-manager.ts
|
|
348
|
-
var import_context2 = require("@dxos/context");
|
|
349
|
-
var import_keys = require("@dxos/keys");
|
|
350
|
-
var import_protocols2 = require("@dxos/protocols");
|
|
351
|
-
var import_blob = require("@dxos/protocols/proto/dxos/echo/blob");
|
|
352
|
-
var SpaceSnapshot = import_protocols2.schema.getCodecForType("dxos.echo.snapshot.SpaceSnapshot");
|
|
353
|
-
var SnapshotManager = class {
|
|
354
|
-
constructor(_snapshotStore, _blobStore, _blobSync) {
|
|
355
|
-
this._snapshotStore = _snapshotStore;
|
|
356
|
-
this._blobStore = _blobStore;
|
|
357
|
-
this._blobSync = _blobSync;
|
|
358
|
-
}
|
|
359
|
-
async _getBlob(blobId) {
|
|
360
|
-
const blob = await this._blobStore.get(blobId);
|
|
361
|
-
return SpaceSnapshot.decode(blob);
|
|
362
|
-
}
|
|
363
|
-
async load(ctx, id) {
|
|
364
|
-
const blobId = import_keys.PublicKey.fromHex(id).asUint8Array();
|
|
365
|
-
const blobMeta = await this._blobStore.getMeta(blobId);
|
|
366
|
-
if (blobMeta && blobMeta.state === import_blob.BlobMeta.State.FULLY_PRESENT) {
|
|
367
|
-
return this._getBlob(blobId);
|
|
368
|
-
}
|
|
369
|
-
const fallbackStore = await (0, import_context2.cancelWithContext)(ctx, this._snapshotStore.loadSnapshot(id));
|
|
370
|
-
if (fallbackStore) {
|
|
371
|
-
return fallbackStore;
|
|
372
|
-
}
|
|
373
|
-
await this._blobSync.download(ctx, blobId);
|
|
374
|
-
return this._getBlob(blobId);
|
|
375
|
-
}
|
|
376
|
-
async store(snapshot) {
|
|
377
|
-
const { id } = await this._blobStore.set(SpaceSnapshot.encode(snapshot));
|
|
378
|
-
await this._blobSync.notifyBlobAdded(id);
|
|
379
|
-
return import_keys.PublicKey.from(id).toHex();
|
|
380
|
-
}
|
|
381
|
-
};
|
|
382
|
-
|
|
383
|
-
// packages/core/echo/echo-pipeline/src/db-host/snapshot-store.ts
|
|
384
|
-
var import_crypto = require("@dxos/crypto");
|
|
385
|
-
var import_protocols3 = require("@dxos/protocols");
|
|
386
|
-
var SpaceSnapshot2 = import_protocols3.schema.getCodecForType("dxos.echo.snapshot.SpaceSnapshot");
|
|
387
|
-
var SnapshotStore = class {
|
|
388
|
-
constructor(_directory) {
|
|
389
|
-
this._directory = _directory;
|
|
390
|
-
}
|
|
391
|
-
async saveSnapshot(snapshot) {
|
|
392
|
-
const encoded = SpaceSnapshot2.encode(snapshot);
|
|
393
|
-
const key = await import_crypto.subtleCrypto.digest("SHA-256", encoded);
|
|
394
|
-
const keyString = Buffer.from(key).toString("hex");
|
|
395
|
-
const file = await this._directory.getOrCreateFile(keyString);
|
|
396
|
-
try {
|
|
397
|
-
await file.write(0, Buffer.from(encoded));
|
|
398
|
-
} finally {
|
|
399
|
-
await file.close();
|
|
400
|
-
}
|
|
401
|
-
return keyString;
|
|
402
|
-
}
|
|
403
|
-
async loadSnapshot(key) {
|
|
404
|
-
const file = await this._directory.getOrCreateFile(key);
|
|
405
|
-
try {
|
|
406
|
-
const { size } = await file.stat();
|
|
407
|
-
if (size === 0) {
|
|
408
|
-
return void 0;
|
|
409
|
-
}
|
|
410
|
-
const buffer = await file.read(0, size);
|
|
411
|
-
return SpaceSnapshot2.decode(buffer);
|
|
412
|
-
} finally {
|
|
413
|
-
await file.close();
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
async listSnapshots() {
|
|
417
|
-
const entries = await this._directory.list();
|
|
418
|
-
return await Promise.all(entries.map(async (key) => {
|
|
419
|
-
const { size } = await this._directory.getOrCreateFile(key).stat();
|
|
420
|
-
return {
|
|
421
|
-
key,
|
|
422
|
-
size
|
|
423
|
-
};
|
|
424
|
-
}));
|
|
425
|
-
}
|
|
426
|
-
};
|
|
427
|
-
|
|
428
|
-
// packages/core/echo/echo-pipeline/src/db-host/data-service.ts
|
|
429
|
-
var import_debug = require("@dxos/debug");
|
|
430
|
-
var import_invariant3 = require("@dxos/invariant");
|
|
431
|
-
var import_keys2 = require("@dxos/keys");
|
|
432
|
-
var import_log2 = require("@dxos/log");
|
|
433
|
-
var import_util2 = require("@dxos/util");
|
|
434
|
-
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/data-service.ts";
|
|
435
|
-
var DataServiceSubscriptions = class {
|
|
436
|
-
constructor() {
|
|
437
|
-
this._spaces = new import_util2.ComplexMap(import_keys2.PublicKey.hash);
|
|
438
|
-
}
|
|
439
|
-
clear() {
|
|
440
|
-
this._spaces.clear();
|
|
441
|
-
}
|
|
442
|
-
async registerSpace(spaceKey, host) {
|
|
443
|
-
(0, import_log2.log)("Registering space", {
|
|
444
|
-
spaceKey
|
|
445
|
-
}, {
|
|
446
|
-
F: __dxlog_file3,
|
|
447
|
-
L: 31,
|
|
448
|
-
S: this,
|
|
449
|
-
C: (f, a) => f(...a)
|
|
450
|
-
});
|
|
451
|
-
(0, import_invariant3.invariant)(!this._spaces.has(spaceKey), void 0, {
|
|
452
|
-
F: __dxlog_file3,
|
|
453
|
-
L: 32,
|
|
454
|
-
S: this,
|
|
455
|
-
A: [
|
|
456
|
-
"!this._spaces.has(spaceKey)",
|
|
457
|
-
""
|
|
458
|
-
]
|
|
459
|
-
});
|
|
460
|
-
await host.open();
|
|
461
|
-
this._spaces.set(spaceKey, host);
|
|
462
|
-
}
|
|
463
|
-
async unregisterSpace(spaceKey) {
|
|
464
|
-
(0, import_log2.log)("Unregistering space", {
|
|
465
|
-
spaceKey
|
|
466
|
-
}, {
|
|
467
|
-
F: __dxlog_file3,
|
|
468
|
-
L: 38,
|
|
469
|
-
S: this,
|
|
470
|
-
C: (f, a) => f(...a)
|
|
471
|
-
});
|
|
472
|
-
const host = this._spaces.get(spaceKey);
|
|
473
|
-
await host?.close();
|
|
474
|
-
this._spaces.delete(spaceKey);
|
|
475
|
-
}
|
|
476
|
-
getDataService(spaceKey) {
|
|
477
|
-
return this._spaces.get(spaceKey);
|
|
478
|
-
}
|
|
479
|
-
};
|
|
480
|
-
var DataServiceImpl = class {
|
|
481
|
-
constructor(_subscriptions) {
|
|
482
|
-
this._subscriptions = _subscriptions;
|
|
483
|
-
}
|
|
484
|
-
subscribe(request) {
|
|
485
|
-
(0, import_invariant3.invariant)(request.spaceKey, void 0, {
|
|
486
|
-
F: __dxlog_file3,
|
|
487
|
-
L: 57,
|
|
488
|
-
S: this,
|
|
489
|
-
A: [
|
|
490
|
-
"request.spaceKey",
|
|
491
|
-
""
|
|
492
|
-
]
|
|
493
|
-
});
|
|
494
|
-
const host = this._subscriptions.getDataService(request.spaceKey) ?? (0, import_debug.raise)(new Error(`space not found: ${request.spaceKey}`));
|
|
495
|
-
return host.subscribe();
|
|
496
|
-
}
|
|
497
|
-
write(request) {
|
|
498
|
-
(0, import_invariant3.invariant)(request.spaceKey, void 0, {
|
|
499
|
-
F: __dxlog_file3,
|
|
500
|
-
L: 64,
|
|
501
|
-
S: this,
|
|
502
|
-
A: [
|
|
503
|
-
"request.spaceKey",
|
|
504
|
-
""
|
|
505
|
-
]
|
|
506
|
-
});
|
|
507
|
-
(0, import_invariant3.invariant)(request.batch, void 0, {
|
|
508
|
-
F: __dxlog_file3,
|
|
509
|
-
L: 65,
|
|
510
|
-
S: this,
|
|
511
|
-
A: [
|
|
512
|
-
"request.batch",
|
|
513
|
-
""
|
|
514
|
-
]
|
|
515
|
-
});
|
|
516
|
-
const host = this._subscriptions.getDataService(request.spaceKey) ?? (0, import_debug.raise)(new Error(`space not found: ${request.spaceKey}`));
|
|
517
|
-
return host.write(request);
|
|
518
|
-
}
|
|
519
|
-
flush(request) {
|
|
520
|
-
(0, import_invariant3.invariant)(request.spaceKey, void 0, {
|
|
521
|
-
F: __dxlog_file3,
|
|
522
|
-
L: 72,
|
|
523
|
-
S: this,
|
|
524
|
-
A: [
|
|
525
|
-
"request.spaceKey",
|
|
526
|
-
""
|
|
527
|
-
]
|
|
528
|
-
});
|
|
529
|
-
const host = this._subscriptions.getDataService(request.spaceKey) ?? (0, import_debug.raise)(new Error(`space not found: ${request.spaceKey}`));
|
|
530
|
-
return host.flush();
|
|
531
|
-
}
|
|
532
|
-
};
|
|
533
|
-
|
|
534
|
-
// packages/core/echo/echo-pipeline/src/metadata/metadata-store.ts
|
|
535
|
-
var import_crc_32 = __toESM(require("crc-32"));
|
|
536
|
-
var import_async2 = require("@dxos/async");
|
|
537
|
-
var import_invariant4 = require("@dxos/invariant");
|
|
538
|
-
var import_keys3 = require("@dxos/keys");
|
|
539
|
-
var import_log3 = require("@dxos/log");
|
|
540
|
-
var import_protocols4 = require("@dxos/protocols");
|
|
541
|
-
var import_services = require("@dxos/protocols/proto/dxos/client/services");
|
|
542
|
-
var import_util3 = require("@dxos/util");
|
|
543
|
-
function _ts_decorate(decorators, target, key, desc) {
|
|
544
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
545
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
546
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
547
|
-
else
|
|
548
|
-
for (var i = decorators.length - 1; i >= 0; i--)
|
|
549
|
-
if (d = decorators[i])
|
|
550
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
551
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
552
|
-
}
|
|
553
|
-
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/metadata/metadata-store.ts";
|
|
554
|
-
var emptyEchoMetadata = () => ({
|
|
555
|
-
version: import_protocols4.STORAGE_VERSION,
|
|
556
|
-
spaces: [],
|
|
557
|
-
created: /* @__PURE__ */ new Date(),
|
|
558
|
-
updated: /* @__PURE__ */ new Date()
|
|
559
|
-
});
|
|
560
|
-
var emptyLargeSpaceMetadata = () => ({});
|
|
561
|
-
var EchoMetadata = import_protocols4.schema.getCodecForType("dxos.echo.metadata.EchoMetadata");
|
|
562
|
-
var LargeSpaceMetadata = import_protocols4.schema.getCodecForType("dxos.echo.metadata.LargeSpaceMetadata");
|
|
563
|
-
var MetadataStore = class {
|
|
564
|
-
constructor(_directory) {
|
|
565
|
-
this._directory = _directory;
|
|
566
|
-
this._metadata = emptyEchoMetadata();
|
|
567
|
-
this._spaceLargeMetadata = new import_util3.ComplexMap(import_keys3.PublicKey.hash);
|
|
568
|
-
this._metadataFile = void 0;
|
|
569
|
-
this.update = new import_async2.Event();
|
|
570
|
-
}
|
|
571
|
-
get metadata() {
|
|
572
|
-
return this._metadata;
|
|
573
|
-
}
|
|
574
|
-
get version() {
|
|
575
|
-
return this._metadata.version ?? 0;
|
|
576
|
-
}
|
|
577
|
-
/**
|
|
578
|
-
* Returns a list of currently saved spaces. The list and objects in it can be modified addSpace and
|
|
579
|
-
* addSpaceFeed functions.
|
|
580
|
-
*/
|
|
581
|
-
get spaces() {
|
|
582
|
-
return this._metadata.spaces ?? [];
|
|
583
|
-
}
|
|
584
|
-
async _readFile(file, codec2) {
|
|
585
|
-
try {
|
|
586
|
-
const { size: fileLength } = await file.stat();
|
|
587
|
-
if (fileLength < 8) {
|
|
588
|
-
return;
|
|
589
|
-
}
|
|
590
|
-
const dataSize = fromBytesInt32(await file.read(0, 4));
|
|
591
|
-
const checksum = fromBytesInt32(await file.read(4, 4));
|
|
592
|
-
(0, import_log3.log)("loaded", {
|
|
593
|
-
size: dataSize,
|
|
594
|
-
checksum,
|
|
595
|
-
name: file.filename
|
|
596
|
-
}, {
|
|
597
|
-
F: __dxlog_file4,
|
|
598
|
-
L: 78,
|
|
599
|
-
S: this,
|
|
600
|
-
C: (f, a) => f(...a)
|
|
601
|
-
});
|
|
602
|
-
if (fileLength < dataSize + 8) {
|
|
603
|
-
throw new import_protocols4.DataCorruptionError("Metadata size is smaller than expected.", {
|
|
604
|
-
fileLength,
|
|
605
|
-
dataSize
|
|
606
|
-
});
|
|
607
|
-
}
|
|
608
|
-
const data = await file.read(8, dataSize);
|
|
609
|
-
const calculatedChecksum = import_crc_32.default.buf(data);
|
|
610
|
-
if (calculatedChecksum !== checksum) {
|
|
611
|
-
throw new import_protocols4.DataCorruptionError("Metadata checksum is invalid.");
|
|
612
|
-
}
|
|
613
|
-
return codec2.decode(data);
|
|
614
|
-
} finally {
|
|
615
|
-
await file.close();
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
async _writeFile(file, codec2, data) {
|
|
619
|
-
const encoded = (0, import_util3.arrayToBuffer)(codec2.encode(data));
|
|
620
|
-
const checksum = import_crc_32.default.buf(encoded);
|
|
621
|
-
const result = Buffer.alloc(8 + encoded.length);
|
|
622
|
-
result.writeInt32LE(encoded.length, 0);
|
|
623
|
-
result.writeInt32LE(checksum, 4);
|
|
624
|
-
encoded.copy(result, 8);
|
|
625
|
-
await file.write(0, result);
|
|
626
|
-
(0, import_log3.log)("saved", {
|
|
627
|
-
size: encoded.length,
|
|
628
|
-
checksum
|
|
629
|
-
}, {
|
|
630
|
-
F: __dxlog_file4,
|
|
631
|
-
L: 110,
|
|
632
|
-
S: this,
|
|
633
|
-
C: (f, a) => f(...a)
|
|
634
|
-
});
|
|
635
|
-
}
|
|
636
|
-
async close() {
|
|
637
|
-
await this.flush();
|
|
638
|
-
await this._metadataFile?.close();
|
|
639
|
-
this._metadataFile = void 0;
|
|
640
|
-
this._metadata = emptyEchoMetadata();
|
|
641
|
-
this._spaceLargeMetadata.clear();
|
|
642
|
-
}
|
|
643
|
-
/**
|
|
644
|
-
* Loads metadata from persistent storage.
|
|
645
|
-
*/
|
|
646
|
-
async load() {
|
|
647
|
-
if (!this._metadataFile || this._metadataFile.closed) {
|
|
648
|
-
this._metadataFile = this._directory.getOrCreateFile("EchoMetadata");
|
|
649
|
-
}
|
|
650
|
-
try {
|
|
651
|
-
const metadata = await this._readFile(this._metadataFile, EchoMetadata);
|
|
652
|
-
if (metadata) {
|
|
653
|
-
this._metadata = metadata;
|
|
654
|
-
}
|
|
655
|
-
this._metadata.spaces?.forEach((space) => {
|
|
656
|
-
space.state ??= import_services.SpaceState.ACTIVE;
|
|
657
|
-
});
|
|
658
|
-
} catch (err) {
|
|
659
|
-
import_log3.log.error("failed to load metadata", {
|
|
660
|
-
err
|
|
661
|
-
}, {
|
|
662
|
-
F: __dxlog_file4,
|
|
663
|
-
L: 141,
|
|
664
|
-
S: this,
|
|
665
|
-
C: (f, a) => f(...a)
|
|
666
|
-
});
|
|
667
|
-
this._metadata = emptyEchoMetadata();
|
|
668
|
-
}
|
|
669
|
-
await (0, import_util3.forEachAsync)([
|
|
670
|
-
this._metadata.identity?.haloSpace.key,
|
|
671
|
-
...this._metadata.spaces?.map((space) => space.key) ?? []
|
|
672
|
-
].filter(import_util3.isNotNullOrUndefined), async (key) => {
|
|
673
|
-
try {
|
|
674
|
-
await this._loadSpaceLargeMetadata(key);
|
|
675
|
-
} catch (err) {
|
|
676
|
-
import_log3.log.error("failed to load space large metadata", {
|
|
677
|
-
err
|
|
678
|
-
}, {
|
|
679
|
-
F: __dxlog_file4,
|
|
680
|
-
L: 153,
|
|
681
|
-
S: this,
|
|
682
|
-
C: (f, a) => f(...a)
|
|
683
|
-
});
|
|
684
|
-
}
|
|
685
|
-
});
|
|
686
|
-
}
|
|
687
|
-
async _save() {
|
|
688
|
-
const data = {
|
|
689
|
-
...this._metadata,
|
|
690
|
-
version: import_protocols4.STORAGE_VERSION,
|
|
691
|
-
created: this._metadata.created ?? /* @__PURE__ */ new Date(),
|
|
692
|
-
updated: /* @__PURE__ */ new Date()
|
|
693
|
-
};
|
|
694
|
-
this.update.emit(data);
|
|
695
|
-
const file = this._directory.getOrCreateFile("EchoMetadata");
|
|
696
|
-
await this._writeFile(file, EchoMetadata, data);
|
|
697
|
-
}
|
|
698
|
-
async _loadSpaceLargeMetadata(key) {
|
|
699
|
-
const file = this._directory.getOrCreateFile(`space_${key.toHex()}_large`);
|
|
700
|
-
try {
|
|
701
|
-
const metadata = await this._readFile(file, LargeSpaceMetadata);
|
|
702
|
-
if (metadata) {
|
|
703
|
-
this._spaceLargeMetadata.set(key, metadata);
|
|
704
|
-
}
|
|
705
|
-
} catch (err) {
|
|
706
|
-
import_log3.log.error("failed to load space large metadata", {
|
|
707
|
-
err
|
|
708
|
-
}, {
|
|
709
|
-
F: __dxlog_file4,
|
|
710
|
-
L: 182,
|
|
711
|
-
S: this,
|
|
712
|
-
C: (f, a) => f(...a)
|
|
713
|
-
});
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
async _saveSpaceLargeMetadata(key) {
|
|
717
|
-
const data = this._getLargeSpaceMetadata(key);
|
|
718
|
-
const file = this._directory.getOrCreateFile(`space_${key.toHex()}_large`);
|
|
719
|
-
await this._writeFile(file, LargeSpaceMetadata, data);
|
|
720
|
-
}
|
|
721
|
-
async flush() {
|
|
722
|
-
await this._directory.flush();
|
|
723
|
-
}
|
|
724
|
-
_getSpace(spaceKey) {
|
|
725
|
-
if (this._metadata.identity?.haloSpace.key.equals(spaceKey)) {
|
|
726
|
-
return this._metadata.identity.haloSpace;
|
|
727
|
-
}
|
|
728
|
-
const space = this.spaces.find((space2) => space2.key === spaceKey);
|
|
729
|
-
(0, import_invariant4.invariant)(space, "Space not found", {
|
|
730
|
-
F: __dxlog_file4,
|
|
731
|
-
L: 204,
|
|
732
|
-
S: this,
|
|
733
|
-
A: [
|
|
734
|
-
"space",
|
|
735
|
-
"'Space not found'"
|
|
736
|
-
]
|
|
737
|
-
});
|
|
738
|
-
return space;
|
|
739
|
-
}
|
|
740
|
-
_getLargeSpaceMetadata(key) {
|
|
741
|
-
let entry = this._spaceLargeMetadata.get(key);
|
|
742
|
-
if (entry) {
|
|
743
|
-
return entry;
|
|
744
|
-
}
|
|
745
|
-
entry = emptyLargeSpaceMetadata();
|
|
746
|
-
this._spaceLargeMetadata.set(key, entry);
|
|
747
|
-
return entry;
|
|
748
|
-
}
|
|
749
|
-
/**
|
|
750
|
-
* Clears storage - doesn't work for now.
|
|
751
|
-
*/
|
|
752
|
-
async clear() {
|
|
753
|
-
(0, import_log3.log)("clearing all metadata", void 0, {
|
|
754
|
-
F: __dxlog_file4,
|
|
755
|
-
L: 223,
|
|
756
|
-
S: this,
|
|
757
|
-
C: (f, a) => f(...a)
|
|
758
|
-
});
|
|
759
|
-
await this._directory.delete();
|
|
760
|
-
this._metadata = emptyEchoMetadata();
|
|
761
|
-
}
|
|
762
|
-
getIdentityRecord() {
|
|
763
|
-
return this._metadata.identity;
|
|
764
|
-
}
|
|
765
|
-
async setIdentityRecord(record) {
|
|
766
|
-
(0, import_invariant4.invariant)(!this._metadata.identity, "Cannot overwrite existing identity in metadata", {
|
|
767
|
-
F: __dxlog_file4,
|
|
768
|
-
L: 233,
|
|
769
|
-
S: this,
|
|
770
|
-
A: [
|
|
771
|
-
"!this._metadata.identity",
|
|
772
|
-
"'Cannot overwrite existing identity in metadata'"
|
|
773
|
-
]
|
|
774
|
-
});
|
|
775
|
-
this._metadata.identity = record;
|
|
776
|
-
await this._save();
|
|
777
|
-
await this.flush();
|
|
778
|
-
}
|
|
779
|
-
async addSpace(record) {
|
|
780
|
-
(0, import_invariant4.invariant)(!(this._metadata.spaces ?? []).find((space) => space.key === record.key), "Cannot overwrite existing space in metadata", {
|
|
781
|
-
F: __dxlog_file4,
|
|
782
|
-
L: 241,
|
|
783
|
-
S: this,
|
|
784
|
-
A: [
|
|
785
|
-
"!(this._metadata.spaces ?? []).find((space) => space.key === record.key)",
|
|
786
|
-
"'Cannot overwrite existing space in metadata'"
|
|
787
|
-
]
|
|
788
|
-
});
|
|
789
|
-
(this._metadata.spaces ??= []).push(record);
|
|
790
|
-
await this._save();
|
|
791
|
-
await this.flush();
|
|
792
|
-
}
|
|
793
|
-
async setSpaceDataLatestTimeframe(spaceKey, timeframe) {
|
|
794
|
-
this._getSpace(spaceKey).dataTimeframe = timeframe;
|
|
795
|
-
await this._save();
|
|
796
|
-
}
|
|
797
|
-
async setSpaceControlLatestTimeframe(spaceKey, timeframe) {
|
|
798
|
-
this._getSpace(spaceKey).controlTimeframe = timeframe;
|
|
799
|
-
await this._save();
|
|
800
|
-
await this.flush();
|
|
801
|
-
}
|
|
802
|
-
async setCache(spaceKey, cache) {
|
|
803
|
-
this._getSpace(spaceKey).cache = cache;
|
|
804
|
-
await this._save();
|
|
805
|
-
}
|
|
806
|
-
async setWritableFeedKeys(spaceKey, controlFeedKey, dataFeedKey) {
|
|
807
|
-
const space = this._getSpace(spaceKey);
|
|
808
|
-
space.controlFeedKey = controlFeedKey;
|
|
809
|
-
space.dataFeedKey = dataFeedKey;
|
|
810
|
-
await this._save();
|
|
811
|
-
await this.flush();
|
|
812
|
-
}
|
|
813
|
-
async setSpaceState(spaceKey, state) {
|
|
814
|
-
this._getSpace(spaceKey).state = state;
|
|
815
|
-
await this._save();
|
|
816
|
-
await this.flush();
|
|
817
|
-
}
|
|
818
|
-
getSpaceControlPipelineSnapshot(spaceKey) {
|
|
819
|
-
return this._getLargeSpaceMetadata(spaceKey).controlPipelineSnapshot;
|
|
820
|
-
}
|
|
821
|
-
async setSpaceControlPipelineSnapshot(spaceKey, snapshot) {
|
|
822
|
-
this._getLargeSpaceMetadata(spaceKey).controlPipelineSnapshot = snapshot;
|
|
823
|
-
await this._saveSpaceLargeMetadata(spaceKey);
|
|
824
|
-
await this.flush();
|
|
825
|
-
}
|
|
826
|
-
};
|
|
827
|
-
_ts_decorate([
|
|
828
|
-
import_async2.synchronized
|
|
829
|
-
], MetadataStore.prototype, "load", null);
|
|
830
|
-
_ts_decorate([
|
|
831
|
-
import_async2.synchronized
|
|
832
|
-
], MetadataStore.prototype, "_save", null);
|
|
833
|
-
_ts_decorate([
|
|
834
|
-
import_async2.synchronized
|
|
835
|
-
], MetadataStore.prototype, "_saveSpaceLargeMetadata", null);
|
|
836
|
-
var fromBytesInt32 = (buf) => buf.readInt32LE(0);
|
|
837
|
-
|
|
838
|
-
// packages/core/echo/echo-pipeline/src/space/auth.ts
|
|
839
|
-
var import_async3 = require("@dxos/async");
|
|
840
|
-
var import_context3 = require("@dxos/context");
|
|
841
|
-
var import_crypto2 = require("@dxos/crypto");
|
|
842
|
-
var import_invariant5 = require("@dxos/invariant");
|
|
843
|
-
var import_log4 = require("@dxos/log");
|
|
844
|
-
var import_protocols5 = require("@dxos/protocols");
|
|
845
|
-
var import_teleport = require("@dxos/teleport");
|
|
846
|
-
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/auth.ts";
|
|
847
|
-
var AuthExtension = class extends import_teleport.RpcExtension {
|
|
848
|
-
constructor(_authParams) {
|
|
849
|
-
super({
|
|
850
|
-
requested: {
|
|
851
|
-
AuthService: import_protocols5.schema.getService("dxos.mesh.teleport.auth.AuthService")
|
|
852
|
-
},
|
|
853
|
-
exposed: {
|
|
854
|
-
AuthService: import_protocols5.schema.getService("dxos.mesh.teleport.auth.AuthService")
|
|
855
|
-
},
|
|
856
|
-
timeout: 60 * 1e3
|
|
857
|
-
});
|
|
858
|
-
this._authParams = _authParams;
|
|
859
|
-
this._ctx = new import_context3.Context({
|
|
860
|
-
onError: (err) => {
|
|
861
|
-
import_log4.log.catch(err, void 0, {
|
|
862
|
-
F: __dxlog_file5,
|
|
863
|
-
L: 28,
|
|
864
|
-
S: this,
|
|
865
|
-
C: (f, a) => f(...a)
|
|
866
|
-
});
|
|
867
|
-
}
|
|
868
|
-
});
|
|
869
|
-
}
|
|
870
|
-
async getHandlers() {
|
|
871
|
-
return {
|
|
872
|
-
AuthService: {
|
|
873
|
-
authenticate: async ({ challenge }) => {
|
|
874
|
-
try {
|
|
875
|
-
const credential = await this._authParams.provider(challenge);
|
|
876
|
-
if (!credential) {
|
|
877
|
-
throw new Error("auth rejected");
|
|
878
|
-
}
|
|
879
|
-
return {
|
|
880
|
-
credential
|
|
881
|
-
};
|
|
882
|
-
} catch (err) {
|
|
883
|
-
import_log4.log.error("failed to generate auth credentials", err, {
|
|
884
|
-
F: __dxlog_file5,
|
|
885
|
-
L: 55,
|
|
886
|
-
S: this,
|
|
887
|
-
C: (f, a) => f(...a)
|
|
888
|
-
});
|
|
889
|
-
throw new Error("auth rejected");
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
};
|
|
894
|
-
}
|
|
895
|
-
async onOpen(context) {
|
|
896
|
-
await super.onOpen(context);
|
|
897
|
-
(0, import_async3.scheduleTask)(this._ctx, async () => {
|
|
898
|
-
try {
|
|
899
|
-
const challenge = (0, import_crypto2.randomBytes)(32);
|
|
900
|
-
const { credential } = await this.rpc.AuthService.authenticate({
|
|
901
|
-
challenge
|
|
902
|
-
});
|
|
903
|
-
(0, import_invariant5.invariant)(credential?.length > 0, "invalid credential", {
|
|
904
|
-
F: __dxlog_file5,
|
|
905
|
-
L: 69,
|
|
906
|
-
S: this,
|
|
907
|
-
A: [
|
|
908
|
-
"credential?.length > 0",
|
|
909
|
-
"'invalid credential'"
|
|
910
|
-
]
|
|
911
|
-
});
|
|
912
|
-
const success = await this._authParams.verifier(challenge, credential);
|
|
913
|
-
(0, import_invariant5.invariant)(success, "credential not verified", {
|
|
914
|
-
F: __dxlog_file5,
|
|
915
|
-
L: 71,
|
|
916
|
-
S: this,
|
|
917
|
-
A: [
|
|
918
|
-
"success",
|
|
919
|
-
"'credential not verified'"
|
|
920
|
-
]
|
|
921
|
-
});
|
|
922
|
-
(0, import_async3.runInContext)(this._ctx, () => this._authParams.onAuthSuccess());
|
|
923
|
-
} catch (err) {
|
|
924
|
-
(0, import_log4.log)("auth failed", err, {
|
|
925
|
-
F: __dxlog_file5,
|
|
926
|
-
L: 74,
|
|
927
|
-
S: this,
|
|
928
|
-
C: (f, a) => f(...a)
|
|
929
|
-
});
|
|
930
|
-
this.close();
|
|
931
|
-
this._authParams.onAuthFailure();
|
|
932
|
-
}
|
|
933
|
-
});
|
|
934
|
-
}
|
|
935
|
-
async onClose() {
|
|
936
|
-
await this._ctx.dispose();
|
|
937
|
-
await super.onClose();
|
|
938
|
-
}
|
|
939
|
-
async onAbort() {
|
|
940
|
-
await this._ctx.dispose();
|
|
941
|
-
await super.onAbort();
|
|
942
|
-
}
|
|
943
|
-
};
|
|
944
|
-
|
|
945
|
-
// packages/core/echo/echo-pipeline/src/space/space.ts
|
|
946
|
-
var import_async8 = require("@dxos/async");
|
|
947
|
-
var import_invariant9 = require("@dxos/invariant");
|
|
948
|
-
var import_log10 = require("@dxos/log");
|
|
949
|
-
var import_credentials4 = require("@dxos/protocols/proto/dxos/halo/credentials");
|
|
950
|
-
var import_tracing3 = require("@dxos/tracing");
|
|
951
|
-
var import_util7 = require("@dxos/util");
|
|
952
|
-
|
|
953
|
-
// packages/core/echo/echo-pipeline/src/space/control-pipeline.ts
|
|
954
|
-
var import_async6 = require("@dxos/async");
|
|
955
|
-
var import_context5 = require("@dxos/context");
|
|
956
|
-
var import_credentials = require("@dxos/credentials");
|
|
957
|
-
var import_keys5 = require("@dxos/keys");
|
|
958
|
-
var import_log8 = require("@dxos/log");
|
|
959
|
-
var import_credentials2 = require("@dxos/protocols/proto/dxos/halo/credentials");
|
|
960
|
-
var import_timeframe3 = require("@dxos/timeframe");
|
|
961
|
-
var import_tracing = require("@dxos/tracing");
|
|
962
|
-
var import_util5 = require("@dxos/util");
|
|
963
|
-
|
|
964
|
-
// packages/core/echo/echo-pipeline/src/pipeline/pipeline.ts
|
|
965
|
-
var import_async5 = require("@dxos/async");
|
|
966
|
-
var import_context4 = require("@dxos/context");
|
|
967
|
-
var import_debug3 = require("@dxos/debug");
|
|
968
|
-
var import_feed_store = require("@dxos/feed-store");
|
|
969
|
-
var import_invariant7 = require("@dxos/invariant");
|
|
970
|
-
var import_keys4 = require("@dxos/keys");
|
|
971
|
-
var import_log7 = require("@dxos/log");
|
|
972
|
-
var import_timeframe2 = require("@dxos/timeframe");
|
|
973
|
-
var import_util4 = require("@dxos/util");
|
|
974
|
-
|
|
975
|
-
// packages/core/echo/echo-pipeline/src/pipeline/message-selector.ts
|
|
976
|
-
var import_invariant6 = require("@dxos/invariant");
|
|
977
|
-
var import_log5 = require("@dxos/log");
|
|
978
|
-
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/pipeline/message-selector.ts";
|
|
979
|
-
var createMessageSelector = (timeframeClock) => {
|
|
980
|
-
return (messages) => {
|
|
981
|
-
for (let i = 0; i < messages.length; i++) {
|
|
982
|
-
const { data: { timeframe } } = messages[i];
|
|
983
|
-
(0, import_invariant6.invariant)(timeframe, void 0, {
|
|
984
|
-
F: __dxlog_file6,
|
|
985
|
-
L: 25,
|
|
986
|
-
S: void 0,
|
|
987
|
-
A: [
|
|
988
|
-
"timeframe",
|
|
989
|
-
""
|
|
990
|
-
]
|
|
991
|
-
});
|
|
992
|
-
if (!timeframeClock.hasGaps(timeframe)) {
|
|
993
|
-
return i;
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
(0, import_log5.log)("Skipping...", void 0, {
|
|
997
|
-
F: __dxlog_file6,
|
|
998
|
-
L: 33,
|
|
999
|
-
S: void 0,
|
|
1000
|
-
C: (f, a) => f(...a)
|
|
1001
|
-
});
|
|
1002
|
-
};
|
|
1003
|
-
};
|
|
1004
|
-
|
|
1005
|
-
// packages/core/echo/echo-pipeline/src/pipeline/timeframe-clock.ts
|
|
1006
|
-
var import_async4 = require("@dxos/async");
|
|
1007
|
-
var import_debug2 = require("@dxos/debug");
|
|
1008
|
-
var import_log6 = require("@dxos/log");
|
|
1009
|
-
var import_timeframe = require("@dxos/timeframe");
|
|
1010
|
-
function _ts_decorate2(decorators, target, key, desc) {
|
|
1011
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1012
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
1013
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
1014
|
-
else
|
|
1015
|
-
for (var i = decorators.length - 1; i >= 0; i--)
|
|
1016
|
-
if (d = decorators[i])
|
|
1017
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1018
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1019
|
-
}
|
|
1020
|
-
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/pipeline/timeframe-clock.ts";
|
|
1021
|
-
var mapFeedIndexesToTimeframe = (indexes) => new import_timeframe.Timeframe(indexes.map(({ feedKey, index }) => [
|
|
1022
|
-
feedKey,
|
|
1023
|
-
index
|
|
1024
|
-
]));
|
|
1025
|
-
var startAfter = (timeframe) => timeframe.frames().map(([feedKey, index]) => ({
|
|
1026
|
-
feedKey,
|
|
1027
|
-
index: index + 1
|
|
1028
|
-
}));
|
|
1029
|
-
var TimeframeClock = class {
|
|
1030
|
-
constructor(_timeframe = new import_timeframe.Timeframe()) {
|
|
1031
|
-
this._timeframe = _timeframe;
|
|
1032
|
-
this.update = new import_async4.Event();
|
|
1033
|
-
this._pendingTimeframe = _timeframe;
|
|
1034
|
-
}
|
|
1035
|
-
/**
|
|
1036
|
-
* Timeframe that was processed by ECHO.
|
|
1037
|
-
*/
|
|
1038
|
-
get timeframe() {
|
|
1039
|
-
return this._timeframe;
|
|
1040
|
-
}
|
|
1041
|
-
/**
|
|
1042
|
-
* Timeframe that is currently being processed by ECHO.
|
|
1043
|
-
* Will be equal to `timeframe` after the processing is complete.
|
|
1044
|
-
*/
|
|
1045
|
-
get pendingTimeframe() {
|
|
1046
|
-
return this._pendingTimeframe;
|
|
1047
|
-
}
|
|
1048
|
-
setTimeframe(timeframe) {
|
|
1049
|
-
this._timeframe = timeframe;
|
|
1050
|
-
this._pendingTimeframe = timeframe;
|
|
1051
|
-
this.update.emit(this._timeframe);
|
|
1052
|
-
}
|
|
1053
|
-
updatePendingTimeframe(key, seq) {
|
|
1054
|
-
this._pendingTimeframe = import_timeframe.Timeframe.merge(this._pendingTimeframe, new import_timeframe.Timeframe([
|
|
1055
|
-
[
|
|
1056
|
-
key,
|
|
1057
|
-
seq
|
|
1058
|
-
]
|
|
1059
|
-
]));
|
|
1060
|
-
}
|
|
1061
|
-
updateTimeframe() {
|
|
1062
|
-
this._timeframe = this._pendingTimeframe;
|
|
1063
|
-
this.update.emit(this._timeframe);
|
|
1064
|
-
}
|
|
1065
|
-
hasGaps(timeframe) {
|
|
1066
|
-
const gaps = import_timeframe.Timeframe.dependencies(timeframe, this._timeframe);
|
|
1067
|
-
return !gaps.isEmpty();
|
|
1068
|
-
}
|
|
1069
|
-
async waitUntilReached(target) {
|
|
1070
|
-
(0, import_log6.log)("waitUntilReached", {
|
|
1071
|
-
target,
|
|
1072
|
-
current: this._timeframe
|
|
1073
|
-
}, {
|
|
1074
|
-
F: __dxlog_file7,
|
|
1075
|
-
L: 70,
|
|
1076
|
-
S: this,
|
|
1077
|
-
C: (f, a) => f(...a)
|
|
1078
|
-
});
|
|
1079
|
-
await this.update.waitForCondition(() => {
|
|
1080
|
-
(0, import_log6.log)("check if reached", {
|
|
1081
|
-
target,
|
|
1082
|
-
current: this._timeframe,
|
|
1083
|
-
deps: import_timeframe.Timeframe.dependencies(target, this._timeframe)
|
|
1084
|
-
}, {
|
|
1085
|
-
F: __dxlog_file7,
|
|
1086
|
-
L: 72,
|
|
1087
|
-
S: this,
|
|
1088
|
-
C: (f, a) => f(...a)
|
|
1089
|
-
});
|
|
1090
|
-
return import_timeframe.Timeframe.dependencies(target, this._timeframe).isEmpty();
|
|
1091
|
-
});
|
|
1092
|
-
}
|
|
1093
|
-
};
|
|
1094
|
-
_ts_decorate2([
|
|
1095
|
-
(0, import_debug2.timed)(5e3)
|
|
1096
|
-
], TimeframeClock.prototype, "waitUntilReached", null);
|
|
1097
|
-
|
|
1098
|
-
// packages/core/echo/echo-pipeline/src/pipeline/pipeline.ts
|
|
1099
|
-
function _ts_decorate3(decorators, target, key, desc) {
|
|
1100
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1101
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
1102
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
1103
|
-
else
|
|
1104
|
-
for (var i = decorators.length - 1; i >= 0; i--)
|
|
1105
|
-
if (d = decorators[i])
|
|
1106
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1107
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1108
|
-
}
|
|
1109
|
-
var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/pipeline/pipeline.ts";
|
|
1110
|
-
var PipelineState = class {
|
|
1111
|
-
constructor(_feeds, _timeframeClock) {
|
|
1112
|
-
this._feeds = _feeds;
|
|
1113
|
-
this._timeframeClock = _timeframeClock;
|
|
1114
|
-
this._ctx = new import_context4.Context();
|
|
1115
|
-
this.timeframeUpdate = this._timeframeClock.update;
|
|
1116
|
-
this.stalled = new import_async5.Event();
|
|
1117
|
-
this._startTimeframe = new import_timeframe2.Timeframe();
|
|
1118
|
-
this._reachedTarget = false;
|
|
1119
|
-
}
|
|
1120
|
-
/**
|
|
1121
|
-
* Latest theoretical timeframe based on the last mutation in each feed.
|
|
1122
|
-
* NOTE: This might never be reached if the mutation dependencies
|
|
1123
|
-
*/
|
|
1124
|
-
// TODO(dmaretskyi): Rename `totalTimeframe`? or `lastTimeframe`.
|
|
1125
|
-
get endTimeframe() {
|
|
1126
|
-
return mapFeedIndexesToTimeframe(Array.from(this._feeds.values()).filter((feed) => feed.length > 0).map((feed) => ({
|
|
1127
|
-
feedKey: feed.key,
|
|
1128
|
-
index: feed.length - 1
|
|
1129
|
-
})));
|
|
1130
|
-
}
|
|
1131
|
-
get startTimeframe() {
|
|
1132
|
-
return this._startTimeframe;
|
|
1133
|
-
}
|
|
1134
|
-
get timeframe() {
|
|
1135
|
-
return this._timeframeClock.timeframe;
|
|
1136
|
-
}
|
|
1137
|
-
get pendingTimeframe() {
|
|
1138
|
-
return this._timeframeClock.pendingTimeframe;
|
|
1139
|
-
}
|
|
1140
|
-
get targetTimeframe() {
|
|
1141
|
-
return this._targetTimeframe ? this._targetTimeframe : new import_timeframe2.Timeframe();
|
|
1142
|
-
}
|
|
1143
|
-
get reachedTarget() {
|
|
1144
|
-
return this._reachedTarget;
|
|
1145
|
-
}
|
|
1146
|
-
get feeds() {
|
|
1147
|
-
return Array.from(this._feeds.values());
|
|
1148
|
-
}
|
|
1149
|
-
async waitUntilTimeframe(target) {
|
|
1150
|
-
await this._timeframeClock.waitUntilReached(target);
|
|
1151
|
-
}
|
|
1152
|
-
setTargetTimeframe(target) {
|
|
1153
|
-
this._targetTimeframe = target;
|
|
1154
|
-
}
|
|
1155
|
-
/**
|
|
1156
|
-
* Wait until the pipeline processes all messages in the feed and reaches the target timeframe if that is set.
|
|
1157
|
-
*
|
|
1158
|
-
* This function will resolve immediately if the pipeline is stalled.
|
|
1159
|
-
*
|
|
1160
|
-
* @param timeout Timeout in milliseconds to specify the maximum wait time.
|
|
1161
|
-
*/
|
|
1162
|
-
async waitUntilReachedTargetTimeframe({ ctx = new import_context4.Context(), timeout, breakOnStall = true } = {}) {
|
|
1163
|
-
(0, import_log7.log)("waitUntilReachedTargetTimeframe", {
|
|
1164
|
-
timeout,
|
|
1165
|
-
current: this.timeframe,
|
|
1166
|
-
target: this.targetTimeframe
|
|
1167
|
-
}, {
|
|
1168
|
-
F: __dxlog_file8,
|
|
1169
|
-
L: 133,
|
|
1170
|
-
S: this,
|
|
1171
|
-
C: (f, a) => f(...a)
|
|
1172
|
-
});
|
|
1173
|
-
this._reachedTargetPromise ??= Promise.race([
|
|
1174
|
-
this._timeframeClock.update.waitForCondition(() => {
|
|
1175
|
-
return import_timeframe2.Timeframe.dependencies(this.targetTimeframe, this.timeframe).isEmpty();
|
|
1176
|
-
}),
|
|
1177
|
-
...breakOnStall ? [
|
|
1178
|
-
this.stalled.discardParameter().waitForCount(1)
|
|
1179
|
-
] : []
|
|
1180
|
-
]);
|
|
1181
|
-
let done = false;
|
|
1182
|
-
if (timeout) {
|
|
1183
|
-
return Promise.race([
|
|
1184
|
-
(0, import_context4.rejectOnDispose)(ctx),
|
|
1185
|
-
(0, import_context4.rejectOnDispose)(this._ctx),
|
|
1186
|
-
this._reachedTargetPromise.then(() => {
|
|
1187
|
-
done = true;
|
|
1188
|
-
this._reachedTarget = true;
|
|
1189
|
-
}),
|
|
1190
|
-
(0, import_async5.sleepWithContext)(this._ctx, timeout).then(() => {
|
|
1191
|
-
if (done) {
|
|
1192
|
-
return;
|
|
1193
|
-
}
|
|
1194
|
-
import_log7.log.warn("waitUntilReachedTargetTimeframe timed out", {
|
|
1195
|
-
timeout,
|
|
1196
|
-
current: this.timeframe,
|
|
1197
|
-
target: this.targetTimeframe,
|
|
1198
|
-
dependencies: import_timeframe2.Timeframe.dependencies(this.targetTimeframe, this.timeframe)
|
|
1199
|
-
}, {
|
|
1200
|
-
F: __dxlog_file8,
|
|
1201
|
-
L: 161,
|
|
1202
|
-
S: this,
|
|
1203
|
-
C: (f, a) => f(...a)
|
|
1204
|
-
});
|
|
1205
|
-
})
|
|
1206
|
-
]);
|
|
1207
|
-
} else {
|
|
1208
|
-
return this._reachedTargetPromise;
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
|
-
};
|
|
1212
|
-
var Pipeline = class {
|
|
1213
|
-
constructor() {
|
|
1214
|
-
this._timeframeClock = new TimeframeClock(new import_timeframe2.Timeframe());
|
|
1215
|
-
this._feeds = new import_util4.ComplexMap(import_keys4.PublicKey.hash);
|
|
1216
|
-
// External state accessor.
|
|
1217
|
-
this._state = new PipelineState(this._feeds, this._timeframeClock);
|
|
1218
|
-
// Waits for the message consumer to process the message and yield control back to the pipeline.
|
|
1219
|
-
this._processingTrigger = new import_async5.Trigger().wake();
|
|
1220
|
-
this._pauseTrigger = new import_async5.Trigger().wake();
|
|
1221
|
-
// Pending downloads.
|
|
1222
|
-
this._downloads = new import_util4.ComplexMap((value) => import_keys4.PublicKey.hash(value.key));
|
|
1223
|
-
this._isStopping = false;
|
|
1224
|
-
this._isStarted = false;
|
|
1225
|
-
this._isBeingConsumed = false;
|
|
1226
|
-
this._isPaused = false;
|
|
1227
|
-
}
|
|
1228
|
-
get state() {
|
|
1229
|
-
return this._state;
|
|
1230
|
-
}
|
|
1231
|
-
get writer() {
|
|
1232
|
-
(0, import_invariant7.invariant)(this._writer, "Writer not set.", {
|
|
1233
|
-
F: __dxlog_file8,
|
|
1234
|
-
L: 242,
|
|
1235
|
-
S: this,
|
|
1236
|
-
A: [
|
|
1237
|
-
"this._writer",
|
|
1238
|
-
"'Writer not set.'"
|
|
1239
|
-
]
|
|
1240
|
-
});
|
|
1241
|
-
return this._writer;
|
|
1242
|
-
}
|
|
1243
|
-
hasFeed(feedKey) {
|
|
1244
|
-
return this._feeds.has(feedKey);
|
|
1245
|
-
}
|
|
1246
|
-
getFeeds() {
|
|
1247
|
-
return this._feedSetIterator.feeds;
|
|
1248
|
-
}
|
|
1249
|
-
// NOTE: This cannot be synchronized with `stop` because stop waits for the mutation processing to complete,
|
|
1250
|
-
// which might be opening feeds during the mutation processing, which w
|
|
1251
|
-
async addFeed(feed) {
|
|
1252
|
-
this._feeds.set(feed.key, feed);
|
|
1253
|
-
if (this._feedSetIterator) {
|
|
1254
|
-
await this._feedSetIterator.addFeed(feed);
|
|
1255
|
-
}
|
|
1256
|
-
if (this._isStarted && !this._isPaused) {
|
|
1257
|
-
this._setFeedDownloadState(feed);
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1260
|
-
setWriteFeed(feed) {
|
|
1261
|
-
(0, import_invariant7.invariant)(!this._writer, "Writer already set.", {
|
|
1262
|
-
F: __dxlog_file8,
|
|
1263
|
-
L: 269,
|
|
1264
|
-
S: this,
|
|
1265
|
-
A: [
|
|
1266
|
-
"!this._writer",
|
|
1267
|
-
"'Writer already set.'"
|
|
1268
|
-
]
|
|
1269
|
-
});
|
|
1270
|
-
(0, import_invariant7.invariant)(feed.properties.writable, "Feed must be writable.", {
|
|
1271
|
-
F: __dxlog_file8,
|
|
1272
|
-
L: 270,
|
|
1273
|
-
S: this,
|
|
1274
|
-
A: [
|
|
1275
|
-
"feed.properties.writable",
|
|
1276
|
-
"'Feed must be writable.'"
|
|
1277
|
-
]
|
|
1278
|
-
});
|
|
1279
|
-
this._writer = createMappedFeedWriter((payload) => ({
|
|
1280
|
-
timeframe: this._timeframeClock.timeframe,
|
|
1281
|
-
payload
|
|
1282
|
-
}), feed.createFeedWriter());
|
|
1283
|
-
}
|
|
1284
|
-
async start() {
|
|
1285
|
-
(0, import_invariant7.invariant)(!this._isStarted, "Pipeline is already started.", {
|
|
1286
|
-
F: __dxlog_file8,
|
|
1287
|
-
L: 283,
|
|
1288
|
-
S: this,
|
|
1289
|
-
A: [
|
|
1290
|
-
"!this._isStarted",
|
|
1291
|
-
"'Pipeline is already started.'"
|
|
1292
|
-
]
|
|
1293
|
-
});
|
|
1294
|
-
(0, import_log7.log)("starting...", void 0, {
|
|
1295
|
-
F: __dxlog_file8,
|
|
1296
|
-
L: 284,
|
|
1297
|
-
S: this,
|
|
1298
|
-
C: (f, a) => f(...a)
|
|
1299
|
-
});
|
|
1300
|
-
await this._initIterator();
|
|
1301
|
-
await this._feedSetIterator.open();
|
|
1302
|
-
this._isStarted = true;
|
|
1303
|
-
(0, import_log7.log)("started", void 0, {
|
|
1304
|
-
F: __dxlog_file8,
|
|
1305
|
-
L: 288,
|
|
1306
|
-
S: this,
|
|
1307
|
-
C: (f, a) => f(...a)
|
|
1308
|
-
});
|
|
1309
|
-
if (!this._isPaused) {
|
|
1310
|
-
for (const feed of this._feeds.values()) {
|
|
1311
|
-
this._setFeedDownloadState(feed);
|
|
1312
|
-
}
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
async stop() {
|
|
1316
|
-
(0, import_log7.log)("stopping...", void 0, {
|
|
1317
|
-
F: __dxlog_file8,
|
|
1318
|
-
L: 299,
|
|
1319
|
-
S: this,
|
|
1320
|
-
C: (f, a) => f(...a)
|
|
1321
|
-
});
|
|
1322
|
-
this._isStopping = true;
|
|
1323
|
-
for (const [feed, handle] of this._downloads.entries()) {
|
|
1324
|
-
feed.undownload(handle);
|
|
1325
|
-
}
|
|
1326
|
-
this._downloads.clear();
|
|
1327
|
-
await this._feedSetIterator?.close();
|
|
1328
|
-
await this._processingTrigger.wait();
|
|
1329
|
-
await this._state._ctx.dispose();
|
|
1330
|
-
this._state._ctx = new import_context4.Context();
|
|
1331
|
-
this._state._reachedTargetPromise = void 0;
|
|
1332
|
-
this._state._reachedTarget = false;
|
|
1333
|
-
this._isStarted = false;
|
|
1334
|
-
(0, import_log7.log)("stopped", void 0, {
|
|
1335
|
-
F: __dxlog_file8,
|
|
1336
|
-
L: 312,
|
|
1337
|
-
S: this,
|
|
1338
|
-
C: (f, a) => f(...a)
|
|
1339
|
-
});
|
|
1340
|
-
}
|
|
1341
|
-
/**
|
|
1342
|
-
* @param timeframe Timeframe of already processed messages.
|
|
1343
|
-
* The pipeline will start processing messages AFTER this timeframe.
|
|
1344
|
-
*/
|
|
1345
|
-
async setCursor(timeframe) {
|
|
1346
|
-
(0, import_invariant7.invariant)(!this._isStarted || this._isPaused, "Invalid state.", {
|
|
1347
|
-
F: __dxlog_file8,
|
|
1348
|
-
L: 321,
|
|
1349
|
-
S: this,
|
|
1350
|
-
A: [
|
|
1351
|
-
"!this._isStarted || this._isPaused",
|
|
1352
|
-
"'Invalid state.'"
|
|
1353
|
-
]
|
|
1354
|
-
});
|
|
1355
|
-
this._state._startTimeframe = timeframe;
|
|
1356
|
-
this._timeframeClock.setTimeframe(timeframe);
|
|
1357
|
-
if (this._feedSetIterator) {
|
|
1358
|
-
await this._feedSetIterator.close();
|
|
1359
|
-
await this._initIterator();
|
|
1360
|
-
await this._feedSetIterator.open();
|
|
1361
|
-
}
|
|
1362
|
-
}
|
|
1363
|
-
/**
|
|
1364
|
-
* Calling pause while processing will cause a deadlock.
|
|
1365
|
-
*/
|
|
1366
|
-
async pause() {
|
|
1367
|
-
if (this._isPaused) {
|
|
1368
|
-
return;
|
|
1369
|
-
}
|
|
1370
|
-
this._pauseTrigger.reset();
|
|
1371
|
-
await this._processingTrigger.wait();
|
|
1372
|
-
this._isPaused = true;
|
|
1373
|
-
}
|
|
1374
|
-
async unpause() {
|
|
1375
|
-
(0, import_invariant7.invariant)(this._isPaused, "Pipeline is not paused.", {
|
|
1376
|
-
F: __dxlog_file8,
|
|
1377
|
-
L: 350,
|
|
1378
|
-
S: this,
|
|
1379
|
-
A: [
|
|
1380
|
-
"this._isPaused",
|
|
1381
|
-
"'Pipeline is not paused.'"
|
|
1382
|
-
]
|
|
1383
|
-
});
|
|
1384
|
-
this._pauseTrigger.wake();
|
|
1385
|
-
this._isPaused = false;
|
|
1386
|
-
for (const feed of this._feeds.values()) {
|
|
1387
|
-
this._setFeedDownloadState(feed);
|
|
1388
|
-
}
|
|
1389
|
-
}
|
|
1390
|
-
/**
|
|
1391
|
-
* Starts to iterate over the ordered messages from the added feeds.
|
|
1392
|
-
* Updates the timeframe clock after the message has bee processed.
|
|
1393
|
-
*/
|
|
1394
|
-
async *consume() {
|
|
1395
|
-
(0, import_invariant7.invariant)(!this._isBeingConsumed, "Pipeline is already being consumed.", {
|
|
1396
|
-
F: __dxlog_file8,
|
|
1397
|
-
L: 365,
|
|
1398
|
-
S: this,
|
|
1399
|
-
A: [
|
|
1400
|
-
"!this._isBeingConsumed",
|
|
1401
|
-
"'Pipeline is already being consumed.'"
|
|
1402
|
-
]
|
|
1403
|
-
});
|
|
1404
|
-
this._isBeingConsumed = true;
|
|
1405
|
-
(0, import_invariant7.invariant)(this._feedSetIterator, "Iterator not initialized.", {
|
|
1406
|
-
F: __dxlog_file8,
|
|
1407
|
-
L: 368,
|
|
1408
|
-
S: this,
|
|
1409
|
-
A: [
|
|
1410
|
-
"this._feedSetIterator",
|
|
1411
|
-
"'Iterator not initialized.'"
|
|
1412
|
-
]
|
|
1413
|
-
});
|
|
1414
|
-
let lastFeedSetIterator = this._feedSetIterator;
|
|
1415
|
-
let iterable = lastFeedSetIterator[Symbol.asyncIterator]();
|
|
1416
|
-
while (!this._isStopping) {
|
|
1417
|
-
await this._pauseTrigger.wait();
|
|
1418
|
-
if (lastFeedSetIterator !== this._feedSetIterator) {
|
|
1419
|
-
(0, import_invariant7.invariant)(this._feedSetIterator, "Iterator not initialized.", {
|
|
1420
|
-
F: __dxlog_file8,
|
|
1421
|
-
L: 377,
|
|
1422
|
-
S: this,
|
|
1423
|
-
A: [
|
|
1424
|
-
"this._feedSetIterator",
|
|
1425
|
-
"'Iterator not initialized.'"
|
|
1426
|
-
]
|
|
1427
|
-
});
|
|
1428
|
-
lastFeedSetIterator = this._feedSetIterator;
|
|
1429
|
-
iterable = lastFeedSetIterator[Symbol.asyncIterator]();
|
|
1430
|
-
}
|
|
1431
|
-
const { done, value } = await iterable.next();
|
|
1432
|
-
if (!done) {
|
|
1433
|
-
const block = value ?? (0, import_debug3.failUndefined)();
|
|
1434
|
-
this._processingTrigger.reset();
|
|
1435
|
-
this._timeframeClock.updatePendingTimeframe(import_keys4.PublicKey.from(block.feedKey), block.seq);
|
|
1436
|
-
yield block;
|
|
1437
|
-
this._processingTrigger.wake();
|
|
1438
|
-
this._timeframeClock.updateTimeframe();
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1441
|
-
this._isBeingConsumed = false;
|
|
1442
|
-
}
|
|
1443
|
-
_setFeedDownloadState(feed) {
|
|
1444
|
-
let handle = this._downloads.get(feed);
|
|
1445
|
-
if (handle) {
|
|
1446
|
-
feed.undownload(handle);
|
|
1447
|
-
}
|
|
1448
|
-
const timeframe = this._state._startTimeframe;
|
|
1449
|
-
const seq = timeframe.get(feed.key) ?? -1;
|
|
1450
|
-
(0, import_log7.log)("download", {
|
|
1451
|
-
feed: feed.key.truncate(),
|
|
1452
|
-
seq,
|
|
1453
|
-
length: feed.length
|
|
1454
|
-
}, {
|
|
1455
|
-
F: __dxlog_file8,
|
|
1456
|
-
L: 406,
|
|
1457
|
-
S: this,
|
|
1458
|
-
C: (f, a) => f(...a)
|
|
1459
|
-
});
|
|
1460
|
-
handle = feed.download({
|
|
1461
|
-
start: seq + 1,
|
|
1462
|
-
linear: true
|
|
1463
|
-
}, (err, data) => {
|
|
1464
|
-
if (err) {
|
|
1465
|
-
} else {
|
|
1466
|
-
import_log7.log.info("downloaded", {
|
|
1467
|
-
data
|
|
1468
|
-
}, {
|
|
1469
|
-
F: __dxlog_file8,
|
|
1470
|
-
L: 411,
|
|
1471
|
-
S: this,
|
|
1472
|
-
C: (f, a) => f(...a)
|
|
1473
|
-
});
|
|
1474
|
-
}
|
|
1475
|
-
});
|
|
1476
|
-
this._downloads.set(feed, handle);
|
|
1477
|
-
}
|
|
1478
|
-
async _initIterator() {
|
|
1479
|
-
this._feedSetIterator = new import_feed_store.FeedSetIterator(createMessageSelector(this._timeframeClock), {
|
|
1480
|
-
start: startAfter(this._timeframeClock.timeframe),
|
|
1481
|
-
stallTimeout: 1e3
|
|
1482
|
-
});
|
|
1483
|
-
this._feedSetIterator.stalled.on((iterator) => {
|
|
1484
|
-
import_log7.log.warn(`Stalled after ${iterator.options.stallTimeout}ms with ${iterator.size} feeds.`, void 0, {
|
|
1485
|
-
F: __dxlog_file8,
|
|
1486
|
-
L: 425,
|
|
1487
|
-
S: this,
|
|
1488
|
-
C: (f, a) => f(...a)
|
|
1489
|
-
});
|
|
1490
|
-
this._state.stalled.emit();
|
|
1491
|
-
});
|
|
1492
|
-
for (const feed of this._feeds.values()) {
|
|
1493
|
-
await this._feedSetIterator.addFeed(feed);
|
|
1494
|
-
}
|
|
1495
|
-
}
|
|
1496
|
-
};
|
|
1497
|
-
_ts_decorate3([
|
|
1498
|
-
import_async5.synchronized
|
|
1499
|
-
], Pipeline.prototype, "start", null);
|
|
1500
|
-
_ts_decorate3([
|
|
1501
|
-
import_async5.synchronized
|
|
1502
|
-
], Pipeline.prototype, "stop", null);
|
|
1503
|
-
_ts_decorate3([
|
|
1504
|
-
import_async5.synchronized
|
|
1505
|
-
], Pipeline.prototype, "setCursor", null);
|
|
1506
|
-
_ts_decorate3([
|
|
1507
|
-
import_async5.synchronized
|
|
1508
|
-
], Pipeline.prototype, "pause", null);
|
|
1509
|
-
_ts_decorate3([
|
|
1510
|
-
import_async5.synchronized
|
|
1511
|
-
], Pipeline.prototype, "unpause", null);
|
|
1512
|
-
|
|
1513
|
-
// packages/core/echo/echo-pipeline/src/space/control-pipeline.ts
|
|
1514
|
-
function _ts_decorate4(decorators, target, key, desc) {
|
|
1515
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1516
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
1517
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
1518
|
-
else
|
|
1519
|
-
for (var i = decorators.length - 1; i >= 0; i--)
|
|
1520
|
-
if (d = decorators[i])
|
|
1521
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1522
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1523
|
-
}
|
|
1524
|
-
var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/control-pipeline.ts";
|
|
1525
|
-
var TIMEFRAME_SAVE_DEBOUNCE_INTERVAL = 500;
|
|
1526
|
-
var CONTROL_PIPELINE_SNAPSHOT_DELAY = 1e4;
|
|
1527
|
-
var USE_SNAPSHOTS = true;
|
|
1528
|
-
var ControlPipeline = class ControlPipeline2 {
|
|
1529
|
-
constructor({ spaceKey, genesisFeed, feedProvider, metadataStore }) {
|
|
1530
|
-
this._ctx = new import_context5.Context();
|
|
1531
|
-
this._lastTimeframeSaveTime = Date.now();
|
|
1532
|
-
this.onFeedAdmitted = new import_util5.Callback();
|
|
1533
|
-
this._usage = new import_tracing.TimeUsageCounter();
|
|
1534
|
-
this._mutations = new import_tracing.TimeSeriesCounter();
|
|
1535
|
-
this._snapshotTask = new import_async6.DeferredTask(this._ctx, async () => {
|
|
1536
|
-
await (0, import_async6.sleepWithContext)(this._ctx, CONTROL_PIPELINE_SNAPSHOT_DELAY);
|
|
1537
|
-
await this._saveSnapshot();
|
|
1538
|
-
});
|
|
1539
|
-
this._spaceKey = spaceKey;
|
|
1540
|
-
this._metadata = metadataStore;
|
|
1541
|
-
this._pipeline = new Pipeline();
|
|
1542
|
-
void this._pipeline.addFeed(genesisFeed);
|
|
1543
|
-
this._spaceStateMachine = new import_credentials.SpaceStateMachine(spaceKey);
|
|
1544
|
-
this._spaceStateMachine.onFeedAdmitted.set(async (info) => {
|
|
1545
|
-
(0, import_log8.log)("feed admitted", {
|
|
1546
|
-
key: info.key
|
|
1547
|
-
}, {
|
|
1548
|
-
F: __dxlog_file9,
|
|
1549
|
-
L: 74,
|
|
1550
|
-
S: this,
|
|
1551
|
-
C: (f, a) => f(...a)
|
|
1552
|
-
});
|
|
1553
|
-
if (info.assertion.designation === import_credentials2.AdmittedFeed.Designation.CONTROL && !info.key.equals(genesisFeed.key)) {
|
|
1554
|
-
queueMicrotask(async () => {
|
|
1555
|
-
try {
|
|
1556
|
-
const feed = await feedProvider(info.key);
|
|
1557
|
-
await this._pipeline.addFeed(feed);
|
|
1558
|
-
} catch (err) {
|
|
1559
|
-
import_log8.log.catch(err, void 0, {
|
|
1560
|
-
F: __dxlog_file9,
|
|
1561
|
-
L: 83,
|
|
1562
|
-
S: this,
|
|
1563
|
-
C: (f, a) => f(...a)
|
|
1564
|
-
});
|
|
1565
|
-
}
|
|
1566
|
-
});
|
|
1567
|
-
}
|
|
1568
|
-
await this.onFeedAdmitted.callIfSet(info);
|
|
1569
|
-
});
|
|
1570
|
-
this.onMemberAdmitted = this._spaceStateMachine.onMemberAdmitted;
|
|
1571
|
-
this.onCredentialProcessed = this._spaceStateMachine.onCredentialProcessed;
|
|
1572
|
-
}
|
|
1573
|
-
get spaceState() {
|
|
1574
|
-
return this._spaceStateMachine;
|
|
1575
|
-
}
|
|
1576
|
-
get pipeline() {
|
|
1577
|
-
return this._pipeline;
|
|
1578
|
-
}
|
|
1579
|
-
setWriteFeed(feed) {
|
|
1580
|
-
this._pipeline.setWriteFeed(feed);
|
|
1581
|
-
}
|
|
1582
|
-
async start() {
|
|
1583
|
-
const snapshot = this._metadata.getSpaceControlPipelineSnapshot(this._spaceKey);
|
|
1584
|
-
(0, import_log8.log)("load snapshot", {
|
|
1585
|
-
key: this._spaceKey,
|
|
1586
|
-
present: !!snapshot,
|
|
1587
|
-
tf: snapshot?.timeframe
|
|
1588
|
-
}, {
|
|
1589
|
-
F: __dxlog_file9,
|
|
1590
|
-
L: 110,
|
|
1591
|
-
S: this,
|
|
1592
|
-
C: (f, a) => f(...a)
|
|
1593
|
-
});
|
|
1594
|
-
if (USE_SNAPSHOTS && snapshot) {
|
|
1595
|
-
await this._processSnapshot(snapshot);
|
|
1596
|
-
}
|
|
1597
|
-
(0, import_log8.log)("starting...", void 0, {
|
|
1598
|
-
F: __dxlog_file9,
|
|
1599
|
-
L: 115,
|
|
1600
|
-
S: this,
|
|
1601
|
-
C: (f, a) => f(...a)
|
|
1602
|
-
});
|
|
1603
|
-
setTimeout(async () => {
|
|
1604
|
-
void this._consumePipeline(new import_context5.Context());
|
|
1605
|
-
});
|
|
1606
|
-
await this._pipeline.start();
|
|
1607
|
-
(0, import_log8.log)("started", void 0, {
|
|
1608
|
-
F: __dxlog_file9,
|
|
1609
|
-
L: 121,
|
|
1610
|
-
S: this,
|
|
1611
|
-
C: (f, a) => f(...a)
|
|
1612
|
-
});
|
|
1613
|
-
}
|
|
1614
|
-
async _processSnapshot(snapshot) {
|
|
1615
|
-
await this._pipeline.setCursor(snapshot.timeframe);
|
|
1616
|
-
for (const message of snapshot.messages ?? []) {
|
|
1617
|
-
const result = await this._spaceStateMachine.process(message.credential, {
|
|
1618
|
-
sourceFeed: message.feedKey,
|
|
1619
|
-
skipVerification: true
|
|
1620
|
-
});
|
|
1621
|
-
if (!result) {
|
|
1622
|
-
import_log8.log.warn("credential processing failed from snapshot", {
|
|
1623
|
-
message
|
|
1624
|
-
}, {
|
|
1625
|
-
F: __dxlog_file9,
|
|
1626
|
-
L: 134,
|
|
1627
|
-
S: this,
|
|
1628
|
-
C: (f, a) => f(...a)
|
|
1629
|
-
});
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
async _saveSnapshot() {
|
|
1634
|
-
await this._pipeline.pause();
|
|
1635
|
-
const snapshot = {
|
|
1636
|
-
timeframe: this._pipeline.state.timeframe,
|
|
1637
|
-
messages: this._spaceStateMachine.credentialEntries.map((entry) => ({
|
|
1638
|
-
feedKey: entry.sourceFeed,
|
|
1639
|
-
credential: entry.credential
|
|
1640
|
-
}))
|
|
1641
|
-
};
|
|
1642
|
-
await this._pipeline.unpause();
|
|
1643
|
-
(0, import_log8.log)("save snapshot", {
|
|
1644
|
-
key: this._spaceKey,
|
|
1645
|
-
snapshot
|
|
1646
|
-
}, {
|
|
1647
|
-
F: __dxlog_file9,
|
|
1648
|
-
L: 150,
|
|
1649
|
-
S: this,
|
|
1650
|
-
C: (f, a) => f(...a)
|
|
1651
|
-
});
|
|
1652
|
-
await this._metadata.setSpaceControlPipelineSnapshot(this._spaceKey, snapshot);
|
|
1653
|
-
}
|
|
1654
|
-
async _consumePipeline(ctx) {
|
|
1655
|
-
for await (const msg of this._pipeline.consume()) {
|
|
1656
|
-
const span = this._usage.beginRecording();
|
|
1657
|
-
this._mutations.inc();
|
|
1658
|
-
try {
|
|
1659
|
-
await this._processMessage(ctx, msg);
|
|
1660
|
-
} catch (err) {
|
|
1661
|
-
import_log8.log.catch(err, void 0, {
|
|
1662
|
-
F: __dxlog_file9,
|
|
1663
|
-
L: 163,
|
|
1664
|
-
S: this,
|
|
1665
|
-
C: (f, a) => f(...a)
|
|
1666
|
-
});
|
|
1667
|
-
}
|
|
1668
|
-
span.end();
|
|
1669
|
-
}
|
|
1670
|
-
}
|
|
1671
|
-
async _processMessage(ctx, msg) {
|
|
1672
|
-
(0, import_log8.log)("processing", {
|
|
1673
|
-
key: msg.feedKey,
|
|
1674
|
-
seq: msg.seq
|
|
1675
|
-
}, {
|
|
1676
|
-
F: __dxlog_file9,
|
|
1677
|
-
L: 173,
|
|
1678
|
-
S: this,
|
|
1679
|
-
C: (f, a) => f(...a)
|
|
1680
|
-
});
|
|
1681
|
-
if (msg.data.payload.credential) {
|
|
1682
|
-
const timer = import_util5.tracer.mark("dxos.echo.pipeline.control");
|
|
1683
|
-
const result = await this._spaceStateMachine.process(msg.data.payload.credential.credential, {
|
|
1684
|
-
sourceFeed: import_keys5.PublicKey.from(msg.feedKey)
|
|
1685
|
-
});
|
|
1686
|
-
timer.end();
|
|
1687
|
-
if (!result) {
|
|
1688
|
-
import_log8.log.warn("processing failed", {
|
|
1689
|
-
msg
|
|
1690
|
-
}, {
|
|
1691
|
-
F: __dxlog_file9,
|
|
1692
|
-
L: 182,
|
|
1693
|
-
S: this,
|
|
1694
|
-
C: (f, a) => f(...a)
|
|
1695
|
-
});
|
|
1696
|
-
} else {
|
|
1697
|
-
await this._noteTargetStateIfNeeded(this._pipeline.state.pendingTimeframe);
|
|
1698
|
-
}
|
|
1699
|
-
this._snapshotTask.schedule();
|
|
1700
|
-
}
|
|
1701
|
-
}
|
|
1702
|
-
async _noteTargetStateIfNeeded(timeframe) {
|
|
1703
|
-
if (Date.now() - this._lastTimeframeSaveTime > TIMEFRAME_SAVE_DEBOUNCE_INTERVAL) {
|
|
1704
|
-
this._lastTimeframeSaveTime = Date.now();
|
|
1705
|
-
await this._saveTargetTimeframe(timeframe);
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
async stop() {
|
|
1709
|
-
(0, import_log8.log)("stopping...", void 0, {
|
|
1710
|
-
F: __dxlog_file9,
|
|
1711
|
-
L: 202,
|
|
1712
|
-
S: this,
|
|
1713
|
-
C: (f, a) => f(...a)
|
|
1714
|
-
});
|
|
1715
|
-
await this._ctx.dispose();
|
|
1716
|
-
await this._pipeline.stop();
|
|
1717
|
-
await this._saveTargetTimeframe(this._pipeline.state.timeframe);
|
|
1718
|
-
(0, import_log8.log)("stopped", void 0, {
|
|
1719
|
-
F: __dxlog_file9,
|
|
1720
|
-
L: 206,
|
|
1721
|
-
S: this,
|
|
1722
|
-
C: (f, a) => f(...a)
|
|
1723
|
-
});
|
|
1724
|
-
}
|
|
1725
|
-
async _saveTargetTimeframe(timeframe) {
|
|
1726
|
-
try {
|
|
1727
|
-
const newTimeframe = import_timeframe3.Timeframe.merge(this._targetTimeframe ?? new import_timeframe3.Timeframe(), timeframe);
|
|
1728
|
-
await this._metadata.setSpaceControlLatestTimeframe(this._spaceKey, newTimeframe);
|
|
1729
|
-
this._targetTimeframe = newTimeframe;
|
|
1730
|
-
} catch (err) {
|
|
1731
|
-
(0, import_log8.log)(err, void 0, {
|
|
1732
|
-
F: __dxlog_file9,
|
|
1733
|
-
L: 215,
|
|
1734
|
-
S: this,
|
|
1735
|
-
C: (f, a) => f(...a)
|
|
1736
|
-
});
|
|
1737
|
-
}
|
|
1738
|
-
}
|
|
1739
|
-
};
|
|
1740
|
-
_ts_decorate4([
|
|
1741
|
-
import_tracing.trace.metricsCounter()
|
|
1742
|
-
], ControlPipeline.prototype, "_usage", void 0);
|
|
1743
|
-
_ts_decorate4([
|
|
1744
|
-
import_tracing.trace.metricsCounter()
|
|
1745
|
-
], ControlPipeline.prototype, "_mutations", void 0);
|
|
1746
|
-
_ts_decorate4([
|
|
1747
|
-
import_tracing.trace.span({
|
|
1748
|
-
showInBrowserTimeline: true
|
|
1749
|
-
})
|
|
1750
|
-
], ControlPipeline.prototype, "start", null);
|
|
1751
|
-
_ts_decorate4([
|
|
1752
|
-
import_tracing.trace.span()
|
|
1753
|
-
], ControlPipeline.prototype, "_consumePipeline", null);
|
|
1754
|
-
_ts_decorate4([
|
|
1755
|
-
import_tracing.trace.span()
|
|
1756
|
-
], ControlPipeline.prototype, "_processMessage", null);
|
|
1757
|
-
ControlPipeline = _ts_decorate4([
|
|
1758
|
-
import_tracing.trace.resource(),
|
|
1759
|
-
(0, import_async6.trackLeaks)("start", "stop")
|
|
1760
|
-
], ControlPipeline);
|
|
1761
|
-
|
|
1762
|
-
// packages/core/echo/echo-pipeline/src/space/data-pipeline.ts
|
|
1763
|
-
var import_async7 = require("@dxos/async");
|
|
1764
|
-
var import_context6 = require("@dxos/context");
|
|
1765
|
-
var import_credentials3 = require("@dxos/credentials");
|
|
1766
|
-
var import_echo_db3 = require("@dxos/echo-db");
|
|
1767
|
-
var import_invariant8 = require("@dxos/invariant");
|
|
1768
|
-
var import_log9 = require("@dxos/log");
|
|
1769
|
-
var import_protocols6 = require("@dxos/protocols");
|
|
1770
|
-
var import_timeframe4 = require("@dxos/timeframe");
|
|
1771
|
-
var import_tracing2 = require("@dxos/tracing");
|
|
1772
|
-
var import_util6 = require("@dxos/util");
|
|
1773
|
-
function _ts_decorate5(decorators, target, key, desc) {
|
|
1774
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1775
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
1776
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
1777
|
-
else
|
|
1778
|
-
for (var i = decorators.length - 1; i >= 0; i--)
|
|
1779
|
-
if (d = decorators[i])
|
|
1780
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1781
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1782
|
-
}
|
|
1783
|
-
var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/data-pipeline.ts";
|
|
1784
|
-
var MESSAGES_PER_SNAPSHOT = 10;
|
|
1785
|
-
var AUTOMATIC_SNAPSHOT_DEBOUNCE_INTERVAL = 5e3;
|
|
1786
|
-
var TIMEFRAME_SAVE_DEBOUNCE_INTERVAL2 = 5e3;
|
|
1787
|
-
var DataPipeline = class DataPipeline2 {
|
|
1788
|
-
constructor(_params) {
|
|
1789
|
-
this._params = _params;
|
|
1790
|
-
this._ctx = new import_context6.Context();
|
|
1791
|
-
this._pipeline = void 0;
|
|
1792
|
-
this._targetTimeframe = void 0;
|
|
1793
|
-
this._lastAutomaticSnapshotTimeframe = new import_timeframe4.Timeframe();
|
|
1794
|
-
this._isOpen = false;
|
|
1795
|
-
this._lastTimeframeSaveTime = 0;
|
|
1796
|
-
this._lastSnapshotSaveTime = 0;
|
|
1797
|
-
this._lastProcessedEpoch = -1;
|
|
1798
|
-
this._usage = new import_tracing2.TimeUsageCounter();
|
|
1799
|
-
this._mutations = new import_tracing2.TimeSeriesCounter();
|
|
1800
|
-
this.currentEpoch = void 0;
|
|
1801
|
-
this.appliedEpoch = void 0;
|
|
1802
|
-
this.onNewEpoch = new import_async7.Event();
|
|
1803
|
-
}
|
|
1804
|
-
get isOpen() {
|
|
1805
|
-
return this._isOpen;
|
|
1806
|
-
}
|
|
1807
|
-
get pipeline() {
|
|
1808
|
-
return this._pipeline;
|
|
1809
|
-
}
|
|
1810
|
-
get pipelineState() {
|
|
1811
|
-
return this._pipeline?.state;
|
|
1812
|
-
}
|
|
1813
|
-
setTargetTimeframe(timeframe) {
|
|
1814
|
-
this._targetTimeframe = timeframe;
|
|
1815
|
-
this._pipeline?.state.setTargetTimeframe(timeframe);
|
|
1816
|
-
}
|
|
1817
|
-
async processCredential(credential) {
|
|
1818
|
-
if (!(0, import_credentials3.checkCredentialType)(credential, "dxos.halo.credentials.Epoch")) {
|
|
1819
|
-
return;
|
|
1820
|
-
}
|
|
1821
|
-
this.currentEpoch = credential;
|
|
1822
|
-
if (this._isOpen) {
|
|
1823
|
-
await this._processEpochInSeparateTask(credential);
|
|
1824
|
-
}
|
|
1825
|
-
}
|
|
1826
|
-
async open() {
|
|
1827
|
-
if (this._isOpen) {
|
|
1828
|
-
return;
|
|
1829
|
-
}
|
|
1830
|
-
this._pipeline = new Pipeline();
|
|
1831
|
-
await this._params.onPipelineCreated(this._pipeline);
|
|
1832
|
-
await this._pipeline.pause();
|
|
1833
|
-
await this._pipeline.start();
|
|
1834
|
-
if (this._targetTimeframe) {
|
|
1835
|
-
this._pipeline.state.setTargetTimeframe(this._targetTimeframe);
|
|
1836
|
-
}
|
|
1837
|
-
const feedWriter = {
|
|
1838
|
-
write: (data, options) => {
|
|
1839
|
-
(0, import_invariant8.invariant)(this._pipeline, "Pipeline is not initialized.", {
|
|
1840
|
-
F: __dxlog_file10,
|
|
1841
|
-
L: 159,
|
|
1842
|
-
S: this,
|
|
1843
|
-
A: [
|
|
1844
|
-
"this._pipeline",
|
|
1845
|
-
"'Pipeline is not initialized.'"
|
|
1846
|
-
]
|
|
1847
|
-
});
|
|
1848
|
-
(0, import_invariant8.invariant)(this.currentEpoch, "Epoch is not initialized.", {
|
|
1849
|
-
F: __dxlog_file10,
|
|
1850
|
-
L: 160,
|
|
1851
|
-
S: this,
|
|
1852
|
-
A: [
|
|
1853
|
-
"this.currentEpoch",
|
|
1854
|
-
"'Epoch is not initialized.'"
|
|
1855
|
-
]
|
|
1856
|
-
});
|
|
1857
|
-
return this._pipeline.writer.write({
|
|
1858
|
-
data
|
|
1859
|
-
}, options);
|
|
1860
|
-
}
|
|
1861
|
-
};
|
|
1862
|
-
this.databaseHost = new DatabaseHost(feedWriter, () => this._flush());
|
|
1863
|
-
this.itemManager = new import_echo_db3.ItemManager(this._params.modelFactory);
|
|
1864
|
-
await this.databaseHost.open(this.itemManager, this._params.modelFactory);
|
|
1865
|
-
(0, import_async7.scheduleTask)(this._ctx, async () => {
|
|
1866
|
-
await this._consumePipeline();
|
|
1867
|
-
});
|
|
1868
|
-
this._isOpen = true;
|
|
1869
|
-
}
|
|
1870
|
-
async close() {
|
|
1871
|
-
if (!this._isOpen) {
|
|
1872
|
-
return;
|
|
1873
|
-
}
|
|
1874
|
-
(0, import_log9.log)("close", void 0, {
|
|
1875
|
-
F: __dxlog_file10,
|
|
1876
|
-
L: 184,
|
|
1877
|
-
S: this,
|
|
1878
|
-
C: (f, a) => f(...a)
|
|
1879
|
-
});
|
|
1880
|
-
this._isOpen = false;
|
|
1881
|
-
await this._ctx.dispose();
|
|
1882
|
-
await this._pipeline?.stop();
|
|
1883
|
-
try {
|
|
1884
|
-
await this._saveCache();
|
|
1885
|
-
if (this._pipeline) {
|
|
1886
|
-
await this._saveTargetTimeframe(this._pipeline.state.timeframe);
|
|
1887
|
-
}
|
|
1888
|
-
} catch (err) {
|
|
1889
|
-
import_log9.log.catch(err, void 0, {
|
|
1890
|
-
F: __dxlog_file10,
|
|
1891
|
-
L: 197,
|
|
1892
|
-
S: this,
|
|
1893
|
-
C: (f, a) => f(...a)
|
|
1894
|
-
});
|
|
1895
|
-
}
|
|
1896
|
-
await this.databaseHost?.close();
|
|
1897
|
-
await this.itemManager?.destroy();
|
|
1898
|
-
this._ctx = new import_context6.Context();
|
|
1899
|
-
this._pipeline = void 0;
|
|
1900
|
-
this._targetTimeframe = void 0;
|
|
1901
|
-
this._lastAutomaticSnapshotTimeframe = new import_timeframe4.Timeframe();
|
|
1902
|
-
this.currentEpoch = void 0;
|
|
1903
|
-
this.appliedEpoch = void 0;
|
|
1904
|
-
this._lastProcessedEpoch = -1;
|
|
1905
|
-
this._epochCtx = void 0;
|
|
1906
|
-
}
|
|
1907
|
-
async _consumePipeline() {
|
|
1908
|
-
if (this.currentEpoch) {
|
|
1909
|
-
const waitForOneEpoch = this.onNewEpoch.waitForCount(1);
|
|
1910
|
-
await this._processEpochInSeparateTask(this.currentEpoch);
|
|
1911
|
-
await waitForOneEpoch;
|
|
1912
|
-
}
|
|
1913
|
-
let messageCounter = 0;
|
|
1914
|
-
(0, import_invariant8.invariant)(this._pipeline, "Pipeline is not initialized.", {
|
|
1915
|
-
F: __dxlog_file10,
|
|
1916
|
-
L: 222,
|
|
1917
|
-
S: this,
|
|
1918
|
-
A: [
|
|
1919
|
-
"this._pipeline",
|
|
1920
|
-
"'Pipeline is not initialized.'"
|
|
1921
|
-
]
|
|
1922
|
-
});
|
|
1923
|
-
for await (const msg of this._pipeline.consume()) {
|
|
1924
|
-
const span = this._usage.beginRecording();
|
|
1925
|
-
this._mutations.inc();
|
|
1926
|
-
const { feedKey, seq, data } = msg;
|
|
1927
|
-
(0, import_log9.log)("processing message", {
|
|
1928
|
-
feedKey,
|
|
1929
|
-
seq
|
|
1930
|
-
}, {
|
|
1931
|
-
F: __dxlog_file10,
|
|
1932
|
-
L: 228,
|
|
1933
|
-
S: this,
|
|
1934
|
-
C: (f, a) => f(...a)
|
|
1935
|
-
});
|
|
1936
|
-
try {
|
|
1937
|
-
if (data.payload.data) {
|
|
1938
|
-
const feedInfo = this._params.feedInfoProvider(feedKey);
|
|
1939
|
-
if (!feedInfo) {
|
|
1940
|
-
import_log9.log.warn("Could not find feed", {
|
|
1941
|
-
feedKey
|
|
1942
|
-
}, {
|
|
1943
|
-
F: __dxlog_file10,
|
|
1944
|
-
L: 234,
|
|
1945
|
-
S: this,
|
|
1946
|
-
C: (f, a) => f(...a)
|
|
1947
|
-
});
|
|
1948
|
-
continue;
|
|
1949
|
-
}
|
|
1950
|
-
const timer = import_util6.tracer.mark("dxos.echo.pipeline.data");
|
|
1951
|
-
this.databaseHost.echoProcessor({
|
|
1952
|
-
batch: data.payload.data.batch,
|
|
1953
|
-
meta: {
|
|
1954
|
-
feedKey,
|
|
1955
|
-
seq,
|
|
1956
|
-
timeframe: data.timeframe,
|
|
1957
|
-
memberKey: feedInfo.assertion.identityKey
|
|
1958
|
-
}
|
|
1959
|
-
});
|
|
1960
|
-
timer.end();
|
|
1961
|
-
import_log9.log.trace("dxos.echo.data-pipeline.processed", {
|
|
1962
|
-
feedKey: feedKey.toHex(),
|
|
1963
|
-
seq,
|
|
1964
|
-
spaceKey: this._params.spaceKey.toHex()
|
|
1965
|
-
}, {
|
|
1966
|
-
F: __dxlog_file10,
|
|
1967
|
-
L: 251,
|
|
1968
|
-
S: this,
|
|
1969
|
-
C: (f, a) => f(...a)
|
|
1970
|
-
});
|
|
1971
|
-
await this._noteTargetStateIfNeeded(this._pipeline.state.pendingTimeframe);
|
|
1972
|
-
}
|
|
1973
|
-
} catch (err) {
|
|
1974
|
-
import_log9.log.catch(err, void 0, {
|
|
1975
|
-
F: __dxlog_file10,
|
|
1976
|
-
L: 261,
|
|
1977
|
-
S: this,
|
|
1978
|
-
C: (f, a) => f(...a)
|
|
1979
|
-
});
|
|
1980
|
-
}
|
|
1981
|
-
span.end();
|
|
1982
|
-
if (++messageCounter > 1e3) {
|
|
1983
|
-
messageCounter = 0;
|
|
1984
|
-
await (0, import_async7.sleep)(1);
|
|
1985
|
-
}
|
|
1986
|
-
}
|
|
1987
|
-
}
|
|
1988
|
-
_createSnapshot() {
|
|
1989
|
-
(0, import_invariant8.invariant)(this.databaseHost, "Database backend is not initialized.", {
|
|
1990
|
-
F: __dxlog_file10,
|
|
1991
|
-
L: 275,
|
|
1992
|
-
S: this,
|
|
1993
|
-
A: [
|
|
1994
|
-
"this.databaseHost",
|
|
1995
|
-
"'Database backend is not initialized.'"
|
|
1996
|
-
]
|
|
1997
|
-
});
|
|
1998
|
-
return {
|
|
1999
|
-
spaceKey: this._params.spaceKey.asUint8Array(),
|
|
2000
|
-
timeframe: this._pipeline.state.timeframe,
|
|
2001
|
-
database: this.databaseHost.createSnapshot()
|
|
2002
|
-
};
|
|
2003
|
-
}
|
|
2004
|
-
async _saveTargetTimeframe(timeframe) {
|
|
2005
|
-
const newTimeframe = import_timeframe4.Timeframe.merge(this._targetTimeframe ?? new import_timeframe4.Timeframe(), timeframe);
|
|
2006
|
-
await this._params.metadataStore.setSpaceDataLatestTimeframe(this._params.spaceKey, newTimeframe);
|
|
2007
|
-
this._targetTimeframe = newTimeframe;
|
|
2008
|
-
}
|
|
2009
|
-
async _saveCache() {
|
|
2010
|
-
const cache = {};
|
|
2011
|
-
try {
|
|
2012
|
-
const propertiesItem = this.itemManager.items.find((item) => item.modelMeta?.type === "dxos.org/model/document" && // TODO(burdon): Document?
|
|
2013
|
-
((0, import_echo_db3.getStateMachineFromItem)(item)?.snapshot()).type === import_echo_db3.TYPE_PROPERTIES);
|
|
2014
|
-
if (propertiesItem) {
|
|
2015
|
-
cache.properties = (0, import_echo_db3.getStateMachineFromItem)(propertiesItem)?.snapshot();
|
|
2016
|
-
}
|
|
2017
|
-
} catch (err) {
|
|
2018
|
-
import_log9.log.warn("Failed to cache properties", err, {
|
|
2019
|
-
F: __dxlog_file10,
|
|
2020
|
-
L: 304,
|
|
2021
|
-
S: this,
|
|
2022
|
-
C: (f, a) => f(...a)
|
|
2023
|
-
});
|
|
2024
|
-
}
|
|
2025
|
-
await this._params.metadataStore.setCache(this._params.spaceKey, cache);
|
|
2026
|
-
}
|
|
2027
|
-
async _noteTargetStateIfNeeded(timeframe) {
|
|
2028
|
-
if (!this._pipeline?.state.reachedTarget) {
|
|
2029
|
-
return;
|
|
2030
|
-
}
|
|
2031
|
-
if (Date.now() - this._lastTimeframeSaveTime > TIMEFRAME_SAVE_DEBOUNCE_INTERVAL2) {
|
|
2032
|
-
this._lastTimeframeSaveTime = Date.now();
|
|
2033
|
-
await this._saveTargetTimeframe(timeframe);
|
|
2034
|
-
}
|
|
2035
|
-
if (Date.now() - this._lastSnapshotSaveTime > AUTOMATIC_SNAPSHOT_DEBOUNCE_INTERVAL && timeframe.totalMessages() - this._lastAutomaticSnapshotTimeframe.totalMessages() > MESSAGES_PER_SNAPSHOT) {
|
|
2036
|
-
await this._saveCache();
|
|
2037
|
-
}
|
|
2038
|
-
}
|
|
2039
|
-
async _processEpochInSeparateTask(epoch) {
|
|
2040
|
-
if (epoch.subject.assertion.number <= this._lastProcessedEpoch) {
|
|
2041
|
-
return;
|
|
2042
|
-
}
|
|
2043
|
-
await this._epochCtx?.dispose();
|
|
2044
|
-
const ctx = new import_context6.Context({
|
|
2045
|
-
onError: (err) => {
|
|
2046
|
-
if (err instanceof import_protocols6.CancelledError) {
|
|
2047
|
-
(0, import_log9.log)("Epoch processing cancelled.", void 0, {
|
|
2048
|
-
F: __dxlog_file10,
|
|
2049
|
-
L: 340,
|
|
2050
|
-
S: this,
|
|
2051
|
-
C: (f, a) => f(...a)
|
|
2052
|
-
});
|
|
2053
|
-
} else {
|
|
2054
|
-
import_log9.log.catch(err, void 0, {
|
|
2055
|
-
F: __dxlog_file10,
|
|
2056
|
-
L: 342,
|
|
2057
|
-
S: this,
|
|
2058
|
-
C: (f, a) => f(...a)
|
|
2059
|
-
});
|
|
2060
|
-
}
|
|
2061
|
-
}
|
|
2062
|
-
});
|
|
2063
|
-
this._epochCtx = ctx;
|
|
2064
|
-
(0, import_async7.scheduleTask)(ctx, async () => {
|
|
2065
|
-
if (!this._isOpen) {
|
|
2066
|
-
return;
|
|
2067
|
-
}
|
|
2068
|
-
await this._processEpoch(ctx, epoch.subject.assertion);
|
|
2069
|
-
this.appliedEpoch = epoch;
|
|
2070
|
-
this.onNewEpoch.emit(epoch);
|
|
2071
|
-
});
|
|
2072
|
-
}
|
|
2073
|
-
async _processEpoch(ctx, epoch) {
|
|
2074
|
-
(0, import_invariant8.invariant)(this._isOpen, "Space is closed.", {
|
|
2075
|
-
F: __dxlog_file10,
|
|
2076
|
-
L: 361,
|
|
2077
|
-
S: this,
|
|
2078
|
-
A: [
|
|
2079
|
-
"this._isOpen",
|
|
2080
|
-
"'Space is closed.'"
|
|
2081
|
-
]
|
|
2082
|
-
});
|
|
2083
|
-
(0, import_invariant8.invariant)(this._pipeline, void 0, {
|
|
2084
|
-
F: __dxlog_file10,
|
|
2085
|
-
L: 362,
|
|
2086
|
-
S: this,
|
|
2087
|
-
A: [
|
|
2088
|
-
"this._pipeline",
|
|
2089
|
-
""
|
|
2090
|
-
]
|
|
2091
|
-
});
|
|
2092
|
-
this._lastProcessedEpoch = epoch.number;
|
|
2093
|
-
(0, import_log9.log)("processing", {
|
|
2094
|
-
epoch: (0, import_log9.omit)(epoch, "proof")
|
|
2095
|
-
}, {
|
|
2096
|
-
F: __dxlog_file10,
|
|
2097
|
-
L: 365,
|
|
2098
|
-
S: this,
|
|
2099
|
-
C: (f, a) => f(...a)
|
|
2100
|
-
});
|
|
2101
|
-
if (epoch.snapshotCid) {
|
|
2102
|
-
const snapshot = await this._params.snapshotManager.load(ctx, epoch.snapshotCid);
|
|
2103
|
-
this.databaseHost._itemDemuxer.restoreFromSnapshot(snapshot.database);
|
|
2104
|
-
}
|
|
2105
|
-
(0, import_log9.log)("restarting pipeline from epoch", void 0, {
|
|
2106
|
-
F: __dxlog_file10,
|
|
2107
|
-
L: 371,
|
|
2108
|
-
S: this,
|
|
2109
|
-
C: (f, a) => f(...a)
|
|
2110
|
-
});
|
|
2111
|
-
await this._pipeline.pause();
|
|
2112
|
-
await this._pipeline.setCursor(epoch.timeframe);
|
|
2113
|
-
await this._pipeline.unpause();
|
|
2114
|
-
}
|
|
2115
|
-
async waitUntilTimeframe(timeframe) {
|
|
2116
|
-
(0, import_invariant8.invariant)(this._pipeline, "Pipeline is not initialized.", {
|
|
2117
|
-
F: __dxlog_file10,
|
|
2118
|
-
L: 378,
|
|
2119
|
-
S: this,
|
|
2120
|
-
A: [
|
|
2121
|
-
"this._pipeline",
|
|
2122
|
-
"'Pipeline is not initialized.'"
|
|
2123
|
-
]
|
|
2124
|
-
});
|
|
2125
|
-
await this._pipeline.state.waitUntilTimeframe(timeframe);
|
|
2126
|
-
}
|
|
2127
|
-
async createEpoch() {
|
|
2128
|
-
(0, import_invariant8.invariant)(this._pipeline, void 0, {
|
|
2129
|
-
F: __dxlog_file10,
|
|
2130
|
-
L: 384,
|
|
2131
|
-
S: this,
|
|
2132
|
-
A: [
|
|
2133
|
-
"this._pipeline",
|
|
2134
|
-
""
|
|
2135
|
-
]
|
|
2136
|
-
});
|
|
2137
|
-
(0, import_invariant8.invariant)(this.currentEpoch, void 0, {
|
|
2138
|
-
F: __dxlog_file10,
|
|
2139
|
-
L: 385,
|
|
2140
|
-
S: this,
|
|
2141
|
-
A: [
|
|
2142
|
-
"this.currentEpoch",
|
|
2143
|
-
""
|
|
2144
|
-
]
|
|
2145
|
-
});
|
|
2146
|
-
await this._pipeline.pause();
|
|
2147
|
-
const snapshot = await this._createSnapshot();
|
|
2148
|
-
const snapshotCid = await this._params.snapshotManager.store(snapshot);
|
|
2149
|
-
const epoch = {
|
|
2150
|
-
previousId: this.currentEpoch.id,
|
|
2151
|
-
timeframe: this._pipeline.state.timeframe,
|
|
2152
|
-
number: this.currentEpoch.subject.assertion.number + 1,
|
|
2153
|
-
snapshotCid
|
|
2154
|
-
};
|
|
2155
|
-
await this._pipeline.unpause();
|
|
2156
|
-
return epoch;
|
|
2157
|
-
}
|
|
2158
|
-
async ensureEpochInitialized() {
|
|
2159
|
-
await this.onNewEpoch.waitForCondition(() => !!this.currentEpoch);
|
|
2160
|
-
}
|
|
2161
|
-
async _flush() {
|
|
2162
|
-
try {
|
|
2163
|
-
await this._saveCache();
|
|
2164
|
-
if (this._pipeline) {
|
|
2165
|
-
await this._saveTargetTimeframe(this._pipeline.state.timeframe);
|
|
2166
|
-
}
|
|
2167
|
-
} catch (err) {
|
|
2168
|
-
import_log9.log.catch(err, void 0, {
|
|
2169
|
-
F: __dxlog_file10,
|
|
2170
|
-
L: 415,
|
|
2171
|
-
S: this,
|
|
2172
|
-
C: (f, a) => f(...a)
|
|
2173
|
-
});
|
|
2174
|
-
}
|
|
2175
|
-
await this._params.metadataStore.flush();
|
|
2176
|
-
}
|
|
2177
|
-
};
|
|
2178
|
-
_ts_decorate5([
|
|
2179
|
-
import_tracing2.trace.metricsCounter()
|
|
2180
|
-
], DataPipeline.prototype, "_usage", void 0);
|
|
2181
|
-
_ts_decorate5([
|
|
2182
|
-
import_tracing2.trace.metricsCounter()
|
|
2183
|
-
], DataPipeline.prototype, "_mutations", void 0);
|
|
2184
|
-
_ts_decorate5([
|
|
2185
|
-
import_async7.synchronized
|
|
2186
|
-
], DataPipeline.prototype, "open", null);
|
|
2187
|
-
_ts_decorate5([
|
|
2188
|
-
import_async7.synchronized
|
|
2189
|
-
], DataPipeline.prototype, "close", null);
|
|
2190
|
-
_ts_decorate5([
|
|
2191
|
-
import_async7.synchronized
|
|
2192
|
-
], DataPipeline.prototype, "_processEpoch", null);
|
|
2193
|
-
_ts_decorate5([
|
|
2194
|
-
import_async7.synchronized
|
|
2195
|
-
], DataPipeline.prototype, "createEpoch", null);
|
|
2196
|
-
DataPipeline = _ts_decorate5([
|
|
2197
|
-
(0, import_async7.trackLeaks)("open", "close"),
|
|
2198
|
-
import_tracing2.trace.resource()
|
|
2199
|
-
], DataPipeline);
|
|
2200
|
-
|
|
2201
|
-
// packages/core/echo/echo-pipeline/src/space/space.ts
|
|
2202
|
-
function _ts_decorate6(decorators, target, key, desc) {
|
|
2203
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2204
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
2205
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
2206
|
-
else
|
|
2207
|
-
for (var i = decorators.length - 1; i >= 0; i--)
|
|
2208
|
-
if (d = decorators[i])
|
|
2209
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2210
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2211
|
-
}
|
|
2212
|
-
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/space.ts";
|
|
2213
|
-
var Space = class Space2 {
|
|
2214
|
-
constructor(params) {
|
|
2215
|
-
this._addFeedLock = new import_async8.Lock();
|
|
2216
|
-
this.onCredentialProcessed = new import_util7.Callback();
|
|
2217
|
-
this.stateUpdate = new import_async8.Event();
|
|
2218
|
-
this._isOpen = false;
|
|
2219
|
-
(0, import_invariant9.invariant)(params.spaceKey && params.feedProvider, void 0, {
|
|
2220
|
-
F: __dxlog_file11,
|
|
2221
|
-
L: 73,
|
|
2222
|
-
S: this,
|
|
2223
|
-
A: [
|
|
2224
|
-
"params.spaceKey && params.feedProvider",
|
|
2225
|
-
""
|
|
2226
|
-
]
|
|
2227
|
-
});
|
|
2228
|
-
this._key = params.spaceKey;
|
|
2229
|
-
this._genesisFeedKey = params.genesisFeed.key;
|
|
2230
|
-
this._feedProvider = params.feedProvider;
|
|
2231
|
-
this._snapshotManager = params.snapshotManager;
|
|
2232
|
-
this._controlPipeline = new ControlPipeline({
|
|
2233
|
-
spaceKey: params.spaceKey,
|
|
2234
|
-
genesisFeed: params.genesisFeed,
|
|
2235
|
-
feedProvider: params.feedProvider,
|
|
2236
|
-
metadataStore: params.metadataStore
|
|
2237
|
-
});
|
|
2238
|
-
this._controlPipeline.onFeedAdmitted.set(async (info) => {
|
|
2239
|
-
const sparse = info.assertion.designation === import_credentials4.AdmittedFeed.Designation.DATA;
|
|
2240
|
-
if (info.assertion.designation === import_credentials4.AdmittedFeed.Designation.DATA) {
|
|
2241
|
-
queueMicrotask(async () => {
|
|
2242
|
-
if (this._dataPipeline.pipeline) {
|
|
2243
|
-
if (!this._dataPipeline.pipeline.hasFeed(info.key)) {
|
|
2244
|
-
return this._dataPipeline.pipeline.addFeed(await this._feedProvider(info.key, {
|
|
2245
|
-
sparse
|
|
2246
|
-
}));
|
|
2247
|
-
}
|
|
2248
|
-
}
|
|
2249
|
-
});
|
|
2250
|
-
}
|
|
2251
|
-
if (!info.key.equals(params.genesisFeed.key)) {
|
|
2252
|
-
queueMicrotask(async () => {
|
|
2253
|
-
this.protocol.addFeed(await params.feedProvider(info.key, {
|
|
2254
|
-
sparse
|
|
2255
|
-
}));
|
|
2256
|
-
});
|
|
2257
|
-
}
|
|
2258
|
-
});
|
|
2259
|
-
this._controlPipeline.onCredentialProcessed.set(async (credential) => {
|
|
2260
|
-
await this.onCredentialProcessed.callIfSet(credential);
|
|
2261
|
-
(0, import_log10.log)("onCredentialProcessed", {
|
|
2262
|
-
credential
|
|
2263
|
-
}, {
|
|
2264
|
-
F: __dxlog_file11,
|
|
2265
|
-
L: 111,
|
|
2266
|
-
S: this,
|
|
2267
|
-
C: (f, a) => f(...a)
|
|
2268
|
-
});
|
|
2269
|
-
this.stateUpdate.emit();
|
|
2270
|
-
});
|
|
2271
|
-
this.protocol = params.protocol;
|
|
2272
|
-
this.protocol.addFeed(params.genesisFeed);
|
|
2273
|
-
this._dataPipeline = new DataPipeline({
|
|
2274
|
-
modelFactory: params.modelFactory,
|
|
2275
|
-
metadataStore: params.metadataStore,
|
|
2276
|
-
snapshotManager: params.snapshotManager,
|
|
2277
|
-
memberKey: params.memberKey,
|
|
2278
|
-
spaceKey: this._key,
|
|
2279
|
-
feedInfoProvider: (feedKey) => this._controlPipeline.spaceState.feeds.get(feedKey),
|
|
2280
|
-
snapshotId: params.snapshotId,
|
|
2281
|
-
onPipelineCreated: async (pipeline) => {
|
|
2282
|
-
if (this._dataFeed) {
|
|
2283
|
-
pipeline.setWriteFeed(this._dataFeed);
|
|
2284
|
-
}
|
|
2285
|
-
await this._addFeedLock.executeSynchronized(async () => {
|
|
2286
|
-
for (const feed of this._controlPipeline.spaceState.feeds.values()) {
|
|
2287
|
-
if (feed.assertion.designation === import_credentials4.AdmittedFeed.Designation.DATA && !pipeline.hasFeed(feed.key)) {
|
|
2288
|
-
await pipeline.addFeed(await this._feedProvider(feed.key, {
|
|
2289
|
-
sparse: true
|
|
2290
|
-
}));
|
|
2291
|
-
}
|
|
2292
|
-
}
|
|
2293
|
-
});
|
|
2294
|
-
}
|
|
2295
|
-
});
|
|
2296
|
-
}
|
|
2297
|
-
get key() {
|
|
2298
|
-
return this._key;
|
|
2299
|
-
}
|
|
2300
|
-
get isOpen() {
|
|
2301
|
-
return this._isOpen;
|
|
2302
|
-
}
|
|
2303
|
-
get genesisFeedKey() {
|
|
2304
|
-
return this._genesisFeedKey;
|
|
2305
|
-
}
|
|
2306
|
-
get controlFeedKey() {
|
|
2307
|
-
return this._controlFeed?.key;
|
|
2308
|
-
}
|
|
2309
|
-
get dataFeedKey() {
|
|
2310
|
-
return this._dataFeed?.key;
|
|
2311
|
-
}
|
|
2312
|
-
get spaceState() {
|
|
2313
|
-
return this._controlPipeline.spaceState;
|
|
2314
|
-
}
|
|
2315
|
-
/**
|
|
2316
|
-
* @test-only
|
|
2317
|
-
*/
|
|
2318
|
-
get controlPipeline() {
|
|
2319
|
-
return this._controlPipeline.pipeline;
|
|
2320
|
-
}
|
|
2321
|
-
get dataPipeline() {
|
|
2322
|
-
return this._dataPipeline;
|
|
2323
|
-
}
|
|
2324
|
-
get snapshotManager() {
|
|
2325
|
-
return this._snapshotManager;
|
|
2326
|
-
}
|
|
2327
|
-
setControlFeed(feed) {
|
|
2328
|
-
(0, import_invariant9.invariant)(!this._controlFeed, "Control feed already set.", {
|
|
2329
|
-
F: __dxlog_file11,
|
|
2330
|
-
L: 186,
|
|
2331
|
-
S: this,
|
|
2332
|
-
A: [
|
|
2333
|
-
"!this._controlFeed",
|
|
2334
|
-
"'Control feed already set.'"
|
|
2335
|
-
]
|
|
2336
|
-
});
|
|
2337
|
-
this._controlFeed = feed;
|
|
2338
|
-
this._controlPipeline.setWriteFeed(feed);
|
|
2339
|
-
return this;
|
|
2340
|
-
}
|
|
2341
|
-
setDataFeed(feed) {
|
|
2342
|
-
(0, import_invariant9.invariant)(!this._dataFeed, "Data feed already set.", {
|
|
2343
|
-
F: __dxlog_file11,
|
|
2344
|
-
L: 193,
|
|
2345
|
-
S: this,
|
|
2346
|
-
A: [
|
|
2347
|
-
"!this._dataFeed",
|
|
2348
|
-
"'Data feed already set.'"
|
|
2349
|
-
]
|
|
2350
|
-
});
|
|
2351
|
-
this._dataFeed = feed;
|
|
2352
|
-
this._dataPipeline.pipeline?.setWriteFeed(feed);
|
|
2353
|
-
return this;
|
|
2354
|
-
}
|
|
2355
|
-
/**
|
|
2356
|
-
* Use for diagnostics.
|
|
2357
|
-
*/
|
|
2358
|
-
getControlFeeds() {
|
|
2359
|
-
return Array.from(this._controlPipeline.spaceState.feeds.values());
|
|
2360
|
-
}
|
|
2361
|
-
/**
|
|
2362
|
-
* Use for diagnostics.
|
|
2363
|
-
*/
|
|
2364
|
-
// getDataFeeds(): FeedInfo[] {
|
|
2365
|
-
// return this._dataPipeline?.getFeeds();
|
|
2366
|
-
// }
|
|
2367
|
-
async open(ctx) {
|
|
2368
|
-
(0, import_log10.log)("opening...", void 0, {
|
|
2369
|
-
F: __dxlog_file11,
|
|
2370
|
-
L: 215,
|
|
2371
|
-
S: this,
|
|
2372
|
-
C: (f, a) => f(...a)
|
|
2373
|
-
});
|
|
2374
|
-
if (this._isOpen) {
|
|
2375
|
-
return;
|
|
2376
|
-
}
|
|
2377
|
-
await this._controlPipeline.start();
|
|
2378
|
-
await this.protocol.start();
|
|
2379
|
-
await this._controlPipeline.spaceState.addCredentialProcessor(this._dataPipeline);
|
|
2380
|
-
this._isOpen = true;
|
|
2381
|
-
(0, import_log10.log)("opened", void 0, {
|
|
2382
|
-
F: __dxlog_file11,
|
|
2383
|
-
L: 226,
|
|
2384
|
-
S: this,
|
|
2385
|
-
C: (f, a) => f(...a)
|
|
2386
|
-
});
|
|
2387
|
-
}
|
|
2388
|
-
async close() {
|
|
2389
|
-
(0, import_log10.log)("closing...", {
|
|
2390
|
-
key: this._key
|
|
2391
|
-
}, {
|
|
2392
|
-
F: __dxlog_file11,
|
|
2393
|
-
L: 231,
|
|
2394
|
-
S: this,
|
|
2395
|
-
C: (f, a) => f(...a)
|
|
2396
|
-
});
|
|
2397
|
-
if (!this._isOpen) {
|
|
2398
|
-
return;
|
|
2399
|
-
}
|
|
2400
|
-
await this._controlPipeline.spaceState.removeCredentialProcessor(this._dataPipeline);
|
|
2401
|
-
await this._dataPipeline.close();
|
|
2402
|
-
await this.protocol.stop();
|
|
2403
|
-
await this._controlPipeline.stop();
|
|
2404
|
-
this._isOpen = false;
|
|
2405
|
-
(0, import_log10.log)("closed", void 0, {
|
|
2406
|
-
F: __dxlog_file11,
|
|
2407
|
-
L: 244,
|
|
2408
|
-
S: this,
|
|
2409
|
-
C: (f, a) => f(...a)
|
|
2410
|
-
});
|
|
2411
|
-
}
|
|
2412
|
-
async initializeDataPipeline() {
|
|
2413
|
-
(0, import_log10.log)("initializeDataPipeline", void 0, {
|
|
2414
|
-
F: __dxlog_file11,
|
|
2415
|
-
L: 249,
|
|
2416
|
-
S: this,
|
|
2417
|
-
C: (f, a) => f(...a)
|
|
2418
|
-
});
|
|
2419
|
-
(0, import_invariant9.invariant)(this._isOpen, "Space must be open to initialize data pipeline.", {
|
|
2420
|
-
F: __dxlog_file11,
|
|
2421
|
-
L: 250,
|
|
2422
|
-
S: this,
|
|
2423
|
-
A: [
|
|
2424
|
-
"this._isOpen",
|
|
2425
|
-
"'Space must be open to initialize data pipeline.'"
|
|
2426
|
-
]
|
|
2427
|
-
});
|
|
2428
|
-
await this._dataPipeline.open();
|
|
2429
|
-
}
|
|
2430
|
-
};
|
|
2431
|
-
_ts_decorate6([
|
|
2432
|
-
import_log10.logInfo,
|
|
2433
|
-
import_tracing3.trace.info()
|
|
2434
|
-
], Space.prototype, "key", null);
|
|
2435
|
-
_ts_decorate6([
|
|
2436
|
-
import_async8.synchronized,
|
|
2437
|
-
import_tracing3.trace.span()
|
|
2438
|
-
], Space.prototype, "open", null);
|
|
2439
|
-
_ts_decorate6([
|
|
2440
|
-
import_async8.synchronized
|
|
2441
|
-
], Space.prototype, "close", null);
|
|
2442
|
-
_ts_decorate6([
|
|
2443
|
-
import_async8.synchronized
|
|
2444
|
-
], Space.prototype, "initializeDataPipeline", null);
|
|
2445
|
-
Space = _ts_decorate6([
|
|
2446
|
-
(0, import_async8.trackLeaks)("open", "close"),
|
|
2447
|
-
import_tracing3.trace.resource()
|
|
2448
|
-
], Space);
|
|
2449
|
-
|
|
2450
|
-
// packages/core/echo/echo-pipeline/src/space/space-manager.ts
|
|
2451
|
-
var import_async9 = require("@dxos/async");
|
|
2452
|
-
var import_debug4 = require("@dxos/debug");
|
|
2453
|
-
var import_keys7 = require("@dxos/keys");
|
|
2454
|
-
var import_log12 = require("@dxos/log");
|
|
2455
|
-
var import_protocols7 = require("@dxos/protocols");
|
|
2456
|
-
var import_util9 = require("@dxos/util");
|
|
2457
|
-
|
|
2458
|
-
// packages/core/echo/echo-pipeline/src/space/space-protocol.ts
|
|
2459
|
-
var import_crypto3 = require("@dxos/crypto");
|
|
2460
|
-
var import_keys6 = require("@dxos/keys");
|
|
2461
|
-
var import_log11 = require("@dxos/log");
|
|
33
|
+
var import_chunk_XWUUSV4Y = require("../chunk-XWUUSV4Y.cjs");
|
|
34
|
+
var import_context = require("@dxos/context");
|
|
35
|
+
var import_credentials = require("@dxos/credentials");
|
|
36
|
+
var import_document_model = require("@dxos/document-model");
|
|
37
|
+
var import_keys = require("@dxos/keys");
|
|
38
|
+
var import_messaging = require("@dxos/messaging");
|
|
39
|
+
var import_model_factory = require("@dxos/model-factory");
|
|
2462
40
|
var import_network_manager = require("@dxos/network-manager");
|
|
2463
|
-
var
|
|
41
|
+
var import_credentials2 = require("@dxos/protocols/proto/dxos/halo/credentials");
|
|
42
|
+
var import_random_access_storage = require("@dxos/random-access-storage");
|
|
43
|
+
var import_teleport_extension_gossip = require("@dxos/teleport-extension-gossip");
|
|
2464
44
|
var import_teleport_extension_object_sync = require("@dxos/teleport-extension-object-sync");
|
|
2465
|
-
var
|
|
2466
|
-
var
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
var
|
|
2478
|
-
var
|
|
2479
|
-
var
|
|
2480
|
-
var
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
blobStore
|
|
2490
|
-
});
|
|
2491
|
-
this._topic = import_crypto3.subtleCrypto.digest("SHA-256", topic.asBuffer()).then(import_crypto3.discoveryKey).then(import_keys6.PublicKey.from);
|
|
2492
|
-
}
|
|
2493
|
-
get sessions() {
|
|
2494
|
-
return this._sessions;
|
|
2495
|
-
}
|
|
2496
|
-
get feeds() {
|
|
2497
|
-
return this._feeds;
|
|
2498
|
-
}
|
|
2499
|
-
get _ownPeerKey() {
|
|
2500
|
-
return this._swarmIdentity.peerKey;
|
|
2501
|
-
}
|
|
2502
|
-
// TODO(burdon): Create abstraction for Space (e.g., add keys and have provider).
|
|
2503
|
-
addFeed(feed) {
|
|
2504
|
-
(0, import_log11.log)("addFeed", {
|
|
2505
|
-
key: feed.key
|
|
2506
|
-
}, {
|
|
2507
|
-
F: __dxlog_file12,
|
|
2508
|
-
L: 96,
|
|
2509
|
-
S: this,
|
|
2510
|
-
C: (f, a) => f(...a)
|
|
2511
|
-
});
|
|
2512
|
-
this._feeds.add(feed);
|
|
2513
|
-
for (const session of this._sessions.values()) {
|
|
2514
|
-
session.replicator.addFeed(feed);
|
|
2515
|
-
}
|
|
2516
|
-
}
|
|
2517
|
-
// TODO(burdon): Rename open? Common open/close interfaces for all services?
|
|
2518
|
-
async start() {
|
|
2519
|
-
if (this._connection) {
|
|
2520
|
-
return;
|
|
2521
|
-
}
|
|
2522
|
-
const credentials = await this._swarmIdentity.credentialProvider(Buffer.from(""));
|
|
2523
|
-
const topologyConfig = {
|
|
2524
|
-
originateConnections: 4,
|
|
2525
|
-
maxPeers: 10,
|
|
2526
|
-
sampleSize: 20
|
|
2527
|
-
};
|
|
2528
|
-
await this.blobSync.open();
|
|
2529
|
-
(0, import_log11.log)("starting...", void 0, {
|
|
2530
|
-
F: __dxlog_file12,
|
|
2531
|
-
L: 122,
|
|
2532
|
-
S: this,
|
|
2533
|
-
C: (f, a) => f(...a)
|
|
2534
|
-
});
|
|
2535
|
-
const topic = await this._topic;
|
|
2536
|
-
this._connection = await this._networkManager.joinSwarm({
|
|
2537
|
-
protocolProvider: this._createProtocolProvider(credentials),
|
|
2538
|
-
peerId: this._swarmIdentity.peerKey,
|
|
2539
|
-
topic,
|
|
2540
|
-
topology: new import_network_manager.MMSTTopology(topologyConfig),
|
|
2541
|
-
label: `space swarm ${topic.truncate()}`
|
|
2542
|
-
});
|
|
2543
|
-
(0, import_log11.log)("started", void 0, {
|
|
2544
|
-
F: __dxlog_file12,
|
|
2545
|
-
L: 132,
|
|
2546
|
-
S: this,
|
|
2547
|
-
C: (f, a) => f(...a)
|
|
2548
|
-
});
|
|
2549
|
-
}
|
|
2550
|
-
async stop() {
|
|
2551
|
-
await this.blobSync.close();
|
|
2552
|
-
if (this._connection) {
|
|
2553
|
-
(0, import_log11.log)("stopping...", void 0, {
|
|
2554
|
-
F: __dxlog_file12,
|
|
2555
|
-
L: 139,
|
|
2556
|
-
S: this,
|
|
2557
|
-
C: (f, a) => f(...a)
|
|
2558
|
-
});
|
|
2559
|
-
await this._connection.close();
|
|
2560
|
-
(0, import_log11.log)("stopped", void 0, {
|
|
2561
|
-
F: __dxlog_file12,
|
|
2562
|
-
L: 141,
|
|
2563
|
-
S: this,
|
|
2564
|
-
C: (f, a) => f(...a)
|
|
2565
|
-
});
|
|
2566
|
-
}
|
|
2567
|
-
}
|
|
2568
|
-
_createProtocolProvider(credentials) {
|
|
2569
|
-
return (wireParams) => {
|
|
2570
|
-
const session = new SpaceProtocolSession({
|
|
2571
|
-
wireParams,
|
|
2572
|
-
swarmIdentity: this._swarmIdentity,
|
|
2573
|
-
onSessionAuth: this._onSessionAuth,
|
|
2574
|
-
onAuthFailure: this._onAuthFailure,
|
|
2575
|
-
blobSync: this.blobSync
|
|
2576
|
-
});
|
|
2577
|
-
this._sessions.set(wireParams.remotePeerId, session);
|
|
2578
|
-
for (const feed of this._feeds) {
|
|
2579
|
-
session.replicator.addFeed(feed);
|
|
2580
|
-
}
|
|
2581
|
-
return session;
|
|
2582
|
-
};
|
|
2583
|
-
}
|
|
2584
|
-
};
|
|
2585
|
-
_ts_decorate7([
|
|
2586
|
-
import_log11.logInfo
|
|
2587
|
-
], SpaceProtocol.prototype, "_topic", void 0);
|
|
2588
|
-
_ts_decorate7([
|
|
2589
|
-
import_log11.logInfo
|
|
2590
|
-
], SpaceProtocol.prototype, "_ownPeerKey", null);
|
|
2591
|
-
var AuthStatus;
|
|
2592
|
-
(function(AuthStatus2) {
|
|
2593
|
-
AuthStatus2["INITIAL"] = "INITIAL";
|
|
2594
|
-
AuthStatus2["SUCCESS"] = "SUCCESS";
|
|
2595
|
-
AuthStatus2["FAILURE"] = "FAILURE";
|
|
2596
|
-
})(AuthStatus || (AuthStatus = {}));
|
|
2597
|
-
var SpaceProtocolSession = class {
|
|
2598
|
-
// TODO(dmaretskyi): Allow to pass in extra extensions.
|
|
2599
|
-
constructor({ wireParams, swarmIdentity, onSessionAuth, onAuthFailure, blobSync }) {
|
|
2600
|
-
// TODO(dmaretskyi): Start with upload=false when switching it on the fly works.
|
|
2601
|
-
this.replicator = new import_teleport_extension_replicator.ReplicatorExtension().setOptions({
|
|
2602
|
-
upload: true
|
|
2603
|
-
});
|
|
2604
|
-
this._authStatus = AuthStatus.INITIAL;
|
|
2605
|
-
this._wireParams = wireParams;
|
|
2606
|
-
this._swarmIdentity = swarmIdentity;
|
|
2607
|
-
this._onSessionAuth = onSessionAuth;
|
|
2608
|
-
this._onAuthFailure = onAuthFailure;
|
|
2609
|
-
this._blobSync = blobSync;
|
|
2610
|
-
this._teleport = new import_teleport2.Teleport(wireParams);
|
|
2611
|
-
}
|
|
2612
|
-
get authStatus() {
|
|
2613
|
-
return this._authStatus;
|
|
2614
|
-
}
|
|
2615
|
-
get stats() {
|
|
2616
|
-
return this._teleport.stats;
|
|
2617
|
-
}
|
|
2618
|
-
get stream() {
|
|
2619
|
-
return this._teleport.stream;
|
|
2620
|
-
}
|
|
2621
|
-
async open() {
|
|
2622
|
-
await this._teleport.open();
|
|
2623
|
-
this._teleport.addExtension("dxos.mesh.teleport.auth", new AuthExtension({
|
|
2624
|
-
provider: this._swarmIdentity.credentialProvider,
|
|
2625
|
-
verifier: this._swarmIdentity.credentialAuthenticator,
|
|
2626
|
-
onAuthSuccess: () => {
|
|
2627
|
-
(0, import_log11.log)("Peer authenticated", void 0, {
|
|
2628
|
-
F: __dxlog_file12,
|
|
2629
|
-
L: 238,
|
|
2630
|
-
S: this,
|
|
2631
|
-
C: (f, a) => f(...a)
|
|
2632
|
-
});
|
|
2633
|
-
this._authStatus = AuthStatus.SUCCESS;
|
|
2634
|
-
this._onSessionAuth?.(this._teleport);
|
|
2635
|
-
},
|
|
2636
|
-
onAuthFailure: () => {
|
|
2637
|
-
this._authStatus = AuthStatus.FAILURE;
|
|
2638
|
-
this._onAuthFailure?.(this._teleport);
|
|
2639
|
-
}
|
|
2640
|
-
}));
|
|
2641
|
-
this._teleport.addExtension("dxos.mesh.teleport.replicator", this.replicator);
|
|
2642
|
-
this._teleport.addExtension("dxos.mesh.teleport.blobsync", this._blobSync.createExtension());
|
|
2643
|
-
}
|
|
2644
|
-
async close() {
|
|
2645
|
-
(0, import_log11.log)("close", void 0, {
|
|
2646
|
-
F: __dxlog_file12,
|
|
2647
|
-
L: 254,
|
|
2648
|
-
S: this,
|
|
2649
|
-
C: (f, a) => f(...a)
|
|
2650
|
-
});
|
|
2651
|
-
await this._teleport.close();
|
|
2652
|
-
}
|
|
2653
|
-
async abort() {
|
|
2654
|
-
await this._teleport.abort();
|
|
2655
|
-
}
|
|
2656
|
-
};
|
|
2657
|
-
_ts_decorate7([
|
|
2658
|
-
import_log11.logInfo
|
|
2659
|
-
], SpaceProtocolSession.prototype, "_wireParams", void 0);
|
|
2660
|
-
_ts_decorate7([
|
|
2661
|
-
import_log11.logInfo
|
|
2662
|
-
], SpaceProtocolSession.prototype, "authStatus", null);
|
|
2663
|
-
|
|
2664
|
-
// packages/core/echo/echo-pipeline/src/space/space-manager.ts
|
|
2665
|
-
function _ts_decorate8(decorators, target, key, desc) {
|
|
2666
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2667
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
2668
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
2669
|
-
else
|
|
2670
|
-
for (var i = decorators.length - 1; i >= 0; i--)
|
|
2671
|
-
if (d = decorators[i])
|
|
2672
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2673
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2674
|
-
}
|
|
2675
|
-
var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/space-manager.ts";
|
|
2676
|
-
var SpaceManager = class SpaceManager2 {
|
|
2677
|
-
constructor({ feedStore, networkManager, modelFactory, metadataStore, snapshotStore, blobStore }) {
|
|
2678
|
-
this._spaces = new import_util9.ComplexMap(import_keys7.PublicKey.hash);
|
|
2679
|
-
this._instanceId = import_keys7.PublicKey.random().toHex();
|
|
2680
|
-
this._feedStore = feedStore;
|
|
2681
|
-
this._networkManager = networkManager;
|
|
2682
|
-
this._modelFactory = modelFactory;
|
|
2683
|
-
this._metadataStore = metadataStore;
|
|
2684
|
-
this._snapshotStore = snapshotStore;
|
|
2685
|
-
this._blobStore = blobStore;
|
|
2686
|
-
}
|
|
2687
|
-
// TODO(burdon): Remove.
|
|
2688
|
-
get spaces() {
|
|
2689
|
-
return this._spaces;
|
|
2690
|
-
}
|
|
2691
|
-
async open() {
|
|
2692
|
-
}
|
|
2693
|
-
async close() {
|
|
2694
|
-
await Promise.all([
|
|
2695
|
-
...this._spaces.values()
|
|
2696
|
-
].map((space) => space.close()));
|
|
2697
|
-
}
|
|
2698
|
-
async constructSpace({ metadata, swarmIdentity, onNetworkConnection, onAuthFailure, memberKey }) {
|
|
2699
|
-
import_log12.log.trace("dxos.echo.space-manager.construct-space", import_protocols7.trace.begin({
|
|
2700
|
-
id: this._instanceId
|
|
2701
|
-
}), {
|
|
2702
|
-
F: __dxlog_file13,
|
|
2703
|
-
L: 97,
|
|
2704
|
-
S: this,
|
|
2705
|
-
C: (f, a) => f(...a)
|
|
2706
|
-
});
|
|
2707
|
-
(0, import_log12.log)("constructing space...", {
|
|
2708
|
-
spaceKey: metadata.genesisFeedKey
|
|
2709
|
-
}, {
|
|
2710
|
-
F: __dxlog_file13,
|
|
2711
|
-
L: 98,
|
|
2712
|
-
S: this,
|
|
2713
|
-
C: (f, a) => f(...a)
|
|
2714
|
-
});
|
|
2715
|
-
const genesisFeed = await this._feedStore.openFeed(metadata.genesisFeedKey ?? (0, import_debug4.failUndefined)());
|
|
2716
|
-
const spaceKey = metadata.key;
|
|
2717
|
-
const protocol = new SpaceProtocol({
|
|
2718
|
-
topic: spaceKey,
|
|
2719
|
-
swarmIdentity,
|
|
2720
|
-
networkManager: this._networkManager,
|
|
2721
|
-
onSessionAuth: onNetworkConnection,
|
|
2722
|
-
onAuthFailure,
|
|
2723
|
-
blobStore: this._blobStore
|
|
2724
|
-
});
|
|
2725
|
-
const snapshotManager = new SnapshotManager(this._snapshotStore, this._blobStore, protocol.blobSync);
|
|
2726
|
-
const space = new Space({
|
|
2727
|
-
spaceKey,
|
|
2728
|
-
protocol,
|
|
2729
|
-
genesisFeed,
|
|
2730
|
-
feedProvider: (feedKey, opts) => this._feedStore.openFeed(feedKey, opts),
|
|
2731
|
-
modelFactory: this._modelFactory,
|
|
2732
|
-
metadataStore: this._metadataStore,
|
|
2733
|
-
snapshotManager,
|
|
2734
|
-
memberKey
|
|
2735
|
-
});
|
|
2736
|
-
this._spaces.set(space.key, space);
|
|
2737
|
-
import_log12.log.trace("dxos.echo.space-manager.construct-space", import_protocols7.trace.end({
|
|
2738
|
-
id: this._instanceId
|
|
2739
|
-
}), {
|
|
2740
|
-
F: __dxlog_file13,
|
|
2741
|
-
L: 126,
|
|
2742
|
-
S: this,
|
|
2743
|
-
C: (f, a) => f(...a)
|
|
45
|
+
var import_util = require("@dxos/util");
|
|
46
|
+
var import_testing = require("@dxos/feed-store/testing");
|
|
47
|
+
var import_async = require("@dxos/async");
|
|
48
|
+
var import_document_model2 = require("@dxos/document-model");
|
|
49
|
+
var import_echo_db = require("@dxos/echo-db");
|
|
50
|
+
var import_testing2 = require("@dxos/feed-store/testing");
|
|
51
|
+
var import_keys2 = require("@dxos/keys");
|
|
52
|
+
var import_model_factory2 = require("@dxos/model-factory");
|
|
53
|
+
var import_random_access_storage2 = require("@dxos/random-access-storage");
|
|
54
|
+
var import_timeframe = require("@dxos/timeframe");
|
|
55
|
+
var import_async2 = require("@dxos/async");
|
|
56
|
+
var import_document_model3 = require("@dxos/document-model");
|
|
57
|
+
var import_echo_db2 = require("@dxos/echo-db");
|
|
58
|
+
var import_invariant = require("@dxos/invariant");
|
|
59
|
+
var import_keys3 = require("@dxos/keys");
|
|
60
|
+
var import_model_factory3 = require("@dxos/model-factory");
|
|
61
|
+
var import_protocols = require("@dxos/protocols");
|
|
62
|
+
var import_text_model = require("@dxos/text-model");
|
|
63
|
+
var import_timeframe2 = require("@dxos/timeframe");
|
|
64
|
+
var import_util2 = require("@dxos/util");
|
|
65
|
+
var TestFeedBuilder = class extends import_testing.TestBuilder {
|
|
66
|
+
constructor() {
|
|
67
|
+
super({
|
|
68
|
+
valueEncoding: import_chunk_XWUUSV4Y.valueEncoding
|
|
2744
69
|
});
|
|
2745
|
-
return space;
|
|
2746
70
|
}
|
|
2747
71
|
};
|
|
2748
|
-
|
|
2749
|
-
import_async9.synchronized
|
|
2750
|
-
], SpaceManager.prototype, "open", null);
|
|
2751
|
-
_ts_decorate8([
|
|
2752
|
-
import_async9.synchronized
|
|
2753
|
-
], SpaceManager.prototype, "close", null);
|
|
2754
|
-
SpaceManager = _ts_decorate8([
|
|
2755
|
-
(0, import_async9.trackLeaks)("open", "close")
|
|
2756
|
-
], SpaceManager);
|
|
2757
|
-
|
|
2758
|
-
// packages/core/echo/echo-pipeline/src/testing/test-agent-builder.ts
|
|
2759
|
-
var MemoryNetworkManagerProvider = (signalContext) => () => new import_network_manager2.NetworkManager({
|
|
72
|
+
var MemoryNetworkManagerProvider = (signalContext) => () => new import_network_manager.NetworkManager({
|
|
2760
73
|
signalManager: new import_messaging.MemorySignalManager(signalContext),
|
|
2761
|
-
transportFactory:
|
|
74
|
+
transportFactory: import_network_manager.MemoryTransportFactory
|
|
2762
75
|
});
|
|
2763
|
-
var WebsocketNetworkManagerProvider = (signalUrl) => () => new
|
|
76
|
+
var WebsocketNetworkManagerProvider = (signalUrl) => () => new import_network_manager.NetworkManager({
|
|
2764
77
|
signalManager: new import_messaging.WebsocketSignalManager([
|
|
2765
78
|
{
|
|
2766
79
|
server: signalUrl
|
|
2767
80
|
}
|
|
2768
81
|
]),
|
|
2769
|
-
transportFactory: (0,
|
|
82
|
+
transportFactory: (0, import_network_manager.createSimplePeerTransportFactory)()
|
|
2770
83
|
});
|
|
2771
84
|
var TestAgentBuilder = class {
|
|
2772
85
|
constructor({ storage, networkManagerProvider } = {}) {
|
|
2773
|
-
this._agents = new
|
|
86
|
+
this._agents = new import_util.ComplexMap(import_keys.PublicKey.hash);
|
|
2774
87
|
this._storage = storage ?? (0, import_random_access_storage.createStorage)({
|
|
2775
88
|
type: import_random_access_storage.StorageType.RAM
|
|
2776
89
|
});
|
|
@@ -2796,20 +109,20 @@ var TestAgentBuilder = class {
|
|
|
2796
109
|
};
|
|
2797
110
|
var TestAgent = class {
|
|
2798
111
|
get metadataStore() {
|
|
2799
|
-
return this._metadataStore ??= new MetadataStore(this.storage.createDirectory("metadata"));
|
|
112
|
+
return this._metadataStore ??= new import_chunk_XWUUSV4Y.MetadataStore(this.storage.createDirectory("metadata"));
|
|
2800
113
|
}
|
|
2801
114
|
get snapshotStore() {
|
|
2802
|
-
return this._snapshotStore ??= new SnapshotStore(this.storage.createDirectory("snapshots"));
|
|
115
|
+
return this._snapshotStore ??= new import_chunk_XWUUSV4Y.SnapshotStore(this.storage.createDirectory("snapshots"));
|
|
2803
116
|
}
|
|
2804
117
|
get blobStore() {
|
|
2805
|
-
return this._blobStore ??= new
|
|
118
|
+
return this._blobStore ??= new import_teleport_extension_object_sync.BlobStore(this.storage.createDirectory("blobs"));
|
|
2806
119
|
}
|
|
2807
120
|
constructor(_networkManagerProvider, _feedBuilder, identityKey, deviceKey) {
|
|
2808
121
|
this._networkManagerProvider = _networkManagerProvider;
|
|
2809
122
|
this._feedBuilder = _feedBuilder;
|
|
2810
123
|
this.identityKey = identityKey;
|
|
2811
124
|
this.deviceKey = deviceKey;
|
|
2812
|
-
this._spaces = new
|
|
125
|
+
this._spaces = new import_util.ComplexMap(import_keys.PublicKey.hash);
|
|
2813
126
|
this.modelFactory = new import_model_factory.ModelFactory().registerModel(import_document_model.DocumentModel);
|
|
2814
127
|
this.storage = this._feedBuilder.storage;
|
|
2815
128
|
this.keyring = this._feedBuilder.keyring;
|
|
@@ -2827,7 +140,7 @@ var TestAgent = class {
|
|
|
2827
140
|
return this._spaces.get(spaceKey);
|
|
2828
141
|
}
|
|
2829
142
|
get spaceManager() {
|
|
2830
|
-
return this._spaceManager ??= new SpaceManager({
|
|
143
|
+
return this._spaceManager ??= new import_chunk_XWUUSV4Y.SpaceManager({
|
|
2831
144
|
feedStore: this.feedStore,
|
|
2832
145
|
networkManager: this._networkManagerProvider(),
|
|
2833
146
|
modelFactory: this.modelFactory,
|
|
@@ -2865,8 +178,8 @@ var TestAgent = class {
|
|
|
2865
178
|
metadata,
|
|
2866
179
|
swarmIdentity: {
|
|
2867
180
|
peerKey: this.deviceKey,
|
|
2868
|
-
credentialProvider: MOCK_AUTH_PROVIDER,
|
|
2869
|
-
credentialAuthenticator: MOCK_AUTH_VERIFIER
|
|
181
|
+
credentialProvider: import_chunk_XWUUSV4Y.MOCK_AUTH_PROVIDER,
|
|
182
|
+
credentialAuthenticator: import_chunk_XWUUSV4Y.MOCK_AUTH_VERIFIER
|
|
2870
183
|
},
|
|
2871
184
|
memberKey: identityKey,
|
|
2872
185
|
onNetworkConnection: (session) => {
|
|
@@ -2877,17 +190,17 @@ var TestAgent = class {
|
|
|
2877
190
|
});
|
|
2878
191
|
space.setControlFeed(controlFeed);
|
|
2879
192
|
space.setDataFeed(dataFeed);
|
|
2880
|
-
await space.open(new
|
|
193
|
+
await space.open(new import_context.Context());
|
|
2881
194
|
this._spaces.set(spaceKey, space);
|
|
2882
195
|
return space;
|
|
2883
196
|
}
|
|
2884
197
|
createSpaceProtocol(topic, gossip) {
|
|
2885
|
-
return new SpaceProtocol({
|
|
198
|
+
return new import_chunk_XWUUSV4Y.SpaceProtocol({
|
|
2886
199
|
topic,
|
|
2887
200
|
swarmIdentity: {
|
|
2888
201
|
peerKey: this.deviceKey,
|
|
2889
|
-
credentialProvider: MOCK_AUTH_PROVIDER,
|
|
2890
|
-
credentialAuthenticator: MOCK_AUTH_VERIFIER
|
|
202
|
+
credentialProvider: import_chunk_XWUUSV4Y.MOCK_AUTH_PROVIDER,
|
|
203
|
+
credentialAuthenticator: import_chunk_XWUUSV4Y.MOCK_AUTH_VERIFIER
|
|
2891
204
|
},
|
|
2892
205
|
networkManager: this._networkManagerProvider(),
|
|
2893
206
|
blobStore: this.blobStore,
|
|
@@ -2912,10 +225,10 @@ var TestAgent = class {
|
|
|
2912
225
|
});
|
|
2913
226
|
}
|
|
2914
227
|
async spaceGenesis(space) {
|
|
2915
|
-
const generator = new
|
|
228
|
+
const generator = new import_credentials.CredentialGenerator(this.keyring, this.identityKey, this.deviceKey);
|
|
2916
229
|
const credentials = [
|
|
2917
230
|
...await generator.createSpaceGenesis(space.key, space.controlFeedKey),
|
|
2918
|
-
await generator.createFeedAdmission(space.key, space.dataFeedKey,
|
|
231
|
+
await generator.createFeedAdmission(space.key, space.dataFeedKey, import_credentials2.AdmittedFeed.Designation.DATA),
|
|
2919
232
|
await generator.createEpochCredential(space.key)
|
|
2920
233
|
];
|
|
2921
234
|
for (const credential of credentials) {
|
|
@@ -2927,25 +240,16 @@ var TestAgent = class {
|
|
|
2927
240
|
}
|
|
2928
241
|
}
|
|
2929
242
|
};
|
|
2930
|
-
|
|
2931
|
-
// packages/core/echo/echo-pipeline/src/testing/util.ts
|
|
2932
|
-
var import_async10 = require("@dxos/async");
|
|
2933
|
-
var import_document_model2 = require("@dxos/document-model");
|
|
2934
|
-
var import_echo_db4 = require("@dxos/echo-db");
|
|
2935
|
-
var import_testing2 = require("@dxos/feed-store/testing");
|
|
2936
|
-
var import_keys9 = require("@dxos/keys");
|
|
2937
|
-
var import_model_factory2 = require("@dxos/model-factory");
|
|
2938
|
-
var import_timeframe5 = require("@dxos/timeframe");
|
|
2939
243
|
var createMemoryDatabase = async (modelFactory) => {
|
|
2940
244
|
const feed = new import_testing2.MockFeedWriter();
|
|
2941
|
-
const backend = new DatabaseHost(feed, async () => {
|
|
245
|
+
const backend = new import_chunk_XWUUSV4Y.DatabaseHost(feed, async () => {
|
|
2942
246
|
});
|
|
2943
247
|
feed.written.on(([data, meta]) => backend.echoProcessor({
|
|
2944
248
|
batch: data.batch,
|
|
2945
249
|
meta: {
|
|
2946
250
|
...meta,
|
|
2947
|
-
memberKey:
|
|
2948
|
-
timeframe: new
|
|
251
|
+
memberKey: import_keys2.PublicKey.random(),
|
|
252
|
+
timeframe: new import_timeframe.Timeframe([
|
|
2949
253
|
[
|
|
2950
254
|
meta.feedKey,
|
|
2951
255
|
meta.seq
|
|
@@ -2953,7 +257,7 @@ var createMemoryDatabase = async (modelFactory) => {
|
|
|
2953
257
|
])
|
|
2954
258
|
}
|
|
2955
259
|
}));
|
|
2956
|
-
const itemManager = new
|
|
260
|
+
const itemManager = new import_echo_db.ItemManager(modelFactory);
|
|
2957
261
|
await backend.open(itemManager, new import_model_factory2.ModelFactory().registerModel(import_document_model2.DocumentModel));
|
|
2958
262
|
return {
|
|
2959
263
|
backend,
|
|
@@ -2961,12 +265,15 @@ var createMemoryDatabase = async (modelFactory) => {
|
|
|
2961
265
|
};
|
|
2962
266
|
};
|
|
2963
267
|
var createRemoteDatabaseFromDataServiceHost = async (modelFactory, dataServiceHost) => {
|
|
2964
|
-
const dataServiceSubscriptions = new DataServiceSubscriptions();
|
|
2965
|
-
const
|
|
2966
|
-
|
|
268
|
+
const dataServiceSubscriptions = new import_chunk_XWUUSV4Y.DataServiceSubscriptions();
|
|
269
|
+
const automergeHost = new import_chunk_XWUUSV4Y.AutomergeHost((0, import_random_access_storage2.createStorage)({
|
|
270
|
+
type: import_random_access_storage2.StorageType.RAM
|
|
271
|
+
}).createDirectory());
|
|
272
|
+
const dataService = new import_chunk_XWUUSV4Y.DataServiceImpl(dataServiceSubscriptions, automergeHost);
|
|
273
|
+
const spaceKey = import_keys2.PublicKey.random();
|
|
2967
274
|
await dataServiceSubscriptions.registerSpace(spaceKey, dataServiceHost);
|
|
2968
|
-
const itemManager = new
|
|
2969
|
-
const backend = new
|
|
275
|
+
const itemManager = new import_echo_db.ItemManager(modelFactory);
|
|
276
|
+
const backend = new import_echo_db.DatabaseProxy({
|
|
2970
277
|
service: dataService,
|
|
2971
278
|
itemManager,
|
|
2972
279
|
spaceKey
|
|
@@ -2978,7 +285,7 @@ var createRemoteDatabaseFromDataServiceHost = async (modelFactory, dataServiceHo
|
|
|
2978
285
|
};
|
|
2979
286
|
};
|
|
2980
287
|
var testLocalDatabase = async (create, check = create) => {
|
|
2981
|
-
const objectId =
|
|
288
|
+
const objectId = import_keys2.PublicKey.random().toHex();
|
|
2982
289
|
await create.databaseHost.getWriteStream()?.write({
|
|
2983
290
|
batch: {
|
|
2984
291
|
objects: [
|
|
@@ -2991,25 +298,13 @@ var testLocalDatabase = async (create, check = create) => {
|
|
|
2991
298
|
]
|
|
2992
299
|
}
|
|
2993
300
|
});
|
|
2994
|
-
await (0,
|
|
301
|
+
await (0, import_async.asyncTimeout)(check.databaseHost._itemDemuxer.mutation.waitForCondition(() => check.itemManager.entities.has(objectId)), 2e3);
|
|
2995
302
|
};
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
var import_async11 = require("@dxos/async");
|
|
2999
|
-
var import_document_model3 = require("@dxos/document-model");
|
|
3000
|
-
var import_echo_db5 = require("@dxos/echo-db");
|
|
3001
|
-
var import_invariant10 = require("@dxos/invariant");
|
|
3002
|
-
var import_keys10 = require("@dxos/keys");
|
|
3003
|
-
var import_model_factory3 = require("@dxos/model-factory");
|
|
3004
|
-
var import_protocols8 = require("@dxos/protocols");
|
|
3005
|
-
var import_text_model = require("@dxos/text-model");
|
|
3006
|
-
var import_timeframe6 = require("@dxos/timeframe");
|
|
3007
|
-
var import_util11 = require("@dxos/util");
|
|
3008
|
-
var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/testing/database-test-rig.ts";
|
|
3009
|
-
var SPACE_KEY = import_keys10.PublicKey.random();
|
|
303
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/testing/database-test-rig.ts";
|
|
304
|
+
var SPACE_KEY = import_keys3.PublicKey.random();
|
|
3010
305
|
var DatabaseTestBuilder = class {
|
|
3011
306
|
constructor() {
|
|
3012
|
-
this.peers = new
|
|
307
|
+
this.peers = new import_util2.ComplexMap(import_keys3.PublicKey.hash);
|
|
3013
308
|
}
|
|
3014
309
|
async createPeer(spaceKey = SPACE_KEY) {
|
|
3015
310
|
const peer = new DatabaseTestPeer(this, spaceKey);
|
|
@@ -3023,17 +318,17 @@ var DatabaseTestPeer = class {
|
|
|
3023
318
|
this.rig = rig;
|
|
3024
319
|
this.spaceKey = spaceKey;
|
|
3025
320
|
this.modelFactory = new import_model_factory3.ModelFactory().registerModel(import_document_model3.DocumentModel).registerModel(import_text_model.TextModel);
|
|
3026
|
-
this.key =
|
|
321
|
+
this.key = import_keys3.PublicKey.random();
|
|
3027
322
|
this.feedMessages = [];
|
|
3028
323
|
this.snapshots = /* @__PURE__ */ new Map();
|
|
3029
324
|
this.confirmed = -1;
|
|
3030
|
-
this.timeframe = new
|
|
3031
|
-
this._onConfirm = new
|
|
325
|
+
this.timeframe = new import_timeframe2.Timeframe();
|
|
326
|
+
this._onConfirm = new import_async2.Event();
|
|
3032
327
|
this._writes = /* @__PURE__ */ new Set();
|
|
3033
328
|
}
|
|
3034
329
|
async open() {
|
|
3035
|
-
this.hostItems = new
|
|
3036
|
-
this.host = new DatabaseHost({
|
|
330
|
+
this.hostItems = new import_echo_db2.ItemManager(this.modelFactory);
|
|
331
|
+
this.host = new import_chunk_XWUUSV4Y.DatabaseHost({
|
|
3037
332
|
write: async (message, { afterWrite }) => {
|
|
3038
333
|
const seq = this.feedMessages.push({
|
|
3039
334
|
timeframe: this.timeframe,
|
|
@@ -3049,7 +344,7 @@ var DatabaseTestPeer = class {
|
|
|
3049
344
|
options: {
|
|
3050
345
|
afterWrite
|
|
3051
346
|
},
|
|
3052
|
-
trigger: new
|
|
347
|
+
trigger: new import_async2.Trigger()
|
|
3053
348
|
};
|
|
3054
349
|
this._writes.add(request);
|
|
3055
350
|
await request.trigger.wait();
|
|
@@ -3061,8 +356,8 @@ var DatabaseTestPeer = class {
|
|
|
3061
356
|
if (this.snapshot) {
|
|
3062
357
|
this.host._itemDemuxer.restoreFromSnapshot(this.snapshot.database);
|
|
3063
358
|
}
|
|
3064
|
-
this.items = new
|
|
3065
|
-
this.proxy = new
|
|
359
|
+
this.items = new import_echo_db2.ItemManager(this.modelFactory);
|
|
360
|
+
this.proxy = new import_echo_db2.DatabaseProxy({
|
|
3066
361
|
service: this.host.createDataServiceHost({
|
|
3067
362
|
deferEvents: false
|
|
3068
363
|
}),
|
|
@@ -3087,7 +382,7 @@ var DatabaseTestPeer = class {
|
|
|
3087
382
|
request.trigger.wake();
|
|
3088
383
|
}
|
|
3089
384
|
}
|
|
3090
|
-
this._processMessages(
|
|
385
|
+
this._processMessages(import_timeframe2.Timeframe.merge(this.timeframe, new import_timeframe2.Timeframe([
|
|
3091
386
|
[
|
|
3092
387
|
this.key,
|
|
3093
388
|
this.confirmed
|
|
@@ -3099,7 +394,7 @@ var DatabaseTestPeer = class {
|
|
|
3099
394
|
* @param to Timeframe to replicate to. If not specified, the database will be replicated to the latest timeframe (based on all other peers).
|
|
3100
395
|
*/
|
|
3101
396
|
replicate(to) {
|
|
3102
|
-
const toTimeframe =
|
|
397
|
+
const toTimeframe = import_timeframe2.Timeframe.merge(to ?? new import_timeframe2.Timeframe(Array.from(this.rig.peers.values()).map((peer) => [
|
|
3103
398
|
peer.key,
|
|
3104
399
|
peer.confirmed
|
|
3105
400
|
])), this.timeframe);
|
|
@@ -3112,7 +407,7 @@ var DatabaseTestPeer = class {
|
|
|
3112
407
|
async reload() {
|
|
3113
408
|
await this.open();
|
|
3114
409
|
const timeframe = this.timeframe;
|
|
3115
|
-
this.timeframe = this.snapshot?.timeframe ?? new
|
|
410
|
+
this.timeframe = this.snapshot?.timeframe ?? new import_timeframe2.Timeframe();
|
|
3116
411
|
this._processMessages(timeframe);
|
|
3117
412
|
}
|
|
3118
413
|
/**
|
|
@@ -3129,10 +424,10 @@ var DatabaseTestPeer = class {
|
|
|
3129
424
|
createEpoch(mockSnapshot) {
|
|
3130
425
|
const snapshot = this.makeSnapshot();
|
|
3131
426
|
mockSnapshot && (snapshot.database = mockSnapshot);
|
|
3132
|
-
const snapshotCid =
|
|
427
|
+
const snapshotCid = import_keys3.PublicKey.from(import_protocols.schema.getCodecForType("dxos.echo.snapshot.SpaceSnapshot").encode(snapshot)).toHex();
|
|
3133
428
|
this.snapshots.set(snapshotCid, snapshot);
|
|
3134
429
|
const epoch = {
|
|
3135
|
-
previousId:
|
|
430
|
+
previousId: import_keys3.PublicKey.random(),
|
|
3136
431
|
timeframe: this.timeframe,
|
|
3137
432
|
number: this.currentEpoch ? this.currentEpoch.number + 1 : 0,
|
|
3138
433
|
snapshotCid
|
|
@@ -3153,7 +448,7 @@ var DatabaseTestPeer = class {
|
|
|
3153
448
|
seq: seq + 1,
|
|
3154
449
|
data: message
|
|
3155
450
|
};
|
|
3156
|
-
}).filter(
|
|
451
|
+
}).filter(import_util2.isNotNullOrUndefined);
|
|
3157
452
|
}
|
|
3158
453
|
_processMessages(to) {
|
|
3159
454
|
let run = true;
|
|
@@ -3169,7 +464,7 @@ var DatabaseTestPeer = class {
|
|
|
3169
464
|
if (candidate.seq <= snapshotSeq) {
|
|
3170
465
|
continue;
|
|
3171
466
|
}
|
|
3172
|
-
if (!
|
|
467
|
+
if (!import_timeframe2.Timeframe.dependencies(candidate.data.timeframe, this.timeframe).isEmpty()) {
|
|
3173
468
|
continue;
|
|
3174
469
|
}
|
|
3175
470
|
run = true;
|
|
@@ -3182,7 +477,7 @@ var DatabaseTestPeer = class {
|
|
|
3182
477
|
timeframe: candidate.data.timeframe
|
|
3183
478
|
}
|
|
3184
479
|
});
|
|
3185
|
-
this.timeframe =
|
|
480
|
+
this.timeframe = import_timeframe2.Timeframe.merge(this.timeframe, new import_timeframe2.Timeframe([
|
|
3186
481
|
[
|
|
3187
482
|
candidate.feedKey,
|
|
3188
483
|
candidate.seq
|
|
@@ -3196,8 +491,8 @@ var DatabaseTestPeer = class {
|
|
|
3196
491
|
if (!item) {
|
|
3197
492
|
return;
|
|
3198
493
|
}
|
|
3199
|
-
(0,
|
|
3200
|
-
F:
|
|
494
|
+
(0, import_invariant.invariant)(item.modelMeta, void 0, {
|
|
495
|
+
F: __dxlog_file,
|
|
3201
496
|
L: 262,
|
|
3202
497
|
S: this,
|
|
3203
498
|
A: [
|
|
@@ -3206,8 +501,8 @@ var DatabaseTestPeer = class {
|
|
|
3206
501
|
]
|
|
3207
502
|
});
|
|
3208
503
|
const ModelConstructor = this.modelFactory.getModel(item.modelMeta.type)?.constructor;
|
|
3209
|
-
(0,
|
|
3210
|
-
F:
|
|
504
|
+
(0, import_invariant.invariant)(ModelConstructor, void 0, {
|
|
505
|
+
F: __dxlog_file,
|
|
3211
506
|
L: 264,
|
|
3212
507
|
S: this,
|
|
3213
508
|
A: [
|
|
@@ -3216,8 +511,8 @@ var DatabaseTestPeer = class {
|
|
|
3216
511
|
]
|
|
3217
512
|
});
|
|
3218
513
|
const model = new ModelConstructor(item.modelMeta, item.id, () => item.state, async (mutation) => {
|
|
3219
|
-
(0,
|
|
3220
|
-
F:
|
|
514
|
+
(0, import_invariant.invariant)(item.modelMeta, void 0, {
|
|
515
|
+
F: __dxlog_file,
|
|
3221
516
|
L: 271,
|
|
3222
517
|
S: this,
|
|
3223
518
|
A: [
|
|
@@ -3225,9 +520,9 @@ var DatabaseTestPeer = class {
|
|
|
3225
520
|
""
|
|
3226
521
|
]
|
|
3227
522
|
});
|
|
3228
|
-
this.proxy.mutate((0,
|
|
523
|
+
this.proxy.mutate((0, import_echo_db2.createModelMutation)(id, (0, import_echo_db2.encodeModelMutation)(item.modelMeta, mutation)));
|
|
3229
524
|
return {
|
|
3230
|
-
feedKey:
|
|
525
|
+
feedKey: import_keys3.PublicKey.from("00"),
|
|
3231
526
|
seq: 0,
|
|
3232
527
|
waitToBeProcessed: () => Promise.resolve()
|
|
3233
528
|
};
|