@dxos/app-framework 0.11.1 → 0.12.0-next-73daef452f1464b62efdbca75fb0067c1066f264
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/API.md +275 -0
- package/ARCHITECTURE.md +190 -0
- package/CHANGELOG.md +243 -0
- package/README.md +3 -0
- package/TASKS.md +25 -0
- package/bin/dx-plugin.mjs +7 -0
- package/dist/lib/chunk-SurfaceManager.mjs +106 -103
- package/dist/lib/chunk-SurfaceManager.mjs.map +1 -1
- package/dist/lib/chunk-capability.mjs +379 -10
- package/dist/lib/chunk-capability.mjs.map +1 -1
- package/dist/lib/chunk-capability2.mjs +17 -0
- package/dist/lib/chunk-capability2.mjs.map +1 -0
- package/dist/lib/chunk-devtools.mjs +110 -0
- package/dist/lib/chunk-devtools.mjs.map +1 -0
- package/dist/lib/chunk-history-tracker.mjs +4 -64
- package/dist/lib/chunk-history-tracker.mjs.map +1 -1
- package/dist/lib/chunk-plugin-manager.mjs +2225 -1147
- package/dist/lib/chunk-plugin-manager.mjs.map +1 -1
- package/dist/lib/chunk-process-manager-capability.mjs +83 -32
- package/dist/lib/chunk-process-manager-capability.mjs.map +1 -1
- package/dist/lib/chunk-ui.mjs +753 -0
- package/dist/lib/chunk-ui.mjs.map +1 -0
- package/dist/lib/cli.mjs +11 -8
- package/dist/lib/cli.mjs.map +1 -1
- package/dist/lib/common/Role.mjs +19 -0
- package/dist/lib/common/Role.mjs.map +1 -0
- package/dist/lib/common/activation-events.mjs +32 -19
- package/dist/lib/common/activation-events.mjs.map +1 -1
- package/dist/lib/common/capabilities.mjs +38 -27
- package/dist/lib/common/capabilities.mjs.map +1 -1
- package/dist/lib/core/activation-event.mjs +33 -2
- package/dist/lib/core/activation-event.mjs.map +1 -1
- package/dist/lib/core/capability-manager.mjs +203 -0
- package/dist/lib/core/capability-manager.mjs.map +1 -0
- package/dist/lib/core/capability.mjs +2 -189
- package/dist/lib/core/plugin-asset-cache.mjs +28 -0
- package/dist/lib/core/plugin-asset-cache.mjs.map +1 -0
- package/dist/lib/core/plugin-manager.mjs +14 -2
- package/dist/lib/core/plugin-manager.mjs.map +1 -0
- package/dist/lib/{chunk-plugin-manifest.mjs → core/plugin-manifest.mjs} +10 -9
- package/dist/lib/core/plugin-manifest.mjs.map +1 -0
- package/dist/lib/core/plugin.mjs +61 -58
- package/dist/lib/core/plugin.mjs.map +1 -1
- package/dist/lib/core/registry.mjs +80 -0
- package/dist/lib/core/registry.mjs.map +1 -0
- package/dist/lib/core/url-loader.mjs +326 -2
- package/dist/lib/core/url-loader.mjs.map +1 -0
- package/dist/lib/index.mjs +47 -45
- package/dist/lib/index.mjs.map +1 -1
- package/dist/lib/plugin-process-manager/history/history-tracker.mjs +2 -0
- package/dist/lib/plugin-process-manager/history/undo-mapping.mjs +47 -0
- package/dist/lib/plugin-process-manager/history/undo-mapping.mjs.map +1 -0
- package/dist/lib/plugin-process-manager/history/undo-registry.mjs +22 -0
- package/dist/lib/plugin-process-manager/history/undo-registry.mjs.map +1 -0
- package/dist/lib/testing/react.mjs +3 -3
- package/dist/lib/testing/react.mjs.map +1 -1
- package/dist/lib/testing.mjs +106 -40
- package/dist/lib/testing.mjs.map +1 -1
- package/dist/lib/ui.mjs +3 -636
- package/dist/lib/vite-plugin/packages.mjs +135 -0
- package/dist/lib/vite-plugin/packages.mjs.map +1 -0
- package/dist/lib/vite-plugin.mjs +51 -164
- package/dist/lib/vite-plugin.mjs.map +1 -1
- package/dist/plugin/node-esm/index.mjs +129 -76
- package/dist/plugin/node-esm/index.mjs.map +4 -4
- package/dist/plugin/node-esm/meta.json +1 -1
- package/dist/plugin-cli/node-esm/main.mjs +754 -0
- package/dist/plugin-cli/node-esm/main.mjs.map +7 -0
- package/dist/plugin-cli/node-esm/meta.json +1 -0
- package/dist/types/src/cli/cli.d.ts +8 -6
- package/dist/types/src/cli/cli.d.ts.map +1 -1
- package/dist/types/src/common/activation-events.d.ts +25 -12
- package/dist/types/src/common/activation-events.d.ts.map +1 -1
- package/dist/types/src/common/capabilities.d.ts +44 -32
- package/dist/types/src/common/capabilities.d.ts.map +1 -1
- package/dist/types/src/common/capabilities.test.d.ts +2 -0
- package/dist/types/src/common/capabilities.test.d.ts.map +1 -0
- package/dist/types/src/common/translations.d.ts +5 -5
- package/dist/types/src/common/translations.d.ts.map +1 -1
- package/dist/types/src/core/activation-event.d.ts +28 -0
- package/dist/types/src/core/activation-event.d.ts.map +1 -1
- package/dist/types/src/core/capability-manager.d.ts +28 -2
- package/dist/types/src/core/capability-manager.d.ts.map +1 -1
- package/dist/types/src/core/capability.d.ts +309 -42
- package/dist/types/src/core/capability.d.ts.map +1 -1
- package/dist/types/src/core/capability.test.d.ts +2 -0
- package/dist/types/src/core/capability.test.d.ts.map +1 -0
- package/dist/types/src/core/errors.d.ts +230 -0
- package/dist/types/src/core/errors.d.ts.map +1 -0
- package/dist/types/src/core/index.d.ts +1 -0
- package/dist/types/src/core/index.d.ts.map +1 -1
- package/dist/types/src/core/plugin-manager/activation-graph.d.ts +83 -0
- package/dist/types/src/core/plugin-manager/activation-graph.d.ts.map +1 -0
- package/dist/types/src/core/plugin-manager/activation-graph.test.d.ts +2 -0
- package/dist/types/src/core/plugin-manager/activation-graph.test.d.ts.map +1 -0
- package/dist/types/src/core/plugin-manager/activation-scheduler.d.ts +98 -0
- package/dist/types/src/core/plugin-manager/activation-scheduler.d.ts.map +1 -0
- package/dist/types/src/core/plugin-manager/idle.d.ts +13 -0
- package/dist/types/src/core/plugin-manager/idle.d.ts.map +1 -0
- package/dist/types/src/core/plugin-manager/index.d.ts +2 -0
- package/dist/types/src/core/plugin-manager/index.d.ts.map +1 -0
- package/dist/types/src/core/plugin-manager/manager-state.d.ts +135 -0
- package/dist/types/src/core/plugin-manager/manager-state.d.ts.map +1 -0
- package/dist/types/src/core/plugin-manager/manager-types.d.ts +104 -0
- package/dist/types/src/core/plugin-manager/manager-types.d.ts.map +1 -0
- package/dist/types/src/core/plugin-manager/module-loader.d.ts +74 -0
- package/dist/types/src/core/plugin-manager/module-loader.d.ts.map +1 -0
- package/dist/types/src/core/plugin-manager/plugin-catalog.d.ts +74 -0
- package/dist/types/src/core/plugin-manager/plugin-catalog.d.ts.map +1 -0
- package/dist/types/src/core/{plugin-manager.d.ts → plugin-manager/plugin-manager.d.ts} +36 -107
- package/dist/types/src/core/plugin-manager/plugin-manager.d.ts.map +1 -0
- package/dist/types/src/core/plugin-manager/plugin-manager.test.d.ts.map +1 -0
- package/dist/types/src/core/plugin-manifest.d.ts +19 -19
- package/dist/types/src/core/plugin-manifest.d.ts.map +1 -1
- package/dist/types/src/core/plugin.d.ts +173 -98
- package/dist/types/src/core/plugin.d.ts.map +1 -1
- package/dist/types/src/core/plugin.test.d.ts +2 -0
- package/dist/types/src/core/plugin.test.d.ts.map +1 -0
- package/dist/types/src/core/registry.d.ts +3 -2
- package/dist/types/src/core/registry.d.ts.map +1 -1
- package/dist/types/src/devtools.d.ts +60 -0
- package/dist/types/src/devtools.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/plugin-cli/barrel.d.ts +21 -0
- package/dist/types/src/plugin-cli/barrel.d.ts.map +1 -0
- package/dist/types/src/plugin-cli/generate.d.ts +21 -0
- package/dist/types/src/plugin-cli/generate.d.ts.map +1 -0
- package/dist/types/src/plugin-cli/generate.test.d.ts +2 -0
- package/dist/types/src/plugin-cli/generate.test.d.ts.map +1 -0
- package/dist/types/src/plugin-cli/main.d.ts +2 -0
- package/dist/types/src/plugin-cli/main.d.ts.map +1 -0
- package/dist/types/src/plugin-cli/maker-defaults.d.ts +18 -0
- package/dist/types/src/plugin-cli/maker-defaults.d.ts.map +1 -0
- package/dist/types/src/plugin-cli/ts-util.d.ts +72 -0
- package/dist/types/src/plugin-cli/ts-util.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/ProcessManagerPlugin.d.ts.map +1 -1
- package/dist/types/src/plugin-process-manager/history/capability.d.ts +1 -1
- package/dist/types/src/plugin-process-manager/history/types.d.ts +1 -1
- package/dist/types/src/plugin-process-manager/history/types.d.ts.map +1 -1
- package/dist/types/src/plugin-process-manager/history/undo-mapping.d.ts +1 -1
- package/dist/types/src/plugin-process-manager/history/undo-mapping.d.ts.map +1 -1
- package/dist/types/src/plugin-process-manager/history/undo-registry.d.ts +1 -1
- package/dist/types/src/plugin-process-manager/history/undo-registry.d.ts.map +1 -1
- package/dist/types/src/plugin-process-manager/idb-key-value-store.d.ts +1 -1
- package/dist/types/src/plugin-process-manager/idb-key-value-store.d.ts.map +1 -1
- package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts +10 -1
- package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts.map +1 -1
- package/dist/types/src/plugin-process-manager/process-manager-capability.test.d.ts +2 -0
- package/dist/types/src/plugin-process-manager/process-manager-capability.test.d.ts.map +1 -0
- package/dist/types/src/plugin-process-manager/testing.d.ts +1 -1
- package/dist/types/src/plugin-process-manager/testing.d.ts.map +1 -1
- package/dist/types/src/testing/demand-gated.d.ts +26 -0
- package/dist/types/src/testing/demand-gated.d.ts.map +1 -0
- package/dist/types/src/testing/harness.d.ts +21 -5
- package/dist/types/src/testing/harness.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +1 -0
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/operationCapture.d.ts +2 -2
- package/dist/types/src/testing/operationCapture.d.ts.map +1 -1
- package/dist/types/src/testing/withPluginManager.d.ts +8 -3
- package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
- package/dist/types/src/testing/withPluginManager.stories.d.ts +2 -1
- package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
- package/dist/types/src/testing/withSurfaceDebug.d.ts +1 -1
- package/dist/types/src/testing/withSurfaceDebug.d.ts.map +1 -1
- package/dist/types/src/ui/components/App/App.d.ts.map +1 -1
- package/dist/types/src/ui/components/App/App.stories.d.ts +2 -1
- package/dist/types/src/ui/components/App/App.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/App/loader.d.ts +5 -0
- package/dist/types/src/ui/components/App/loader.d.ts.map +1 -1
- package/dist/types/src/ui/components/HomeSection/HomeSection.stories.d.ts +2 -1
- package/dist/types/src/ui/components/HomeSection/HomeSection.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/PluginManager/PluginManagerContext.stories.d.ts +2 -1
- package/dist/types/src/ui/components/PluginManager/PluginManagerContext.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts +2 -3
- package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts +3 -2
- package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceDebug.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceManager.d.ts +22 -3
- package/dist/types/src/ui/components/Surface/SurfaceManager.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/index.d.ts +16 -16
- package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/types.d.ts +7 -19
- package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -1
- package/dist/types/src/ui/hooks/index.d.ts +1 -0
- package/dist/types/src/ui/hooks/index.d.ts.map +1 -1
- package/dist/types/src/ui/hooks/useActivationSignal.d.ts +9 -0
- package/dist/types/src/ui/hooks/useActivationSignal.d.ts.map +1 -0
- package/dist/types/src/ui/hooks/useApp.d.ts +0 -1
- package/dist/types/src/ui/hooks/useApp.d.ts.map +1 -1
- package/dist/types/src/ui/hooks/useCapabilities.d.ts +20 -6
- package/dist/types/src/ui/hooks/useCapabilities.d.ts.map +1 -1
- package/dist/types/src/ui/hooks/useProcessManagerRuntime.d.ts +2 -2
- package/dist/types/src/ui/hooks/useProcessManagerRuntime.d.ts.map +1 -1
- package/dist/types/src/ui/hooks/useSettingsState.d.ts +1 -1
- package/dist/types/src/ui/hooks/useSettingsState.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/import-map/index.d.ts +8 -0
- package/dist/types/src/vite-plugin/import-map/index.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/import-map/index.test.d.ts +2 -0
- package/dist/types/src/vite-plugin/import-map/index.test.d.ts.map +1 -0
- package/dist/types/src/vite-plugin/load.d.ts +7 -5
- package/dist/types/src/vite-plugin/load.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/packages.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/docs/activation-sequence.md +138 -0
- package/moon.yml +18 -1
- package/package.json +87 -44
- package/src/cli/cli.ts +14 -10
- package/src/common/activation-events.ts +27 -21
- package/src/common/capabilities.test.ts +71 -0
- package/src/common/capabilities.ts +65 -39
- package/src/common/translations.ts +10 -11
- package/src/core/activation-event.ts +31 -0
- package/src/core/capability-manager.test.ts +53 -15
- package/src/core/capability-manager.ts +110 -10
- package/src/core/capability.test.ts +124 -0
- package/src/core/capability.ts +530 -88
- package/src/core/capability.tst.ts +52 -0
- package/src/core/errors.ts +82 -0
- package/src/core/index.ts +1 -0
- package/src/core/plugin-manager/activation-graph.test.ts +177 -0
- package/src/core/plugin-manager/activation-graph.ts +269 -0
- package/src/core/plugin-manager/activation-scheduler.ts +1012 -0
- package/src/core/plugin-manager/idle.ts +67 -0
- package/src/core/plugin-manager/index.ts +7 -0
- package/src/core/plugin-manager/manager-state.ts +376 -0
- package/src/core/plugin-manager/manager-types.ts +68 -0
- package/src/core/plugin-manager/module-loader.ts +559 -0
- package/src/core/plugin-manager/plugin-catalog.ts +683 -0
- package/src/core/plugin-manager/plugin-manager.test.ts +3417 -0
- package/src/core/plugin-manager/plugin-manager.ts +611 -0
- package/src/core/plugin-manifest.ts +6 -5
- package/src/core/plugin.test.ts +374 -0
- package/src/core/plugin.ts +227 -80
- package/src/core/registry.ts +3 -2
- package/src/devtools.ts +219 -0
- package/src/globals.d.ts +16 -0
- package/src/index.ts +1 -0
- package/src/plugin-cli/barrel.ts +155 -0
- package/src/plugin-cli/generate.test.ts +171 -0
- package/src/plugin-cli/generate.ts +295 -0
- package/src/plugin-cli/main.ts +53 -0
- package/src/plugin-cli/maker-defaults.ts +152 -0
- package/src/plugin-cli/ts-util.ts +326 -0
- package/src/plugin-process-manager/ProcessManagerPlugin.ts +36 -13
- package/src/plugin-process-manager/history/capability.ts +6 -8
- package/src/plugin-process-manager/history/history-tracker.test.ts +17 -18
- package/src/plugin-process-manager/history/types.ts +1 -1
- package/src/plugin-process-manager/history/undo-mapping.ts +1 -1
- package/src/plugin-process-manager/history/undo-registry.test.ts +1 -1
- package/src/plugin-process-manager/history/undo-registry.ts +1 -1
- package/src/plugin-process-manager/idb-key-value-store.ts +3 -11
- package/src/plugin-process-manager/process-manager-capability.test.ts +144 -0
- package/src/plugin-process-manager/process-manager-capability.ts +88 -27
- package/src/plugin-process-manager/testing.ts +9 -9
- package/src/testing/demand-gated.ts +54 -0
- package/src/testing/harness.ts +35 -15
- package/src/testing/index.ts +1 -0
- package/src/testing/operationCapture.ts +3 -3
- package/src/testing/react.test.tsx +5 -5
- package/src/testing/react.tsx +2 -2
- package/src/testing/withPluginManager.stories.tsx +1 -1
- package/src/testing/withPluginManager.tsx +70 -21
- package/src/testing/withSurfaceDebug.tsx +1 -1
- package/src/ui/components/App/App.stories.tsx +3 -3
- package/src/ui/components/App/App.tsx +36 -18
- package/src/ui/components/App/loader.ts +5 -0
- package/src/ui/components/PluginManager/PluginManagerContext.stories.tsx +7 -6
- package/src/ui/components/PluginManager/PluginManagerProvider.ts +2 -3
- package/src/ui/components/Surface/SurfaceComponent.stories.tsx +2 -2
- package/src/ui/components/Surface/SurfaceComponent.test.tsx +199 -18
- package/src/ui/components/Surface/SurfaceComponent.tsx +83 -7
- package/src/ui/components/Surface/SurfaceManager.ts +82 -15
- package/src/ui/components/Surface/types.test.ts +6 -2
- package/src/ui/components/Surface/types.ts +23 -27
- package/src/ui/hooks/index.ts +1 -0
- package/src/ui/hooks/useActivationSignal.ts +26 -0
- package/src/ui/hooks/useApp.test.tsx +7 -4
- package/src/ui/hooks/useApp.tsx +37 -19
- package/src/ui/hooks/useCapabilities.ts +32 -19
- package/src/ui/hooks/useProcessManagerRuntime.ts +11 -6
- package/src/ui/hooks/useSettingsState.ts +3 -1
- package/src/vite-plugin/boot-loader/loader-app/Loader.solid-stories.tsx +96 -0
- package/src/vite-plugin/boot-loader/loader-app/Loader.tsx +11 -0
- package/src/vite-plugin/boot-loader/loader-app/boot-loader.css +42 -0
- package/src/vite-plugin/boot-loader/loader-app/bridge.ts +1 -0
- package/src/vite-plugin/boot-loader/loader-app/entry.tsx +6 -0
- package/src/vite-plugin/boot-loader/loader-app/store.test.ts +53 -0
- package/src/vite-plugin/boot-loader/loader-app/store.ts +42 -2
- package/src/vite-plugin/boot-loader/loader-app/types.ts +10 -0
- package/src/vite-plugin/import-map/index.test.ts +60 -0
- package/src/vite-plugin/import-map/index.ts +29 -2
- package/src/vite-plugin/load.ts +30 -28
- package/src/vite-plugin/manifest.test.ts +5 -5
- package/src/vite-plugin/packages.ts +1 -4
- package/tsconfig.json +5 -10
- package/vite.config.ts +12 -1
- package/dist/lib/chunk-plugin-manifest.mjs.map +0 -1
- package/dist/lib/chunk-url-loader.mjs +0 -347
- package/dist/lib/chunk-url-loader.mjs.map +0 -1
- package/dist/lib/core/capability.mjs.map +0 -1
- package/dist/lib/ui.mjs.map +0 -1
- package/dist/types/src/common/annotations.d.ts +0 -1
- package/dist/types/src/common/annotations.d.ts.map +0 -1
- package/dist/types/src/core/plugin-manager.d.ts.map +0 -1
- package/dist/types/src/core/plugin-manager.test.d.ts.map +0 -1
- package/src/common/annotations.ts +0 -3
- package/src/core/plugin-manager.test.ts +0 -1960
- package/src/core/plugin-manager.ts +0 -1719
- package/src/vite-plugin/boot-loader/BootLoader.solid-stories.tsx +0 -198
- /package/dist/types/src/core/{plugin-manager.test.d.ts → plugin-manager/plugin-manager.test.d.ts} +0 -0
package/API.md
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# DXOS App Framework API
|
|
2
|
+
|
|
3
|
+
Companion to [ARCHITECTURE.md](./ARCHITECTURE.md), which covers how the pieces relate. This is the
|
|
4
|
+
API surface.
|
|
5
|
+
|
|
6
|
+
## Imports
|
|
7
|
+
|
|
8
|
+
```ts
|
|
9
|
+
import {
|
|
10
|
+
ActivationEvent, // Runtime activation events (make/oneOf/allOf)
|
|
11
|
+
ActivationEvents, // Well-known framework events (Startup, ...)
|
|
12
|
+
Capabilities, // Well-known capability tags (ReactSurface, OperationHandler, ...)
|
|
13
|
+
Capability, // Capability tags, contributions, module authoring
|
|
14
|
+
Plugin, // Plugin definition + builder
|
|
15
|
+
PluginManager, // Manager type (usually obtained, not constructed)
|
|
16
|
+
} from '@dxos/app-framework';
|
|
17
|
+
import { Surface, useApp, useCapabilities, useCapability } from '@dxos/app-framework/ui';
|
|
18
|
+
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Defining a capability
|
|
24
|
+
|
|
25
|
+
A capability is a typed, NSID-keyed slot. **Arity is chosen at definition** and decides what
|
|
26
|
+
consumers get.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
// Multi (the default): an open registry many modules contribute to.
|
|
30
|
+
export const Template = Capability.make<Template>()('org.dxos.plugin.projects.capability.template');
|
|
31
|
+
|
|
32
|
+
// Singleton: exactly one provider.
|
|
33
|
+
export const Client = Capability.makeSingleton<ClientApi>()('org.dxos.plugin.client.capability.client');
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Both are curried — `make<T>()(nsid)` — so the NSID string literal is captured and brands the
|
|
37
|
+
identifier. NSIDs must be camelCase (`DXN.Name`). The single-call form `make<T>(nsid)` still compiles
|
|
38
|
+
but widens the NSID to `string`, making the compile-time check vacuous; prefer the curried form.
|
|
39
|
+
|
|
40
|
+
| | `makeSingleton` → `Tag<T>` | `make` → `MultiTag<T>` |
|
|
41
|
+
| ------------------ | ------------------------------------ | ----------------------------------------- |
|
|
42
|
+
| `yield* tag` gives | `T` | `Contributions<T>` (live view) |
|
|
43
|
+
| Requiring it | gates activation on its one provider | never gates — the collection may be empty |
|
|
44
|
+
| Two providers | `DuplicateProviderError` | normal |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Authoring a module
|
|
49
|
+
|
|
50
|
+
A module is a body plus a declaration of what it `requires` and `provides`.
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
// Code-split (the common case) — the chunk loads when the module activates.
|
|
54
|
+
export const Coordinator = Capability.lazyModule(
|
|
55
|
+
'ConnectorCoordinator',
|
|
56
|
+
{ requires: [ClientCapabilities.Client], provides: [ConnectorCoordinator] },
|
|
57
|
+
() => import('./connector-coordinator'),
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// Eager — body defined inline, no separate chunk.
|
|
61
|
+
export const Extractor = Capability.inlineModule(
|
|
62
|
+
'SummarizeExtractor',
|
|
63
|
+
{ provides: [InboxCapabilities.ObjectExtractor] },
|
|
64
|
+
() => Effect.succeed(Capability.contribute(InboxCapabilities.ObjectExtractor, extractor)),
|
|
65
|
+
);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The body is written with `Capability.makeModule` and yields its declared requirements:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
export default Capability.makeModule(
|
|
72
|
+
Effect.fnUntraced(function* () {
|
|
73
|
+
const client = yield* ClientCapabilities.Client; // declared in `requires`
|
|
74
|
+
const coordinator = new Coordinator(client);
|
|
75
|
+
return Capability.contribute(ConnectorCoordinator, coordinator);
|
|
76
|
+
}),
|
|
77
|
+
);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Yielding a tag that is not in `requires` is a type error (it escapes the `R` channel); failing to
|
|
81
|
+
contribute a declared `provides` is also a type error.
|
|
82
|
+
|
|
83
|
+
**Makers.** Capability owners export a maker so call sites don't repeat `provides`.
|
|
84
|
+
`@dxos/app-toolkit` ships them for the common capabilities:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
export const ReactSurface = AppCapability.surface(() => import('./react-surface'));
|
|
88
|
+
export const AppGraphBuilder = AppCapability.appGraphBuilder(() => import('./app-graph-builder'), {
|
|
89
|
+
requires: [SomeCapabilities.Thing],
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Build your own with `Capability.moduleMaker(name, tag)`.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Composing a plugin
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
export const FooPlugin = Plugin.define(meta).pipe(
|
|
101
|
+
Plugin.addModule(ReactSurface),
|
|
102
|
+
Plugin.addModule(Coordinator),
|
|
103
|
+
Plugin.addModule(AppCapability.translations(translations)),
|
|
104
|
+
Plugin.addModule(AppCapability.schema([Foo.Foo])),
|
|
105
|
+
Plugin.make,
|
|
106
|
+
);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`Plugin.define(meta)` starts a builder; each `addModule` adds one module; `Plugin.make` seals it.
|
|
110
|
+
When the plugin takes options, `addModule` also accepts `(options) => module` and makers accept a
|
|
111
|
+
`props` mapping from plugin options to body props. If every option is optional, calling
|
|
112
|
+
`FooPlugin()` with no argument is allowed.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Consuming capabilities
|
|
117
|
+
|
|
118
|
+
Three access paths, for three situations.
|
|
119
|
+
|
|
120
|
+
**1. Inside a module body** — declared, type-checked, ordering-aware.
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
Effect.fnUntraced(function* () {
|
|
124
|
+
const client = yield* ClientCapabilities.Client; // singleton → T
|
|
125
|
+
const templates = yield* ProjectCapabilities.Template; // multi → Contributions<T>
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**2. Outside a module** (operations, callbacks, non-module code) — dynamic, string-keyed.
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
Effect.gen(function* () {
|
|
133
|
+
const handlers = yield* Capability.getAll(Capabilities.OperationHandler);
|
|
134
|
+
const maybe = yield* Capability.getOption(AppCapabilities.ProgressRegistry);
|
|
135
|
+
const surfaces = yield* Capability.atom(Capabilities.ReactSurface); // reactive
|
|
136
|
+
const client = yield* Capability.waitFor(ClientCapabilities.Client); // resolves when contributed
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**3. React.**
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
const surfaces = useCapabilities(Capabilities.ReactSurface);
|
|
144
|
+
const client = useCapability(ClientCapabilities.Client);
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
> In graph-extension atom callbacks always use `Capability.atom`, never a synchronous
|
|
148
|
+
> `Capability.get` — a sync read inside an atom body caches a defect fallback with no reactive
|
|
149
|
+
> dependency.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Contributing values
|
|
154
|
+
|
|
155
|
+
A module returns its contributions from `activate`. `contribute` carries one value, `contributeAll`
|
|
156
|
+
carries several for the same capability; both produce a single `Contribution`.
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
return [
|
|
160
|
+
Capability.contribute(Capabilities.ReactSurface, surface),
|
|
161
|
+
Capability.contributeAll(Capabilities.LayerSpec, [clientSpec, databaseSpec]),
|
|
162
|
+
];
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
A module providing exactly one capability may return the `Contribution` directly, without the array.
|
|
166
|
+
An optional third argument is a `deactivate` hook, run once when the module is deactivated.
|
|
167
|
+
|
|
168
|
+
The return is checked against the module's declared `provides`: omitting a declared capability is a
|
|
169
|
+
type error, and contributing an undeclared one fails at runtime.
|
|
170
|
+
|
|
171
|
+
## Reading a multi capability
|
|
172
|
+
|
|
173
|
+
A multi capability has no single value, and its membership changes as plugins are enabled and
|
|
174
|
+
disabled. Reading one therefore gives a live `Contributions<T>` view rather than an array:
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
Effect.fnUntraced(function* () {
|
|
178
|
+
const templates = yield* ProjectCapabilities.Template; // Contributions<Template>
|
|
179
|
+
|
|
180
|
+
templates.get(); // readonly Template[] — snapshot as of now
|
|
181
|
+
templates.subscribe((values) => setTemplates(values)); // → unsubscribe
|
|
182
|
+
templates.atom; // Atom<Template[]> for Atom-based composition
|
|
183
|
+
});
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
`get()` is a point-in-time snapshot: hold onto it and it will not reflect capabilities contributed
|
|
187
|
+
later. Consume the collection reactively — via `subscribe`, `atom`, or the React hooks — unless the
|
|
188
|
+
value is used immediately and discarded.
|
|
189
|
+
|
|
190
|
+
### `Contribution` vs `Contributions`
|
|
191
|
+
|
|
192
|
+
Two types one letter apart, on either side of the registry:
|
|
193
|
+
|
|
194
|
+
| | `Contribution` | `Contributions<T>` |
|
|
195
|
+
| ----------- | ----------------------------------------- | ------------------------------------------------------------ |
|
|
196
|
+
| Direction | what a module **produces** | what a consumer **reads** |
|
|
197
|
+
| Produced by | `Capability.contribute` / `contributeAll` | `yield*` on a `MultiTag`, or `Capability.contributions(tag)` |
|
|
198
|
+
| Shape | `{ capability, values, deactivate? }` | `{ atom, get(), subscribe() }` |
|
|
199
|
+
| Scope | one module's values for one capability | every module's values for one capability |
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Activation
|
|
204
|
+
|
|
205
|
+
A module activates in one of two modes, normalized onto `PluginModule.activation`:
|
|
206
|
+
|
|
207
|
+
- **Dependency mode** (the default) — declared `requires`/`provides`. The manager topologically
|
|
208
|
+
orders modules so providers run before consumers. A module with no `requires` is a startup root.
|
|
209
|
+
- **Event mode** — `activatesOn` a genuine runtime event; `requires` are pulled on demand when it
|
|
210
|
+
fires.
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
Capability.lazyModule(
|
|
214
|
+
'OnSpaceCreated',
|
|
215
|
+
{ activatesOn: SpaceEvents.SpaceCreated, provides: [] },
|
|
216
|
+
() => import('./on-space-created'),
|
|
217
|
+
);
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Surviving events are runtime occurrences only — `ActivationEvents.Startup`, `SpacesReady`,
|
|
221
|
+
`SpaceCreated`, `IdentityCreated`, `TypeAdded`, plus parameterized `createStateEvent` /
|
|
222
|
+
`createSettingsEvent`. Ordering-only `Setup*`/`*Ready` events were removed; express ordering as
|
|
223
|
+
`requires`/`provides`.
|
|
224
|
+
|
|
225
|
+
Structural problems isolate rather than abort startup: a dependency cycle, duplicate singleton
|
|
226
|
+
provider, or unsatisfiable requirement puts the owning plugin in an error state
|
|
227
|
+
(`DependencyCycleError`, `DuplicateProviderError`, `MissingProviderError`,
|
|
228
|
+
`ProvidesMismatchError`) and everything else proceeds.
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Well-known capabilities
|
|
233
|
+
|
|
234
|
+
`Capabilities` (framework) — `ReactSurface`, `ReactContext`, `ReactRoot`, `OperationHandler`,
|
|
235
|
+
`OperationInvoker`, `UndoMapping`, `Command`, `Layer`, `LayerSpec`, `TraceSink`, `AtomRegistry`,
|
|
236
|
+
`ServiceResolver`, `ProcessManagerRuntime`, `ProcessMonitor`, `PluginManager`.
|
|
237
|
+
|
|
238
|
+
`AppCapabilities` (`@dxos/app-toolkit`) — `Translations`, `Schema`, `Settings`, `AppGraph`,
|
|
239
|
+
`AppGraphBuilder`, `SkillDefinition`, `PluginAsset`, `Toolkit`, `NavigationTargetResolver`,
|
|
240
|
+
`NavigationHandler`, `TextContent`, `CommentConfig`, `AnchorSort`, `AnchorResolver`, `Layout`.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Testing
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
withPluginManager({
|
|
248
|
+
plugins: [ClientPlugin(), FooPlugin()],
|
|
249
|
+
capabilities: [Capability.contribute(SomeCapability, stub)], // takes Contribution[]
|
|
250
|
+
});
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
`@dxos/app-framework/testing` also exports `harness` (headless activation assertions) and
|
|
254
|
+
`createComposerTestApp`.
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Type reference
|
|
259
|
+
|
|
260
|
+
| Type | Meaning |
|
|
261
|
+
| ----------------------------- | -------------------------------------------------------------- |
|
|
262
|
+
| `Capability.Tag<T, S>` | Singleton tag; `yield*` → `T` |
|
|
263
|
+
| `Capability.MultiTag<T, S>` | Multi tag; `yield*` → `Contributions<T>` |
|
|
264
|
+
| `Capability.AnyTag` | `Tag \| MultiTag` |
|
|
265
|
+
| `Capability.Contribution` | One branded contribution (capability + n values) |
|
|
266
|
+
| `Capability.Contributions<T>` | Live view: `{ atom, get(), subscribe() }` |
|
|
267
|
+
| `Capability.Any` | A registry entry: `{ interface, implementation, deactivate? }` |
|
|
268
|
+
| `Capability.Module<Options>` | An authored module, opaque except for its options type |
|
|
269
|
+
| `Plugin.Plugin` | `{ meta, modules }` |
|
|
270
|
+
| `Plugin.PluginModule` | `{ id, activation, activate() }` |
|
|
271
|
+
| `Plugin.ActivationSpec` | `dependency \| event` discriminated union |
|
|
272
|
+
|
|
273
|
+
`Contribution` → `Capability.Any` is a 1-to-n expansion performed by the manager
|
|
274
|
+
(`CapabilityManager.expandContributions`); see
|
|
275
|
+
[ARCHITECTURE.md](./ARCHITECTURE.md#the-two-layer-split).
|
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
How plugins, modules, capabilities and contributions relate.
|
|
4
|
+
|
|
5
|
+
The short version: a **plugin** is a bag of **modules**; a module declares which **capabilities** it
|
|
6
|
+
`requires` and `provides`, and its body returns **contributions**; the manager topologically orders
|
|
7
|
+
activation from those declarations and expands each contribution into the flat entries the
|
|
8
|
+
**capability registry** stores.
|
|
9
|
+
|
|
10
|
+
## Domain model
|
|
11
|
+
|
|
12
|
+
```mermaid
|
|
13
|
+
classDiagram
|
|
14
|
+
direction TB
|
|
15
|
+
|
|
16
|
+
class Plugin {
|
|
17
|
+
+Meta meta
|
|
18
|
+
+PluginModule[] modules
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
class PluginModule {
|
|
22
|
+
+string id
|
|
23
|
+
+ActivationSpec activation
|
|
24
|
+
+activate(props) Effect
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
class ActivationSpec {
|
|
28
|
+
+mode dependency | event
|
|
29
|
+
+AnyTag[] requires
|
|
30
|
+
+AnyTag[] provides
|
|
31
|
+
+Events activatesOn
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
class Module {
|
|
35
|
+
+AnyTag[] requires
|
|
36
|
+
+AnyTag[] provides
|
|
37
|
+
+Events activatesOn
|
|
38
|
+
+call(options) Effect
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
class Tag {
|
|
42
|
+
+arity single
|
|
43
|
+
+yield* gives T
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
class MultiTag {
|
|
47
|
+
+arity multi
|
|
48
|
+
+yield* gives Contributions
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
class Contribution {
|
|
52
|
+
+AnyTag capability
|
|
53
|
+
+unknown[] values
|
|
54
|
+
+deactivate()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
class CapabilityEntry {
|
|
58
|
+
+InterfaceDef interface
|
|
59
|
+
+T implementation
|
|
60
|
+
+deactivate()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
class Contributions {
|
|
64
|
+
+Atom atom
|
|
65
|
+
+get() T[]
|
|
66
|
+
+subscribe(cb)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
class CapabilityManager {
|
|
70
|
+
+contribute(entry)
|
|
71
|
+
+get(tag) T
|
|
72
|
+
+getAll(tag) T[]
|
|
73
|
+
+atom(tag) Atom
|
|
74
|
+
+contributions(tag) Contributions
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
class PluginManager {
|
|
78
|
+
+start()
|
|
79
|
+
+activate(event)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
Plugin "1" *-- "0..n" PluginModule : modules
|
|
83
|
+
PluginModule --> ActivationSpec : activation
|
|
84
|
+
Module ..> PluginModule : Plugin.addModule()
|
|
85
|
+
ActivationSpec ..> Tag : requires / provides
|
|
86
|
+
ActivationSpec ..> MultiTag : requires / provides
|
|
87
|
+
Tag ..> Contribution : Capability.contribute()
|
|
88
|
+
MultiTag ..> Contribution : Capability.contributeAll()
|
|
89
|
+
Contribution ..> CapabilityEntry : expandContributions() 1 to n
|
|
90
|
+
CapabilityManager "1" o-- "0..n" CapabilityEntry : registry keyed by NSID
|
|
91
|
+
CapabilityManager ..> Contributions : live view for a MultiTag
|
|
92
|
+
PluginManager --> PluginModule : orders and activates
|
|
93
|
+
PluginManager --> CapabilityManager : owns
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### The two-layer split
|
|
97
|
+
|
|
98
|
+
`Contribution` and `CapabilityEntry` (exported as `Capability.Any`) sit on either side of the
|
|
99
|
+
registry boundary — the authoring layer and the storage layer:
|
|
100
|
+
|
|
101
|
+
| | `Contribution` (authoring) | `Capability.Any` (registry) |
|
|
102
|
+
| ------------ | ---------------------------------------------------------------------------------------------- | --------------------------------------- |
|
|
103
|
+
| Produced by | `Capability.contribute` / `contributeAll` | `CapabilityManager.expandContributions` |
|
|
104
|
+
| Holds | **n** values for one capability | exactly **one** implementation |
|
|
105
|
+
| Identity | branded by capability identity (NSID + arity) — powers the `EnsureProvides` completeness check | the `InterfaceDef` only |
|
|
106
|
+
| Service type | erased to `AnyTag`, so a body's service type never leaks into `.d.ts` emit | names `T` directly |
|
|
107
|
+
|
|
108
|
+
`expandContributions` is the one-way bridge: a `contributeAll(tag, [a, b, c])` is one `Contribution`
|
|
109
|
+
that becomes three registry entries, with the `deactivate` hook pinned to the first so it runs
|
|
110
|
+
exactly once.
|
|
111
|
+
|
|
112
|
+
## Activation
|
|
113
|
+
|
|
114
|
+
```mermaid
|
|
115
|
+
flowchart TB
|
|
116
|
+
subgraph authoring["Authoring (compile time)"]
|
|
117
|
+
A1["Capability.make / makeSingleton<br/>defines a Tag"]
|
|
118
|
+
A2["Capability.lazyModule / inlineModule<br/>or an AppCapability maker<br/>→ Capability.Module"]
|
|
119
|
+
A3["Plugin.define(meta).pipe(<br/>Plugin.addModule(...), Plugin.make)<br/>→ Plugin"]
|
|
120
|
+
A1 --> A2 --> A3
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
subgraph ordering["Ordering (PluginManager.start)"]
|
|
124
|
+
B1["Collect every enabled plugin's modules"]
|
|
125
|
+
B2{"activation.mode"}
|
|
126
|
+
B3["dependency:<br/>edges from requires → provides<br/>Kahn topological waves"]
|
|
127
|
+
B4["event:<br/>parked until activatesOn fires,<br/>requires pulled on demand"]
|
|
128
|
+
B1 --> B2
|
|
129
|
+
B2 -->|dependency| B3
|
|
130
|
+
B2 -->|event| B4
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
subgraph runtime["Activation + registry"]
|
|
134
|
+
C1["Build the module's Context<br/>from its requires"]
|
|
135
|
+
C2["activate(props) → Contribution[]"]
|
|
136
|
+
C3["Validate against declared provides"]
|
|
137
|
+
C4["expandContributions → Capability.Any[]"]
|
|
138
|
+
C5["CapabilityManager.contribute(entry)"]
|
|
139
|
+
C1 --> C2 --> C3 --> C4 --> C5
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
subgraph consume["Consumption"]
|
|
143
|
+
D1["In a module body:<br/>yield* Tag"]
|
|
144
|
+
D2["Dynamically:<br/>Capability.get / getAll / atom"]
|
|
145
|
+
D3["Reactively:<br/>Contributions.atom"]
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
A3 --> B1
|
|
149
|
+
B3 --> C1
|
|
150
|
+
B4 --> C1
|
|
151
|
+
C5 --> D1
|
|
152
|
+
C5 --> D2
|
|
153
|
+
C5 --> D3
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Failure modes are structural rather than fatal: a dependency cycle, a duplicate singleton provider,
|
|
157
|
+
or an unsatisfiable `requires` puts the owning plugin into an error state and excludes it from
|
|
158
|
+
further rounds, while everything else proceeds. A consumer whose provider is event-gated **waits**
|
|
159
|
+
rather than erroring, and activates in a later round once the provider contributes.
|
|
160
|
+
|
|
161
|
+
### Singleton vs multi
|
|
162
|
+
|
|
163
|
+
Arity is a property of the tag and decides what `yield*` gives you:
|
|
164
|
+
|
|
165
|
+
- `Capability.makeSingleton<T>()(nsid)` → `Tag`. `yield* tag` gives `T`. Requiring one gates
|
|
166
|
+
activation on its single provider; two providers is a `DuplicateProviderError`.
|
|
167
|
+
- `Capability.make<T>()(nsid)` → `MultiTag` (the default). `yield* tag` gives a live
|
|
168
|
+
`Contributions<T>` collection. Providers never gate consumers, so consume it reactively — a
|
|
169
|
+
one-shot snapshot silently misses late contributions.
|
|
170
|
+
|
|
171
|
+
Both forms are curried so the NSID string literal is captured and brands the identifier; the NSID
|
|
172
|
+
must be camelCase (`DXN.Name`).
|
|
173
|
+
|
|
174
|
+
## Where things live
|
|
175
|
+
|
|
176
|
+
| Concept | File |
|
|
177
|
+
| -------------------------------------------------------------------- | -------------------------------------------------------- |
|
|
178
|
+
| Tags, arity, `Contribution`, `contribute`, module makers | `src/core/capability.ts` |
|
|
179
|
+
| `Plugin`, `PluginModule`, `ActivationSpec`, the builder | `src/core/plugin.ts` |
|
|
180
|
+
| Public manager API, unit composition, shutdown, failure policy | `src/core/plugin-manager/plugin-manager.ts` |
|
|
181
|
+
| Shared substrate: atoms, status channel, fibers (`ManagerState`) | `src/core/plugin-manager/manager-state.ts` |
|
|
182
|
+
| Catalog: add/enable/disable, lazy resolution, dependency closure | `src/core/plugin-manager/plugin-catalog.ts` |
|
|
183
|
+
| Lifecycle engine: start/activate/deactivate/reset, rounds, waves | `src/core/plugin-manager/activation-scheduler.ts` |
|
|
184
|
+
| Ordering logic (runnable selection, waves, cycles), on `@dxos/graph` | `src/core/plugin-manager/activation-graph.ts` |
|
|
185
|
+
| Memoized module loads, provides validation, deactivation | `src/core/plugin-manager/module-loader.ts` |
|
|
186
|
+
| The NSID-keyed registry and its reactive views | `src/core/capability-manager.ts` |
|
|
187
|
+
| Tagged errors (cycle, missing/duplicate provider, mismatch) | `src/core/errors.ts` |
|
|
188
|
+
| Per-capability module makers (`surface`, `settings`, …) | `@dxos/app-toolkit` `src/app-framework/AppCapability.ts` |
|
|
189
|
+
|
|
190
|
+
Worked examples: `@dxos/plugin-client` and `@dxos/plugin-markdown`.
|