@dxos/echo-pipeline 0.8.4-main.ae835ea → 0.8.4-main.bc2380dfbc

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 (221) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/{browser/chunk-WJJXJTNS.mjs → neutral/chunk-46DCRDA7.mjs} +44 -13
  4. package/dist/lib/neutral/chunk-46DCRDA7.mjs.map +7 -0
  5. package/dist/lib/{browser/chunk-FR6GJ4S4.mjs → neutral/chunk-LR7UFVQX.mjs} +145 -618
  6. package/dist/lib/neutral/chunk-LR7UFVQX.mjs.map +7 -0
  7. package/dist/lib/{browser → neutral}/filter/index.mjs +1 -2
  8. package/dist/lib/neutral/index.mjs +7332 -0
  9. package/dist/lib/neutral/index.mjs.map +7 -0
  10. package/dist/lib/neutral/meta.json +1 -0
  11. package/dist/lib/{browser → neutral}/testing/index.mjs +49 -292
  12. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  13. package/dist/types/src/automerge/automerge-host-subduction.test.d.ts +2 -0
  14. package/dist/types/src/automerge/automerge-host-subduction.test.d.ts.map +1 -0
  15. package/dist/types/src/automerge/automerge-host.d.ts +105 -27
  16. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  17. package/dist/types/src/automerge/automerge-repo-subduction.test.d.ts +2 -0
  18. package/dist/types/src/automerge/automerge-repo-subduction.test.d.ts.map +1 -0
  19. package/dist/types/src/automerge/automerge-repo.test.d.ts +1 -1
  20. package/dist/types/src/automerge/automerge-repo.test.d.ts.map +1 -1
  21. package/dist/types/src/automerge/automerge-subduction.test.d.ts +2 -0
  22. package/dist/types/src/automerge/automerge-subduction.test.d.ts.map +1 -0
  23. package/dist/types/src/automerge/collection-synchronizer.d.ts +22 -2
  24. package/dist/types/src/automerge/collection-synchronizer.d.ts.map +1 -1
  25. package/dist/types/src/automerge/echo-data-monitor.d.ts.map +1 -1
  26. package/dist/types/src/automerge/echo-network-adapter.d.ts +17 -11
  27. package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
  28. package/dist/types/src/automerge/echo-replicator.d.ts +28 -16
  29. package/dist/types/src/automerge/echo-replicator.d.ts.map +1 -1
  30. package/dist/types/src/automerge/errors.d.ts +35 -0
  31. package/dist/types/src/automerge/errors.d.ts.map +1 -0
  32. package/dist/types/src/automerge/handle-state.d.ts +52 -0
  33. package/dist/types/src/automerge/handle-state.d.ts.map +1 -0
  34. package/dist/types/src/automerge/heads-store.d.ts +9 -2
  35. package/dist/types/src/automerge/heads-store.d.ts.map +1 -1
  36. package/dist/types/src/automerge/index.d.ts +2 -0
  37. package/dist/types/src/automerge/index.d.ts.map +1 -1
  38. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +10 -4
  39. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -1
  40. package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts +8 -8
  41. package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts.map +1 -1
  42. package/dist/types/src/automerge/mesh-echo-replicator.d.ts +6 -5
  43. package/dist/types/src/automerge/mesh-echo-replicator.d.ts.map +1 -1
  44. package/dist/types/src/automerge/network-protocol.d.ts.map +1 -1
  45. package/dist/types/src/automerge/space-collection.d.ts.map +1 -1
  46. package/dist/types/src/common/feeds.d.ts.map +1 -1
  47. package/dist/types/src/common/space-id.d.ts.map +1 -1
  48. package/dist/types/src/db-host/automerge-data-source.d.ts +35 -0
  49. package/dist/types/src/db-host/automerge-data-source.d.ts.map +1 -0
  50. package/dist/types/src/db-host/automerge-data-source.test.d.ts +2 -0
  51. package/dist/types/src/db-host/automerge-data-source.test.d.ts.map +1 -0
  52. package/dist/types/src/db-host/automerge-metrics.d.ts.map +1 -1
  53. package/dist/types/src/db-host/data-service.d.ts +12 -6
  54. package/dist/types/src/db-host/data-service.d.ts.map +1 -1
  55. package/dist/types/src/db-host/database-root.d.ts +9 -3
  56. package/dist/types/src/db-host/database-root.d.ts.map +1 -1
  57. package/dist/types/src/db-host/documents-synchronizer.d.ts +30 -8
  58. package/dist/types/src/db-host/documents-synchronizer.d.ts.map +1 -1
  59. package/dist/types/src/db-host/echo-host.d.ts +74 -28
  60. package/dist/types/src/db-host/echo-host.d.ts.map +1 -1
  61. package/dist/types/src/db-host/index.d.ts +2 -0
  62. package/dist/types/src/db-host/index.d.ts.map +1 -1
  63. package/dist/types/src/db-host/invalidation-hint.d.ts +19 -0
  64. package/dist/types/src/db-host/invalidation-hint.d.ts.map +1 -0
  65. package/dist/types/src/db-host/local-queue-service.d.ts +19 -0
  66. package/dist/types/src/db-host/local-queue-service.d.ts.map +1 -0
  67. package/dist/types/src/db-host/query-invalidation.test.d.ts +2 -0
  68. package/dist/types/src/db-host/query-invalidation.test.d.ts.map +1 -0
  69. package/dist/types/src/db-host/query-service.d.ts +18 -10
  70. package/dist/types/src/db-host/query-service.d.ts.map +1 -1
  71. package/dist/types/src/db-host/queue-data-source.d.ts +38 -0
  72. package/dist/types/src/db-host/queue-data-source.d.ts.map +1 -0
  73. package/dist/types/src/db-host/queue-service.test.d.ts +2 -0
  74. package/dist/types/src/db-host/queue-service.test.d.ts.map +1 -0
  75. package/dist/types/src/db-host/space-state-manager.d.ts +3 -2
  76. package/dist/types/src/db-host/space-state-manager.d.ts.map +1 -1
  77. package/dist/types/src/db-host/stub.d.ts +11 -0
  78. package/dist/types/src/db-host/stub.d.ts.map +1 -0
  79. package/dist/types/src/edge/echo-edge-replicator.d.ts +7 -6
  80. package/dist/types/src/edge/echo-edge-replicator.d.ts.map +1 -1
  81. package/dist/types/src/edge/echo-edge-subduction-replicator.d.ts +39 -0
  82. package/dist/types/src/edge/echo-edge-subduction-replicator.d.ts.map +1 -0
  83. package/dist/types/src/edge/echo-edge-subduction-replicator.test.d.ts +2 -0
  84. package/dist/types/src/edge/echo-edge-subduction-replicator.test.d.ts.map +1 -0
  85. package/dist/types/src/edge/index.d.ts +1 -0
  86. package/dist/types/src/edge/index.d.ts.map +1 -1
  87. package/dist/types/src/edge/inflight-request-limiter.d.ts.map +1 -1
  88. package/dist/types/src/filter/filter-match.d.ts +1 -1
  89. package/dist/types/src/filter/filter-match.d.ts.map +1 -1
  90. package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
  91. package/dist/types/src/pipeline/message-selector.d.ts.map +1 -1
  92. package/dist/types/src/pipeline/pipeline.d.ts +2 -2
  93. package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
  94. package/dist/types/src/pipeline/timeframe-clock.d.ts.map +1 -1
  95. package/dist/types/src/query/errors.d.ts +16 -20
  96. package/dist/types/src/query/errors.d.ts.map +1 -1
  97. package/dist/types/src/query/plan.d.ts +59 -8
  98. package/dist/types/src/query/plan.d.ts.map +1 -1
  99. package/dist/types/src/query/query-executor.d.ts +55 -12
  100. package/dist/types/src/query/query-executor.d.ts.map +1 -1
  101. package/dist/types/src/query/query-planner.d.ts +10 -1
  102. package/dist/types/src/query/query-planner.d.ts.map +1 -1
  103. package/dist/types/src/space/admission-discovery-extension.d.ts.map +1 -1
  104. package/dist/types/src/space/auth.d.ts +3 -3
  105. package/dist/types/src/space/auth.d.ts.map +1 -1
  106. package/dist/types/src/space/control-pipeline.d.ts +4 -3
  107. package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
  108. package/dist/types/src/space/space-manager.d.ts +7 -7
  109. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  110. package/dist/types/src/space/space-protocol.d.ts +9 -8
  111. package/dist/types/src/space/space-protocol.d.ts.map +1 -1
  112. package/dist/types/src/space/space.d.ts +5 -5
  113. package/dist/types/src/space/space.d.ts.map +1 -1
  114. package/dist/types/src/testing/change-metadata.d.ts.map +1 -1
  115. package/dist/types/src/testing/index.d.ts +0 -2
  116. package/dist/types/src/testing/index.d.ts.map +1 -1
  117. package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
  118. package/dist/types/src/testing/test-feed-builder.d.ts.map +1 -1
  119. package/dist/types/src/testing/test-network-adapter.d.ts +1 -1
  120. package/dist/types/src/testing/test-network-adapter.d.ts.map +1 -1
  121. package/dist/types/src/testing/test-replicator.d.ts +13 -13
  122. package/dist/types/src/testing/test-replicator.d.ts.map +1 -1
  123. package/dist/types/src/util.d.ts.map +1 -1
  124. package/dist/types/tsconfig.tsbuildinfo +1 -1
  125. package/package.json +56 -54
  126. package/src/automerge/automerge-host-subduction.test.ts +263 -0
  127. package/src/automerge/automerge-host.test.ts +145 -32
  128. package/src/automerge/automerge-host.ts +442 -163
  129. package/src/automerge/automerge-repo-subduction.test.ts +1054 -0
  130. package/src/automerge/automerge-repo.test.ts +284 -77
  131. package/src/automerge/automerge-subduction.test.ts +330 -0
  132. package/src/automerge/collection-synchronizer.test.ts +96 -16
  133. package/src/automerge/collection-synchronizer.ts +125 -26
  134. package/src/automerge/echo-network-adapter.test.ts +2 -1
  135. package/src/automerge/echo-network-adapter.ts +44 -32
  136. package/src/automerge/echo-replicator.ts +30 -16
  137. package/src/automerge/errors.ts +10 -0
  138. package/src/automerge/handle-state.ts +62 -0
  139. package/src/automerge/heads-store.ts +42 -3
  140. package/src/automerge/index.ts +2 -0
  141. package/src/automerge/leveldb-storage-adapter.ts +70 -4
  142. package/src/automerge/mesh-echo-replicator-connection.ts +8 -8
  143. package/src/automerge/mesh-echo-replicator.ts +14 -11
  144. package/src/db-host/automerge-data-source.test.ts +299 -0
  145. package/src/db-host/automerge-data-source.ts +187 -0
  146. package/src/db-host/data-service.ts +27 -10
  147. package/src/db-host/database-root.ts +19 -7
  148. package/src/db-host/documents-synchronizer.test.ts +145 -14
  149. package/src/db-host/documents-synchronizer.ts +158 -59
  150. package/src/db-host/echo-host.ts +376 -90
  151. package/src/db-host/index.ts +2 -0
  152. package/src/db-host/invalidation-hint.ts +50 -0
  153. package/src/db-host/local-queue-service.ts +127 -0
  154. package/src/db-host/query-invalidation.test.ts +270 -0
  155. package/src/db-host/query-service.ts +108 -111
  156. package/src/db-host/queue-data-source.ts +160 -0
  157. package/src/db-host/queue-service.test.ts +145 -0
  158. package/src/db-host/space-state-manager.ts +11 -9
  159. package/src/db-host/stub.ts +33 -0
  160. package/src/edge/echo-edge-replicator.test.ts +9 -9
  161. package/src/edge/echo-edge-replicator.ts +50 -42
  162. package/src/edge/echo-edge-subduction-replicator.test.ts +158 -0
  163. package/src/edge/echo-edge-subduction-replicator.ts +377 -0
  164. package/src/edge/index.ts +1 -0
  165. package/src/filter/filter-match.test.ts +41 -25
  166. package/src/filter/filter-match.ts +75 -20
  167. package/src/metadata/metadata-store.ts +8 -5
  168. package/src/pipeline/pipeline-stress.test.ts +1 -3
  169. package/src/pipeline/pipeline.test.ts +0 -1
  170. package/src/pipeline/pipeline.ts +2 -3
  171. package/src/query/errors.ts +2 -2
  172. package/src/query/plan.ts +73 -9
  173. package/src/query/query-executor.ts +1064 -172
  174. package/src/query/query-planner.test.ts +854 -86
  175. package/src/query/query-planner.ts +444 -38
  176. package/src/space/admission-discovery-extension.ts +1 -1
  177. package/src/space/auth.ts +6 -6
  178. package/src/space/control-pipeline.test.ts +2 -2
  179. package/src/space/control-pipeline.ts +7 -7
  180. package/src/space/space-manager.ts +12 -17
  181. package/src/space/space-protocol.browser.test.ts +13 -12
  182. package/src/space/space-protocol.test.ts +13 -13
  183. package/src/space/space-protocol.ts +16 -15
  184. package/src/space/space.test.ts +2 -2
  185. package/src/space/space.ts +9 -10
  186. package/src/testing/index.ts +0 -2
  187. package/src/testing/test-agent-builder.ts +0 -1
  188. package/src/testing/test-network-adapter.ts +24 -3
  189. package/src/testing/test-replicator.ts +15 -20
  190. package/src/util.ts +7 -3
  191. package/dist/lib/browser/chunk-CGS2ULMK.mjs +0 -11
  192. package/dist/lib/browser/chunk-CGS2ULMK.mjs.map +0 -7
  193. package/dist/lib/browser/chunk-FR6GJ4S4.mjs.map +0 -7
  194. package/dist/lib/browser/chunk-WJJXJTNS.mjs.map +0 -7
  195. package/dist/lib/browser/index.mjs +0 -5492
  196. package/dist/lib/browser/index.mjs.map +0 -7
  197. package/dist/lib/browser/meta.json +0 -1
  198. package/dist/lib/browser/testing/index.mjs.map +0 -7
  199. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
  200. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +0 -7
  201. package/dist/lib/node-esm/chunk-JQCCVDLT.mjs +0 -2144
  202. package/dist/lib/node-esm/chunk-JQCCVDLT.mjs.map +0 -7
  203. package/dist/lib/node-esm/chunk-LEQ77KAT.mjs +0 -240
  204. package/dist/lib/node-esm/chunk-LEQ77KAT.mjs.map +0 -7
  205. package/dist/lib/node-esm/filter/index.mjs +0 -13
  206. package/dist/lib/node-esm/filter/index.mjs.map +0 -7
  207. package/dist/lib/node-esm/index.mjs +0 -5492
  208. package/dist/lib/node-esm/index.mjs.map +0 -7
  209. package/dist/lib/node-esm/meta.json +0 -1
  210. package/dist/lib/node-esm/testing/index.mjs +0 -764
  211. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  212. package/dist/types/src/db-host/documents-iterator.d.ts +0 -7
  213. package/dist/types/src/db-host/documents-iterator.d.ts.map +0 -1
  214. package/dist/types/src/testing/test-data.d.ts +0 -18
  215. package/dist/types/src/testing/test-data.d.ts.map +0 -1
  216. package/dist/types/src/testing/test-schema.d.ts +0 -37
  217. package/dist/types/src/testing/test-schema.d.ts.map +0 -1
  218. package/src/db-host/documents-iterator.ts +0 -74
  219. package/src/testing/test-data.ts +0 -127
  220. package/src/testing/test-schema.ts +0 -53
  221. /package/dist/lib/{browser → neutral}/filter/index.mjs.map +0 -0
@@ -1,2144 +0,0 @@
1
- import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
-
3
- // src/common/codec.ts
4
- import { createCodecEncoding } from "@dxos/hypercore";
5
- import { schema } from "@dxos/protocols/proto";
6
- var codec = schema.getCodecForType("dxos.echo.feed.FeedMessage");
7
- var valueEncoding = createCodecEncoding(codec);
8
-
9
- // src/common/feeds.ts
10
- import { invariant } from "@dxos/invariant";
11
- var __dxlog_file = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/common/feeds.ts";
12
- var createMappedFeedWriter = (mapper, writer) => {
13
- invariant(mapper, void 0, {
14
- F: __dxlog_file,
15
- L: 16,
16
- S: void 0,
17
- A: [
18
- "mapper",
19
- ""
20
- ]
21
- });
22
- invariant(writer, void 0, {
23
- F: __dxlog_file,
24
- L: 17,
25
- S: void 0,
26
- A: [
27
- "writer",
28
- ""
29
- ]
30
- });
31
- return {
32
- write: async (data, options) => await writer.write(await mapper(data), options)
33
- };
34
- };
35
-
36
- // src/common/space-id.ts
37
- import { subtleCrypto } from "@dxos/crypto";
38
- import { PublicKey, SpaceId } from "@dxos/keys";
39
- import { ComplexMap } from "@dxos/util";
40
- var SPACE_IDS_CACHE = new ComplexMap(PublicKey.hash);
41
- var createIdFromSpaceKey = async (spaceKey) => {
42
- const cachedValue = SPACE_IDS_CACHE.get(spaceKey);
43
- if (cachedValue !== void 0) {
44
- return cachedValue;
45
- }
46
- const digest = await subtleCrypto.digest("SHA-256", spaceKey.asUint8Array());
47
- const bytes = new Uint8Array(digest).slice(0, SpaceId.byteLength);
48
- const spaceId = SpaceId.encode(bytes);
49
- SPACE_IDS_CACHE.set(spaceKey, spaceId);
50
- return spaceId;
51
- };
52
-
53
- // src/metadata/metadata-store.ts
54
- import CRC32 from "crc-32";
55
- import { Event, scheduleTaskInterval, synchronized } from "@dxos/async";
56
- import { Context } from "@dxos/context";
57
- import { invariant as invariant2 } from "@dxos/invariant";
58
- import { PublicKey as PublicKey2 } from "@dxos/keys";
59
- import { log } from "@dxos/log";
60
- import { DataCorruptionError, STORAGE_VERSION } from "@dxos/protocols";
61
- import { schema as schema2 } from "@dxos/protocols/proto";
62
- import { Invitation, SpaceState } from "@dxos/protocols/proto/dxos/client/services";
63
- import { ComplexMap as ComplexMap2, arrayToBuffer, forEachAsync, isNonNullable } from "@dxos/util";
64
- function _ts_decorate(decorators, target, key, desc) {
65
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
66
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
67
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
68
- return c > 3 && r && Object.defineProperty(target, key, r), r;
69
- }
70
- var __dxlog_file2 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/metadata/metadata-store.ts";
71
- var EXPIRED_INVITATION_CLEANUP_INTERVAL = 60 * 60 * 1e3;
72
- var emptyEchoMetadata = () => ({
73
- version: STORAGE_VERSION,
74
- spaces: [],
75
- created: /* @__PURE__ */ new Date(),
76
- updated: /* @__PURE__ */ new Date()
77
- });
78
- var emptyLargeSpaceMetadata = () => ({});
79
- var EchoMetadata = schema2.getCodecForType("dxos.echo.metadata.EchoMetadata");
80
- var LargeSpaceMetadata = schema2.getCodecForType("dxos.echo.metadata.LargeSpaceMetadata");
81
- var MetadataStore = class {
82
- _metadata = emptyEchoMetadata();
83
- _spaceLargeMetadata = new ComplexMap2(PublicKey2.hash);
84
- _metadataFile = void 0;
85
- update = new Event();
86
- _invitationCleanupCtx = new Context(void 0, {
87
- F: __dxlog_file2,
88
- L: 55
89
- });
90
- /**
91
- * @internal
92
- */
93
- _directory;
94
- constructor(directory) {
95
- this._directory = directory;
96
- }
97
- get metadata() {
98
- return this._metadata;
99
- }
100
- get version() {
101
- return this._metadata.version ?? 0;
102
- }
103
- /**
104
- * Returns a list of currently saved spaces. The list and objects in it can be modified addSpace and
105
- * addSpaceFeed functions.
106
- */
107
- get spaces() {
108
- return this._metadata.spaces ?? [];
109
- }
110
- async _readFile(file, codec2) {
111
- try {
112
- const { size: fileLength } = await file.stat();
113
- if (fileLength < 8) {
114
- return;
115
- }
116
- const dataSize = fromBytesInt32(await file.read(0, 4));
117
- const checksum = fromBytesInt32(await file.read(4, 4));
118
- log("loaded", {
119
- size: dataSize,
120
- checksum,
121
- name: file.filename
122
- }, {
123
- F: __dxlog_file2,
124
- L: 91,
125
- S: this,
126
- C: (f, a) => f(...a)
127
- });
128
- if (fileLength < dataSize + 8) {
129
- throw new DataCorruptionError("Metadata size is smaller than expected.", {
130
- fileLength,
131
- dataSize
132
- });
133
- }
134
- const data = await file.read(8, dataSize);
135
- const calculatedChecksum = CRC32.buf(data);
136
- if (calculatedChecksum !== checksum) {
137
- throw new DataCorruptionError("Metadata checksum is invalid.");
138
- }
139
- return codec2.decode(data);
140
- } finally {
141
- await file.close();
142
- }
143
- }
144
- /**
145
- * @internal
146
- */
147
- async _writeFile(file, codec2, data) {
148
- const encoded = arrayToBuffer(codec2.encode(data));
149
- const checksum = CRC32.buf(encoded);
150
- const result = Buffer.alloc(8 + encoded.length);
151
- result.writeInt32LE(encoded.length, 0);
152
- result.writeInt32LE(checksum, 4);
153
- encoded.copy(result, 8);
154
- await file.write(0, result);
155
- log("saved", {
156
- size: encoded.length,
157
- checksum
158
- }, {
159
- F: __dxlog_file2,
160
- L: 126,
161
- S: this,
162
- C: (f, a) => f(...a)
163
- });
164
- }
165
- async close() {
166
- await this._invitationCleanupCtx.dispose();
167
- await this.flush();
168
- await this._metadataFile?.close();
169
- this._metadataFile = void 0;
170
- this._metadata = emptyEchoMetadata();
171
- this._spaceLargeMetadata.clear();
172
- }
173
- /**
174
- * Loads metadata from persistent storage.
175
- */
176
- async load() {
177
- if (!this._metadataFile || this._metadataFile.closed) {
178
- this._metadataFile = this._directory.getOrCreateFile("EchoMetadata");
179
- }
180
- try {
181
- const metadata = await this._readFile(this._metadataFile, EchoMetadata);
182
- if (metadata) {
183
- this._metadata = metadata;
184
- }
185
- this._metadata.spaces?.forEach((space) => {
186
- space.state ??= SpaceState.SPACE_ACTIVE;
187
- });
188
- } catch (err) {
189
- log.error("failed to load metadata", {
190
- err
191
- }, {
192
- F: __dxlog_file2,
193
- L: 158,
194
- S: this,
195
- C: (f, a) => f(...a)
196
- });
197
- this._metadata = emptyEchoMetadata();
198
- }
199
- await forEachAsync([
200
- this._metadata.identity?.haloSpace.key,
201
- ...this._metadata.spaces?.map((space) => space.key) ?? []
202
- ].filter(isNonNullable), async (key) => {
203
- try {
204
- await this._loadSpaceLargeMetadata(key);
205
- } catch (err) {
206
- log.error("failed to load space large metadata", {
207
- err
208
- }, {
209
- F: __dxlog_file2,
210
- L: 170,
211
- S: this,
212
- C: (f, a) => f(...a)
213
- });
214
- }
215
- });
216
- scheduleTaskInterval(this._invitationCleanupCtx, async () => {
217
- for (const invitation of this._metadata.invitations ?? []) {
218
- if (hasInvitationExpired(invitation) || isLegacyInvitationFormat(invitation)) {
219
- await this.removeInvitation(invitation.invitationId);
220
- }
221
- }
222
- }, EXPIRED_INVITATION_CLEANUP_INTERVAL);
223
- }
224
- async _save() {
225
- const data = {
226
- ...this._metadata,
227
- version: STORAGE_VERSION,
228
- created: this._metadata.created ?? /* @__PURE__ */ new Date(),
229
- updated: /* @__PURE__ */ new Date()
230
- };
231
- this.update.emit(data);
232
- const file = this._directory.getOrCreateFile("EchoMetadata");
233
- await this._writeFile(file, EchoMetadata, data);
234
- }
235
- async _loadSpaceLargeMetadata(key) {
236
- const file = this._directory.getOrCreateFile(`space_${key.toHex()}_large`);
237
- try {
238
- const metadata = await this._readFile(file, LargeSpaceMetadata);
239
- if (metadata) {
240
- this._spaceLargeMetadata.set(key, metadata);
241
- }
242
- } catch (err) {
243
- log.error("failed to load space large metadata", {
244
- err
245
- }, {
246
- F: __dxlog_file2,
247
- L: 212,
248
- S: this,
249
- C: (f, a) => f(...a)
250
- });
251
- }
252
- }
253
- async _saveSpaceLargeMetadata(key) {
254
- const data = this._getLargeSpaceMetadata(key);
255
- const file = this._directory.getOrCreateFile(`space_${key.toHex()}_large`);
256
- await this._writeFile(file, LargeSpaceMetadata, data);
257
- }
258
- async flush() {
259
- await this._directory.flush();
260
- }
261
- _getSpace(spaceKey) {
262
- if (this._metadata.identity?.haloSpace.key.equals(spaceKey)) {
263
- return this._metadata.identity.haloSpace;
264
- }
265
- const space = this.spaces.find((space2) => space2.key.equals(spaceKey));
266
- invariant2(space, "Space not found", {
267
- F: __dxlog_file2,
268
- L: 234,
269
- S: this,
270
- A: [
271
- "space",
272
- "'Space not found'"
273
- ]
274
- });
275
- return space;
276
- }
277
- hasSpace(spaceKey) {
278
- if (this._metadata.identity?.haloSpace.key.equals(spaceKey)) {
279
- return true;
280
- }
281
- return !!this.spaces.find((space) => space.key.equals(spaceKey));
282
- }
283
- _getLargeSpaceMetadata(key) {
284
- let entry = this._spaceLargeMetadata.get(key);
285
- if (entry) {
286
- return entry;
287
- }
288
- entry = emptyLargeSpaceMetadata();
289
- this._spaceLargeMetadata.set(key, entry);
290
- return entry;
291
- }
292
- /**
293
- * Clears storage - doesn't work for now.
294
- */
295
- async clear() {
296
- log("clearing all metadata", void 0, {
297
- F: __dxlog_file2,
298
- L: 262,
299
- S: this,
300
- C: (f, a) => f(...a)
301
- });
302
- await this._directory.delete();
303
- this._metadata = emptyEchoMetadata();
304
- }
305
- getIdentityRecord() {
306
- return this._metadata.identity;
307
- }
308
- async setIdentityRecord(record) {
309
- invariant2(!this._metadata.identity, "Cannot overwrite existing identity in metadata", {
310
- F: __dxlog_file2,
311
- L: 272,
312
- S: this,
313
- A: [
314
- "!this._metadata.identity",
315
- "'Cannot overwrite existing identity in metadata'"
316
- ]
317
- });
318
- this._metadata.identity = record;
319
- await this._save();
320
- await this.flush();
321
- }
322
- getInvitations() {
323
- return this._metadata.invitations ?? [];
324
- }
325
- async addInvitation(invitation) {
326
- if (this._metadata.invitations?.find((i) => i.invitationId === invitation.invitationId)) {
327
- return;
328
- }
329
- (this._metadata.invitations ??= []).push(invitation);
330
- await this._save();
331
- await this.flush();
332
- }
333
- async removeInvitation(invitationId) {
334
- this._metadata.invitations = (this._metadata.invitations ?? []).filter((i) => i.invitationId !== invitationId);
335
- await this._save();
336
- await this.flush();
337
- }
338
- async addSpace(record) {
339
- invariant2(!(this._metadata.spaces ?? []).find((space) => space.key.equals(record.key)), "Cannot overwrite existing space in metadata", {
340
- F: __dxlog_file2,
341
- L: 300,
342
- S: this,
343
- A: [
344
- "!(this._metadata.spaces ?? []).find((space) => space.key.equals(record.key))",
345
- "'Cannot overwrite existing space in metadata'"
346
- ]
347
- });
348
- (this._metadata.spaces ??= []).push(record);
349
- await this._save();
350
- await this.flush();
351
- }
352
- async setSpaceDataLatestTimeframe(spaceKey, timeframe) {
353
- this._getSpace(spaceKey).dataTimeframe = timeframe;
354
- await this._save();
355
- }
356
- async setSpaceControlLatestTimeframe(spaceKey, timeframe) {
357
- this._getSpace(spaceKey).controlTimeframe = timeframe;
358
- await this._save();
359
- await this.flush();
360
- }
361
- async setCache(spaceKey, cache) {
362
- this._getSpace(spaceKey).cache = cache;
363
- await this._save();
364
- }
365
- async setWritableFeedKeys(spaceKey, controlFeedKey, dataFeedKey) {
366
- const space = this._getSpace(spaceKey);
367
- space.controlFeedKey = controlFeedKey;
368
- space.dataFeedKey = dataFeedKey;
369
- await this._save();
370
- await this.flush();
371
- }
372
- async setSpaceState(spaceKey, state) {
373
- this._getSpace(spaceKey).state = state;
374
- await this._save();
375
- await this.flush();
376
- }
377
- getSpaceControlPipelineSnapshot(spaceKey) {
378
- return this._getLargeSpaceMetadata(spaceKey).controlPipelineSnapshot;
379
- }
380
- async setSpaceControlPipelineSnapshot(spaceKey, snapshot) {
381
- this._getLargeSpaceMetadata(spaceKey).controlPipelineSnapshot = snapshot;
382
- await this._saveSpaceLargeMetadata(spaceKey);
383
- await this.flush();
384
- }
385
- getSpaceEdgeReplicationSetting(spaceKey) {
386
- return this.hasSpace(spaceKey) ? this._getSpace(spaceKey).edgeReplication : void 0;
387
- }
388
- async setSpaceEdgeReplicationSetting(spaceKey, setting) {
389
- this._getSpace(spaceKey).edgeReplication = setting;
390
- await this._save();
391
- await this.flush();
392
- }
393
- };
394
- _ts_decorate([
395
- synchronized
396
- ], MetadataStore.prototype, "load", null);
397
- _ts_decorate([
398
- synchronized
399
- ], MetadataStore.prototype, "_save", null);
400
- _ts_decorate([
401
- synchronized
402
- ], MetadataStore.prototype, "_saveSpaceLargeMetadata", null);
403
- var fromBytesInt32 = (buf) => buf.readInt32LE(0);
404
- var hasInvitationExpired = (invitation) => {
405
- return Boolean(invitation.created && invitation.lifetime && invitation.lifetime !== 0 && invitation.created.getTime() + invitation.lifetime * 1e3 < Date.now());
406
- };
407
- var isLegacyInvitationFormat = (invitation) => {
408
- return invitation.type === Invitation.Type.MULTIUSE;
409
- };
410
-
411
- // src/pipeline/timeframe-clock.ts
412
- import { Event as Event2 } from "@dxos/async";
413
- import { timed } from "@dxos/debug";
414
- import { log as log2 } from "@dxos/log";
415
- import { Timeframe } from "@dxos/timeframe";
416
- function _ts_decorate2(decorators, target, key, desc) {
417
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
418
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
419
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
420
- return c > 3 && r && Object.defineProperty(target, key, r), r;
421
- }
422
- var __dxlog_file3 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/pipeline/timeframe-clock.ts";
423
- var mapTimeframeToFeedIndexes = (timeframe) => timeframe.frames().map(([feedKey, index]) => ({
424
- feedKey,
425
- index
426
- }));
427
- var mapFeedIndexesToTimeframe = (indexes) => new Timeframe(indexes.map(({ feedKey, index }) => [
428
- feedKey,
429
- index
430
- ]));
431
- var startAfter = (timeframe) => timeframe.frames().map(([feedKey, index]) => ({
432
- feedKey,
433
- index: index + 1
434
- }));
435
- var TimeframeClock = class {
436
- _timeframe;
437
- update = new Event2();
438
- _pendingTimeframe;
439
- constructor(_timeframe = new Timeframe()) {
440
- this._timeframe = _timeframe;
441
- this._pendingTimeframe = _timeframe;
442
- }
443
- /**
444
- * Timeframe that was processed by ECHO.
445
- */
446
- get timeframe() {
447
- return this._timeframe;
448
- }
449
- /**
450
- * Timeframe that is currently being processed by ECHO.
451
- * Will be equal to `timeframe` after the processing is complete.
452
- */
453
- get pendingTimeframe() {
454
- return this._pendingTimeframe;
455
- }
456
- setTimeframe(timeframe) {
457
- this._timeframe = timeframe;
458
- this._pendingTimeframe = timeframe;
459
- this.update.emit(this._timeframe);
460
- }
461
- updatePendingTimeframe(key, seq) {
462
- this._pendingTimeframe = Timeframe.merge(this._pendingTimeframe, new Timeframe([
463
- [
464
- key,
465
- seq
466
- ]
467
- ]));
468
- }
469
- updateTimeframe() {
470
- this._timeframe = this._pendingTimeframe;
471
- this.update.emit(this._timeframe);
472
- }
473
- hasGaps(timeframe) {
474
- const gaps = Timeframe.dependencies(timeframe, this._timeframe);
475
- return !gaps.isEmpty();
476
- }
477
- async waitUntilReached(target) {
478
- log2("waitUntilReached", {
479
- target,
480
- current: this._timeframe
481
- }, {
482
- F: __dxlog_file3,
483
- L: 70,
484
- S: this,
485
- C: (f, a) => f(...a)
486
- });
487
- await this.update.waitForCondition(() => {
488
- log2("check if reached", {
489
- target,
490
- current: this._timeframe,
491
- deps: Timeframe.dependencies(target, this._timeframe)
492
- }, {
493
- F: __dxlog_file3,
494
- L: 72,
495
- S: this,
496
- C: (f, a) => f(...a)
497
- });
498
- return Timeframe.dependencies(target, this._timeframe).isEmpty();
499
- });
500
- }
501
- };
502
- _ts_decorate2([
503
- timed(5e3)
504
- ], TimeframeClock.prototype, "waitUntilReached", null);
505
-
506
- // src/pipeline/pipeline.ts
507
- import { Event as Event3, Trigger, sleepWithContext, synchronized as synchronized2 } from "@dxos/async";
508
- import { Context as Context2, rejectOnDispose } from "@dxos/context";
509
- import { failUndefined } from "@dxos/debug";
510
- import { FeedSetIterator } from "@dxos/feed-store";
511
- import { invariant as invariant4 } from "@dxos/invariant";
512
- import { PublicKey as PublicKey3 } from "@dxos/keys";
513
- import { log as log4 } from "@dxos/log";
514
- import { Timeframe as Timeframe2 } from "@dxos/timeframe";
515
- import { ComplexMap as ComplexMap3 } from "@dxos/util";
516
-
517
- // src/pipeline/message-selector.ts
518
- import { invariant as invariant3 } from "@dxos/invariant";
519
- import { log as log3 } from "@dxos/log";
520
- var __dxlog_file4 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/pipeline/message-selector.ts";
521
- var createMessageSelector = (timeframeClock) => {
522
- return (messages) => {
523
- for (let i = 0; i < messages.length; i++) {
524
- const { data: { timeframe } } = messages[i];
525
- invariant3(timeframe, void 0, {
526
- F: __dxlog_file4,
527
- L: 25,
528
- S: void 0,
529
- A: [
530
- "timeframe",
531
- ""
532
- ]
533
- });
534
- if (!timeframeClock.hasGaps(timeframe)) {
535
- return i;
536
- }
537
- }
538
- log3("Skipping...", void 0, {
539
- F: __dxlog_file4,
540
- L: 33,
541
- S: void 0,
542
- C: (f, a) => f(...a)
543
- });
544
- };
545
- };
546
-
547
- // src/pipeline/pipeline.ts
548
- function _ts_decorate3(decorators, target, key, desc) {
549
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
550
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
551
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
552
- return c > 3 && r && Object.defineProperty(target, key, r), r;
553
- }
554
- var __dxlog_file5 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/pipeline/pipeline.ts";
555
- var PipelineState = class {
556
- _feeds;
557
- _timeframeClock;
558
- /**
559
- * @internal
560
- */
561
- _ctx = new Context2(void 0, {
562
- F: __dxlog_file5,
563
- L: 42
564
- });
565
- // TODO(dmaretskyi): Remove?. Avoid accessing `_timeframeClock` before constructor initialization.
566
- get timeframeUpdate() {
567
- return this._timeframeClock.update;
568
- }
569
- stalled = new Event3();
570
- /**
571
- * @internal
572
- */
573
- _startTimeframe = new Timeframe2();
574
- /**
575
- * Target timeframe we are waiting to reach.
576
- */
577
- _targetTimeframe;
578
- /**
579
- * @internal
580
- */
581
- _reachedTargetPromise;
582
- /**
583
- * @internal
584
- */
585
- _reachedTarget = false;
586
- constructor(_feeds, _timeframeClock) {
587
- this._feeds = _feeds;
588
- this._timeframeClock = _timeframeClock;
589
- }
590
- /**
591
- * Latest theoretical timeframe based on the last mutation in each feed.
592
- * NOTE: This might never be reached if the mutation dependencies
593
- */
594
- // TODO(dmaretskyi): Rename `totalTimeframe`? or `lastTimeframe`.
595
- get endTimeframe() {
596
- return mapFeedIndexesToTimeframe(Array.from(this._feeds.values()).filter((feed) => feed.length > 0).map((feed) => ({
597
- feedKey: feed.key,
598
- index: feed.length - 1
599
- })));
600
- }
601
- get startTimeframe() {
602
- return this._startTimeframe;
603
- }
604
- get timeframe() {
605
- return this._timeframeClock.timeframe;
606
- }
607
- get pendingTimeframe() {
608
- return this._timeframeClock.pendingTimeframe;
609
- }
610
- get targetTimeframe() {
611
- return this._targetTimeframe ? this._targetTimeframe : new Timeframe2();
612
- }
613
- get reachedTarget() {
614
- return this._reachedTarget;
615
- }
616
- get feeds() {
617
- return Array.from(this._feeds.values());
618
- }
619
- async waitUntilTimeframe(target) {
620
- await this._timeframeClock.waitUntilReached(target);
621
- }
622
- setTargetTimeframe(target) {
623
- this._targetTimeframe = target;
624
- }
625
- /**
626
- * Wait until the pipeline processes all messages in the feed and reaches the target timeframe if that is set.
627
- *
628
- * This function will resolve immediately if the pipeline is stalled.
629
- *
630
- * @param timeout Timeout in milliseconds to specify the maximum wait time.
631
- */
632
- async waitUntilReachedTargetTimeframe({ ctx = new Context2(void 0, {
633
- F: __dxlog_file5,
634
- L: 132
635
- }), timeout, breakOnStall = true } = {}) {
636
- log4("waitUntilReachedTargetTimeframe", {
637
- timeout,
638
- current: this.timeframe,
639
- target: this.targetTimeframe
640
- }, {
641
- F: __dxlog_file5,
642
- L: 136,
643
- S: this,
644
- C: (f, a) => f(...a)
645
- });
646
- this._reachedTargetPromise ??= Promise.race([
647
- this._timeframeClock.update.waitForCondition(() => {
648
- return Timeframe2.dependencies(this.targetTimeframe, this.timeframe).isEmpty();
649
- }),
650
- ...breakOnStall ? [
651
- this.stalled.discardParameter().waitForCount(1)
652
- ] : []
653
- ]);
654
- let done = false;
655
- if (timeout) {
656
- return Promise.race([
657
- rejectOnDispose(ctx),
658
- rejectOnDispose(this._ctx),
659
- this._reachedTargetPromise.then(() => {
660
- done = true;
661
- this._reachedTarget = true;
662
- }),
663
- sleepWithContext(this._ctx, timeout).then(() => {
664
- if (done) {
665
- return;
666
- }
667
- log4.warn("waitUntilReachedTargetTimeframe timed out", {
668
- timeout,
669
- current: this.timeframe,
670
- target: this.targetTimeframe,
671
- dependencies: Timeframe2.dependencies(this.targetTimeframe, this.timeframe)
672
- }, {
673
- F: __dxlog_file5,
674
- L: 164,
675
- S: this,
676
- C: (f, a) => f(...a)
677
- });
678
- })
679
- ]);
680
- } else {
681
- return this._reachedTargetPromise;
682
- }
683
- }
684
- };
685
- var Pipeline = class {
686
- _timeframeClock = new TimeframeClock(new Timeframe2());
687
- _feeds = new ComplexMap3(PublicKey3.hash);
688
- // External state accessor.
689
- _state = new PipelineState(this._feeds, this._timeframeClock);
690
- // Waits for the message consumer to process the message and yield control back to the pipeline.
691
- _processingTrigger = new Trigger().wake();
692
- _pauseTrigger = new Trigger().wake();
693
- // Pending downloads.
694
- _downloads = new ComplexMap3((value) => PublicKey3.hash(value.key));
695
- // Inbound feed stream.
696
- _feedSetIterator;
697
- // Outbound feed writer.
698
- _writer;
699
- _isStopping = false;
700
- _isStarted = false;
701
- _isBeingConsumed = false;
702
- _isPaused = false;
703
- get state() {
704
- return this._state;
705
- }
706
- get writer() {
707
- invariant4(this._writer, "Writer not set.", {
708
- F: __dxlog_file5,
709
- L: 246,
710
- S: this,
711
- A: [
712
- "this._writer",
713
- "'Writer not set.'"
714
- ]
715
- });
716
- return this._writer;
717
- }
718
- hasFeed(feedKey) {
719
- return this._feeds.has(feedKey);
720
- }
721
- getFeeds() {
722
- return this._feedSetIterator.feeds;
723
- }
724
- // NOTE: This cannot be synchronized with `stop` because stop waits for the mutation processing to complete,
725
- // which might be opening feeds during the mutation processing, which w
726
- async addFeed(feed) {
727
- this._feeds.set(feed.key, feed);
728
- if (this._feedSetIterator) {
729
- await this._feedSetIterator.addFeed(feed);
730
- }
731
- if (this._isStarted && !this._isPaused) {
732
- this._setFeedDownloadState(feed);
733
- }
734
- }
735
- setWriteFeed(feed) {
736
- invariant4(!this._writer, "Writer already set.", {
737
- F: __dxlog_file5,
738
- L: 273,
739
- S: this,
740
- A: [
741
- "!this._writer",
742
- "'Writer already set.'"
743
- ]
744
- });
745
- invariant4(feed.properties.writable, "Feed must be writable.", {
746
- F: __dxlog_file5,
747
- L: 274,
748
- S: this,
749
- A: [
750
- "feed.properties.writable",
751
- "'Feed must be writable.'"
752
- ]
753
- });
754
- this._writer = createMappedFeedWriter((payload) => ({
755
- timeframe: this._timeframeClock.timeframe,
756
- payload
757
- }), feed.createFeedWriter());
758
- }
759
- async start() {
760
- invariant4(!this._isStarted, "Pipeline is already started.", {
761
- F: __dxlog_file5,
762
- L: 287,
763
- S: this,
764
- A: [
765
- "!this._isStarted",
766
- "'Pipeline is already started.'"
767
- ]
768
- });
769
- log4("starting...", void 0, {
770
- F: __dxlog_file5,
771
- L: 288,
772
- S: this,
773
- C: (f, a) => f(...a)
774
- });
775
- await this._initIterator();
776
- await this._feedSetIterator.open();
777
- this._isStarted = true;
778
- log4("started", void 0, {
779
- F: __dxlog_file5,
780
- L: 292,
781
- S: this,
782
- C: (f, a) => f(...a)
783
- });
784
- if (!this._isPaused) {
785
- for (const feed of this._feeds.values()) {
786
- this._setFeedDownloadState(feed);
787
- }
788
- }
789
- }
790
- async stop() {
791
- log4("stopping...", void 0, {
792
- F: __dxlog_file5,
793
- L: 303,
794
- S: this,
795
- C: (f, a) => f(...a)
796
- });
797
- this._isStopping = true;
798
- for (const [feed, handle] of this._downloads.entries()) {
799
- feed.undownload(handle);
800
- }
801
- this._downloads.clear();
802
- await this._feedSetIterator?.close();
803
- await this._processingTrigger.wait();
804
- await this._state._ctx.dispose();
805
- this._state._ctx = new Context2(void 0, {
806
- F: __dxlog_file5,
807
- L: 312
808
- });
809
- this._state._reachedTargetPromise = void 0;
810
- this._state._reachedTarget = false;
811
- this._isStarted = false;
812
- log4("stopped", void 0, {
813
- F: __dxlog_file5,
814
- L: 316,
815
- S: this,
816
- C: (f, a) => f(...a)
817
- });
818
- }
819
- /**
820
- * @param timeframe Timeframe of already processed messages.
821
- * The pipeline will start processing messages AFTER this timeframe.
822
- */
823
- async setCursor(timeframe) {
824
- invariant4(!this._isStarted || this._isPaused, "Invalid state.", {
825
- F: __dxlog_file5,
826
- L: 325,
827
- S: this,
828
- A: [
829
- "!this._isStarted || this._isPaused",
830
- "'Invalid state.'"
831
- ]
832
- });
833
- this._state._startTimeframe = timeframe;
834
- this._timeframeClock.setTimeframe(timeframe);
835
- if (this._feedSetIterator) {
836
- await this._feedSetIterator.close();
837
- await this._initIterator();
838
- await this._feedSetIterator.open();
839
- }
840
- }
841
- /**
842
- * Calling pause while processing will cause a deadlock.
843
- */
844
- async pause() {
845
- if (this._isPaused) {
846
- return;
847
- }
848
- this._pauseTrigger.reset();
849
- await this._processingTrigger.wait();
850
- this._isPaused = true;
851
- }
852
- async unpause() {
853
- invariant4(this._isPaused, "Pipeline is not paused.", {
854
- F: __dxlog_file5,
855
- L: 354,
856
- S: this,
857
- A: [
858
- "this._isPaused",
859
- "'Pipeline is not paused.'"
860
- ]
861
- });
862
- this._pauseTrigger.wake();
863
- this._isPaused = false;
864
- for (const feed of this._feeds.values()) {
865
- this._setFeedDownloadState(feed);
866
- }
867
- }
868
- /**
869
- * Starts to iterate over the ordered messages from the added feeds.
870
- * Updates the timeframe clock after the message has bee processed.
871
- */
872
- async *consume() {
873
- invariant4(!this._isBeingConsumed, "Pipeline is already being consumed.", {
874
- F: __dxlog_file5,
875
- L: 369,
876
- S: this,
877
- A: [
878
- "!this._isBeingConsumed",
879
- "'Pipeline is already being consumed.'"
880
- ]
881
- });
882
- this._isBeingConsumed = true;
883
- invariant4(this._feedSetIterator, "Iterator not initialized.", {
884
- F: __dxlog_file5,
885
- L: 372,
886
- S: this,
887
- A: [
888
- "this._feedSetIterator",
889
- "'Iterator not initialized.'"
890
- ]
891
- });
892
- let lastFeedSetIterator = this._feedSetIterator;
893
- let iterable = lastFeedSetIterator[Symbol.asyncIterator]();
894
- while (!this._isStopping) {
895
- await this._pauseTrigger.wait();
896
- if (lastFeedSetIterator !== this._feedSetIterator) {
897
- invariant4(this._feedSetIterator, "Iterator not initialized.", {
898
- F: __dxlog_file5,
899
- L: 381,
900
- S: this,
901
- A: [
902
- "this._feedSetIterator",
903
- "'Iterator not initialized.'"
904
- ]
905
- });
906
- lastFeedSetIterator = this._feedSetIterator;
907
- iterable = lastFeedSetIterator[Symbol.asyncIterator]();
908
- }
909
- const { done, value } = await iterable.next();
910
- if (!done) {
911
- const block = value ?? failUndefined();
912
- this._processingTrigger.reset();
913
- this._timeframeClock.updatePendingTimeframe(PublicKey3.from(block.feedKey), block.seq);
914
- yield block;
915
- this._processingTrigger.wake();
916
- this._timeframeClock.updateTimeframe();
917
- }
918
- }
919
- this._isBeingConsumed = false;
920
- }
921
- _setFeedDownloadState(feed) {
922
- let handle = this._downloads.get(feed);
923
- if (handle) {
924
- feed.undownload(handle);
925
- }
926
- const timeframe = this._state._startTimeframe;
927
- const seq = timeframe.get(feed.key) ?? -1;
928
- log4("download", {
929
- feed: feed.key.truncate(),
930
- seq,
931
- length: feed.length
932
- }, {
933
- F: __dxlog_file5,
934
- L: 410,
935
- S: this,
936
- C: (f, a) => f(...a)
937
- });
938
- handle = feed.download({
939
- start: seq + 1,
940
- linear: true
941
- }, (err, data) => {
942
- if (err) {
943
- } else {
944
- log4("downloaded", {
945
- data
946
- }, {
947
- F: __dxlog_file5,
948
- L: 415,
949
- S: this,
950
- C: (f, a) => f(...a)
951
- });
952
- }
953
- });
954
- this._downloads.set(feed, handle);
955
- }
956
- async _initIterator() {
957
- this._feedSetIterator = new FeedSetIterator(createMessageSelector(this._timeframeClock), {
958
- start: startAfter(this._timeframeClock.timeframe),
959
- stallTimeout: 1e3
960
- });
961
- this._feedSetIterator.stalled.on((iterator) => {
962
- log4.warn(`Stalled after ${iterator.options.stallTimeout}ms with ${iterator.size} feeds.`, {
963
- currentTimeframe: this._timeframeClock.timeframe,
964
- targetTimeframe: this._state.targetTimeframe
965
- }, {
966
- F: __dxlog_file5,
967
- L: 429,
968
- S: this,
969
- C: (f, a) => f(...a)
970
- });
971
- this._state.stalled.emit();
972
- });
973
- for (const feed of this._feeds.values()) {
974
- await this._feedSetIterator.addFeed(feed);
975
- }
976
- }
977
- };
978
- _ts_decorate3([
979
- synchronized2
980
- ], Pipeline.prototype, "start", null);
981
- _ts_decorate3([
982
- synchronized2
983
- ], Pipeline.prototype, "stop", null);
984
- _ts_decorate3([
985
- synchronized2
986
- ], Pipeline.prototype, "setCursor", null);
987
- _ts_decorate3([
988
- synchronized2
989
- ], Pipeline.prototype, "pause", null);
990
- _ts_decorate3([
991
- synchronized2
992
- ], Pipeline.prototype, "unpause", null);
993
-
994
- // src/space/auth.ts
995
- import { runInContext, scheduleTask } from "@dxos/async";
996
- import { Context as Context3 } from "@dxos/context";
997
- import { randomBytes } from "@dxos/crypto";
998
- import { invariant as invariant5 } from "@dxos/invariant";
999
- import { log as log5 } from "@dxos/log";
1000
- import { schema as schema3 } from "@dxos/protocols/proto";
1001
- import { RpcExtension } from "@dxos/teleport";
1002
- var __dxlog_file6 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/space/auth.ts";
1003
- var AuthExtension = class extends RpcExtension {
1004
- _authParams;
1005
- _ctx = new Context3({
1006
- onError: (err) => {
1007
- log5.catch(err, void 0, {
1008
- F: __dxlog_file6,
1009
- L: 28,
1010
- S: this,
1011
- C: (f, a) => f(...a)
1012
- });
1013
- }
1014
- }, {
1015
- F: __dxlog_file6,
1016
- L: 26
1017
- });
1018
- constructor(_authParams) {
1019
- super({
1020
- requested: {
1021
- AuthService: schema3.getService("dxos.mesh.teleport.auth.AuthService")
1022
- },
1023
- exposed: {
1024
- AuthService: schema3.getService("dxos.mesh.teleport.auth.AuthService")
1025
- },
1026
- timeout: 60 * 1e3
1027
- }), this._authParams = _authParams;
1028
- }
1029
- async getHandlers() {
1030
- return {
1031
- AuthService: {
1032
- authenticate: async ({ challenge }) => {
1033
- try {
1034
- const credential = await this._authParams.provider(challenge);
1035
- if (!credential) {
1036
- throw new Error("auth rejected");
1037
- }
1038
- return {
1039
- credential
1040
- };
1041
- } catch (err) {
1042
- log5.error("failed to generate auth credentials", err, {
1043
- F: __dxlog_file6,
1044
- L: 55,
1045
- S: this,
1046
- C: (f, a) => f(...a)
1047
- });
1048
- throw new Error("auth rejected");
1049
- }
1050
- }
1051
- }
1052
- };
1053
- }
1054
- async onOpen(context) {
1055
- await super.onOpen(context);
1056
- scheduleTask(this._ctx, async () => {
1057
- try {
1058
- const challenge = randomBytes(32);
1059
- const { credential } = await this.rpc.AuthService.authenticate({
1060
- challenge
1061
- });
1062
- invariant5(credential?.length > 0, "invalid credential", {
1063
- F: __dxlog_file6,
1064
- L: 69,
1065
- S: this,
1066
- A: [
1067
- "credential?.length > 0",
1068
- "'invalid credential'"
1069
- ]
1070
- });
1071
- const success = await this._authParams.verifier(challenge, credential);
1072
- invariant5(success, "credential not verified", {
1073
- F: __dxlog_file6,
1074
- L: 71,
1075
- S: this,
1076
- A: [
1077
- "success",
1078
- "'credential not verified'"
1079
- ]
1080
- });
1081
- runInContext(this._ctx, () => this._authParams.onAuthSuccess());
1082
- } catch (err) {
1083
- log5("auth failed", err, {
1084
- F: __dxlog_file6,
1085
- L: 74,
1086
- S: this,
1087
- C: (f, a) => f(...a)
1088
- });
1089
- this.close();
1090
- this._authParams.onAuthFailure();
1091
- }
1092
- });
1093
- }
1094
- async onClose() {
1095
- await this._ctx.dispose();
1096
- await super.onClose();
1097
- }
1098
- async onAbort() {
1099
- await this._ctx.dispose();
1100
- await super.onAbort();
1101
- }
1102
- };
1103
-
1104
- // src/space/space.ts
1105
- import { Event as Event4, scheduleMicroTask as scheduleMicroTask2, synchronized as synchronized3, trackLeaks as trackLeaks2 } from "@dxos/async";
1106
- import { Resource } from "@dxos/context";
1107
- import { invariant as invariant6 } from "@dxos/invariant";
1108
- import { log as log7, logInfo } from "@dxos/log";
1109
- import { AdmittedFeed as AdmittedFeed2 } from "@dxos/protocols/proto/dxos/halo/credentials";
1110
- import { trace as trace2 } from "@dxos/tracing";
1111
- import { Callback as Callback2 } from "@dxos/util";
1112
-
1113
- // src/space/control-pipeline.ts
1114
- import { DeferredTask, scheduleMicroTask, sleepWithContext as sleepWithContext2, trackLeaks } from "@dxos/async";
1115
- import { Context as Context4 } from "@dxos/context";
1116
- import { SpaceStateMachine } from "@dxos/credentials";
1117
- import { PublicKey as PublicKey4 } from "@dxos/keys";
1118
- import { log as log6 } from "@dxos/log";
1119
- import { AdmittedFeed } from "@dxos/protocols/proto/dxos/halo/credentials";
1120
- import { Timeframe as Timeframe3 } from "@dxos/timeframe";
1121
- import { TimeSeriesCounter, TimeUsageCounter, trace } from "@dxos/tracing";
1122
- import { Callback, tracer } from "@dxos/util";
1123
- function _ts_decorate4(decorators, target, key, desc) {
1124
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1125
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1126
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1127
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1128
- }
1129
- var __dxlog_file7 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/space/control-pipeline.ts";
1130
- var TIMEFRAME_SAVE_DEBOUNCE_INTERVAL = 500;
1131
- var CONTROL_PIPELINE_SNAPSHOT_DELAY = 1e4;
1132
- var USE_SNAPSHOTS = true;
1133
- var ControlPipeline = class {
1134
- _ctx = new Context4(void 0, {
1135
- F: __dxlog_file7,
1136
- L: 47
1137
- });
1138
- _pipeline;
1139
- _spaceStateMachine;
1140
- _spaceKey;
1141
- _metadata;
1142
- _targetTimeframe;
1143
- _lastTimeframeSaveTime = Date.now();
1144
- onFeedAdmitted = new Callback();
1145
- onMemberRoleChanged;
1146
- onCredentialProcessed;
1147
- onDelegatedInvitation;
1148
- onDelegatedInvitationRemoved;
1149
- _usage = new TimeUsageCounter();
1150
- _mutations = new TimeSeriesCounter();
1151
- _snapshotTask = new DeferredTask(this._ctx, async () => {
1152
- await sleepWithContext2(this._ctx, CONTROL_PIPELINE_SNAPSHOT_DELAY);
1153
- await this._saveSnapshot();
1154
- });
1155
- constructor({ spaceKey, genesisFeed, feedProvider, metadataStore }) {
1156
- this._spaceKey = spaceKey;
1157
- this._metadata = metadataStore;
1158
- this._pipeline = new Pipeline();
1159
- void this._pipeline.addFeed(genesisFeed);
1160
- this._spaceStateMachine = new SpaceStateMachine(spaceKey);
1161
- this._spaceStateMachine.onFeedAdmitted.set(async (info) => {
1162
- log6("feed admitted", {
1163
- key: info.key
1164
- }, {
1165
- F: __dxlog_file7,
1166
- L: 82,
1167
- S: this,
1168
- C: (f, a) => f(...a)
1169
- });
1170
- if (info.assertion.designation === AdmittedFeed.Designation.CONTROL && !info.key.equals(genesisFeed.key)) {
1171
- scheduleMicroTask(this._ctx, async () => {
1172
- try {
1173
- const feed = await feedProvider(info.key);
1174
- if (this._ctx.disposed) {
1175
- return;
1176
- }
1177
- if (!this._pipeline.hasFeed(feed.key)) {
1178
- await this._pipeline.addFeed(feed);
1179
- }
1180
- } catch (err) {
1181
- log6.catch(err, void 0, {
1182
- F: __dxlog_file7,
1183
- L: 96,
1184
- S: this,
1185
- C: (f, a) => f(...a)
1186
- });
1187
- }
1188
- });
1189
- }
1190
- await this.onFeedAdmitted.callIfSet(info);
1191
- });
1192
- this.onMemberRoleChanged = this._spaceStateMachine.onMemberRoleChanged;
1193
- this.onCredentialProcessed = this._spaceStateMachine.onCredentialProcessed;
1194
- this.onDelegatedInvitation = this._spaceStateMachine.onDelegatedInvitation;
1195
- this.onDelegatedInvitationRemoved = this._spaceStateMachine.onDelegatedInvitationRemoved;
1196
- }
1197
- get spaceState() {
1198
- return this._spaceStateMachine;
1199
- }
1200
- get pipeline() {
1201
- return this._pipeline;
1202
- }
1203
- async setWriteFeed(feed) {
1204
- await this._pipeline.addFeed(feed);
1205
- this._pipeline.setWriteFeed(feed);
1206
- }
1207
- async start() {
1208
- const snapshot = this._metadata.getSpaceControlPipelineSnapshot(this._spaceKey);
1209
- log6("load snapshot", {
1210
- key: this._spaceKey,
1211
- present: !!snapshot,
1212
- tf: snapshot?.timeframe
1213
- }, {
1214
- F: __dxlog_file7,
1215
- L: 126,
1216
- S: this,
1217
- C: (f, a) => f(...a)
1218
- });
1219
- if (USE_SNAPSHOTS && snapshot) {
1220
- await this._processSnapshot(snapshot);
1221
- }
1222
- log6("starting...", void 0, {
1223
- F: __dxlog_file7,
1224
- L: 131,
1225
- S: this,
1226
- C: (f, a) => f(...a)
1227
- });
1228
- setTimeout(async () => {
1229
- void this._consumePipeline(new Context4(void 0, {
1230
- F: __dxlog_file7,
1231
- L: 133
1232
- }));
1233
- });
1234
- await this._pipeline.start();
1235
- log6("started", void 0, {
1236
- F: __dxlog_file7,
1237
- L: 137,
1238
- S: this,
1239
- C: (f, a) => f(...a)
1240
- });
1241
- }
1242
- async _processSnapshot(snapshot) {
1243
- await this._pipeline.setCursor(snapshot.timeframe);
1244
- for (const message of snapshot.messages ?? []) {
1245
- const result = await this._spaceStateMachine.process(message.credential, {
1246
- sourceFeed: message.feedKey,
1247
- skipVerification: true
1248
- });
1249
- if (!result) {
1250
- log6.warn("credential processing failed from snapshot", {
1251
- message
1252
- }, {
1253
- F: __dxlog_file7,
1254
- L: 150,
1255
- S: this,
1256
- C: (f, a) => f(...a)
1257
- });
1258
- }
1259
- }
1260
- }
1261
- async _saveSnapshot() {
1262
- await this._pipeline.pause();
1263
- const snapshot = {
1264
- timeframe: this._pipeline.state.timeframe,
1265
- messages: this._spaceStateMachine.credentialEntries.map((entry) => ({
1266
- feedKey: entry.sourceFeed,
1267
- credential: entry.credential
1268
- }))
1269
- };
1270
- await this._pipeline.unpause();
1271
- log6("save snapshot", {
1272
- key: this._spaceKey,
1273
- snapshot: getSnapshotLoggerContext(snapshot)
1274
- }, {
1275
- F: __dxlog_file7,
1276
- L: 166,
1277
- S: this,
1278
- C: (f, a) => f(...a)
1279
- });
1280
- await this._metadata.setSpaceControlPipelineSnapshot(this._spaceKey, snapshot);
1281
- }
1282
- async _consumePipeline(ctx) {
1283
- for await (const msg of this._pipeline.consume()) {
1284
- const span = this._usage.beginRecording();
1285
- this._mutations.inc();
1286
- try {
1287
- await this._processMessage(ctx, msg);
1288
- } catch (err) {
1289
- log6.catch(err, void 0, {
1290
- F: __dxlog_file7,
1291
- L: 179,
1292
- S: this,
1293
- C: (f, a) => f(...a)
1294
- });
1295
- }
1296
- span.end();
1297
- }
1298
- }
1299
- async _processMessage(ctx, msg) {
1300
- log6("processing", {
1301
- key: msg.feedKey,
1302
- seq: msg.seq
1303
- }, {
1304
- F: __dxlog_file7,
1305
- L: 188,
1306
- S: this,
1307
- C: (f, a) => f(...a)
1308
- });
1309
- if (msg.data.payload.credential) {
1310
- const timer = tracer.mark("dxos.echo.pipeline.control");
1311
- const result = await this._spaceStateMachine.process(msg.data.payload.credential.credential, {
1312
- sourceFeed: PublicKey4.from(msg.feedKey)
1313
- });
1314
- timer.end();
1315
- if (!result) {
1316
- log6.warn("processing failed", {
1317
- msg
1318
- }, {
1319
- F: __dxlog_file7,
1320
- L: 197,
1321
- S: this,
1322
- C: (f, a) => f(...a)
1323
- });
1324
- } else {
1325
- await this._noteTargetStateIfNeeded(this._pipeline.state.pendingTimeframe);
1326
- }
1327
- this._snapshotTask.schedule();
1328
- }
1329
- }
1330
- async _noteTargetStateIfNeeded(timeframe) {
1331
- if (Date.now() - this._lastTimeframeSaveTime > TIMEFRAME_SAVE_DEBOUNCE_INTERVAL) {
1332
- this._lastTimeframeSaveTime = Date.now();
1333
- await this._saveTargetTimeframe(timeframe);
1334
- }
1335
- }
1336
- async stop() {
1337
- log6("stopping...", void 0, {
1338
- F: __dxlog_file7,
1339
- L: 217,
1340
- S: this,
1341
- C: (f, a) => f(...a)
1342
- });
1343
- await this._ctx.dispose();
1344
- await this._pipeline.stop();
1345
- await this._saveTargetTimeframe(this._pipeline.state.timeframe);
1346
- log6("stopped", void 0, {
1347
- F: __dxlog_file7,
1348
- L: 221,
1349
- S: this,
1350
- C: (f, a) => f(...a)
1351
- });
1352
- }
1353
- async _saveTargetTimeframe(timeframe) {
1354
- try {
1355
- const newTimeframe = Timeframe3.merge(this._targetTimeframe ?? new Timeframe3(), timeframe);
1356
- await this._metadata.setSpaceControlLatestTimeframe(this._spaceKey, newTimeframe);
1357
- this._targetTimeframe = newTimeframe;
1358
- } catch (err) {
1359
- log6(err, void 0, {
1360
- F: __dxlog_file7,
1361
- L: 230,
1362
- S: this,
1363
- C: (f, a) => f(...a)
1364
- });
1365
- }
1366
- }
1367
- };
1368
- _ts_decorate4([
1369
- trace.metricsCounter()
1370
- ], ControlPipeline.prototype, "_usage", void 0);
1371
- _ts_decorate4([
1372
- trace.metricsCounter()
1373
- ], ControlPipeline.prototype, "_mutations", void 0);
1374
- _ts_decorate4([
1375
- trace.span({
1376
- showInBrowserTimeline: true
1377
- })
1378
- ], ControlPipeline.prototype, "start", null);
1379
- _ts_decorate4([
1380
- trace.span()
1381
- ], ControlPipeline.prototype, "_consumePipeline", null);
1382
- _ts_decorate4([
1383
- trace.span()
1384
- ], ControlPipeline.prototype, "_processMessage", null);
1385
- ControlPipeline = _ts_decorate4([
1386
- trace.resource(),
1387
- trackLeaks("start", "stop")
1388
- ], ControlPipeline);
1389
- var getSnapshotLoggerContext = (snapshot) => {
1390
- return snapshot.messages?.map((msg) => {
1391
- const issuer = msg.credential.issuer;
1392
- const subject = msg.credential.subject.id;
1393
- const type = msg.credential.subject.assertion["@type"];
1394
- return {
1395
- issuer,
1396
- subject,
1397
- type
1398
- };
1399
- });
1400
- };
1401
-
1402
- // src/space/space.ts
1403
- function _ts_decorate5(decorators, target, key, desc) {
1404
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1405
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1406
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1407
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1408
- }
1409
- var __dxlog_file8 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/space/space.ts";
1410
- var Space = class extends Resource {
1411
- onCredentialProcessed = new Callback2();
1412
- stateUpdate = new Event4();
1413
- protocol;
1414
- _id;
1415
- _key;
1416
- _genesisFeedKey;
1417
- _feedProvider;
1418
- _controlPipeline;
1419
- _controlFeed;
1420
- _dataFeed;
1421
- constructor(params) {
1422
- super();
1423
- invariant6(params.spaceKey && params.feedProvider, void 0, {
1424
- F: __dxlog_file8,
1425
- L: 73,
1426
- S: this,
1427
- A: [
1428
- "params.spaceKey && params.feedProvider",
1429
- ""
1430
- ]
1431
- });
1432
- this._id = params.id;
1433
- this._key = params.spaceKey;
1434
- this._genesisFeedKey = params.genesisFeed.key;
1435
- this._feedProvider = params.feedProvider;
1436
- this._controlPipeline = new ControlPipeline({
1437
- spaceKey: params.spaceKey,
1438
- genesisFeed: params.genesisFeed,
1439
- feedProvider: params.feedProvider,
1440
- metadataStore: params.metadataStore
1441
- });
1442
- this._controlPipeline.onFeedAdmitted.set(async (info) => {
1443
- const sparse = info.assertion.designation === AdmittedFeed2.Designation.DATA;
1444
- if (!info.key.equals(params.genesisFeed.key)) {
1445
- scheduleMicroTask2(this._ctx, async () => {
1446
- await this.protocol.addFeed(await params.feedProvider(info.key, {
1447
- sparse
1448
- }));
1449
- });
1450
- }
1451
- });
1452
- this._controlPipeline.onCredentialProcessed.set(async (credential) => {
1453
- await this.onCredentialProcessed.callIfSet(credential);
1454
- log7("onCredentialProcessed", {
1455
- credential
1456
- }, {
1457
- F: __dxlog_file8,
1458
- L: 100,
1459
- S: this,
1460
- C: (f, a) => f(...a)
1461
- });
1462
- this.stateUpdate.emit();
1463
- });
1464
- this._controlPipeline.onDelegatedInvitation.set(async (invitation) => {
1465
- log7("onDelegatedInvitation", {
1466
- invitation
1467
- }, {
1468
- F: __dxlog_file8,
1469
- L: 104,
1470
- S: this,
1471
- C: (f, a) => f(...a)
1472
- });
1473
- await params.onDelegatedInvitationStatusChange(invitation, true);
1474
- });
1475
- this._controlPipeline.onDelegatedInvitationRemoved.set(async (invitation) => {
1476
- log7("onDelegatedInvitationRemoved", {
1477
- invitation
1478
- }, {
1479
- F: __dxlog_file8,
1480
- L: 108,
1481
- S: this,
1482
- C: (f, a) => f(...a)
1483
- });
1484
- await params.onDelegatedInvitationStatusChange(invitation, false);
1485
- });
1486
- this._controlPipeline.onMemberRoleChanged.set(async (changedMembers) => {
1487
- log7("onMemberRoleChanged", () => ({
1488
- changedMembers: changedMembers.map((m) => [
1489
- m.key,
1490
- m.role
1491
- ])
1492
- }), {
1493
- F: __dxlog_file8,
1494
- L: 112,
1495
- S: this,
1496
- C: (f, a) => f(...a)
1497
- });
1498
- await params.onMemberRolesChanged(changedMembers);
1499
- });
1500
- this.protocol = params.protocol;
1501
- }
1502
- get id() {
1503
- return this._id;
1504
- }
1505
- get key() {
1506
- return this._key;
1507
- }
1508
- get genesisFeedKey() {
1509
- return this._genesisFeedKey;
1510
- }
1511
- get controlFeedKey() {
1512
- return this._controlFeed?.key;
1513
- }
1514
- get dataFeedKey() {
1515
- return this._dataFeed?.key;
1516
- }
1517
- get spaceState() {
1518
- return this._controlPipeline.spaceState;
1519
- }
1520
- /**
1521
- * @test-only
1522
- */
1523
- get controlPipeline() {
1524
- return this._controlPipeline.pipeline;
1525
- }
1526
- async setControlFeed(feed) {
1527
- invariant6(!this._controlFeed, "Control feed already set.", {
1528
- F: __dxlog_file8,
1529
- L: 156,
1530
- S: this,
1531
- A: [
1532
- "!this._controlFeed",
1533
- "'Control feed already set.'"
1534
- ]
1535
- });
1536
- this._controlFeed = feed;
1537
- await this._controlPipeline.setWriteFeed(feed);
1538
- return this;
1539
- }
1540
- async setDataFeed(feed) {
1541
- invariant6(!this._dataFeed, "Data feed already set.", {
1542
- F: __dxlog_file8,
1543
- L: 163,
1544
- S: this,
1545
- A: [
1546
- "!this._dataFeed",
1547
- "'Data feed already set.'"
1548
- ]
1549
- });
1550
- this._dataFeed = feed;
1551
- return this;
1552
- }
1553
- /**
1554
- * Use for diagnostics.
1555
- */
1556
- getControlFeeds() {
1557
- return Array.from(this._controlPipeline.spaceState.feeds.values());
1558
- }
1559
- async _open(ctx) {
1560
- log7("opening...", void 0, {
1561
- F: __dxlog_file8,
1562
- L: 177,
1563
- S: this,
1564
- C: (f, a) => f(...a)
1565
- });
1566
- await this._controlPipeline.start();
1567
- log7("opened", void 0, {
1568
- F: __dxlog_file8,
1569
- L: 182,
1570
- S: this,
1571
- C: (f, a) => f(...a)
1572
- });
1573
- }
1574
- async startProtocol() {
1575
- invariant6(this.isOpen, void 0, {
1576
- F: __dxlog_file8,
1577
- L: 187,
1578
- S: this,
1579
- A: [
1580
- "this.isOpen",
1581
- ""
1582
- ]
1583
- });
1584
- await this.protocol.start();
1585
- await this.protocol.addFeed(await this._feedProvider(this._genesisFeedKey));
1586
- }
1587
- async _close() {
1588
- log7("closing...", {
1589
- key: this._key
1590
- }, {
1591
- F: __dxlog_file8,
1592
- L: 194,
1593
- S: this,
1594
- C: (f, a) => f(...a)
1595
- });
1596
- await this.protocol.stop();
1597
- await this._controlPipeline.stop();
1598
- log7("closed", void 0, {
1599
- F: __dxlog_file8,
1600
- L: 200,
1601
- S: this,
1602
- C: (f, a) => f(...a)
1603
- });
1604
- }
1605
- };
1606
- _ts_decorate5([
1607
- trace2.info()
1608
- ], Space.prototype, "protocol", void 0);
1609
- _ts_decorate5([
1610
- trace2.info()
1611
- ], Space.prototype, "_controlPipeline", void 0);
1612
- _ts_decorate5([
1613
- logInfo,
1614
- trace2.info()
1615
- ], Space.prototype, "id", null);
1616
- _ts_decorate5([
1617
- logInfo,
1618
- trace2.info()
1619
- ], Space.prototype, "key", null);
1620
- _ts_decorate5([
1621
- trace2.span()
1622
- ], Space.prototype, "_open", null);
1623
- _ts_decorate5([
1624
- synchronized3
1625
- ], Space.prototype, "startProtocol", null);
1626
- _ts_decorate5([
1627
- synchronized3
1628
- ], Space.prototype, "_close", null);
1629
- Space = _ts_decorate5([
1630
- trackLeaks2("open", "close"),
1631
- trace2.resource()
1632
- ], Space);
1633
-
1634
- // src/space/admission-discovery-extension.ts
1635
- import { scheduleTask as scheduleTask2 } from "@dxos/async";
1636
- import { Context as Context5 } from "@dxos/context";
1637
- import { ProtocolError } from "@dxos/protocols";
1638
- import { schema as schema4 } from "@dxos/protocols/proto";
1639
- import { RpcExtension as RpcExtension2 } from "@dxos/teleport";
1640
- var __dxlog_file9 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/space/admission-discovery-extension.ts";
1641
- var CredentialRetrieverExtension = class extends RpcExtension2 {
1642
- _request;
1643
- _onResult;
1644
- _ctx = new Context5(void 0, {
1645
- F: __dxlog_file9,
1646
- L: 26
1647
- });
1648
- constructor(_request, _onResult) {
1649
- super({
1650
- requested: {
1651
- AdmissionDiscoveryService: schema4.getService("dxos.mesh.teleport.AdmissionDiscoveryService")
1652
- }
1653
- }), this._request = _request, this._onResult = _onResult;
1654
- }
1655
- async getHandlers() {
1656
- return {};
1657
- }
1658
- async onOpen(context) {
1659
- await super.onOpen(context);
1660
- scheduleTask2(this._ctx, async () => {
1661
- try {
1662
- const result = await this.rpc.AdmissionDiscoveryService.getAdmissionCredential(this._request);
1663
- this._onResult.wake(result.admissionCredential);
1664
- } catch (err) {
1665
- context.close(err);
1666
- }
1667
- });
1668
- }
1669
- async onClose() {
1670
- await this._ctx.dispose();
1671
- }
1672
- async onAbort() {
1673
- await this._ctx.dispose();
1674
- }
1675
- };
1676
- var CredentialServerExtension = class extends RpcExtension2 {
1677
- _space;
1678
- constructor(_space) {
1679
- super({
1680
- exposed: {
1681
- AdmissionDiscoveryService: schema4.getService("dxos.mesh.teleport.AdmissionDiscoveryService")
1682
- }
1683
- }), this._space = _space;
1684
- }
1685
- async getHandlers() {
1686
- return {
1687
- AdmissionDiscoveryService: {
1688
- getAdmissionCredential: async (request) => {
1689
- const memberInfo = this._space.spaceState.members.get(request.memberKey);
1690
- if (!memberInfo?.credential) {
1691
- throw new ProtocolError("Space member not found.", request);
1692
- }
1693
- return {
1694
- admissionCredential: memberInfo.credential
1695
- };
1696
- }
1697
- }
1698
- };
1699
- }
1700
- };
1701
-
1702
- // src/space/space-protocol.ts
1703
- import { discoveryKey, subtleCrypto as subtleCrypto2 } from "@dxos/crypto";
1704
- import { PublicKey as PublicKey5 } from "@dxos/keys";
1705
- import { log as log8, logInfo as logInfo2 } from "@dxos/log";
1706
- import { MMSTTopology } from "@dxos/network-manager";
1707
- import { Teleport } from "@dxos/teleport";
1708
- import { BlobSync } from "@dxos/teleport-extension-object-sync";
1709
- import { ReplicatorExtension } from "@dxos/teleport-extension-replicator";
1710
- import { trace as trace3 } from "@dxos/tracing";
1711
- import { CallbackCollection, ComplexMap as ComplexMap4 } from "@dxos/util";
1712
- function _ts_decorate6(decorators, target, key, desc) {
1713
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1714
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1715
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1716
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1717
- }
1718
- var __dxlog_file10 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/space/space-protocol.ts";
1719
- var MOCK_AUTH_PROVIDER = async (nonce) => Buffer.from("mock");
1720
- var MOCK_AUTH_VERIFIER = async (nonce, credential) => true;
1721
- var SpaceProtocol = class {
1722
- _networkManager;
1723
- _swarmIdentity;
1724
- _onSessionAuth;
1725
- _onAuthFailure;
1726
- blobSync;
1727
- _disableP2pReplication;
1728
- _topic;
1729
- _spaceKey;
1730
- _feeds = /* @__PURE__ */ new Set();
1731
- _sessions = new ComplexMap4(PublicKey5.hash);
1732
- // TODO(burdon): Move to config (with sensible defaults).
1733
- _topology = new MMSTTopology({
1734
- originateConnections: 4,
1735
- maxPeers: 10,
1736
- sampleSize: 20
1737
- });
1738
- _connection;
1739
- feedAdded = new CallbackCollection();
1740
- get sessions() {
1741
- return this._sessions;
1742
- }
1743
- get feeds() {
1744
- return this._feeds;
1745
- }
1746
- get _ownPeerKey() {
1747
- return this._swarmIdentity.peerKey;
1748
- }
1749
- constructor({ topic, swarmIdentity, networkManager, onSessionAuth, onAuthFailure, blobStore, disableP2pReplication }) {
1750
- this._spaceKey = topic;
1751
- this._networkManager = networkManager;
1752
- this._swarmIdentity = swarmIdentity;
1753
- this._onSessionAuth = onSessionAuth;
1754
- this._onAuthFailure = onAuthFailure;
1755
- this.blobSync = new BlobSync({
1756
- blobStore
1757
- });
1758
- this._topic = subtleCrypto2.digest("SHA-256", topic.asBuffer()).then(discoveryKey).then(PublicKey5.from);
1759
- this._disableP2pReplication = disableP2pReplication ?? false;
1760
- }
1761
- // TODO(burdon): Create abstraction for Space (e.g., add keys and have provider).
1762
- async addFeed(feed) {
1763
- log8("addFeed", {
1764
- key: feed.key
1765
- }, {
1766
- F: __dxlog_file10,
1767
- L: 131,
1768
- S: this,
1769
- C: (f, a) => f(...a)
1770
- });
1771
- this._feeds.add(feed);
1772
- for (const session of this._sessions.values()) {
1773
- session.replicator.addFeed(feed);
1774
- }
1775
- await this.feedAdded.callSerial(feed);
1776
- }
1777
- // TODO(burdon): Rename open? Common open/close interfaces for all services?
1778
- async start() {
1779
- if (this._connection) {
1780
- return;
1781
- }
1782
- const credentials = await this._swarmIdentity.credentialProvider(Buffer.from(""));
1783
- await this.blobSync.open();
1784
- log8("starting...", void 0, {
1785
- F: __dxlog_file10,
1786
- L: 152,
1787
- S: this,
1788
- C: (f, a) => f(...a)
1789
- });
1790
- const topic = await this._topic;
1791
- this._connection = await this._networkManager.joinSwarm({
1792
- protocolProvider: this._createProtocolProvider(credentials),
1793
- topic,
1794
- topology: this._topology,
1795
- label: `swarm ${topic.truncate()} for space ${this._spaceKey.truncate()}`
1796
- });
1797
- log8("started", void 0, {
1798
- F: __dxlog_file10,
1799
- L: 161,
1800
- S: this,
1801
- C: (f, a) => f(...a)
1802
- });
1803
- }
1804
- updateTopology() {
1805
- this._topology.forceUpdate();
1806
- }
1807
- async stop() {
1808
- await this.blobSync.close();
1809
- if (this._connection) {
1810
- log8("stopping...", void 0, {
1811
- F: __dxlog_file10,
1812
- L: 172,
1813
- S: this,
1814
- C: (f, a) => f(...a)
1815
- });
1816
- await this._connection.close();
1817
- log8("stopped", void 0, {
1818
- F: __dxlog_file10,
1819
- L: 174,
1820
- S: this,
1821
- C: (f, a) => f(...a)
1822
- });
1823
- }
1824
- }
1825
- _createProtocolProvider(credentials) {
1826
- return (wireParams) => {
1827
- const session = new SpaceProtocolSession({
1828
- wireParams,
1829
- swarmIdentity: this._swarmIdentity,
1830
- onSessionAuth: this._onSessionAuth,
1831
- onAuthFailure: this._onAuthFailure,
1832
- blobSync: this.blobSync,
1833
- disableP2pReplication: this._disableP2pReplication
1834
- });
1835
- this._sessions.set(wireParams.remotePeerId, session);
1836
- for (const feed of this._feeds) {
1837
- session.replicator.addFeed(feed);
1838
- }
1839
- return session;
1840
- };
1841
- }
1842
- };
1843
- _ts_decorate6([
1844
- logInfo2,
1845
- trace3.info()
1846
- ], SpaceProtocol.prototype, "_topic", void 0);
1847
- _ts_decorate6([
1848
- trace3.info()
1849
- ], SpaceProtocol.prototype, "_spaceKey", void 0);
1850
- _ts_decorate6([
1851
- logInfo2
1852
- ], SpaceProtocol.prototype, "_ownPeerKey", null);
1853
- SpaceProtocol = _ts_decorate6([
1854
- trace3.resource()
1855
- ], SpaceProtocol);
1856
- var AuthStatus = /* @__PURE__ */ (function(AuthStatus2) {
1857
- AuthStatus2["INITIAL"] = "INITIAL";
1858
- AuthStatus2["SUCCESS"] = "SUCCESS";
1859
- AuthStatus2["FAILURE"] = "FAILURE";
1860
- return AuthStatus2;
1861
- })({});
1862
- var SpaceProtocolSession = class {
1863
- _wireParams;
1864
- _disableP2pReplication;
1865
- _onSessionAuth;
1866
- _onAuthFailure;
1867
- _swarmIdentity;
1868
- _blobSync;
1869
- _teleport;
1870
- // TODO(dmaretskyi): Start with upload=false when switching it on the fly works.
1871
- replicator = new ReplicatorExtension().setOptions({
1872
- upload: true
1873
- });
1874
- _authStatus = "INITIAL";
1875
- get authStatus() {
1876
- return this._authStatus;
1877
- }
1878
- get stats() {
1879
- return this._teleport.stats;
1880
- }
1881
- // TODO(dmaretskyi): Allow to pass in extra extensions.
1882
- constructor({ wireParams, swarmIdentity, onSessionAuth, onAuthFailure, blobSync, disableP2pReplication }) {
1883
- this._wireParams = wireParams;
1884
- this._swarmIdentity = swarmIdentity;
1885
- this._onSessionAuth = onSessionAuth;
1886
- this._onAuthFailure = onAuthFailure;
1887
- this._blobSync = blobSync;
1888
- this._teleport = new Teleport(wireParams);
1889
- this._disableP2pReplication = disableP2pReplication ?? false;
1890
- }
1891
- get stream() {
1892
- return this._teleport.stream;
1893
- }
1894
- async open(sessionId) {
1895
- await this._teleport.open(sessionId);
1896
- this._teleport.addExtension("dxos.mesh.teleport.auth", new AuthExtension({
1897
- provider: this._swarmIdentity.credentialProvider,
1898
- verifier: this._swarmIdentity.credentialAuthenticator,
1899
- onAuthSuccess: () => {
1900
- log8("Peer authenticated", void 0, {
1901
- F: __dxlog_file10,
1902
- L: 285,
1903
- S: this,
1904
- C: (f, a) => f(...a)
1905
- });
1906
- this._authStatus = "SUCCESS";
1907
- this._onSessionAuth?.(this._teleport);
1908
- },
1909
- onAuthFailure: () => {
1910
- this._authStatus = "FAILURE";
1911
- this._onAuthFailure?.(this._teleport);
1912
- }
1913
- }));
1914
- if (!this._disableP2pReplication) {
1915
- this._teleport.addExtension("dxos.mesh.teleport.replicator", this.replicator);
1916
- }
1917
- this._teleport.addExtension("dxos.mesh.teleport.blobsync", this._blobSync.createExtension());
1918
- }
1919
- async close() {
1920
- log8("close", void 0, {
1921
- F: __dxlog_file10,
1922
- L: 304,
1923
- S: this,
1924
- C: (f, a) => f(...a)
1925
- });
1926
- await this._teleport.close();
1927
- }
1928
- async abort() {
1929
- await this._teleport.abort();
1930
- }
1931
- };
1932
- _ts_decorate6([
1933
- logInfo2
1934
- ], SpaceProtocolSession.prototype, "_wireParams", void 0);
1935
- _ts_decorate6([
1936
- logInfo2
1937
- ], SpaceProtocolSession.prototype, "authStatus", null);
1938
-
1939
- // src/space/space-manager.ts
1940
- import { parseAutomergeUrl } from "@automerge/automerge-repo";
1941
- import { Trigger as Trigger2, synchronized as synchronized4, trackLeaks as trackLeaks3 } from "@dxos/async";
1942
- import { getCredentialAssertion } from "@dxos/credentials";
1943
- import { failUndefined as failUndefined2 } from "@dxos/debug";
1944
- import { PublicKey as PublicKey6 } from "@dxos/keys";
1945
- import { log as log9 } from "@dxos/log";
1946
- import { trace as trace4 } from "@dxos/protocols";
1947
- import { ComplexMap as ComplexMap5 } from "@dxos/util";
1948
- function _ts_decorate7(decorators, target, key, desc) {
1949
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1950
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1951
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1952
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1953
- }
1954
- var __dxlog_file11 = "/__w/dxos/dxos/packages/core/echo/echo-pipeline/src/space/space-manager.ts";
1955
- var SpaceManager = class {
1956
- _spaces = new ComplexMap5(PublicKey6.hash);
1957
- _feedStore;
1958
- _networkManager;
1959
- _metadataStore;
1960
- _blobStore;
1961
- _instanceId = PublicKey6.random().toHex();
1962
- _disableP2pReplication;
1963
- constructor({ feedStore, networkManager, metadataStore, blobStore, disableP2pReplication }) {
1964
- this._feedStore = feedStore;
1965
- this._networkManager = networkManager;
1966
- this._metadataStore = metadataStore;
1967
- this._blobStore = blobStore;
1968
- this._disableP2pReplication = disableP2pReplication ?? false;
1969
- }
1970
- // TODO(burdon): Remove.
1971
- get spaces() {
1972
- return this._spaces;
1973
- }
1974
- async open() {
1975
- }
1976
- async close() {
1977
- await Promise.all([
1978
- ...this._spaces.values()
1979
- ].map((space) => space.close()));
1980
- }
1981
- async constructSpace({ metadata, swarmIdentity, onAuthorizedConnection, onAuthFailure, onDelegatedInvitationStatusChange, onMemberRolesChanged, memberKey }) {
1982
- log9.trace("dxos.echo.space-manager.construct-space", trace4.begin({
1983
- id: this._instanceId
1984
- }), {
1985
- F: __dxlog_file11,
1986
- L: 103,
1987
- S: this,
1988
- C: (f, a) => f(...a)
1989
- });
1990
- log9("constructing space...", {
1991
- spaceKey: metadata.genesisFeedKey
1992
- }, {
1993
- F: __dxlog_file11,
1994
- L: 104,
1995
- S: this,
1996
- C: (f, a) => f(...a)
1997
- });
1998
- const genesisFeed = await this._feedStore.openFeed(metadata.genesisFeedKey ?? failUndefined2());
1999
- const spaceKey = metadata.key;
2000
- const spaceId = await createIdFromSpaceKey(spaceKey);
2001
- const protocol = new SpaceProtocol({
2002
- topic: spaceKey,
2003
- swarmIdentity,
2004
- networkManager: this._networkManager,
2005
- onSessionAuth: onAuthorizedConnection,
2006
- onAuthFailure,
2007
- blobStore: this._blobStore,
2008
- disableP2pReplication: this._disableP2pReplication
2009
- });
2010
- const space = new Space({
2011
- id: spaceId,
2012
- spaceKey,
2013
- protocol,
2014
- genesisFeed,
2015
- feedProvider: (feedKey, opts) => this._feedStore.openFeed(feedKey, opts),
2016
- metadataStore: this._metadataStore,
2017
- memberKey,
2018
- onDelegatedInvitationStatusChange,
2019
- onMemberRolesChanged
2020
- });
2021
- this._spaces.set(space.key, space);
2022
- log9.trace("dxos.echo.space-manager.construct-space", trace4.end({
2023
- id: this._instanceId
2024
- }), {
2025
- F: __dxlog_file11,
2026
- L: 134,
2027
- S: this,
2028
- C: (f, a) => f(...a)
2029
- });
2030
- return space;
2031
- }
2032
- async requestSpaceAdmissionCredential(params) {
2033
- const traceKey = "dxos.echo.space-manager.request-space-admission";
2034
- log9.trace(traceKey, trace4.begin({
2035
- id: this._instanceId
2036
- }), {
2037
- F: __dxlog_file11,
2038
- L: 140,
2039
- S: this,
2040
- C: (f, a) => f(...a)
2041
- });
2042
- log9("requesting space admission credential...", {
2043
- spaceKey: params.spaceKey
2044
- }, {
2045
- F: __dxlog_file11,
2046
- L: 141,
2047
- S: this,
2048
- C: (f, a) => f(...a)
2049
- });
2050
- const onCredentialResolved = new Trigger2();
2051
- const protocol = new SpaceProtocol({
2052
- topic: params.spaceKey,
2053
- swarmIdentity: params.swarmIdentity,
2054
- networkManager: this._networkManager,
2055
- onSessionAuth: (session) => {
2056
- session.addExtension("dxos.mesh.teleport.admission-discovery", new CredentialRetrieverExtension({
2057
- spaceKey: params.spaceKey,
2058
- memberKey: params.identityKey
2059
- }, onCredentialResolved));
2060
- },
2061
- onAuthFailure: (session) => session.close(),
2062
- blobStore: this._blobStore,
2063
- disableP2pReplication: this._disableP2pReplication
2064
- });
2065
- try {
2066
- await protocol.start();
2067
- const credential = await onCredentialResolved.wait({
2068
- timeout: params.timeout
2069
- });
2070
- log9.trace(traceKey, trace4.end({
2071
- id: this._instanceId
2072
- }), {
2073
- F: __dxlog_file11,
2074
- L: 165,
2075
- S: this,
2076
- C: (f, a) => f(...a)
2077
- });
2078
- return credential;
2079
- } catch (err) {
2080
- log9.trace(traceKey, trace4.error({
2081
- id: this._instanceId,
2082
- error: err
2083
- }), {
2084
- F: __dxlog_file11,
2085
- L: 168,
2086
- S: this,
2087
- C: (f, a) => f(...a)
2088
- });
2089
- throw err;
2090
- } finally {
2091
- await protocol.stop();
2092
- }
2093
- }
2094
- findSpaceByRootDocumentId(documentId) {
2095
- return [
2096
- ...this._spaces.values()
2097
- ].find((space) => {
2098
- return space.spaceState.credentials.some((credential) => {
2099
- const assertion = getCredentialAssertion(credential);
2100
- if (assertion["@type"] !== "dxos.halo.credentials.Epoch") {
2101
- return false;
2102
- }
2103
- if (!assertion?.automergeRoot) {
2104
- return false;
2105
- }
2106
- return parseAutomergeUrl(assertion.automergeRoot).documentId === documentId;
2107
- });
2108
- });
2109
- }
2110
- };
2111
- _ts_decorate7([
2112
- synchronized4
2113
- ], SpaceManager.prototype, "open", null);
2114
- _ts_decorate7([
2115
- synchronized4
2116
- ], SpaceManager.prototype, "close", null);
2117
- SpaceManager = _ts_decorate7([
2118
- trackLeaks3("open", "close")
2119
- ], SpaceManager);
2120
-
2121
- export {
2122
- codec,
2123
- valueEncoding,
2124
- createMappedFeedWriter,
2125
- createIdFromSpaceKey,
2126
- MetadataStore,
2127
- hasInvitationExpired,
2128
- mapTimeframeToFeedIndexes,
2129
- mapFeedIndexesToTimeframe,
2130
- startAfter,
2131
- TimeframeClock,
2132
- Pipeline,
2133
- AuthExtension,
2134
- Space,
2135
- CredentialRetrieverExtension,
2136
- CredentialServerExtension,
2137
- MOCK_AUTH_PROVIDER,
2138
- MOCK_AUTH_VERIFIER,
2139
- SpaceProtocol,
2140
- AuthStatus,
2141
- SpaceProtocolSession,
2142
- SpaceManager
2143
- };
2144
- //# sourceMappingURL=chunk-JQCCVDLT.mjs.map