@dxos/client-services 0.1.53 → 0.1.54-main.270ec56

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.
Files changed (69) hide show
  1. package/dist/lib/browser/{chunk-6ITWCQIT.mjs → chunk-F4BHRFH4.mjs} +861 -702
  2. package/dist/lib/browser/chunk-F4BHRFH4.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +115 -173
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/packlets/testing/index.mjs +24 -7
  7. package/dist/lib/browser/packlets/testing/index.mjs.map +3 -3
  8. package/dist/lib/node/index.cjs +951 -853
  9. package/dist/lib/node/index.cjs.map +4 -4
  10. package/dist/lib/node/meta.json +1 -1
  11. package/dist/lib/node/packlets/testing/index.cjs +832 -708
  12. package/dist/lib/node/packlets/testing/index.cjs.map +4 -4
  13. package/dist/types/src/packlets/identity/authenticator.d.ts.map +1 -1
  14. package/dist/types/src/packlets/identity/identity.d.ts.map +1 -1
  15. package/dist/types/src/packlets/services/index.d.ts +1 -0
  16. package/dist/types/src/packlets/services/index.d.ts.map +1 -1
  17. package/dist/types/src/packlets/services/service-context.d.ts.map +1 -1
  18. package/dist/types/src/packlets/services/service-host.d.ts +7 -1
  19. package/dist/types/src/packlets/services/service-host.d.ts.map +1 -1
  20. package/dist/types/src/packlets/spaces/data-space-manager.d.ts.map +1 -1
  21. package/dist/types/src/packlets/spaces/data-space.d.ts +11 -2
  22. package/dist/types/src/packlets/spaces/data-space.d.ts.map +1 -1
  23. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts +2 -1
  24. package/dist/types/src/packlets/spaces/notarization-plugin.d.ts.map +1 -1
  25. package/dist/types/src/packlets/spaces/spaces-service.d.ts +1 -1
  26. package/dist/types/src/packlets/spaces/spaces-service.d.ts.map +1 -1
  27. package/dist/types/src/packlets/testing/test-builder.d.ts +7 -1
  28. package/dist/types/src/packlets/testing/test-builder.d.ts.map +1 -1
  29. package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts +1 -1
  30. package/dist/types/src/packlets/vault/iframe-host-runtime.d.ts.map +1 -1
  31. package/dist/types/src/packlets/vault/iframe-proxy-runtime.d.ts +1 -1
  32. package/dist/types/src/packlets/vault/iframe-proxy-runtime.d.ts.map +1 -1
  33. package/dist/types/src/packlets/vault/shell-runtime.d.ts +1 -21
  34. package/dist/types/src/packlets/vault/shell-runtime.d.ts.map +1 -1
  35. package/dist/types/src/packlets/vault/worker-session.d.ts.map +1 -1
  36. package/package.json +33 -32
  37. package/src/packlets/identity/authenticator.ts +4 -2
  38. package/src/packlets/identity/identity-manager.test.ts +1 -1
  39. package/src/packlets/identity/identity-manager.ts +8 -8
  40. package/src/packlets/identity/identity-service.ts +2 -2
  41. package/src/packlets/identity/identity.test.ts +1 -1
  42. package/src/packlets/identity/identity.ts +22 -27
  43. package/src/packlets/invitations/device-invitation-protocol.ts +4 -4
  44. package/src/packlets/invitations/invitation-extension.ts +5 -5
  45. package/src/packlets/invitations/invitations-handler.ts +6 -6
  46. package/src/packlets/invitations/invitations-service.ts +3 -3
  47. package/src/packlets/invitations/space-invitation-protocol.ts +9 -9
  48. package/src/packlets/locks/node.ts +2 -2
  49. package/src/packlets/logging/logging-service.ts +4 -4
  50. package/src/packlets/services/index.ts +1 -0
  51. package/src/packlets/services/service-context.test.ts +1 -1
  52. package/src/packlets/services/service-context.ts +12 -10
  53. package/src/packlets/services/service-host.test.ts +50 -2
  54. package/src/packlets/services/service-host.ts +25 -9
  55. package/src/packlets/spaces/data-space-manager.test.ts +75 -119
  56. package/src/packlets/spaces/data-space-manager.ts +18 -9
  57. package/src/packlets/spaces/data-space.ts +66 -20
  58. package/src/packlets/spaces/notarization-plugin.test.ts +1 -1
  59. package/src/packlets/spaces/notarization-plugin.ts +9 -5
  60. package/src/packlets/spaces/spaces-service.test.ts +5 -3
  61. package/src/packlets/spaces/spaces-service.ts +26 -8
  62. package/src/packlets/testing/invitation-utils.ts +2 -2
  63. package/src/packlets/testing/test-builder.ts +36 -4
  64. package/src/packlets/vault/iframe-host-runtime.ts +2 -2
  65. package/src/packlets/vault/iframe-proxy-runtime.ts +2 -2
  66. package/src/packlets/vault/shell-runtime.ts +3 -49
  67. package/src/packlets/vault/worker-runtime.ts +1 -1
  68. package/src/packlets/vault/worker-session.ts +7 -6
  69. package/dist/lib/browser/chunk-6ITWCQIT.mjs.map +0 -7
@@ -4,8 +4,10 @@
4
4
 
5
5
  import { EventSubscriptions, UpdateScheduler, scheduleTask } from '@dxos/async';
6
6
  import { Stream } from '@dxos/codec-protobuf';
7
- import { raise, todo } from '@dxos/debug';
7
+ import { CredentialProcessor } from '@dxos/credentials';
8
+ import { raise } from '@dxos/debug';
8
9
  import { DataServiceSubscriptions, SpaceManager, SpaceNotFoundError } from '@dxos/echo-pipeline';
10
+ import { ApiError } from '@dxos/errors';
9
11
  import { log } from '@dxos/log';
10
12
  import { encodeError } from '@dxos/protocols';
11
13
  import {
@@ -15,6 +17,7 @@ import {
15
17
  QuerySpacesResponse,
16
18
  Space,
17
19
  SpaceMember,
20
+ SpaceState,
18
21
  SpacesService,
19
22
  SubscribeMessagesRequest,
20
23
  UpdateSpaceRequest,
@@ -46,8 +49,23 @@ export class SpacesServiceImpl implements SpacesService {
46
49
  return this._serializeSpace(space);
47
50
  }
48
51
 
49
- async updateSpace(request: UpdateSpaceRequest) {
50
- todo();
52
+ async updateSpace({ spaceKey, state }: UpdateSpaceRequest) {
53
+ const dataSpaceManager = await this._getDataSpaceManager();
54
+ const space = dataSpaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));
55
+
56
+ if (state) {
57
+ switch (state) {
58
+ case SpaceState.ACTIVE:
59
+ await space.activate();
60
+ break;
61
+
62
+ case SpaceState.INACTIVE:
63
+ await space.deactivate();
64
+ break;
65
+ default:
66
+ throw new ApiError('Invalid space state');
67
+ }
68
+ }
51
69
  }
52
70
 
53
71
  querySpaces(): Stream<QuerySpacesResponse> {
@@ -124,13 +142,13 @@ export class SpacesServiceImpl implements SpacesService {
124
142
  return new Stream(({ ctx, next }) => {
125
143
  const space = this._spaceManager.spaces.get(spaceKey) ?? raise(new SpaceNotFoundError(spaceKey));
126
144
 
127
- const processor = space.spaceState.registerProcessor({
128
- process: async (credential) => {
145
+ const processor: CredentialProcessor = {
146
+ processCredential: async (credential) => {
129
147
  next(credential);
130
148
  },
131
- });
132
- ctx.onDispose(() => processor.close());
133
- scheduleTask(ctx, () => processor.open());
149
+ };
150
+ ctx.onDispose(() => space.spaceState.removeCredentialProcessor(processor));
151
+ scheduleTask(ctx, () => space.spaceState.addCredentialProcessor(processor));
134
152
  });
135
153
  }
136
154
 
@@ -2,7 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import assert from 'node:assert';
5
+ import invariant from 'tiny-invariant';
6
6
 
7
7
  import { Trigger } from '@dxos/async';
8
8
  import { AuthenticatingInvitationObservable, CancellableInvitationObservable } from '@dxos/client-protocol';
@@ -82,7 +82,7 @@ export const performInvitation = ({
82
82
  if (hooks?.guest?.onConnecting?.(guestObservable)) {
83
83
  break;
84
84
  }
85
- assert(hostInvitation.swarmKey!.equals(guestInvitation.swarmKey!));
85
+ invariant(hostInvitation.swarmKey!.equals(guestInvitation.swarmKey!));
86
86
  break;
87
87
  }
88
88
 
@@ -2,11 +2,18 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import { createDefaultModelFactory } from '@dxos/client-protocol';
6
5
  import { Config } from '@dxos/config';
7
6
  import { Context } from '@dxos/context';
8
7
  import { createCredentialSignerWithChain, CredentialGenerator } from '@dxos/credentials';
9
- import { SnapshotStore, DataPipeline, MetadataStore, SpaceManager, valueEncoding } from '@dxos/echo-pipeline';
8
+ import { failUndefined } from '@dxos/debug';
9
+ import {
10
+ SnapshotStore,
11
+ DataPipeline,
12
+ MetadataStore,
13
+ SpaceManager,
14
+ valueEncoding,
15
+ DataServiceSubscriptions,
16
+ } from '@dxos/echo-pipeline';
10
17
  import { testLocalDatabase } from '@dxos/echo-pipeline/testing';
11
18
  import { FeedFactory, FeedStore } from '@dxos/feed-store';
12
19
  import { Keyring } from '@dxos/keyring';
@@ -15,8 +22,8 @@ import { MemoryTransportFactory, NetworkManager } from '@dxos/network-manager';
15
22
  import { createStorage, Storage, StorageType } from '@dxos/random-access-storage';
16
23
  import { BlobStore } from '@dxos/teleport-extension-object-sync';
17
24
 
18
- import { ClientServicesHost, ServiceContext } from '../services';
19
- import { SigningContext } from '../spaces';
25
+ import { ClientServicesHost, createDefaultModelFactory, ServiceContext } from '../services';
26
+ import { DataSpaceManager, SigningContext } from '../spaces';
20
27
 
21
28
  //
22
29
  // TODO(burdon): Replace with test builder.
@@ -97,7 +104,9 @@ export type TestPeerProps = {
97
104
  keyring?: Keyring;
98
105
  networkManager?: NetworkManager;
99
106
  spaceManager?: SpaceManager;
107
+ dataSpaceManager?: DataSpaceManager;
100
108
  snapshotStore?: SnapshotStore;
109
+ signingContext?: SigningContext;
101
110
  blobStore?: BlobStore;
102
111
  };
103
112
 
@@ -109,6 +118,10 @@ export class TestPeer {
109
118
  private readonly opts: TestPeerOpts = { storageType: StorageType.RAM },
110
119
  ) {}
111
120
 
121
+ get props() {
122
+ return this._props;
123
+ }
124
+
112
125
  get storage() {
113
126
  return (this._props.storage ??= createStorage({ type: this.opts.storageType }));
114
127
  }
@@ -159,6 +172,25 @@ export class TestPeer {
159
172
  }));
160
173
  }
161
174
 
175
+ get identity() {
176
+ return this._props.signingContext ?? failUndefined();
177
+ }
178
+
179
+ get dataSpaceManager() {
180
+ return (this._props.dataSpaceManager ??= new DataSpaceManager(
181
+ this.spaceManager,
182
+ this.metadataStore,
183
+ new DataServiceSubscriptions(),
184
+ this.keyring,
185
+ this.identity,
186
+ this.feedStore,
187
+ ));
188
+ }
189
+
190
+ async createIdentity() {
191
+ this._props.signingContext ??= await createSigningContext(this.keyring);
192
+ }
193
+
162
194
  async destroy() {
163
195
  await this.storage.reset();
164
196
  }
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { Trigger } from '@dxos/async';
6
- import { PROXY_CONNECTION_TIMEOUT } from '@dxos/client-protocol';
6
+ import { PROXY_CONNECTION_TIMEOUT, ShellRuntime } from '@dxos/client-protocol';
7
7
  import { Config } from '@dxos/config';
8
8
  import { log, logInfo } from '@dxos/log';
9
9
  import { MemorySignalManager, MemorySignalManagerContext, WebsocketSignalManager } from '@dxos/messaging';
@@ -13,7 +13,7 @@ import { getAsyncValue, MaybePromise, Provider } from '@dxos/util';
13
13
 
14
14
  import { ClientServicesHost } from '../services';
15
15
  import { ClientRpcServer, ClientRpcServerParams } from '../services/client-rpc-server';
16
- import { ShellRuntime, ShellRuntimeImpl } from './shell-runtime';
16
+ import { ShellRuntimeImpl } from './shell-runtime';
17
17
 
18
18
  const LOCK_KEY = 'DXOS_RESOURCE_LOCK';
19
19
 
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { Trigger } from '@dxos/async';
6
- import { iframeServiceBundle, workerServiceBundle, WorkerServiceBundle } from '@dxos/client-protocol';
6
+ import { iframeServiceBundle, ShellRuntime, workerServiceBundle, WorkerServiceBundle } from '@dxos/client-protocol';
7
7
  import { Config } from '@dxos/config';
8
8
  import { RemoteServiceConnectionError } from '@dxos/errors';
9
9
  import { log } from '@dxos/log';
@@ -12,7 +12,7 @@ import { BridgeService } from '@dxos/protocols/proto/dxos/mesh/bridge';
12
12
  import { createProtoRpcPeer, ProtoRpcPeer, RpcPort } from '@dxos/rpc';
13
13
  import { getAsyncValue, MaybePromise, Provider } from '@dxos/util';
14
14
 
15
- import { ShellRuntime, ShellRuntimeImpl } from './shell-runtime';
15
+ import { ShellRuntimeImpl } from './shell-runtime';
16
16
 
17
17
  // NOTE: Keep as RpcPorts to avoid dependency on @dxos/rpc-tunnel so we don't depend on browser-specific apis.
18
18
  export type IFrameProxyRuntimeParams = {
@@ -2,23 +2,14 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import assert from 'node:assert';
5
+ import invariant from 'tiny-invariant';
6
6
 
7
7
  import { Event } from '@dxos/async';
8
- import { appServiceBundle, AppServiceBundle, shellServiceBundle } from '@dxos/client-protocol';
8
+ import { appServiceBundle, AppServiceBundle, ShellRuntime, shellServiceBundle } from '@dxos/client-protocol';
9
9
  import { PublicKey } from '@dxos/keys';
10
10
  import { AppContextRequest, LayoutRequest, ShellLayout } from '@dxos/protocols/proto/dxos/iframe';
11
11
  import { createProtoRpcPeer, ProtoRpcPeer, RpcPort } from '@dxos/rpc';
12
12
 
13
- export interface ShellRuntime {
14
- layoutUpdate: Event<LayoutRequest>;
15
- layout: ShellLayout;
16
- invitationCode?: string;
17
- spaceKey?: PublicKey;
18
- setLayout: (layout: ShellLayout, options?: Omit<LayoutRequest, 'layout'>) => void;
19
- setAppContext: (context: AppContextRequest) => Promise<void>;
20
- }
21
-
22
13
  /**
23
14
  * Endpoint that handles shell services.
24
15
  */
@@ -51,7 +42,7 @@ export class ShellRuntimeImpl implements ShellRuntime {
51
42
  }
52
43
 
53
44
  async setAppContext(context: AppContextRequest) {
54
- assert(this._appRpc, 'runtime not open');
45
+ invariant(this._appRpc, 'runtime not open');
55
46
 
56
47
  await this._appRpc.rpc.AppService.setContext(context);
57
48
  }
@@ -81,40 +72,3 @@ export class ShellRuntimeImpl implements ShellRuntime {
81
72
  this._appRpc = undefined;
82
73
  }
83
74
  }
84
-
85
- export class MemoryShellRuntime implements ShellRuntime {
86
- readonly layoutUpdate = new Event<LayoutRequest>();
87
- readonly contextUpdate = new Event<AppContextRequest>();
88
- private _layout: ShellLayout;
89
- private _invitationCode?: string;
90
- private _spaceKey?: PublicKey;
91
-
92
- constructor({ layout, invitationCode, spaceKey }: Partial<LayoutRequest> & Partial<AppContextRequest> = {}) {
93
- this._layout = layout ?? ShellLayout.DEFAULT;
94
- this._invitationCode = invitationCode;
95
- this._spaceKey = spaceKey;
96
- }
97
-
98
- get layout() {
99
- return this._layout;
100
- }
101
-
102
- get invitationCode() {
103
- return this._invitationCode;
104
- }
105
-
106
- get spaceKey() {
107
- return this._spaceKey;
108
- }
109
-
110
- setLayout(layout: ShellLayout, options: Omit<LayoutRequest, 'layout'> = {}) {
111
- this._layout = layout;
112
- this._invitationCode = options.invitationCode;
113
- this._spaceKey = options.spaceKey;
114
- this.layoutUpdate.emit({ layout, ...options });
115
- }
116
-
117
- async setAppContext(context: AppContextRequest) {
118
- this.contextUpdate.emit(context);
119
- }
120
- }
@@ -37,7 +37,7 @@ export class WorkerRuntime {
37
37
  constructor(
38
38
  private readonly _configProvider: () => MaybePromise<Config>
39
39
  ) {
40
- this._clientServices = new ClientServicesHost();
40
+ this._clientServices = new ClientServicesHost({ callbacks: { onReset: async () => { self.close(); } } });
41
41
  }
42
42
 
43
43
  get host() {
@@ -2,7 +2,7 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import assert from 'node:assert';
5
+ import invariant from 'tiny-invariant';
6
6
 
7
7
  import { asyncTimeout, Trigger } from '@dxos/async';
8
8
  import {
@@ -16,8 +16,7 @@ import { BridgeService } from '@dxos/protocols/proto/dxos/mesh/bridge';
16
16
  import { createProtoRpcPeer, ProtoRpcPeer, RpcPort } from '@dxos/rpc';
17
17
  import { Callback, MaybePromise } from '@dxos/util';
18
18
 
19
- import { ClientServicesHost } from '../services';
20
- import { ClientRpcServer, ClientRpcServerParams } from '../services/client-rpc-server';
19
+ import { ClientServicesHost, ClientRpcServer, ClientRpcServerParams } from '../services';
21
20
 
22
21
  export type WorkerSessionParams = {
23
22
  serviceHost: ClientServicesHost;
@@ -48,7 +47,7 @@ export class WorkerSession {
48
47
  public bridgeService?: BridgeService;
49
48
 
50
49
  constructor({ serviceHost, systemPort, appPort, shellPort, readySignal }: WorkerSessionParams) {
51
- assert(serviceHost);
50
+ invariant(serviceHost);
52
51
  this._serviceHost = serviceHost;
53
52
 
54
53
  const middleware: Pick<ClientRpcServerParams, 'handleCall' | 'handleStream'> = {
@@ -111,17 +110,18 @@ export class WorkerSession {
111
110
  }
112
111
 
113
112
  async open() {
114
- log.info('opening..');
113
+ log.info('opening...');
115
114
  await Promise.all([this._clientRpc.open(), this._iframeRpc.open(), this._maybeOpenShell()]);
116
115
 
117
116
  await this._startTrigger.wait({ timeout: PROXY_CONNECTION_TIMEOUT });
118
117
  if (this.lockKey) {
119
118
  void this._afterLockReleases(this.lockKey, () => this.close());
120
119
  }
120
+ log.info('opened');
121
121
  }
122
122
 
123
123
  async close() {
124
- log.info('closing..');
124
+ log.info('closing...');
125
125
  try {
126
126
  await this.onClose.callIfSet();
127
127
  } catch (err: any) {
@@ -129,6 +129,7 @@ export class WorkerSession {
129
129
  }
130
130
 
131
131
  await Promise.all([this._clientRpc.close(), this._iframeRpc.close()]);
132
+ log.info('closed');
132
133
  }
133
134
 
134
135
  private async _maybeOpenShell() {