@dxos/echo-pipeline 0.4.8-main.c67d72c → 0.4.8-main.cd60bd2

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