@dxos/plugin-client 0.7.5-main.9d26e3a → 0.7.5-main.e9bb01b

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 (134) hide show
  1. package/dist/lib/browser/app-graph-builder-6LOTDB4T.mjs +44 -0
  2. package/dist/lib/browser/app-graph-builder-6LOTDB4T.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-52IJQ35F.mjs → chunk-E3OUNOEL.mjs} +4 -6
  4. package/dist/lib/browser/chunk-E3OUNOEL.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-MSK3TLIH.mjs +17 -0
  6. package/dist/lib/browser/chunk-MSK3TLIH.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-X4QUPYC6.mjs → chunk-NHIL4T3L.mjs} +3 -3
  8. package/dist/lib/browser/chunk-NHIL4T3L.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-PDSHZE3P.mjs +162 -0
  10. package/dist/lib/browser/chunk-PDSHZE3P.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-RGMLBYIF.mjs +18 -0
  12. package/dist/lib/browser/chunk-RGMLBYIF.mjs.map +7 -0
  13. package/dist/lib/browser/client-BEJK55IM.mjs +41 -0
  14. package/dist/lib/browser/client-BEJK55IM.mjs.map +7 -0
  15. package/dist/lib/browser/index.mjs +75 -369
  16. package/dist/lib/browser/index.mjs.map +4 -4
  17. package/dist/lib/browser/intent-resolver-XNZZLRBY.mjs +159 -0
  18. package/dist/lib/browser/intent-resolver-XNZZLRBY.mjs.map +7 -0
  19. package/dist/lib/browser/meta.json +1 -1
  20. package/dist/lib/browser/react-context-PHX2CVI7.mjs +24 -0
  21. package/dist/lib/browser/react-context-PHX2CVI7.mjs.map +7 -0
  22. package/dist/lib/browser/react-surface-K5NKVCIB.mjs +41 -0
  23. package/dist/lib/browser/react-surface-K5NKVCIB.mjs.map +7 -0
  24. package/dist/lib/browser/schema-AL34NY2M.mjs +33 -0
  25. package/dist/lib/browser/schema-AL34NY2M.mjs.map +7 -0
  26. package/dist/lib/browser/types.mjs +4 -6
  27. package/dist/lib/node/app-graph-builder-JCND3P6G.cjs +58 -0
  28. package/dist/lib/node/app-graph-builder-JCND3P6G.cjs.map +7 -0
  29. package/dist/lib/node/{chunk-NFO3ADQC.cjs → chunk-NVYWMDF3.cjs} +8 -11
  30. package/dist/lib/node/chunk-NVYWMDF3.cjs.map +7 -0
  31. package/dist/lib/node/{chunk-RUA5KXVW.cjs → chunk-OIFPM5ZW.cjs} +7 -7
  32. package/dist/lib/node/chunk-OIFPM5ZW.cjs.map +7 -0
  33. package/dist/lib/node/chunk-VUJ3ZPK3.cjs +190 -0
  34. package/dist/lib/node/chunk-VUJ3ZPK3.cjs.map +7 -0
  35. package/dist/lib/node/chunk-XPC4JOPP.cjs +37 -0
  36. package/dist/lib/node/chunk-XPC4JOPP.cjs.map +7 -0
  37. package/dist/lib/node/{meta.cjs → chunk-ZI7AV5RP.cjs} +14 -8
  38. package/dist/lib/node/chunk-ZI7AV5RP.cjs.map +7 -0
  39. package/dist/lib/node/client-AHIW24VM.cjs +55 -0
  40. package/dist/lib/node/client-AHIW24VM.cjs.map +7 -0
  41. package/dist/lib/node/index.cjs +72 -358
  42. package/dist/lib/node/index.cjs.map +4 -4
  43. package/dist/lib/node/intent-resolver-UZEK4ODS.cjs +167 -0
  44. package/dist/lib/node/intent-resolver-UZEK4ODS.cjs.map +7 -0
  45. package/dist/lib/node/meta.json +1 -1
  46. package/dist/lib/node/react-context-WMOFXPT4.cjs +48 -0
  47. package/dist/lib/node/react-context-WMOFXPT4.cjs.map +7 -0
  48. package/dist/lib/node/react-surface-YQ2PKXNV.cjs +62 -0
  49. package/dist/lib/node/react-surface-YQ2PKXNV.cjs.map +7 -0
  50. package/dist/lib/node/schema-HW4W3QYU.cjs +49 -0
  51. package/dist/lib/node/schema-HW4W3QYU.cjs.map +7 -0
  52. package/dist/lib/node/types.cjs +4 -6
  53. package/dist/lib/node/types.cjs.map +2 -2
  54. package/dist/lib/node-esm/app-graph-builder-ZLGKFBLY.mjs +45 -0
  55. package/dist/lib/node-esm/app-graph-builder-ZLGKFBLY.mjs.map +7 -0
  56. package/dist/lib/node-esm/{chunk-TI4GNGMM.mjs → chunk-74T33KTB.mjs} +4 -6
  57. package/dist/lib/node-esm/chunk-74T33KTB.mjs.map +7 -0
  58. package/dist/lib/node-esm/chunk-B73LKPGU.mjs +18 -0
  59. package/dist/lib/node-esm/chunk-B73LKPGU.mjs.map +7 -0
  60. package/dist/lib/node-esm/{chunk-GMGRQ5Q7.mjs → chunk-HO7WDE7C.mjs} +3 -3
  61. package/dist/lib/node-esm/chunk-HO7WDE7C.mjs.map +7 -0
  62. package/dist/lib/node-esm/chunk-QR72BXJK.mjs +19 -0
  63. package/dist/lib/node-esm/chunk-QR72BXJK.mjs.map +7 -0
  64. package/dist/lib/node-esm/chunk-WS4CKCUR.mjs +163 -0
  65. package/dist/lib/node-esm/chunk-WS4CKCUR.mjs.map +7 -0
  66. package/dist/lib/node-esm/client-FY7IDNRL.mjs +42 -0
  67. package/dist/lib/node-esm/client-FY7IDNRL.mjs.map +7 -0
  68. package/dist/lib/node-esm/index.mjs +75 -369
  69. package/dist/lib/node-esm/index.mjs.map +4 -4
  70. package/dist/lib/node-esm/intent-resolver-DLCCRSFV.mjs +160 -0
  71. package/dist/lib/node-esm/intent-resolver-DLCCRSFV.mjs.map +7 -0
  72. package/dist/lib/node-esm/meta.json +1 -1
  73. package/dist/lib/node-esm/react-context-EEGDXBWA.mjs +25 -0
  74. package/dist/lib/node-esm/react-context-EEGDXBWA.mjs.map +7 -0
  75. package/dist/lib/node-esm/react-surface-H34XQPWC.mjs +42 -0
  76. package/dist/lib/node-esm/react-surface-H34XQPWC.mjs.map +7 -0
  77. package/dist/lib/node-esm/schema-74LVJ3EU.mjs +34 -0
  78. package/dist/lib/node-esm/schema-74LVJ3EU.mjs.map +7 -0
  79. package/dist/lib/node-esm/types.mjs +4 -6
  80. package/dist/types/src/ClientPlugin.d.ts +2 -3
  81. package/dist/types/src/ClientPlugin.d.ts.map +1 -1
  82. package/dist/types/src/capabilities/app-graph-builder.d.ts +181 -0
  83. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
  84. package/dist/types/src/capabilities/capabilities.d.ts +8 -0
  85. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -0
  86. package/dist/types/src/capabilities/client.d.ts +9 -0
  87. package/dist/types/src/capabilities/client.d.ts.map +1 -0
  88. package/dist/types/src/capabilities/index.d.ts +194 -0
  89. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  90. package/dist/types/src/capabilities/intent-resolver.d.ts +8 -0
  91. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
  92. package/dist/types/src/capabilities/react-context.d.ts +8 -0
  93. package/dist/types/src/capabilities/react-context.d.ts.map +1 -0
  94. package/dist/types/src/capabilities/react-surface.d.ts +7 -0
  95. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  96. package/dist/types/src/capabilities/schema.d.ts +4 -0
  97. package/dist/types/src/capabilities/schema.d.ts.map +1 -0
  98. package/dist/types/src/events.d.ts +7 -0
  99. package/dist/types/src/events.d.ts.map +1 -0
  100. package/dist/types/src/index.d.ts +3 -2
  101. package/dist/types/src/index.d.ts.map +1 -1
  102. package/dist/types/src/meta.d.ts +1 -2
  103. package/dist/types/src/meta.d.ts.map +1 -1
  104. package/dist/types/src/types.d.ts +5 -17
  105. package/dist/types/src/types.d.ts.map +1 -1
  106. package/dist/types/tsconfig.tsbuildinfo +1 -1
  107. package/package.json +17 -23
  108. package/src/ClientPlugin.ts +64 -0
  109. package/src/capabilities/app-graph-builder.ts +39 -0
  110. package/src/capabilities/capabilities.ts +16 -0
  111. package/src/capabilities/client.ts +42 -0
  112. package/src/capabilities/index.ts +14 -0
  113. package/src/capabilities/intent-resolver.ts +130 -0
  114. package/src/capabilities/react-context.tsx +20 -0
  115. package/src/capabilities/react-surface.tsx +44 -0
  116. package/src/capabilities/schema.ts +36 -0
  117. package/src/components/IdentityDialog.tsx +3 -3
  118. package/src/components/JoinDialog.tsx +1 -1
  119. package/src/events.ts +14 -0
  120. package/src/index.ts +4 -4
  121. package/src/meta.ts +1 -1
  122. package/src/types.ts +5 -31
  123. package/dist/lib/browser/chunk-52IJQ35F.mjs.map +0 -7
  124. package/dist/lib/browser/chunk-X4QUPYC6.mjs.map +0 -7
  125. package/dist/lib/browser/meta.mjs +0 -9
  126. package/dist/lib/browser/meta.mjs.map +0 -7
  127. package/dist/lib/node/chunk-NFO3ADQC.cjs.map +0 -7
  128. package/dist/lib/node/chunk-RUA5KXVW.cjs.map +0 -7
  129. package/dist/lib/node/meta.cjs.map +0 -7
  130. package/dist/lib/node-esm/chunk-GMGRQ5Q7.mjs.map +0 -7
  131. package/dist/lib/node-esm/chunk-TI4GNGMM.mjs.map +0 -7
  132. package/dist/lib/node-esm/meta.mjs +0 -10
  133. package/dist/lib/node-esm/meta.mjs.map +0 -7
  134. package/src/ClientPlugin.tsx +0 -227
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-client",
3
- "version": "0.7.5-main.9d26e3a",
3
+ "version": "0.7.5-main.e9bb01b",
4
4
  "description": "DXOS Surface plugin for DXOS Client",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -13,11 +13,6 @@
13
13
  "browser": "./dist/lib/browser/index.mjs",
14
14
  "node": "./dist/lib/node-esm/index.mjs"
15
15
  },
16
- "./meta": {
17
- "types": "./dist/types/src/meta.d.ts",
18
- "browser": "./dist/lib/browser/meta.mjs",
19
- "node": "./dist/lib/node-esm/meta.mjs"
20
- },
21
16
  "./types": {
22
17
  "types": "./dist/types/src/types.d.ts",
23
18
  "browser": "./dist/lib/browser/types.mjs",
@@ -27,9 +22,6 @@
27
22
  "types": "dist/types/src/index.d.ts",
28
23
  "typesVersions": {
29
24
  "*": {
30
- "meta": [
31
- "dist/types/src/meta.d.ts"
32
- ],
33
25
  "types": [
34
26
  "dist/types/src/types.d.ts"
35
27
  ]
@@ -40,27 +32,29 @@
40
32
  "src"
41
33
  ],
42
34
  "dependencies": {
43
- "@phosphor-icons/react": "^2.1.5",
44
- "@dxos/app-framework": "0.7.5-main.9d26e3a",
45
- "@dxos/echo-schema": "0.7.5-main.9d26e3a",
46
- "@dxos/echo-signals": "0.7.5-main.9d26e3a",
47
- "@dxos/invariant": "0.7.5-main.9d26e3a",
48
- "@dxos/local-storage": "0.7.5-main.9d26e3a",
49
- "@dxos/log": "0.7.5-main.9d26e3a",
50
- "@dxos/plugin-graph": "0.7.5-main.9d26e3a",
51
- "@dxos/plugin-observability": "0.7.5-main.9d26e3a",
52
- "@dxos/react-client": "0.7.5-main.9d26e3a",
53
- "@dxos/shell": "0.7.5-main.9d26e3a",
54
- "@dxos/react-ui": "0.7.5-main.9d26e3a",
55
- "@dxos/config": "0.7.5-main.9d26e3a"
35
+ "@preact/signals-core": "^1.6.0",
36
+ "@dxos/app-framework": "0.7.5-main.e9bb01b",
37
+ "@dxos/config": "0.7.5-main.e9bb01b",
38
+ "@dxos/echo-signals": "0.7.5-main.e9bb01b",
39
+ "@dxos/echo-schema": "0.7.5-main.e9bb01b",
40
+ "@dxos/local-storage": "0.7.5-main.e9bb01b",
41
+ "@dxos/invariant": "0.7.5-main.e9bb01b",
42
+ "@dxos/plugin-observability": "0.7.5-main.e9bb01b",
43
+ "@dxos/log": "0.7.5-main.e9bb01b",
44
+ "@dxos/plugin-graph": "0.7.5-main.e9bb01b",
45
+ "@dxos/react-client": "0.7.5-main.e9bb01b",
46
+ "@dxos/react-ui": "0.7.5-main.e9bb01b",
47
+ "@dxos/util": "0.7.5-main.e9bb01b",
48
+ "@dxos/shell": "0.7.5-main.e9bb01b"
56
49
  },
57
50
  "devDependencies": {
51
+ "@phosphor-icons/react": "^2.1.5",
58
52
  "@types/react": "~18.2.0",
59
53
  "@types/react-dom": "~18.2.0",
60
54
  "react": "~18.2.0",
61
55
  "react-dom": "~18.2.0",
62
56
  "vite": "5.4.7",
63
- "@dxos/storybook-utils": "0.7.5-main.9d26e3a"
57
+ "@dxos/storybook-utils": "0.7.5-main.e9bb01b"
64
58
  },
65
59
  "peerDependencies": {
66
60
  "@phosphor-icons/react": "^2.1.5",
@@ -0,0 +1,64 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { Capabilities, contributes, defineModule, definePlugin, Events, oneOf } from '@dxos/app-framework';
6
+
7
+ import { Client, AppGraphBuilder, IntentResolver, ReactContext, ReactSurface, Schema } from './capabilities';
8
+ import { ClientEvents } from './events';
9
+ import { meta } from './meta';
10
+ import translations from './translations';
11
+ import { type ClientPluginOptions } from './types';
12
+
13
+ export const ClientPlugin = ({
14
+ invitationUrl = window.location.origin,
15
+ invitationParam = 'deviceInvitationCode',
16
+ onReset,
17
+ ...options
18
+ }: ClientPluginOptions) => {
19
+ const createInvitationUrl = (invitationCode: string) => {
20
+ const baseUrl = new URL(invitationUrl);
21
+ baseUrl.searchParams.set(invitationParam, invitationCode);
22
+ return baseUrl.toString();
23
+ };
24
+
25
+ return definePlugin(meta, [
26
+ defineModule({
27
+ id: `${meta.id}/module/client`,
28
+ activatesOn: oneOf(Events.Startup, Events.SetupAppGraph),
29
+ activatesAfter: [ClientEvents.ClientReady],
30
+ activate: (context) => Client({ ...options, context }),
31
+ }),
32
+ defineModule({
33
+ id: `${meta.id}/module/schema`,
34
+ activatesOn: ClientEvents.ClientReady,
35
+ activatesBefore: [ClientEvents.SetupSchema],
36
+ activate: Schema,
37
+ }),
38
+ defineModule({
39
+ id: `${meta.id}/module/react-context`,
40
+ activatesOn: Events.Startup,
41
+ activate: ReactContext,
42
+ }),
43
+ defineModule({
44
+ id: `${meta.id}/module/react-surface`,
45
+ activatesOn: Events.SetupSurfaces,
46
+ activate: () => ReactSurface({ createInvitationUrl }),
47
+ }),
48
+ defineModule({
49
+ id: `${meta.id}/module/app-graph-builder`,
50
+ activatesOn: Events.SetupAppGraph,
51
+ activate: AppGraphBuilder,
52
+ }),
53
+ defineModule({
54
+ id: `${meta.id}/module/intent-resolver`,
55
+ activatesOn: Events.SetupIntents,
56
+ activate: (context) => IntentResolver({ context, onReset }),
57
+ }),
58
+ defineModule({
59
+ id: `${meta.id}/module/translations`,
60
+ activatesOn: Events.SetupTranslations,
61
+ activate: () => contributes(Capabilities.Translations, translations),
62
+ }),
63
+ ]);
64
+ };
@@ -0,0 +1,39 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { createIntent } from '@dxos/app-framework';
6
+ import { Capabilities, contributes, type PluginsContext } from '@dxos/app-framework';
7
+ import { createExtension, type Node } from '@dxos/plugin-graph';
8
+
9
+ import { CLIENT_PLUGIN } from '../meta';
10
+ import { ClientAction } from '../types';
11
+
12
+ export default (context: PluginsContext) =>
13
+ contributes(
14
+ Capabilities.AppGraphBuilder,
15
+ createExtension({
16
+ id: CLIENT_PLUGIN,
17
+ filter: (node): node is Node<null> => node.id === 'root',
18
+ actions: () => [
19
+ {
20
+ id: `${CLIENT_PLUGIN}/open-shell`,
21
+ data: async () => {
22
+ const { dispatchPromise: dispatch } = context.requestCapability(Capabilities.IntentDispatcher);
23
+ await dispatch(createIntent(ClientAction.ShareIdentity));
24
+ },
25
+ properties: {
26
+ label: ['open shell label', { ns: CLIENT_PLUGIN }],
27
+ icon: 'ph--address-book--regular',
28
+ keyBinding: {
29
+ macos: 'meta+shift+.',
30
+ // TODO(wittjosiah): Test on windows to see if it behaves the same as linux.
31
+ windows: 'alt+shift+.',
32
+ linux: 'alt+shift+>',
33
+ },
34
+ testId: 'clientPlugin.openShell',
35
+ },
36
+ },
37
+ ],
38
+ }),
39
+ );
@@ -0,0 +1,16 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { defineCapability } from '@dxos/app-framework';
6
+ import { type TypedObject } from '@dxos/echo-schema';
7
+ import { type Client } from '@dxos/react-client';
8
+
9
+ import { CLIENT_PLUGIN } from '../meta';
10
+
11
+ export namespace ClientCapabilities {
12
+ export const Client = defineCapability<Client>(`${CLIENT_PLUGIN}/capability/client`);
13
+ export const Schema = defineCapability<TypedObject[]>(`${CLIENT_PLUGIN}/capability/schema`);
14
+ // TODO(wittjosiah): Rename this. Reserve "system" nomenclature for internal use.
15
+ export const SystemSchema = defineCapability<TypedObject[]>(`${CLIENT_PLUGIN}/capability/system-schema`);
16
+ }
@@ -0,0 +1,42 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { contributes, type PluginsContext } from '@dxos/app-framework';
6
+ import { Config, Defaults, Envs, Local, Storage } from '@dxos/config';
7
+ import { Client } from '@dxos/react-client';
8
+
9
+ import { ClientCapabilities } from './capabilities';
10
+ import { ClientEvents } from '../events';
11
+ import { type ClientPluginOptions } from '../types';
12
+
13
+ type ClientCapabilityOptions = Omit<ClientPluginOptions, 'appKey' | 'invitationUrl' | 'invitationParam' | 'onReset'> & {
14
+ context: PluginsContext;
15
+ };
16
+
17
+ export default async ({ context, onClientInitialized, ...options }: ClientCapabilityOptions) => {
18
+ const config = new Config(await Storage(), Envs(), Local(), Defaults());
19
+ const client = new Client({ config, ...options });
20
+ await client.initialize();
21
+ await onClientInitialized?.(context, client);
22
+
23
+ // TODO(wittjosiah): Remove. This is a hack to get the app to boot with the new identity after a reset.
24
+ client.reloaded.on(() => {
25
+ client.halo.identity.subscribe(async (identity) => {
26
+ if (identity) {
27
+ window.location.href = window.location.origin;
28
+ }
29
+ });
30
+ });
31
+
32
+ const subscription = client.spaces.isReady.subscribe(async (ready) => {
33
+ if (ready) {
34
+ await context.activate(ClientEvents.SpacesReady);
35
+ }
36
+ });
37
+
38
+ return contributes(ClientCapabilities.Client, client, async () => {
39
+ subscription.unsubscribe();
40
+ await client.destroy();
41
+ });
42
+ };
@@ -0,0 +1,14 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { lazy } from '@dxos/app-framework';
6
+
7
+ export const AppGraphBuilder = lazy(async () => import('./app-graph-builder'));
8
+ export const Client = lazy(async () => import('./client'));
9
+ export const IntentResolver = lazy(async () => import('./intent-resolver'));
10
+ export const ReactContext = lazy(async () => import('./react-context'));
11
+ export const ReactSurface = lazy(async () => import('./react-surface'));
12
+ export const Schema = lazy(async () => import('./schema'));
13
+
14
+ export * from './capabilities';
@@ -0,0 +1,130 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import {
6
+ Capabilities,
7
+ contributes,
8
+ createIntent,
9
+ createResolver,
10
+ LayoutAction,
11
+ type PluginsContext,
12
+ } from '@dxos/app-framework';
13
+ import { invariant } from '@dxos/invariant';
14
+ import { ObservabilityAction } from '@dxos/plugin-observability/types';
15
+ import { type JoinPanelProps } from '@dxos/shell/react';
16
+
17
+ import { ClientCapabilities } from './capabilities';
18
+ import { IDENTITY_DIALOG, JOIN_DIALOG, RECOVER_CODE_DIALOG } from '../components';
19
+ import { ClientEvents } from '../events';
20
+ import { ClientAction, type ClientPluginOptions } from '../types';
21
+
22
+ type IntentResolverOptions = Pick<ClientPluginOptions, 'onReset'> & {
23
+ context: PluginsContext;
24
+ };
25
+
26
+ export default ({ context, onReset }: IntentResolverOptions) =>
27
+ contributes(Capabilities.IntentResolver, [
28
+ createResolver({
29
+ intent: ClientAction.CreateIdentity,
30
+ resolve: async () => {
31
+ const manager = context.requestCapability(Capabilities.PluginManager);
32
+ const client = context.requestCapability(ClientCapabilities.Client);
33
+ const data = await client.halo.createIdentity();
34
+ await manager.activate(ClientEvents.IdentityCreated);
35
+ return { data, intents: [createIntent(ObservabilityAction.SendEvent, { name: 'identity.create' })] };
36
+ },
37
+ }),
38
+ createResolver({
39
+ intent: ClientAction.JoinIdentity,
40
+ resolve: async (data) => {
41
+ return {
42
+ intents: [
43
+ createIntent(LayoutAction.UpdateDialog, {
44
+ part: 'dialog',
45
+ subject: JOIN_DIALOG,
46
+ options: {
47
+ blockAlign: 'start',
48
+ props: {
49
+ initialInvitationCode: data.invitationCode,
50
+ initialDisposition: 'accept-halo-invitation',
51
+ },
52
+ },
53
+ }),
54
+ ],
55
+ };
56
+ },
57
+ }),
58
+ createResolver({
59
+ intent: ClientAction.ShareIdentity,
60
+ resolve: async () => {
61
+ return {
62
+ intents: [
63
+ createIntent(LayoutAction.UpdateDialog, {
64
+ part: 'dialog',
65
+ subject: IDENTITY_DIALOG,
66
+ options: {
67
+ blockAlign: 'start',
68
+ },
69
+ }),
70
+ createIntent(ObservabilityAction.SendEvent, { name: 'identity.share' }),
71
+ ],
72
+ };
73
+ },
74
+ }),
75
+ createResolver({
76
+ intent: ClientAction.RecoverIdentity,
77
+ resolve: async () => {
78
+ return {
79
+ intents: [
80
+ createIntent(LayoutAction.UpdateDialog, {
81
+ part: 'dialog',
82
+ subject: JOIN_DIALOG,
83
+ options: {
84
+ blockAlign: 'start',
85
+ props: {
86
+ initialDisposition: 'recover-identity',
87
+ } satisfies Partial<JoinPanelProps>,
88
+ },
89
+ }),
90
+ ],
91
+ };
92
+ },
93
+ }),
94
+ createResolver({
95
+ intent: ClientAction.ResetStorage,
96
+ resolve: async (data) => {
97
+ await onReset?.({ target: data.target });
98
+ },
99
+ }),
100
+ createResolver({
101
+ intent: ClientAction.CreateAgent,
102
+ resolve: async () => {
103
+ const client = context.requestCapability(ClientCapabilities.Client);
104
+ invariant(client.services.services.EdgeAgentService, 'Missing EdgeAgentService');
105
+ await client.services.services.EdgeAgentService.createAgent(null as any, { timeout: 10_000 });
106
+ },
107
+ }),
108
+ createResolver({
109
+ intent: ClientAction.CreateRecoveryCode,
110
+ resolve: async () => {
111
+ const client = context.requestCapability(ClientCapabilities.Client);
112
+ invariant(client.services.services.IdentityService, 'IdentityService not available');
113
+ // TODO(wittjosiah): This needs a proper api. Rename property.
114
+ const { seedphrase } = await client.services.services.IdentityService.createRecoveryPhrase();
115
+ return {
116
+ intents: [
117
+ createIntent(LayoutAction.UpdateDialog, {
118
+ part: 'dialog',
119
+ subject: RECOVER_CODE_DIALOG,
120
+ options: {
121
+ blockAlign: 'start',
122
+ type: 'alert',
123
+ props: { code: seedphrase },
124
+ },
125
+ }),
126
+ ],
127
+ };
128
+ },
129
+ }),
130
+ ]);
@@ -0,0 +1,20 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { Capabilities, contributes, useCapability } from '@dxos/app-framework';
8
+ import { ClientProvider } from '@dxos/react-client';
9
+
10
+ import { ClientCapabilities } from './capabilities';
11
+ import { CLIENT_PLUGIN } from '../meta';
12
+
13
+ export default () =>
14
+ contributes(Capabilities.ReactContext, {
15
+ id: CLIENT_PLUGIN,
16
+ context: ({ children }) => {
17
+ const client = useCapability(ClientCapabilities.Client);
18
+ return <ClientProvider client={client}>{children}</ClientProvider>;
19
+ },
20
+ });
@@ -0,0 +1,44 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { createSurface, Capabilities, contributes } from '@dxos/app-framework';
8
+ import { type IdentityPanelProps, type JoinPanelProps } from '@dxos/shell/react';
9
+
10
+ import {
11
+ IDENTITY_DIALOG,
12
+ IdentityDialog,
13
+ JOIN_DIALOG,
14
+ JoinDialog,
15
+ RECOVER_CODE_DIALOG,
16
+ RecoveryCodeDialog,
17
+ type RecoveryCodeDialogProps,
18
+ } from '../components';
19
+
20
+ type ReactSurfaceOptions = {
21
+ createInvitationUrl: (invitationCode: string) => string;
22
+ };
23
+
24
+ export default ({ createInvitationUrl }: ReactSurfaceOptions) =>
25
+ contributes(Capabilities.ReactSurface, [
26
+ createSurface({
27
+ id: IDENTITY_DIALOG,
28
+ role: 'dialog',
29
+ filter: (data): data is { props: IdentityPanelProps } => data.component === IDENTITY_DIALOG,
30
+ component: ({ data }) => <IdentityDialog {...data.props} createInvitationUrl={createInvitationUrl} />,
31
+ }),
32
+ createSurface({
33
+ id: JOIN_DIALOG,
34
+ role: 'dialog',
35
+ filter: (data): data is { props: JoinPanelProps } => data.component === JOIN_DIALOG,
36
+ component: ({ data }) => <JoinDialog {...data.props} />,
37
+ }),
38
+ createSurface({
39
+ id: RECOVER_CODE_DIALOG,
40
+ role: 'dialog',
41
+ filter: (data): data is { props: RecoveryCodeDialogProps } => data.component === RECOVER_CODE_DIALOG,
42
+ component: ({ data }) => <RecoveryCodeDialog {...data.props} />,
43
+ }),
44
+ ]);
@@ -0,0 +1,36 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { effect } from '@preact/signals-core';
6
+
7
+ import { Capabilities, contributes, type PluginsContext } from '@dxos/app-framework';
8
+ import { type TypedObject } from '@dxos/echo-schema';
9
+
10
+ import { ClientCapabilities } from './capabilities';
11
+
12
+ // TODO(wittjosiah): Remove types?
13
+ export default (context: PluginsContext) => {
14
+ const client = context.requestCapability(ClientCapabilities.Client);
15
+
16
+ let previousSystem: TypedObject[] = [];
17
+ const unsubscribeSystem = effect(() => {
18
+ const systemSchemas = Array.from(new Set(context.requestCapabilities(ClientCapabilities.SystemSchema).flat()));
19
+ const newSchemas = systemSchemas.filter((schema) => !previousSystem.includes(schema));
20
+ previousSystem = systemSchemas;
21
+ client.addTypes(newSchemas);
22
+ });
23
+
24
+ let previous: TypedObject[] = [];
25
+ const unsubscribe = effect(() => {
26
+ const schemas = Array.from(new Set(context.requestCapabilities(ClientCapabilities.Schema).flat()));
27
+ const newSchemas = schemas.filter((schema) => !previous.includes(schema));
28
+ previous = schemas;
29
+ client.addTypes(newSchemas);
30
+ });
31
+
32
+ return contributes(Capabilities.Null, null, () => {
33
+ unsubscribeSystem();
34
+ unsubscribe();
35
+ });
36
+ };
@@ -21,9 +21,9 @@ export const IdentityDialog = (props: IdentityPanelProps) => {
21
21
  const handleDone = useCallback(
22
22
  () =>
23
23
  dispatch(
24
- createIntent(LayoutAction.SetLayout, {
25
- element: 'dialog',
26
- state: false,
24
+ createIntent(LayoutAction.UpdateDialog, {
25
+ part: 'dialog',
26
+ options: { state: false },
27
27
  }),
28
28
  ),
29
29
  [dispatch],
@@ -24,7 +24,7 @@ export const JoinDialog = (props: JoinPanelProps) => {
24
24
  async (result: InvitationResult | null) => {
25
25
  if (result?.identityKey) {
26
26
  await Promise.all([
27
- dispatch(createIntent(LayoutAction.SetLayout, { element: 'dialog', state: false })),
27
+ dispatch(createIntent(LayoutAction.UpdateDialog, { part: 'dialog', options: { state: false } })),
28
28
  dispatch(
29
29
  createIntent(ObservabilityAction.SendEvent, {
30
30
  name: props.initialDisposition === 'recover-identity' ? 'identity.recover' : 'identity.join',
package/src/events.ts ADDED
@@ -0,0 +1,14 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { defineEvent } from '@dxos/app-framework';
6
+
7
+ import { CLIENT_PLUGIN } from './meta';
8
+
9
+ export namespace ClientEvents {
10
+ export const ClientReady = defineEvent(`${CLIENT_PLUGIN}/event/client-ready`);
11
+ export const SetupSchema = defineEvent(`${CLIENT_PLUGIN}/event/setup-schema`);
12
+ export const IdentityCreated = defineEvent(`${CLIENT_PLUGIN}/event/identity-created`);
13
+ export const SpacesReady = defineEvent(`${CLIENT_PLUGIN}/event/spaces-ready`);
14
+ }
package/src/index.ts CHANGED
@@ -2,8 +2,8 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { ClientPlugin } from './ClientPlugin';
6
-
7
- export default ClientPlugin;
8
-
9
5
  export * from './ClientPlugin';
6
+ export * from './meta';
7
+
8
+ export { ClientCapabilities } from './capabilities';
9
+ export { ClientEvents } from './events';
package/src/meta.ts CHANGED
@@ -6,7 +6,7 @@ import { type PluginMeta } from '@dxos/app-framework';
6
6
 
7
7
  export const CLIENT_PLUGIN = 'dxos.org/plugin/client';
8
8
 
9
- export default {
9
+ export const meta = {
10
10
  id: CLIENT_PLUGIN,
11
11
  name: 'Client',
12
12
  } satisfies PluginMeta;
package/src/types.ts CHANGED
@@ -2,15 +2,10 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import {
6
- type GraphBuilderProvides,
7
- type IntentResolverProvides,
8
- type Plugin,
9
- type SurfaceProvides,
10
- type TranslationsProvides,
11
- } from '@dxos/app-framework';
5
+ import { type PluginsContext } from '@dxos/app-framework';
12
6
  import { S } from '@dxos/echo-schema';
13
- import { Client, PublicKey, type ClientOptions } from '@dxos/react-client';
7
+ import { type Client, PublicKey, type ClientOptions } from '@dxos/react-client';
8
+ import { type MaybePromise } from '@dxos/util';
14
9
 
15
10
  import { CLIENT_PLUGIN } from './meta';
16
11
 
@@ -72,11 +67,6 @@ export namespace ClientAction {
72
67
  }
73
68
 
74
69
  export type ClientPluginOptions = ClientOptions & {
75
- /**
76
- * Used to track app-specific state in spaces.
77
- */
78
- appKey: string;
79
-
80
70
  /**
81
71
  * Base URL for the invitation link.
82
72
  */
@@ -90,26 +80,10 @@ export type ClientPluginOptions = ClientOptions & {
90
80
  /**
91
81
  * Run after the client has been initialized.
92
82
  */
93
- onClientInitialized?: (client: Client) => Promise<void>;
94
-
95
- /**
96
- * Run after the identity has been successfully initialized.
97
- * Run with client during plugin ready phase.
98
- */
99
- onReady?: (client: Client, plugins: Plugin[]) => Promise<void>;
83
+ onClientInitialized?: (context: PluginsContext, client: Client) => MaybePromise<void>;
100
84
 
101
85
  /**
102
86
  * Called when the client is reset.
103
87
  */
104
- onReset?: (params: { target?: string }) => Promise<void>;
88
+ onReset?: (params: { target?: string }) => MaybePromise<void>;
105
89
  };
106
-
107
- export type ClientPluginProvides = IntentResolverProvides &
108
- GraphBuilderProvides &
109
- SurfaceProvides &
110
- TranslationsProvides & {
111
- client: Client;
112
- };
113
-
114
- export const parseClientPlugin = (plugin?: Plugin) =>
115
- (plugin?.provides as any).client instanceof Client ? (plugin as Plugin<ClientPluginProvides>) : undefined;
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/types.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport {\n type GraphBuilderProvides,\n type IntentResolverProvides,\n type Plugin,\n type SurfaceProvides,\n type TranslationsProvides,\n} from '@dxos/app-framework';\nimport { S } from '@dxos/echo-schema';\nimport { Client, PublicKey, type ClientOptions } from '@dxos/react-client';\n\nimport { CLIENT_PLUGIN } from './meta';\n\n// TODO(wittjosiah): Factor out. Generate?\nconst IdentitySchema = S.Struct({\n identityKey: S.instanceOf(PublicKey),\n spaceKey: S.optional(S.instanceOf(PublicKey)),\n profile: S.optional(\n S.Struct({\n displayName: S.optional(S.String),\n avatarCid: S.optional(S.String),\n data: S.optional(S.Record({ key: S.String, value: S.Any })),\n }),\n ),\n});\n\nconst CLIENT_ACTION = `${CLIENT_PLUGIN}/action`;\nexport namespace ClientAction {\n export class CreateIdentity extends S.TaggedClass<CreateIdentity>()(`${CLIENT_ACTION}/create-identity`, {\n input: S.Struct({\n displayName: S.optional(S.String),\n }),\n output: IdentitySchema,\n }) {}\n\n export class JoinIdentity extends S.TaggedClass<JoinIdentity>()(`${CLIENT_ACTION}/join-identity`, {\n input: S.Struct({\n invitationCode: S.String,\n }),\n output: S.Void,\n }) {}\n\n export class ShareIdentity extends S.TaggedClass<ShareIdentity>()(`${CLIENT_ACTION}/share-identity`, {\n input: S.Void,\n output: S.Void,\n }) {}\n\n export class RecoverIdentity extends S.TaggedClass<RecoverIdentity>()(`${CLIENT_ACTION}/recover-identity`, {\n input: S.Void,\n output: S.Void,\n }) {}\n\n export class ResetStorage extends S.TaggedClass<ResetStorage>()(`${CLIENT_ACTION}/reset-storage`, {\n input: S.Struct({\n target: S.optional(S.String),\n }),\n output: S.Void,\n }) {}\n\n export class CreateAgent extends S.TaggedClass<CreateAgent>()(`${CLIENT_ACTION}/create-agent`, {\n input: S.Void,\n output: S.Void,\n }) {}\n\n export class CreateRecoveryCode extends S.TaggedClass<CreateRecoveryCode>()(`${CLIENT_ACTION}/create-recovery-code`, {\n input: S.Void,\n output: S.Void,\n }) {}\n}\n\nexport type ClientPluginOptions = ClientOptions & {\n /**\n * Used to track app-specific state in spaces.\n */\n appKey: string;\n\n /**\n * Base URL for the invitation link.\n */\n invitationUrl?: string;\n\n /**\n * Query parameter for the invitation code.\n */\n invitationParam?: string;\n\n /**\n * Run after the client has been initialized.\n */\n onClientInitialized?: (client: Client) => Promise<void>;\n\n /**\n * Run after the identity has been successfully initialized.\n * Run with client during plugin ready phase.\n */\n onReady?: (client: Client, plugins: Plugin[]) => Promise<void>;\n\n /**\n * Called when the client is reset.\n */\n onReset?: (params: { target?: string }) => Promise<void>;\n};\n\nexport type ClientPluginProvides = IntentResolverProvides &\n GraphBuilderProvides &\n SurfaceProvides &\n TranslationsProvides & {\n client: Client;\n };\n\nexport const parseClientPlugin = (plugin?: Plugin) =>\n (plugin?.provides as any).client instanceof Client ? (plugin as Plugin<ClientPluginProvides>) : undefined;\n"],
5
- "mappings": ";;;;;AAWA,SAASA,SAAS;AAClB,SAASC,QAAQC,iBAAqC;AAKtD,IAAMC,iBAAiBC,EAAEC,OAAO;EAC9BC,aAAaF,EAAEG,WAAWC,SAAAA;EAC1BC,UAAUL,EAAEM,SAASN,EAAEG,WAAWC,SAAAA,CAAAA;EAClCG,SAASP,EAAEM,SACTN,EAAEC,OAAO;IACPO,aAAaR,EAAEM,SAASN,EAAES,MAAM;IAChCC,WAAWV,EAAEM,SAASN,EAAES,MAAM;IAC9BE,MAAMX,EAAEM,SAASN,EAAEY,OAAO;MAAEC,KAAKb,EAAES;MAAQK,OAAOd,EAAEe;IAAI,CAAA,CAAA;EAC1D,CAAA,CAAA;AAEJ,CAAA;AAEA,IAAMC,gBAAgB,GAAGC,aAAAA;;UACRC,eAAAA;EACR,MAAMC,uBAAuBnB,EAAEoB,YAAW,EAAmB,GAAGJ,aAAAA,oBAAiC;IACtGK,OAAOrB,EAAEC,OAAO;MACdO,aAAaR,EAAEM,SAASN,EAAES,MAAM;IAClC,CAAA;IACAa,QAAQvB;EACV,CAAA,EAAA;EAAI;gBALSoB,iBAAAA;EAON,MAAMI,qBAAqBvB,EAAEoB,YAAW,EAAiB,GAAGJ,aAAAA,kBAA+B;IAChGK,OAAOrB,EAAEC,OAAO;MACduB,gBAAgBxB,EAAES;IACpB,CAAA;IACAa,QAAQtB,EAAEyB;EACZ,CAAA,EAAA;EAAI;gBALSF,eAAAA;EAON,MAAMG,sBAAsB1B,EAAEoB,YAAW,EAAkB,GAAGJ,aAAAA,mBAAgC;IACnGK,OAAOrB,EAAEyB;IACTH,QAAQtB,EAAEyB;EACZ,CAAA,EAAA;EAAI;gBAHSC,gBAAAA;EAKN,MAAMC,wBAAwB3B,EAAEoB,YAAW,EAAoB,GAAGJ,aAAAA,qBAAkC;IACzGK,OAAOrB,EAAEyB;IACTH,QAAQtB,EAAEyB;EACZ,CAAA,EAAA;EAAI;gBAHSE,kBAAAA;EAKN,MAAMC,qBAAqB5B,EAAEoB,YAAW,EAAiB,GAAGJ,aAAAA,kBAA+B;IAChGK,OAAOrB,EAAEC,OAAO;MACd4B,QAAQ7B,EAAEM,SAASN,EAAES,MAAM;IAC7B,CAAA;IACAa,QAAQtB,EAAEyB;EACZ,CAAA,EAAA;EAAI;gBALSG,eAAAA;EAON,MAAME,oBAAoB9B,EAAEoB,YAAW,EAAgB,GAAGJ,aAAAA,iBAA8B;IAC7FK,OAAOrB,EAAEyB;IACTH,QAAQtB,EAAEyB;EACZ,CAAA,EAAA;EAAI;gBAHSK,cAAAA;EAKN,MAAMC,2BAA2B/B,EAAEoB,YAAW,EAAuB,GAAGJ,aAAAA,yBAAsC;IACnHK,OAAOrB,EAAEyB;IACTH,QAAQtB,EAAEyB;EACZ,CAAA,EAAA;EAAI;gBAHSM,qBAAAA;AAIf,GAzCiBb,iBAAAA,eAAAA,CAAAA,EAAAA;AAmFV,IAAMc,oBAAoB,CAACC,YAC/BA,QAAQC,UAAiBC,kBAAkBC,SAAUH,SAA0CI;",
6
- "names": ["S", "Client", "PublicKey", "IdentitySchema", "S", "Struct", "identityKey", "instanceOf", "PublicKey", "spaceKey", "optional", "profile", "displayName", "String", "avatarCid", "data", "Record", "key", "value", "Any", "CLIENT_ACTION", "CLIENT_PLUGIN", "ClientAction", "CreateIdentity", "TaggedClass", "input", "output", "JoinIdentity", "invitationCode", "Void", "ShareIdentity", "RecoverIdentity", "ResetStorage", "target", "CreateAgent", "CreateRecoveryCode", "parseClientPlugin", "plugin", "provides", "client", "Client", "undefined"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/meta.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type PluginMeta } from '@dxos/app-framework';\n\nexport const CLIENT_PLUGIN = 'dxos.org/plugin/client';\n\nexport default {\n id: CLIENT_PLUGIN,\n name: 'Client',\n} satisfies PluginMeta;\n"],
5
- "mappings": ";AAMO,IAAMA,gBAAgB;AAE7B,IAAA,eAAe;EACbC,IAAID;EACJE,MAAM;AACR;",
6
- "names": ["CLIENT_PLUGIN", "id", "name"]
7
- }
@@ -1,9 +0,0 @@
1
- import {
2
- CLIENT_PLUGIN,
3
- meta_default
4
- } from "./chunk-X4QUPYC6.mjs";
5
- export {
6
- CLIENT_PLUGIN,
7
- meta_default as default
8
- };
9
- //# sourceMappingURL=meta.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "sourcesContent": [],
5
- "mappings": "",
6
- "names": []
7
- }