@dxos/echo-pipeline 0.4.10-main.3e0c8a5 → 0.4.10-main.3f5e2d2

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 (74) hide show
  1. package/dist/lib/browser/{chunk-RTEEJ723.mjs → chunk-KMWJLYEQ.mjs} +77 -57
  2. package/dist/lib/browser/chunk-KMWJLYEQ.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +395 -254
  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 +10 -2
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node/{chunk-7VZVCCNF.cjs → chunk-YZA42CKA.cjs} +82 -62
  9. package/dist/lib/node/chunk-YZA42CKA.cjs.map +7 -0
  10. package/dist/lib/node/index.cjs +423 -283
  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 +20 -13
  14. package/dist/lib/node/testing/index.cjs.map +4 -4
  15. package/dist/types/src/automerge/automerge-doc-loader.d.ts +2 -0
  16. package/dist/types/src/automerge/automerge-doc-loader.d.ts.map +1 -1
  17. package/dist/types/src/automerge/automerge-host.d.ts +21 -18
  18. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  19. package/dist/types/src/automerge/automerge-repo.test.d.ts +2 -0
  20. package/dist/types/src/automerge/automerge-repo.test.d.ts.map +1 -0
  21. package/dist/types/src/automerge/index.d.ts +2 -0
  22. package/dist/types/src/automerge/index.d.ts.map +1 -1
  23. package/dist/types/src/automerge/level.test.d.ts +2 -0
  24. package/dist/types/src/automerge/level.test.d.ts.map +1 -0
  25. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +30 -0
  26. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -0
  27. package/dist/types/src/automerge/local-host-network-adapter.d.ts +8 -1
  28. package/dist/types/src/automerge/local-host-network-adapter.d.ts.map +1 -1
  29. package/dist/types/src/automerge/migrations.d.ts +7 -0
  30. package/dist/types/src/automerge/migrations.d.ts.map +1 -0
  31. package/dist/types/src/automerge/reference.d.ts +15 -0
  32. package/dist/types/src/automerge/reference.d.ts.map +1 -0
  33. package/dist/types/src/automerge/storage-adapter.test.d.ts +2 -0
  34. package/dist/types/src/automerge/storage-adapter.test.d.ts.map +1 -0
  35. package/dist/types/src/automerge/types.d.ts +8 -2
  36. package/dist/types/src/automerge/types.d.ts.map +1 -1
  37. package/dist/types/src/metadata/metadata-store.d.ts +2 -1
  38. package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
  39. package/dist/types/src/space/control-pipeline.d.ts +3 -1
  40. package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
  41. package/dist/types/src/space/space-manager.d.ts +3 -1
  42. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  43. package/dist/types/src/space/space.d.ts +6 -9
  44. package/dist/types/src/space/space.d.ts.map +1 -1
  45. package/dist/types/src/testing/index.d.ts +1 -0
  46. package/dist/types/src/testing/index.d.ts.map +1 -1
  47. package/dist/types/src/testing/level.d.ts +3 -0
  48. package/dist/types/src/testing/level.d.ts.map +1 -0
  49. package/dist/types/src/testing/test-agent-builder.d.ts +2 -2
  50. package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
  51. package/package.json +33 -30
  52. package/src/automerge/automerge-doc-loader.ts +9 -0
  53. package/src/automerge/automerge-host.test.ts +44 -21
  54. package/src/automerge/automerge-host.ts +93 -113
  55. package/src/automerge/automerge-repo.test.ts +61 -0
  56. package/src/automerge/index.ts +2 -0
  57. package/src/automerge/level.test.ts +82 -0
  58. package/src/automerge/leveldb-storage-adapter.ts +117 -0
  59. package/src/automerge/local-host-network-adapter.ts +19 -13
  60. package/src/automerge/migrations.ts +41 -0
  61. package/src/automerge/reference.ts +31 -0
  62. package/src/automerge/storage-adapter.test.ts +90 -0
  63. package/src/automerge/types.ts +8 -5
  64. package/src/db-host/data-service.ts +1 -1
  65. package/src/metadata/metadata-store.ts +17 -8
  66. package/src/space/control-pipeline.ts +11 -1
  67. package/src/space/space-manager.ts +4 -0
  68. package/src/space/space.test.ts +7 -7
  69. package/src/space/space.ts +17 -22
  70. package/src/testing/index.ts +1 -0
  71. package/src/testing/level.ts +12 -0
  72. package/src/testing/test-agent-builder.ts +1 -0
  73. package/dist/lib/browser/chunk-RTEEJ723.mjs.map +0 -7
  74. package/dist/lib/node/chunk-7VZVCCNF.cjs.map +0 -7
@@ -18,168 +18,171 @@ 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_7VZVCCNF.AuthExtension,
22
- AuthStatus: () => import_chunk_7VZVCCNF.AuthStatus,
21
+ AuthExtension: () => import_chunk_YZA42CKA.AuthExtension,
22
+ AuthStatus: () => import_chunk_YZA42CKA.AuthStatus,
23
23
  AutomergeDocumentLoaderImpl: () => AutomergeDocumentLoaderImpl,
24
24
  AutomergeHost: () => AutomergeHost,
25
25
  AutomergeStorageAdapter: () => AutomergeStorageAdapter,
26
- DataServiceImpl: () => import_chunk_7VZVCCNF.DataServiceImpl,
26
+ DataServiceImpl: () => import_chunk_YZA42CKA.DataServiceImpl,
27
+ LevelDBStorageAdapter: () => LevelDBStorageAdapter,
27
28
  LocalHostNetworkAdapter: () => LocalHostNetworkAdapter,
28
- MOCK_AUTH_PROVIDER: () => import_chunk_7VZVCCNF.MOCK_AUTH_PROVIDER,
29
- MOCK_AUTH_VERIFIER: () => import_chunk_7VZVCCNF.MOCK_AUTH_VERIFIER,
29
+ MOCK_AUTH_PROVIDER: () => import_chunk_YZA42CKA.MOCK_AUTH_PROVIDER,
30
+ MOCK_AUTH_VERIFIER: () => import_chunk_YZA42CKA.MOCK_AUTH_VERIFIER,
30
31
  MeshNetworkAdapter: () => MeshNetworkAdapter,
31
- MetadataStore: () => import_chunk_7VZVCCNF.MetadataStore,
32
- Pipeline: () => import_chunk_7VZVCCNF.Pipeline,
33
- SnapshotManager: () => import_chunk_7VZVCCNF.SnapshotManager,
34
- SnapshotStore: () => import_chunk_7VZVCCNF.SnapshotStore,
35
- Space: () => import_chunk_7VZVCCNF.Space,
36
- SpaceManager: () => import_chunk_7VZVCCNF.SpaceManager,
37
- SpaceProtocol: () => import_chunk_7VZVCCNF.SpaceProtocol,
38
- SpaceProtocolSession: () => import_chunk_7VZVCCNF.SpaceProtocolSession,
39
- TimeframeClock: () => import_chunk_7VZVCCNF.TimeframeClock,
40
- codec: () => import_chunk_7VZVCCNF.codec,
41
- createMappedFeedWriter: () => import_chunk_7VZVCCNF.createMappedFeedWriter,
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,
46
+ encodingOptions: () => encodingOptions,
42
47
  getSpaceKeyFromDoc: () => getSpaceKeyFromDoc,
43
- mapFeedIndexesToTimeframe: () => import_chunk_7VZVCCNF.mapFeedIndexesToTimeframe,
44
- mapTimeframeToFeedIndexes: () => import_chunk_7VZVCCNF.mapTimeframeToFeedIndexes,
45
- startAfter: () => import_chunk_7VZVCCNF.startAfter,
46
- valueEncoding: () => import_chunk_7VZVCCNF.valueEncoding
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
47
54
  });
48
55
  module.exports = __toCommonJS(node_exports);
49
- var import_chunk_7VZVCCNF = require("./chunk-7VZVCCNF.cjs");
56
+ var import_chunk_YZA42CKA = require("./chunk-YZA42CKA.cjs");
57
+ var import_async = require("@dxos/async");
50
58
  var import_automerge = require("@dxos/automerge/automerge");
51
59
  var import_automerge_repo = require("@dxos/automerge/automerge-repo");
52
- var import_automerge_repo_storage_indexeddb = require("@dxos/automerge/automerge-repo-storage-indexeddb");
53
60
  var import_context = require("@dxos/context");
61
+ var import_invariant = require("@dxos/invariant");
54
62
  var import_keys = require("@dxos/keys");
55
63
  var import_log = require("@dxos/log");
56
- var import_protocols = require("@dxos/protocols");
57
- var import_random_access_storage = require("@dxos/random-access-storage");
58
64
  var import_tracing = require("@dxos/tracing");
59
65
  var import_util = require("@dxos/util");
60
- var import_util2 = require("@dxos/util");
61
- var import_async = require("@dxos/async");
66
+ var import_context2 = require("@dxos/context");
67
+ var import_async2 = require("@dxos/async");
62
68
  var import_automerge_repo2 = require("@dxos/automerge/automerge-repo");
63
69
  var import_codec_protobuf = require("@dxos/codec-protobuf");
64
- var import_invariant = require("@dxos/invariant");
65
- var import_log2 = require("@dxos/log");
66
- var import_async2 = require("@dxos/async");
67
- var import_automerge_repo3 = require("@dxos/automerge/automerge-repo");
68
70
  var import_invariant2 = require("@dxos/invariant");
69
- var import_log3 = require("@dxos/log");
70
- var import_teleport_extension_automerge_replicator = require("@dxos/teleport-extension-automerge-replicator");
71
71
  var import_async3 = require("@dxos/async");
72
- var import_context2 = require("@dxos/context");
73
- var import_debug = require("@dxos/debug");
72
+ var import_automerge_repo3 = require("@dxos/automerge/automerge-repo");
74
73
  var import_invariant3 = require("@dxos/invariant");
74
+ var import_log2 = require("@dxos/log");
75
+ var import_teleport_extension_automerge_replicator = require("@dxos/teleport-extension-automerge-replicator");
76
+ var import_automerge_repo_storage_indexeddb = require("@dxos/automerge/automerge-repo-storage-indexeddb");
77
+ var import_log3 = require("@dxos/log");
78
+ var import_random_access_storage = require("@dxos/random-access-storage");
79
+ var import_util2 = require("@dxos/util");
80
+ var import_async4 = require("@dxos/async");
81
+ var import_context3 = require("@dxos/context");
82
+ var import_debug = require("@dxos/debug");
83
+ var import_invariant4 = require("@dxos/invariant");
75
84
  var import_log4 = require("@dxos/log");
76
- var AutomergeStorageAdapter = class {
77
- constructor(_directory) {
78
- this._directory = _directory;
79
- this._state = "opened";
85
+ var import_tracing2 = require("@dxos/tracing");
86
+ var import_echo_schema = require("@dxos/echo-schema");
87
+ var LevelDBStorageAdapter = class extends import_context2.Resource {
88
+ constructor(_params) {
89
+ super();
90
+ this._params = _params;
80
91
  }
81
- async load(key) {
82
- if (this._state !== "opened") {
83
- return void 0;
84
- }
85
- const filename = this._getFilename(key);
86
- const file = this._directory.getOrCreateFile(filename);
87
- const { size } = await file.stat();
88
- if (!size || size === 0) {
89
- return void 0;
92
+ async load(keyArray) {
93
+ try {
94
+ if (this._lifecycleState !== import_context2.LifecycleState.OPEN) {
95
+ return void 0;
96
+ }
97
+ return await this._params.db.get(keyArray, {
98
+ ...encodingOptions
99
+ });
100
+ } catch (err) {
101
+ if (isLevelDbNotFoundError(err)) {
102
+ return void 0;
103
+ }
104
+ throw err;
90
105
  }
91
- const buffer = await file.read(0, size);
92
- return (0, import_util2.bufferToArray)(buffer);
93
106
  }
94
- async save(key, data) {
95
- if (this._state !== "opened") {
107
+ async save(keyArray, binary) {
108
+ if (this._lifecycleState !== import_context2.LifecycleState.OPEN) {
96
109
  return void 0;
97
110
  }
98
- const filename = this._getFilename(key);
99
- const file = this._directory.getOrCreateFile(filename);
100
- await file.write(0, (0, import_util2.arrayToBuffer)(data));
101
- await file.truncate?.(data.length);
102
- await file.flush?.();
111
+ const batch = this._params.db.batch();
112
+ await this._params.callbacks?.beforeSave?.({
113
+ path: keyArray,
114
+ batch
115
+ });
116
+ batch.put(keyArray, Buffer.from(binary), {
117
+ ...encodingOptions
118
+ });
119
+ await batch.write();
120
+ await this._params.callbacks?.afterSave?.(keyArray);
103
121
  }
104
- async remove(key) {
105
- if (this._state !== "opened") {
122
+ async remove(keyArray) {
123
+ if (this._lifecycleState !== import_context2.LifecycleState.OPEN) {
106
124
  return void 0;
107
125
  }
108
- const filename = this._getFilename(key);
109
- const file = this._directory.getOrCreateFile(filename);
110
- await file.destroy();
126
+ await this._params.db.del(keyArray, {
127
+ ...encodingOptions
128
+ });
111
129
  }
112
130
  async loadRange(keyPrefix) {
113
- if (this._state !== "opened") {
131
+ if (this._lifecycleState !== import_context2.LifecycleState.OPEN) {
114
132
  return [];
115
133
  }
116
- const filename = this._getFilename(keyPrefix);
117
- const entries = await this._directory.list();
118
- return Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
119
- const file = this._directory.getOrCreateFile(entry);
120
- const { size } = await file.stat();
121
- const buffer = await file.read(0, size);
122
- return {
123
- key: this._getKeyFromFilename(entry),
124
- data: (0, import_util2.bufferToArray)(buffer)
125
- };
126
- }));
134
+ const result = [];
135
+ for await (const [key, value] of this._params.db.iterator({
136
+ gte: keyPrefix,
137
+ lte: [
138
+ ...keyPrefix,
139
+ "\uFFFF"
140
+ ],
141
+ ...encodingOptions
142
+ })) {
143
+ result.push({
144
+ key,
145
+ data: value
146
+ });
147
+ }
148
+ return result;
127
149
  }
128
150
  async removeRange(keyPrefix) {
129
- if (this._state !== "opened") {
151
+ if (this._lifecycleState !== import_context2.LifecycleState.OPEN) {
130
152
  return void 0;
131
153
  }
132
- const filename = this._getFilename(keyPrefix);
133
- const entries = await this._directory.list();
134
- await Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
135
- const file = this._directory.getOrCreateFile(entry);
136
- await file.destroy();
137
- }));
138
- }
139
- async close() {
140
- this._state = "closed";
141
- }
142
- _getFilename(key) {
143
- return key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-");
144
- }
145
- _getKeyFromFilename(filename) {
146
- return filename.split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"));
147
- }
148
- };
149
- var AutomergeStorageWrapper = class {
150
- constructor({ storage, callbacks }) {
151
- this._storage = storage;
152
- this._callbacks = callbacks;
153
- }
154
- async load(key) {
155
- return this._storage.load(key);
156
- }
157
- async save(key, value) {
158
- await this._callbacks.beforeSave?.(key);
159
- await this._storage.save(key, value);
160
- await this._callbacks.afterSave?.(key);
161
- }
162
- async remove(key) {
163
- return this._storage.remove(key);
164
- }
165
- async loadRange(keyPrefix) {
166
- return this._storage.loadRange(keyPrefix);
167
- }
168
- async removeRange(keyPrefix) {
169
- return this._storage.removeRange(keyPrefix);
170
- }
171
- async close() {
172
- if (this._storage instanceof AutomergeStorageAdapter) {
173
- return this._storage.close();
154
+ const batch = this._params.db.batch();
155
+ for await (const [key] of this._params.db.iterator({
156
+ gte: keyPrefix,
157
+ lte: [
158
+ ...keyPrefix,
159
+ "\uFFFF"
160
+ ],
161
+ ...encodingOptions
162
+ })) {
163
+ batch.del(key, {
164
+ ...encodingOptions
165
+ });
174
166
  }
167
+ await batch.write();
175
168
  }
176
169
  };
170
+ var keyEncoder = {
171
+ encode: (key) => Buffer.from(key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-")),
172
+ decode: (key) => Buffer.from(key).toString().split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"))
173
+ };
174
+ var encodingOptions = {
175
+ keyEncoding: keyEncoder,
176
+ valueEncoding: "buffer"
177
+ };
178
+ var isLevelDbNotFoundError = (err) => err.code === "LEVEL_NOT_FOUND";
177
179
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts";
178
180
  var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapter {
179
181
  constructor() {
180
182
  super(...arguments);
181
183
  this._peers = /* @__PURE__ */ new Map();
182
- this._connected = new import_async.Trigger();
184
+ this._connected = new import_async2.Trigger();
185
+ this._isConnected = false;
183
186
  }
184
187
  /**
185
188
  * Emits `ready` event. That signals to `Repo` that it can start using the adapter.
@@ -189,15 +192,21 @@ var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapte
189
192
  network: this
190
193
  });
191
194
  }
195
+ /**
196
+ * Called by `Repo` to connect to the network.
197
+ *
198
+ * @param peerId Our peer Id.
199
+ */
192
200
  connect(peerId) {
193
201
  this.peerId = peerId;
202
+ this._isConnected = true;
194
203
  this._connected.wake();
195
204
  }
196
205
  send(message) {
197
206
  const peer = this._peers.get(message.targetId);
198
- (0, import_invariant.invariant)(peer, "Peer not found.", {
207
+ (0, import_invariant2.invariant)(peer, "Peer not found.", {
199
208
  F: __dxlog_file,
200
- L: 45,
209
+ L: 51,
201
210
  S: this,
202
211
  A: [
203
212
  "peer",
@@ -212,12 +221,17 @@ var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapte
212
221
  }
213
222
  disconnect() {
214
223
  }
224
+ async whenConnected() {
225
+ await this._connected.wait({
226
+ timeout: 1e4
227
+ });
228
+ }
215
229
  syncRepo({ id, syncMessage }) {
216
230
  const peerId = this._getPeerId(id);
217
231
  return new import_codec_protobuf.Stream(({ next, close }) => {
218
- (0, import_invariant.invariant)(!this._peers.has(peerId), "Peer already connected.", {
232
+ (0, import_invariant2.invariant)(!this._peers.has(peerId), "Peer already connected.", {
219
233
  F: __dxlog_file,
220
- L: 63,
234
+ L: 73,
221
235
  S: this,
222
236
  A: [
223
237
  "!this._peers.has(peerId)",
@@ -239,35 +253,47 @@ var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapte
239
253
  });
240
254
  }
241
255
  });
242
- this._connected.wait({
243
- timeout: 1e3
244
- }).then(() => {
245
- this.emit("peer-candidate", {
246
- peerMetadata: {},
247
- peerId
248
- });
249
- }).catch((err) => import_log2.log.catch(err, void 0, {
256
+ (0, import_invariant2.invariant)(this._isConnected, void 0, {
250
257
  F: __dxlog_file,
251
- L: 88,
258
+ L: 90,
252
259
  S: this,
253
- C: (f, a) => f(...a)
254
- }));
260
+ A: [
261
+ "this._isConnected",
262
+ ""
263
+ ]
264
+ });
265
+ this.emit("peer-candidate", {
266
+ peerMetadata: {},
267
+ peerId
268
+ });
255
269
  });
256
270
  }
257
271
  async sendSyncMessage({ id, syncMessage }) {
258
- await this._connected.wait({
259
- timeout: 1e3
272
+ (0, import_invariant2.invariant)(this._isConnected, void 0, {
273
+ F: __dxlog_file,
274
+ L: 99,
275
+ S: this,
276
+ A: [
277
+ "this._isConnected",
278
+ ""
279
+ ]
260
280
  });
261
281
  const message = import_automerge_repo2.cbor.decode(syncMessage);
262
282
  this.emit("message", message);
263
283
  }
264
284
  async getHostInfo() {
265
- await this._connected.wait({
266
- timeout: 1e3
285
+ (0, import_invariant2.invariant)(this._isConnected, void 0, {
286
+ F: __dxlog_file,
287
+ L: 105,
288
+ S: this,
289
+ A: [
290
+ "this._isConnected",
291
+ ""
292
+ ]
267
293
  });
268
- (0, import_invariant.invariant)(this.peerId, "Peer id not set.", {
294
+ (0, import_invariant2.invariant)(this.peerId, "Peer id not set.", {
269
295
  F: __dxlog_file,
270
- L: 100,
296
+ L: 106,
271
297
  S: this,
272
298
  A: [
273
299
  "this.peerId",
@@ -287,7 +313,7 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
287
313
  constructor() {
288
314
  super(...arguments);
289
315
  this._extensions = /* @__PURE__ */ new Map();
290
- this._connected = new import_async2.Trigger();
316
+ this._connected = new import_async3.Trigger();
291
317
  }
292
318
  /**
293
319
  * Emits `ready` event. That signals to `Repo` that it can start using the adapter.
@@ -304,7 +330,7 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
304
330
  send(message) {
305
331
  const receiverId = message.targetId;
306
332
  const extension = this._extensions.get(receiverId);
307
- (0, import_invariant2.invariant)(extension, "Extension not found.", {
333
+ (0, import_invariant3.invariant)(extension, "Extension not found.", {
308
334
  F: __dxlog_file2,
309
335
  L: 38,
310
336
  S: this,
@@ -315,7 +341,7 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
315
341
  });
316
342
  extension.sendSyncMessage({
317
343
  payload: import_automerge_repo3.cbor.encode(message)
318
- }).catch((err) => import_log3.log.catch(err, void 0, {
344
+ }).catch((err) => import_log2.log.catch(err, void 0, {
319
345
  F: __dxlog_file2,
320
346
  L: 39,
321
347
  S: this,
@@ -325,7 +351,7 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
325
351
  disconnect() {
326
352
  }
327
353
  createExtension() {
328
- (0, import_invariant2.invariant)(this.peerId, "Peer id not set.", {
354
+ (0, import_invariant3.invariant)(this.peerId, "Peer id not set.", {
329
355
  F: __dxlog_file2,
330
356
  L: 47,
331
357
  S: this,
@@ -340,7 +366,7 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
340
366
  }, {
341
367
  onStartReplication: async (info, remotePeerId) => {
342
368
  await this._connected.wait();
343
- (0, import_log3.log)("onStartReplication", {
369
+ (0, import_log2.log)("onStartReplication", {
344
370
  id: info.id,
345
371
  thisPeerId: this.peerId,
346
372
  remotePeerId: remotePeerId.toHex()
@@ -353,7 +379,7 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
353
379
  if (!this._extensions.has(info.id)) {
354
380
  peerInfo = info;
355
381
  this._extensions.set(info.id, extension);
356
- (0, import_log3.log)("peer-candidate", {
382
+ (0, import_log2.log)("peer-candidate", {
357
383
  id: info.id,
358
384
  thisPeerId: this.peerId,
359
385
  remotePeerId: remotePeerId.toHex()
@@ -392,6 +418,108 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
392
418
  return extension;
393
419
  }
394
420
  };
421
+ var AutomergeStorageAdapter = class {
422
+ constructor(_directory) {
423
+ this._directory = _directory;
424
+ this._state = "opened";
425
+ }
426
+ async load(key) {
427
+ if (this._state !== "opened") {
428
+ return void 0;
429
+ }
430
+ const filename = this._getFilename(key);
431
+ const file = this._directory.getOrCreateFile(filename);
432
+ const { size } = await file.stat();
433
+ if (!size || size === 0) {
434
+ return void 0;
435
+ }
436
+ const buffer = await file.read(0, size);
437
+ return (0, import_util2.bufferToArray)(buffer);
438
+ }
439
+ async save(key, data) {
440
+ if (this._state !== "opened") {
441
+ return void 0;
442
+ }
443
+ const filename = this._getFilename(key);
444
+ const file = this._directory.getOrCreateFile(filename);
445
+ await file.write(0, (0, import_util2.arrayToBuffer)(data));
446
+ await file.truncate?.(data.length);
447
+ await file.flush?.();
448
+ }
449
+ async remove(key) {
450
+ if (this._state !== "opened") {
451
+ return void 0;
452
+ }
453
+ const filename = this._getFilename(key);
454
+ const file = this._directory.getOrCreateFile(filename);
455
+ await file.destroy();
456
+ }
457
+ async loadRange(keyPrefix) {
458
+ if (this._state !== "opened") {
459
+ return [];
460
+ }
461
+ const filename = this._getFilename(keyPrefix);
462
+ const entries = await this._directory.list();
463
+ return Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
464
+ const file = this._directory.getOrCreateFile(entry);
465
+ const { size } = await file.stat();
466
+ const buffer = await file.read(0, size);
467
+ return {
468
+ key: this._getKeyFromFilename(entry),
469
+ data: (0, import_util2.bufferToArray)(buffer)
470
+ };
471
+ }));
472
+ }
473
+ async removeRange(keyPrefix) {
474
+ if (this._state !== "opened") {
475
+ return void 0;
476
+ }
477
+ const filename = this._getFilename(keyPrefix);
478
+ const entries = await this._directory.list();
479
+ await Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
480
+ const file = this._directory.getOrCreateFile(entry);
481
+ await file.destroy();
482
+ }));
483
+ }
484
+ async close() {
485
+ this._state = "closed";
486
+ }
487
+ _getFilename(key) {
488
+ return key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-");
489
+ }
490
+ _getKeyFromFilename(filename) {
491
+ return filename.split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"));
492
+ }
493
+ };
494
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/migrations.ts";
495
+ var levelMigration = async ({ db, directory }) => {
496
+ const isNewLevel = !await db.iterator({
497
+ ...encodingOptions
498
+ }).next();
499
+ if (!isNewLevel) {
500
+ return;
501
+ }
502
+ const oldStorageAdapter = directory.type === import_random_access_storage.StorageType.IDB ? new import_automerge_repo_storage_indexeddb.IndexedDBStorageAdapter(directory.path, "data") : new AutomergeStorageAdapter(directory);
503
+ const chunks = await oldStorageAdapter.loadRange([]);
504
+ if (chunks.length === 0) {
505
+ return;
506
+ }
507
+ const batch = db.batch();
508
+ import_log3.log.info("found chunks on old storage adapter", {
509
+ chunks: chunks.length
510
+ }, {
511
+ F: __dxlog_file3,
512
+ L: 36,
513
+ S: void 0,
514
+ C: (f, a) => f(...a)
515
+ });
516
+ for (const { key, data } of await oldStorageAdapter.loadRange([])) {
517
+ data && batch.put(key, data, {
518
+ ...encodingOptions
519
+ });
520
+ }
521
+ await batch.write();
522
+ };
395
523
  function _ts_decorate(decorators, target, key, desc) {
396
524
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
397
525
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
@@ -402,26 +530,29 @@ function _ts_decorate(decorators, target, key, desc) {
402
530
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
403
531
  return c > 3 && r && Object.defineProperty(target, key, r), r;
404
532
  }
405
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
533
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
406
534
  var AutomergeHost = class {
407
- constructor({ directory, metadata }) {
535
+ constructor({ directory, db, storageCallbacks }) {
408
536
  this._ctx = new import_context.Context();
409
537
  this._authorizedDevices = new import_util.ComplexMap(import_keys.PublicKey.hash);
410
- this._updatingMetadata = /* @__PURE__ */ new Map();
411
538
  this._requestedDocs = /* @__PURE__ */ new Set();
412
- this._metadata = metadata;
413
- this._meshNetwork = new MeshNetworkAdapter();
414
- this._clientNetwork = new LocalHostNetworkAdapter();
415
- this._storage = new AutomergeStorageWrapper({
416
- storage: (
417
- // TODO(mykola): Delete specific handling of IDB storage.
418
- directory.type === import_random_access_storage.StorageType.IDB ? new import_automerge_repo_storage_indexeddb.IndexedDBStorageAdapter(directory.path, "data") : new AutomergeStorageAdapter(directory)
419
- ),
420
- callbacks: {
421
- beforeSave: (params) => this._beforeSave(params)
422
- }
539
+ this._directory = directory;
540
+ this._db = db;
541
+ this._storageCallbacks = storageCallbacks;
542
+ }
543
+ async open() {
544
+ this._directory && await levelMigration({
545
+ db: this._db,
546
+ directory: this._directory
547
+ });
548
+ this._storage = new LevelDBStorageAdapter({
549
+ db: this._db,
550
+ callbacks: this._storageCallbacks
423
551
  });
552
+ await this._storage.open?.();
424
553
  this._peerId = `host-${import_keys.PublicKey.random().toHex()}`;
554
+ this._meshNetwork = new MeshNetworkAdapter();
555
+ this._clientNetwork = new LocalHostNetworkAdapter();
425
556
  this._repo = new import_automerge_repo.Repo({
426
557
  peerId: this._peerId,
427
558
  network: [
@@ -446,8 +577,8 @@ var AutomergeHost = class {
446
577
  documentId,
447
578
  isRequested
448
579
  }, {
449
- F: __dxlog_file3,
450
- L: 96,
580
+ F: __dxlog_file4,
581
+ L: 108,
451
582
  S: this,
452
583
  C: (f, a) => f(...a)
453
584
  });
@@ -460,8 +591,8 @@ var AutomergeHost = class {
460
591
  peerId,
461
592
  documentId
462
593
  }, {
463
- F: __dxlog_file3,
464
- L: 103,
594
+ F: __dxlog_file4,
595
+ L: 115,
465
596
  S: this,
466
597
  C: (f, a) => f(...a)
467
598
  });
@@ -474,8 +605,8 @@ var AutomergeHost = class {
474
605
  peerId,
475
606
  documentId
476
607
  }, {
477
- F: __dxlog_file3,
478
- L: 112,
608
+ F: __dxlog_file4,
609
+ L: 124,
479
610
  S: this,
480
611
  C: (f, a) => f(...a)
481
612
  });
@@ -491,16 +622,16 @@ var AutomergeHost = class {
491
622
  spaceKey,
492
623
  isAuthorized
493
624
  }, {
494
- F: __dxlog_file3,
495
- L: 118,
625
+ F: __dxlog_file4,
626
+ L: 130,
496
627
  S: this,
497
628
  C: (f, a) => f(...a)
498
629
  });
499
630
  return isAuthorized;
500
631
  } catch (err) {
501
632
  import_log.log.catch(err, void 0, {
502
- F: __dxlog_file3,
503
- L: 128,
633
+ F: __dxlog_file4,
634
+ L: 140,
504
635
  S: this,
505
636
  C: (f, a) => f(...a)
506
637
  });
@@ -510,69 +641,22 @@ var AutomergeHost = class {
510
641
  });
511
642
  this._clientNetwork.ready();
512
643
  this._meshNetwork.ready();
513
- {
514
- const listener = ({ handle }) => this._onDocument(handle);
515
- this._repo.on("document", listener);
516
- this._ctx.onDispose(() => {
517
- this._repo.off("document", listener);
518
- });
519
- }
644
+ await this._clientNetwork.whenConnected();
645
+ }
646
+ async close() {
647
+ await this._storage.close?.();
648
+ await this._clientNetwork.close();
649
+ await this._ctx.dispose();
520
650
  }
521
651
  get repo() {
522
652
  return this._repo;
523
653
  }
524
- async _beforeSave(path) {
525
- const id = path[0];
526
- if (this._updatingMetadata.has(id)) {
527
- return this._updatingMetadata.get(id);
528
- }
529
- }
530
- _onDocument(handle) {
531
- const listener = (event) => this._onUpdate(event);
532
- handle.on("change", listener);
533
- this._ctx.onDispose(() => {
534
- handle.off("change", listener);
535
- });
536
- }
537
- _onUpdate(event) {
538
- if (this._metadata == null) {
539
- return;
540
- }
541
- const objectIds = getInlineChanges(event);
542
- if (objectIds.length === 0) {
543
- return;
544
- }
545
- const heads = (0, import_automerge.getHeads)(event.doc);
546
- const lastAvailableHash = heads.join("");
547
- if (!lastAvailableHash) {
548
- return;
549
- }
550
- const encodedIds = objectIds.map((objectId) => import_protocols.idCodec.encode({
551
- documentId: event.handle.documentId,
552
- objectId
553
- }));
554
- const idToLastHash = new Map(encodedIds.map((id) => [
555
- id,
556
- lastAvailableHash
557
- ]));
558
- const markingDirtyPromise = this._metadata.markDirty(idToLastHash).then(() => {
559
- this._updatingMetadata.delete(event.handle.documentId);
560
- }).catch((err) => {
561
- this._ctx.disposed && import_log.log.catch(err, void 0, {
562
- F: __dxlog_file3,
563
- L: 188,
564
- S: this,
565
- C: (f, a) => f(...a)
566
- });
567
- });
568
- this._updatingMetadata.set(event.handle.documentId, markingDirtyPromise);
569
- }
570
654
  _automergeDocs() {
571
655
  return (0, import_util.mapValues)(this._repo.handles, (handle) => ({
572
656
  state: handle.state,
573
657
  hasDoc: !!handle.docSync(),
574
658
  heads: handle.docSync() ? import_automerge.next.getHeads(handle.docSync()) : null,
575
- data: handle.docSync()?.doc && (0, import_util.mapValues)(handle.docSync()?.doc, (value, key) => {
659
+ data: handle.docSync() && (0, import_util.mapValues)(handle.docSync(), (value, key) => {
576
660
  try {
577
661
  switch (key) {
578
662
  case "access":
@@ -592,14 +676,25 @@ var AutomergeHost = class {
592
676
  _automergePeers() {
593
677
  return this._repo.peers;
594
678
  }
595
- async close() {
596
- await this._storage.close();
597
- await this._clientNetwork.close();
598
- await this._ctx.dispose();
599
- }
600
679
  //
601
680
  // Methods for client-services.
602
681
  //
682
+ async flush({ states }) {
683
+ await Promise.all(states?.map(async ({ heads, documentId }) => {
684
+ (0, import_invariant.invariant)(heads, "heads are required for flush", {
685
+ F: __dxlog_file4,
686
+ L: 200,
687
+ S: this,
688
+ A: [
689
+ "heads",
690
+ "'heads are required for flush'"
691
+ ]
692
+ });
693
+ const handle = this.repo.handles[documentId] ?? this._repo.find(documentId);
694
+ await waitForHeads(handle, heads);
695
+ }) ?? []);
696
+ await this._repo.flush(states?.map(({ documentId }) => documentId));
697
+ }
603
698
  syncRepo(request) {
604
699
  return this._clientNetwork.syncRepo(request);
605
700
  }
@@ -620,8 +715,8 @@ var AutomergeHost = class {
620
715
  spaceKey,
621
716
  deviceKey
622
717
  }, {
623
- F: __dxlog_file3,
624
- L: 255,
718
+ F: __dxlog_file4,
719
+ L: 230,
625
720
  S: this,
626
721
  C: (f, a) => f(...a)
627
722
  });
@@ -641,27 +736,14 @@ _ts_decorate([
641
736
  depth: null
642
737
  })
643
738
  ], AutomergeHost.prototype, "_automergePeers", null);
739
+ _ts_decorate([
740
+ import_tracing.trace.span({
741
+ showInBrowserTimeline: true
742
+ })
743
+ ], AutomergeHost.prototype, "flush", null);
644
744
  AutomergeHost = _ts_decorate([
645
745
  import_tracing.trace.resource()
646
746
  ], AutomergeHost);
647
- var getInlineChanges = (event) => {
648
- const inlineChangedObjectIds = /* @__PURE__ */ new Set();
649
- for (const { path } of event.patches) {
650
- if (path.length < 2) {
651
- continue;
652
- }
653
- switch (path[0]) {
654
- case "objects":
655
- if (path.length >= 2) {
656
- inlineChangedObjectIds.add(path[1]);
657
- }
658
- break;
659
- }
660
- }
661
- return [
662
- ...inlineChangedObjectIds
663
- ];
664
- };
665
747
  var getSpaceKeyFromDoc = (doc) => {
666
748
  const rawSpaceKey = doc.access?.spaceKey ?? doc.experimental_spaceKey;
667
749
  if (rawSpaceKey == null) {
@@ -669,7 +751,35 @@ var getSpaceKeyFromDoc = (doc) => {
669
751
  }
670
752
  return String(rawSpaceKey);
671
753
  };
672
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
754
+ var waitForHeads = async (handle, heads) => {
755
+ await handle.whenReady();
756
+ const unavailableHeads = new Set(heads);
757
+ await import_async.Event.wrap(handle, "change").waitForCondition(() => {
758
+ for (const changeHash of unavailableHeads.values()) {
759
+ if (changeIsPresentInDoc(handle.docSync(), changeHash)) {
760
+ unavailableHeads.delete(changeHash);
761
+ }
762
+ }
763
+ if (unavailableHeads.size === 0) {
764
+ return true;
765
+ }
766
+ return false;
767
+ });
768
+ };
769
+ var changeIsPresentInDoc = (doc, changeHash) => {
770
+ return !!(0, import_automerge.getBackend)(doc).getChangeByHash(changeHash);
771
+ };
772
+ function _ts_decorate2(decorators, target, key, desc) {
773
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
774
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
775
+ r = Reflect.decorate(decorators, target, key, desc);
776
+ else
777
+ for (var i = decorators.length - 1; i >= 0; i--)
778
+ if (d = decorators[i])
779
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
780
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
781
+ }
782
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
673
783
  var AutomergeDocumentLoaderImpl = class {
674
784
  constructor(_spaceKey, _repo) {
675
785
  this._spaceKey = _spaceKey;
@@ -677,7 +787,12 @@ var AutomergeDocumentLoaderImpl = class {
677
787
  this._spaceRootDocHandle = null;
678
788
  this._objectDocumentHandles = /* @__PURE__ */ new Map();
679
789
  this._objectsPendingDocumentLoad = /* @__PURE__ */ new Set();
680
- this.onObjectDocumentLoaded = new import_async3.Event();
790
+ this.onObjectDocumentLoaded = new import_async4.Event();
791
+ }
792
+ getAllHandles() {
793
+ return [
794
+ ...new Set(this._objectDocumentHandles.values())
795
+ ];
681
796
  }
682
797
  async loadSpaceRootDocHandle(ctx, spaceState) {
683
798
  if (this._spaceRootDocHandle != null) {
@@ -687,8 +802,8 @@ var AutomergeDocumentLoaderImpl = class {
687
802
  import_log4.log.error("Database opened with no rootUrl", {
688
803
  spaceKey: this._spaceKey
689
804
  }, {
690
- F: __dxlog_file4,
691
- L: 60,
805
+ F: __dxlog_file5,
806
+ L: 69,
692
807
  S: this,
693
808
  C: (f, a) => f(...a)
694
809
  });
@@ -696,9 +811,9 @@ var AutomergeDocumentLoaderImpl = class {
696
811
  } else {
697
812
  const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);
698
813
  const doc = existingDocHandle.docSync();
699
- (0, import_invariant3.invariant)(doc, void 0, {
700
- F: __dxlog_file4,
701
- L: 65,
814
+ (0, import_invariant4.invariant)(doc, void 0, {
815
+ F: __dxlog_file5,
816
+ L: 74,
702
817
  S: this,
703
818
  A: [
704
819
  "doc",
@@ -712,9 +827,9 @@ var AutomergeDocumentLoaderImpl = class {
712
827
  }
713
828
  }
714
829
  loadObjectDocument(objectId) {
715
- (0, import_invariant3.invariant)(this._spaceRootDocHandle, void 0, {
716
- F: __dxlog_file4,
717
- L: 74,
830
+ (0, import_invariant4.invariant)(this._spaceRootDocHandle, void 0, {
831
+ F: __dxlog_file5,
832
+ L: 83,
718
833
  S: this,
719
834
  A: [
720
835
  "this._spaceRootDocHandle",
@@ -725,9 +840,9 @@ var AutomergeDocumentLoaderImpl = class {
725
840
  return;
726
841
  }
727
842
  const spaceRootDoc = this._spaceRootDocHandle.docSync();
728
- (0, import_invariant3.invariant)(spaceRootDoc, void 0, {
729
- F: __dxlog_file4,
730
- L: 79,
843
+ (0, import_invariant4.invariant)(spaceRootDoc, void 0, {
844
+ F: __dxlog_file5,
845
+ L: 88,
731
846
  S: this,
732
847
  A: [
733
848
  "spaceRootDoc",
@@ -740,8 +855,8 @@ var AutomergeDocumentLoaderImpl = class {
740
855
  import_log4.log.info("loading delayed until object links are initialized", {
741
856
  objectId
742
857
  }, {
743
- F: __dxlog_file4,
744
- L: 83,
858
+ F: __dxlog_file5,
859
+ L: 92,
745
860
  S: this,
746
861
  C: (f, a) => f(...a)
747
862
  });
@@ -760,9 +875,9 @@ var AutomergeDocumentLoaderImpl = class {
760
875
  linksAwaitingLoad.forEach(([objectId]) => this._objectsPendingDocumentLoad.delete(objectId));
761
876
  }
762
877
  getSpaceRootDocHandle() {
763
- (0, import_invariant3.invariant)(this._spaceRootDocHandle, void 0, {
764
- F: __dxlog_file4,
765
- L: 101,
878
+ (0, import_invariant4.invariant)(this._spaceRootDocHandle, void 0, {
879
+ F: __dxlog_file5,
880
+ L: 110,
766
881
  S: this,
767
882
  A: [
768
883
  "this._spaceRootDocHandle",
@@ -772,9 +887,9 @@ var AutomergeDocumentLoaderImpl = class {
772
887
  return this._spaceRootDocHandle;
773
888
  }
774
889
  createDocumentForObject(objectId) {
775
- (0, import_invariant3.invariant)(this._spaceRootDocHandle, void 0, {
776
- F: __dxlog_file4,
777
- L: 106,
890
+ (0, import_invariant4.invariant)(this._spaceRootDocHandle, void 0, {
891
+ F: __dxlog_file5,
892
+ L: 115,
778
893
  S: this,
779
894
  A: [
780
895
  "this._spaceRootDocHandle",
@@ -816,8 +931,8 @@ var AutomergeDocumentLoaderImpl = class {
816
931
  ...logMeta,
817
932
  actualDocumentUrl: objectDocumentHandle.url
818
933
  }, {
819
- F: __dxlog_file4,
820
- L: 136,
934
+ F: __dxlog_file5,
935
+ L: 145,
821
936
  S: this,
822
937
  C: (f, a) => f(...a)
823
938
  });
@@ -825,8 +940,8 @@ var AutomergeDocumentLoaderImpl = class {
825
940
  }
826
941
  if (objectDocumentHandle?.url === automergeUrl) {
827
942
  import_log4.log.warn("object document was already loaded", logMeta, {
828
- F: __dxlog_file4,
829
- L: 143,
943
+ F: __dxlog_file5,
944
+ L: 152,
830
945
  S: this,
831
946
  C: (f, a) => f(...a)
832
947
  });
@@ -834,8 +949,8 @@ var AutomergeDocumentLoaderImpl = class {
834
949
  }
835
950
  const handle = this._repo.find(automergeUrl);
836
951
  import_log4.log.debug("document loading triggered", logMeta, {
837
- F: __dxlog_file4,
838
- L: 147,
952
+ F: __dxlog_file5,
953
+ L: 156,
839
954
  S: this,
840
955
  C: (f, a) => f(...a)
841
956
  });
@@ -848,7 +963,7 @@ var AutomergeDocumentLoaderImpl = class {
848
963
  while (true) {
849
964
  try {
850
965
  await (0, import_debug.warnAfterTimeout)(5e3, "Automerge root doc load timeout (AutomergeDb)", async () => {
851
- await (0, import_context2.cancelWithContext)(ctx, docHandle.whenReady());
966
+ await (0, import_context3.cancelWithContext)(ctx, docHandle.whenReady());
852
967
  });
853
968
  break;
854
969
  } catch (err) {
@@ -857,8 +972,8 @@ var AutomergeDocumentLoaderImpl = class {
857
972
  id: docHandle.documentId,
858
973
  state: docHandle.state
859
974
  }, {
860
- F: __dxlog_file4,
861
- L: 163,
975
+ F: __dxlog_file5,
976
+ L: 172,
862
977
  S: this,
863
978
  C: (f, a) => f(...a)
864
979
  });
@@ -899,8 +1014,8 @@ var AutomergeDocumentLoaderImpl = class {
899
1014
  };
900
1015
  if (this.onObjectDocumentLoaded.listenerCount() === 0) {
901
1016
  import_log4.log.info("document loaded after all listeners were removed", logMeta, {
902
- F: __dxlog_file4,
903
- L: 199,
1017
+ F: __dxlog_file5,
1018
+ L: 208,
904
1019
  S: this,
905
1020
  C: (f, a) => f(...a)
906
1021
  });
@@ -909,8 +1024,8 @@ var AutomergeDocumentLoaderImpl = class {
909
1024
  const objectDocHandle = this._objectDocumentHandles.get(objectId);
910
1025
  if (objectDocHandle?.url !== handle.url) {
911
1026
  import_log4.log.warn("object was rebound while a document was loading, discarding handle", logMeta, {
912
- F: __dxlog_file4,
913
- L: 204,
1027
+ F: __dxlog_file5,
1028
+ L: 213,
914
1029
  S: this,
915
1030
  C: (f, a) => f(...a)
916
1031
  });
@@ -928,8 +1043,8 @@ var AutomergeDocumentLoaderImpl = class {
928
1043
  retryLoading: shouldRetryLoading,
929
1044
  err
930
1045
  }, {
931
- F: __dxlog_file4,
932
- L: 210,
1046
+ F: __dxlog_file5,
1047
+ L: 219,
933
1048
  S: this,
934
1049
  C: (f, a) => f(...a)
935
1050
  });
@@ -939,6 +1054,24 @@ var AutomergeDocumentLoaderImpl = class {
939
1054
  }
940
1055
  }
941
1056
  };
1057
+ _ts_decorate2([
1058
+ import_tracing2.trace.span({
1059
+ showInBrowserTimeline: true
1060
+ })
1061
+ ], AutomergeDocumentLoaderImpl.prototype, "loadSpaceRootDocHandle", null);
1062
+ AutomergeDocumentLoaderImpl = _ts_decorate2([
1063
+ import_tracing2.trace.resource()
1064
+ ], AutomergeDocumentLoaderImpl);
1065
+ var REFERENCE_TYPE_TAG = "dxos.echo.model.document.Reference";
1066
+ var encodeReference = (reference) => ({
1067
+ "@type": REFERENCE_TYPE_TAG,
1068
+ // NOTE: Automerge do not support undefined values, so we need to use null instead.
1069
+ itemId: reference.itemId ?? null,
1070
+ protocol: reference.protocol ?? null,
1071
+ host: reference.host ?? null
1072
+ });
1073
+ var decodeReference = (value) => new import_echo_schema.Reference(value.itemId, value.protocol ?? void 0, value.host ?? void 0);
1074
+ var isEncodedReferenceObject = (value) => typeof value === "object" && value !== null && value["@type"] === REFERENCE_TYPE_TAG;
942
1075
  // Annotate the CommonJS export names for ESM import in node:
943
1076
  0 && (module.exports = {
944
1077
  AuthExtension,
@@ -947,12 +1080,14 @@ var AutomergeDocumentLoaderImpl = class {
947
1080
  AutomergeHost,
948
1081
  AutomergeStorageAdapter,
949
1082
  DataServiceImpl,
1083
+ LevelDBStorageAdapter,
950
1084
  LocalHostNetworkAdapter,
951
1085
  MOCK_AUTH_PROVIDER,
952
1086
  MOCK_AUTH_VERIFIER,
953
1087
  MeshNetworkAdapter,
954
1088
  MetadataStore,
955
1089
  Pipeline,
1090
+ REFERENCE_TYPE_TAG,
956
1091
  SnapshotManager,
957
1092
  SnapshotStore,
958
1093
  Space,
@@ -962,7 +1097,12 @@ var AutomergeDocumentLoaderImpl = class {
962
1097
  TimeframeClock,
963
1098
  codec,
964
1099
  createMappedFeedWriter,
1100
+ decodeReference,
1101
+ encodeReference,
1102
+ encodingOptions,
965
1103
  getSpaceKeyFromDoc,
1104
+ hasInvitationExpired,
1105
+ isEncodedReferenceObject,
966
1106
  mapFeedIndexesToTimeframe,
967
1107
  mapTimeframeToFeedIndexes,
968
1108
  startAfter,