@dxos/echo-pipeline 0.1.56-main.738e1fa → 0.1.56-main.76a8709

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 (46) hide show
  1. package/dist/lib/browser/{chunk-7RPTJNLX.mjs → chunk-GELWTWOW.mjs} +313 -279
  2. package/dist/lib/browser/chunk-GELWTWOW.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 +14 -18
  7. package/dist/lib/browser/testing/index.mjs.map +3 -3
  8. package/dist/lib/node/index.cjs +320 -286
  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 +333 -303
  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/db-host/snapshot-manager.d.ts.map +1 -1
  15. package/dist/types/src/pipeline/pipeline-stress.test.d.ts +2 -0
  16. package/dist/types/src/pipeline/pipeline-stress.test.d.ts.map +1 -0
  17. package/dist/types/src/pipeline/pipeline.d.ts +4 -3
  18. package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
  19. package/dist/types/src/space/control-pipeline.d.ts +4 -0
  20. package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
  21. package/dist/types/src/space/data-pipeline.d.ts +2 -0
  22. package/dist/types/src/space/data-pipeline.d.ts.map +1 -1
  23. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  24. package/dist/types/src/space/space-protocol.d.ts.map +1 -1
  25. package/dist/types/src/space/space.d.ts +2 -1
  26. package/dist/types/src/space/space.d.ts.map +1 -1
  27. package/dist/types/src/testing/database-test-rig.d.ts +4 -1
  28. package/dist/types/src/testing/database-test-rig.d.ts.map +1 -1
  29. package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
  30. package/package.json +32 -31
  31. package/src/db-host/data-service-host.ts +9 -2
  32. package/src/db-host/snapshot-manager.ts +0 -2
  33. package/src/metadata/metadata-store.ts +1 -1
  34. package/src/pipeline/pipeline-stress.test.ts +226 -0
  35. package/src/pipeline/pipeline.test.ts +30 -206
  36. package/src/pipeline/pipeline.ts +49 -22
  37. package/src/space/control-pipeline.ts +47 -22
  38. package/src/space/data-pipeline.ts +20 -10
  39. package/src/space/space-manager.ts +1 -0
  40. package/src/space/space-protocol.ts +3 -1
  41. package/src/space/space.test.ts +10 -9
  42. package/src/space/space.ts +6 -1
  43. package/src/testing/database-test-rig.ts +27 -2
  44. package/src/testing/test-agent-builder.ts +2 -1
  45. package/src/tests/database-unit.test.ts +39 -0
  46. package/dist/lib/browser/chunk-7RPTJNLX.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,15 +208,13 @@ 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
 
215
215
  // packages/core/echo/echo-pipeline/src/db-host/snapshot-manager.ts
216
216
  import { trackLeaks } from "@dxos/async";
217
217
  import { cancelWithContext } from "@dxos/context";
218
- import { timed } from "@dxos/debug";
219
218
  import { PublicKey } from "@dxos/keys";
220
219
  import { schema as schema2 } from "@dxos/protocols";
221
220
  import { BlobMeta } from "@dxos/protocols/proto/dxos/echo/blob";
@@ -260,9 +259,6 @@ var SnapshotManager = class SnapshotManager2 {
260
259
  return PublicKey.from(id).toHex();
261
260
  }
262
261
  };
263
- _ts_decorate([
264
- timed(1e4)
265
- ], SnapshotManager.prototype, "load", null);
266
262
  SnapshotManager = _ts_decorate([
267
263
  trackLeaks("open", "close")
268
264
  ], SnapshotManager);
@@ -358,7 +354,7 @@ var DataServiceSubscriptions = class {
358
354
  C: (f, a) => f(...a)
359
355
  });
360
356
  const host = this._spaces.get(spaceKey);
361
- await (host == null ? void 0 : host.close());
357
+ await host?.close();
362
358
  this._spaces.delete(spaceKey);
363
359
  }
364
360
  getDataService(spaceKey) {
@@ -370,7 +366,6 @@ var DataServiceImpl = class {
370
366
  this._subscriptions = _subscriptions;
371
367
  }
372
368
  subscribe(request) {
373
- var _a;
374
369
  invariant3(request.spaceKey, void 0, {
375
370
  F: __dxlog_file3,
376
371
  L: 56,
@@ -380,11 +375,10 @@ var DataServiceImpl = class {
380
375
  ""
381
376
  ]
382
377
  });
383
- 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}`));
384
379
  return host.subscribe();
385
380
  }
386
381
  write(request) {
387
- var _a;
388
382
  invariant3(request.spaceKey, void 0, {
389
383
  F: __dxlog_file3,
390
384
  L: 63,
@@ -403,7 +397,7 @@ var DataServiceImpl = class {
403
397
  ""
404
398
  ]
405
399
  });
406
- 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}`));
407
401
  return host.write(request);
408
402
  }
409
403
  };
@@ -431,8 +425,8 @@ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipelin
431
425
  var emptyEchoMetadata = () => ({
432
426
  version: STORAGE_VERSION,
433
427
  spaces: [],
434
- created: new Date(),
435
- updated: new Date()
428
+ created: /* @__PURE__ */ new Date(),
429
+ updated: /* @__PURE__ */ new Date()
436
430
  });
437
431
  var EchoMetadata = schema4.getCodecForType("dxos.echo.metadata.EchoMetadata");
438
432
  var MetadataStore = class {
@@ -446,22 +440,19 @@ var MetadataStore = class {
446
440
  return this._metadata;
447
441
  }
448
442
  get version() {
449
- var _a;
450
- return (_a = this._metadata.version) != null ? _a : 0;
443
+ return this._metadata.version ?? 0;
451
444
  }
452
445
  /**
453
446
  * Returns a list of currently saved spaces. The list and objects in it can be modified addSpace and
454
447
  * addSpaceFeed functions.
455
448
  */
456
449
  get spaces() {
457
- var _a;
458
- return (_a = this._metadata.spaces) != null ? _a : [];
450
+ return this._metadata.spaces ?? [];
459
451
  }
460
452
  /**
461
453
  * Loads metadata from persistent storage.
462
454
  */
463
455
  async load() {
464
- var _a;
465
456
  const file = this._directory.getOrCreateFile("EchoMetadata");
466
457
  try {
467
458
  const { size: fileLength } = await file.stat();
@@ -480,7 +471,10 @@ var MetadataStore = class {
480
471
  C: (f, a) => f(...a)
481
472
  });
482
473
  if (fileLength < dataSize + 8) {
483
- throw new DataCorruptionError("Metadata size is smaller than expected.");
474
+ throw new DataCorruptionError("Metadata size is smaller than expected.", {
475
+ fileLength,
476
+ dataSize
477
+ });
484
478
  }
485
479
  const data = await file.read(8, dataSize);
486
480
  const calculatedChecksum = CRC32.buf(data);
@@ -488,9 +482,8 @@ var MetadataStore = class {
488
482
  throw new DataCorruptionError("Metadata checksum is invalid.");
489
483
  }
490
484
  this._metadata = EchoMetadata.decode(data);
491
- (_a = this._metadata.spaces) == null ? void 0 : _a.forEach((space) => {
492
- var _a2;
493
- (_a2 = space.state) != null ? _a2 : space.state = SpaceState.ACTIVE;
485
+ this._metadata.spaces?.forEach((space) => {
486
+ space.state ??= SpaceState.ACTIVE;
494
487
  });
495
488
  } catch (err) {
496
489
  log3.error("failed to load metadata", {
@@ -507,12 +500,11 @@ var MetadataStore = class {
507
500
  }
508
501
  }
509
502
  async _save() {
510
- var _a;
511
503
  const data = {
512
504
  ...this._metadata,
513
505
  version: STORAGE_VERSION,
514
- created: (_a = this._metadata.created) != null ? _a : new Date(),
515
- updated: new Date()
506
+ created: this._metadata.created ?? /* @__PURE__ */ new Date(),
507
+ updated: /* @__PURE__ */ new Date()
516
508
  };
517
509
  this.update.emit(data);
518
510
  const file = this._directory.getOrCreateFile("EchoMetadata");
@@ -538,8 +530,7 @@ var MetadataStore = class {
538
530
  }
539
531
  }
540
532
  _getSpace(spaceKey) {
541
- var _a;
542
- if ((_a = this._metadata.identity) == null ? void 0 : _a.haloSpace.key.equals(spaceKey)) {
533
+ if (this._metadata.identity?.haloSpace.key.equals(spaceKey)) {
543
534
  return this._metadata.identity.haloSpace;
544
535
  }
545
536
  const space = this.spaces.find((space2) => space2.key === spaceKey);
@@ -584,8 +575,7 @@ var MetadataStore = class {
584
575
  await this._save();
585
576
  }
586
577
  async addSpace(record) {
587
- var _a, _b, _c;
588
- 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", {
589
579
  F: __dxlog_file4,
590
580
  L: 162,
591
581
  S: this,
@@ -594,7 +584,7 @@ var MetadataStore = class {
594
584
  "'Cannot overwrite existing space in metadata'"
595
585
  ]
596
586
  });
597
- ((_c = (_b = this._metadata).spaces) != null ? _c : _b.spaces = []).push(record);
587
+ (this._metadata.spaces ??= []).push(record);
598
588
  await this._save();
599
589
  }
600
590
  async setSpaceDataLatestTimeframe(spaceKey, timeframe) {
@@ -630,7 +620,7 @@ var fromBytesInt32 = (buf) => buf.readInt32LE(0);
630
620
 
631
621
  // packages/core/echo/echo-pipeline/src/pipeline/timeframe-clock.ts
632
622
  import { Event as Event2 } from "@dxos/async";
633
- import { timed as timed2 } from "@dxos/debug";
623
+ import { timed } from "@dxos/debug";
634
624
  import { log as log4 } from "@dxos/log";
635
625
  import { Timeframe } from "@dxos/timeframe";
636
626
  function _ts_decorate3(decorators, target, key, desc) {
@@ -723,7 +713,7 @@ var TimeframeClock = class {
723
713
  }
724
714
  };
725
715
  _ts_decorate3([
726
- timed2(5e3)
716
+ timed(5e3)
727
717
  ], TimeframeClock.prototype, "waitUntilReached", null);
728
718
 
729
719
  // packages/core/echo/echo-pipeline/src/pipeline/pipeline.ts
@@ -829,7 +819,6 @@ var PipelineState = class {
829
819
  * @param timeout Timeout in milliseconds to specify the maximum wait time.
830
820
  */
831
821
  async waitUntilReachedTargetTimeframe({ ctx = new Context2(), timeout, breakOnStall = true } = {}) {
832
- var _a;
833
822
  log6("waitUntilReachedTargetTimeframe", {
834
823
  timeout,
835
824
  current: this.timeframe,
@@ -840,7 +829,7 @@ var PipelineState = class {
840
829
  S: this,
841
830
  C: (f, a) => f(...a)
842
831
  });
843
- (_a = this._reachedTargetPromise) != null ? _a : this._reachedTargetPromise = Promise.race([
832
+ this._reachedTargetPromise ??= Promise.race([
844
833
  this._timeframeClock.update.waitForCondition(() => {
845
834
  return Timeframe2.dependencies(this.targetTimeframe, this.timeframe).isEmpty();
846
835
  }),
@@ -887,9 +876,11 @@ var Pipeline = class {
887
876
  // Waits for the message consumer to process the message and yield control back to the pipeline.
888
877
  this._processingTrigger = new Trigger().wake();
889
878
  this._pauseTrigger = new Trigger().wake();
879
+ // Pending downloads.
880
+ this._downloads = new ComplexMap3((value) => PublicKey3.hash(value.key));
890
881
  this._isStopping = false;
891
882
  this._isStarted = false;
892
- this._isOpen = false;
883
+ this._isBeingConsumed = false;
893
884
  this._isPaused = false;
894
885
  }
895
886
  get state() {
@@ -898,7 +889,7 @@ var Pipeline = class {
898
889
  get writer() {
899
890
  invariant6(this._writer, "Writer not set.", {
900
891
  F: __dxlog_file7,
901
- L: 230,
892
+ L: 233,
902
893
  S: this,
903
894
  A: [
904
895
  "this._writer",
@@ -920,12 +911,14 @@ var Pipeline = class {
920
911
  if (this._feedSetIterator) {
921
912
  await this._feedSetIterator.addFeed(feed);
922
913
  }
923
- this._setFeedDownloadState(feed);
914
+ if (this._isStarted && !this._isPaused) {
915
+ this._setFeedDownloadState(feed);
916
+ }
924
917
  }
925
918
  setWriteFeed(feed) {
926
919
  invariant6(!this._writer, "Writer already set.", {
927
920
  F: __dxlog_file7,
928
- L: 253,
921
+ L: 260,
929
922
  S: this,
930
923
  A: [
931
924
  "!this._writer",
@@ -934,7 +927,7 @@ var Pipeline = class {
934
927
  });
935
928
  invariant6(feed.properties.writable, "Feed must be writable.", {
936
929
  F: __dxlog_file7,
937
- L: 254,
930
+ L: 261,
938
931
  S: this,
939
932
  A: [
940
933
  "feed.properties.writable",
@@ -947,9 +940,18 @@ var Pipeline = class {
947
940
  }), feed.createFeedWriter());
948
941
  }
949
942
  async start() {
943
+ invariant6(!this._isStarted, "Pipeline is already started.", {
944
+ F: __dxlog_file7,
945
+ L: 274,
946
+ S: this,
947
+ A: [
948
+ "!this._isStarted",
949
+ "'Pipeline is already started.'"
950
+ ]
951
+ });
950
952
  log6("starting...", void 0, {
951
953
  F: __dxlog_file7,
952
- L: 267,
954
+ L: 275,
953
955
  S: this,
954
956
  C: (f, a) => f(...a)
955
957
  });
@@ -958,21 +960,29 @@ var Pipeline = class {
958
960
  this._isStarted = true;
959
961
  log6("started", void 0, {
960
962
  F: __dxlog_file7,
961
- L: 271,
963
+ L: 279,
962
964
  S: this,
963
965
  C: (f, a) => f(...a)
964
966
  });
967
+ if (!this._isPaused) {
968
+ for (const feed of this._feeds.values()) {
969
+ this._setFeedDownloadState(feed);
970
+ }
971
+ }
965
972
  }
966
973
  async stop() {
967
- var _a;
968
974
  log6("stopping...", void 0, {
969
975
  F: __dxlog_file7,
970
- L: 276,
976
+ L: 290,
971
977
  S: this,
972
978
  C: (f, a) => f(...a)
973
979
  });
974
980
  this._isStopping = true;
975
- 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();
976
986
  await this._processingTrigger.wait();
977
987
  await this._state._ctx.dispose();
978
988
  this._state._ctx = new Context2();
@@ -980,7 +990,7 @@ var Pipeline = class {
980
990
  this._isStarted = false;
981
991
  log6("stopped", void 0, {
982
992
  F: __dxlog_file7,
983
- L: 284,
993
+ L: 302,
984
994
  S: this,
985
995
  C: (f, a) => f(...a)
986
996
  });
@@ -992,7 +1002,7 @@ var Pipeline = class {
992
1002
  async setCursor(timeframe) {
993
1003
  invariant6(!this._isStarted || this._isPaused, "Invalid state.", {
994
1004
  F: __dxlog_file7,
995
- L: 293,
1005
+ L: 311,
996
1006
  S: this,
997
1007
  A: [
998
1008
  "!this._isStarted || this._isPaused",
@@ -1001,9 +1011,6 @@ var Pipeline = class {
1001
1011
  });
1002
1012
  this._state._startTimeframe = timeframe;
1003
1013
  this._timeframeClock.setTimeframe(timeframe);
1004
- for (const feed of this._feeds.values()) {
1005
- this._setFeedDownloadState(feed);
1006
- }
1007
1014
  if (this._feedSetIterator) {
1008
1015
  await this._feedSetIterator.close();
1009
1016
  await this._initIterator();
@@ -1014,15 +1021,6 @@ var Pipeline = class {
1014
1021
  * Calling pause while processing will cause a deadlock.
1015
1022
  */
1016
1023
  async pause() {
1017
- invariant6(this._isStarted, "Pipeline is not open.", {
1018
- F: __dxlog_file7,
1019
- L: 315,
1020
- S: this,
1021
- A: [
1022
- "this._isStarted",
1023
- "'Pipeline is not open.'"
1024
- ]
1025
- });
1026
1024
  if (this._isPaused) {
1027
1025
  return;
1028
1026
  }
@@ -1031,18 +1029,9 @@ var Pipeline = class {
1031
1029
  this._isPaused = true;
1032
1030
  }
1033
1031
  async unpause() {
1034
- invariant6(this._isStarted, "Pipeline is not open.", {
1035
- F: __dxlog_file7,
1036
- L: 327,
1037
- S: this,
1038
- A: [
1039
- "this._isStarted",
1040
- "'Pipeline is not open.'"
1041
- ]
1042
- });
1043
1032
  invariant6(this._isPaused, "Pipeline is not paused.", {
1044
1033
  F: __dxlog_file7,
1045
- L: 328,
1034
+ L: 340,
1046
1035
  S: this,
1047
1036
  A: [
1048
1037
  "this._isPaused",
@@ -1051,25 +1040,28 @@ var Pipeline = class {
1051
1040
  });
1052
1041
  this._pauseTrigger.wake();
1053
1042
  this._isPaused = false;
1043
+ for (const feed of this._feeds.values()) {
1044
+ this._setFeedDownloadState(feed);
1045
+ }
1054
1046
  }
1055
1047
  /**
1056
1048
  * Starts to iterate over the ordered messages from the added feeds.
1057
1049
  * Updates the timeframe clock after the message has bee processed.
1058
1050
  */
1059
1051
  async *consume() {
1060
- invariant6(!this._isOpen, "Pipeline is already being consumed.", {
1052
+ invariant6(!this._isBeingConsumed, "Pipeline is already being consumed.", {
1061
1053
  F: __dxlog_file7,
1062
- L: 339,
1054
+ L: 355,
1063
1055
  S: this,
1064
1056
  A: [
1065
- "!this._isOpen",
1057
+ "!this._isBeingConsumed",
1066
1058
  "'Pipeline is already being consumed.'"
1067
1059
  ]
1068
1060
  });
1069
- this._isOpen = true;
1061
+ this._isBeingConsumed = true;
1070
1062
  invariant6(this._feedSetIterator, "Iterator not initialized.", {
1071
1063
  F: __dxlog_file7,
1072
- L: 342,
1064
+ L: 358,
1073
1065
  S: this,
1074
1066
  A: [
1075
1067
  "this._feedSetIterator",
@@ -1083,7 +1075,7 @@ var Pipeline = class {
1083
1075
  if (lastFeedSetIterator !== this._feedSetIterator) {
1084
1076
  invariant6(this._feedSetIterator, "Iterator not initialized.", {
1085
1077
  F: __dxlog_file7,
1086
- L: 351,
1078
+ L: 367,
1087
1079
  S: this,
1088
1080
  A: [
1089
1081
  "this._feedSetIterator",
@@ -1095,7 +1087,7 @@ var Pipeline = class {
1095
1087
  }
1096
1088
  const { done, value } = await iterable.next();
1097
1089
  if (!done) {
1098
- const block = value != null ? value : failUndefined();
1090
+ const block = value ?? failUndefined();
1099
1091
  this._processingTrigger.reset();
1100
1092
  this._timeframeClock.updatePendingTimeframe(PublicKey3.from(block.feedKey), block.seq);
1101
1093
  yield block;
@@ -1103,33 +1095,42 @@ var Pipeline = class {
1103
1095
  this._timeframeClock.updateTimeframe();
1104
1096
  }
1105
1097
  }
1106
- this._isOpen = false;
1098
+ this._isBeingConsumed = false;
1107
1099
  }
1108
1100
  _setFeedDownloadState(feed) {
1109
- var _a;
1101
+ let handle = this._downloads.get(feed);
1102
+ if (handle) {
1103
+ feed.undownload(handle);
1104
+ }
1110
1105
  const timeframe = this._state._startTimeframe;
1111
- const seq = (_a = timeframe.get(feed.key)) != null ? _a : 0;
1112
- feed.undownload({
1113
- callback: () => log6("undownload", void 0, {
1114
- F: __dxlog_file7,
1115
- L: 375,
1116
- S: this,
1117
- C: (f, a) => f(...a)
1118
- })
1106
+ const seq = timeframe.get(feed.key) ?? -1;
1107
+ log6("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)
1119
1116
  });
1120
- feed.download({
1117
+ handle = feed.download({
1121
1118
  start: seq + 1,
1122
1119
  linear: true
1123
- }).catch((err) => {
1124
- log6("failed to download feed", {
1125
- err
1126
- }, {
1127
- F: __dxlog_file7,
1128
- L: 377,
1129
- S: this,
1130
- C: (f, a) => f(...a)
1131
- });
1120
+ }, (err, data) => {
1121
+ if (err) {
1122
+ } else {
1123
+ log6.info("downloaded", {
1124
+ data
1125
+ }, {
1126
+ F: __dxlog_file7,
1127
+ L: 401,
1128
+ S: this,
1129
+ C: (f, a) => f(...a)
1130
+ });
1131
+ }
1132
1132
  });
1133
+ this._downloads.set(feed, handle);
1133
1134
  }
1134
1135
  async _initIterator() {
1135
1136
  this._feedSetIterator = new FeedSetIterator(createMessageSelector(this._timeframeClock), {
@@ -1139,7 +1140,7 @@ var Pipeline = class {
1139
1140
  this._feedSetIterator.stalled.on((iterator) => {
1140
1141
  log6.warn(`Stalled after ${iterator.options.stallTimeout}ms with ${iterator.size} feeds.`, void 0, {
1141
1142
  F: __dxlog_file7,
1142
- L: 388,
1143
+ L: 415,
1143
1144
  S: this,
1144
1145
  C: (f, a) => f(...a)
1145
1146
  });
@@ -1231,7 +1232,7 @@ var AuthExtension = class extends RpcExtension {
1231
1232
  const { credential } = await this.rpc.AuthService.authenticate({
1232
1233
  challenge
1233
1234
  });
1234
- invariant7((credential == null ? void 0 : credential.length) > 0, "invalid credential", {
1235
+ invariant7(credential?.length > 0, "invalid credential", {
1235
1236
  F: __dxlog_file8,
1236
1237
  L: 69,
1237
1238
  S: this,
@@ -1273,11 +1274,12 @@ var AuthExtension = class extends RpcExtension {
1273
1274
  import { Event as Event4, scheduleTask as scheduleTask2, synchronized as synchronized3, trackLeaks as trackLeaks2 } from "@dxos/async";
1274
1275
  import { Context as Context4 } from "@dxos/context";
1275
1276
  import { checkCredentialType } from "@dxos/credentials";
1276
- import { getStateMachineFromItem, ItemManager } from "@dxos/echo-db";
1277
+ import { getStateMachineFromItem, ItemManager, TYPE_PROPERTIES } from "@dxos/echo-db";
1277
1278
  import { CancelledError } from "@dxos/errors";
1278
1279
  import { invariant as invariant8 } from "@dxos/invariant";
1279
- import { log as log8 } from "@dxos/log";
1280
+ import { log as log8, omit } from "@dxos/log";
1280
1281
  import { Timeframe as Timeframe3 } from "@dxos/timeframe";
1282
+ import { TimeSeriesCounter, TimeUsageCounter, trace } from "@dxos/tracing";
1281
1283
  import { tracer } from "@dxos/util";
1282
1284
  function _ts_decorate5(decorators, target, key, desc) {
1283
1285
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -1304,6 +1306,8 @@ var DataPipeline = class DataPipeline2 {
1304
1306
  this._lastTimeframeSaveTime = 0;
1305
1307
  this._lastSnapshotSaveTime = 0;
1306
1308
  this._lastProcessedEpoch = -1;
1309
+ this._usage = new TimeUsageCounter();
1310
+ this._mutations = new TimeSeriesCounter();
1307
1311
  this.currentEpoch = void 0;
1308
1312
  this.appliedEpoch = void 0;
1309
1313
  this.onNewEpoch = new Event4();
@@ -1315,13 +1319,11 @@ var DataPipeline = class DataPipeline2 {
1315
1319
  return this._pipeline;
1316
1320
  }
1317
1321
  get pipelineState() {
1318
- var _a;
1319
- return (_a = this._pipeline) == null ? void 0 : _a.state;
1322
+ return this._pipeline?.state;
1320
1323
  }
1321
1324
  setTargetTimeframe(timeframe) {
1322
- var _a;
1323
1325
  this._targetTimeframe = timeframe;
1324
- (_a = this._pipeline) == null ? void 0 : _a.state.setTargetTimeframe(timeframe);
1326
+ this._pipeline?.state.setTargetTimeframe(timeframe);
1325
1327
  }
1326
1328
  async processCredential(credential) {
1327
1329
  if (!checkCredentialType(credential, "dxos.halo.credentials.Epoch")) {
@@ -1338,8 +1340,8 @@ var DataPipeline = class DataPipeline2 {
1338
1340
  }
1339
1341
  this._pipeline = new Pipeline();
1340
1342
  await this._params.onPipelineCreated(this._pipeline);
1341
- await this._pipeline.start();
1342
1343
  await this._pipeline.pause();
1344
+ await this._pipeline.start();
1343
1345
  if (this._targetTimeframe) {
1344
1346
  this._pipeline.state.setTargetTimeframe(this._targetTimeframe);
1345
1347
  }
@@ -1347,7 +1349,7 @@ var DataPipeline = class DataPipeline2 {
1347
1349
  write: (data, options) => {
1348
1350
  invariant8(this._pipeline, "Pipeline is not initialized.", {
1349
1351
  F: __dxlog_file9,
1350
- L: 145,
1352
+ L: 154,
1351
1353
  S: this,
1352
1354
  A: [
1353
1355
  "this._pipeline",
@@ -1356,7 +1358,7 @@ var DataPipeline = class DataPipeline2 {
1356
1358
  });
1357
1359
  invariant8(this.currentEpoch, "Epoch is not initialized.", {
1358
1360
  F: __dxlog_file9,
1359
- L: 146,
1361
+ L: 155,
1360
1362
  S: this,
1361
1363
  A: [
1362
1364
  "this.currentEpoch",
@@ -1377,19 +1379,18 @@ var DataPipeline = class DataPipeline2 {
1377
1379
  this._isOpen = true;
1378
1380
  }
1379
1381
  async close() {
1380
- var _a, _b, _c;
1381
1382
  if (!this._isOpen) {
1382
1383
  return;
1383
1384
  }
1384
1385
  log8("close", void 0, {
1385
1386
  F: __dxlog_file9,
1386
- L: 170,
1387
+ L: 179,
1387
1388
  S: this,
1388
1389
  C: (f, a) => f(...a)
1389
1390
  });
1390
1391
  this._isOpen = false;
1391
1392
  await this._ctx.dispose();
1392
- await ((_a = this._pipeline) == null ? void 0 : _a.stop());
1393
+ await this._pipeline?.stop();
1393
1394
  try {
1394
1395
  await this._saveCache();
1395
1396
  if (this._pipeline) {
@@ -1398,13 +1399,13 @@ var DataPipeline = class DataPipeline2 {
1398
1399
  } catch (err) {
1399
1400
  log8.catch(err, void 0, {
1400
1401
  F: __dxlog_file9,
1401
- L: 183,
1402
+ L: 192,
1402
1403
  S: this,
1403
1404
  C: (f, a) => f(...a)
1404
1405
  });
1405
1406
  }
1406
- await ((_b = this.databaseHost) == null ? void 0 : _b.close());
1407
- await ((_c = this.itemManager) == null ? void 0 : _c.destroy());
1407
+ await this.databaseHost?.close();
1408
+ await this.itemManager?.destroy();
1408
1409
  this._ctx = new Context4();
1409
1410
  this._pipeline = void 0;
1410
1411
  this._targetTimeframe = void 0;
@@ -1422,7 +1423,7 @@ var DataPipeline = class DataPipeline2 {
1422
1423
  }
1423
1424
  invariant8(this._pipeline, "Pipeline is not initialized.", {
1424
1425
  F: __dxlog_file9,
1425
- L: 206,
1426
+ L: 215,
1426
1427
  S: this,
1427
1428
  A: [
1428
1429
  "this._pipeline",
@@ -1430,13 +1431,15 @@ var DataPipeline = class DataPipeline2 {
1430
1431
  ]
1431
1432
  });
1432
1433
  for await (const msg of this._pipeline.consume()) {
1434
+ const span = this._usage.beginRecording();
1435
+ this._mutations.inc();
1433
1436
  const { feedKey, seq, data } = msg;
1434
1437
  log8("processing message", {
1435
1438
  feedKey,
1436
1439
  seq
1437
1440
  }, {
1438
1441
  F: __dxlog_file9,
1439
- L: 209,
1442
+ L: 221,
1440
1443
  S: this,
1441
1444
  C: (f, a) => f(...a)
1442
1445
  });
@@ -1448,7 +1451,7 @@ var DataPipeline = class DataPipeline2 {
1448
1451
  feedKey
1449
1452
  }, {
1450
1453
  F: __dxlog_file9,
1451
- L: 215,
1454
+ L: 227,
1452
1455
  S: this,
1453
1456
  C: (f, a) => f(...a)
1454
1457
  });
@@ -1471,7 +1474,7 @@ var DataPipeline = class DataPipeline2 {
1471
1474
  spaceKey: this._params.spaceKey.toHex()
1472
1475
  }, {
1473
1476
  F: __dxlog_file9,
1474
- L: 232,
1477
+ L: 244,
1475
1478
  S: this,
1476
1479
  C: (f, a) => f(...a)
1477
1480
  });
@@ -1480,17 +1483,18 @@ var DataPipeline = class DataPipeline2 {
1480
1483
  } catch (err) {
1481
1484
  log8.catch(err, void 0, {
1482
1485
  F: __dxlog_file9,
1483
- L: 242,
1486
+ L: 254,
1484
1487
  S: this,
1485
1488
  C: (f, a) => f(...a)
1486
1489
  });
1487
1490
  }
1491
+ span.end();
1488
1492
  }
1489
1493
  }
1490
1494
  _createSnapshot() {
1491
1495
  invariant8(this.databaseHost, "Database backend is not initialized.", {
1492
1496
  F: __dxlog_file9,
1493
- L: 248,
1497
+ L: 262,
1494
1498
  S: this,
1495
1499
  A: [
1496
1500
  "this.databaseHost",
@@ -1504,26 +1508,22 @@ var DataPipeline = class DataPipeline2 {
1504
1508
  };
1505
1509
  }
1506
1510
  async _saveTargetTimeframe(timeframe) {
1507
- var _a;
1508
- const newTimeframe = Timeframe3.merge((_a = this._targetTimeframe) != null ? _a : new Timeframe3(), timeframe);
1511
+ const newTimeframe = Timeframe3.merge(this._targetTimeframe ?? new Timeframe3(), timeframe);
1509
1512
  await this._params.metadataStore.setSpaceDataLatestTimeframe(this._params.spaceKey, newTimeframe);
1510
1513
  this._targetTimeframe = newTimeframe;
1511
1514
  }
1512
1515
  async _saveCache() {
1513
- var _a;
1514
1516
  const cache = {};
1515
1517
  try {
1516
- const propertiesItem = this.itemManager.items.find((item) => {
1517
- var _a2, _b;
1518
- 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";
1519
- });
1518
+ const propertiesItem = this.itemManager.items.find((item) => item.modelMeta?.type === "dxos:model/document" && // TODO(burdon): Document?
1519
+ (getStateMachineFromItem(item)?.snapshot()).type === TYPE_PROPERTIES);
1520
1520
  if (propertiesItem) {
1521
- cache.properties = (_a = getStateMachineFromItem(propertiesItem)) == null ? void 0 : _a.snapshot();
1521
+ cache.properties = getStateMachineFromItem(propertiesItem)?.snapshot();
1522
1522
  }
1523
1523
  } catch (err) {
1524
1524
  log8.warn("Failed to cache properties", err, {
1525
1525
  F: __dxlog_file9,
1526
- L: 277,
1526
+ L: 291,
1527
1527
  S: this,
1528
1528
  C: (f, a) => f(...a)
1529
1529
  });
@@ -1540,24 +1540,23 @@ var DataPipeline = class DataPipeline2 {
1540
1540
  }
1541
1541
  }
1542
1542
  async _processEpochInSeparateTask(epoch) {
1543
- var _a;
1544
1543
  if (epoch.subject.assertion.number <= this._lastProcessedEpoch) {
1545
1544
  return;
1546
1545
  }
1547
- await ((_a = this._epochCtx) == null ? void 0 : _a.dispose());
1546
+ await this._epochCtx?.dispose();
1548
1547
  const ctx = new Context4({
1549
1548
  onError: (err) => {
1550
1549
  if (err instanceof CancelledError) {
1551
1550
  log8("Epoch processing cancelled.", void 0, {
1552
1551
  F: __dxlog_file9,
1553
- L: 309,
1552
+ L: 323,
1554
1553
  S: this,
1555
1554
  C: (f, a) => f(...a)
1556
1555
  });
1557
1556
  } else {
1558
1557
  log8.catch(err, void 0, {
1559
1558
  F: __dxlog_file9,
1560
- L: 311,
1559
+ L: 325,
1561
1560
  S: this,
1562
1561
  C: (f, a) => f(...a)
1563
1562
  });
@@ -1569,14 +1568,6 @@ var DataPipeline = class DataPipeline2 {
1569
1568
  if (!this._isOpen) {
1570
1569
  return;
1571
1570
  }
1572
- log8("process epoch", {
1573
- epoch
1574
- }, {
1575
- F: __dxlog_file9,
1576
- L: 321,
1577
- S: this,
1578
- C: (f, a) => f(...a)
1579
- });
1580
1571
  await this._processEpoch(ctx, epoch.subject.assertion);
1581
1572
  this.appliedEpoch = epoch;
1582
1573
  this.onNewEpoch.emit(epoch);
@@ -1585,7 +1576,7 @@ var DataPipeline = class DataPipeline2 {
1585
1576
  async _processEpoch(ctx, epoch) {
1586
1577
  invariant8(this._isOpen, "Space is closed.", {
1587
1578
  F: __dxlog_file9,
1588
- L: 331,
1579
+ L: 344,
1589
1580
  S: this,
1590
1581
  A: [
1591
1582
  "this._isOpen",
@@ -1594,7 +1585,7 @@ var DataPipeline = class DataPipeline2 {
1594
1585
  });
1595
1586
  invariant8(this._pipeline, void 0, {
1596
1587
  F: __dxlog_file9,
1597
- L: 332,
1588
+ L: 345,
1598
1589
  S: this,
1599
1590
  A: [
1600
1591
  "this._pipeline",
@@ -1602,11 +1593,11 @@ var DataPipeline = class DataPipeline2 {
1602
1593
  ]
1603
1594
  });
1604
1595
  this._lastProcessedEpoch = epoch.number;
1605
- log8("Processing epoch", {
1606
- epoch
1596
+ log8("processing", {
1597
+ epoch: omit(epoch, "proof")
1607
1598
  }, {
1608
1599
  F: __dxlog_file9,
1609
- L: 335,
1600
+ L: 348,
1610
1601
  S: this,
1611
1602
  C: (f, a) => f(...a)
1612
1603
  });
@@ -1614,9 +1605,9 @@ var DataPipeline = class DataPipeline2 {
1614
1605
  const snapshot = await this._params.snapshotManager.load(ctx, epoch.snapshotCid);
1615
1606
  this.databaseHost._itemDemuxer.restoreFromSnapshot(snapshot.database);
1616
1607
  }
1617
- log8("restarting pipeline for epoch", void 0, {
1608
+ log8("restarting pipeline from epoch", void 0, {
1618
1609
  F: __dxlog_file9,
1619
- L: 343,
1610
+ L: 354,
1620
1611
  S: this,
1621
1612
  C: (f, a) => f(...a)
1622
1613
  });
@@ -1627,7 +1618,7 @@ var DataPipeline = class DataPipeline2 {
1627
1618
  async waitUntilTimeframe(timeframe) {
1628
1619
  invariant8(this._pipeline, "Pipeline is not initialized.", {
1629
1620
  F: __dxlog_file9,
1630
- L: 351,
1621
+ L: 361,
1631
1622
  S: this,
1632
1623
  A: [
1633
1624
  "this._pipeline",
@@ -1639,7 +1630,7 @@ var DataPipeline = class DataPipeline2 {
1639
1630
  async createEpoch() {
1640
1631
  invariant8(this._pipeline, void 0, {
1641
1632
  F: __dxlog_file9,
1642
- L: 357,
1633
+ L: 367,
1643
1634
  S: this,
1644
1635
  A: [
1645
1636
  "this._pipeline",
@@ -1648,7 +1639,7 @@ var DataPipeline = class DataPipeline2 {
1648
1639
  });
1649
1640
  invariant8(this.currentEpoch, void 0, {
1650
1641
  F: __dxlog_file9,
1651
- L: 358,
1642
+ L: 368,
1652
1643
  S: this,
1653
1644
  A: [
1654
1645
  "this.currentEpoch",
@@ -1671,6 +1662,12 @@ var DataPipeline = class DataPipeline2 {
1671
1662
  await this.onNewEpoch.waitForCondition(() => !!this.currentEpoch);
1672
1663
  }
1673
1664
  };
1665
+ _ts_decorate5([
1666
+ trace.metricsCounter()
1667
+ ], DataPipeline.prototype, "_usage", void 0);
1668
+ _ts_decorate5([
1669
+ trace.metricsCounter()
1670
+ ], DataPipeline.prototype, "_mutations", void 0);
1674
1671
  _ts_decorate5([
1675
1672
  synchronized3
1676
1673
  ], DataPipeline.prototype, "open", null);
@@ -1684,7 +1681,8 @@ _ts_decorate5([
1684
1681
  synchronized3
1685
1682
  ], DataPipeline.prototype, "createEpoch", null);
1686
1683
  DataPipeline = _ts_decorate5([
1687
- trackLeaks2("open", "close")
1684
+ trackLeaks2("open", "close"),
1685
+ trace.resource()
1688
1686
  ], DataPipeline);
1689
1687
 
1690
1688
  // packages/core/echo/echo-pipeline/src/space/space.ts
@@ -1692,21 +1690,36 @@ import { Event as Event5, synchronized as synchronized4, trackLeaks as trackLeak
1692
1690
  import { invariant as invariant9 } from "@dxos/invariant";
1693
1691
  import { log as log10, logInfo } from "@dxos/log";
1694
1692
  import { AdmittedFeed as AdmittedFeed2 } from "@dxos/protocols/proto/dxos/halo/credentials";
1693
+ import { trace as trace3 } from "@dxos/tracing";
1695
1694
  import { Callback as Callback2 } from "@dxos/util";
1696
1695
 
1697
1696
  // packages/core/echo/echo-pipeline/src/space/control-pipeline.ts
1697
+ import { Context as Context5 } from "@dxos/context";
1698
1698
  import { SpaceStateMachine } from "@dxos/credentials";
1699
1699
  import { PublicKey as PublicKey4 } from "@dxos/keys";
1700
1700
  import { log as log9 } from "@dxos/log";
1701
1701
  import { AdmittedFeed } from "@dxos/protocols/proto/dxos/halo/credentials";
1702
1702
  import { Timeframe as Timeframe4 } from "@dxos/timeframe";
1703
+ import { TimeSeriesCounter as TimeSeriesCounter2, TimeUsageCounter as TimeUsageCounter2, trace as trace2 } from "@dxos/tracing";
1703
1704
  import { Callback, tracer as tracer2 } from "@dxos/util";
1705
+ function _ts_decorate6(decorators, target, key, desc) {
1706
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1707
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
1708
+ r = Reflect.decorate(decorators, target, key, desc);
1709
+ else
1710
+ for (var i = decorators.length - 1; i >= 0; i--)
1711
+ if (d = decorators[i])
1712
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1713
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1714
+ }
1704
1715
  var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/space/control-pipeline.ts";
1705
1716
  var TIMEFRAME_SAVE_DEBOUNCE_INTERVAL2 = 500;
1706
- var ControlPipeline = class {
1717
+ var ControlPipeline = class ControlPipeline2 {
1707
1718
  constructor({ spaceKey, genesisFeed, feedProvider, metadataStore }) {
1708
1719
  this._lastTimeframeSaveTime = Date.now();
1709
1720
  this.onFeedAdmitted = new Callback();
1721
+ this._usage = new TimeUsageCounter2();
1722
+ this._mutations = new TimeSeriesCounter2();
1710
1723
  this._spaceKey = spaceKey;
1711
1724
  this._metadata = metadataStore;
1712
1725
  this._pipeline = new Pipeline();
@@ -1717,7 +1730,7 @@ var ControlPipeline = class {
1717
1730
  key: info.key
1718
1731
  }, {
1719
1732
  F: __dxlog_file10,
1720
- L: 51,
1733
+ L: 61,
1721
1734
  S: this,
1722
1735
  C: (f, a) => f(...a)
1723
1736
  });
@@ -1728,7 +1741,7 @@ var ControlPipeline = class {
1728
1741
  } catch (err) {
1729
1742
  log9.catch(err, void 0, {
1730
1743
  F: __dxlog_file10,
1731
- L: 59,
1744
+ L: 69,
1732
1745
  S: this,
1733
1746
  C: (f, a) => f(...a)
1734
1747
  });
@@ -1751,56 +1764,65 @@ var ControlPipeline = class {
1751
1764
  async start() {
1752
1765
  log9("starting...", void 0, {
1753
1766
  F: __dxlog_file10,
1754
- L: 83,
1767
+ L: 93,
1755
1768
  S: this,
1756
1769
  C: (f, a) => f(...a)
1757
1770
  });
1758
1771
  setTimeout(async () => {
1759
- for await (const msg of this._pipeline.consume()) {
1760
- try {
1761
- log9("processing", {
1762
- key: msg.feedKey,
1763
- seq: msg.seq
1764
- }, {
1765
- F: __dxlog_file10,
1766
- L: 88,
1767
- S: this,
1768
- C: (f, a) => f(...a)
1769
- });
1770
- if (msg.data.payload.credential) {
1771
- const timer = tracer2.mark("dxos.echo.pipeline.control");
1772
- const result = await this._spaceStateMachine.process(msg.data.payload.credential.credential, PublicKey4.from(msg.feedKey));
1773
- timer.end();
1774
- if (!result) {
1775
- log9.warn("processing failed", {
1776
- msg
1777
- }, {
1778
- F: __dxlog_file10,
1779
- L: 98,
1780
- S: this,
1781
- C: (f, a) => f(...a)
1782
- });
1783
- } else {
1784
- await this._noteTargetStateIfNeeded(this._pipeline.state.pendingTimeframe);
1785
- }
1786
- }
1787
- } catch (err) {
1788
- log9.catch(err, void 0, {
1789
- F: __dxlog_file10,
1790
- L: 104,
1791
- S: this,
1792
- C: (f, a) => f(...a)
1793
- });
1794
- }
1795
- }
1772
+ void this._consumePipeline(new Context5());
1796
1773
  });
1797
1774
  await this._pipeline.start();
1798
1775
  log9("started", void 0, {
1799
1776
  F: __dxlog_file10,
1800
- L: 110,
1777
+ L: 99,
1778
+ S: this,
1779
+ C: (f, a) => f(...a)
1780
+ });
1781
+ }
1782
+ async _consumePipeline(ctx) {
1783
+ for await (const msg of this._pipeline.consume()) {
1784
+ const span = this._usage.beginRecording();
1785
+ this._mutations.inc();
1786
+ try {
1787
+ await this._processMessage(ctx, msg);
1788
+ } catch (err) {
1789
+ log9.catch(err, void 0, {
1790
+ F: __dxlog_file10,
1791
+ L: 111,
1792
+ S: this,
1793
+ C: (f, a) => f(...a)
1794
+ });
1795
+ }
1796
+ span.end();
1797
+ }
1798
+ }
1799
+ async _processMessage(ctx, msg) {
1800
+ log9("processing", {
1801
+ key: msg.feedKey,
1802
+ seq: msg.seq
1803
+ }, {
1804
+ F: __dxlog_file10,
1805
+ L: 121,
1801
1806
  S: this,
1802
1807
  C: (f, a) => f(...a)
1803
1808
  });
1809
+ if (msg.data.payload.credential) {
1810
+ const timer = tracer2.mark("dxos.echo.pipeline.control");
1811
+ const result = await this._spaceStateMachine.process(msg.data.payload.credential.credential, PublicKey4.from(msg.feedKey));
1812
+ timer.end();
1813
+ if (!result) {
1814
+ log9.warn("processing failed", {
1815
+ msg
1816
+ }, {
1817
+ F: __dxlog_file10,
1818
+ L: 131,
1819
+ S: this,
1820
+ C: (f, a) => f(...a)
1821
+ });
1822
+ } else {
1823
+ await this._noteTargetStateIfNeeded(this._pipeline.state.pendingTimeframe);
1824
+ }
1825
+ }
1804
1826
  }
1805
1827
  async _noteTargetStateIfNeeded(timeframe) {
1806
1828
  if (Date.now() - this._lastTimeframeSaveTime > TIMEFRAME_SAVE_DEBOUNCE_INTERVAL2) {
@@ -1811,7 +1833,7 @@ var ControlPipeline = class {
1811
1833
  async stop() {
1812
1834
  log9("stopping...", void 0, {
1813
1835
  F: __dxlog_file10,
1814
- L: 124,
1836
+ L: 149,
1815
1837
  S: this,
1816
1838
  C: (f, a) => f(...a)
1817
1839
  });
@@ -1819,30 +1841,44 @@ var ControlPipeline = class {
1819
1841
  await this._saveTargetTimeframe(this._pipeline.state.timeframe);
1820
1842
  log9("stopped", void 0, {
1821
1843
  F: __dxlog_file10,
1822
- L: 127,
1844
+ L: 152,
1823
1845
  S: this,
1824
1846
  C: (f, a) => f(...a)
1825
1847
  });
1826
1848
  }
1827
1849
  async _saveTargetTimeframe(timeframe) {
1828
- var _a;
1829
1850
  try {
1830
- const newTimeframe = Timeframe4.merge((_a = this._targetTimeframe) != null ? _a : new Timeframe4(), timeframe);
1851
+ const newTimeframe = Timeframe4.merge(this._targetTimeframe ?? new Timeframe4(), timeframe);
1831
1852
  await this._metadata.setSpaceControlLatestTimeframe(this._spaceKey, newTimeframe);
1832
1853
  this._targetTimeframe = newTimeframe;
1833
1854
  } catch (err) {
1834
1855
  log9(err, void 0, {
1835
1856
  F: __dxlog_file10,
1836
- L: 136,
1857
+ L: 161,
1837
1858
  S: this,
1838
1859
  C: (f, a) => f(...a)
1839
1860
  });
1840
1861
  }
1841
1862
  }
1842
1863
  };
1864
+ _ts_decorate6([
1865
+ trace2.metricsCounter()
1866
+ ], ControlPipeline.prototype, "_usage", void 0);
1867
+ _ts_decorate6([
1868
+ trace2.metricsCounter()
1869
+ ], ControlPipeline.prototype, "_mutations", void 0);
1870
+ _ts_decorate6([
1871
+ trace2.span()
1872
+ ], ControlPipeline.prototype, "_consumePipeline", null);
1873
+ _ts_decorate6([
1874
+ trace2.span()
1875
+ ], ControlPipeline.prototype, "_processMessage", null);
1876
+ ControlPipeline = _ts_decorate6([
1877
+ trace2.resource()
1878
+ ], ControlPipeline);
1843
1879
 
1844
1880
  // packages/core/echo/echo-pipeline/src/space/space.ts
1845
- function _ts_decorate6(decorators, target, key, desc) {
1881
+ function _ts_decorate7(decorators, target, key, desc) {
1846
1882
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1847
1883
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
1848
1884
  r = Reflect.decorate(decorators, target, key, desc);
@@ -1861,7 +1897,7 @@ var Space = class Space2 {
1861
1897
  this._isOpen = false;
1862
1898
  invariant9(params.spaceKey && params.feedProvider, void 0, {
1863
1899
  F: __dxlog_file11,
1864
- L: 70,
1900
+ L: 73,
1865
1901
  S: this,
1866
1902
  A: [
1867
1903
  "params.spaceKey && params.feedProvider",
@@ -1903,7 +1939,7 @@ var Space = class Space2 {
1903
1939
  credential
1904
1940
  }, {
1905
1941
  F: __dxlog_file11,
1906
- L: 106,
1942
+ L: 109,
1907
1943
  S: this,
1908
1944
  C: (f, a) => f(...a)
1909
1945
  });
@@ -1945,12 +1981,10 @@ var Space = class Space2 {
1945
1981
  return this._genesisFeedKey;
1946
1982
  }
1947
1983
  get controlFeedKey() {
1948
- var _a;
1949
- return (_a = this._controlFeed) == null ? void 0 : _a.key;
1984
+ return this._controlFeed?.key;
1950
1985
  }
1951
1986
  get dataFeedKey() {
1952
- var _a;
1953
- return (_a = this._dataFeed) == null ? void 0 : _a.key;
1987
+ return this._dataFeed?.key;
1954
1988
  }
1955
1989
  get spaceState() {
1956
1990
  return this._controlPipeline.spaceState;
@@ -1970,7 +2004,7 @@ var Space = class Space2 {
1970
2004
  setControlFeed(feed) {
1971
2005
  invariant9(!this._controlFeed, "Control feed already set.", {
1972
2006
  F: __dxlog_file11,
1973
- L: 180,
2007
+ L: 184,
1974
2008
  S: this,
1975
2009
  A: [
1976
2010
  "!this._controlFeed",
@@ -1982,10 +2016,9 @@ var Space = class Space2 {
1982
2016
  return this;
1983
2017
  }
1984
2018
  setDataFeed(feed) {
1985
- var _a;
1986
2019
  invariant9(!this._dataFeed, "Data feed already set.", {
1987
2020
  F: __dxlog_file11,
1988
- L: 187,
2021
+ L: 191,
1989
2022
  S: this,
1990
2023
  A: [
1991
2024
  "!this._dataFeed",
@@ -1993,7 +2026,7 @@ var Space = class Space2 {
1993
2026
  ]
1994
2027
  });
1995
2028
  this._dataFeed = feed;
1996
- (_a = this._dataPipeline.pipeline) == null ? void 0 : _a.setWriteFeed(feed);
2029
+ this._dataPipeline.pipeline?.setWriteFeed(feed);
1997
2030
  return this;
1998
2031
  }
1999
2032
  /**
@@ -2008,10 +2041,10 @@ var Space = class Space2 {
2008
2041
  // getDataFeeds(): FeedInfo[] {
2009
2042
  // return this._dataPipeline?.getFeeds();
2010
2043
  // }
2011
- async open() {
2044
+ async open(ctx) {
2012
2045
  log10("opening...", void 0, {
2013
2046
  F: __dxlog_file11,
2014
- L: 208,
2047
+ L: 213,
2015
2048
  S: this,
2016
2049
  C: (f, a) => f(...a)
2017
2050
  });
@@ -2024,7 +2057,7 @@ var Space = class Space2 {
2024
2057
  this._isOpen = true;
2025
2058
  log10("opened", void 0, {
2026
2059
  F: __dxlog_file11,
2027
- L: 219,
2060
+ L: 224,
2028
2061
  S: this,
2029
2062
  C: (f, a) => f(...a)
2030
2063
  });
@@ -2034,7 +2067,7 @@ var Space = class Space2 {
2034
2067
  key: this._key
2035
2068
  }, {
2036
2069
  F: __dxlog_file11,
2037
- L: 224,
2070
+ L: 229,
2038
2071
  S: this,
2039
2072
  C: (f, a) => f(...a)
2040
2073
  });
@@ -2048,7 +2081,7 @@ var Space = class Space2 {
2048
2081
  this._isOpen = false;
2049
2082
  log10("closed", void 0, {
2050
2083
  F: __dxlog_file11,
2051
- L: 237,
2084
+ L: 242,
2052
2085
  S: this,
2053
2086
  C: (f, a) => f(...a)
2054
2087
  });
@@ -2056,13 +2089,13 @@ var Space = class Space2 {
2056
2089
  async initializeDataPipeline() {
2057
2090
  log10("initializeDataPipeline", void 0, {
2058
2091
  F: __dxlog_file11,
2059
- L: 242,
2092
+ L: 247,
2060
2093
  S: this,
2061
2094
  C: (f, a) => f(...a)
2062
2095
  });
2063
2096
  invariant9(this._isOpen, "Space must be open to initialize data pipeline.", {
2064
2097
  F: __dxlog_file11,
2065
- L: 243,
2098
+ L: 248,
2066
2099
  S: this,
2067
2100
  A: [
2068
2101
  "this._isOpen",
@@ -2072,20 +2105,23 @@ var Space = class Space2 {
2072
2105
  await this._dataPipeline.open();
2073
2106
  }
2074
2107
  };
2075
- _ts_decorate6([
2076
- logInfo
2108
+ _ts_decorate7([
2109
+ logInfo,
2110
+ trace3.info()
2077
2111
  ], Space.prototype, "key", null);
2078
- _ts_decorate6([
2079
- synchronized4
2112
+ _ts_decorate7([
2113
+ synchronized4,
2114
+ trace3.span()
2080
2115
  ], Space.prototype, "open", null);
2081
- _ts_decorate6([
2116
+ _ts_decorate7([
2082
2117
  synchronized4
2083
2118
  ], Space.prototype, "close", null);
2084
- _ts_decorate6([
2119
+ _ts_decorate7([
2085
2120
  synchronized4
2086
2121
  ], Space.prototype, "initializeDataPipeline", null);
2087
- Space = _ts_decorate6([
2088
- trackLeaks3("open", "close")
2122
+ Space = _ts_decorate7([
2123
+ trackLeaks3("open", "close"),
2124
+ trace3.resource()
2089
2125
  ], Space);
2090
2126
 
2091
2127
  // packages/core/echo/echo-pipeline/src/space/space-protocol.ts
@@ -2097,7 +2133,7 @@ import { Teleport } from "@dxos/teleport";
2097
2133
  import { BlobSync } from "@dxos/teleport-extension-object-sync";
2098
2134
  import { ReplicatorExtension } from "@dxos/teleport-extension-replicator";
2099
2135
  import { ComplexMap as ComplexMap4 } from "@dxos/util";
2100
- function _ts_decorate7(decorators, target, key, desc) {
2136
+ function _ts_decorate8(decorators, target, key, desc) {
2101
2137
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2102
2138
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
2103
2139
  r = Reflect.decorate(decorators, target, key, desc);
@@ -2138,7 +2174,7 @@ var SpaceProtocol = class {
2138
2174
  key: feed.key
2139
2175
  }, {
2140
2176
  F: __dxlog_file12,
2141
- L: 95,
2177
+ L: 96,
2142
2178
  S: this,
2143
2179
  C: (f, a) => f(...a)
2144
2180
  });
@@ -2147,6 +2183,7 @@ var SpaceProtocol = class {
2147
2183
  session.replicator.addFeed(feed);
2148
2184
  }
2149
2185
  }
2186
+ // TODO(burdon): Rename open? Common open/close interfaces for all services?
2150
2187
  async start() {
2151
2188
  if (this._connection) {
2152
2189
  return;
@@ -2160,7 +2197,7 @@ var SpaceProtocol = class {
2160
2197
  await this.blobSync.open();
2161
2198
  log11("starting...", void 0, {
2162
2199
  F: __dxlog_file12,
2163
- L: 120,
2200
+ L: 122,
2164
2201
  S: this,
2165
2202
  C: (f, a) => f(...a)
2166
2203
  });
@@ -2170,11 +2207,11 @@ var SpaceProtocol = class {
2170
2207
  peerId: this._swarmIdentity.peerKey,
2171
2208
  topic,
2172
2209
  topology: new MMSTTopology(topologyConfig),
2173
- label: `Protocol swarm: ${topic}`
2210
+ label: `space swarm ${topic.truncate()}`
2174
2211
  });
2175
2212
  log11("started", void 0, {
2176
2213
  F: __dxlog_file12,
2177
- L: 130,
2214
+ L: 132,
2178
2215
  S: this,
2179
2216
  C: (f, a) => f(...a)
2180
2217
  });
@@ -2184,14 +2221,14 @@ var SpaceProtocol = class {
2184
2221
  if (this._connection) {
2185
2222
  log11("stopping...", void 0, {
2186
2223
  F: __dxlog_file12,
2187
- L: 137,
2224
+ L: 139,
2188
2225
  S: this,
2189
2226
  C: (f, a) => f(...a)
2190
2227
  });
2191
2228
  await this._connection.close();
2192
2229
  log11("stopped", void 0, {
2193
2230
  F: __dxlog_file12,
2194
- L: 139,
2231
+ L: 141,
2195
2232
  S: this,
2196
2233
  C: (f, a) => f(...a)
2197
2234
  });
@@ -2214,10 +2251,10 @@ var SpaceProtocol = class {
2214
2251
  };
2215
2252
  }
2216
2253
  };
2217
- _ts_decorate7([
2254
+ _ts_decorate8([
2218
2255
  logInfo2
2219
2256
  ], SpaceProtocol.prototype, "_topic", void 0);
2220
- _ts_decorate7([
2257
+ _ts_decorate8([
2221
2258
  logInfo2
2222
2259
  ], SpaceProtocol.prototype, "_ownPeerKey", null);
2223
2260
  var AuthStatus;
@@ -2256,20 +2293,18 @@ var SpaceProtocolSession = class {
2256
2293
  provider: this._swarmIdentity.credentialProvider,
2257
2294
  verifier: this._swarmIdentity.credentialAuthenticator,
2258
2295
  onAuthSuccess: () => {
2259
- var _a;
2260
2296
  log11("Peer authenticated", void 0, {
2261
2297
  F: __dxlog_file12,
2262
- L: 236,
2298
+ L: 238,
2263
2299
  S: this,
2264
2300
  C: (f, a) => f(...a)
2265
2301
  });
2266
2302
  this._authStatus = AuthStatus.SUCCESS;
2267
- (_a = this._onSessionAuth) == null ? void 0 : _a.call(this, this._teleport);
2303
+ this._onSessionAuth?.(this._teleport);
2268
2304
  },
2269
2305
  onAuthFailure: () => {
2270
- var _a;
2271
2306
  this._authStatus = AuthStatus.FAILURE;
2272
- (_a = this._onAuthFailure) == null ? void 0 : _a.call(this, this._teleport);
2307
+ this._onAuthFailure?.(this._teleport);
2273
2308
  }
2274
2309
  }));
2275
2310
  this._teleport.addExtension("dxos.mesh.teleport.replicator", this.replicator);
@@ -2279,10 +2314,10 @@ var SpaceProtocolSession = class {
2279
2314
  await this._teleport.close();
2280
2315
  }
2281
2316
  };
2282
- _ts_decorate7([
2317
+ _ts_decorate8([
2283
2318
  logInfo2
2284
2319
  ], SpaceProtocolSession.prototype, "_wireParams", void 0);
2285
- _ts_decorate7([
2320
+ _ts_decorate8([
2286
2321
  logInfo2
2287
2322
  ], SpaceProtocolSession.prototype, "authStatus", null);
2288
2323
 
@@ -2291,9 +2326,9 @@ import { synchronized as synchronized5, trackLeaks as trackLeaks4 } from "@dxos/
2291
2326
  import { failUndefined as failUndefined2 } from "@dxos/debug";
2292
2327
  import { PublicKey as PublicKey6 } from "@dxos/keys";
2293
2328
  import { log as log12 } from "@dxos/log";
2294
- import { trace } from "@dxos/protocols";
2329
+ import { trace as trace4 } from "@dxos/protocols";
2295
2330
  import { ComplexMap as ComplexMap5 } from "@dxos/util";
2296
- function _ts_decorate8(decorators, target, key, desc) {
2331
+ function _ts_decorate9(decorators, target, key, desc) {
2297
2332
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2298
2333
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
2299
2334
  r = Reflect.decorate(decorators, target, key, desc);
@@ -2327,8 +2362,7 @@ var SpaceManager = class SpaceManager2 {
2327
2362
  ].map((space) => space.close()));
2328
2363
  }
2329
2364
  async constructSpace({ metadata, swarmIdentity, onNetworkConnection, onAuthFailure, memberKey }) {
2330
- var _a;
2331
- log12.trace("dxos.echo.space-manager.construct-space", trace.begin({
2365
+ log12.trace("dxos.echo.space-manager.construct-space", trace4.begin({
2332
2366
  id: this._instanceId
2333
2367
  }), {
2334
2368
  F: __dxlog_file13,
@@ -2344,7 +2378,7 @@ var SpaceManager = class SpaceManager2 {
2344
2378
  S: this,
2345
2379
  C: (f, a) => f(...a)
2346
2380
  });
2347
- const genesisFeed = await this._feedStore.openFeed((_a = metadata.genesisFeedKey) != null ? _a : failUndefined2());
2381
+ const genesisFeed = await this._feedStore.openFeed(metadata.genesisFeedKey ?? failUndefined2());
2348
2382
  const spaceKey = metadata.key;
2349
2383
  const protocol = new SpaceProtocol({
2350
2384
  topic: spaceKey,
@@ -2366,24 +2400,24 @@ var SpaceManager = class SpaceManager2 {
2366
2400
  memberKey
2367
2401
  });
2368
2402
  this._spaces.set(space.key, space);
2369
- log12.trace("dxos.echo.space-manager.construct-space", trace.end({
2403
+ log12.trace("dxos.echo.space-manager.construct-space", trace4.end({
2370
2404
  id: this._instanceId
2371
2405
  }), {
2372
2406
  F: __dxlog_file13,
2373
- L: 125,
2407
+ L: 126,
2374
2408
  S: this,
2375
2409
  C: (f, a) => f(...a)
2376
2410
  });
2377
2411
  return space;
2378
2412
  }
2379
2413
  };
2380
- _ts_decorate8([
2414
+ _ts_decorate9([
2381
2415
  synchronized5
2382
2416
  ], SpaceManager.prototype, "open", null);
2383
- _ts_decorate8([
2417
+ _ts_decorate9([
2384
2418
  synchronized5
2385
2419
  ], SpaceManager.prototype, "close", null);
2386
- SpaceManager = _ts_decorate8([
2420
+ SpaceManager = _ts_decorate9([
2387
2421
  trackLeaks4("open", "close")
2388
2422
  ], SpaceManager);
2389
2423
 
@@ -2413,4 +2447,4 @@ export {
2413
2447
  SpaceProtocolSession,
2414
2448
  SpaceManager
2415
2449
  };
2416
- //# sourceMappingURL=chunk-7RPTJNLX.mjs.map
2450
+ //# sourceMappingURL=chunk-GELWTWOW.mjs.map