@dxos/echo-pipeline 0.6.4 → 0.6.5-staging.42fccfe

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 (35) hide show
  1. package/dist/lib/browser/{chunk-6MJEONOX.mjs → chunk-2MII6KJX.mjs} +464 -104
  2. package/dist/lib/browser/chunk-2MII6KJX.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +3 -1
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/testing/index.mjs +1 -1
  6. package/dist/lib/node/{chunk-PT5LWMPA.cjs → chunk-6MWU4MHX.cjs} +475 -116
  7. package/dist/lib/node/chunk-6MWU4MHX.cjs.map +7 -0
  8. package/dist/lib/node/index.cjs +36 -34
  9. package/dist/lib/node/index.cjs.map +2 -2
  10. package/dist/lib/node/meta.json +1 -1
  11. package/dist/lib/node/testing/index.cjs +11 -11
  12. package/dist/types/src/automerge/automerge-host.d.ts +3 -2
  13. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  14. package/dist/types/src/automerge/echo-data-monitor.d.ts +73 -0
  15. package/dist/types/src/automerge/echo-data-monitor.d.ts.map +1 -0
  16. package/dist/types/src/automerge/echo-data-monitor.test.d.ts +2 -0
  17. package/dist/types/src/automerge/echo-data-monitor.test.d.ts.map +1 -0
  18. package/dist/types/src/automerge/echo-network-adapter.d.ts +9 -0
  19. package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
  20. package/dist/types/src/automerge/index.d.ts +1 -0
  21. package/dist/types/src/automerge/index.d.ts.map +1 -1
  22. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +7 -0
  23. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -1
  24. package/dist/types/src/space/space.d.ts +0 -1
  25. package/dist/types/src/space/space.d.ts.map +1 -1
  26. package/package.json +41 -39
  27. package/src/automerge/automerge-host.ts +11 -34
  28. package/src/automerge/echo-data-monitor.test.ts +55 -0
  29. package/src/automerge/echo-data-monitor.ts +374 -0
  30. package/src/automerge/echo-network-adapter.ts +37 -13
  31. package/src/automerge/index.ts +1 -0
  32. package/src/automerge/leveldb-storage-adapter.ts +19 -1
  33. package/src/space/space.ts +1 -3
  34. package/dist/lib/browser/chunk-6MJEONOX.mjs.map +0 -7
  35. package/dist/lib/node/chunk-PT5LWMPA.cjs.map +0 -7
@@ -446,9 +446,13 @@ var LevelDBStorageAdapter = class extends Resource3 {
446
446
  if (this._lifecycleState !== LifecycleState.OPEN) {
447
447
  return void 0;
448
448
  }
449
- return await this._params.db.get(keyArray, {
449
+ const startMs = Date.now();
450
+ const chunk = await this._params.db.get(keyArray, {
450
451
  ...encodingOptions
451
452
  });
453
+ this._params.monitor?.recordBytesLoaded(chunk.byteLength);
454
+ this._params.monitor?.recordLoadDuration(Date.now() - startMs);
455
+ return chunk;
452
456
  } catch (err) {
453
457
  if (isLevelDbNotFoundError(err)) {
454
458
  return void 0;
@@ -460,6 +464,7 @@ var LevelDBStorageAdapter = class extends Resource3 {
460
464
  if (this._lifecycleState !== LifecycleState.OPEN) {
461
465
  return void 0;
462
466
  }
467
+ const startMs = Date.now();
463
468
  const batch = this._params.db.batch();
464
469
  await this._params.callbacks?.beforeSave?.({
465
470
  path: keyArray,
@@ -469,7 +474,9 @@ var LevelDBStorageAdapter = class extends Resource3 {
469
474
  ...encodingOptions
470
475
  });
471
476
  await batch.write();
477
+ this._params.monitor?.recordBytesStored(binary.byteLength);
472
478
  await this._params.callbacks?.afterSave?.(keyArray);
479
+ this._params.monitor?.recordStoreDuration(Date.now() - startMs);
473
480
  }
474
481
  async remove(keyArray) {
475
482
  if (this._lifecycleState !== LifecycleState.OPEN) {
@@ -483,6 +490,7 @@ var LevelDBStorageAdapter = class extends Resource3 {
483
490
  if (this._lifecycleState !== LifecycleState.OPEN) {
484
491
  return [];
485
492
  }
493
+ const startMs = Date.now();
486
494
  const result = [];
487
495
  for await (const [key, value] of this._params.db.iterator({
488
496
  gte: keyPrefix,
@@ -496,7 +504,9 @@ var LevelDBStorageAdapter = class extends Resource3 {
496
504
  key,
497
505
  data: value
498
506
  });
507
+ this._params.monitor?.recordBytesLoaded(value.byteLength);
499
508
  }
509
+ this._params.monitor?.recordLoadDuration(Date.now() - startMs);
500
510
  return result;
501
511
  }
502
512
  async removeRange(keyPrefix) {
@@ -532,7 +542,7 @@ var isLevelDbNotFoundError = (err) => err.code === "LEVEL_NOT_FOUND";
532
542
 
533
543
  // packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
534
544
  import { Event as Event2, asyncTimeout } from "@dxos/async";
535
- import { next as automerge, getBackend, getHeads, isAutomerge, equals as headsEquals, save } from "@dxos/automerge/automerge";
545
+ import { getBackend, getHeads, isAutomerge, equals as headsEquals, save } from "@dxos/automerge/automerge";
536
546
  import { Repo } from "@dxos/automerge/automerge-repo";
537
547
  import { Context, Resource as Resource4, cancelWithContext as cancelWithContext2 } from "@dxos/context";
538
548
  import { invariant as invariant4 } from "@dxos/invariant";
@@ -540,7 +550,6 @@ import { PublicKey as PublicKey2 } from "@dxos/keys";
540
550
  import { log as log3 } from "@dxos/log";
541
551
  import { objectPointerCodec } from "@dxos/protocols";
542
552
  import { trace } from "@dxos/tracing";
543
- import { mapValues } from "@dxos/util";
544
553
 
545
554
  // packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts
546
555
  import { synchronized, Trigger } from "@dxos/async";
@@ -583,20 +592,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
583
592
  this._connected.wake();
584
593
  }
585
594
  send(message) {
586
- const connectionEntry = this._connections.get(message.targetId);
587
- if (!connectionEntry) {
588
- throw new Error("Connection not found.");
589
- }
590
- connectionEntry.writer.write(message).catch((err) => {
591
- if (connectionEntry.isOpen) {
592
- log2.catch(err, void 0, {
593
- F: __dxlog_file3,
594
- L: 63,
595
- S: this,
596
- C: (f, a) => f(...a)
597
- });
598
- }
599
- });
595
+ this._send(message);
600
596
  }
601
597
  disconnect() {
602
598
  }
@@ -607,7 +603,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
607
603
  this._lifecycleState = LifecycleState2.OPEN;
608
604
  log2("emit ready", void 0, {
609
605
  F: __dxlog_file3,
610
- L: 79,
606
+ L: 78,
611
607
  S: this,
612
608
  C: (f, a) => f(...a)
613
609
  });
@@ -633,7 +629,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
633
629
  async addReplicator(replicator) {
634
630
  invariant3(this._lifecycleState === LifecycleState2.OPEN, void 0, {
635
631
  F: __dxlog_file3,
636
- L: 105,
632
+ L: 104,
637
633
  S: this,
638
634
  A: [
639
635
  "this._lifecycleState === LifecycleState.OPEN",
@@ -642,7 +638,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
642
638
  });
643
639
  invariant3(this.peerId, void 0, {
644
640
  F: __dxlog_file3,
645
- L: 106,
641
+ L: 105,
646
642
  S: this,
647
643
  A: [
648
644
  "this.peerId",
@@ -651,7 +647,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
651
647
  });
652
648
  invariant3(!this._replicators.has(replicator), void 0, {
653
649
  F: __dxlog_file3,
654
- L: 107,
650
+ L: 106,
655
651
  S: this,
656
652
  A: [
657
653
  "!this._replicators.has(replicator)",
@@ -670,7 +666,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
670
666
  async removeReplicator(replicator) {
671
667
  invariant3(this._lifecycleState === LifecycleState2.OPEN, void 0, {
672
668
  F: __dxlog_file3,
673
- L: 121,
669
+ L: 120,
674
670
  S: this,
675
671
  A: [
676
672
  "this._lifecycleState === LifecycleState.OPEN",
@@ -679,7 +675,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
679
675
  });
680
676
  invariant3(this._replicators.has(replicator), void 0, {
681
677
  F: __dxlog_file3,
682
- L: 122,
678
+ L: 121,
683
679
  S: this,
684
680
  A: [
685
681
  "this._replicators.has(replicator)",
@@ -710,7 +706,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
710
706
  targetId,
711
707
  collectionId
712
708
  };
713
- this.send(message);
709
+ this._send(message);
714
710
  }
715
711
  sendCollectionState(collectionId, targetId, state) {
716
712
  const message = {
@@ -720,7 +716,28 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
720
716
  collectionId,
721
717
  state
722
718
  };
723
- this.send(message);
719
+ this._send(message);
720
+ }
721
+ _send(message) {
722
+ const connectionEntry = this._connections.get(message.targetId);
723
+ if (!connectionEntry) {
724
+ throw new Error("Connection not found.");
725
+ }
726
+ const writeStart = Date.now();
727
+ connectionEntry.writer.write(message).then(() => {
728
+ const durationMs = Date.now() - writeStart;
729
+ this._params.monitor?.recordMessageSent(message, durationMs);
730
+ }).catch((err) => {
731
+ if (connectionEntry.isOpen) {
732
+ log2.catch(err, void 0, {
733
+ F: __dxlog_file3,
734
+ L: 181,
735
+ S: this,
736
+ C: (f, a) => f(...a)
737
+ });
738
+ }
739
+ this._params.monitor?.recordMessageSendingFailed(message);
740
+ });
724
741
  }
725
742
  // TODO(dmaretskyi): Remove.
726
743
  getPeersInterestedInCollection(collectionId) {
@@ -735,13 +752,13 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
735
752
  peerId: connection.peerId
736
753
  }, {
737
754
  F: __dxlog_file3,
738
- L: 178,
755
+ L: 199,
739
756
  S: this,
740
757
  C: (f, a) => f(...a)
741
758
  });
742
759
  invariant3(!this._connections.has(connection.peerId), void 0, {
743
760
  F: __dxlog_file3,
744
- L: 179,
761
+ L: 200,
745
762
  S: this,
746
763
  A: [
747
764
  "!this._connections.has(connection.peerId as PeerId)",
@@ -770,7 +787,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
770
787
  if (connectionEntry.isOpen) {
771
788
  log2.catch(err, void 0, {
772
789
  F: __dxlog_file3,
773
- L: 198,
790
+ L: 219,
774
791
  S: this,
775
792
  C: (f, a) => f(...a)
776
793
  });
@@ -781,11 +798,12 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
781
798
  peerId: connection.peerId
782
799
  }, {
783
800
  F: __dxlog_file3,
784
- L: 203,
801
+ L: 224,
785
802
  S: this,
786
803
  C: (f, a) => f(...a)
787
804
  });
788
805
  this._emitPeerCandidate(connection);
806
+ this._params.monitor?.recordPeerConnected(connection.peerId);
789
807
  }
790
808
  _onMessage(message) {
791
809
  if (isCollectionQueryMessage(message)) {
@@ -795,6 +813,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
795
813
  } else {
796
814
  this.emit("message", message);
797
815
  }
816
+ this._params.monitor?.recordMessageReceived(message);
798
817
  }
799
818
  /**
800
819
  * Trigger doc-synchronizer shared documents set recalculation. Happens on peer-candidate.
@@ -805,14 +824,14 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
805
824
  peerId: connection.peerId
806
825
  }, {
807
826
  F: __dxlog_file3,
808
- L: 222,
827
+ L: 245,
809
828
  S: this,
810
829
  C: (f, a) => f(...a)
811
830
  });
812
831
  const entry = this._connections.get(connection.peerId);
813
832
  invariant3(entry, void 0, {
814
833
  F: __dxlog_file3,
815
- L: 224,
834
+ L: 247,
816
835
  S: this,
817
836
  A: [
818
837
  "entry",
@@ -829,14 +848,14 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
829
848
  peerId: connection.peerId
830
849
  }, {
831
850
  F: __dxlog_file3,
832
- L: 230,
851
+ L: 253,
833
852
  S: this,
834
853
  C: (f, a) => f(...a)
835
854
  });
836
855
  const entry = this._connections.get(connection.peerId);
837
856
  invariant3(entry, void 0, {
838
857
  F: __dxlog_file3,
839
- L: 232,
858
+ L: 255,
840
859
  S: this,
841
860
  A: [
842
861
  "entry",
@@ -847,15 +866,16 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
847
866
  this.emit("peer-disconnected", {
848
867
  peerId: connection.peerId
849
868
  });
869
+ this._params.monitor?.recordPeerDisconnected(connection.peerId);
850
870
  void entry.reader.cancel().catch((err) => log2.catch(err, void 0, {
851
871
  F: __dxlog_file3,
852
- L: 237,
872
+ L: 261,
853
873
  S: this,
854
874
  C: (f, a) => f(...a)
855
875
  }));
856
876
  void entry.writer.abort().catch((err) => log2.catch(err, void 0, {
857
877
  F: __dxlog_file3,
858
- L: 238,
878
+ L: 262,
859
879
  S: this,
860
880
  C: (f, a) => f(...a)
861
881
  }));
@@ -921,13 +941,8 @@ function _ts_decorate2(decorators, target, key, desc) {
921
941
  }
922
942
  var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
923
943
  var AutomergeHost = class extends Resource4 {
924
- constructor({ db, indexMetadataStore }) {
944
+ constructor({ db, indexMetadataStore, dataMonitor }) {
925
945
  super();
926
- this._echoNetworkAdapter = new EchoNetworkAdapter({
927
- getContainingSpaceForDocument: this._getContainingSpaceForDocument.bind(this),
928
- onCollectionStateQueried: this._onCollectionStateQueried.bind(this),
929
- onCollectionStateReceived: this._onCollectionStateReceived.bind(this)
930
- });
931
946
  this._collectionSynchronizer = new CollectionSynchronizer({
932
947
  queryCollectionState: this._queryCollectionState.bind(this),
933
948
  sendCollectionState: this._sendCollectionState.bind(this),
@@ -939,7 +954,14 @@ var AutomergeHost = class extends Resource4 {
939
954
  callbacks: {
940
955
  beforeSave: async (params) => this._beforeSave(params),
941
956
  afterSave: async (key) => this._afterSave(key)
942
- }
957
+ },
958
+ monitor: dataMonitor
959
+ });
960
+ this._echoNetworkAdapter = new EchoNetworkAdapter({
961
+ getContainingSpaceForDocument: this._getContainingSpaceForDocument.bind(this),
962
+ onCollectionStateQueried: this._onCollectionStateQueried.bind(this),
963
+ onCollectionStateReceived: this._onCollectionStateReceived.bind(this),
964
+ monitor: dataMonitor
943
965
  });
944
966
  this._headsStore = new HeadsStore({
945
967
  db: db.sublevel("heads")
@@ -1044,7 +1066,7 @@ var AutomergeHost = class extends Resource4 {
1044
1066
  await Promise.all(headsToWait.map(async (entry, index) => {
1045
1067
  const handle = await this.loadDoc(Context.default(void 0, {
1046
1068
  F: __dxlog_file4,
1047
- L: 223
1069
+ L: 226
1048
1070
  }), entry.documentId);
1049
1071
  await waitForHeads(handle, entry.heads);
1050
1072
  }));
@@ -1057,7 +1079,7 @@ var AutomergeHost = class extends Resource4 {
1057
1079
  documentId
1058
1080
  }, {
1059
1081
  F: __dxlog_file4,
1060
- L: 235,
1082
+ L: 238,
1061
1083
  S: this,
1062
1084
  C: (f, a) => f(...a)
1063
1085
  });
@@ -1073,7 +1095,7 @@ var AutomergeHost = class extends Resource4 {
1073
1095
  documentId
1074
1096
  }, {
1075
1097
  F: __dxlog_file4,
1076
- L: 239,
1098
+ L: 242,
1077
1099
  S: this,
1078
1100
  C: (f, a) => f(...a)
1079
1101
  });
@@ -1082,7 +1104,7 @@ var AutomergeHost = class extends Resource4 {
1082
1104
  const doc = handle.docSync();
1083
1105
  invariant4(doc, void 0, {
1084
1106
  F: __dxlog_file4,
1085
- L: 244,
1107
+ L: 247,
1086
1108
  S: this,
1087
1109
  A: [
1088
1110
  "doc",
@@ -1096,7 +1118,7 @@ var AutomergeHost = class extends Resource4 {
1096
1118
  }
1097
1119
  log3.info("done re-indexing heads", void 0, {
1098
1120
  F: __dxlog_file4,
1099
- L: 251,
1121
+ L: 254,
1100
1122
  S: this,
1101
1123
  C: (f, a) => f(...a)
1102
1124
  });
@@ -1165,28 +1187,6 @@ var AutomergeHost = class extends Resource4 {
1165
1187
  this._onHeadsChanged(documentId, heads);
1166
1188
  }
1167
1189
  }
1168
- _automergeDocs() {
1169
- return mapValues(this._repo.handles, (handle) => ({
1170
- state: handle.state,
1171
- hasDoc: !!handle.docSync(),
1172
- heads: handle.docSync() ? automerge.getHeads(handle.docSync()) : null,
1173
- data: handle.docSync() && mapValues(handle.docSync(), (value, key) => {
1174
- try {
1175
- switch (key) {
1176
- case "access":
1177
- case "links":
1178
- return value;
1179
- case "objects":
1180
- return Object.keys(value);
1181
- default:
1182
- return `${value}`;
1183
- }
1184
- } catch (err) {
1185
- return `${err}`;
1186
- }
1187
- })
1188
- }));
1189
- }
1190
1190
  _automergePeers() {
1191
1191
  return this._repo.peers;
1192
1192
  }
@@ -1304,7 +1304,7 @@ var AutomergeHost = class extends Resource4 {
1304
1304
  count: different.length
1305
1305
  }, {
1306
1306
  F: __dxlog_file4,
1307
- L: 486,
1307
+ L: 463,
1308
1308
  S: this,
1309
1309
  C: (f, a) => f(...a)
1310
1310
  });
@@ -1326,11 +1326,6 @@ var AutomergeHost = class extends Resource4 {
1326
1326
  _ts_decorate2([
1327
1327
  trace.info()
1328
1328
  ], AutomergeHost.prototype, "_peerId", void 0);
1329
- _ts_decorate2([
1330
- trace.info({
1331
- depth: null
1332
- })
1333
- ], AutomergeHost.prototype, "_automergeDocs", null);
1334
1329
  _ts_decorate2([
1335
1330
  trace.info({
1336
1331
  depth: null
@@ -1369,7 +1364,7 @@ var changeIsPresentInDoc = (doc, changeHash) => {
1369
1364
  var decodeCollectionState = (state) => {
1370
1365
  invariant4(typeof state === "object" && state !== null, "Invalid state", {
1371
1366
  F: __dxlog_file4,
1372
- L: 539,
1367
+ L: 516,
1373
1368
  S: void 0,
1374
1369
  A: [
1375
1370
  "typeof state === 'object' && state !== null",
@@ -2074,7 +2069,7 @@ _ts_decorate4([
2074
2069
  ], Pipeline.prototype, "unpause", null);
2075
2070
 
2076
2071
  // packages/core/echo/echo-pipeline/src/space/space.ts
2077
- import { Event as Event5, Mutex, synchronized as synchronized3, trackLeaks as trackLeaks2 } from "@dxos/async";
2072
+ import { Event as Event5, synchronized as synchronized3, trackLeaks as trackLeaks2 } from "@dxos/async";
2078
2073
  import { LifecycleState as LifecycleState3, Resource as Resource5 } from "@dxos/context";
2079
2074
  import { subtleCrypto as subtleCrypto2 } from "@dxos/crypto";
2080
2075
  import { invariant as invariant9 } from "@dxos/invariant";
@@ -2368,12 +2363,11 @@ var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeli
2368
2363
  var Space = class extends Resource5 {
2369
2364
  constructor(params) {
2370
2365
  super();
2371
- this._addFeedMutex = new Mutex();
2372
2366
  this.onCredentialProcessed = new Callback2();
2373
2367
  this.stateUpdate = new Event5();
2374
2368
  invariant9(params.spaceKey && params.feedProvider, void 0, {
2375
2369
  F: __dxlog_file11,
2376
- L: 78,
2370
+ L: 76,
2377
2371
  S: this,
2378
2372
  A: [
2379
2373
  "params.spaceKey && params.feedProvider",
@@ -2407,7 +2401,7 @@ var Space = class extends Resource5 {
2407
2401
  credential
2408
2402
  }, {
2409
2403
  F: __dxlog_file11,
2410
- L: 106,
2404
+ L: 104,
2411
2405
  S: this,
2412
2406
  C: (f, a) => f(...a)
2413
2407
  });
@@ -2418,7 +2412,7 @@ var Space = class extends Resource5 {
2418
2412
  invitation
2419
2413
  }, {
2420
2414
  F: __dxlog_file11,
2421
- L: 110,
2415
+ L: 108,
2422
2416
  S: this,
2423
2417
  C: (f, a) => f(...a)
2424
2418
  });
@@ -2429,7 +2423,7 @@ var Space = class extends Resource5 {
2429
2423
  invitation
2430
2424
  }, {
2431
2425
  F: __dxlog_file11,
2432
- L: 114,
2426
+ L: 112,
2433
2427
  S: this,
2434
2428
  C: (f, a) => f(...a)
2435
2429
  });
@@ -2443,7 +2437,7 @@ var Space = class extends Resource5 {
2443
2437
  ])
2444
2438
  }), {
2445
2439
  F: __dxlog_file11,
2446
- L: 118,
2440
+ L: 116,
2447
2441
  S: this,
2448
2442
  C: (f, a) => f(...a)
2449
2443
  });
@@ -2485,7 +2479,7 @@ var Space = class extends Resource5 {
2485
2479
  async setControlFeed(feed) {
2486
2480
  invariant9(!this._controlFeed, "Control feed already set.", {
2487
2481
  F: __dxlog_file11,
2488
- L: 171,
2482
+ L: 169,
2489
2483
  S: this,
2490
2484
  A: [
2491
2485
  "!this._controlFeed",
@@ -2499,7 +2493,7 @@ var Space = class extends Resource5 {
2499
2493
  async setDataFeed(feed) {
2500
2494
  invariant9(!this._dataFeed, "Data feed already set.", {
2501
2495
  F: __dxlog_file11,
2502
- L: 178,
2496
+ L: 176,
2503
2497
  S: this,
2504
2498
  A: [
2505
2499
  "!this._dataFeed",
@@ -2518,7 +2512,7 @@ var Space = class extends Resource5 {
2518
2512
  async _open(ctx) {
2519
2513
  log9("opening...", void 0, {
2520
2514
  F: __dxlog_file11,
2521
- L: 192,
2515
+ L: 190,
2522
2516
  S: this,
2523
2517
  C: (f, a) => f(...a)
2524
2518
  });
@@ -2526,7 +2520,7 @@ var Space = class extends Resource5 {
2526
2520
  await this.protocol.start();
2527
2521
  log9("opened", void 0, {
2528
2522
  F: __dxlog_file11,
2529
- L: 198,
2523
+ L: 196,
2530
2524
  S: this,
2531
2525
  C: (f, a) => f(...a)
2532
2526
  });
@@ -2536,7 +2530,7 @@ var Space = class extends Resource5 {
2536
2530
  key: this._key
2537
2531
  }, {
2538
2532
  F: __dxlog_file11,
2539
- L: 203,
2533
+ L: 201,
2540
2534
  S: this,
2541
2535
  C: (f, a) => f(...a)
2542
2536
  });
@@ -2544,7 +2538,7 @@ var Space = class extends Resource5 {
2544
2538
  await this._controlPipeline.stop();
2545
2539
  log9("closed", void 0, {
2546
2540
  F: __dxlog_file11,
2547
- L: 209,
2541
+ L: 207,
2548
2542
  S: this,
2549
2543
  C: (f, a) => f(...a)
2550
2544
  });
@@ -2878,7 +2872,7 @@ import { synchronized as synchronized4, trackLeaks as trackLeaks3, Trigger as Tr
2878
2872
  import { failUndefined as failUndefined2 } from "@dxos/debug";
2879
2873
  import { PublicKey as PublicKey8 } from "@dxos/keys";
2880
2874
  import { log as log14 } from "@dxos/log";
2881
- import { trace as trace5 } from "@dxos/protocols";
2875
+ import { trace as trace6 } from "@dxos/protocols";
2882
2876
  import { ComplexMap as ComplexMap4 } from "@dxos/util";
2883
2877
 
2884
2878
  // packages/core/echo/echo-pipeline/src/db-host/data-service.ts
@@ -3215,6 +3209,371 @@ var MeshEchoReplicator = class {
3215
3209
  }
3216
3210
  };
3217
3211
 
3212
+ // packages/core/echo/echo-pipeline/src/automerge/echo-data-monitor.ts
3213
+ import { trace as trace5 } from "@dxos/tracing";
3214
+ import { CircularBuffer, mapValues, SlidingWindowSummary } from "@dxos/util";
3215
+ function _ts_decorate8(decorators, target, key, desc) {
3216
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3217
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
3218
+ r = Reflect.decorate(decorators, target, key, desc);
3219
+ else
3220
+ for (var i = decorators.length - 1; i >= 0; i--)
3221
+ if (d = decorators[i])
3222
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3223
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
3224
+ }
3225
+ var PER_SECOND_RATE_AVG_WINDOW_SIZE = 5;
3226
+ var DEFAULT_AVG_WINDOW_SIZE = 25;
3227
+ var EchoDataMonitor = class {
3228
+ constructor(_params = {
3229
+ timeSeriesLength: 30
3230
+ }) {
3231
+ this._params = _params;
3232
+ this._lastTick = 0;
3233
+ this._activeCounters = createLocalCounters();
3234
+ this._localTimeSeries = createLocalTimeSeries();
3235
+ this._storageAverages = createStorageAverages();
3236
+ this._replicationAverages = createNetworkAverages();
3237
+ this._sizeByMessageType = {};
3238
+ this._lastReceivedMessages = new CircularBuffer(100);
3239
+ this._lastSentMessages = new CircularBuffer(100);
3240
+ this._connectionsCount = 0;
3241
+ }
3242
+ tick(timeMs) {
3243
+ this._advanceTimeWindow(timeMs - this._lastTick);
3244
+ this._lastTick = timeMs;
3245
+ }
3246
+ computeStats() {
3247
+ return {
3248
+ meta: {
3249
+ rateAverageOverSeconds: PER_SECOND_RATE_AVG_WINDOW_SIZE
3250
+ },
3251
+ storage: {
3252
+ reads: {
3253
+ payloadSize: this._storageAverages.loadedChunkSize.average(),
3254
+ opDuration: this._storageAverages.loadDuration.average(),
3255
+ countPerSecond: this._storageAverages.loadsPerSecond.average()
3256
+ },
3257
+ writes: {
3258
+ payloadSize: this._storageAverages.storedChunkSize.average(),
3259
+ opDuration: this._storageAverages.storeDuration.average(),
3260
+ countPerSecond: this._storageAverages.storesPerSecond.average()
3261
+ }
3262
+ },
3263
+ replicator: {
3264
+ connections: this._connectionsCount,
3265
+ receivedMessages: {
3266
+ payloadSize: this._replicationAverages.receivedMessageSize.average(),
3267
+ countPerSecond: this._replicationAverages.receivedPerSecond.average()
3268
+ },
3269
+ sentMessages: {
3270
+ payloadSize: this._replicationAverages.sentMessageSize.average(),
3271
+ opDuration: this._replicationAverages.sendDuration.average(),
3272
+ countPerSecond: this._replicationAverages.sentPerSecond.average(),
3273
+ failedPerSecond: this._replicationAverages.sendsFailedPerSecond.average()
3274
+ },
3275
+ countByMessageType: this._computeMessageHistogram("type"),
3276
+ avgSizeByMessageType: mapValues(this._sizeByMessageType, (summary) => summary.average())
3277
+ }
3278
+ };
3279
+ }
3280
+ get connectionsCount() {
3281
+ return this._connectionsCount;
3282
+ }
3283
+ /**
3284
+ * @internal
3285
+ */
3286
+ get lastPerSecondStats() {
3287
+ return this._lastCompleteCounters;
3288
+ }
3289
+ /**
3290
+ * @internal
3291
+ */
3292
+ get timeSeries() {
3293
+ return {
3294
+ ...this._localTimeSeries.storage,
3295
+ ...this._localTimeSeries.replication
3296
+ };
3297
+ }
3298
+ /**
3299
+ * @internal
3300
+ */
3301
+ get messagesByPeerId() {
3302
+ return this._computeMessageHistogram("peerId");
3303
+ }
3304
+ _advanceTimeWindow(millisPassed) {
3305
+ const oldMetrics = Object.freeze(this._activeCounters);
3306
+ this._activeCounters = createLocalCounters();
3307
+ this._lastCompleteCounters = oldMetrics;
3308
+ for (const peerId of Object.keys(oldMetrics.byPeerId)) {
3309
+ this._activeCounters.byPeerId[peerId] = createMessageCounter();
3310
+ }
3311
+ this._addToTimeSeries(oldMetrics.replication, this._localTimeSeries.replication);
3312
+ this._addToTimeSeries(oldMetrics.storage, this._localTimeSeries.storage);
3313
+ if (Math.abs(millisPassed - 1e3) < 100) {
3314
+ this._reportPerSecondRate(oldMetrics);
3315
+ }
3316
+ }
3317
+ _addToTimeSeries(values, timeSeries) {
3318
+ for (const [key, value] of Object.entries(values)) {
3319
+ const values2 = timeSeries[key];
3320
+ values2.push(value);
3321
+ if (values2.length > this._params.timeSeriesLength) {
3322
+ values2.shift();
3323
+ }
3324
+ }
3325
+ }
3326
+ _reportPerSecondRate(metrics) {
3327
+ const toReport = [
3328
+ [
3329
+ "storage.load",
3330
+ metrics.storage.loadedChunks,
3331
+ this._storageAverages.loadsPerSecond
3332
+ ],
3333
+ [
3334
+ "storage.store",
3335
+ metrics.storage.storedChunks,
3336
+ this._storageAverages.storesPerSecond
3337
+ ],
3338
+ [
3339
+ "network.receive",
3340
+ metrics.replication.received,
3341
+ this._replicationAverages.receivedPerSecond
3342
+ ],
3343
+ [
3344
+ "network.send",
3345
+ metrics.replication.sent,
3346
+ this._replicationAverages.sentPerSecond
3347
+ ]
3348
+ ];
3349
+ for (const [metricName, metric, summary] of toReport) {
3350
+ summary.record(metric);
3351
+ if (metric > 0) {
3352
+ trace5.metrics.distribution(`dxos.echo.${metricName}-rate`, metric);
3353
+ trace5.metrics.increment(`dxos.echo.${metricName}`, 1, {
3354
+ tags: {
3355
+ status: "busy"
3356
+ }
3357
+ });
3358
+ } else {
3359
+ trace5.metrics.increment(`dxos.echo.${metricName}`, 1, {
3360
+ tags: {
3361
+ status: "idle"
3362
+ }
3363
+ });
3364
+ }
3365
+ }
3366
+ this._replicationAverages.sendsFailedPerSecond.record(metrics.replication.failed);
3367
+ }
3368
+ recordPeerConnected(peerId) {
3369
+ this._activeCounters.byPeerId[peerId] = createMessageCounter();
3370
+ this._connectionsCount++;
3371
+ }
3372
+ recordPeerDisconnected(peerId) {
3373
+ this._connectionsCount--;
3374
+ delete this._activeCounters.byPeerId[peerId];
3375
+ }
3376
+ recordBytesStored(count) {
3377
+ this._activeCounters.storage.storedChunks++;
3378
+ this._activeCounters.storage.storedBytes += count;
3379
+ this._storageAverages.storedChunkSize.record(count);
3380
+ trace5.metrics.distribution("dxos.echo.storage.bytes-stored", count, {
3381
+ unit: "bytes"
3382
+ });
3383
+ }
3384
+ recordLoadDuration(durationMs) {
3385
+ this._storageAverages.loadDuration.record(durationMs);
3386
+ }
3387
+ recordStoreDuration(durationMs) {
3388
+ this._storageAverages.storeDuration.record(durationMs);
3389
+ }
3390
+ recordBytesLoaded(count) {
3391
+ this._activeCounters.storage.loadedChunks++;
3392
+ this._activeCounters.storage.loadedBytes += count;
3393
+ this._storageAverages.loadedChunkSize.record(count);
3394
+ trace5.metrics.distribution("dxos.echo.storage.bytes-loaded", count, {
3395
+ unit: "bytes"
3396
+ });
3397
+ }
3398
+ recordMessageSent(message, duration) {
3399
+ let metricsGroupName;
3400
+ const bytes = getByteCount(message);
3401
+ const tags = {
3402
+ type: message.type
3403
+ };
3404
+ if (isAutomergeProtocolMessage(message)) {
3405
+ this._activeCounters.replication.sent++;
3406
+ this._replicationAverages.sendDuration.record(duration);
3407
+ this._replicationAverages.sentMessageSize.record(bytes);
3408
+ metricsGroupName = "replication";
3409
+ } else {
3410
+ metricsGroupName = "collection-sync";
3411
+ }
3412
+ trace5.metrics.distribution(`dxos.echo.${metricsGroupName}.bytes-sent`, bytes, {
3413
+ unit: "bytes",
3414
+ tags
3415
+ });
3416
+ trace5.metrics.distribution(`dxos.echo.${metricsGroupName}.send-duration`, duration, {
3417
+ unit: "millisecond",
3418
+ tags
3419
+ });
3420
+ trace5.metrics.increment(`dxos.echo.${metricsGroupName}.send-status`, 1, {
3421
+ tags: {
3422
+ ...tags,
3423
+ success: true
3424
+ }
3425
+ });
3426
+ const { messageSize, messageCounts } = this._getStatsForType(message);
3427
+ messageSize.record(bytes);
3428
+ messageCounts.sent++;
3429
+ this._lastSentMessages.push({
3430
+ type: message.type,
3431
+ peerId: message.targetId
3432
+ });
3433
+ }
3434
+ recordMessageReceived(message) {
3435
+ const bytes = getByteCount(message);
3436
+ const tags = {
3437
+ type: message.type
3438
+ };
3439
+ if (isAutomergeProtocolMessage(message)) {
3440
+ this._activeCounters.replication.received++;
3441
+ this._replicationAverages.receivedMessageSize.record(bytes);
3442
+ trace5.metrics.distribution("dxos.echo.replication.bytes-received", bytes, {
3443
+ unit: "bytes",
3444
+ tags
3445
+ });
3446
+ } else {
3447
+ trace5.metrics.distribution("dxos.echo.collection-sync.bytes-received", bytes, {
3448
+ unit: "bytes",
3449
+ tags
3450
+ });
3451
+ }
3452
+ const { messageSize, messageCounts } = this._getStatsForType(message);
3453
+ messageSize.record(bytes);
3454
+ messageCounts.received++;
3455
+ this._lastReceivedMessages.push({
3456
+ type: message.type,
3457
+ peerId: message.senderId
3458
+ });
3459
+ }
3460
+ recordMessageSendingFailed(message) {
3461
+ const tags = {
3462
+ type: message.type,
3463
+ success: false
3464
+ };
3465
+ if (isAutomergeProtocolMessage(message)) {
3466
+ this._activeCounters.replication.failed++;
3467
+ trace5.metrics.increment("dxos.echo.replication.send-status", 1, {
3468
+ unit: "bytes",
3469
+ tags
3470
+ });
3471
+ } else {
3472
+ trace5.metrics.increment("dxos.echo.collection-sync.send-status", 1, {
3473
+ unit: "bytes",
3474
+ tags
3475
+ });
3476
+ }
3477
+ const { messageCounts } = this._getStatsForType(message);
3478
+ messageCounts.failed++;
3479
+ }
3480
+ _getStatsForType(message) {
3481
+ const messageSize = this._sizeByMessageType[message.type] ??= createSlidingWindow();
3482
+ const messageCounts = this._activeCounters.byType[message.type] ??= createMessageCounter();
3483
+ return {
3484
+ messageCounts,
3485
+ messageSize
3486
+ };
3487
+ }
3488
+ _computeMessageHistogram(groupKey) {
3489
+ const result = {};
3490
+ for (const receivedMessage of this._lastReceivedMessages) {
3491
+ const counters = result[receivedMessage[groupKey]] ??= {
3492
+ received: 0,
3493
+ sent: 0
3494
+ };
3495
+ counters.received++;
3496
+ }
3497
+ for (const receivedMessage of this._lastSentMessages) {
3498
+ const counters = result[receivedMessage[groupKey]] ??= {
3499
+ received: 0,
3500
+ sent: 0
3501
+ };
3502
+ counters.sent++;
3503
+ }
3504
+ return result;
3505
+ }
3506
+ };
3507
+ EchoDataMonitor = _ts_decorate8([
3508
+ trace5.resource()
3509
+ ], EchoDataMonitor);
3510
+ var isAutomergeProtocolMessage = (message) => {
3511
+ return !(isCollectionQueryMessage(message) || isCollectionStateMessage(message));
3512
+ };
3513
+ var createSlidingWindow = (overrides) => new SlidingWindowSummary({
3514
+ dataPoints: DEFAULT_AVG_WINDOW_SIZE,
3515
+ precision: 2,
3516
+ ...overrides
3517
+ });
3518
+ var createLocalCounters = () => ({
3519
+ storage: {
3520
+ loadedBytes: 0,
3521
+ storedBytes: 0,
3522
+ storedChunks: 0,
3523
+ loadedChunks: 0
3524
+ },
3525
+ replication: createMessageCounter(),
3526
+ byPeerId: {},
3527
+ byType: {}
3528
+ });
3529
+ var createLocalTimeSeries = () => ({
3530
+ storage: {
3531
+ loadedBytes: [],
3532
+ storedBytes: [],
3533
+ storedChunks: [],
3534
+ loadedChunks: []
3535
+ },
3536
+ replication: {
3537
+ sent: [],
3538
+ failed: [],
3539
+ received: []
3540
+ }
3541
+ });
3542
+ var createMessageCounter = () => ({
3543
+ sent: 0,
3544
+ received: 0,
3545
+ failed: 0
3546
+ });
3547
+ var createNetworkAverages = () => ({
3548
+ receivedMessageSize: createSlidingWindow(),
3549
+ sentMessageSize: createSlidingWindow(),
3550
+ sendDuration: createSlidingWindow(),
3551
+ receivedPerSecond: createSlidingWindow({
3552
+ dataPoints: PER_SECOND_RATE_AVG_WINDOW_SIZE
3553
+ }),
3554
+ sentPerSecond: createSlidingWindow({
3555
+ dataPoints: PER_SECOND_RATE_AVG_WINDOW_SIZE
3556
+ }),
3557
+ sendsFailedPerSecond: createSlidingWindow({
3558
+ dataPoints: PER_SECOND_RATE_AVG_WINDOW_SIZE
3559
+ })
3560
+ });
3561
+ var createStorageAverages = () => ({
3562
+ storedChunkSize: createSlidingWindow(),
3563
+ loadedChunkSize: createSlidingWindow(),
3564
+ loadDuration: createSlidingWindow(),
3565
+ storeDuration: createSlidingWindow(),
3566
+ loadsPerSecond: createSlidingWindow({
3567
+ dataPoints: PER_SECOND_RATE_AVG_WINDOW_SIZE
3568
+ }),
3569
+ storesPerSecond: createSlidingWindow({
3570
+ dataPoints: PER_SECOND_RATE_AVG_WINDOW_SIZE
3571
+ })
3572
+ });
3573
+ var getByteCount = (message) => {
3574
+ return message.type.length + message.senderId.length + message.targetId.length + (message.data?.byteLength ?? 0) + (message.documentId?.length ?? 0);
3575
+ };
3576
+
3218
3577
  // packages/core/echo/echo-pipeline/src/db-host/data-service.ts
3219
3578
  var __dxlog_file16 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/db-host/data-service.ts";
3220
3579
  var DataServiceImpl = class {
@@ -3332,7 +3691,7 @@ var DataServiceImpl = class {
3332
3691
  };
3333
3692
 
3334
3693
  // packages/core/echo/echo-pipeline/src/space/space-manager.ts
3335
- function _ts_decorate8(decorators, target, key, desc) {
3694
+ function _ts_decorate9(decorators, target, key, desc) {
3336
3695
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3337
3696
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
3338
3697
  r = Reflect.decorate(decorators, target, key, desc);
@@ -3365,7 +3724,7 @@ var SpaceManager = class {
3365
3724
  ].map((space) => space.close()));
3366
3725
  }
3367
3726
  async constructSpace({ metadata, swarmIdentity, onAuthorizedConnection, onAuthFailure, onDelegatedInvitationStatusChange, onMemberRolesChanged, memberKey }) {
3368
- log14.trace("dxos.echo.space-manager.construct-space", trace5.begin({
3727
+ log14.trace("dxos.echo.space-manager.construct-space", trace6.begin({
3369
3728
  id: this._instanceId
3370
3729
  }), {
3371
3730
  F: __dxlog_file17,
@@ -3406,7 +3765,7 @@ var SpaceManager = class {
3406
3765
  onMemberRolesChanged
3407
3766
  });
3408
3767
  this._spaces.set(space.key, space);
3409
- log14.trace("dxos.echo.space-manager.construct-space", trace5.end({
3768
+ log14.trace("dxos.echo.space-manager.construct-space", trace6.end({
3410
3769
  id: this._instanceId
3411
3770
  }), {
3412
3771
  F: __dxlog_file17,
@@ -3418,7 +3777,7 @@ var SpaceManager = class {
3418
3777
  }
3419
3778
  async requestSpaceAdmissionCredential(params) {
3420
3779
  const traceKey = "dxos.echo.space-manager.request-space-admission";
3421
- log14.trace(traceKey, trace5.begin({
3780
+ log14.trace(traceKey, trace6.begin({
3422
3781
  id: this._instanceId
3423
3782
  }), {
3424
3783
  F: __dxlog_file17,
@@ -3453,7 +3812,7 @@ var SpaceManager = class {
3453
3812
  const credential = await onCredentialResolved.wait({
3454
3813
  timeout: params.timeout
3455
3814
  });
3456
- log14.trace(traceKey, trace5.end({
3815
+ log14.trace(traceKey, trace6.end({
3457
3816
  id: this._instanceId
3458
3817
  }), {
3459
3818
  F: __dxlog_file17,
@@ -3463,7 +3822,7 @@ var SpaceManager = class {
3463
3822
  });
3464
3823
  return credential;
3465
3824
  } catch (err) {
3466
- log14.trace(traceKey, trace5.error({
3825
+ log14.trace(traceKey, trace6.error({
3467
3826
  id: this._instanceId,
3468
3827
  error: err
3469
3828
  }), {
@@ -3478,13 +3837,13 @@ var SpaceManager = class {
3478
3837
  }
3479
3838
  }
3480
3839
  };
3481
- _ts_decorate8([
3840
+ _ts_decorate9([
3482
3841
  synchronized4
3483
3842
  ], SpaceManager.prototype, "open", null);
3484
- _ts_decorate8([
3843
+ _ts_decorate9([
3485
3844
  synchronized4
3486
3845
  ], SpaceManager.prototype, "close", null);
3487
- SpaceManager = _ts_decorate8([
3846
+ SpaceManager = _ts_decorate9([
3488
3847
  trackLeaks3("open", "close")
3489
3848
  ], SpaceManager);
3490
3849
 
@@ -3498,7 +3857,7 @@ import { log as log15 } from "@dxos/log";
3498
3857
  import { DataCorruptionError, STORAGE_VERSION, schema as schema6 } from "@dxos/protocols";
3499
3858
  import { Invitation, SpaceState } from "@dxos/protocols/proto/dxos/client/services";
3500
3859
  import { ComplexMap as ComplexMap5, arrayToBuffer, forEachAsync, isNotNullOrUndefined } from "@dxos/util";
3501
- function _ts_decorate9(decorators, target, key, desc) {
3860
+ function _ts_decorate10(decorators, target, key, desc) {
3502
3861
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3503
3862
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
3504
3863
  r = Reflect.decorate(decorators, target, key, desc);
@@ -3814,13 +4173,13 @@ var MetadataStore = class {
3814
4173
  await this.flush();
3815
4174
  }
3816
4175
  };
3817
- _ts_decorate9([
4176
+ _ts_decorate10([
3818
4177
  synchronized5
3819
4178
  ], MetadataStore.prototype, "load", null);
3820
- _ts_decorate9([
4179
+ _ts_decorate10([
3821
4180
  synchronized5
3822
4181
  ], MetadataStore.prototype, "_save", null);
3823
- _ts_decorate9([
4182
+ _ts_decorate10([
3824
4183
  synchronized5
3825
4184
  ], MetadataStore.prototype, "_saveSpaceLargeMetadata", null);
3826
4185
  var fromBytesInt32 = (buf) => buf.readInt32LE(0);
@@ -3862,8 +4221,9 @@ export {
3862
4221
  SpaceProtocolSession,
3863
4222
  SpaceManager,
3864
4223
  MeshEchoReplicator,
4224
+ EchoDataMonitor,
3865
4225
  DataServiceImpl,
3866
4226
  MetadataStore,
3867
4227
  hasInvitationExpired
3868
4228
  };
3869
- //# sourceMappingURL=chunk-6MJEONOX.mjs.map
4229
+ //# sourceMappingURL=chunk-2MII6KJX.mjs.map