@dxos/app-framework 0.9.0 → 0.9.1-staging.ee54ba693a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/{capability-BOPAKKWG.mjs → capability-S44TE2H7.mjs} +9 -9
- package/dist/lib/browser/{chunk-66IXTIVK.mjs → chunk-3NQLTQCP.mjs} +6 -7
- package/dist/lib/browser/chunk-3NQLTQCP.mjs.map +7 -0
- package/dist/lib/browser/chunk-53HJHMS5.mjs +7 -0
- package/dist/lib/browser/chunk-53HJHMS5.mjs.map +7 -0
- package/dist/lib/browser/{chunk-Y66ELD4U.mjs → chunk-KRJ4KK2W.mjs} +36 -7
- package/dist/lib/browser/chunk-KRJ4KK2W.mjs.map +7 -0
- package/dist/lib/browser/{chunk-KZUDO43J.mjs → chunk-LUH4Y5F2.mjs} +31 -23
- package/dist/lib/browser/chunk-LUH4Y5F2.mjs.map +7 -0
- package/dist/lib/browser/{chunk-CO3XLNUX.mjs → chunk-NKVRSMFN.mjs} +18 -18
- package/dist/lib/browser/chunk-NKVRSMFN.mjs.map +7 -0
- package/dist/lib/browser/{chunk-DC3WRPBV.mjs → chunk-OO53M5UK.mjs} +45 -12
- package/dist/lib/browser/chunk-OO53M5UK.mjs.map +7 -0
- package/dist/lib/browser/{chunk-IW44C7UL.mjs → chunk-OPTS3ZSN.mjs} +1 -1
- package/dist/lib/browser/chunk-OPTS3ZSN.mjs.map +7 -0
- package/dist/lib/browser/{chunk-HFLKXMT7.mjs → chunk-U5MESPM5.mjs} +61 -45
- package/dist/lib/browser/chunk-U5MESPM5.mjs.map +7 -0
- package/dist/lib/browser/{chunk-XHS5KDNX.mjs → chunk-UGYCLOXE.mjs} +25 -25
- package/dist/lib/browser/chunk-UGYCLOXE.mjs.map +7 -0
- package/dist/lib/browser/{chunk-5GY3YOEL.mjs → chunk-VF37YTXJ.mjs} +5 -5
- package/dist/lib/browser/chunk-VF37YTXJ.mjs.map +7 -0
- package/dist/lib/browser/{chunk-FO3IYSLV.mjs → chunk-YUVQIOTB.mjs} +29 -37
- package/dist/lib/browser/chunk-YUVQIOTB.mjs.map +7 -0
- package/dist/lib/browser/cli/index.mjs +9 -9
- package/dist/lib/browser/cli/index.mjs.map +2 -2
- package/dist/lib/browser/common/activation-events.mjs +7 -7
- package/dist/lib/browser/common/capabilities.mjs +7 -7
- package/dist/lib/browser/config/index.mjs +8 -0
- package/dist/lib/browser/config/index.mjs.map +7 -0
- package/dist/lib/browser/core/activation-event.mjs +1 -1
- package/dist/lib/browser/core/capability.mjs +1 -1
- package/dist/lib/browser/core/plugin-manager.mjs +4 -4
- package/dist/lib/browser/core/plugin.mjs +12 -2
- package/dist/lib/browser/core/url-loader.mjs +3 -3
- package/dist/lib/browser/index.mjs +14 -10
- package/dist/lib/browser/index.mjs.map +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{process-manager-capability-GXNUO7AR.mjs → process-manager-capability-QK4BMKMN.mjs} +9 -9
- package/dist/lib/browser/testing/index.mjs +15 -15
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/testing/react.mjs +11 -11
- package/dist/lib/browser/testing/react.mjs.map +3 -3
- package/dist/lib/browser/ui/index.mjs +18 -10
- package/dist/lib/node-esm/{capability-KZWRTX7R.mjs → capability-3YRF77LV.mjs} +9 -9
- package/dist/lib/node-esm/chunk-2UPUZXGU.mjs +9 -0
- package/dist/lib/node-esm/chunk-2UPUZXGU.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-XIGPWXCQ.mjs → chunk-4SE7SX7N.mjs} +45 -12
- package/dist/lib/node-esm/chunk-4SE7SX7N.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-XOCUANHO.mjs → chunk-BMW6P6QA.mjs} +6 -7
- package/dist/lib/node-esm/chunk-BMW6P6QA.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-A5CHGAZE.mjs → chunk-DRT75WGD.mjs} +61 -45
- package/dist/lib/node-esm/chunk-DRT75WGD.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-XGBUKRCK.mjs → chunk-FKMVORZN.mjs} +31 -23
- package/dist/lib/node-esm/chunk-FKMVORZN.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-CTKEZHKF.mjs → chunk-GLH4LGHZ.mjs} +1 -1
- package/dist/lib/node-esm/chunk-GLH4LGHZ.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-SX5NVETP.mjs → chunk-IL7O7IRX.mjs} +25 -25
- package/dist/lib/node-esm/chunk-IL7O7IRX.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-FSVGKTF6.mjs → chunk-ND2HETHD.mjs} +36 -7
- package/dist/lib/node-esm/chunk-ND2HETHD.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-KFZEB6BV.mjs → chunk-TLKYZKPW.mjs} +5 -5
- package/dist/lib/node-esm/chunk-TLKYZKPW.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-WK7OIQKI.mjs → chunk-VCPGX7WN.mjs} +29 -37
- package/dist/lib/node-esm/chunk-VCPGX7WN.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-NULBHQYS.mjs → chunk-XSZMX53L.mjs} +18 -18
- package/dist/lib/node-esm/chunk-XSZMX53L.mjs.map +7 -0
- package/dist/lib/node-esm/cli/index.mjs +9 -9
- package/dist/lib/node-esm/cli/index.mjs.map +2 -2
- package/dist/lib/node-esm/common/activation-events.mjs +7 -7
- package/dist/lib/node-esm/common/capabilities.mjs +7 -7
- package/dist/lib/node-esm/config/index.mjs +9 -0
- package/dist/lib/node-esm/config/index.mjs.map +7 -0
- package/dist/lib/node-esm/core/activation-event.mjs +1 -1
- package/dist/lib/node-esm/core/capability.mjs +1 -1
- package/dist/lib/node-esm/core/plugin-manager.mjs +4 -4
- package/dist/lib/node-esm/core/plugin.mjs +12 -2
- package/dist/lib/node-esm/core/url-loader.mjs +3 -3
- package/dist/lib/node-esm/index.mjs +14 -10
- package/dist/lib/node-esm/index.mjs.map +1 -1
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{process-manager-capability-TX5TA6YN.mjs → process-manager-capability-5S7WZ2JR.mjs} +9 -9
- package/dist/lib/node-esm/testing/index.mjs +15 -15
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/testing/react.mjs +11 -11
- package/dist/lib/node-esm/testing/react.mjs.map +3 -3
- package/dist/lib/node-esm/ui/index.mjs +18 -10
- package/dist/plugin/node-esm/index.mjs +414 -81
- package/dist/plugin/node-esm/index.mjs.map +4 -4
- package/dist/plugin/node-esm/meta.json +1 -1
- package/dist/types/src/cli/cli.d.ts +1 -1
- package/dist/types/src/common/activation-events.d.ts.map +1 -1
- package/dist/types/src/common/capabilities.d.ts +2 -2
- package/dist/types/src/common/capabilities.d.ts.map +1 -1
- package/dist/types/src/config/index.d.ts +2 -0
- package/dist/types/src/config/index.d.ts.map +1 -0
- package/dist/types/src/core/activation-event.d.ts +9 -6
- package/dist/types/src/core/activation-event.d.ts.map +1 -1
- package/dist/types/src/core/capability.d.ts +9 -3
- package/dist/types/src/core/capability.d.ts.map +1 -1
- package/dist/types/src/core/edge-registry-plugin-provider.d.ts +6 -11
- package/dist/types/src/core/edge-registry-plugin-provider.d.ts.map +1 -1
- package/dist/types/src/core/plugin-manager.d.ts.map +1 -1
- package/dist/types/src/core/plugin-manifest.d.ts +25 -7
- package/dist/types/src/core/plugin-manifest.d.ts.map +1 -1
- package/dist/types/src/core/plugin.d.ts +89 -91
- package/dist/types/src/core/plugin.d.ts.map +1 -1
- package/dist/types/src/core/registry.d.ts +17 -57
- package/dist/types/src/core/registry.d.ts.map +1 -1
- package/dist/types/src/core/url-loader.d.ts +2 -2
- package/dist/types/src/core/url-loader.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/plugin-process-manager/history/capability.d.ts +1 -3
- package/dist/types/src/plugin-process-manager/history/capability.d.ts.map +1 -1
- package/dist/types/src/plugin-process-manager/meta.d.ts +32 -2
- package/dist/types/src/plugin-process-manager/meta.d.ts.map +1 -1
- package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts +1 -4
- package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts.map +1 -1
- package/dist/types/src/testing/harness.d.ts +1 -1
- package/dist/types/src/testing/harness.d.ts.map +1 -1
- package/dist/types/src/testing/react.d.ts +6 -5
- package/dist/types/src/testing/react.d.ts.map +1 -1
- package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
- package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/App/App.stories.d.ts +2 -2
- package/dist/types/src/ui/components/App/App.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts +6 -0
- package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts +6 -10
- package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/context.d.ts +6 -2
- package/dist/types/src/ui/components/Surface/context.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/index.d.ts +11 -4
- package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/types.d.ts +52 -72
- package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -1
- package/dist/types/src/ui/hooks/useApp.d.ts +1 -1
- package/dist/types/src/ui/hooks/useCapabilities.d.ts +17 -1
- package/dist/types/src/ui/hooks/useCapabilities.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/composer/index.d.ts +11 -4
- package/dist/types/src/vite-plugin/composer/index.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/import-map/index.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/index.d.ts +1 -0
- package/dist/types/src/vite-plugin/index.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/load.d.ts +16 -0
- package/dist/types/src/vite-plugin/load.d.ts.map +1 -0
- package/dist/types/src/vite-plugin/manifest.d.ts +16 -4
- package/dist/types/src/vite-plugin/manifest.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/registry-spec.md +331 -0
- package/moon.yml +1 -0
- package/package.json +50 -39
- package/src/cli/cli.ts +2 -2
- package/src/common/activation-events.ts +3 -3
- package/src/common/capabilities.ts +18 -18
- package/src/config/index.ts +5 -0
- package/src/core/activation-event.ts +15 -8
- package/src/core/capability.ts +18 -6
- package/src/core/edge-registry-plugin-provider.ts +41 -42
- package/src/core/plugin-manager.test.ts +133 -137
- package/src/core/plugin-manager.ts +25 -19
- package/src/core/plugin-manifest.test.ts +5 -5
- package/src/core/plugin-manifest.ts +13 -10
- package/src/core/plugin.ts +58 -114
- package/src/core/registry.ts +20 -60
- package/src/core/url-loader.test.ts +2 -2
- package/src/core/url-loader.ts +23 -19
- package/src/index.ts +1 -0
- package/src/testing/harness.ts +5 -3
- package/src/testing/react.test.tsx +4 -2
- package/src/testing/react.tsx +10 -9
- package/src/testing/service.ts +2 -2
- package/src/testing/withPluginManager.stories.tsx +4 -2
- package/src/testing/withPluginManager.tsx +3 -1
- package/src/ui/components/App/App.stories.tsx +2 -2
- package/src/ui/components/PluginManager/PluginManagerProvider.ts +7 -0
- package/src/ui/components/Surface/SurfaceComponent.stories.tsx +22 -22
- package/src/ui/components/Surface/SurfaceComponent.tsx +90 -79
- package/src/ui/components/Surface/SurfaceProfilerContext.tsx +1 -1
- package/src/ui/components/Surface/context.ts +6 -4
- package/src/ui/components/Surface/index.ts +14 -3
- package/src/ui/components/Surface/types.test.ts +43 -51
- package/src/ui/components/Surface/types.ts +99 -64
- package/src/ui/hooks/useApp.test.tsx +1 -1
- package/src/ui/hooks/useApp.tsx +2 -2
- package/src/ui/hooks/useCapabilities.ts +49 -2
- package/src/vite-plugin/boot-loader/BootLoader.solid-stories.tsx +11 -11
- package/src/vite-plugin/boot-loader/loader.ts +3 -3
- package/src/vite-plugin/composer/index.ts +134 -61
- package/src/vite-plugin/import-map/index.ts +23 -7
- package/src/vite-plugin/index.ts +1 -0
- package/src/vite-plugin/load.ts +57 -0
- package/src/vite-plugin/manifest.test.ts +3 -3
- package/src/vite-plugin/manifest.ts +21 -10
- package/src/vite-plugin/packages.ts +0 -2
- package/tsconfig.json +5 -2
- package/dist/lib/browser/chunk-5GY3YOEL.mjs.map +0 -7
- package/dist/lib/browser/chunk-66IXTIVK.mjs.map +0 -7
- package/dist/lib/browser/chunk-CO3XLNUX.mjs.map +0 -7
- package/dist/lib/browser/chunk-DC3WRPBV.mjs.map +0 -7
- package/dist/lib/browser/chunk-FO3IYSLV.mjs.map +0 -7
- package/dist/lib/browser/chunk-HFLKXMT7.mjs.map +0 -7
- package/dist/lib/browser/chunk-IW44C7UL.mjs.map +0 -7
- package/dist/lib/browser/chunk-KZUDO43J.mjs.map +0 -7
- package/dist/lib/browser/chunk-XHS5KDNX.mjs.map +0 -7
- package/dist/lib/browser/chunk-Y66ELD4U.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-A5CHGAZE.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-CTKEZHKF.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-FSVGKTF6.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-KFZEB6BV.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-NULBHQYS.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-SX5NVETP.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-WK7OIQKI.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XGBUKRCK.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XIGPWXCQ.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XOCUANHO.mjs.map +0 -7
- /package/dist/lib/browser/{capability-BOPAKKWG.mjs.map → capability-S44TE2H7.mjs.map} +0 -0
- /package/dist/lib/browser/{process-manager-capability-GXNUO7AR.mjs.map → process-manager-capability-QK4BMKMN.mjs.map} +0 -0
- /package/dist/lib/node-esm/{capability-KZWRTX7R.mjs.map → capability-3YRF77LV.mjs.map} +0 -0
- /package/dist/lib/node-esm/{process-manager-capability-TX5TA6YN.mjs.map → process-manager-capability-5S7WZ2JR.mjs.map} +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/common/capabilities.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Atom, type Registry } from '@effect-atom/atom-react';\nimport type * as Command$ from '@effect/cli/Command';\nimport * as Effect from 'effect/Effect';\nimport type * as Exit$ from 'effect/Exit';\nimport type * as Fiber$ from 'effect/Fiber';\nimport type * as Layer$ from 'effect/Layer';\nimport type * as ManagedRuntime$ from 'effect/ManagedRuntime';\nimport type * as Runtime$ from 'effect/Runtime';\nimport type { FC, PropsWithChildren } from 'react';\n\nimport type {\n OperationHandlerSet,\n LayerSpec as LayerSpec$,\n Operation as Operation$,\n Process as Process$,\n ServiceResolver as ServiceResolver$,\n Trace as Trace$,\n} from '@dxos/compute';\nimport type { ProcessManager as ProcessManager$ } from '@dxos/compute-runtime';\nimport { OperationInvoker as OperationInvoker$ } from '@dxos/operation';\n\nimport { Capability as Capability$, Plugin as Plugin$, type PluginManager as PluginManager$ } from '../core';\nimport type {\n HistoryTracker as HistoryTracker$,\n UndoMapping as UndoMapping$,\n UndoRegistry as UndoRegistry$,\n} from '../plugin-process-manager';\nimport type { Surface } from '../ui';\n\n/**\n * Null capability.\n * @category Capability\n */\nexport const Null = Capability$.make<null>('org.dxos.app-framework.capability.null');\n\n/**\n * @category Capability\n */\nexport const PluginManager = Capability$.make<PluginManager$.PluginManager>(\n 'org.dxos.app-framework.capability.pluginManager',\n);\n\n/**\n * @category Capability\n */\nexport const AtomRegistry = Capability$.make<Registry.Registry>('org.dxos.app-framework.capability.atomRegistry');\n\nexport type ReactContext = Readonly<{\n id: string;\n dependsOn?: string[];\n context: FC<PropsWithChildren>;\n}>;\n\n/**\n * @category Capability\n */\nexport const ReactContext = Capability$.make<ReactContext>('org.dxos.app-framework.capability.reactContext');\n\nexport type ReactRoot = Readonly<{ id: string; root: FC<PropsWithChildren> }>;\n\n/**\n * @category Capability\n */\nexport const ReactRoot = Capability$.make<ReactRoot>('org.dxos.app-framework.capability.reactRoot');\n\n/**\n * Surface definitions that can be either React components or Web Components.\n */\nexport type ReactSurface = Surface.Definition | readonly Surface.Definition[];\n\n/**\n * @category Capability\n */\nexport const ReactSurface = Capability$.make<ReactSurface>('org.dxos.app-framework.capability.reactSurface');\n\nexport type AnyCommand = Command$.Command<any, any, any, any>;\n\n/**\n * @category Capability\n */\nexport const Command = Capability$.make<AnyCommand>('org.dxos.app-framework.capability.command');\n\n/**\n * @category Capability\n */\nexport const Layer = Capability$.make<Layer$.Layer<any, any, any>>('org.dxos.app-framework.capability.layer');\n\n/**\n * Layer specification contributed by plugins.\n *\n * Plugins contribute {@link LayerSpec.LayerSpec} entries that are collected by the\n * process-manager module and composed into a {@link LayerStack} which backs the\n * {@link ProcessManagerRuntime}'s service resolver.\n *\n * @category Capability\n */\nexport const LayerSpec = Capability$.make<LayerSpec$.LayerSpec>('org.dxos.app-framework.capability.layerSpec');\n\n/**\n * Context passed to {@link TraceSinkFactory} implementations when the\n * process-manager capability materialises contributed sinks.\n */\nexport interface TraceSinkFactoryContext {\n /**\n * Service resolver backing the shared {@link ProcessManagerRuntime}. Use it\n * to resolve per-space (or per-process) services like `FeedTraceSink` when\n * building a routing sink.\n */\n readonly resolver: ServiceResolver$.ServiceResolver;\n}\n\n/**\n * Factory that builds a {@link Trace$.Sink} when the process-manager\n * capability is ready. Plugins that only need a static sink can ignore the\n * context (e.g. `() => myConsoleSink`); plugins that need per-space routing\n * can use {@link TraceSinkFactoryContext.resolver} to look up services.\n */\nexport type TraceSinkFactory = (ctx: TraceSinkFactoryContext) => Trace$.Sink;\n\n/**\n * Trace sink contribution.\n *\n * Plugins contribute {@link TraceSinkFactory} functions; the process-manager\n * capability invokes each factory with the runtime's\n * {@link ServiceResolver$.ServiceResolver}, collects the resulting\n * {@link Trace$.Sink}s, merges them via {@link Trace$.mergeSinks}, and\n * installs the merged sink as {@link Trace$.TraceSink} in the runtime layer\n * so every process writes to every contributed sink.\n *\n * @category Capability\n */\nexport const TraceSink = Capability$.make<TraceSinkFactory>('org.dxos.app-framework.capability.traceSink');\n\n/**\n * Service resolver backing the shared {@link ProcessManagerRuntime}.\n *\n * Contributed by the process-manager capability module. Consumers can combine\n * it with {@link ServiceResolver$.provide} to build space-scoped layers without\n * having to go through the process-manager runtime:\n *\n * @example\n * ```ts\n * const resolver = yield* Capability.get(Capabilities.ServiceResolver);\n * yield* effect.pipe(\n * Effect.provide(\n * ServiceResolver.provide({ space }, Database.Service).pipe(\n * Layer.provide(Layer.succeed(ServiceResolver.ServiceResolver, resolver)),\n * ),\n * ),\n * );\n * ```\n *\n * @category Capability\n */\nexport const ServiceResolver = Capability$.make<ServiceResolver$.ServiceResolver>(\n 'org.dxos.app-framework.capability.serviceResolver',\n);\n\n/**\n * Process monitor backing the shared {@link ProcessManagerRuntime}. Exposes the\n * live process tree (including inactive/terminated entries) via\n * {@link Process$.Monitor#processTreeAtom}.\n *\n * @category Capability\n */\nexport const ProcessMonitor = Capability$.make<Process$.Monitor>('org.dxos.app-framework.capability.processMonitor');\n\n/**\n * Services that are always available when running effects through a {@link ProcessManagerRuntime}.\n */\nexport type ProcessManagerRuntimeServices =\n | Capability$.Service\n | Plugin$.Service\n | ProcessManager$.ProcessManagerService\n | Operation$.Service\n | ProcessManager$.ProcessOperationInvoker.Service\n | ServiceResolver$.ServiceResolver;\n\n/**\n * Runtime that runs effects requiring a fixed set of capability-manager and\n * process-manager services.\n *\n * The shape mirrors {@link ManagedRuntime$.ManagedRuntime} but deliberately does\n * not expose `dispose` – lifecycle is driven by the host plugin manager.\n */\nexport interface ProcessManagerRuntime {\n runPromise<A, E>(\n effect: Effect.Effect<A, E, ProcessManagerRuntimeServices>,\n options?: { readonly signal?: AbortSignal },\n ): Promise<A>;\n runPromiseExit<A, E>(\n effect: Effect.Effect<A, E, ProcessManagerRuntimeServices>,\n options?: { readonly signal?: AbortSignal },\n ): Promise<Exit$.Exit<A, E>>;\n runFork<A, E>(\n effect: Effect.Effect<A, E, ProcessManagerRuntimeServices>,\n options?: Runtime$.RunForkOptions,\n ): Fiber$.RuntimeFiber<A, E>;\n runSync<A, E>(effect: Effect.Effect<A, E, ProcessManagerRuntimeServices>): A;\n}\n\n/**\n * @category Capability\n */\nexport const ProcessManagerRuntime = Capability$.make<ProcessManagerRuntime>(\n 'org.dxos.app-framework.capability.processManagerRuntime',\n);\n\nexport type ManagedRuntime = ManagedRuntime$.ManagedRuntime<any, any>;\n\n/**\n * @category Capability\n */\nexport const ManagedRuntime = Capability$.make<ManagedRuntime>('org.dxos.app-framework.capability.managedRuntime');\n\n//\n// Operation System Capabilities\n//\n\nexport const OperationHandler = Capability$.make<OperationHandlerSet.OperationHandlerSet>(\n 'org.dxos.app-framework.capability.operationHandler',\n);\n\nexport type UndoMapping = UndoMapping$.UndoMapping;\n\n/**\n * Undo mapping registration - contributed by plugins.\n * @category Capability\n */\nexport const UndoMapping = Capability$.make<UndoMapping[]>('org.dxos.app-framework.capability.undoMapping');\n\n/**\n * Operation invoker backed by the process manager. Spawns a process per\n * operation invocation; see {@link ProcessManager$.ProcessOperationInvoker}.\n */\nexport type OperationInvoker = OperationInvoker$.OperationInvoker;\n\n/**\n * Operation invoker - provided by the process-manager capability.\n * @category Capability\n */\nexport const OperationInvoker = Capability$.make<OperationInvoker>(\n 'org.dxos.app-framework.capability.operationInvoker',\n);\n\nexport type UndoRegistry = UndoRegistry$.UndoRegistry;\n\n/**\n * Undo registry - provided by ProcessManagerPlugin.\n * @category Capability\n */\nexport const UndoRegistry = Capability$.make<UndoRegistry>('org.dxos.app-framework.capability.undoRegistry');\n\nexport type HistoryTracker = HistoryTracker$.HistoryTracker;\n\n/**\n * History tracker - provided by ProcessManagerPlugin.\n * @category Capability\n */\nexport const HistoryTracker = Capability$.make<HistoryTracker>('org.dxos.app-framework.capability.historyTracker');\n\n//\n// Atom Capability Helpers\n//\n\n/**\n * Get the current value of an atom capability.\n * @example const settings = yield* Capabilities.getAtomValue(CommentCapabilities.Settings);\n */\nexport const getAtomValue = <T>(\n atomCapability: Capability$.InterfaceDef<Atom.Atom<T>>,\n): Effect.Effect<T, Error, Capability$.Service> =>\n Effect.gen(function* () {\n const registry = yield* Capability$.get(AtomRegistry);\n const atom = yield* Capability$.get(atomCapability);\n return registry.get(atom);\n });\n\n/**\n * Update an atom capability value (requires writable atom).\n * @example yield* Capabilities.updateAtomValue(CommentCapabilities.Settings, (s) => ({ ...s, foo: true }));\n */\nexport const updateAtomValue = <T>(\n atomCapability: Capability$.InterfaceDef<Atom.Writable<T>>,\n fn: (current: T) => T,\n): Effect.Effect<void, Error, Capability$.Service> =>\n Effect.gen(function* () {\n const registry = yield* Capability$.get(AtomRegistry);\n const atom = yield* Capability$.get(atomCapability);\n registry.set(atom, fn(registry.get(atom)));\n });\n\n/**\n * Subscribe to an atom capability.\n * @example const unsubscribe = yield* Capabilities.subscribeAtom(CommentCapabilities.Settings, (value) => ...);\n */\nexport const subscribeAtom = <T>(\n atomCapability: Capability$.InterfaceDef<Atom.Atom<T>>,\n callback: (value: T) => void,\n): Effect.Effect<() => void, Error, Capability$.Service> =>\n Effect.gen(function* () {\n const registry = yield* Capability$.get(AtomRegistry);\n const atom = yield* Capability$.get(atomCapability);\n return registry.subscribe(atom, () => callback(registry.get(atom)));\n });\n"],
|
|
5
|
+
"mappings": ";;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,YAAYA,YAAY;AA+BjB,IAAMC,OAAOC,mBAAYC,KAAW,wCAAA;AAKpC,IAAMC,gBAAgBF,mBAAYC,KACvC,iDAAA;AAMK,IAAME,eAAeH,mBAAYC,KAAwB,gDAAA;AAWzD,IAAMG,eAAeJ,mBAAYC,KAAmB,gDAAA;AAOpD,IAAMI,YAAYL,mBAAYC,KAAgB,6CAAA;AAU9C,IAAMK,eAAeN,mBAAYC,KAAmB,gDAAA;AAOpD,IAAMM,UAAUP,mBAAYC,KAAiB,2CAAA;AAK7C,IAAMO,QAAQR,mBAAYC,KAAkC,yCAAA;AAW5D,IAAMQ,YAAYT,mBAAYC,KAA2B,6CAAA;AAmCzD,IAAMS,YAAYV,mBAAYC,KAAuB,6CAAA;AAuBrD,IAAMU,kBAAkBX,mBAAYC,KACzC,mDAAA;AAUK,IAAMW,iBAAiBZ,mBAAYC,KAAuB,kDAAA;AAuC1D,IAAMY,wBAAwBb,mBAAYC,KAC/C,yDAAA;AAQK,IAAMa,iBAAiBd,mBAAYC,KAAqB,kDAAA;AAMxD,IAAMc,mBAAmBf,mBAAYC,KAC1C,oDAAA;AASK,IAAMe,cAAchB,mBAAYC,KAAoB,+CAAA;AAYpD,IAAMgB,mBAAmBjB,mBAAYC,KAC1C,oDAAA;AASK,IAAMiB,eAAelB,mBAAYC,KAAmB,gDAAA;AAQpD,IAAMkB,iBAAiBnB,mBAAYC,KAAqB,kDAAA;AAUxD,IAAMmB,eAAe,CAC1BC,mBAEOC,WAAI,aAAA;AACT,QAAMC,WAAW,OAAOvB,mBAAYwB,IAAIrB,YAAAA;AACxC,QAAMsB,OAAO,OAAOzB,mBAAYwB,IAAIH,cAAAA;AACpC,SAAOE,SAASC,IAAIC,IAAAA;AACtB,CAAA;AAMK,IAAMC,kBAAkB,CAC7BL,gBACAM,OAEOL,WAAI,aAAA;AACT,QAAMC,WAAW,OAAOvB,mBAAYwB,IAAIrB,YAAAA;AACxC,QAAMsB,OAAO,OAAOzB,mBAAYwB,IAAIH,cAAAA;AACpCE,WAASK,IAAIH,MAAME,GAAGJ,SAASC,IAAIC,IAAAA,CAAAA,CAAAA;AACrC,CAAA;AAMK,IAAMI,gBAAgB,CAC3BR,gBACAS,aAEOR,WAAI,aAAA;AACT,QAAMC,WAAW,OAAOvB,mBAAYwB,IAAIrB,YAAAA;AACxC,QAAMsB,OAAO,OAAOzB,mBAAYwB,IAAIH,cAAAA;AACpC,SAAOE,SAASQ,UAAUN,MAAM,MAAMK,SAASP,SAASC,IAAIC,IAAAA,CAAAA,CAAAA;AAC9D,CAAA;",
|
|
6
|
+
"names": ["Effect", "Null", "Capability$", "make", "PluginManager", "AtomRegistry", "ReactContext", "ReactRoot", "ReactSurface", "Command", "Layer", "LayerSpec", "TraceSink", "ServiceResolver", "ProcessMonitor", "ProcessManagerRuntime", "ManagedRuntime", "OperationHandler", "UndoMapping", "OperationInvoker", "UndoRegistry", "HistoryTracker", "getAtomValue", "atomCapability", "gen", "registry", "get", "atom", "updateAtomValue", "fn", "set", "subscribeAtom", "callback", "subscribe"]
|
|
7
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getModuleTag
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-OPTS3ZSN.mjs";
|
|
4
4
|
import {
|
|
5
5
|
__export
|
|
6
6
|
} from "./chunk-J5LGTIGS.mjs";
|
|
@@ -9,13 +9,18 @@ import {
|
|
|
9
9
|
var plugin_exports = {};
|
|
10
10
|
__export(plugin_exports, {
|
|
11
11
|
LazyPluginError: () => LazyPluginError,
|
|
12
|
+
Meta: () => Meta,
|
|
12
13
|
PluginDependencyError: () => PluginDependencyError,
|
|
13
14
|
PluginModuleTypeId: () => PluginModuleTypeId,
|
|
14
15
|
PluginTypeId: () => PluginTypeId,
|
|
16
|
+
Profile: () => Profile,
|
|
17
|
+
Release: () => Release,
|
|
15
18
|
Service: () => Service,
|
|
16
19
|
activate: () => activate,
|
|
17
20
|
addModule: () => addModule,
|
|
18
21
|
define: () => define,
|
|
22
|
+
getMetaFromConfig: () => getMetaFromConfig,
|
|
23
|
+
getURI: () => getURI,
|
|
19
24
|
isLazy: () => isLazy,
|
|
20
25
|
isPlugin: () => isPlugin,
|
|
21
26
|
isPluginModule: () => isPluginModule,
|
|
@@ -30,9 +35,11 @@ import * as Context from "effect/Context";
|
|
|
30
35
|
import * as Effect from "effect/Effect";
|
|
31
36
|
import * as Option from "effect/Option";
|
|
32
37
|
import * as Pipeable from "effect/Pipeable";
|
|
38
|
+
import * as Schema from "effect/Schema";
|
|
33
39
|
import { BaseError } from "@dxos/errors";
|
|
34
40
|
import { invariant } from "@dxos/invariant";
|
|
35
41
|
import { DXN } from "@dxos/keys";
|
|
42
|
+
import { PluginProfileSchema, PluginReleaseSchema } from "@dxos/protocols";
|
|
36
43
|
var __dxlog_file = "/__w/dxos/dxos/packages/sdk/app-framework/src/core/plugin.ts";
|
|
37
44
|
var Service = class extends Context.Tag("@dxos/app-framework/PluginManager")() {
|
|
38
45
|
};
|
|
@@ -61,11 +68,32 @@ var PluginModuleImpl = class {
|
|
|
61
68
|
this.activate = options.activate;
|
|
62
69
|
}
|
|
63
70
|
};
|
|
64
|
-
var
|
|
65
|
-
...
|
|
66
|
-
|
|
67
|
-
version: DXN.getVersion(options.key)
|
|
71
|
+
var Profile = Schema.Struct({
|
|
72
|
+
...PluginProfileSchema.fields,
|
|
73
|
+
author: Schema.optional(Schema.String)
|
|
68
74
|
});
|
|
75
|
+
var Release = PluginReleaseSchema;
|
|
76
|
+
var Meta = Schema.Struct({
|
|
77
|
+
profile: Profile,
|
|
78
|
+
release: Schema.optional(Release)
|
|
79
|
+
});
|
|
80
|
+
var makeMeta = (options) => {
|
|
81
|
+
const { key, ...rest } = options;
|
|
82
|
+
return {
|
|
83
|
+
profile: {
|
|
84
|
+
...rest,
|
|
85
|
+
key: DXN.getName(key)
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
var getURI = (meta) => DXN.make(meta.profile.key, meta.release?.version);
|
|
90
|
+
var getMetaFromConfig = ({ plugin }) => {
|
|
91
|
+
const { key, ...rest } = plugin;
|
|
92
|
+
return makeMeta({
|
|
93
|
+
key: DXN.make(key),
|
|
94
|
+
...rest
|
|
95
|
+
});
|
|
96
|
+
};
|
|
69
97
|
var PluginTypeId = /* @__PURE__ */ Symbol.for("@dxos/app-framework/Plugin");
|
|
70
98
|
var isPlugin = (value) => {
|
|
71
99
|
return typeof value === "object" && value !== null && PluginTypeId in value;
|
|
@@ -112,11 +140,11 @@ function addModule(moduleOptionsOrBuilder, moduleOptions) {
|
|
|
112
140
|
}
|
|
113
141
|
var resolveModule = (meta, module, options) => {
|
|
114
142
|
const moduleOptions = typeof module === "function" ? module(options) : module;
|
|
115
|
-
const pluginName = meta.
|
|
143
|
+
const pluginName = meta.profile.key;
|
|
116
144
|
const id = Option.fromNullable(moduleOptions.id).pipe(Option.match({
|
|
117
145
|
onNone: () => {
|
|
118
146
|
const exportName = getModuleTag(moduleOptions.activate);
|
|
119
|
-
invariant(exportName, `Plugin module missing name. Plugin: ${meta.
|
|
147
|
+
invariant(exportName, `Plugin module missing name. Plugin: ${meta.profile.key}`, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 174, S: void 0, A: ["exportName", "`Plugin module missing name. Plugin: ${meta.profile.key}`"] });
|
|
120
148
|
return computeModuleId(pluginName, exportName);
|
|
121
149
|
},
|
|
122
150
|
onSome: (id2) => computeModuleId(pluginName, id2)
|
|
@@ -128,7 +156,7 @@ var resolveModule = (meta, module, options) => {
|
|
|
128
156
|
};
|
|
129
157
|
function make(builder) {
|
|
130
158
|
const meta = builder.meta;
|
|
131
|
-
invariant(!meta.dependsOn?.includes(meta.
|
|
159
|
+
invariant(!meta.profile.dependsOn?.includes(meta.profile.key), `Plugin ${meta.profile.key} declares itself as a dependency.`, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 187, S: this, A: ["!meta.profile.dependsOn?.includes(meta.profile.key)", "`Plugin ${meta.profile.key} declares itself as a dependency.`"] });
|
|
132
160
|
const factory = (options) => {
|
|
133
161
|
const modules = builder.modules.map((module) => resolveModule(meta, module, options));
|
|
134
162
|
return new PluginImpl(meta, modules);
|
|
@@ -163,7 +191,7 @@ var resolveLazy = (plugin) => Effect.gen(function* () {
|
|
|
163
191
|
if (!isLazy(plugin)) {
|
|
164
192
|
return plugin;
|
|
165
193
|
}
|
|
166
|
-
const id = plugin.meta.
|
|
194
|
+
const id = plugin.meta.profile.key;
|
|
167
195
|
const { loader, options } = plugin[LazyTag];
|
|
168
196
|
const mod = yield* Effect.tryPromise({
|
|
169
197
|
try: loader,
|
|
@@ -192,12 +220,12 @@ var resolveLazy = (plugin) => Effect.gen(function* () {
|
|
|
192
220
|
}
|
|
193
221
|
}));
|
|
194
222
|
}
|
|
195
|
-
if (result.meta.
|
|
223
|
+
if (result.meta.profile.key !== id) {
|
|
196
224
|
return yield* Effect.fail(new LazyPluginError({
|
|
197
225
|
context: {
|
|
198
226
|
id,
|
|
199
227
|
reason: "meta-mismatch",
|
|
200
|
-
returnedId: result.meta.
|
|
228
|
+
returnedId: result.meta.profile.key
|
|
201
229
|
}
|
|
202
230
|
}));
|
|
203
231
|
}
|
|
@@ -211,7 +239,12 @@ export {
|
|
|
211
239
|
shutdown,
|
|
212
240
|
PluginModuleTypeId,
|
|
213
241
|
isPluginModule,
|
|
242
|
+
Profile,
|
|
243
|
+
Release,
|
|
244
|
+
Meta,
|
|
214
245
|
makeMeta,
|
|
246
|
+
getURI,
|
|
247
|
+
getMetaFromConfig,
|
|
215
248
|
PluginTypeId,
|
|
216
249
|
isPlugin,
|
|
217
250
|
define,
|
|
@@ -224,4 +257,4 @@ export {
|
|
|
224
257
|
resolveLazy,
|
|
225
258
|
plugin_exports
|
|
226
259
|
};
|
|
227
|
-
//# sourceMappingURL=chunk-
|
|
260
|
+
//# sourceMappingURL=chunk-OO53M5UK.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/core/plugin.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Context from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Option from 'effect/Option';\nimport * as Pipeable from 'effect/Pipeable';\nimport * as Schema from 'effect/Schema';\n\nimport { BaseError } from '@dxos/errors';\nimport { invariant } from '@dxos/invariant';\nimport { DXN } from '@dxos/keys';\nimport { Config2, PluginProfileSchema, PluginReleaseSchema } from '@dxos/protocols';\n\nimport type * as ActivationEvent from './activation-event';\nimport * as Capability from './capability';\nimport type * as PluginManager from './plugin-manager';\n\n//\n// Plugin Service Layer\n//\n\n/**\n * Effect Context.Tag for accessing PluginManager via the Effect layer system.\n * This allows lifecycle operations to access the plugin manager without having it passed as an argument.\n */\nexport class Service extends Context.Tag('@dxos/app-framework/PluginManager')<Service, PluginManager.PluginManager>() {}\n\n//\n// Lifecycle Functions\n//\n\n/**\n * Activates plugins based on the activation event.\n * Accesses the PluginManager via the Effect layer system.\n * @param event The activation event.\n * @returns Whether the activation was successful.\n */\nexport const activate = (event: ActivationEvent.ActivationEvent): Effect.Effect<boolean, Error, Service> =>\n Effect.flatMap(Service, (manager) => manager.activate(event));\n\n/**\n * Re-activates the modules that were activated by the event.\n * Accesses the PluginManager via the Effect layer system.\n * @param event The activation event.\n * @returns Whether the reset was successful.\n */\nexport const reset = (event: ActivationEvent.ActivationEvent): Effect.Effect<boolean, Error, Service> =>\n Effect.flatMap(Service, (manager) => manager.reset(event));\n\n/**\n * Shuts down the plugin manager, deactivating all active modules and clearing lifecycle state.\n * Accesses the PluginManager via the Effect layer system.\n */\nexport const shutdown = (): Effect.Effect<boolean, Error, Service> =>\n Effect.flatMap(Service, (manager) => manager.shutdown());\n\n/**\n * Computes a module ID from plugin ID and export name.\n */\nconst computeModuleId = (pluginId: string, moduleName: string): string => {\n return `${pluginId}.module.${moduleName}`;\n};\n\n/**\n * Identifier denoting a PluginModule.\n */\nexport const PluginModuleTypeId: unique symbol = Symbol.for('@dxos/app-framework/PluginModule');\nexport type PluginModuleTypeId = typeof PluginModuleTypeId;\n\n/**\n * Type guard to check if a value is a PluginModule.\n */\nexport const isPluginModule = (value: unknown): value is PluginModule => {\n return typeof value === 'object' && value !== null && PluginModuleTypeId in value;\n};\n\n/**\n * A unit of containment of modular functionality that can be provided to an application.\n * Activation of a module is async allowing for code to split and loaded lazily.\n */\nexport interface PluginModule {\n readonly [PluginModuleTypeId]: PluginModuleTypeId;\n /**\n * Unique id of the module.\n */\n id: string;\n\n /**\n * Events for which the module will be activated.\n */\n activatesOn: ActivationEvent.Events;\n\n /**\n * Events that this module fires *before* its own activation runs.\n *\n * When this module is asked to activate (via {@link activatesOn}), the\n * plugin manager first activates every event listed here, ensuring any\n * other modules that contribute to those events have completed before\n * this module's {@link activate} body executes. These events are fired\n * by the framework on this module's behalf — the module does not need\n * to wait for some other code to fire them.\n *\n * The module is marked as needing reset if a module activated by one\n * of these events is later removed.\n *\n * Read as: \"this module fires these events before [its] activation\".\n */\n firesBeforeActivation?: ActivationEvent.ActivationEvent[];\n\n /**\n * Events that this module fires *after* its own activation completes.\n *\n * Once this module's {@link activate} body has finished executing, the\n * plugin manager activates every event listed here, causing any modules\n * listening on those events to run. These events are fired by the\n * framework on this module's behalf as part of this module's lifecycle.\n *\n * Read as: \"this module fires these events after [its] activation\".\n */\n firesAfterActivation?: ActivationEvent.ActivationEvent[];\n\n /**\n * Called when the module is activated.\n * CapabilityManager is accessed via the Effect layer system (Capability.Service).\n * PluginManager is accessed via Plugin.Service.\n * @param props Optional props passed to the module.\n * @returns The capabilities of the module.\n */\n activate: (props?: any) => Effect.Effect<Capability.ModuleReturn, Error, Capability.Service | Service | never>;\n}\n\nexport type PluginModuleOptions = Omit<PluginModule, 'id' | typeof PluginModuleTypeId> & { id?: string };\n\nclass PluginModuleImpl implements PluginModule {\n readonly [PluginModuleTypeId]: PluginModuleTypeId = PluginModuleTypeId;\n readonly id: PluginModule['id'];\n readonly activatesOn: PluginModule['activatesOn'];\n readonly firesBeforeActivation?: PluginModule['firesBeforeActivation'];\n readonly firesAfterActivation?: PluginModule['firesAfterActivation'];\n readonly activate: PluginModule['activate'];\n\n constructor(options: Omit<PluginModule, typeof PluginModuleTypeId>) {\n this.id = options.id;\n this.activatesOn = options.activatesOn;\n this.firesBeforeActivation = options.firesBeforeActivation;\n this.firesAfterActivation = options.firesAfterActivation;\n this.activate = options.activate;\n }\n}\n\n/**\n * Runtime plugin metadata, derived from the `@dxos/protocols` registry schemas (protocols owns the\n * config + registry schemas; the runtime projection lives here).\n *\n * - {@link Profile}: version-independent identity + display + provenance — the wire `PluginProfileSchema`\n * (which carries `key`, the display fields, `dependsOn`, `spec`) plus `author` (resolved at runtime\n * from the publisher's handle/DID for registry plugins, or self-declared for bundled).\n * - {@link Release}: a specific hosted release — the wire `PluginReleaseSchema` (version, moduleUrl, dependencies).\n * - {@link Meta}: a resolved single-release view — `{ profile, release? }`, both nested. `release` is\n * unset for bundled plugins (compiled in) and set for registry plugins.\n */\nexport const Profile = Schema.Struct({\n ...PluginProfileSchema.fields,\n author: Schema.optional(Schema.String),\n});\nexport type Profile = Schema.Schema.Type<typeof Profile>;\n\nexport const Release = PluginReleaseSchema;\nexport type Release = Schema.Schema.Type<typeof Release>;\n\nexport const Meta = Schema.Struct({\n profile: Profile,\n release: Schema.optional(Release),\n});\nexport type Meta = Schema.Schema.Type<typeof Meta>;\n\n/** Options for {@link makeMeta}: the {@link Profile} content fields plus the canonical DXN `key`. */\nexport type MakeMetaOptions = {\n key: DXN.DXN;\n name: string;\n description?: string;\n author?: string;\n homePage?: string;\n source?: string;\n tags?: readonly string[];\n dependsOn?: readonly string[];\n spec?: string;\n icon?: Config2.Icon;\n screenshots?: ReadonlyArray<Config2.Screenshot>;\n};\n\n/** Constructs a bundled-plugin {@link Meta} from a canonical DXN. `profile.key` is the bare NSID derived from `key`. */\nexport const makeMeta = (options: MakeMetaOptions): Meta => {\n const { key, ...rest } = options;\n return { profile: { ...rest, key: DXN.getName(key) } };\n};\n\n/** Returns the plugin's canonical DXN URI, constructed from `meta.profile.key` and `meta.release?.version`. */\nexport const getURI = (meta: Meta): DXN.DXN => DXN.make(meta.profile.key, meta.release?.version);\n\n/**\n * Derives a runtime {@link Meta} from a loaded `dx.config.ts` (the `@dxos/protocols` `Config2.Config`).\n * Maps the flat authoring config to the nested profile; bundled plugins have no `release`.\n */\nexport const getMetaFromConfig = ({ plugin }: Config2.Config): Meta => {\n const { key, ...rest } = plugin;\n return makeMeta({ key: DXN.make(key), ...rest });\n};\n\n/**\n * Identifier denoting a Plugin.\n */\nexport const PluginTypeId: unique symbol = Symbol.for('@dxos/app-framework/Plugin');\nexport type PluginTypeId = typeof PluginTypeId;\n\n/**\n * Type guard to check if a value is a Plugin.\n */\nexport const isPlugin = (value: unknown): value is Plugin => {\n return typeof value === 'object' && value !== null && PluginTypeId in value;\n};\n\n/**\n * A collection of modules that are be enabled/disabled as a unit.\n * Plugins provide things such as components, state, actions, etc. to the application.\n */\n// TODO(burdon): Convert to ECHO schema.\nexport interface Plugin {\n readonly [PluginTypeId]: PluginTypeId;\n readonly meta: Readonly<Meta>;\n readonly modules: ReadonlyArray<PluginModule>;\n}\n\n/**\n * Internal implementation of Plugin.\n * @internal\n */\nclass PluginImpl implements Plugin {\n readonly [PluginTypeId]: PluginTypeId = PluginTypeId;\n\n constructor(\n private readonly _meta: Meta,\n private readonly _modules: PluginModule[],\n ) {}\n\n get meta(): Readonly<Meta> {\n return this._meta;\n }\n\n get modules(): ReadonlyArray<PluginModule> {\n return this._modules;\n }\n}\n\n/**\n * Builder interface for creating plugins incrementally.\n */\nexport interface PluginBuilder<T = void> extends Pipeable.Pipeable {\n readonly meta: Meta;\n readonly modules: ReadonlyArray<PluginModuleOptions | ((options: T) => PluginModuleOptions)>;\n addModule(moduleOptions: PluginModuleOptions | ((options: T) => PluginModuleOptions)): PluginBuilder<T>;\n}\n\n/**\n * Builder implementation for creating plugins incrementally.\n */\nclass PluginBuilderImpl<T = void> implements PluginBuilder<T> {\n readonly meta: Meta;\n private readonly _modules: Array<PluginModuleOptions | ((options: T) => PluginModuleOptions)> = [];\n\n constructor(meta: Meta) {\n this.meta = meta;\n }\n\n get modules(): ReadonlyArray<PluginModuleOptions | ((options: T) => PluginModuleOptions)> {\n return this._modules;\n }\n\n addModule(moduleOptions: PluginModuleOptions | ((options: T) => PluginModuleOptions)): PluginBuilder<T> {\n this._modules.push(moduleOptions);\n return this;\n }\n\n pipe() {\n // eslint-disable-next-line prefer-rest-params\n return Pipeable.pipeArguments(this, arguments);\n }\n}\n\n/**\n * Creates a new PluginBuilder to start building a plugin.\n */\nexport const define = <T = void>(meta: Meta): PluginBuilder<T> => new PluginBuilderImpl<T>(meta);\n\n/**\n * Adds a module to a plugin builder.\n * Supports both pipeline and direct call styles.\n * Modules can be either PluginModuleOptions or functions that receive options.\n */\nexport function addModule<T>(\n moduleOptions: PluginModuleOptions | ((options: T) => PluginModuleOptions),\n): (builder: PluginBuilder<T>) => PluginBuilder<T>;\nexport function addModule<T>(\n builder: PluginBuilder<T>,\n moduleOptions: PluginModuleOptions | ((options: T) => PluginModuleOptions),\n): PluginBuilder<T>;\nexport function addModule<T>(\n moduleOptionsOrBuilder: PluginModuleOptions | ((options: T) => PluginModuleOptions) | PluginBuilder<T>,\n moduleOptions?: PluginModuleOptions | ((options: T) => PluginModuleOptions),\n): ((builder: PluginBuilder<T>) => PluginBuilder<T>) | PluginBuilder<T> {\n // If second arg is provided, it's the direct call style: addModule(builder, moduleOptions)\n if (moduleOptions !== undefined) {\n return (moduleOptionsOrBuilder as PluginBuilder<T>).addModule(moduleOptions);\n }\n // Otherwise it's pipeline style: addModule(moduleOptions) returns a function\n const moduleOpts = moduleOptionsOrBuilder as PluginModuleOptions | ((options: T) => PluginModuleOptions);\n return (builder: PluginBuilder<T>) => builder.addModule(moduleOpts);\n}\n\nexport type PluginFactory<T = void> = ((options: T) => Plugin) & { meta: Meta };\n\n/**\n * Resolves a module from either PluginModuleOptions or a function that returns PluginModuleOptions.\n */\nconst resolveModule = (\n meta: Meta,\n module: PluginModuleOptions | ((options: any) => PluginModuleOptions),\n options?: any,\n): PluginModuleImpl => {\n const moduleOptions = typeof module === 'function' ? module(options) : module;\n const pluginName = meta.profile.key;\n const id = Option.fromNullable(moduleOptions.id).pipe(\n Option.match({\n onNone: () => {\n const exportName = Capability.getModuleTag(moduleOptions.activate);\n invariant(exportName, `Plugin module missing name. Plugin: ${meta.profile.key}`);\n return computeModuleId(pluginName, exportName);\n },\n onSome: (id) => computeModuleId(pluginName, id),\n }),\n );\n return new PluginModuleImpl({ ...moduleOptions, id });\n};\n\n/**\n * Creates a Plugin from a builder.\n * Supports both pipeline and direct call styles.\n * Always returns a factory function (options: T) => Plugin.\n * When T is void, the function takes no arguments: () => Plugin.\n */\nexport function make<T>(builder: PluginBuilder<T>): PluginFactory<T>;\nexport function make<T>(builder: PluginBuilder<T>): PluginFactory<T> {\n const meta = builder.meta;\n // `dependsOn` entries and `key` are both bare NSIDs, so compare directly.\n invariant(\n !meta.profile.dependsOn?.includes(meta.profile.key),\n `Plugin ${meta.profile.key} declares itself as a dependency.`,\n );\n\n const factory = (options: T) => {\n const modules = builder.modules.map((module) => resolveModule(meta, module, options));\n return new PluginImpl(meta, modules);\n };\n\n return Object.assign(factory, { meta });\n}\n\n//\n// Lazy plugin loading\n//\n\n/**\n * Symbol used to tag lazy plugin stubs with their loader closure.\n * Hidden from enumeration so plugin manager iteration / serialization paths\n * don't trip over it.\n */\nconst LazyTag: unique symbol = Symbol.for('@dxos/app-framework/Plugin/Lazy');\n\n/**\n * Async loader for a lazy plugin's real implementation.\n * The default export of the loaded module must be a `PluginFactory<T>` —\n * i.e. the same shape `Plugin.make` produces.\n */\nexport type LazyLoader<T = void> = () => Promise<{ default: PluginFactory<T> }>;\n\n/** Internal: payload carried on a lazy stub. */\ntype LazyPayload = { loader: LazyLoader<any>; options: unknown };\n\n/**\n * Defines a lazy plugin whose body is loaded on first enable.\n *\n * The returned factory produces a stub `Plugin` that exposes `meta`\n * synchronously (so callers can read `Plugin.meta.profile.key` for free) but defers\n * loading the real plugin's modules until the manager calls\n * `Plugin.resolveLazy`. This lets the plugin's main entry point ship as a\n * tiny meta-only chunk — the heavy capabilities, schema, React surfaces,\n * etc. live behind the dynamic `import()` and become a separate Rollup\n * chunk that is only fetched when the plugin is enabled.\n *\n * @example\n * ```ts\n * // plugin-markdown/src/index.ts\n * import { Plugin } from '@dxos/app-framework';\n * import { meta } from './meta';\n *\n * export const MarkdownPlugin = Plugin.lazy(meta, () => import('./MarkdownPlugin'));\n *\n * // plugin-markdown/src/MarkdownPlugin.tsx\n * export const MarkdownPlugin = Plugin.define(meta).pipe(...heavy modules..., Plugin.make);\n * export default MarkdownPlugin;\n * ```\n */\nexport const lazy = <T = void>(meta: Meta, loader: LazyLoader<T>): PluginFactory<T> => {\n const factory = (options: T): Plugin => {\n const stub = new PluginImpl(meta, []);\n Object.defineProperty(stub, LazyTag, {\n value: { loader, options } satisfies LazyPayload,\n enumerable: false,\n });\n return stub;\n };\n return Object.assign(factory, { meta });\n};\n\n/**\n * Type guard for lazy plugin stubs produced by {@link lazy}.\n */\nexport const isLazy = (plugin: Plugin): boolean => LazyTag in plugin;\n\n/**\n * Tagged error for failures during lazy plugin resolution. `context.id` is\n * the lazy plugin's `meta.profile.key`; `context.reason` discriminates the failure\n * mode (`'load-failed' | 'missing-default' | 'invalid-plugin' |\n * 'meta-mismatch'`) so callers can route on it.\n */\nexport class LazyPluginError extends BaseError.extend('LazyPluginError', 'Failed to resolve lazy plugin') {}\n\n/**\n * Tagged error for plugin-level dependency resolution failures.\n *\n * `context.id` is the plugin id the manager was acting on. `context.reason`\n * discriminates the failure mode:\n * - `'missing'` — declared dep is neither registered nor in the catalog.\n * `context.missing` lists offending ids.\n * - `'install-failed'` — dep was found in the catalog but `add()` failed.\n * `cause` carries the original error.\n * - `'cycle'` — closure walk detected a cycle. `context.path` is the cycle path.\n * - `'core-dependent'` — cascade-disable would have to disable a core plugin.\n * `context.coreDependent` is the blocking id.\n */\nexport class PluginDependencyError extends BaseError.extend(\n 'PluginDependencyError',\n 'Plugin dependency resolution failed',\n) {}\n\n/**\n * Resolves a lazy plugin stub to its real plugin.\n * Returns the plugin unchanged if it is not lazy. Failures surface as\n * {@link LazyPluginError} with `context.reason` indicating the failure mode\n * and (for loader failures) `cause` set to the original error.\n */\nexport const resolveLazy = (plugin: Plugin): Effect.Effect<Plugin, LazyPluginError> =>\n Effect.gen(function* () {\n if (!isLazy(plugin)) {\n return plugin;\n }\n const id = plugin.meta.profile.key;\n const { loader, options } = (plugin as unknown as { [LazyTag]: LazyPayload })[LazyTag];\n const mod = yield* Effect.tryPromise({\n try: loader,\n catch: (error) => new LazyPluginError({ context: { id, reason: 'load-failed' }, cause: error }),\n });\n if (!mod || typeof mod.default !== 'function') {\n return yield* Effect.fail(new LazyPluginError({ context: { id, reason: 'missing-default' } }));\n }\n const result = mod.default(options);\n if (!isPlugin(result)) {\n return yield* Effect.fail(new LazyPluginError({ context: { id, reason: 'invalid-plugin' } }));\n }\n if (result.meta.profile.key !== id) {\n return yield* Effect.fail(\n new LazyPluginError({ context: { id, reason: 'meta-mismatch', returnedId: result.meta.profile.key } }),\n );\n }\n return result;\n });\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Context", "Effect", "Option", "Pipeable", "Schema", "BaseError", "invariant", "DXN", "PluginProfileSchema", "PluginReleaseSchema", "PluginModuleImpl", "id", "activatesOn", "firesBeforeActivation", "firesAfterActivation", "activate", "author", "Schema", "Release", "PluginReleaseSchema", "profile", "Profile", "release", "optional", "DXN", "makeMeta", "key", "make", "rest", "_meta", "_modules", "meta", "modules", "addModule", "moduleOptions", "pipe", "undefined", "pluginName", "fromNullable", "Option", "onNone", "exportName", "Capability", "getModuleTag", "invariant", "onSome", "computeModuleId", "builder", "module", "resolveModule", "options", "PluginImpl", "Object", "assign", "factory", "stub", "defineProperty", "value", "loader", "enumerable", "plugin", "mod", "Effect", "tryPromise", "try", "catch", "error", "LazyPluginError", "reason", "cause", "context", "result", "fail", "returnedId"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/core/capability.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Atom } from '@effect-atom/atom-react';\nimport * as Context from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nimport type { DXN } from '@dxos/keys';\n\nimport type * as CapabilityManager from './capability-manager';\nimport type * as Plugin from './plugin';\n\n//\n// Capability Service Layer\n//\n\n/**\n * Effect Context.Tag for accessing CapabilityManager via the Effect layer system.\n * This allows capability modules to access the capability manager without having it passed as an argument.\n */\nexport class Service extends Context.Tag('@dxos/app-framework/CapabilityManager')<\n Service,\n CapabilityManager.CapabilityManager\n>() {}\n\n/**\n * Get a single capability from the capability manager.\n * @param interfaceDef The interface definition of the capability.\n * @returns The capability implementation.\n * @throws If no capability is found.\n */\n// TODO(wittjosiah): Add custom tagged errors (Data.TaggedError) for app-framework to enable\n// type-safe error handling with Effect. Consider CapabilityNotFoundError, ModuleActivationError, etc.\nexport const get = <T>(interfaceDef: InterfaceDef<T>): Effect.Effect<T, Error, Service> =>\n Effect.flatMap(Service, (manager) =>\n Effect.try({\n try: () => manager.get(interfaceDef),\n catch: (error) => (error instanceof Error ? error : new Error(String(error))),\n }),\n );\n\n/**\n * Get all capabilities from the capability manager for a given interface.\n * @param interfaceDef The interface definition of the capability.\n * @returns An array of capability implementations.\n */\nexport const getAll = <T>(interfaceDef: InterfaceDef<T>): Effect.Effect<T[], never, Service> =>\n Effect.map(Service, (manager) => manager.getAll(interfaceDef));\n\n/**\n * Wait for a capability to be available.\n * @param interfaceDef The interface definition of the capability.\n * @returns The capability implementation once available.\n */\nexport const waitFor = <T>(interfaceDef: InterfaceDef<T>): Effect.Effect<T, Error, Service> =>\n Effect.flatMap(Service, (manager) => manager.waitFor(interfaceDef));\n\n/**\n * Get the Atom reference to capabilities for reactive access.\n * @param interfaceDef The interface definition of the capability.\n * @returns An Atom containing the array of capability implementations.\n */\nexport const atom = <T>(interfaceDef: InterfaceDef<T>): Effect.Effect<Atom.Atom<T[]>, never, Service> =>\n Effect.map(Service, (manager) => manager.atom(interfaceDef));\n\n/**\n * Get capabilities grouped by the module that contributed them.\n * @param interfaceDef The interface definition of the capability.\n * @returns An Atom containing a record from module ID to capability implementations.\n */\nexport const atomByModule = <T>(\n interfaceDef: InterfaceDef<T>,\n): Effect.Effect<Atom.Atom<Record<string, T[]>>, never, Service> =>\n Effect.map(Service, (manager) => manager.atomByModule(interfaceDef));\n\n/**\n * Constructs a layer that will request its interface implementation from the capability manager.\n */\nexport const asLayer = <T, I>(interfaceDef: InterfaceDef<T>, tag: Context.Tag<I, T>): Layer.Layer<I, never, Service> =>\n Layer.effect(tag, get(interfaceDef).pipe(Effect.orDie));\n\nconst InterfaceDefTypeId: unique symbol = Symbol.for('InterfaceDefTypeId');\n\n/**\n * Symbol used to tag lazy capability functions with their module ID.\n */\nexport const ModuleTag: unique symbol = Symbol.for('@dxos/app-framework/ModuleTag');\n\n/**\n * The interface definition of a capability.\n */\nexport type InterfaceDef<T> = {\n [InterfaceDefTypeId]: T;\n identifier: string;\n};\n\nexport namespace InterfaceDef {\n export type Implementation<I extends InterfaceDef<any>> = I extends InterfaceDef<infer T> ? T : never;\n}\n\n/**\n * Helper to define the interface of a capability.\n * Static NSID strings are validated at compile time via {@link DXN.Name}.\n */\nexport const make: {\n <T, S extends string = string>(\n identifier: [DXN.Name<S>] extends [never] ? `Invalid NSID \"${S}\": final segment must be camelCase (no hyphens)` : S,\n ): InterfaceDef<T>;\n} = <T>(identifier: string): InterfaceDef<T> => {\n return { identifier } as InterfaceDef<T>;\n};\n\n/**\n * A unique string identifier with a Typescript type associated with it.\n * When a capability is contributed to the application an implementation of the interface is provided.\n */\nexport type Capability<T> = {\n /**\n * The interface definition of the capability.\n */\n readonly interface: InterfaceDef<T>;\n\n /**\n * The implementation of the capability.\n */\n readonly implementation: T;\n\n /**\n * Called when the capability is deactivated.\n */\n readonly deactivate?: () => Effect.Effect<void, Error>;\n};\n\nexport type Any = Capability<any>;\n\n/**\n * Union type representing all valid return types for a capability module.\n * Supports single capabilities, arrays, and tuples of different capability types.\n */\nexport type ModuleReturn = void | Any | Any[] | readonly Any[] | [Any, ...Any[]] | readonly [Any, ...Any[]];\n\n/**\n * Helper to define the implementation of a capability.\n * Returns the opaque base type so callers cannot discriminate on capability kind,\n * keeping d.ts emit portable across packages.\n */\nexport const contributes = <I extends InterfaceDef<any>>(\n interfaceDef: I,\n implementation: Capability<InterfaceDef.Implementation<I>>['implementation'],\n deactivate?: Capability<InterfaceDef.Implementation<I>>['deactivate'],\n): Any => {\n return {\n interface: interfaceDef,\n implementation,\n deactivate,\n } satisfies Capability<I>;\n};\n\ntype LoadCapability<Props, Capabilities extends ModuleReturn = ModuleReturn> = () => Promise<{\n default: (props: Props) => Effect.Effect<Capabilities, Error, Service | Plugin.Service | never>;\n}>;\ntype LoadCapabilities<Props, Capabilities extends ModuleReturn = ModuleReturn> = () => Promise<{\n default: (props: Props) => Effect.Effect<Capabilities, Error, Service | Plugin.Service | never>;\n}>;\n\ntype NormalizeReturn<R> = R extends readonly (infer A)[]\n ? A[]\n : R extends (infer A)[]\n ? A[]\n : R extends Any\n ? [R]\n : Any[];\n\nexport type LazyCapability<Props = void, Capabilities extends ModuleReturn = ModuleReturn, E extends Error = Error> = (\n props: Props,\n) => Effect.Effect<NormalizeReturn<Capabilities>, E, Service | Plugin.Service | never>;\n\n/**\n * Helper to define a lazily loaded implementation of a capability.\n * Supports single capabilities, arrays, and tuples of different capability types.\n * @param name The export name (e.g., 'AppGraphBuilder') - used to auto-compute module IDs.\n * @param loader The lazy loader function.\n * @returns A lazy capability function with ModuleTag symbol attached.\n */\nexport const lazy = <T = void, R extends ModuleReturn = ModuleReturn>(\n name: string,\n c: LoadCapability<T, R> | LoadCapabilities<T, R>,\n): LazyCapability<T> => {\n const lazyFn = (props: T) =>\n Effect.gen(function* () {\n const { default: getCapability } = yield* Effect.promise(() => c());\n const result = yield* getCapability(props);\n const normalized = result == null ? [] : Array.isArray(result) ? Array.from(result) : [result];\n return normalized as NormalizeReturn<R>;\n });\n\n // Props (T) are preserved so callers pass correctly-typed options, but the contributed\n // Capabilities type is widened to the opaque base. The concrete capability type often traces to a\n // module-internal source path that TypeScript cannot name in declaration files (TS2883); the base\n // type is portable. The contributed type is checked at Capability.contributes regardless.\n return Object.assign(lazyFn, { [ModuleTag]: name }) as LazyCapability<T>;\n};\n\n/**\n * Gets the module tag (export name) from a lazy capability function.\n * @param capability The lazy capability function.\n * @returns The module tag if present, undefined otherwise.\n */\n// TODO(wittjosiah): Stricter type for capability.\nexport const getModuleTag = (capability: unknown): string | undefined => {\n return capability && typeof capability === 'function' && ModuleTag in capability\n ? String(capability[ModuleTag])\n : undefined;\n};\n\n/**\n * Helper to define a capability module with explicit typing.\n * Wraps the default export function to provide better type inference and make the pattern explicit.\n *\n * This helper provides explicit typing for the module activation function,\n * making it clear that the function should:\n * - Access CapabilityManager via the Effect layer system (Capability.get, Capability.getAll, etc.)\n * - Return a capability, array of capabilities, or tuple of different capability types (sync or async)\n *\n * Supports returning multiple capabilities of different types as a tuple, which will be normalized\n * to an array at runtime for compatibility with the plugin system.\n *\n * @example\n * ```ts\n * // Module without options - single capability\n * export default Capability.makeModule(\n * Effect.fnUntraced(function* () {\n * const client = yield* Capability.get(ClientCapabilities.Client);\n * return contributes(Capabilities.SettingsStore, store);\n * })\n * );\n *\n * // Module with multiple capabilities\n * export default Capability.makeModule(\n * Effect.fnUntraced(function* () {\n * return [\n * contributes(Capabilities.SettingsStore, store),\n * contributes(Capabilities.Translations, translations),\n * ];\n * })\n * );\n *\n * // Module with required options (context accessed via layer)\n * export default Capability.makeModule(\n * Effect.fnUntraced(function* (props: { observability: boolean }) {\n * const invoker = yield* Capability.get(Capabilities.OperationInvoker);\n * return contributes(Capabilities.OperationHandler, ...);\n * })\n * );\n * ```\n */\nexport const makeModule = <\n TProps = void,\n TReturn extends ModuleReturn = ModuleReturn,\n E extends Error = Error,\n R extends Service | Plugin.Service | never = Service,\n>(\n fn: (props: TProps) => Effect.Effect<TReturn, E, R>,\n): ((props: TProps) => Effect.Effect<TReturn, E, R>) => fn;\n"],
|
|
5
|
+
"mappings": ";;;;;AAAA;;;;;;;;;;;;;;;;AAKA,YAAYA,aAAa;AACzB,YAAYC,YAAY;AACxB,YAAYC,WAAW;AAehB,IAAMC,UAAN,cAA8BC,YAAI,uCAAA,EAAA,EAAA;AAGpC;AAUE,IAAMC,MAAM,CAAIC,iBACdC,eAAQJ,SAAS,CAACK,YAChBC,WAAI;EACTA,KAAK,MAAMD,QAAQH,IAAIC,YAAAA;EACvBI,OAAO,CAACC,UAAWA,iBAAiBC,QAAQD,QAAQ,IAAIC,MAAMC,OAAOF,KAAAA,CAAAA;AACvE,CAAA,CAAA;AAQG,IAAMG,SAAS,CAAIR,iBACjBS,WAAIZ,SAAS,CAACK,YAAYA,QAAQM,OAAOR,YAAAA,CAAAA;AAO3C,IAAMU,UAAU,CAAIV,iBAClBC,eAAQJ,SAAS,CAACK,YAAYA,QAAQQ,QAAQV,YAAAA,CAAAA;AAOhD,IAAMW,OAAO,CAAIX,iBACfS,WAAIZ,SAAS,CAACK,YAAYA,QAAQS,KAAKX,YAAAA,CAAAA;AAOzC,IAAMY,eAAe,CAC1BZ,iBAEOS,WAAIZ,SAAS,CAACK,YAAYA,QAAQU,aAAaZ,YAAAA,CAAAA;AAKjD,IAAMa,UAAU,CAAOb,cAA+Bc,QACrDC,aAAOD,KAAKf,IAAIC,YAAAA,EAAcgB,KAAYC,YAAK,CAAA;AAOhD,IAAMC,YAA2BC,uBAAOC,IAAI,+BAAA;AAkB5C,IAAMC,OAIT,CAAIC,eAAAA;AACN,SAAO;IAAEA;EAAW;AACtB;AAoCO,IAAMC,cAAc,CACzBC,cACAC,gBACAC,eAAAA;AAEA,SAAO;IACLC,WAAWH;IACXC;IACAC;EACF;AACF;AA4BO,IAAME,OAAO,CAClBC,MACAC,MAAAA;AAEA,QAAMC,SAAS,CAACC,UACPC,WAAI,aAAA;AACT,UAAM,EAAEC,SAASC,cAAa,IAAK,OAAcC,eAAQ,MAAMN,EAAAA,CAAAA;AAC/D,UAAMO,SAAS,OAAOF,cAAcH,KAAAA;AACpC,UAAMM,aAAaD,UAAU,OAAO,CAAA,IAAKE,MAAMC,QAAQH,MAAAA,IAAUE,MAAME,KAAKJ,MAAAA,IAAU;MAACA;;AACvF,WAAOC;EACT,CAAA;AAMF,SAAOI,OAAOC,OAAOZ,QAAQ;IAAE,CAACb,SAAAA,GAAYW;EAAK,CAAA;AACnD;AAQO,IAAMe,eAAe,CAACC,eAAAA;AAC3B,SAAOA,cAAc,OAAOA,eAAe,cAAc3B,aAAa2B,aAClEC,OAAOD,WAAW3B,SAAAA,CAAU,IAC5B6B;AACN;AA2CO,IAAMC,aAAa,CAMxBC,OACsDA;",
|
|
6
|
+
"names": ["Context", "Effect", "Layer", "Service", "Tag", "get", "interfaceDef", "flatMap", "manager", "try", "catch", "error", "Error", "String", "getAll", "map", "waitFor", "atom", "atomByModule", "asLayer", "tag", "effect", "pipe", "orDie", "ModuleTag", "Symbol", "for", "make", "identifier", "contributes", "interfaceDef", "implementation", "deactivate", "interface", "lazy", "name", "c", "lazyFn", "props", "gen", "default", "getCapability", "promise", "result", "normalized", "Array", "isArray", "from", "Object", "assign", "getModuleTag", "capability", "String", "undefined", "makeModule", "fn"]
|
|
7
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
capabilities_exports
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NKVRSMFN.mjs";
|
|
4
4
|
|
|
5
5
|
// src/helpers.ts
|
|
6
6
|
var topologicalSort = (nodes) => {
|
|
@@ -42,6 +42,7 @@ import { createContext, useContext } from "react";
|
|
|
42
42
|
import { raise } from "@dxos/debug";
|
|
43
43
|
var PluginManagerContext = createContext(void 0);
|
|
44
44
|
var usePluginManager = () => useContext(PluginManagerContext) ?? raise(new Error("Missing PluginManagerContext"));
|
|
45
|
+
var useOptionalPluginManager = () => useContext(PluginManagerContext);
|
|
45
46
|
var PluginManagerProvider = PluginManagerContext.Provider;
|
|
46
47
|
|
|
47
48
|
// src/ui/components/Surface/context.ts
|
|
@@ -54,7 +55,7 @@ import React3, { Fragment, Profiler, Suspense, forwardRef as forwardRef2, memo,
|
|
|
54
55
|
import { log } from "@dxos/log";
|
|
55
56
|
import { ErrorBoundary } from "@dxos/react-error-boundary";
|
|
56
57
|
import { useDefaultValue } from "@dxos/react-hooks";
|
|
57
|
-
import {
|
|
58
|
+
import { Position } from "@dxos/util";
|
|
58
59
|
|
|
59
60
|
// src/ui/components/Surface/SurfaceInfo.tsx
|
|
60
61
|
import React, { cloneElement, forwardRef, useCallback, useLayoutEffect, useState } from "react";
|
|
@@ -263,7 +264,7 @@ var emptySnapshot = () => EMPTY_SNAPSHOT;
|
|
|
263
264
|
|
|
264
265
|
// src/ui/components/Surface/SurfaceComponent.tsx
|
|
265
266
|
var __dxlog_file = "/__w/dxos/dxos/packages/sdk/app-framework/src/ui/components/Surface/SurfaceComponent.tsx";
|
|
266
|
-
var DEBUG = import.meta.env
|
|
267
|
+
var DEBUG = import.meta.env?.VITE_DEBUG;
|
|
267
268
|
var DEFAULT_PLACEHOLDER = /* @__PURE__ */ React3.createElement(Fragment, null);
|
|
268
269
|
var WebComponentWrapper = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef2(({ id, role, data, limit, definition, ...rest }, forwardedRef) => {
|
|
269
270
|
const containerRef = useRef2(null);
|
|
@@ -409,15 +410,15 @@ var SurfaceContextProvider = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef2(({
|
|
|
409
410
|
}))));
|
|
410
411
|
}));
|
|
411
412
|
SurfaceContextProvider.displayName = "SurfaceContextProvider";
|
|
412
|
-
var SurfaceComponent = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef2(({ id: _id,
|
|
413
|
+
var SurfaceComponent = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef2(({ id: _id, type, data: dataProp, limit, placeholder = DEFAULT_PLACEHOLDER, ...rest }, forwardedRef) => {
|
|
413
414
|
const data = useDefaultValue(dataProp, () => ({}));
|
|
414
415
|
const surfaces = useSurfaces();
|
|
415
|
-
const effectiveRole =
|
|
416
|
+
const effectiveRole = type?.role;
|
|
416
417
|
if (effectiveRole == null) {
|
|
417
418
|
if (DEBUG) {
|
|
418
|
-
log.warn("Surface
|
|
419
|
+
log.warn("Surface is missing required `type` prop", {
|
|
419
420
|
id: _id
|
|
420
|
-
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L:
|
|
421
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 193, S: void 0 });
|
|
421
422
|
}
|
|
422
423
|
return null;
|
|
423
424
|
}
|
|
@@ -430,7 +431,7 @@ var SurfaceComponent = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef2(({ id: _
|
|
|
430
431
|
log.warn("no candidates for surface", {
|
|
431
432
|
role: effectiveRole,
|
|
432
433
|
data
|
|
433
|
-
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L:
|
|
434
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 206, S: void 0 });
|
|
434
435
|
return null;
|
|
435
436
|
}
|
|
436
437
|
return /* @__PURE__ */ React3.createElement(Suspense, {
|
|
@@ -459,14 +460,14 @@ var ErrorFallback = ({ error }) => {
|
|
|
459
460
|
}, message));
|
|
460
461
|
};
|
|
461
462
|
var findCandidates = (surfaces, { role, data }) => {
|
|
462
|
-
return Object.values(surfaces).filter((definition) => Array.isArray(definition.role) ? definition.role.includes(role) : definition.role === role).filter(({ filter }) => filter ? filter(data ?? {}, role) : true).toSorted(
|
|
463
|
+
return Object.values(surfaces).filter((definition) => Array.isArray(definition.role) ? definition.role.includes(role) : definition.role === role).filter(({ filter }) => filter ? filter(data ?? {}, role) : true).toSorted(Position.compare);
|
|
463
464
|
};
|
|
464
465
|
var useSurfaces = () => {
|
|
465
466
|
const manager = usePluginManager();
|
|
466
467
|
const surfacesByModule = useAtomValue(manager.capabilities.atomByModule(capabilities_exports.ReactSurface));
|
|
467
468
|
return useMemo2(() => {
|
|
468
469
|
const result = [];
|
|
469
|
-
for (const [
|
|
470
|
+
for (const [_moduleId, surfaces] of Object.entries(surfacesByModule)) {
|
|
470
471
|
for (const def of surfaces.flat()) {
|
|
471
472
|
result.push(def);
|
|
472
473
|
}
|
|
@@ -476,24 +477,49 @@ var useSurfaces = () => {
|
|
|
476
477
|
surfacesByModule
|
|
477
478
|
]);
|
|
478
479
|
};
|
|
479
|
-
function isSurfaceAvailable(capabilityManager,
|
|
480
|
-
const effectiveRole =
|
|
480
|
+
function isSurfaceAvailable(capabilityManager, args) {
|
|
481
|
+
const effectiveRole = args.type?.role;
|
|
481
482
|
if (effectiveRole == null) {
|
|
482
483
|
return false;
|
|
483
484
|
}
|
|
484
485
|
const surfaces = capabilityManager.getAll(capabilities_exports.ReactSurface);
|
|
485
486
|
const candidates = findCandidates(surfaces.flat(), {
|
|
486
487
|
role: effectiveRole,
|
|
487
|
-
data
|
|
488
|
+
data: args.data
|
|
488
489
|
});
|
|
489
490
|
return candidates.length > 0;
|
|
490
491
|
}
|
|
491
492
|
|
|
492
493
|
// src/ui/components/Surface/types.ts
|
|
494
|
+
import { log as log2 } from "@dxos/log";
|
|
495
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/sdk/app-framework/src/ui/components/Surface/types.ts";
|
|
493
496
|
var isSurfaceFilter = (value) => typeof value === "object" && value !== null && Array.isArray(value.bindings);
|
|
494
|
-
var makeType = (
|
|
495
|
-
|
|
496
|
-
});
|
|
497
|
+
var makeType = (nsid) => {
|
|
498
|
+
if (typeof nsid !== "string" || !/^[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(\.[a-zA-Z][a-zA-Z0-9]{0,62})$/.test(nsid)) {
|
|
499
|
+
throw new Error(`Invalid role NSID: "${nsid}". Must be a dotted name with a camelCase final segment (no hyphens in the last segment).`);
|
|
500
|
+
}
|
|
501
|
+
return {
|
|
502
|
+
role: nsid
|
|
503
|
+
};
|
|
504
|
+
};
|
|
505
|
+
var makeFilter = (token, guard) => {
|
|
506
|
+
const boundGuard = guard == null ? () => true : (data) => {
|
|
507
|
+
try {
|
|
508
|
+
return guard(data);
|
|
509
|
+
} catch (err) {
|
|
510
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 39, S: void 0 });
|
|
511
|
+
return false;
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
return {
|
|
515
|
+
bindings: [
|
|
516
|
+
{
|
|
517
|
+
role: token.role,
|
|
518
|
+
guard: boundGuard
|
|
519
|
+
}
|
|
520
|
+
]
|
|
521
|
+
};
|
|
522
|
+
};
|
|
497
523
|
var expandBindings = (filter) => {
|
|
498
524
|
const bindings = filter.bindings;
|
|
499
525
|
const roles = Array.from(new Set(bindings.map((binding) => binding.role)));
|
|
@@ -517,40 +543,28 @@ var validateLocalId = (id) => {
|
|
|
517
543
|
};
|
|
518
544
|
function create(definition) {
|
|
519
545
|
validateLocalId(definition.id);
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
const { role, guard } = expandBindings(filter);
|
|
523
|
-
return {
|
|
524
|
-
kind: "react",
|
|
525
|
-
id,
|
|
526
|
-
role,
|
|
527
|
-
position,
|
|
528
|
-
component,
|
|
529
|
-
filter: guard
|
|
530
|
-
};
|
|
531
|
-
}
|
|
546
|
+
const { id, filter, component, position } = definition;
|
|
547
|
+
const { role, guard } = expandBindings(filter);
|
|
532
548
|
return {
|
|
533
|
-
|
|
534
|
-
|
|
549
|
+
kind: "react",
|
|
550
|
+
id,
|
|
551
|
+
role,
|
|
552
|
+
position,
|
|
553
|
+
component,
|
|
554
|
+
filter: guard
|
|
535
555
|
};
|
|
536
556
|
}
|
|
537
557
|
function createWeb(definition) {
|
|
538
558
|
validateLocalId(definition.id);
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
const { role, guard } = expandBindings(filter);
|
|
542
|
-
return {
|
|
543
|
-
kind: "web-component",
|
|
544
|
-
id,
|
|
545
|
-
role,
|
|
546
|
-
position,
|
|
547
|
-
tagName,
|
|
548
|
-
filter: guard
|
|
549
|
-
};
|
|
550
|
-
}
|
|
559
|
+
const { id, filter, tagName, position } = definition;
|
|
560
|
+
const { role, guard } = expandBindings(filter);
|
|
551
561
|
return {
|
|
552
|
-
|
|
553
|
-
|
|
562
|
+
kind: "web-component",
|
|
563
|
+
id,
|
|
564
|
+
role,
|
|
565
|
+
position,
|
|
566
|
+
tagName,
|
|
567
|
+
filter: guard
|
|
554
568
|
};
|
|
555
569
|
}
|
|
556
570
|
|
|
@@ -562,6 +576,7 @@ function createWeb(definition) {
|
|
|
562
576
|
Surface2.Surface = SurfaceComponent;
|
|
563
577
|
Surface2.isAvailable = isSurfaceAvailable;
|
|
564
578
|
Surface2.makeType = makeType;
|
|
579
|
+
Surface2.makeFilter = makeFilter;
|
|
565
580
|
Surface2.isFilter = isSurfaceFilter;
|
|
566
581
|
Surface2.ProfilerProvider = SurfaceProfilerProvider;
|
|
567
582
|
Surface2.useProfilerCallback = useSurfaceProfilerCallback;
|
|
@@ -580,8 +595,9 @@ export {
|
|
|
580
595
|
topologicalSort,
|
|
581
596
|
useSurface,
|
|
582
597
|
usePluginManager,
|
|
598
|
+
useOptionalPluginManager,
|
|
583
599
|
PluginManagerProvider,
|
|
584
600
|
SurfaceComponent,
|
|
585
601
|
Surface
|
|
586
602
|
};
|
|
587
|
-
//# sourceMappingURL=chunk-
|
|
603
|
+
//# sourceMappingURL=chunk-U5MESPM5.mjs.map
|