@dxos/echo-pipeline 0.1.31-next.ea8f0bc → 0.1.32-next.77d513e

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 (49) hide show
  1. package/dist/lib/browser/{chunk-L44NG4N6.mjs → chunk-EM5HSJ7J.mjs} +192 -122
  2. package/dist/lib/browser/chunk-EM5HSJ7J.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +3 -5
  4. package/dist/lib/browser/index.mjs.map +1 -1
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +34 -17
  7. package/dist/lib/browser/testing/index.mjs.map +3 -3
  8. package/dist/lib/node/index.cjs +189 -120
  9. package/dist/lib/node/index.cjs.map +4 -4
  10. package/dist/lib/node/meta.json +1 -1
  11. package/dist/lib/node/testing/index.cjs +175 -119
  12. package/dist/lib/node/testing/index.cjs.map +4 -4
  13. package/dist/types/src/dbhost/data-service-host.d.ts.map +1 -1
  14. package/dist/types/src/dbhost/database-backend.d.ts +2 -2
  15. package/dist/types/src/dbhost/database-backend.d.ts.map +1 -1
  16. package/dist/types/src/metadata/metadata-store.d.ts +1 -2
  17. package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
  18. package/dist/types/src/pipeline/pipeline.d.ts +10 -1
  19. package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
  20. package/dist/types/src/space/{data-pipeline-controller.d.ts → data-pipeline.d.ts} +10 -18
  21. package/dist/types/src/space/data-pipeline.d.ts.map +1 -0
  22. package/dist/types/src/space/genesis.d.ts.map +1 -1
  23. package/dist/types/src/space/index.d.ts +1 -1
  24. package/dist/types/src/space/index.d.ts.map +1 -1
  25. package/dist/types/src/space/space.d.ts +6 -4
  26. package/dist/types/src/space/space.d.ts.map +1 -1
  27. package/dist/types/src/testing/test-agent-builder.d.ts +6 -5
  28. package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
  29. package/dist/types/src/testing/util.d.ts +2 -2
  30. package/dist/types/src/testing/util.d.ts.map +1 -1
  31. package/package.json +29 -29
  32. package/src/dbhost/data-service-host.ts +19 -25
  33. package/src/dbhost/database-backend.ts +1 -1
  34. package/src/metadata/metadata-store.ts +1 -2
  35. package/src/pipeline/pipeline.test.ts +12 -4
  36. package/src/pipeline/pipeline.ts +18 -3
  37. package/src/space/{data-pipeline-controller.ts → data-pipeline.ts} +62 -39
  38. package/src/space/genesis.ts +47 -7
  39. package/src/space/index.ts +1 -1
  40. package/src/space/space-protocol.browser.test.ts +8 -6
  41. package/src/space/space-protocol.test.ts +8 -6
  42. package/src/space/space.ts +22 -23
  43. package/src/testing/database-test-rig.ts +1 -1
  44. package/src/testing/test-agent-builder.ts +23 -11
  45. package/src/testing/util.ts +13 -12
  46. package/src/tests/database-unit.test.ts +25 -0
  47. package/src/tests/database.test.ts +5 -5
  48. package/dist/lib/browser/chunk-L44NG4N6.mjs.map +0 -7
  49. package/dist/types/src/space/data-pipeline-controller.d.ts.map +0 -1
@@ -55,7 +55,7 @@ var MetadataStore = class {
55
55
  size: dataSize
56
56
  }, {
57
57
  file: "metadata-store.ts",
58
- line: 68,
58
+ line: 67,
59
59
  scope: this,
60
60
  callSite: (f, a) => f(...a)
61
61
  });
@@ -71,7 +71,7 @@ var MetadataStore = class {
71
71
  err
72
72
  }, {
73
73
  file: "metadata-store.ts",
74
- line: 80,
74
+ line: 79,
75
75
  scope: this,
76
76
  callSite: (f, a) => f(...a)
77
77
  });
@@ -96,7 +96,7 @@ var MetadataStore = class {
96
96
  size: encoded.length
97
97
  }, {
98
98
  file: "metadata-store.ts",
99
- line: 103,
99
+ line: 102,
100
100
  scope: this,
101
101
  callSite: (f, a) => f(...a)
102
102
  });
@@ -111,7 +111,7 @@ var MetadataStore = class {
111
111
  async clear() {
112
112
  log("clearing all metadata", {}, {
113
113
  file: "metadata-store.ts",
114
- line: 116,
114
+ line: 115,
115
115
  scope: this,
116
116
  callSite: (f, a) => f(...a)
117
117
  });
@@ -257,6 +257,7 @@ __decorate2([
257
257
  // packages/core/echo/echo-pipeline/src/pipeline/pipeline.ts
258
258
  import assert4 from "@dxos/node-std/assert";
259
259
  import { sleep, Trigger } from "@dxos/async";
260
+ import { Context, rejectOnDispose } from "@dxos/context";
260
261
  import { FeedSetIterator } from "@dxos/feed-store";
261
262
  import { PublicKey } from "@dxos/keys";
262
263
  import { log as log4 } from "@dxos/log";
@@ -301,7 +302,7 @@ var PipelineState = class {
301
302
  return this._timeframeClock.timeframe;
302
303
  }
303
304
  get targetTimeframe() {
304
- return this._targetTimeframe ? Timeframe2.merge(this.endTimeframe, this._targetTimeframe) : this.endTimeframe;
305
+ return this._targetTimeframe ? this._targetTimeframe : new Timeframe2();
305
306
  }
306
307
  async waitUntilTimeframe(target) {
307
308
  await this._timeframeClock.waitUntilReached(target);
@@ -316,7 +317,7 @@ var PipelineState = class {
316
317
  *
317
318
  * @param timeout Timeout in milliseconds to specify the maximum wait time.
318
319
  */
319
- async waitUntilReachedTargetTimeframe({ timeout } = {}) {
320
+ async waitUntilReachedTargetTimeframe({ ctx = new Context(), timeout, breakOnStall = true } = {}) {
320
321
  var _a;
321
322
  log4("waitUntilReachedTargetTimeframe", {
322
323
  timeout,
@@ -324,7 +325,7 @@ var PipelineState = class {
324
325
  target: this.targetTimeframe
325
326
  }, {
326
327
  file: "pipeline.ts",
327
- line: 82,
328
+ line: 96,
328
329
  scope: this,
329
330
  callSite: (f, a) => f(...a)
330
331
  });
@@ -332,11 +333,14 @@ var PipelineState = class {
332
333
  this._timeframeClock.update.waitForCondition(() => {
333
334
  return Timeframe2.dependencies(this.targetTimeframe, this.timeframe).isEmpty();
334
335
  }),
335
- this._iterator.stalled.discardParameter().waitForCount(1)
336
+ ...breakOnStall ? [
337
+ this._iterator.stalled.discardParameter().waitForCount(1)
338
+ ] : []
336
339
  ]);
337
340
  let done = false;
338
341
  if (timeout) {
339
342
  return Promise.race([
343
+ rejectOnDispose(ctx),
340
344
  this._reachedTargetPromise.then(() => {
341
345
  done = true;
342
346
  }),
@@ -351,7 +355,7 @@ var PipelineState = class {
351
355
  dependencies: Timeframe2.dependencies(this.targetTimeframe, this.timeframe)
352
356
  }, {
353
357
  file: "pipeline.ts",
354
- line: 107,
358
+ line: 122,
355
359
  scope: this,
356
360
  callSite: (f, a) => f(...a)
357
361
  });
@@ -377,7 +381,7 @@ var Pipeline = class {
377
381
  this._feedSetIterator.stalled.on((iterator) => {
378
382
  log4.warn(`Stalled after ${iterator.options.stallTimeout}ms with ${iterator.size} feeds.`, {}, {
379
383
  file: "pipeline.ts",
380
- line: 183,
384
+ line: 198,
381
385
  scope: this,
382
386
  callSite: (f, a) => f(...a)
383
387
  });
@@ -407,14 +411,14 @@ var Pipeline = class {
407
411
  async start() {
408
412
  log4("starting...", {}, {
409
413
  file: "pipeline.ts",
410
- line: 218,
414
+ line: 233,
411
415
  scope: this,
412
416
  callSite: (f, a) => f(...a)
413
417
  });
414
418
  await this._feedSetIterator.open();
415
419
  log4("started", {}, {
416
420
  file: "pipeline.ts",
417
- line: 220,
421
+ line: 235,
418
422
  scope: this,
419
423
  callSite: (f, a) => f(...a)
420
424
  });
@@ -422,7 +426,7 @@ var Pipeline = class {
422
426
  async stop() {
423
427
  log4("stopping...", {}, {
424
428
  file: "pipeline.ts",
425
- line: 224,
429
+ line: 239,
426
430
  scope: this,
427
431
  callSite: (f, a) => f(...a)
428
432
  });
@@ -430,7 +434,7 @@ var Pipeline = class {
430
434
  await this._processingTrigger.wait();
431
435
  log4("stopped", {}, {
432
436
  file: "pipeline.ts",
433
- line: 227,
437
+ line: 242,
434
438
  scope: this,
435
439
  callSite: (f, a) => f(...a)
436
440
  });
@@ -455,7 +459,7 @@ var Pipeline = class {
455
459
  // packages/core/echo/echo-pipeline/src/space/auth.ts
456
460
  import assert5 from "@dxos/node-std/assert";
457
461
  import { runInContext, scheduleTask } from "@dxos/async";
458
- import { Context } from "@dxos/context";
462
+ import { Context as Context2 } from "@dxos/context";
459
463
  import { randomBytes } from "@dxos/crypto";
460
464
  import { log as log5 } from "@dxos/log";
461
465
  import { schema as schema3 } from "@dxos/protocols";
@@ -473,7 +477,7 @@ var AuthExtension = class extends RpcExtension {
473
477
  // Long timeout because auth can wait for sync in certain cases.
474
478
  });
475
479
  this._authParams = _authParams;
476
- this._ctx = new Context({
480
+ this._ctx = new Context2({
477
481
  onError: (err) => {
478
482
  log5.catch(err, {}, {
479
483
  file: "auth.ts",
@@ -702,7 +706,7 @@ var Space = class Space2 {
702
706
  credential
703
707
  }, {
704
708
  file: "space.ts",
705
- line: 74,
709
+ line: 79,
706
710
  scope: this,
707
711
  callSite: (f, a) => f(...a)
708
712
  });
@@ -765,7 +769,7 @@ var Space = class Space2 {
765
769
  async open() {
766
770
  log7("opening...", {}, {
767
771
  file: "space.ts",
768
- line: 145,
772
+ line: 149,
769
773
  scope: this,
770
774
  callSite: (f, a) => f(...a)
771
775
  });
@@ -777,18 +781,17 @@ var Space = class Space2 {
777
781
  this._isOpen = true;
778
782
  log7("opened", {}, {
779
783
  file: "space.ts",
780
- line: 155,
784
+ line: 159,
781
785
  scope: this,
782
786
  callSite: (f, a) => f(...a)
783
787
  });
784
788
  }
785
789
  async close() {
786
- var _a;
787
790
  log7("closing...", {
788
791
  key: this._key
789
792
  }, {
790
793
  file: "space.ts",
791
- line: 160,
794
+ line: 164,
792
795
  scope: this,
793
796
  callSite: (f, a) => f(...a)
794
797
  });
@@ -796,37 +799,30 @@ var Space = class Space2 {
796
799
  return;
797
800
  }
798
801
  await this.protocol.stop();
799
- await ((_a = this._dataPipelineController) == null ? void 0 : _a.close());
800
802
  await this._controlPipeline.stop();
801
803
  this._isOpen = false;
802
804
  log7("closed", {}, {
803
805
  file: "space.ts",
804
- line: 171,
806
+ line: 174,
805
807
  scope: this,
806
808
  callSite: (f, a) => f(...a)
807
809
  });
808
810
  }
809
- async initDataPipeline(controller) {
811
+ // TODO(dmaretskyi): Make reusable.
812
+ async createDataPipeline({ start }) {
810
813
  assert6(this._isOpen, "Space must be open to initialize data pipeline.");
811
- assert6(!this._dataPipelineController, "Data pipeline already initialized.");
812
814
  assert6(!this._dataPipeline, "Data pipeline already initialized.");
813
- this._dataPipelineController = controller;
814
- await this._dataPipelineController.open({
815
- openPipeline: async (start) => {
816
- assert6(!this._dataPipeline, "Data pipeline already initialized.");
817
- this._dataPipeline = new Pipeline(start);
818
- if (this._dataFeed) {
819
- this._dataPipeline.setWriteFeed(this._dataFeed);
820
- }
821
- for (const feed of this._controlPipeline.spaceState.feeds.values()) {
822
- if (feed.assertion.designation === AdmittedFeed2.Designation.DATA) {
823
- await this._dataPipeline.addFeed(await this._feedProvider(feed.key));
824
- }
825
- }
826
- await this._dataPipeline.start();
827
- return this._dataPipeline;
815
+ const pipeline = new Pipeline(start);
816
+ if (this._dataFeed) {
817
+ pipeline.setWriteFeed(this._dataFeed);
818
+ }
819
+ this._dataPipeline = pipeline;
820
+ for (const feed of this._controlPipeline.spaceState.feeds.values()) {
821
+ if (feed.assertion.designation === AdmittedFeed2.Designation.DATA) {
822
+ await pipeline.addFeed(await this._feedProvider(feed.key));
828
823
  }
829
- });
824
+ }
825
+ return pipeline;
830
826
  }
831
827
  };
832
828
  __decorate3([
@@ -1099,15 +1095,53 @@ SpaceManager = __decorate5([
1099
1095
  ], SpaceManager);
1100
1096
 
1101
1097
  // packages/core/echo/echo-pipeline/src/space/genesis.ts
1102
- import { CredentialGenerator } from "@dxos/credentials";
1098
+ import { createCredential } from "@dxos/credentials";
1103
1099
  import { failUndefined as failUndefined2 } from "@dxos/debug";
1104
- import { AdmittedFeed as AdmittedFeed3 } from "@dxos/protocols/proto/dxos/halo/credentials";
1100
+ import { AdmittedFeed as AdmittedFeed3, SpaceMember } from "@dxos/protocols/proto/dxos/halo/credentials";
1105
1101
  var spaceGenesis = async (keyring, signingContext, space) => {
1106
- var _a, _b;
1107
- const generator = new CredentialGenerator(keyring, signingContext.identityKey, signingContext.deviceKey);
1102
+ var _a, _b, _c;
1108
1103
  const credentials = [
1109
- ...await generator.createSpaceGenesis(space.key, (_a = space.controlFeedKey) != null ? _a : failUndefined2(), signingContext.profile),
1110
- await generator.createFeedAdmission(space.key, (_b = space.dataFeedKey) != null ? _b : failUndefined2(), AdmittedFeed3.Designation.DATA)
1104
+ await createCredential({
1105
+ signer: keyring,
1106
+ issuer: space.key,
1107
+ subject: space.key,
1108
+ assertion: {
1109
+ "@type": "dxos.halo.credentials.SpaceGenesis",
1110
+ spaceKey: space.key
1111
+ }
1112
+ }),
1113
+ await createCredential({
1114
+ signer: keyring,
1115
+ issuer: space.key,
1116
+ subject: signingContext.identityKey,
1117
+ assertion: {
1118
+ "@type": "dxos.halo.credentials.SpaceMember",
1119
+ spaceKey: space.key,
1120
+ role: SpaceMember.Role.ADMIN,
1121
+ profile: signingContext.profile,
1122
+ genesisFeedKey: (_a = space.controlFeedKey) != null ? _a : failUndefined2()
1123
+ }
1124
+ }),
1125
+ await signingContext.credentialSigner.createCredential({
1126
+ subject: (_b = space.controlFeedKey) != null ? _b : failUndefined2(),
1127
+ assertion: {
1128
+ "@type": "dxos.halo.credentials.AdmittedFeed",
1129
+ spaceKey: space.key,
1130
+ identityKey: signingContext.identityKey,
1131
+ deviceKey: signingContext.deviceKey,
1132
+ designation: AdmittedFeed3.Designation.CONTROL
1133
+ }
1134
+ }),
1135
+ await signingContext.credentialSigner.createCredential({
1136
+ subject: (_c = space.dataFeedKey) != null ? _c : failUndefined2(),
1137
+ assertion: {
1138
+ "@type": "dxos.halo.credentials.AdmittedFeed",
1139
+ spaceKey: space.key,
1140
+ identityKey: signingContext.identityKey,
1141
+ deviceKey: signingContext.deviceKey,
1142
+ designation: AdmittedFeed3.Designation.DATA
1143
+ }
1144
+ })
1111
1145
  ];
1112
1146
  for (const credential of credentials) {
1113
1147
  await space.controlPipeline.writer.write({
@@ -1122,7 +1156,7 @@ var spaceGenesis = async (keyring, signingContext, space) => {
1122
1156
  // packages/core/echo/echo-pipeline/src/dbhost/data-service-host.ts
1123
1157
  import assert7 from "@dxos/node-std/assert";
1124
1158
  import { Stream } from "@dxos/codec-protobuf";
1125
- import { tagMutationsInBatch } from "@dxos/echo-db";
1159
+ import { tagMutationsInBatch, setMetadataOnObject } from "@dxos/echo-db";
1126
1160
  import { log as log10 } from "@dxos/log";
1127
1161
  import { ComplexMap as ComplexMap3 } from "@dxos/util";
1128
1162
  var DataServiceHost = class {
@@ -1143,56 +1177,53 @@ var DataServiceHost = class {
1143
1177
  objects
1144
1178
  }
1145
1179
  });
1146
- this._itemDemuxer.mutation.on(ctx, (mutation) => {
1180
+ this._itemDemuxer.mutation.on(ctx, (message) => {
1147
1181
  var _a;
1182
+ const { batch, meta } = message;
1148
1183
  log10("Object update", {
1149
- mutation
1184
+ batch,
1185
+ meta
1150
1186
  }, {
1151
1187
  file: "data-service-host.ts",
1152
- line: 49,
1188
+ line: 50,
1153
1189
  scope: this,
1154
1190
  callSite: (f, a) => f(...a)
1155
1191
  });
1156
1192
  const clientTag = this._clientTagMap.get([
1157
- mutation.meta.feedKey,
1158
- mutation.meta.seq
1193
+ message.meta.feedKey,
1194
+ message.meta.seq
1159
1195
  ]);
1160
- const batch = {
1161
- objects: [
1162
- {
1163
- ...mutation.data,
1164
- mutations: (_a = mutation.data.mutations) == null ? void 0 : _a.map((m, mutationIdx) => ({
1165
- ...m,
1166
- meta: mutation.meta
1167
- })),
1168
- meta: mutation.meta
1169
- }
1170
- ]
1171
- };
1196
+ (_a = batch.objects) == null ? void 0 : _a.forEach((object) => {
1197
+ setMetadataOnObject(object, meta);
1198
+ });
1172
1199
  if (clientTag) {
1173
1200
  tagMutationsInBatch(batch, clientTag);
1174
1201
  }
1175
1202
  next({
1176
1203
  clientTag,
1177
- feedKey: mutation.meta.feedKey,
1178
- seq: mutation.meta.seq,
1204
+ feedKey: message.meta.feedKey,
1205
+ seq: message.meta.seq,
1179
1206
  batch
1180
1207
  });
1181
1208
  });
1182
1209
  });
1183
1210
  }
1184
1211
  async write(request) {
1185
- var _a, _b;
1212
+ var _a;
1186
1213
  assert7(this._writeStream, "Cannot write mutations in readonly mode");
1187
- assert7(((_a = request.batch.objects) == null ? void 0 : _a.length) === 1, "Only single object mutations are supported");
1188
1214
  const receipt = await this._writeStream.write({
1189
- object: {
1190
- ...request.batch.objects[0],
1191
- mutations: (_b = request.batch.objects[0].mutations) == null ? void 0 : _b.map((m) => ({
1192
- ...m,
1193
- meta: void 0
1194
- })),
1195
- meta: void 0
1215
+ batch: {
1216
+ objects: (_a = request.batch.objects) == null ? void 0 : _a.map((object) => {
1217
+ var _a2;
1218
+ return {
1219
+ ...object,
1220
+ mutations: (_a2 = object.mutations) == null ? void 0 : _a2.map((m) => ({
1221
+ ...m,
1222
+ meta: void 0
1223
+ })),
1224
+ meta: void 0
1225
+ };
1226
+ })
1196
1227
  }
1197
1228
  });
1198
1229
  if (request.clientTag) {
@@ -1395,10 +1426,10 @@ var DataServiceImpl = class {
1395
1426
  }
1396
1427
  };
1397
1428
 
1398
- // packages/core/echo/echo-pipeline/src/space/data-pipeline-controller.ts
1429
+ // packages/core/echo/echo-pipeline/src/space/data-pipeline.ts
1399
1430
  import assert9 from "@dxos/node-std/assert";
1400
- import { Event as Event3, scheduleTask as scheduleTask2, trackLeaks as trackLeaks4 } from "@dxos/async";
1401
- import { Context as Context2 } from "@dxos/context";
1431
+ import { Event as Event3, scheduleTask as scheduleTask2, synchronized as synchronized4, trackLeaks as trackLeaks4 } from "@dxos/async";
1432
+ import { Context as Context3 } from "@dxos/context";
1402
1433
  import { failUndefined as failUndefined3 } from "@dxos/debug";
1403
1434
  import { ItemManager } from "@dxos/echo-db";
1404
1435
  import { log as log12 } from "@dxos/log";
@@ -1413,22 +1444,21 @@ var __decorate7 = function(decorators, target, key, desc) {
1413
1444
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1414
1445
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1415
1446
  };
1416
- var NoopDataPipelineController = class {
1417
- async open(context) {
1418
- }
1419
- async close() {
1420
- }
1421
- };
1422
1447
  var MESSAGES_PER_SNAPSHOT = 10;
1423
1448
  var AUTOMATIC_SNAPSHOT_DEBOUNCE_INTERVAL = 5e3;
1424
1449
  var TIMEFRAME_SAVE_DEBOUNCE_INTERVAL = 500;
1425
- var DataPipelineControllerImpl = class DataPipelineControllerImpl2 {
1450
+ var DISABLE_SNAPSHOT_CACHE = false;
1451
+ var DataPipeline = class DataPipeline2 {
1426
1452
  constructor(_params) {
1427
1453
  this._params = _params;
1428
- this._ctx = new Context2();
1454
+ this._ctx = new Context3();
1429
1455
  this._lastAutomaticSnapshotTimeframe = new Timeframe3();
1456
+ this._isOpen = false;
1430
1457
  this.onTimeframeReached = new Event3();
1431
1458
  }
1459
+ get isOpen() {
1460
+ return this._isOpen;
1461
+ }
1432
1462
  get pipelineState() {
1433
1463
  var _a;
1434
1464
  return (_a = this._pipeline) == null ? void 0 : _a.state;
@@ -1441,14 +1471,25 @@ var DataPipelineControllerImpl = class DataPipelineControllerImpl2 {
1441
1471
  var _a;
1442
1472
  return snapshotTimeframeToStartingTimeframe((_a = this.snapshotTimeframe) != null ? _a : new Timeframe3());
1443
1473
  }
1474
+ setTargetTimeframe(timeframe) {
1475
+ var _a;
1476
+ this._targetTimeframe = timeframe;
1477
+ (_a = this._pipeline) == null ? void 0 : _a.state.setTargetTimeframe(timeframe);
1478
+ }
1444
1479
  async open(spaceContext) {
1445
1480
  var _a, _b, _c, _d;
1481
+ if (this._isOpen) {
1482
+ return;
1483
+ }
1446
1484
  this._spaceContext = spaceContext;
1447
1485
  if (this._params.snapshotId) {
1448
1486
  this._snapshot = await this._params.snapshotManager.load(this._params.snapshotId);
1449
1487
  this._lastAutomaticSnapshotTimeframe = (_b = (_a = this._snapshot) == null ? void 0 : _a.timeframe) != null ? _b : new Timeframe3();
1450
1488
  }
1451
1489
  this._pipeline = await this._spaceContext.openPipeline(this.getStartTimeframe());
1490
+ if (this._targetTimeframe) {
1491
+ this._pipeline.state.setTargetTimeframe(this._targetTimeframe);
1492
+ }
1452
1493
  const feedWriter = createMappedFeedWriter((data) => ({
1453
1494
  data
1454
1495
  }), (_c = this._pipeline.writer) != null ? _c : failUndefined3());
@@ -1459,30 +1500,33 @@ var DataPipelineControllerImpl = class DataPipelineControllerImpl2 {
1459
1500
  await this._consumePipeline();
1460
1501
  });
1461
1502
  this._createPeriodicSnapshots();
1503
+ this._isOpen = true;
1462
1504
  }
1463
1505
  _createPeriodicSnapshots() {
1464
1506
  this.onTimeframeReached.debounce(TIMEFRAME_SAVE_DEBOUNCE_INTERVAL).on(this._ctx, async () => {
1465
1507
  await this._saveLatestTimeframe();
1466
1508
  });
1467
- this.onTimeframeReached.debounce(AUTOMATIC_SNAPSHOT_DEBOUNCE_INTERVAL).on(this._ctx, async () => {
1468
- var _a, _b;
1469
- const latestTimeframe = (_a = this._pipeline) == null ? void 0 : _a.state.timeframe;
1470
- if (!latestTimeframe) {
1471
- return;
1472
- }
1473
- if (latestTimeframe.totalMessages() - this._lastAutomaticSnapshotTimeframe.totalMessages() > MESSAGES_PER_SNAPSHOT) {
1474
- const snapshot = await this._saveSnapshot();
1475
- this._lastAutomaticSnapshotTimeframe = (_b = snapshot.timeframe) != null ? _b : failUndefined3();
1476
- log12("save", {
1477
- snapshot
1478
- }, {
1479
- file: "data-pipeline-controller.ts",
1480
- line: 149,
1481
- scope: this,
1482
- callSite: (f, a) => f(...a)
1483
- });
1484
- }
1485
- });
1509
+ if (!DISABLE_SNAPSHOT_CACHE) {
1510
+ this.onTimeframeReached.debounce(AUTOMATIC_SNAPSHOT_DEBOUNCE_INTERVAL).on(this._ctx, async () => {
1511
+ var _a, _b;
1512
+ const latestTimeframe = (_a = this._pipeline) == null ? void 0 : _a.state.timeframe;
1513
+ if (!latestTimeframe) {
1514
+ return;
1515
+ }
1516
+ if (latestTimeframe.totalMessages() - this._lastAutomaticSnapshotTimeframe.totalMessages() > MESSAGES_PER_SNAPSHOT) {
1517
+ const snapshot = await this._saveSnapshot();
1518
+ this._lastAutomaticSnapshotTimeframe = (_b = snapshot.timeframe) != null ? _b : failUndefined3();
1519
+ log12("save", {
1520
+ snapshot
1521
+ }, {
1522
+ file: "data-pipeline.ts",
1523
+ line: 161,
1524
+ scope: this,
1525
+ callSite: (f, a) => f(...a)
1526
+ });
1527
+ }
1528
+ });
1529
+ }
1486
1530
  }
1487
1531
  async _saveSnapshot() {
1488
1532
  const snapshot = await this.createSnapshot();
@@ -1491,21 +1535,41 @@ var DataPipelineControllerImpl = class DataPipelineControllerImpl2 {
1491
1535
  return snapshot;
1492
1536
  }
1493
1537
  async _saveLatestTimeframe() {
1494
- var _a;
1538
+ var _a, _b;
1495
1539
  const latestTimeframe = (_a = this._pipeline) == null ? void 0 : _a.state.timeframe;
1540
+ log12("save latest timeframe", {
1541
+ latestTimeframe,
1542
+ spaceKey: this._params.spaceKey
1543
+ }, {
1544
+ file: "data-pipeline.ts",
1545
+ line: 176,
1546
+ scope: this,
1547
+ callSite: (f, a) => f(...a)
1548
+ });
1496
1549
  if (latestTimeframe) {
1497
- await this._params.metadataStore.setSpaceLatestTimeframe(this._params.spaceKey, latestTimeframe);
1550
+ const newTimeframe = Timeframe3.merge((_b = this._targetTimeframe) != null ? _b : new Timeframe3(), latestTimeframe);
1551
+ await this._params.metadataStore.setSpaceLatestTimeframe(this._params.spaceKey, newTimeframe);
1498
1552
  }
1499
1553
  }
1500
1554
  async close() {
1501
1555
  var _a, _b, _c;
1556
+ if (!this._isOpen) {
1557
+ return;
1558
+ }
1559
+ log12("close", {}, {
1560
+ file: "data-pipeline.ts",
1561
+ line: 188,
1562
+ scope: this,
1563
+ callSite: (f, a) => f(...a)
1564
+ });
1565
+ this._isOpen = false;
1502
1566
  try {
1503
1567
  await this._saveLatestTimeframe();
1504
1568
  await this._saveSnapshot();
1505
1569
  } catch (err) {
1506
1570
  log12.catch(err, {}, {
1507
- file: "data-pipeline-controller.ts",
1508
- line: 173,
1571
+ file: "data-pipeline.ts",
1572
+ line: 195,
1509
1573
  scope: this,
1510
1574
  callSite: (f, a) => f(...a)
1511
1575
  });
@@ -1518,6 +1582,7 @@ var DataPipelineControllerImpl = class DataPipelineControllerImpl2 {
1518
1582
  }
1519
1583
  createSnapshot() {
1520
1584
  var _a, _b;
1585
+ assert9(this.databaseBackend, "Database backend is not initialized.");
1521
1586
  return {
1522
1587
  spaceKey: this._params.spaceKey.asUint8Array(),
1523
1588
  timeframe: (_b = (_a = this._pipeline) == null ? void 0 : _a.state.timeframe) != null ? _b : new Timeframe3(),
@@ -1531,8 +1596,8 @@ var DataPipelineControllerImpl = class DataPipelineControllerImpl2 {
1531
1596
  log12("processing message", {
1532
1597
  msg
1533
1598
  }, {
1534
- file: "data-pipeline-controller.ts",
1535
- line: 194,
1599
+ file: "data-pipeline.ts",
1600
+ line: 217,
1536
1601
  scope: this,
1537
1602
  callSite: (f, a) => f(...a)
1538
1603
  });
@@ -1543,15 +1608,15 @@ var DataPipelineControllerImpl = class DataPipelineControllerImpl2 {
1543
1608
  log12.error("Could not find feed.", {
1544
1609
  feedKey
1545
1610
  }, {
1546
- file: "data-pipeline-controller.ts",
1547
- line: 200,
1611
+ file: "data-pipeline.ts",
1612
+ line: 223,
1548
1613
  scope: this,
1549
1614
  callSite: (f, a) => f(...a)
1550
1615
  });
1551
1616
  continue;
1552
1617
  }
1553
1618
  await this.databaseBackend.echoProcessor({
1554
- data: data.payload.data.object,
1619
+ batch: data.payload.data.batch,
1555
1620
  meta: {
1556
1621
  feedKey,
1557
1622
  seq,
@@ -1563,8 +1628,8 @@ var DataPipelineControllerImpl = class DataPipelineControllerImpl2 {
1563
1628
  }
1564
1629
  } catch (err) {
1565
1630
  log12.catch(err, {}, {
1566
- file: "data-pipeline-controller.ts",
1567
- line: 216,
1631
+ file: "data-pipeline.ts",
1632
+ line: 239,
1568
1633
  scope: this,
1569
1634
  callSite: (f, a) => f(...a)
1570
1635
  });
@@ -1576,9 +1641,15 @@ var DataPipelineControllerImpl = class DataPipelineControllerImpl2 {
1576
1641
  await this._pipeline.state.waitUntilTimeframe(timeframe);
1577
1642
  }
1578
1643
  };
1579
- DataPipelineControllerImpl = __decorate7([
1644
+ __decorate7([
1645
+ synchronized4
1646
+ ], DataPipeline.prototype, "open", null);
1647
+ __decorate7([
1648
+ synchronized4
1649
+ ], DataPipeline.prototype, "close", null);
1650
+ DataPipeline = __decorate7([
1580
1651
  trackLeaks4("open", "close")
1581
- ], DataPipelineControllerImpl);
1652
+ ], DataPipeline);
1582
1653
  var snapshotTimeframeToStartingTimeframe = (snapshotTimeframe) => {
1583
1654
  return snapshotTimeframe.map(([key, seq]) => [
1584
1655
  key,
@@ -1611,7 +1682,6 @@ export {
1611
1682
  SnapshotStore,
1612
1683
  DataServiceSubscriptions,
1613
1684
  DataServiceImpl,
1614
- NoopDataPipelineController,
1615
- DataPipelineControllerImpl
1685
+ DataPipeline
1616
1686
  };
1617
- //# sourceMappingURL=chunk-L44NG4N6.mjs.map
1687
+ //# sourceMappingURL=chunk-EM5HSJ7J.mjs.map