@dxos/echo-pipeline 0.5.3-main.3456876 → 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 +287 -434
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +277 -424
- 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 +85 -59
- 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 -235
|
@@ -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
|
|
34
|
+
import { log as log4 } from "@dxos/log";
|
|
35
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) {
|
|
@@ -806,25 +927,14 @@ var AutomergeHost = class {
|
|
|
806
927
|
_automergePeers() {
|
|
807
928
|
return this._repo.peers;
|
|
808
929
|
}
|
|
809
|
-
async _getContainingSpaceForDocument(documentId) {
|
|
810
|
-
const doc = this._repo.handles[documentId]?.docSync();
|
|
811
|
-
if (!doc) {
|
|
812
|
-
return null;
|
|
813
|
-
}
|
|
814
|
-
const spaceKeyHex = getSpaceKeyFromDoc(doc);
|
|
815
|
-
if (!spaceKeyHex) {
|
|
816
|
-
return null;
|
|
817
|
-
}
|
|
818
|
-
return PublicKey.from(spaceKeyHex);
|
|
819
|
-
}
|
|
820
930
|
//
|
|
821
931
|
// Methods for client-services.
|
|
822
932
|
//
|
|
823
933
|
async flush({ states }) {
|
|
824
934
|
await Promise.all(states?.map(async ({ heads, documentId }) => {
|
|
825
|
-
|
|
826
|
-
F:
|
|
827
|
-
L:
|
|
935
|
+
invariant4(heads, "heads are required for flush", {
|
|
936
|
+
F: __dxlog_file5,
|
|
937
|
+
L: 252,
|
|
828
938
|
S: this,
|
|
829
939
|
A: [
|
|
830
940
|
"heads",
|
|
@@ -845,6 +955,24 @@ var AutomergeHost = class {
|
|
|
845
955
|
async getHostInfo() {
|
|
846
956
|
return this._clientNetwork.getHostInfo();
|
|
847
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
|
+
}
|
|
848
976
|
};
|
|
849
977
|
_ts_decorate2([
|
|
850
978
|
trace.info()
|
|
@@ -897,8 +1025,8 @@ var changeIsPresentInDoc = (doc, changeHash) => {
|
|
|
897
1025
|
import { Event as Event2 } from "@dxos/async";
|
|
898
1026
|
import { cancelWithContext } from "@dxos/context";
|
|
899
1027
|
import { warnAfterTimeout } from "@dxos/debug";
|
|
900
|
-
import { invariant as
|
|
901
|
-
import { log as
|
|
1028
|
+
import { invariant as invariant5 } from "@dxos/invariant";
|
|
1029
|
+
import { log as log5 } from "@dxos/log";
|
|
902
1030
|
import { trace as trace2 } from "@dxos/tracing";
|
|
903
1031
|
function _ts_decorate3(decorators, target, key, desc) {
|
|
904
1032
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -910,7 +1038,7 @@ function _ts_decorate3(decorators, target, key, desc) {
|
|
|
910
1038
|
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
911
1039
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
912
1040
|
}
|
|
913
|
-
var
|
|
1041
|
+
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/automerge-doc-loader.ts";
|
|
914
1042
|
var AutomergeDocumentLoaderImpl = class {
|
|
915
1043
|
constructor(_spaceKey, _repo) {
|
|
916
1044
|
this._spaceKey = _spaceKey;
|
|
@@ -931,10 +1059,10 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
931
1059
|
return;
|
|
932
1060
|
}
|
|
933
1061
|
if (!spaceState.rootUrl) {
|
|
934
|
-
|
|
1062
|
+
log5.error("Database opened with no rootUrl", {
|
|
935
1063
|
spaceKey: this._spaceKey
|
|
936
1064
|
}, {
|
|
937
|
-
F:
|
|
1065
|
+
F: __dxlog_file6,
|
|
938
1066
|
L: 70,
|
|
939
1067
|
S: this,
|
|
940
1068
|
C: (f, a) => f(...a)
|
|
@@ -943,8 +1071,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
943
1071
|
} else {
|
|
944
1072
|
const existingDocHandle = await this._initDocHandle(ctx, spaceState.rootUrl);
|
|
945
1073
|
const doc = existingDocHandle.docSync();
|
|
946
|
-
|
|
947
|
-
F:
|
|
1074
|
+
invariant5(doc, void 0, {
|
|
1075
|
+
F: __dxlog_file6,
|
|
948
1076
|
L: 75,
|
|
949
1077
|
S: this,
|
|
950
1078
|
A: [
|
|
@@ -965,8 +1093,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
965
1093
|
let hasUrlsToLoad = false;
|
|
966
1094
|
const urlsToLoad = {};
|
|
967
1095
|
for (const objectId of objectIds) {
|
|
968
|
-
|
|
969
|
-
F:
|
|
1096
|
+
invariant5(this._spaceRootDocHandle, void 0, {
|
|
1097
|
+
F: __dxlog_file6,
|
|
970
1098
|
L: 88,
|
|
971
1099
|
S: this,
|
|
972
1100
|
A: [
|
|
@@ -978,8 +1106,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
978
1106
|
continue;
|
|
979
1107
|
}
|
|
980
1108
|
const spaceRootDoc = this._spaceRootDocHandle.docSync();
|
|
981
|
-
|
|
982
|
-
F:
|
|
1109
|
+
invariant5(spaceRootDoc, void 0, {
|
|
1110
|
+
F: __dxlog_file6,
|
|
983
1111
|
L: 93,
|
|
984
1112
|
S: this,
|
|
985
1113
|
A: [
|
|
@@ -990,10 +1118,10 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
990
1118
|
const documentUrl = (spaceRootDoc.links ?? {})[objectId];
|
|
991
1119
|
if (documentUrl == null) {
|
|
992
1120
|
this._objectsPendingDocumentLoad.add(objectId);
|
|
993
|
-
|
|
1121
|
+
log5.info("loading delayed until object links are initialized", {
|
|
994
1122
|
objectId
|
|
995
1123
|
}, {
|
|
996
|
-
F:
|
|
1124
|
+
F: __dxlog_file6,
|
|
997
1125
|
L: 97,
|
|
998
1126
|
S: this,
|
|
999
1127
|
C: (f, a) => f(...a)
|
|
@@ -1016,8 +1144,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1016
1144
|
linksAwaitingLoad.forEach(([objectId]) => this._objectsPendingDocumentLoad.delete(objectId));
|
|
1017
1145
|
}
|
|
1018
1146
|
getSpaceRootDocHandle() {
|
|
1019
|
-
|
|
1020
|
-
F:
|
|
1147
|
+
invariant5(this._spaceRootDocHandle, void 0, {
|
|
1148
|
+
F: __dxlog_file6,
|
|
1021
1149
|
L: 120,
|
|
1022
1150
|
S: this,
|
|
1023
1151
|
A: [
|
|
@@ -1028,8 +1156,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1028
1156
|
return this._spaceRootDocHandle;
|
|
1029
1157
|
}
|
|
1030
1158
|
createDocumentForObject(objectId) {
|
|
1031
|
-
|
|
1032
|
-
F:
|
|
1159
|
+
invariant5(this._spaceRootDocHandle, void 0, {
|
|
1160
|
+
F: __dxlog_file6,
|
|
1033
1161
|
L: 125,
|
|
1034
1162
|
S: this,
|
|
1035
1163
|
A: [
|
|
@@ -1068,11 +1196,11 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1068
1196
|
};
|
|
1069
1197
|
const objectDocumentHandle = this._objectDocumentHandles.get(objectId);
|
|
1070
1198
|
if (objectDocumentHandle != null && objectDocumentHandle.url !== automergeUrl) {
|
|
1071
|
-
|
|
1199
|
+
log5.warn("object already inlined in a different document, ignoring the link", {
|
|
1072
1200
|
...logMeta,
|
|
1073
1201
|
actualDocumentUrl: objectDocumentHandle.url
|
|
1074
1202
|
}, {
|
|
1075
|
-
F:
|
|
1203
|
+
F: __dxlog_file6,
|
|
1076
1204
|
L: 155,
|
|
1077
1205
|
S: this,
|
|
1078
1206
|
C: (f, a) => f(...a)
|
|
@@ -1080,8 +1208,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1080
1208
|
continue;
|
|
1081
1209
|
}
|
|
1082
1210
|
if (objectDocumentHandle?.url === automergeUrl) {
|
|
1083
|
-
|
|
1084
|
-
F:
|
|
1211
|
+
log5.warn("object document was already loaded", logMeta, {
|
|
1212
|
+
F: __dxlog_file6,
|
|
1085
1213
|
L: 162,
|
|
1086
1214
|
S: this,
|
|
1087
1215
|
C: (f, a) => f(...a)
|
|
@@ -1089,8 +1217,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1089
1217
|
continue;
|
|
1090
1218
|
}
|
|
1091
1219
|
const handle = this._repo.find(automergeUrl);
|
|
1092
|
-
|
|
1093
|
-
F:
|
|
1220
|
+
log5.debug("document loading triggered", logMeta, {
|
|
1221
|
+
F: __dxlog_file6,
|
|
1094
1222
|
L: 166,
|
|
1095
1223
|
S: this,
|
|
1096
1224
|
C: (f, a) => f(...a)
|
|
@@ -1109,11 +1237,11 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1109
1237
|
break;
|
|
1110
1238
|
} catch (err) {
|
|
1111
1239
|
if (`${err}`.includes("Timeout")) {
|
|
1112
|
-
|
|
1240
|
+
log5.info("wraparound", {
|
|
1113
1241
|
id: docHandle.documentId,
|
|
1114
1242
|
state: docHandle.state
|
|
1115
1243
|
}, {
|
|
1116
|
-
F:
|
|
1244
|
+
F: __dxlog_file6,
|
|
1117
1245
|
L: 182,
|
|
1118
1246
|
S: this,
|
|
1119
1247
|
C: (f, a) => f(...a)
|
|
@@ -1154,8 +1282,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1154
1282
|
docUrl: handle.url
|
|
1155
1283
|
};
|
|
1156
1284
|
if (this.onObjectDocumentLoaded.listenerCount() === 0) {
|
|
1157
|
-
|
|
1158
|
-
F:
|
|
1285
|
+
log5.info("document loaded after all listeners were removed", logMeta, {
|
|
1286
|
+
F: __dxlog_file6,
|
|
1159
1287
|
L: 218,
|
|
1160
1288
|
S: this,
|
|
1161
1289
|
C: (f, a) => f(...a)
|
|
@@ -1164,8 +1292,8 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1164
1292
|
}
|
|
1165
1293
|
const objectDocHandle = this._objectDocumentHandles.get(objectId);
|
|
1166
1294
|
if (objectDocHandle?.url !== handle.url) {
|
|
1167
|
-
|
|
1168
|
-
F:
|
|
1295
|
+
log5.warn("object was rebound while a document was loading, discarding handle", logMeta, {
|
|
1296
|
+
F: __dxlog_file6,
|
|
1169
1297
|
L: 223,
|
|
1170
1298
|
S: this,
|
|
1171
1299
|
C: (f, a) => f(...a)
|
|
@@ -1178,13 +1306,13 @@ var AutomergeDocumentLoaderImpl = class {
|
|
|
1178
1306
|
});
|
|
1179
1307
|
} catch (err) {
|
|
1180
1308
|
const shouldRetryLoading = this.onObjectDocumentLoaded.listenerCount() > 0;
|
|
1181
|
-
|
|
1309
|
+
log5.warn("failed to load a document", {
|
|
1182
1310
|
objectId,
|
|
1183
1311
|
automergeUrl: handle.url,
|
|
1184
1312
|
retryLoading: shouldRetryLoading,
|
|
1185
1313
|
err
|
|
1186
1314
|
}, {
|
|
1187
|
-
F:
|
|
1315
|
+
F: __dxlog_file6,
|
|
1188
1316
|
L: 229,
|
|
1189
1317
|
S: this,
|
|
1190
1318
|
C: (f, a) => f(...a)
|
|
@@ -1203,281 +1331,6 @@ _ts_decorate3([
|
|
|
1203
1331
|
AutomergeDocumentLoaderImpl = _ts_decorate3([
|
|
1204
1332
|
trace2.resource()
|
|
1205
1333
|
], AutomergeDocumentLoaderImpl);
|
|
1206
|
-
|
|
1207
|
-
// packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts
|
|
1208
|
-
import { cbor as cbor2 } from "@dxos/automerge/automerge-repo";
|
|
1209
|
-
import { Resource as Resource2 } from "@dxos/context";
|
|
1210
|
-
import { invariant as invariant5 } from "@dxos/invariant";
|
|
1211
|
-
import { PublicKey as PublicKey2 } from "@dxos/keys";
|
|
1212
|
-
import { log as log5 } from "@dxos/log";
|
|
1213
|
-
import { AutomergeReplicator } from "@dxos/teleport-extension-automerge-replicator";
|
|
1214
|
-
import { ComplexMap, ComplexSet, defaultMap } from "@dxos/util";
|
|
1215
|
-
var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/core/echo/echo-pipeline/src/automerge/mesh-echo-replicator.ts";
|
|
1216
|
-
var MeshEchoReplicator = class {
|
|
1217
|
-
constructor() {
|
|
1218
|
-
this._connections = /* @__PURE__ */ new Set();
|
|
1219
|
-
/**
|
|
1220
|
-
* Using automerge peerId as a key.
|
|
1221
|
-
*/
|
|
1222
|
-
this._connectionsPerPeer = /* @__PURE__ */ new Map();
|
|
1223
|
-
/**
|
|
1224
|
-
* spaceKey -> deviceKey[]
|
|
1225
|
-
*/
|
|
1226
|
-
this._authorizedDevices = new ComplexMap(PublicKey2.hash);
|
|
1227
|
-
this._context = null;
|
|
1228
|
-
}
|
|
1229
|
-
async connect(context) {
|
|
1230
|
-
this._context = context;
|
|
1231
|
-
}
|
|
1232
|
-
async disconnect() {
|
|
1233
|
-
for (const connection of this._connections) {
|
|
1234
|
-
await connection.close();
|
|
1235
|
-
}
|
|
1236
|
-
this._connections.clear();
|
|
1237
|
-
this._connectionsPerPeer.clear();
|
|
1238
|
-
this._context = null;
|
|
1239
|
-
}
|
|
1240
|
-
createExtension() {
|
|
1241
|
-
invariant5(this._context, void 0, {
|
|
1242
|
-
F: __dxlog_file6,
|
|
1243
|
-
L: 54,
|
|
1244
|
-
S: this,
|
|
1245
|
-
A: [
|
|
1246
|
-
"this._context",
|
|
1247
|
-
""
|
|
1248
|
-
]
|
|
1249
|
-
});
|
|
1250
|
-
const connection = new MeshReplicatorConnection({
|
|
1251
|
-
ownPeerId: this._context.peerId,
|
|
1252
|
-
onRemoteConnected: async () => {
|
|
1253
|
-
log5("onRemoteConnected", {
|
|
1254
|
-
peerId: connection.peerId
|
|
1255
|
-
}, {
|
|
1256
|
-
F: __dxlog_file6,
|
|
1257
|
-
L: 59,
|
|
1258
|
-
S: this,
|
|
1259
|
-
C: (f, a) => f(...a)
|
|
1260
|
-
});
|
|
1261
|
-
invariant5(this._context, void 0, {
|
|
1262
|
-
F: __dxlog_file6,
|
|
1263
|
-
L: 60,
|
|
1264
|
-
S: this,
|
|
1265
|
-
A: [
|
|
1266
|
-
"this._context",
|
|
1267
|
-
""
|
|
1268
|
-
]
|
|
1269
|
-
});
|
|
1270
|
-
if (!this._connectionsPerPeer.has(connection.peerId)) {
|
|
1271
|
-
this._connectionsPerPeer.set(connection.peerId, connection);
|
|
1272
|
-
await connection.enable();
|
|
1273
|
-
this._context.onConnectionOpen(connection);
|
|
1274
|
-
}
|
|
1275
|
-
},
|
|
1276
|
-
onRemoteDisconnected: async () => {
|
|
1277
|
-
log5("onRemoteDisconnected", {
|
|
1278
|
-
peerId: connection.peerId
|
|
1279
|
-
}, {
|
|
1280
|
-
F: __dxlog_file6,
|
|
1281
|
-
L: 69,
|
|
1282
|
-
S: this,
|
|
1283
|
-
C: (f, a) => f(...a)
|
|
1284
|
-
});
|
|
1285
|
-
invariant5(this._context, void 0, {
|
|
1286
|
-
F: __dxlog_file6,
|
|
1287
|
-
L: 70,
|
|
1288
|
-
S: this,
|
|
1289
|
-
A: [
|
|
1290
|
-
"this._context",
|
|
1291
|
-
""
|
|
1292
|
-
]
|
|
1293
|
-
});
|
|
1294
|
-
this._context.onConnectionClosed(connection);
|
|
1295
|
-
await connection.disable();
|
|
1296
|
-
this._connectionsPerPeer.delete(connection.peerId);
|
|
1297
|
-
this._connections.delete(connection);
|
|
1298
|
-
},
|
|
1299
|
-
shouldAdvertize: async (params) => {
|
|
1300
|
-
log5("shouldAdvertize", {
|
|
1301
|
-
peerId: connection.peerId,
|
|
1302
|
-
documentId: params.documentId
|
|
1303
|
-
}, {
|
|
1304
|
-
F: __dxlog_file6,
|
|
1305
|
-
L: 77,
|
|
1306
|
-
S: this,
|
|
1307
|
-
C: (f, a) => f(...a)
|
|
1308
|
-
});
|
|
1309
|
-
invariant5(this._context, void 0, {
|
|
1310
|
-
F: __dxlog_file6,
|
|
1311
|
-
L: 78,
|
|
1312
|
-
S: this,
|
|
1313
|
-
A: [
|
|
1314
|
-
"this._context",
|
|
1315
|
-
""
|
|
1316
|
-
]
|
|
1317
|
-
});
|
|
1318
|
-
try {
|
|
1319
|
-
const spaceKey = await this._context.getContainingSpaceForDocument(params.documentId);
|
|
1320
|
-
if (!spaceKey) {
|
|
1321
|
-
log5("space key not found for share policy check", {
|
|
1322
|
-
peerId: connection.peerId,
|
|
1323
|
-
documentId: params.documentId
|
|
1324
|
-
}, {
|
|
1325
|
-
F: __dxlog_file6,
|
|
1326
|
-
L: 82,
|
|
1327
|
-
S: this,
|
|
1328
|
-
C: (f, a) => f(...a)
|
|
1329
|
-
});
|
|
1330
|
-
return false;
|
|
1331
|
-
}
|
|
1332
|
-
const authorizedDevices = this._authorizedDevices.get(spaceKey);
|
|
1333
|
-
if (!connection.remoteDeviceKey) {
|
|
1334
|
-
log5("device key not found for share policy check", {
|
|
1335
|
-
peerId: connection.peerId,
|
|
1336
|
-
documentId: params.documentId
|
|
1337
|
-
}, {
|
|
1338
|
-
F: __dxlog_file6,
|
|
1339
|
-
L: 94,
|
|
1340
|
-
S: this,
|
|
1341
|
-
C: (f, a) => f(...a)
|
|
1342
|
-
});
|
|
1343
|
-
return false;
|
|
1344
|
-
}
|
|
1345
|
-
const isAuthorized = authorizedDevices?.has(connection.remoteDeviceKey) ?? false;
|
|
1346
|
-
log5("share policy check", {
|
|
1347
|
-
localPeer: this._context.peerId,
|
|
1348
|
-
remotePeer: connection.peerId,
|
|
1349
|
-
documentId: params.documentId,
|
|
1350
|
-
deviceKey: connection.remoteDeviceKey,
|
|
1351
|
-
spaceKey,
|
|
1352
|
-
isAuthorized
|
|
1353
|
-
}, {
|
|
1354
|
-
F: __dxlog_file6,
|
|
1355
|
-
L: 103,
|
|
1356
|
-
S: this,
|
|
1357
|
-
C: (f, a) => f(...a)
|
|
1358
|
-
});
|
|
1359
|
-
return isAuthorized;
|
|
1360
|
-
} catch (err) {
|
|
1361
|
-
log5.catch(err, void 0, {
|
|
1362
|
-
F: __dxlog_file6,
|
|
1363
|
-
L: 113,
|
|
1364
|
-
S: this,
|
|
1365
|
-
C: (f, a) => f(...a)
|
|
1366
|
-
});
|
|
1367
|
-
return false;
|
|
1368
|
-
}
|
|
1369
|
-
}
|
|
1370
|
-
});
|
|
1371
|
-
this._connections.add(connection);
|
|
1372
|
-
return connection.replicatorExtension;
|
|
1373
|
-
}
|
|
1374
|
-
authorizeDevice(spaceKey, deviceKey) {
|
|
1375
|
-
log5("authorizeDevice", {
|
|
1376
|
-
spaceKey,
|
|
1377
|
-
deviceKey
|
|
1378
|
-
}, {
|
|
1379
|
-
F: __dxlog_file6,
|
|
1380
|
-
L: 124,
|
|
1381
|
-
S: this,
|
|
1382
|
-
C: (f, a) => f(...a)
|
|
1383
|
-
});
|
|
1384
|
-
defaultMap(this._authorizedDevices, spaceKey, () => new ComplexSet(PublicKey2.hash)).add(deviceKey);
|
|
1385
|
-
}
|
|
1386
|
-
};
|
|
1387
|
-
var MeshReplicatorConnection = class extends Resource2 {
|
|
1388
|
-
constructor(_params) {
|
|
1389
|
-
super();
|
|
1390
|
-
this._params = _params;
|
|
1391
|
-
this.remoteDeviceKey = null;
|
|
1392
|
-
this._remotePeerId = null;
|
|
1393
|
-
this._isEnabled = false;
|
|
1394
|
-
let readableStreamController;
|
|
1395
|
-
this.readable = new ReadableStream({
|
|
1396
|
-
start: (controller) => {
|
|
1397
|
-
readableStreamController = controller;
|
|
1398
|
-
this._ctx.onDispose(() => controller.close());
|
|
1399
|
-
}
|
|
1400
|
-
});
|
|
1401
|
-
this.writable = new WritableStream({
|
|
1402
|
-
write: async (message, controller) => {
|
|
1403
|
-
this.replicatorExtension.sendSyncMessage({
|
|
1404
|
-
payload: cbor2.encode(message)
|
|
1405
|
-
}).catch((err) => {
|
|
1406
|
-
controller.error(err);
|
|
1407
|
-
});
|
|
1408
|
-
}
|
|
1409
|
-
});
|
|
1410
|
-
this.replicatorExtension = new AutomergeReplicator({
|
|
1411
|
-
peerId: this._params.ownPeerId
|
|
1412
|
-
}, {
|
|
1413
|
-
onStartReplication: async (info, remotePeerId) => {
|
|
1414
|
-
this.remoteDeviceKey = remotePeerId;
|
|
1415
|
-
this._remotePeerId = info.id;
|
|
1416
|
-
log5("onStartReplication", {
|
|
1417
|
-
id: info.id,
|
|
1418
|
-
thisPeerId: this.peerId,
|
|
1419
|
-
remotePeerId: remotePeerId.toHex()
|
|
1420
|
-
}, {
|
|
1421
|
-
F: __dxlog_file6,
|
|
1422
|
-
L: 189,
|
|
1423
|
-
S: this,
|
|
1424
|
-
C: (f, a) => f(...a)
|
|
1425
|
-
});
|
|
1426
|
-
await this._params.onRemoteConnected();
|
|
1427
|
-
},
|
|
1428
|
-
onSyncMessage: async ({ payload }) => {
|
|
1429
|
-
if (!this._isEnabled) {
|
|
1430
|
-
return;
|
|
1431
|
-
}
|
|
1432
|
-
const message = cbor2.decode(payload);
|
|
1433
|
-
readableStreamController.enqueue(message);
|
|
1434
|
-
},
|
|
1435
|
-
onClose: async () => {
|
|
1436
|
-
if (!this._isEnabled) {
|
|
1437
|
-
return;
|
|
1438
|
-
}
|
|
1439
|
-
await this._params.onRemoteDisconnected();
|
|
1440
|
-
}
|
|
1441
|
-
});
|
|
1442
|
-
}
|
|
1443
|
-
get peerId() {
|
|
1444
|
-
invariant5(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1445
|
-
F: __dxlog_file6,
|
|
1446
|
-
L: 212,
|
|
1447
|
-
S: this,
|
|
1448
|
-
A: [
|
|
1449
|
-
"this._remotePeerId != null",
|
|
1450
|
-
"'Remote peer has not connected yet.'"
|
|
1451
|
-
]
|
|
1452
|
-
});
|
|
1453
|
-
return this._remotePeerId;
|
|
1454
|
-
}
|
|
1455
|
-
async shouldAdvertize(params) {
|
|
1456
|
-
return this._params.shouldAdvertize(params);
|
|
1457
|
-
}
|
|
1458
|
-
/**
|
|
1459
|
-
* Start exchanging messages with the remote peer.
|
|
1460
|
-
* Call after the remote peer has connected.
|
|
1461
|
-
*/
|
|
1462
|
-
async enable() {
|
|
1463
|
-
invariant5(this._remotePeerId != null, "Remote peer has not connected yet.", {
|
|
1464
|
-
F: __dxlog_file6,
|
|
1465
|
-
L: 225,
|
|
1466
|
-
S: this,
|
|
1467
|
-
A: [
|
|
1468
|
-
"this._remotePeerId != null",
|
|
1469
|
-
"'Remote peer has not connected yet.'"
|
|
1470
|
-
]
|
|
1471
|
-
});
|
|
1472
|
-
this._isEnabled = true;
|
|
1473
|
-
}
|
|
1474
|
-
/**
|
|
1475
|
-
* Stop exchanging messages with the remote peer.
|
|
1476
|
-
*/
|
|
1477
|
-
async disable() {
|
|
1478
|
-
this._isEnabled = false;
|
|
1479
|
-
}
|
|
1480
|
-
};
|
|
1481
1334
|
export {
|
|
1482
1335
|
AuthExtension,
|
|
1483
1336
|
AuthStatus,
|
|
@@ -1489,7 +1342,7 @@ export {
|
|
|
1489
1342
|
LocalHostNetworkAdapter,
|
|
1490
1343
|
MOCK_AUTH_PROVIDER,
|
|
1491
1344
|
MOCK_AUTH_VERIFIER,
|
|
1492
|
-
|
|
1345
|
+
MeshNetworkAdapter,
|
|
1493
1346
|
MetadataStore,
|
|
1494
1347
|
Pipeline,
|
|
1495
1348
|
SnapshotManager,
|