@dxos/client-services 0.8.4-main.c1de068 → 0.8.4-main.c85a9c8dae
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-Q7DAO5CH.mjs → chunk-MQ6PWJ76.mjs} +3614 -3438
- package/dist/lib/browser/chunk-MQ6PWJ76.mjs.map +7 -0
- package/dist/lib/browser/chunk-NQSC7HOE.mjs +22 -0
- package/dist/lib/browser/chunk-NQSC7HOE.mjs.map +7 -0
- package/dist/lib/browser/chunk-QCWEHHJW.mjs +24 -0
- package/dist/lib/browser/chunk-QCWEHHJW.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +471 -77
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs +93 -0
- package/dist/lib/browser/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
- package/dist/lib/browser/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/browser/packlets/locks/browser.mjs +126 -0
- package/dist/lib/browser/packlets/locks/browser.mjs.map +7 -0
- package/dist/lib/browser/packlets/locks/node.mjs +66 -0
- package/dist/lib/browser/packlets/locks/node.mjs.map +7 -0
- package/dist/lib/browser/testing/index.mjs +34 -22
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/chunk-2SZHAWBN.mjs +24 -0
- package/dist/lib/node-esm/chunk-2SZHAWBN.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-LBKPPVZO.mjs → chunk-GUAL4U7S.mjs} +3573 -3265
- package/dist/lib/node-esm/chunk-GUAL4U7S.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-PKEGMOQ4.mjs +22 -0
- package/dist/lib/node-esm/chunk-PKEGMOQ4.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +471 -77
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs +93 -0
- package/dist/lib/node-esm/packlets/diagnostics/browser-diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs +11 -0
- package/dist/lib/node-esm/packlets/diagnostics/diagnostics-broadcast.mjs.map +7 -0
- package/dist/lib/node-esm/packlets/locks/browser.mjs +126 -0
- package/dist/lib/node-esm/packlets/locks/browser.mjs.map +7 -0
- package/dist/lib/node-esm/packlets/locks/node.mjs +66 -0
- package/dist/lib/node-esm/packlets/locks/node.mjs.map +7 -0
- package/dist/lib/node-esm/testing/index.mjs +34 -22
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts +1 -1
- package/dist/types/src/packlets/agents/edge-agent-service.d.ts.map +1 -1
- package/dist/types/src/packlets/devices/devices-service.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/devtools.d.ts +20 -20
- package/dist/types/src/packlets/devtools/devtools.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/feeds.d.ts +1 -1
- package/dist/types/src/packlets/devtools/feeds.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/network.d.ts +1 -1
- package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts +1 -1
- package/dist/types/src/packlets/diagnostics/browser-diagnostics-broadcast.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics-broadcast.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
- package/dist/types/src/packlets/diagnostics/index.d.ts +1 -1
- package/dist/types/src/packlets/diagnostics/index.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/authenticator.d.ts +2 -2
- package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/contacts-service.d.ts +1 -1
- package/dist/types/src/packlets/identity/contacts-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/default-space-state-machine.d.ts +3 -3
- package/dist/types/src/packlets/identity/default-space-state-machine.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-manager.d.ts +5 -5
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +2 -2
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-service.d.ts +1 -1
- package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts +3 -3
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts +4 -4
- package/dist/types/src/packlets/invitations/device-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts +1 -1
- package/dist/types/src/packlets/invitations/edge-invitation-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-guest-extenstion.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-host-extension.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts +3 -4
- package/dist/types/src/packlets/invitations/invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts +4 -4
- package/dist/types/src/packlets/invitations/invitations-handler.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-service.d.ts +1 -1
- package/dist/types/src/packlets/invitations/invitations-service.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +3 -3
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/utils.d.ts.map +1 -1
- package/dist/types/src/packlets/locks/index.d.ts +1 -1
- package/dist/types/src/packlets/locks/index.d.ts.map +1 -1
- package/dist/types/src/packlets/logging/logging-service.d.ts +5 -1
- package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
- package/dist/types/src/packlets/network/network-service.d.ts +2 -2
- package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
- package/dist/types/src/packlets/services/client-rpc-server.d.ts +2 -2
- package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
- package/dist/types/src/packlets/services/feed-syncer.d.ts +59 -0
- package/dist/types/src/packlets/services/feed-syncer.d.ts.map +1 -0
- package/dist/types/src/packlets/services/feed-syncer.test.d.ts +2 -0
- package/dist/types/src/packlets/services/feed-syncer.test.d.ts.map +1 -0
- package/dist/types/src/packlets/services/platform.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-context.d.ts +13 -8
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts +19 -5
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/space-archive-writer.d.ts +1 -1
- package/dist/types/src/packlets/space-export/space-archive-writer.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/automerge-space-state.d.ts +1 -1
- package/dist/types/src/packlets/spaces/automerge-space-state.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts +12 -7
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts +6 -6
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts +2 -2
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +6 -6
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts +2 -2
- package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/profile-archive.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/storage.d.ts.map +1 -1
- package/dist/types/src/packlets/system/system-service.d.ts +1 -1
- package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/invitation-utils.d.ts +6 -3
- package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts +8 -7
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-runtime.d.ts +31 -4
- package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-session.d.ts +2 -2
- package/dist/types/src/packlets/worker/worker-session.d.ts.map +1 -1
- package/dist/types/src/version.d.ts +1 -1
- package/dist/types/src/version.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +72 -48
- package/src/packlets/agents/edge-agent-manager.ts +2 -2
- package/src/packlets/agents/edge-agent-service.ts +13 -3
- package/src/packlets/devices/devices-service.test.ts +4 -3
- package/src/packlets/devices/devices-service.ts +2 -2
- package/src/packlets/devtools/devtools.ts +30 -29
- package/src/packlets/devtools/feeds.ts +2 -2
- package/src/packlets/devtools/network.ts +1 -1
- package/src/packlets/diagnostics/browser-diagnostics-broadcast.ts +1 -1
- package/src/packlets/diagnostics/diagnostics-broadcast.ts +1 -1
- package/src/packlets/diagnostics/diagnostics-collector.ts +1 -1
- package/src/packlets/diagnostics/diagnostics.ts +1 -1
- package/src/packlets/diagnostics/index.ts +1 -1
- package/src/packlets/identity/authenticator.node.test.ts +1 -1
- package/src/packlets/identity/authenticator.ts +3 -3
- package/src/packlets/identity/contacts-service.ts +3 -2
- package/src/packlets/identity/default-space-state-machine.ts +3 -3
- package/src/packlets/identity/identity-manager.test.ts +3 -3
- package/src/packlets/identity/identity-manager.ts +9 -9
- package/src/packlets/identity/identity-recovery-manager.ts +2 -2
- package/src/packlets/identity/identity-service.test.ts +3 -2
- package/src/packlets/identity/identity-service.ts +2 -1
- package/src/packlets/identity/identity.test.ts +9 -9
- package/src/packlets/identity/identity.ts +9 -8
- package/src/packlets/invitations/device-invitation-protocol.test.ts +1 -1
- package/src/packlets/invitations/device-invitation-protocol.ts +6 -5
- package/src/packlets/invitations/edge-invitation-handler.ts +1 -1
- package/src/packlets/invitations/invitation-guest-extenstion.ts +7 -5
- package/src/packlets/invitations/invitation-host-extension.ts +8 -6
- package/src/packlets/invitations/invitation-protocol.ts +3 -4
- package/src/packlets/invitations/invitations-handler.test.ts +4 -3
- package/src/packlets/invitations/invitations-handler.ts +10 -10
- package/src/packlets/invitations/invitations-manager.ts +3 -3
- package/src/packlets/invitations/invitations-service.ts +1 -1
- package/src/packlets/invitations/space-invitation-protocol.test.ts +2 -2
- package/src/packlets/invitations/space-invitation-protocol.ts +10 -15
- package/src/packlets/invitations/utils.ts +1 -1
- package/src/packlets/locks/browser.ts +1 -1
- package/src/packlets/locks/index.ts +1 -1
- package/src/packlets/logging/logging-service.ts +7 -3
- package/src/packlets/logging/logging.test.ts +1 -1
- package/src/packlets/network/network-service.test.ts +4 -3
- package/src/packlets/network/network-service.ts +2 -2
- package/src/packlets/services/client-rpc-server.ts +5 -5
- package/src/packlets/services/feed-syncer.test.ts +340 -0
- package/src/packlets/services/feed-syncer.ts +330 -0
- package/src/packlets/services/platform.ts +7 -1
- package/src/packlets/services/service-context.test.ts +1 -1
- package/src/packlets/services/service-context.ts +62 -29
- package/src/packlets/services/service-host.test.ts +3 -2
- package/src/packlets/services/service-host.ts +69 -24
- package/src/packlets/services/service-registry.test.ts +2 -1
- package/src/packlets/space-export/space-archive-reader.ts +2 -2
- package/src/packlets/space-export/space-archive-writer.ts +7 -5
- package/src/packlets/space-export/tar.test.ts +1 -1
- package/src/packlets/spaces/automerge-space-state.ts +1 -1
- package/src/packlets/spaces/data-space-manager.ts +76 -36
- package/src/packlets/spaces/data-space.ts +18 -13
- package/src/packlets/spaces/edge-feed-replicator.test.ts +3 -3
- package/src/packlets/spaces/edge-feed-replicator.ts +4 -4
- package/src/packlets/spaces/epoch-migrations.ts +2 -2
- package/src/packlets/spaces/notarization-plugin.test.ts +3 -3
- package/src/packlets/spaces/notarization-plugin.ts +11 -11
- package/src/packlets/spaces/spaces-service.test.ts +3 -2
- package/src/packlets/spaces/spaces-service.ts +27 -23
- package/src/packlets/storage/profile-archive.ts +1 -1
- package/src/packlets/storage/storage.ts +7 -8
- package/src/packlets/system/system-service.test.ts +1 -1
- package/src/packlets/system/system-service.ts +4 -4
- package/src/packlets/testing/invitation-utils.ts +8 -5
- package/src/packlets/testing/test-builder.ts +39 -13
- package/src/packlets/worker/worker-runtime.ts +151 -12
- package/src/packlets/worker/worker-session.ts +11 -11
- package/src/version.ts +1 -1
- package/dist/lib/browser/chunk-Q7DAO5CH.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-LBKPPVZO.mjs.map +0 -7
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import type * as SqlClient from '@effect/sql/SqlClient';
|
|
6
|
+
import { Encoder, decode as cborXdecode } from 'cbor-x';
|
|
7
|
+
import * as Effect from 'effect/Effect';
|
|
8
|
+
import * as Schema from 'effect/Schema';
|
|
9
|
+
|
|
10
|
+
import { AsyncTask, scheduleTask } from '@dxos/async';
|
|
11
|
+
import { Resource } from '@dxos/context';
|
|
12
|
+
import { type EdgeConnection, MessageSchema } from '@dxos/edge-client';
|
|
13
|
+
import { RuntimeProvider } from '@dxos/effect';
|
|
14
|
+
import { type FeedStore, SyncClient } from '@dxos/feed';
|
|
15
|
+
import { invariant } from '@dxos/invariant';
|
|
16
|
+
import { SpaceId } from '@dxos/keys';
|
|
17
|
+
import { FeedProtocol } from '@dxos/protocols';
|
|
18
|
+
import { EdgeService } from '@dxos/protocols';
|
|
19
|
+
import { createBuf } from '@dxos/protocols/buf';
|
|
20
|
+
import { type Message as RouterMessage } from '@dxos/protocols/buf/dxos/edge/messenger_pb';
|
|
21
|
+
import type { SqlTransaction } from '@dxos/sql-sqlite';
|
|
22
|
+
import { bufferToArray } from '@dxos/util';
|
|
23
|
+
|
|
24
|
+
const encoder = new Encoder({ tagUint8Array: false, useRecords: false });
|
|
25
|
+
|
|
26
|
+
const DEFAULT_MESSAGE_BLOCKS_LIMIT = 50;
|
|
27
|
+
const DEFAULT_SYNC_CONCURRENCY = 5;
|
|
28
|
+
const DEFAULT_POLLING_INTERVAL = 5_000;
|
|
29
|
+
const DEFAULT_POLL_REQUEST_THROTTLE_MS = 250;
|
|
30
|
+
const MAX_BLOCKING_SYNC_ITERATIONS = 100;
|
|
31
|
+
|
|
32
|
+
interface FeedSyncerOptions {
|
|
33
|
+
runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient | SqlTransaction.SqlTransaction>;
|
|
34
|
+
feedStore: FeedStore;
|
|
35
|
+
edgeClient: EdgeConnection;
|
|
36
|
+
peerId: string;
|
|
37
|
+
getSpaceIds: () => SpaceId[];
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Namespaces to sync.
|
|
41
|
+
*/
|
|
42
|
+
syncNamespaces: string[];
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Maximum number of blocks to sync in a single message.
|
|
46
|
+
* @default 50
|
|
47
|
+
*/
|
|
48
|
+
messageBlocksLimit?: number;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Maximum number of spaces to sync concurrently.
|
|
52
|
+
* @default 5
|
|
53
|
+
*/
|
|
54
|
+
syncConcurrency?: number;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Interval between full polls.
|
|
58
|
+
* @default 10 seconds
|
|
59
|
+
*/
|
|
60
|
+
pollingInterval?: number;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Minimum delay between externally requested best-effort polls.
|
|
64
|
+
* @default 250 ms
|
|
65
|
+
*/
|
|
66
|
+
pollRequestThrottleMs?: number;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export class FeedSyncer extends Resource {
|
|
70
|
+
readonly #syncNamespaces: string[];
|
|
71
|
+
readonly #messageBlocksLimit: number;
|
|
72
|
+
readonly #syncConcurrency: number;
|
|
73
|
+
readonly #pollingInterval: number;
|
|
74
|
+
readonly #pollRequestThrottleMs: number;
|
|
75
|
+
|
|
76
|
+
readonly #runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient | SqlTransaction.SqlTransaction>;
|
|
77
|
+
readonly #feedStore: FeedStore;
|
|
78
|
+
readonly #edgeClient: EdgeConnection;
|
|
79
|
+
readonly #syncClient: SyncClient;
|
|
80
|
+
readonly #getSpaceIds: () => SpaceId[];
|
|
81
|
+
|
|
82
|
+
#spacesToPoll = new Set<SpaceId>();
|
|
83
|
+
/** Last time full poll was completed. */
|
|
84
|
+
#lastFullPoll: number | null = null;
|
|
85
|
+
#throttledPollScheduled = false;
|
|
86
|
+
#lastRequestedPollAt: number | null = null;
|
|
87
|
+
|
|
88
|
+
constructor(options: FeedSyncerOptions) {
|
|
89
|
+
super();
|
|
90
|
+
this.#runtime = options.runtime;
|
|
91
|
+
this.#feedStore = options.feedStore;
|
|
92
|
+
this.#edgeClient = options.edgeClient;
|
|
93
|
+
this.#syncClient = new SyncClient({
|
|
94
|
+
peerId: options.peerId,
|
|
95
|
+
feedStore: options.feedStore,
|
|
96
|
+
sendMessage: this.#sendMessage.bind(this),
|
|
97
|
+
});
|
|
98
|
+
this.#getSpaceIds = options.getSpaceIds;
|
|
99
|
+
this.#syncNamespaces = options.syncNamespaces;
|
|
100
|
+
this.#messageBlocksLimit = options.messageBlocksLimit ?? DEFAULT_MESSAGE_BLOCKS_LIMIT;
|
|
101
|
+
this.#syncConcurrency = options.syncConcurrency ?? DEFAULT_SYNC_CONCURRENCY;
|
|
102
|
+
this.#pollingInterval = options.pollingInterval ?? DEFAULT_POLLING_INTERVAL;
|
|
103
|
+
this.#pollRequestThrottleMs = options.pollRequestThrottleMs ?? DEFAULT_POLL_REQUEST_THROTTLE_MS;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
protected override async _open(): Promise<void> {
|
|
107
|
+
this._ctx.onDispose(
|
|
108
|
+
this.#edgeClient.onMessage((msg: RouterMessage) => {
|
|
109
|
+
if (!msg.serviceId) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const service = msg.serviceId.split(':')[0];
|
|
113
|
+
if (service !== EdgeService.QUEUE_REPLICATOR) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const handleMessageEffect = Effect.gen(this, function* () {
|
|
117
|
+
const decoded = yield* Effect.try({
|
|
118
|
+
try: () => cborXdecode(msg.payload!.value),
|
|
119
|
+
catch: (error) => new Error(`Failed to decode feed sync message: ${error}`),
|
|
120
|
+
});
|
|
121
|
+
const payload = yield* Schema.validate(FeedProtocol.ProtocolMessage)(decoded);
|
|
122
|
+
yield* this.#syncClient.handleMessage(payload);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
void RuntimeProvider.runPromise(this.#runtime)(handleMessageEffect);
|
|
126
|
+
}),
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
this._ctx.onDispose(
|
|
130
|
+
// NOTE: This will fire immediately if the connection is already open.
|
|
131
|
+
this.#edgeClient.onReconnected(async () => {}),
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
this.#feedStore.onNewBlocks.on(this._ctx, () => {
|
|
135
|
+
this.#pushTask.schedule();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
await this.#pollTask.open();
|
|
139
|
+
await this.#pushTask.open();
|
|
140
|
+
|
|
141
|
+
this.#resetSpacesToPoll();
|
|
142
|
+
this.#pollTask.schedule();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
protected override async _close(): Promise<void> {
|
|
146
|
+
await this.#pollTask.close();
|
|
147
|
+
await this.#pushTask.close();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Schedules a best-effort pull without blocking the caller.
|
|
152
|
+
*/
|
|
153
|
+
schedulePoll(): void {
|
|
154
|
+
this.#resetSpacesToPoll();
|
|
155
|
+
if (this.#throttledPollScheduled) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const now = Date.now();
|
|
160
|
+
const delay =
|
|
161
|
+
this.#lastRequestedPollAt == null
|
|
162
|
+
? 0
|
|
163
|
+
: Math.max(this.#pollRequestThrottleMs - (now - this.#lastRequestedPollAt), 0);
|
|
164
|
+
this.#throttledPollScheduled = true;
|
|
165
|
+
scheduleTask(
|
|
166
|
+
this._ctx,
|
|
167
|
+
() => {
|
|
168
|
+
this.#throttledPollScheduled = false;
|
|
169
|
+
this.#lastRequestedPollAt = Date.now();
|
|
170
|
+
this.#pollTask.schedule();
|
|
171
|
+
},
|
|
172
|
+
delay,
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Performs queue sync and blocks until there are no pending sync batches.
|
|
178
|
+
*/
|
|
179
|
+
async syncBlocking({
|
|
180
|
+
spaceId,
|
|
181
|
+
subspaceTag,
|
|
182
|
+
shouldPush = true,
|
|
183
|
+
shouldPull = true,
|
|
184
|
+
}: {
|
|
185
|
+
spaceId: SpaceId;
|
|
186
|
+
subspaceTag: string;
|
|
187
|
+
shouldPush?: boolean;
|
|
188
|
+
shouldPull?: boolean;
|
|
189
|
+
}): Promise<void> {
|
|
190
|
+
invariant(SpaceId.isValid(spaceId));
|
|
191
|
+
invariant(FeedProtocol.isWellKnownNamespace(subspaceTag));
|
|
192
|
+
if (!shouldPush && !shouldPull) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
await RuntimeProvider.runPromise(this.#runtime)(
|
|
197
|
+
Effect.gen(this, function* () {
|
|
198
|
+
let done = false;
|
|
199
|
+
let iterations = 0;
|
|
200
|
+
while (!done) {
|
|
201
|
+
done = true;
|
|
202
|
+
if (shouldPull) {
|
|
203
|
+
const pullResult = yield* this.#syncClient.pull({
|
|
204
|
+
spaceId,
|
|
205
|
+
feedNamespace: subspaceTag,
|
|
206
|
+
limit: this.#messageBlocksLimit,
|
|
207
|
+
});
|
|
208
|
+
done &&= pullResult.done;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (shouldPush) {
|
|
212
|
+
const pushResult = yield* this.#syncClient.push({
|
|
213
|
+
spaceId,
|
|
214
|
+
feedNamespace: subspaceTag,
|
|
215
|
+
limit: this.#messageBlocksLimit,
|
|
216
|
+
});
|
|
217
|
+
done &&= pushResult.done;
|
|
218
|
+
}
|
|
219
|
+
iterations++;
|
|
220
|
+
if (iterations > MAX_BLOCKING_SYNC_ITERATIONS) {
|
|
221
|
+
throw new Error('Blocking sync exceeded max iterations.');
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}),
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
#resetSpacesToPoll(): void {
|
|
229
|
+
this.#spacesToPoll.clear();
|
|
230
|
+
this.#getSpaceIds().forEach((spaceId) => {
|
|
231
|
+
this.#spacesToPoll.add(spaceId);
|
|
232
|
+
});
|
|
233
|
+
this.#lastFullPoll = Date.now();
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
#sendMessage(message: FeedProtocol.QueryRequest | FeedProtocol.AppendRequest): Effect.Effect<void, unknown, never> {
|
|
237
|
+
return Effect.gen(this, function* () {
|
|
238
|
+
const encoded = encoder.encode(message);
|
|
239
|
+
yield* Effect.tryPromise(async () =>
|
|
240
|
+
this.#edgeClient.send(
|
|
241
|
+
createBuf(MessageSchema, {
|
|
242
|
+
source: {
|
|
243
|
+
identityKey: this.#edgeClient.identityKey,
|
|
244
|
+
peerKey: this.#edgeClient.peerKey,
|
|
245
|
+
},
|
|
246
|
+
serviceId: this.#getTargetServiceId(message),
|
|
247
|
+
payload: { value: bufferToArray(encoded) },
|
|
248
|
+
}),
|
|
249
|
+
),
|
|
250
|
+
);
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
#getTargetServiceId(message: FeedProtocol.QueryRequest | FeedProtocol.AppendRequest): string {
|
|
255
|
+
// TODO(dmaretskyi): Perhaps in the future we will want to include the queue namespace here as well.
|
|
256
|
+
// This would require putting it at the top level of the message.
|
|
257
|
+
// For now, we let the edge router handle it.
|
|
258
|
+
return FeedProtocol.encodeServiceId(message.feedNamespace, message.spaceId as SpaceId);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
readonly #pollTask = new AsyncTask(async () =>
|
|
262
|
+
Effect.gen(this, function* () {
|
|
263
|
+
yield* Effect.forEach(
|
|
264
|
+
this.#spacesToPoll,
|
|
265
|
+
(spaceId) =>
|
|
266
|
+
Effect.gen(this, function* () {
|
|
267
|
+
let doneForAllNamespaces = true;
|
|
268
|
+
for (const feedNamespace of this.#syncNamespaces) {
|
|
269
|
+
const { done } = yield* this.#syncClient.pull({
|
|
270
|
+
spaceId,
|
|
271
|
+
feedNamespace,
|
|
272
|
+
limit: this.#messageBlocksLimit,
|
|
273
|
+
});
|
|
274
|
+
if (!done) {
|
|
275
|
+
doneForAllNamespaces = false;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (doneForAllNamespaces) {
|
|
279
|
+
this.#spacesToPoll.delete(spaceId);
|
|
280
|
+
}
|
|
281
|
+
}),
|
|
282
|
+
{ concurrency: this.#syncConcurrency },
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
// If its time to do a full poll, reset the spaces to poll and schedule the next poll immediately.
|
|
286
|
+
if (this.#lastFullPoll == null || Date.now() - this.#lastFullPoll > this.#pollingInterval) {
|
|
287
|
+
this.#resetSpacesToPoll();
|
|
288
|
+
this.#pollTask.schedule();
|
|
289
|
+
} else if (this.#spacesToPoll.size > 0) {
|
|
290
|
+
// If there are some spaces still syncing, poll them immediately.
|
|
291
|
+
this.#pollTask.schedule();
|
|
292
|
+
} else {
|
|
293
|
+
// All spaces sync, and there's time before the next full poll, schedule it later.
|
|
294
|
+
this.#resetSpacesToPoll();
|
|
295
|
+
scheduleTask(
|
|
296
|
+
this._ctx,
|
|
297
|
+
() => this.#pollTask.schedule(),
|
|
298
|
+
Math.max(this.#pollingInterval - (Date.now() - (this.#lastFullPoll ?? 0)), 0),
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
}).pipe(RuntimeProvider.runPromise(this.#runtime)),
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
readonly #pushTask = new AsyncTask(async () =>
|
|
305
|
+
Effect.gen(this, function* () {
|
|
306
|
+
yield* Effect.forEach(
|
|
307
|
+
this.#getSpaceIds(),
|
|
308
|
+
(spaceId) =>
|
|
309
|
+
Effect.gen(this, function* () {
|
|
310
|
+
let doneForAllNamespaces = true;
|
|
311
|
+
for (const feedNamespace of this.#syncNamespaces) {
|
|
312
|
+
const { done } = yield* this.#syncClient.push({
|
|
313
|
+
spaceId,
|
|
314
|
+
feedNamespace,
|
|
315
|
+
limit: this.#messageBlocksLimit,
|
|
316
|
+
});
|
|
317
|
+
if (!done) {
|
|
318
|
+
doneForAllNamespaces = false;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if (!doneForAllNamespaces) {
|
|
322
|
+
// Keep pushing until all blocks are pushed.
|
|
323
|
+
this.#pushTask.schedule();
|
|
324
|
+
}
|
|
325
|
+
}),
|
|
326
|
+
{ concurrency: this.#syncConcurrency },
|
|
327
|
+
);
|
|
328
|
+
}).pipe(RuntimeProvider.runPromise(this.#runtime)),
|
|
329
|
+
);
|
|
330
|
+
}
|
|
@@ -14,12 +14,18 @@ export const getPlatform = (): Platform => {
|
|
|
14
14
|
userAgent,
|
|
15
15
|
uptime: Math.floor((Date.now() - window.performance.timeOrigin) / 1_000),
|
|
16
16
|
};
|
|
17
|
-
} else {
|
|
17
|
+
} else if (typeof SharedWorkerGlobalScope !== 'undefined') {
|
|
18
18
|
// Shared worker.
|
|
19
19
|
return {
|
|
20
20
|
type: Platform.PLATFORM_TYPE.SHARED_WORKER,
|
|
21
21
|
uptime: Math.floor((Date.now() - performance.timeOrigin) / 1_000),
|
|
22
22
|
};
|
|
23
|
+
} else {
|
|
24
|
+
// Dedicated worker.
|
|
25
|
+
return {
|
|
26
|
+
type: Platform.PLATFORM_TYPE.DEDICATED_WORKER,
|
|
27
|
+
uptime: Math.floor((Date.now() - performance.timeOrigin) / 1_000),
|
|
28
|
+
};
|
|
23
29
|
}
|
|
24
30
|
} else {
|
|
25
31
|
// Node.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { describe, test } from 'vitest';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { MemorySignalManager, MemorySignalManagerContext } from '@dxos/messaging';
|
|
8
8
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
9
9
|
import { openAndClose } from '@dxos/test-utils';
|
|
10
10
|
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import type * as SqlClient from '@effect/sql/SqlClient';
|
|
6
|
+
|
|
5
7
|
import { Mutex, Trigger } from '@dxos/async';
|
|
6
8
|
import { Context, Resource } from '@dxos/context';
|
|
7
|
-
import {
|
|
9
|
+
import { type CredentialProcessor, getCredentialAssertion } from '@dxos/credentials';
|
|
8
10
|
import { failUndefined, warnAfterTimeout } from '@dxos/debug';
|
|
9
11
|
import {
|
|
10
12
|
EchoEdgeReplicator,
|
|
@@ -15,49 +17,54 @@ import {
|
|
|
15
17
|
valueEncoding,
|
|
16
18
|
} from '@dxos/echo-pipeline';
|
|
17
19
|
import { createChainEdgeIdentity, createEphemeralEdgeIdentity } from '@dxos/edge-client';
|
|
18
|
-
import type {
|
|
20
|
+
import type { EdgeConnection, EdgeHttpClient, EdgeIdentity } from '@dxos/edge-client';
|
|
21
|
+
import { type RuntimeProvider } from '@dxos/effect';
|
|
19
22
|
import { FeedFactory, FeedStore } from '@dxos/feed-store';
|
|
20
23
|
import { invariant } from '@dxos/invariant';
|
|
21
24
|
import { Keyring } from '@dxos/keyring';
|
|
22
|
-
import { PublicKey } from '@dxos/keys';
|
|
25
|
+
import { PublicKey, type SpaceId } from '@dxos/keys';
|
|
23
26
|
import { type LevelDB } from '@dxos/kv-store';
|
|
24
27
|
import { log } from '@dxos/log';
|
|
25
28
|
import { type SignalManager } from '@dxos/messaging';
|
|
26
29
|
import { type SwarmNetworkManager } from '@dxos/network-manager';
|
|
27
30
|
import { InvalidStorageVersionError, STORAGE_VERSION, trace } from '@dxos/protocols';
|
|
31
|
+
import { FeedProtocol } from '@dxos/protocols';
|
|
28
32
|
import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
|
|
29
33
|
import { type Runtime } from '@dxos/protocols/proto/dxos/config';
|
|
30
34
|
import type { FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
31
35
|
import { type Credential, type ProfileDocument } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
32
36
|
import { type Storage } from '@dxos/random-access-storage';
|
|
37
|
+
import type * as SqlTransaction from '@dxos/sql-sqlite/SqlTransaction';
|
|
33
38
|
import { BlobStore } from '@dxos/teleport-extension-object-sync';
|
|
34
39
|
import { trace as Trace } from '@dxos/tracing';
|
|
35
40
|
import { safeInstanceof } from '@dxos/util';
|
|
36
41
|
|
|
37
42
|
import { EdgeAgentManager } from '../agents';
|
|
38
43
|
import {
|
|
39
|
-
IdentityManager,
|
|
40
44
|
type CreateIdentityOptions,
|
|
41
|
-
|
|
42
|
-
type
|
|
45
|
+
IdentityManager,
|
|
46
|
+
type IdentityManagerProps,
|
|
47
|
+
type JoinIdentityProps,
|
|
43
48
|
} from '../identity';
|
|
44
49
|
import { EdgeIdentityRecoveryManager } from '../identity/identity-recovery-manager';
|
|
45
50
|
import {
|
|
46
51
|
DeviceInvitationProtocol,
|
|
47
|
-
type
|
|
52
|
+
type InvitationConnectionProps,
|
|
53
|
+
type InvitationProtocol,
|
|
48
54
|
InvitationsHandler,
|
|
49
55
|
InvitationsManager,
|
|
50
56
|
SpaceInvitationProtocol,
|
|
51
|
-
type InvitationProtocol,
|
|
52
57
|
} from '../invitations';
|
|
53
|
-
import { DataSpaceManager, type
|
|
58
|
+
import { DataSpaceManager, type DataSpaceManagerRuntimeProps, type SigningContext } from '../spaces';
|
|
59
|
+
|
|
60
|
+
import { FeedSyncer } from './feed-syncer';
|
|
54
61
|
|
|
55
|
-
export type
|
|
56
|
-
|
|
62
|
+
export type ServiceContextRuntimeProps = Pick<
|
|
63
|
+
IdentityManagerProps,
|
|
57
64
|
'devicePresenceOfflineTimeout' | 'devicePresenceAnnounceInterval'
|
|
58
65
|
> &
|
|
59
|
-
|
|
60
|
-
|
|
66
|
+
DataSpaceManagerRuntimeProps & {
|
|
67
|
+
invitationConnectionDefaultProps?: InvitationConnectionProps;
|
|
61
68
|
disableP2pReplication?: boolean;
|
|
62
69
|
enableVectorIndexing?: boolean;
|
|
63
70
|
};
|
|
@@ -84,6 +91,7 @@ export class ServiceContext extends Resource {
|
|
|
84
91
|
public readonly echoHost: EchoHost;
|
|
85
92
|
private readonly _meshReplicator?: MeshEchoReplicator = undefined;
|
|
86
93
|
private readonly _echoEdgeReplicator?: EchoEdgeReplicator = undefined;
|
|
94
|
+
private readonly _feedSyncer?: FeedSyncer = undefined;
|
|
87
95
|
|
|
88
96
|
// Initialized after identity is initialized.
|
|
89
97
|
public dataSpaceManager?: DataSpaceManager;
|
|
@@ -105,11 +113,15 @@ export class ServiceContext extends Resource {
|
|
|
105
113
|
public readonly signalManager: SignalManager,
|
|
106
114
|
private readonly _edgeConnection: EdgeConnection | undefined,
|
|
107
115
|
private readonly _edgeHttpClient: EdgeHttpClient | undefined,
|
|
108
|
-
|
|
116
|
+
private readonly _runtime: RuntimeProvider.RuntimeProvider<SqlClient.SqlClient | SqlTransaction.SqlTransaction>,
|
|
117
|
+
public readonly _runtimeProps?: ServiceContextRuntimeProps,
|
|
109
118
|
private readonly _edgeFeatures?: Runtime.Client.EdgeFeatures,
|
|
110
119
|
) {
|
|
111
120
|
super();
|
|
112
121
|
|
|
122
|
+
log('runtimeProps', this._runtimeProps);
|
|
123
|
+
log('edgeFeatures', this._edgeFeatures);
|
|
124
|
+
|
|
113
125
|
// TODO(burdon): Move strings to constants.
|
|
114
126
|
this.metadataStore = new MetadataStore(storage.createDirectory('metadata'));
|
|
115
127
|
this.blobStore = new BlobStore(storage.createDirectory('blobs'));
|
|
@@ -131,7 +143,7 @@ export class ServiceContext extends Resource {
|
|
|
131
143
|
networkManager: this.networkManager,
|
|
132
144
|
blobStore: this.blobStore,
|
|
133
145
|
metadataStore: this.metadataStore,
|
|
134
|
-
disableP2pReplication: this.
|
|
146
|
+
disableP2pReplication: this._runtimeProps?.disableP2pReplication,
|
|
135
147
|
});
|
|
136
148
|
|
|
137
149
|
this.identityManager = new IdentityManager({
|
|
@@ -139,8 +151,8 @@ export class ServiceContext extends Resource {
|
|
|
139
151
|
keyring: this.keyring,
|
|
140
152
|
feedStore: this.feedStore,
|
|
141
153
|
spaceManager: this.spaceManager,
|
|
142
|
-
devicePresenceOfflineTimeout: this.
|
|
143
|
-
devicePresenceAnnounceInterval: this.
|
|
154
|
+
devicePresenceOfflineTimeout: this._runtimeProps?.devicePresenceOfflineTimeout,
|
|
155
|
+
devicePresenceAnnounceInterval: this._runtimeProps?.devicePresenceAnnounceInterval,
|
|
144
156
|
edgeConnection: this._edgeConnection,
|
|
145
157
|
edgeFeatures: this._edgeFeatures,
|
|
146
158
|
});
|
|
@@ -156,17 +168,21 @@ export class ServiceContext extends Resource {
|
|
|
156
168
|
kv: this.level,
|
|
157
169
|
peerIdProvider: () => this.identityManager.identity?.deviceKey?.toHex(),
|
|
158
170
|
getSpaceKeyByRootDocumentId: (documentId) => this.spaceManager.findSpaceByRootDocumentId(documentId)?.key,
|
|
159
|
-
|
|
160
|
-
|
|
171
|
+
runtime: this._runtime,
|
|
172
|
+
syncQueue: async (request) => {
|
|
173
|
+
return this._feedSyncer?.syncBlocking({
|
|
174
|
+
spaceId: request.spaceId as SpaceId,
|
|
175
|
+
subspaceTag: request.subspaceTag,
|
|
176
|
+
shouldPush: request.shouldPush,
|
|
177
|
+
shouldPull: request.shouldPull,
|
|
178
|
+
});
|
|
161
179
|
},
|
|
162
180
|
});
|
|
163
181
|
|
|
164
|
-
this._meshReplicator = new MeshEchoReplicator();
|
|
165
|
-
|
|
166
182
|
this.invitations = new InvitationsHandler(
|
|
167
183
|
this.networkManager, //
|
|
168
184
|
this._edgeHttpClient,
|
|
169
|
-
|
|
185
|
+
_runtimeProps?.invitationConnectionDefaultProps,
|
|
170
186
|
);
|
|
171
187
|
this.invitationsManager = new InvitationsManager(
|
|
172
188
|
this.invitations,
|
|
@@ -186,12 +202,24 @@ export class ServiceContext extends Resource {
|
|
|
186
202
|
),
|
|
187
203
|
);
|
|
188
204
|
|
|
189
|
-
if (!this.
|
|
205
|
+
if (!this._runtimeProps?.disableP2pReplication) {
|
|
190
206
|
this._meshReplicator = new MeshEchoReplicator();
|
|
191
207
|
}
|
|
192
|
-
if (this._edgeConnection && this._edgeFeatures?.echoReplicator) {
|
|
208
|
+
if (this._edgeConnection && this._edgeFeatures?.echoReplicator && this._edgeHttpClient) {
|
|
193
209
|
this._echoEdgeReplicator = new EchoEdgeReplicator({
|
|
194
210
|
edgeConnection: this._edgeConnection,
|
|
211
|
+
edgeHttpClient: this._edgeHttpClient,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (this.echoHost.feedStore && this._edgeConnection) {
|
|
216
|
+
this._feedSyncer = new FeedSyncer({
|
|
217
|
+
runtime: this._runtime,
|
|
218
|
+
feedStore: this.echoHost.feedStore,
|
|
219
|
+
edgeClient: this._edgeConnection,
|
|
220
|
+
peerId: this.identityManager.identity?.deviceKey?.toHex() ?? '',
|
|
221
|
+
getSpaceIds: () => this.echoHost!.spaceIds,
|
|
222
|
+
syncNamespaces: [FeedProtocol.WellKnownNamespaces.data, FeedProtocol.WellKnownNamespaces.trace],
|
|
195
223
|
});
|
|
196
224
|
}
|
|
197
225
|
}
|
|
@@ -228,6 +256,8 @@ export class ServiceContext extends Resource {
|
|
|
228
256
|
await this._initialize(ctx);
|
|
229
257
|
}
|
|
230
258
|
|
|
259
|
+
await this._feedSyncer?.open();
|
|
260
|
+
|
|
231
261
|
const loadedInvitations = await this.invitationsManager.loadPersistentInvitations();
|
|
232
262
|
log('loaded persistent invitations', { count: loadedInvitations.invitations?.length });
|
|
233
263
|
|
|
@@ -237,6 +267,9 @@ export class ServiceContext extends Resource {
|
|
|
237
267
|
|
|
238
268
|
protected override async _close(ctx: Context): Promise<void> {
|
|
239
269
|
log('closing...');
|
|
270
|
+
|
|
271
|
+
await this._feedSyncer?.close();
|
|
272
|
+
|
|
240
273
|
if (this._deviceSpaceSync && this.identityManager.identity) {
|
|
241
274
|
await this.identityManager.identity.space.spaceState.removeCredentialProcessor(this._deviceSpaceSync);
|
|
242
275
|
}
|
|
@@ -244,13 +277,13 @@ export class ServiceContext extends Resource {
|
|
|
244
277
|
await this.edgeAgentManager?.close();
|
|
245
278
|
await this.identityManager.close();
|
|
246
279
|
await this.spaceManager.close();
|
|
247
|
-
await this.feedStore.close();
|
|
248
|
-
await this.metadataStore.close();
|
|
249
|
-
|
|
250
280
|
await this.echoHost.close(ctx);
|
|
281
|
+
|
|
251
282
|
await this.networkManager.close();
|
|
252
283
|
await this.signalManager.close();
|
|
253
284
|
await this._edgeConnection?.close();
|
|
285
|
+
await this.feedStore.close();
|
|
286
|
+
await this.metadataStore.close();
|
|
254
287
|
|
|
255
288
|
log('closed');
|
|
256
289
|
}
|
|
@@ -282,7 +315,7 @@ export class ServiceContext extends Resource {
|
|
|
282
315
|
}
|
|
283
316
|
}
|
|
284
317
|
|
|
285
|
-
private async _acceptIdentity(params:
|
|
318
|
+
private async _acceptIdentity(params: JoinIdentityProps) {
|
|
286
319
|
const { identity, identityRecord } = await this.identityManager.prepareIdentity(params);
|
|
287
320
|
await this._setNetworkIdentity({ deviceCredential: params.authorizedDeviceCredential! });
|
|
288
321
|
await identity.joinNetwork();
|
|
@@ -326,7 +359,7 @@ export class ServiceContext extends Resource {
|
|
|
326
359
|
edgeHttpClient: this._edgeHttpClient,
|
|
327
360
|
echoEdgeReplicator: this._echoEdgeReplicator,
|
|
328
361
|
meshReplicator: this._meshReplicator,
|
|
329
|
-
|
|
362
|
+
runtimeProps: this._runtimeProps as DataSpaceManagerRuntimeProps,
|
|
330
363
|
edgeFeatures: this._edgeFeatures,
|
|
331
364
|
});
|
|
332
365
|
await this.dataSpaceManager.open();
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { rmSync } from 'node:fs';
|
|
6
|
-
import { afterEach, onTestFinished, describe, expect, test } from 'vitest';
|
|
7
6
|
|
|
8
|
-
import {
|
|
7
|
+
import { afterEach, describe, expect, onTestFinished, test } from 'vitest';
|
|
8
|
+
|
|
9
|
+
import { Trigger, asyncTimeout, latch } from '@dxos/async';
|
|
9
10
|
import { Config } from '@dxos/config';
|
|
10
11
|
import { Context } from '@dxos/context';
|
|
11
12
|
import { verifyPresentation } from '@dxos/credentials';
|