@dxos/echo-pipeline 0.4.8-next.fff1521 → 0.4.9-main.1057b49

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 (64) hide show
  1. package/dist/lib/browser/{chunk-3FVT6KX6.mjs → chunk-RTEEJ723.mjs} +289 -1807
  2. package/dist/lib/browser/chunk-RTEEJ723.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +633 -14
  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 +4 -332
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/node/chunk-7VZVCCNF.cjs +1948 -0
  9. package/dist/lib/node/chunk-7VZVCCNF.cjs.map +7 -0
  10. package/dist/lib/node/index.cjs +643 -34
  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 -338
  14. package/dist/lib/node/testing/index.cjs.map +4 -4
  15. package/dist/types/src/db-host/data-service.d.ts +3 -13
  16. package/dist/types/src/db-host/data-service.d.ts.map +1 -1
  17. package/dist/types/src/db-host/index.d.ts +0 -2
  18. package/dist/types/src/db-host/index.d.ts.map +1 -1
  19. package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
  20. package/dist/types/src/space/index.d.ts +0 -1
  21. package/dist/types/src/space/index.d.ts.map +1 -1
  22. package/dist/types/src/space/space-manager.d.ts +1 -4
  23. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  24. package/dist/types/src/space/space.d.ts +1 -7
  25. package/dist/types/src/space/space.d.ts.map +1 -1
  26. package/dist/types/src/testing/index.d.ts +0 -2
  27. package/dist/types/src/testing/index.d.ts.map +1 -1
  28. package/dist/types/src/testing/test-agent-builder.d.ts +1 -3
  29. package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
  30. package/package.json +30 -33
  31. package/src/automerge/automerge-host.ts +1 -1
  32. package/src/db-host/data-service.ts +10 -56
  33. package/src/db-host/index.ts +0 -2
  34. package/src/space/control-pipeline.ts +3 -1
  35. package/src/space/index.ts +0 -1
  36. package/src/space/space-manager.ts +1 -13
  37. package/src/space/space.test.ts +2 -112
  38. package/src/space/space.ts +2 -60
  39. package/src/testing/index.ts +0 -2
  40. package/src/testing/test-agent-builder.ts +3 -8
  41. package/dist/lib/browser/chunk-3FVT6KX6.mjs.map +0 -7
  42. package/dist/lib/node/chunk-WZ4WTAN6.cjs +0 -3454
  43. package/dist/lib/node/chunk-WZ4WTAN6.cjs.map +0 -7
  44. package/dist/types/src/db-host/data-service-host.d.ts +0 -38
  45. package/dist/types/src/db-host/data-service-host.d.ts.map +0 -1
  46. package/dist/types/src/db-host/database-host.d.ts +0 -27
  47. package/dist/types/src/db-host/database-host.d.ts.map +0 -1
  48. package/dist/types/src/space/data-pipeline.d.ts +0 -80
  49. package/dist/types/src/space/data-pipeline.d.ts.map +0 -1
  50. package/dist/types/src/space/data-pipeline.test.d.ts +0 -1
  51. package/dist/types/src/space/data-pipeline.test.d.ts.map +0 -1
  52. package/dist/types/src/testing/database-test-rig.d.ts +0 -67
  53. package/dist/types/src/testing/database-test-rig.d.ts.map +0 -1
  54. package/dist/types/src/testing/util.d.ts +0 -14
  55. package/dist/types/src/testing/util.d.ts.map +0 -1
  56. package/dist/types/src/tests/database.test.d.ts +0 -2
  57. package/dist/types/src/tests/database.test.d.ts.map +0 -1
  58. package/src/db-host/data-service-host.ts +0 -233
  59. package/src/db-host/database-host.ts +0 -63
  60. package/src/space/data-pipeline.test.ts +0 -3
  61. package/src/space/data-pipeline.ts +0 -468
  62. package/src/testing/database-test-rig.ts +0 -289
  63. package/src/testing/util.ts +0 -85
  64. package/src/tests/database.test.ts +0 -100
@@ -2,17 +2,9 @@ import "@dxos/node-std/globals";
2
2
  import {
3
3
  AuthExtension,
4
4
  AuthStatus,
5
- AutomergeHost,
6
- AutomergeStorageAdapter,
7
- DataPipeline,
8
- DataServiceHost,
9
5
  DataServiceImpl,
10
- DataServiceSubscriptions,
11
- DatabaseHost,
12
- LocalHostNetworkAdapter,
13
6
  MOCK_AUTH_PROVIDER,
14
7
  MOCK_AUTH_VERIFIER,
15
- MeshNetworkAdapter,
16
8
  MetadataStore,
17
9
  Pipeline,
18
10
  SnapshotManager,
@@ -24,22 +16,649 @@ import {
24
16
  TimeframeClock,
25
17
  codec,
26
18
  createMappedFeedWriter,
27
- getSpaceKeyFromDoc,
28
19
  mapFeedIndexesToTimeframe,
29
20
  mapTimeframeToFeedIndexes,
30
21
  startAfter,
31
22
  valueEncoding
32
- } from "./chunk-3FVT6KX6.mjs";
23
+ } from "./chunk-RTEEJ723.mjs";
24
+
25
+ // packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
26
+ import { next as automerge, getHeads } from "@dxos/automerge/automerge";
27
+ import { Repo } from "@dxos/automerge/automerge-repo";
28
+ import { IndexedDBStorageAdapter } from "@dxos/automerge/automerge-repo-storage-indexeddb";
29
+ import { Context } from "@dxos/context";
30
+ import { PublicKey } from "@dxos/keys";
31
+ import { log as log3 } from "@dxos/log";
32
+ import { idCodec } from "@dxos/protocols";
33
+ import { StorageType } from "@dxos/random-access-storage";
34
+ import { trace } from "@dxos/tracing";
35
+ import { ComplexMap, ComplexSet, defaultMap, mapValues } from "@dxos/util";
36
+
37
+ // packages/core/echo/echo-pipeline/src/automerge/automerge-storage-adapter.ts
38
+ import { arrayToBuffer, bufferToArray } from "@dxos/util";
39
+ var AutomergeStorageAdapter = class {
40
+ constructor(_directory) {
41
+ this._directory = _directory;
42
+ this._state = "opened";
43
+ }
44
+ async load(key) {
45
+ if (this._state !== "opened") {
46
+ return void 0;
47
+ }
48
+ const filename = this._getFilename(key);
49
+ const file = this._directory.getOrCreateFile(filename);
50
+ const { size } = await file.stat();
51
+ if (!size || size === 0) {
52
+ return void 0;
53
+ }
54
+ const buffer = await file.read(0, size);
55
+ return bufferToArray(buffer);
56
+ }
57
+ async save(key, data) {
58
+ if (this._state !== "opened") {
59
+ return void 0;
60
+ }
61
+ const filename = this._getFilename(key);
62
+ const file = this._directory.getOrCreateFile(filename);
63
+ await file.write(0, arrayToBuffer(data));
64
+ await file.truncate?.(data.length);
65
+ await file.flush?.();
66
+ }
67
+ async remove(key) {
68
+ if (this._state !== "opened") {
69
+ return void 0;
70
+ }
71
+ const filename = this._getFilename(key);
72
+ const file = this._directory.getOrCreateFile(filename);
73
+ await file.destroy();
74
+ }
75
+ async loadRange(keyPrefix) {
76
+ if (this._state !== "opened") {
77
+ return [];
78
+ }
79
+ const filename = this._getFilename(keyPrefix);
80
+ const entries = await this._directory.list();
81
+ return Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
82
+ const file = this._directory.getOrCreateFile(entry);
83
+ const { size } = await file.stat();
84
+ const buffer = await file.read(0, size);
85
+ return {
86
+ key: this._getKeyFromFilename(entry),
87
+ data: bufferToArray(buffer)
88
+ };
89
+ }));
90
+ }
91
+ async removeRange(keyPrefix) {
92
+ if (this._state !== "opened") {
93
+ return void 0;
94
+ }
95
+ const filename = this._getFilename(keyPrefix);
96
+ const entries = await this._directory.list();
97
+ await Promise.all(entries.filter((entry) => entry.startsWith(filename)).map(async (entry) => {
98
+ const file = this._directory.getOrCreateFile(entry);
99
+ await file.destroy();
100
+ }));
101
+ }
102
+ async close() {
103
+ this._state = "closed";
104
+ }
105
+ _getFilename(key) {
106
+ return key.map((k) => k.replaceAll("%", "%25").replaceAll("-", "%2D")).join("-");
107
+ }
108
+ _getKeyFromFilename(filename) {
109
+ return filename.split("-").map((k) => k.replaceAll("%2D", "-").replaceAll("%25", "%"));
110
+ }
111
+ };
112
+
113
+ // packages/core/echo/echo-pipeline/src/automerge/automerge-storage–wrapper.ts
114
+ var AutomergeStorageWrapper = class {
115
+ constructor({ storage, callbacks }) {
116
+ this._storage = storage;
117
+ this._callbacks = callbacks;
118
+ }
119
+ async load(key) {
120
+ return this._storage.load(key);
121
+ }
122
+ async save(key, value) {
123
+ await this._callbacks.beforeSave?.(key);
124
+ await this._storage.save(key, value);
125
+ await this._callbacks.afterSave?.(key);
126
+ }
127
+ async remove(key) {
128
+ return this._storage.remove(key);
129
+ }
130
+ async loadRange(keyPrefix) {
131
+ return this._storage.loadRange(keyPrefix);
132
+ }
133
+ async removeRange(keyPrefix) {
134
+ return this._storage.removeRange(keyPrefix);
135
+ }
136
+ async close() {
137
+ if (this._storage instanceof AutomergeStorageAdapter) {
138
+ return this._storage.close();
139
+ }
140
+ }
141
+ };
142
+
143
+ // packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts
144
+ import { Trigger } from "@dxos/async";
145
+ import { NetworkAdapter, cbor } from "@dxos/automerge/automerge-repo";
146
+ import { Stream } from "@dxos/codec-protobuf";
147
+ import { invariant } from "@dxos/invariant";
148
+ import { log } from "@dxos/log";
149
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/local-host-network-adapter.ts";
150
+ var LocalHostNetworkAdapter = class extends NetworkAdapter {
151
+ constructor() {
152
+ super(...arguments);
153
+ this._peers = /* @__PURE__ */ new Map();
154
+ this._connected = new Trigger();
155
+ }
156
+ /**
157
+ * Emits `ready` event. That signals to `Repo` that it can start using the adapter.
158
+ */
159
+ ready() {
160
+ this.emit("ready", {
161
+ network: this
162
+ });
163
+ }
164
+ connect(peerId) {
165
+ this.peerId = peerId;
166
+ this._connected.wake();
167
+ }
168
+ send(message) {
169
+ const peer = this._peers.get(message.targetId);
170
+ invariant(peer, "Peer not found.", {
171
+ F: __dxlog_file,
172
+ L: 45,
173
+ S: this,
174
+ A: [
175
+ "peer",
176
+ "'Peer not found.'"
177
+ ]
178
+ });
179
+ peer.send(message);
180
+ }
181
+ async close() {
182
+ this._peers.forEach((peer) => peer.disconnect());
183
+ this.emit("close");
184
+ }
185
+ disconnect() {
186
+ }
187
+ syncRepo({ id, syncMessage }) {
188
+ const peerId = this._getPeerId(id);
189
+ return new Stream(({ next, close }) => {
190
+ invariant(!this._peers.has(peerId), "Peer already connected.", {
191
+ F: __dxlog_file,
192
+ L: 63,
193
+ S: this,
194
+ A: [
195
+ "!this._peers.has(peerId)",
196
+ "'Peer already connected.'"
197
+ ]
198
+ });
199
+ this._peers.set(peerId, {
200
+ connected: true,
201
+ send: (message) => {
202
+ next({
203
+ syncMessage: cbor.encode(message)
204
+ });
205
+ },
206
+ disconnect: () => {
207
+ this._peers.delete(peerId);
208
+ close();
209
+ this.emit("peer-disconnected", {
210
+ peerId
211
+ });
212
+ }
213
+ });
214
+ this._connected.wait({
215
+ timeout: 1e3
216
+ }).then(() => {
217
+ this.emit("peer-candidate", {
218
+ peerMetadata: {},
219
+ peerId
220
+ });
221
+ }).catch((err) => log.catch(err, void 0, {
222
+ F: __dxlog_file,
223
+ L: 88,
224
+ S: this,
225
+ C: (f, a) => f(...a)
226
+ }));
227
+ });
228
+ }
229
+ async sendSyncMessage({ id, syncMessage }) {
230
+ await this._connected.wait({
231
+ timeout: 1e3
232
+ });
233
+ const message = cbor.decode(syncMessage);
234
+ this.emit("message", message);
235
+ }
236
+ async getHostInfo() {
237
+ await this._connected.wait({
238
+ timeout: 1e3
239
+ });
240
+ invariant(this.peerId, "Peer id not set.", {
241
+ F: __dxlog_file,
242
+ L: 100,
243
+ S: this,
244
+ A: [
245
+ "this.peerId",
246
+ "'Peer id not set.'"
247
+ ]
248
+ });
249
+ return {
250
+ peerId: this.peerId
251
+ };
252
+ }
253
+ _getPeerId(id) {
254
+ return id;
255
+ }
256
+ };
257
+
258
+ // packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts
259
+ import { Trigger as Trigger2 } from "@dxos/async";
260
+ import { NetworkAdapter as NetworkAdapter2, cbor as cbor2 } from "@dxos/automerge/automerge-repo";
261
+ import { invariant as invariant2 } from "@dxos/invariant";
262
+ import { log as log2 } from "@dxos/log";
263
+ import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
264
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts";
265
+ var MeshNetworkAdapter = class extends NetworkAdapter2 {
266
+ constructor() {
267
+ super(...arguments);
268
+ this._extensions = /* @__PURE__ */ new Map();
269
+ this._connected = new Trigger2();
270
+ }
271
+ /**
272
+ * Emits `ready` event. That signals to `Repo` that it can start using the adapter.
273
+ */
274
+ ready() {
275
+ this.emit("ready", {
276
+ network: this
277
+ });
278
+ }
279
+ connect(peerId) {
280
+ this.peerId = peerId;
281
+ this._connected.wake();
282
+ }
283
+ send(message) {
284
+ const receiverId = message.targetId;
285
+ const extension = this._extensions.get(receiverId);
286
+ invariant2(extension, "Extension not found.", {
287
+ F: __dxlog_file2,
288
+ L: 38,
289
+ S: this,
290
+ A: [
291
+ "extension",
292
+ "'Extension not found.'"
293
+ ]
294
+ });
295
+ extension.sendSyncMessage({
296
+ payload: cbor2.encode(message)
297
+ }).catch((err) => log2.catch(err, void 0, {
298
+ F: __dxlog_file2,
299
+ L: 39,
300
+ S: this,
301
+ C: (f, a) => f(...a)
302
+ }));
303
+ }
304
+ disconnect() {
305
+ }
306
+ createExtension() {
307
+ invariant2(this.peerId, "Peer id not set.", {
308
+ F: __dxlog_file2,
309
+ L: 47,
310
+ S: this,
311
+ A: [
312
+ "this.peerId",
313
+ "'Peer id not set.'"
314
+ ]
315
+ });
316
+ let peerInfo;
317
+ const extension = new AutomergeReplicator({
318
+ peerId: this.peerId
319
+ }, {
320
+ onStartReplication: async (info, remotePeerId) => {
321
+ await this._connected.wait();
322
+ log2("onStartReplication", {
323
+ id: info.id,
324
+ thisPeerId: this.peerId,
325
+ remotePeerId: remotePeerId.toHex()
326
+ }, {
327
+ F: __dxlog_file2,
328
+ L: 70,
329
+ S: this,
330
+ C: (f, a) => f(...a)
331
+ });
332
+ if (!this._extensions.has(info.id)) {
333
+ peerInfo = info;
334
+ this._extensions.set(info.id, extension);
335
+ log2("peer-candidate", {
336
+ id: info.id,
337
+ thisPeerId: this.peerId,
338
+ remotePeerId: remotePeerId.toHex()
339
+ }, {
340
+ F: __dxlog_file2,
341
+ L: 76,
342
+ S: this,
343
+ C: (f, a) => f(...a)
344
+ });
345
+ this.emit("peer-candidate", {
346
+ // TODO(mykola): Hack, stop abusing `peerMetadata` field.
347
+ peerMetadata: {
348
+ dxos_deviceKey: remotePeerId.toHex()
349
+ },
350
+ peerId: info.id
351
+ });
352
+ }
353
+ },
354
+ onSyncMessage: async ({ payload }) => {
355
+ if (!peerInfo) {
356
+ return;
357
+ }
358
+ const message = cbor2.decode(payload);
359
+ this.emit("message", message);
360
+ },
361
+ onClose: async () => {
362
+ if (!peerInfo) {
363
+ return;
364
+ }
365
+ this.emit("peer-disconnected", {
366
+ peerId: peerInfo.id
367
+ });
368
+ this._extensions.delete(peerInfo.id);
369
+ }
370
+ });
371
+ return extension;
372
+ }
373
+ };
374
+
375
+ // packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts
376
+ function _ts_decorate(decorators, target, key, desc) {
377
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
378
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
379
+ r = Reflect.decorate(decorators, target, key, desc);
380
+ else
381
+ for (var i = decorators.length - 1; i >= 0; i--)
382
+ if (d = decorators[i])
383
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
384
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
385
+ }
386
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
387
+ var AutomergeHost = class {
388
+ constructor({ directory, metadata }) {
389
+ this._ctx = new Context();
390
+ /**
391
+ * spaceKey -> deviceKey[]
392
+ */
393
+ this._authorizedDevices = new ComplexMap(PublicKey.hash);
394
+ this._updatingMetadata = /* @__PURE__ */ new Map();
395
+ this._requestedDocs = /* @__PURE__ */ new Set();
396
+ this._metadata = metadata;
397
+ this._meshNetwork = new MeshNetworkAdapter();
398
+ this._clientNetwork = new LocalHostNetworkAdapter();
399
+ this._storage = new AutomergeStorageWrapper({
400
+ storage: (
401
+ // TODO(mykola): Delete specific handling of IDB storage.
402
+ directory.type === StorageType.IDB ? new IndexedDBStorageAdapter(directory.path, "data") : new AutomergeStorageAdapter(directory)
403
+ ),
404
+ callbacks: {
405
+ beforeSave: (params) => this._beforeSave(params)
406
+ }
407
+ });
408
+ this._peerId = `host-${PublicKey.random().toHex()}`;
409
+ this._repo = new Repo({
410
+ peerId: this._peerId,
411
+ network: [
412
+ this._clientNetwork,
413
+ this._meshNetwork
414
+ ],
415
+ storage: this._storage,
416
+ // TODO(dmaretskyi): Share based on HALO permissions and space affinity.
417
+ // Hosts, running in the worker, don't share documents unless requested by other peers.
418
+ sharePolicy: async (peerId, documentId) => {
419
+ if (peerId.startsWith("client-")) {
420
+ return false;
421
+ }
422
+ if (!documentId) {
423
+ return false;
424
+ }
425
+ const doc = this._repo.handles[documentId]?.docSync();
426
+ if (!doc) {
427
+ const isRequested = this._requestedDocs.has(`automerge:${documentId}`);
428
+ log3("doc share policy check", {
429
+ peerId,
430
+ documentId,
431
+ isRequested
432
+ }, {
433
+ F: __dxlog_file3,
434
+ L: 96,
435
+ S: this,
436
+ C: (f, a) => f(...a)
437
+ });
438
+ return isRequested;
439
+ }
440
+ try {
441
+ const spaceKey = getSpaceKeyFromDoc(doc);
442
+ if (!spaceKey) {
443
+ log3("space key not found for share policy check", {
444
+ peerId,
445
+ documentId
446
+ }, {
447
+ F: __dxlog_file3,
448
+ L: 103,
449
+ S: this,
450
+ C: (f, a) => f(...a)
451
+ });
452
+ return false;
453
+ }
454
+ const authorizedDevices = this._authorizedDevices.get(PublicKey.from(spaceKey));
455
+ const deviceKeyHex = this.repo.peerMetadataByPeerId[peerId]?.dxos_deviceKey;
456
+ if (!deviceKeyHex) {
457
+ log3("device key not found for share policy check", {
458
+ peerId,
459
+ documentId
460
+ }, {
461
+ F: __dxlog_file3,
462
+ L: 112,
463
+ S: this,
464
+ C: (f, a) => f(...a)
465
+ });
466
+ return false;
467
+ }
468
+ const deviceKey = PublicKey.from(deviceKeyHex);
469
+ const isAuthorized = authorizedDevices?.has(deviceKey) ?? false;
470
+ log3("share policy check", {
471
+ localPeer: this._peerId,
472
+ remotePeer: peerId,
473
+ documentId,
474
+ deviceKey,
475
+ spaceKey,
476
+ isAuthorized
477
+ }, {
478
+ F: __dxlog_file3,
479
+ L: 118,
480
+ S: this,
481
+ C: (f, a) => f(...a)
482
+ });
483
+ return isAuthorized;
484
+ } catch (err) {
485
+ log3.catch(err, void 0, {
486
+ F: __dxlog_file3,
487
+ L: 128,
488
+ S: this,
489
+ C: (f, a) => f(...a)
490
+ });
491
+ return false;
492
+ }
493
+ }
494
+ });
495
+ this._clientNetwork.ready();
496
+ this._meshNetwork.ready();
497
+ {
498
+ const listener = ({ handle }) => this._onDocument(handle);
499
+ this._repo.on("document", listener);
500
+ this._ctx.onDispose(() => {
501
+ this._repo.off("document", listener);
502
+ });
503
+ }
504
+ }
505
+ get repo() {
506
+ return this._repo;
507
+ }
508
+ async _beforeSave(path) {
509
+ const id = path[0];
510
+ if (this._updatingMetadata.has(id)) {
511
+ return this._updatingMetadata.get(id);
512
+ }
513
+ }
514
+ _onDocument(handle) {
515
+ const listener = (event) => this._onUpdate(event);
516
+ handle.on("change", listener);
517
+ this._ctx.onDispose(() => {
518
+ handle.off("change", listener);
519
+ });
520
+ }
521
+ _onUpdate(event) {
522
+ if (this._metadata == null) {
523
+ return;
524
+ }
525
+ const objectIds = getInlineChanges(event);
526
+ if (objectIds.length === 0) {
527
+ return;
528
+ }
529
+ const heads = getHeads(event.doc);
530
+ const lastAvailableHash = heads.join("");
531
+ if (!lastAvailableHash) {
532
+ return;
533
+ }
534
+ const encodedIds = objectIds.map((objectId) => idCodec.encode({
535
+ documentId: event.handle.documentId,
536
+ objectId
537
+ }));
538
+ const idToLastHash = new Map(encodedIds.map((id) => [
539
+ id,
540
+ lastAvailableHash
541
+ ]));
542
+ const markingDirtyPromise = this._metadata.markDirty(idToLastHash).then(() => {
543
+ this._updatingMetadata.delete(event.handle.documentId);
544
+ }).catch((err) => {
545
+ this._ctx.disposed && log3.catch(err, void 0, {
546
+ F: __dxlog_file3,
547
+ L: 188,
548
+ S: this,
549
+ C: (f, a) => f(...a)
550
+ });
551
+ });
552
+ this._updatingMetadata.set(event.handle.documentId, markingDirtyPromise);
553
+ }
554
+ _automergeDocs() {
555
+ return mapValues(this._repo.handles, (handle) => ({
556
+ state: handle.state,
557
+ hasDoc: !!handle.docSync(),
558
+ heads: handle.docSync() ? automerge.getHeads(handle.docSync()) : null,
559
+ data: handle.docSync()?.doc && mapValues(handle.docSync()?.doc, (value, key) => {
560
+ try {
561
+ switch (key) {
562
+ case "access":
563
+ case "links":
564
+ return value;
565
+ case "objects":
566
+ return Object.keys(value);
567
+ default:
568
+ return `${value}`;
569
+ }
570
+ } catch (err) {
571
+ return `${err}`;
572
+ }
573
+ })
574
+ }));
575
+ }
576
+ _automergePeers() {
577
+ return this._repo.peers;
578
+ }
579
+ async close() {
580
+ await this._storage.close();
581
+ await this._clientNetwork.close();
582
+ await this._ctx.dispose();
583
+ }
584
+ //
585
+ // Methods for client-services.
586
+ //
587
+ syncRepo(request) {
588
+ return this._clientNetwork.syncRepo(request);
589
+ }
590
+ sendSyncMessage(request) {
591
+ return this._clientNetwork.sendSyncMessage(request);
592
+ }
593
+ async getHostInfo() {
594
+ return this._clientNetwork.getHostInfo();
595
+ }
596
+ //
597
+ // Mesh replication.
598
+ //
599
+ createExtension() {
600
+ return this._meshNetwork.createExtension();
601
+ }
602
+ authorizeDevice(spaceKey, deviceKey) {
603
+ log3("authorizeDevice", {
604
+ spaceKey,
605
+ deviceKey
606
+ }, {
607
+ F: __dxlog_file3,
608
+ L: 255,
609
+ S: this,
610
+ C: (f, a) => f(...a)
611
+ });
612
+ defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey.hash)).add(deviceKey);
613
+ }
614
+ };
615
+ _ts_decorate([
616
+ trace.info()
617
+ ], AutomergeHost.prototype, "_peerId", void 0);
618
+ _ts_decorate([
619
+ trace.info({
620
+ depth: null
621
+ })
622
+ ], AutomergeHost.prototype, "_automergeDocs", null);
623
+ _ts_decorate([
624
+ trace.info({
625
+ depth: null
626
+ })
627
+ ], AutomergeHost.prototype, "_automergePeers", null);
628
+ AutomergeHost = _ts_decorate([
629
+ trace.resource()
630
+ ], AutomergeHost);
631
+ var getInlineChanges = (event) => {
632
+ const inlineChangedObjectIds = /* @__PURE__ */ new Set();
633
+ for (const { path } of event.patches) {
634
+ if (path.length < 2) {
635
+ continue;
636
+ }
637
+ switch (path[0]) {
638
+ case "objects":
639
+ if (path.length >= 2) {
640
+ inlineChangedObjectIds.add(path[1]);
641
+ }
642
+ break;
643
+ }
644
+ }
645
+ return [
646
+ ...inlineChangedObjectIds
647
+ ];
648
+ };
649
+ var getSpaceKeyFromDoc = (doc) => {
650
+ const rawSpaceKey = doc.access?.spaceKey ?? doc.experimental_spaceKey;
651
+ if (rawSpaceKey == null) {
652
+ return null;
653
+ }
654
+ return String(rawSpaceKey);
655
+ };
33
656
  export {
34
657
  AuthExtension,
35
658
  AuthStatus,
36
659
  AutomergeHost,
37
660
  AutomergeStorageAdapter,
38
- DataPipeline,
39
- DataServiceHost,
40
661
  DataServiceImpl,
41
- DataServiceSubscriptions,
42
- DatabaseHost,
43
662
  LocalHostNetworkAdapter,
44
663
  MOCK_AUTH_PROVIDER,
45
664
  MOCK_AUTH_VERIFIER,