@dxos/echo-pipeline 0.1.24-next.6b1f434
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/LICENSE +8 -0
- package/README.md +22 -0
- package/dist/lib/browser/chunk-3GAE5CKD.mjs +1621 -0
- package/dist/lib/browser/chunk-3GAE5CKD.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +114 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/lib/browser/testing/index.mjs +238 -0
- package/dist/lib/browser/testing/index.mjs.map +7 -0
- package/dist/lib/node/index.cjs +1747 -0
- package/dist/lib/node/index.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -0
- package/dist/lib/node/testing/index.cjs +1835 -0
- package/dist/lib/node/testing/index.cjs.map +7 -0
- package/dist/types/src/common/codec.d.ts +12 -0
- package/dist/types/src/common/codec.d.ts.map +1 -0
- package/dist/types/src/common/feeds.d.ts +7 -0
- package/dist/types/src/common/feeds.d.ts.map +1 -0
- package/dist/types/src/common/index.d.ts +3 -0
- package/dist/types/src/common/index.d.ts.map +1 -0
- package/dist/types/src/dbhost/data-service-host.d.ts +22 -0
- package/dist/types/src/dbhost/data-service-host.d.ts.map +1 -0
- package/dist/types/src/dbhost/data-service.d.ts +21 -0
- package/dist/types/src/dbhost/data-service.d.ts.map +1 -0
- package/dist/types/src/dbhost/database-backend.d.ts +28 -0
- package/dist/types/src/dbhost/database-backend.d.ts.map +1 -0
- package/dist/types/src/dbhost/index.d.ts +6 -0
- package/dist/types/src/dbhost/index.d.ts.map +1 -0
- package/dist/types/src/dbhost/snapshot-manager.d.ts +17 -0
- package/dist/types/src/dbhost/snapshot-manager.d.ts.map +1 -0
- package/dist/types/src/dbhost/snapshot-store.d.ts +9 -0
- package/dist/types/src/dbhost/snapshot-store.d.ts.map +1 -0
- package/dist/types/src/dbhost/snapshot-store.test.d.ts +2 -0
- package/dist/types/src/dbhost/snapshot-store.test.d.ts.map +1 -0
- package/dist/types/src/errors/errors.d.ts +26 -0
- package/dist/types/src/errors/errors.d.ts.map +1 -0
- package/dist/types/src/errors/index.d.ts +2 -0
- package/dist/types/src/errors/index.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +7 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/metadata/index.d.ts +2 -0
- package/dist/types/src/metadata/index.d.ts.map +1 -0
- package/dist/types/src/metadata/metadata-store.d.ts +42 -0
- package/dist/types/src/metadata/metadata-store.d.ts.map +1 -0
- package/dist/types/src/pipeline/index.d.ts +3 -0
- package/dist/types/src/pipeline/index.d.ts.map +1 -0
- package/dist/types/src/pipeline/message-selector.d.ts +11 -0
- package/dist/types/src/pipeline/message-selector.d.ts.map +1 -0
- package/dist/types/src/pipeline/pipeline.d.ts +98 -0
- package/dist/types/src/pipeline/pipeline.d.ts.map +1 -0
- package/dist/types/src/pipeline/pipeline.test.d.ts +2 -0
- package/dist/types/src/pipeline/pipeline.test.d.ts.map +1 -0
- package/dist/types/src/pipeline/timeframe-clock.d.ts +19 -0
- package/dist/types/src/pipeline/timeframe-clock.d.ts.map +1 -0
- package/dist/types/src/space/auth.d.ts +23 -0
- package/dist/types/src/space/auth.d.ts.map +1 -0
- package/dist/types/src/space/control-pipeline.d.ts +31 -0
- package/dist/types/src/space/control-pipeline.d.ts.map +1 -0
- package/dist/types/src/space/control-pipeline.test.d.ts +2 -0
- package/dist/types/src/space/control-pipeline.test.d.ts.map +1 -0
- package/dist/types/src/space/data-pipeline-controller.d.ts +63 -0
- package/dist/types/src/space/data-pipeline-controller.d.ts.map +1 -0
- package/dist/types/src/space/genesis.d.ts +5 -0
- package/dist/types/src/space/genesis.d.ts.map +1 -0
- package/dist/types/src/space/index.d.ts +7 -0
- package/dist/types/src/space/index.d.ts.map +1 -0
- package/dist/types/src/space/replication.browser.test.d.ts +2 -0
- package/dist/types/src/space/replication.browser.test.d.ts.map +1 -0
- package/dist/types/src/space/space-manager.browser.test.d.ts +2 -0
- package/dist/types/src/space/space-manager.browser.test.d.ts.map +1 -0
- package/dist/types/src/space/space-manager.d.ts +41 -0
- package/dist/types/src/space/space-manager.d.ts.map +1 -0
- package/dist/types/src/space/space-protocol.browser.test.d.ts +2 -0
- package/dist/types/src/space/space-protocol.browser.test.d.ts.map +1 -0
- package/dist/types/src/space/space-protocol.d.ts +76 -0
- package/dist/types/src/space/space-protocol.d.ts.map +1 -0
- package/dist/types/src/space/space-protocol.test.d.ts +2 -0
- package/dist/types/src/space/space-protocol.test.d.ts.map +1 -0
- package/dist/types/src/space/space.d.ts +59 -0
- package/dist/types/src/space/space.d.ts.map +1 -0
- package/dist/types/src/space/space.test.d.ts +2 -0
- package/dist/types/src/space/space.test.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +4 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/test-agent-builder.d.ts +52 -0
- package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -0
- package/dist/types/src/testing/test-feed-builder.d.ts +9 -0
- package/dist/types/src/testing/test-feed-builder.d.ts.map +1 -0
- package/dist/types/src/testing/util.d.ts +14 -0
- package/dist/types/src/testing/util.d.ts.map +1 -0
- package/dist/types/src/tests/database.test.d.ts +2 -0
- package/dist/types/src/tests/database.test.d.ts.map +1 -0
- package/package.json +60 -0
- package/src/common/codec.ts +18 -0
- package/src/common/feeds.ts +23 -0
- package/src/common/index.ts +6 -0
- package/src/dbhost/data-service-host.ts +103 -0
- package/src/dbhost/data-service.ts +66 -0
- package/src/dbhost/database-backend.ts +64 -0
- package/src/dbhost/index.ts +9 -0
- package/src/dbhost/snapshot-manager.ts +68 -0
- package/src/dbhost/snapshot-store.test.ts +30 -0
- package/src/dbhost/snapshot-store.ts +45 -0
- package/src/errors/errors.ts +52 -0
- package/src/errors/index.ts +5 -0
- package/src/index.ts +10 -0
- package/src/metadata/index.ts +5 -0
- package/src/metadata/metadata-store.ts +173 -0
- package/src/pipeline/index.ts +6 -0
- package/src/pipeline/message-selector.ts +38 -0
- package/src/pipeline/pipeline.test.ts +71 -0
- package/src/pipeline/pipeline.ts +249 -0
- package/src/pipeline/timeframe-clock.ts +56 -0
- package/src/space/auth.ts +88 -0
- package/src/space/control-pipeline.test.ts +162 -0
- package/src/space/control-pipeline.ts +103 -0
- package/src/space/data-pipeline-controller.ts +234 -0
- package/src/space/genesis.ts +29 -0
- package/src/space/index.ts +10 -0
- package/src/space/replication.browser.test.ts +64 -0
- package/src/space/space-manager.browser.test.ts +44 -0
- package/src/space/space-manager.ts +92 -0
- package/src/space/space-protocol.browser.test.ts +135 -0
- package/src/space/space-protocol.test.ts +136 -0
- package/src/space/space-protocol.ts +222 -0
- package/src/space/space.test.ts +144 -0
- package/src/space/space.ts +199 -0
- package/src/testing/index.ts +7 -0
- package/src/testing/test-agent-builder.ts +193 -0
- package/src/testing/test-feed-builder.ts +19 -0
- package/src/testing/util.ts +77 -0
- package/src/tests/database.test.ts +53 -0
- package/testing.d.ts +11 -0
- package/testing.js +5 -0
|
@@ -0,0 +1,1747 @@
|
|
|
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
|
+
|
|
30
|
+
// packages/core/echo/echo-pipeline/src/index.ts
|
|
31
|
+
var src_exports = {};
|
|
32
|
+
__export(src_exports, {
|
|
33
|
+
AuthExtension: () => AuthExtension,
|
|
34
|
+
AuthStatus: () => AuthStatus,
|
|
35
|
+
DBError: () => DBError,
|
|
36
|
+
DataPipelineControllerImpl: () => DataPipelineControllerImpl,
|
|
37
|
+
DataServiceHost: () => DataServiceHost,
|
|
38
|
+
DataServiceImpl: () => DataServiceImpl,
|
|
39
|
+
DataServiceSubscriptions: () => DataServiceSubscriptions,
|
|
40
|
+
DatabaseBackendHost: () => DatabaseBackendHost,
|
|
41
|
+
EntityNotFoundError: () => EntityNotFoundError,
|
|
42
|
+
IdentityNotInitializedError: () => IdentityNotInitializedError,
|
|
43
|
+
InvalidInvitationError: () => InvalidInvitationError,
|
|
44
|
+
InvalidStorageVersionError: () => InvalidStorageVersionError,
|
|
45
|
+
MOCK_AUTH_PROVIDER: () => MOCK_AUTH_PROVIDER,
|
|
46
|
+
MOCK_AUTH_VERIFIER: () => MOCK_AUTH_VERIFIER,
|
|
47
|
+
MetadataStore: () => MetadataStore,
|
|
48
|
+
NoopDataPipelineController: () => NoopDataPipelineController,
|
|
49
|
+
Pipeline: () => Pipeline,
|
|
50
|
+
STORAGE_VERSION: () => STORAGE_VERSION,
|
|
51
|
+
SnapshotManager: () => SnapshotManager,
|
|
52
|
+
SnapshotStore: () => SnapshotStore,
|
|
53
|
+
Space: () => Space,
|
|
54
|
+
SpaceManager: () => SpaceManager,
|
|
55
|
+
SpaceNotFoundError: () => SpaceNotFoundError,
|
|
56
|
+
SpaceProtocol: () => SpaceProtocol,
|
|
57
|
+
SpaceProtocolSession: () => SpaceProtocolSession,
|
|
58
|
+
TimeframeClock: () => TimeframeClock,
|
|
59
|
+
UnknownModelError: () => UnknownModelError,
|
|
60
|
+
codec: () => codec,
|
|
61
|
+
createMappedFeedWriter: () => createMappedFeedWriter,
|
|
62
|
+
mapFeedIndexesToTimeframe: () => mapFeedIndexesToTimeframe,
|
|
63
|
+
mapTimeframeToFeedIndexes: () => mapTimeframeToFeedIndexes,
|
|
64
|
+
spaceGenesis: () => spaceGenesis,
|
|
65
|
+
valueEncoding: () => valueEncoding
|
|
66
|
+
});
|
|
67
|
+
module.exports = __toCommonJS(src_exports);
|
|
68
|
+
|
|
69
|
+
// packages/core/echo/echo-pipeline/src/errors/errors.ts
|
|
70
|
+
var DBError = class extends Error {
|
|
71
|
+
constructor(code, message, context) {
|
|
72
|
+
super(message ? `${code}: ${message}` : code.toString());
|
|
73
|
+
this.code = code;
|
|
74
|
+
this.context = context;
|
|
75
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
var IdentityNotInitializedError = class extends DBError {
|
|
79
|
+
constructor() {
|
|
80
|
+
super("IDENTITY_NOT_INITIALIZED", "Identity not initialized.");
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
var InvalidInvitationError = class extends DBError {
|
|
84
|
+
constructor() {
|
|
85
|
+
super("INVALID_INVITATION", "Invitation is invalid.");
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
var InvalidStorageVersionError = class extends DBError {
|
|
89
|
+
constructor(expected, actual) {
|
|
90
|
+
super("INVALID_STORAGE_VERSION", "Invalid storage version.", {
|
|
91
|
+
expected,
|
|
92
|
+
actual
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
var SpaceNotFoundError = class extends DBError {
|
|
97
|
+
constructor(spaceKey) {
|
|
98
|
+
super("SPACE_NOT_FOUND", "Space not found.", {
|
|
99
|
+
spaceKey
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
var EntityNotFoundError = class extends DBError {
|
|
104
|
+
constructor(entityId) {
|
|
105
|
+
super("ITEM_NOT_FOUND", "Item not found.", {
|
|
106
|
+
entityId
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
var UnknownModelError = class extends DBError {
|
|
111
|
+
constructor(model) {
|
|
112
|
+
super("UNKNOWN_MODEL", "Unknown model.", {
|
|
113
|
+
model
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// packages/core/echo/echo-pipeline/src/metadata/metadata-store.ts
|
|
119
|
+
var import_node_assert = __toESM(require("node:assert"));
|
|
120
|
+
var import_async = require("@dxos/async");
|
|
121
|
+
var import_log = require("@dxos/log");
|
|
122
|
+
var import_protocols = require("@dxos/protocols");
|
|
123
|
+
var __decorate = function(decorators, target, key, desc) {
|
|
124
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
125
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
126
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
127
|
+
else
|
|
128
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
129
|
+
if (d = decorators[i])
|
|
130
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
131
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
132
|
+
};
|
|
133
|
+
var STORAGE_VERSION = 1;
|
|
134
|
+
var emptyEchoMetadata = () => ({
|
|
135
|
+
version: STORAGE_VERSION,
|
|
136
|
+
spaces: [],
|
|
137
|
+
created: new Date(),
|
|
138
|
+
updated: new Date()
|
|
139
|
+
});
|
|
140
|
+
var MetadataStore = class {
|
|
141
|
+
// prettier-ignore
|
|
142
|
+
constructor(_directory) {
|
|
143
|
+
this._directory = _directory;
|
|
144
|
+
this._metadata = emptyEchoMetadata();
|
|
145
|
+
}
|
|
146
|
+
get version() {
|
|
147
|
+
var _a;
|
|
148
|
+
return (_a = this._metadata.version) != null ? _a : 0;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Returns a list of currently saved spaces. The list and objects in it can be modified addSpace and
|
|
152
|
+
* addSpaceFeed functions.
|
|
153
|
+
*/
|
|
154
|
+
get spaces() {
|
|
155
|
+
var _a;
|
|
156
|
+
return (_a = this._metadata.spaces) != null ? _a : [];
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Loads metadata from persistent storage.
|
|
160
|
+
*/
|
|
161
|
+
async load() {
|
|
162
|
+
const file = this._directory.getOrCreateFile("EchoMetadata");
|
|
163
|
+
try {
|
|
164
|
+
const { size: fileLength } = await file.stat();
|
|
165
|
+
if (fileLength < 4) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const dataSize = fromBytesInt32(await file.read(0, 4));
|
|
169
|
+
(0, import_log.log)("loaded", {
|
|
170
|
+
size: dataSize
|
|
171
|
+
}, {
|
|
172
|
+
file: "metadata-store.ts",
|
|
173
|
+
line: 68,
|
|
174
|
+
scope: this,
|
|
175
|
+
callSite: (f, a) => f(...a)
|
|
176
|
+
});
|
|
177
|
+
{
|
|
178
|
+
if (fileLength < dataSize + 4) {
|
|
179
|
+
throw new Error("Metadata storage is corrupted");
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
const data = await file.read(4, dataSize);
|
|
183
|
+
this._metadata = import_protocols.schema.getCodecForType("dxos.echo.metadata.EchoMetadata").decode(data);
|
|
184
|
+
} catch (err) {
|
|
185
|
+
import_log.log.error("failed to load metadata", {
|
|
186
|
+
err
|
|
187
|
+
}, {
|
|
188
|
+
file: "metadata-store.ts",
|
|
189
|
+
line: 80,
|
|
190
|
+
scope: this,
|
|
191
|
+
callSite: (f, a) => f(...a)
|
|
192
|
+
});
|
|
193
|
+
this._metadata = emptyEchoMetadata();
|
|
194
|
+
} finally {
|
|
195
|
+
await file.close();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
async _save() {
|
|
199
|
+
var _a;
|
|
200
|
+
const data = {
|
|
201
|
+
...this._metadata,
|
|
202
|
+
version: STORAGE_VERSION,
|
|
203
|
+
created: (_a = this._metadata.created) != null ? _a : new Date(),
|
|
204
|
+
updated: new Date()
|
|
205
|
+
};
|
|
206
|
+
const file = this._directory.getOrCreateFile("EchoMetadata");
|
|
207
|
+
try {
|
|
208
|
+
const encoded = Buffer.from(import_protocols.schema.getCodecForType("dxos.echo.metadata.EchoMetadata").encode(data));
|
|
209
|
+
await file.write(0, toBytesInt32(encoded.length));
|
|
210
|
+
(0, import_log.log)("saved", {
|
|
211
|
+
size: encoded.length
|
|
212
|
+
}, {
|
|
213
|
+
file: "metadata-store.ts",
|
|
214
|
+
line: 103,
|
|
215
|
+
scope: this,
|
|
216
|
+
callSite: (f, a) => f(...a)
|
|
217
|
+
});
|
|
218
|
+
await file.write(4, encoded);
|
|
219
|
+
} finally {
|
|
220
|
+
await file.close();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Clears storage - doesn't work for now.
|
|
225
|
+
*/
|
|
226
|
+
async clear() {
|
|
227
|
+
(0, import_log.log)("clearing all metadata", {}, {
|
|
228
|
+
file: "metadata-store.ts",
|
|
229
|
+
line: 116,
|
|
230
|
+
scope: this,
|
|
231
|
+
callSite: (f, a) => f(...a)
|
|
232
|
+
});
|
|
233
|
+
await this._directory.delete();
|
|
234
|
+
}
|
|
235
|
+
getIdentityRecord() {
|
|
236
|
+
return this._metadata.identity;
|
|
237
|
+
}
|
|
238
|
+
async setIdentityRecord(record) {
|
|
239
|
+
(0, import_node_assert.default)(!this._metadata.identity, "Cannot overwrite existing identity in metadata");
|
|
240
|
+
this._metadata.identity = record;
|
|
241
|
+
await this._save();
|
|
242
|
+
}
|
|
243
|
+
async addSpace(record) {
|
|
244
|
+
var _a, _b, _c;
|
|
245
|
+
(0, import_node_assert.default)(!((_a = this._metadata.spaces) != null ? _a : []).find((space) => space.key === record.key), "Cannot overwrite existing space in metadata");
|
|
246
|
+
((_c = (_b = this._metadata).spaces) != null ? _c : _b.spaces = []).push(record);
|
|
247
|
+
await this._save();
|
|
248
|
+
}
|
|
249
|
+
async setSpaceLatestTimeframe(spaceKey, timeframe) {
|
|
250
|
+
const space = this.spaces.find((space2) => space2.key === spaceKey);
|
|
251
|
+
(0, import_node_assert.default)(space, "Space not found");
|
|
252
|
+
space.dataTimeframe = timeframe;
|
|
253
|
+
await this._save();
|
|
254
|
+
}
|
|
255
|
+
async setSpaceSnapshot(spaceKey, snapshot) {
|
|
256
|
+
const space = this.spaces.find((space2) => space2.key === spaceKey);
|
|
257
|
+
(0, import_node_assert.default)(space, "Space not found");
|
|
258
|
+
space.snapshot = snapshot;
|
|
259
|
+
await this._save();
|
|
260
|
+
}
|
|
261
|
+
async setWritableFeedKeys(spaceKey, controlFeedKey, dataFeedKey) {
|
|
262
|
+
const space = this.spaces.find((space2) => space2.key === spaceKey);
|
|
263
|
+
(0, import_node_assert.default)(space, "Space not found");
|
|
264
|
+
space.controlFeedKey = controlFeedKey;
|
|
265
|
+
space.dataFeedKey = dataFeedKey;
|
|
266
|
+
await this._save();
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
__decorate([
|
|
270
|
+
import_async.synchronized
|
|
271
|
+
], MetadataStore.prototype, "load", null);
|
|
272
|
+
__decorate([
|
|
273
|
+
import_async.synchronized
|
|
274
|
+
], MetadataStore.prototype, "_save", null);
|
|
275
|
+
var toBytesInt32 = (num) => {
|
|
276
|
+
const buf = Buffer.alloc(4);
|
|
277
|
+
buf.writeInt32LE(num, 0);
|
|
278
|
+
return buf;
|
|
279
|
+
};
|
|
280
|
+
var fromBytesInt32 = (buf) => buf.readInt32LE(0);
|
|
281
|
+
|
|
282
|
+
// packages/core/echo/echo-pipeline/src/pipeline/pipeline.ts
|
|
283
|
+
var import_node_assert4 = __toESM(require("node:assert"));
|
|
284
|
+
var import_async3 = require("@dxos/async");
|
|
285
|
+
var import_feed_store = require("@dxos/feed-store");
|
|
286
|
+
var import_keys = require("@dxos/keys");
|
|
287
|
+
var import_log3 = require("@dxos/log");
|
|
288
|
+
var import_timeframe2 = require("@dxos/timeframe");
|
|
289
|
+
|
|
290
|
+
// packages/core/echo/echo-pipeline/src/common/codec.ts
|
|
291
|
+
var import_hypercore = require("@dxos/hypercore");
|
|
292
|
+
var import_protocols2 = require("@dxos/protocols");
|
|
293
|
+
var codec = import_protocols2.schema.getCodecForType("dxos.echo.feed.FeedMessage");
|
|
294
|
+
var valueEncoding = (0, import_hypercore.createCodecEncoding)(codec);
|
|
295
|
+
|
|
296
|
+
// packages/core/echo/echo-pipeline/src/common/feeds.ts
|
|
297
|
+
var import_node_assert2 = __toESM(require("node:assert"));
|
|
298
|
+
var createMappedFeedWriter = (mapper, writer) => {
|
|
299
|
+
(0, import_node_assert2.default)(mapper);
|
|
300
|
+
(0, import_node_assert2.default)(writer);
|
|
301
|
+
return {
|
|
302
|
+
write: async (data) => await writer.write(await mapper(data))
|
|
303
|
+
};
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
// packages/core/echo/echo-pipeline/src/pipeline/message-selector.ts
|
|
307
|
+
var import_debug = __toESM(require("debug"));
|
|
308
|
+
var import_node_assert3 = __toESM(require("node:assert"));
|
|
309
|
+
var log2 = (0, import_debug.default)("dxos:echo-db:message-selector");
|
|
310
|
+
var createMessageSelector = (timeframeClock) => {
|
|
311
|
+
return (messages) => {
|
|
312
|
+
for (let i = 0; i < messages.length; i++) {
|
|
313
|
+
const { data: { timeframe } } = messages[i];
|
|
314
|
+
(0, import_node_assert3.default)(timeframe);
|
|
315
|
+
if (!timeframeClock.hasGaps(timeframe)) {
|
|
316
|
+
return i;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
log2("Skipping...");
|
|
320
|
+
};
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
// packages/core/echo/echo-pipeline/src/pipeline/timeframe-clock.ts
|
|
324
|
+
var import_async2 = require("@dxos/async");
|
|
325
|
+
var import_debug2 = require("@dxos/debug");
|
|
326
|
+
var import_log2 = require("@dxos/log");
|
|
327
|
+
var import_timeframe = require("@dxos/timeframe");
|
|
328
|
+
var __decorate2 = function(decorators, target, key, desc) {
|
|
329
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
330
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
331
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
332
|
+
else
|
|
333
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
334
|
+
if (d = decorators[i])
|
|
335
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
336
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
337
|
+
};
|
|
338
|
+
var mapTimeframeToFeedIndexes = (timeframe) => timeframe.frames().map(([feedKey, index]) => ({
|
|
339
|
+
feedKey,
|
|
340
|
+
index
|
|
341
|
+
}));
|
|
342
|
+
var mapFeedIndexesToTimeframe = (indexes) => new import_timeframe.Timeframe(indexes.map(({ feedKey, index }) => [
|
|
343
|
+
feedKey,
|
|
344
|
+
index
|
|
345
|
+
]));
|
|
346
|
+
var TimeframeClock = class {
|
|
347
|
+
// prettier-ignore
|
|
348
|
+
constructor(_timeframe = new import_timeframe.Timeframe()) {
|
|
349
|
+
this._timeframe = _timeframe;
|
|
350
|
+
this.update = new import_async2.Event();
|
|
351
|
+
}
|
|
352
|
+
get timeframe() {
|
|
353
|
+
return this._timeframe;
|
|
354
|
+
}
|
|
355
|
+
updateTimeframe(key, seq) {
|
|
356
|
+
this._timeframe = import_timeframe.Timeframe.merge(this._timeframe, new import_timeframe.Timeframe([
|
|
357
|
+
[
|
|
358
|
+
key,
|
|
359
|
+
seq
|
|
360
|
+
]
|
|
361
|
+
]));
|
|
362
|
+
this.update.emit(this._timeframe);
|
|
363
|
+
}
|
|
364
|
+
hasGaps(timeframe) {
|
|
365
|
+
const gaps = import_timeframe.Timeframe.dependencies(timeframe, this._timeframe);
|
|
366
|
+
return !gaps.isEmpty();
|
|
367
|
+
}
|
|
368
|
+
async waitUntilReached(target) {
|
|
369
|
+
import_log2.log.debug("waitUntilReached", {
|
|
370
|
+
target,
|
|
371
|
+
current: this._timeframe
|
|
372
|
+
}, {
|
|
373
|
+
file: "timeframe-clock.ts",
|
|
374
|
+
line: 45,
|
|
375
|
+
scope: this,
|
|
376
|
+
callSite: (f, a) => f(...a)
|
|
377
|
+
});
|
|
378
|
+
await this.update.waitForCondition(() => {
|
|
379
|
+
(0, import_log2.log)("check if reached", {
|
|
380
|
+
target,
|
|
381
|
+
current: this._timeframe,
|
|
382
|
+
deps: import_timeframe.Timeframe.dependencies(target, this._timeframe)
|
|
383
|
+
}, {
|
|
384
|
+
file: "timeframe-clock.ts",
|
|
385
|
+
line: 47,
|
|
386
|
+
scope: this,
|
|
387
|
+
callSite: (f, a) => f(...a)
|
|
388
|
+
});
|
|
389
|
+
return import_timeframe.Timeframe.dependencies(target, this._timeframe).isEmpty();
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
__decorate2([
|
|
394
|
+
(0, import_debug2.timed)(5e3)
|
|
395
|
+
], TimeframeClock.prototype, "waitUntilReached", null);
|
|
396
|
+
|
|
397
|
+
// packages/core/echo/echo-pipeline/src/pipeline/pipeline.ts
|
|
398
|
+
var PipelineState = class {
|
|
399
|
+
// prettier-ignore
|
|
400
|
+
constructor(_iterator, _timeframeClock) {
|
|
401
|
+
this._iterator = _iterator;
|
|
402
|
+
this._timeframeClock = _timeframeClock;
|
|
403
|
+
this.timeframeUpdate = this._timeframeClock.update;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Latest theoretical timeframe based on the last mutation in each feed.
|
|
407
|
+
* NOTE: This might never be reached if the mutation dependencies
|
|
408
|
+
*/
|
|
409
|
+
get endTimeframe() {
|
|
410
|
+
return mapFeedIndexesToTimeframe(this._iterator.feeds.filter((feed) => feed.properties.length > 0).map((feed) => ({
|
|
411
|
+
feedKey: feed.key,
|
|
412
|
+
index: feed.properties.length - 1
|
|
413
|
+
})));
|
|
414
|
+
}
|
|
415
|
+
get timeframe() {
|
|
416
|
+
return this._timeframeClock.timeframe;
|
|
417
|
+
}
|
|
418
|
+
get targetTimeframe() {
|
|
419
|
+
return this._targetTimeframe ? import_timeframe2.Timeframe.merge(this.endTimeframe, this._targetTimeframe) : this.endTimeframe;
|
|
420
|
+
}
|
|
421
|
+
async waitUntilTimeframe(target) {
|
|
422
|
+
await this._timeframeClock.waitUntilReached(target);
|
|
423
|
+
}
|
|
424
|
+
setTargetTimeframe(target) {
|
|
425
|
+
this._targetTimeframe = target;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Wait until the pipeline processes all messages in the feed and reaches the target timeframe if that is set.
|
|
429
|
+
*
|
|
430
|
+
* This function will resolve immediately if the pipeline is stalled.
|
|
431
|
+
*
|
|
432
|
+
* @param timeout Timeout in milliseconds to specify the maximum wait time.
|
|
433
|
+
*/
|
|
434
|
+
async waitUntilReachedTargetTimeframe({ timeout } = {}) {
|
|
435
|
+
var _a;
|
|
436
|
+
(0, import_log3.log)("waitUntilReachedTargetTimeframe", {
|
|
437
|
+
timeout,
|
|
438
|
+
current: this.timeframe,
|
|
439
|
+
target: this.targetTimeframe
|
|
440
|
+
}, {
|
|
441
|
+
file: "pipeline.ts",
|
|
442
|
+
line: 82,
|
|
443
|
+
scope: this,
|
|
444
|
+
callSite: (f, a) => f(...a)
|
|
445
|
+
});
|
|
446
|
+
(_a = this._reachedTargetPromise) != null ? _a : this._reachedTargetPromise = Promise.race([
|
|
447
|
+
this._timeframeClock.update.waitForCondition(() => {
|
|
448
|
+
return import_timeframe2.Timeframe.dependencies(this.targetTimeframe, this.timeframe).isEmpty();
|
|
449
|
+
}),
|
|
450
|
+
this._iterator.stalled.discardParameter().waitForCount(1)
|
|
451
|
+
]);
|
|
452
|
+
let done = false;
|
|
453
|
+
if (timeout) {
|
|
454
|
+
return Promise.race([
|
|
455
|
+
this._reachedTargetPromise.then(() => {
|
|
456
|
+
done = true;
|
|
457
|
+
}),
|
|
458
|
+
(0, import_async3.sleep)(timeout).then(() => {
|
|
459
|
+
if (done) {
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
import_log3.log.warn("waitUntilReachedTargetTimeframe timed out", {
|
|
463
|
+
timeout,
|
|
464
|
+
current: this.timeframe,
|
|
465
|
+
target: this.targetTimeframe,
|
|
466
|
+
dependencies: import_timeframe2.Timeframe.dependencies(this.targetTimeframe, this.timeframe)
|
|
467
|
+
}, {
|
|
468
|
+
file: "pipeline.ts",
|
|
469
|
+
line: 107,
|
|
470
|
+
scope: this,
|
|
471
|
+
callSite: (f, a) => f(...a)
|
|
472
|
+
});
|
|
473
|
+
})
|
|
474
|
+
]);
|
|
475
|
+
} else {
|
|
476
|
+
return this._reachedTargetPromise;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
var Pipeline = class {
|
|
481
|
+
// prettier-ignore
|
|
482
|
+
constructor(_initialTimeframe = new import_timeframe2.Timeframe()) {
|
|
483
|
+
this._initialTimeframe = _initialTimeframe;
|
|
484
|
+
this._timeframeClock = new TimeframeClock(this._initialTimeframe);
|
|
485
|
+
this._feedSetIterator = new import_feed_store.FeedSetIterator(createMessageSelector(this._timeframeClock), {
|
|
486
|
+
start: mapTimeframeToFeedIndexes(this._initialTimeframe),
|
|
487
|
+
stallTimeout: 1e3
|
|
488
|
+
});
|
|
489
|
+
this._state = new PipelineState(this._feedSetIterator, this._timeframeClock);
|
|
490
|
+
this._processingTrigger = new import_async3.Trigger().wake();
|
|
491
|
+
this._isOpen = false;
|
|
492
|
+
this._feedSetIterator.stalled.on((iterator) => {
|
|
493
|
+
import_log3.log.warn(`Stalled after ${iterator.options.stallTimeout}ms with ${iterator.size} feeds.`, {}, {
|
|
494
|
+
file: "pipeline.ts",
|
|
495
|
+
line: 183,
|
|
496
|
+
scope: this,
|
|
497
|
+
callSite: (f, a) => f(...a)
|
|
498
|
+
});
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
get state() {
|
|
502
|
+
return this._state;
|
|
503
|
+
}
|
|
504
|
+
get writer() {
|
|
505
|
+
(0, import_node_assert4.default)(this._writer, "Writer not set.");
|
|
506
|
+
return this._writer;
|
|
507
|
+
}
|
|
508
|
+
getFeeds() {
|
|
509
|
+
return this._feedSetIterator.feeds;
|
|
510
|
+
}
|
|
511
|
+
async addFeed(feed) {
|
|
512
|
+
await this._feedSetIterator.addFeed(feed);
|
|
513
|
+
}
|
|
514
|
+
setWriteFeed(feed) {
|
|
515
|
+
(0, import_node_assert4.default)(!this._writer, "Writer already set.");
|
|
516
|
+
(0, import_node_assert4.default)(feed.properties.writable, "Feed must be writable.");
|
|
517
|
+
this._writer = createMappedFeedWriter((payload) => ({
|
|
518
|
+
timeframe: this._timeframeClock.timeframe,
|
|
519
|
+
payload
|
|
520
|
+
}), feed.createFeedWriter());
|
|
521
|
+
}
|
|
522
|
+
async start() {
|
|
523
|
+
(0, import_log3.log)("starting...", {}, {
|
|
524
|
+
file: "pipeline.ts",
|
|
525
|
+
line: 218,
|
|
526
|
+
scope: this,
|
|
527
|
+
callSite: (f, a) => f(...a)
|
|
528
|
+
});
|
|
529
|
+
await this._feedSetIterator.open();
|
|
530
|
+
(0, import_log3.log)("started", {}, {
|
|
531
|
+
file: "pipeline.ts",
|
|
532
|
+
line: 220,
|
|
533
|
+
scope: this,
|
|
534
|
+
callSite: (f, a) => f(...a)
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
async stop() {
|
|
538
|
+
(0, import_log3.log)("stopping...", {}, {
|
|
539
|
+
file: "pipeline.ts",
|
|
540
|
+
line: 224,
|
|
541
|
+
scope: this,
|
|
542
|
+
callSite: (f, a) => f(...a)
|
|
543
|
+
});
|
|
544
|
+
await this._feedSetIterator.close();
|
|
545
|
+
await this._processingTrigger.wait();
|
|
546
|
+
(0, import_log3.log)("stopped", {}, {
|
|
547
|
+
file: "pipeline.ts",
|
|
548
|
+
line: 227,
|
|
549
|
+
scope: this,
|
|
550
|
+
callSite: (f, a) => f(...a)
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Starts to iterate over the ordered messages from the added feeds.
|
|
555
|
+
* Updates the timeframe clock after the message has bee processed.
|
|
556
|
+
*/
|
|
557
|
+
async *consume() {
|
|
558
|
+
(0, import_node_assert4.default)(!this._isOpen, "Pipeline is already being consumed.");
|
|
559
|
+
this._isOpen = true;
|
|
560
|
+
for await (const block of this._feedSetIterator) {
|
|
561
|
+
this._processingTrigger.reset();
|
|
562
|
+
yield block;
|
|
563
|
+
this._processingTrigger.wake();
|
|
564
|
+
this._timeframeClock.updateTimeframe(import_keys.PublicKey.from(block.feedKey), block.seq);
|
|
565
|
+
}
|
|
566
|
+
this._isOpen = false;
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
// packages/core/echo/echo-pipeline/src/space/auth.ts
|
|
571
|
+
var import_node_assert5 = __toESM(require("node:assert"));
|
|
572
|
+
var import_async4 = require("@dxos/async");
|
|
573
|
+
var import_context = require("@dxos/context");
|
|
574
|
+
var import_crypto = require("@dxos/crypto");
|
|
575
|
+
var import_log4 = require("@dxos/log");
|
|
576
|
+
var import_protocols3 = require("@dxos/protocols");
|
|
577
|
+
var import_teleport = require("@dxos/teleport");
|
|
578
|
+
var AuthExtension = class extends import_teleport.RpcExtension {
|
|
579
|
+
constructor(_authParams) {
|
|
580
|
+
super({
|
|
581
|
+
requested: {
|
|
582
|
+
AuthService: import_protocols3.schema.getService("dxos.mesh.teleport.auth.AuthService")
|
|
583
|
+
},
|
|
584
|
+
exposed: {
|
|
585
|
+
AuthService: import_protocols3.schema.getService("dxos.mesh.teleport.auth.AuthService")
|
|
586
|
+
},
|
|
587
|
+
timeout: 60 * 1e3
|
|
588
|
+
// Long timeout because auth can wait for sync in certain cases.
|
|
589
|
+
});
|
|
590
|
+
this._authParams = _authParams;
|
|
591
|
+
this._ctx = new import_context.Context({
|
|
592
|
+
onError: (err) => {
|
|
593
|
+
import_log4.log.catch(err, {}, {
|
|
594
|
+
file: "auth.ts",
|
|
595
|
+
line: 29,
|
|
596
|
+
scope: this,
|
|
597
|
+
callSite: (f, a) => f(...a)
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
async getHandlers() {
|
|
603
|
+
return {
|
|
604
|
+
AuthService: {
|
|
605
|
+
authenticate: async ({ challenge }) => {
|
|
606
|
+
try {
|
|
607
|
+
const credential = await this._authParams.provider(challenge);
|
|
608
|
+
if (!credential) {
|
|
609
|
+
throw new Error("auth rejected");
|
|
610
|
+
}
|
|
611
|
+
return {
|
|
612
|
+
credential
|
|
613
|
+
};
|
|
614
|
+
} catch (err) {
|
|
615
|
+
import_log4.log.error("failed to generate auth credentials", err, {
|
|
616
|
+
file: "auth.ts",
|
|
617
|
+
line: 56,
|
|
618
|
+
scope: this,
|
|
619
|
+
callSite: (f, a) => f(...a)
|
|
620
|
+
});
|
|
621
|
+
throw new Error("auth rejected");
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
async onOpen(context) {
|
|
628
|
+
await super.onOpen(context);
|
|
629
|
+
(0, import_async4.scheduleTask)(this._ctx, async () => {
|
|
630
|
+
try {
|
|
631
|
+
const challenge = (0, import_crypto.randomBytes)(32);
|
|
632
|
+
const { credential } = await this.rpc.AuthService.authenticate({
|
|
633
|
+
challenge
|
|
634
|
+
});
|
|
635
|
+
(0, import_node_assert5.default)((credential == null ? void 0 : credential.length) > 0, "invalid credential");
|
|
636
|
+
const success = await this._authParams.verifier(challenge, credential);
|
|
637
|
+
(0, import_node_assert5.default)(success, "credential not verified");
|
|
638
|
+
(0, import_async4.runInContext)(this._ctx, () => this._authParams.onAuthSuccess());
|
|
639
|
+
} catch (err) {
|
|
640
|
+
import_log4.log.warn("auth failed", err, {
|
|
641
|
+
file: "auth.ts",
|
|
642
|
+
line: 75,
|
|
643
|
+
scope: this,
|
|
644
|
+
callSite: (f, a) => f(...a)
|
|
645
|
+
});
|
|
646
|
+
this.close();
|
|
647
|
+
this._authParams.onAuthFailure();
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
async onClose() {
|
|
652
|
+
await this._ctx.dispose();
|
|
653
|
+
await super.onClose();
|
|
654
|
+
}
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
// packages/core/echo/echo-pipeline/src/space/space.ts
|
|
658
|
+
var import_node_assert6 = __toESM(require("node:assert"));
|
|
659
|
+
var import_async5 = require("@dxos/async");
|
|
660
|
+
var import_log6 = require("@dxos/log");
|
|
661
|
+
var import_credentials3 = require("@dxos/protocols/proto/dxos/halo/credentials");
|
|
662
|
+
var import_util2 = require("@dxos/util");
|
|
663
|
+
|
|
664
|
+
// packages/core/echo/echo-pipeline/src/space/control-pipeline.ts
|
|
665
|
+
var import_credentials = require("@dxos/credentials");
|
|
666
|
+
var import_keys2 = require("@dxos/keys");
|
|
667
|
+
var import_log5 = require("@dxos/log");
|
|
668
|
+
var import_credentials2 = require("@dxos/protocols/proto/dxos/halo/credentials");
|
|
669
|
+
var import_util = require("@dxos/util");
|
|
670
|
+
var ControlPipeline = class {
|
|
671
|
+
constructor({ spaceKey, genesisFeed, feedProvider, initialTimeframe }) {
|
|
672
|
+
this.onFeedAdmitted = new import_util.Callback();
|
|
673
|
+
this._pipeline = new Pipeline(initialTimeframe);
|
|
674
|
+
void this._pipeline.addFeed(genesisFeed);
|
|
675
|
+
this._spaceStateMachine = new import_credentials.SpaceStateMachine(spaceKey);
|
|
676
|
+
this._spaceStateMachine.onFeedAdmitted.set(async (info) => {
|
|
677
|
+
(0, import_log5.log)("feed admitted", {
|
|
678
|
+
key: info.key
|
|
679
|
+
}, {
|
|
680
|
+
file: "control-pipeline.ts",
|
|
681
|
+
line: 41,
|
|
682
|
+
scope: this,
|
|
683
|
+
callSite: (f, a) => f(...a)
|
|
684
|
+
});
|
|
685
|
+
if (info.assertion.designation === import_credentials2.AdmittedFeed.Designation.CONTROL && !info.key.equals(genesisFeed.key)) {
|
|
686
|
+
try {
|
|
687
|
+
const feed = await feedProvider(info.key);
|
|
688
|
+
await this._pipeline.addFeed(feed);
|
|
689
|
+
} catch (err) {
|
|
690
|
+
import_log5.log.catch(err, {}, {
|
|
691
|
+
file: "control-pipeline.ts",
|
|
692
|
+
line: 49,
|
|
693
|
+
scope: this,
|
|
694
|
+
callSite: (f, a) => f(...a)
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
await this.onFeedAdmitted.callIfSet(info);
|
|
699
|
+
});
|
|
700
|
+
this.onMemberAdmitted = this._spaceStateMachine.onMemberAdmitted;
|
|
701
|
+
this.onCredentialProcessed = this._spaceStateMachine.onCredentialProcessed;
|
|
702
|
+
}
|
|
703
|
+
get spaceState() {
|
|
704
|
+
return this._spaceStateMachine;
|
|
705
|
+
}
|
|
706
|
+
get pipeline() {
|
|
707
|
+
return this._pipeline;
|
|
708
|
+
}
|
|
709
|
+
setWriteFeed(feed) {
|
|
710
|
+
this._pipeline.setWriteFeed(feed);
|
|
711
|
+
}
|
|
712
|
+
async start() {
|
|
713
|
+
(0, import_log5.log)("starting...", {}, {
|
|
714
|
+
file: "control-pipeline.ts",
|
|
715
|
+
line: 73,
|
|
716
|
+
scope: this,
|
|
717
|
+
callSite: (f, a) => f(...a)
|
|
718
|
+
});
|
|
719
|
+
setTimeout(async () => {
|
|
720
|
+
for await (const msg of this._pipeline.consume()) {
|
|
721
|
+
try {
|
|
722
|
+
(0, import_log5.log)("processing", {
|
|
723
|
+
key: msg.feedKey,
|
|
724
|
+
seq: msg.seq
|
|
725
|
+
}, {
|
|
726
|
+
file: "control-pipeline.ts",
|
|
727
|
+
line: 78,
|
|
728
|
+
scope: this,
|
|
729
|
+
callSite: (f, a) => f(...a)
|
|
730
|
+
});
|
|
731
|
+
if (msg.data.payload.credential) {
|
|
732
|
+
const result = await this._spaceStateMachine.process(msg.data.payload.credential.credential, import_keys2.PublicKey.from(msg.feedKey));
|
|
733
|
+
if (!result) {
|
|
734
|
+
import_log5.log.warn("processing failed", {
|
|
735
|
+
msg
|
|
736
|
+
}, {
|
|
737
|
+
file: "control-pipeline.ts",
|
|
738
|
+
line: 85,
|
|
739
|
+
scope: this,
|
|
740
|
+
callSite: (f, a) => f(...a)
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
} catch (err) {
|
|
745
|
+
import_log5.log.catch(err, {}, {
|
|
746
|
+
file: "control-pipeline.ts",
|
|
747
|
+
line: 89,
|
|
748
|
+
scope: this,
|
|
749
|
+
callSite: (f, a) => f(...a)
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
});
|
|
754
|
+
await this._pipeline.start();
|
|
755
|
+
(0, import_log5.log)("started", {}, {
|
|
756
|
+
file: "control-pipeline.ts",
|
|
757
|
+
line: 95,
|
|
758
|
+
scope: this,
|
|
759
|
+
callSite: (f, a) => f(...a)
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
async stop() {
|
|
763
|
+
(0, import_log5.log)("stopping...", {}, {
|
|
764
|
+
file: "control-pipeline.ts",
|
|
765
|
+
line: 99,
|
|
766
|
+
scope: this,
|
|
767
|
+
callSite: (f, a) => f(...a)
|
|
768
|
+
});
|
|
769
|
+
await this._pipeline.stop();
|
|
770
|
+
(0, import_log5.log)("stopped", {}, {
|
|
771
|
+
file: "control-pipeline.ts",
|
|
772
|
+
line: 101,
|
|
773
|
+
scope: this,
|
|
774
|
+
callSite: (f, a) => f(...a)
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
// packages/core/echo/echo-pipeline/src/space/space.ts
|
|
780
|
+
var __decorate3 = function(decorators, target, key, desc) {
|
|
781
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
782
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
783
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
784
|
+
else
|
|
785
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
786
|
+
if (d = decorators[i])
|
|
787
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
788
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
789
|
+
};
|
|
790
|
+
var Space = class Space2 {
|
|
791
|
+
constructor({ spaceKey, protocol, genesisFeed, feedProvider }) {
|
|
792
|
+
this.onCredentialProcessed = new import_util2.Callback();
|
|
793
|
+
this.stateUpdate = new import_async5.Event();
|
|
794
|
+
this._isOpen = false;
|
|
795
|
+
(0, import_node_assert6.default)(spaceKey && feedProvider);
|
|
796
|
+
this._key = spaceKey;
|
|
797
|
+
this._genesisFeedKey = genesisFeed.key;
|
|
798
|
+
this._feedProvider = feedProvider;
|
|
799
|
+
this._controlPipeline = new ControlPipeline({
|
|
800
|
+
spaceKey,
|
|
801
|
+
genesisFeed,
|
|
802
|
+
feedProvider
|
|
803
|
+
});
|
|
804
|
+
this._controlPipeline.onFeedAdmitted.set(async (info) => {
|
|
805
|
+
if (info.assertion.designation === import_credentials3.AdmittedFeed.Designation.DATA) {
|
|
806
|
+
if (this._dataPipeline) {
|
|
807
|
+
await this._dataPipeline.addFeed(await feedProvider(info.key));
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
if (!info.key.equals(genesisFeed.key)) {
|
|
811
|
+
this.protocol.addFeed(await feedProvider(info.key));
|
|
812
|
+
}
|
|
813
|
+
});
|
|
814
|
+
this._controlPipeline.onCredentialProcessed.set(async (credential) => {
|
|
815
|
+
await this.onCredentialProcessed.callIfSet(credential);
|
|
816
|
+
(0, import_log6.log)("onCredentialProcessed", {
|
|
817
|
+
credential
|
|
818
|
+
}, {
|
|
819
|
+
file: "space.ts",
|
|
820
|
+
line: 74,
|
|
821
|
+
scope: this,
|
|
822
|
+
callSite: (f, a) => f(...a)
|
|
823
|
+
});
|
|
824
|
+
this.stateUpdate.emit();
|
|
825
|
+
});
|
|
826
|
+
this.protocol = protocol;
|
|
827
|
+
this.protocol.addFeed(genesisFeed);
|
|
828
|
+
}
|
|
829
|
+
get key() {
|
|
830
|
+
return this._key;
|
|
831
|
+
}
|
|
832
|
+
get isOpen() {
|
|
833
|
+
return this._isOpen;
|
|
834
|
+
}
|
|
835
|
+
get genesisFeedKey() {
|
|
836
|
+
return this._genesisFeedKey;
|
|
837
|
+
}
|
|
838
|
+
get controlFeedKey() {
|
|
839
|
+
var _a;
|
|
840
|
+
return (_a = this._controlFeed) == null ? void 0 : _a.key;
|
|
841
|
+
}
|
|
842
|
+
get dataFeedKey() {
|
|
843
|
+
var _a;
|
|
844
|
+
return (_a = this._dataFeed) == null ? void 0 : _a.key;
|
|
845
|
+
}
|
|
846
|
+
get spaceState() {
|
|
847
|
+
return this._controlPipeline.spaceState;
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* @test-only
|
|
851
|
+
*/
|
|
852
|
+
get controlPipeline() {
|
|
853
|
+
return this._controlPipeline.pipeline;
|
|
854
|
+
}
|
|
855
|
+
setControlFeed(feed) {
|
|
856
|
+
(0, import_node_assert6.default)(!this._controlFeed, "Control feed already set.");
|
|
857
|
+
this._controlFeed = feed;
|
|
858
|
+
this._controlPipeline.setWriteFeed(feed);
|
|
859
|
+
return this;
|
|
860
|
+
}
|
|
861
|
+
setDataFeed(feed) {
|
|
862
|
+
var _a;
|
|
863
|
+
(0, import_node_assert6.default)(!this._dataFeed, "Data feed already set.");
|
|
864
|
+
this._dataFeed = feed;
|
|
865
|
+
(_a = this._dataPipeline) == null ? void 0 : _a.setWriteFeed(feed);
|
|
866
|
+
return this;
|
|
867
|
+
}
|
|
868
|
+
/**
|
|
869
|
+
* Use for diagnostics.
|
|
870
|
+
*/
|
|
871
|
+
getControlFeeds() {
|
|
872
|
+
return Array.from(this._controlPipeline.spaceState.feeds.values());
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* Use for diagnostics.
|
|
876
|
+
*/
|
|
877
|
+
// getDataFeeds(): FeedInfo[] {
|
|
878
|
+
// return this._dataPipeline?.getFeeds();
|
|
879
|
+
// }
|
|
880
|
+
async open() {
|
|
881
|
+
(0, import_log6.log)("opening...", {}, {
|
|
882
|
+
file: "space.ts",
|
|
883
|
+
line: 145,
|
|
884
|
+
scope: this,
|
|
885
|
+
callSite: (f, a) => f(...a)
|
|
886
|
+
});
|
|
887
|
+
if (this._isOpen) {
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
await this._controlPipeline.start();
|
|
891
|
+
await this.protocol.start();
|
|
892
|
+
this._isOpen = true;
|
|
893
|
+
(0, import_log6.log)("opened", {}, {
|
|
894
|
+
file: "space.ts",
|
|
895
|
+
line: 155,
|
|
896
|
+
scope: this,
|
|
897
|
+
callSite: (f, a) => f(...a)
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
async close() {
|
|
901
|
+
var _a;
|
|
902
|
+
(0, import_log6.log)("closing...", {
|
|
903
|
+
key: this._key
|
|
904
|
+
}, {
|
|
905
|
+
file: "space.ts",
|
|
906
|
+
line: 160,
|
|
907
|
+
scope: this,
|
|
908
|
+
callSite: (f, a) => f(...a)
|
|
909
|
+
});
|
|
910
|
+
if (!this._isOpen) {
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
await this.protocol.stop();
|
|
914
|
+
await ((_a = this._dataPipelineController) == null ? void 0 : _a.close());
|
|
915
|
+
await this._controlPipeline.stop();
|
|
916
|
+
this._isOpen = false;
|
|
917
|
+
(0, import_log6.log)("closed", {}, {
|
|
918
|
+
file: "space.ts",
|
|
919
|
+
line: 171,
|
|
920
|
+
scope: this,
|
|
921
|
+
callSite: (f, a) => f(...a)
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
async initDataPipeline(controller) {
|
|
925
|
+
(0, import_node_assert6.default)(this._isOpen, "Space must be open to initialize data pipeline.");
|
|
926
|
+
(0, import_node_assert6.default)(!this._dataPipelineController, "Data pipeline already initialized.");
|
|
927
|
+
(0, import_node_assert6.default)(!this._dataPipeline, "Data pipeline already initialized.");
|
|
928
|
+
this._dataPipelineController = controller;
|
|
929
|
+
await this._dataPipelineController.open({
|
|
930
|
+
openPipeline: async (start) => {
|
|
931
|
+
(0, import_node_assert6.default)(!this._dataPipeline, "Data pipeline already initialized.");
|
|
932
|
+
this._dataPipeline = new Pipeline(start);
|
|
933
|
+
if (this._dataFeed) {
|
|
934
|
+
this._dataPipeline.setWriteFeed(this._dataFeed);
|
|
935
|
+
}
|
|
936
|
+
for (const feed of this._controlPipeline.spaceState.feeds.values()) {
|
|
937
|
+
if (feed.assertion.designation === import_credentials3.AdmittedFeed.Designation.DATA) {
|
|
938
|
+
await this._dataPipeline.addFeed(await this._feedProvider(feed.key));
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
await this._dataPipeline.start();
|
|
942
|
+
return this._dataPipeline;
|
|
943
|
+
}
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
};
|
|
947
|
+
__decorate3([
|
|
948
|
+
import_log6.logInfo
|
|
949
|
+
], Space.prototype, "key", null);
|
|
950
|
+
__decorate3([
|
|
951
|
+
import_async5.synchronized
|
|
952
|
+
], Space.prototype, "open", null);
|
|
953
|
+
__decorate3([
|
|
954
|
+
import_async5.synchronized
|
|
955
|
+
], Space.prototype, "close", null);
|
|
956
|
+
Space = __decorate3([
|
|
957
|
+
(0, import_async5.trackLeaks)("open", "close")
|
|
958
|
+
], Space);
|
|
959
|
+
|
|
960
|
+
// packages/core/echo/echo-pipeline/src/space/space-manager.ts
|
|
961
|
+
var import_async6 = require("@dxos/async");
|
|
962
|
+
var import_debug3 = require("@dxos/debug");
|
|
963
|
+
var import_keys4 = require("@dxos/keys");
|
|
964
|
+
var import_log8 = require("@dxos/log");
|
|
965
|
+
var import_util4 = require("@dxos/util");
|
|
966
|
+
|
|
967
|
+
// packages/core/echo/echo-pipeline/src/space/space-protocol.ts
|
|
968
|
+
var import_crypto2 = require("@dxos/crypto");
|
|
969
|
+
var import_keys3 = require("@dxos/keys");
|
|
970
|
+
var import_log7 = require("@dxos/log");
|
|
971
|
+
var import_network_manager = require("@dxos/network-manager");
|
|
972
|
+
var import_teleport2 = require("@dxos/teleport");
|
|
973
|
+
var import_teleport_extension_replicator = require("@dxos/teleport-extension-replicator");
|
|
974
|
+
var import_util3 = require("@dxos/util");
|
|
975
|
+
var __decorate4 = function(decorators, target, key, desc) {
|
|
976
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
977
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
978
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
979
|
+
else
|
|
980
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
981
|
+
if (d = decorators[i])
|
|
982
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
983
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
984
|
+
};
|
|
985
|
+
var MOCK_AUTH_PROVIDER = async (nonce) => Buffer.from("mock");
|
|
986
|
+
var MOCK_AUTH_VERIFIER = async (nonce, credential) => true;
|
|
987
|
+
var SpaceProtocol = class {
|
|
988
|
+
constructor({ topic, swarmIdentity, networkManager, onSessionAuth }) {
|
|
989
|
+
this._feeds = /* @__PURE__ */ new Set();
|
|
990
|
+
this._sessions = new import_util3.ComplexMap(import_keys3.PublicKey.hash);
|
|
991
|
+
this._networkManager = networkManager;
|
|
992
|
+
this._swarmIdentity = swarmIdentity;
|
|
993
|
+
this._onSessionAuth = onSessionAuth;
|
|
994
|
+
this._topic = import_keys3.PublicKey.from((0, import_crypto2.discoveryKey)((0, import_crypto2.sha256)(topic.toHex())));
|
|
995
|
+
}
|
|
996
|
+
get sessions() {
|
|
997
|
+
return this._sessions;
|
|
998
|
+
}
|
|
999
|
+
get feeds() {
|
|
1000
|
+
return this._feeds;
|
|
1001
|
+
}
|
|
1002
|
+
get _ownPeerKey() {
|
|
1003
|
+
return this._swarmIdentity.peerKey;
|
|
1004
|
+
}
|
|
1005
|
+
// TODO(burdon): Create abstraction for Space (e.g., add keys and have provider).
|
|
1006
|
+
addFeed(feed) {
|
|
1007
|
+
(0, import_log7.log)("addFeed", {
|
|
1008
|
+
key: feed.key
|
|
1009
|
+
}, {
|
|
1010
|
+
file: "space-protocol.ts",
|
|
1011
|
+
line: 84,
|
|
1012
|
+
scope: this,
|
|
1013
|
+
callSite: (f, a) => f(...a)
|
|
1014
|
+
});
|
|
1015
|
+
this._feeds.add(feed);
|
|
1016
|
+
for (const session of this._sessions.values()) {
|
|
1017
|
+
session.replicator.addFeed(feed);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
async start() {
|
|
1021
|
+
if (this._connection) {
|
|
1022
|
+
return;
|
|
1023
|
+
}
|
|
1024
|
+
const credentials = await this._swarmIdentity.credentialProvider(Buffer.from(""));
|
|
1025
|
+
const topologyConfig = {
|
|
1026
|
+
originateConnections: 4,
|
|
1027
|
+
maxPeers: 10,
|
|
1028
|
+
sampleSize: 20
|
|
1029
|
+
};
|
|
1030
|
+
(0, import_log7.log)("starting...", {}, {
|
|
1031
|
+
file: "space-protocol.ts",
|
|
1032
|
+
line: 107,
|
|
1033
|
+
scope: this,
|
|
1034
|
+
callSite: (f, a) => f(...a)
|
|
1035
|
+
});
|
|
1036
|
+
this._connection = await this._networkManager.joinSwarm({
|
|
1037
|
+
protocolProvider: this._createProtocolProvider(credentials),
|
|
1038
|
+
peerId: this._swarmIdentity.peerKey,
|
|
1039
|
+
topic: this._topic,
|
|
1040
|
+
topology: new import_network_manager.MMSTTopology(topologyConfig),
|
|
1041
|
+
label: `Protocol swarm: ${this._topic}`
|
|
1042
|
+
});
|
|
1043
|
+
(0, import_log7.log)("started", {}, {
|
|
1044
|
+
file: "space-protocol.ts",
|
|
1045
|
+
line: 116,
|
|
1046
|
+
scope: this,
|
|
1047
|
+
callSite: (f, a) => f(...a)
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
async stop() {
|
|
1051
|
+
if (this._connection) {
|
|
1052
|
+
(0, import_log7.log)("stopping...", {}, {
|
|
1053
|
+
file: "space-protocol.ts",
|
|
1054
|
+
line: 121,
|
|
1055
|
+
scope: this,
|
|
1056
|
+
callSite: (f, a) => f(...a)
|
|
1057
|
+
});
|
|
1058
|
+
await this._connection.close();
|
|
1059
|
+
(0, import_log7.log)("stopped", {}, {
|
|
1060
|
+
file: "space-protocol.ts",
|
|
1061
|
+
line: 123,
|
|
1062
|
+
scope: this,
|
|
1063
|
+
callSite: (f, a) => f(...a)
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
_createProtocolProvider(credentials) {
|
|
1068
|
+
return (wireParams) => {
|
|
1069
|
+
const session = new SpaceProtocolSession({
|
|
1070
|
+
wireParams,
|
|
1071
|
+
swarmIdentity: this._swarmIdentity,
|
|
1072
|
+
onSessionAuth: this._onSessionAuth
|
|
1073
|
+
});
|
|
1074
|
+
this._sessions.set(wireParams.remotePeerId, session);
|
|
1075
|
+
for (const feed of this._feeds) {
|
|
1076
|
+
session.replicator.addFeed(feed);
|
|
1077
|
+
}
|
|
1078
|
+
return session;
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
};
|
|
1082
|
+
__decorate4([
|
|
1083
|
+
import_log7.logInfo
|
|
1084
|
+
], SpaceProtocol.prototype, "_topic", void 0);
|
|
1085
|
+
__decorate4([
|
|
1086
|
+
import_log7.logInfo
|
|
1087
|
+
], SpaceProtocol.prototype, "_ownPeerKey", null);
|
|
1088
|
+
var AuthStatus;
|
|
1089
|
+
(function(AuthStatus2) {
|
|
1090
|
+
AuthStatus2["INITIAL"] = "INITIAL";
|
|
1091
|
+
AuthStatus2["SUCCESS"] = "SUCCESS";
|
|
1092
|
+
AuthStatus2["FAILURE"] = "FAILURE";
|
|
1093
|
+
})(AuthStatus || (AuthStatus = {}));
|
|
1094
|
+
var SpaceProtocolSession = class {
|
|
1095
|
+
// TODO(dmaretskyi): Allow to pass in extra extensions.
|
|
1096
|
+
constructor({ wireParams, swarmIdentity, onSessionAuth }) {
|
|
1097
|
+
// TODO(dmaretskyi): Start with upload=false when switching it on the fly works.
|
|
1098
|
+
this.replicator = new import_teleport_extension_replicator.ReplicatorExtension().setOptions({
|
|
1099
|
+
upload: true
|
|
1100
|
+
});
|
|
1101
|
+
this._authStatus = AuthStatus.INITIAL;
|
|
1102
|
+
this._wireParams = wireParams;
|
|
1103
|
+
this._swarmIdentity = swarmIdentity;
|
|
1104
|
+
this._onSessionAuth = onSessionAuth;
|
|
1105
|
+
this._teleport = new import_teleport2.Teleport(wireParams);
|
|
1106
|
+
}
|
|
1107
|
+
get authStatus() {
|
|
1108
|
+
return this._authStatus;
|
|
1109
|
+
}
|
|
1110
|
+
get stream() {
|
|
1111
|
+
return this._teleport.stream;
|
|
1112
|
+
}
|
|
1113
|
+
async initialize() {
|
|
1114
|
+
await this._teleport.open();
|
|
1115
|
+
this._teleport.addExtension("dxos.mesh.teleport.auth", new AuthExtension({
|
|
1116
|
+
provider: this._swarmIdentity.credentialProvider,
|
|
1117
|
+
verifier: this._swarmIdentity.credentialAuthenticator,
|
|
1118
|
+
onAuthSuccess: () => {
|
|
1119
|
+
var _a;
|
|
1120
|
+
this._authStatus = AuthStatus.SUCCESS;
|
|
1121
|
+
(0, import_log7.log)("Peer authenticated", {}, {
|
|
1122
|
+
file: "space-protocol.ts",
|
|
1123
|
+
line: 206,
|
|
1124
|
+
scope: this,
|
|
1125
|
+
callSite: (f, a) => f(...a)
|
|
1126
|
+
});
|
|
1127
|
+
(_a = this._onSessionAuth) == null ? void 0 : _a.call(this, this._teleport);
|
|
1128
|
+
},
|
|
1129
|
+
onAuthFailure: () => {
|
|
1130
|
+
import_log7.log.warn("Auth failed", {}, {
|
|
1131
|
+
file: "space-protocol.ts",
|
|
1132
|
+
line: 211,
|
|
1133
|
+
scope: this,
|
|
1134
|
+
callSite: (f, a) => f(...a)
|
|
1135
|
+
});
|
|
1136
|
+
this._authStatus = AuthStatus.FAILURE;
|
|
1137
|
+
}
|
|
1138
|
+
}));
|
|
1139
|
+
this._teleport.addExtension("dxos.mesh.teleport.replicator", this.replicator);
|
|
1140
|
+
}
|
|
1141
|
+
async destroy() {
|
|
1142
|
+
await this._teleport.close();
|
|
1143
|
+
}
|
|
1144
|
+
};
|
|
1145
|
+
__decorate4([
|
|
1146
|
+
import_log7.logInfo
|
|
1147
|
+
], SpaceProtocolSession.prototype, "_wireParams", void 0);
|
|
1148
|
+
__decorate4([
|
|
1149
|
+
import_log7.logInfo
|
|
1150
|
+
], SpaceProtocolSession.prototype, "authStatus", null);
|
|
1151
|
+
|
|
1152
|
+
// packages/core/echo/echo-pipeline/src/space/space-manager.ts
|
|
1153
|
+
var __decorate5 = function(decorators, target, key, desc) {
|
|
1154
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1155
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
1156
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
1157
|
+
else
|
|
1158
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
1159
|
+
if (d = decorators[i])
|
|
1160
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1161
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1162
|
+
};
|
|
1163
|
+
var SpaceManager = class SpaceManager2 {
|
|
1164
|
+
constructor({ feedStore, networkManager }) {
|
|
1165
|
+
this._spaces = new import_util4.ComplexMap(import_keys4.PublicKey.hash);
|
|
1166
|
+
this._feedStore = feedStore;
|
|
1167
|
+
this._networkManager = networkManager;
|
|
1168
|
+
}
|
|
1169
|
+
// TODO(burdon): Remove.
|
|
1170
|
+
get spaces() {
|
|
1171
|
+
return this._spaces;
|
|
1172
|
+
}
|
|
1173
|
+
async open() {
|
|
1174
|
+
}
|
|
1175
|
+
async close() {
|
|
1176
|
+
await Promise.all([
|
|
1177
|
+
...this._spaces.values()
|
|
1178
|
+
].map((space) => space.close()));
|
|
1179
|
+
}
|
|
1180
|
+
async constructSpace({ metadata, swarmIdentity, onNetworkConnection }) {
|
|
1181
|
+
var _a;
|
|
1182
|
+
(0, import_log8.log)("constructing space...", {
|
|
1183
|
+
spaceKey: metadata.genesisFeedKey
|
|
1184
|
+
}, {
|
|
1185
|
+
file: "space-manager.ts",
|
|
1186
|
+
line: 70,
|
|
1187
|
+
scope: this,
|
|
1188
|
+
callSite: (f, a) => f(...a)
|
|
1189
|
+
});
|
|
1190
|
+
const genesisFeed = await this._feedStore.openFeed((_a = metadata.genesisFeedKey) != null ? _a : (0, import_debug3.failUndefined)());
|
|
1191
|
+
const spaceKey = metadata.key;
|
|
1192
|
+
const protocol = new SpaceProtocol({
|
|
1193
|
+
topic: spaceKey,
|
|
1194
|
+
swarmIdentity,
|
|
1195
|
+
networkManager: this._networkManager,
|
|
1196
|
+
onSessionAuth: onNetworkConnection
|
|
1197
|
+
});
|
|
1198
|
+
const space = new Space({
|
|
1199
|
+
spaceKey,
|
|
1200
|
+
protocol,
|
|
1201
|
+
genesisFeed,
|
|
1202
|
+
feedProvider: (feedKey) => this._feedStore.openFeed(feedKey)
|
|
1203
|
+
});
|
|
1204
|
+
this._spaces.set(space.key, space);
|
|
1205
|
+
return space;
|
|
1206
|
+
}
|
|
1207
|
+
};
|
|
1208
|
+
__decorate5([
|
|
1209
|
+
import_async6.synchronized
|
|
1210
|
+
], SpaceManager.prototype, "open", null);
|
|
1211
|
+
__decorate5([
|
|
1212
|
+
import_async6.synchronized
|
|
1213
|
+
], SpaceManager.prototype, "close", null);
|
|
1214
|
+
SpaceManager = __decorate5([
|
|
1215
|
+
(0, import_async6.trackLeaks)("open", "close")
|
|
1216
|
+
], SpaceManager);
|
|
1217
|
+
|
|
1218
|
+
// packages/core/echo/echo-pipeline/src/space/genesis.ts
|
|
1219
|
+
var import_credentials4 = require("@dxos/credentials");
|
|
1220
|
+
var import_debug4 = require("@dxos/debug");
|
|
1221
|
+
var import_credentials5 = require("@dxos/protocols/proto/dxos/halo/credentials");
|
|
1222
|
+
var spaceGenesis = async (keyring, signingContext, space) => {
|
|
1223
|
+
var _a, _b;
|
|
1224
|
+
const generator = new import_credentials4.CredentialGenerator(keyring, signingContext.identityKey, signingContext.deviceKey);
|
|
1225
|
+
const credentials = [
|
|
1226
|
+
...await generator.createSpaceGenesis(space.key, (_a = space.controlFeedKey) != null ? _a : (0, import_debug4.failUndefined)(), signingContext.profile),
|
|
1227
|
+
await generator.createFeedAdmission(space.key, (_b = space.dataFeedKey) != null ? _b : (0, import_debug4.failUndefined)(), import_credentials5.AdmittedFeed.Designation.DATA)
|
|
1228
|
+
];
|
|
1229
|
+
for (const credential of credentials) {
|
|
1230
|
+
await space.controlPipeline.writer.write({
|
|
1231
|
+
credential: {
|
|
1232
|
+
credential
|
|
1233
|
+
}
|
|
1234
|
+
});
|
|
1235
|
+
}
|
|
1236
|
+
return credentials;
|
|
1237
|
+
};
|
|
1238
|
+
|
|
1239
|
+
// packages/core/echo/echo-pipeline/src/space/data-pipeline-controller.ts
|
|
1240
|
+
var import_node_assert9 = __toESM(require("node:assert"));
|
|
1241
|
+
var import_async8 = require("@dxos/async");
|
|
1242
|
+
var import_context2 = require("@dxos/context");
|
|
1243
|
+
var import_debug6 = require("@dxos/debug");
|
|
1244
|
+
var import_echo_db3 = require("@dxos/echo-db");
|
|
1245
|
+
var import_log11 = require("@dxos/log");
|
|
1246
|
+
var import_timeframe3 = require("@dxos/timeframe");
|
|
1247
|
+
|
|
1248
|
+
// packages/core/echo/echo-pipeline/src/dbhost/data-service-host.ts
|
|
1249
|
+
var import_node_assert7 = __toESM(require("node:assert"));
|
|
1250
|
+
var import_codec_protobuf = require("@dxos/codec-protobuf");
|
|
1251
|
+
var import_echo_db = require("@dxos/echo-db");
|
|
1252
|
+
var import_log9 = require("@dxos/log");
|
|
1253
|
+
var import_util5 = require("@dxos/util");
|
|
1254
|
+
var DataServiceHost = class {
|
|
1255
|
+
constructor(_itemManager, _itemDemuxer, _writeStream) {
|
|
1256
|
+
this._itemManager = _itemManager;
|
|
1257
|
+
this._itemDemuxer = _itemDemuxer;
|
|
1258
|
+
this._writeStream = _writeStream;
|
|
1259
|
+
this._clientTagMap = new import_util5.ComplexMap(([feedKey, seq]) => `${feedKey.toHex()}:${seq}`);
|
|
1260
|
+
}
|
|
1261
|
+
/**
|
|
1262
|
+
* Real-time subscription to data objects in a space.
|
|
1263
|
+
*/
|
|
1264
|
+
subscribe() {
|
|
1265
|
+
return new import_codec_protobuf.Stream(({ next, ctx }) => {
|
|
1266
|
+
const objects = Array.from(this._itemManager.entities.values()).map((entity) => entity.createSnapshot());
|
|
1267
|
+
next({
|
|
1268
|
+
batch: {
|
|
1269
|
+
objects
|
|
1270
|
+
}
|
|
1271
|
+
});
|
|
1272
|
+
this._itemDemuxer.mutation.on(ctx, (mutation) => {
|
|
1273
|
+
var _a;
|
|
1274
|
+
(0, import_log9.log)("Object update", {
|
|
1275
|
+
mutation
|
|
1276
|
+
}, {
|
|
1277
|
+
file: "data-service-host.ts",
|
|
1278
|
+
line: 49,
|
|
1279
|
+
scope: this,
|
|
1280
|
+
callSite: (f, a) => f(...a)
|
|
1281
|
+
});
|
|
1282
|
+
const clientTag = this._clientTagMap.get([
|
|
1283
|
+
mutation.meta.feedKey,
|
|
1284
|
+
mutation.meta.seq
|
|
1285
|
+
]);
|
|
1286
|
+
const batch = {
|
|
1287
|
+
objects: [
|
|
1288
|
+
{
|
|
1289
|
+
...mutation.data,
|
|
1290
|
+
mutations: (_a = mutation.data.mutations) == null ? void 0 : _a.map((m, mutationIdx) => ({
|
|
1291
|
+
...m,
|
|
1292
|
+
meta: mutation.meta
|
|
1293
|
+
})),
|
|
1294
|
+
meta: mutation.meta
|
|
1295
|
+
}
|
|
1296
|
+
]
|
|
1297
|
+
};
|
|
1298
|
+
if (clientTag) {
|
|
1299
|
+
(0, import_echo_db.tagMutationsInBatch)(batch, clientTag);
|
|
1300
|
+
}
|
|
1301
|
+
next({
|
|
1302
|
+
clientTag,
|
|
1303
|
+
feedKey: mutation.meta.feedKey,
|
|
1304
|
+
seq: mutation.meta.seq,
|
|
1305
|
+
batch
|
|
1306
|
+
});
|
|
1307
|
+
});
|
|
1308
|
+
});
|
|
1309
|
+
}
|
|
1310
|
+
async write(request) {
|
|
1311
|
+
var _a, _b;
|
|
1312
|
+
(0, import_node_assert7.default)(this._writeStream, "Cannot write mutations in readonly mode");
|
|
1313
|
+
(0, import_node_assert7.default)(((_a = request.batch.objects) == null ? void 0 : _a.length) === 1, "Only single object mutations are supported");
|
|
1314
|
+
const receipt = await this._writeStream.write({
|
|
1315
|
+
object: {
|
|
1316
|
+
...request.batch.objects[0],
|
|
1317
|
+
mutations: (_b = request.batch.objects[0].mutations) == null ? void 0 : _b.map((m) => ({
|
|
1318
|
+
...m,
|
|
1319
|
+
meta: void 0
|
|
1320
|
+
})),
|
|
1321
|
+
meta: void 0
|
|
1322
|
+
}
|
|
1323
|
+
});
|
|
1324
|
+
if (request.clientTag) {
|
|
1325
|
+
this._clientTagMap.set([
|
|
1326
|
+
receipt.feedKey,
|
|
1327
|
+
receipt.seq
|
|
1328
|
+
], request.clientTag);
|
|
1329
|
+
}
|
|
1330
|
+
return receipt;
|
|
1331
|
+
}
|
|
1332
|
+
};
|
|
1333
|
+
|
|
1334
|
+
// packages/core/echo/echo-pipeline/src/dbhost/database-backend.ts
|
|
1335
|
+
var import_echo_db2 = require("@dxos/echo-db");
|
|
1336
|
+
var DatabaseBackendHost = class {
|
|
1337
|
+
constructor(_outboundStream, _snapshot, _options = {}) {
|
|
1338
|
+
this._outboundStream = _outboundStream;
|
|
1339
|
+
this._snapshot = _snapshot;
|
|
1340
|
+
this._options = _options;
|
|
1341
|
+
}
|
|
1342
|
+
get isReadOnly() {
|
|
1343
|
+
return !!this._outboundStream;
|
|
1344
|
+
}
|
|
1345
|
+
get echoProcessor() {
|
|
1346
|
+
return this._echoProcessor;
|
|
1347
|
+
}
|
|
1348
|
+
async open(itemManager, modelFactory) {
|
|
1349
|
+
this._itemManager = itemManager;
|
|
1350
|
+
this._itemManager._debugLabel = "host";
|
|
1351
|
+
this._itemDemuxer = new import_echo_db2.ItemDemuxer(itemManager, modelFactory, this._options);
|
|
1352
|
+
this._echoProcessor = this._itemDemuxer.open();
|
|
1353
|
+
if (this._snapshot) {
|
|
1354
|
+
await this._itemDemuxer.restoreFromSnapshot(this._snapshot);
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
async close() {
|
|
1358
|
+
}
|
|
1359
|
+
getWriteStream() {
|
|
1360
|
+
return this._outboundStream;
|
|
1361
|
+
}
|
|
1362
|
+
createSnapshot() {
|
|
1363
|
+
return this._itemDemuxer.createSnapshot();
|
|
1364
|
+
}
|
|
1365
|
+
createDataServiceHost() {
|
|
1366
|
+
var _a;
|
|
1367
|
+
return new DataServiceHost(this._itemManager, this._itemDemuxer, (_a = this._outboundStream) != null ? _a : void 0);
|
|
1368
|
+
}
|
|
1369
|
+
};
|
|
1370
|
+
|
|
1371
|
+
// packages/core/echo/echo-pipeline/src/dbhost/snapshot-manager.ts
|
|
1372
|
+
var import_async7 = require("@dxos/async");
|
|
1373
|
+
var import_protocols4 = require("@dxos/protocols");
|
|
1374
|
+
var import_teleport_extension_object_sync = require("@dxos/teleport-extension-object-sync");
|
|
1375
|
+
var __decorate6 = function(decorators, target, key, desc) {
|
|
1376
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1377
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
1378
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
1379
|
+
else
|
|
1380
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
1381
|
+
if (d = decorators[i])
|
|
1382
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1383
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1384
|
+
};
|
|
1385
|
+
var SnapshotManager = class SnapshotManager2 {
|
|
1386
|
+
// prettier-ignore
|
|
1387
|
+
constructor(_snapshotStore) {
|
|
1388
|
+
this._snapshotStore = _snapshotStore;
|
|
1389
|
+
this._objectSync = new import_teleport_extension_object_sync.ObjectSync({
|
|
1390
|
+
getObject: async (id) => {
|
|
1391
|
+
const snapshot = await this._snapshotStore.loadSnapshot(id);
|
|
1392
|
+
if (!snapshot) {
|
|
1393
|
+
return void 0;
|
|
1394
|
+
}
|
|
1395
|
+
return {
|
|
1396
|
+
id,
|
|
1397
|
+
payload: import_protocols4.schema.getCodecForType("dxos.echo.snapshot.SpaceSnapshot").encodeAsAny(snapshot)
|
|
1398
|
+
};
|
|
1399
|
+
},
|
|
1400
|
+
setObject: async (data) => {
|
|
1401
|
+
const snapshot = import_protocols4.schema.getCodecForType("dxos.echo.snapshot.SpaceSnapshot").decode(data.payload);
|
|
1402
|
+
await this._snapshotStore.saveSnapshot(snapshot);
|
|
1403
|
+
}
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
1406
|
+
get objectSync() {
|
|
1407
|
+
return this._objectSync;
|
|
1408
|
+
}
|
|
1409
|
+
async open() {
|
|
1410
|
+
await this._objectSync.open();
|
|
1411
|
+
}
|
|
1412
|
+
async close() {
|
|
1413
|
+
await this._objectSync.close();
|
|
1414
|
+
}
|
|
1415
|
+
async load(id) {
|
|
1416
|
+
const local = await this._snapshotStore.loadSnapshot(id);
|
|
1417
|
+
if (local) {
|
|
1418
|
+
return local;
|
|
1419
|
+
}
|
|
1420
|
+
const remote = await this._objectSync.download(id);
|
|
1421
|
+
return import_protocols4.schema.getCodecForType("dxos.echo.snapshot.SpaceSnapshot").decode(remote.payload);
|
|
1422
|
+
}
|
|
1423
|
+
async store(snapshot) {
|
|
1424
|
+
const id = await this._snapshotStore.saveSnapshot(snapshot);
|
|
1425
|
+
return id;
|
|
1426
|
+
}
|
|
1427
|
+
};
|
|
1428
|
+
SnapshotManager = __decorate6([
|
|
1429
|
+
(0, import_async7.trackLeaks)("open", "close")
|
|
1430
|
+
], SnapshotManager);
|
|
1431
|
+
|
|
1432
|
+
// packages/core/echo/echo-pipeline/src/dbhost/snapshot-store.ts
|
|
1433
|
+
var import_crypto3 = require("@dxos/crypto");
|
|
1434
|
+
var import_protocols5 = require("@dxos/protocols");
|
|
1435
|
+
var SnapshotStore = class {
|
|
1436
|
+
// prettier-ignore
|
|
1437
|
+
constructor(_directory) {
|
|
1438
|
+
this._directory = _directory;
|
|
1439
|
+
}
|
|
1440
|
+
async saveSnapshot(snapshot) {
|
|
1441
|
+
const encoded = import_protocols5.schema.getCodecForType("dxos.echo.snapshot.SpaceSnapshot").encode(snapshot);
|
|
1442
|
+
const key = await import_crypto3.subtleCrypto.digest("SHA-256", encoded);
|
|
1443
|
+
const keyString = Buffer.from(key).toString("hex");
|
|
1444
|
+
const file = await this._directory.getOrCreateFile(keyString);
|
|
1445
|
+
try {
|
|
1446
|
+
await file.write(0, Buffer.from(encoded));
|
|
1447
|
+
} finally {
|
|
1448
|
+
await file.close();
|
|
1449
|
+
}
|
|
1450
|
+
return keyString;
|
|
1451
|
+
}
|
|
1452
|
+
async loadSnapshot(key) {
|
|
1453
|
+
const file = await this._directory.getOrCreateFile(key);
|
|
1454
|
+
try {
|
|
1455
|
+
const { size } = await file.stat();
|
|
1456
|
+
if (size === 0) {
|
|
1457
|
+
return void 0;
|
|
1458
|
+
}
|
|
1459
|
+
const buffer = await file.read(0, size);
|
|
1460
|
+
return import_protocols5.schema.getCodecForType("dxos.echo.snapshot.SpaceSnapshot").decode(buffer);
|
|
1461
|
+
} finally {
|
|
1462
|
+
await file.close();
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
};
|
|
1466
|
+
|
|
1467
|
+
// packages/core/echo/echo-pipeline/src/dbhost/data-service.ts
|
|
1468
|
+
var import_node_assert8 = __toESM(require("node:assert"));
|
|
1469
|
+
var import_debug5 = require("@dxos/debug");
|
|
1470
|
+
var import_keys5 = require("@dxos/keys");
|
|
1471
|
+
var import_log10 = require("@dxos/log");
|
|
1472
|
+
var import_util6 = require("@dxos/util");
|
|
1473
|
+
var DataServiceSubscriptions = class {
|
|
1474
|
+
constructor() {
|
|
1475
|
+
this._spaces = new import_util6.ComplexMap(import_keys5.PublicKey.hash);
|
|
1476
|
+
}
|
|
1477
|
+
clear() {
|
|
1478
|
+
this._spaces.clear();
|
|
1479
|
+
}
|
|
1480
|
+
registerSpace(spaceKey, host) {
|
|
1481
|
+
(0, import_log10.log)("Registering space", {
|
|
1482
|
+
spaceKey
|
|
1483
|
+
}, {
|
|
1484
|
+
file: "data-service.ts",
|
|
1485
|
+
line: 31,
|
|
1486
|
+
scope: this,
|
|
1487
|
+
callSite: (f, a) => f(...a)
|
|
1488
|
+
});
|
|
1489
|
+
this._spaces.set(spaceKey, host);
|
|
1490
|
+
}
|
|
1491
|
+
unregisterSpace(spaceKey) {
|
|
1492
|
+
(0, import_log10.log)("Unregistering space", {
|
|
1493
|
+
spaceKey
|
|
1494
|
+
}, {
|
|
1495
|
+
file: "data-service.ts",
|
|
1496
|
+
line: 36,
|
|
1497
|
+
scope: this,
|
|
1498
|
+
callSite: (f, a) => f(...a)
|
|
1499
|
+
});
|
|
1500
|
+
this._spaces.delete(spaceKey);
|
|
1501
|
+
}
|
|
1502
|
+
getDataService(spaceKey) {
|
|
1503
|
+
return this._spaces.get(spaceKey);
|
|
1504
|
+
}
|
|
1505
|
+
};
|
|
1506
|
+
var DataServiceImpl = class {
|
|
1507
|
+
constructor(_subscriptions) {
|
|
1508
|
+
this._subscriptions = _subscriptions;
|
|
1509
|
+
}
|
|
1510
|
+
subscribe(request) {
|
|
1511
|
+
var _a;
|
|
1512
|
+
(0, import_node_assert8.default)(request.spaceKey);
|
|
1513
|
+
const host = (_a = this._subscriptions.getDataService(request.spaceKey)) != null ? _a : (0, import_debug5.raise)(new Error(`space not found: ${request.spaceKey}`));
|
|
1514
|
+
return host.subscribe();
|
|
1515
|
+
}
|
|
1516
|
+
write(request) {
|
|
1517
|
+
var _a;
|
|
1518
|
+
(0, import_node_assert8.default)(request.spaceKey);
|
|
1519
|
+
(0, import_node_assert8.default)(request.batch);
|
|
1520
|
+
const host = (_a = this._subscriptions.getDataService(request.spaceKey)) != null ? _a : (0, import_debug5.raise)(new Error(`space not found: ${request.spaceKey}`));
|
|
1521
|
+
return host.write(request);
|
|
1522
|
+
}
|
|
1523
|
+
};
|
|
1524
|
+
|
|
1525
|
+
// packages/core/echo/echo-pipeline/src/space/data-pipeline-controller.ts
|
|
1526
|
+
var __decorate7 = function(decorators, target, key, desc) {
|
|
1527
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1528
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
1529
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
1530
|
+
else
|
|
1531
|
+
for (var i = decorators.length - 1; i >= 0; i--)
|
|
1532
|
+
if (d = decorators[i])
|
|
1533
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1534
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1535
|
+
};
|
|
1536
|
+
var NoopDataPipelineController = class {
|
|
1537
|
+
async open(context) {
|
|
1538
|
+
}
|
|
1539
|
+
async close() {
|
|
1540
|
+
}
|
|
1541
|
+
};
|
|
1542
|
+
var MESSAGES_PER_SNAPSHOT = 10;
|
|
1543
|
+
var AUTOMATIC_SNAPSHOT_DEBOUNCE_INTERVAL = 5e3;
|
|
1544
|
+
var TIMEFRAME_SAVE_DEBOUNCE_INTERVAL = 500;
|
|
1545
|
+
var DataPipelineControllerImpl = class DataPipelineControllerImpl2 {
|
|
1546
|
+
constructor(_params) {
|
|
1547
|
+
this._params = _params;
|
|
1548
|
+
this._ctx = new import_context2.Context();
|
|
1549
|
+
this._lastAutomaticSnapshotTimeframe = new import_timeframe3.Timeframe();
|
|
1550
|
+
this.onTimeframeReached = new import_async8.Event();
|
|
1551
|
+
}
|
|
1552
|
+
get pipelineState() {
|
|
1553
|
+
var _a;
|
|
1554
|
+
return (_a = this._pipeline) == null ? void 0 : _a.state;
|
|
1555
|
+
}
|
|
1556
|
+
get snapshotTimeframe() {
|
|
1557
|
+
var _a;
|
|
1558
|
+
return (_a = this._snapshot) == null ? void 0 : _a.timeframe;
|
|
1559
|
+
}
|
|
1560
|
+
getStartTimeframe() {
|
|
1561
|
+
var _a;
|
|
1562
|
+
return snapshotTimeframeToStartingTimeframe((_a = this.snapshotTimeframe) != null ? _a : new import_timeframe3.Timeframe());
|
|
1563
|
+
}
|
|
1564
|
+
async open(spaceContext) {
|
|
1565
|
+
var _a, _b, _c, _d;
|
|
1566
|
+
this._spaceContext = spaceContext;
|
|
1567
|
+
if (this._params.snapshotId) {
|
|
1568
|
+
this._snapshot = await this._params.snapshotManager.load(this._params.snapshotId);
|
|
1569
|
+
this._lastAutomaticSnapshotTimeframe = (_b = (_a = this._snapshot) == null ? void 0 : _a.timeframe) != null ? _b : new import_timeframe3.Timeframe();
|
|
1570
|
+
}
|
|
1571
|
+
this._pipeline = await this._spaceContext.openPipeline(this.getStartTimeframe());
|
|
1572
|
+
const feedWriter = createMappedFeedWriter((data) => ({
|
|
1573
|
+
data
|
|
1574
|
+
}), (_c = this._pipeline.writer) != null ? _c : (0, import_debug6.failUndefined)());
|
|
1575
|
+
this.databaseBackend = new DatabaseBackendHost(feedWriter, (_d = this._snapshot) == null ? void 0 : _d.database, {
|
|
1576
|
+
snapshots: true
|
|
1577
|
+
// TODO(burdon): Config.
|
|
1578
|
+
});
|
|
1579
|
+
this._itemManager = new import_echo_db3.ItemManager(this._params.modelFactory);
|
|
1580
|
+
await this.databaseBackend.open(this._itemManager, this._params.modelFactory);
|
|
1581
|
+
(0, import_async8.scheduleTask)(this._ctx, async () => {
|
|
1582
|
+
await this._consumePipeline();
|
|
1583
|
+
});
|
|
1584
|
+
this._createPeriodicSnapshots();
|
|
1585
|
+
}
|
|
1586
|
+
_createPeriodicSnapshots() {
|
|
1587
|
+
this.onTimeframeReached.debounce(TIMEFRAME_SAVE_DEBOUNCE_INTERVAL).on(this._ctx, async () => {
|
|
1588
|
+
await this._saveLatestTimeframe();
|
|
1589
|
+
});
|
|
1590
|
+
this.onTimeframeReached.debounce(AUTOMATIC_SNAPSHOT_DEBOUNCE_INTERVAL).on(this._ctx, async () => {
|
|
1591
|
+
var _a, _b;
|
|
1592
|
+
const latestTimeframe = (_a = this._pipeline) == null ? void 0 : _a.state.timeframe;
|
|
1593
|
+
if (!latestTimeframe) {
|
|
1594
|
+
return;
|
|
1595
|
+
}
|
|
1596
|
+
if (latestTimeframe.totalMessages() - this._lastAutomaticSnapshotTimeframe.totalMessages() > MESSAGES_PER_SNAPSHOT) {
|
|
1597
|
+
const snapshot = await this._saveSnapshot();
|
|
1598
|
+
this._lastAutomaticSnapshotTimeframe = (_b = snapshot.timeframe) != null ? _b : (0, import_debug6.failUndefined)();
|
|
1599
|
+
(0, import_log11.log)("save", {
|
|
1600
|
+
snapshot
|
|
1601
|
+
}, {
|
|
1602
|
+
file: "data-pipeline-controller.ts",
|
|
1603
|
+
line: 151,
|
|
1604
|
+
scope: this,
|
|
1605
|
+
callSite: (f, a) => f(...a)
|
|
1606
|
+
});
|
|
1607
|
+
}
|
|
1608
|
+
});
|
|
1609
|
+
}
|
|
1610
|
+
async _saveSnapshot() {
|
|
1611
|
+
const snapshot = await this.createSnapshot();
|
|
1612
|
+
const snapshotKey = await this._params.snapshotManager.store(snapshot);
|
|
1613
|
+
await this._params.metadataStore.setSpaceSnapshot(this._params.spaceKey, snapshotKey);
|
|
1614
|
+
return snapshot;
|
|
1615
|
+
}
|
|
1616
|
+
async _saveLatestTimeframe() {
|
|
1617
|
+
var _a;
|
|
1618
|
+
const latestTimeframe = (_a = this._pipeline) == null ? void 0 : _a.state.timeframe;
|
|
1619
|
+
if (latestTimeframe) {
|
|
1620
|
+
await this._params.metadataStore.setSpaceLatestTimeframe(this._params.spaceKey, latestTimeframe);
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
async close() {
|
|
1624
|
+
var _a, _b, _c;
|
|
1625
|
+
try {
|
|
1626
|
+
await this._saveLatestTimeframe();
|
|
1627
|
+
await this._saveSnapshot();
|
|
1628
|
+
} catch (err) {
|
|
1629
|
+
import_log11.log.catch(err, {}, {
|
|
1630
|
+
file: "data-pipeline-controller.ts",
|
|
1631
|
+
line: 175,
|
|
1632
|
+
scope: this,
|
|
1633
|
+
callSite: (f, a) => f(...a)
|
|
1634
|
+
});
|
|
1635
|
+
}
|
|
1636
|
+
await this._ctx.dispose();
|
|
1637
|
+
await ((_a = this._pipeline) == null ? void 0 : _a.stop());
|
|
1638
|
+
await ((_b = this.databaseBackend) == null ? void 0 : _b.close());
|
|
1639
|
+
await ((_c = this._itemManager) == null ? void 0 : _c.destroy());
|
|
1640
|
+
await this._params.snapshotManager.close();
|
|
1641
|
+
}
|
|
1642
|
+
createSnapshot() {
|
|
1643
|
+
var _a, _b;
|
|
1644
|
+
return {
|
|
1645
|
+
spaceKey: this._params.spaceKey.asUint8Array(),
|
|
1646
|
+
timeframe: (_b = (_a = this._pipeline) == null ? void 0 : _a.state.timeframe) != null ? _b : new import_timeframe3.Timeframe(),
|
|
1647
|
+
database: this.databaseBackend.createSnapshot()
|
|
1648
|
+
};
|
|
1649
|
+
}
|
|
1650
|
+
async _consumePipeline() {
|
|
1651
|
+
(0, import_node_assert9.default)(this._pipeline, "Pipeline is not initialized.");
|
|
1652
|
+
for await (const msg of this._pipeline.consume()) {
|
|
1653
|
+
const { feedKey, seq, data } = msg;
|
|
1654
|
+
(0, import_log11.log)("processing message", {
|
|
1655
|
+
msg
|
|
1656
|
+
}, {
|
|
1657
|
+
file: "data-pipeline-controller.ts",
|
|
1658
|
+
line: 196,
|
|
1659
|
+
scope: this,
|
|
1660
|
+
callSite: (f, a) => f(...a)
|
|
1661
|
+
});
|
|
1662
|
+
try {
|
|
1663
|
+
if (data.payload.data) {
|
|
1664
|
+
const feedInfo = this._params.feedInfoProvider(feedKey);
|
|
1665
|
+
if (!feedInfo) {
|
|
1666
|
+
import_log11.log.error("Could not find feed.", {
|
|
1667
|
+
feedKey
|
|
1668
|
+
}, {
|
|
1669
|
+
file: "data-pipeline-controller.ts",
|
|
1670
|
+
line: 202,
|
|
1671
|
+
scope: this,
|
|
1672
|
+
callSite: (f, a) => f(...a)
|
|
1673
|
+
});
|
|
1674
|
+
continue;
|
|
1675
|
+
}
|
|
1676
|
+
await this.databaseBackend.echoProcessor({
|
|
1677
|
+
data: data.payload.data.object,
|
|
1678
|
+
meta: {
|
|
1679
|
+
feedKey,
|
|
1680
|
+
seq,
|
|
1681
|
+
timeframe: data.timeframe,
|
|
1682
|
+
memberKey: feedInfo.assertion.identityKey
|
|
1683
|
+
}
|
|
1684
|
+
});
|
|
1685
|
+
this.onTimeframeReached.emit(data.timeframe);
|
|
1686
|
+
}
|
|
1687
|
+
} catch (err) {
|
|
1688
|
+
import_log11.log.catch(err, {}, {
|
|
1689
|
+
file: "data-pipeline-controller.ts",
|
|
1690
|
+
line: 218,
|
|
1691
|
+
scope: this,
|
|
1692
|
+
callSite: (f, a) => f(...a)
|
|
1693
|
+
});
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
async waitUntilTimeframe(timeframe) {
|
|
1698
|
+
(0, import_node_assert9.default)(this._pipeline, "Pipeline is not initialized.");
|
|
1699
|
+
await this._pipeline.state.waitUntilTimeframe(timeframe);
|
|
1700
|
+
}
|
|
1701
|
+
};
|
|
1702
|
+
DataPipelineControllerImpl = __decorate7([
|
|
1703
|
+
(0, import_async8.trackLeaks)("open", "close")
|
|
1704
|
+
], DataPipelineControllerImpl);
|
|
1705
|
+
var snapshotTimeframeToStartingTimeframe = (snapshotTimeframe) => {
|
|
1706
|
+
return snapshotTimeframe.map(([key, seq]) => [
|
|
1707
|
+
key,
|
|
1708
|
+
seq + 1
|
|
1709
|
+
]);
|
|
1710
|
+
};
|
|
1711
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1712
|
+
0 && (module.exports = {
|
|
1713
|
+
AuthExtension,
|
|
1714
|
+
AuthStatus,
|
|
1715
|
+
DBError,
|
|
1716
|
+
DataPipelineControllerImpl,
|
|
1717
|
+
DataServiceHost,
|
|
1718
|
+
DataServiceImpl,
|
|
1719
|
+
DataServiceSubscriptions,
|
|
1720
|
+
DatabaseBackendHost,
|
|
1721
|
+
EntityNotFoundError,
|
|
1722
|
+
IdentityNotInitializedError,
|
|
1723
|
+
InvalidInvitationError,
|
|
1724
|
+
InvalidStorageVersionError,
|
|
1725
|
+
MOCK_AUTH_PROVIDER,
|
|
1726
|
+
MOCK_AUTH_VERIFIER,
|
|
1727
|
+
MetadataStore,
|
|
1728
|
+
NoopDataPipelineController,
|
|
1729
|
+
Pipeline,
|
|
1730
|
+
STORAGE_VERSION,
|
|
1731
|
+
SnapshotManager,
|
|
1732
|
+
SnapshotStore,
|
|
1733
|
+
Space,
|
|
1734
|
+
SpaceManager,
|
|
1735
|
+
SpaceNotFoundError,
|
|
1736
|
+
SpaceProtocol,
|
|
1737
|
+
SpaceProtocolSession,
|
|
1738
|
+
TimeframeClock,
|
|
1739
|
+
UnknownModelError,
|
|
1740
|
+
codec,
|
|
1741
|
+
createMappedFeedWriter,
|
|
1742
|
+
mapFeedIndexesToTimeframe,
|
|
1743
|
+
mapTimeframeToFeedIndexes,
|
|
1744
|
+
spaceGenesis,
|
|
1745
|
+
valueEncoding
|
|
1746
|
+
});
|
|
1747
|
+
//# sourceMappingURL=index.cjs.map
|