@dxos/echo-pipeline 0.6.7 → 0.6.8-main.3be982f
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-NE5LORNQ.mjs +2028 -0
- package/dist/lib/browser/chunk-NE5LORNQ.mjs.map +7 -0
- package/dist/lib/browser/chunk-Q4B5JN6L.mjs +2150 -0
- package/dist/lib/browser/chunk-Q4B5JN6L.mjs.map +7 -0
- package/dist/lib/browser/chunk-XPCF2V5U.mjs +31 -0
- package/dist/lib/browser/chunk-XPCF2V5U.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +16 -16
- package/dist/lib/browser/light.mjs +32 -0
- package/dist/lib/browser/light.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +3 -7
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/chunk-5KNTTBQK.cjs +2146 -0
- package/dist/lib/node/chunk-5KNTTBQK.cjs.map +7 -0
- package/dist/lib/node/chunk-DZVH7HDD.cjs +43 -0
- package/dist/lib/node/chunk-DZVH7HDD.cjs.map +7 -0
- package/dist/lib/node/chunk-IHR4UMVA.cjs +2043 -0
- package/dist/lib/node/chunk-IHR4UMVA.cjs.map +7 -0
- package/dist/lib/node/index.cjs +35 -37
- package/dist/lib/node/index.cjs.map +2 -2
- package/dist/lib/node/light.cjs +52 -0
- package/dist/lib/node/light.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +12 -15
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
- package/dist/types/src/automerge/network-protocol.d.ts.map +1 -1
- package/dist/types/src/common/codec.d.ts +0 -1
- package/dist/types/src/common/codec.d.ts.map +1 -1
- package/dist/types/src/common/feeds.d.ts.map +1 -1
- package/dist/types/src/common/index.d.ts +1 -0
- package/dist/types/src/common/index.d.ts.map +1 -1
- package/dist/types/src/common/space-id.d.ts +7 -0
- package/dist/types/src/common/space-id.d.ts.map +1 -0
- package/dist/types/src/db-host/index.d.ts +0 -2
- package/dist/types/src/db-host/index.d.ts.map +1 -1
- package/dist/types/src/light.d.ts +4 -0
- package/dist/types/src/light.d.ts.map +1 -0
- package/dist/types/src/pipeline/message-selector.d.ts.map +1 -1
- package/dist/types/src/space/space-manager.d.ts +1 -7
- package/dist/types/src/space/space-manager.d.ts.map +1 -1
- package/dist/types/src/space/space-protocol.d.ts +0 -1
- package/dist/types/src/space/space-protocol.d.ts.map +1 -1
- package/dist/types/src/space/space.d.ts +1 -10
- package/dist/types/src/space/space.d.ts.map +1 -1
- package/dist/types/src/testing/test-agent-builder.d.ts +0 -3
- package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
- package/package.json +43 -33
- package/src/automerge/echo-network-adapter.ts +1 -1
- package/src/automerge/mesh-echo-replicator.ts +1 -1
- package/src/common/index.ts +1 -0
- package/src/common/space-id.ts +27 -0
- package/src/db-host/index.ts +0 -2
- package/src/light.ts +7 -0
- package/src/space/space-manager.ts +3 -19
- package/src/space/space.ts +2 -32
- package/src/testing/test-agent-builder.ts +0 -7
- package/dist/lib/browser/chunk-P6XSIJKM.mjs +0 -4281
- package/dist/lib/browser/chunk-P6XSIJKM.mjs.map +0 -7
- package/dist/lib/node/chunk-IYTGTZ7D.cjs +0 -4255
- package/dist/lib/node/chunk-IYTGTZ7D.cjs.map +0 -7
- package/dist/types/src/db-host/snapshot-manager.d.ts +0 -19
- package/dist/types/src/db-host/snapshot-manager.d.ts.map +0 -1
- package/dist/types/src/db-host/snapshot-store.d.ts +0 -16
- package/dist/types/src/db-host/snapshot-store.d.ts.map +0 -1
- package/dist/types/src/db-host/snapshot-store.test.d.ts +0 -2
- package/dist/types/src/db-host/snapshot-store.test.d.ts.map +0 -1
- package/src/db-host/snapshot-manager.ts +0 -54
- package/src/db-host/snapshot-store.test.ts +0 -31
- package/src/db-host/snapshot-store.ts +0 -61
|
@@ -0,0 +1,2043 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
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
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var chunk_IHR4UMVA_exports = {};
|
|
30
|
+
__export(chunk_IHR4UMVA_exports, {
|
|
31
|
+
AuthExtension: () => AuthExtension,
|
|
32
|
+
AuthStatus: () => AuthStatus,
|
|
33
|
+
CredentialRetrieverExtension: () => CredentialRetrieverExtension,
|
|
34
|
+
CredentialServerExtension: () => CredentialServerExtension,
|
|
35
|
+
MOCK_AUTH_PROVIDER: () => MOCK_AUTH_PROVIDER,
|
|
36
|
+
MOCK_AUTH_VERIFIER: () => MOCK_AUTH_VERIFIER,
|
|
37
|
+
MetadataStore: () => MetadataStore,
|
|
38
|
+
Pipeline: () => Pipeline,
|
|
39
|
+
Space: () => Space,
|
|
40
|
+
SpaceManager: () => SpaceManager,
|
|
41
|
+
SpaceProtocol: () => SpaceProtocol,
|
|
42
|
+
SpaceProtocolSession: () => SpaceProtocolSession,
|
|
43
|
+
TimeframeClock: () => TimeframeClock,
|
|
44
|
+
codec: () => codec,
|
|
45
|
+
createMappedFeedWriter: () => createMappedFeedWriter,
|
|
46
|
+
hasInvitationExpired: () => hasInvitationExpired,
|
|
47
|
+
mapFeedIndexesToTimeframe: () => mapFeedIndexesToTimeframe,
|
|
48
|
+
mapTimeframeToFeedIndexes: () => mapTimeframeToFeedIndexes,
|
|
49
|
+
startAfter: () => startAfter,
|
|
50
|
+
valueEncoding: () => valueEncoding
|
|
51
|
+
});
|
|
52
|
+
module.exports = __toCommonJS(chunk_IHR4UMVA_exports);
|
|
53
|
+
var import_chunk_DZVH7HDD = require("./chunk-DZVH7HDD.cjs");
|
|
54
|
+
var import_hypercore = require("@dxos/hypercore");
|
|
55
|
+
var import_protocols = require("@dxos/protocols");
|
|
56
|
+
var import_invariant = require("@dxos/invariant");
|
|
57
|
+
var import_crc_32 = __toESM(require("crc-32"));
|
|
58
|
+
var import_async = require("@dxos/async");
|
|
59
|
+
var import_context = require("@dxos/context");
|
|
60
|
+
var import_invariant2 = require("@dxos/invariant");
|
|
61
|
+
var import_keys = require("@dxos/keys");
|
|
62
|
+
var import_log = require("@dxos/log");
|
|
63
|
+
var import_protocols2 = require("@dxos/protocols");
|
|
64
|
+
var import_services = require("@dxos/protocols/proto/dxos/client/services");
|
|
65
|
+
var import_util = require("@dxos/util");
|
|
66
|
+
var import_async2 = require("@dxos/async");
|
|
67
|
+
var import_debug = require("@dxos/debug");
|
|
68
|
+
var import_log2 = require("@dxos/log");
|
|
69
|
+
var import_timeframe = require("@dxos/timeframe");
|
|
70
|
+
var import_async3 = require("@dxos/async");
|
|
71
|
+
var import_context2 = require("@dxos/context");
|
|
72
|
+
var import_debug2 = require("@dxos/debug");
|
|
73
|
+
var import_feed_store = require("@dxos/feed-store");
|
|
74
|
+
var import_invariant3 = require("@dxos/invariant");
|
|
75
|
+
var import_keys2 = require("@dxos/keys");
|
|
76
|
+
var import_log3 = require("@dxos/log");
|
|
77
|
+
var import_timeframe2 = require("@dxos/timeframe");
|
|
78
|
+
var import_util2 = require("@dxos/util");
|
|
79
|
+
var import_invariant4 = require("@dxos/invariant");
|
|
80
|
+
var import_log4 = require("@dxos/log");
|
|
81
|
+
var import_async4 = require("@dxos/async");
|
|
82
|
+
var import_context3 = require("@dxos/context");
|
|
83
|
+
var import_crypto = require("@dxos/crypto");
|
|
84
|
+
var import_invariant5 = require("@dxos/invariant");
|
|
85
|
+
var import_log5 = require("@dxos/log");
|
|
86
|
+
var import_protocols3 = require("@dxos/protocols");
|
|
87
|
+
var import_teleport = require("@dxos/teleport");
|
|
88
|
+
var import_async5 = require("@dxos/async");
|
|
89
|
+
var import_context4 = require("@dxos/context");
|
|
90
|
+
var import_invariant6 = require("@dxos/invariant");
|
|
91
|
+
var import_log6 = require("@dxos/log");
|
|
92
|
+
var import_credentials = require("@dxos/protocols/proto/dxos/halo/credentials");
|
|
93
|
+
var import_tracing = require("@dxos/tracing");
|
|
94
|
+
var import_util3 = require("@dxos/util");
|
|
95
|
+
var import_async6 = require("@dxos/async");
|
|
96
|
+
var import_context5 = require("@dxos/context");
|
|
97
|
+
var import_credentials2 = require("@dxos/credentials");
|
|
98
|
+
var import_keys3 = require("@dxos/keys");
|
|
99
|
+
var import_log7 = require("@dxos/log");
|
|
100
|
+
var import_credentials3 = require("@dxos/protocols/proto/dxos/halo/credentials");
|
|
101
|
+
var import_timeframe3 = require("@dxos/timeframe");
|
|
102
|
+
var import_tracing2 = require("@dxos/tracing");
|
|
103
|
+
var import_util4 = require("@dxos/util");
|
|
104
|
+
var import_async7 = require("@dxos/async");
|
|
105
|
+
var import_context6 = require("@dxos/context");
|
|
106
|
+
var import_protocols4 = require("@dxos/protocols");
|
|
107
|
+
var import_teleport2 = require("@dxos/teleport");
|
|
108
|
+
var import_crypto2 = require("@dxos/crypto");
|
|
109
|
+
var import_keys4 = require("@dxos/keys");
|
|
110
|
+
var import_log8 = require("@dxos/log");
|
|
111
|
+
var import_network_manager = require("@dxos/network-manager");
|
|
112
|
+
var import_teleport3 = require("@dxos/teleport");
|
|
113
|
+
var import_teleport_extension_object_sync = require("@dxos/teleport-extension-object-sync");
|
|
114
|
+
var import_teleport_extension_replicator = require("@dxos/teleport-extension-replicator");
|
|
115
|
+
var import_tracing3 = require("@dxos/tracing");
|
|
116
|
+
var import_util5 = require("@dxos/util");
|
|
117
|
+
var import_async8 = require("@dxos/async");
|
|
118
|
+
var import_debug3 = require("@dxos/debug");
|
|
119
|
+
var import_keys5 = require("@dxos/keys");
|
|
120
|
+
var import_log9 = require("@dxos/log");
|
|
121
|
+
var import_protocols5 = require("@dxos/protocols");
|
|
122
|
+
var import_util6 = require("@dxos/util");
|
|
123
|
+
var codec = import_protocols.schema.getCodecForType("dxos.echo.feed.FeedMessage");
|
|
124
|
+
var valueEncoding = (0, import_hypercore.createCodecEncoding)(codec);
|
|
125
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/common/feeds.ts";
|
|
126
|
+
var createMappedFeedWriter = (mapper, writer) => {
|
|
127
|
+
(0, import_invariant.invariant)(mapper, void 0, {
|
|
128
|
+
F: __dxlog_file,
|
|
129
|
+
L: 16,
|
|
130
|
+
S: void 0,
|
|
131
|
+
A: [
|
|
132
|
+
"mapper",
|
|
133
|
+
""
|
|
134
|
+
]
|
|
135
|
+
});
|
|
136
|
+
(0, import_invariant.invariant)(writer, void 0, {
|
|
137
|
+
F: __dxlog_file,
|
|
138
|
+
L: 17,
|
|
139
|
+
S: void 0,
|
|
140
|
+
A: [
|
|
141
|
+
"writer",
|
|
142
|
+
""
|
|
143
|
+
]
|
|
144
|
+
});
|
|
145
|
+
return {
|
|
146
|
+
write: async (data, options) => await writer.write(await mapper(data), options)
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
150
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
151
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
152
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
153
|
+
else
|
|
154
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
155
|
+
if (d = decorators[i])
|
|
156
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
157
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
158
|
+
}
|
|
159
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/metadata/metadata-store.ts";
|
|
160
|
+
var EXPIRED_INVITATION_CLEANUP_INTERVAL = 60 * 60 * 1e3;
|
|
161
|
+
var emptyEchoMetadata = () => ({
|
|
162
|
+
version: import_protocols2.STORAGE_VERSION,
|
|
163
|
+
spaces: [],
|
|
164
|
+
created: /* @__PURE__ */ new Date(),
|
|
165
|
+
updated: /* @__PURE__ */ new Date()
|
|
166
|
+
});
|
|
167
|
+
var emptyLargeSpaceMetadata = () => ({});
|
|
168
|
+
var EchoMetadata = import_protocols2.schema.getCodecForType("dxos.echo.metadata.EchoMetadata");
|
|
169
|
+
var LargeSpaceMetadata = import_protocols2.schema.getCodecForType("dxos.echo.metadata.LargeSpaceMetadata");
|
|
170
|
+
var MetadataStore = class {
|
|
171
|
+
constructor(directory) {
|
|
172
|
+
this._metadata = emptyEchoMetadata();
|
|
173
|
+
this._spaceLargeMetadata = new import_util.ComplexMap(import_keys.PublicKey.hash);
|
|
174
|
+
this._metadataFile = void 0;
|
|
175
|
+
this.update = new import_async.Event();
|
|
176
|
+
this._invitationCleanupCtx = new import_context.Context(void 0, {
|
|
177
|
+
F: __dxlog_file2,
|
|
178
|
+
L: 53
|
|
179
|
+
});
|
|
180
|
+
this._directory = directory;
|
|
181
|
+
}
|
|
182
|
+
get metadata() {
|
|
183
|
+
return this._metadata;
|
|
184
|
+
}
|
|
185
|
+
get version() {
|
|
186
|
+
return this._metadata.version ?? 0;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Returns a list of currently saved spaces. The list and objects in it can be modified addSpace and
|
|
190
|
+
* addSpaceFeed functions.
|
|
191
|
+
*/
|
|
192
|
+
get spaces() {
|
|
193
|
+
return this._metadata.spaces ?? [];
|
|
194
|
+
}
|
|
195
|
+
async _readFile(file, codec2) {
|
|
196
|
+
try {
|
|
197
|
+
const { size: fileLength } = await file.stat();
|
|
198
|
+
if (fileLength < 8) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const dataSize = fromBytesInt32(await file.read(0, 4));
|
|
202
|
+
const checksum = fromBytesInt32(await file.read(4, 4));
|
|
203
|
+
(0, import_log.log)("loaded", {
|
|
204
|
+
size: dataSize,
|
|
205
|
+
checksum,
|
|
206
|
+
name: file.filename
|
|
207
|
+
}, {
|
|
208
|
+
F: __dxlog_file2,
|
|
209
|
+
L: 89,
|
|
210
|
+
S: this,
|
|
211
|
+
C: (f, a) => f(...a)
|
|
212
|
+
});
|
|
213
|
+
if (fileLength < dataSize + 8) {
|
|
214
|
+
throw new import_protocols2.DataCorruptionError("Metadata size is smaller than expected.", {
|
|
215
|
+
fileLength,
|
|
216
|
+
dataSize
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
const data = await file.read(8, dataSize);
|
|
220
|
+
const calculatedChecksum = import_crc_32.default.buf(data);
|
|
221
|
+
if (calculatedChecksum !== checksum) {
|
|
222
|
+
throw new import_protocols2.DataCorruptionError("Metadata checksum is invalid.");
|
|
223
|
+
}
|
|
224
|
+
return codec2.decode(data);
|
|
225
|
+
} finally {
|
|
226
|
+
await file.close();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* @internal
|
|
231
|
+
*/
|
|
232
|
+
async _writeFile(file, codec2, data) {
|
|
233
|
+
const encoded = (0, import_util.arrayToBuffer)(codec2.encode(data));
|
|
234
|
+
const checksum = import_crc_32.default.buf(encoded);
|
|
235
|
+
const result = Buffer.alloc(8 + encoded.length);
|
|
236
|
+
result.writeInt32LE(encoded.length, 0);
|
|
237
|
+
result.writeInt32LE(checksum, 4);
|
|
238
|
+
encoded.copy(result, 8);
|
|
239
|
+
await file.write(0, result);
|
|
240
|
+
(0, import_log.log)("saved", {
|
|
241
|
+
size: encoded.length,
|
|
242
|
+
checksum
|
|
243
|
+
}, {
|
|
244
|
+
F: __dxlog_file2,
|
|
245
|
+
L: 124,
|
|
246
|
+
S: this,
|
|
247
|
+
C: (f, a) => f(...a)
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
async close() {
|
|
251
|
+
await this._invitationCleanupCtx.dispose();
|
|
252
|
+
await this.flush();
|
|
253
|
+
await this._metadataFile?.close();
|
|
254
|
+
this._metadataFile = void 0;
|
|
255
|
+
this._metadata = emptyEchoMetadata();
|
|
256
|
+
this._spaceLargeMetadata.clear();
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Loads metadata from persistent storage.
|
|
260
|
+
*/
|
|
261
|
+
async load() {
|
|
262
|
+
if (!this._metadataFile || this._metadataFile.closed) {
|
|
263
|
+
this._metadataFile = this._directory.getOrCreateFile("EchoMetadata");
|
|
264
|
+
}
|
|
265
|
+
try {
|
|
266
|
+
const metadata = await this._readFile(this._metadataFile, EchoMetadata);
|
|
267
|
+
if (metadata) {
|
|
268
|
+
this._metadata = metadata;
|
|
269
|
+
}
|
|
270
|
+
this._metadata.spaces?.forEach((space) => {
|
|
271
|
+
space.state ??= import_services.SpaceState.SPACE_ACTIVE;
|
|
272
|
+
});
|
|
273
|
+
} catch (err) {
|
|
274
|
+
import_log.log.error("failed to load metadata", {
|
|
275
|
+
err
|
|
276
|
+
}, {
|
|
277
|
+
F: __dxlog_file2,
|
|
278
|
+
L: 156,
|
|
279
|
+
S: this,
|
|
280
|
+
C: (f, a) => f(...a)
|
|
281
|
+
});
|
|
282
|
+
this._metadata = emptyEchoMetadata();
|
|
283
|
+
}
|
|
284
|
+
await (0, import_util.forEachAsync)([
|
|
285
|
+
this._metadata.identity?.haloSpace.key,
|
|
286
|
+
...this._metadata.spaces?.map((space) => space.key) ?? []
|
|
287
|
+
].filter(import_util.isNotNullOrUndefined), async (key) => {
|
|
288
|
+
try {
|
|
289
|
+
await this._loadSpaceLargeMetadata(key);
|
|
290
|
+
} catch (err) {
|
|
291
|
+
import_log.log.error("failed to load space large metadata", {
|
|
292
|
+
err
|
|
293
|
+
}, {
|
|
294
|
+
F: __dxlog_file2,
|
|
295
|
+
L: 168,
|
|
296
|
+
S: this,
|
|
297
|
+
C: (f, a) => f(...a)
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
(0, import_async.scheduleTaskInterval)(this._invitationCleanupCtx, async () => {
|
|
302
|
+
for (const invitation of this._metadata.invitations ?? []) {
|
|
303
|
+
if (hasInvitationExpired(invitation) || isLegacyInvitationFormat(invitation)) {
|
|
304
|
+
await this.removeInvitation(invitation.invitationId);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}, EXPIRED_INVITATION_CLEANUP_INTERVAL);
|
|
308
|
+
}
|
|
309
|
+
async _save() {
|
|
310
|
+
const data = {
|
|
311
|
+
...this._metadata,
|
|
312
|
+
version: import_protocols2.STORAGE_VERSION,
|
|
313
|
+
created: this._metadata.created ?? /* @__PURE__ */ new Date(),
|
|
314
|
+
updated: /* @__PURE__ */ new Date()
|
|
315
|
+
};
|
|
316
|
+
this.update.emit(data);
|
|
317
|
+
const file = this._directory.getOrCreateFile("EchoMetadata");
|
|
318
|
+
await this._writeFile(file, EchoMetadata, data);
|
|
319
|
+
}
|
|
320
|
+
async _loadSpaceLargeMetadata(key) {
|
|
321
|
+
const file = this._directory.getOrCreateFile(`space_${key.toHex()}_large`);
|
|
322
|
+
try {
|
|
323
|
+
const metadata = await this._readFile(file, LargeSpaceMetadata);
|
|
324
|
+
if (metadata) {
|
|
325
|
+
this._spaceLargeMetadata.set(key, metadata);
|
|
326
|
+
}
|
|
327
|
+
} catch (err) {
|
|
328
|
+
import_log.log.error("failed to load space large metadata", {
|
|
329
|
+
err
|
|
330
|
+
}, {
|
|
331
|
+
F: __dxlog_file2,
|
|
332
|
+
L: 210,
|
|
333
|
+
S: this,
|
|
334
|
+
C: (f, a) => f(...a)
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
async _saveSpaceLargeMetadata(key) {
|
|
339
|
+
const data = this._getLargeSpaceMetadata(key);
|
|
340
|
+
const file = this._directory.getOrCreateFile(`space_${key.toHex()}_large`);
|
|
341
|
+
await this._writeFile(file, LargeSpaceMetadata, data);
|
|
342
|
+
}
|
|
343
|
+
async flush() {
|
|
344
|
+
await this._directory.flush();
|
|
345
|
+
}
|
|
346
|
+
_getSpace(spaceKey) {
|
|
347
|
+
if (this._metadata.identity?.haloSpace.key.equals(spaceKey)) {
|
|
348
|
+
return this._metadata.identity.haloSpace;
|
|
349
|
+
}
|
|
350
|
+
const space = this.spaces.find((space2) => space2.key === spaceKey);
|
|
351
|
+
(0, import_invariant2.invariant)(space, "Space not found", {
|
|
352
|
+
F: __dxlog_file2,
|
|
353
|
+
L: 232,
|
|
354
|
+
S: this,
|
|
355
|
+
A: [
|
|
356
|
+
"space",
|
|
357
|
+
"'Space not found'"
|
|
358
|
+
]
|
|
359
|
+
});
|
|
360
|
+
return space;
|
|
361
|
+
}
|
|
362
|
+
_getLargeSpaceMetadata(key) {
|
|
363
|
+
let entry = this._spaceLargeMetadata.get(key);
|
|
364
|
+
if (entry) {
|
|
365
|
+
return entry;
|
|
366
|
+
}
|
|
367
|
+
entry = emptyLargeSpaceMetadata();
|
|
368
|
+
this._spaceLargeMetadata.set(key, entry);
|
|
369
|
+
return entry;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Clears storage - doesn't work for now.
|
|
373
|
+
*/
|
|
374
|
+
async clear() {
|
|
375
|
+
(0, import_log.log)("clearing all metadata", void 0, {
|
|
376
|
+
F: __dxlog_file2,
|
|
377
|
+
L: 251,
|
|
378
|
+
S: this,
|
|
379
|
+
C: (f, a) => f(...a)
|
|
380
|
+
});
|
|
381
|
+
await this._directory.delete();
|
|
382
|
+
this._metadata = emptyEchoMetadata();
|
|
383
|
+
}
|
|
384
|
+
getIdentityRecord() {
|
|
385
|
+
return this._metadata.identity;
|
|
386
|
+
}
|
|
387
|
+
async setIdentityRecord(record) {
|
|
388
|
+
(0, import_invariant2.invariant)(!this._metadata.identity, "Cannot overwrite existing identity in metadata", {
|
|
389
|
+
F: __dxlog_file2,
|
|
390
|
+
L: 261,
|
|
391
|
+
S: this,
|
|
392
|
+
A: [
|
|
393
|
+
"!this._metadata.identity",
|
|
394
|
+
"'Cannot overwrite existing identity in metadata'"
|
|
395
|
+
]
|
|
396
|
+
});
|
|
397
|
+
this._metadata.identity = record;
|
|
398
|
+
await this._save();
|
|
399
|
+
await this.flush();
|
|
400
|
+
}
|
|
401
|
+
getInvitations() {
|
|
402
|
+
return this._metadata.invitations ?? [];
|
|
403
|
+
}
|
|
404
|
+
async addInvitation(invitation) {
|
|
405
|
+
if (this._metadata.invitations?.find((i) => i.invitationId === invitation.invitationId)) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
(this._metadata.invitations ??= []).push(invitation);
|
|
409
|
+
await this._save();
|
|
410
|
+
await this.flush();
|
|
411
|
+
}
|
|
412
|
+
async removeInvitation(invitationId) {
|
|
413
|
+
this._metadata.invitations = (this._metadata.invitations ?? []).filter((i) => i.invitationId !== invitationId);
|
|
414
|
+
await this._save();
|
|
415
|
+
await this.flush();
|
|
416
|
+
}
|
|
417
|
+
async addSpace(record) {
|
|
418
|
+
(0, import_invariant2.invariant)(!(this._metadata.spaces ?? []).find((space) => space.key === record.key), "Cannot overwrite existing space in metadata", {
|
|
419
|
+
F: __dxlog_file2,
|
|
420
|
+
L: 289,
|
|
421
|
+
S: this,
|
|
422
|
+
A: [
|
|
423
|
+
"!(this._metadata.spaces ?? []).find((space) => space.key === record.key)",
|
|
424
|
+
"'Cannot overwrite existing space in metadata'"
|
|
425
|
+
]
|
|
426
|
+
});
|
|
427
|
+
(this._metadata.spaces ??= []).push(record);
|
|
428
|
+
await this._save();
|
|
429
|
+
await this.flush();
|
|
430
|
+
}
|
|
431
|
+
async setSpaceDataLatestTimeframe(spaceKey, timeframe) {
|
|
432
|
+
this._getSpace(spaceKey).dataTimeframe = timeframe;
|
|
433
|
+
await this._save();
|
|
434
|
+
}
|
|
435
|
+
async setSpaceControlLatestTimeframe(spaceKey, timeframe) {
|
|
436
|
+
this._getSpace(spaceKey).controlTimeframe = timeframe;
|
|
437
|
+
await this._save();
|
|
438
|
+
await this.flush();
|
|
439
|
+
}
|
|
440
|
+
async setCache(spaceKey, cache) {
|
|
441
|
+
this._getSpace(spaceKey).cache = cache;
|
|
442
|
+
await this._save();
|
|
443
|
+
}
|
|
444
|
+
async setWritableFeedKeys(spaceKey, controlFeedKey, dataFeedKey) {
|
|
445
|
+
const space = this._getSpace(spaceKey);
|
|
446
|
+
space.controlFeedKey = controlFeedKey;
|
|
447
|
+
space.dataFeedKey = dataFeedKey;
|
|
448
|
+
await this._save();
|
|
449
|
+
await this.flush();
|
|
450
|
+
}
|
|
451
|
+
async setSpaceState(spaceKey, state) {
|
|
452
|
+
this._getSpace(spaceKey).state = state;
|
|
453
|
+
await this._save();
|
|
454
|
+
await this.flush();
|
|
455
|
+
}
|
|
456
|
+
getSpaceControlPipelineSnapshot(spaceKey) {
|
|
457
|
+
return this._getLargeSpaceMetadata(spaceKey).controlPipelineSnapshot;
|
|
458
|
+
}
|
|
459
|
+
async setSpaceControlPipelineSnapshot(spaceKey, snapshot) {
|
|
460
|
+
this._getLargeSpaceMetadata(spaceKey).controlPipelineSnapshot = snapshot;
|
|
461
|
+
await this._saveSpaceLargeMetadata(spaceKey);
|
|
462
|
+
await this.flush();
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
_ts_decorate([
|
|
466
|
+
import_async.synchronized
|
|
467
|
+
], MetadataStore.prototype, "load", null);
|
|
468
|
+
_ts_decorate([
|
|
469
|
+
import_async.synchronized
|
|
470
|
+
], MetadataStore.prototype, "_save", null);
|
|
471
|
+
_ts_decorate([
|
|
472
|
+
import_async.synchronized
|
|
473
|
+
], MetadataStore.prototype, "_saveSpaceLargeMetadata", null);
|
|
474
|
+
var fromBytesInt32 = (buf) => buf.readInt32LE(0);
|
|
475
|
+
var hasInvitationExpired = (invitation) => {
|
|
476
|
+
return Boolean(invitation.created && invitation.lifetime && invitation.lifetime !== 0 && invitation.created.getTime() + invitation.lifetime * 1e3 < Date.now());
|
|
477
|
+
};
|
|
478
|
+
var isLegacyInvitationFormat = (invitation) => {
|
|
479
|
+
return invitation.type === import_services.Invitation.Type.MULTIUSE;
|
|
480
|
+
};
|
|
481
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
482
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
483
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
484
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
485
|
+
else
|
|
486
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
487
|
+
if (d = decorators[i])
|
|
488
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
489
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
490
|
+
}
|
|
491
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/pipeline/timeframe-clock.ts";
|
|
492
|
+
var mapTimeframeToFeedIndexes = (timeframe) => timeframe.frames().map(([feedKey, index]) => ({
|
|
493
|
+
feedKey,
|
|
494
|
+
index
|
|
495
|
+
}));
|
|
496
|
+
var mapFeedIndexesToTimeframe = (indexes) => new import_timeframe.Timeframe(indexes.map(({ feedKey, index }) => [
|
|
497
|
+
feedKey,
|
|
498
|
+
index
|
|
499
|
+
]));
|
|
500
|
+
var startAfter = (timeframe) => timeframe.frames().map(([feedKey, index]) => ({
|
|
501
|
+
feedKey,
|
|
502
|
+
index: index + 1
|
|
503
|
+
}));
|
|
504
|
+
var TimeframeClock = class {
|
|
505
|
+
constructor(_timeframe = new import_timeframe.Timeframe()) {
|
|
506
|
+
this._timeframe = _timeframe;
|
|
507
|
+
this.update = new import_async2.Event();
|
|
508
|
+
this._pendingTimeframe = _timeframe;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Timeframe that was processed by ECHO.
|
|
512
|
+
*/
|
|
513
|
+
get timeframe() {
|
|
514
|
+
return this._timeframe;
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Timeframe that is currently being processed by ECHO.
|
|
518
|
+
* Will be equal to `timeframe` after the processing is complete.
|
|
519
|
+
*/
|
|
520
|
+
get pendingTimeframe() {
|
|
521
|
+
return this._pendingTimeframe;
|
|
522
|
+
}
|
|
523
|
+
setTimeframe(timeframe) {
|
|
524
|
+
this._timeframe = timeframe;
|
|
525
|
+
this._pendingTimeframe = timeframe;
|
|
526
|
+
this.update.emit(this._timeframe);
|
|
527
|
+
}
|
|
528
|
+
updatePendingTimeframe(key, seq) {
|
|
529
|
+
this._pendingTimeframe = import_timeframe.Timeframe.merge(this._pendingTimeframe, new import_timeframe.Timeframe([
|
|
530
|
+
[
|
|
531
|
+
key,
|
|
532
|
+
seq
|
|
533
|
+
]
|
|
534
|
+
]));
|
|
535
|
+
}
|
|
536
|
+
updateTimeframe() {
|
|
537
|
+
this._timeframe = this._pendingTimeframe;
|
|
538
|
+
this.update.emit(this._timeframe);
|
|
539
|
+
}
|
|
540
|
+
hasGaps(timeframe) {
|
|
541
|
+
const gaps = import_timeframe.Timeframe.dependencies(timeframe, this._timeframe);
|
|
542
|
+
return !gaps.isEmpty();
|
|
543
|
+
}
|
|
544
|
+
async waitUntilReached(target) {
|
|
545
|
+
(0, import_log2.log)("waitUntilReached", {
|
|
546
|
+
target,
|
|
547
|
+
current: this._timeframe
|
|
548
|
+
}, {
|
|
549
|
+
F: __dxlog_file3,
|
|
550
|
+
L: 70,
|
|
551
|
+
S: this,
|
|
552
|
+
C: (f, a) => f(...a)
|
|
553
|
+
});
|
|
554
|
+
await this.update.waitForCondition(() => {
|
|
555
|
+
(0, import_log2.log)("check if reached", {
|
|
556
|
+
target,
|
|
557
|
+
current: this._timeframe,
|
|
558
|
+
deps: import_timeframe.Timeframe.dependencies(target, this._timeframe)
|
|
559
|
+
}, {
|
|
560
|
+
F: __dxlog_file3,
|
|
561
|
+
L: 72,
|
|
562
|
+
S: this,
|
|
563
|
+
C: (f, a) => f(...a)
|
|
564
|
+
});
|
|
565
|
+
return import_timeframe.Timeframe.dependencies(target, this._timeframe).isEmpty();
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
_ts_decorate2([
|
|
570
|
+
(0, import_debug.timed)(5e3)
|
|
571
|
+
], TimeframeClock.prototype, "waitUntilReached", null);
|
|
572
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/pipeline/message-selector.ts";
|
|
573
|
+
var createMessageSelector = (timeframeClock) => {
|
|
574
|
+
return (messages) => {
|
|
575
|
+
for (let i = 0; i < messages.length; i++) {
|
|
576
|
+
const { data: { timeframe } } = messages[i];
|
|
577
|
+
(0, import_invariant4.invariant)(timeframe, void 0, {
|
|
578
|
+
F: __dxlog_file4,
|
|
579
|
+
L: 25,
|
|
580
|
+
S: void 0,
|
|
581
|
+
A: [
|
|
582
|
+
"timeframe",
|
|
583
|
+
""
|
|
584
|
+
]
|
|
585
|
+
});
|
|
586
|
+
if (!timeframeClock.hasGaps(timeframe)) {
|
|
587
|
+
return i;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
(0, import_log4.log)("Skipping...", void 0, {
|
|
591
|
+
F: __dxlog_file4,
|
|
592
|
+
L: 33,
|
|
593
|
+
S: void 0,
|
|
594
|
+
C: (f, a) => f(...a)
|
|
595
|
+
});
|
|
596
|
+
};
|
|
597
|
+
};
|
|
598
|
+
function _ts_decorate3(decorators, target, key, desc) {
|
|
599
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
600
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
601
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
602
|
+
else
|
|
603
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
604
|
+
if (d = decorators[i])
|
|
605
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
606
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
607
|
+
}
|
|
608
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/pipeline/pipeline.ts";
|
|
609
|
+
var PipelineState = class {
|
|
610
|
+
constructor(_feeds, _timeframeClock) {
|
|
611
|
+
this._feeds = _feeds;
|
|
612
|
+
this._timeframeClock = _timeframeClock;
|
|
613
|
+
this._ctx = new import_context2.Context(void 0, {
|
|
614
|
+
F: __dxlog_file5,
|
|
615
|
+
L: 41
|
|
616
|
+
});
|
|
617
|
+
this.timeframeUpdate = this._timeframeClock.update;
|
|
618
|
+
this.stalled = new import_async3.Event();
|
|
619
|
+
this._startTimeframe = new import_timeframe2.Timeframe();
|
|
620
|
+
this._reachedTarget = false;
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Latest theoretical timeframe based on the last mutation in each feed.
|
|
624
|
+
* NOTE: This might never be reached if the mutation dependencies
|
|
625
|
+
*/
|
|
626
|
+
// TODO(dmaretskyi): Rename `totalTimeframe`? or `lastTimeframe`.
|
|
627
|
+
get endTimeframe() {
|
|
628
|
+
return mapFeedIndexesToTimeframe(Array.from(this._feeds.values()).filter((feed) => feed.length > 0).map((feed) => ({
|
|
629
|
+
feedKey: feed.key,
|
|
630
|
+
index: feed.length - 1
|
|
631
|
+
})));
|
|
632
|
+
}
|
|
633
|
+
get startTimeframe() {
|
|
634
|
+
return this._startTimeframe;
|
|
635
|
+
}
|
|
636
|
+
get timeframe() {
|
|
637
|
+
return this._timeframeClock.timeframe;
|
|
638
|
+
}
|
|
639
|
+
get pendingTimeframe() {
|
|
640
|
+
return this._timeframeClock.pendingTimeframe;
|
|
641
|
+
}
|
|
642
|
+
get targetTimeframe() {
|
|
643
|
+
return this._targetTimeframe ? this._targetTimeframe : new import_timeframe2.Timeframe();
|
|
644
|
+
}
|
|
645
|
+
get reachedTarget() {
|
|
646
|
+
return this._reachedTarget;
|
|
647
|
+
}
|
|
648
|
+
get feeds() {
|
|
649
|
+
return Array.from(this._feeds.values());
|
|
650
|
+
}
|
|
651
|
+
async waitUntilTimeframe(target) {
|
|
652
|
+
await this._timeframeClock.waitUntilReached(target);
|
|
653
|
+
}
|
|
654
|
+
setTargetTimeframe(target) {
|
|
655
|
+
this._targetTimeframe = target;
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Wait until the pipeline processes all messages in the feed and reaches the target timeframe if that is set.
|
|
659
|
+
*
|
|
660
|
+
* This function will resolve immediately if the pipeline is stalled.
|
|
661
|
+
*
|
|
662
|
+
* @param timeout Timeout in milliseconds to specify the maximum wait time.
|
|
663
|
+
*/
|
|
664
|
+
async waitUntilReachedTargetTimeframe({ ctx = new import_context2.Context(void 0, {
|
|
665
|
+
F: __dxlog_file5,
|
|
666
|
+
L: 129
|
|
667
|
+
}), timeout, breakOnStall = true } = {}) {
|
|
668
|
+
(0, import_log3.log)("waitUntilReachedTargetTimeframe", {
|
|
669
|
+
timeout,
|
|
670
|
+
current: this.timeframe,
|
|
671
|
+
target: this.targetTimeframe
|
|
672
|
+
}, {
|
|
673
|
+
F: __dxlog_file5,
|
|
674
|
+
L: 133,
|
|
675
|
+
S: this,
|
|
676
|
+
C: (f, a) => f(...a)
|
|
677
|
+
});
|
|
678
|
+
this._reachedTargetPromise ??= Promise.race([
|
|
679
|
+
this._timeframeClock.update.waitForCondition(() => {
|
|
680
|
+
return import_timeframe2.Timeframe.dependencies(this.targetTimeframe, this.timeframe).isEmpty();
|
|
681
|
+
}),
|
|
682
|
+
...breakOnStall ? [
|
|
683
|
+
this.stalled.discardParameter().waitForCount(1)
|
|
684
|
+
] : []
|
|
685
|
+
]);
|
|
686
|
+
let done = false;
|
|
687
|
+
if (timeout) {
|
|
688
|
+
return Promise.race([
|
|
689
|
+
(0, import_context2.rejectOnDispose)(ctx),
|
|
690
|
+
(0, import_context2.rejectOnDispose)(this._ctx),
|
|
691
|
+
this._reachedTargetPromise.then(() => {
|
|
692
|
+
done = true;
|
|
693
|
+
this._reachedTarget = true;
|
|
694
|
+
}),
|
|
695
|
+
(0, import_async3.sleepWithContext)(this._ctx, timeout).then(() => {
|
|
696
|
+
if (done) {
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
import_log3.log.warn("waitUntilReachedTargetTimeframe timed out", {
|
|
700
|
+
timeout,
|
|
701
|
+
current: this.timeframe,
|
|
702
|
+
target: this.targetTimeframe,
|
|
703
|
+
dependencies: import_timeframe2.Timeframe.dependencies(this.targetTimeframe, this.timeframe)
|
|
704
|
+
}, {
|
|
705
|
+
F: __dxlog_file5,
|
|
706
|
+
L: 161,
|
|
707
|
+
S: this,
|
|
708
|
+
C: (f, a) => f(...a)
|
|
709
|
+
});
|
|
710
|
+
})
|
|
711
|
+
]);
|
|
712
|
+
} else {
|
|
713
|
+
return this._reachedTargetPromise;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
};
|
|
717
|
+
var Pipeline = class {
|
|
718
|
+
constructor() {
|
|
719
|
+
this._timeframeClock = new TimeframeClock(new import_timeframe2.Timeframe());
|
|
720
|
+
this._feeds = new import_util2.ComplexMap(import_keys2.PublicKey.hash);
|
|
721
|
+
this._state = new PipelineState(this._feeds, this._timeframeClock);
|
|
722
|
+
this._processingTrigger = new import_async3.Trigger().wake();
|
|
723
|
+
this._pauseTrigger = new import_async3.Trigger().wake();
|
|
724
|
+
this._downloads = new import_util2.ComplexMap((value) => import_keys2.PublicKey.hash(value.key));
|
|
725
|
+
this._isStopping = false;
|
|
726
|
+
this._isStarted = false;
|
|
727
|
+
this._isBeingConsumed = false;
|
|
728
|
+
this._isPaused = false;
|
|
729
|
+
}
|
|
730
|
+
get state() {
|
|
731
|
+
return this._state;
|
|
732
|
+
}
|
|
733
|
+
get writer() {
|
|
734
|
+
(0, import_invariant3.invariant)(this._writer, "Writer not set.", {
|
|
735
|
+
F: __dxlog_file5,
|
|
736
|
+
L: 243,
|
|
737
|
+
S: this,
|
|
738
|
+
A: [
|
|
739
|
+
"this._writer",
|
|
740
|
+
"'Writer not set.'"
|
|
741
|
+
]
|
|
742
|
+
});
|
|
743
|
+
return this._writer;
|
|
744
|
+
}
|
|
745
|
+
hasFeed(feedKey) {
|
|
746
|
+
return this._feeds.has(feedKey);
|
|
747
|
+
}
|
|
748
|
+
getFeeds() {
|
|
749
|
+
return this._feedSetIterator.feeds;
|
|
750
|
+
}
|
|
751
|
+
// NOTE: This cannot be synchronized with `stop` because stop waits for the mutation processing to complete,
|
|
752
|
+
// which might be opening feeds during the mutation processing, which w
|
|
753
|
+
async addFeed(feed) {
|
|
754
|
+
this._feeds.set(feed.key, feed);
|
|
755
|
+
if (this._feedSetIterator) {
|
|
756
|
+
await this._feedSetIterator.addFeed(feed);
|
|
757
|
+
}
|
|
758
|
+
if (this._isStarted && !this._isPaused) {
|
|
759
|
+
this._setFeedDownloadState(feed);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
setWriteFeed(feed) {
|
|
763
|
+
(0, import_invariant3.invariant)(!this._writer, "Writer already set.", {
|
|
764
|
+
F: __dxlog_file5,
|
|
765
|
+
L: 270,
|
|
766
|
+
S: this,
|
|
767
|
+
A: [
|
|
768
|
+
"!this._writer",
|
|
769
|
+
"'Writer already set.'"
|
|
770
|
+
]
|
|
771
|
+
});
|
|
772
|
+
(0, import_invariant3.invariant)(feed.properties.writable, "Feed must be writable.", {
|
|
773
|
+
F: __dxlog_file5,
|
|
774
|
+
L: 271,
|
|
775
|
+
S: this,
|
|
776
|
+
A: [
|
|
777
|
+
"feed.properties.writable",
|
|
778
|
+
"'Feed must be writable.'"
|
|
779
|
+
]
|
|
780
|
+
});
|
|
781
|
+
this._writer = createMappedFeedWriter((payload) => ({
|
|
782
|
+
timeframe: this._timeframeClock.timeframe,
|
|
783
|
+
payload
|
|
784
|
+
}), feed.createFeedWriter());
|
|
785
|
+
}
|
|
786
|
+
async start() {
|
|
787
|
+
(0, import_invariant3.invariant)(!this._isStarted, "Pipeline is already started.", {
|
|
788
|
+
F: __dxlog_file5,
|
|
789
|
+
L: 284,
|
|
790
|
+
S: this,
|
|
791
|
+
A: [
|
|
792
|
+
"!this._isStarted",
|
|
793
|
+
"'Pipeline is already started.'"
|
|
794
|
+
]
|
|
795
|
+
});
|
|
796
|
+
(0, import_log3.log)("starting...", void 0, {
|
|
797
|
+
F: __dxlog_file5,
|
|
798
|
+
L: 285,
|
|
799
|
+
S: this,
|
|
800
|
+
C: (f, a) => f(...a)
|
|
801
|
+
});
|
|
802
|
+
await this._initIterator();
|
|
803
|
+
await this._feedSetIterator.open();
|
|
804
|
+
this._isStarted = true;
|
|
805
|
+
(0, import_log3.log)("started", void 0, {
|
|
806
|
+
F: __dxlog_file5,
|
|
807
|
+
L: 289,
|
|
808
|
+
S: this,
|
|
809
|
+
C: (f, a) => f(...a)
|
|
810
|
+
});
|
|
811
|
+
if (!this._isPaused) {
|
|
812
|
+
for (const feed of this._feeds.values()) {
|
|
813
|
+
this._setFeedDownloadState(feed);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
async stop() {
|
|
818
|
+
(0, import_log3.log)("stopping...", void 0, {
|
|
819
|
+
F: __dxlog_file5,
|
|
820
|
+
L: 300,
|
|
821
|
+
S: this,
|
|
822
|
+
C: (f, a) => f(...a)
|
|
823
|
+
});
|
|
824
|
+
this._isStopping = true;
|
|
825
|
+
for (const [feed, handle] of this._downloads.entries()) {
|
|
826
|
+
feed.undownload(handle);
|
|
827
|
+
}
|
|
828
|
+
this._downloads.clear();
|
|
829
|
+
await this._feedSetIterator?.close();
|
|
830
|
+
await this._processingTrigger.wait();
|
|
831
|
+
await this._state._ctx.dispose();
|
|
832
|
+
this._state._ctx = new import_context2.Context(void 0, {
|
|
833
|
+
F: __dxlog_file5,
|
|
834
|
+
L: 309
|
|
835
|
+
});
|
|
836
|
+
this._state._reachedTargetPromise = void 0;
|
|
837
|
+
this._state._reachedTarget = false;
|
|
838
|
+
this._isStarted = false;
|
|
839
|
+
(0, import_log3.log)("stopped", void 0, {
|
|
840
|
+
F: __dxlog_file5,
|
|
841
|
+
L: 313,
|
|
842
|
+
S: this,
|
|
843
|
+
C: (f, a) => f(...a)
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* @param timeframe Timeframe of already processed messages.
|
|
848
|
+
* The pipeline will start processing messages AFTER this timeframe.
|
|
849
|
+
*/
|
|
850
|
+
async setCursor(timeframe) {
|
|
851
|
+
(0, import_invariant3.invariant)(!this._isStarted || this._isPaused, "Invalid state.", {
|
|
852
|
+
F: __dxlog_file5,
|
|
853
|
+
L: 322,
|
|
854
|
+
S: this,
|
|
855
|
+
A: [
|
|
856
|
+
"!this._isStarted || this._isPaused",
|
|
857
|
+
"'Invalid state.'"
|
|
858
|
+
]
|
|
859
|
+
});
|
|
860
|
+
this._state._startTimeframe = timeframe;
|
|
861
|
+
this._timeframeClock.setTimeframe(timeframe);
|
|
862
|
+
if (this._feedSetIterator) {
|
|
863
|
+
await this._feedSetIterator.close();
|
|
864
|
+
await this._initIterator();
|
|
865
|
+
await this._feedSetIterator.open();
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
/**
|
|
869
|
+
* Calling pause while processing will cause a deadlock.
|
|
870
|
+
*/
|
|
871
|
+
async pause() {
|
|
872
|
+
if (this._isPaused) {
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
this._pauseTrigger.reset();
|
|
876
|
+
await this._processingTrigger.wait();
|
|
877
|
+
this._isPaused = true;
|
|
878
|
+
}
|
|
879
|
+
async unpause() {
|
|
880
|
+
(0, import_invariant3.invariant)(this._isPaused, "Pipeline is not paused.", {
|
|
881
|
+
F: __dxlog_file5,
|
|
882
|
+
L: 351,
|
|
883
|
+
S: this,
|
|
884
|
+
A: [
|
|
885
|
+
"this._isPaused",
|
|
886
|
+
"'Pipeline is not paused.'"
|
|
887
|
+
]
|
|
888
|
+
});
|
|
889
|
+
this._pauseTrigger.wake();
|
|
890
|
+
this._isPaused = false;
|
|
891
|
+
for (const feed of this._feeds.values()) {
|
|
892
|
+
this._setFeedDownloadState(feed);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* Starts to iterate over the ordered messages from the added feeds.
|
|
897
|
+
* Updates the timeframe clock after the message has bee processed.
|
|
898
|
+
*/
|
|
899
|
+
async *consume() {
|
|
900
|
+
(0, import_invariant3.invariant)(!this._isBeingConsumed, "Pipeline is already being consumed.", {
|
|
901
|
+
F: __dxlog_file5,
|
|
902
|
+
L: 366,
|
|
903
|
+
S: this,
|
|
904
|
+
A: [
|
|
905
|
+
"!this._isBeingConsumed",
|
|
906
|
+
"'Pipeline is already being consumed.'"
|
|
907
|
+
]
|
|
908
|
+
});
|
|
909
|
+
this._isBeingConsumed = true;
|
|
910
|
+
(0, import_invariant3.invariant)(this._feedSetIterator, "Iterator not initialized.", {
|
|
911
|
+
F: __dxlog_file5,
|
|
912
|
+
L: 369,
|
|
913
|
+
S: this,
|
|
914
|
+
A: [
|
|
915
|
+
"this._feedSetIterator",
|
|
916
|
+
"'Iterator not initialized.'"
|
|
917
|
+
]
|
|
918
|
+
});
|
|
919
|
+
let lastFeedSetIterator = this._feedSetIterator;
|
|
920
|
+
let iterable = lastFeedSetIterator[Symbol.asyncIterator]();
|
|
921
|
+
while (!this._isStopping) {
|
|
922
|
+
await this._pauseTrigger.wait();
|
|
923
|
+
if (lastFeedSetIterator !== this._feedSetIterator) {
|
|
924
|
+
(0, import_invariant3.invariant)(this._feedSetIterator, "Iterator not initialized.", {
|
|
925
|
+
F: __dxlog_file5,
|
|
926
|
+
L: 378,
|
|
927
|
+
S: this,
|
|
928
|
+
A: [
|
|
929
|
+
"this._feedSetIterator",
|
|
930
|
+
"'Iterator not initialized.'"
|
|
931
|
+
]
|
|
932
|
+
});
|
|
933
|
+
lastFeedSetIterator = this._feedSetIterator;
|
|
934
|
+
iterable = lastFeedSetIterator[Symbol.asyncIterator]();
|
|
935
|
+
}
|
|
936
|
+
const { done, value } = await iterable.next();
|
|
937
|
+
if (!done) {
|
|
938
|
+
const block = value ?? (0, import_debug2.failUndefined)();
|
|
939
|
+
this._processingTrigger.reset();
|
|
940
|
+
this._timeframeClock.updatePendingTimeframe(import_keys2.PublicKey.from(block.feedKey), block.seq);
|
|
941
|
+
yield block;
|
|
942
|
+
this._processingTrigger.wake();
|
|
943
|
+
this._timeframeClock.updateTimeframe();
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
this._isBeingConsumed = false;
|
|
947
|
+
}
|
|
948
|
+
_setFeedDownloadState(feed) {
|
|
949
|
+
let handle = this._downloads.get(feed);
|
|
950
|
+
if (handle) {
|
|
951
|
+
feed.undownload(handle);
|
|
952
|
+
}
|
|
953
|
+
const timeframe = this._state._startTimeframe;
|
|
954
|
+
const seq = timeframe.get(feed.key) ?? -1;
|
|
955
|
+
(0, import_log3.log)("download", {
|
|
956
|
+
feed: feed.key.truncate(),
|
|
957
|
+
seq,
|
|
958
|
+
length: feed.length
|
|
959
|
+
}, {
|
|
960
|
+
F: __dxlog_file5,
|
|
961
|
+
L: 407,
|
|
962
|
+
S: this,
|
|
963
|
+
C: (f, a) => f(...a)
|
|
964
|
+
});
|
|
965
|
+
handle = feed.download({
|
|
966
|
+
start: seq + 1,
|
|
967
|
+
linear: true
|
|
968
|
+
}, (err, data) => {
|
|
969
|
+
if (err) {
|
|
970
|
+
} else {
|
|
971
|
+
import_log3.log.info("downloaded", {
|
|
972
|
+
data
|
|
973
|
+
}, {
|
|
974
|
+
F: __dxlog_file5,
|
|
975
|
+
L: 412,
|
|
976
|
+
S: this,
|
|
977
|
+
C: (f, a) => f(...a)
|
|
978
|
+
});
|
|
979
|
+
}
|
|
980
|
+
});
|
|
981
|
+
this._downloads.set(feed, handle);
|
|
982
|
+
}
|
|
983
|
+
async _initIterator() {
|
|
984
|
+
this._feedSetIterator = new import_feed_store.FeedSetIterator(createMessageSelector(this._timeframeClock), {
|
|
985
|
+
start: startAfter(this._timeframeClock.timeframe),
|
|
986
|
+
stallTimeout: 1e3
|
|
987
|
+
});
|
|
988
|
+
this._feedSetIterator.stalled.on((iterator) => {
|
|
989
|
+
import_log3.log.warn(`Stalled after ${iterator.options.stallTimeout}ms with ${iterator.size} feeds.`, void 0, {
|
|
990
|
+
F: __dxlog_file5,
|
|
991
|
+
L: 426,
|
|
992
|
+
S: this,
|
|
993
|
+
C: (f, a) => f(...a)
|
|
994
|
+
});
|
|
995
|
+
this._state.stalled.emit();
|
|
996
|
+
});
|
|
997
|
+
for (const feed of this._feeds.values()) {
|
|
998
|
+
await this._feedSetIterator.addFeed(feed);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
1002
|
+
_ts_decorate3([
|
|
1003
|
+
import_async3.synchronized
|
|
1004
|
+
], Pipeline.prototype, "start", null);
|
|
1005
|
+
_ts_decorate3([
|
|
1006
|
+
import_async3.synchronized
|
|
1007
|
+
], Pipeline.prototype, "stop", null);
|
|
1008
|
+
_ts_decorate3([
|
|
1009
|
+
import_async3.synchronized
|
|
1010
|
+
], Pipeline.prototype, "setCursor", null);
|
|
1011
|
+
_ts_decorate3([
|
|
1012
|
+
import_async3.synchronized
|
|
1013
|
+
], Pipeline.prototype, "pause", null);
|
|
1014
|
+
_ts_decorate3([
|
|
1015
|
+
import_async3.synchronized
|
|
1016
|
+
], Pipeline.prototype, "unpause", null);
|
|
1017
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/auth.ts";
|
|
1018
|
+
var AuthExtension = class extends import_teleport.RpcExtension {
|
|
1019
|
+
constructor(_authParams) {
|
|
1020
|
+
super({
|
|
1021
|
+
requested: {
|
|
1022
|
+
AuthService: import_protocols3.schema.getService("dxos.mesh.teleport.auth.AuthService")
|
|
1023
|
+
},
|
|
1024
|
+
exposed: {
|
|
1025
|
+
AuthService: import_protocols3.schema.getService("dxos.mesh.teleport.auth.AuthService")
|
|
1026
|
+
},
|
|
1027
|
+
timeout: 60 * 1e3
|
|
1028
|
+
});
|
|
1029
|
+
this._authParams = _authParams;
|
|
1030
|
+
this._ctx = new import_context3.Context({
|
|
1031
|
+
onError: (err) => {
|
|
1032
|
+
import_log5.log.catch(err, void 0, {
|
|
1033
|
+
F: __dxlog_file6,
|
|
1034
|
+
L: 28,
|
|
1035
|
+
S: this,
|
|
1036
|
+
C: (f, a) => f(...a)
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
}, {
|
|
1040
|
+
F: __dxlog_file6,
|
|
1041
|
+
L: 26
|
|
1042
|
+
});
|
|
1043
|
+
}
|
|
1044
|
+
async getHandlers() {
|
|
1045
|
+
return {
|
|
1046
|
+
AuthService: {
|
|
1047
|
+
authenticate: async ({ challenge }) => {
|
|
1048
|
+
try {
|
|
1049
|
+
const credential = await this._authParams.provider(challenge);
|
|
1050
|
+
if (!credential) {
|
|
1051
|
+
throw new Error("auth rejected");
|
|
1052
|
+
}
|
|
1053
|
+
return {
|
|
1054
|
+
credential
|
|
1055
|
+
};
|
|
1056
|
+
} catch (err) {
|
|
1057
|
+
import_log5.log.error("failed to generate auth credentials", err, {
|
|
1058
|
+
F: __dxlog_file6,
|
|
1059
|
+
L: 55,
|
|
1060
|
+
S: this,
|
|
1061
|
+
C: (f, a) => f(...a)
|
|
1062
|
+
});
|
|
1063
|
+
throw new Error("auth rejected");
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
async onOpen(context) {
|
|
1070
|
+
await super.onOpen(context);
|
|
1071
|
+
(0, import_async4.scheduleTask)(this._ctx, async () => {
|
|
1072
|
+
try {
|
|
1073
|
+
const challenge = (0, import_crypto.randomBytes)(32);
|
|
1074
|
+
const { credential } = await this.rpc.AuthService.authenticate({
|
|
1075
|
+
challenge
|
|
1076
|
+
});
|
|
1077
|
+
(0, import_invariant5.invariant)(credential?.length > 0, "invalid credential", {
|
|
1078
|
+
F: __dxlog_file6,
|
|
1079
|
+
L: 69,
|
|
1080
|
+
S: this,
|
|
1081
|
+
A: [
|
|
1082
|
+
"credential?.length > 0",
|
|
1083
|
+
"'invalid credential'"
|
|
1084
|
+
]
|
|
1085
|
+
});
|
|
1086
|
+
const success = await this._authParams.verifier(challenge, credential);
|
|
1087
|
+
(0, import_invariant5.invariant)(success, "credential not verified", {
|
|
1088
|
+
F: __dxlog_file6,
|
|
1089
|
+
L: 71,
|
|
1090
|
+
S: this,
|
|
1091
|
+
A: [
|
|
1092
|
+
"success",
|
|
1093
|
+
"'credential not verified'"
|
|
1094
|
+
]
|
|
1095
|
+
});
|
|
1096
|
+
(0, import_async4.runInContext)(this._ctx, () => this._authParams.onAuthSuccess());
|
|
1097
|
+
} catch (err) {
|
|
1098
|
+
(0, import_log5.log)("auth failed", err, {
|
|
1099
|
+
F: __dxlog_file6,
|
|
1100
|
+
L: 74,
|
|
1101
|
+
S: this,
|
|
1102
|
+
C: (f, a) => f(...a)
|
|
1103
|
+
});
|
|
1104
|
+
this.close();
|
|
1105
|
+
this._authParams.onAuthFailure();
|
|
1106
|
+
}
|
|
1107
|
+
});
|
|
1108
|
+
}
|
|
1109
|
+
async onClose() {
|
|
1110
|
+
await this._ctx.dispose();
|
|
1111
|
+
await super.onClose();
|
|
1112
|
+
}
|
|
1113
|
+
async onAbort() {
|
|
1114
|
+
await this._ctx.dispose();
|
|
1115
|
+
await super.onAbort();
|
|
1116
|
+
}
|
|
1117
|
+
};
|
|
1118
|
+
function _ts_decorate4(decorators, target, key, desc) {
|
|
1119
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1120
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
1121
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
1122
|
+
else
|
|
1123
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
1124
|
+
if (d = decorators[i])
|
|
1125
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1126
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1127
|
+
}
|
|
1128
|
+
var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/control-pipeline.ts";
|
|
1129
|
+
var TIMEFRAME_SAVE_DEBOUNCE_INTERVAL = 500;
|
|
1130
|
+
var CONTROL_PIPELINE_SNAPSHOT_DELAY = 1e4;
|
|
1131
|
+
var USE_SNAPSHOTS = true;
|
|
1132
|
+
var ControlPipeline = class {
|
|
1133
|
+
constructor({ spaceKey, genesisFeed, feedProvider, metadataStore }) {
|
|
1134
|
+
this._ctx = new import_context5.Context(void 0, {
|
|
1135
|
+
F: __dxlog_file7,
|
|
1136
|
+
L: 47
|
|
1137
|
+
});
|
|
1138
|
+
this._lastTimeframeSaveTime = Date.now();
|
|
1139
|
+
this.onFeedAdmitted = new import_util4.Callback();
|
|
1140
|
+
this._usage = new import_tracing2.TimeUsageCounter();
|
|
1141
|
+
this._mutations = new import_tracing2.TimeSeriesCounter();
|
|
1142
|
+
this._snapshotTask = new import_async6.DeferredTask(this._ctx, async () => {
|
|
1143
|
+
await (0, import_async6.sleepWithContext)(this._ctx, CONTROL_PIPELINE_SNAPSHOT_DELAY);
|
|
1144
|
+
await this._saveSnapshot();
|
|
1145
|
+
});
|
|
1146
|
+
this._spaceKey = spaceKey;
|
|
1147
|
+
this._metadata = metadataStore;
|
|
1148
|
+
this._pipeline = new Pipeline();
|
|
1149
|
+
void this._pipeline.addFeed(genesisFeed);
|
|
1150
|
+
this._spaceStateMachine = new import_credentials2.SpaceStateMachine(spaceKey);
|
|
1151
|
+
this._spaceStateMachine.onFeedAdmitted.set(async (info) => {
|
|
1152
|
+
(0, import_log7.log)("feed admitted", {
|
|
1153
|
+
key: info.key
|
|
1154
|
+
}, {
|
|
1155
|
+
F: __dxlog_file7,
|
|
1156
|
+
L: 82,
|
|
1157
|
+
S: this,
|
|
1158
|
+
C: (f, a) => f(...a)
|
|
1159
|
+
});
|
|
1160
|
+
if (info.assertion.designation === import_credentials3.AdmittedFeed.Designation.CONTROL && !info.key.equals(genesisFeed.key)) {
|
|
1161
|
+
queueMicrotask(async () => {
|
|
1162
|
+
try {
|
|
1163
|
+
const feed = await feedProvider(info.key);
|
|
1164
|
+
if (!this._pipeline.hasFeed(feed.key)) {
|
|
1165
|
+
await this._pipeline.addFeed(feed);
|
|
1166
|
+
}
|
|
1167
|
+
} catch (err) {
|
|
1168
|
+
import_log7.log.catch(err, void 0, {
|
|
1169
|
+
F: __dxlog_file7,
|
|
1170
|
+
L: 93,
|
|
1171
|
+
S: this,
|
|
1172
|
+
C: (f, a) => f(...a)
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
await this.onFeedAdmitted.callIfSet(info);
|
|
1178
|
+
});
|
|
1179
|
+
this.onMemberRoleChanged = this._spaceStateMachine.onMemberRoleChanged;
|
|
1180
|
+
this.onCredentialProcessed = this._spaceStateMachine.onCredentialProcessed;
|
|
1181
|
+
this.onDelegatedInvitation = this._spaceStateMachine.onDelegatedInvitation;
|
|
1182
|
+
this.onDelegatedInvitationRemoved = this._spaceStateMachine.onDelegatedInvitationRemoved;
|
|
1183
|
+
}
|
|
1184
|
+
get spaceState() {
|
|
1185
|
+
return this._spaceStateMachine;
|
|
1186
|
+
}
|
|
1187
|
+
get pipeline() {
|
|
1188
|
+
return this._pipeline;
|
|
1189
|
+
}
|
|
1190
|
+
async setWriteFeed(feed) {
|
|
1191
|
+
await this._pipeline.addFeed(feed);
|
|
1192
|
+
this._pipeline.setWriteFeed(feed);
|
|
1193
|
+
}
|
|
1194
|
+
async start() {
|
|
1195
|
+
const snapshot = this._metadata.getSpaceControlPipelineSnapshot(this._spaceKey);
|
|
1196
|
+
(0, import_log7.log)("load snapshot", {
|
|
1197
|
+
key: this._spaceKey,
|
|
1198
|
+
present: !!snapshot,
|
|
1199
|
+
tf: snapshot?.timeframe
|
|
1200
|
+
}, {
|
|
1201
|
+
F: __dxlog_file7,
|
|
1202
|
+
L: 123,
|
|
1203
|
+
S: this,
|
|
1204
|
+
C: (f, a) => f(...a)
|
|
1205
|
+
});
|
|
1206
|
+
if (USE_SNAPSHOTS && snapshot) {
|
|
1207
|
+
await this._processSnapshot(snapshot);
|
|
1208
|
+
}
|
|
1209
|
+
(0, import_log7.log)("starting...", void 0, {
|
|
1210
|
+
F: __dxlog_file7,
|
|
1211
|
+
L: 128,
|
|
1212
|
+
S: this,
|
|
1213
|
+
C: (f, a) => f(...a)
|
|
1214
|
+
});
|
|
1215
|
+
setTimeout(async () => {
|
|
1216
|
+
void this._consumePipeline(new import_context5.Context(void 0, {
|
|
1217
|
+
F: __dxlog_file7,
|
|
1218
|
+
L: 130
|
|
1219
|
+
}));
|
|
1220
|
+
});
|
|
1221
|
+
await this._pipeline.start();
|
|
1222
|
+
(0, import_log7.log)("started", void 0, {
|
|
1223
|
+
F: __dxlog_file7,
|
|
1224
|
+
L: 134,
|
|
1225
|
+
S: this,
|
|
1226
|
+
C: (f, a) => f(...a)
|
|
1227
|
+
});
|
|
1228
|
+
}
|
|
1229
|
+
async _processSnapshot(snapshot) {
|
|
1230
|
+
await this._pipeline.setCursor(snapshot.timeframe);
|
|
1231
|
+
for (const message of snapshot.messages ?? []) {
|
|
1232
|
+
const result = await this._spaceStateMachine.process(message.credential, {
|
|
1233
|
+
sourceFeed: message.feedKey,
|
|
1234
|
+
skipVerification: true
|
|
1235
|
+
});
|
|
1236
|
+
if (!result) {
|
|
1237
|
+
import_log7.log.warn("credential processing failed from snapshot", {
|
|
1238
|
+
message
|
|
1239
|
+
}, {
|
|
1240
|
+
F: __dxlog_file7,
|
|
1241
|
+
L: 147,
|
|
1242
|
+
S: this,
|
|
1243
|
+
C: (f, a) => f(...a)
|
|
1244
|
+
});
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
async _saveSnapshot() {
|
|
1249
|
+
await this._pipeline.pause();
|
|
1250
|
+
const snapshot = {
|
|
1251
|
+
timeframe: this._pipeline.state.timeframe,
|
|
1252
|
+
messages: this._spaceStateMachine.credentialEntries.map((entry) => ({
|
|
1253
|
+
feedKey: entry.sourceFeed,
|
|
1254
|
+
credential: entry.credential
|
|
1255
|
+
}))
|
|
1256
|
+
};
|
|
1257
|
+
await this._pipeline.unpause();
|
|
1258
|
+
(0, import_log7.log)("save snapshot", {
|
|
1259
|
+
key: this._spaceKey,
|
|
1260
|
+
snapshot
|
|
1261
|
+
}, {
|
|
1262
|
+
F: __dxlog_file7,
|
|
1263
|
+
L: 163,
|
|
1264
|
+
S: this,
|
|
1265
|
+
C: (f, a) => f(...a)
|
|
1266
|
+
});
|
|
1267
|
+
await this._metadata.setSpaceControlPipelineSnapshot(this._spaceKey, snapshot);
|
|
1268
|
+
}
|
|
1269
|
+
async _consumePipeline(ctx) {
|
|
1270
|
+
for await (const msg of this._pipeline.consume()) {
|
|
1271
|
+
const span = this._usage.beginRecording();
|
|
1272
|
+
this._mutations.inc();
|
|
1273
|
+
try {
|
|
1274
|
+
await this._processMessage(ctx, msg);
|
|
1275
|
+
} catch (err) {
|
|
1276
|
+
import_log7.log.catch(err, void 0, {
|
|
1277
|
+
F: __dxlog_file7,
|
|
1278
|
+
L: 176,
|
|
1279
|
+
S: this,
|
|
1280
|
+
C: (f, a) => f(...a)
|
|
1281
|
+
});
|
|
1282
|
+
}
|
|
1283
|
+
span.end();
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
async _processMessage(ctx, msg) {
|
|
1287
|
+
(0, import_log7.log)("processing", {
|
|
1288
|
+
key: msg.feedKey,
|
|
1289
|
+
seq: msg.seq
|
|
1290
|
+
}, {
|
|
1291
|
+
F: __dxlog_file7,
|
|
1292
|
+
L: 186,
|
|
1293
|
+
S: this,
|
|
1294
|
+
C: (f, a) => f(...a)
|
|
1295
|
+
});
|
|
1296
|
+
if (msg.data.payload.credential) {
|
|
1297
|
+
const timer = import_util4.tracer.mark("dxos.echo.pipeline.control");
|
|
1298
|
+
const result = await this._spaceStateMachine.process(msg.data.payload.credential.credential, {
|
|
1299
|
+
sourceFeed: import_keys3.PublicKey.from(msg.feedKey)
|
|
1300
|
+
});
|
|
1301
|
+
timer.end();
|
|
1302
|
+
if (!result) {
|
|
1303
|
+
import_log7.log.warn("processing failed", {
|
|
1304
|
+
msg
|
|
1305
|
+
}, {
|
|
1306
|
+
F: __dxlog_file7,
|
|
1307
|
+
L: 195,
|
|
1308
|
+
S: this,
|
|
1309
|
+
C: (f, a) => f(...a)
|
|
1310
|
+
});
|
|
1311
|
+
} else {
|
|
1312
|
+
await this._noteTargetStateIfNeeded(this._pipeline.state.pendingTimeframe);
|
|
1313
|
+
}
|
|
1314
|
+
this._snapshotTask.schedule();
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
async _noteTargetStateIfNeeded(timeframe) {
|
|
1318
|
+
if (Date.now() - this._lastTimeframeSaveTime > TIMEFRAME_SAVE_DEBOUNCE_INTERVAL) {
|
|
1319
|
+
this._lastTimeframeSaveTime = Date.now();
|
|
1320
|
+
await this._saveTargetTimeframe(timeframe);
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
async stop() {
|
|
1324
|
+
(0, import_log7.log)("stopping...", void 0, {
|
|
1325
|
+
F: __dxlog_file7,
|
|
1326
|
+
L: 215,
|
|
1327
|
+
S: this,
|
|
1328
|
+
C: (f, a) => f(...a)
|
|
1329
|
+
});
|
|
1330
|
+
await this._ctx.dispose();
|
|
1331
|
+
await this._pipeline.stop();
|
|
1332
|
+
await this._saveTargetTimeframe(this._pipeline.state.timeframe);
|
|
1333
|
+
(0, import_log7.log)("stopped", void 0, {
|
|
1334
|
+
F: __dxlog_file7,
|
|
1335
|
+
L: 219,
|
|
1336
|
+
S: this,
|
|
1337
|
+
C: (f, a) => f(...a)
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1340
|
+
async _saveTargetTimeframe(timeframe) {
|
|
1341
|
+
try {
|
|
1342
|
+
const newTimeframe = import_timeframe3.Timeframe.merge(this._targetTimeframe ?? new import_timeframe3.Timeframe(), timeframe);
|
|
1343
|
+
await this._metadata.setSpaceControlLatestTimeframe(this._spaceKey, newTimeframe);
|
|
1344
|
+
this._targetTimeframe = newTimeframe;
|
|
1345
|
+
} catch (err) {
|
|
1346
|
+
(0, import_log7.log)(err, void 0, {
|
|
1347
|
+
F: __dxlog_file7,
|
|
1348
|
+
L: 228,
|
|
1349
|
+
S: this,
|
|
1350
|
+
C: (f, a) => f(...a)
|
|
1351
|
+
});
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
};
|
|
1355
|
+
_ts_decorate4([
|
|
1356
|
+
import_tracing2.trace.metricsCounter()
|
|
1357
|
+
], ControlPipeline.prototype, "_usage", void 0);
|
|
1358
|
+
_ts_decorate4([
|
|
1359
|
+
import_tracing2.trace.metricsCounter()
|
|
1360
|
+
], ControlPipeline.prototype, "_mutations", void 0);
|
|
1361
|
+
_ts_decorate4([
|
|
1362
|
+
import_tracing2.trace.span({
|
|
1363
|
+
showInBrowserTimeline: true
|
|
1364
|
+
})
|
|
1365
|
+
], ControlPipeline.prototype, "start", null);
|
|
1366
|
+
_ts_decorate4([
|
|
1367
|
+
import_tracing2.trace.span()
|
|
1368
|
+
], ControlPipeline.prototype, "_consumePipeline", null);
|
|
1369
|
+
_ts_decorate4([
|
|
1370
|
+
import_tracing2.trace.span()
|
|
1371
|
+
], ControlPipeline.prototype, "_processMessage", null);
|
|
1372
|
+
ControlPipeline = _ts_decorate4([
|
|
1373
|
+
import_tracing2.trace.resource(),
|
|
1374
|
+
(0, import_async6.trackLeaks)("start", "stop")
|
|
1375
|
+
], ControlPipeline);
|
|
1376
|
+
function _ts_decorate5(decorators, target, key, desc) {
|
|
1377
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1378
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
1379
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
1380
|
+
else
|
|
1381
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
1382
|
+
if (d = decorators[i])
|
|
1383
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1384
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1385
|
+
}
|
|
1386
|
+
var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/space.ts";
|
|
1387
|
+
var Space = class extends import_context4.Resource {
|
|
1388
|
+
constructor(params) {
|
|
1389
|
+
super();
|
|
1390
|
+
this.onCredentialProcessed = new import_util3.Callback();
|
|
1391
|
+
this.stateUpdate = new import_async5.Event();
|
|
1392
|
+
(0, import_invariant6.invariant)(params.spaceKey && params.feedProvider, void 0, {
|
|
1393
|
+
F: __dxlog_file8,
|
|
1394
|
+
L: 71,
|
|
1395
|
+
S: this,
|
|
1396
|
+
A: [
|
|
1397
|
+
"params.spaceKey && params.feedProvider",
|
|
1398
|
+
""
|
|
1399
|
+
]
|
|
1400
|
+
});
|
|
1401
|
+
this._id = params.id;
|
|
1402
|
+
this._key = params.spaceKey;
|
|
1403
|
+
this._genesisFeedKey = params.genesisFeed.key;
|
|
1404
|
+
this._feedProvider = params.feedProvider;
|
|
1405
|
+
this._controlPipeline = new ControlPipeline({
|
|
1406
|
+
spaceKey: params.spaceKey,
|
|
1407
|
+
genesisFeed: params.genesisFeed,
|
|
1408
|
+
feedProvider: params.feedProvider,
|
|
1409
|
+
metadataStore: params.metadataStore
|
|
1410
|
+
});
|
|
1411
|
+
this._controlPipeline.onFeedAdmitted.set(async (info) => {
|
|
1412
|
+
const sparse = info.assertion.designation === import_credentials.AdmittedFeed.Designation.DATA;
|
|
1413
|
+
if (!info.key.equals(params.genesisFeed.key)) {
|
|
1414
|
+
(0, import_async5.scheduleMicroTask)(this._ctx, async () => {
|
|
1415
|
+
await this.protocol.addFeed(await params.feedProvider(info.key, {
|
|
1416
|
+
sparse
|
|
1417
|
+
}));
|
|
1418
|
+
});
|
|
1419
|
+
}
|
|
1420
|
+
});
|
|
1421
|
+
this._controlPipeline.onCredentialProcessed.set(async (credential) => {
|
|
1422
|
+
await this.onCredentialProcessed.callIfSet(credential);
|
|
1423
|
+
(0, import_log6.log)("onCredentialProcessed", {
|
|
1424
|
+
credential
|
|
1425
|
+
}, {
|
|
1426
|
+
F: __dxlog_file8,
|
|
1427
|
+
L: 98,
|
|
1428
|
+
S: this,
|
|
1429
|
+
C: (f, a) => f(...a)
|
|
1430
|
+
});
|
|
1431
|
+
this.stateUpdate.emit();
|
|
1432
|
+
});
|
|
1433
|
+
this._controlPipeline.onDelegatedInvitation.set(async (invitation) => {
|
|
1434
|
+
(0, import_log6.log)("onDelegatedInvitation", {
|
|
1435
|
+
invitation
|
|
1436
|
+
}, {
|
|
1437
|
+
F: __dxlog_file8,
|
|
1438
|
+
L: 102,
|
|
1439
|
+
S: this,
|
|
1440
|
+
C: (f, a) => f(...a)
|
|
1441
|
+
});
|
|
1442
|
+
await params.onDelegatedInvitationStatusChange(invitation, true);
|
|
1443
|
+
});
|
|
1444
|
+
this._controlPipeline.onDelegatedInvitationRemoved.set(async (invitation) => {
|
|
1445
|
+
(0, import_log6.log)("onDelegatedInvitationRemoved", {
|
|
1446
|
+
invitation
|
|
1447
|
+
}, {
|
|
1448
|
+
F: __dxlog_file8,
|
|
1449
|
+
L: 106,
|
|
1450
|
+
S: this,
|
|
1451
|
+
C: (f, a) => f(...a)
|
|
1452
|
+
});
|
|
1453
|
+
await params.onDelegatedInvitationStatusChange(invitation, false);
|
|
1454
|
+
});
|
|
1455
|
+
this._controlPipeline.onMemberRoleChanged.set(async (changedMembers) => {
|
|
1456
|
+
(0, import_log6.log)("onMemberRoleChanged", () => ({
|
|
1457
|
+
changedMembers: changedMembers.map((m) => [
|
|
1458
|
+
m.key,
|
|
1459
|
+
m.role
|
|
1460
|
+
])
|
|
1461
|
+
}), {
|
|
1462
|
+
F: __dxlog_file8,
|
|
1463
|
+
L: 110,
|
|
1464
|
+
S: this,
|
|
1465
|
+
C: (f, a) => f(...a)
|
|
1466
|
+
});
|
|
1467
|
+
await params.onMemberRolesChanged(changedMembers);
|
|
1468
|
+
});
|
|
1469
|
+
this.protocol = params.protocol;
|
|
1470
|
+
}
|
|
1471
|
+
get id() {
|
|
1472
|
+
return this._id;
|
|
1473
|
+
}
|
|
1474
|
+
get key() {
|
|
1475
|
+
return this._key;
|
|
1476
|
+
}
|
|
1477
|
+
get isOpen() {
|
|
1478
|
+
return this._lifecycleState === import_context4.LifecycleState.OPEN;
|
|
1479
|
+
}
|
|
1480
|
+
get genesisFeedKey() {
|
|
1481
|
+
return this._genesisFeedKey;
|
|
1482
|
+
}
|
|
1483
|
+
get controlFeedKey() {
|
|
1484
|
+
return this._controlFeed?.key;
|
|
1485
|
+
}
|
|
1486
|
+
get dataFeedKey() {
|
|
1487
|
+
return this._dataFeed?.key;
|
|
1488
|
+
}
|
|
1489
|
+
get spaceState() {
|
|
1490
|
+
return this._controlPipeline.spaceState;
|
|
1491
|
+
}
|
|
1492
|
+
/**
|
|
1493
|
+
* @test-only
|
|
1494
|
+
*/
|
|
1495
|
+
get controlPipeline() {
|
|
1496
|
+
return this._controlPipeline.pipeline;
|
|
1497
|
+
}
|
|
1498
|
+
async setControlFeed(feed) {
|
|
1499
|
+
(0, import_invariant6.invariant)(!this._controlFeed, "Control feed already set.", {
|
|
1500
|
+
F: __dxlog_file8,
|
|
1501
|
+
L: 158,
|
|
1502
|
+
S: this,
|
|
1503
|
+
A: [
|
|
1504
|
+
"!this._controlFeed",
|
|
1505
|
+
"'Control feed already set.'"
|
|
1506
|
+
]
|
|
1507
|
+
});
|
|
1508
|
+
this._controlFeed = feed;
|
|
1509
|
+
await this._controlPipeline.setWriteFeed(feed);
|
|
1510
|
+
return this;
|
|
1511
|
+
}
|
|
1512
|
+
async setDataFeed(feed) {
|
|
1513
|
+
(0, import_invariant6.invariant)(!this._dataFeed, "Data feed already set.", {
|
|
1514
|
+
F: __dxlog_file8,
|
|
1515
|
+
L: 165,
|
|
1516
|
+
S: this,
|
|
1517
|
+
A: [
|
|
1518
|
+
"!this._dataFeed",
|
|
1519
|
+
"'Data feed already set.'"
|
|
1520
|
+
]
|
|
1521
|
+
});
|
|
1522
|
+
this._dataFeed = feed;
|
|
1523
|
+
return this;
|
|
1524
|
+
}
|
|
1525
|
+
/**
|
|
1526
|
+
* Use for diagnostics.
|
|
1527
|
+
*/
|
|
1528
|
+
getControlFeeds() {
|
|
1529
|
+
return Array.from(this._controlPipeline.spaceState.feeds.values());
|
|
1530
|
+
}
|
|
1531
|
+
async _open(ctx) {
|
|
1532
|
+
(0, import_log6.log)("opening...", void 0, {
|
|
1533
|
+
F: __dxlog_file8,
|
|
1534
|
+
L: 179,
|
|
1535
|
+
S: this,
|
|
1536
|
+
C: (f, a) => f(...a)
|
|
1537
|
+
});
|
|
1538
|
+
await this._controlPipeline.start();
|
|
1539
|
+
await this.protocol.start();
|
|
1540
|
+
await this.protocol.addFeed(await this._feedProvider(this._genesisFeedKey));
|
|
1541
|
+
(0, import_log6.log)("opened", void 0, {
|
|
1542
|
+
F: __dxlog_file8,
|
|
1543
|
+
L: 186,
|
|
1544
|
+
S: this,
|
|
1545
|
+
C: (f, a) => f(...a)
|
|
1546
|
+
});
|
|
1547
|
+
}
|
|
1548
|
+
async _close() {
|
|
1549
|
+
(0, import_log6.log)("closing...", {
|
|
1550
|
+
key: this._key
|
|
1551
|
+
}, {
|
|
1552
|
+
F: __dxlog_file8,
|
|
1553
|
+
L: 191,
|
|
1554
|
+
S: this,
|
|
1555
|
+
C: (f, a) => f(...a)
|
|
1556
|
+
});
|
|
1557
|
+
await this.protocol.stop();
|
|
1558
|
+
await this._controlPipeline.stop();
|
|
1559
|
+
(0, import_log6.log)("closed", void 0, {
|
|
1560
|
+
F: __dxlog_file8,
|
|
1561
|
+
L: 197,
|
|
1562
|
+
S: this,
|
|
1563
|
+
C: (f, a) => f(...a)
|
|
1564
|
+
});
|
|
1565
|
+
}
|
|
1566
|
+
};
|
|
1567
|
+
_ts_decorate5([
|
|
1568
|
+
import_tracing.trace.info()
|
|
1569
|
+
], Space.prototype, "protocol", void 0);
|
|
1570
|
+
_ts_decorate5([
|
|
1571
|
+
import_tracing.trace.info()
|
|
1572
|
+
], Space.prototype, "_controlPipeline", void 0);
|
|
1573
|
+
_ts_decorate5([
|
|
1574
|
+
import_log6.logInfo,
|
|
1575
|
+
import_tracing.trace.info()
|
|
1576
|
+
], Space.prototype, "id", null);
|
|
1577
|
+
_ts_decorate5([
|
|
1578
|
+
import_log6.logInfo,
|
|
1579
|
+
import_tracing.trace.info()
|
|
1580
|
+
], Space.prototype, "key", null);
|
|
1581
|
+
_ts_decorate5([
|
|
1582
|
+
import_tracing.trace.span()
|
|
1583
|
+
], Space.prototype, "_open", null);
|
|
1584
|
+
_ts_decorate5([
|
|
1585
|
+
import_async5.synchronized
|
|
1586
|
+
], Space.prototype, "_close", null);
|
|
1587
|
+
Space = _ts_decorate5([
|
|
1588
|
+
(0, import_async5.trackLeaks)("open", "close"),
|
|
1589
|
+
import_tracing.trace.resource()
|
|
1590
|
+
], Space);
|
|
1591
|
+
var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/admission-discovery-extension.ts";
|
|
1592
|
+
var CredentialRetrieverExtension = class extends import_teleport2.RpcExtension {
|
|
1593
|
+
constructor(_request, _onResult) {
|
|
1594
|
+
super({
|
|
1595
|
+
requested: {
|
|
1596
|
+
AdmissionDiscoveryService: import_protocols4.schema.getService("dxos.mesh.teleport.AdmissionDiscoveryService")
|
|
1597
|
+
}
|
|
1598
|
+
});
|
|
1599
|
+
this._request = _request;
|
|
1600
|
+
this._onResult = _onResult;
|
|
1601
|
+
this._ctx = new import_context6.Context(void 0, {
|
|
1602
|
+
F: __dxlog_file9,
|
|
1603
|
+
L: 25
|
|
1604
|
+
});
|
|
1605
|
+
}
|
|
1606
|
+
async getHandlers() {
|
|
1607
|
+
return {};
|
|
1608
|
+
}
|
|
1609
|
+
async onOpen(context) {
|
|
1610
|
+
await super.onOpen(context);
|
|
1611
|
+
(0, import_async7.scheduleTask)(this._ctx, async () => {
|
|
1612
|
+
try {
|
|
1613
|
+
const result = await this.rpc.AdmissionDiscoveryService.getAdmissionCredential(this._request);
|
|
1614
|
+
this._onResult.wake(result.admissionCredential);
|
|
1615
|
+
} catch (err) {
|
|
1616
|
+
context.close(err);
|
|
1617
|
+
}
|
|
1618
|
+
});
|
|
1619
|
+
}
|
|
1620
|
+
async onClose() {
|
|
1621
|
+
await this._ctx.dispose();
|
|
1622
|
+
}
|
|
1623
|
+
async onAbort() {
|
|
1624
|
+
await this._ctx.dispose();
|
|
1625
|
+
}
|
|
1626
|
+
};
|
|
1627
|
+
var CredentialServerExtension = class extends import_teleport2.RpcExtension {
|
|
1628
|
+
constructor(_space) {
|
|
1629
|
+
super({
|
|
1630
|
+
exposed: {
|
|
1631
|
+
AdmissionDiscoveryService: import_protocols4.schema.getService("dxos.mesh.teleport.AdmissionDiscoveryService")
|
|
1632
|
+
}
|
|
1633
|
+
});
|
|
1634
|
+
this._space = _space;
|
|
1635
|
+
}
|
|
1636
|
+
async getHandlers() {
|
|
1637
|
+
return {
|
|
1638
|
+
AdmissionDiscoveryService: {
|
|
1639
|
+
getAdmissionCredential: async (request) => {
|
|
1640
|
+
const memberInfo = this._space.spaceState.members.get(request.memberKey);
|
|
1641
|
+
if (!memberInfo?.credential) {
|
|
1642
|
+
throw new import_protocols4.ProtocolError("Space member not found.", request);
|
|
1643
|
+
}
|
|
1644
|
+
return {
|
|
1645
|
+
admissionCredential: memberInfo.credential
|
|
1646
|
+
};
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
};
|
|
1650
|
+
}
|
|
1651
|
+
};
|
|
1652
|
+
function _ts_decorate6(decorators, target, key, desc) {
|
|
1653
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1654
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
1655
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
1656
|
+
else
|
|
1657
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
1658
|
+
if (d = decorators[i])
|
|
1659
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1660
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1661
|
+
}
|
|
1662
|
+
var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/space-protocol.ts";
|
|
1663
|
+
var MOCK_AUTH_PROVIDER = async (nonce) => Buffer.from("mock");
|
|
1664
|
+
var MOCK_AUTH_VERIFIER = async (nonce, credential) => true;
|
|
1665
|
+
var SpaceProtocol = class {
|
|
1666
|
+
constructor({ topic, swarmIdentity, networkManager, onSessionAuth, onAuthFailure, blobStore, disableP2pReplication }) {
|
|
1667
|
+
this._feeds = /* @__PURE__ */ new Set();
|
|
1668
|
+
this._sessions = new import_util5.ComplexMap(import_keys4.PublicKey.hash);
|
|
1669
|
+
this._topology = new import_network_manager.MMSTTopology({
|
|
1670
|
+
originateConnections: 4,
|
|
1671
|
+
maxPeers: 10,
|
|
1672
|
+
sampleSize: 20
|
|
1673
|
+
});
|
|
1674
|
+
this.feedAdded = new import_util5.CallbackCollection();
|
|
1675
|
+
this._spaceKey = topic;
|
|
1676
|
+
this._networkManager = networkManager;
|
|
1677
|
+
this._swarmIdentity = swarmIdentity;
|
|
1678
|
+
this._onSessionAuth = onSessionAuth;
|
|
1679
|
+
this._onAuthFailure = onAuthFailure;
|
|
1680
|
+
this.blobSync = new import_teleport_extension_object_sync.BlobSync({
|
|
1681
|
+
blobStore
|
|
1682
|
+
});
|
|
1683
|
+
this._topic = import_crypto2.subtleCrypto.digest("SHA-256", topic.asBuffer()).then(import_crypto2.discoveryKey).then(import_keys4.PublicKey.from);
|
|
1684
|
+
this._disableP2pReplication = disableP2pReplication ?? false;
|
|
1685
|
+
}
|
|
1686
|
+
get sessions() {
|
|
1687
|
+
return this._sessions;
|
|
1688
|
+
}
|
|
1689
|
+
get feeds() {
|
|
1690
|
+
return this._feeds;
|
|
1691
|
+
}
|
|
1692
|
+
get _ownPeerKey() {
|
|
1693
|
+
return this._swarmIdentity.peerKey;
|
|
1694
|
+
}
|
|
1695
|
+
// TODO(burdon): Create abstraction for Space (e.g., add keys and have provider).
|
|
1696
|
+
async addFeed(feed) {
|
|
1697
|
+
(0, import_log8.log)("addFeed", {
|
|
1698
|
+
key: feed.key
|
|
1699
|
+
}, {
|
|
1700
|
+
F: __dxlog_file10,
|
|
1701
|
+
L: 127,
|
|
1702
|
+
S: this,
|
|
1703
|
+
C: (f, a) => f(...a)
|
|
1704
|
+
});
|
|
1705
|
+
this._feeds.add(feed);
|
|
1706
|
+
for (const session of this._sessions.values()) {
|
|
1707
|
+
session.replicator.addFeed(feed);
|
|
1708
|
+
}
|
|
1709
|
+
await this.feedAdded.callSerial(feed);
|
|
1710
|
+
}
|
|
1711
|
+
// TODO(burdon): Rename open? Common open/close interfaces for all services?
|
|
1712
|
+
async start() {
|
|
1713
|
+
if (this._connection) {
|
|
1714
|
+
return;
|
|
1715
|
+
}
|
|
1716
|
+
const credentials = await this._swarmIdentity.credentialProvider(Buffer.from(""));
|
|
1717
|
+
await this.blobSync.open();
|
|
1718
|
+
(0, import_log8.log)("starting...", void 0, {
|
|
1719
|
+
F: __dxlog_file10,
|
|
1720
|
+
L: 148,
|
|
1721
|
+
S: this,
|
|
1722
|
+
C: (f, a) => f(...a)
|
|
1723
|
+
});
|
|
1724
|
+
const topic = await this._topic;
|
|
1725
|
+
this._connection = await this._networkManager.joinSwarm({
|
|
1726
|
+
protocolProvider: this._createProtocolProvider(credentials),
|
|
1727
|
+
peerId: this._swarmIdentity.peerKey,
|
|
1728
|
+
topic,
|
|
1729
|
+
topology: this._topology,
|
|
1730
|
+
label: `swarm ${topic.truncate()} for space ${this._spaceKey.truncate()}`
|
|
1731
|
+
});
|
|
1732
|
+
(0, import_log8.log)("started", void 0, {
|
|
1733
|
+
F: __dxlog_file10,
|
|
1734
|
+
L: 158,
|
|
1735
|
+
S: this,
|
|
1736
|
+
C: (f, a) => f(...a)
|
|
1737
|
+
});
|
|
1738
|
+
}
|
|
1739
|
+
updateTopology() {
|
|
1740
|
+
this._topology.forceUpdate();
|
|
1741
|
+
}
|
|
1742
|
+
async stop() {
|
|
1743
|
+
await this.blobSync.close();
|
|
1744
|
+
if (this._connection) {
|
|
1745
|
+
(0, import_log8.log)("stopping...", void 0, {
|
|
1746
|
+
F: __dxlog_file10,
|
|
1747
|
+
L: 169,
|
|
1748
|
+
S: this,
|
|
1749
|
+
C: (f, a) => f(...a)
|
|
1750
|
+
});
|
|
1751
|
+
await this._connection.close();
|
|
1752
|
+
(0, import_log8.log)("stopped", void 0, {
|
|
1753
|
+
F: __dxlog_file10,
|
|
1754
|
+
L: 171,
|
|
1755
|
+
S: this,
|
|
1756
|
+
C: (f, a) => f(...a)
|
|
1757
|
+
});
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
_createProtocolProvider(credentials) {
|
|
1761
|
+
return (wireParams) => {
|
|
1762
|
+
const session = new SpaceProtocolSession({
|
|
1763
|
+
wireParams,
|
|
1764
|
+
swarmIdentity: this._swarmIdentity,
|
|
1765
|
+
onSessionAuth: this._onSessionAuth,
|
|
1766
|
+
onAuthFailure: this._onAuthFailure,
|
|
1767
|
+
blobSync: this.blobSync,
|
|
1768
|
+
disableP2pReplication: this._disableP2pReplication
|
|
1769
|
+
});
|
|
1770
|
+
this._sessions.set(wireParams.remotePeerId, session);
|
|
1771
|
+
for (const feed of this._feeds) {
|
|
1772
|
+
session.replicator.addFeed(feed);
|
|
1773
|
+
}
|
|
1774
|
+
return session;
|
|
1775
|
+
};
|
|
1776
|
+
}
|
|
1777
|
+
};
|
|
1778
|
+
_ts_decorate6([
|
|
1779
|
+
import_log8.logInfo,
|
|
1780
|
+
import_tracing3.trace.info()
|
|
1781
|
+
], SpaceProtocol.prototype, "_topic", void 0);
|
|
1782
|
+
_ts_decorate6([
|
|
1783
|
+
import_tracing3.trace.info()
|
|
1784
|
+
], SpaceProtocol.prototype, "_spaceKey", void 0);
|
|
1785
|
+
_ts_decorate6([
|
|
1786
|
+
import_log8.logInfo
|
|
1787
|
+
], SpaceProtocol.prototype, "_ownPeerKey", null);
|
|
1788
|
+
SpaceProtocol = _ts_decorate6([
|
|
1789
|
+
import_tracing3.trace.resource()
|
|
1790
|
+
], SpaceProtocol);
|
|
1791
|
+
var AuthStatus;
|
|
1792
|
+
(function(AuthStatus2) {
|
|
1793
|
+
AuthStatus2["INITIAL"] = "INITIAL";
|
|
1794
|
+
AuthStatus2["SUCCESS"] = "SUCCESS";
|
|
1795
|
+
AuthStatus2["FAILURE"] = "FAILURE";
|
|
1796
|
+
})(AuthStatus || (AuthStatus = {}));
|
|
1797
|
+
var SpaceProtocolSession = class {
|
|
1798
|
+
// TODO(dmaretskyi): Allow to pass in extra extensions.
|
|
1799
|
+
constructor({ wireParams, swarmIdentity, onSessionAuth, onAuthFailure, blobSync, disableP2pReplication }) {
|
|
1800
|
+
this.replicator = new import_teleport_extension_replicator.ReplicatorExtension().setOptions({
|
|
1801
|
+
upload: true
|
|
1802
|
+
});
|
|
1803
|
+
this._authStatus = "INITIAL";
|
|
1804
|
+
this._wireParams = wireParams;
|
|
1805
|
+
this._swarmIdentity = swarmIdentity;
|
|
1806
|
+
this._onSessionAuth = onSessionAuth;
|
|
1807
|
+
this._onAuthFailure = onAuthFailure;
|
|
1808
|
+
this._blobSync = blobSync;
|
|
1809
|
+
this._teleport = new import_teleport3.Teleport(wireParams);
|
|
1810
|
+
this._disableP2pReplication = disableP2pReplication ?? false;
|
|
1811
|
+
}
|
|
1812
|
+
get authStatus() {
|
|
1813
|
+
return this._authStatus;
|
|
1814
|
+
}
|
|
1815
|
+
get stats() {
|
|
1816
|
+
return this._teleport.stats;
|
|
1817
|
+
}
|
|
1818
|
+
get stream() {
|
|
1819
|
+
return this._teleport.stream;
|
|
1820
|
+
}
|
|
1821
|
+
async open(sessionId) {
|
|
1822
|
+
await this._teleport.open(sessionId);
|
|
1823
|
+
this._teleport.addExtension("dxos.mesh.teleport.auth", new AuthExtension({
|
|
1824
|
+
provider: this._swarmIdentity.credentialProvider,
|
|
1825
|
+
verifier: this._swarmIdentity.credentialAuthenticator,
|
|
1826
|
+
onAuthSuccess: () => {
|
|
1827
|
+
(0, import_log8.log)("Peer authenticated", void 0, {
|
|
1828
|
+
F: __dxlog_file10,
|
|
1829
|
+
L: 282,
|
|
1830
|
+
S: this,
|
|
1831
|
+
C: (f, a) => f(...a)
|
|
1832
|
+
});
|
|
1833
|
+
this._authStatus = "SUCCESS";
|
|
1834
|
+
this._onSessionAuth?.(this._teleport);
|
|
1835
|
+
},
|
|
1836
|
+
onAuthFailure: () => {
|
|
1837
|
+
this._authStatus = "FAILURE";
|
|
1838
|
+
this._onAuthFailure?.(this._teleport);
|
|
1839
|
+
}
|
|
1840
|
+
}));
|
|
1841
|
+
if (!this._disableP2pReplication) {
|
|
1842
|
+
this._teleport.addExtension("dxos.mesh.teleport.replicator", this.replicator);
|
|
1843
|
+
}
|
|
1844
|
+
this._teleport.addExtension("dxos.mesh.teleport.blobsync", this._blobSync.createExtension());
|
|
1845
|
+
}
|
|
1846
|
+
async close() {
|
|
1847
|
+
(0, import_log8.log)("close", void 0, {
|
|
1848
|
+
F: __dxlog_file10,
|
|
1849
|
+
L: 301,
|
|
1850
|
+
S: this,
|
|
1851
|
+
C: (f, a) => f(...a)
|
|
1852
|
+
});
|
|
1853
|
+
await this._teleport.close();
|
|
1854
|
+
}
|
|
1855
|
+
async abort() {
|
|
1856
|
+
await this._teleport.abort();
|
|
1857
|
+
}
|
|
1858
|
+
};
|
|
1859
|
+
_ts_decorate6([
|
|
1860
|
+
import_log8.logInfo
|
|
1861
|
+
], SpaceProtocolSession.prototype, "_wireParams", void 0);
|
|
1862
|
+
_ts_decorate6([
|
|
1863
|
+
import_log8.logInfo
|
|
1864
|
+
], SpaceProtocolSession.prototype, "authStatus", null);
|
|
1865
|
+
function _ts_decorate7(decorators, target, key, desc) {
|
|
1866
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1867
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
1868
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
1869
|
+
else
|
|
1870
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
1871
|
+
if (d = decorators[i])
|
|
1872
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1873
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1874
|
+
}
|
|
1875
|
+
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/space-manager.ts";
|
|
1876
|
+
var SpaceManager = class {
|
|
1877
|
+
constructor({ feedStore, networkManager, metadataStore, blobStore, disableP2pReplication }) {
|
|
1878
|
+
this._spaces = new import_util6.ComplexMap(import_keys5.PublicKey.hash);
|
|
1879
|
+
this._instanceId = import_keys5.PublicKey.random().toHex();
|
|
1880
|
+
this._feedStore = feedStore;
|
|
1881
|
+
this._networkManager = networkManager;
|
|
1882
|
+
this._metadataStore = metadataStore;
|
|
1883
|
+
this._blobStore = blobStore;
|
|
1884
|
+
this._disableP2pReplication = disableP2pReplication ?? false;
|
|
1885
|
+
}
|
|
1886
|
+
// TODO(burdon): Remove.
|
|
1887
|
+
get spaces() {
|
|
1888
|
+
return this._spaces;
|
|
1889
|
+
}
|
|
1890
|
+
async open() {
|
|
1891
|
+
}
|
|
1892
|
+
async close() {
|
|
1893
|
+
await Promise.all([
|
|
1894
|
+
...this._spaces.values()
|
|
1895
|
+
].map((space) => space.close()));
|
|
1896
|
+
}
|
|
1897
|
+
async constructSpace({ metadata, swarmIdentity, onAuthorizedConnection, onAuthFailure, onDelegatedInvitationStatusChange, onMemberRolesChanged, memberKey }) {
|
|
1898
|
+
import_log9.log.trace("dxos.echo.space-manager.construct-space", import_protocols5.trace.begin({
|
|
1899
|
+
id: this._instanceId
|
|
1900
|
+
}), {
|
|
1901
|
+
F: __dxlog_file11,
|
|
1902
|
+
L: 100,
|
|
1903
|
+
S: this,
|
|
1904
|
+
C: (f, a) => f(...a)
|
|
1905
|
+
});
|
|
1906
|
+
(0, import_log9.log)("constructing space...", {
|
|
1907
|
+
spaceKey: metadata.genesisFeedKey
|
|
1908
|
+
}, {
|
|
1909
|
+
F: __dxlog_file11,
|
|
1910
|
+
L: 101,
|
|
1911
|
+
S: this,
|
|
1912
|
+
C: (f, a) => f(...a)
|
|
1913
|
+
});
|
|
1914
|
+
const genesisFeed = await this._feedStore.openFeed(metadata.genesisFeedKey ?? (0, import_debug3.failUndefined)());
|
|
1915
|
+
const spaceKey = metadata.key;
|
|
1916
|
+
const spaceId = await (0, import_chunk_DZVH7HDD.createIdFromSpaceKey)(spaceKey);
|
|
1917
|
+
const protocol = new SpaceProtocol({
|
|
1918
|
+
topic: spaceKey,
|
|
1919
|
+
swarmIdentity,
|
|
1920
|
+
networkManager: this._networkManager,
|
|
1921
|
+
onSessionAuth: onAuthorizedConnection,
|
|
1922
|
+
onAuthFailure,
|
|
1923
|
+
blobStore: this._blobStore,
|
|
1924
|
+
disableP2pReplication: this._disableP2pReplication
|
|
1925
|
+
});
|
|
1926
|
+
const space = new Space({
|
|
1927
|
+
id: spaceId,
|
|
1928
|
+
spaceKey,
|
|
1929
|
+
protocol,
|
|
1930
|
+
genesisFeed,
|
|
1931
|
+
feedProvider: (feedKey, opts) => this._feedStore.openFeed(feedKey, opts),
|
|
1932
|
+
metadataStore: this._metadataStore,
|
|
1933
|
+
memberKey,
|
|
1934
|
+
onDelegatedInvitationStatusChange,
|
|
1935
|
+
onMemberRolesChanged
|
|
1936
|
+
});
|
|
1937
|
+
this._spaces.set(space.key, space);
|
|
1938
|
+
import_log9.log.trace("dxos.echo.space-manager.construct-space", import_protocols5.trace.end({
|
|
1939
|
+
id: this._instanceId
|
|
1940
|
+
}), {
|
|
1941
|
+
F: __dxlog_file11,
|
|
1942
|
+
L: 131,
|
|
1943
|
+
S: this,
|
|
1944
|
+
C: (f, a) => f(...a)
|
|
1945
|
+
});
|
|
1946
|
+
return space;
|
|
1947
|
+
}
|
|
1948
|
+
async requestSpaceAdmissionCredential(params) {
|
|
1949
|
+
const traceKey = "dxos.echo.space-manager.request-space-admission";
|
|
1950
|
+
import_log9.log.trace(traceKey, import_protocols5.trace.begin({
|
|
1951
|
+
id: this._instanceId
|
|
1952
|
+
}), {
|
|
1953
|
+
F: __dxlog_file11,
|
|
1954
|
+
L: 137,
|
|
1955
|
+
S: this,
|
|
1956
|
+
C: (f, a) => f(...a)
|
|
1957
|
+
});
|
|
1958
|
+
(0, import_log9.log)("requesting space admission credential...", {
|
|
1959
|
+
spaceKey: params.spaceKey
|
|
1960
|
+
}, {
|
|
1961
|
+
F: __dxlog_file11,
|
|
1962
|
+
L: 138,
|
|
1963
|
+
S: this,
|
|
1964
|
+
C: (f, a) => f(...a)
|
|
1965
|
+
});
|
|
1966
|
+
const onCredentialResolved = new import_async8.Trigger();
|
|
1967
|
+
const protocol = new SpaceProtocol({
|
|
1968
|
+
topic: params.spaceKey,
|
|
1969
|
+
swarmIdentity: params.swarmIdentity,
|
|
1970
|
+
networkManager: this._networkManager,
|
|
1971
|
+
onSessionAuth: (session) => {
|
|
1972
|
+
session.addExtension("dxos.mesh.teleport.admission-discovery", new CredentialRetrieverExtension({
|
|
1973
|
+
spaceKey: params.spaceKey,
|
|
1974
|
+
memberKey: params.identityKey
|
|
1975
|
+
}, onCredentialResolved));
|
|
1976
|
+
},
|
|
1977
|
+
onAuthFailure: (session) => session.close(),
|
|
1978
|
+
blobStore: this._blobStore,
|
|
1979
|
+
disableP2pReplication: this._disableP2pReplication
|
|
1980
|
+
});
|
|
1981
|
+
try {
|
|
1982
|
+
await protocol.start();
|
|
1983
|
+
const credential = await onCredentialResolved.wait({
|
|
1984
|
+
timeout: params.timeout
|
|
1985
|
+
});
|
|
1986
|
+
import_log9.log.trace(traceKey, import_protocols5.trace.end({
|
|
1987
|
+
id: this._instanceId
|
|
1988
|
+
}), {
|
|
1989
|
+
F: __dxlog_file11,
|
|
1990
|
+
L: 162,
|
|
1991
|
+
S: this,
|
|
1992
|
+
C: (f, a) => f(...a)
|
|
1993
|
+
});
|
|
1994
|
+
return credential;
|
|
1995
|
+
} catch (err) {
|
|
1996
|
+
import_log9.log.trace(traceKey, import_protocols5.trace.error({
|
|
1997
|
+
id: this._instanceId,
|
|
1998
|
+
error: err
|
|
1999
|
+
}), {
|
|
2000
|
+
F: __dxlog_file11,
|
|
2001
|
+
L: 165,
|
|
2002
|
+
S: this,
|
|
2003
|
+
C: (f, a) => f(...a)
|
|
2004
|
+
});
|
|
2005
|
+
throw err;
|
|
2006
|
+
} finally {
|
|
2007
|
+
await protocol.stop();
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
};
|
|
2011
|
+
_ts_decorate7([
|
|
2012
|
+
import_async8.synchronized
|
|
2013
|
+
], SpaceManager.prototype, "open", null);
|
|
2014
|
+
_ts_decorate7([
|
|
2015
|
+
import_async8.synchronized
|
|
2016
|
+
], SpaceManager.prototype, "close", null);
|
|
2017
|
+
SpaceManager = _ts_decorate7([
|
|
2018
|
+
(0, import_async8.trackLeaks)("open", "close")
|
|
2019
|
+
], SpaceManager);
|
|
2020
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
2021
|
+
0 && (module.exports = {
|
|
2022
|
+
AuthExtension,
|
|
2023
|
+
AuthStatus,
|
|
2024
|
+
CredentialRetrieverExtension,
|
|
2025
|
+
CredentialServerExtension,
|
|
2026
|
+
MOCK_AUTH_PROVIDER,
|
|
2027
|
+
MOCK_AUTH_VERIFIER,
|
|
2028
|
+
MetadataStore,
|
|
2029
|
+
Pipeline,
|
|
2030
|
+
Space,
|
|
2031
|
+
SpaceManager,
|
|
2032
|
+
SpaceProtocol,
|
|
2033
|
+
SpaceProtocolSession,
|
|
2034
|
+
TimeframeClock,
|
|
2035
|
+
codec,
|
|
2036
|
+
createMappedFeedWriter,
|
|
2037
|
+
hasInvitationExpired,
|
|
2038
|
+
mapFeedIndexesToTimeframe,
|
|
2039
|
+
mapTimeframeToFeedIndexes,
|
|
2040
|
+
startAfter,
|
|
2041
|
+
valueEncoding
|
|
2042
|
+
});
|
|
2043
|
+
//# sourceMappingURL=chunk-IHR4UMVA.cjs.map
|