@dxos/echo-pipeline 0.8.2-staging.7ac8446 → 0.8.2
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/{chunk-32WDI3LB.mjs → chunk-3XSXS5EX.mjs} +15 -21
- package/dist/lib/browser/chunk-3XSXS5EX.mjs.map +7 -0
- package/dist/lib/browser/chunk-CGS2ULMK.mjs +11 -0
- package/dist/lib/browser/chunk-CGS2ULMK.mjs.map +7 -0
- package/dist/lib/browser/chunk-TQJTKNMS.mjs +126 -0
- package/dist/lib/browser/chunk-TQJTKNMS.mjs.map +7 -0
- package/dist/lib/browser/filter/index.mjs +11 -0
- package/dist/lib/browser/filter/index.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1380 -516
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +202 -22
- package/dist/lib/browser/testing/index.mjs.map +4 -4
- package/dist/lib/node/chunk-HOPOFWAL.cjs +147 -0
- package/dist/lib/node/chunk-HOPOFWAL.cjs.map +7 -0
- package/dist/lib/node/chunk-Q7SFCCGT.cjs +33 -0
- package/dist/lib/node/chunk-Q7SFCCGT.cjs.map +7 -0
- package/dist/lib/node/{chunk-TC2PRBEU.cjs → chunk-SG2PL5RH.cjs} +18 -24
- package/dist/lib/node/chunk-SG2PL5RH.cjs.map +7 -0
- package/dist/lib/node/filter/index.cjs +32 -0
- package/dist/lib/node/filter/index.cjs.map +7 -0
- package/dist/lib/node/index.cjs +1381 -525
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +207 -31
- package/dist/lib/node/testing/index.cjs.map +4 -4
- package/dist/lib/node-esm/{chunk-UKOLB3LW.mjs → chunk-3BZP75TJ.mjs} +15 -21
- package/dist/lib/node-esm/chunk-3BZP75TJ.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-RVK35BS7.mjs +126 -0
- package/dist/lib/node-esm/chunk-RVK35BS7.mjs.map +7 -0
- package/dist/lib/node-esm/filter/index.mjs +11 -0
- package/dist/lib/node-esm/filter/index.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +1380 -516
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +202 -22
- package/dist/lib/node-esm/testing/index.mjs.map +4 -4
- package/dist/types/src/automerge/automerge-host.d.ts +6 -4
- package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
- package/dist/types/src/automerge/collection-synchronizer.d.ts +1 -1
- package/dist/types/src/automerge/collection-synchronizer.d.ts.map +1 -1
- package/dist/types/src/automerge/echo-data-monitor.d.ts +6 -6
- package/dist/types/src/automerge/echo-data-monitor.d.ts.map +1 -1
- package/dist/types/src/automerge/echo-network-adapter.d.ts +4 -1
- package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
- package/dist/types/src/automerge/heads-store.d.ts +2 -2
- package/dist/types/src/automerge/heads-store.d.ts.map +1 -1
- package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +1 -1
- package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -1
- package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts.map +1 -1
- package/dist/types/src/automerge/mesh-echo-replicator.d.ts.map +1 -1
- package/dist/types/src/automerge/network-protocol.d.ts +1 -1
- package/dist/types/src/automerge/network-protocol.d.ts.map +1 -1
- package/dist/types/src/automerge/space-collection.d.ts +1 -1
- package/dist/types/src/automerge/space-collection.d.ts.map +1 -1
- package/dist/types/src/common/feeds.d.ts.map +1 -1
- package/dist/types/src/common/space-id.d.ts.map +1 -1
- package/dist/types/src/db-host/automerge-metrics.d.ts +1 -1
- package/dist/types/src/db-host/automerge-metrics.d.ts.map +1 -1
- package/dist/types/src/db-host/data-service.d.ts.map +1 -1
- package/dist/types/src/db-host/database-root.d.ts +7 -7
- package/dist/types/src/db-host/database-root.d.ts.map +1 -1
- package/dist/types/src/db-host/documents-iterator.d.ts +1 -1
- package/dist/types/src/db-host/documents-iterator.d.ts.map +1 -1
- package/dist/types/src/db-host/documents-synchronizer.d.ts +4 -4
- package/dist/types/src/db-host/documents-synchronizer.d.ts.map +1 -1
- package/dist/types/src/db-host/echo-host.d.ts +13 -2
- package/dist/types/src/db-host/echo-host.d.ts.map +1 -1
- package/dist/types/src/db-host/index.d.ts +0 -1
- package/dist/types/src/db-host/index.d.ts.map +1 -1
- package/dist/types/src/db-host/query-service.d.ts +2 -0
- package/dist/types/src/db-host/query-service.d.ts.map +1 -1
- package/dist/types/src/db-host/space-state-manager.d.ts +4 -3
- package/dist/types/src/db-host/space-state-manager.d.ts.map +1 -1
- package/dist/types/src/edge/echo-edge-replicator.d.ts.map +1 -1
- package/dist/types/src/edge/inflight-request-limiter.d.ts.map +1 -1
- package/dist/types/src/filter/filter-match.d.ts +13 -0
- package/dist/types/src/filter/filter-match.d.ts.map +1 -0
- package/dist/types/src/filter/filter-match.test.d.ts +2 -0
- package/dist/types/src/filter/filter-match.test.d.ts.map +1 -0
- package/dist/types/src/filter/index.d.ts +2 -0
- package/dist/types/src/filter/index.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
- package/dist/types/src/pipeline/message-selector.d.ts.map +1 -1
- package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
- package/dist/types/src/pipeline/timeframe-clock.d.ts.map +1 -1
- package/dist/types/src/query/errors.d.ts +23 -0
- package/dist/types/src/query/errors.d.ts.map +1 -0
- package/dist/types/src/query/index.d.ts +5 -0
- package/dist/types/src/query/index.d.ts.map +1 -0
- package/dist/types/src/query/plan.d.ts +132 -0
- package/dist/types/src/query/plan.d.ts.map +1 -0
- package/dist/types/src/query/query-executor.d.ts +83 -0
- package/dist/types/src/query/query-executor.d.ts.map +1 -0
- package/dist/types/src/query/query-planner.d.ts +33 -0
- package/dist/types/src/query/query-planner.d.ts.map +1 -0
- package/dist/types/src/query/query-planner.test.d.ts +2 -0
- package/dist/types/src/query/query-planner.test.d.ts.map +1 -0
- package/dist/types/src/space/admission-discovery-extension.d.ts.map +1 -1
- package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
- package/dist/types/src/space/space-manager.d.ts.map +1 -1
- package/dist/types/src/space/space-protocol.d.ts.map +1 -1
- package/dist/types/src/space/space.d.ts.map +1 -1
- package/dist/types/src/testing/change-metadata.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +2 -0
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
- package/dist/types/src/testing/test-data.d.ts +18 -0
- package/dist/types/src/testing/test-data.d.ts.map +1 -0
- package/dist/types/src/testing/test-network-adapter.d.ts +3 -2
- package/dist/types/src/testing/test-network-adapter.d.ts.map +1 -1
- package/dist/types/src/testing/test-schema.d.ts +39 -0
- package/dist/types/src/testing/test-schema.d.ts.map +1 -0
- package/dist/types/src/util.d.ts +2 -2
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +43 -34
- package/src/automerge/automerge-host.test.ts +7 -7
- package/src/automerge/automerge-host.ts +58 -60
- package/src/automerge/automerge-repo.test.ts +65 -65
- package/src/automerge/collection-synchronizer.test.ts +1 -1
- package/src/automerge/collection-synchronizer.ts +11 -10
- package/src/automerge/echo-data-monitor.ts +21 -20
- package/src/automerge/echo-network-adapter.test.ts +1 -1
- package/src/automerge/echo-network-adapter.ts +25 -18
- package/src/automerge/heads-store.ts +4 -3
- package/src/automerge/leveldb-storage-adapter.ts +1 -1
- package/src/automerge/mesh-echo-replicator-connection.ts +6 -5
- package/src/automerge/mesh-echo-replicator.ts +2 -2
- package/src/automerge/network-protocol.ts +2 -1
- package/src/automerge/space-collection.ts +2 -1
- package/src/db-host/automerge-metrics.ts +2 -1
- package/src/db-host/data-service.ts +4 -3
- package/src/db-host/database-root.ts +17 -22
- package/src/db-host/documents-iterator.ts +9 -8
- package/src/db-host/documents-synchronizer.test.ts +2 -2
- package/src/db-host/documents-synchronizer.ts +20 -18
- package/src/db-host/echo-host.ts +44 -15
- package/src/db-host/index.ts +0 -1
- package/src/db-host/query-service.ts +43 -37
- package/src/db-host/space-state-manager.ts +14 -4
- package/src/edge/echo-edge-replicator.test.ts +3 -3
- package/src/edge/echo-edge-replicator.ts +9 -8
- package/src/edge/inflight-request-limiter.ts +4 -4
- package/src/filter/filter-match.test.ts +101 -0
- package/src/filter/filter-match.ts +174 -0
- package/src/filter/index.ts +5 -0
- package/src/index.ts +1 -0
- package/src/metadata/metadata-store.ts +13 -13
- package/src/pipeline/pipeline-stress.test.ts +9 -9
- package/src/pipeline/pipeline.ts +13 -13
- package/src/pipeline/timeframe-clock.ts +5 -5
- package/src/query/errors.ts +7 -0
- package/src/query/index.ts +8 -0
- package/src/query/plan.ts +179 -0
- package/src/query/query-executor.ts +648 -0
- package/src/query/query-planner.test.ts +613 -0
- package/src/query/query-planner.ts +470 -0
- package/src/space/admission-discovery-extension.ts +2 -2
- package/src/space/control-pipeline.ts +8 -8
- package/src/space/space-manager.ts +5 -4
- package/src/space/space-protocol.browser.test.ts +1 -0
- package/src/space/space-protocol.test.ts +1 -0
- package/src/space/space-protocol.ts +4 -4
- package/src/space/space.ts +5 -5
- package/src/testing/index.ts +2 -0
- package/src/testing/test-agent-builder.ts +6 -6
- package/src/testing/test-data.ts +127 -0
- package/src/testing/test-network-adapter.ts +15 -12
- package/src/testing/test-replicator.ts +2 -2
- package/src/testing/test-schema.ts +53 -0
- package/src/util.ts +7 -3
- package/dist/lib/browser/chunk-32WDI3LB.mjs.map +0 -7
- package/dist/lib/node/chunk-TC2PRBEU.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-UKOLB3LW.mjs.map +0 -7
- package/dist/types/src/db-host/query-state.d.ts +0 -41
- package/dist/types/src/db-host/query-state.d.ts.map +0 -1
- package/src/db-host/query-state.ts +0 -217
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { NetworkAdapter, type Message, type PeerId, type PeerMetadata } from '@automerge/automerge-repo';
|
|
6
|
+
|
|
5
7
|
import { synchronized, Trigger } from '@dxos/async';
|
|
6
|
-
import { NetworkAdapter, type Message, type PeerId, type PeerMetadata } from '@dxos/automerge/automerge-repo';
|
|
7
8
|
import { LifecycleState } from '@dxos/context';
|
|
8
9
|
import { invariant } from '@dxos/invariant';
|
|
9
10
|
import { type PublicKey } from '@dxos/keys';
|
|
@@ -53,11 +54,20 @@ export class EchoNetworkAdapter extends NetworkAdapter {
|
|
|
53
54
|
private readonly _connections = new Map<PeerId, ConnectionEntry>();
|
|
54
55
|
private _lifecycleState: LifecycleState = LifecycleState.CLOSED;
|
|
55
56
|
private readonly _connected = new Trigger();
|
|
57
|
+
private readonly _ready = new Trigger();
|
|
56
58
|
|
|
57
59
|
constructor(private readonly _params: EchoNetworkAdapterParams) {
|
|
58
60
|
super();
|
|
59
61
|
}
|
|
60
62
|
|
|
63
|
+
override isReady(): boolean {
|
|
64
|
+
return this._lifecycleState === LifecycleState.OPEN;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
override whenReady(): Promise<void> {
|
|
68
|
+
return this._ready.wait();
|
|
69
|
+
}
|
|
70
|
+
|
|
61
71
|
override connect(peerId: PeerId, peerMetadata?: PeerMetadata | undefined): void {
|
|
62
72
|
this.peerId = peerId;
|
|
63
73
|
this.peerMetadata = peerMetadata;
|
|
@@ -73,20 +83,16 @@ export class EchoNetworkAdapter extends NetworkAdapter {
|
|
|
73
83
|
}
|
|
74
84
|
|
|
75
85
|
@synchronized
|
|
76
|
-
async open() {
|
|
86
|
+
async open(): Promise<void> {
|
|
77
87
|
if (this._lifecycleState === LifecycleState.OPEN) {
|
|
78
88
|
return;
|
|
79
89
|
}
|
|
80
90
|
this._lifecycleState = LifecycleState.OPEN;
|
|
81
|
-
|
|
82
|
-
log('emit ready');
|
|
83
|
-
this.emit('ready', {
|
|
84
|
-
network: this,
|
|
85
|
-
});
|
|
91
|
+
this._ready.wake();
|
|
86
92
|
}
|
|
87
93
|
|
|
88
94
|
@synchronized
|
|
89
|
-
async close() {
|
|
95
|
+
async close(): Promise<this | undefined> {
|
|
90
96
|
if (this._lifecycleState === LifecycleState.CLOSED) {
|
|
91
97
|
return this;
|
|
92
98
|
}
|
|
@@ -96,15 +102,16 @@ export class EchoNetworkAdapter extends NetworkAdapter {
|
|
|
96
102
|
}
|
|
97
103
|
this._replicators.clear();
|
|
98
104
|
|
|
105
|
+
this._ready.reset();
|
|
99
106
|
this._lifecycleState = LifecycleState.CLOSED;
|
|
100
107
|
}
|
|
101
108
|
|
|
102
|
-
async whenConnected() {
|
|
109
|
+
async whenConnected(): Promise<void> {
|
|
103
110
|
await this._connected.wait({ timeout: 10_000 });
|
|
104
111
|
}
|
|
105
112
|
|
|
106
113
|
@synchronized
|
|
107
|
-
async addReplicator(replicator: EchoReplicator) {
|
|
114
|
+
async addReplicator(replicator: EchoReplicator): Promise<void> {
|
|
108
115
|
invariant(this._lifecycleState === LifecycleState.OPEN);
|
|
109
116
|
invariant(this.peerId);
|
|
110
117
|
invariant(!this._replicators.has(replicator));
|
|
@@ -125,7 +132,7 @@ export class EchoNetworkAdapter extends NetworkAdapter {
|
|
|
125
132
|
}
|
|
126
133
|
|
|
127
134
|
@synchronized
|
|
128
|
-
async removeReplicator(replicator: EchoReplicator) {
|
|
135
|
+
async removeReplicator(replicator: EchoReplicator): Promise<void> {
|
|
129
136
|
invariant(this._lifecycleState === LifecycleState.OPEN);
|
|
130
137
|
invariant(this._replicators.has(replicator));
|
|
131
138
|
await replicator.disconnect();
|
|
@@ -171,7 +178,7 @@ export class EchoNetworkAdapter extends NetworkAdapter {
|
|
|
171
178
|
this._send(message);
|
|
172
179
|
}
|
|
173
180
|
|
|
174
|
-
private _send(message: Message) {
|
|
181
|
+
private _send(message: Message): void {
|
|
175
182
|
const connectionEntry = this._connections.get(message.targetId);
|
|
176
183
|
if (!connectionEntry) {
|
|
177
184
|
throw new Error('Connection not found.');
|
|
@@ -204,7 +211,7 @@ export class EchoNetworkAdapter extends NetworkAdapter {
|
|
|
204
211
|
.filter(isNonNullable);
|
|
205
212
|
}
|
|
206
213
|
|
|
207
|
-
private _onConnectionOpen(connection: ReplicatorConnection) {
|
|
214
|
+
private _onConnectionOpen(connection: ReplicatorConnection): void {
|
|
208
215
|
log('Connection opened', { peerId: connection.peerId });
|
|
209
216
|
invariant(!this._connections.has(connection.peerId as PeerId));
|
|
210
217
|
const reader = connection.readable.getReader();
|
|
@@ -235,7 +242,7 @@ export class EchoNetworkAdapter extends NetworkAdapter {
|
|
|
235
242
|
this._params.monitor?.recordPeerConnected(connection.peerId);
|
|
236
243
|
}
|
|
237
244
|
|
|
238
|
-
private _onMessage(message: Message) {
|
|
245
|
+
private _onMessage(message: Message): void {
|
|
239
246
|
if (isCollectionQueryMessage(message)) {
|
|
240
247
|
this._params.onCollectionStateQueried(message.collectionId, message.senderId);
|
|
241
248
|
} else if (isCollectionStateMessage(message)) {
|
|
@@ -246,7 +253,7 @@ export class EchoNetworkAdapter extends NetworkAdapter {
|
|
|
246
253
|
this._params.monitor?.recordMessageReceived(message);
|
|
247
254
|
}
|
|
248
255
|
|
|
249
|
-
public onConnectionAuthScopeChanged(peer: PeerId) {
|
|
256
|
+
public onConnectionAuthScopeChanged(peer: PeerId): void {
|
|
250
257
|
const entry = this._connections.get(peer);
|
|
251
258
|
if (entry) {
|
|
252
259
|
this._onConnectionAuthScopeChanged(entry.connection);
|
|
@@ -257,7 +264,7 @@ export class EchoNetworkAdapter extends NetworkAdapter {
|
|
|
257
264
|
* Trigger doc-synchronizer shared documents set recalculation. Happens on peer-candidate.
|
|
258
265
|
* TODO(y): replace with a proper API call when sharePolicy update becomes supported by automerge-repo
|
|
259
266
|
*/
|
|
260
|
-
private _onConnectionAuthScopeChanged(connection: ReplicatorConnection) {
|
|
267
|
+
private _onConnectionAuthScopeChanged(connection: ReplicatorConnection): void {
|
|
261
268
|
log('Connection auth scope changed', { peerId: connection.peerId });
|
|
262
269
|
const entry = this._connections.get(connection.peerId as PeerId);
|
|
263
270
|
invariant(entry);
|
|
@@ -265,7 +272,7 @@ export class EchoNetworkAdapter extends NetworkAdapter {
|
|
|
265
272
|
this._emitPeerCandidate(connection);
|
|
266
273
|
}
|
|
267
274
|
|
|
268
|
-
private _onConnectionClosed(connection: ReplicatorConnection) {
|
|
275
|
+
private _onConnectionClosed(connection: ReplicatorConnection): void {
|
|
269
276
|
log('Connection closed', { peerId: connection.peerId });
|
|
270
277
|
const entry = this._connections.get(connection.peerId as PeerId);
|
|
271
278
|
invariant(entry);
|
|
@@ -280,7 +287,7 @@ export class EchoNetworkAdapter extends NetworkAdapter {
|
|
|
280
287
|
this._connections.delete(connection.peerId as PeerId);
|
|
281
288
|
}
|
|
282
289
|
|
|
283
|
-
private _emitPeerCandidate(connection: ReplicatorConnection) {
|
|
290
|
+
private _emitPeerCandidate(connection: ReplicatorConnection): void {
|
|
284
291
|
this.emit('peer-candidate', {
|
|
285
292
|
peerId: connection.peerId as PeerId,
|
|
286
293
|
peerMetadata: createEchoPeerMetadata(),
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import type { Heads } from '@
|
|
6
|
-
import type { DocumentId } from '@
|
|
5
|
+
import type { Heads } from '@automerge/automerge';
|
|
6
|
+
import type { DocumentId } from '@automerge/automerge-repo';
|
|
7
|
+
|
|
7
8
|
import { headsEncoding } from '@dxos/indexing';
|
|
8
9
|
import type { BatchLevel, SublevelDB } from '@dxos/kv-store';
|
|
9
10
|
|
|
@@ -18,7 +19,7 @@ export class HeadsStore {
|
|
|
18
19
|
this._db = db;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
setHeads(documentId: DocumentId, heads: Heads, batch: BatchLevel) {
|
|
22
|
+
setHeads(documentId: DocumentId, heads: Heads, batch: BatchLevel): void {
|
|
22
23
|
batch.put<DocumentId, Heads>(documentId, heads, {
|
|
23
24
|
sublevel: this._db,
|
|
24
25
|
keyEncoding: 'utf8',
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
// s
|
|
4
4
|
|
|
5
|
+
import { type StorageAdapterInterface, type Chunk, type StorageKey } from '@automerge/automerge-repo';
|
|
5
6
|
import { type MixedEncoding } from 'level-transcoder';
|
|
6
7
|
|
|
7
|
-
import { type StorageAdapterInterface, type Chunk, type StorageKey } from '@dxos/automerge/automerge-repo';
|
|
8
8
|
import { LifecycleState, Resource } from '@dxos/context';
|
|
9
9
|
import { type BatchLevel, type SublevelDB } from '@dxos/kv-store';
|
|
10
10
|
import { type MaybePromise } from '@dxos/util';
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import * as A from '@
|
|
6
|
-
import { cbor } from '@
|
|
5
|
+
import * as A from '@automerge/automerge';
|
|
6
|
+
import { cbor } from '@automerge/automerge-repo';
|
|
7
|
+
|
|
7
8
|
import { Resource } from '@dxos/context';
|
|
8
9
|
import { invariant } from '@dxos/invariant';
|
|
9
10
|
import { type PublicKey } from '@dxos/keys';
|
|
@@ -95,7 +96,7 @@ export class MeshReplicatorConnection extends Resource implements ReplicatorConn
|
|
|
95
96
|
]);
|
|
96
97
|
}
|
|
97
98
|
|
|
98
|
-
private _disconnectIfEnabled() {
|
|
99
|
+
private _disconnectIfEnabled(): void {
|
|
99
100
|
if (this._isEnabled) {
|
|
100
101
|
this._params.onRemoteDisconnected();
|
|
101
102
|
}
|
|
@@ -122,7 +123,7 @@ export class MeshReplicatorConnection extends Resource implements ReplicatorConn
|
|
|
122
123
|
* Start exchanging messages with the remote peer.
|
|
123
124
|
* Call after the remote peer has connected.
|
|
124
125
|
*/
|
|
125
|
-
enable() {
|
|
126
|
+
enable(): void {
|
|
126
127
|
invariant(this._remotePeerId != null, 'Remote peer has not connected yet.');
|
|
127
128
|
this._isEnabled = true;
|
|
128
129
|
}
|
|
@@ -130,7 +131,7 @@ export class MeshReplicatorConnection extends Resource implements ReplicatorConn
|
|
|
130
131
|
/**
|
|
131
132
|
* Stop exchanging messages with the remote peer.
|
|
132
133
|
*/
|
|
133
|
-
disable() {
|
|
134
|
+
disable(): void {
|
|
134
135
|
this._isEnabled = false;
|
|
135
136
|
}
|
|
136
137
|
}
|
|
@@ -46,7 +46,7 @@ export class MeshEchoReplicator implements EchoReplicator {
|
|
|
46
46
|
this._context = context;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
async disconnect() {
|
|
49
|
+
async disconnect(): Promise<void> {
|
|
50
50
|
for (const connection of this._connections) {
|
|
51
51
|
if (connection.isEnabled) {
|
|
52
52
|
this._context?.onConnectionClosed(connection);
|
|
@@ -180,7 +180,7 @@ export class MeshEchoReplicator implements EchoReplicator {
|
|
|
180
180
|
return connection.replicatorExtension;
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
async authorizeDevice(spaceKey: PublicKey, deviceKey: PublicKey) {
|
|
183
|
+
async authorizeDevice(spaceKey: PublicKey, deviceKey: PublicKey): Promise<void> {
|
|
184
184
|
log('authorizeDevice', { spaceKey, deviceKey });
|
|
185
185
|
const spaceId = await createIdFromSpaceKey(spaceKey);
|
|
186
186
|
defaultMap(this._authorizedDevices, spaceId, () => new ComplexSet(PublicKey.hash)).add(deviceKey);
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type DocumentId } from '@
|
|
5
|
+
import { type DocumentId } from '@automerge/automerge-repo';
|
|
6
|
+
|
|
6
7
|
import type { CollectionId } from '@dxos/echo-protocol';
|
|
7
8
|
import { invariant } from '@dxos/invariant';
|
|
8
9
|
import { SpaceId } from '@dxos/keys';
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
// Copyright 2021 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { type DocumentId } from '@automerge/automerge-repo';
|
|
6
|
+
|
|
5
7
|
import { UpdateScheduler } from '@dxos/async';
|
|
6
|
-
import { type DocumentId } from '@dxos/automerge/automerge-repo';
|
|
7
8
|
import { type RequestOptions } from '@dxos/codec-protobuf';
|
|
8
9
|
import { Stream } from '@dxos/codec-protobuf/stream';
|
|
9
10
|
import { invariant } from '@dxos/invariant';
|
|
@@ -72,7 +73,7 @@ export class DataServiceImpl implements DataService {
|
|
|
72
73
|
});
|
|
73
74
|
}
|
|
74
75
|
|
|
75
|
-
async updateSubscription(request: UpdateSubscriptionRequest) {
|
|
76
|
+
async updateSubscription(request: UpdateSubscriptionRequest): Promise<void> {
|
|
76
77
|
const synchronizer = this._subscriptions.get(request.subscriptionId);
|
|
77
78
|
invariant(synchronizer, 'Subscription not found');
|
|
78
79
|
|
|
@@ -122,7 +123,7 @@ export class DataServiceImpl implements DataService {
|
|
|
122
123
|
await this._automergeHost.reIndexHeads((request.documentIds ?? []) as DocumentId[]);
|
|
123
124
|
}
|
|
124
125
|
|
|
125
|
-
async updateIndexes() {
|
|
126
|
+
async updateIndexes(): Promise<void> {
|
|
126
127
|
await this._updateIndexes();
|
|
127
128
|
}
|
|
128
129
|
|
|
@@ -2,21 +2,16 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import type * as A from '@
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
type DocHandle,
|
|
10
|
-
type DocumentId,
|
|
11
|
-
} from '@dxos/automerge/automerge-repo';
|
|
12
|
-
import { type SpaceDoc, SpaceDocVersion } from '@dxos/echo-protocol';
|
|
5
|
+
import type * as A from '@automerge/automerge';
|
|
6
|
+
import { interpretAsDocumentId, type AutomergeUrl, type DocHandle, type DocumentId } from '@automerge/automerge-repo';
|
|
7
|
+
|
|
8
|
+
import { DatabaseDirectory, SpaceDocVersion } from '@dxos/echo-protocol';
|
|
13
9
|
import { invariant } from '@dxos/invariant';
|
|
14
10
|
|
|
15
11
|
import { measureDocMetrics, type DocMetrics } from './automerge-metrics';
|
|
16
|
-
import { getSpaceKeyFromDoc } from '../automerge';
|
|
17
12
|
|
|
18
13
|
export class DatabaseRoot {
|
|
19
|
-
static mapLinks(doc: DocHandle<
|
|
14
|
+
static mapLinks(doc: DocHandle<DatabaseDirectory>, mapping: Record<DocumentId, DocumentId>): void {
|
|
20
15
|
doc.change((d) => {
|
|
21
16
|
if (!d.links) {
|
|
22
17
|
return;
|
|
@@ -30,7 +25,7 @@ export class DatabaseRoot {
|
|
|
30
25
|
});
|
|
31
26
|
}
|
|
32
27
|
|
|
33
|
-
constructor(private readonly _rootHandle: DocHandle<
|
|
28
|
+
constructor(private readonly _rootHandle: DocHandle<DatabaseDirectory>) {}
|
|
34
29
|
|
|
35
30
|
get documentId(): DocumentId {
|
|
36
31
|
return this._rootHandle.documentId;
|
|
@@ -41,19 +36,19 @@ export class DatabaseRoot {
|
|
|
41
36
|
}
|
|
42
37
|
|
|
43
38
|
get isLoaded(): boolean {
|
|
44
|
-
return
|
|
39
|
+
return this._rootHandle.isReady();
|
|
45
40
|
}
|
|
46
41
|
|
|
47
|
-
get handle(): DocHandle<
|
|
42
|
+
get handle(): DocHandle<DatabaseDirectory> {
|
|
48
43
|
return this._rootHandle;
|
|
49
44
|
}
|
|
50
45
|
|
|
51
|
-
|
|
52
|
-
return this._rootHandle.
|
|
46
|
+
doc(): A.Doc<DatabaseDirectory> | null {
|
|
47
|
+
return this._rootHandle.isReady() ? this._rootHandle.doc() : null;
|
|
53
48
|
}
|
|
54
49
|
|
|
55
50
|
getVersion(): SpaceDocVersion | null {
|
|
56
|
-
const doc = this.
|
|
51
|
+
const doc = this.doc();
|
|
57
52
|
if (!doc) {
|
|
58
53
|
return null;
|
|
59
54
|
}
|
|
@@ -62,16 +57,16 @@ export class DatabaseRoot {
|
|
|
62
57
|
}
|
|
63
58
|
|
|
64
59
|
getSpaceKey(): string | null {
|
|
65
|
-
const doc = this.
|
|
60
|
+
const doc = this.doc();
|
|
66
61
|
if (!doc) {
|
|
67
62
|
return null;
|
|
68
63
|
}
|
|
69
64
|
|
|
70
|
-
return
|
|
65
|
+
return DatabaseDirectory.getSpaceKey(doc);
|
|
71
66
|
}
|
|
72
67
|
|
|
73
68
|
getInlineObjectCount(): number | null {
|
|
74
|
-
const doc = this.
|
|
69
|
+
const doc = this.doc();
|
|
75
70
|
if (!doc) {
|
|
76
71
|
return null;
|
|
77
72
|
}
|
|
@@ -80,7 +75,7 @@ export class DatabaseRoot {
|
|
|
80
75
|
}
|
|
81
76
|
|
|
82
77
|
getLinkedObjectCount(): number | null {
|
|
83
|
-
const doc = this.
|
|
78
|
+
const doc = this.doc();
|
|
84
79
|
if (!doc) {
|
|
85
80
|
return null;
|
|
86
81
|
}
|
|
@@ -89,7 +84,7 @@ export class DatabaseRoot {
|
|
|
89
84
|
}
|
|
90
85
|
|
|
91
86
|
getAllLinkedDocuments(): AutomergeUrl[] {
|
|
92
|
-
const doc = this.
|
|
87
|
+
const doc = this.doc();
|
|
93
88
|
invariant(doc);
|
|
94
89
|
|
|
95
90
|
// .toString() to handle RawString.
|
|
@@ -97,7 +92,7 @@ export class DatabaseRoot {
|
|
|
97
92
|
}
|
|
98
93
|
|
|
99
94
|
measureMetrics(): DocMetrics | null {
|
|
100
|
-
const doc = this.
|
|
95
|
+
const doc = this.doc();
|
|
101
96
|
if (!doc) {
|
|
102
97
|
return null;
|
|
103
98
|
}
|
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import * as A from '@
|
|
6
|
-
import { type DocumentId } from '@
|
|
5
|
+
import * as A from '@automerge/automerge';
|
|
6
|
+
import { type DocumentId } from '@automerge/automerge-repo';
|
|
7
|
+
|
|
7
8
|
import { Context } from '@dxos/context';
|
|
8
|
-
import {
|
|
9
|
-
import { type
|
|
9
|
+
import { DatabaseDirectory, SpaceDocVersion } from '@dxos/echo-protocol';
|
|
10
|
+
import { type IdToHeads, type ObjectSnapshot } from '@dxos/indexing';
|
|
10
11
|
import { invariant } from '@dxos/invariant';
|
|
11
12
|
import { log } from '@dxos/log';
|
|
12
13
|
import { ObjectPointerVersion, objectPointerCodec } from '@dxos/protocols';
|
|
13
14
|
|
|
14
|
-
import { type AutomergeHost
|
|
15
|
+
import { type AutomergeHost } from '../automerge';
|
|
15
16
|
|
|
16
17
|
const LOG_VIEW_OPERATION_THRESHOLD = 300;
|
|
17
18
|
|
|
@@ -27,9 +28,9 @@ export const createSelectedDocumentsIterator = (automergeHost: AutomergeHost) =>
|
|
|
27
28
|
for (const [id, heads] of objects.entries()) {
|
|
28
29
|
try {
|
|
29
30
|
const { documentId, objectId } = objectPointerCodec.decode(id);
|
|
30
|
-
const handle = await automergeHost.loadDoc<
|
|
31
|
+
const handle = await automergeHost.loadDoc<DatabaseDirectory>(Context.default(), documentId as DocumentId);
|
|
31
32
|
|
|
32
|
-
let doc = handle.
|
|
33
|
+
let doc = handle.doc();
|
|
33
34
|
invariant(doc);
|
|
34
35
|
|
|
35
36
|
const currentHeads = A.getHeads(doc);
|
|
@@ -61,7 +62,7 @@ export const createSelectedDocumentsIterator = (automergeHost: AutomergeHost) =>
|
|
|
61
62
|
// Upgrade V0 object pointers to V1.
|
|
62
63
|
let newId = id;
|
|
63
64
|
if (objectPointerCodec.getVersion(id) === ObjectPointerVersion.V0) {
|
|
64
|
-
const spaceKey =
|
|
65
|
+
const spaceKey = DatabaseDirectory.getSpaceKey(doc) ?? undefined;
|
|
65
66
|
newId = objectPointerCodec.encode({ documentId, objectId, spaceKey });
|
|
66
67
|
}
|
|
67
68
|
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { next as A } from '@automerge/automerge';
|
|
6
|
+
import { generateAutomergeUrl, parseAutomergeUrl, Repo } from '@automerge/automerge-repo';
|
|
5
7
|
import { describe, expect, test } from 'vitest';
|
|
6
8
|
|
|
7
9
|
import { sleep } from '@dxos/async';
|
|
8
|
-
import { next as A } from '@dxos/automerge/automerge';
|
|
9
|
-
import { generateAutomergeUrl, parseAutomergeUrl, Repo } from '@dxos/automerge/automerge-repo';
|
|
10
10
|
import { openAndClose } from '@dxos/test-utils';
|
|
11
11
|
|
|
12
12
|
import { DocumentsSynchronizer } from './documents-synchronizer';
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { next as A, type Heads } from '@automerge/automerge';
|
|
6
|
+
import { type Repo, type DocHandle, type DocumentId } from '@automerge/automerge-repo';
|
|
7
|
+
|
|
5
8
|
import { UpdateScheduler } from '@dxos/async';
|
|
6
|
-
import { next as A, type Heads } from '@dxos/automerge/automerge';
|
|
7
|
-
import { type Repo, type DocHandle, type DocumentId } from '@dxos/automerge/automerge-repo';
|
|
8
9
|
import { Resource } from '@dxos/context';
|
|
9
|
-
import { type
|
|
10
|
+
import { type DatabaseDirectory } from '@dxos/echo-protocol';
|
|
10
11
|
import { invariant } from '@dxos/invariant';
|
|
11
12
|
import { log } from '@dxos/log';
|
|
12
13
|
import { type BatchedDocumentUpdates, type DocumentUpdate } from '@dxos/protocols/proto/dxos/echo/service';
|
|
@@ -19,7 +20,7 @@ export type DocumentsSynchronizerParams = {
|
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
interface DocSyncState {
|
|
22
|
-
handle: DocHandle<
|
|
23
|
+
handle: DocHandle<DatabaseDirectory>;
|
|
23
24
|
lastSentHead?: Heads;
|
|
24
25
|
clearSubscriptions?: () => void;
|
|
25
26
|
}
|
|
@@ -44,17 +45,17 @@ export class DocumentsSynchronizer extends Resource {
|
|
|
44
45
|
super();
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
addDocuments(documentIds: DocumentId[], retryCounter = 0) {
|
|
48
|
+
addDocuments(documentIds: DocumentId[], retryCounter = 0): void {
|
|
48
49
|
if (retryCounter > 3) {
|
|
49
50
|
log.warn('Failed to load document, retry limit reached', { documentIds });
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
for (const documentId of documentIds) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
.
|
|
57
|
-
|
|
55
|
+
this._params.repo
|
|
56
|
+
.find<DatabaseDirectory>(documentId as DocumentId)
|
|
57
|
+
.then(async (doc) => {
|
|
58
|
+
await doc.whenReady();
|
|
58
59
|
this._startSync(doc);
|
|
59
60
|
this._pendingUpdates.add(doc.documentId);
|
|
60
61
|
this._sendUpdatesJob!.trigger();
|
|
@@ -66,7 +67,7 @@ export class DocumentsSynchronizer extends Resource {
|
|
|
66
67
|
}
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
removeDocuments(documentIds: DocumentId[]) {
|
|
70
|
+
removeDocuments(documentIds: DocumentId[]): void {
|
|
70
71
|
for (const documentId of documentIds) {
|
|
71
72
|
this._syncStates.get(documentId)?.clearSubscriptions?.();
|
|
72
73
|
this._syncStates.delete(documentId);
|
|
@@ -85,10 +86,10 @@ export class DocumentsSynchronizer extends Resource {
|
|
|
85
86
|
this._syncStates.clear();
|
|
86
87
|
}
|
|
87
88
|
|
|
88
|
-
update(updates: DocumentUpdate[]) {
|
|
89
|
+
update(updates: DocumentUpdate[]): void {
|
|
89
90
|
for (const { documentId, mutation, isNew } of updates) {
|
|
90
91
|
if (isNew) {
|
|
91
|
-
const doc = this._params.repo.
|
|
92
|
+
const { handle: doc } = this._params.repo.findWithProgress<DatabaseDirectory>(documentId as DocumentId);
|
|
92
93
|
doc.update((doc) => A.loadIncremental(doc, mutation));
|
|
93
94
|
this._startSync(doc);
|
|
94
95
|
} else {
|
|
@@ -97,7 +98,7 @@ export class DocumentsSynchronizer extends Resource {
|
|
|
97
98
|
}
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
private _startSync(doc: DocHandle<
|
|
101
|
+
private _startSync(doc: DocHandle<DatabaseDirectory>): void {
|
|
101
102
|
if (this._syncStates.has(doc.documentId)) {
|
|
102
103
|
log.info('Document already being synced', { documentId: doc.documentId });
|
|
103
104
|
return;
|
|
@@ -108,7 +109,7 @@ export class DocumentsSynchronizer extends Resource {
|
|
|
108
109
|
this._syncStates.set(doc.documentId, syncState);
|
|
109
110
|
}
|
|
110
111
|
|
|
111
|
-
_subscribeForChanges(syncState: DocSyncState) {
|
|
112
|
+
_subscribeForChanges(syncState: DocSyncState): void {
|
|
112
113
|
const handler = () => {
|
|
113
114
|
this._pendingUpdates.add(syncState.handle.documentId);
|
|
114
115
|
this._sendUpdatesJob!.trigger();
|
|
@@ -117,7 +118,7 @@ export class DocumentsSynchronizer extends Resource {
|
|
|
117
118
|
syncState.clearSubscriptions = () => syncState.handle.off('heads-changed', handler);
|
|
118
119
|
}
|
|
119
120
|
|
|
120
|
-
private async _checkAndSendUpdates() {
|
|
121
|
+
private async _checkAndSendUpdates(): Promise<void> {
|
|
121
122
|
const updates: DocumentUpdate[] = [];
|
|
122
123
|
|
|
123
124
|
const docsWithPendingUpdates = Array.from(this._pendingUpdates);
|
|
@@ -141,10 +142,11 @@ export class DocumentsSynchronizer extends Resource {
|
|
|
141
142
|
private _getPendingChanges(documentId: DocumentId): Uint8Array | void {
|
|
142
143
|
const syncState = this._syncStates.get(documentId);
|
|
143
144
|
invariant(syncState, 'Sync state for document not found');
|
|
144
|
-
const
|
|
145
|
-
if (!doc) {
|
|
145
|
+
const handle = syncState.handle;
|
|
146
|
+
if (!handle || !handle.isReady() || !handle.doc()) {
|
|
146
147
|
return;
|
|
147
148
|
}
|
|
149
|
+
const doc = handle.doc();
|
|
148
150
|
const mutation = syncState.lastSentHead ? A.saveSince(doc, syncState.lastSentHead) : A.save(doc);
|
|
149
151
|
if (mutation.length === 0) {
|
|
150
152
|
return;
|
|
@@ -153,7 +155,7 @@ export class DocumentsSynchronizer extends Resource {
|
|
|
153
155
|
return mutation;
|
|
154
156
|
}
|
|
155
157
|
|
|
156
|
-
private _writeMutation(documentId: DocumentId, mutation: Uint8Array) {
|
|
158
|
+
private _writeMutation(documentId: DocumentId, mutation: Uint8Array): void {
|
|
157
159
|
const syncState = this._syncStates.get(documentId);
|
|
158
160
|
invariant(syncState, 'Sync state for document not found');
|
|
159
161
|
syncState.handle.update((doc) => {
|