@dxos/echo-pipeline 0.1.50-next.88a1229 → 0.1.51-main.04cd027

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.
Files changed (37) hide show
  1. package/dist/lib/browser/{chunk-CSFWTLPD.mjs → chunk-KTQITKUX.mjs} +191 -60
  2. package/dist/lib/browser/chunk-KTQITKUX.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +1 -1
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/testing/index.mjs +4 -3
  6. package/dist/lib/browser/testing/index.mjs.map +3 -3
  7. package/dist/lib/node/index.cjs +197 -66
  8. package/dist/lib/node/index.cjs.map +3 -3
  9. package/dist/lib/node/meta.json +1 -1
  10. package/dist/lib/node/testing/index.cjs +207 -75
  11. package/dist/lib/node/testing/index.cjs.map +3 -3
  12. package/dist/types/src/dbhost/snapshot-manager.d.ts +2 -1
  13. package/dist/types/src/dbhost/snapshot-manager.d.ts.map +1 -1
  14. package/dist/types/src/metadata/metadata-store.d.ts +2 -1
  15. package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
  16. package/dist/types/src/pipeline/pipeline.d.ts +1 -0
  17. package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
  18. package/dist/types/src/space/control-pipeline.d.ts +9 -1
  19. package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
  20. package/dist/types/src/space/data-pipeline.d.ts +10 -0
  21. package/dist/types/src/space/data-pipeline.d.ts.map +1 -1
  22. package/dist/types/src/space/space.d.ts +2 -2
  23. package/dist/types/src/space/space.d.ts.map +1 -1
  24. package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
  25. package/package.json +30 -30
  26. package/src/dbhost/snapshot-manager.ts +4 -3
  27. package/src/metadata/metadata-store.ts +12 -1
  28. package/src/pipeline/pipeline.ts +24 -0
  29. package/src/space/control-pipeline.test.ts +4 -0
  30. package/src/space/control-pipeline.ts +36 -1
  31. package/src/space/data-pipeline.ts +62 -8
  32. package/src/space/space-manager.ts +1 -1
  33. package/src/space/space.test.ts +2 -5
  34. package/src/space/space.ts +11 -7
  35. package/src/testing/test-agent-builder.ts +4 -1
  36. package/src/testing/util.ts +1 -1
  37. package/dist/lib/browser/chunk-CSFWTLPD.mjs.map +0 -7
@@ -121,6 +121,10 @@ var MetadataStore = class {
121
121
  }
122
122
  }
123
123
  _getSpace(spaceKey) {
124
+ var _a;
125
+ if ((_a = this._metadata.identity) == null ? void 0 : _a.haloSpace.key.equals(spaceKey)) {
126
+ return this._metadata.identity.haloSpace;
127
+ }
124
128
  const space = this.spaces.find((space2) => space2.key === spaceKey);
125
129
  assert(space, "Space not found");
126
130
  return space;
@@ -131,7 +135,7 @@ var MetadataStore = class {
131
135
  async clear() {
132
136
  log("clearing all metadata", {}, {
133
137
  file: "metadata-store.ts",
134
- line: 131,
138
+ line: 136,
135
139
  scope: this,
136
140
  callSite: (f, a) => f(...a)
137
141
  });
@@ -152,10 +156,14 @@ var MetadataStore = class {
152
156
  ((_c = (_b = this._metadata).spaces) != null ? _c : _b.spaces = []).push(record);
153
157
  await this._save();
154
158
  }
155
- async setSpaceLatestTimeframe(spaceKey, timeframe) {
159
+ async setSpaceDataLatestTimeframe(spaceKey, timeframe) {
156
160
  this._getSpace(spaceKey).dataTimeframe = timeframe;
157
161
  await this._save();
158
162
  }
163
+ async setSpaceControlLatestTimeframe(spaceKey, timeframe) {
164
+ this._getSpace(spaceKey).controlTimeframe = timeframe;
165
+ await this._save();
166
+ }
159
167
  async setCache(spaceKey, cache) {
160
168
  this._getSpace(spaceKey).cache = cache;
161
169
  await this._save();
@@ -334,6 +342,7 @@ var PipelineState = class {
334
342
  this._timeframeClock = _timeframeClock;
335
343
  this.timeframeUpdate = this._timeframeClock.update;
336
344
  this.stalled = new Event3();
345
+ this._startTimeframe = new Timeframe2();
337
346
  }
338
347
  /**
339
348
  * Latest theoretical timeframe based on the last mutation in each feed.
@@ -346,6 +355,9 @@ var PipelineState = class {
346
355
  index: feed.length - 1
347
356
  })));
348
357
  }
358
+ get startTimeframe() {
359
+ return this._startTimeframe;
360
+ }
349
361
  get timeframe() {
350
362
  return this._timeframeClock.timeframe;
351
363
  }
@@ -379,7 +391,7 @@ var PipelineState = class {
379
391
  target: this.targetTimeframe
380
392
  }, {
381
393
  file: "pipeline.ts",
382
- line: 109,
394
+ line: 118,
383
395
  scope: this,
384
396
  callSite: (f, a) => f(...a)
385
397
  });
@@ -409,7 +421,7 @@ var PipelineState = class {
409
421
  dependencies: Timeframe2.dependencies(this.targetTimeframe, this.timeframe)
410
422
  }, {
411
423
  file: "pipeline.ts",
412
- line: 135,
424
+ line: 144,
413
425
  scope: this,
414
426
  callSite: (f, a) => f(...a)
415
427
  });
@@ -466,7 +478,7 @@ var Pipeline = class {
466
478
  async start() {
467
479
  log4("starting...", {}, {
468
480
  file: "pipeline.ts",
469
- line: 254,
481
+ line: 263,
470
482
  scope: this,
471
483
  callSite: (f, a) => f(...a)
472
484
  });
@@ -474,7 +486,7 @@ var Pipeline = class {
474
486
  await this._feedSetIterator.open();
475
487
  log4("started", {}, {
476
488
  file: "pipeline.ts",
477
- line: 257,
489
+ line: 266,
478
490
  scope: this,
479
491
  callSite: (f, a) => f(...a)
480
492
  });
@@ -484,7 +496,7 @@ var Pipeline = class {
484
496
  var _a;
485
497
  log4("stopping...", {}, {
486
498
  file: "pipeline.ts",
487
- line: 263,
499
+ line: 272,
488
500
  scope: this,
489
501
  callSite: (f, a) => f(...a)
490
502
  });
@@ -493,7 +505,7 @@ var Pipeline = class {
493
505
  await this._processingTrigger.wait();
494
506
  log4("stopped", {}, {
495
507
  file: "pipeline.ts",
496
- line: 267,
508
+ line: 276,
497
509
  scope: this,
498
510
  callSite: (f, a) => f(...a)
499
511
  });
@@ -504,7 +516,35 @@ var Pipeline = class {
504
516
  */
505
517
  async setCursor(timeframe) {
506
518
  assert4(!this._isStarted || this._isPaused, "Invalid state.");
519
+ this._state._startTimeframe = timeframe;
507
520
  this._timeframeClock.setTimeframe(timeframe);
521
+ for (const [key, seq] of timeframe.frames()) {
522
+ const feed = this._feeds.get(key);
523
+ if (!feed) {
524
+ throw new Error("Feed not found");
525
+ }
526
+ feed.undownload({
527
+ callback: () => log4("Undownloaded", {}, {
528
+ file: "pipeline.ts",
529
+ line: 297,
530
+ scope: this,
531
+ callSite: (f, a) => f(...a)
532
+ })
533
+ });
534
+ feed.download({
535
+ start: seq + 1,
536
+ linear: true
537
+ }).catch((err) => {
538
+ log4("failed to download feed", {
539
+ err
540
+ }, {
541
+ file: "pipeline.ts",
542
+ line: 300,
543
+ scope: this,
544
+ callSite: (f, a) => f(...a)
545
+ });
546
+ });
547
+ }
508
548
  if (this._feedSetIterator) {
509
549
  await this._feedSetIterator.close();
510
550
  await this._initIterator();
@@ -567,7 +607,7 @@ var Pipeline = class {
567
607
  this._feedSetIterator.stalled.on((iterator) => {
568
608
  log4.warn(`Stalled after ${iterator.options.stallTimeout}ms with ${iterator.size} feeds.`, {}, {
569
609
  file: "pipeline.ts",
570
- line: 357,
610
+ line: 381,
571
611
  scope: this,
572
612
  callSite: (f, a) => f(...a)
573
613
  });
@@ -827,6 +867,7 @@ var DatabaseHost = class {
827
867
 
828
868
  // packages/core/echo/echo-pipeline/src/dbhost/snapshot-manager.ts
829
869
  import { trackLeaks } from "@dxos/async";
870
+ import { cancelWithContext } from "@dxos/context";
830
871
  import { timed as timed2 } from "@dxos/debug";
831
872
  import { log as log7 } from "@dxos/log";
832
873
  import { schema as schema4 } from "@dxos/protocols";
@@ -853,7 +894,7 @@ var SnapshotManager = class SnapshotManager2 {
853
894
  snapshot
854
895
  }, {
855
896
  file: "snapshot-manager.ts",
856
- line: 30,
897
+ line: 31,
857
898
  scope: this,
858
899
  callSite: (f, a) => f(...a)
859
900
  });
@@ -870,7 +911,7 @@ var SnapshotManager = class SnapshotManager2 {
870
911
  data
871
912
  }, {
872
913
  file: "snapshot-manager.ts",
873
- line: 40,
914
+ line: 41,
874
915
  scope: this,
875
916
  callSite: (f, a) => f(...a)
876
917
  });
@@ -888,12 +929,12 @@ var SnapshotManager = class SnapshotManager2 {
888
929
  async close() {
889
930
  await this._objectSync.close();
890
931
  }
891
- async load(id) {
892
- const local = await this._snapshotStore.loadSnapshot(id);
932
+ async load(ctx, id) {
933
+ const local = await cancelWithContext(ctx, this._snapshotStore.loadSnapshot(id));
893
934
  if (local) {
894
935
  return local;
895
936
  }
896
- const remote = await this._objectSync.download(id);
937
+ const remote = await cancelWithContext(ctx, this._objectSync.download(ctx, id));
897
938
  return schema4.getCodecForType("dxos.echo.snapshot.SpaceSnapshot").decode(remote.payload.value);
898
939
  }
899
940
  async store(snapshot) {
@@ -1017,6 +1058,7 @@ import { Event as Event4, scheduleTask as scheduleTask2, synchronized as synchro
1017
1058
  import { Context as Context3 } from "@dxos/context";
1018
1059
  import { checkCredentialType } from "@dxos/credentials";
1019
1060
  import { getStateMachineFromItem, ItemManager } from "@dxos/echo-db";
1061
+ import { CancelledError } from "@dxos/errors";
1020
1062
  import { log as log9 } from "@dxos/log";
1021
1063
  import { Timeframe as Timeframe3 } from "@dxos/timeframe";
1022
1064
  var __decorate5 = function(decorators, target, key, desc) {
@@ -1040,6 +1082,7 @@ var DataPipeline = class DataPipeline2 {
1040
1082
  this._isOpen = false;
1041
1083
  this._lastTimeframeSaveTime = 0;
1042
1084
  this._lastSnapshotSaveTime = 0;
1085
+ this._lastProcessedEpoch = -1;
1043
1086
  this.onNewEpoch = new Event4();
1044
1087
  }
1045
1088
  get isOpen() {
@@ -1063,17 +1106,10 @@ var DataPipeline = class DataPipeline2 {
1063
1106
  if (!checkCredentialType(credential, "dxos.halo.credentials.Epoch")) {
1064
1107
  return;
1065
1108
  }
1066
- log9("new epoch", {
1067
- credential
1068
- }, {
1069
- file: "data-pipeline.ts",
1070
- line: 109,
1071
- scope: this,
1072
- callSite: (f, a) => f(...a)
1073
- });
1074
- await this._processEpoch(credential.subject.assertion);
1075
1109
  this.currentEpoch = credential;
1076
- this.onNewEpoch.emit(credential);
1110
+ if (this._isOpen) {
1111
+ await this._processEpochInSeparateTask(credential);
1112
+ }
1077
1113
  }
1078
1114
  };
1079
1115
  }
@@ -1112,7 +1148,7 @@ var DataPipeline = class DataPipeline2 {
1112
1148
  }
1113
1149
  log9("close", {}, {
1114
1150
  file: "data-pipeline.ts",
1115
- line: 161,
1151
+ line: 174,
1116
1152
  scope: this,
1117
1153
  callSite: (f, a) => f(...a)
1118
1154
  });
@@ -1127,7 +1163,7 @@ var DataPipeline = class DataPipeline2 {
1127
1163
  } catch (err) {
1128
1164
  log9.catch(err, {}, {
1129
1165
  file: "data-pipeline.ts",
1130
- line: 174,
1166
+ line: 187,
1131
1167
  scope: this,
1132
1168
  callSite: (f, a) => f(...a)
1133
1169
  });
@@ -1137,6 +1173,11 @@ var DataPipeline = class DataPipeline2 {
1137
1173
  await this._params.snapshotManager.close();
1138
1174
  }
1139
1175
  async _consumePipeline() {
1176
+ if (this.currentEpoch) {
1177
+ const waitForOneEpoch = this.onNewEpoch.waitForCount(1);
1178
+ await this._processEpochInSeparateTask(this.currentEpoch);
1179
+ await waitForOneEpoch;
1180
+ }
1140
1181
  assert8(this._pipeline, "Pipeline is not initialized.");
1141
1182
  for await (const msg of this._pipeline.consume()) {
1142
1183
  const { feedKey, seq, data } = msg;
@@ -1145,7 +1186,7 @@ var DataPipeline = class DataPipeline2 {
1145
1186
  seq
1146
1187
  }, {
1147
1188
  file: "data-pipeline.ts",
1148
- line: 186,
1189
+ line: 205,
1149
1190
  scope: this,
1150
1191
  callSite: (f, a) => f(...a)
1151
1192
  });
@@ -1157,7 +1198,7 @@ var DataPipeline = class DataPipeline2 {
1157
1198
  feedKey
1158
1199
  }, {
1159
1200
  file: "data-pipeline.ts",
1160
- line: 192,
1201
+ line: 211,
1161
1202
  scope: this,
1162
1203
  callSite: (f, a) => f(...a)
1163
1204
  });
@@ -1172,12 +1213,22 @@ var DataPipeline = class DataPipeline2 {
1172
1213
  memberKey: feedInfo.assertion.identityKey
1173
1214
  }
1174
1215
  });
1216
+ log9.trace("dxos.echo.data-pipeline.processed", {
1217
+ feedKey: feedKey.toHex(),
1218
+ seq,
1219
+ spaceKey: this._params.spaceKey.toHex()
1220
+ }, {
1221
+ file: "data-pipeline.ts",
1222
+ line: 225,
1223
+ scope: this,
1224
+ callSite: (f, a) => f(...a)
1225
+ });
1175
1226
  await this._noteTargetStateIfNeeded(this._pipeline.state.pendingTimeframe);
1176
1227
  }
1177
1228
  } catch (err) {
1178
1229
  log9.catch(err, {}, {
1179
1230
  file: "data-pipeline.ts",
1180
- line: 210,
1231
+ line: 235,
1181
1232
  scope: this,
1182
1233
  callSite: (f, a) => f(...a)
1183
1234
  });
@@ -1195,7 +1246,7 @@ var DataPipeline = class DataPipeline2 {
1195
1246
  async _saveTargetTimeframe(timeframe) {
1196
1247
  var _a;
1197
1248
  const newTimeframe = Timeframe3.merge((_a = this._targetTimeframe) != null ? _a : new Timeframe3(), timeframe);
1198
- await this._params.metadataStore.setSpaceLatestTimeframe(this._params.spaceKey, newTimeframe);
1249
+ await this._params.metadataStore.setSpaceDataLatestTimeframe(this._params.spaceKey, newTimeframe);
1199
1250
  this._targetTimeframe = newTimeframe;
1200
1251
  }
1201
1252
  async _saveCache() {
@@ -1212,7 +1263,7 @@ var DataPipeline = class DataPipeline2 {
1212
1263
  } catch (err) {
1213
1264
  log9.warn("Failed to cache properties", err, {
1214
1265
  file: "data-pipeline.ts",
1215
- line: 244,
1266
+ line: 269,
1216
1267
  scope: this,
1217
1268
  callSite: (f, a) => f(...a)
1218
1269
  });
@@ -1228,24 +1279,68 @@ var DataPipeline = class DataPipeline2 {
1228
1279
  await this._saveCache();
1229
1280
  }
1230
1281
  }
1231
- async _processEpoch(epoch) {
1232
- assert8(this._isOpen);
1282
+ async _processEpochInSeparateTask(epoch) {
1283
+ var _a;
1284
+ if (epoch.subject.assertion.number <= this._lastProcessedEpoch) {
1285
+ return;
1286
+ }
1287
+ await ((_a = this._epochCtx) == null ? void 0 : _a.dispose());
1288
+ const ctx = new Context3({
1289
+ onError: (err) => {
1290
+ if (err instanceof CancelledError) {
1291
+ log9("Epoch processing cancelled.", {}, {
1292
+ file: "data-pipeline.ts",
1293
+ line: 301,
1294
+ scope: this,
1295
+ callSite: (f, a) => f(...a)
1296
+ });
1297
+ } else {
1298
+ log9.catch(err, {}, {
1299
+ file: "data-pipeline.ts",
1300
+ line: 303,
1301
+ scope: this,
1302
+ callSite: (f, a) => f(...a)
1303
+ });
1304
+ }
1305
+ }
1306
+ });
1307
+ this._epochCtx = ctx;
1308
+ scheduleTask2(ctx, async () => {
1309
+ if (!this._isOpen) {
1310
+ return;
1311
+ }
1312
+ log9("process epoch", {
1313
+ epoch
1314
+ }, {
1315
+ file: "data-pipeline.ts",
1316
+ line: 313,
1317
+ scope: this,
1318
+ callSite: (f, a) => f(...a)
1319
+ });
1320
+ await this._processEpoch(ctx, epoch.subject.assertion);
1321
+ this.appliedEpoch = epoch;
1322
+ this.onNewEpoch.emit(epoch);
1323
+ });
1324
+ }
1325
+ async _processEpoch(ctx, epoch) {
1326
+ assert8(this._isOpen, "Space is closed.");
1233
1327
  assert8(this._pipeline);
1328
+ this._lastProcessedEpoch = epoch.number;
1234
1329
  log9("Processing epoch", {
1235
1330
  epoch
1236
1331
  }, {
1237
1332
  file: "data-pipeline.ts",
1238
- line: 273,
1333
+ line: 327,
1239
1334
  scope: this,
1240
1335
  callSite: (f, a) => f(...a)
1241
1336
  });
1242
1337
  if (epoch.snapshotCid) {
1243
- const snapshot = await this._params.snapshotManager.load(epoch.snapshotCid);
1338
+ const snapshot = await this._params.snapshotManager.load(ctx, epoch.snapshotCid);
1244
1339
  this.databaseHost._itemDemuxer.restoreFromSnapshot(snapshot.database);
1245
1340
  }
1246
1341
  log9("restarting pipeline for epoch", {}, {
1247
1342
  file: "data-pipeline.ts",
1248
- line: 281,
1343
+ line: 335,
1249
1344
  scope: this,
1250
1345
  callSite: (f, a) => f(...a)
1251
1346
  });
@@ -1304,10 +1399,15 @@ import { SpaceStateMachine } from "@dxos/credentials";
1304
1399
  import { PublicKey as PublicKey3 } from "@dxos/keys";
1305
1400
  import { log as log10 } from "@dxos/log";
1306
1401
  import { AdmittedFeed } from "@dxos/protocols/proto/dxos/halo/credentials";
1402
+ import { Timeframe as Timeframe4 } from "@dxos/timeframe";
1307
1403
  import { Callback } from "@dxos/util";
1404
+ var TIMEFRAME_SAVE_DEBOUNCE_INTERVAL2 = 500;
1308
1405
  var ControlPipeline = class {
1309
- constructor({ spaceKey, genesisFeed, feedProvider }) {
1406
+ constructor({ spaceKey, genesisFeed, feedProvider, metadataStore }) {
1407
+ this._lastTimeframeSaveTime = Date.now();
1310
1408
  this.onFeedAdmitted = new Callback();
1409
+ this._spaceKey = spaceKey;
1410
+ this._metadata = metadataStore;
1311
1411
  this._pipeline = new Pipeline();
1312
1412
  void this._pipeline.addFeed(genesisFeed);
1313
1413
  this._spaceStateMachine = new SpaceStateMachine(spaceKey);
@@ -1316,7 +1416,7 @@ var ControlPipeline = class {
1316
1416
  key: info.key
1317
1417
  }, {
1318
1418
  file: "control-pipeline.ts",
1319
- line: 39,
1419
+ line: 51,
1320
1420
  scope: this,
1321
1421
  callSite: (f, a) => f(...a)
1322
1422
  });
@@ -1327,7 +1427,7 @@ var ControlPipeline = class {
1327
1427
  } catch (err) {
1328
1428
  log10.catch(err, {}, {
1329
1429
  file: "control-pipeline.ts",
1330
- line: 47,
1430
+ line: 59,
1331
1431
  scope: this,
1332
1432
  callSite: (f, a) => f(...a)
1333
1433
  });
@@ -1350,7 +1450,7 @@ var ControlPipeline = class {
1350
1450
  async start() {
1351
1451
  log10("starting...", {}, {
1352
1452
  file: "control-pipeline.ts",
1353
- line: 71,
1453
+ line: 83,
1354
1454
  scope: this,
1355
1455
  callSite: (f, a) => f(...a)
1356
1456
  });
@@ -1362,7 +1462,7 @@ var ControlPipeline = class {
1362
1462
  seq: msg.seq
1363
1463
  }, {
1364
1464
  file: "control-pipeline.ts",
1365
- line: 76,
1465
+ line: 88,
1366
1466
  scope: this,
1367
1467
  callSite: (f, a) => f(...a)
1368
1468
  });
@@ -1373,16 +1473,18 @@ var ControlPipeline = class {
1373
1473
  msg
1374
1474
  }, {
1375
1475
  file: "control-pipeline.ts",
1376
- line: 83,
1476
+ line: 95,
1377
1477
  scope: this,
1378
1478
  callSite: (f, a) => f(...a)
1379
1479
  });
1480
+ } else {
1481
+ await this._noteTargetStateIfNeeded(this._pipeline.state.pendingTimeframe);
1380
1482
  }
1381
1483
  }
1382
1484
  } catch (err) {
1383
1485
  log10.catch(err, {}, {
1384
1486
  file: "control-pipeline.ts",
1385
- line: 87,
1487
+ line: 101,
1386
1488
  scope: this,
1387
1489
  callSite: (f, a) => f(...a)
1388
1490
  });
@@ -1392,26 +1494,48 @@ var ControlPipeline = class {
1392
1494
  await this._pipeline.start();
1393
1495
  log10("started", {}, {
1394
1496
  file: "control-pipeline.ts",
1395
- line: 93,
1497
+ line: 107,
1396
1498
  scope: this,
1397
1499
  callSite: (f, a) => f(...a)
1398
1500
  });
1399
1501
  }
1502
+ async _noteTargetStateIfNeeded(timeframe) {
1503
+ if (Date.now() - this._lastTimeframeSaveTime > TIMEFRAME_SAVE_DEBOUNCE_INTERVAL2) {
1504
+ this._lastTimeframeSaveTime = Date.now();
1505
+ await this._saveTargetTimeframe(timeframe);
1506
+ }
1507
+ }
1400
1508
  async stop() {
1401
1509
  log10("stopping...", {}, {
1402
1510
  file: "control-pipeline.ts",
1403
- line: 97,
1511
+ line: 121,
1404
1512
  scope: this,
1405
1513
  callSite: (f, a) => f(...a)
1406
1514
  });
1407
1515
  await this._pipeline.stop();
1516
+ await this._saveTargetTimeframe(this._pipeline.state.timeframe);
1408
1517
  log10("stopped", {}, {
1409
1518
  file: "control-pipeline.ts",
1410
- line: 99,
1519
+ line: 124,
1411
1520
  scope: this,
1412
1521
  callSite: (f, a) => f(...a)
1413
1522
  });
1414
1523
  }
1524
+ async _saveTargetTimeframe(timeframe) {
1525
+ var _a;
1526
+ try {
1527
+ const newTimeframe = Timeframe4.merge((_a = this._targetTimeframe) != null ? _a : new Timeframe4(), timeframe);
1528
+ await this._metadata.setSpaceControlLatestTimeframe(this._spaceKey, newTimeframe);
1529
+ this._targetTimeframe = newTimeframe;
1530
+ } catch (err) {
1531
+ log10(err, {}, {
1532
+ file: "control-pipeline.ts",
1533
+ line: 133,
1534
+ scope: this,
1535
+ callSite: (f, a) => f(...a)
1536
+ });
1537
+ }
1538
+ }
1415
1539
  };
1416
1540
 
1417
1541
  // packages/core/echo/echo-pipeline/src/space/space.ts
@@ -1441,20 +1565,26 @@ var Space = class Space2 {
1441
1565
  this._controlPipeline = new ControlPipeline({
1442
1566
  spaceKey: params.spaceKey,
1443
1567
  genesisFeed: params.genesisFeed,
1444
- feedProvider: params.feedProvider
1568
+ feedProvider: params.feedProvider,
1569
+ metadataStore: params.metadataStore
1445
1570
  });
1446
1571
  this._controlPipeline.onFeedAdmitted.set(async (info) => {
1572
+ const sparse = info.assertion.designation === AdmittedFeed2.Designation.DATA;
1447
1573
  if (info.assertion.designation === AdmittedFeed2.Designation.DATA) {
1448
1574
  await this._addFeedLock.executeSynchronized(async () => {
1449
1575
  if (this._dataPipeline.pipeline) {
1450
1576
  if (!this._dataPipeline.pipeline.hasFeed(info.key)) {
1451
- return this._dataPipeline.pipeline.addFeed(await this._feedProvider(info.key));
1577
+ return this._dataPipeline.pipeline.addFeed(await this._feedProvider(info.key, {
1578
+ sparse
1579
+ }));
1452
1580
  }
1453
1581
  }
1454
1582
  });
1455
1583
  }
1456
1584
  if (!info.key.equals(params.genesisFeed.key)) {
1457
- this.protocol.addFeed(await params.feedProvider(info.key));
1585
+ this.protocol.addFeed(await params.feedProvider(info.key, {
1586
+ sparse
1587
+ }));
1458
1588
  }
1459
1589
  });
1460
1590
  this._controlPipeline.onCredentialProcessed.set(async (credential) => {
@@ -1463,7 +1593,7 @@ var Space = class Space2 {
1463
1593
  credential
1464
1594
  }, {
1465
1595
  file: "space.ts",
1466
- line: 106,
1596
+ line: 110,
1467
1597
  scope: this,
1468
1598
  callSite: (f, a) => f(...a)
1469
1599
  });
@@ -1486,7 +1616,9 @@ var Space = class Space2 {
1486
1616
  await this._addFeedLock.executeSynchronized(async () => {
1487
1617
  for (const feed of this._controlPipeline.spaceState.feeds.values()) {
1488
1618
  if (feed.assertion.designation === AdmittedFeed2.Designation.DATA && !pipeline.hasFeed(feed.key)) {
1489
- await pipeline.addFeed(await this._feedProvider(feed.key));
1619
+ await pipeline.addFeed(await this._feedProvider(feed.key, {
1620
+ sparse: true
1621
+ }));
1490
1622
  }
1491
1623
  }
1492
1624
  });
@@ -1553,7 +1685,7 @@ var Space = class Space2 {
1553
1685
  async open() {
1554
1686
  log11("opening...", {}, {
1555
1687
  file: "space.ts",
1556
- line: 208,
1688
+ line: 212,
1557
1689
  scope: this,
1558
1690
  callSite: (f, a) => f(...a)
1559
1691
  });
@@ -1563,10 +1695,11 @@ var Space = class Space2 {
1563
1695
  await this._controlPipeline.start();
1564
1696
  await this.protocol.start();
1565
1697
  this._dataPipelineCredentialConsumer = this._controlPipeline.spaceState.registerProcessor(this._dataPipeline.createCredentialProcessor());
1698
+ await this._dataPipelineCredentialConsumer.open();
1566
1699
  this._isOpen = true;
1567
1700
  log11("opened", {}, {
1568
1701
  file: "space.ts",
1569
- line: 222,
1702
+ line: 228,
1570
1703
  scope: this,
1571
1704
  callSite: (f, a) => f(...a)
1572
1705
  });
@@ -1577,7 +1710,7 @@ var Space = class Space2 {
1577
1710
  key: this._key
1578
1711
  }, {
1579
1712
  file: "space.ts",
1580
- line: 227,
1713
+ line: 233,
1581
1714
  scope: this,
1582
1715
  callSite: (f, a) => f(...a)
1583
1716
  });
@@ -1592,7 +1725,7 @@ var Space = class Space2 {
1592
1725
  this._isOpen = false;
1593
1726
  log11("closed", {}, {
1594
1727
  file: "space.ts",
1595
- line: 241,
1728
+ line: 247,
1596
1729
  scope: this,
1597
1730
  callSite: (f, a) => f(...a)
1598
1731
  });
@@ -1600,14 +1733,12 @@ var Space = class Space2 {
1600
1733
  async initializeDataPipeline() {
1601
1734
  log11("initializeDataPipeline", {}, {
1602
1735
  file: "space.ts",
1603
- line: 246,
1736
+ line: 252,
1604
1737
  scope: this,
1605
1738
  callSite: (f, a) => f(...a)
1606
1739
  });
1607
1740
  assert9(this._isOpen, "Space must be open to initialize data pipeline.");
1608
1741
  await this._dataPipeline.open();
1609
- assert9(this._dataPipelineCredentialConsumer);
1610
- await this._dataPipelineCredentialConsumer.open();
1611
1742
  }
1612
1743
  };
1613
1744
  __decorate6([
@@ -1880,7 +2011,7 @@ var SpaceManager = class SpaceManager2 {
1880
2011
  spaceKey,
1881
2012
  protocol,
1882
2013
  genesisFeed,
1883
- feedProvider: (feedKey) => this._feedStore.openFeed(feedKey),
2014
+ feedProvider: (feedKey, opts) => this._feedStore.openFeed(feedKey, opts),
1884
2015
  modelFactory: this._modelFactory,
1885
2016
  metadataStore: this._metadataStore,
1886
2017
  snapshotManager,
@@ -1934,4 +2065,4 @@ export {
1934
2065
  SpaceProtocolSession,
1935
2066
  SpaceManager
1936
2067
  };
1937
- //# sourceMappingURL=chunk-CSFWTLPD.mjs.map
2068
+ //# sourceMappingURL=chunk-KTQITKUX.mjs.map