@dxos/client-services 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-2TKMQ2UP.mjs → chunk-IFPYIR2N.mjs} +535 -551
- package/dist/lib/browser/chunk-IFPYIR2N.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1 -1
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +1 -1
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/{chunk-HUMVSL5Y.cjs → chunk-VC4EAGT6.cjs} +704 -709
- package/dist/lib/node/chunk-VC4EAGT6.cjs.map +7 -0
- package/dist/lib/node/index.cjs +47 -47
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +8 -8
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/lib/node-esm/{chunk-DQCPFIVI.mjs → chunk-SV2U4CXT.mjs} +535 -540
- package/dist/lib/node-esm/chunk-SV2U4CXT.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +1 -1
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +1 -1
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/packlets/agents/edge-agent-manager.d.ts.map +1 -1
- 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/feeds.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/keys.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/metadata.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/network.d.ts.map +1 -1
- package/dist/types/src/packlets/devtools/spaces.d.ts.map +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.map +1 -1
- package/dist/types/src/packlets/diagnostics/diagnostics.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
- 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 +2 -2
- package/dist/types/src/packlets/identity/identity-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts +1 -1
- package/dist/types/src/packlets/identity/identity-recovery-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity-service.d.ts.map +1 -1
- package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
- 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.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-state.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitation-topology.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/invitations-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/invitations/space-invitation-protocol.d.ts +1 -1
- 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/browser.d.ts.map +1 -1
- package/dist/types/src/packlets/locks/node.d.ts.map +1 -1
- package/dist/types/src/packlets/logging/logging-service.d.ts.map +1 -1
- package/dist/types/src/packlets/network/network-service.d.ts +3 -1
- package/dist/types/src/packlets/network/network-service.d.ts.map +1 -1
- package/dist/types/src/packlets/services/client-rpc-server.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-context.d.ts +1 -0
- package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
- package/dist/types/src/packlets/services/service-registry.d.ts.map +1 -1
- package/dist/types/src/packlets/services/util.d.ts.map +1 -1
- package/dist/types/src/packlets/space-export/space-archive-reader.d.ts +1 -1
- package/dist/types/src/packlets/space-export/space-archive-reader.d.ts.map +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.map +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts +1 -1
- package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/edge-feed-replicator.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/epoch-migrations.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/genesis.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
- package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
- package/dist/types/src/packlets/storage/level.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/storage/util.d.ts.map +1 -1
- package/dist/types/src/packlets/system/system-service.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/credential-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/invitation-utils.d.ts.map +1 -1
- package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/packlets/worker/worker-runtime.d.ts.map +1 -1
- 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 +39 -38
- package/src/packlets/agents/edge-agent-manager.ts +6 -6
- package/src/packlets/agents/edge-agent-service.ts +8 -11
- package/src/packlets/devices/devices-service.ts +5 -3
- package/src/packlets/identity/authenticator.ts +2 -2
- package/src/packlets/identity/default-space-state-machine.ts +1 -1
- package/src/packlets/identity/identity-manager.ts +13 -9
- package/src/packlets/identity/identity-recovery-manager.ts +6 -4
- package/src/packlets/identity/identity-service.ts +4 -4
- package/src/packlets/identity/identity.test.ts +9 -6
- package/src/packlets/identity/identity.ts +5 -5
- package/src/packlets/invitations/device-invitation-protocol.ts +1 -1
- package/src/packlets/invitations/edge-invitation-handler.ts +3 -3
- package/src/packlets/invitations/invitation-guest-extenstion.ts +3 -3
- package/src/packlets/invitations/invitation-host-extension.ts +5 -5
- package/src/packlets/invitations/invitation-topology.ts +1 -1
- package/src/packlets/invitations/invitations-handler.ts +2 -2
- package/src/packlets/invitations/invitations-manager.ts +15 -4
- package/src/packlets/invitations/space-invitation-protocol.ts +1 -1
- package/src/packlets/locks/browser.ts +4 -4
- package/src/packlets/locks/node.ts +2 -2
- package/src/packlets/logging/logging-service.ts +2 -2
- package/src/packlets/network/network-service.ts +11 -17
- package/src/packlets/services/client-rpc-server.ts +2 -2
- package/src/packlets/services/service-context.ts +10 -6
- package/src/packlets/services/service-host.ts +13 -5
- package/src/packlets/services/service-registry.ts +3 -3
- package/src/packlets/space-export/space-archive-reader.ts +2 -1
- package/src/packlets/space-export/space-archive-writer.ts +3 -3
- package/src/packlets/spaces/automerge-space-state.ts +3 -3
- package/src/packlets/spaces/data-space-manager.ts +47 -41
- package/src/packlets/spaces/data-space.ts +27 -20
- package/src/packlets/spaces/edge-feed-replicator.test.ts +2 -1
- package/src/packlets/spaces/edge-feed-replicator.ts +14 -13
- package/src/packlets/spaces/epoch-migrations.ts +3 -2
- package/src/packlets/spaces/notarization-plugin.test.ts +1 -1
- package/src/packlets/spaces/notarization-plugin.ts +18 -18
- package/src/packlets/spaces/spaces-service.ts +7 -6
- package/src/packlets/storage/profile-archive.ts +2 -1
- package/src/packlets/system/system-service.ts +2 -2
- package/src/packlets/testing/test-builder.ts +3 -3
- package/src/packlets/worker/worker-runtime.ts +4 -4
- package/src/packlets/worker/worker-session.ts +3 -3
- package/src/version.ts +5 -1
- package/dist/lib/browser/chunk-2TKMQ2UP.mjs.map +0 -7
- package/dist/lib/node/chunk-HUMVSL5Y.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-DQCPFIVI.mjs.map +0 -7
|
@@ -41,7 +41,7 @@ export class IdentityServiceImpl extends Resource implements IdentityService {
|
|
|
41
41
|
super();
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
protected override async _open() {
|
|
44
|
+
protected override async _open(): Promise<void> {
|
|
45
45
|
const identity = this._identityManager.identity;
|
|
46
46
|
if (identity && !identity.defaultSpaceId) {
|
|
47
47
|
await this._fixIdentityWithoutDefaultSpace(identity);
|
|
@@ -49,13 +49,13 @@ export class IdentityServiceImpl extends Resource implements IdentityService {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
async createIdentity(request: CreateIdentityRequest): Promise<IdentityProto> {
|
|
52
|
-
await this._createIdentity({
|
|
52
|
+
await this._createIdentity({ profile: request.profile, deviceProfile: request.deviceProfile });
|
|
53
53
|
const dataSpaceManager = this._dataSpaceManagerProvider();
|
|
54
54
|
await this._createDefaultSpace(dataSpaceManager);
|
|
55
55
|
return this._getIdentity()!;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
private async _createDefaultSpace(dataSpaceManager: DataSpaceManager) {
|
|
58
|
+
private async _createDefaultSpace(dataSpaceManager: DataSpaceManager): Promise<void> {
|
|
59
59
|
const space = await dataSpaceManager!.createDefaultSpace();
|
|
60
60
|
const identity = this._identityManager.identity;
|
|
61
61
|
invariant(identity);
|
|
@@ -141,7 +141,7 @@ export class IdentityServiceImpl extends Resource implements IdentityService {
|
|
|
141
141
|
});
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
private async _fixIdentityWithoutDefaultSpace(identity: Identity) {
|
|
144
|
+
private async _fixIdentityWithoutDefaultSpace(identity: Identity): Promise<void> {
|
|
145
145
|
let recodedDefaultSpace = false;
|
|
146
146
|
let foundDefaultSpace = false;
|
|
147
147
|
const dataSpaceManager = this._dataSpaceManagerProvider();
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { onTestFinished, describe, expect, test } from 'vitest';
|
|
6
6
|
|
|
7
|
+
import { Event } from '@dxos/async';
|
|
7
8
|
import { Context } from '@dxos/context';
|
|
8
9
|
import { createDidFromIdentityKey, CredentialGenerator, verifyCredential } from '@dxos/credentials';
|
|
9
10
|
import {
|
|
@@ -22,6 +23,7 @@ import { Keyring } from '@dxos/keyring';
|
|
|
22
23
|
import { type PublicKey } from '@dxos/keys';
|
|
23
24
|
import { MemorySignalManager, MemorySignalManagerContext } from '@dxos/messaging';
|
|
24
25
|
import { MemoryTransportFactory, SwarmNetworkManager } from '@dxos/network-manager';
|
|
26
|
+
import { EdgeStatus } from '@dxos/protocols/proto/dxos/client/services';
|
|
25
27
|
import { type FeedMessage } from '@dxos/protocols/proto/dxos/echo/feed';
|
|
26
28
|
import { AdmittedFeed } from '@dxos/protocols/proto/dxos/halo/credentials';
|
|
27
29
|
import { createStorage, StorageType } from '@dxos/random-access-storage';
|
|
@@ -107,21 +109,22 @@ describe('identity/identity', () => {
|
|
|
107
109
|
|
|
108
110
|
test('edge feed replicator', async () => {
|
|
109
111
|
let replicationStarted = false;
|
|
110
|
-
let
|
|
112
|
+
let status = EdgeStatus.NOT_CONNECTED;
|
|
111
113
|
const listeners: Array<() => void> = [];
|
|
112
114
|
const setup = await setupIdentity({
|
|
113
115
|
edgeConnection: {
|
|
116
|
+
statusChanged: new Event(),
|
|
117
|
+
get status() {
|
|
118
|
+
return status;
|
|
119
|
+
},
|
|
114
120
|
onReconnected: (listener) => {
|
|
115
|
-
if (
|
|
121
|
+
if (status === EdgeStatus.CONNECTED) {
|
|
116
122
|
listener();
|
|
117
123
|
} else {
|
|
118
124
|
listeners.push(listener);
|
|
119
125
|
}
|
|
120
126
|
return () => {};
|
|
121
127
|
},
|
|
122
|
-
get isConnected() {
|
|
123
|
-
return isConnected;
|
|
124
|
-
},
|
|
125
128
|
open: async () => {},
|
|
126
129
|
close: async () => {},
|
|
127
130
|
onMessage: (_: MessageListener): (() => void) => {
|
|
@@ -135,7 +138,7 @@ describe('identity/identity', () => {
|
|
|
135
138
|
|
|
136
139
|
await writeGenesisCredential(setup);
|
|
137
140
|
listeners.forEach((callback) => callback());
|
|
138
|
-
|
|
141
|
+
status = EdgeStatus.CONNECTED;
|
|
139
142
|
|
|
140
143
|
await expect.poll(() => replicationStarted).toBeTruthy();
|
|
141
144
|
});
|
|
@@ -116,7 +116,7 @@ export class Identity {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
@trace.span()
|
|
119
|
-
async open(ctx: Context) {
|
|
119
|
+
async open(ctx: Context): Promise<void> {
|
|
120
120
|
await this._presence?.open();
|
|
121
121
|
await this.space.spaceState.addCredentialProcessor(this._deviceStateMachine);
|
|
122
122
|
await this.space.spaceState.addCredentialProcessor(this._profileStateMachine);
|
|
@@ -127,13 +127,13 @@ export class Identity {
|
|
|
127
127
|
await this.space.open(ctx);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
public async joinNetwork() {
|
|
130
|
+
public async joinNetwork(): Promise<void> {
|
|
131
131
|
await this.space.startProtocol();
|
|
132
132
|
await this._edgeFeedReplicator?.open();
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
@trace.span()
|
|
136
|
-
async close(ctx: Context) {
|
|
136
|
+
async close(ctx: Context): Promise<void> {
|
|
137
137
|
await this._presence?.close();
|
|
138
138
|
await this.authVerifier.close();
|
|
139
139
|
await this.space.spaceState.removeCredentialProcessor(this._defaultSpaceStateMachine);
|
|
@@ -149,7 +149,7 @@ export class Identity {
|
|
|
149
149
|
await this.space.close();
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
async ready() {
|
|
152
|
+
async ready(): Promise<void> {
|
|
153
153
|
await this._deviceStateMachine.deviceChainReady.wait();
|
|
154
154
|
|
|
155
155
|
await this.controlPipeline.state.waitUntilReachedTargetTimeframe({ timeout: LOAD_CONTROL_FEEDS_TIMEOUT });
|
|
@@ -210,7 +210,7 @@ export class Identity {
|
|
|
210
210
|
return createCredentialSignerWithKey(this._signer, this.deviceKey);
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
async updateDefaultSpace(spaceId: SpaceId) {
|
|
213
|
+
async updateDefaultSpace(spaceId: SpaceId): Promise<void> {
|
|
214
214
|
const credential = await this.getDeviceCredentialSigner().createCredential({
|
|
215
215
|
subject: this.identityKey,
|
|
216
216
|
assertion: { '@type': 'dxos.halo.credentials.DefaultSpace', spaceId },
|
|
@@ -66,7 +66,7 @@ export class DeviceInvitationProtocol implements InvitationProtocol {
|
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
checkInvitation(invitation: Partial<Invitation>) {
|
|
69
|
+
checkInvitation(invitation: Partial<Invitation>): AlreadyJoinedError | undefined {
|
|
70
70
|
try {
|
|
71
71
|
const identity = this._getIdentity();
|
|
72
72
|
if (identity) {
|
|
@@ -61,7 +61,7 @@ export class EdgeInvitationHandler implements FlowLockHolder {
|
|
|
61
61
|
guardedState: GuardedInvitationState,
|
|
62
62
|
protocol: InvitationProtocol,
|
|
63
63
|
deviceProfile?: DeviceProfileDocument,
|
|
64
|
-
) {
|
|
64
|
+
): void {
|
|
65
65
|
if (!this._client) {
|
|
66
66
|
log('edge disabled');
|
|
67
67
|
return;
|
|
@@ -118,7 +118,7 @@ export class EdgeInvitationHandler implements FlowLockHolder {
|
|
|
118
118
|
guardedState: GuardedInvitationState,
|
|
119
119
|
admissionRequest: SpaceAdmissionRequest,
|
|
120
120
|
spaceId: SpaceId,
|
|
121
|
-
) {
|
|
121
|
+
): Promise<void> {
|
|
122
122
|
try {
|
|
123
123
|
log('edge invitation flow');
|
|
124
124
|
this._flowLock = await tryAcquireBeforeContextDisposed(ctx, guardedState.mutex);
|
|
@@ -182,7 +182,7 @@ export class EdgeInvitationHandler implements FlowLockHolder {
|
|
|
182
182
|
return this._flowLock != null;
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
private _calculateNextRetryMs() {
|
|
185
|
+
private _calculateNextRetryMs(): number {
|
|
186
186
|
return this._retryInterval + Math.random() * this._retryJitter;
|
|
187
187
|
}
|
|
188
188
|
}
|
|
@@ -82,7 +82,7 @@ export class InvitationGuestExtension
|
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
override async onOpen(context: ExtensionContext) {
|
|
85
|
+
override async onOpen(context: ExtensionContext): Promise<void> {
|
|
86
86
|
await super.onOpen(context);
|
|
87
87
|
|
|
88
88
|
try {
|
|
@@ -115,7 +115,7 @@ export class InvitationGuestExtension
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
override async onClose() {
|
|
118
|
+
override async onClose(): Promise<void> {
|
|
119
119
|
await this._destroy();
|
|
120
120
|
}
|
|
121
121
|
|
|
@@ -123,7 +123,7 @@ export class InvitationGuestExtension
|
|
|
123
123
|
await this._destroy();
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
private async _destroy() {
|
|
126
|
+
private async _destroy(): Promise<void> {
|
|
127
127
|
await this._ctx.dispose();
|
|
128
128
|
if (this._invitationFlowLock != null) {
|
|
129
129
|
this._invitationFlowLock.release();
|
|
@@ -232,7 +232,7 @@ export class InvitationHostExtension
|
|
|
232
232
|
};
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
-
override async onOpen(context: ExtensionContext) {
|
|
235
|
+
override async onOpen(context: ExtensionContext): Promise<void> {
|
|
236
236
|
await super.onOpen(context);
|
|
237
237
|
|
|
238
238
|
try {
|
|
@@ -272,7 +272,7 @@ export class InvitationHostExtension
|
|
|
272
272
|
return invitation;
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
-
private _assertInvitationState(stateOrMany: Invitation.State | Invitation.State[]) {
|
|
275
|
+
private _assertInvitationState(stateOrMany: Invitation.State | Invitation.State[]): void {
|
|
276
276
|
const invitation = this._requireActiveInvitation();
|
|
277
277
|
const validStates = Array.isArray(stateOrMany) ? stateOrMany : [stateOrMany];
|
|
278
278
|
if (!validStates.includes(invitation.state)) {
|
|
@@ -283,15 +283,15 @@ export class InvitationHostExtension
|
|
|
283
283
|
}
|
|
284
284
|
}
|
|
285
285
|
|
|
286
|
-
override async onClose() {
|
|
286
|
+
override async onClose(): Promise<void> {
|
|
287
287
|
await this._destroy();
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
-
override async onAbort() {
|
|
290
|
+
override async onAbort(): Promise<void> {
|
|
291
291
|
await this._destroy();
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
private async _destroy() {
|
|
294
|
+
private async _destroy(): Promise<void> {
|
|
295
295
|
await this._ctx.dispose();
|
|
296
296
|
if (this._invitationFlowLock != null) {
|
|
297
297
|
this._invitationFlowLock?.release();
|
|
@@ -453,7 +453,7 @@ export class InvitationsHandler {
|
|
|
453
453
|
setState: (newState: Invitation.State) => void,
|
|
454
454
|
authenticated: Trigger<string>,
|
|
455
455
|
options: { timeout: number },
|
|
456
|
-
) {
|
|
456
|
+
): Promise<void> {
|
|
457
457
|
for (let attempt = 1; attempt <= MAX_OTP_ATTEMPTS; attempt++) {
|
|
458
458
|
log('guest waiting for authentication code...');
|
|
459
459
|
setState(Invitation.State.READY_FOR_AUTHENTICATION);
|
|
@@ -482,7 +482,7 @@ export class InvitationsHandler {
|
|
|
482
482
|
setState: (newState: Invitation.State) => void,
|
|
483
483
|
invitation: Invitation,
|
|
484
484
|
introductionResponse: IntroductionResponse,
|
|
485
|
-
) {
|
|
485
|
+
): Promise<void> {
|
|
486
486
|
if (invitation.guestKeypair?.privateKey == null) {
|
|
487
487
|
throw new Error('keypair missing in the invitation');
|
|
488
488
|
}
|
|
@@ -182,7 +182,7 @@ export class InvitationsManager {
|
|
|
182
182
|
return [...this._acceptInvitations.values()].map((i) => i.get());
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
onPersistentInvitationsLoaded(ctx: Context, callback: () => void) {
|
|
185
|
+
onPersistentInvitationsLoaded(ctx: Context, callback: () => void): void {
|
|
186
186
|
if (this._persistentInvitationsLoaded) {
|
|
187
187
|
callback();
|
|
188
188
|
} else {
|
|
@@ -231,7 +231,10 @@ export class InvitationsManager {
|
|
|
231
231
|
} satisfies Invitation;
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
private _createObservableInvitation(
|
|
234
|
+
private _createObservableInvitation(
|
|
235
|
+
handler: InvitationProtocol,
|
|
236
|
+
invitation: Invitation,
|
|
237
|
+
): { ctx: Context; stream: PushStream<Invitation>; observableInvitation: CancellableInvitation } {
|
|
235
238
|
const stream = new PushStream<Invitation>();
|
|
236
239
|
const ctx = new Context({
|
|
237
240
|
onError: (err) => {
|
|
@@ -254,7 +257,15 @@ export class InvitationsManager {
|
|
|
254
257
|
return { ctx, stream, observableInvitation };
|
|
255
258
|
}
|
|
256
259
|
|
|
257
|
-
private _createObservableAcceptingInvitation(
|
|
260
|
+
private _createObservableAcceptingInvitation(
|
|
261
|
+
handler: InvitationProtocol,
|
|
262
|
+
initialState: Invitation,
|
|
263
|
+
): {
|
|
264
|
+
ctx: Context;
|
|
265
|
+
invitation: AuthenticatingInvitation;
|
|
266
|
+
stream: PushStream<Invitation>;
|
|
267
|
+
otpEnteredTrigger: Trigger<string>;
|
|
268
|
+
} {
|
|
258
269
|
const otpEnteredTrigger = new Trigger<string>();
|
|
259
270
|
const stream = new PushStream<Invitation>();
|
|
260
271
|
const ctx = new Context({
|
|
@@ -310,7 +321,7 @@ export class InvitationsManager {
|
|
|
310
321
|
}
|
|
311
322
|
}
|
|
312
323
|
|
|
313
|
-
private _onInvitationComplete(invitation: CancellableInvitation, callback: () => void) {
|
|
324
|
+
private _onInvitationComplete(invitation: CancellableInvitation, callback: () => void): void {
|
|
314
325
|
invitation.subscribe(
|
|
315
326
|
() => {},
|
|
316
327
|
() => {},
|
|
@@ -145,7 +145,7 @@ export class SpaceInvitationProtocol implements InvitationProtocol {
|
|
|
145
145
|
await writeMessages(space.inner.controlPipeline.writer, [credential]);
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
checkInvitation(invitation: Partial<Invitation>) {
|
|
148
|
+
checkInvitation(invitation: Partial<Invitation>): InvalidInvitationError | AlreadyJoinedError | undefined {
|
|
149
149
|
if (invitation.spaceKey == null) {
|
|
150
150
|
return new InvalidInvitationError('No spaceKey was provided for a space invitation.');
|
|
151
151
|
}
|
|
@@ -33,7 +33,7 @@ export class Lock implements ResourceLock {
|
|
|
33
33
|
return this._lockKey;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
async acquire() {
|
|
36
|
+
async acquire(): Promise<void> {
|
|
37
37
|
this._broadcastChannel.postMessage({
|
|
38
38
|
message: Message.ACQUIRING,
|
|
39
39
|
});
|
|
@@ -49,17 +49,17 @@ export class Lock implements ResourceLock {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
async release() {
|
|
52
|
+
async release(): Promise<void> {
|
|
53
53
|
this._releaseTrigger.wake();
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
private _onMessage(event: MessageEvent<any>) {
|
|
56
|
+
private _onMessage(event: MessageEvent<any>): void {
|
|
57
57
|
if (event.data.message === Message.ACQUIRING) {
|
|
58
58
|
this._releaseTrigger.wake();
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
private async _requestLock(steal = false) {
|
|
62
|
+
private async _requestLock(steal = false): Promise<void> {
|
|
63
63
|
log('requesting lock...', { steal });
|
|
64
64
|
const acquired = new Trigger();
|
|
65
65
|
|
|
@@ -28,7 +28,7 @@ export class Lock implements ResourceLock {
|
|
|
28
28
|
return this._lockPath;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
async acquire() {
|
|
31
|
+
async acquire(): Promise<void> {
|
|
32
32
|
log('acquiring lock...');
|
|
33
33
|
this._fileHandle = await LockFile.acquire(this._lockPath);
|
|
34
34
|
|
|
@@ -37,7 +37,7 @@ export class Lock implements ResourceLock {
|
|
|
37
37
|
log('acquired lock');
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
async release() {
|
|
40
|
+
async release(): Promise<void> {
|
|
41
41
|
await this._onRelease?.();
|
|
42
42
|
invariant(this._fileHandle, 'Lock is not acquired');
|
|
43
43
|
await LockFile.release(this._fileHandle);
|
|
@@ -32,11 +32,11 @@ export class LoggingServiceImpl implements LoggingService {
|
|
|
32
32
|
private readonly _started = Date.now();
|
|
33
33
|
private readonly _sessionId = PublicKey.random().toHex();
|
|
34
34
|
|
|
35
|
-
async open() {
|
|
35
|
+
async open(): Promise<void> {
|
|
36
36
|
log.runtimeConfig.processors.push(this._logProcessor);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
async close() {
|
|
39
|
+
async close(): Promise<void> {
|
|
40
40
|
const index = log.runtimeConfig.processors.findIndex((processor) => processor === this._logProcessor);
|
|
41
41
|
log.runtimeConfig.processors.splice(index, 1);
|
|
42
42
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Stream } from '@dxos/codec-protobuf/stream';
|
|
6
|
+
import { type EdgeConnection } from '@dxos/edge-client';
|
|
6
7
|
import { type SignalManager } from '@dxos/messaging';
|
|
7
8
|
import { type SwarmNetworkManager } from '@dxos/network-manager';
|
|
8
9
|
import {
|
|
@@ -23,10 +24,11 @@ export class NetworkServiceImpl implements NetworkService {
|
|
|
23
24
|
constructor(
|
|
24
25
|
private readonly networkManager: SwarmNetworkManager,
|
|
25
26
|
private readonly signalManager: SignalManager,
|
|
27
|
+
private readonly edgeConnection?: EdgeConnection,
|
|
26
28
|
) {}
|
|
27
29
|
|
|
28
|
-
queryStatus() {
|
|
29
|
-
return new Stream<NetworkStatus>(({ next }) => {
|
|
30
|
+
queryStatus(): Stream<NetworkStatus> {
|
|
31
|
+
return new Stream<NetworkStatus>(({ ctx, next }) => {
|
|
30
32
|
const update = () => {
|
|
31
33
|
next({
|
|
32
34
|
swarm: this.networkManager.connectionState,
|
|
@@ -35,18 +37,13 @@ export class NetworkServiceImpl implements NetworkService {
|
|
|
35
37
|
});
|
|
36
38
|
};
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
this.networkManager.connectionStateChanged.on(ctx, () => update());
|
|
41
|
+
this.signalManager.statusChanged?.on(ctx, () => update());
|
|
40
42
|
update();
|
|
41
|
-
|
|
42
|
-
return () => {
|
|
43
|
-
unsubscribeSwarm();
|
|
44
|
-
unsubscribeSignal?.();
|
|
45
|
-
};
|
|
46
43
|
});
|
|
47
44
|
}
|
|
48
45
|
|
|
49
|
-
async updateConfig(request: UpdateConfigRequest) {
|
|
46
|
+
async updateConfig(request: UpdateConfigRequest): Promise<void> {
|
|
50
47
|
await this.networkManager.setConnectionState(request.swarm);
|
|
51
48
|
}
|
|
52
49
|
|
|
@@ -63,13 +60,12 @@ export class NetworkServiceImpl implements NetworkService {
|
|
|
63
60
|
}
|
|
64
61
|
|
|
65
62
|
subscribeSwarmState(request: SubscribeSwarmStateRequest): Stream<SwarmResponse> {
|
|
66
|
-
return new Stream<SwarmResponse>(({ next }) => {
|
|
67
|
-
|
|
63
|
+
return new Stream<SwarmResponse>(({ ctx, next }) => {
|
|
64
|
+
this.signalManager.swarmState?.on(ctx, (state) => {
|
|
68
65
|
if (request.topic.equals(state.swarmKey)) {
|
|
69
66
|
next(state);
|
|
70
67
|
}
|
|
71
68
|
});
|
|
72
|
-
return unsubscribe;
|
|
73
69
|
});
|
|
74
70
|
}
|
|
75
71
|
|
|
@@ -78,14 +74,12 @@ export class NetworkServiceImpl implements NetworkService {
|
|
|
78
74
|
}
|
|
79
75
|
|
|
80
76
|
subscribeMessages(peer: Peer): Stream<Message> {
|
|
81
|
-
return new Stream<Message>(({ next }) => {
|
|
82
|
-
|
|
77
|
+
return new Stream<Message>(({ ctx, next }) => {
|
|
78
|
+
this.signalManager.onMessage.on(ctx, (message) => {
|
|
83
79
|
if (message.recipient.peerKey === peer.peerKey) {
|
|
84
80
|
next(message);
|
|
85
81
|
}
|
|
86
82
|
});
|
|
87
|
-
|
|
88
|
-
return unsubscribe;
|
|
89
83
|
});
|
|
90
84
|
}
|
|
91
85
|
}
|
|
@@ -59,6 +59,7 @@ export type ServiceContextRuntimeParams = Pick<
|
|
|
59
59
|
DataSpaceManagerRuntimeParams & {
|
|
60
60
|
invitationConnectionDefaultParams?: InvitationConnectionParams;
|
|
61
61
|
disableP2pReplication?: boolean;
|
|
62
|
+
enableVectorIndexing?: boolean;
|
|
62
63
|
};
|
|
63
64
|
/**
|
|
64
65
|
* Shared backend for all client services.
|
|
@@ -155,6 +156,9 @@ export class ServiceContext extends Resource {
|
|
|
155
156
|
kv: this.level,
|
|
156
157
|
peerIdProvider: () => this.identityManager.identity?.deviceKey?.toHex(),
|
|
157
158
|
getSpaceKeyByRootDocumentId: (documentId) => this.spaceManager.findSpaceByRootDocumentId(documentId)?.key,
|
|
159
|
+
indexing: {
|
|
160
|
+
vector: this._runtimeParams?.enableVectorIndexing,
|
|
161
|
+
},
|
|
158
162
|
});
|
|
159
163
|
|
|
160
164
|
this._meshReplicator = new MeshEchoReplicator();
|
|
@@ -193,7 +197,7 @@ export class ServiceContext extends Resource {
|
|
|
193
197
|
}
|
|
194
198
|
|
|
195
199
|
@Trace.span()
|
|
196
|
-
protected override async _open(ctx: Context) {
|
|
200
|
+
protected override async _open(ctx: Context): Promise<void> {
|
|
197
201
|
await this._checkStorageVersion();
|
|
198
202
|
|
|
199
203
|
log('opening...');
|
|
@@ -231,7 +235,7 @@ export class ServiceContext extends Resource {
|
|
|
231
235
|
log('opened');
|
|
232
236
|
}
|
|
233
237
|
|
|
234
|
-
protected override async _close(ctx: Context) {
|
|
238
|
+
protected override async _close(ctx: Context): Promise<void> {
|
|
235
239
|
log('closing...');
|
|
236
240
|
if (this._deviceSpaceSync && this.identityManager.identity) {
|
|
237
241
|
await this.identityManager.identity.space.spaceState.removeCredentialProcessor(this._deviceSpaceSync);
|
|
@@ -268,7 +272,7 @@ export class ServiceContext extends Resource {
|
|
|
268
272
|
return factory(invitation);
|
|
269
273
|
}
|
|
270
274
|
|
|
271
|
-
async broadcastProfileUpdate(profile: ProfileDocument | undefined) {
|
|
275
|
+
async broadcastProfileUpdate(profile: ProfileDocument | undefined): Promise<void> {
|
|
272
276
|
if (!profile || !this.dataSpaceManager) {
|
|
273
277
|
return;
|
|
274
278
|
}
|
|
@@ -287,7 +291,7 @@ export class ServiceContext extends Resource {
|
|
|
287
291
|
return identity;
|
|
288
292
|
}
|
|
289
293
|
|
|
290
|
-
private async _checkStorageVersion() {
|
|
294
|
+
private async _checkStorageVersion(): Promise<void> {
|
|
291
295
|
await this.metadataStore.load();
|
|
292
296
|
if (this.metadataStore.version !== STORAGE_VERSION) {
|
|
293
297
|
throw new InvalidStorageVersionError(STORAGE_VERSION, this.metadataStore.version);
|
|
@@ -297,7 +301,7 @@ export class ServiceContext extends Resource {
|
|
|
297
301
|
|
|
298
302
|
// Called when identity is created.
|
|
299
303
|
@Trace.span()
|
|
300
|
-
private async _initialize(ctx: Context) {
|
|
304
|
+
private async _initialize(ctx: Context): Promise<void> {
|
|
301
305
|
log('initializing spaces...');
|
|
302
306
|
const identity = this.identityManager.identity ?? failUndefined();
|
|
303
307
|
const signingContext: SigningContext = {
|
|
@@ -375,7 +379,7 @@ export class ServiceContext extends Resource {
|
|
|
375
379
|
await identity.space.spaceState.addCredentialProcessor(this._deviceSpaceSync);
|
|
376
380
|
}
|
|
377
381
|
|
|
378
|
-
private async _setNetworkIdentity(params?: { deviceCredential: Credential }) {
|
|
382
|
+
private async _setNetworkIdentity(params?: { deviceCredential: Credential }): Promise<void> {
|
|
379
383
|
using _ = await this._edgeIdentityUpdateMutex.acquire();
|
|
380
384
|
|
|
381
385
|
let edgeIdentity: EdgeIdentity;
|
|
@@ -125,6 +125,10 @@ export class ClientServicesHost {
|
|
|
125
125
|
this._runtimeParams.disableP2pReplication = config?.get('runtime.client.disableP2pReplication', false);
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
if (this._runtimeParams.enableVectorIndexing === undefined) {
|
|
129
|
+
this._runtimeParams.enableVectorIndexing = config?.get('runtime.client.enableVectorIndexing', false);
|
|
130
|
+
}
|
|
131
|
+
|
|
128
132
|
if (config) {
|
|
129
133
|
this.initialize({ config, transportFactory, signalManager });
|
|
130
134
|
}
|
|
@@ -199,7 +203,7 @@ export class ClientServicesHost {
|
|
|
199
203
|
* Config can also be provided in the constructor.
|
|
200
204
|
* Can only be called once.
|
|
201
205
|
*/
|
|
202
|
-
initialize({ config, ...options }: InitializeOptions) {
|
|
206
|
+
initialize({ config, ...options }: InitializeOptions): void {
|
|
203
207
|
invariant(!this._open, 'service host is open');
|
|
204
208
|
log('initializing...');
|
|
205
209
|
|
|
@@ -252,7 +256,7 @@ export class ClientServicesHost {
|
|
|
252
256
|
|
|
253
257
|
@synchronized
|
|
254
258
|
@Trace.span()
|
|
255
|
-
async open(ctx: Context) {
|
|
259
|
+
async open(ctx: Context): Promise<void> {
|
|
256
260
|
if (this._open) {
|
|
257
261
|
return;
|
|
258
262
|
}
|
|
@@ -329,7 +333,11 @@ export class ClientServicesHost {
|
|
|
329
333
|
DataService: this._serviceContext.echoHost.dataService,
|
|
330
334
|
QueryService: this._serviceContext.echoHost.queryService,
|
|
331
335
|
|
|
332
|
-
NetworkService: new NetworkServiceImpl(
|
|
336
|
+
NetworkService: new NetworkServiceImpl(
|
|
337
|
+
this._serviceContext.networkManager,
|
|
338
|
+
this._serviceContext.signalManager,
|
|
339
|
+
this._edgeConnection,
|
|
340
|
+
),
|
|
333
341
|
|
|
334
342
|
LoggingService: this._loggingService,
|
|
335
343
|
TracingService: this._tracingService,
|
|
@@ -369,7 +377,7 @@ export class ClientServicesHost {
|
|
|
369
377
|
|
|
370
378
|
@synchronized
|
|
371
379
|
@Trace.span()
|
|
372
|
-
async close() {
|
|
380
|
+
async close(): Promise<void> {
|
|
373
381
|
if (!this._open) {
|
|
374
382
|
return;
|
|
375
383
|
}
|
|
@@ -387,7 +395,7 @@ export class ClientServicesHost {
|
|
|
387
395
|
log('closed', { deviceKey });
|
|
388
396
|
}
|
|
389
397
|
|
|
390
|
-
async reset() {
|
|
398
|
+
async reset(): Promise<void> {
|
|
391
399
|
const traceId = PublicKey.random().toHex();
|
|
392
400
|
log.trace('dxos.sdk.client-services-host.reset', trace.begin({ id: traceId }));
|
|
393
401
|
|
|
@@ -22,15 +22,15 @@ export class ServiceRegistry<Services> {
|
|
|
22
22
|
return this._handlers;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
setServices(services: Partial<Services>) {
|
|
25
|
+
setServices(services: Partial<Services>): void {
|
|
26
26
|
this._handlers = services;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
addService(name: keyof Services, service: Services[keyof Services]) {
|
|
29
|
+
addService(name: keyof Services, service: Services[keyof Services]): void {
|
|
30
30
|
this._handlers[name] = service;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
removeService(name: keyof Services) {
|
|
33
|
+
removeService(name: keyof Services): void {
|
|
34
34
|
delete this._handlers[name];
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import type { DocumentId } from '@
|
|
5
|
+
import type { DocumentId } from '@automerge/automerge-repo';
|
|
6
|
+
|
|
6
7
|
import { assertArgument, failedInvariant, invariant } from '@dxos/invariant';
|
|
7
8
|
import { log } from '@dxos/log';
|
|
8
9
|
import { SpaceArchiveFileStructure, type SpaceArchiveMetadata } from '@dxos/protocols';
|
|
@@ -36,21 +36,21 @@ export class SpaceArchiveWriter extends Resource {
|
|
|
36
36
|
return Promise.resolve();
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
async begin(meta: SpaceArchiveBeginProps) {
|
|
39
|
+
async begin(meta: SpaceArchiveBeginProps): Promise<void> {
|
|
40
40
|
assertState(this._tar, 'Not open');
|
|
41
41
|
assertState(!this._meta, 'Already started');
|
|
42
42
|
this._meta = meta;
|
|
43
43
|
this._archive = new this._tar.Archive();
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
async setCurrentRootUrl(url: string) {
|
|
46
|
+
async setCurrentRootUrl(url: string): Promise<void> {
|
|
47
47
|
assertArgument(url.startsWith('automerge:'), 'Invalid root URL');
|
|
48
48
|
assertState(this._tar, 'Not open');
|
|
49
49
|
assertState(this._meta, 'Not started');
|
|
50
50
|
this._currentRootUrl = url;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
async writeDocument(documentId: string, data: Uint8Array) {
|
|
53
|
+
async writeDocument(documentId: string, data: Uint8Array): Promise<void> {
|
|
54
54
|
assertArgument(!documentId.startsWith('automerge:'), 'Invalid document ID');
|
|
55
55
|
assertState(this._archive, 'Not open');
|
|
56
56
|
this._archive.addBinaryFile(`${SpaceArchiveFileStructure.documents}/${documentId}.bin`, data);
|