@dxos/app-framework 0.6.13-main.548ca8d → 0.6.13-staging.1e988a3

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 (43) hide show
  1. package/dist/lib/browser/index.mjs +163 -169
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +182 -183
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/types/src/App.d.ts +4 -4
  8. package/dist/types/src/App.d.ts.map +1 -1
  9. package/dist/types/src/plugins/PluginHost/PluginContext.d.ts +4 -4
  10. package/dist/types/src/plugins/PluginHost/PluginContext.d.ts.map +1 -1
  11. package/dist/types/src/plugins/PluginHost/PluginHost.d.ts +8 -4
  12. package/dist/types/src/plugins/PluginHost/PluginHost.d.ts.map +1 -1
  13. package/dist/types/src/plugins/PluginHost/plugin.d.ts +83 -37
  14. package/dist/types/src/plugins/PluginHost/plugin.d.ts.map +1 -1
  15. package/dist/types/src/plugins/PluginHost/plugin.test.d.ts.map +1 -1
  16. package/dist/types/src/plugins/common/navigation.d.ts +12 -1
  17. package/dist/types/src/plugins/common/navigation.d.ts.map +1 -1
  18. package/package.json +11 -14
  19. package/project.json +8 -3
  20. package/src/App.tsx +9 -10
  21. package/src/plugins/PluginHost/PluginContext.tsx +14 -8
  22. package/src/plugins/PluginHost/PluginHost.tsx +121 -18
  23. package/src/plugins/PluginHost/plugin.test.ts +2 -1
  24. package/src/plugins/PluginHost/plugin.ts +52 -45
  25. package/src/plugins/common/navigation.ts +12 -4
  26. package/tsconfig.json +29 -1
  27. package/dist/lib/node-esm/chunk-ERPIGFBI.mjs +0 -28
  28. package/dist/lib/node-esm/chunk-ERPIGFBI.mjs.map +0 -7
  29. package/dist/lib/node-esm/chunk-IY7HCP4K.mjs +0 -22
  30. package/dist/lib/node-esm/chunk-IY7HCP4K.mjs.map +0 -7
  31. package/dist/lib/node-esm/chunk-P2TQLXZR.mjs +0 -54
  32. package/dist/lib/node-esm/chunk-P2TQLXZR.mjs.map +0 -7
  33. package/dist/lib/node-esm/index.mjs +0 -683
  34. package/dist/lib/node-esm/index.mjs.map +0 -7
  35. package/dist/lib/node-esm/meta.json +0 -1
  36. package/dist/lib/node-esm/plugin-24ZP3LDU.mjs +0 -40
  37. package/dist/lib/node-esm/plugin-24ZP3LDU.mjs.map +0 -7
  38. package/dist/lib/node-esm/plugin-5AAUGDB3.mjs +0 -168
  39. package/dist/lib/node-esm/plugin-5AAUGDB3.mjs.map +0 -7
  40. package/dist/types/src/plugins/PluginHost/PluginContainer.d.ts +0 -14
  41. package/dist/types/src/plugins/PluginHost/PluginContainer.d.ts.map +0 -1
  42. package/src/plugins/PluginHost/PluginContainer.tsx +0 -120
  43. package/vitest.config.ts +0 -9
@@ -1,3 +1,4 @@
1
+ import type { IconProps } from '@phosphor-icons/react';
1
2
  import type { FC, PropsWithChildren } from 'react';
2
3
  /**
3
4
  * Capabilities provided by a plugin.
@@ -10,48 +11,52 @@ export type PluginProvides<TProvides> = TProvides & {
10
11
  context?: FC<PropsWithChildren>;
11
12
  root?: FC<PropsWithChildren>;
12
13
  };
13
- export type PluginMeta = {
14
- /**
15
- * Globally unique ID.
16
- *
17
- * Expected to be in the form of a valid URL.
18
- *
19
- * @example dxos.org/plugin/example
20
- */
21
- id: string;
22
- /**
23
- * Short ID for use in URLs.
24
- *
25
- * NOTE: This is especially experimental and likely to change.
26
- */
27
- shortId?: string;
28
- /**
29
- * Human-readable name.
30
- */
31
- name?: string;
32
- /**
33
- * Short description of plugin functionality.
34
- */
35
- description?: string;
36
- /**
37
- * URL of home page.
38
- */
39
- homePage?: string;
40
- /**
41
- * Tags to help categorize the plugin.
42
- */
43
- tags?: string[];
44
- /**
45
- * A grep-able symbol string which can be resolved to an icon asset by @ch-ui/icons, via @ch-ui/vite-plugin-icons.
46
- */
47
- icon?: string;
48
- };
49
14
  /**
50
15
  * A unit of containment of modular functionality that can be provided to an application.
51
16
  * Plugins provide things like components, state, actions, etc. to the application.
52
17
  */
53
18
  export type Plugin<TProvides = {}> = {
54
- meta: PluginMeta;
19
+ meta: {
20
+ /**
21
+ * Globally unique ID.
22
+ *
23
+ * Expected to be in the form of a valid URL.
24
+ *
25
+ * @example dxos.org/plugin/example
26
+ */
27
+ id: string;
28
+ /**
29
+ * Short ID for use in URLs.
30
+ *
31
+ * NOTE: This is especially experimental and likely to change.
32
+ */
33
+ shortId?: string;
34
+ /**
35
+ * Human-readable name.
36
+ */
37
+ name?: string;
38
+ /**
39
+ * Short description of plugin functionality.
40
+ */
41
+ description?: string;
42
+ /**
43
+ * URL of home page.
44
+ */
45
+ homePage?: string;
46
+ /**
47
+ * Tags to help categorize the plugin.
48
+ */
49
+ tags?: string[];
50
+ /**
51
+ * Component to render icon for the plugin when displayed in a list.
52
+ * @deprecated
53
+ */
54
+ iconComponent?: FC<IconProps>;
55
+ /**
56
+ * A grep-able symbol string which can be resolved to an icon asset by @ch-ui/icons, via @ch-ui/vite-plugin-icons.
57
+ */
58
+ iconSymbol?: string;
59
+ };
55
60
  /**
56
61
  * Capabilities provided by the plugin.
57
62
  */
@@ -84,6 +89,47 @@ export type PluginDefinition<TProvides = {}, TInitializeProvides = {}> = Omit<Pl
84
89
  */
85
90
  unload?: () => Promise<void>;
86
91
  };
92
+ export declare const pluginMeta: (meta: Plugin["meta"]) => {
93
+ /**
94
+ * Globally unique ID.
95
+ *
96
+ * Expected to be in the form of a valid URL.
97
+ *
98
+ * @example dxos.org/plugin/example
99
+ */
100
+ id: string;
101
+ /**
102
+ * Short ID for use in URLs.
103
+ *
104
+ * NOTE: This is especially experimental and likely to change.
105
+ */
106
+ shortId?: string;
107
+ /**
108
+ * Human-readable name.
109
+ */
110
+ name?: string;
111
+ /**
112
+ * Short description of plugin functionality.
113
+ */
114
+ description?: string;
115
+ /**
116
+ * URL of home page.
117
+ */
118
+ homePage?: string;
119
+ /**
120
+ * Tags to help categorize the plugin.
121
+ */
122
+ tags?: string[];
123
+ /**
124
+ * Component to render icon for the plugin when displayed in a list.
125
+ * @deprecated
126
+ */
127
+ iconComponent?: FC<IconProps>;
128
+ /**
129
+ * A grep-able symbol string which can be resolved to an icon asset by @ch-ui/icons, via @ch-ui/vite-plugin-icons.
130
+ */
131
+ iconSymbol?: string;
132
+ };
87
133
  type LazyPlugin<T> = () => Promise<{
88
134
  default: (props: T) => PluginDefinition;
89
135
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/PluginHost/plugin.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAEnD;;;GAGG;AACH,MAAM,MAAM,cAAc,CAAC,SAAS,IAAI,SAAS,GAAG;IAClD;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC;IAKhC,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB;;;;;;OAMG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;;;OAIG;IAEH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,MAAM,CAAC,SAAS,GAAG,EAAE,IAAI;IACnC,IAAI,EAAE,UAAU,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC;CACrC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAAC,SAAS,GAAG,EAAE,EAAE,mBAAmB,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG;IAClG;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,CAAC;IAEzC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC,CAAC;IAEvE;;;;;OAKG;IAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC;AAEF,KAAK,UAAU,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC;IAAE,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,gBAAgB,CAAA;CAAE,CAAC,CAAC;AAEhF,yBAAiB,MAAM,CAAC;IACf,MAAM,IAAI,GAAI,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,4CAKlD,CAAC;CACH"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/PluginHost/plugin.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAEnD;;;GAGG;AACH,MAAM,MAAM,cAAc,CAAC,SAAS,IAAI,SAAS,GAAG;IAClD;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC;IAKhC,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC;CAC9B,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,MAAM,CAAC,SAAS,GAAG,EAAE,IAAI;IACnC,IAAI,EAAE;QACJ;;;;;;WAMG;QACH,EAAE,EAAE,MAAM,CAAC;QAEX;;;;WAIG;QAEH,OAAO,CAAC,EAAE,MAAM,CAAC;QAEjB;;WAEG;QACH,IAAI,CAAC,EAAE,MAAM,CAAC;QAEd;;WAEG;QACH,WAAW,CAAC,EAAE,MAAM,CAAC;QAErB;;WAEG;QACH,QAAQ,CAAC,EAAE,MAAM,CAAC;QAElB;;WAEG;QACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAEhB;;;WAGG;QACH,aAAa,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC;QAE9B;;WAEG;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IAEF;;OAEG;IACH,QAAQ,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC;CACrC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAAC,SAAS,GAAG,EAAE,EAAE,mBAAmB,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG;IAClG;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,CAAC;IAEzC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC,CAAC;IAEvE;;;;;OAKG;IAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,UAAU,SAAU,MAAM,CAAC,MAAM,CAAC;IAvF3C;;;;;;OAMG;QACC,MAAM;IAEV;;;;OAIG;cAEO,MAAM;IAEhB;;OAEG;WACI,MAAM;IAEb;;OAEG;kBACW,MAAM;IAEpB;;OAEG;eACQ,MAAM;IAEjB;;OAEG;WACI,MAAM,EAAE;IAEf;;;OAGG;oBACa,EAAE,CAAC,SAAS,CAAC;IAE7B;;OAEG;iBACU,MAAM;CAyCiC,CAAC;AAEzD,KAAK,UAAU,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC;IAAE,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,gBAAgB,CAAA;CAAE,CAAC,CAAC;AAEhF,yBAAiB,MAAM,CAAC;IACf,MAAM,IAAI,GAAI,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,4CAKlD,CAAC;CACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.test.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/PluginHost/plugin.test.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAQhC,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,KAAK,YAAY,CAAC,CAAC,IAAI;IACrB,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAClB,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAG,YAAY,CAAC,CAAC,CAAoB,CAAC;AAE3F,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;CAChC,CAAC;AAEF,qBAAa,UAAU;IACrB,QAAQ,CAAC,WAAW,mBAA0B;gBAClC,EAAE,QAAQ,EAAE,EAAE,WAAW;IAIrC,YAAY,GAAI,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,KAAG,CAAC,GAAG,SAAS,CAAkC;CACvF;AAYD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,GAAG,SAAS,KAAK,IAAI,CAAC;CACxC;AAED,eAAO,MAAM,SAAS,EAAE,SAAS,CAAC,SAAS,CAAwB,CAAC;AAEpE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACpC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,KAAK,IAAI,CAAC;CACvD;AAED,eAAO,MAAM,UAAU,EAAE,SAAS,CAAC,UAAU,CAAyB,CAAC;AAGvE,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;IAAE,MAAM,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAA;CAAE,CAAC,CAAC;AAE1F,eAAO,MAAM,OAAO,EAAE,SAAS,CAAC,OAAO,CAAmB,CAAC"}
1
+ {"version":3,"file":"plugin.test.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/PluginHost/plugin.test.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAQhC,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,KAAK,YAAY,CAAC,CAAC,IAAI;IACrB,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAClB,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAG,YAAY,CAAC,CAAC,CAAoB,CAAC;AAE3F,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;CAChC,CAAC;AAEF,qBAAa,UAAU;IACrB,QAAQ,CAAC,WAAW,mBAA0B;gBAClC,EAAE,QAAQ,EAAE,EAAE,WAAW;IAIrC,YAAY,GAAI,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,KAAG,CAAC,GAAG,SAAS,CAAkC;CACvF;AAYD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,GAAG,SAAS,KAAK,IAAI,CAAC;CACxC;AAED,eAAO,MAAM,SAAS,EAAE,SAAS,CAAC,SAAS,CAAwB,CAAC;AAEpE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACpC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,KAAK,IAAI,CAAC;CACvD;AAED,eAAO,MAAM,UAAU,EAAE,SAAS,CAAC,UAAU,CAAyB,CAAC;AAGvE,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;IAAE,MAAM,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAA;CAAE,CAAC,CAAC;AAE1F,eAAO,MAAM,OAAO,EAAE,SAAS,CAAC,OAAO,CAAmB,CAAC"}
@@ -1,5 +1,5 @@
1
- import { Schema as S } from '@effect/schema';
2
1
  import { z } from 'zod';
2
+ import { S } from '@dxos/echo-schema';
3
3
  import type { IntentData } from '../IntentPlugin';
4
4
  import type { Plugin } from '../PluginHost';
5
5
  export declare const SLUG_LIST_SEPARATOR = "+";
@@ -80,6 +80,17 @@ export type LayoutContainerProps<T> = T & {
80
80
  role?: string;
81
81
  coordinate?: LayoutCoordinate;
82
82
  };
83
+ /**
84
+ * Basic state provided by a navigation plugin.
85
+ */
86
+ export declare const Attention: z.ZodObject<{
87
+ attended: z.ZodOptional<z.ZodSet<z.ZodString>>;
88
+ }, "strip", z.ZodTypeAny, {
89
+ attended?: Set<string> | undefined;
90
+ }, {
91
+ attended?: Set<string> | undefined;
92
+ }>;
93
+ export type Attention = z.infer<typeof Attention>;
83
94
  /**
84
95
  * Provides for a plugin that can manage the app navigation.
85
96
  */
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/common/navigation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/common/navigation.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/app-framework",
3
- "version": "0.6.13-main.548ca8d",
3
+ "version": "0.6.13-staging.1e988a3",
4
4
  "description": "A framework for building applications from composible plugins.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -10,8 +10,7 @@
10
10
  ".": {
11
11
  "browser": "./dist/lib/browser/index.mjs",
12
12
  "node": {
13
- "require": "./dist/lib/node/index.cjs",
14
- "default": "./dist/lib/node-esm/index.mjs"
13
+ "default": "./dist/lib/node/index.cjs"
15
14
  },
16
15
  "types": "./dist/types/src/index.d.ts"
17
16
  }
@@ -21,26 +20,24 @@
21
20
  "*": {}
22
21
  },
23
22
  "dependencies": {
24
- "@effect/schema": "^0.75.1",
25
23
  "@phosphor-icons/react": "^2.1.5",
26
24
  "@preact/signals-core": "^1.6.0",
27
25
  "zod": "^3.22.4",
28
- "@dxos/app-graph": "0.6.13-main.548ca8d",
29
- "@dxos/async": "0.6.13-main.548ca8d",
30
- "@dxos/client-protocol": "0.6.13-main.548ca8d",
31
- "@dxos/echo-schema": "0.6.13-main.548ca8d",
32
- "@dxos/invariant": "0.6.13-main.548ca8d",
33
- "@dxos/debug": "0.6.13-main.548ca8d",
34
- "@dxos/log": "0.6.13-main.548ca8d",
35
- "@dxos/util": "0.6.13-main.548ca8d",
36
- "@dxos/local-storage": "0.6.13-main.548ca8d"
26
+ "@dxos/app-graph": "0.6.13-staging.1e988a3",
27
+ "@dxos/async": "0.6.13-staging.1e988a3",
28
+ "@dxos/client-protocol": "0.6.13-staging.1e988a3",
29
+ "@dxos/debug": "0.6.13-staging.1e988a3",
30
+ "@dxos/echo-schema": "0.6.13-staging.1e988a3",
31
+ "@dxos/local-storage": "0.6.13-staging.1e988a3",
32
+ "@dxos/invariant": "0.6.13-staging.1e988a3",
33
+ "@dxos/log": "0.6.13-staging.1e988a3",
34
+ "@dxos/util": "0.6.13-staging.1e988a3"
37
35
  },
38
36
  "devDependencies": {
39
37
  "@types/react": "~18.2.0",
40
38
  "react": "~18.2.0"
41
39
  },
42
40
  "peerDependencies": {
43
- "@phosphor-icons/react": "^2.1.5",
44
41
  "react": "~18.2.0"
45
42
  },
46
43
  "publishConfig": {
package/project.json CHANGED
@@ -16,10 +16,15 @@
16
16
  }
17
17
  },
18
18
  "lint": {},
19
- "test": {}
19
+ "test": {
20
+ "options": {
21
+ "ciEnvironments": [
22
+ "nodejs"
23
+ ]
24
+ }
25
+ }
20
26
  },
21
27
  "implicitDependencies": [
22
- "esbuild",
23
- "node-std"
28
+ "test"
24
29
  ]
25
30
  }
package/src/App.tsx CHANGED
@@ -15,7 +15,7 @@ import SurfaceMeta from './plugins/SurfacePlugin/meta';
15
15
  * Initializes plugins and renders the root components.
16
16
  *
17
17
  * @example
18
- * const meta = [LayoutMeta, MyPluginMeta];
18
+ * const order = [LayoutMeta, MyPluginMeta];
19
19
  * const plugins = {
20
20
  * [LayoutMeta.id]: Plugin.lazy(() => import('./plugins/LayoutPlugin/plugin')),
21
21
  * [MyPluginMeta.id]: Plugin.lazy(() => import('./plugins/MyPlugin/plugin')),
@@ -30,29 +30,28 @@ import SurfaceMeta from './plugins/SurfacePlugin/meta';
30
30
  * </StrictMode>,
31
31
  * );
32
32
  *
33
+ * @param params.order Total ordering of plugins.
33
34
  * @param params.plugins All plugins available to the application.
34
- * @param params.meta All plugin metadata.
35
35
  * @param params.core Core plugins which will always be enabled.
36
- * @param params.defaults Default plugins are enabled by default but can be disabled by the user.
36
+ * @param params.default Default plugins are enabled by default but can be disabled by the user.
37
37
  * @param params.fallback Fallback component to render while plugins are initializing.
38
38
  */
39
- export const createApp = ({ meta, plugins, core, ...params }: BootstrapPluginsParams) => {
39
+ export const createApp = ({ order, plugins, core = order.map(({ id }) => id), ...params }: BootstrapPluginsParams) => {
40
40
  const host = PluginHost({
41
+ order: [SurfaceMeta, IntentMeta, ...order],
41
42
  plugins: {
42
43
  ...plugins,
43
44
  [SurfaceMeta.id]: Plugin.lazy(() => import('./plugins/SurfacePlugin/plugin')),
44
45
  [IntentMeta.id]: Plugin.lazy(() => import('./plugins/IntentPlugin/plugin')),
45
46
  },
46
- // TODO(burdon): Why not include in core?
47
- meta: [SurfaceMeta, IntentMeta, ...meta],
48
47
  core: [SurfaceMeta.id, IntentMeta.id, ...core],
49
48
  ...params,
50
49
  });
51
50
 
52
- invariant(host.provides);
53
- const { context: Context, root: Root } = host.provides;
54
- invariant(Context);
55
- invariant(Root);
51
+ invariant(host.provides?.context);
52
+ invariant(host.provides?.root);
53
+ const Context = host.provides.context;
54
+ const Root = host.provides.root;
56
55
 
57
56
  return () => (
58
57
  <Context>
@@ -2,12 +2,11 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { createContext, useContext, useMemo } from 'react';
5
+ import { type Context, type Provider, createContext, useContext, useMemo } from 'react';
6
6
 
7
- import { raise } from '@dxos/debug';
8
7
  import { nonNullable } from '@dxos/util';
9
8
 
10
- import { type Plugin, type PluginMeta } from './plugin';
9
+ import { type Plugin } from './plugin';
11
10
  import { findPlugin, resolvePlugin } from '../helpers';
12
11
 
13
12
  export type PluginContext = {
@@ -33,9 +32,9 @@ export type PluginContext = {
33
32
 
34
33
  /**
35
34
  * All available plugins.
36
- * NOTE: This is metadata rather than just ids because it includes plugins which have not been fully loaded yet.
37
35
  */
38
- available: PluginMeta[];
36
+ // This is metadata rather then just ids because it includes plugins which have not been fully loaded yet.
37
+ available: Plugin['meta'][];
39
38
 
40
39
  /**
41
40
  * Mark plugin as enabled.
@@ -44,12 +43,19 @@ export type PluginContext = {
44
43
  setPlugin: (id: string, enabled: boolean) => void;
45
44
  };
46
45
 
47
- const PluginContext = createContext<PluginContext | undefined>(undefined);
46
+ const PluginContext: Context<PluginContext> = createContext<PluginContext>({
47
+ ready: false,
48
+ core: [],
49
+ enabled: [],
50
+ plugins: [],
51
+ available: [],
52
+ setPlugin: () => {},
53
+ });
48
54
 
49
55
  /**
50
56
  * Get all plugins.
51
57
  */
52
- export const usePlugins = (): PluginContext => useContext(PluginContext) ?? raise(new Error('Missing PluginContext'));
58
+ export const usePlugins = (): PluginContext => useContext(PluginContext);
53
59
 
54
60
  /**
55
61
  * Get a plugin by ID.
@@ -75,4 +81,4 @@ export const useResolvePlugins = <T,>(predicate: (plugin: Plugin) => Plugin<T> |
75
81
  return useMemo(() => plugins.map(predicate).filter(nonNullable), [plugins, predicate]);
76
82
  };
77
83
 
78
- export const PluginProvider = PluginContext.Provider;
84
+ export const PluginProvider: Provider<PluginContext> = PluginContext.Provider;
@@ -2,20 +2,19 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import React, { type ReactNode } from 'react';
5
+ import React, { type JSX, type FC, type PropsWithChildren, type ReactNode, useEffect, useState } from 'react';
6
6
 
7
7
  import { LocalStorageStore } from '@dxos/local-storage';
8
+ import { log } from '@dxos/log';
8
9
 
9
- import { PluginContainer } from './PluginContainer';
10
10
  import { type PluginContext, PluginProvider } from './PluginContext';
11
- import { type Plugin, type PluginDefinition, type PluginMeta } from './plugin';
11
+ import { type Plugin, type PluginDefinition, type PluginProvides } from './plugin';
12
12
  import { ErrorBoundary } from '../SurfacePlugin';
13
13
 
14
14
  export type BootstrapPluginsParams = {
15
+ order: PluginDefinition['meta'][];
15
16
  plugins: Record<string, () => Promise<PluginDefinition>>;
16
- // Ordered list of plugins.
17
- meta: PluginMeta[];
18
- core: string[];
17
+ core?: string[];
19
18
  defaults?: string[];
20
19
  fallback?: ErrorBoundary['props']['fallback'];
21
20
  placeholder?: ReactNode;
@@ -34,9 +33,9 @@ const PLUGIN_HOST = 'dxos.org/plugin/host';
34
33
  * Bootstraps an application by initializing plugins and rendering root components.
35
34
  */
36
35
  export const PluginHost = ({
37
- plugins,
38
- meta,
39
- core,
36
+ order,
37
+ plugins: definitions,
38
+ core = [],
40
39
  defaults = [],
41
40
  fallback = DefaultFallback,
42
41
  placeholder = null,
@@ -46,7 +45,7 @@ export const PluginHost = ({
46
45
  core,
47
46
  enabled: [...defaults],
48
47
  plugins: [],
49
- available: meta.filter(({ id }) => !core.includes(id)),
48
+ available: order.filter(({ id }) => !core.includes(id)),
50
49
  setPlugin: (id: string, enabled: boolean) => {
51
50
  if (enabled) {
52
51
  state.values.enabled.push(id);
@@ -57,7 +56,6 @@ export const PluginHost = ({
57
56
  },
58
57
  });
59
58
 
60
- // Register and load values.
61
59
  state.prop({ key: 'enabled', type: LocalStorageStore.json<string[]>() });
62
60
 
63
61
  return {
@@ -67,13 +65,11 @@ export const PluginHost = ({
67
65
  },
68
66
  provides: {
69
67
  plugins: state.values,
70
- context: ({ children }) => {
71
- return <PluginProvider value={state.values}>{children}</PluginProvider>;
72
- },
68
+ context: ({ children }) => <PluginProvider value={state.values}>{children}</PluginProvider>,
73
69
  root: () => {
74
70
  return (
75
71
  <ErrorBoundary fallback={fallback}>
76
- <PluginContainer plugins={plugins} core={core} state={state.values} placeholder={placeholder} />
72
+ <Root order={order} core={core} definitions={definitions} state={state.values} placeholder={placeholder} />
77
73
  </ErrorBoundary>
78
74
  );
79
75
  },
@@ -81,9 +77,6 @@ export const PluginHost = ({
81
77
  };
82
78
  };
83
79
 
84
- /**
85
- * Fallback does not use tailwind or theme.
86
- */
87
80
  const DefaultFallback = ({ error }: { error: Error }) => {
88
81
  return (
89
82
  <div style={{ padding: '1rem' }}>
@@ -93,3 +86,113 @@ const DefaultFallback = ({ error }: { error: Error }) => {
93
86
  </div>
94
87
  );
95
88
  };
89
+
90
+ type RootProps = {
91
+ order: PluginDefinition['meta'][];
92
+ state: PluginContext;
93
+ definitions: Record<string, () => Promise<PluginDefinition>>;
94
+ core: string[];
95
+ placeholder: ReactNode;
96
+ };
97
+
98
+ const Root = ({ order, core: corePluginIds, definitions, state, placeholder }: RootProps) => {
99
+ const [error, setError] = useState<unknown>();
100
+
101
+ useEffect(() => {
102
+ log('initializing plugins', { enabled: state.enabled });
103
+ const timeout = setTimeout(async () => {
104
+ try {
105
+ const enabledIds = [...corePluginIds, ...state.enabled].sort((a, b) => {
106
+ const indexA = order.findIndex(({ id }) => id === a);
107
+ const indexB = order.findIndex(({ id }) => id === b);
108
+ return indexA - indexB;
109
+ });
110
+
111
+ const enabled = await Promise.all(
112
+ enabledIds
113
+ .map((id) => definitions[id])
114
+ // If local storage indicates a plugin is enabled, but it is not available, ignore it.
115
+ .filter((definition): definition is () => Promise<PluginDefinition> => Boolean(definition))
116
+ .map((definition) => definition()),
117
+ );
118
+
119
+ const plugins = await Promise.all(
120
+ enabled.map(async (definition) => {
121
+ const plugin = await initializePlugin(definition).catch((err) => {
122
+ log.error('Failed to initialize plugin:', { id: definition.meta.id, err });
123
+ return undefined;
124
+ });
125
+ return plugin;
126
+ }),
127
+ ).then((plugins) => plugins.filter((plugin): plugin is Plugin => Boolean(plugin)));
128
+ log('plugins initialized', { plugins });
129
+
130
+ await Promise.all(enabled.map((pluginDefinition) => pluginDefinition.ready?.(plugins)));
131
+ log('plugins ready', { plugins });
132
+
133
+ state.plugins = plugins;
134
+ state.ready = true;
135
+ } catch (err) {
136
+ setError(err);
137
+ }
138
+ });
139
+
140
+ return () => {
141
+ clearTimeout(timeout);
142
+ state.ready = false;
143
+ // TODO(wittjosiah): Does this ever need to be called prior to having dynamic plugins?
144
+ // void Promise.all(enabled.map((definition) => definition.unload?.()));
145
+ };
146
+ }, []);
147
+
148
+ if (error) {
149
+ throw error;
150
+ }
151
+
152
+ if (!state.ready) {
153
+ return <>{placeholder}</>;
154
+ }
155
+
156
+ const ComposedContext = composeContext(state.plugins);
157
+
158
+ return <ComposedContext>{rootComponents(state.plugins)}</ComposedContext>;
159
+ };
160
+
161
+ /**
162
+ * Resolve a `PluginDefinition` into a fully initialized `Plugin`.
163
+ */
164
+ export const initializePlugin = async <T, U>(pluginDefinition: PluginDefinition<T, U>): Promise<Plugin<T & U>> => {
165
+ const provides = await pluginDefinition.initialize?.();
166
+ return {
167
+ ...pluginDefinition,
168
+ provides: {
169
+ ...pluginDefinition.provides,
170
+ ...provides,
171
+ } as PluginProvides<T & U>,
172
+ };
173
+ };
174
+
175
+ const rootComponents = (plugins: Plugin[]) => {
176
+ return plugins
177
+ .map((plugin) => {
178
+ const Component = plugin.provides.root;
179
+ if (Component) {
180
+ return <Component key={plugin.meta.id} />;
181
+ } else {
182
+ return null;
183
+ }
184
+ })
185
+ .filter((node): node is JSX.Element => Boolean(node));
186
+ };
187
+
188
+ const composeContext = (plugins: Plugin[]) => {
189
+ return compose(plugins.map((p) => p.provides.context!).filter(Boolean));
190
+ };
191
+
192
+ const compose = (contexts: FC<PropsWithChildren>[]) => {
193
+ return [...contexts].reduce((Acc, Next) => ({ children }) => (
194
+ <Acc>
195
+ <Next>{children}</Next>
196
+ </Acc>
197
+ ));
198
+ };
@@ -2,10 +2,11 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
+ import { expect } from 'chai';
5
6
  import { type FC } from 'react';
6
- import { describe, expect, test } from 'vitest';
7
7
 
8
8
  import { log } from '@dxos/log';
9
+ import { describe, test } from '@dxos/test';
9
10
 
10
11
  import { type Plugin } from './plugin';
11
12