@dxos/echo-pipeline 0.4.10-main.c32f430 → 0.4.10-main.ccba876

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-RTEEJ723.mjs → chunk-SYE4EK33.mjs} +30 -35
  2. package/dist/lib/browser/chunk-SYE4EK33.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +279 -159
  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 +8 -2
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node/{chunk-7VZVCCNF.cjs → chunk-WCTX6RNS.cjs} +35 -40
  9. package/dist/lib/node/chunk-WCTX6RNS.cjs.map +7 -0
  10. package/dist/lib/node/index.cjs +285 -168
  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 +18 -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 +20 -10
  18. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  19. package/dist/types/src/automerge/index.d.ts +1 -0
  20. package/dist/types/src/automerge/index.d.ts.map +1 -1
  21. package/dist/types/src/automerge/level.test.d.ts +2 -0
  22. package/dist/types/src/automerge/level.test.d.ts.map +1 -0
  23. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +27 -0
  24. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -0
  25. package/dist/types/src/automerge/migrations.d.ts +7 -0
  26. package/dist/types/src/automerge/migrations.d.ts.map +1 -0
  27. package/dist/types/src/automerge/reference.d.ts +15 -0
  28. package/dist/types/src/automerge/reference.d.ts.map +1 -0
  29. package/dist/types/src/automerge/storage-adapter.test.d.ts +2 -0
  30. package/dist/types/src/automerge/storage-adapter.test.d.ts.map +1 -0
  31. package/dist/types/src/automerge/types.d.ts +7 -2
  32. package/dist/types/src/automerge/types.d.ts.map +1 -1
  33. package/dist/types/src/metadata/metadata-store.d.ts +2 -1
  34. package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
  35. package/dist/types/src/space/space.d.ts +4 -8
  36. package/dist/types/src/space/space.d.ts.map +1 -1
  37. package/dist/types/src/testing/index.d.ts +1 -0
  38. package/dist/types/src/testing/index.d.ts.map +1 -1
  39. package/dist/types/src/testing/level.d.ts +3 -0
  40. package/dist/types/src/testing/level.d.ts.map +1 -0
  41. package/dist/types/src/testing/test-agent-builder.d.ts +2 -2
  42. package/package.json +33 -30
  43. package/src/automerge/automerge-doc-loader.ts +6 -0
  44. package/src/automerge/automerge-host.test.ts +19 -5
  45. package/src/automerge/automerge-host.ts +52 -33
  46. package/src/automerge/index.ts +1 -0
  47. package/src/automerge/level.test.ts +43 -0
  48. package/src/automerge/leveldb-storage-adapter.ts +105 -0
  49. package/src/automerge/migrations.ts +41 -0
  50. package/src/automerge/reference.ts +31 -0
  51. package/src/automerge/storage-adapter.test.ts +90 -0
  52. package/src/automerge/types.ts +7 -5
  53. package/src/db-host/data-service.ts +1 -1
  54. package/src/metadata/metadata-store.ts +17 -8
  55. package/src/space/space.test.ts +7 -7
  56. package/src/space/space.ts +6 -21
  57. package/src/testing/index.ts +1 -0
  58. package/src/testing/level.ts +11 -0
  59. package/dist/lib/browser/chunk-RTEEJ723.mjs.map +0 -7
  60. package/dist/lib/node/chunk-7VZVCCNF.cjs.map +0 -7
@@ -18,46 +18,48 @@ 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_WCTX6RNS.AuthExtension,
22
+ AuthStatus: () => import_chunk_WCTX6RNS.AuthStatus,
23
23
  AutomergeDocumentLoaderImpl: () => AutomergeDocumentLoaderImpl,
24
24
  AutomergeHost: () => AutomergeHost,
25
25
  AutomergeStorageAdapter: () => AutomergeStorageAdapter,
26
- DataServiceImpl: () => import_chunk_7VZVCCNF.DataServiceImpl,
26
+ DataServiceImpl: () => import_chunk_WCTX6RNS.DataServiceImpl,
27
27
  LocalHostNetworkAdapter: () => LocalHostNetworkAdapter,
28
- MOCK_AUTH_PROVIDER: () => import_chunk_7VZVCCNF.MOCK_AUTH_PROVIDER,
29
- MOCK_AUTH_VERIFIER: () => import_chunk_7VZVCCNF.MOCK_AUTH_VERIFIER,
28
+ MOCK_AUTH_PROVIDER: () => import_chunk_WCTX6RNS.MOCK_AUTH_PROVIDER,
29
+ MOCK_AUTH_VERIFIER: () => import_chunk_WCTX6RNS.MOCK_AUTH_VERIFIER,
30
30
  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,
31
+ MetadataStore: () => import_chunk_WCTX6RNS.MetadataStore,
32
+ Pipeline: () => import_chunk_WCTX6RNS.Pipeline,
33
+ REFERENCE_TYPE_TAG: () => REFERENCE_TYPE_TAG,
34
+ SnapshotManager: () => import_chunk_WCTX6RNS.SnapshotManager,
35
+ SnapshotStore: () => import_chunk_WCTX6RNS.SnapshotStore,
36
+ Space: () => import_chunk_WCTX6RNS.Space,
37
+ SpaceManager: () => import_chunk_WCTX6RNS.SpaceManager,
38
+ SpaceProtocol: () => import_chunk_WCTX6RNS.SpaceProtocol,
39
+ SpaceProtocolSession: () => import_chunk_WCTX6RNS.SpaceProtocolSession,
40
+ TimeframeClock: () => import_chunk_WCTX6RNS.TimeframeClock,
41
+ codec: () => import_chunk_WCTX6RNS.codec,
42
+ createMappedFeedWriter: () => import_chunk_WCTX6RNS.createMappedFeedWriter,
43
+ decodeReference: () => decodeReference,
44
+ encodeReference: () => encodeReference,
42
45
  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
46
+ hasInvitationExpired: () => import_chunk_WCTX6RNS.hasInvitationExpired,
47
+ isEncodedReferenceObject: () => isEncodedReferenceObject,
48
+ mapFeedIndexesToTimeframe: () => import_chunk_WCTX6RNS.mapFeedIndexesToTimeframe,
49
+ mapTimeframeToFeedIndexes: () => import_chunk_WCTX6RNS.mapTimeframeToFeedIndexes,
50
+ startAfter: () => import_chunk_WCTX6RNS.startAfter,
51
+ valueEncoding: () => import_chunk_WCTX6RNS.valueEncoding
47
52
  });
48
53
  module.exports = __toCommonJS(node_exports);
49
- var import_chunk_7VZVCCNF = require("./chunk-7VZVCCNF.cjs");
54
+ var import_chunk_WCTX6RNS = require("./chunk-WCTX6RNS.cjs");
50
55
  var import_automerge = require("@dxos/automerge/automerge");
51
56
  var import_automerge_repo = require("@dxos/automerge/automerge-repo");
52
- var import_automerge_repo_storage_indexeddb = require("@dxos/automerge/automerge-repo-storage-indexeddb");
53
57
  var import_context = require("@dxos/context");
54
58
  var import_keys = require("@dxos/keys");
55
59
  var import_log = require("@dxos/log");
56
60
  var import_protocols = require("@dxos/protocols");
57
- var import_random_access_storage = require("@dxos/random-access-storage");
58
61
  var import_tracing = require("@dxos/tracing");
59
62
  var import_util = require("@dxos/util");
60
- var import_util2 = require("@dxos/util");
61
63
  var import_async = require("@dxos/async");
62
64
  var import_automerge_repo2 = require("@dxos/automerge/automerge-repo");
63
65
  var import_codec_protobuf = require("@dxos/codec-protobuf");
@@ -68,111 +70,97 @@ var import_automerge_repo3 = require("@dxos/automerge/automerge-repo");
68
70
  var import_invariant2 = require("@dxos/invariant");
69
71
  var import_log3 = require("@dxos/log");
70
72
  var import_teleport_extension_automerge_replicator = require("@dxos/teleport-extension-automerge-replicator");
73
+ var import_automerge_repo_storage_indexeddb = require("@dxos/automerge/automerge-repo-storage-indexeddb");
74
+ var import_log4 = require("@dxos/log");
75
+ var import_random_access_storage = require("@dxos/random-access-storage");
76
+ var import_util2 = require("@dxos/util");
71
77
  var import_async3 = require("@dxos/async");
72
78
  var import_context2 = require("@dxos/context");
73
79
  var import_debug = require("@dxos/debug");
74
80
  var import_invariant3 = require("@dxos/invariant");
75
- var import_log4 = require("@dxos/log");
76
- var AutomergeStorageAdapter = class {
77
- constructor(_directory) {
78
- this._directory = _directory;
81
+ var import_log5 = require("@dxos/log");
82
+ var import_echo_db = require("@dxos/echo-db");
83
+ var LevelDBStorageAdapter = class {
84
+ constructor(_params) {
85
+ this._params = _params;
79
86
  this._state = "opened";
80
87
  }
81
- async load(key) {
88
+ async load(keyArray) {
82
89
  if (this._state !== "opened") {
83
90
  return void 0;
84
91
  }
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;
90
- }
91
- const buffer = await file.read(0, size);
92
- return (0, import_util2.bufferToArray)(buffer);
92
+ return this._params.db.get(keyArray, {
93
+ ...encodingOptions
94
+ }).catch((err) => err.code === "LEVEL_NOT_FOUND" ? void 0 : Promise.reject(err));
93
95
  }
94
- async save(key, data) {
96
+ async save(keyArray, binary) {
95
97
  if (this._state !== "opened") {
96
98
  return void 0;
97
99
  }
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?.();
100
+ await this._params.callbacks?.beforeSave?.(keyArray);
101
+ await this._params.db.put(keyArray, Buffer.from(binary), {
102
+ ...encodingOptions
103
+ });
104
+ await this._params.callbacks?.afterSave?.(keyArray);
103
105
  }
104
- async remove(key) {
106
+ async remove(keyArray) {
105
107
  if (this._state !== "opened") {
106
108
  return void 0;
107
109
  }
108
- const filename = this._getFilename(key);
109
- const file = this._directory.getOrCreateFile(filename);
110
- await file.destroy();
110
+ await this._params.db.del(keyArray, {
111
+ ...encodingOptions
112
+ });
111
113
  }
112
114
  async loadRange(keyPrefix) {
113
115
  if (this._state !== "opened") {
114
116
  return [];
115
117
  }
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
- }));
118
+ const result = [];
119
+ for await (const [key, value] of this._params.db.iterator({
120
+ gte: keyPrefix,
121
+ lte: [
122
+ ...keyPrefix,
123
+ "\uFFFF"
124
+ ],
125
+ ...encodingOptions
126
+ })) {
127
+ result.push({
128
+ key,
129
+ data: value
130
+ });
131
+ }
132
+ return result;
127
133
  }
128
134
  async removeRange(keyPrefix) {
129
135
  if (this._state !== "opened") {
130
136
  return void 0;
131
137
  }
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
+ const batch = this._params.db.batch();
139
+ for await (const [key] of this._params.db.iterator({
140
+ gte: keyPrefix,
141
+ lte: [
142
+ ...keyPrefix,
143
+ "\uFFFF"
144
+ ],
145
+ ...encodingOptions
146
+ })) {
147
+ batch.del(key, {
148
+ ...encodingOptions
149
+ });
150
+ }
151
+ await batch.write();
138
152
  }
139
- async close() {
153
+ close() {
140
154
  this._state = "closed";
141
155
  }
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
156
  };
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();
174
- }
175
- }
157
+ var keyEncoder = {
158
+ encode: (key) => Buffer.from(key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-")),
159
+ decode: (key) => Buffer.from(key).toString().split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"))
160
+ };
161
+ var encodingOptions = {
162
+ keyEncoding: keyEncoder,
163
+ valueEncoding: "buffer"
176
164
  };
177
165
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts";
178
166
  var LocalHostNetworkAdapter = class extends import_automerge_repo2.NetworkAdapter {
@@ -392,6 +380,108 @@ var MeshNetworkAdapter = class extends import_automerge_repo3.NetworkAdapter {
392
380
  return extension;
393
381
  }
394
382
  };
383
+ var AutomergeStorageAdapter = class {
384
+ constructor(_directory) {
385
+ this._directory = _directory;
386
+ this._state = "opened";
387
+ }
388
+ async load(key) {
389
+ if (this._state !== "opened") {
390
+ return void 0;
391
+ }
392
+ const filename = this._getFilename(key);
393
+ const file = this._directory.getOrCreateFile(filename);
394
+ const { size } = await file.stat();
395
+ if (!size || size === 0) {
396
+ return void 0;
397
+ }
398
+ const buffer = await file.read(0, size);
399
+ return (0, import_util2.bufferToArray)(buffer);
400
+ }
401
+ async save(key, data) {
402
+ if (this._state !== "opened") {
403
+ return void 0;
404
+ }
405
+ const filename = this._getFilename(key);
406
+ const file = this._directory.getOrCreateFile(filename);
407
+ await file.write(0, (0, import_util2.arrayToBuffer)(data));
408
+ await file.truncate?.(data.length);
409
+ await file.flush?.();
410
+ }
411
+ async remove(key) {
412
+ if (this._state !== "opened") {
413
+ return void 0;
414
+ }
415
+ const filename = this._getFilename(key);
416
+ const file = this._directory.getOrCreateFile(filename);
417
+ await file.destroy();
418
+ }
419
+ async loadRange(keyPrefix) {
420
+ if (this._state !== "opened") {
421
+ return [];
422
+ }
423
+ const filename = this._getFilename(keyPrefix);
424
+ const entries = await this._directory.list();
425
+ return Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
426
+ const file = this._directory.getOrCreateFile(entry);
427
+ const { size } = await file.stat();
428
+ const buffer = await file.read(0, size);
429
+ return {
430
+ key: this._getKeyFromFilename(entry),
431
+ data: (0, import_util2.bufferToArray)(buffer)
432
+ };
433
+ }));
434
+ }
435
+ async removeRange(keyPrefix) {
436
+ if (this._state !== "opened") {
437
+ return void 0;
438
+ }
439
+ const filename = this._getFilename(keyPrefix);
440
+ const entries = await this._directory.list();
441
+ await Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
442
+ const file = this._directory.getOrCreateFile(entry);
443
+ await file.destroy();
444
+ }));
445
+ }
446
+ async close() {
447
+ this._state = "closed";
448
+ }
449
+ _getFilename(key) {
450
+ return key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-");
451
+ }
452
+ _getKeyFromFilename(filename) {
453
+ return filename.split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"));
454
+ }
455
+ };
456
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/migrations.ts";
457
+ var levelMigration = async ({ db, directory }) => {
458
+ const isNewLevel = !await db.iterator({
459
+ ...encodingOptions
460
+ }).next();
461
+ if (!isNewLevel) {
462
+ return;
463
+ }
464
+ const oldStorageAdapter = directory.type === import_random_access_storage.StorageType.IDB ? new import_automerge_repo_storage_indexeddb.IndexedDBStorageAdapter(directory.path, "data") : new AutomergeStorageAdapter(directory);
465
+ const chunks = await oldStorageAdapter.loadRange([]);
466
+ if (chunks.length === 0) {
467
+ return;
468
+ }
469
+ const batch = db.batch();
470
+ import_log4.log.info("found chunks on old storage adapter", {
471
+ chunks: chunks.length
472
+ }, {
473
+ F: __dxlog_file3,
474
+ L: 36,
475
+ S: void 0,
476
+ C: (f, a) => f(...a)
477
+ });
478
+ for (const { key, data } of await oldStorageAdapter.loadRange([])) {
479
+ data && batch.put(key, data, {
480
+ ...encodingOptions
481
+ });
482
+ }
483
+ await batch.write();
484
+ };
395
485
  function _ts_decorate(decorators, target, key, desc) {
396
486
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
397
487
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
@@ -402,26 +492,31 @@ function _ts_decorate(decorators, target, key, desc) {
402
492
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
403
493
  return c > 3 && r && Object.defineProperty(target, key, r), r;
404
494
  }
405
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
495
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
406
496
  var AutomergeHost = class {
407
- constructor({ directory, metadata }) {
497
+ constructor({ directory, db, metadata }) {
408
498
  this._ctx = new import_context.Context();
409
499
  this._authorizedDevices = new import_util.ComplexMap(import_keys.PublicKey.hash);
410
500
  this._updatingMetadata = /* @__PURE__ */ new Map();
411
501
  this._requestedDocs = /* @__PURE__ */ new Set();
502
+ this._directory = directory;
503
+ this._db = db;
412
504
  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
- ),
505
+ }
506
+ async open() {
507
+ this._directory && await levelMigration({
508
+ db: await this._db,
509
+ directory: this._directory
510
+ });
511
+ this._storage = new LevelDBStorageAdapter({
512
+ db: await this._db,
420
513
  callbacks: {
421
514
  beforeSave: (params) => this._beforeSave(params)
422
515
  }
423
516
  });
424
517
  this._peerId = `host-${import_keys.PublicKey.random().toHex()}`;
518
+ this._meshNetwork = new MeshNetworkAdapter();
519
+ this._clientNetwork = new LocalHostNetworkAdapter();
425
520
  this._repo = new import_automerge_repo.Repo({
426
521
  peerId: this._peerId,
427
522
  network: [
@@ -446,8 +541,8 @@ var AutomergeHost = class {
446
541
  documentId,
447
542
  isRequested
448
543
  }, {
449
- F: __dxlog_file3,
450
- L: 96,
544
+ F: __dxlog_file4,
545
+ L: 111,
451
546
  S: this,
452
547
  C: (f, a) => f(...a)
453
548
  });
@@ -460,8 +555,8 @@ var AutomergeHost = class {
460
555
  peerId,
461
556
  documentId
462
557
  }, {
463
- F: __dxlog_file3,
464
- L: 103,
558
+ F: __dxlog_file4,
559
+ L: 118,
465
560
  S: this,
466
561
  C: (f, a) => f(...a)
467
562
  });
@@ -474,8 +569,8 @@ var AutomergeHost = class {
474
569
  peerId,
475
570
  documentId
476
571
  }, {
477
- F: __dxlog_file3,
478
- L: 112,
572
+ F: __dxlog_file4,
573
+ L: 127,
479
574
  S: this,
480
575
  C: (f, a) => f(...a)
481
576
  });
@@ -491,16 +586,16 @@ var AutomergeHost = class {
491
586
  spaceKey,
492
587
  isAuthorized
493
588
  }, {
494
- F: __dxlog_file3,
495
- L: 118,
589
+ F: __dxlog_file4,
590
+ L: 133,
496
591
  S: this,
497
592
  C: (f, a) => f(...a)
498
593
  });
499
594
  return isAuthorized;
500
595
  } catch (err) {
501
596
  import_log.log.catch(err, void 0, {
502
- F: __dxlog_file3,
503
- L: 128,
597
+ F: __dxlog_file4,
598
+ L: 143,
504
599
  S: this,
505
600
  C: (f, a) => f(...a)
506
601
  });
@@ -515,9 +610,15 @@ var AutomergeHost = class {
515
610
  this._repo.on("document", listener);
516
611
  this._ctx.onDispose(() => {
517
612
  this._repo.off("document", listener);
613
+ Object.values(this._repo.handles).forEach((handle) => handle.off("change"));
518
614
  });
519
615
  }
520
616
  }
617
+ async close() {
618
+ this._storage.close?.();
619
+ await this._clientNetwork.close();
620
+ await this._ctx.dispose();
621
+ }
521
622
  get repo() {
522
623
  return this._repo;
523
624
  }
@@ -530,9 +631,6 @@ var AutomergeHost = class {
530
631
  _onDocument(handle) {
531
632
  const listener = (event) => this._onUpdate(event);
532
633
  handle.on("change", listener);
533
- this._ctx.onDispose(() => {
534
- handle.off("change", listener);
535
- });
536
634
  }
537
635
  _onUpdate(event) {
538
636
  if (this._metadata == null) {
@@ -559,8 +657,8 @@ var AutomergeHost = class {
559
657
  this._updatingMetadata.delete(event.handle.documentId);
560
658
  }).catch((err) => {
561
659
  this._ctx.disposed && import_log.log.catch(err, void 0, {
562
- F: __dxlog_file3,
563
- L: 188,
660
+ F: __dxlog_file4,
661
+ L: 207,
564
662
  S: this,
565
663
  C: (f, a) => f(...a)
566
664
  });
@@ -572,7 +670,7 @@ var AutomergeHost = class {
572
670
  state: handle.state,
573
671
  hasDoc: !!handle.docSync(),
574
672
  heads: handle.docSync() ? import_automerge.next.getHeads(handle.docSync()) : null,
575
- data: handle.docSync()?.doc && (0, import_util.mapValues)(handle.docSync()?.doc, (value, key) => {
673
+ data: handle.docSync() && (0, import_util.mapValues)(handle.docSync(), (value, key) => {
576
674
  try {
577
675
  switch (key) {
578
676
  case "access":
@@ -592,14 +690,13 @@ var AutomergeHost = class {
592
690
  _automergePeers() {
593
691
  return this._repo.peers;
594
692
  }
595
- async close() {
596
- await this._storage.close();
597
- await this._clientNetwork.close();
598
- await this._ctx.dispose();
599
- }
600
693
  //
601
694
  // Methods for client-services.
602
695
  //
696
+ async flush({ documentIds }) {
697
+ await Promise.all(documentIds?.map((id) => this._repo.find(id).whenReady()) ?? []);
698
+ await this._repo.flush(documentIds);
699
+ }
603
700
  syncRepo(request) {
604
701
  return this._clientNetwork.syncRepo(request);
605
702
  }
@@ -620,8 +717,8 @@ var AutomergeHost = class {
620
717
  spaceKey,
621
718
  deviceKey
622
719
  }, {
623
- F: __dxlog_file3,
624
- L: 255,
720
+ F: __dxlog_file4,
721
+ L: 274,
625
722
  S: this,
626
723
  C: (f, a) => f(...a)
627
724
  });
@@ -669,7 +766,7 @@ var getSpaceKeyFromDoc = (doc) => {
669
766
  }
670
767
  return String(rawSpaceKey);
671
768
  };
672
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
769
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
673
770
  var AutomergeDocumentLoaderImpl = class {
674
771
  constructor(_spaceKey, _repo) {
675
772
  this._spaceKey = _spaceKey;
@@ -679,16 +776,21 @@ var AutomergeDocumentLoaderImpl = class {
679
776
  this._objectsPendingDocumentLoad = /* @__PURE__ */ new Set();
680
777
  this.onObjectDocumentLoaded = new import_async3.Event();
681
778
  }
779
+ getAllHandles() {
780
+ return [
781
+ ...new Set(this._objectDocumentHandles.values())
782
+ ];
783
+ }
682
784
  async loadSpaceRootDocHandle(ctx, spaceState) {
683
785
  if (this._spaceRootDocHandle != null) {
684
786
  return;
685
787
  }
686
788
  if (!spaceState.rootUrl) {
687
- import_log4.log.error("Database opened with no rootUrl", {
789
+ import_log5.log.error("Database opened with no rootUrl", {
688
790
  spaceKey: this._spaceKey
689
791
  }, {
690
- F: __dxlog_file4,
691
- L: 60,
792
+ F: __dxlog_file5,
793
+ L: 66,
692
794
  S: this,
693
795
  C: (f, a) => f(...a)
694
796
  });
@@ -697,8 +799,8 @@ var AutomergeDocumentLoaderImpl = class {
697
799
  const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);
698
800
  const doc = existingDocHandle.docSync();
699
801
  (0, import_invariant3.invariant)(doc, void 0, {
700
- F: __dxlog_file4,
701
- L: 65,
802
+ F: __dxlog_file5,
803
+ L: 71,
702
804
  S: this,
703
805
  A: [
704
806
  "doc",
@@ -713,8 +815,8 @@ var AutomergeDocumentLoaderImpl = class {
713
815
  }
714
816
  loadObjectDocument(objectId) {
715
817
  (0, import_invariant3.invariant)(this._spaceRootDocHandle, void 0, {
716
- F: __dxlog_file4,
717
- L: 74,
818
+ F: __dxlog_file5,
819
+ L: 80,
718
820
  S: this,
719
821
  A: [
720
822
  "this._spaceRootDocHandle",
@@ -726,8 +828,8 @@ var AutomergeDocumentLoaderImpl = class {
726
828
  }
727
829
  const spaceRootDoc = this._spaceRootDocHandle.docSync();
728
830
  (0, import_invariant3.invariant)(spaceRootDoc, void 0, {
729
- F: __dxlog_file4,
730
- L: 79,
831
+ F: __dxlog_file5,
832
+ L: 85,
731
833
  S: this,
732
834
  A: [
733
835
  "spaceRootDoc",
@@ -737,11 +839,11 @@ var AutomergeDocumentLoaderImpl = class {
737
839
  const documentUrl = (spaceRootDoc.links ?? {})[objectId];
738
840
  if (documentUrl == null) {
739
841
  this._objectsPendingDocumentLoad.add(objectId);
740
- import_log4.log.info("loading delayed until object links are initialized", {
842
+ import_log5.log.info("loading delayed until object links are initialized", {
741
843
  objectId
742
844
  }, {
743
- F: __dxlog_file4,
744
- L: 83,
845
+ F: __dxlog_file5,
846
+ L: 89,
745
847
  S: this,
746
848
  C: (f, a) => f(...a)
747
849
  });
@@ -761,8 +863,8 @@ var AutomergeDocumentLoaderImpl = class {
761
863
  }
762
864
  getSpaceRootDocHandle() {
763
865
  (0, import_invariant3.invariant)(this._spaceRootDocHandle, void 0, {
764
- F: __dxlog_file4,
765
- L: 101,
866
+ F: __dxlog_file5,
867
+ L: 107,
766
868
  S: this,
767
869
  A: [
768
870
  "this._spaceRootDocHandle",
@@ -773,8 +875,8 @@ var AutomergeDocumentLoaderImpl = class {
773
875
  }
774
876
  createDocumentForObject(objectId) {
775
877
  (0, import_invariant3.invariant)(this._spaceRootDocHandle, void 0, {
776
- F: __dxlog_file4,
777
- L: 106,
878
+ F: __dxlog_file5,
879
+ L: 112,
778
880
  S: this,
779
881
  A: [
780
882
  "this._spaceRootDocHandle",
@@ -812,30 +914,30 @@ var AutomergeDocumentLoaderImpl = class {
812
914
  };
813
915
  const objectDocumentHandle = this._objectDocumentHandles.get(objectId);
814
916
  if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {
815
- import_log4.log.warn("object already inlined in a different document, ignoring the link", {
917
+ import_log5.log.warn("object already inlined in a different document, ignoring the link", {
816
918
  ...logMeta,
817
919
  actualDocumentUrl: objectDocumentHandle.url
818
920
  }, {
819
- F: __dxlog_file4,
820
- L: 136,
921
+ F: __dxlog_file5,
922
+ L: 142,
821
923
  S: this,
822
924
  C: (f, a) => f(...a)
823
925
  });
824
926
  continue;
825
927
  }
826
928
  if (objectDocumentHandle?.url === automergeUrl) {
827
- import_log4.log.warn("object document was already loaded", logMeta, {
828
- F: __dxlog_file4,
829
- L: 143,
929
+ import_log5.log.warn("object document was already loaded", logMeta, {
930
+ F: __dxlog_file5,
931
+ L: 149,
830
932
  S: this,
831
933
  C: (f, a) => f(...a)
832
934
  });
833
935
  continue;
834
936
  }
835
937
  const handle = this._repo.find(automergeUrl);
836
- import_log4.log.debug("document loading triggered", logMeta, {
837
- F: __dxlog_file4,
838
- L: 147,
938
+ import_log5.log.debug("document loading triggered", logMeta, {
939
+ F: __dxlog_file5,
940
+ L: 153,
839
941
  S: this,
840
942
  C: (f, a) => f(...a)
841
943
  });
@@ -853,12 +955,12 @@ var AutomergeDocumentLoaderImpl = class {
853
955
  break;
854
956
  } catch (err) {
855
957
  if (`${err}`.includes("Timeout")) {
856
- import_log4.log.info("wraparound", {
958
+ import_log5.log.info("wraparound", {
857
959
  id: docHandle.documentId,
858
960
  state: docHandle.state
859
961
  }, {
860
- F: __dxlog_file4,
861
- L: 163,
962
+ F: __dxlog_file5,
963
+ L: 169,
862
964
  S: this,
863
965
  C: (f, a) => f(...a)
864
966
  });
@@ -898,9 +1000,9 @@ var AutomergeDocumentLoaderImpl = class {
898
1000
  docUrl: handle.url
899
1001
  };
900
1002
  if (this.onObjectDocumentLoaded.listenerCount() === 0) {
901
- import_log4.log.info("document loaded after all listeners were removed", logMeta, {
902
- F: __dxlog_file4,
903
- L: 199,
1003
+ import_log5.log.info("document loaded after all listeners were removed", logMeta, {
1004
+ F: __dxlog_file5,
1005
+ L: 205,
904
1006
  S: this,
905
1007
  C: (f, a) => f(...a)
906
1008
  });
@@ -908,9 +1010,9 @@ var AutomergeDocumentLoaderImpl = class {
908
1010
  }
909
1011
  const objectDocHandle = this._objectDocumentHandles.get(objectId);
910
1012
  if (objectDocHandle?.url !== handle.url) {
911
- import_log4.log.warn("object was rebound while a document was loading, discarding handle", logMeta, {
912
- F: __dxlog_file4,
913
- L: 204,
1013
+ import_log5.log.warn("object was rebound while a document was loading, discarding handle", logMeta, {
1014
+ F: __dxlog_file5,
1015
+ L: 210,
914
1016
  S: this,
915
1017
  C: (f, a) => f(...a)
916
1018
  });
@@ -922,14 +1024,14 @@ var AutomergeDocumentLoaderImpl = class {
922
1024
  });
923
1025
  } catch (err) {
924
1026
  const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;
925
- import_log4.log.warn("failed to load a document", {
1027
+ import_log5.log.warn("failed to load a document", {
926
1028
  objectId,
927
1029
  automergeUrl: handle.url,
928
1030
  retryLoading: shouldRetryLoading,
929
1031
  err
930
1032
  }, {
931
- F: __dxlog_file4,
932
- L: 210,
1033
+ F: __dxlog_file5,
1034
+ L: 216,
933
1035
  S: this,
934
1036
  C: (f, a) => f(...a)
935
1037
  });
@@ -939,6 +1041,16 @@ var AutomergeDocumentLoaderImpl = class {
939
1041
  }
940
1042
  }
941
1043
  };
1044
+ var REFERENCE_TYPE_TAG = "dxos.echo.model.document.Reference";
1045
+ var encodeReference = (reference) => ({
1046
+ "@type": REFERENCE_TYPE_TAG,
1047
+ // NOTE: Automerge do not support undefined values, so we need to use null instead.
1048
+ itemId: reference.itemId ?? null,
1049
+ protocol: reference.protocol ?? null,
1050
+ host: reference.host ?? null
1051
+ });
1052
+ var decodeReference = (value) => new import_echo_db.Reference(value.itemId, value.protocol ?? void 0, value.host ?? void 0);
1053
+ var isEncodedReferenceObject = (value) => typeof value === "object" && value !== null && value["@type"] === REFERENCE_TYPE_TAG;
942
1054
  // Annotate the CommonJS export names for ESM import in node:
943
1055
  0 && (module.exports = {
944
1056
  AuthExtension,
@@ -953,6 +1065,7 @@ var AutomergeDocumentLoaderImpl = class {
953
1065
  MeshNetworkAdapter,
954
1066
  MetadataStore,
955
1067
  Pipeline,
1068
+ REFERENCE_TYPE_TAG,
956
1069
  SnapshotManager,
957
1070
  SnapshotStore,
958
1071
  Space,
@@ -962,7 +1075,11 @@ var AutomergeDocumentLoaderImpl = class {
962
1075
  TimeframeClock,
963
1076
  codec,
964
1077
  createMappedFeedWriter,
1078
+ decodeReference,
1079
+ encodeReference,
965
1080
  getSpaceKeyFromDoc,
1081
+ hasInvitationExpired,
1082
+ isEncodedReferenceObject,
966
1083
  mapFeedIndexesToTimeframe,
967
1084
  mapTimeframeToFeedIndexes,
968
1085
  startAfter,