@dxos/echo-pipeline 0.5.3-main.37bbd91 → 0.5.3-main.3b535c7
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.
- package/dist/lib/browser/index.mjs +290 -430
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +279 -419
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/automerge/automerge-host.d.ts +9 -2
- package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
- package/dist/types/src/automerge/echo-network-adapter.d.ts +0 -6
- package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
- package/dist/types/src/automerge/echo-replicator.d.ts +0 -2
- package/dist/types/src/automerge/echo-replicator.d.ts.map +1 -1
- package/dist/types/src/automerge/index.d.ts +1 -1
- package/dist/types/src/automerge/mesh-network-adapter.d.ts +18 -0
- package/dist/types/src/automerge/mesh-network-adapter.d.ts.map +1 -0
- package/package.json +33 -33
- package/src/automerge/automerge-host.test.ts +9 -22
- package/src/automerge/automerge-host.ts +87 -65
- package/src/automerge/automerge-repo.test.ts +1 -10
- package/src/automerge/echo-network-adapter.ts +0 -19
- package/src/automerge/echo-replicator.ts +0 -3
- package/src/automerge/index.ts +1 -1
- package/src/automerge/mesh-network-adapter.ts +107 -0
- package/dist/types/src/automerge/mesh-echo-replicator.d.ts +0 -23
- package/dist/types/src/automerge/mesh-echo-replicator.d.ts.map +0 -1
- package/src/automerge/mesh-echo-replicator.ts +0 -231
|
@@ -29,12 +29,12 @@ import { Event } from "@dxos/async";
|
|
|
29
29
|
import { next as automerge, getBackend, getHeads } from "@dxos/automerge/automerge";
|
|
30
30
|
import { Repo } from "@dxos/automerge/automerge-repo";
|
|
31
31
|
import { Context } from "@dxos/context";
|
|
32
|
-
import { invariant as
|
|
32
|
+
import { invariant as invariant4 } from "@dxos/invariant";
|
|
33
33
|
import { PublicKey } from "@dxos/keys";
|
|
34
|
-
import { log as
|
|
35
|
-
import {
|
|
34
|
+
import { log as log4 } from "@dxos/log";
|
|
35
|
+
import { idCodec } from "@dxos/protocols";
|
|
36
36
|
import { trace } from "@dxos/tracing";
|
|
37
|
-
import { mapValues } from "@dxos/util";
|
|
37
|
+
import { ComplexMap, ComplexSet, defaultMap, mapValues } from "@dxos/util";
|
|
38
38
|
|
|
39
39
|
// packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts
|
|
40
40
|
import { Trigger, synchronized } from "@dxos/async";
|
|
@@ -54,10 +54,12 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
54
54
|
}
|
|
55
55
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/echo-network-adapter.ts";
|
|
56
56
|
var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
57
|
-
constructor(
|
|
58
|
-
super();
|
|
59
|
-
this._params = _params;
|
|
57
|
+
constructor() {
|
|
58
|
+
super(...arguments);
|
|
60
59
|
this._replicators = /* @__PURE__ */ new Set();
|
|
60
|
+
/**
|
|
61
|
+
* Remote peer id -> connection.
|
|
62
|
+
*/
|
|
61
63
|
this._connections = /* @__PURE__ */ new Map();
|
|
62
64
|
this._lifecycleState = LifecycleState.CLOSED;
|
|
63
65
|
this._connected = new Trigger();
|
|
@@ -76,7 +78,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
76
78
|
if (connectionEntry.isOpen) {
|
|
77
79
|
log.catch(err, void 0, {
|
|
78
80
|
F: __dxlog_file,
|
|
79
|
-
L:
|
|
81
|
+
L: 40,
|
|
80
82
|
S: this,
|
|
81
83
|
C: (f, a) => f(...a)
|
|
82
84
|
});
|
|
@@ -88,7 +90,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
88
90
|
async open() {
|
|
89
91
|
invariant(this._lifecycleState === LifecycleState.CLOSED, void 0, {
|
|
90
92
|
F: __dxlog_file,
|
|
91
|
-
L:
|
|
93
|
+
L: 51,
|
|
92
94
|
S: this,
|
|
93
95
|
A: [
|
|
94
96
|
"this._lifecycleState === LifecycleState.CLOSED",
|
|
@@ -96,12 +98,6 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
96
98
|
]
|
|
97
99
|
});
|
|
98
100
|
this._lifecycleState = LifecycleState.OPEN;
|
|
99
|
-
log("emit ready", void 0, {
|
|
100
|
-
F: __dxlog_file,
|
|
101
|
-
L: 63,
|
|
102
|
-
S: this,
|
|
103
|
-
C: (f, a) => f(...a)
|
|
104
|
-
});
|
|
105
101
|
this.emit("ready", {
|
|
106
102
|
network: this
|
|
107
103
|
});
|
|
@@ -109,7 +105,7 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
109
105
|
async close() {
|
|
110
106
|
invariant(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
111
107
|
F: __dxlog_file,
|
|
112
|
-
L:
|
|
108
|
+
L: 61,
|
|
113
109
|
S: this,
|
|
114
110
|
A: [
|
|
115
111
|
"this._lifecycleState === LifecycleState.OPEN",
|
|
@@ -128,18 +124,9 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
128
124
|
});
|
|
129
125
|
}
|
|
130
126
|
async addReplicator(replicator) {
|
|
131
|
-
invariant(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
132
|
-
F: __dxlog_file,
|
|
133
|
-
L: 87,
|
|
134
|
-
S: this,
|
|
135
|
-
A: [
|
|
136
|
-
"this._lifecycleState === LifecycleState.OPEN",
|
|
137
|
-
""
|
|
138
|
-
]
|
|
139
|
-
});
|
|
140
127
|
invariant(this.peerId, void 0, {
|
|
141
128
|
F: __dxlog_file,
|
|
142
|
-
L:
|
|
129
|
+
L: 77,
|
|
143
130
|
S: this,
|
|
144
131
|
A: [
|
|
145
132
|
"this.peerId",
|
|
@@ -148,43 +135,30 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
148
135
|
});
|
|
149
136
|
invariant(!this._replicators.has(replicator), void 0, {
|
|
150
137
|
F: __dxlog_file,
|
|
151
|
-
L:
|
|
138
|
+
L: 78,
|
|
152
139
|
S: this,
|
|
153
140
|
A: [
|
|
154
141
|
"!this._replicators.has(replicator)",
|
|
155
142
|
""
|
|
156
143
|
]
|
|
157
144
|
});
|
|
158
|
-
this._replicators.add(replicator);
|
|
159
145
|
await replicator.connect({
|
|
160
146
|
peerId: this.peerId,
|
|
161
147
|
onConnectionOpen: this._onConnectionOpen.bind(this),
|
|
162
|
-
onConnectionClosed: this._onConnectionClosed.bind(this)
|
|
163
|
-
getContainingSpaceForDocument: this._params.getContainingSpaceForDocument
|
|
148
|
+
onConnectionClosed: this._onConnectionClosed.bind(this)
|
|
164
149
|
});
|
|
165
150
|
}
|
|
166
151
|
async removeReplicator(replicator) {
|
|
167
|
-
invariant(this._lifecycleState === LifecycleState.OPEN, void 0, {
|
|
168
|
-
F: __dxlog_file,
|
|
169
|
-
L: 102,
|
|
170
|
-
S: this,
|
|
171
|
-
A: [
|
|
172
|
-
"this._lifecycleState === LifecycleState.OPEN",
|
|
173
|
-
""
|
|
174
|
-
]
|
|
175
|
-
});
|
|
176
152
|
invariant(this._replicators.has(replicator), void 0, {
|
|
177
153
|
F: __dxlog_file,
|
|
178
|
-
L:
|
|
154
|
+
L: 89,
|
|
179
155
|
S: this,
|
|
180
156
|
A: [
|
|
181
157
|
"this._replicators.has(replicator)",
|
|
182
158
|
""
|
|
183
159
|
]
|
|
184
160
|
});
|
|
185
|
-
"";
|
|
186
161
|
await replicator.disconnect();
|
|
187
|
-
this._replicators.delete(replicator);
|
|
188
162
|
}
|
|
189
163
|
async shouldAdvertize(peerId, params) {
|
|
190
164
|
const connection = this._connections.get(peerId);
|
|
@@ -194,17 +168,9 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
194
168
|
return connection.connection.shouldAdvertize(params);
|
|
195
169
|
}
|
|
196
170
|
_onConnectionOpen(connection) {
|
|
197
|
-
log("Connection opened", {
|
|
198
|
-
peerId: connection.peerId
|
|
199
|
-
}, {
|
|
200
|
-
F: __dxlog_file,
|
|
201
|
-
L: 119,
|
|
202
|
-
S: this,
|
|
203
|
-
C: (f, a) => f(...a)
|
|
204
|
-
});
|
|
205
171
|
invariant(!this._connections.has(connection.peerId), void 0, {
|
|
206
172
|
F: __dxlog_file,
|
|
207
|
-
L:
|
|
173
|
+
L: 103,
|
|
208
174
|
S: this,
|
|
209
175
|
A: [
|
|
210
176
|
"!this._connections.has(connection.peerId as PeerId)",
|
|
@@ -233,21 +199,13 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
233
199
|
if (connectionEntry.isOpen) {
|
|
234
200
|
log.catch(err, void 0, {
|
|
235
201
|
F: __dxlog_file,
|
|
236
|
-
L:
|
|
202
|
+
L: 122,
|
|
237
203
|
S: this,
|
|
238
204
|
C: (f, a) => f(...a)
|
|
239
205
|
});
|
|
240
206
|
}
|
|
241
207
|
}
|
|
242
208
|
});
|
|
243
|
-
log("emit peer-candidate", {
|
|
244
|
-
peerId: connection.peerId
|
|
245
|
-
}, {
|
|
246
|
-
F: __dxlog_file,
|
|
247
|
-
L: 144,
|
|
248
|
-
S: this,
|
|
249
|
-
C: (f, a) => f(...a)
|
|
250
|
-
});
|
|
251
209
|
this.emit("peer-candidate", {
|
|
252
210
|
peerId: connection.peerId,
|
|
253
211
|
peerMetadata: {
|
|
@@ -257,18 +215,10 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
257
215
|
});
|
|
258
216
|
}
|
|
259
217
|
_onConnectionClosed(connection) {
|
|
260
|
-
log("Connection closed", {
|
|
261
|
-
peerId: connection.peerId
|
|
262
|
-
}, {
|
|
263
|
-
F: __dxlog_file,
|
|
264
|
-
L: 155,
|
|
265
|
-
S: this,
|
|
266
|
-
C: (f, a) => f(...a)
|
|
267
|
-
});
|
|
268
218
|
const entry = this._connections.get(connection.peerId);
|
|
269
219
|
invariant(entry, void 0, {
|
|
270
220
|
F: __dxlog_file,
|
|
271
|
-
L:
|
|
221
|
+
L: 138,
|
|
272
222
|
S: this,
|
|
273
223
|
A: [
|
|
274
224
|
"entry",
|
|
@@ -281,13 +231,13 @@ var EchoNetworkAdapter = class extends NetworkAdapter {
|
|
|
281
231
|
});
|
|
282
232
|
void entry.reader.cancel().catch((err) => log.catch(err, void 0, {
|
|
283
233
|
F: __dxlog_file,
|
|
284
|
-
L:
|
|
234
|
+
L: 143,
|
|
285
235
|
S: this,
|
|
286
236
|
C: (f, a) => f(...a)
|
|
287
237
|
}));
|
|
288
238
|
void entry.writer.abort().catch((err) => log.catch(err, void 0, {
|
|
289
239
|
F: __dxlog_file,
|
|
290
|
-
L:
|
|
240
|
+
L: 144,
|
|
291
241
|
S: this,
|
|
292
242
|
C: (f, a) => f(...a)
|
|
293
243
|
}));
|
|
@@ -541,9 +491,126 @@ var LocalHostNetworkAdapter = class extends NetworkAdapter2 {
|
|
|
541
491
|
}
|
|
542
492
|
};
|
|
543
493
|
|
|
494
|
+
// packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts
|
|
495
|
+
import { Trigger as Trigger3 } from "@dxos/async";
|
|
496
|
+
import { NetworkAdapter as NetworkAdapter3, cbor as cbor2 } from "@dxos/automerge/automerge-repo";
|
|
497
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
498
|
+
import { log as log2 } from "@dxos/log";
|
|
499
|
+
import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
|
|
500
|
+
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-network-adapter.ts";
|
|
501
|
+
var MeshNetworkAdapter = class extends NetworkAdapter3 {
|
|
502
|
+
constructor() {
|
|
503
|
+
super(...arguments);
|
|
504
|
+
this._extensions = /* @__PURE__ */ new Map();
|
|
505
|
+
this._connected = new Trigger3();
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Emits `ready` event. That signals to `Repo` that it can start using the adapter.
|
|
509
|
+
*/
|
|
510
|
+
ready() {
|
|
511
|
+
this.emit("ready", {
|
|
512
|
+
network: this
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
connect(peerId) {
|
|
516
|
+
this.peerId = peerId;
|
|
517
|
+
this._connected.wake();
|
|
518
|
+
}
|
|
519
|
+
send(message) {
|
|
520
|
+
const receiverId = message.targetId;
|
|
521
|
+
const extension = this._extensions.get(receiverId);
|
|
522
|
+
invariant3(extension, "Extension not found.", {
|
|
523
|
+
F: __dxlog_file3,
|
|
524
|
+
L: 38,
|
|
525
|
+
S: this,
|
|
526
|
+
A: [
|
|
527
|
+
"extension",
|
|
528
|
+
"'Extension not found.'"
|
|
529
|
+
]
|
|
530
|
+
});
|
|
531
|
+
extension.sendSyncMessage({
|
|
532
|
+
payload: cbor2.encode(message)
|
|
533
|
+
}).catch((err) => log2.catch(err, void 0, {
|
|
534
|
+
F: __dxlog_file3,
|
|
535
|
+
L: 39,
|
|
536
|
+
S: this,
|
|
537
|
+
C: (f, a) => f(...a)
|
|
538
|
+
}));
|
|
539
|
+
}
|
|
540
|
+
disconnect() {
|
|
541
|
+
}
|
|
542
|
+
createExtension() {
|
|
543
|
+
invariant3(this.peerId, "Peer id not set.", {
|
|
544
|
+
F: __dxlog_file3,
|
|
545
|
+
L: 47,
|
|
546
|
+
S: this,
|
|
547
|
+
A: [
|
|
548
|
+
"this.peerId",
|
|
549
|
+
"'Peer id not set.'"
|
|
550
|
+
]
|
|
551
|
+
});
|
|
552
|
+
let peerInfo;
|
|
553
|
+
const extension = new AutomergeReplicator({
|
|
554
|
+
peerId: this.peerId
|
|
555
|
+
}, {
|
|
556
|
+
onStartReplication: async (info, remotePeerId) => {
|
|
557
|
+
await this._connected.wait();
|
|
558
|
+
log2("onStartReplication", {
|
|
559
|
+
id: info.id,
|
|
560
|
+
thisPeerId: this.peerId,
|
|
561
|
+
remotePeerId: remotePeerId.toHex()
|
|
562
|
+
}, {
|
|
563
|
+
F: __dxlog_file3,
|
|
564
|
+
L: 70,
|
|
565
|
+
S: this,
|
|
566
|
+
C: (f, a) => f(...a)
|
|
567
|
+
});
|
|
568
|
+
if (!this._extensions.has(info.id)) {
|
|
569
|
+
peerInfo = info;
|
|
570
|
+
this._extensions.set(info.id, extension);
|
|
571
|
+
log2("peer-candidate", {
|
|
572
|
+
id: info.id,
|
|
573
|
+
thisPeerId: this.peerId,
|
|
574
|
+
remotePeerId: remotePeerId.toHex()
|
|
575
|
+
}, {
|
|
576
|
+
F: __dxlog_file3,
|
|
577
|
+
L: 76,
|
|
578
|
+
S: this,
|
|
579
|
+
C: (f, a) => f(...a)
|
|
580
|
+
});
|
|
581
|
+
this.emit("peer-candidate", {
|
|
582
|
+
// TODO(mykola): Hack, stop abusing `peerMetadata` field.
|
|
583
|
+
peerMetadata: {
|
|
584
|
+
dxos_deviceKey: remotePeerId.toHex()
|
|
585
|
+
},
|
|
586
|
+
peerId: info.id
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
},
|
|
590
|
+
onSyncMessage: async ({ payload }) => {
|
|
591
|
+
if (!peerInfo) {
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
const message = cbor2.decode(payload);
|
|
595
|
+
this.emit("message", message);
|
|
596
|
+
},
|
|
597
|
+
onClose: async () => {
|
|
598
|
+
if (!peerInfo) {
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
this.emit("peer-disconnected", {
|
|
602
|
+
peerId: peerInfo.id
|
|
603
|
+
});
|
|
604
|
+
this._extensions.delete(peerInfo.id);
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
return extension;
|
|
608
|
+
}
|
|
609
|
+
};
|
|
610
|
+
|
|
544
611
|
// packages/core/echo/echo-pipeline/src/automerge/migrations.ts
|
|
545
612
|
import { IndexedDBStorageAdapter } from "@dxos/automerge/automerge-repo-storage-indexeddb";
|
|
546
|
-
import { log as
|
|
613
|
+
import { log as log3 } from "@dxos/log";
|
|
547
614
|
import { StorageType } from "@dxos/random-access-storage";
|
|
548
615
|
|
|
549
616
|
// packages/core/echo/echo-pipeline/src/automerge/automerge-storage-adapter.ts
|
|
@@ -623,7 +690,7 @@ var AutomergeStorageAdapter = class {
|
|
|
623
690
|
};
|
|
624
691
|
|
|
625
692
|
// packages/core/echo/echo-pipeline/src/automerge/migrations.ts
|
|
626
|
-
var
|
|
693
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/migrations.ts";
|
|
627
694
|
var levelMigration = async ({ db, directory }) => {
|
|
628
695
|
const isNewLevel = !await db.iterator({
|
|
629
696
|
...encodingOptions
|
|
@@ -637,10 +704,10 @@ var levelMigration = async ({ db, directory }) => {
|
|
|
637
704
|
return;
|
|
638
705
|
}
|
|
639
706
|
const batch = db.batch();
|
|
640
|
-
|
|
707
|
+
log3.info("found chunks on old storage adapter", {
|
|
641
708
|
chunks: chunks.length
|
|
642
709
|
}, {
|
|
643
|
-
F:
|
|
710
|
+
F: __dxlog_file4,
|
|
644
711
|
L: 36,
|
|
645
712
|
S: void 0,
|
|
646
713
|
C: (f, a) => f(...a)
|
|
@@ -664,13 +731,15 @@ function _ts_decorate2(decorators, target, key, desc) {
|
|
|
664
731
|
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
665
732
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
666
733
|
}
|
|
667
|
-
var
|
|
734
|
+
var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-host.ts";
|
|
668
735
|
var AutomergeHost = class {
|
|
669
736
|
constructor({ directory, db, indexMetadataStore }) {
|
|
670
737
|
this._ctx = new Context();
|
|
671
|
-
this._echoNetworkAdapter = new EchoNetworkAdapter(
|
|
672
|
-
|
|
673
|
-
|
|
738
|
+
this._echoNetworkAdapter = new EchoNetworkAdapter();
|
|
739
|
+
/**
|
|
740
|
+
* spaceKey -> deviceKey[]
|
|
741
|
+
*/
|
|
742
|
+
this._authorizedDevices = new ComplexMap(PublicKey.hash);
|
|
674
743
|
this._requestedDocs = /* @__PURE__ */ new Set();
|
|
675
744
|
this._directory = directory;
|
|
676
745
|
this._db = db;
|
|
@@ -690,17 +759,103 @@ var AutomergeHost = class {
|
|
|
690
759
|
});
|
|
691
760
|
await this._storage.open?.();
|
|
692
761
|
this._peerId = `host-${PublicKey.random().toHex()}`;
|
|
762
|
+
this._meshNetwork = new MeshNetworkAdapter();
|
|
693
763
|
this._clientNetwork = new LocalHostNetworkAdapter();
|
|
694
764
|
this._repo = new Repo({
|
|
695
765
|
peerId: this._peerId,
|
|
696
766
|
network: [
|
|
697
767
|
this._clientNetwork,
|
|
768
|
+
this._meshNetwork,
|
|
698
769
|
this._echoNetworkAdapter
|
|
699
770
|
],
|
|
700
771
|
storage: this._storage,
|
|
701
|
-
|
|
772
|
+
// TODO(dmaretskyi): Share based on HALO permissions and space affinity.
|
|
773
|
+
// Hosts, running in the worker, don't share documents unless requested by other peers.
|
|
774
|
+
sharePolicy: async (peerId, documentId) => {
|
|
775
|
+
if (peerId.startsWith("client-")) {
|
|
776
|
+
return false;
|
|
777
|
+
}
|
|
778
|
+
if (!documentId) {
|
|
779
|
+
return false;
|
|
780
|
+
}
|
|
781
|
+
const peerMetadata = this.repo.peerMetadataByPeerId[peerId];
|
|
782
|
+
if (peerMetadata?.dxos_peerSource === "EchoNetworkAdapter") {
|
|
783
|
+
return this._echoNetworkAdapter.shouldAdvertize(peerId, {
|
|
784
|
+
documentId
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
const doc = this._repo.handles[documentId]?.docSync();
|
|
788
|
+
if (!doc) {
|
|
789
|
+
const isRequested = this._requestedDocs.has(`automerge:${documentId}`);
|
|
790
|
+
log4("doc share policy check", {
|
|
791
|
+
peerId,
|
|
792
|
+
documentId,
|
|
793
|
+
isRequested
|
|
794
|
+
}, {
|
|
795
|
+
F: __dxlog_file5,
|
|
796
|
+
L: 124,
|
|
797
|
+
S: this,
|
|
798
|
+
C: (f, a) => f(...a)
|
|
799
|
+
});
|
|
800
|
+
return isRequested;
|
|
801
|
+
}
|
|
802
|
+
try {
|
|
803
|
+
const spaceKey = getSpaceKeyFromDoc(doc);
|
|
804
|
+
if (!spaceKey) {
|
|
805
|
+
log4("space key not found for share policy check", {
|
|
806
|
+
peerId,
|
|
807
|
+
documentId
|
|
808
|
+
}, {
|
|
809
|
+
F: __dxlog_file5,
|
|
810
|
+
L: 131,
|
|
811
|
+
S: this,
|
|
812
|
+
C: (f, a) => f(...a)
|
|
813
|
+
});
|
|
814
|
+
return false;
|
|
815
|
+
}
|
|
816
|
+
const authorizedDevices = this._authorizedDevices.get(PublicKey.from(spaceKey));
|
|
817
|
+
const deviceKeyHex = peerMetadata?.dxos_deviceKey;
|
|
818
|
+
if (!deviceKeyHex) {
|
|
819
|
+
log4("device key not found for share policy check", {
|
|
820
|
+
peerId,
|
|
821
|
+
documentId
|
|
822
|
+
}, {
|
|
823
|
+
F: __dxlog_file5,
|
|
824
|
+
L: 140,
|
|
825
|
+
S: this,
|
|
826
|
+
C: (f, a) => f(...a)
|
|
827
|
+
});
|
|
828
|
+
return false;
|
|
829
|
+
}
|
|
830
|
+
const deviceKey = PublicKey.from(deviceKeyHex);
|
|
831
|
+
const isAuthorized = authorizedDevices?.has(deviceKey) ?? false;
|
|
832
|
+
log4("share policy check", {
|
|
833
|
+
localPeer: this._peerId,
|
|
834
|
+
remotePeer: peerId,
|
|
835
|
+
documentId,
|
|
836
|
+
deviceKey,
|
|
837
|
+
spaceKey,
|
|
838
|
+
isAuthorized
|
|
839
|
+
}, {
|
|
840
|
+
F: __dxlog_file5,
|
|
841
|
+
L: 146,
|
|
842
|
+
S: this,
|
|
843
|
+
C: (f, a) => f(...a)
|
|
844
|
+
});
|
|
845
|
+
return isAuthorized;
|
|
846
|
+
} catch (err) {
|
|
847
|
+
log4.catch(err, void 0, {
|
|
848
|
+
F: __dxlog_file5,
|
|
849
|
+
L: 156,
|
|
850
|
+
S: this,
|
|
851
|
+
C: (f, a) => f(...a)
|
|
852
|
+
});
|
|
853
|
+
return false;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
702
856
|
});
|
|
703
857
|
this._clientNetwork.ready();
|
|
858
|
+
this._meshNetwork.ready();
|
|
704
859
|
await this._echoNetworkAdapter.open();
|
|
705
860
|
await this._clientNetwork.whenConnected();
|
|
706
861
|
await this._echoNetworkAdapter.whenConnected();
|
|
@@ -720,40 +875,6 @@ var AutomergeHost = class {
|
|
|
720
875
|
async removeReplicator(replicator) {
|
|
721
876
|
await this._echoNetworkAdapter.removeReplicator(replicator);
|
|
722
877
|
}
|
|
723
|
-
// TODO(dmaretskyi): Share based on HALO permissions and space affinity.
|
|
724
|
-
// Hosts, running in the worker, don't share documents unless requested by other peers.
|
|
725
|
-
// NOTE: If both peers return sharePolicy=false the replication will not happen
|
|
726
|
-
// https://github.com/automerge/automerge-repo/pull/292
|
|
727
|
-
async _sharePolicy(peerId, documentId) {
|
|
728
|
-
if (peerId.startsWith("client-")) {
|
|
729
|
-
return false;
|
|
730
|
-
}
|
|
731
|
-
if (!documentId) {
|
|
732
|
-
return false;
|
|
733
|
-
}
|
|
734
|
-
const doc = this._repo.handles[documentId]?.docSync();
|
|
735
|
-
if (!doc) {
|
|
736
|
-
const isRequested = this._requestedDocs.has(`automerge:${documentId}`);
|
|
737
|
-
log3("doc share policy check", {
|
|
738
|
-
peerId,
|
|
739
|
-
documentId,
|
|
740
|
-
isRequested
|
|
741
|
-
}, {
|
|
742
|
-
F: __dxlog_file4,
|
|
743
|
-
L: 149,
|
|
744
|
-
S: this,
|
|
745
|
-
C: (f, a) => f(...a)
|
|
746
|
-
});
|
|
747
|
-
return isRequested;
|
|
748
|
-
}
|
|
749
|
-
const peerMetadata = this.repo.peerMetadataByPeerId[peerId];
|
|
750
|
-
if (peerMetadata?.dxos_peerSource === "EchoNetworkAdapter") {
|
|
751
|
-
return this._echoNetworkAdapter.shouldAdvertize(peerId, {
|
|
752
|
-
documentId
|
|
753
|
-
});
|
|
754
|
-
}
|
|
755
|
-
return false;
|
|
756
|
-
}
|
|
757
878
|
async _beforeSave({ path, batch }) {
|
|
758
879
|
const handle = this._repo.handles[path[0]];
|
|
759
880
|
if (!handle) {
|
|
@@ -763,13 +884,11 @@ var AutomergeHost = class {
|
|
|
763
884
|
if (!doc) {
|
|
764
885
|
return;
|
|
765
886
|
}
|
|
766
|
-
const spaceKey = getSpaceKeyFromDoc(doc) ?? void 0;
|
|
767
887
|
const lastAvailableHash = getHeads(doc);
|
|
768
888
|
const objectIds = Object.keys(doc.objects ?? {});
|
|
769
|
-
const encodedIds = objectIds.map((objectId) =>
|
|
889
|
+
const encodedIds = objectIds.map((objectId) => idCodec.encode({
|
|
770
890
|
documentId: handle.documentId,
|
|
771
|
-
objectId
|
|
772
|
-
spaceKey
|
|
891
|
+
objectId
|
|
773
892
|
}));
|
|
774
893
|
const idToLastHash = new Map(encodedIds.map((id) => [
|
|
775
894
|
id,
|
|
@@ -808,25 +927,14 @@ var AutomergeHost = class {
|
|
|
808
927
|
_automergePeers() {
|
|
809
928
|
return this._repo.peers;
|
|
810
929
|
}
|
|
811
|
-
async _getContainingSpaceForDocument(documentId) {
|
|
812
|
-
const doc = this._repo.handles[documentId]?.docSync();
|
|
813
|
-
if (!doc) {
|
|
814
|
-
return null;
|
|
815
|
-
}
|
|
816
|
-
const spaceKeyHex = getSpaceKeyFromDoc(doc);
|
|
817
|
-
if (!spaceKeyHex) {
|
|
818
|
-
return null;
|
|
819
|
-
}
|
|
820
|
-
return PublicKey.from(spaceKeyHex);
|
|
821
|
-
}
|
|
822
930
|
//
|
|
823
931
|
// Methods for client-services.
|
|
824
932
|
//
|
|
825
933
|
async flush({ states }) {
|
|
826
934
|
await Promise.all(states?.map(async ({ heads, documentId }) => {
|
|
827
|
-
|
|
828
|
-
F:
|
|
829
|
-
L:
|
|
935
|
+
invariant4(heads, "heads are required for flush", {
|
|
936
|
+
F: __dxlog_file5,
|
|
937
|
+
L: 252,
|
|
830
938
|
S: this,
|
|
831
939
|
A: [
|
|
832
940
|
"heads",
|
|
@@ -847,6 +955,24 @@ var AutomergeHost = class {
|
|
|
847
955
|
async getHostInfo() {
|
|
848
956
|
return this._clientNetwork.getHostInfo();
|
|
849
957
|
}
|
|
958
|
+
//
|
|
959
|
+
// Mesh replication.
|
|
960
|
+
//
|
|
961
|
+
createExtension() {
|
|
962
|
+
return this._meshNetwork.createExtension();
|
|
963
|
+
}
|
|
964
|
+
authorizeDevice(spaceKey, deviceKey) {
|
|
965
|
+
log4("authorizeDevice", {
|
|
966
|
+
spaceKey,
|
|
967
|
+
deviceKey
|
|
968
|
+
}, {
|
|
969
|
+
F: __dxlog_file5,
|
|
970
|
+
L: 282,
|
|
971
|
+
S: this,
|
|
972
|
+
C: (f, a) => f(...a)
|
|
973
|
+
});
|
|
974
|
+
defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey.hash)).add(deviceKey);
|
|
975
|
+
}
|
|
850
976
|
};
|
|
851
977
|
_ts_decorate2([
|
|
852
978
|
trace.info()
|
|
@@ -899,8 +1025,8 @@ var changeIsPresentInDoc = (doc, changeHash) => {
|
|
|
899
1025
|
import { Event as Event2 } from "@dxos/async";
|
|
900
1026
|
import { cancelWithContext } from "@dxos/context";
|
|
901
1027
|
import { warnAfterTimeout } from "@dxos/debug";
|
|
902
|
-
import { invariant as
|
|
903
|
-
import { log as
|
|
1028
|
+
import { invariant as invariant5 } from "@dxos/invariant";
|
|
1029
|
+
import { log as log5 } from "@dxos/log";
|
|
904
1030
|
import { trace as trace2 } from "@dxos/tracing";
|
|
905
1031
|
function _ts_decorate3(decorators, target, key, desc) {
|
|
906
1032
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -912,7 +1038,7 @@ function _ts_decorate3(decorators, target, key, desc) {
|
|
|
912
1038
|
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
913
1039
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
914
1040
|
}
|
|
915
|
-
var
|
|
1041
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
|
|
916
1042
|
var AutomergeDocumentLoaderImpl = class {
|
|
917
1043
|
constructor(_spaceKey, _repo) {
|
|
918
1044
|
this._spaceKey = _spaceKey;
|
|
@@ -933,10 +1059,10 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
933
1059
|
return;
|
|
934
1060
|
}
|
|
935
1061
|
if (!spaceState.rootUrl) {
|
|
936
|
-
|
|
1062
|
+
log5.error("Database opened with no rootUrl", {
|
|
937
1063
|
spaceKey: this._spaceKey
|
|
938
1064
|
}, {
|
|
939
|
-
F:
|
|
1065
|
+
F: __dxlog_file6,
|
|
940
1066
|
L: 70,
|
|
941
1067
|
S: this,
|
|
942
1068
|
C: (f, a) => f(...a)
|
|
@@ -945,8 +1071,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
945
1071
|
} else {
|
|
946
1072
|
const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);
|
|
947
1073
|
const doc = existingDocHandle.docSync();
|
|
948
|
-
|
|
949
|
-
F:
|
|
1074
|
+
invariant5(doc, void 0, {
|
|
1075
|
+
F: __dxlog_file6,
|
|
950
1076
|
L: 75,
|
|
951
1077
|
S: this,
|
|
952
1078
|
A: [
|
|
@@ -967,8 +1093,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
967
1093
|
let hasUrlsToLoad = false;
|
|
968
1094
|
const urlsToLoad = {};
|
|
969
1095
|
for (const objectId of objectIds) {
|
|
970
|
-
|
|
971
|
-
F:
|
|
1096
|
+
invariant5(this._spaceRootDocHandle, void 0, {
|
|
1097
|
+
F: __dxlog_file6,
|
|
972
1098
|
L: 88,
|
|
973
1099
|
S: this,
|
|
974
1100
|
A: [
|
|
@@ -980,8 +1106,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
980
1106
|
continue;
|
|
981
1107
|
}
|
|
982
1108
|
const spaceRootDoc = this._spaceRootDocHandle.docSync();
|
|
983
|
-
|
|
984
|
-
F:
|
|
1109
|
+
invariant5(spaceRootDoc, void 0, {
|
|
1110
|
+
F: __dxlog_file6,
|
|
985
1111
|
L: 93,
|
|
986
1112
|
S: this,
|
|
987
1113
|
A: [
|
|
@@ -992,10 +1118,10 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
992
1118
|
const documentUrl = (spaceRootDoc.links ?? {})[objectId];
|
|
993
1119
|
if (documentUrl == null) {
|
|
994
1120
|
this._objectsPendingDocumentLoad.add(objectId);
|
|
995
|
-
|
|
1121
|
+
log5.info("loading delayed until object links are initialized", {
|
|
996
1122
|
objectId
|
|
997
1123
|
}, {
|
|
998
|
-
F:
|
|
1124
|
+
F: __dxlog_file6,
|
|
999
1125
|
L: 97,
|
|
1000
1126
|
S: this,
|
|
1001
1127
|
C: (f, a) => f(...a)
|
|
@@ -1018,8 +1144,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1018
1144
|
linksAwaitingLoad.forEach(([objectId]) => this._objectsPendingDocumentLoad.delete(objectId));
|
|
1019
1145
|
}
|
|
1020
1146
|
getSpaceRootDocHandle() {
|
|
1021
|
-
|
|
1022
|
-
F:
|
|
1147
|
+
invariant5(this._spaceRootDocHandle, void 0, {
|
|
1148
|
+
F: __dxlog_file6,
|
|
1023
1149
|
L: 120,
|
|
1024
1150
|
S: this,
|
|
1025
1151
|
A: [
|
|
@@ -1030,8 +1156,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1030
1156
|
return this._spaceRootDocHandle;
|
|
1031
1157
|
}
|
|
1032
1158
|
createDocumentForObject(objectId) {
|
|
1033
|
-
|
|
1034
|
-
F:
|
|
1159
|
+
invariant5(this._spaceRootDocHandle, void 0, {
|
|
1160
|
+
F: __dxlog_file6,
|
|
1035
1161
|
L: 125,
|
|
1036
1162
|
S: this,
|
|
1037
1163
|
A: [
|
|
@@ -1070,11 +1196,11 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1070
1196
|
};
|
|
1071
1197
|
const objectDocumentHandle = this._objectDocumentHandles.get(objectId);
|
|
1072
1198
|
if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {
|
|
1073
|
-
|
|
1199
|
+
log5.warn("object already inlined in a different document, ignoring the link", {
|
|
1074
1200
|
...logMeta,
|
|
1075
1201
|
actualDocumentUrl: objectDocumentHandle.url
|
|
1076
1202
|
}, {
|
|
1077
|
-
F:
|
|
1203
|
+
F: __dxlog_file6,
|
|
1078
1204
|
L: 155,
|
|
1079
1205
|
S: this,
|
|
1080
1206
|
C: (f, a) => f(...a)
|
|
@@ -1082,8 +1208,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1082
1208
|
continue;
|
|
1083
1209
|
}
|
|
1084
1210
|
if (objectDocumentHandle?.url === automergeUrl) {
|
|
1085
|
-
|
|
1086
|
-
F:
|
|
1211
|
+
log5.warn("object document was already loaded", logMeta, {
|
|
1212
|
+
F: __dxlog_file6,
|
|
1087
1213
|
L: 162,
|
|
1088
1214
|
S: this,
|
|
1089
1215
|
C: (f, a) => f(...a)
|
|
@@ -1091,8 +1217,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1091
1217
|
continue;
|
|
1092
1218
|
}
|
|
1093
1219
|
const handle = this._repo.find(automergeUrl);
|
|
1094
|
-
|
|
1095
|
-
F:
|
|
1220
|
+
log5.debug("document loading triggered", logMeta, {
|
|
1221
|
+
F: __dxlog_file6,
|
|
1096
1222
|
L: 166,
|
|
1097
1223
|
S: this,
|
|
1098
1224
|
C: (f, a) => f(...a)
|
|
@@ -1111,11 +1237,11 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1111
1237
|
break;
|
|
1112
1238
|
} catch (err) {
|
|
1113
1239
|
if (`${err}`.includes("Timeout")) {
|
|
1114
|
-
|
|
1240
|
+
log5.info("wraparound", {
|
|
1115
1241
|
id: docHandle.documentId,
|
|
1116
1242
|
state: docHandle.state
|
|
1117
1243
|
}, {
|
|
1118
|
-
F:
|
|
1244
|
+
F: __dxlog_file6,
|
|
1119
1245
|
L: 182,
|
|
1120
1246
|
S: this,
|
|
1121
1247
|
C: (f, a) => f(...a)
|
|
@@ -1156,8 +1282,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1156
1282
|
docUrl: handle.url
|
|
1157
1283
|
};
|
|
1158
1284
|
if (this.onObjectDocumentLoaded.listenerCount() === 0) {
|
|
1159
|
-
|
|
1160
|
-
F:
|
|
1285
|
+
log5.info("document loaded after all listeners were removed", logMeta, {
|
|
1286
|
+
F: __dxlog_file6,
|
|
1161
1287
|
L: 218,
|
|
1162
1288
|
S: this,
|
|
1163
1289
|
C: (f, a) => f(...a)
|
|
@@ -1166,8 +1292,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1166
1292
|
}
|
|
1167
1293
|
const objectDocHandle = this._objectDocumentHandles.get(objectId);
|
|
1168
1294
|
if (objectDocHandle?.url !== handle.url) {
|
|
1169
|
-
|
|
1170
|
-
F:
|
|
1295
|
+
log5.warn("object was rebound while a document was loading, discarding handle", logMeta, {
|
|
1296
|
+
F: __dxlog_file6,
|
|
1171
1297
|
L: 223,
|
|
1172
1298
|
S: this,
|
|
1173
1299
|
C: (f, a) => f(...a)
|
|
@@ -1180,13 +1306,13 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1180
1306
|
});
|
|
1181
1307
|
} catch (err) {
|
|
1182
1308
|
const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;
|
|
1183
|
-
|
|
1309
|
+
log5.warn("failed to load a document", {
|
|
1184
1310
|
objectId,
|
|
1185
1311
|
automergeUrl: handle.url,
|
|
1186
1312
|
retryLoading: shouldRetryLoading,
|
|
1187
1313
|
err
|
|
1188
1314
|
}, {
|
|
1189
|
-
F:
|
|
1315
|
+
F: __dxlog_file6,
|
|
1190
1316
|
L: 229,
|
|
1191
1317
|
S: this,
|
|
1192
1318
|
C: (f, a) => f(...a)
|
|
@@ -1205,272 +1331,6 @@ _ts_decorate3([
|
|
|
1205
1331
|
AutomergeDocumentLoaderImpl = _ts_decorate3([
|
|
1206
1332
|
trace2.resource()
|
|
1207
1333
|
], AutomergeDocumentLoaderImpl);
|
|
1208
|
-
|
|
1209
|
-
// packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts
|
|
1210
|
-
import { cbor as cbor2 } from "@dxos/automerge/automerge-repo";
|
|
1211
|
-
import { Resource as Resource2 } from "@dxos/context";
|
|
1212
|
-
import { invariant as invariant5 } from "@dxos/invariant";
|
|
1213
|
-
import { PublicKey as PublicKey2 } from "@dxos/keys";
|
|
1214
|
-
import { log as log5 } from "@dxos/log";
|
|
1215
|
-
import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
|
|
1216
|
-
import { ComplexMap, ComplexSet, defaultMap } from "@dxos/util";
|
|
1217
|
-
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts";
|
|
1218
|
-
var MeshEchoReplicator = class {
|
|
1219
|
-
constructor() {
|
|
1220
|
-
this._connections = /* @__PURE__ */ new Set();
|
|
1221
|
-
/**
|
|
1222
|
-
* Using automerge peerId as a key.
|
|
1223
|
-
*/
|
|
1224
|
-
this._connectionsPerPeer = /* @__PURE__ */ new Map();
|
|
1225
|
-
/**
|
|
1226
|
-
* spaceKey -> deviceKey[]
|
|
1227
|
-
*/
|
|
1228
|
-
this._authorizedDevices = new ComplexMap(PublicKey2.hash);
|
|
1229
|
-
this._context = null;
|
|
1230
|
-
}
|
|
1231
|
-
async connect(context) {
|
|
1232
|
-
this._context = context;
|
|
1233
|
-
}
|
|
1234
|
-
async disconnect() {
|
|
1235
|
-
for (const connection of this._connections) {
|
|
1236
|
-
await connection.close();
|
|
1237
|
-
}
|
|
1238
|
-
this._connections.clear();
|
|
1239
|
-
this._connectionsPerPeer.clear();
|
|
1240
|
-
this._context = null;
|
|
1241
|
-
}
|
|
1242
|
-
createExtension() {
|
|
1243
|
-
invariant5(this._context, void 0, {
|
|
1244
|
-
F: __dxlog_file6,
|
|
1245
|
-
L: 54,
|
|
1246
|
-
S: this,
|
|
1247
|
-
A: [
|
|
1248
|
-
"this._context",
|
|
1249
|
-
""
|
|
1250
|
-
]
|
|
1251
|
-
});
|
|
1252
|
-
const connection = new MeshReplicatorConnection({
|
|
1253
|
-
ownPeerId: this._context.peerId,
|
|
1254
|
-
onRemoteConnected: async () => {
|
|
1255
|
-
log5("onRemoteConnected", {
|
|
1256
|
-
peerId: connection.peerId
|
|
1257
|
-
}, {
|
|
1258
|
-
F: __dxlog_file6,
|
|
1259
|
-
L: 59,
|
|
1260
|
-
S: this,
|
|
1261
|
-
C: (f, a) => f(...a)
|
|
1262
|
-
});
|
|
1263
|
-
invariant5(this._context, void 0, {
|
|
1264
|
-
F: __dxlog_file6,
|
|
1265
|
-
L: 60,
|
|
1266
|
-
S: this,
|
|
1267
|
-
A: [
|
|
1268
|
-
"this._context",
|
|
1269
|
-
""
|
|
1270
|
-
]
|
|
1271
|
-
});
|
|
1272
|
-
if (!this._connectionsPerPeer.has(connection.peerId)) {
|
|
1273
|
-
this._connectionsPerPeer.set(connection.peerId, connection);
|
|
1274
|
-
await connection.enable();
|
|
1275
|
-
this._context.onConnectionOpen(connection);
|
|
1276
|
-
}
|
|
1277
|
-
},
|
|
1278
|
-
onRemoteDisconnected: async () => {
|
|
1279
|
-
log5("onRemoteDisconnected", {
|
|
1280
|
-
peerId: connection.peerId
|
|
1281
|
-
}, {
|
|
1282
|
-
F: __dxlog_file6,
|
|
1283
|
-
L: 69,
|
|
1284
|
-
S: this,
|
|
1285
|
-
C: (f, a) => f(...a)
|
|
1286
|
-
});
|
|
1287
|
-
this._context?.onConnectionClosed(connection);
|
|
1288
|
-
await connection.disable();
|
|
1289
|
-
this._connectionsPerPeer.delete(connection.peerId);
|
|
1290
|
-
this._connections.delete(connection);
|
|
1291
|
-
},
|
|
1292
|
-
shouldAdvertize: async (params) => {
|
|
1293
|
-
log5("shouldAdvertize", {
|
|
1294
|
-
peerId: connection.peerId,
|
|
1295
|
-
documentId: params.documentId
|
|
1296
|
-
}, {
|
|
1297
|
-
F: __dxlog_file6,
|
|
1298
|
-
L: 76,
|
|
1299
|
-
S: this,
|
|
1300
|
-
C: (f, a) => f(...a)
|
|
1301
|
-
});
|
|
1302
|
-
invariant5(this._context, void 0, {
|
|
1303
|
-
F: __dxlog_file6,
|
|
1304
|
-
L: 77,
|
|
1305
|
-
S: this,
|
|
1306
|
-
A: [
|
|
1307
|
-
"this._context",
|
|
1308
|
-
""
|
|
1309
|
-
]
|
|
1310
|
-
});
|
|
1311
|
-
try {
|
|
1312
|
-
const spaceKey = await this._context.getContainingSpaceForDocument(params.documentId);
|
|
1313
|
-
if (!spaceKey) {
|
|
1314
|
-
log5("space key not found for share policy check", {
|
|
1315
|
-
peerId: connection.peerId,
|
|
1316
|
-
documentId: params.documentId
|
|
1317
|
-
}, {
|
|
1318
|
-
F: __dxlog_file6,
|
|
1319
|
-
L: 81,
|
|
1320
|
-
S: this,
|
|
1321
|
-
C: (f, a) => f(...a)
|
|
1322
|
-
});
|
|
1323
|
-
return false;
|
|
1324
|
-
}
|
|
1325
|
-
const authorizedDevices = this._authorizedDevices.get(spaceKey);
|
|
1326
|
-
if (!connection.remoteDeviceKey) {
|
|
1327
|
-
log5("device key not found for share policy check", {
|
|
1328
|
-
peerId: connection.peerId,
|
|
1329
|
-
documentId: params.documentId
|
|
1330
|
-
}, {
|
|
1331
|
-
F: __dxlog_file6,
|
|
1332
|
-
L: 91,
|
|
1333
|
-
S: this,
|
|
1334
|
-
C: (f, a) => f(...a)
|
|
1335
|
-
});
|
|
1336
|
-
return false;
|
|
1337
|
-
}
|
|
1338
|
-
const isAuthorized = authorizedDevices?.has(connection.remoteDeviceKey) ?? false;
|
|
1339
|
-
log5("share policy check", {
|
|
1340
|
-
localPeer: this._context.peerId,
|
|
1341
|
-
remotePeer: connection.peerId,
|
|
1342
|
-
documentId: params.documentId,
|
|
1343
|
-
deviceKey: connection.remoteDeviceKey,
|
|
1344
|
-
spaceKey,
|
|
1345
|
-
isAuthorized
|
|
1346
|
-
}, {
|
|
1347
|
-
F: __dxlog_file6,
|
|
1348
|
-
L: 99,
|
|
1349
|
-
S: this,
|
|
1350
|
-
C: (f, a) => f(...a)
|
|
1351
|
-
});
|
|
1352
|
-
return isAuthorized;
|
|
1353
|
-
} catch (err) {
|
|
1354
|
-
log5.catch(err, void 0, {
|
|
1355
|
-
F: __dxlog_file6,
|
|
1356
|
-
L: 109,
|
|
1357
|
-
S: this,
|
|
1358
|
-
C: (f, a) => f(...a)
|
|
1359
|
-
});
|
|
1360
|
-
return false;
|
|
1361
|
-
}
|
|
1362
|
-
}
|
|
1363
|
-
});
|
|
1364
|
-
this._connections.add(connection);
|
|
1365
|
-
return connection.replicatorExtension;
|
|
1366
|
-
}
|
|
1367
|
-
authorizeDevice(spaceKey, deviceKey) {
|
|
1368
|
-
log5("authorizeDevice", {
|
|
1369
|
-
spaceKey,
|
|
1370
|
-
deviceKey
|
|
1371
|
-
}, {
|
|
1372
|
-
F: __dxlog_file6,
|
|
1373
|
-
L: 120,
|
|
1374
|
-
S: this,
|
|
1375
|
-
C: (f, a) => f(...a)
|
|
1376
|
-
});
|
|
1377
|
-
defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey2.hash)).add(deviceKey);
|
|
1378
|
-
}
|
|
1379
|
-
};
|
|
1380
|
-
var MeshReplicatorConnection = class extends Resource2 {
|
|
1381
|
-
constructor(_params) {
|
|
1382
|
-
super();
|
|
1383
|
-
this._params = _params;
|
|
1384
|
-
this.remoteDeviceKey = null;
|
|
1385
|
-
this._remotePeerId = null;
|
|
1386
|
-
this._isEnabled = false;
|
|
1387
|
-
let readableStreamController;
|
|
1388
|
-
this.readable = new ReadableStream({
|
|
1389
|
-
start: (controller) => {
|
|
1390
|
-
readableStreamController = controller;
|
|
1391
|
-
this._ctx.onDispose(() => controller.close());
|
|
1392
|
-
}
|
|
1393
|
-
});
|
|
1394
|
-
this.writable = new WritableStream({
|
|
1395
|
-
write: async (message, controller) => {
|
|
1396
|
-
this.replicatorExtension.sendSyncMessage({
|
|
1397
|
-
payload: cbor2.encode(message)
|
|
1398
|
-
}).catch((err) => {
|
|
1399
|
-
controller.error(err);
|
|
1400
|
-
});
|
|
1401
|
-
}
|
|
1402
|
-
});
|
|
1403
|
-
this.replicatorExtension = new AutomergeReplicator({
|
|
1404
|
-
peerId: this._params.ownPeerId
|
|
1405
|
-
}, {
|
|
1406
|
-
onStartReplication: async (info, remotePeerId) => {
|
|
1407
|
-
this.remoteDeviceKey = remotePeerId;
|
|
1408
|
-
this._remotePeerId = info.id;
|
|
1409
|
-
log5("onStartReplication", {
|
|
1410
|
-
id: info.id,
|
|
1411
|
-
thisPeerId: this.peerId,
|
|
1412
|
-
remotePeerId: remotePeerId.toHex()
|
|
1413
|
-
}, {
|
|
1414
|
-
F: __dxlog_file6,
|
|
1415
|
-
L: 185,
|
|
1416
|
-
S: this,
|
|
1417
|
-
C: (f, a) => f(...a)
|
|
1418
|
-
});
|
|
1419
|
-
await this._params.onRemoteConnected();
|
|
1420
|
-
},
|
|
1421
|
-
onSyncMessage: async ({ payload }) => {
|
|
1422
|
-
if (!this._isEnabled) {
|
|
1423
|
-
return;
|
|
1424
|
-
}
|
|
1425
|
-
const message = cbor2.decode(payload);
|
|
1426
|
-
readableStreamController.enqueue(message);
|
|
1427
|
-
},
|
|
1428
|
-
onClose: async () => {
|
|
1429
|
-
if (!this._isEnabled) {
|
|
1430
|
-
return;
|
|
1431
|
-
}
|
|
1432
|
-
await this._params.onRemoteDisconnected();
|
|
1433
|
-
}
|
|
1434
|
-
});
|
|
1435
|
-
}
|
|
1436
|
-
get peerId() {
|
|
1437
|
-
invariant5(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1438
|
-
F: __dxlog_file6,
|
|
1439
|
-
L: 208,
|
|
1440
|
-
S: this,
|
|
1441
|
-
A: [
|
|
1442
|
-
"this._remotePeerId != null",
|
|
1443
|
-
"'Remote peer has not connected yet.'"
|
|
1444
|
-
]
|
|
1445
|
-
});
|
|
1446
|
-
return this._remotePeerId;
|
|
1447
|
-
}
|
|
1448
|
-
async shouldAdvertize(params) {
|
|
1449
|
-
return this._params.shouldAdvertize(params);
|
|
1450
|
-
}
|
|
1451
|
-
/**
|
|
1452
|
-
* Start exchanging messages with the remote peer.
|
|
1453
|
-
* Call after the remote peer has connected.
|
|
1454
|
-
*/
|
|
1455
|
-
async enable() {
|
|
1456
|
-
invariant5(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1457
|
-
F: __dxlog_file6,
|
|
1458
|
-
L: 221,
|
|
1459
|
-
S: this,
|
|
1460
|
-
A: [
|
|
1461
|
-
"this._remotePeerId != null",
|
|
1462
|
-
"'Remote peer has not connected yet.'"
|
|
1463
|
-
]
|
|
1464
|
-
});
|
|
1465
|
-
this._isEnabled = true;
|
|
1466
|
-
}
|
|
1467
|
-
/**
|
|
1468
|
-
* Stop exchanging messages with the remote peer.
|
|
1469
|
-
*/
|
|
1470
|
-
async disable() {
|
|
1471
|
-
this._isEnabled = false;
|
|
1472
|
-
}
|
|
1473
|
-
};
|
|
1474
1334
|
export {
|
|
1475
1335
|
AuthExtension,
|
|
1476
1336
|
AuthStatus,
|
|
@@ -1482,7 +1342,7 @@ export {
|
|
|
1482
1342
|
LocalHostNetworkAdapter,
|
|
1483
1343
|
MOCK_AUTH_PROVIDER,
|
|
1484
1344
|
MOCK_AUTH_VERIFIER,
|
|
1485
|
-
|
|
1345
|
+
MeshNetworkAdapter,
|
|
1486
1346
|
MetadataStore,
|
|
1487
1347
|
Pipeline,
|
|
1488
1348
|
SnapshotManager,
|