@dxos/echo-pipeline 0.1.56-main.c19b7cd → 0.1.56-main.c277f68

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 (40) hide show
  1. package/dist/lib/browser/{chunk-EJ35NHZV.mjs → chunk-GDF4DQU2.mjs} +296 -272
  2. package/dist/lib/browser/chunk-GDF4DQU2.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +1 -1
  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 +12 -17
  7. package/dist/lib/browser/testing/index.mjs.map +1 -1
  8. package/dist/lib/node/index.cjs +300 -276
  9. package/dist/lib/node/index.cjs.map +3 -3
  10. package/dist/lib/node/meta.json +1 -1
  11. package/dist/lib/node/testing/index.cjs +313 -294
  12. package/dist/lib/node/testing/index.cjs.map +3 -3
  13. package/dist/types/src/db-host/data-service-host.d.ts.map +1 -1
  14. package/dist/types/src/pipeline/pipeline-stress.test.d.ts +2 -0
  15. package/dist/types/src/pipeline/pipeline-stress.test.d.ts.map +1 -0
  16. package/dist/types/src/pipeline/pipeline.d.ts +4 -3
  17. package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
  18. package/dist/types/src/space/control-pipeline.d.ts +4 -0
  19. package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
  20. package/dist/types/src/space/data-pipeline.d.ts +2 -0
  21. package/dist/types/src/space/data-pipeline.d.ts.map +1 -1
  22. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  23. package/dist/types/src/space/space-protocol.d.ts.map +1 -1
  24. package/dist/types/src/space/space.d.ts.map +1 -1
  25. package/dist/types/src/testing/database-test-rig.d.ts +4 -1
  26. package/dist/types/src/testing/database-test-rig.d.ts.map +1 -1
  27. package/package.json +32 -32
  28. package/src/db-host/data-service-host.ts +9 -2
  29. package/src/metadata/metadata-store.ts +1 -1
  30. package/src/pipeline/pipeline-stress.test.ts +226 -0
  31. package/src/pipeline/pipeline.test.ts +2 -214
  32. package/src/pipeline/pipeline.ts +47 -22
  33. package/src/space/control-pipeline.ts +47 -22
  34. package/src/space/data-pipeline.ts +20 -10
  35. package/src/space/space-manager.ts +1 -0
  36. package/src/space/space-protocol.ts +3 -1
  37. package/src/space/space.ts +1 -0
  38. package/src/testing/database-test-rig.ts +27 -2
  39. package/src/tests/database-unit.test.ts +39 -0
  40. package/dist/lib/browser/chunk-EJ35NHZV.mjs.map +0 -7
@@ -39,6 +39,7 @@ import { Context } from "@dxos/context";
39
39
  import { tagMutationsInBatch, setMetadataOnObject } from "@dxos/echo-db";
40
40
  import { invariant as invariant2 } from "@dxos/invariant";
41
41
  import { log } from "@dxos/log";
42
+ import { EchoEvent } from "@dxos/protocols/proto/dxos/echo/service";
42
43
  import { ComplexMap } from "@dxos/util";
43
44
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/data-service-host.ts";
44
45
  var DataServiceHost = class {
@@ -66,12 +67,19 @@ var DataServiceHost = class {
66
67
  objects
67
68
  }
68
69
  });
70
+ this._itemDemuxer.snapshot.on(ctx, (snapshot) => {
71
+ next({
72
+ action: EchoEvent.DatabaseAction.RESET,
73
+ batch: {
74
+ objects: snapshot.items
75
+ }
76
+ });
77
+ });
69
78
  this._itemDemuxer.mutation.on(ctx, (message) => {
70
- var _a;
71
79
  const { batch, meta } = message;
72
80
  invariant2(!meta.clientTag, "Unexpected client tag in mutation message", {
73
81
  F: __dxlog_file2,
74
- L: 61,
82
+ L: 68,
75
83
  S: this,
76
84
  A: [
77
85
  "!(meta as any).clientTag",
@@ -79,11 +87,11 @@ var DataServiceHost = class {
79
87
  ]
80
88
  });
81
89
  log("message", {
82
- batch,
90
+ batch: batch.objects?.length,
83
91
  meta
84
92
  }, {
85
93
  F: __dxlog_file2,
86
- L: 62,
94
+ L: 69,
87
95
  S: this,
88
96
  C: (f, a) => f(...a)
89
97
  });
@@ -91,7 +99,7 @@ var DataServiceHost = class {
91
99
  message.meta.feedKey,
92
100
  message.meta.seq
93
101
  ]);
94
- (_a = batch.objects) == null ? void 0 : _a.forEach((object) => {
102
+ batch.objects?.forEach((object) => {
95
103
  setMetadataOnObject(object, {
96
104
  ...meta
97
105
  });
@@ -109,10 +117,9 @@ var DataServiceHost = class {
109
117
  });
110
118
  }
111
119
  async write(request) {
112
- var _a, _b;
113
120
  invariant2(!this._ctx.disposed, "Cannot write to closed DataServiceHost", {
114
121
  F: __dxlog_file2,
115
- L: 88,
122
+ L: 95,
116
123
  S: this,
117
124
  A: [
118
125
  "!this._ctx.disposed",
@@ -121,7 +128,7 @@ var DataServiceHost = class {
121
128
  });
122
129
  invariant2(this._writeStream, "Cannot write mutations in readonly mode", {
123
130
  F: __dxlog_file2,
124
- L: 89,
131
+ L: 96,
125
132
  S: this,
126
133
  A: [
127
134
  "this._writeStream",
@@ -130,10 +137,10 @@ var DataServiceHost = class {
130
137
  });
131
138
  log("write", {
132
139
  clientTag: request.clientTag,
133
- objectCount: (_b = (_a = request.batch.objects) == null ? void 0 : _a.length) != null ? _b : 0
140
+ objectCount: request.batch.objects?.length ?? 0
134
141
  }, {
135
142
  F: __dxlog_file2,
136
- L: 91,
143
+ L: 98,
137
144
  S: this,
138
145
  C: (f, a) => f(...a)
139
146
  });
@@ -147,7 +154,7 @@ var DataServiceHost = class {
147
154
  seq: receipt2.seq
148
155
  }, {
149
156
  F: __dxlog_file2,
150
- L: 100,
157
+ L: 107,
151
158
  S: this,
152
159
  C: (f, a) => f(...a)
153
160
  });
@@ -161,24 +168,18 @@ var DataServiceHost = class {
161
168
  return receipt;
162
169
  }
163
170
  };
164
- var createDataMessage = (batch) => {
165
- var _a;
166
- return {
167
- batch: {
168
- objects: (_a = batch.objects) == null ? void 0 : _a.map((object) => {
169
- var _a2;
170
- return {
171
- ...object,
172
- mutations: (_a2 = object.mutations) == null ? void 0 : _a2.map((mutation) => ({
173
- ...mutation,
174
- meta: void 0
175
- })),
176
- meta: void 0
177
- };
178
- })
179
- }
180
- };
181
- };
171
+ var createDataMessage = (batch) => ({
172
+ batch: {
173
+ objects: batch.objects?.map((object) => ({
174
+ ...object,
175
+ mutations: object.mutations?.map((mutation) => ({
176
+ ...mutation,
177
+ meta: void 0
178
+ })),
179
+ meta: void 0
180
+ }))
181
+ }
182
+ });
182
183
 
183
184
  // packages/core/echo/echo-pipeline/src/db-host/database-host.ts
184
185
  import { ItemDemuxer } from "@dxos/echo-db";
@@ -207,8 +208,7 @@ var DatabaseHost = class {
207
208
  return this._itemDemuxer.createSnapshot();
208
209
  }
209
210
  createDataServiceHost() {
210
- var _a;
211
- return new DataServiceHost(this._itemManager, this._itemDemuxer, (_a = this._outboundStream) != null ? _a : void 0);
211
+ return new DataServiceHost(this._itemManager, this._itemDemuxer, this._outboundStream ?? void 0);
212
212
  }
213
213
  };
214
214
 
@@ -354,7 +354,7 @@ var DataServiceSubscriptions = class {
354
354
  C: (f, a) => f(...a)
355
355
  });
356
356
  const host = this._spaces.get(spaceKey);
357
- await (host == null ? void 0 : host.close());
357
+ await host?.close();
358
358
  this._spaces.delete(spaceKey);
359
359
  }
360
360
  getDataService(spaceKey) {
@@ -366,7 +366,6 @@ var DataServiceImpl = class {
366
366
  this._subscriptions = _subscriptions;
367
367
  }
368
368
  subscribe(request) {
369
- var _a;
370
369
  invariant3(request.spaceKey, void 0, {
371
370
  F: __dxlog_file3,
372
371
  L: 56,
@@ -376,11 +375,10 @@ var DataServiceImpl = class {
376
375
  ""
377
376
  ]
378
377
  });
379
- const host = (_a = this._subscriptions.getDataService(request.spaceKey)) != null ? _a : raise(new Error(`space not found: ${request.spaceKey}`));
378
+ const host = this._subscriptions.getDataService(request.spaceKey) ?? raise(new Error(`space not found: ${request.spaceKey}`));
380
379
  return host.subscribe();
381
380
  }
382
381
  write(request) {
383
- var _a;
384
382
  invariant3(request.spaceKey, void 0, {
385
383
  F: __dxlog_file3,
386
384
  L: 63,
@@ -399,7 +397,7 @@ var DataServiceImpl = class {
399
397
  ""
400
398
  ]
401
399
  });
402
- const host = (_a = this._subscriptions.getDataService(request.spaceKey)) != null ? _a : raise(new Error(`space not found: ${request.spaceKey}`));
400
+ const host = this._subscriptions.getDataService(request.spaceKey) ?? raise(new Error(`space not found: ${request.spaceKey}`));
403
401
  return host.write(request);
404
402
  }
405
403
  };
@@ -427,8 +425,8 @@ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipelin
427
425
  var emptyEchoMetadata = () => ({
428
426
  version: STORAGE_VERSION,
429
427
  spaces: [],
430
- created: new Date(),
431
- updated: new Date()
428
+ created: /* @__PURE__ */ new Date(),
429
+ updated: /* @__PURE__ */ new Date()
432
430
  });
433
431
  var EchoMetadata = schema4.getCodecForType("dxos.echo.metadata.EchoMetadata");
434
432
  var MetadataStore = class {
@@ -442,22 +440,19 @@ var MetadataStore = class {
442
440
  return this._metadata;
443
441
  }
444
442
  get version() {
445
- var _a;
446
- return (_a = this._metadata.version) != null ? _a : 0;
443
+ return this._metadata.version ?? 0;
447
444
  }
448
445
  /**
449
446
  * Returns a list of currently saved spaces. The list and objects in it can be modified addSpace and
450
447
  * addSpaceFeed functions.
451
448
  */
452
449
  get spaces() {
453
- var _a;
454
- return (_a = this._metadata.spaces) != null ? _a : [];
450
+ return this._metadata.spaces ?? [];
455
451
  }
456
452
  /**
457
453
  * Loads metadata from persistent storage.
458
454
  */
459
455
  async load() {
460
- var _a;
461
456
  const file = this._directory.getOrCreateFile("EchoMetadata");
462
457
  try {
463
458
  const { size: fileLength } = await file.stat();
@@ -476,7 +471,10 @@ var MetadataStore = class {
476
471
  C: (f, a) => f(...a)
477
472
  });
478
473
  if (fileLength < dataSize + 8) {
479
- throw new DataCorruptionError("Metadata size is smaller than expected.");
474
+ throw new DataCorruptionError("Metadata size is smaller than expected.", {
475
+ fileLength,
476
+ dataSize
477
+ });
480
478
  }
481
479
  const data = await file.read(8, dataSize);
482
480
  const calculatedChecksum = CRC32.buf(data);
@@ -484,9 +482,8 @@ var MetadataStore = class {
484
482
  throw new DataCorruptionError("Metadata checksum is invalid.");
485
483
  }
486
484
  this._metadata = EchoMetadata.decode(data);
487
- (_a = this._metadata.spaces) == null ? void 0 : _a.forEach((space) => {
488
- var _a2;
489
- (_a2 = space.state) != null ? _a2 : space.state = SpaceState.ACTIVE;
485
+ this._metadata.spaces?.forEach((space) => {
486
+ space.state ??= SpaceState.ACTIVE;
490
487
  });
491
488
  } catch (err) {
492
489
  log3.error("failed to load metadata", {
@@ -503,12 +500,11 @@ var MetadataStore = class {
503
500
  }
504
501
  }
505
502
  async _save() {
506
- var _a;
507
503
  const data = {
508
504
  ...this._metadata,
509
505
  version: STORAGE_VERSION,
510
- created: (_a = this._metadata.created) != null ? _a : new Date(),
511
- updated: new Date()
506
+ created: this._metadata.created ?? /* @__PURE__ */ new Date(),
507
+ updated: /* @__PURE__ */ new Date()
512
508
  };
513
509
  this.update.emit(data);
514
510
  const file = this._directory.getOrCreateFile("EchoMetadata");
@@ -534,8 +530,7 @@ var MetadataStore = class {
534
530
  }
535
531
  }
536
532
  _getSpace(spaceKey) {
537
- var _a;
538
- if ((_a = this._metadata.identity) == null ? void 0 : _a.haloSpace.key.equals(spaceKey)) {
533
+ if (this._metadata.identity?.haloSpace.key.equals(spaceKey)) {
539
534
  return this._metadata.identity.haloSpace;
540
535
  }
541
536
  const space = this.spaces.find((space2) => space2.key === spaceKey);
@@ -580,8 +575,7 @@ var MetadataStore = class {
580
575
  await this._save();
581
576
  }
582
577
  async addSpace(record) {
583
- var _a, _b, _c;
584
- invariant4(!((_a = this._metadata.spaces) != null ? _a : []).find((space) => space.key === record.key), "Cannot overwrite existing space in metadata", {
578
+ invariant4(!(this._metadata.spaces ?? []).find((space) => space.key === record.key), "Cannot overwrite existing space in metadata", {
585
579
  F: __dxlog_file4,
586
580
  L: 162,
587
581
  S: this,
@@ -590,7 +584,7 @@ var MetadataStore = class {
590
584
  "'Cannot overwrite existing space in metadata'"
591
585
  ]
592
586
  });
593
- ((_c = (_b = this._metadata).spaces) != null ? _c : _b.spaces = []).push(record);
587
+ (this._metadata.spaces ??= []).push(record);
594
588
  await this._save();
595
589
  }
596
590
  async setSpaceDataLatestTimeframe(spaceKey, timeframe) {
@@ -825,7 +819,6 @@ var PipelineState = class {
825
819
  * @param timeout Timeout in milliseconds to specify the maximum wait time.
826
820
  */
827
821
  async waitUntilReachedTargetTimeframe({ ctx = new Context2(), timeout, breakOnStall = true } = {}) {
828
- var _a;
829
822
  log6("waitUntilReachedTargetTimeframe", {
830
823
  timeout,
831
824
  current: this.timeframe,
@@ -836,7 +829,7 @@ var PipelineState = class {
836
829
  S: this,
837
830
  C: (f, a) => f(...a)
838
831
  });
839
- (_a = this._reachedTargetPromise) != null ? _a : this._reachedTargetPromise = Promise.race([
832
+ this._reachedTargetPromise ??= Promise.race([
840
833
  this._timeframeClock.update.waitForCondition(() => {
841
834
  return Timeframe2.dependencies(this.targetTimeframe, this.timeframe).isEmpty();
842
835
  }),
@@ -883,9 +876,11 @@ var Pipeline = class {
883
876
  // Waits for the message consumer to process the message and yield control back to the pipeline.
884
877
  this._processingTrigger = new Trigger().wake();
885
878
  this._pauseTrigger = new Trigger().wake();
879
+ // Pending downloads.
880
+ this._downloads = new ComplexMap3((value) => PublicKey3.hash(value.key));
886
881
  this._isStopping = false;
887
882
  this._isStarted = false;
888
- this._isOpen = false;
883
+ this._isBeingConsumed = false;
889
884
  this._isPaused = false;
890
885
  }
891
886
  get state() {
@@ -894,7 +889,7 @@ var Pipeline = class {
894
889
  get writer() {
895
890
  invariant6(this._writer, "Writer not set.", {
896
891
  F: __dxlog_file7,
897
- L: 230,
892
+ L: 233,
898
893
  S: this,
899
894
  A: [
900
895
  "this._writer",
@@ -916,12 +911,14 @@ var Pipeline = class {
916
911
  if (this._feedSetIterator) {
917
912
  await this._feedSetIterator.addFeed(feed);
918
913
  }
919
- this._setFeedDownloadState(feed);
914
+ if (this._isStarted && !this._isPaused) {
915
+ this._setFeedDownloadState(feed);
916
+ }
920
917
  }
921
918
  setWriteFeed(feed) {
922
919
  invariant6(!this._writer, "Writer already set.", {
923
920
  F: __dxlog_file7,
924
- L: 253,
921
+ L: 260,
925
922
  S: this,
926
923
  A: [
927
924
  "!this._writer",
@@ -930,7 +927,7 @@ var Pipeline = class {
930
927
  });
931
928
  invariant6(feed.properties.writable, "Feed must be writable.", {
932
929
  F: __dxlog_file7,
933
- L: 254,
930
+ L: 261,
934
931
  S: this,
935
932
  A: [
936
933
  "feed.properties.writable",
@@ -945,7 +942,7 @@ var Pipeline = class {
945
942
  async start() {
946
943
  invariant6(!this._isStarted, "Pipeline is already started.", {
947
944
  F: __dxlog_file7,
948
- L: 267,
945
+ L: 274,
949
946
  S: this,
950
947
  A: [
951
948
  "!this._isStarted",
@@ -954,7 +951,7 @@ var Pipeline = class {
954
951
  });
955
952
  log6("starting...", void 0, {
956
953
  F: __dxlog_file7,
957
- L: 268,
954
+ L: 275,
958
955
  S: this,
959
956
  C: (f, a) => f(...a)
960
957
  });
@@ -963,21 +960,29 @@ var Pipeline = class {
963
960
  this._isStarted = true;
964
961
  log6("started", void 0, {
965
962
  F: __dxlog_file7,
966
- L: 272,
963
+ L: 279,
967
964
  S: this,
968
965
  C: (f, a) => f(...a)
969
966
  });
967
+ if (!this._isPaused) {
968
+ for (const feed of this._feeds.values()) {
969
+ this._setFeedDownloadState(feed);
970
+ }
971
+ }
970
972
  }
971
973
  async stop() {
972
- var _a;
973
974
  log6("stopping...", void 0, {
974
975
  F: __dxlog_file7,
975
- L: 277,
976
+ L: 290,
976
977
  S: this,
977
978
  C: (f, a) => f(...a)
978
979
  });
979
980
  this._isStopping = true;
980
- await ((_a = this._feedSetIterator) == null ? void 0 : _a.close());
981
+ for (const [feed, handle] of this._downloads.entries()) {
982
+ feed.undownload(handle);
983
+ }
984
+ this._downloads.clear();
985
+ await this._feedSetIterator?.close();
981
986
  await this._processingTrigger.wait();
982
987
  await this._state._ctx.dispose();
983
988
  this._state._ctx = new Context2();
@@ -985,7 +990,7 @@ var Pipeline = class {
985
990
  this._isStarted = false;
986
991
  log6("stopped", void 0, {
987
992
  F: __dxlog_file7,
988
- L: 285,
993
+ L: 302,
989
994
  S: this,
990
995
  C: (f, a) => f(...a)
991
996
  });
@@ -997,7 +1002,7 @@ var Pipeline = class {
997
1002
  async setCursor(timeframe) {
998
1003
  invariant6(!this._isStarted || this._isPaused, "Invalid state.", {
999
1004
  F: __dxlog_file7,
1000
- L: 294,
1005
+ L: 311,
1001
1006
  S: this,
1002
1007
  A: [
1003
1008
  "!this._isStarted || this._isPaused",
@@ -1006,9 +1011,6 @@ var Pipeline = class {
1006
1011
  });
1007
1012
  this._state._startTimeframe = timeframe;
1008
1013
  this._timeframeClock.setTimeframe(timeframe);
1009
- for (const feed of this._feeds.values()) {
1010
- this._setFeedDownloadState(feed);
1011
- }
1012
1014
  if (this._feedSetIterator) {
1013
1015
  await this._feedSetIterator.close();
1014
1016
  await this._initIterator();
@@ -1019,15 +1021,6 @@ var Pipeline = class {
1019
1021
  * Calling pause while processing will cause a deadlock.
1020
1022
  */
1021
1023
  async pause() {
1022
- invariant6(this._isStarted, "Pipeline is not open.", {
1023
- F: __dxlog_file7,
1024
- L: 316,
1025
- S: this,
1026
- A: [
1027
- "this._isStarted",
1028
- "'Pipeline is not open.'"
1029
- ]
1030
- });
1031
1024
  if (this._isPaused) {
1032
1025
  return;
1033
1026
  }
@@ -1036,18 +1029,9 @@ var Pipeline = class {
1036
1029
  this._isPaused = true;
1037
1030
  }
1038
1031
  async unpause() {
1039
- invariant6(this._isStarted, "Pipeline is not open.", {
1040
- F: __dxlog_file7,
1041
- L: 328,
1042
- S: this,
1043
- A: [
1044
- "this._isStarted",
1045
- "'Pipeline is not open.'"
1046
- ]
1047
- });
1048
1032
  invariant6(this._isPaused, "Pipeline is not paused.", {
1049
1033
  F: __dxlog_file7,
1050
- L: 329,
1034
+ L: 340,
1051
1035
  S: this,
1052
1036
  A: [
1053
1037
  "this._isPaused",
@@ -1056,25 +1040,28 @@ var Pipeline = class {
1056
1040
  });
1057
1041
  this._pauseTrigger.wake();
1058
1042
  this._isPaused = false;
1043
+ for (const feed of this._feeds.values()) {
1044
+ this._setFeedDownloadState(feed);
1045
+ }
1059
1046
  }
1060
1047
  /**
1061
1048
  * Starts to iterate over the ordered messages from the added feeds.
1062
1049
  * Updates the timeframe clock after the message has bee processed.
1063
1050
  */
1064
1051
  async *consume() {
1065
- invariant6(!this._isOpen, "Pipeline is already being consumed.", {
1052
+ invariant6(!this._isBeingConsumed, "Pipeline is already being consumed.", {
1066
1053
  F: __dxlog_file7,
1067
- L: 340,
1054
+ L: 355,
1068
1055
  S: this,
1069
1056
  A: [
1070
- "!this._isOpen",
1057
+ "!this._isBeingConsumed",
1071
1058
  "'Pipeline is already being consumed.'"
1072
1059
  ]
1073
1060
  });
1074
- this._isOpen = true;
1061
+ this._isBeingConsumed = true;
1075
1062
  invariant6(this._feedSetIterator, "Iterator not initialized.", {
1076
1063
  F: __dxlog_file7,
1077
- L: 343,
1064
+ L: 358,
1078
1065
  S: this,
1079
1066
  A: [
1080
1067
  "this._feedSetIterator",
@@ -1088,7 +1075,7 @@ var Pipeline = class {
1088
1075
  if (lastFeedSetIterator !== this._feedSetIterator) {
1089
1076
  invariant6(this._feedSetIterator, "Iterator not initialized.", {
1090
1077
  F: __dxlog_file7,
1091
- L: 352,
1078
+ L: 367,
1092
1079
  S: this,
1093
1080
  A: [
1094
1081
  "this._feedSetIterator",
@@ -1100,7 +1087,7 @@ var Pipeline = class {
1100
1087
  }
1101
1088
  const { done, value } = await iterable.next();
1102
1089
  if (!done) {
1103
- const block = value != null ? value : failUndefined();
1090
+ const block = value ?? failUndefined();
1104
1091
  this._processingTrigger.reset();
1105
1092
  this._timeframeClock.updatePendingTimeframe(PublicKey3.from(block.feedKey), block.seq);
1106
1093
  yield block;
@@ -1108,33 +1095,40 @@ var Pipeline = class {
1108
1095
  this._timeframeClock.updateTimeframe();
1109
1096
  }
1110
1097
  }
1111
- this._isOpen = false;
1098
+ this._isBeingConsumed = false;
1112
1099
  }
1113
1100
  _setFeedDownloadState(feed) {
1114
- var _a;
1101
+ let handle = this._downloads.get(feed);
1102
+ if (handle) {
1103
+ feed.undownload(handle);
1104
+ }
1115
1105
  const timeframe = this._state._startTimeframe;
1116
- const seq = (_a = timeframe.get(feed.key)) != null ? _a : 0;
1117
- feed.undownload({
1118
- callback: () => log6("undownload", void 0, {
1119
- F: __dxlog_file7,
1120
- L: 377,
1121
- S: this,
1122
- C: (f, a) => f(...a)
1123
- })
1106
+ const seq = timeframe.get(feed.key) ?? -1;
1107
+ log6.info("download", {
1108
+ feed: feed.key.truncate(),
1109
+ seq,
1110
+ length: feed.length
1111
+ }, {
1112
+ F: __dxlog_file7,
1113
+ L: 396,
1114
+ S: this,
1115
+ C: (f, a) => f(...a)
1124
1116
  });
1125
- feed.download({
1117
+ handle = feed.download({
1126
1118
  start: seq + 1,
1127
1119
  linear: true
1128
- }).catch((err) => {
1129
- log6("failed to download feed", {
1130
- err
1131
- }, {
1132
- F: __dxlog_file7,
1133
- L: 379,
1134
- S: this,
1135
- C: (f, a) => f(...a)
1136
- });
1120
+ }, (err, data) => {
1121
+ if (err) {
1122
+ } else {
1123
+ log6.info("data", data, {
1124
+ F: __dxlog_file7,
1125
+ L: 401,
1126
+ S: this,
1127
+ C: (f, a) => f(...a)
1128
+ });
1129
+ }
1137
1130
  });
1131
+ this._downloads.set(feed, handle);
1138
1132
  }
1139
1133
  async _initIterator() {
1140
1134
  this._feedSetIterator = new FeedSetIterator(createMessageSelector(this._timeframeClock), {
@@ -1144,7 +1138,7 @@ var Pipeline = class {
1144
1138
  this._feedSetIterator.stalled.on((iterator) => {
1145
1139
  log6.warn(`Stalled after ${iterator.options.stallTimeout}ms with ${iterator.size} feeds.`, void 0, {
1146
1140
  F: __dxlog_file7,
1147
- L: 390,
1141
+ L: 415,
1148
1142
  S: this,
1149
1143
  C: (f, a) => f(...a)
1150
1144
  });
@@ -1236,7 +1230,7 @@ var AuthExtension = class extends RpcExtension {
1236
1230
  const { credential } = await this.rpc.AuthService.authenticate({
1237
1231
  challenge
1238
1232
  });
1239
- invariant7((credential == null ? void 0 : credential.length) > 0, "invalid credential", {
1233
+ invariant7(credential?.length > 0, "invalid credential", {
1240
1234
  F: __dxlog_file8,
1241
1235
  L: 69,
1242
1236
  S: this,
@@ -1278,11 +1272,12 @@ var AuthExtension = class extends RpcExtension {
1278
1272
  import { Event as Event4, scheduleTask as scheduleTask2, synchronized as synchronized3, trackLeaks as trackLeaks2 } from "@dxos/async";
1279
1273
  import { Context as Context4 } from "@dxos/context";
1280
1274
  import { checkCredentialType } from "@dxos/credentials";
1281
- import { getStateMachineFromItem, ItemManager } from "@dxos/echo-db";
1275
+ import { getStateMachineFromItem, ItemManager, TYPE_PROPERTIES } from "@dxos/echo-db";
1282
1276
  import { CancelledError } from "@dxos/errors";
1283
1277
  import { invariant as invariant8 } from "@dxos/invariant";
1284
- import { log as log8 } from "@dxos/log";
1278
+ import { log as log8, omit } from "@dxos/log";
1285
1279
  import { Timeframe as Timeframe3 } from "@dxos/timeframe";
1280
+ import { TimeSeriesCounter, TimeUsageCounter, trace } from "@dxos/tracing";
1286
1281
  import { tracer } from "@dxos/util";
1287
1282
  function _ts_decorate5(decorators, target, key, desc) {
1288
1283
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -1309,6 +1304,8 @@ var DataPipeline = class DataPipeline2 {
1309
1304
  this._lastTimeframeSaveTime = 0;
1310
1305
  this._lastSnapshotSaveTime = 0;
1311
1306
  this._lastProcessedEpoch = -1;
1307
+ this._usage = new TimeUsageCounter();
1308
+ this._mutations = new TimeSeriesCounter();
1312
1309
  this.currentEpoch = void 0;
1313
1310
  this.appliedEpoch = void 0;
1314
1311
  this.onNewEpoch = new Event4();
@@ -1320,13 +1317,11 @@ var DataPipeline = class DataPipeline2 {
1320
1317
  return this._pipeline;
1321
1318
  }
1322
1319
  get pipelineState() {
1323
- var _a;
1324
- return (_a = this._pipeline) == null ? void 0 : _a.state;
1320
+ return this._pipeline?.state;
1325
1321
  }
1326
1322
  setTargetTimeframe(timeframe) {
1327
- var _a;
1328
1323
  this._targetTimeframe = timeframe;
1329
- (_a = this._pipeline) == null ? void 0 : _a.state.setTargetTimeframe(timeframe);
1324
+ this._pipeline?.state.setTargetTimeframe(timeframe);
1330
1325
  }
1331
1326
  async processCredential(credential) {
1332
1327
  if (!checkCredentialType(credential, "dxos.halo.credentials.Epoch")) {
@@ -1343,8 +1338,8 @@ var DataPipeline = class DataPipeline2 {
1343
1338
  }
1344
1339
  this._pipeline = new Pipeline();
1345
1340
  await this._params.onPipelineCreated(this._pipeline);
1346
- await this._pipeline.start();
1347
1341
  await this._pipeline.pause();
1342
+ await this._pipeline.start();
1348
1343
  if (this._targetTimeframe) {
1349
1344
  this._pipeline.state.setTargetTimeframe(this._targetTimeframe);
1350
1345
  }
@@ -1352,7 +1347,7 @@ var DataPipeline = class DataPipeline2 {
1352
1347
  write: (data, options) => {
1353
1348
  invariant8(this._pipeline, "Pipeline is not initialized.", {
1354
1349
  F: __dxlog_file9,
1355
- L: 145,
1350
+ L: 154,
1356
1351
  S: this,
1357
1352
  A: [
1358
1353
  "this._pipeline",
@@ -1361,7 +1356,7 @@ var DataPipeline = class DataPipeline2 {
1361
1356
  });
1362
1357
  invariant8(this.currentEpoch, "Epoch is not initialized.", {
1363
1358
  F: __dxlog_file9,
1364
- L: 146,
1359
+ L: 155,
1365
1360
  S: this,
1366
1361
  A: [
1367
1362
  "this.currentEpoch",
@@ -1382,19 +1377,18 @@ var DataPipeline = class DataPipeline2 {
1382
1377
  this._isOpen = true;
1383
1378
  }
1384
1379
  async close() {
1385
- var _a, _b, _c;
1386
1380
  if (!this._isOpen) {
1387
1381
  return;
1388
1382
  }
1389
1383
  log8("close", void 0, {
1390
1384
  F: __dxlog_file9,
1391
- L: 170,
1385
+ L: 179,
1392
1386
  S: this,
1393
1387
  C: (f, a) => f(...a)
1394
1388
  });
1395
1389
  this._isOpen = false;
1396
1390
  await this._ctx.dispose();
1397
- await ((_a = this._pipeline) == null ? void 0 : _a.stop());
1391
+ await this._pipeline?.stop();
1398
1392
  try {
1399
1393
  await this._saveCache();
1400
1394
  if (this._pipeline) {
@@ -1403,13 +1397,13 @@ var DataPipeline = class DataPipeline2 {
1403
1397
  } catch (err) {
1404
1398
  log8.catch(err, void 0, {
1405
1399
  F: __dxlog_file9,
1406
- L: 183,
1400
+ L: 192,
1407
1401
  S: this,
1408
1402
  C: (f, a) => f(...a)
1409
1403
  });
1410
1404
  }
1411
- await ((_b = this.databaseHost) == null ? void 0 : _b.close());
1412
- await ((_c = this.itemManager) == null ? void 0 : _c.destroy());
1405
+ await this.databaseHost?.close();
1406
+ await this.itemManager?.destroy();
1413
1407
  this._ctx = new Context4();
1414
1408
  this._pipeline = void 0;
1415
1409
  this._targetTimeframe = void 0;
@@ -1427,7 +1421,7 @@ var DataPipeline = class DataPipeline2 {
1427
1421
  }
1428
1422
  invariant8(this._pipeline, "Pipeline is not initialized.", {
1429
1423
  F: __dxlog_file9,
1430
- L: 206,
1424
+ L: 215,
1431
1425
  S: this,
1432
1426
  A: [
1433
1427
  "this._pipeline",
@@ -1435,13 +1429,15 @@ var DataPipeline = class DataPipeline2 {
1435
1429
  ]
1436
1430
  });
1437
1431
  for await (const msg of this._pipeline.consume()) {
1432
+ const span = this._usage.beginRecording();
1433
+ this._mutations.inc();
1438
1434
  const { feedKey, seq, data } = msg;
1439
1435
  log8("processing message", {
1440
1436
  feedKey,
1441
1437
  seq
1442
1438
  }, {
1443
1439
  F: __dxlog_file9,
1444
- L: 209,
1440
+ L: 221,
1445
1441
  S: this,
1446
1442
  C: (f, a) => f(...a)
1447
1443
  });
@@ -1453,7 +1449,7 @@ var DataPipeline = class DataPipeline2 {
1453
1449
  feedKey
1454
1450
  }, {
1455
1451
  F: __dxlog_file9,
1456
- L: 215,
1452
+ L: 227,
1457
1453
  S: this,
1458
1454
  C: (f, a) => f(...a)
1459
1455
  });
@@ -1476,7 +1472,7 @@ var DataPipeline = class DataPipeline2 {
1476
1472
  spaceKey: this._params.spaceKey.toHex()
1477
1473
  }, {
1478
1474
  F: __dxlog_file9,
1479
- L: 232,
1475
+ L: 244,
1480
1476
  S: this,
1481
1477
  C: (f, a) => f(...a)
1482
1478
  });
@@ -1485,17 +1481,18 @@ var DataPipeline = class DataPipeline2 {
1485
1481
  } catch (err) {
1486
1482
  log8.catch(err, void 0, {
1487
1483
  F: __dxlog_file9,
1488
- L: 242,
1484
+ L: 254,
1489
1485
  S: this,
1490
1486
  C: (f, a) => f(...a)
1491
1487
  });
1492
1488
  }
1489
+ span.end();
1493
1490
  }
1494
1491
  }
1495
1492
  _createSnapshot() {
1496
1493
  invariant8(this.databaseHost, "Database backend is not initialized.", {
1497
1494
  F: __dxlog_file9,
1498
- L: 248,
1495
+ L: 262,
1499
1496
  S: this,
1500
1497
  A: [
1501
1498
  "this.databaseHost",
@@ -1509,26 +1506,22 @@ var DataPipeline = class DataPipeline2 {
1509
1506
  };
1510
1507
  }
1511
1508
  async _saveTargetTimeframe(timeframe) {
1512
- var _a;
1513
- const newTimeframe = Timeframe3.merge((_a = this._targetTimeframe) != null ? _a : new Timeframe3(), timeframe);
1509
+ const newTimeframe = Timeframe3.merge(this._targetTimeframe ?? new Timeframe3(), timeframe);
1514
1510
  await this._params.metadataStore.setSpaceDataLatestTimeframe(this._params.spaceKey, newTimeframe);
1515
1511
  this._targetTimeframe = newTimeframe;
1516
1512
  }
1517
1513
  async _saveCache() {
1518
- var _a;
1519
1514
  const cache = {};
1520
1515
  try {
1521
- const propertiesItem = this.itemManager.items.find((item) => {
1522
- var _a2, _b;
1523
- return ((_a2 = item.modelMeta) == null ? void 0 : _a2.type) === "dxos:model/document" && ((_b = getStateMachineFromItem(item)) == null ? void 0 : _b.snapshot()).type === "dxos.sdk.client.Properties";
1524
- });
1516
+ const propertiesItem = this.itemManager.items.find((item) => item.modelMeta?.type === "dxos:model/document" && // TODO(burdon): Document?
1517
+ (getStateMachineFromItem(item)?.snapshot()).type === TYPE_PROPERTIES);
1525
1518
  if (propertiesItem) {
1526
- cache.properties = (_a = getStateMachineFromItem(propertiesItem)) == null ? void 0 : _a.snapshot();
1519
+ cache.properties = getStateMachineFromItem(propertiesItem)?.snapshot();
1527
1520
  }
1528
1521
  } catch (err) {
1529
1522
  log8.warn("Failed to cache properties", err, {
1530
1523
  F: __dxlog_file9,
1531
- L: 277,
1524
+ L: 291,
1532
1525
  S: this,
1533
1526
  C: (f, a) => f(...a)
1534
1527
  });
@@ -1545,24 +1538,23 @@ var DataPipeline = class DataPipeline2 {
1545
1538
  }
1546
1539
  }
1547
1540
  async _processEpochInSeparateTask(epoch) {
1548
- var _a;
1549
1541
  if (epoch.subject.assertion.number <= this._lastProcessedEpoch) {
1550
1542
  return;
1551
1543
  }
1552
- await ((_a = this._epochCtx) == null ? void 0 : _a.dispose());
1544
+ await this._epochCtx?.dispose();
1553
1545
  const ctx = new Context4({
1554
1546
  onError: (err) => {
1555
1547
  if (err instanceof CancelledError) {
1556
1548
  log8("Epoch processing cancelled.", void 0, {
1557
1549
  F: __dxlog_file9,
1558
- L: 309,
1550
+ L: 323,
1559
1551
  S: this,
1560
1552
  C: (f, a) => f(...a)
1561
1553
  });
1562
1554
  } else {
1563
1555
  log8.catch(err, void 0, {
1564
1556
  F: __dxlog_file9,
1565
- L: 311,
1557
+ L: 325,
1566
1558
  S: this,
1567
1559
  C: (f, a) => f(...a)
1568
1560
  });
@@ -1574,14 +1566,6 @@ var DataPipeline = class DataPipeline2 {
1574
1566
  if (!this._isOpen) {
1575
1567
  return;
1576
1568
  }
1577
- log8("process epoch", {
1578
- epoch
1579
- }, {
1580
- F: __dxlog_file9,
1581
- L: 321,
1582
- S: this,
1583
- C: (f, a) => f(...a)
1584
- });
1585
1569
  await this._processEpoch(ctx, epoch.subject.assertion);
1586
1570
  this.appliedEpoch = epoch;
1587
1571
  this.onNewEpoch.emit(epoch);
@@ -1590,7 +1574,7 @@ var DataPipeline = class DataPipeline2 {
1590
1574
  async _processEpoch(ctx, epoch) {
1591
1575
  invariant8(this._isOpen, "Space is closed.", {
1592
1576
  F: __dxlog_file9,
1593
- L: 331,
1577
+ L: 344,
1594
1578
  S: this,
1595
1579
  A: [
1596
1580
  "this._isOpen",
@@ -1599,7 +1583,7 @@ var DataPipeline = class DataPipeline2 {
1599
1583
  });
1600
1584
  invariant8(this._pipeline, void 0, {
1601
1585
  F: __dxlog_file9,
1602
- L: 332,
1586
+ L: 345,
1603
1587
  S: this,
1604
1588
  A: [
1605
1589
  "this._pipeline",
@@ -1607,11 +1591,11 @@ var DataPipeline = class DataPipeline2 {
1607
1591
  ]
1608
1592
  });
1609
1593
  this._lastProcessedEpoch = epoch.number;
1610
- log8("Processing epoch", {
1611
- epoch
1594
+ log8("processing", {
1595
+ epoch: omit(epoch, "proof")
1612
1596
  }, {
1613
1597
  F: __dxlog_file9,
1614
- L: 335,
1598
+ L: 348,
1615
1599
  S: this,
1616
1600
  C: (f, a) => f(...a)
1617
1601
  });
@@ -1619,9 +1603,9 @@ var DataPipeline = class DataPipeline2 {
1619
1603
  const snapshot = await this._params.snapshotManager.load(ctx, epoch.snapshotCid);
1620
1604
  this.databaseHost._itemDemuxer.restoreFromSnapshot(snapshot.database);
1621
1605
  }
1622
- log8("restarting pipeline for epoch", void 0, {
1606
+ log8("restarting pipeline from epoch", void 0, {
1623
1607
  F: __dxlog_file9,
1624
- L: 343,
1608
+ L: 354,
1625
1609
  S: this,
1626
1610
  C: (f, a) => f(...a)
1627
1611
  });
@@ -1632,7 +1616,7 @@ var DataPipeline = class DataPipeline2 {
1632
1616
  async waitUntilTimeframe(timeframe) {
1633
1617
  invariant8(this._pipeline, "Pipeline is not initialized.", {
1634
1618
  F: __dxlog_file9,
1635
- L: 351,
1619
+ L: 361,
1636
1620
  S: this,
1637
1621
  A: [
1638
1622
  "this._pipeline",
@@ -1644,7 +1628,7 @@ var DataPipeline = class DataPipeline2 {
1644
1628
  async createEpoch() {
1645
1629
  invariant8(this._pipeline, void 0, {
1646
1630
  F: __dxlog_file9,
1647
- L: 357,
1631
+ L: 367,
1648
1632
  S: this,
1649
1633
  A: [
1650
1634
  "this._pipeline",
@@ -1653,7 +1637,7 @@ var DataPipeline = class DataPipeline2 {
1653
1637
  });
1654
1638
  invariant8(this.currentEpoch, void 0, {
1655
1639
  F: __dxlog_file9,
1656
- L: 358,
1640
+ L: 368,
1657
1641
  S: this,
1658
1642
  A: [
1659
1643
  "this.currentEpoch",
@@ -1676,6 +1660,12 @@ var DataPipeline = class DataPipeline2 {
1676
1660
  await this.onNewEpoch.waitForCondition(() => !!this.currentEpoch);
1677
1661
  }
1678
1662
  };
1663
+ _ts_decorate5([
1664
+ trace.metricsCounter()
1665
+ ], DataPipeline.prototype, "_usage", void 0);
1666
+ _ts_decorate5([
1667
+ trace.metricsCounter()
1668
+ ], DataPipeline.prototype, "_mutations", void 0);
1679
1669
  _ts_decorate5([
1680
1670
  synchronized3
1681
1671
  ], DataPipeline.prototype, "open", null);
@@ -1689,7 +1679,8 @@ _ts_decorate5([
1689
1679
  synchronized3
1690
1680
  ], DataPipeline.prototype, "createEpoch", null);
1691
1681
  DataPipeline = _ts_decorate5([
1692
- trackLeaks2("open", "close")
1682
+ trackLeaks2("open", "close"),
1683
+ trace.resource()
1693
1684
  ], DataPipeline);
1694
1685
 
1695
1686
  // packages/core/echo/echo-pipeline/src/space/space.ts
@@ -1697,22 +1688,36 @@ import { Event as Event5, synchronized as synchronized4, trackLeaks as trackLeak
1697
1688
  import { invariant as invariant9 } from "@dxos/invariant";
1698
1689
  import { log as log10, logInfo } from "@dxos/log";
1699
1690
  import { AdmittedFeed as AdmittedFeed2 } from "@dxos/protocols/proto/dxos/halo/credentials";
1700
- import { trace } from "@dxos/tracing";
1691
+ import { trace as trace3 } from "@dxos/tracing";
1701
1692
  import { Callback as Callback2 } from "@dxos/util";
1702
1693
 
1703
1694
  // packages/core/echo/echo-pipeline/src/space/control-pipeline.ts
1695
+ import { Context as Context5 } from "@dxos/context";
1704
1696
  import { SpaceStateMachine } from "@dxos/credentials";
1705
1697
  import { PublicKey as PublicKey4 } from "@dxos/keys";
1706
1698
  import { log as log9 } from "@dxos/log";
1707
1699
  import { AdmittedFeed } from "@dxos/protocols/proto/dxos/halo/credentials";
1708
1700
  import { Timeframe as Timeframe4 } from "@dxos/timeframe";
1701
+ import { TimeSeriesCounter as TimeSeriesCounter2, TimeUsageCounter as TimeUsageCounter2, trace as trace2 } from "@dxos/tracing";
1709
1702
  import { Callback, tracer as tracer2 } from "@dxos/util";
1703
+ function _ts_decorate6(decorators, target, key, desc) {
1704
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1705
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
1706
+ r = Reflect.decorate(decorators, target, key, desc);
1707
+ else
1708
+ for (var i = decorators.length - 1; i >= 0; i--)
1709
+ if (d = decorators[i])
1710
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1711
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1712
+ }
1710
1713
  var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/control-pipeline.ts";
1711
1714
  var TIMEFRAME_SAVE_DEBOUNCE_INTERVAL2 = 500;
1712
- var ControlPipeline = class {
1715
+ var ControlPipeline = class ControlPipeline2 {
1713
1716
  constructor({ spaceKey, genesisFeed, feedProvider, metadataStore }) {
1714
1717
  this._lastTimeframeSaveTime = Date.now();
1715
1718
  this.onFeedAdmitted = new Callback();
1719
+ this._usage = new TimeUsageCounter2();
1720
+ this._mutations = new TimeSeriesCounter2();
1716
1721
  this._spaceKey = spaceKey;
1717
1722
  this._metadata = metadataStore;
1718
1723
  this._pipeline = new Pipeline();
@@ -1723,7 +1728,7 @@ var ControlPipeline = class {
1723
1728
  key: info.key
1724
1729
  }, {
1725
1730
  F: __dxlog_file10,
1726
- L: 51,
1731
+ L: 61,
1727
1732
  S: this,
1728
1733
  C: (f, a) => f(...a)
1729
1734
  });
@@ -1734,7 +1739,7 @@ var ControlPipeline = class {
1734
1739
  } catch (err) {
1735
1740
  log9.catch(err, void 0, {
1736
1741
  F: __dxlog_file10,
1737
- L: 59,
1742
+ L: 69,
1738
1743
  S: this,
1739
1744
  C: (f, a) => f(...a)
1740
1745
  });
@@ -1757,57 +1762,66 @@ var ControlPipeline = class {
1757
1762
  async start() {
1758
1763
  log9("starting...", void 0, {
1759
1764
  F: __dxlog_file10,
1760
- L: 83,
1765
+ L: 93,
1761
1766
  S: this,
1762
1767
  C: (f, a) => f(...a)
1763
1768
  });
1764
1769
  setTimeout(async () => {
1765
- for await (const msg of this._pipeline.consume()) {
1766
- try {
1767
- log9("processing", {
1768
- key: msg.feedKey,
1769
- seq: msg.seq
1770
- }, {
1771
- F: __dxlog_file10,
1772
- L: 88,
1773
- S: this,
1774
- C: (f, a) => f(...a)
1775
- });
1776
- if (msg.data.payload.credential) {
1777
- const timer = tracer2.mark("dxos.echo.pipeline.control");
1778
- const result = await this._spaceStateMachine.process(msg.data.payload.credential.credential, PublicKey4.from(msg.feedKey));
1779
- timer.end();
1780
- if (!result) {
1781
- log9.warn("processing failed", {
1782
- msg
1783
- }, {
1784
- F: __dxlog_file10,
1785
- L: 98,
1786
- S: this,
1787
- C: (f, a) => f(...a)
1788
- });
1789
- } else {
1790
- await this._noteTargetStateIfNeeded(this._pipeline.state.pendingTimeframe);
1791
- }
1792
- }
1793
- } catch (err) {
1794
- log9.catch(err, void 0, {
1795
- F: __dxlog_file10,
1796
- L: 104,
1797
- S: this,
1798
- C: (f, a) => f(...a)
1799
- });
1800
- }
1801
- }
1770
+ void this._consumePipeline(new Context5());
1802
1771
  });
1803
1772
  await this._pipeline.start();
1804
1773
  log9("started", void 0, {
1805
1774
  F: __dxlog_file10,
1806
- L: 110,
1775
+ L: 99,
1807
1776
  S: this,
1808
1777
  C: (f, a) => f(...a)
1809
1778
  });
1810
1779
  }
1780
+ async _consumePipeline(ctx) {
1781
+ for await (const msg of this._pipeline.consume()) {
1782
+ const span = this._usage.beginRecording();
1783
+ this._mutations.inc();
1784
+ try {
1785
+ await this._processMessage(ctx, msg);
1786
+ } catch (err) {
1787
+ log9.catch(err, void 0, {
1788
+ F: __dxlog_file10,
1789
+ L: 111,
1790
+ S: this,
1791
+ C: (f, a) => f(...a)
1792
+ });
1793
+ }
1794
+ span.end();
1795
+ }
1796
+ }
1797
+ async _processMessage(ctx, msg) {
1798
+ log9("processing", {
1799
+ key: msg.feedKey,
1800
+ seq: msg.seq
1801
+ }, {
1802
+ F: __dxlog_file10,
1803
+ L: 121,
1804
+ S: this,
1805
+ C: (f, a) => f(...a)
1806
+ });
1807
+ if (msg.data.payload.credential) {
1808
+ const timer = tracer2.mark("dxos.echo.pipeline.control");
1809
+ const result = await this._spaceStateMachine.process(msg.data.payload.credential.credential, PublicKey4.from(msg.feedKey));
1810
+ timer.end();
1811
+ if (!result) {
1812
+ log9.warn("processing failed", {
1813
+ msg
1814
+ }, {
1815
+ F: __dxlog_file10,
1816
+ L: 131,
1817
+ S: this,
1818
+ C: (f, a) => f(...a)
1819
+ });
1820
+ } else {
1821
+ await this._noteTargetStateIfNeeded(this._pipeline.state.pendingTimeframe);
1822
+ }
1823
+ }
1824
+ }
1811
1825
  async _noteTargetStateIfNeeded(timeframe) {
1812
1826
  if (Date.now() - this._lastTimeframeSaveTime > TIMEFRAME_SAVE_DEBOUNCE_INTERVAL2) {
1813
1827
  this._lastTimeframeSaveTime = Date.now();
@@ -1817,7 +1831,7 @@ var ControlPipeline = class {
1817
1831
  async stop() {
1818
1832
  log9("stopping...", void 0, {
1819
1833
  F: __dxlog_file10,
1820
- L: 124,
1834
+ L: 149,
1821
1835
  S: this,
1822
1836
  C: (f, a) => f(...a)
1823
1837
  });
@@ -1825,30 +1839,44 @@ var ControlPipeline = class {
1825
1839
  await this._saveTargetTimeframe(this._pipeline.state.timeframe);
1826
1840
  log9("stopped", void 0, {
1827
1841
  F: __dxlog_file10,
1828
- L: 127,
1842
+ L: 152,
1829
1843
  S: this,
1830
1844
  C: (f, a) => f(...a)
1831
1845
  });
1832
1846
  }
1833
1847
  async _saveTargetTimeframe(timeframe) {
1834
- var _a;
1835
1848
  try {
1836
- const newTimeframe = Timeframe4.merge((_a = this._targetTimeframe) != null ? _a : new Timeframe4(), timeframe);
1849
+ const newTimeframe = Timeframe4.merge(this._targetTimeframe ?? new Timeframe4(), timeframe);
1837
1850
  await this._metadata.setSpaceControlLatestTimeframe(this._spaceKey, newTimeframe);
1838
1851
  this._targetTimeframe = newTimeframe;
1839
1852
  } catch (err) {
1840
1853
  log9(err, void 0, {
1841
1854
  F: __dxlog_file10,
1842
- L: 136,
1855
+ L: 161,
1843
1856
  S: this,
1844
1857
  C: (f, a) => f(...a)
1845
1858
  });
1846
1859
  }
1847
1860
  }
1848
1861
  };
1862
+ _ts_decorate6([
1863
+ trace2.metricsCounter()
1864
+ ], ControlPipeline.prototype, "_usage", void 0);
1865
+ _ts_decorate6([
1866
+ trace2.metricsCounter()
1867
+ ], ControlPipeline.prototype, "_mutations", void 0);
1868
+ _ts_decorate6([
1869
+ trace2.span()
1870
+ ], ControlPipeline.prototype, "_consumePipeline", null);
1871
+ _ts_decorate6([
1872
+ trace2.span()
1873
+ ], ControlPipeline.prototype, "_processMessage", null);
1874
+ ControlPipeline = _ts_decorate6([
1875
+ trace2.resource()
1876
+ ], ControlPipeline);
1849
1877
 
1850
1878
  // packages/core/echo/echo-pipeline/src/space/space.ts
1851
- function _ts_decorate6(decorators, target, key, desc) {
1879
+ function _ts_decorate7(decorators, target, key, desc) {
1852
1880
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1853
1881
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
1854
1882
  r = Reflect.decorate(decorators, target, key, desc);
@@ -1951,12 +1979,10 @@ var Space = class Space2 {
1951
1979
  return this._genesisFeedKey;
1952
1980
  }
1953
1981
  get controlFeedKey() {
1954
- var _a;
1955
- return (_a = this._controlFeed) == null ? void 0 : _a.key;
1982
+ return this._controlFeed?.key;
1956
1983
  }
1957
1984
  get dataFeedKey() {
1958
- var _a;
1959
- return (_a = this._dataFeed) == null ? void 0 : _a.key;
1985
+ return this._dataFeed?.key;
1960
1986
  }
1961
1987
  get spaceState() {
1962
1988
  return this._controlPipeline.spaceState;
@@ -1976,7 +2002,7 @@ var Space = class Space2 {
1976
2002
  setControlFeed(feed) {
1977
2003
  invariant9(!this._controlFeed, "Control feed already set.", {
1978
2004
  F: __dxlog_file11,
1979
- L: 183,
2005
+ L: 184,
1980
2006
  S: this,
1981
2007
  A: [
1982
2008
  "!this._controlFeed",
@@ -1988,10 +2014,9 @@ var Space = class Space2 {
1988
2014
  return this;
1989
2015
  }
1990
2016
  setDataFeed(feed) {
1991
- var _a;
1992
2017
  invariant9(!this._dataFeed, "Data feed already set.", {
1993
2018
  F: __dxlog_file11,
1994
- L: 190,
2019
+ L: 191,
1995
2020
  S: this,
1996
2021
  A: [
1997
2022
  "!this._dataFeed",
@@ -1999,7 +2024,7 @@ var Space = class Space2 {
1999
2024
  ]
2000
2025
  });
2001
2026
  this._dataFeed = feed;
2002
- (_a = this._dataPipeline.pipeline) == null ? void 0 : _a.setWriteFeed(feed);
2027
+ this._dataPipeline.pipeline?.setWriteFeed(feed);
2003
2028
  return this;
2004
2029
  }
2005
2030
  /**
@@ -2017,7 +2042,7 @@ var Space = class Space2 {
2017
2042
  async open(ctx) {
2018
2043
  log10("opening...", void 0, {
2019
2044
  F: __dxlog_file11,
2020
- L: 212,
2045
+ L: 213,
2021
2046
  S: this,
2022
2047
  C: (f, a) => f(...a)
2023
2048
  });
@@ -2030,7 +2055,7 @@ var Space = class Space2 {
2030
2055
  this._isOpen = true;
2031
2056
  log10("opened", void 0, {
2032
2057
  F: __dxlog_file11,
2033
- L: 223,
2058
+ L: 224,
2034
2059
  S: this,
2035
2060
  C: (f, a) => f(...a)
2036
2061
  });
@@ -2040,7 +2065,7 @@ var Space = class Space2 {
2040
2065
  key: this._key
2041
2066
  }, {
2042
2067
  F: __dxlog_file11,
2043
- L: 228,
2068
+ L: 229,
2044
2069
  S: this,
2045
2070
  C: (f, a) => f(...a)
2046
2071
  });
@@ -2054,7 +2079,7 @@ var Space = class Space2 {
2054
2079
  this._isOpen = false;
2055
2080
  log10("closed", void 0, {
2056
2081
  F: __dxlog_file11,
2057
- L: 241,
2082
+ L: 242,
2058
2083
  S: this,
2059
2084
  C: (f, a) => f(...a)
2060
2085
  });
@@ -2062,13 +2087,13 @@ var Space = class Space2 {
2062
2087
  async initializeDataPipeline() {
2063
2088
  log10("initializeDataPipeline", void 0, {
2064
2089
  F: __dxlog_file11,
2065
- L: 246,
2090
+ L: 247,
2066
2091
  S: this,
2067
2092
  C: (f, a) => f(...a)
2068
2093
  });
2069
2094
  invariant9(this._isOpen, "Space must be open to initialize data pipeline.", {
2070
2095
  F: __dxlog_file11,
2071
- L: 247,
2096
+ L: 248,
2072
2097
  S: this,
2073
2098
  A: [
2074
2099
  "this._isOpen",
@@ -2078,22 +2103,23 @@ var Space = class Space2 {
2078
2103
  await this._dataPipeline.open();
2079
2104
  }
2080
2105
  };
2081
- _ts_decorate6([
2082
- logInfo
2106
+ _ts_decorate7([
2107
+ logInfo,
2108
+ trace3.info()
2083
2109
  ], Space.prototype, "key", null);
2084
- _ts_decorate6([
2110
+ _ts_decorate7([
2085
2111
  synchronized4,
2086
- trace.span()
2112
+ trace3.span()
2087
2113
  ], Space.prototype, "open", null);
2088
- _ts_decorate6([
2114
+ _ts_decorate7([
2089
2115
  synchronized4
2090
2116
  ], Space.prototype, "close", null);
2091
- _ts_decorate6([
2117
+ _ts_decorate7([
2092
2118
  synchronized4
2093
2119
  ], Space.prototype, "initializeDataPipeline", null);
2094
- Space = _ts_decorate6([
2120
+ Space = _ts_decorate7([
2095
2121
  trackLeaks3("open", "close"),
2096
- trace.resource()
2122
+ trace3.resource()
2097
2123
  ], Space);
2098
2124
 
2099
2125
  // packages/core/echo/echo-pipeline/src/space/space-protocol.ts
@@ -2105,7 +2131,7 @@ import { Teleport } from "@dxos/teleport";
2105
2131
  import { BlobSync } from "@dxos/teleport-extension-object-sync";
2106
2132
  import { ReplicatorExtension } from "@dxos/teleport-extension-replicator";
2107
2133
  import { ComplexMap as ComplexMap4 } from "@dxos/util";
2108
- function _ts_decorate7(decorators, target, key, desc) {
2134
+ function _ts_decorate8(decorators, target, key, desc) {
2109
2135
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2110
2136
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
2111
2137
  r = Reflect.decorate(decorators, target, key, desc);
@@ -2146,7 +2172,7 @@ var SpaceProtocol = class {
2146
2172
  key: feed.key
2147
2173
  }, {
2148
2174
  F: __dxlog_file12,
2149
- L: 95,
2175
+ L: 96,
2150
2176
  S: this,
2151
2177
  C: (f, a) => f(...a)
2152
2178
  });
@@ -2155,6 +2181,7 @@ var SpaceProtocol = class {
2155
2181
  session.replicator.addFeed(feed);
2156
2182
  }
2157
2183
  }
2184
+ // TODO(burdon): Rename open? Common open/close interfaces for all services?
2158
2185
  async start() {
2159
2186
  if (this._connection) {
2160
2187
  return;
@@ -2168,7 +2195,7 @@ var SpaceProtocol = class {
2168
2195
  await this.blobSync.open();
2169
2196
  log11("starting...", void 0, {
2170
2197
  F: __dxlog_file12,
2171
- L: 120,
2198
+ L: 122,
2172
2199
  S: this,
2173
2200
  C: (f, a) => f(...a)
2174
2201
  });
@@ -2178,11 +2205,11 @@ var SpaceProtocol = class {
2178
2205
  peerId: this._swarmIdentity.peerKey,
2179
2206
  topic,
2180
2207
  topology: new MMSTTopology(topologyConfig),
2181
- label: `Protocol swarm: ${topic}`
2208
+ label: `space swarm ${topic.truncate()}`
2182
2209
  });
2183
2210
  log11("started", void 0, {
2184
2211
  F: __dxlog_file12,
2185
- L: 130,
2212
+ L: 132,
2186
2213
  S: this,
2187
2214
  C: (f, a) => f(...a)
2188
2215
  });
@@ -2192,14 +2219,14 @@ var SpaceProtocol = class {
2192
2219
  if (this._connection) {
2193
2220
  log11("stopping...", void 0, {
2194
2221
  F: __dxlog_file12,
2195
- L: 137,
2222
+ L: 139,
2196
2223
  S: this,
2197
2224
  C: (f, a) => f(...a)
2198
2225
  });
2199
2226
  await this._connection.close();
2200
2227
  log11("stopped", void 0, {
2201
2228
  F: __dxlog_file12,
2202
- L: 139,
2229
+ L: 141,
2203
2230
  S: this,
2204
2231
  C: (f, a) => f(...a)
2205
2232
  });
@@ -2222,10 +2249,10 @@ var SpaceProtocol = class {
2222
2249
  };
2223
2250
  }
2224
2251
  };
2225
- _ts_decorate7([
2252
+ _ts_decorate8([
2226
2253
  logInfo2
2227
2254
  ], SpaceProtocol.prototype, "_topic", void 0);
2228
- _ts_decorate7([
2255
+ _ts_decorate8([
2229
2256
  logInfo2
2230
2257
  ], SpaceProtocol.prototype, "_ownPeerKey", null);
2231
2258
  var AuthStatus;
@@ -2264,20 +2291,18 @@ var SpaceProtocolSession = class {
2264
2291
  provider: this._swarmIdentity.credentialProvider,
2265
2292
  verifier: this._swarmIdentity.credentialAuthenticator,
2266
2293
  onAuthSuccess: () => {
2267
- var _a;
2268
2294
  log11("Peer authenticated", void 0, {
2269
2295
  F: __dxlog_file12,
2270
- L: 236,
2296
+ L: 238,
2271
2297
  S: this,
2272
2298
  C: (f, a) => f(...a)
2273
2299
  });
2274
2300
  this._authStatus = AuthStatus.SUCCESS;
2275
- (_a = this._onSessionAuth) == null ? void 0 : _a.call(this, this._teleport);
2301
+ this._onSessionAuth?.(this._teleport);
2276
2302
  },
2277
2303
  onAuthFailure: () => {
2278
- var _a;
2279
2304
  this._authStatus = AuthStatus.FAILURE;
2280
- (_a = this._onAuthFailure) == null ? void 0 : _a.call(this, this._teleport);
2305
+ this._onAuthFailure?.(this._teleport);
2281
2306
  }
2282
2307
  }));
2283
2308
  this._teleport.addExtension("dxos.mesh.teleport.replicator", this.replicator);
@@ -2287,10 +2312,10 @@ var SpaceProtocolSession = class {
2287
2312
  await this._teleport.close();
2288
2313
  }
2289
2314
  };
2290
- _ts_decorate7([
2315
+ _ts_decorate8([
2291
2316
  logInfo2
2292
2317
  ], SpaceProtocolSession.prototype, "_wireParams", void 0);
2293
- _ts_decorate7([
2318
+ _ts_decorate8([
2294
2319
  logInfo2
2295
2320
  ], SpaceProtocolSession.prototype, "authStatus", null);
2296
2321
 
@@ -2299,9 +2324,9 @@ import { synchronized as synchronized5, trackLeaks as trackLeaks4 } from "@dxos/
2299
2324
  import { failUndefined as failUndefined2 } from "@dxos/debug";
2300
2325
  import { PublicKey as PublicKey6 } from "@dxos/keys";
2301
2326
  import { log as log12 } from "@dxos/log";
2302
- import { trace as trace2 } from "@dxos/protocols";
2327
+ import { trace as trace4 } from "@dxos/protocols";
2303
2328
  import { ComplexMap as ComplexMap5 } from "@dxos/util";
2304
- function _ts_decorate8(decorators, target, key, desc) {
2329
+ function _ts_decorate9(decorators, target, key, desc) {
2305
2330
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2306
2331
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
2307
2332
  r = Reflect.decorate(decorators, target, key, desc);
@@ -2335,8 +2360,7 @@ var SpaceManager = class SpaceManager2 {
2335
2360
  ].map((space) => space.close()));
2336
2361
  }
2337
2362
  async constructSpace({ metadata, swarmIdentity, onNetworkConnection, onAuthFailure, memberKey }) {
2338
- var _a;
2339
- log12.trace("dxos.echo.space-manager.construct-space", trace2.begin({
2363
+ log12.trace("dxos.echo.space-manager.construct-space", trace4.begin({
2340
2364
  id: this._instanceId
2341
2365
  }), {
2342
2366
  F: __dxlog_file13,
@@ -2352,7 +2376,7 @@ var SpaceManager = class SpaceManager2 {
2352
2376
  S: this,
2353
2377
  C: (f, a) => f(...a)
2354
2378
  });
2355
- const genesisFeed = await this._feedStore.openFeed((_a = metadata.genesisFeedKey) != null ? _a : failUndefined2());
2379
+ const genesisFeed = await this._feedStore.openFeed(metadata.genesisFeedKey ?? failUndefined2());
2356
2380
  const spaceKey = metadata.key;
2357
2381
  const protocol = new SpaceProtocol({
2358
2382
  topic: spaceKey,
@@ -2374,24 +2398,24 @@ var SpaceManager = class SpaceManager2 {
2374
2398
  memberKey
2375
2399
  });
2376
2400
  this._spaces.set(space.key, space);
2377
- log12.trace("dxos.echo.space-manager.construct-space", trace2.end({
2401
+ log12.trace("dxos.echo.space-manager.construct-space", trace4.end({
2378
2402
  id: this._instanceId
2379
2403
  }), {
2380
2404
  F: __dxlog_file13,
2381
- L: 125,
2405
+ L: 126,
2382
2406
  S: this,
2383
2407
  C: (f, a) => f(...a)
2384
2408
  });
2385
2409
  return space;
2386
2410
  }
2387
2411
  };
2388
- _ts_decorate8([
2412
+ _ts_decorate9([
2389
2413
  synchronized5
2390
2414
  ], SpaceManager.prototype, "open", null);
2391
- _ts_decorate8([
2415
+ _ts_decorate9([
2392
2416
  synchronized5
2393
2417
  ], SpaceManager.prototype, "close", null);
2394
- SpaceManager = _ts_decorate8([
2418
+ SpaceManager = _ts_decorate9([
2395
2419
  trackLeaks4("open", "close")
2396
2420
  ], SpaceManager);
2397
2421
 
@@ -2421,4 +2445,4 @@ export {
2421
2445
  SpaceProtocolSession,
2422
2446
  SpaceManager
2423
2447
  };
2424
- //# sourceMappingURL=chunk-EJ35NHZV.mjs.map
2448
+ //# sourceMappingURL=chunk-GDF4DQU2.mjs.map