@dxos/echo-pipeline 0.8.4-main.ae835ea → 0.8.4-main.bc2380dfbc
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/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/{browser/chunk-WJJXJTNS.mjs → neutral/chunk-46DCRDA7.mjs} +44 -13
- package/dist/lib/neutral/chunk-46DCRDA7.mjs.map +7 -0
- package/dist/lib/{browser/chunk-FR6GJ4S4.mjs → neutral/chunk-LR7UFVQX.mjs} +145 -618
- package/dist/lib/neutral/chunk-LR7UFVQX.mjs.map +7 -0
- package/dist/lib/{browser → neutral}/filter/index.mjs +1 -2
- package/dist/lib/neutral/index.mjs +7332 -0
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/lib/{browser → neutral}/testing/index.mjs +49 -292
- package/dist/lib/neutral/testing/index.mjs.map +7 -0
- package/dist/types/src/automerge/automerge-host-subduction.test.d.ts +2 -0
- package/dist/types/src/automerge/automerge-host-subduction.test.d.ts.map +1 -0
- package/dist/types/src/automerge/automerge-host.d.ts +105 -27
- package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
- package/dist/types/src/automerge/automerge-repo-subduction.test.d.ts +2 -0
- package/dist/types/src/automerge/automerge-repo-subduction.test.d.ts.map +1 -0
- package/dist/types/src/automerge/automerge-repo.test.d.ts +1 -1
- package/dist/types/src/automerge/automerge-repo.test.d.ts.map +1 -1
- package/dist/types/src/automerge/automerge-subduction.test.d.ts +2 -0
- package/dist/types/src/automerge/automerge-subduction.test.d.ts.map +1 -0
- package/dist/types/src/automerge/collection-synchronizer.d.ts +22 -2
- package/dist/types/src/automerge/collection-synchronizer.d.ts.map +1 -1
- package/dist/types/src/automerge/echo-data-monitor.d.ts.map +1 -1
- package/dist/types/src/automerge/echo-network-adapter.d.ts +17 -11
- package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
- package/dist/types/src/automerge/echo-replicator.d.ts +28 -16
- package/dist/types/src/automerge/echo-replicator.d.ts.map +1 -1
- package/dist/types/src/automerge/errors.d.ts +35 -0
- package/dist/types/src/automerge/errors.d.ts.map +1 -0
- package/dist/types/src/automerge/handle-state.d.ts +52 -0
- package/dist/types/src/automerge/handle-state.d.ts.map +1 -0
- package/dist/types/src/automerge/heads-store.d.ts +9 -2
- package/dist/types/src/automerge/heads-store.d.ts.map +1 -1
- package/dist/types/src/automerge/index.d.ts +2 -0
- package/dist/types/src/automerge/index.d.ts.map +1 -1
- package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +10 -4
- package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -1
- package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts +8 -8
- package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts.map +1 -1
- package/dist/types/src/automerge/mesh-echo-replicator.d.ts +6 -5
- package/dist/types/src/automerge/mesh-echo-replicator.d.ts.map +1 -1
- package/dist/types/src/automerge/network-protocol.d.ts.map +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-data-source.d.ts +35 -0
- package/dist/types/src/db-host/automerge-data-source.d.ts.map +1 -0
- package/dist/types/src/db-host/automerge-data-source.test.d.ts +2 -0
- package/dist/types/src/db-host/automerge-data-source.test.d.ts.map +1 -0
- package/dist/types/src/db-host/automerge-metrics.d.ts.map +1 -1
- package/dist/types/src/db-host/data-service.d.ts +12 -6
- package/dist/types/src/db-host/data-service.d.ts.map +1 -1
- package/dist/types/src/db-host/database-root.d.ts +9 -3
- package/dist/types/src/db-host/database-root.d.ts.map +1 -1
- package/dist/types/src/db-host/documents-synchronizer.d.ts +30 -8
- package/dist/types/src/db-host/documents-synchronizer.d.ts.map +1 -1
- package/dist/types/src/db-host/echo-host.d.ts +74 -28
- package/dist/types/src/db-host/echo-host.d.ts.map +1 -1
- package/dist/types/src/db-host/index.d.ts +2 -0
- package/dist/types/src/db-host/index.d.ts.map +1 -1
- package/dist/types/src/db-host/invalidation-hint.d.ts +19 -0
- package/dist/types/src/db-host/invalidation-hint.d.ts.map +1 -0
- package/dist/types/src/db-host/local-queue-service.d.ts +19 -0
- package/dist/types/src/db-host/local-queue-service.d.ts.map +1 -0
- package/dist/types/src/db-host/query-invalidation.test.d.ts +2 -0
- package/dist/types/src/db-host/query-invalidation.test.d.ts.map +1 -0
- package/dist/types/src/db-host/query-service.d.ts +18 -10
- package/dist/types/src/db-host/query-service.d.ts.map +1 -1
- package/dist/types/src/db-host/queue-data-source.d.ts +38 -0
- package/dist/types/src/db-host/queue-data-source.d.ts.map +1 -0
- package/dist/types/src/db-host/queue-service.test.d.ts +2 -0
- package/dist/types/src/db-host/queue-service.test.d.ts.map +1 -0
- package/dist/types/src/db-host/space-state-manager.d.ts +3 -2
- package/dist/types/src/db-host/space-state-manager.d.ts.map +1 -1
- package/dist/types/src/db-host/stub.d.ts +11 -0
- package/dist/types/src/db-host/stub.d.ts.map +1 -0
- package/dist/types/src/edge/echo-edge-replicator.d.ts +7 -6
- package/dist/types/src/edge/echo-edge-replicator.d.ts.map +1 -1
- package/dist/types/src/edge/echo-edge-subduction-replicator.d.ts +39 -0
- package/dist/types/src/edge/echo-edge-subduction-replicator.d.ts.map +1 -0
- package/dist/types/src/edge/echo-edge-subduction-replicator.test.d.ts +2 -0
- package/dist/types/src/edge/echo-edge-subduction-replicator.test.d.ts.map +1 -0
- package/dist/types/src/edge/index.d.ts +1 -0
- package/dist/types/src/edge/index.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 +1 -1
- package/dist/types/src/filter/filter-match.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 +2 -2
- 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 +16 -20
- package/dist/types/src/query/errors.d.ts.map +1 -1
- package/dist/types/src/query/plan.d.ts +59 -8
- package/dist/types/src/query/plan.d.ts.map +1 -1
- package/dist/types/src/query/query-executor.d.ts +55 -12
- package/dist/types/src/query/query-executor.d.ts.map +1 -1
- package/dist/types/src/query/query-planner.d.ts +10 -1
- package/dist/types/src/query/query-planner.d.ts.map +1 -1
- package/dist/types/src/space/admission-discovery-extension.d.ts.map +1 -1
- package/dist/types/src/space/auth.d.ts +3 -3
- package/dist/types/src/space/auth.d.ts.map +1 -1
- package/dist/types/src/space/control-pipeline.d.ts +4 -3
- package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
- package/dist/types/src/space/space-manager.d.ts +7 -7
- package/dist/types/src/space/space-manager.d.ts.map +1 -1
- package/dist/types/src/space/space-protocol.d.ts +9 -8
- package/dist/types/src/space/space-protocol.d.ts.map +1 -1
- package/dist/types/src/space/space.d.ts +5 -5
- 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 +0 -2
- 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-feed-builder.d.ts.map +1 -1
- package/dist/types/src/testing/test-network-adapter.d.ts +1 -1
- package/dist/types/src/testing/test-network-adapter.d.ts.map +1 -1
- package/dist/types/src/testing/test-replicator.d.ts +13 -13
- package/dist/types/src/testing/test-replicator.d.ts.map +1 -1
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +56 -54
- package/src/automerge/automerge-host-subduction.test.ts +263 -0
- package/src/automerge/automerge-host.test.ts +145 -32
- package/src/automerge/automerge-host.ts +442 -163
- package/src/automerge/automerge-repo-subduction.test.ts +1054 -0
- package/src/automerge/automerge-repo.test.ts +284 -77
- package/src/automerge/automerge-subduction.test.ts +330 -0
- package/src/automerge/collection-synchronizer.test.ts +96 -16
- package/src/automerge/collection-synchronizer.ts +125 -26
- package/src/automerge/echo-network-adapter.test.ts +2 -1
- package/src/automerge/echo-network-adapter.ts +44 -32
- package/src/automerge/echo-replicator.ts +30 -16
- package/src/automerge/errors.ts +10 -0
- package/src/automerge/handle-state.ts +62 -0
- package/src/automerge/heads-store.ts +42 -3
- package/src/automerge/index.ts +2 -0
- package/src/automerge/leveldb-storage-adapter.ts +70 -4
- package/src/automerge/mesh-echo-replicator-connection.ts +8 -8
- package/src/automerge/mesh-echo-replicator.ts +14 -11
- package/src/db-host/automerge-data-source.test.ts +299 -0
- package/src/db-host/automerge-data-source.ts +187 -0
- package/src/db-host/data-service.ts +27 -10
- package/src/db-host/database-root.ts +19 -7
- package/src/db-host/documents-synchronizer.test.ts +145 -14
- package/src/db-host/documents-synchronizer.ts +158 -59
- package/src/db-host/echo-host.ts +376 -90
- package/src/db-host/index.ts +2 -0
- package/src/db-host/invalidation-hint.ts +50 -0
- package/src/db-host/local-queue-service.ts +127 -0
- package/src/db-host/query-invalidation.test.ts +270 -0
- package/src/db-host/query-service.ts +108 -111
- package/src/db-host/queue-data-source.ts +160 -0
- package/src/db-host/queue-service.test.ts +145 -0
- package/src/db-host/space-state-manager.ts +11 -9
- package/src/db-host/stub.ts +33 -0
- package/src/edge/echo-edge-replicator.test.ts +9 -9
- package/src/edge/echo-edge-replicator.ts +50 -42
- package/src/edge/echo-edge-subduction-replicator.test.ts +158 -0
- package/src/edge/echo-edge-subduction-replicator.ts +377 -0
- package/src/edge/index.ts +1 -0
- package/src/filter/filter-match.test.ts +41 -25
- package/src/filter/filter-match.ts +75 -20
- package/src/metadata/metadata-store.ts +8 -5
- package/src/pipeline/pipeline-stress.test.ts +1 -3
- package/src/pipeline/pipeline.test.ts +0 -1
- package/src/pipeline/pipeline.ts +2 -3
- package/src/query/errors.ts +2 -2
- package/src/query/plan.ts +73 -9
- package/src/query/query-executor.ts +1064 -172
- package/src/query/query-planner.test.ts +854 -86
- package/src/query/query-planner.ts +444 -38
- package/src/space/admission-discovery-extension.ts +1 -1
- package/src/space/auth.ts +6 -6
- package/src/space/control-pipeline.test.ts +2 -2
- package/src/space/control-pipeline.ts +7 -7
- package/src/space/space-manager.ts +12 -17
- package/src/space/space-protocol.browser.test.ts +13 -12
- package/src/space/space-protocol.test.ts +13 -13
- package/src/space/space-protocol.ts +16 -15
- package/src/space/space.test.ts +2 -2
- package/src/space/space.ts +9 -10
- package/src/testing/index.ts +0 -2
- package/src/testing/test-agent-builder.ts +0 -1
- package/src/testing/test-network-adapter.ts +24 -3
- package/src/testing/test-replicator.ts +15 -20
- package/src/util.ts +7 -3
- package/dist/lib/browser/chunk-CGS2ULMK.mjs +0 -11
- package/dist/lib/browser/chunk-CGS2ULMK.mjs.map +0 -7
- package/dist/lib/browser/chunk-FR6GJ4S4.mjs.map +0 -7
- package/dist/lib/browser/chunk-WJJXJTNS.mjs.map +0 -7
- package/dist/lib/browser/index.mjs +0 -5492
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/testing/index.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-JQCCVDLT.mjs +0 -2144
- package/dist/lib/node-esm/chunk-JQCCVDLT.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-LEQ77KAT.mjs +0 -240
- package/dist/lib/node-esm/chunk-LEQ77KAT.mjs.map +0 -7
- package/dist/lib/node-esm/filter/index.mjs +0 -13
- package/dist/lib/node-esm/filter/index.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -5492
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/testing/index.mjs +0 -764
- package/dist/lib/node-esm/testing/index.mjs.map +0 -7
- package/dist/types/src/db-host/documents-iterator.d.ts +0 -7
- package/dist/types/src/db-host/documents-iterator.d.ts.map +0 -1
- package/dist/types/src/testing/test-data.d.ts +0 -18
- package/dist/types/src/testing/test-data.d.ts.map +0 -1
- package/dist/types/src/testing/test-schema.d.ts +0 -37
- package/dist/types/src/testing/test-schema.d.ts.map +0 -1
- package/src/db-host/documents-iterator.ts +0 -74
- package/src/testing/test-data.ts +0 -127
- package/src/testing/test-schema.ts +0 -53
- /package/dist/lib/{browser → neutral}/filter/index.mjs.map +0 -0
package/src/space/auth.ts
CHANGED
|
@@ -15,7 +15,7 @@ export type AuthProvider = (nonce: Uint8Array) => Promise<Uint8Array | undefined
|
|
|
15
15
|
|
|
16
16
|
export type AuthVerifier = (nonce: Uint8Array, credential: Uint8Array) => Promise<boolean>;
|
|
17
17
|
|
|
18
|
-
export type
|
|
18
|
+
export type AuthExtensionProps = {
|
|
19
19
|
provider: AuthProvider;
|
|
20
20
|
verifier: AuthVerifier;
|
|
21
21
|
onAuthSuccess: () => void;
|
|
@@ -29,7 +29,7 @@ export class AuthExtension extends RpcExtension<Services, Services> {
|
|
|
29
29
|
},
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
constructor(private readonly
|
|
32
|
+
constructor(private readonly _authProps: AuthExtensionProps) {
|
|
33
33
|
super({
|
|
34
34
|
requested: {
|
|
35
35
|
AuthService: schema.getService('dxos.mesh.teleport.auth.AuthService'),
|
|
@@ -46,7 +46,7 @@ export class AuthExtension extends RpcExtension<Services, Services> {
|
|
|
46
46
|
AuthService: {
|
|
47
47
|
authenticate: async ({ challenge }) => {
|
|
48
48
|
try {
|
|
49
|
-
const credential = await this.
|
|
49
|
+
const credential = await this._authProps.provider(challenge);
|
|
50
50
|
if (!credential) {
|
|
51
51
|
throw new Error('auth rejected');
|
|
52
52
|
}
|
|
@@ -67,13 +67,13 @@ export class AuthExtension extends RpcExtension<Services, Services> {
|
|
|
67
67
|
const challenge = randomBytes(32);
|
|
68
68
|
const { credential } = await this.rpc.AuthService.authenticate({ challenge });
|
|
69
69
|
invariant(credential?.length > 0, 'invalid credential');
|
|
70
|
-
const success = await this.
|
|
70
|
+
const success = await this._authProps.verifier(challenge, credential);
|
|
71
71
|
invariant(success, 'credential not verified');
|
|
72
|
-
runInContext(this._ctx, () => this.
|
|
72
|
+
runInContext(this._ctx, () => this._authProps.onAuthSuccess());
|
|
73
73
|
} catch (err) {
|
|
74
74
|
log('auth failed', err);
|
|
75
75
|
this.close();
|
|
76
|
-
this.
|
|
76
|
+
this._authProps.onAuthFailure();
|
|
77
77
|
}
|
|
78
78
|
});
|
|
79
79
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { describe, expect, onTestFinished, test } from 'vitest';
|
|
6
6
|
|
|
7
|
+
import { Context } from '@dxos/context';
|
|
7
8
|
import { CredentialGenerator, createCredential } from '@dxos/credentials';
|
|
8
9
|
import { FeedFactory, FeedStore } from '@dxos/feed-store';
|
|
9
10
|
import { Keyring } from '@dxos/keyring';
|
|
@@ -16,7 +17,6 @@ import { Timeframe } from '@dxos/timeframe';
|
|
|
16
17
|
|
|
17
18
|
import { valueEncoding } from '../common';
|
|
18
19
|
import { MetadataStore } from '../metadata';
|
|
19
|
-
|
|
20
20
|
import { ControlPipeline } from './control-pipeline';
|
|
21
21
|
|
|
22
22
|
describe('space/control-pipeline', () => {
|
|
@@ -60,7 +60,7 @@ describe('space/control-pipeline', () => {
|
|
|
60
60
|
expect(admittedFeeds).toEqual([]);
|
|
61
61
|
|
|
62
62
|
await controlPipeline.setWriteFeed(genesisFeed);
|
|
63
|
-
await controlPipeline.start();
|
|
63
|
+
await controlPipeline.start(Context.default());
|
|
64
64
|
|
|
65
65
|
onTestFinished(() => controlPipeline.stop());
|
|
66
66
|
|
|
@@ -25,7 +25,7 @@ import { type AsyncCallback, Callback, tracer } from '@dxos/util';
|
|
|
25
25
|
import { type MetadataStore } from '../metadata';
|
|
26
26
|
import { Pipeline, type PipelineAccessor } from '../pipeline';
|
|
27
27
|
|
|
28
|
-
export type
|
|
28
|
+
export type ControlPipelineProps = {
|
|
29
29
|
spaceKey: PublicKey;
|
|
30
30
|
genesisFeed: FeedWrapper<FeedMessage>;
|
|
31
31
|
feedProvider: (feedKey: PublicKey) => Promise<FeedWrapper<FeedMessage>>;
|
|
@@ -48,6 +48,7 @@ export class ControlPipeline {
|
|
|
48
48
|
private readonly _pipeline: Pipeline;
|
|
49
49
|
private readonly _spaceStateMachine: SpaceStateMachine;
|
|
50
50
|
|
|
51
|
+
@trace.info({ spanAttribute: true })
|
|
51
52
|
private readonly _spaceKey: PublicKey;
|
|
52
53
|
private readonly _metadata: MetadataStore;
|
|
53
54
|
private _targetTimeframe?: Timeframe;
|
|
@@ -70,7 +71,7 @@ export class ControlPipeline {
|
|
|
70
71
|
await this._saveSnapshot();
|
|
71
72
|
});
|
|
72
73
|
|
|
73
|
-
constructor({ spaceKey, genesisFeed, feedProvider, metadataStore }:
|
|
74
|
+
constructor({ spaceKey, genesisFeed, feedProvider, metadataStore }: ControlPipelineProps) {
|
|
74
75
|
this._spaceKey = spaceKey;
|
|
75
76
|
this._metadata = metadataStore;
|
|
76
77
|
this._pipeline = new Pipeline();
|
|
@@ -120,8 +121,8 @@ export class ControlPipeline {
|
|
|
120
121
|
this._pipeline.setWriteFeed(feed);
|
|
121
122
|
}
|
|
122
123
|
|
|
123
|
-
@trace.span({ showInBrowserTimeline: true })
|
|
124
|
-
async start(): Promise<void> {
|
|
124
|
+
@trace.span({ showInBrowserTimeline: true, op: 'lifecycle' })
|
|
125
|
+
async start(ctx: Context): Promise<void> {
|
|
125
126
|
const snapshot = this._metadata.getSpaceControlPipelineSnapshot(this._spaceKey);
|
|
126
127
|
log('load snapshot', { key: this._spaceKey, present: !!snapshot, tf: snapshot?.timeframe });
|
|
127
128
|
if (USE_SNAPSHOTS && snapshot) {
|
|
@@ -130,7 +131,7 @@ export class ControlPipeline {
|
|
|
130
131
|
|
|
131
132
|
log('starting...');
|
|
132
133
|
setTimeout(async () => {
|
|
133
|
-
void this._consumePipeline(
|
|
134
|
+
void this._consumePipeline(ctx);
|
|
134
135
|
});
|
|
135
136
|
|
|
136
137
|
await this._pipeline.start();
|
|
@@ -167,7 +168,6 @@ export class ControlPipeline {
|
|
|
167
168
|
await this._metadata.setSpaceControlPipelineSnapshot(this._spaceKey, snapshot);
|
|
168
169
|
}
|
|
169
170
|
|
|
170
|
-
@trace.span()
|
|
171
171
|
private async _consumePipeline(ctx: Context): Promise<void> {
|
|
172
172
|
for await (const msg of this._pipeline.consume()) {
|
|
173
173
|
const span = this._usage.beginRecording();
|
|
@@ -183,7 +183,7 @@ export class ControlPipeline {
|
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
-
@trace.span()
|
|
186
|
+
@trace.span({ showInBrowserTimeline: true, showInRemoteTracing: false })
|
|
187
187
|
private async _processMessage(ctx: Context, msg: FeedMessageBlock): Promise<void> {
|
|
188
188
|
log('processing', { key: msg.feedKey, seq: msg.seq });
|
|
189
189
|
if (msg.data.payload.credential) {
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
import { type AutomergeUrl, parseAutomergeUrl } from '@automerge/automerge-repo';
|
|
6
6
|
|
|
7
7
|
import { Trigger, synchronized, trackLeaks } from '@dxos/async';
|
|
8
|
+
import { Context } from '@dxos/context';
|
|
8
9
|
import { type DelegateInvitationCredential, type MemberInfo, getCredentialAssertion } from '@dxos/credentials';
|
|
9
10
|
import { failUndefined } from '@dxos/debug';
|
|
10
11
|
import { type FeedStore } from '@dxos/feed-store';
|
|
11
12
|
import { PublicKey } from '@dxos/keys';
|
|
12
13
|
import { log } from '@dxos/log';
|
|
13
14
|
import { type SwarmNetworkManager } from '@dxos/network-manager';
|
|
14
|
-
import { trace } from '@dxos/protocols';
|
|
15
15
|
import type { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
16
16
|
import { type SpaceMetadata } from '@dxos/protocols/proto/dxos/echo/metadata';
|
|
17
17
|
import type { Credential } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
@@ -21,12 +21,11 @@ import { ComplexMap } from '@dxos/util';
|
|
|
21
21
|
|
|
22
22
|
import { createIdFromSpaceKey } from '../common/space-id';
|
|
23
23
|
import { type MetadataStore } from '../metadata';
|
|
24
|
-
|
|
25
24
|
import { CredentialRetrieverExtension } from './admission-discovery-extension';
|
|
26
25
|
import { Space } from './space';
|
|
27
26
|
import { SpaceProtocol, type SwarmIdentity } from './space-protocol';
|
|
28
27
|
|
|
29
|
-
export type
|
|
28
|
+
export type SpaceManagerProps = {
|
|
30
29
|
feedStore: FeedStore<FeedMessage>;
|
|
31
30
|
networkManager: SwarmNetworkManager;
|
|
32
31
|
metadataStore: MetadataStore;
|
|
@@ -36,7 +35,7 @@ export type SpaceManagerParams = {
|
|
|
36
35
|
disableP2pReplication?: boolean;
|
|
37
36
|
};
|
|
38
37
|
|
|
39
|
-
export type
|
|
38
|
+
export type ConstructSpaceProps = {
|
|
40
39
|
metadata: SpaceMetadata;
|
|
41
40
|
swarmIdentity: SwarmIdentity;
|
|
42
41
|
memberKey: PublicKey;
|
|
@@ -49,7 +48,7 @@ export type ConstructSpaceParams = {
|
|
|
49
48
|
onMemberRolesChanged: (member: MemberInfo[]) => Promise<void>;
|
|
50
49
|
};
|
|
51
50
|
|
|
52
|
-
export type
|
|
51
|
+
export type RequestSpaceAdmissionCredentialProps = {
|
|
53
52
|
spaceKey: PublicKey;
|
|
54
53
|
identityKey: PublicKey;
|
|
55
54
|
swarmIdentity: SwarmIdentity;
|
|
@@ -66,10 +65,9 @@ export class SpaceManager {
|
|
|
66
65
|
private readonly _networkManager: SwarmNetworkManager;
|
|
67
66
|
private readonly _metadataStore: MetadataStore;
|
|
68
67
|
private readonly _blobStore: BlobStore;
|
|
69
|
-
private readonly _instanceId = PublicKey.random().toHex();
|
|
70
68
|
private readonly _disableP2pReplication: boolean;
|
|
71
69
|
|
|
72
|
-
constructor({ feedStore, networkManager, metadataStore, blobStore, disableP2pReplication }:
|
|
70
|
+
constructor({ feedStore, networkManager, metadataStore, blobStore, disableP2pReplication }: SpaceManagerProps) {
|
|
73
71
|
// TODO(burdon): Assert.
|
|
74
72
|
this._feedStore = feedStore;
|
|
75
73
|
this._networkManager = networkManager;
|
|
@@ -99,8 +97,7 @@ export class SpaceManager {
|
|
|
99
97
|
onDelegatedInvitationStatusChange,
|
|
100
98
|
onMemberRolesChanged,
|
|
101
99
|
memberKey,
|
|
102
|
-
}:
|
|
103
|
-
log.trace('dxos.echo.space-manager.construct-space', trace.begin({ id: this._instanceId }));
|
|
100
|
+
}: ConstructSpaceProps): Promise<Space> {
|
|
104
101
|
log('constructing space...', { spaceKey: metadata.genesisFeedKey });
|
|
105
102
|
|
|
106
103
|
// The genesis feed will be the same as the control feed if the space was created by the local agent.
|
|
@@ -131,13 +128,13 @@ export class SpaceManager {
|
|
|
131
128
|
});
|
|
132
129
|
this._spaces.set(space.key, space);
|
|
133
130
|
|
|
134
|
-
log.trace('dxos.echo.space-manager.construct-space', trace.end({ id: this._instanceId }));
|
|
135
131
|
return space;
|
|
136
132
|
}
|
|
137
133
|
|
|
138
|
-
public async requestSpaceAdmissionCredential(
|
|
139
|
-
|
|
140
|
-
|
|
134
|
+
public async requestSpaceAdmissionCredential(
|
|
135
|
+
ctx: Context,
|
|
136
|
+
params: RequestSpaceAdmissionCredentialProps,
|
|
137
|
+
): Promise<Credential> {
|
|
141
138
|
log('requesting space admission credential...', { spaceKey: params.spaceKey });
|
|
142
139
|
|
|
143
140
|
const onCredentialResolved = new Trigger<Credential>();
|
|
@@ -160,15 +157,13 @@ export class SpaceManager {
|
|
|
160
157
|
});
|
|
161
158
|
|
|
162
159
|
try {
|
|
163
|
-
await protocol.start();
|
|
160
|
+
await protocol.start(ctx);
|
|
164
161
|
const credential = await onCredentialResolved.wait({ timeout: params.timeout });
|
|
165
|
-
log.trace(traceKey, trace.end({ id: this._instanceId }));
|
|
166
162
|
return credential;
|
|
167
163
|
} catch (err: any) {
|
|
168
|
-
log.trace(traceKey, trace.error({ id: this._instanceId, error: err }));
|
|
169
164
|
throw err;
|
|
170
165
|
} finally {
|
|
171
|
-
await protocol.stop();
|
|
166
|
+
await protocol.stop(ctx);
|
|
172
167
|
}
|
|
173
168
|
}
|
|
174
169
|
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { describe, expect, onTestFinished, test } from 'vitest';
|
|
6
6
|
|
|
7
|
+
import { Context } from '@dxos/context';
|
|
7
8
|
import { Keyring } from '@dxos/keyring';
|
|
8
9
|
import { PublicKey } from '@dxos/keys';
|
|
9
10
|
import { createStorage } from '@dxos/random-access-storage';
|
|
@@ -35,11 +36,11 @@ describe('space/space-protocol', () => {
|
|
|
35
36
|
const presence2 = peer2.createPresence(gossip2);
|
|
36
37
|
const protocol2 = peer2.createSpaceProtocol(topic, gossip2);
|
|
37
38
|
|
|
38
|
-
await protocol1.start();
|
|
39
|
-
await protocol2.start();
|
|
39
|
+
await protocol1.start(Context.default());
|
|
40
|
+
await protocol2.start(Context.default());
|
|
40
41
|
|
|
41
|
-
onTestFinished(() => protocol1.stop());
|
|
42
|
-
onTestFinished(() => protocol2.stop());
|
|
42
|
+
onTestFinished(() => protocol1.stop(Context.default()));
|
|
43
|
+
onTestFinished(() => protocol2.stop(Context.default()));
|
|
43
44
|
|
|
44
45
|
await expect
|
|
45
46
|
.poll(() => presence1.getPeersOnline().some(({ identityKey }) => identityKey.equals(peer2.identityKey)))
|
|
@@ -62,11 +63,11 @@ describe('space/space-protocol', () => {
|
|
|
62
63
|
const peer2 = await builder.createPeer();
|
|
63
64
|
const protocol2 = peer2.createSpaceProtocol(topic);
|
|
64
65
|
|
|
65
|
-
await protocol1.start();
|
|
66
|
-
await protocol2.start();
|
|
66
|
+
await protocol1.start(Context.default());
|
|
67
|
+
await protocol2.start(Context.default());
|
|
67
68
|
|
|
68
|
-
onTestFinished(() => protocol1.stop());
|
|
69
|
-
onTestFinished(() => protocol2.stop());
|
|
69
|
+
onTestFinished(() => protocol1.stop(Context.default()));
|
|
70
|
+
onTestFinished(() => protocol2.stop(Context.default()));
|
|
70
71
|
|
|
71
72
|
const builder1 = new TestFeedBuilder();
|
|
72
73
|
const feedStore1 = builder1.createFeedStore();
|
|
@@ -109,11 +110,11 @@ describe('space/space-protocol', () => {
|
|
|
109
110
|
const peer2 = await builder.createPeer();
|
|
110
111
|
const protocol2 = peer2.createSpaceProtocol(topic);
|
|
111
112
|
|
|
112
|
-
await protocol1.start();
|
|
113
|
-
await protocol2.start();
|
|
113
|
+
await protocol1.start(Context.default());
|
|
114
|
+
await protocol2.start(Context.default());
|
|
114
115
|
|
|
115
|
-
onTestFinished(() => protocol1.stop());
|
|
116
|
-
onTestFinished(() => protocol2.stop());
|
|
116
|
+
onTestFinished(() => protocol1.stop(Context.default()));
|
|
117
|
+
onTestFinished(() => protocol2.stop(Context.default()));
|
|
117
118
|
|
|
118
119
|
const feedKey = await peer1.keyring.createKey();
|
|
119
120
|
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { describe, expect, onTestFinished, test } from 'vitest';
|
|
6
6
|
|
|
7
|
+
import { Context } from '@dxos/context';
|
|
7
8
|
import { PublicKey } from '@dxos/keys';
|
|
8
9
|
import { MemorySignalManager, MemorySignalManagerContext } from '@dxos/messaging';
|
|
9
10
|
import { MemoryTransportFactory, SwarmNetworkManager } from '@dxos/network-manager';
|
|
@@ -12,7 +13,6 @@ import { BlobStore } from '@dxos/teleport-extension-object-sync';
|
|
|
12
13
|
import { Timeframe } from '@dxos/timeframe';
|
|
13
14
|
|
|
14
15
|
import { TestAgentBuilder, TestFeedBuilder } from '../testing';
|
|
15
|
-
|
|
16
16
|
import { AuthStatus, MOCK_AUTH_PROVIDER, MOCK_AUTH_VERIFIER, SpaceProtocol } from './space-protocol';
|
|
17
17
|
|
|
18
18
|
describe('space/space-protocol', () => {
|
|
@@ -36,11 +36,11 @@ describe('space/space-protocol', () => {
|
|
|
36
36
|
await presence2.open();
|
|
37
37
|
const protocol2 = peer2.createSpaceProtocol(topic, gossip2);
|
|
38
38
|
|
|
39
|
-
await protocol1.start();
|
|
40
|
-
onTestFinished(() => protocol1.stop());
|
|
39
|
+
await protocol1.start(Context.default());
|
|
40
|
+
onTestFinished(() => protocol1.stop(Context.default()));
|
|
41
41
|
|
|
42
|
-
await protocol2.start();
|
|
43
|
-
onTestFinished(() => protocol2.stop());
|
|
42
|
+
await protocol2.start(Context.default());
|
|
43
|
+
onTestFinished(() => protocol2.stop(Context.default()));
|
|
44
44
|
|
|
45
45
|
await expect
|
|
46
46
|
.poll(() => presence1.getPeersOnline().some(({ identityKey }) => identityKey.equals(peer2.identityKey)), {
|
|
@@ -96,11 +96,11 @@ describe('space/space-protocol', () => {
|
|
|
96
96
|
}),
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
-
await protocol1.start();
|
|
100
|
-
onTestFinished(() => protocol1.stop());
|
|
99
|
+
await protocol1.start(Context.default());
|
|
100
|
+
onTestFinished(() => protocol1.stop(Context.default()));
|
|
101
101
|
|
|
102
|
-
await protocol2.start();
|
|
103
|
-
onTestFinished(() => protocol2.stop());
|
|
102
|
+
await protocol2.start(Context.default());
|
|
103
|
+
onTestFinished(() => protocol2.stop(Context.default()));
|
|
104
104
|
|
|
105
105
|
await expect.poll(() => protocol1.sessions.get(peerId2)?.authStatus).toEqual(AuthStatus.FAILURE);
|
|
106
106
|
});
|
|
@@ -119,11 +119,11 @@ describe('space/space-protocol', () => {
|
|
|
119
119
|
const peer2 = await builder.createPeer();
|
|
120
120
|
const protocol2 = peer2.createSpaceProtocol(topic);
|
|
121
121
|
|
|
122
|
-
await protocol1.start();
|
|
123
|
-
await protocol2.start();
|
|
122
|
+
await protocol1.start(Context.default());
|
|
123
|
+
await protocol2.start(Context.default());
|
|
124
124
|
|
|
125
|
-
onTestFinished(() => protocol1.stop());
|
|
126
|
-
onTestFinished(() => protocol2.stop());
|
|
125
|
+
onTestFinished(() => protocol1.stop(Context.default()));
|
|
126
|
+
onTestFinished(() => protocol2.stop(Context.default()));
|
|
127
127
|
|
|
128
128
|
//
|
|
129
129
|
// Create feeds.
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Event } from '@dxos/async';
|
|
6
|
+
import { Context } from '@dxos/context';
|
|
6
7
|
import { discoveryKey, subtleCrypto } from '@dxos/crypto';
|
|
7
8
|
import { type FeedWrapper } from '@dxos/feed-store';
|
|
8
9
|
import { PublicKey } from '@dxos/keys';
|
|
@@ -12,7 +13,7 @@ import {
|
|
|
12
13
|
type SwarmConnection,
|
|
13
14
|
type SwarmNetworkManager,
|
|
14
15
|
type WireProtocol,
|
|
15
|
-
type
|
|
16
|
+
type WireProtocolProps,
|
|
16
17
|
type WireProtocolProvider,
|
|
17
18
|
} from '@dxos/network-manager';
|
|
18
19
|
import type { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
@@ -139,7 +140,7 @@ export class SpaceProtocol {
|
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
// TODO(burdon): Rename open? Common open/close interfaces for all services?
|
|
142
|
-
async start(): Promise<void> {
|
|
143
|
+
async start(ctx: Context): Promise<void> {
|
|
143
144
|
if (this._connection) {
|
|
144
145
|
return;
|
|
145
146
|
}
|
|
@@ -151,7 +152,7 @@ export class SpaceProtocol {
|
|
|
151
152
|
|
|
152
153
|
log('starting...');
|
|
153
154
|
const topic = await this._topic;
|
|
154
|
-
this._connection = await this._networkManager.joinSwarm({
|
|
155
|
+
this._connection = await this._networkManager.joinSwarm(ctx, {
|
|
155
156
|
protocolProvider: this._createProtocolProvider(credentials),
|
|
156
157
|
topic,
|
|
157
158
|
topology: this._topology,
|
|
@@ -165,27 +166,27 @@ export class SpaceProtocol {
|
|
|
165
166
|
this._topology.forceUpdate();
|
|
166
167
|
}
|
|
167
168
|
|
|
168
|
-
async stop(): Promise<void> {
|
|
169
|
+
async stop(ctx: Context): Promise<void> {
|
|
169
170
|
await this.blobSync.close();
|
|
170
171
|
|
|
171
172
|
if (this._connection) {
|
|
172
173
|
log('stopping...');
|
|
173
|
-
await this._connection.close();
|
|
174
|
+
await this._connection.close(ctx);
|
|
174
175
|
log('stopped');
|
|
175
176
|
}
|
|
176
177
|
}
|
|
177
178
|
|
|
178
179
|
private _createProtocolProvider(credentials: Uint8Array | undefined): WireProtocolProvider {
|
|
179
|
-
return (
|
|
180
|
+
return (wireProps) => {
|
|
180
181
|
const session = new SpaceProtocolSession({
|
|
181
|
-
|
|
182
|
+
wireProps,
|
|
182
183
|
swarmIdentity: this._swarmIdentity,
|
|
183
184
|
onSessionAuth: this._onSessionAuth,
|
|
184
185
|
onAuthFailure: this._onAuthFailure,
|
|
185
186
|
blobSync: this.blobSync,
|
|
186
187
|
disableP2pReplication: this._disableP2pReplication,
|
|
187
188
|
});
|
|
188
|
-
this._sessions.set(
|
|
189
|
+
this._sessions.set(wireProps.remotePeerId, session);
|
|
189
190
|
|
|
190
191
|
for (const feed of this._feeds) {
|
|
191
192
|
session.replicator.addFeed(feed);
|
|
@@ -196,8 +197,8 @@ export class SpaceProtocol {
|
|
|
196
197
|
}
|
|
197
198
|
}
|
|
198
199
|
|
|
199
|
-
export type
|
|
200
|
-
|
|
200
|
+
export type SpaceProtocolSessionProps = {
|
|
201
|
+
wireProps: WireProtocolProps;
|
|
201
202
|
swarmIdentity: SwarmIdentity;
|
|
202
203
|
|
|
203
204
|
blobSync: BlobSync;
|
|
@@ -225,7 +226,7 @@ export enum AuthStatus {
|
|
|
225
226
|
*/
|
|
226
227
|
export class SpaceProtocolSession implements WireProtocol {
|
|
227
228
|
@logInfo
|
|
228
|
-
private readonly
|
|
229
|
+
private readonly _wireProps: WireProtocolProps;
|
|
229
230
|
|
|
230
231
|
private readonly _disableP2pReplication: boolean;
|
|
231
232
|
|
|
@@ -252,20 +253,20 @@ export class SpaceProtocolSession implements WireProtocol {
|
|
|
252
253
|
|
|
253
254
|
// TODO(dmaretskyi): Allow to pass in extra extensions.
|
|
254
255
|
constructor({
|
|
255
|
-
|
|
256
|
+
wireProps,
|
|
256
257
|
swarmIdentity,
|
|
257
258
|
onSessionAuth,
|
|
258
259
|
onAuthFailure,
|
|
259
260
|
blobSync,
|
|
260
261
|
disableP2pReplication,
|
|
261
|
-
}:
|
|
262
|
-
this.
|
|
262
|
+
}: SpaceProtocolSessionProps) {
|
|
263
|
+
this._wireProps = wireProps;
|
|
263
264
|
this._swarmIdentity = swarmIdentity;
|
|
264
265
|
this._onSessionAuth = onSessionAuth;
|
|
265
266
|
this._onAuthFailure = onAuthFailure;
|
|
266
267
|
this._blobSync = blobSync;
|
|
267
268
|
|
|
268
|
-
this._teleport = new Teleport(
|
|
269
|
+
this._teleport = new Teleport(wireProps);
|
|
269
270
|
|
|
270
271
|
this._disableP2pReplication = disableP2pReplication ?? false;
|
|
271
272
|
}
|
package/src/space/space.test.ts
CHANGED
|
@@ -49,7 +49,7 @@ describe('space/space', () => {
|
|
|
49
49
|
const space = await agent.createSpace(agent.identityKey);
|
|
50
50
|
|
|
51
51
|
await space.open(Context.default());
|
|
52
|
-
await space.startProtocol();
|
|
52
|
+
await space.startProtocol(Context.default());
|
|
53
53
|
expect(space.isOpen).toBeTruthy();
|
|
54
54
|
onTestFinished(async () => {
|
|
55
55
|
await space.close();
|
|
@@ -71,7 +71,7 @@ describe('space/space', () => {
|
|
|
71
71
|
const space = await agent.createSpace(agent.identityKey, space1.key, space1.genesisFeedKey, undefined, true);
|
|
72
72
|
|
|
73
73
|
await space.open(Context.default());
|
|
74
|
-
await space.startProtocol();
|
|
74
|
+
await space.startProtocol(Context.default());
|
|
75
75
|
expect(space.isOpen).toBeTruthy();
|
|
76
76
|
onTestFinished(async () => {
|
|
77
77
|
await space.close();
|
package/src/space/space.ts
CHANGED
|
@@ -17,14 +17,13 @@ import { type AsyncCallback, Callback } from '@dxos/util';
|
|
|
17
17
|
|
|
18
18
|
import { type MetadataStore } from '../metadata';
|
|
19
19
|
import { type PipelineAccessor } from '../pipeline';
|
|
20
|
-
|
|
21
20
|
import { ControlPipeline } from './control-pipeline';
|
|
22
21
|
import { type SpaceProtocol } from './space-protocol';
|
|
23
22
|
|
|
24
23
|
// TODO(burdon): Factor out?
|
|
25
24
|
type FeedProvider = (feedKey: PublicKey, opts?: FeedOptions) => Promise<FeedWrapper<FeedMessage>>;
|
|
26
25
|
|
|
27
|
-
export type
|
|
26
|
+
export type SpaceProps = {
|
|
28
27
|
id: SpaceId;
|
|
29
28
|
spaceKey: PublicKey;
|
|
30
29
|
protocol: SpaceProtocol;
|
|
@@ -40,7 +39,7 @@ export type SpaceParams = {
|
|
|
40
39
|
onMemberRolesChanged: (member: MemberInfo[]) => Promise<void>;
|
|
41
40
|
};
|
|
42
41
|
|
|
43
|
-
export type
|
|
42
|
+
export type CreatePipelineProps = {
|
|
44
43
|
start: Timeframe;
|
|
45
44
|
// designation: AdmittedFeed.Designation;
|
|
46
45
|
};
|
|
@@ -68,7 +67,7 @@ export class Space extends Resource {
|
|
|
68
67
|
private _controlFeed?: FeedWrapper<FeedMessage>;
|
|
69
68
|
private _dataFeed?: FeedWrapper<FeedMessage>;
|
|
70
69
|
|
|
71
|
-
constructor(params:
|
|
70
|
+
constructor(params: SpaceProps) {
|
|
72
71
|
super();
|
|
73
72
|
invariant(params.spaceKey && params.feedProvider);
|
|
74
73
|
this._id = params.id;
|
|
@@ -172,29 +171,29 @@ export class Space extends Resource {
|
|
|
172
171
|
return Array.from(this._controlPipeline.spaceState.feeds.values());
|
|
173
172
|
}
|
|
174
173
|
|
|
175
|
-
@trace.span()
|
|
174
|
+
@trace.span({ op: 'lifecycle' })
|
|
176
175
|
protected override async _open(ctx: Context): Promise<void> {
|
|
177
176
|
log('opening...');
|
|
178
177
|
|
|
179
178
|
// Order is important.
|
|
180
|
-
await this._controlPipeline.start();
|
|
179
|
+
await this._controlPipeline.start(ctx);
|
|
181
180
|
|
|
182
181
|
log('opened');
|
|
183
182
|
}
|
|
184
183
|
|
|
185
184
|
@synchronized
|
|
186
|
-
public async startProtocol(): Promise<void> {
|
|
185
|
+
public async startProtocol(ctx: Context): Promise<void> {
|
|
187
186
|
invariant(this.isOpen);
|
|
188
|
-
await this.protocol.start();
|
|
187
|
+
await this.protocol.start(ctx);
|
|
189
188
|
await this.protocol.addFeed(await this._feedProvider(this._genesisFeedKey));
|
|
190
189
|
}
|
|
191
190
|
|
|
192
191
|
@synchronized
|
|
193
|
-
protected override async _close(): Promise<void> {
|
|
192
|
+
protected override async _close(ctx: Context): Promise<void> {
|
|
194
193
|
log('closing...', { key: this._key });
|
|
195
194
|
|
|
196
195
|
// Closes in reverse order to open.
|
|
197
|
-
await this.protocol.stop();
|
|
196
|
+
await this.protocol.stop(ctx);
|
|
198
197
|
await this._controlPipeline.stop();
|
|
199
198
|
|
|
200
199
|
log('closed');
|
package/src/testing/index.ts
CHANGED
|
@@ -19,7 +19,6 @@ import { ComplexMap } from '@dxos/util';
|
|
|
19
19
|
|
|
20
20
|
import { MetadataStore } from '../metadata';
|
|
21
21
|
import { MOCK_AUTH_PROVIDER, MOCK_AUTH_VERIFIER, type Space, SpaceManager, SpaceProtocol } from '../space';
|
|
22
|
-
|
|
23
22
|
import { TestFeedBuilder } from './test-feed-builder';
|
|
24
23
|
|
|
25
24
|
export type NetworkManagerProvider = () => SwarmNetworkManager;
|
|
@@ -11,12 +11,33 @@ import { log } from '@dxos/log';
|
|
|
11
11
|
export type TestConnectionStateProvider = () => 'on' | 'off';
|
|
12
12
|
|
|
13
13
|
export class TestAdapter extends NetworkAdapter {
|
|
14
|
-
static createPair(
|
|
14
|
+
static createPair(
|
|
15
|
+
connectionStateProvider: TestConnectionStateProvider = () => 'on',
|
|
16
|
+
onMessage?: (message: Message) => void,
|
|
17
|
+
): TestAdapter[] {
|
|
15
18
|
const adapter1: TestAdapter = new TestAdapter({
|
|
16
|
-
send: (message: Message) =>
|
|
19
|
+
send: (message: Message) => {
|
|
20
|
+
onMessage?.(message);
|
|
21
|
+
if (connectionStateProvider() === 'on') {
|
|
22
|
+
void sleep(10).then(() => {
|
|
23
|
+
if (connectionStateProvider() === 'on' && adapter2.peerId) {
|
|
24
|
+
adapter2.receive(message);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
},
|
|
17
29
|
});
|
|
18
30
|
const adapter2: TestAdapter = new TestAdapter({
|
|
19
|
-
send: (message: Message) =>
|
|
31
|
+
send: (message: Message) => {
|
|
32
|
+
onMessage?.(message);
|
|
33
|
+
if (connectionStateProvider() === 'on') {
|
|
34
|
+
void sleep(10).then(() => {
|
|
35
|
+
if (connectionStateProvider() === 'on' && adapter1.peerId) {
|
|
36
|
+
adapter1.receive(message);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
},
|
|
20
41
|
});
|
|
21
42
|
|
|
22
43
|
return [adapter1, adapter2];
|