@dxos/echo-pipeline 0.5.0 → 0.5.1-main.0ba1ecb

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 (60) hide show
  1. package/dist/lib/browser/{chunk-KMWJLYEQ.mjs → chunk-VQQD32DM.mjs} +18 -18
  2. package/dist/lib/browser/{chunk-KMWJLYEQ.mjs.map → chunk-VQQD32DM.mjs.map} +3 -3
  3. package/dist/lib/browser/index.mjs +471 -189
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +2 -8
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node/{chunk-YZA42CKA.cjs → chunk-P7L7ICAH.cjs} +21 -21
  9. package/dist/lib/node/{chunk-YZA42CKA.cjs.map → chunk-P7L7ICAH.cjs.map} +3 -3
  10. package/dist/lib/node/index.cjs +482 -207
  11. package/dist/lib/node/index.cjs.map +4 -4
  12. package/dist/lib/node/meta.json +1 -1
  13. package/dist/lib/node/testing/index.cjs +13 -18
  14. package/dist/lib/node/testing/index.cjs.map +4 -4
  15. package/dist/types/src/automerge/automerge-doc-loader.d.ts +3 -3
  16. package/dist/types/src/automerge/automerge-doc-loader.d.ts.map +1 -1
  17. package/dist/types/src/automerge/automerge-host.d.ts +15 -6
  18. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  19. package/dist/types/src/automerge/echo-network-adapter.d.ts +26 -0
  20. package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -0
  21. package/dist/types/src/automerge/echo-replicator.d.ts +43 -0
  22. package/dist/types/src/automerge/echo-replicator.d.ts.map +1 -0
  23. package/dist/types/src/automerge/index.d.ts +1 -2
  24. package/dist/types/src/automerge/index.d.ts.map +1 -1
  25. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +3 -2
  26. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -1
  27. package/dist/types/src/automerge/migrations.d.ts +1 -1
  28. package/dist/types/src/automerge/migrations.d.ts.map +1 -1
  29. package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
  30. package/dist/types/src/space/control-pipeline.d.ts +1 -1
  31. package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
  32. package/dist/types/src/testing/index.d.ts +0 -1
  33. package/dist/types/src/testing/index.d.ts.map +1 -1
  34. package/package.json +33 -30
  35. package/src/automerge/automerge-doc-loader.test.ts +1 -1
  36. package/src/automerge/automerge-doc-loader.ts +26 -16
  37. package/src/automerge/automerge-host.test.ts +33 -16
  38. package/src/automerge/automerge-host.ts +105 -21
  39. package/src/automerge/automerge-repo.test.ts +38 -6
  40. package/src/automerge/echo-network-adapter.ts +155 -0
  41. package/src/automerge/echo-replicator.ts +56 -0
  42. package/src/automerge/index.ts +1 -2
  43. package/src/automerge/leveldb-storage-adapter.ts +2 -2
  44. package/src/automerge/migrations.ts +1 -1
  45. package/src/automerge/storage-adapter.test.ts +1 -1
  46. package/src/pipeline/pipeline.ts +1 -0
  47. package/src/space/control-pipeline.ts +2 -2
  48. package/src/testing/index.ts +0 -1
  49. package/dist/types/src/automerge/level.test.d.ts +0 -2
  50. package/dist/types/src/automerge/level.test.d.ts.map +0 -1
  51. package/dist/types/src/automerge/reference.d.ts +0 -15
  52. package/dist/types/src/automerge/reference.d.ts.map +0 -1
  53. package/dist/types/src/automerge/types.d.ts +0 -73
  54. package/dist/types/src/automerge/types.d.ts.map +0 -1
  55. package/dist/types/src/testing/level.d.ts +0 -3
  56. package/dist/types/src/testing/level.d.ts.map +0 -1
  57. package/src/automerge/level.test.ts +0 -82
  58. package/src/automerge/reference.ts +0 -31
  59. package/src/automerge/types.ts +0 -86
  60. package/src/testing/level.ts +0 -11
@@ -18,79 +18,292 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var node_exports = {};
20
20
  __export(node_exports, {
21
- AuthExtension: () => import_chunk_YZA42CKA.AuthExtension,
22
- AuthStatus: () => import_chunk_YZA42CKA.AuthStatus,
21
+ AuthExtension: () => import_chunk_P7L7ICAH.AuthExtension,
22
+ AuthStatus: () => import_chunk_P7L7ICAH.AuthStatus,
23
23
  AutomergeDocumentLoaderImpl: () => AutomergeDocumentLoaderImpl,
24
24
  AutomergeHost: () => AutomergeHost,
25
25
  AutomergeStorageAdapter: () => AutomergeStorageAdapter,
26
- DataServiceImpl: () => import_chunk_YZA42CKA.DataServiceImpl,
26
+ DataServiceImpl: () => import_chunk_P7L7ICAH.DataServiceImpl,
27
27
  LevelDBStorageAdapter: () => LevelDBStorageAdapter,
28
28
  LocalHostNetworkAdapter: () => LocalHostNetworkAdapter,
29
- MOCK_AUTH_PROVIDER: () => import_chunk_YZA42CKA.MOCK_AUTH_PROVIDER,
30
- MOCK_AUTH_VERIFIER: () => import_chunk_YZA42CKA.MOCK_AUTH_VERIFIER,
29
+ MOCK_AUTH_PROVIDER: () => import_chunk_P7L7ICAH.MOCK_AUTH_PROVIDER,
30
+ MOCK_AUTH_VERIFIER: () => import_chunk_P7L7ICAH.MOCK_AUTH_VERIFIER,
31
31
  MeshNetworkAdapter: () => MeshNetworkAdapter,
32
- MetadataStore: () => import_chunk_YZA42CKA.MetadataStore,
33
- Pipeline: () => import_chunk_YZA42CKA.Pipeline,
34
- REFERENCE_TYPE_TAG: () => REFERENCE_TYPE_TAG,
35
- SnapshotManager: () => import_chunk_YZA42CKA.SnapshotManager,
36
- SnapshotStore: () => import_chunk_YZA42CKA.SnapshotStore,
37
- Space: () => import_chunk_YZA42CKA.Space,
38
- SpaceManager: () => import_chunk_YZA42CKA.SpaceManager,
39
- SpaceProtocol: () => import_chunk_YZA42CKA.SpaceProtocol,
40
- SpaceProtocolSession: () => import_chunk_YZA42CKA.SpaceProtocolSession,
41
- TimeframeClock: () => import_chunk_YZA42CKA.TimeframeClock,
42
- codec: () => import_chunk_YZA42CKA.codec,
43
- createMappedFeedWriter: () => import_chunk_YZA42CKA.createMappedFeedWriter,
44
- decodeReference: () => decodeReference,
45
- encodeReference: () => encodeReference,
32
+ MetadataStore: () => import_chunk_P7L7ICAH.MetadataStore,
33
+ Pipeline: () => import_chunk_P7L7ICAH.Pipeline,
34
+ SnapshotManager: () => import_chunk_P7L7ICAH.SnapshotManager,
35
+ SnapshotStore: () => import_chunk_P7L7ICAH.SnapshotStore,
36
+ Space: () => import_chunk_P7L7ICAH.Space,
37
+ SpaceManager: () => import_chunk_P7L7ICAH.SpaceManager,
38
+ SpaceProtocol: () => import_chunk_P7L7ICAH.SpaceProtocol,
39
+ SpaceProtocolSession: () => import_chunk_P7L7ICAH.SpaceProtocolSession,
40
+ TimeframeClock: () => import_chunk_P7L7ICAH.TimeframeClock,
41
+ codec: () => import_chunk_P7L7ICAH.codec,
42
+ createMappedFeedWriter: () => import_chunk_P7L7ICAH.createMappedFeedWriter,
46
43
  encodingOptions: () => encodingOptions,
47
44
  getSpaceKeyFromDoc: () => getSpaceKeyFromDoc,
48
- hasInvitationExpired: () => import_chunk_YZA42CKA.hasInvitationExpired,
49
- isEncodedReferenceObject: () => isEncodedReferenceObject,
50
- mapFeedIndexesToTimeframe: () => import_chunk_YZA42CKA.mapFeedIndexesToTimeframe,
51
- mapTimeframeToFeedIndexes: () => import_chunk_YZA42CKA.mapTimeframeToFeedIndexes,
52
- startAfter: () => import_chunk_YZA42CKA.startAfter,
53
- valueEncoding: () => import_chunk_YZA42CKA.valueEncoding
45
+ hasInvitationExpired: () => import_chunk_P7L7ICAH.hasInvitationExpired,
46
+ mapFeedIndexesToTimeframe: () => import_chunk_P7L7ICAH.mapFeedIndexesToTimeframe,
47
+ mapTimeframeToFeedIndexes: () => import_chunk_P7L7ICAH.mapTimeframeToFeedIndexes,
48
+ startAfter: () => import_chunk_P7L7ICAH.startAfter,
49
+ valueEncoding: () => import_chunk_P7L7ICAH.valueEncoding
54
50
  });
55
51
  module.exports = __toCommonJS(node_exports);
56
- var import_chunk_YZA42CKA = require("./chunk-YZA42CKA.cjs");
52
+ var import_chunk_P7L7ICAH = require("./chunk-P7L7ICAH.cjs");
57
53
  var import_async = require("@dxos/async");
58
54
  var import_automerge = require("@dxos/automerge/automerge");
59
55
  var import_automerge_repo = require("@dxos/automerge/automerge-repo");
60
56
  var import_context = require("@dxos/context");
57
+ var import_invariant = require("@dxos/invariant");
61
58
  var import_keys = require("@dxos/keys");
62
59
  var import_log = require("@dxos/log");
60
+ var import_protocols = require("@dxos/protocols");
63
61
  var import_tracing = require("@dxos/tracing");
64
62
  var import_util = require("@dxos/util");
65
- var import_context2 = require("@dxos/context");
66
63
  var import_async2 = require("@dxos/async");
67
64
  var import_automerge_repo2 = require("@dxos/automerge/automerge-repo");
68
- var import_codec_protobuf = require("@dxos/codec-protobuf");
69
- var import_invariant = require("@dxos/invariant");
70
- var import_async3 = require("@dxos/async");
71
- var import_automerge_repo3 = require("@dxos/automerge/automerge-repo");
65
+ var import_context2 = require("@dxos/context");
72
66
  var import_invariant2 = require("@dxos/invariant");
73
67
  var import_log2 = require("@dxos/log");
68
+ var import_context3 = require("@dxos/context");
69
+ var import_async3 = require("@dxos/async");
70
+ var import_automerge_repo3 = require("@dxos/automerge/automerge-repo");
71
+ var import_codec_protobuf = require("@dxos/codec-protobuf");
72
+ var import_invariant3 = require("@dxos/invariant");
73
+ var import_async4 = require("@dxos/async");
74
+ var import_automerge_repo4 = require("@dxos/automerge/automerge-repo");
75
+ var import_invariant4 = require("@dxos/invariant");
76
+ var import_log3 = require("@dxos/log");
74
77
  var import_teleport_extension_automerge_replicator = require("@dxos/teleport-extension-automerge-replicator");
75
78
  var import_automerge_repo_storage_indexeddb = require("@dxos/automerge/automerge-repo-storage-indexeddb");
76
- var import_log3 = require("@dxos/log");
79
+ var import_log4 = require("@dxos/log");
77
80
  var import_random_access_storage = require("@dxos/random-access-storage");
78
81
  var import_util2 = require("@dxos/util");
79
- var import_async4 = require("@dxos/async");
80
- var import_context3 = require("@dxos/context");
82
+ var import_async5 = require("@dxos/async");
83
+ var import_context4 = require("@dxos/context");
81
84
  var import_debug = require("@dxos/debug");
82
- var import_invariant3 = require("@dxos/invariant");
83
- var import_log4 = require("@dxos/log");
85
+ var import_invariant5 = require("@dxos/invariant");
86
+ var import_log5 = require("@dxos/log");
84
87
  var import_tracing2 = require("@dxos/tracing");
85
- var import_echo_schema = require("@dxos/echo-schema");
86
- var LevelDBStorageAdapter = class extends import_context2.Resource {
88
+ function _ts_decorate(decorators, target, key, desc) {
89
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
90
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
91
+ r = Reflect.decorate(decorators, target, key, desc);
92
+ else
93
+ for (var i = decorators.length - 1; i >= 0; i--)
94
+ if (d = decorators[i])
95
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
96
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
97
+ }
98
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts";
99
+ var EchoNetworkAdapter = class extends import_automerge_repo2.NetworkAdapter {
100
+ constructor() {
101
+ super(...arguments);
102
+ this._replicators = /* @__PURE__ */ new Set();
103
+ this._connections = /* @__PURE__ */ new Map();
104
+ this._lifecycleState = import_context2.LifecycleState.CLOSED;
105
+ this._connected = new import_async2.Trigger();
106
+ }
107
+ connect(peerId, peerMetadata) {
108
+ this.peerId = peerId;
109
+ this.peerMetadata = peerMetadata;
110
+ this._connected.wake();
111
+ }
112
+ send(message) {
113
+ const connectionEntry = this._connections.get(message.targetId);
114
+ if (!connectionEntry) {
115
+ throw new Error("Connection not found.");
116
+ }
117
+ connectionEntry.writer.write(message).catch((err) => {
118
+ if (connectionEntry.isOpen) {
119
+ import_log2.log.catch(err, void 0, {
120
+ F: __dxlog_file,
121
+ L: 40,
122
+ S: this,
123
+ C: (f, a) => f(...a)
124
+ });
125
+ }
126
+ });
127
+ }
128
+ disconnect() {
129
+ }
130
+ async open() {
131
+ (0, import_invariant2.invariant)(this._lifecycleState === import_context2.LifecycleState.CLOSED, void 0, {
132
+ F: __dxlog_file,
133
+ L: 51,
134
+ S: this,
135
+ A: [
136
+ "this._lifecycleState === LifecycleState.CLOSED",
137
+ ""
138
+ ]
139
+ });
140
+ this._lifecycleState = import_context2.LifecycleState.OPEN;
141
+ this.emit("ready", {
142
+ network: this
143
+ });
144
+ }
145
+ async close() {
146
+ (0, import_invariant2.invariant)(this._lifecycleState === import_context2.LifecycleState.OPEN, void 0, {
147
+ F: __dxlog_file,
148
+ L: 61,
149
+ S: this,
150
+ A: [
151
+ "this._lifecycleState === LifecycleState.OPEN",
152
+ ""
153
+ ]
154
+ });
155
+ for (const replicator of this._replicators) {
156
+ await replicator.disconnect();
157
+ }
158
+ this._replicators.clear();
159
+ this._lifecycleState = import_context2.LifecycleState.CLOSED;
160
+ }
161
+ async whenConnected() {
162
+ await this._connected.wait({
163
+ timeout: 1e4
164
+ });
165
+ }
166
+ async addReplicator(replicator) {
167
+ (0, import_invariant2.invariant)(this.peerId, void 0, {
168
+ F: __dxlog_file,
169
+ L: 77,
170
+ S: this,
171
+ A: [
172
+ "this.peerId",
173
+ ""
174
+ ]
175
+ });
176
+ (0, import_invariant2.invariant)(!this._replicators.has(replicator), void 0, {
177
+ F: __dxlog_file,
178
+ L: 78,
179
+ S: this,
180
+ A: [
181
+ "!this._replicators.has(replicator)",
182
+ ""
183
+ ]
184
+ });
185
+ await replicator.connect({
186
+ peerId: this.peerId,
187
+ onConnectionOpen: this._onConnectionOpen.bind(this),
188
+ onConnectionClosed: this._onConnectionClosed.bind(this)
189
+ });
190
+ }
191
+ async removeReplicator(replicator) {
192
+ (0, import_invariant2.invariant)(this._replicators.has(replicator), void 0, {
193
+ F: __dxlog_file,
194
+ L: 89,
195
+ S: this,
196
+ A: [
197
+ "this._replicators.has(replicator)",
198
+ ""
199
+ ]
200
+ });
201
+ await replicator.disconnect();
202
+ }
203
+ async shouldAdvertize(peerId, params) {
204
+ const connection = this._connections.get(peerId);
205
+ if (!connection) {
206
+ return false;
207
+ }
208
+ return connection.connection.shouldAdvertize(params);
209
+ }
210
+ _onConnectionOpen(connection) {
211
+ (0, import_invariant2.invariant)(!this._connections.has(connection.peerId), void 0, {
212
+ F: __dxlog_file,
213
+ L: 103,
214
+ S: this,
215
+ A: [
216
+ "!this._connections.has(connection.peerId as PeerId)",
217
+ ""
218
+ ]
219
+ });
220
+ const reader = connection.readable.getReader();
221
+ const writer = connection.writable.getWriter();
222
+ const connectionEntry = {
223
+ connection,
224
+ reader,
225
+ writer,
226
+ isOpen: true
227
+ };
228
+ this._connections.set(connection.peerId, connectionEntry);
229
+ queueMicrotask(async () => {
230
+ try {
231
+ while (true) {
232
+ const { done, value } = await reader.read();
233
+ if (done) {
234
+ break;
235
+ }
236
+ this.emit("message", value);
237
+ }
238
+ } catch (err) {
239
+ if (connectionEntry.isOpen) {
240
+ import_log2.log.catch(err, void 0, {
241
+ F: __dxlog_file,
242
+ L: 122,
243
+ S: this,
244
+ C: (f, a) => f(...a)
245
+ });
246
+ }
247
+ }
248
+ });
249
+ this.emit("peer-candidate", {
250
+ peerId: connection.peerId,
251
+ peerMetadata: {
252
+ // TODO(dmaretskyi): Refactor this.
253
+ dxos_peerSource: "EchoNetworkAdapter"
254
+ }
255
+ });
256
+ }
257
+ _onConnectionClosed(connection) {
258
+ const entry = this._connections.get(connection.peerId);
259
+ (0, import_invariant2.invariant)(entry, void 0, {
260
+ F: __dxlog_file,
261
+ L: 138,
262
+ S: this,
263
+ A: [
264
+ "entry",
265
+ ""
266
+ ]
267
+ });
268
+ entry.isOpen = false;
269
+ this.emit("peer-disconnected", {
270
+ peerId: connection.peerId
271
+ });
272
+ void entry.reader.cancel().catch((err) => import_log2.log.catch(err, void 0, {
273
+ F: __dxlog_file,
274
+ L: 143,
275
+ S: this,
276
+ C: (f, a) => f(...a)
277
+ }));
278
+ void entry.writer.abort().catch((err) => import_log2.log.catch(err, void 0, {
279
+ F: __dxlog_file,
280
+ L: 144,
281
+ S: this,
282
+ C: (f, a) => f(...a)
283
+ }));
284
+ this._connections.delete(connection.peerId);
285
+ }
286
+ };
287
+ _ts_decorate([
288
+ import_async2.synchronized
289
+ ], EchoNetworkAdapter.prototype, "open", null);
290
+ _ts_decorate([
291
+ import_async2.synchronized
292
+ ], EchoNetworkAdapter.prototype, "close", null);
293
+ _ts_decorate([
294
+ import_async2.synchronized
295
+ ], EchoNetworkAdapter.prototype, "addReplicator", null);
296
+ _ts_decorate([
297
+ import_async2.synchronized
298
+ ], EchoNetworkAdapter.prototype, "removeReplicator", null);
299
+ var LevelDBStorageAdapter = class extends import_context3.Resource {
87
300
  constructor(_params) {
88
301
  super();
89
302
  this._params = _params;
90
303
  }
91
304
  async load(keyArray) {
92
305
  try {
93
- if (this._lifecycleState !== import_context2.LifecycleState.OPEN) {
306
+ if (this._lifecycleState !== import_context3.LifecycleState.OPEN) {
94
307
  return void 0;
95
308
  }
96
309
  return await this._params.db.get(keyArray, {
@@ -104,7 +317,7 @@ var LevelDBStorageAdapter = class extends import_context2.Resource {
104
317
  }
105
318
  }
106
319
  async save(keyArray, binary) {
107
- if (this._lifecycleState !== import_context2.LifecycleState.OPEN) {
320
+ if (this._lifecycleState !== import_context3.LifecycleState.OPEN) {
108
321
  return void 0;
109
322
  }
110
323
  const batch = this._params.db.batch();
@@ -119,7 +332,7 @@ var LevelDBStorageAdapter = class extends import_context2.Resource {
119
332
  await this._params.callbacks?.afterSave?.(keyArray);
120
333
  }
121
334
  async remove(keyArray) {
122
- if (this._lifecycleState !== import_context2.LifecycleState.OPEN) {
335
+ if (this._lifecycleState !== import_context3.LifecycleState.OPEN) {
123
336
  return void 0;
124
337
  }
125
338
  await this._params.db.del(keyArray, {
@@ -127,7 +340,7 @@ var LevelDBStorageAdapter = class extends import_context2.Resource {
127
340
  });
128
341
  }
129
342
  async loadRange(keyPrefix) {
130
- if (this._lifecycleState !== import_context2.LifecycleState.OPEN) {
343
+ if (this._lifecycleState !== import_context3.LifecycleState.OPEN) {
131
344
  return [];
132
345
  }
133
346
  const result = [];
@@ -147,7 +360,7 @@ var LevelDBStorageAdapter = class extends import_context2.Resource {
147
360
  return result;
148
361
  }
149
362
  async removeRange(keyPrefix) {
150
- if (this._lifecycleState !== import_context2.LifecycleState.OPEN) {
363
+ if (this._lifecycleState !== import_context3.LifecycleState.OPEN) {
151
364
  return void 0;
152
365
  }
153
366
  const batch = this._params.db.batch();
@@ -168,19 +381,20 @@ var LevelDBStorageAdapter = class extends import_context2.Resource {
168
381
  };
169
382
  var keyEncoder = {
170
383
  encode: (key) => Buffer.from(key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-")),
171
- decode: (key) => Buffer.from(key).toString().split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"))
384
+ decode: (key) => Buffer.from(key).toString().split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%")),
385
+ format: "buffer"
172
386
  };
173
387
  var encodingOptions = {
174
388
  keyEncoding: keyEncoder,
175
389
  valueEncoding: "buffer"
176
390
  };
177
391
  var isLevelDbNotFoundError = (err) => err.code === "LEVEL_NOT_FOUND";
178
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts";
179
- var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapter {
392
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts";
393
+ var LocalHostNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
180
394
  constructor() {
181
395
  super(...arguments);
182
396
  this._peers = /* @__PURE__ */ new Map();
183
- this._connected = new import_async2.Trigger();
397
+ this._connected = new import_async3.Trigger();
184
398
  this._isConnected = false;
185
399
  }
186
400
  /**
@@ -203,8 +417,8 @@ var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapte
203
417
  }
204
418
  send(message) {
205
419
  const peer = this._peers.get(message.targetId);
206
- (0, import_invariant.invariant)(peer, "Peer not found.", {
207
- F: __dxlog_file,
420
+ (0, import_invariant3.invariant)(peer, "Peer not found.", {
421
+ F: __dxlog_file2,
208
422
  L: 51,
209
423
  S: this,
210
424
  A: [
@@ -228,8 +442,8 @@ var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapte
228
442
  syncRepo({ id, syncMessage }) {
229
443
  const peerId = this._getPeerId(id);
230
444
  return new import_codec_protobuf.Stream(({ next, close }) => {
231
- (0, import_invariant.invariant)(!this._peers.has(peerId), "Peer already connected.", {
232
- F: __dxlog_file,
445
+ (0, import_invariant3.invariant)(!this._peers.has(peerId), "Peer already connected.", {
446
+ F: __dxlog_file2,
233
447
  L: 73,
234
448
  S: this,
235
449
  A: [
@@ -241,7 +455,7 @@ var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapte
241
455
  connected: true,
242
456
  send: (message) => {
243
457
  next({
244
- syncMessage: import_automerge_repo2.cbor.encode(message)
458
+ syncMessage: import_automerge_repo3.cbor.encode(message)
245
459
  });
246
460
  },
247
461
  disconnect: () => {
@@ -252,8 +466,8 @@ var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapte
252
466
  });
253
467
  }
254
468
  });
255
- (0, import_invariant.invariant)(this._isConnected, void 0, {
256
- F: __dxlog_file,
469
+ (0, import_invariant3.invariant)(this._isConnected, void 0, {
470
+ F: __dxlog_file2,
257
471
  L: 90,
258
472
  S: this,
259
473
  A: [
@@ -268,8 +482,8 @@ var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapte
268
482
  });
269
483
  }
270
484
  async sendSyncMessage({ id, syncMessage }) {
271
- (0, import_invariant.invariant)(this._isConnected, void 0, {
272
- F: __dxlog_file,
485
+ (0, import_invariant3.invariant)(this._isConnected, void 0, {
486
+ F: __dxlog_file2,
273
487
  L: 99,
274
488
  S: this,
275
489
  A: [
@@ -277,12 +491,12 @@ var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapte
277
491
  ""
278
492
  ]
279
493
  });
280
- const message = import_automerge_repo2.cbor.decode(syncMessage);
494
+ const message = import_automerge_repo3.cbor.decode(syncMessage);
281
495
  this.emit("message", message);
282
496
  }
283
497
  async getHostInfo() {
284
- (0, import_invariant.invariant)(this._isConnected, void 0, {
285
- F: __dxlog_file,
498
+ (0, import_invariant3.invariant)(this._isConnected, void 0, {
499
+ F: __dxlog_file2,
286
500
  L: 105,
287
501
  S: this,
288
502
  A: [
@@ -290,8 +504,8 @@ var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapte
290
504
  ""
291
505
  ]
292
506
  });
293
- (0, import_invariant.invariant)(this.peerId, "Peer id not set.", {
294
- F: __dxlog_file,
507
+ (0, import_invariant3.invariant)(this.peerId, "Peer id not set.", {
508
+ F: __dxlog_file2,
295
509
  L: 106,
296
510
  S: this,
297
511
  A: [
@@ -307,12 +521,12 @@ var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapte
307
521
  return id;
308
522
  }
309
523
  };
310
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts";
311
- var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
524
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts";
525
+ var MeshNetworkAdapter = class extends import_automerge_repo4.NetworkAdapter {
312
526
  constructor() {
313
527
  super(...arguments);
314
528
  this._extensions = /* @__PURE__ */ new Map();
315
- this._connected = new import_async3.Trigger();
529
+ this._connected = new import_async4.Trigger();
316
530
  }
317
531
  /**
318
532
  * Emits `ready` event. That signals to `Repo` that it can start using the adapter.
@@ -329,8 +543,8 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
329
543
  send(message) {
330
544
  const receiverId = message.targetId;
331
545
  const extension = this._extensions.get(receiverId);
332
- (0, import_invariant2.invariant)(extension, "Extension not found.", {
333
- F: __dxlog_file2,
546
+ (0, import_invariant4.invariant)(extension, "Extension not found.", {
547
+ F: __dxlog_file3,
334
548
  L: 38,
335
549
  S: this,
336
550
  A: [
@@ -339,9 +553,9 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
339
553
  ]
340
554
  });
341
555
  extension.sendSyncMessage({
342
- payload: import_automerge_repo3.cbor.encode(message)
343
- }).catch((err) => import_log2.log.catch(err, void 0, {
344
- F: __dxlog_file2,
556
+ payload: import_automerge_repo4.cbor.encode(message)
557
+ }).catch((err) => import_log3.log.catch(err, void 0, {
558
+ F: __dxlog_file3,
345
559
  L: 39,
346
560
  S: this,
347
561
  C: (f, a) => f(...a)
@@ -350,8 +564,8 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
350
564
  disconnect() {
351
565
  }
352
566
  createExtension() {
353
- (0, import_invariant2.invariant)(this.peerId, "Peer id not set.", {
354
- F: __dxlog_file2,
567
+ (0, import_invariant4.invariant)(this.peerId, "Peer id not set.", {
568
+ F: __dxlog_file3,
355
569
  L: 47,
356
570
  S: this,
357
571
  A: [
@@ -365,12 +579,12 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
365
579
  }, {
366
580
  onStartReplication: async (info, remotePeerId) => {
367
581
  await this._connected.wait();
368
- (0, import_log2.log)("onStartReplication", {
582
+ (0, import_log3.log)("onStartReplication", {
369
583
  id: info.id,
370
584
  thisPeerId: this.peerId,
371
585
  remotePeerId: remotePeerId.toHex()
372
586
  }, {
373
- F: __dxlog_file2,
587
+ F: __dxlog_file3,
374
588
  L: 70,
375
589
  S: this,
376
590
  C: (f, a) => f(...a)
@@ -378,12 +592,12 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
378
592
  if (!this._extensions.has(info.id)) {
379
593
  peerInfo = info;
380
594
  this._extensions.set(info.id, extension);
381
- (0, import_log2.log)("peer-candidate", {
595
+ (0, import_log3.log)("peer-candidate", {
382
596
  id: info.id,
383
597
  thisPeerId: this.peerId,
384
598
  remotePeerId: remotePeerId.toHex()
385
599
  }, {
386
- F: __dxlog_file2,
600
+ F: __dxlog_file3,
387
601
  L: 76,
388
602
  S: this,
389
603
  C: (f, a) => f(...a)
@@ -401,7 +615,7 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
401
615
  if (!peerInfo) {
402
616
  return;
403
617
  }
404
- const message = import_automerge_repo3.cbor.decode(payload);
618
+ const message = import_automerge_repo4.cbor.decode(payload);
405
619
  this.emit("message", message);
406
620
  },
407
621
  onClose: async () => {
@@ -490,7 +704,7 @@ var AutomergeStorageAdapter = class {
490
704
  return filename.split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"));
491
705
  }
492
706
  };
493
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/migrations.ts";
707
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/migrations.ts";
494
708
  var levelMigration = async ({ db, directory }) => {
495
709
  const isNewLevel = !await db.iterator({
496
710
  ...encodingOptions
@@ -504,10 +718,10 @@ var levelMigration = async ({ db, directory }) => {
504
718
  return;
505
719
  }
506
720
  const batch = db.batch();
507
- import_log3.log.info("found chunks on old storage adapter", {
721
+ import_log4.log.info("found chunks on old storage adapter", {
508
722
  chunks: chunks.length
509
723
  }, {
510
- F: __dxlog_file3,
724
+ F: __dxlog_file4,
511
725
  L: 36,
512
726
  S: void 0,
513
727
  C: (f, a) => f(...a)
@@ -519,7 +733,7 @@ var levelMigration = async ({ db, directory }) => {
519
733
  }
520
734
  await batch.write();
521
735
  };
522
- function _ts_decorate(decorators, target, key, desc) {
736
+ function _ts_decorate2(decorators, target, key, desc) {
523
737
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
524
738
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
525
739
  r = Reflect.decorate(decorators, target, key, desc);
@@ -529,15 +743,16 @@ function _ts_decorate(decorators, target, key, desc) {
529
743
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
530
744
  return c > 3 && r && Object.defineProperty(target, key, r), r;
531
745
  }
532
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
746
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
533
747
  var AutomergeHost = class {
534
- constructor({ directory, db, storageCallbacks }) {
748
+ constructor({ directory, db, indexMetadataStore }) {
535
749
  this._ctx = new import_context.Context();
750
+ this._echoNetworkAdapter = new EchoNetworkAdapter();
536
751
  this._authorizedDevices = new import_util.ComplexMap(import_keys.PublicKey.hash);
537
752
  this._requestedDocs = /* @__PURE__ */ new Set();
538
753
  this._directory = directory;
539
754
  this._db = db;
540
- this._storageCallbacks = storageCallbacks;
755
+ this._indexMetadataStore = indexMetadataStore;
541
756
  }
542
757
  async open() {
543
758
  this._directory && await levelMigration({
@@ -546,7 +761,10 @@ var AutomergeHost = class {
546
761
  });
547
762
  this._storage = new LevelDBStorageAdapter({
548
763
  db: this._db,
549
- callbacks: this._storageCallbacks
764
+ callbacks: {
765
+ beforeSave: async (params) => this._beforeSave(params),
766
+ afterSave: async () => this._afterSave()
767
+ }
550
768
  });
551
769
  await this._storage.open?.();
552
770
  this._peerId = `host-${import_keys.PublicKey.random().toHex()}`;
@@ -556,7 +774,8 @@ var AutomergeHost = class {
556
774
  peerId: this._peerId,
557
775
  network: [
558
776
  this._clientNetwork,
559
- this._meshNetwork
777
+ this._meshNetwork,
778
+ this._echoNetworkAdapter
560
779
  ],
561
780
  storage: this._storage,
562
781
  // TODO(dmaretskyi): Share based on HALO permissions and space affinity.
@@ -568,6 +787,12 @@ var AutomergeHost = class {
568
787
  if (!documentId) {
569
788
  return false;
570
789
  }
790
+ const peerMetadata = this.repo.peerMetadataByPeerId[peerId];
791
+ if (peerMetadata?.dxos_peerSource === "EchoNetworkAdapter") {
792
+ return this._echoNetworkAdapter.shouldAdvertize(peerId, {
793
+ documentId
794
+ });
795
+ }
571
796
  const doc = this._repo.handles[documentId]?.docSync();
572
797
  if (!doc) {
573
798
  const isRequested = this._requestedDocs.has(`automerge:${documentId}`);
@@ -576,8 +801,8 @@ var AutomergeHost = class {
576
801
  documentId,
577
802
  isRequested
578
803
  }, {
579
- F: __dxlog_file4,
580
- L: 100,
804
+ F: __dxlog_file5,
805
+ L: 124,
581
806
  S: this,
582
807
  C: (f, a) => f(...a)
583
808
  });
@@ -590,22 +815,22 @@ var AutomergeHost = class {
590
815
  peerId,
591
816
  documentId
592
817
  }, {
593
- F: __dxlog_file4,
594
- L: 107,
818
+ F: __dxlog_file5,
819
+ L: 131,
595
820
  S: this,
596
821
  C: (f, a) => f(...a)
597
822
  });
598
823
  return false;
599
824
  }
600
825
  const authorizedDevices = this._authorizedDevices.get(import_keys.PublicKey.from(spaceKey));
601
- const deviceKeyHex = this.repo.peerMetadataByPeerId[peerId]?.dxos_deviceKey;
826
+ const deviceKeyHex = peerMetadata?.dxos_deviceKey;
602
827
  if (!deviceKeyHex) {
603
828
  (0, import_log.log)("device key not found for share policy check", {
604
829
  peerId,
605
830
  documentId
606
831
  }, {
607
- F: __dxlog_file4,
608
- L: 116,
832
+ F: __dxlog_file5,
833
+ L: 140,
609
834
  S: this,
610
835
  C: (f, a) => f(...a)
611
836
  });
@@ -621,16 +846,16 @@ var AutomergeHost = class {
621
846
  spaceKey,
622
847
  isAuthorized
623
848
  }, {
624
- F: __dxlog_file4,
625
- L: 122,
849
+ F: __dxlog_file5,
850
+ L: 146,
626
851
  S: this,
627
852
  C: (f, a) => f(...a)
628
853
  });
629
854
  return isAuthorized;
630
855
  } catch (err) {
631
856
  import_log.log.catch(err, void 0, {
632
- F: __dxlog_file4,
633
- L: 132,
857
+ F: __dxlog_file5,
858
+ L: 156,
634
859
  S: this,
635
860
  C: (f, a) => f(...a)
636
861
  });
@@ -640,16 +865,52 @@ var AutomergeHost = class {
640
865
  });
641
866
  this._clientNetwork.ready();
642
867
  this._meshNetwork.ready();
868
+ await this._echoNetworkAdapter.open();
643
869
  await this._clientNetwork.whenConnected();
870
+ await this._echoNetworkAdapter.whenConnected();
644
871
  }
645
872
  async close() {
646
873
  await this._storage.close?.();
647
874
  await this._clientNetwork.close();
875
+ await this._echoNetworkAdapter.close();
648
876
  await this._ctx.dispose();
649
877
  }
650
878
  get repo() {
651
879
  return this._repo;
652
880
  }
881
+ async addReplicator(replicator) {
882
+ await this._echoNetworkAdapter.addReplicator(replicator);
883
+ }
884
+ async removeReplicator(replicator) {
885
+ await this._echoNetworkAdapter.removeReplicator(replicator);
886
+ }
887
+ async _beforeSave({ path, batch }) {
888
+ const handle = this._repo.handles[path[0]];
889
+ if (!handle) {
890
+ return;
891
+ }
892
+ const doc = handle.docSync();
893
+ if (!doc) {
894
+ return;
895
+ }
896
+ const lastAvailableHash = (0, import_automerge.getHeads)(doc);
897
+ const objectIds = Object.keys(doc.objects ?? {});
898
+ const encodedIds = objectIds.map((objectId) => import_protocols.idCodec.encode({
899
+ documentId: handle.documentId,
900
+ objectId
901
+ }));
902
+ const idToLastHash = new Map(encodedIds.map((id) => [
903
+ id,
904
+ lastAvailableHash
905
+ ]));
906
+ this._indexMetadataStore.markDirty(idToLastHash, batch);
907
+ }
908
+ /**
909
+ * Called by AutomergeStorageAdapter after levelDB batch commit.
910
+ */
911
+ async _afterSave() {
912
+ this._indexMetadataStore.notifyMarkedDirty();
913
+ }
653
914
  _automergeDocs() {
654
915
  return (0, import_util.mapValues)(this._repo.handles, (handle) => ({
655
916
  state: handle.state,
@@ -678,21 +939,21 @@ var AutomergeHost = class {
678
939
  //
679
940
  // Methods for client-services.
680
941
  //
681
- async flush({ documentIds }) {
682
- await Promise.all(documentIds?.map((id) => this._repo.find(id).whenReady()) ?? []);
683
- try {
684
- await (0, import_async.asyncTimeout)(this._repo.flush(documentIds), 500);
685
- } catch (err) {
686
- import_log.log.warn("flush error", {
687
- documentIds,
688
- err
689
- }, {
690
- F: __dxlog_file4,
691
- L: 196,
942
+ async flush({ states }) {
943
+ await Promise.all(states?.map(async ({ heads, documentId }) => {
944
+ (0, import_invariant.invariant)(heads, "heads are required for flush", {
945
+ F: __dxlog_file5,
946
+ L: 252,
692
947
  S: this,
693
- C: (f, a) => f(...a)
948
+ A: [
949
+ "heads",
950
+ "'heads are required for flush'"
951
+ ]
694
952
  });
695
- }
953
+ const handle = this.repo.handles[documentId] ?? this._repo.find(documentId);
954
+ await waitForHeads(handle, heads);
955
+ }) ?? []);
956
+ await this._repo.flush(states?.map(({ documentId }) => documentId));
696
957
  }
697
958
  syncRepo(request) {
698
959
  return this._clientNetwork.syncRepo(request);
@@ -714,33 +975,33 @@ var AutomergeHost = class {
714
975
  spaceKey,
715
976
  deviceKey
716
977
  }, {
717
- F: __dxlog_file4,
718
- L: 221,
978
+ F: __dxlog_file5,
979
+ L: 282,
719
980
  S: this,
720
981
  C: (f, a) => f(...a)
721
982
  });
722
983
  (0, import_util.defaultMap)(this._authorizedDevices, spaceKey, () => new import_util.ComplexSet(import_keys.PublicKey.hash)).add(deviceKey);
723
984
  }
724
985
  };
725
- _ts_decorate([
986
+ _ts_decorate2([
726
987
  import_tracing.trace.info()
727
988
  ], AutomergeHost.prototype, "_peerId", void 0);
728
- _ts_decorate([
989
+ _ts_decorate2([
729
990
  import_tracing.trace.info({
730
991
  depth: null
731
992
  })
732
993
  ], AutomergeHost.prototype, "_automergeDocs", null);
733
- _ts_decorate([
994
+ _ts_decorate2([
734
995
  import_tracing.trace.info({
735
996
  depth: null
736
997
  })
737
998
  ], AutomergeHost.prototype, "_automergePeers", null);
738
- _ts_decorate([
999
+ _ts_decorate2([
739
1000
  import_tracing.trace.span({
740
1001
  showInBrowserTimeline: true
741
1002
  })
742
1003
  ], AutomergeHost.prototype, "flush", null);
743
- AutomergeHost = _ts_decorate([
1004
+ AutomergeHost = _ts_decorate2([
744
1005
  import_tracing.trace.resource()
745
1006
  ], AutomergeHost);
746
1007
  var getSpaceKeyFromDoc = (doc) => {
@@ -750,7 +1011,25 @@ var getSpaceKeyFromDoc = (doc) => {
750
1011
  }
751
1012
  return String(rawSpaceKey);
752
1013
  };
753
- function _ts_decorate2(decorators, target, key, desc) {
1014
+ var waitForHeads = async (handle, heads) => {
1015
+ await handle.whenReady();
1016
+ const unavailableHeads = new Set(heads);
1017
+ await import_async.Event.wrap(handle, "change").waitForCondition(() => {
1018
+ for (const changeHash of unavailableHeads.values()) {
1019
+ if (changeIsPresentInDoc(handle.docSync(), changeHash)) {
1020
+ unavailableHeads.delete(changeHash);
1021
+ }
1022
+ }
1023
+ if (unavailableHeads.size === 0) {
1024
+ return true;
1025
+ }
1026
+ return false;
1027
+ });
1028
+ };
1029
+ var changeIsPresentInDoc = (doc, changeHash) => {
1030
+ return !!(0, import_automerge.getBackend)(doc).getChangeByHash(changeHash);
1031
+ };
1032
+ function _ts_decorate3(decorators, target, key, desc) {
754
1033
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
755
1034
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
756
1035
  r = Reflect.decorate(decorators, target, key, desc);
@@ -760,7 +1039,7 @@ function _ts_decorate2(decorators, target, key, desc) {
760
1039
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
761
1040
  return c > 3 && r && Object.defineProperty(target, key, r), r;
762
1041
  }
763
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
1042
+ var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
764
1043
  var AutomergeDocumentLoaderImpl = class {
765
1044
  constructor(_spaceKey, _repo) {
766
1045
  this._spaceKey = _spaceKey;
@@ -768,23 +1047,24 @@ var AutomergeDocumentLoaderImpl = class {
768
1047
  this._spaceRootDocHandle = null;
769
1048
  this._objectDocumentHandles = /* @__PURE__ */ new Map();
770
1049
  this._objectsPendingDocumentLoad = /* @__PURE__ */ new Set();
771
- this.onObjectDocumentLoaded = new import_async4.Event();
1050
+ this.onObjectDocumentLoaded = new import_async5.Event();
772
1051
  }
773
1052
  getAllHandles() {
774
- return [
1053
+ return this._spaceRootDocHandle != null ? [
1054
+ this._spaceRootDocHandle,
775
1055
  ...new Set(this._objectDocumentHandles.values())
776
- ];
1056
+ ] : [];
777
1057
  }
778
1058
  async loadSpaceRootDocHandle(ctx, spaceState) {
779
1059
  if (this._spaceRootDocHandle != null) {
780
1060
  return;
781
1061
  }
782
1062
  if (!spaceState.rootUrl) {
783
- import_log4.log.error("Database opened with no rootUrl", {
1063
+ import_log5.log.error("Database opened with no rootUrl", {
784
1064
  spaceKey: this._spaceKey
785
1065
  }, {
786
- F: __dxlog_file5,
787
- L: 69,
1066
+ F: __dxlog_file6,
1067
+ L: 70,
788
1068
  S: this,
789
1069
  C: (f, a) => f(...a)
790
1070
  });
@@ -792,9 +1072,9 @@ var AutomergeDocumentLoaderImpl = class {
792
1072
  } else {
793
1073
  const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);
794
1074
  const doc = existingDocHandle.docSync();
795
- (0, import_invariant3.invariant)(doc, void 0, {
796
- F: __dxlog_file5,
797
- L: 74,
1075
+ (0, import_invariant5.invariant)(doc, void 0, {
1076
+ F: __dxlog_file6,
1077
+ L: 75,
798
1078
  S: this,
799
1079
  A: [
800
1080
  "doc",
@@ -807,45 +1087,54 @@ var AutomergeDocumentLoaderImpl = class {
807
1087
  this._spaceRootDocHandle = existingDocHandle;
808
1088
  }
809
1089
  }
810
- loadObjectDocument(objectId) {
811
- (0, import_invariant3.invariant)(this._spaceRootDocHandle, void 0, {
812
- F: __dxlog_file5,
813
- L: 83,
814
- S: this,
815
- A: [
816
- "this._spaceRootDocHandle",
817
- ""
818
- ]
819
- });
820
- if (this._objectDocumentHandles.has(objectId) || this._objectsPendingDocumentLoad.has(objectId)) {
821
- return;
822
- }
823
- const spaceRootDoc = this._spaceRootDocHandle.docSync();
824
- (0, import_invariant3.invariant)(spaceRootDoc, void 0, {
825
- F: __dxlog_file5,
826
- L: 88,
827
- S: this,
828
- A: [
829
- "spaceRootDoc",
830
- ""
831
- ]
832
- });
833
- const documentUrl = (spaceRootDoc.links ?? {})[objectId];
834
- if (documentUrl == null) {
835
- this._objectsPendingDocumentLoad.add(objectId);
836
- import_log4.log.info("loading delayed until object links are initialized", {
837
- objectId
838
- }, {
839
- F: __dxlog_file5,
840
- L: 92,
1090
+ loadObjectDocument(objectIdOrMany) {
1091
+ const objectIds = Array.isArray(objectIdOrMany) ? objectIdOrMany : [
1092
+ objectIdOrMany
1093
+ ];
1094
+ let hasUrlsToLoad = false;
1095
+ const urlsToLoad = {};
1096
+ for (const objectId of objectIds) {
1097
+ (0, import_invariant5.invariant)(this._spaceRootDocHandle, void 0, {
1098
+ F: __dxlog_file6,
1099
+ L: 88,
841
1100
  S: this,
842
- C: (f, a) => f(...a)
1101
+ A: [
1102
+ "this._spaceRootDocHandle",
1103
+ ""
1104
+ ]
843
1105
  });
844
- return;
1106
+ if (this._objectDocumentHandles.has(objectId) || this._objectsPendingDocumentLoad.has(objectId)) {
1107
+ continue;
1108
+ }
1109
+ const spaceRootDoc = this._spaceRootDocHandle.docSync();
1110
+ (0, import_invariant5.invariant)(spaceRootDoc, void 0, {
1111
+ F: __dxlog_file6,
1112
+ L: 93,
1113
+ S: this,
1114
+ A: [
1115
+ "spaceRootDoc",
1116
+ ""
1117
+ ]
1118
+ });
1119
+ const documentUrl = (spaceRootDoc.links ?? {})[objectId];
1120
+ if (documentUrl == null) {
1121
+ this._objectsPendingDocumentLoad.add(objectId);
1122
+ import_log5.log.info("loading delayed until object links are initialized", {
1123
+ objectId
1124
+ }, {
1125
+ F: __dxlog_file6,
1126
+ L: 97,
1127
+ S: this,
1128
+ C: (f, a) => f(...a)
1129
+ });
1130
+ } else {
1131
+ urlsToLoad[objectId] = documentUrl;
1132
+ hasUrlsToLoad = true;
1133
+ }
1134
+ }
1135
+ if (hasUrlsToLoad) {
1136
+ this._loadLinkedObjects(urlsToLoad);
845
1137
  }
846
- this._loadLinkedObjects({
847
- [objectId]: documentUrl
848
- });
849
1138
  }
850
1139
  onObjectLinksUpdated(links) {
851
1140
  if (!links) {
@@ -856,9 +1145,9 @@ var AutomergeDocumentLoaderImpl = class {
856
1145
  linksAwaitingLoad.forEach(([objectId]) => this._objectsPendingDocumentLoad.delete(objectId));
857
1146
  }
858
1147
  getSpaceRootDocHandle() {
859
- (0, import_invariant3.invariant)(this._spaceRootDocHandle, void 0, {
860
- F: __dxlog_file5,
861
- L: 110,
1148
+ (0, import_invariant5.invariant)(this._spaceRootDocHandle, void 0, {
1149
+ F: __dxlog_file6,
1150
+ L: 120,
862
1151
  S: this,
863
1152
  A: [
864
1153
  "this._spaceRootDocHandle",
@@ -868,9 +1157,9 @@ var AutomergeDocumentLoaderImpl = class {
868
1157
  return this._spaceRootDocHandle;
869
1158
  }
870
1159
  createDocumentForObject(objectId) {
871
- (0, import_invariant3.invariant)(this._spaceRootDocHandle, void 0, {
872
- F: __dxlog_file5,
873
- L: 115,
1160
+ (0, import_invariant5.invariant)(this._spaceRootDocHandle, void 0, {
1161
+ F: __dxlog_file6,
1162
+ L: 125,
874
1163
  S: this,
875
1164
  A: [
876
1165
  "this._spaceRootDocHandle",
@@ -908,30 +1197,30 @@ var AutomergeDocumentLoaderImpl = class {
908
1197
  };
909
1198
  const objectDocumentHandle = this._objectDocumentHandles.get(objectId);
910
1199
  if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {
911
- import_log4.log.warn("object already inlined in a different document, ignoring the link", {
1200
+ import_log5.log.warn("object already inlined in a different document, ignoring the link", {
912
1201
  ...logMeta,
913
1202
  actualDocumentUrl: objectDocumentHandle.url
914
1203
  }, {
915
- F: __dxlog_file5,
916
- L: 145,
1204
+ F: __dxlog_file6,
1205
+ L: 155,
917
1206
  S: this,
918
1207
  C: (f, a) => f(...a)
919
1208
  });
920
1209
  continue;
921
1210
  }
922
1211
  if (objectDocumentHandle?.url === automergeUrl) {
923
- import_log4.log.warn("object document was already loaded", logMeta, {
924
- F: __dxlog_file5,
925
- L: 152,
1212
+ import_log5.log.warn("object document was already loaded", logMeta, {
1213
+ F: __dxlog_file6,
1214
+ L: 162,
926
1215
  S: this,
927
1216
  C: (f, a) => f(...a)
928
1217
  });
929
1218
  continue;
930
1219
  }
931
1220
  const handle = this._repo.find(automergeUrl);
932
- import_log4.log.debug("document loading triggered", logMeta, {
933
- F: __dxlog_file5,
934
- L: 156,
1221
+ import_log5.log.debug("document loading triggered", logMeta, {
1222
+ F: __dxlog_file6,
1223
+ L: 166,
935
1224
  S: this,
936
1225
  C: (f, a) => f(...a)
937
1226
  });
@@ -944,17 +1233,17 @@ var AutomergeDocumentLoaderImpl = class {
944
1233
  while (true) {
945
1234
  try {
946
1235
  await (0, import_debug.warnAfterTimeout)(5e3, "Automerge root doc load timeout (AutomergeDb)", async () => {
947
- await (0, import_context3.cancelWithContext)(ctx, docHandle.whenReady());
1236
+ await (0, import_context4.cancelWithContext)(ctx, docHandle.whenReady());
948
1237
  });
949
1238
  break;
950
1239
  } catch (err) {
951
1240
  if (`${err}`.includes("Timeout")) {
952
- import_log4.log.info("wraparound", {
1241
+ import_log5.log.info("wraparound", {
953
1242
  id: docHandle.documentId,
954
1243
  state: docHandle.state
955
1244
  }, {
956
- F: __dxlog_file5,
957
- L: 172,
1245
+ F: __dxlog_file6,
1246
+ L: 182,
958
1247
  S: this,
959
1248
  C: (f, a) => f(...a)
960
1249
  });
@@ -994,9 +1283,9 @@ var AutomergeDocumentLoaderImpl = class {
994
1283
  docUrl: handle.url
995
1284
  };
996
1285
  if (this.onObjectDocumentLoaded.listenerCount() === 0) {
997
- import_log4.log.info("document loaded after all listeners were removed", logMeta, {
998
- F: __dxlog_file5,
999
- L: 208,
1286
+ import_log5.log.info("document loaded after all listeners were removed", logMeta, {
1287
+ F: __dxlog_file6,
1288
+ L: 218,
1000
1289
  S: this,
1001
1290
  C: (f, a) => f(...a)
1002
1291
  });
@@ -1004,9 +1293,9 @@ var AutomergeDocumentLoaderImpl = class {
1004
1293
  }
1005
1294
  const objectDocHandle = this._objectDocumentHandles.get(objectId);
1006
1295
  if (objectDocHandle?.url !== handle.url) {
1007
- import_log4.log.warn("object was rebound while a document was loading, discarding handle", logMeta, {
1008
- F: __dxlog_file5,
1009
- L: 213,
1296
+ import_log5.log.warn("object was rebound while a document was loading, discarding handle", logMeta, {
1297
+ F: __dxlog_file6,
1298
+ L: 223,
1010
1299
  S: this,
1011
1300
  C: (f, a) => f(...a)
1012
1301
  });
@@ -1018,14 +1307,14 @@ var AutomergeDocumentLoaderImpl = class {
1018
1307
  });
1019
1308
  } catch (err) {
1020
1309
  const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;
1021
- import_log4.log.warn("failed to load a document", {
1310
+ import_log5.log.warn("failed to load a document", {
1022
1311
  objectId,
1023
1312
  automergeUrl: handle.url,
1024
1313
  retryLoading: shouldRetryLoading,
1025
1314
  err
1026
1315
  }, {
1027
- F: __dxlog_file5,
1028
- L: 219,
1316
+ F: __dxlog_file6,
1317
+ L: 229,
1029
1318
  S: this,
1030
1319
  C: (f, a) => f(...a)
1031
1320
  });
@@ -1035,24 +1324,14 @@ var AutomergeDocumentLoaderImpl = class {
1035
1324
  }
1036
1325
  }
1037
1326
  };
1038
- _ts_decorate2([
1327
+ _ts_decorate3([
1039
1328
  import_tracing2.trace.span({
1040
1329
  showInBrowserTimeline: true
1041
1330
  })
1042
1331
  ], AutomergeDocumentLoaderImpl.prototype, "loadSpaceRootDocHandle", null);
1043
- AutomergeDocumentLoaderImpl = _ts_decorate2([
1332
+ AutomergeDocumentLoaderImpl = _ts_decorate3([
1044
1333
  import_tracing2.trace.resource()
1045
1334
  ], AutomergeDocumentLoaderImpl);
1046
- var REFERENCE_TYPE_TAG = "dxos.echo.model.document.Reference";
1047
- var encodeReference = (reference) => ({
1048
- "@type": REFERENCE_TYPE_TAG,
1049
- // NOTE: Automerge do not support undefined values, so we need to use null instead.
1050
- itemId: reference.itemId ?? null,
1051
- protocol: reference.protocol ?? null,
1052
- host: reference.host ?? null
1053
- });
1054
- var decodeReference = (value) => new import_echo_schema.Reference(value.itemId, value.protocol ?? void 0, value.host ?? void 0);
1055
- var isEncodedReferenceObject = (value) => typeof value === "object" && value !== null && value["@type"] === REFERENCE_TYPE_TAG;
1056
1335
  // Annotate the CommonJS export names for ESM import in node:
1057
1336
  0 && (module.exports = {
1058
1337
  AuthExtension,
@@ -1068,7 +1347,6 @@ var isEncodedReferenceObject = (value) => typeof value === "object" && value !==
1068
1347
  MeshNetworkAdapter,
1069
1348
  MetadataStore,
1070
1349
  Pipeline,
1071
- REFERENCE_TYPE_TAG,
1072
1350
  SnapshotManager,
1073
1351
  SnapshotStore,
1074
1352
  Space,
@@ -1078,12 +1356,9 @@ var isEncodedReferenceObject = (value) => typeof value === "object" && value !==
1078
1356
  TimeframeClock,
1079
1357
  codec,
1080
1358
  createMappedFeedWriter,
1081
- decodeReference,
1082
- encodeReference,
1083
1359
  encodingOptions,
1084
1360
  getSpaceKeyFromDoc,
1085
1361
  hasInvitationExpired,
1086
- isEncodedReferenceObject,
1087
1362
  mapFeedIndexesToTimeframe,
1088
1363
  mapTimeframeToFeedIndexes,
1089
1364
  startAfter,