@dxos/app-framework 0.9.1-main.c7dcc2e112 → 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-Z4MRP3CP.mjs → capability-S44TE2H7.mjs} +6 -6
- package/dist/lib/browser/{chunk-DFVSOBV2.mjs → chunk-KRJ4KK2W.mjs} +24 -5
- package/dist/lib/browser/{chunk-DFVSOBV2.mjs.map → chunk-KRJ4KK2W.mjs.map} +3 -3
- package/dist/lib/browser/{chunk-3UTDRCKX.mjs → chunk-LUH4Y5F2.mjs} +2 -2
- package/dist/lib/browser/{chunk-37PG7XJC.mjs → chunk-NKVRSMFN.mjs} +2 -2
- package/dist/lib/browser/{chunk-37PG7XJC.mjs.map → chunk-NKVRSMFN.mjs.map} +1 -1
- package/dist/lib/browser/{chunk-S2ZBYQPI.mjs → chunk-OO53M5UK.mjs} +2 -2
- package/dist/lib/browser/{chunk-CMINFVA5.mjs → chunk-OPTS3ZSN.mjs} +1 -1
- package/dist/lib/browser/{chunk-CMINFVA5.mjs.map → chunk-OPTS3ZSN.mjs.map} +2 -2
- package/dist/lib/browser/{chunk-SWECIICH.mjs → chunk-U5MESPM5.mjs} +6 -6
- package/dist/lib/browser/chunk-U5MESPM5.mjs.map +7 -0
- package/dist/lib/browser/{chunk-W4BHZING.mjs → chunk-UGYCLOXE.mjs} +3 -3
- package/dist/lib/browser/cli/index.mjs +5 -5
- package/dist/lib/browser/common/activation-events.mjs +4 -4
- package/dist/lib/browser/common/capabilities.mjs +5 -5
- package/dist/lib/browser/core/capability.mjs +1 -1
- package/dist/lib/browser/core/plugin-manager.mjs +3 -3
- package/dist/lib/browser/core/plugin.mjs +2 -2
- package/dist/lib/browser/core/url-loader.mjs +3 -3
- package/dist/lib/browser/index.mjs +7 -7
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{process-manager-capability-RDROCCQD.mjs → process-manager-capability-QK4BMKMN.mjs} +6 -6
- package/dist/lib/browser/testing/index.mjs +7 -7
- package/dist/lib/browser/testing/react.mjs +6 -6
- package/dist/lib/browser/testing/react.mjs.map +2 -2
- package/dist/lib/browser/ui/index.mjs +9 -7
- package/dist/lib/node-esm/{capability-34Z6NPVR.mjs → capability-3YRF77LV.mjs} +6 -6
- package/dist/lib/node-esm/{chunk-WERVO5EK.mjs → chunk-4SE7SX7N.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-H7T7XXLS.mjs → chunk-DRT75WGD.mjs} +6 -6
- package/dist/lib/node-esm/chunk-DRT75WGD.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-TEQSMP2O.mjs → chunk-FKMVORZN.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-AIDZMJ3U.mjs → chunk-GLH4LGHZ.mjs} +1 -1
- package/dist/lib/node-esm/{chunk-AIDZMJ3U.mjs.map → chunk-GLH4LGHZ.mjs.map} +2 -2
- package/dist/lib/node-esm/{chunk-ZRTG4TSS.mjs → chunk-IL7O7IRX.mjs} +3 -3
- package/dist/lib/node-esm/{chunk-A4O42ZO3.mjs → chunk-ND2HETHD.mjs} +24 -5
- package/dist/lib/node-esm/{chunk-A4O42ZO3.mjs.map → chunk-ND2HETHD.mjs.map} +3 -3
- package/dist/lib/node-esm/{chunk-LUK3FCTH.mjs → chunk-XSZMX53L.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-LUK3FCTH.mjs.map → chunk-XSZMX53L.mjs.map} +1 -1
- package/dist/lib/node-esm/cli/index.mjs +5 -5
- package/dist/lib/node-esm/common/activation-events.mjs +4 -4
- package/dist/lib/node-esm/common/capabilities.mjs +5 -5
- package/dist/lib/node-esm/core/capability.mjs +1 -1
- package/dist/lib/node-esm/core/plugin-manager.mjs +3 -3
- package/dist/lib/node-esm/core/plugin.mjs +2 -2
- package/dist/lib/node-esm/core/url-loader.mjs +3 -3
- package/dist/lib/node-esm/index.mjs +7 -7
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{process-manager-capability-6OCXSKUW.mjs → process-manager-capability-5S7WZ2JR.mjs} +6 -6
- package/dist/lib/node-esm/testing/index.mjs +7 -7
- package/dist/lib/node-esm/testing/react.mjs +6 -6
- package/dist/lib/node-esm/testing/react.mjs.map +2 -2
- package/dist/lib/node-esm/ui/index.mjs +9 -7
- package/dist/plugin/node-esm/index.mjs +9 -11
- package/dist/plugin/node-esm/index.mjs.map +3 -3
- package/dist/plugin/node-esm/meta.json +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/core/capability.d.ts +3 -1
- package/dist/types/src/core/capability.d.ts.map +1 -1
- package/dist/types/src/core/plugin.d.ts +8 -0
- package/dist/types/src/core/plugin.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 +4 -0
- 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/react.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/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.map +1 -1
- package/dist/types/src/ui/components/Surface/index.d.ts +1 -1
- package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/types.d.ts +2 -2
- package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -1
- package/dist/types/src/ui/hooks/useCapabilities.d.ts +6 -0
- package/dist/types/src/ui/hooks/useCapabilities.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/packages.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/docs/registry-spec.md +26 -26
- package/package.json +44 -38
- package/src/common/capabilities.ts +2 -2
- package/src/core/capability.ts +3 -2
- package/src/testing/react.tsx +1 -1
- package/src/ui/components/App/App.stories.tsx +2 -2
- package/src/ui/components/Surface/SurfaceComponent.stories.tsx +11 -8
- package/src/ui/components/Surface/SurfaceComponent.tsx +6 -5
- package/src/ui/components/Surface/SurfaceProfilerContext.tsx +1 -1
- package/src/ui/components/Surface/context.ts +0 -1
- package/src/ui/components/Surface/index.ts +2 -2
- package/src/ui/components/Surface/types.test.ts +4 -2
- package/src/ui/components/Surface/types.ts +4 -4
- package/src/ui/hooks/useCapabilities.ts +25 -0
- 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 +1 -1
- package/src/vite-plugin/import-map/index.ts +23 -7
- package/src/vite-plugin/packages.ts +0 -1
- package/tsconfig.json +5 -2
- package/dist/lib/browser/chunk-SWECIICH.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-H7T7XXLS.mjs.map +0 -7
- /package/dist/lib/browser/{capability-Z4MRP3CP.mjs.map → capability-S44TE2H7.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-3UTDRCKX.mjs.map → chunk-LUH4Y5F2.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-S2ZBYQPI.mjs.map → chunk-OO53M5UK.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-W4BHZING.mjs.map → chunk-UGYCLOXE.mjs.map} +0 -0
- /package/dist/lib/browser/{process-manager-capability-RDROCCQD.mjs.map → process-manager-capability-QK4BMKMN.mjs.map} +0 -0
- /package/dist/lib/node-esm/{capability-34Z6NPVR.mjs.map → capability-3YRF77LV.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-WERVO5EK.mjs.map → chunk-4SE7SX7N.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-TEQSMP2O.mjs.map → chunk-FKMVORZN.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-ZRTG4TSS.mjs.map → chunk-IL7O7IRX.mjs.map} +0 -0
- /package/dist/lib/node-esm/{process-manager-capability-6OCXSKUW.mjs.map → process-manager-capability-5S7WZ2JR.mjs.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/testing/react.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2026 DXOS.org\n//\n\nimport { RegistryContext } from '@effect-atom/atom-react';\nimport {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;AAIA,SAASA,uBAAuB;AAChC,
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2026 DXOS.org\n//\n\nimport { RegistryContext } from '@effect-atom/atom-react';\nimport { type RenderOptions, type RenderResult, render as rtlRender } from '@testing-library/react';\nimport React, { type FC, Fragment, type PropsWithChildren, type ReactNode } from 'react';\n\nimport { ContextProtocolProvider } from '@dxos/web-context-react';\n\nimport { Capabilities } from '../common';\nimport { PluginManagerContext } from '../context';\nimport { topologicalSort } from '../helpers';\nimport { PluginManagerProvider } from '../ui/components/PluginManager/PluginManagerProvider';\nimport { SurfaceComponent } from '../ui/components/Surface/SurfaceComponent';\nimport { type RoleToken } from '../ui/components/Surface/types';\nimport { type TestHarness } from './harness';\n\nexport type HarnessRenderOptions = Omit<RenderOptions, 'wrapper'> & {\n /** Additional providers to wrap around the harness tree (applied innermost first). */\n reactContexts?: FC<PropsWithChildren>[];\n};\n\n/**\n * Renders `ui` wrapped in the same provider tree as `useApp` plus every contributed\n * `Capabilities.ReactContext`.\n */\nexport const render = (harness: TestHarness, ui: ReactNode, options?: HarnessRenderOptions): RenderResult => {\n const { reactContexts = [], ...rest } = options ?? {};\n const Wrapper = ({ children }: PropsWithChildren) => (\n <HarnessProviders harness={harness} extra={reactContexts}>\n {children}\n </HarnessProviders>\n );\n return rtlRender(<>{ui}</>, { ...rest, wrapper: Wrapper });\n};\n\nexport type RenderSurfaceProps<TToken extends RoleToken<any>> = {\n type: TToken;\n data?: TToken extends RoleToken<infer D> ? D : never;\n limit?: number;\n fallback?: FC<{ error: Error; data?: any }>;\n placeholder?: ReactNode;\n};\n\n/**\n * Renders a `Surface` with the given role token/data inside the harness provider tree.\n */\nexport const renderSurface = <TToken extends RoleToken<any>>(\n harness: TestHarness,\n props: RenderSurfaceProps<TToken>,\n options?: HarnessRenderOptions,\n): RenderResult => {\n const { type, data, limit, fallback, placeholder } = props;\n return render(\n harness,\n <SurfaceComponent type={type} data={data as any} limit={limit} fallback={fallback} placeholder={placeholder} />,\n options,\n );\n};\n\ntype HarnessProvidersProps = PropsWithChildren<{\n harness: TestHarness;\n extra: FC<PropsWithChildren>[];\n}>;\n\nconst HarnessProviders = ({ harness, extra, children }: HarnessProvidersProps) => {\n const contributed = harness.getAll(Capabilities.ReactContext);\n const ContributedContext = composeContexts(contributed);\n const ExtraContext = composeExtra(extra);\n return (\n <PluginManagerProvider value={harness.manager}>\n <ContextProtocolProvider value={harness.manager} context={PluginManagerContext}>\n <RegistryContext.Provider value={harness.registry}>\n <ContributedContext>\n <ExtraContext>{children}</ExtraContext>\n </ContributedContext>\n </RegistryContext.Provider>\n </ContextProtocolProvider>\n </PluginManagerProvider>\n );\n};\n\nconst composeContexts = (contexts: Capabilities.ReactContext[]): FC<PropsWithChildren> => {\n if (contexts.length === 0) {\n return Passthrough;\n }\n return topologicalSort(contexts)\n .map(({ context }) => context)\n .reduce((Acc, Next) => ({ children }: PropsWithChildren) => (\n <Acc>\n <Next>{children}</Next>\n </Acc>\n ));\n};\n\n// Composes in innermost-first order: the first context in the array wraps\n// `children` directly; subsequent contexts wrap the accumulator.\nconst composeExtra = (contexts: FC<PropsWithChildren>[]): FC<PropsWithChildren> => {\n if (contexts.length === 0) {\n return Passthrough;\n }\n return contexts.reduce<FC<PropsWithChildren>>(\n (Acc, Next) =>\n ({ children }: PropsWithChildren) => (\n <Next>\n <Acc>{children}</Acc>\n </Next>\n ),\n Passthrough,\n );\n};\n\nconst Passthrough: FC<PropsWithChildren> = ({ children }) => <Fragment>{children}</Fragment>;\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;AAIA,SAASA,uBAAuB;AAChC,SAAgDC,UAAUC,iBAAiB;AAC3E,OAAOC,SAAkBC,gBAAwD;AAEjF,SAASC,+BAA+B;AAmBjC,IAAMC,SAAS,CAACC,SAAsBC,IAAeC,YAAAA;AAC1D,QAAM,EAAEC,gBAAgB,CAAA,GAAI,GAAGC,KAAAA,IAASF,WAAW,CAAC;AACpD,QAAMG,UAAU,CAAC,EAAEC,SAAQ,MACzB,sBAAA,cAACC,kBAAAA;IAAiBP;IAAkBQ,OAAOL;KACxCG,QAAAA;AAGL,SAAOG,UAAU,sBAAA,cAAA,MAAA,UAAA,MAAGR,EAAAA,GAAQ;IAAE,GAAGG;IAAMM,SAASL;EAAQ,CAAA;AAC1D;AAaO,IAAMM,gBAAgB,CAC3BX,SACAY,OACAV,YAAAA;AAEA,QAAM,EAAEW,MAAMC,MAAMC,OAAOC,UAAUC,YAAW,IAAKL;AACrD,SAAOb,OACLC,SACA,sBAAA,cAACkB,kBAAAA;IAAiBL;IAAYC;IAAmBC;IAAcC;IAAoBC;MACnFf,OAAAA;AAEJ;AAOA,IAAMK,mBAAmB,CAAC,EAAEP,SAASQ,OAAOF,SAAQ,MAAyB;AAC3E,QAAMa,cAAcnB,QAAQoB,OAAOC,qBAAaC,YAAY;AAC5D,QAAMC,qBAAqBC,gBAAgBL,WAAAA;AAC3C,QAAMM,eAAeC,aAAalB,KAAAA;AAClC,SACE,sBAAA,cAACmB,uBAAAA;IAAsBC,OAAO5B,QAAQ6B;KACpC,sBAAA,cAACC,yBAAAA;IAAwBF,OAAO5B,QAAQ6B;IAASE,SAASC;KACxD,sBAAA,cAACC,gBAAgBC,UAAQ;IAACN,OAAO5B,QAAQmC;KACvC,sBAAA,cAACZ,oBAAAA,MACC,sBAAA,cAACE,cAAAA,MAAcnB,QAAAA,CAAAA,CAAAA,CAAAA,CAAAA;AAM3B;AAEA,IAAMkB,kBAAkB,CAACY,aAAAA;AACvB,MAAIA,SAASC,WAAW,GAAG;AACzB,WAAOC;EACT;AACA,SAAOC,gBAAgBH,QAAAA,EACpBI,IAAI,CAAC,EAAET,QAAO,MAAOA,OAAAA,EACrBU,OAAO,CAACC,KAAKC,SAAS,CAAC,EAAErC,SAAQ,MAChC,sBAAA,cAACoC,KAAAA,MACC,sBAAA,cAACC,MAAAA,MAAMrC,QAAAA,CAAAA,CAAAA;AAGf;AAIA,IAAMoB,eAAe,CAACU,aAAAA;AACpB,MAAIA,SAASC,WAAW,GAAG;AACzB,WAAOC;EACT;AACA,SAAOF,SAASK,OACd,CAACC,KAAKC,SACJ,CAAC,EAAErC,SAAQ,MACT,sBAAA,cAACqC,MAAAA,MACC,sBAAA,cAACD,KAAAA,MAAKpC,QAAAA,CAAAA,GAGZgC,WAAAA;AAEJ;AAEA,IAAMA,cAAqC,CAAC,EAAEhC,SAAQ,MAAO,sBAAA,cAACsC,UAAAA,MAAUtC,QAAAA;",
|
|
6
6
|
"names": ["RegistryContext", "render", "rtlRender", "React", "Fragment", "ContextProtocolProvider", "render", "harness", "ui", "options", "reactContexts", "rest", "Wrapper", "children", "HarnessProviders", "extra", "rtlRender", "wrapper", "renderSurface", "props", "type", "data", "limit", "fallback", "placeholder", "SurfaceComponent", "contributed", "getAll", "Capabilities", "ReactContext", "ContributedContext", "composeContexts", "ExtraContext", "composeExtra", "PluginManagerProvider", "value", "manager", "ContextProtocolProvider", "context", "PluginManagerContext", "RegistryContext", "Provider", "registry", "contexts", "length", "Passthrough", "topologicalSort", "map", "reduce", "Acc", "Next", "Fragment"]
|
|
7
7
|
}
|
|
@@ -8,30 +8,31 @@ import {
|
|
|
8
8
|
useCapability,
|
|
9
9
|
useLoading,
|
|
10
10
|
useOperationInvoker,
|
|
11
|
+
useOptionalAtomCapabilityState,
|
|
11
12
|
useOptionalCapabilities,
|
|
12
13
|
useOptionalCapability,
|
|
13
14
|
useProcessManagerRuntime,
|
|
14
15
|
useSettingsState,
|
|
15
16
|
useSpaceCallback,
|
|
16
17
|
useSpaceService
|
|
17
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-KRJ4KK2W.mjs";
|
|
18
19
|
import {
|
|
19
20
|
PluginManagerProvider,
|
|
20
21
|
Surface,
|
|
21
22
|
useOptionalPluginManager,
|
|
22
23
|
usePluginManager,
|
|
23
24
|
useSurface
|
|
24
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-U5MESPM5.mjs";
|
|
25
26
|
import "../chunk-FJ4765WW.mjs";
|
|
26
27
|
import "../chunk-Q2GLJTVV.mjs";
|
|
27
|
-
import "../chunk-
|
|
28
|
+
import "../chunk-NKVRSMFN.mjs";
|
|
28
29
|
import "../chunk-VF37YTXJ.mjs";
|
|
29
30
|
import "../chunk-YUVQIOTB.mjs";
|
|
30
|
-
import "../chunk-
|
|
31
|
-
import "../chunk-
|
|
31
|
+
import "../chunk-LUH4Y5F2.mjs";
|
|
32
|
+
import "../chunk-UGYCLOXE.mjs";
|
|
32
33
|
import "../chunk-3NQLTQCP.mjs";
|
|
33
|
-
import "../chunk-
|
|
34
|
-
import "../chunk-
|
|
34
|
+
import "../chunk-OO53M5UK.mjs";
|
|
35
|
+
import "../chunk-OPTS3ZSN.mjs";
|
|
35
36
|
import "../chunk-J5LGTIGS.mjs";
|
|
36
37
|
export {
|
|
37
38
|
App,
|
|
@@ -45,6 +46,7 @@ export {
|
|
|
45
46
|
useCapability,
|
|
46
47
|
useLoading,
|
|
47
48
|
useOperationInvoker,
|
|
49
|
+
useOptionalAtomCapabilityState,
|
|
48
50
|
useOptionalCapabilities,
|
|
49
51
|
useOptionalCapability,
|
|
50
52
|
useOptionalPluginManager,
|
|
@@ -6,16 +6,16 @@ import {
|
|
|
6
6
|
import "./chunk-FPW45EZH.mjs";
|
|
7
7
|
import {
|
|
8
8
|
capabilities_exports
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-XSZMX53L.mjs";
|
|
10
10
|
import "./chunk-TLKYZKPW.mjs";
|
|
11
11
|
import "./chunk-VCPGX7WN.mjs";
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-FKMVORZN.mjs";
|
|
13
|
+
import "./chunk-IL7O7IRX.mjs";
|
|
14
14
|
import "./chunk-BMW6P6QA.mjs";
|
|
15
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-4SE7SX7N.mjs";
|
|
16
16
|
import {
|
|
17
17
|
capability_exports
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-GLH4LGHZ.mjs";
|
|
19
19
|
import "./chunk-HSLMI22Q.mjs";
|
|
20
20
|
|
|
21
21
|
// src/plugin-process-manager/history/capability.ts
|
|
@@ -33,4 +33,4 @@ var capability_default = capability_exports.makeModule(Effect.fnUntraced(functio
|
|
|
33
33
|
export {
|
|
34
34
|
capability_default as default
|
|
35
35
|
};
|
|
36
|
-
//# sourceMappingURL=capability-
|
|
36
|
+
//# sourceMappingURL=capability-3YRF77LV.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
getModuleTag
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-GLH4LGHZ.mjs";
|
|
5
5
|
import {
|
|
6
6
|
__export
|
|
7
7
|
} from "./chunk-HSLMI22Q.mjs";
|
|
@@ -258,4 +258,4 @@ export {
|
|
|
258
258
|
resolveLazy,
|
|
259
259
|
plugin_exports
|
|
260
260
|
};
|
|
261
|
-
//# sourceMappingURL=chunk-
|
|
261
|
+
//# sourceMappingURL=chunk-4SE7SX7N.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
capabilities_exports
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-XSZMX53L.mjs";
|
|
5
5
|
|
|
6
6
|
// src/helpers.ts
|
|
7
7
|
var topologicalSort = (nodes) => {
|
|
@@ -56,7 +56,7 @@ import React3, { Fragment, Profiler, Suspense, forwardRef as forwardRef2, memo,
|
|
|
56
56
|
import { log } from "@dxos/log";
|
|
57
57
|
import { ErrorBoundary } from "@dxos/react-error-boundary";
|
|
58
58
|
import { useDefaultValue } from "@dxos/react-hooks";
|
|
59
|
-
import {
|
|
59
|
+
import { Position } from "@dxos/util";
|
|
60
60
|
|
|
61
61
|
// src/ui/components/Surface/SurfaceInfo.tsx
|
|
62
62
|
import React, { cloneElement, forwardRef, useCallback, useLayoutEffect, useState } from "react";
|
|
@@ -265,7 +265,7 @@ var emptySnapshot = () => EMPTY_SNAPSHOT;
|
|
|
265
265
|
|
|
266
266
|
// src/ui/components/Surface/SurfaceComponent.tsx
|
|
267
267
|
var __dxlog_file = "/__w/dxos/dxos/packages/sdk/app-framework/src/ui/components/Surface/SurfaceComponent.tsx";
|
|
268
|
-
var DEBUG = import.meta.env
|
|
268
|
+
var DEBUG = import.meta.env?.VITE_DEBUG;
|
|
269
269
|
var DEFAULT_PLACEHOLDER = /* @__PURE__ */ React3.createElement(Fragment, null);
|
|
270
270
|
var WebComponentWrapper = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef2(({ id, role, data, limit, definition, ...rest }, forwardedRef) => {
|
|
271
271
|
const containerRef = useRef2(null);
|
|
@@ -461,14 +461,14 @@ var ErrorFallback = ({ error }) => {
|
|
|
461
461
|
}, message));
|
|
462
462
|
};
|
|
463
463
|
var findCandidates = (surfaces, { role, data }) => {
|
|
464
|
-
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(
|
|
464
|
+
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);
|
|
465
465
|
};
|
|
466
466
|
var useSurfaces = () => {
|
|
467
467
|
const manager = usePluginManager();
|
|
468
468
|
const surfacesByModule = useAtomValue(manager.capabilities.atomByModule(capabilities_exports.ReactSurface));
|
|
469
469
|
return useMemo2(() => {
|
|
470
470
|
const result = [];
|
|
471
|
-
for (const [
|
|
471
|
+
for (const [_moduleId, surfaces] of Object.entries(surfacesByModule)) {
|
|
472
472
|
for (const def of surfaces.flat()) {
|
|
473
473
|
result.push(def);
|
|
474
474
|
}
|
|
@@ -601,4 +601,4 @@ export {
|
|
|
601
601
|
SurfaceComponent,
|
|
602
602
|
Surface
|
|
603
603
|
};
|
|
604
|
-
//# sourceMappingURL=chunk-
|
|
604
|
+
//# sourceMappingURL=chunk-DRT75WGD.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/helpers.ts", "../../../src/ui/hooks/useSurface.ts", "../../../src/ui/components/PluginManager/PluginManagerProvider.ts", "../../../src/ui/components/Surface/context.ts", "../../../src/ui/components/Surface/SurfaceComponent.tsx", "../../../src/ui/components/Surface/SurfaceInfo.tsx", "../../../src/ui/components/Surface/SurfaceProfilerContext.tsx", "../../../src/ui/components/Surface/types.ts", "../../../src/ui/components/Surface/index.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\ntype DependencyNode = {\n id: string;\n dependsOn?: string[];\n};\n\n/**\n * Topologically sorts a list of nodes based on their dependencies.\n */\n// TODO(wittjosiah): Factor out?\nexport const topologicalSort = <T extends DependencyNode>(nodes: T[]): T[] => {\n const getDependencies = (nodeId: string, seen = new Set<string>(), path = new Set<string>()): string[] => {\n if (path.has(nodeId)) {\n throw new Error(`Circular dependency detected involving ${nodeId}`);\n }\n if (seen.has(nodeId)) {\n return [];\n }\n\n const node = nodes.find((n) => n.id === nodeId);\n if (!node) {\n throw new Error(`Node ${nodeId} not found but is listed as a dependency`);\n }\n\n const newPath = new Set([...path, nodeId]);\n const newSeen = new Set([...seen, nodeId]);\n\n const dependsOn = node.dependsOn ?? [];\n return [...dependsOn.flatMap((depId) => getDependencies(depId, newSeen, newPath)), nodeId];\n };\n\n // Get all unique dependencies.\n const allDependencies = nodes\n .map((node) => node.id)\n .flatMap((id) => getDependencies(id))\n .filter((id, index, self) => self.indexOf(id) === index);\n\n // Map back to original nodes\n return allDependencies\n .map((id) => nodes.find((node) => node.id === id))\n .filter((node): node is T => node !== undefined);\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { useContext } from 'react';\n\nimport { raise } from '@dxos/debug';\n\nimport { Surface } from '../components';\n\nexport const useSurface = (): Surface.Context => {\n return useContext(Surface.Context) ?? raise(new Error('Missing SurfaceContext'));\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { createContext, useContext } from 'react';\n\nimport { raise } from '@dxos/debug';\n\nimport { type PluginManager } from '../../../core';\n\nconst PluginManagerContext = createContext<PluginManager.PluginManager | undefined>(undefined);\n\n/**\n * Get the plugin manager.\n */\nexport const usePluginManager = (): PluginManager.PluginManager =>\n useContext(PluginManagerContext) ?? raise(new Error('Missing PluginManagerContext'));\n\n/**\n * Get the plugin manager if present, or `undefined` when rendered outside a {@link PluginManagerProvider}\n * (e.g. a standalone component story). Lets components treat plugin capabilities as a progressive\n * enhancement rather than a hard requirement.\n */\nexport const useOptionalPluginManager = (): PluginManager.PluginManager | undefined => useContext(PluginManagerContext);\n\n/**\n * Context provider for a plugin manager.\n */\nexport const PluginManagerProvider = PluginManagerContext.Provider;\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Context, createContext } from 'react';\n\nexport type SurfaceContext = {\n id?: string;\n /** The resolved role NSID (e.g. `org.dxos.role.article`). */\n role: string;\n data?: Record<string, any>;\n};\n\nexport const SurfaceContext: Context<SurfaceContext | undefined> = createContext<SurfaceContext | undefined>(undefined);\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { useAtomValue } from '@effect-atom/atom-react';\nimport React, {\n type FC,\n Fragment,\n type NamedExoticComponent,\n Profiler,\n type RefAttributes,\n Suspense,\n forwardRef,\n memo,\n useEffect,\n useMemo,\n useRef,\n} from 'react';\n\nimport { log } from '@dxos/log';\nimport { ErrorBoundary } from '@dxos/react-error-boundary';\nimport { useDefaultValue } from '@dxos/react-hooks';\nimport { Position } from '@dxos/util';\n\nimport { Capabilities } from '../../../common';\nimport { type CapabilityManager } from '../../../core';\nimport { usePluginManager } from '../PluginManager';\nimport { SurfaceContext } from './context';\nimport { SurfaceInfo } from './SurfaceInfo';\nimport { useSurfaceProfilerCallback } from './SurfaceProfilerContext';\nimport {\n type Definition,\n type Props,\n type RoleToken,\n type TokenData,\n type TypedProps,\n type WebComponentDefinition,\n} from './types';\n\nconst DEBUG = import.meta.env?.VITE_DEBUG;\n\nconst DEFAULT_PLACEHOLDER = <Fragment />;\n\n/**\n * Wrapper component for rendering Web Component surfaces.\n * Handles creation, prop setting, and cleanup of Web Components.\n */\ntype WebComponentWrapperProps = {\n id?: string;\n role: string;\n data?: Record<string, any>;\n limit?: number;\n definition: WebComponentDefinition;\n [key: string]: any;\n};\n\nconst WebComponentWrapper = memo(\n forwardRef<HTMLElement, WebComponentWrapperProps>(({ id, role, data, limit, definition, ...rest }, forwardedRef) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const elementRef = useRef<HTMLElement | null>(null);\n const propsRef = useRef({ id, role, data, limit, ...rest });\n\n // Update props ref on every render\n propsRef.current = { id, role, data, limit, ...rest };\n\n // Create element only once\n useEffect(() => {\n if (!containerRef.current || elementRef.current) {\n return;\n }\n\n // Create the Web Component\n const element = document.createElement(definition.tagName);\n elementRef.current = element;\n\n // Set initial properties on the Web Component\n Object.assign(element, propsRef.current);\n\n // Append to container\n containerRef.current.appendChild(element);\n\n // Setup ref forwarding if provided\n if (typeof forwardedRef === 'function') {\n forwardedRef(element);\n } else if (forwardedRef) {\n forwardedRef.current = element;\n }\n\n // Cleanup on unmount to prevent memory leaks\n return () => {\n if (elementRef.current && containerRef.current?.contains(elementRef.current)) {\n containerRef.current.removeChild(elementRef.current);\n }\n if (typeof forwardedRef === 'function') {\n forwardedRef(null);\n } else if (forwardedRef) {\n forwardedRef.current = null;\n }\n elementRef.current = null;\n };\n }, [definition.tagName, forwardedRef]);\n\n // Update props on existing element without recreating it\n // This runs on every render to ensure all props (including those in `rest`) are kept up to date\n useEffect(() => {\n const element = elementRef.current;\n if (!element) {\n return;\n }\n\n // Update properties on the existing Web Component\n Object.assign(element, propsRef.current);\n });\n\n return <div ref={containerRef} />;\n }),\n);\n\nWebComponentWrapper.displayName = 'WebComponentWrapper';\n\ntype SurfaceContextProviderProps = {\n id: string;\n role: string;\n data?: Record<string, any>;\n limit?: number;\n fallback?: FC<{ error: Error; data?: any }>;\n definition: Definition;\n [key: string]: any;\n};\n\n/**\n * Wrapper component that provides context for a surface.\n */\n// TODO(burdon): Allow DebugPlugin to provide different fallback using react-ui ErrorFallback.\nconst SurfaceContextProvider = memo(\n forwardRef<HTMLElement, SurfaceContextProviderProps>(\n ({ id, role, data, limit, fallback = ErrorFallback, definition, ...rest }, forwardedRef) => {\n const contextValue = useMemo(() => ({ id, role, data }), [id, role, data]);\n const onProfilerRender = useSurfaceProfilerCallback();\n const profilerId = `surface/${id}/${role}`;\n\n // Handle Web Component surfaces\n if (definition.kind === 'web-component') {\n return (\n <ErrorBoundary name='surface' resetKeys={[data]} FallbackComponent={fallback}>\n <SurfaceContext.Provider value={contextValue}>\n <WebComponentWrapper\n id={id}\n role={role}\n data={data}\n limit={limit}\n definition={definition}\n ref={forwardedRef}\n {...rest}\n />\n </SurfaceContext.Provider>\n </ErrorBoundary>\n );\n }\n\n // Handle React component surfaces\n const Component = definition.component;\n\n // TODO(burdon): Remove from production build?\n const debug = DEBUG || '__DX_DEBUG__' in window;\n if (debug) {\n return (\n <ErrorBoundary name='surface' resetKeys={[data]} FallbackComponent={fallback}>\n <div className='contents' data-id={id} data-role={role}>\n <SurfaceContext.Provider value={contextValue}>\n <SurfaceInfo ref={forwardedRef}>\n {onProfilerRender && !profilerId.includes('org.dxos.plugin.debug') ? (\n <Profiler id={profilerId} onRender={onProfilerRender}>\n <Component id={id} role={role} data={data} limit={limit} {...rest} />\n </Profiler>\n ) : (\n <Component id={id} role={role} data={data} limit={limit} {...rest} />\n )}\n </SurfaceInfo>\n </SurfaceContext.Provider>\n </div>\n </ErrorBoundary>\n );\n }\n\n return (\n <ErrorBoundary name='surface' resetKeys={[data]} FallbackComponent={fallback}>\n <div className='contents' data-id={id} data-role={role}>\n <SurfaceContext.Provider value={contextValue}>\n <Component id={id} role={role} data={data} limit={limit} {...rest} ref={forwardedRef} />\n </SurfaceContext.Provider>\n </div>\n </ErrorBoundary>\n );\n },\n ),\n);\n\nSurfaceContextProvider.displayName = 'SurfaceContextProvider';\n\n/**\n * A surface is a named region of the screen that can be populated by plugins.\n * The `type` prop is a {@link RoleToken} that defines which region and its\n * associated data contract.\n */\n// TODO(burdon): Remove `ref` since relying on this would be error prone.\nexport const SurfaceComponent = memo(\n forwardRef<HTMLElement, TypedProps<RoleToken<any>>>(\n ({ id: _id, type, data: dataProp, limit, placeholder = DEFAULT_PLACEHOLDER, ...rest }, forwardedRef) => {\n const data = useDefaultValue(dataProp, () => ({}));\n // TODO(wittjosiah): This will make all surfaces depend on a single signal.\n // This isn't ideal because it means that any change to the data will cause all surfaces to re-render.\n // This effectively means that plugin modules which contribute surfaces need to all be activated at startup.\n // This should be fine for now because it's how it worked prior to capabilities api anyway.\n // In the future, it would be nice to be able to bucket the surface contributions by role.\n const surfaces = useSurfaces();\n\n const effectiveRole = type?.role;\n if (effectiveRole == null) {\n if (DEBUG) {\n log.warn('Surface is missing required `type` prop', { id: _id });\n }\n return null;\n }\n\n // NOTE: Memoizing the candidates makes the surface not re-render based on reactivity within data.\n const definitions = findCandidates(surfaces, { role: effectiveRole, data });\n const candidates = limit ? definitions.slice(0, limit) : definitions;\n if (DEBUG && candidates.length === 0) {\n log.warn('no candidates for surface', { role: effectiveRole, data });\n return null;\n }\n\n return (\n <Suspense fallback={placeholder}>\n {candidates.map((definition) => (\n <SurfaceContextProvider\n key={definition.id}\n id={definition.id}\n role={effectiveRole}\n data={data}\n limit={limit}\n definition={definition}\n ref={forwardedRef}\n {...rest}\n />\n ))}\n </Suspense>\n );\n },\n ),\n) as (<TToken extends RoleToken<any>>(props: TypedProps<TToken> & RefAttributes<HTMLElement>) => React.ReactNode) &\n NamedExoticComponent<TypedProps<RoleToken<any>> & RefAttributes<HTMLElement>>;\n\nSurfaceComponent.displayName = 'Surface';\n\n// TODO(burdon): Make user facing, with telemetry.\nconst ErrorFallback = ({ error }: { error: Error }) => {\n const { message } = error instanceof Error ? error : { message: String(error) };\n return (\n <div role='alert' data-testid='error-boundary-fallback'>\n <h1 className='flex gap-2 text-sm mt-2 text-info-text'>{message}</h1>\n </div>\n );\n};\n\nconst findCandidates = (surfaces: Definition[], { role, data }: { role: string; data: Props['data'] }) => {\n return Object.values(surfaces)\n .filter((definition) =>\n Array.isArray(definition.role) ? definition.role.includes(role) : definition.role === role,\n )\n .filter(({ filter }) => (filter ? filter(data ?? {}, role) : true))\n .toSorted(Position.compare);\n};\n\n/**\n * @internal\n */\nexport const useSurfaces = () => {\n const manager = usePluginManager();\n const surfacesByModule = useAtomValue(manager.capabilities.atomByModule(Capabilities.ReactSurface));\n return useMemo(() => {\n const result: Definition[] = [];\n for (const [_moduleId, surfaces] of Object.entries(surfacesByModule)) {\n for (const def of surfaces.flat()) {\n result.push(def);\n }\n }\n return result;\n }, [surfacesByModule]);\n};\n\n/**\n * @returns `true` if there is a contributed surface which matches the specified role & data, `false` otherwise.\n *\n * Typed: pass a `type` role token and `data` is constrained to the token's\n * declared contract (e.g. `AppSurface.Section` requires `attendableId`).\n */\nexport function isSurfaceAvailable<TToken extends RoleToken<any>>(\n capabilityManager: CapabilityManager.CapabilityManager,\n args: { type: TToken; data?: TokenData<TToken> },\n): boolean {\n const effectiveRole = args.type?.role;\n if (effectiveRole == null) {\n return false;\n }\n\n const surfaces = capabilityManager.getAll(Capabilities.ReactSurface);\n const candidates = findCandidates(surfaces.flat(), {\n role: effectiveRole,\n data: args.data as Props['data'],\n });\n return candidates.length > 0;\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport React, {\n type ReactElement,\n type Ref,\n cloneElement,\n forwardRef,\n useCallback,\n useLayoutEffect,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { addEventListener, combine } from '@dxos/async';\nimport { useMergeRefs } from '@dxos/react-hooks';\n\nimport { useSurface } from '../../hooks';\n\nexport type SurfaceInfoProps = {\n children: ReactElement<{ ref?: Ref<HTMLElement> }>;\n};\n\n/**\n * Debug wrapper for surfaces.\n */\nexport const SurfaceInfo = forwardRef<HTMLElement, SurfaceInfoProps>(({ children }, forwardedRef) => {\n const [rect, setRect] = useState<DOMRect | null>(null);\n const [expand, setExpand] = useState(false);\n const info = useSurface();\n\n const [root, setRoot] = useState<HTMLElement | null>(null);\n const measureRef = useCallback((node: HTMLElement | null) => setRoot(node), []);\n const mergedRef = useMergeRefs([measureRef, forwardedRef]);\n const childWithRef = cloneElement(children, { ref: mergedRef });\n\n useLayoutEffect(() => {\n if (!root) {\n setRect(null);\n return;\n }\n\n const measure = () => {\n setRect(root.getBoundingClientRect());\n };\n\n const observer = new ResizeObserver(measure);\n observer.observe(root);\n measure();\n\n return combine(\n addEventListener(window, 'scroll', measure, true),\n addEventListener(window, 'resize', measure),\n () => {\n observer.disconnect();\n },\n );\n }, [root]);\n\n const padding = 0;\n return (\n <>\n {childWithRef}\n {rect &&\n createPortal(\n <div\n className='z-[100] fixed flex flex-col-reverse scrollbar-none overflow-auto pointer-events-none'\n style={{\n top: rect.top + padding,\n left: rect.left + padding,\n width: rect.width - padding * 2,\n height: rect.height - padding * 2,\n }}\n >\n {expand ? (\n <div\n className='absolute inset-0 bg-deck-surface border border-green-500 cursor-pointer pointer-events-auto overflow-auto'\n onPointerDown={(ev) => ev.stopPropagation()}\n onClick={(ev) => {\n ev.stopPropagation();\n setExpand(false);\n }}\n >\n <pre className='p-2 text-xs text-description font-mono'>{JSON.stringify({ info }, null, 2)}</pre>\n </div>\n ) : (\n <span\n className='absolute right-1 bottom-0 flex items-center p-1 text-green-500 opacity-80 hover:opacity-100 text-xl cursor-pointer pointer-events-auto'\n title={info.id}\n onPointerDown={(ev) => ev.stopPropagation()}\n onClick={(ev) => {\n ev.stopPropagation();\n setExpand(true);\n }}\n >\n ⓘ\n </span>\n )}\n </div>,\n // TODO(burdon): Create well-known element to gather all debug portals.\n document.body,\n )}\n </>\n );\n});\n", "//\n// Copyright 2026 DXOS.org\n//\n\nimport React, {\n type Context,\n type ProfilerOnRenderCallback,\n type PropsWithChildren,\n createContext,\n useContext,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from 'react';\n\nconst MAX_ENTRIES = 500;\n\n/**\n * Single profiler record captured from React Profiler onRender callback.\n */\nexport type SurfaceProfilerEntry = {\n id: string;\n phase: 'mount' | 'update' | 'nested-update';\n actualDuration: number;\n baseDuration: number;\n startTime: number;\n commitTime: number;\n timestamp: number;\n};\n\n/**\n * Aggregated stats for a single profiled surface.\n */\nexport type SurfaceProfilerStats = {\n id: string;\n mountCount: number;\n updateCount: number;\n totalRenders: number;\n avgActualDuration: number;\n maxActualDuration: number;\n avgBaseDuration: number;\n lastActualDuration: number;\n lastCommitTime: number;\n};\n\n/**\n * Store that collects profiler entries and notifies subscribers.\n */\nclass SurfaceProfilerStore {\n private _entries: SurfaceProfilerEntry[] = [];\n private _listeners = new Set<() => void>();\n private _snapshot: readonly SurfaceProfilerEntry[] = [];\n private _pendingNotify = false;\n\n /** Records an entry and schedules a deferred notification to avoid re-render loops. */\n record(entry: SurfaceProfilerEntry) {\n this._entries.push(entry);\n if (this._entries.length > MAX_ENTRIES) {\n this._entries = this._entries.slice(-MAX_ENTRIES);\n }\n this._snapshot = [...this._entries];\n this._scheduleNotify();\n }\n\n clear() {\n this._entries = [];\n this._snapshot = [];\n this._notifySync();\n }\n\n subscribe = (listener: () => void) => {\n this._listeners.add(listener);\n return () => {\n this._listeners.delete(listener);\n };\n };\n\n getSnapshot = (): readonly SurfaceProfilerEntry[] => {\n return this._snapshot;\n };\n\n /**\n * Defers notification to the next animation frame to break the\n * Profiler onRender → record → notify → re-render → onRender loop.\n */\n private _scheduleNotify() {\n if (!this._pendingNotify) {\n this._pendingNotify = true;\n requestAnimationFrame(() => {\n this._pendingNotify = false;\n this._notifySync();\n });\n }\n }\n\n private _notifySync() {\n for (const listener of this._listeners) {\n listener();\n }\n }\n}\n\ntype SurfaceProfilerContextValue = {\n store: SurfaceProfilerStore;\n};\n\nconst SurfaceProfilerContext: Context<SurfaceProfilerContextValue | undefined> = createContext<\n SurfaceProfilerContextValue | undefined\n>(undefined);\n\n/**\n * Provider that collects React Profiler data from Surface components.\n */\nexport const SurfaceProfilerProvider = ({ children }: PropsWithChildren) => {\n const storeRef = useRef<SurfaceProfilerStore>(null);\n if (!storeRef.current) {\n storeRef.current = new SurfaceProfilerStore();\n }\n return (\n <SurfaceProfilerContext.Provider value={{ store: storeRef.current }}>{children}</SurfaceProfilerContext.Provider>\n );\n};\n\n/**\n * Returns a stable onRender callback for use with React Profiler.\n */\nexport const useSurfaceProfilerCallback = (): ProfilerOnRenderCallback | undefined => {\n const store = useContext(SurfaceProfilerContext)?.store;\n return useMemo<ProfilerOnRenderCallback | undefined>(() => {\n if (!store) {\n return undefined;\n }\n return (id, phase, actualDuration, baseDuration, startTime, commitTime) => {\n store.record({\n id,\n phase,\n actualDuration,\n baseDuration,\n startTime,\n commitTime,\n timestamp: Date.now(),\n });\n };\n }, [store]);\n};\n\n/**\n * Returns all profiler entries reactively.\n */\nexport const useSurfaceProfilerEntries = (): readonly SurfaceProfilerEntry[] => {\n const context = useContext(SurfaceProfilerContext);\n return useSyncExternalStore(context?.store.subscribe ?? noop, context?.store.getSnapshot ?? emptySnapshot);\n};\n\n/**\n * Returns aggregated stats grouped by surface id.\n */\nexport const useSurfaceProfilerStats = (): SurfaceProfilerStats[] => {\n const entries = useSurfaceProfilerEntries();\n const statsMap = new Map<string, SurfaceProfilerStats>();\n\n for (const entry of entries) {\n let stats = statsMap.get(entry.id);\n if (!stats) {\n stats = {\n id: entry.id,\n mountCount: 0,\n updateCount: 0,\n totalRenders: 0,\n avgActualDuration: 0,\n maxActualDuration: 0,\n avgBaseDuration: 0,\n lastActualDuration: 0,\n lastCommitTime: 0,\n };\n statsMap.set(entry.id, stats);\n }\n\n if (entry.phase === 'mount') {\n stats.mountCount++;\n } else {\n stats.updateCount++;\n }\n stats.totalRenders++;\n stats.avgActualDuration =\n (stats.avgActualDuration * (stats.totalRenders - 1) + entry.actualDuration) / stats.totalRenders;\n stats.avgBaseDuration =\n (stats.avgBaseDuration * (stats.totalRenders - 1) + entry.baseDuration) / stats.totalRenders;\n stats.maxActualDuration = Math.max(stats.maxActualDuration, entry.actualDuration);\n stats.lastActualDuration = entry.actualDuration;\n stats.lastCommitTime = entry.commitTime;\n }\n\n return [...statsMap.values()].sort((a, b) => b.maxActualDuration - a.maxActualDuration);\n};\n\n/**\n * Clears all collected profiler entries.\n */\nexport const useSurfaceProfilerClear = (): (() => void) | undefined => {\n const store = useContext(SurfaceProfilerContext)?.store;\n return useMemo(() => (store ? () => store.clear() : undefined), [store]);\n};\n\nconst noop = () => () => {};\nconst EMPTY_SNAPSHOT: readonly SurfaceProfilerEntry[] = [];\nconst emptySnapshot = () => EMPTY_SNAPSHOT;\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport type { FC, PropsWithChildren, ReactNode, Ref } from 'react';\n\nimport type { DXN } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport type { MakeOptional, Position } from '@dxos/util';\n\n/**\n * A typed role token. Carries a role NSID for runtime dispatch plus a phantom\n * data type so consumers using `type={SomeToken}` and providers using\n * `AppSurface.object(SomeToken, ...)` share a single type-level contract.\n *\n * Mint via {@link makeType}. The `role` field holds the bare NSID (e.g.\n * `org.dxos.role.article`) — the dispatch key, `data-role` attribute value,\n * and what `.role` comparisons inside matched components see.\n */\nexport type RoleToken<TData> = {\n readonly role: string;\n /** Covariant phantom; never accessed at runtime. */\n readonly _phantom?: TData;\n};\n\n/**\n * One entry in a {@link SurfaceFilter} — a role NSID plus the guard that\n * validates the data shape when the Surface dispatcher is matching that role.\n */\nexport type SurfaceBinding = {\n readonly role: string;\n readonly guard: (data: unknown) => boolean;\n};\n\n/**\n * Typed filter binding for {@link create}. Combines one or more `(role, guard)`\n * pairs so a provider can register against multiple roles while keeping the\n * role and its data shape in a single expression.\n */\nexport type SurfaceFilter<TData> = {\n readonly bindings: ReadonlyArray<SurfaceBinding>;\n /** Covariant phantom; never accessed at runtime. */\n readonly _phantom?: TData;\n};\n\n/**\n * Narrow data type carried by a role token.\n */\nexport type TokenData<T> = T extends RoleToken<infer D> ? D : never;\n\n/**\n * Runtime guard for {@link SurfaceFilter}. Distinguishes new-style filter\n * bindings from legacy predicate filters.\n */\nexport const isSurfaceFilter = (value: unknown): value is SurfaceFilter<any> =>\n typeof value === 'object' && value !== null && Array.isArray((value as { bindings?: unknown }).bindings);\n\n/**\n * Mints a typed role token. The NSID is validated at compile time via\n * {@link DXN.Name}: the final segment must be camelCase (no hyphens).\n * Dynamic NSIDs (template-literal / runtime strings) are validated at runtime.\n *\n * Identity is structural; all tokens with the same `role` string are\n * interchangeable at runtime.\n */\nexport const makeType: {\n <TData = unknown, T extends string = string>(\n nsid: [DXN.Name<T>] extends [never] ? `Invalid NSID \"${T}\": final segment must be camelCase (no hyphens)` : T,\n ): RoleToken<TData>;\n} = <TData>(nsid: string): RoleToken<TData> => {\n // Runtime guard for dynamic NSIDs that bypass the compile-time DXN.Name<T> check.\n if (\n typeof nsid !== 'string' ||\n !/^[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(\n nsid,\n )\n ) {\n throw new Error(\n `Invalid role NSID: \"${nsid}\". Must be a dotted name with a camelCase final segment (no hyphens in the last segment).`,\n );\n }\n return { role: nsid };\n};\n\n/**\n * Creates a {@link SurfaceFilter} from a role token and an optional guard.\n *\n * When `guard` is omitted the filter matches any data at the token's role\n * (role-only dispatch). Pass a guard to add runtime data-shape validation on\n * top of the role match.\n *\n * This is the framework-level primitive; `@dxos/app-toolkit` builds richer\n * domain-aware helpers (ECHO schema checks, literal matching, etc.) on top of it.\n */\nexport const makeFilter = <TData>(token: RoleToken<TData>, guard?: (data: TData) => boolean): SurfaceFilter<TData> => {\n const boundGuard =\n guard == null\n ? () => true\n : (data: unknown): boolean => {\n try {\n return guard(data as TData);\n } catch (err) {\n log.catch(err);\n return false;\n }\n };\n return { bindings: [{ role: token.role, guard: boundGuard }] };\n};\n\n/**\n * Typed Surface consumer props — carries the role/data-shape contract via a\n * {@link RoleToken}. The `type` prop is required; the string `role` prop has\n * been removed from the consumer-facing API.\n */\nexport type Props<T extends Record<string, any> = Record<string, unknown>> = {\n /**\n * If specified, the Surface will be wrapped in an error boundary.\n * The fallback component will be rendered if an error occurs.\n */\n fallback?: FC<{ error: Error; data?: any }>;\n\n /**\n * If specified, the Surface will be wrapped in a suspense boundary.\n * The placeholder component will be rendered while the surface component is loading.\n */\n placeholder?: ReactNode;\n} & MakeOptional<CoreProps<T>, 'id' | 'data'>;\n\n/**\n * Typed Surface consumer props — carries the role/data-shape contract via a\n * {@link RoleToken}. Available as a typed overload of the Surface component so\n * ad-hoc `type` fields on arbitrary spread props don't conflict with the\n * untyped consumer form.\n */\nexport type TypedProps<TToken extends RoleToken<any>> = {\n fallback?: FC<{ error: Error; data?: any }>;\n placeholder?: ReactNode;\n id?: string;\n type: TToken;\n data?: TokenData<TToken>;\n limit?: number | undefined;\n} & {\n /**\n * Additional pass-through props. Known prop names are excluded so the\n * catch-all doesn't widen `data` / `type` / etc. to `any` at the intersection.\n */\n [K in keyof Record<string, any>]: K extends 'fallback' | 'placeholder' | 'id' | 'type' | 'data' | 'limit'\n ? never\n : any;\n};\n\n/**\n * NOTE: If `[key: string]: unknown` is included in shared types, when re-used other fields become unknown as well.\n * The `type` prop is the only way to set the role; it is required here and\n * optional in {@link Props} via MakeOptional.\n */\nexport type CoreProps<T extends Record<string, any> = Record<string, unknown>> = PropsWithChildren<{\n /**\n * ID for debugging.\n */\n id: string;\n\n /**\n * The role token defining how the data should be rendered.\n */\n type: RoleToken<T>;\n\n /**\n * The data to be rendered by the surface.\n * NOTE: This must be a stable value.\n */\n data: T;\n\n /**\n * If more than one component is resolved, the limit determines how many are rendered.\n */\n limit?: number | undefined;\n}>;\n\n// TODO(burdon): Remove ref since relying on this would be error prone.\nexport type ComponentProps<T extends Record<string, any> = Record<string, any>> = {\n /**\n * The resolved role NSID string (e.g. `org.dxos.role.article`). Present on\n * matched components only — multi-role containers can branch on this value\n * by comparing against a token's `.role` (e.g. `role === AppSurface.Section.role`).\n */\n role: string;\n ref?: Ref<HTMLElement>;\n} & PropsWithChildren<{\n id: string;\n data: T;\n limit?: number | undefined;\n}> &\n Record<string, any>;\n\n/**\n * React component used to render a surface once is has matched.\n */\nexport type ComponentFunction<T extends Record<string, any> = Record<string, any>> = (\n props: ComponentProps<T>,\n) => ReactNode;\n\n/**\n * Definition of when a React component surface should be rendered.\n *\n * The optional `filter` receives the consumer-supplied `role` as its second\n * argument so a single definition can encode role-specific guards (used by the\n * {@link SurfaceFilter}-based `create` overload).\n *\n * @internal The `role` field is populated by the framework from the filter\n * bindings and is not authored directly.\n */\nexport type ReactDefinition<T extends Record<string, any> = any> = Readonly<{\n kind: 'react';\n id: string;\n role: string | string[];\n position?: Position.Position;\n component: ComponentFunction<T>;\n filter?: (data: Record<string, unknown>, role?: string) => data is T;\n}>;\n\n/**\n * Definition of when a Web Component surface should be rendered.\n *\n * @internal The `role` field is populated by the framework from the filter\n * bindings and is not authored directly.\n */\nexport type WebComponentDefinition<T extends Record<string, any> = any> = Readonly<{\n kind: 'web-component';\n id: string;\n role: string | string[];\n position?: Position.Position;\n /**\n * The tag name of the Web Component to render.\n * The Web Component will receive the same props as React surfaces via properties/attributes.\n */\n tagName: string;\n filter?: (data: Record<string, unknown>, role?: string) => data is T;\n}>;\n\n/**\n * Definition of when a surface (React or Web Component) should be rendered.\n */\nexport type Definition<T extends Record<string, any> = any> = ReactDefinition<T> | WebComponentDefinition<T>;\n\n/**\n * Typed React surface definition — role is derived from the filter's bindings.\n */\nexport type TypedReactDefinition<T extends Record<string, any> = any> = Readonly<{\n id: string;\n filter: SurfaceFilter<T>;\n component: ComponentFunction<T>;\n position?: Position.Position;\n}>;\n\n/**\n * Typed Web Component surface definition.\n */\nexport type TypedWebComponentDefinition<T extends Record<string, any> = any> = Readonly<{\n id: string;\n filter: SurfaceFilter<T>;\n tagName: string;\n position?: Position.Position;\n}>;\n\nconst expandBindings = <T extends Record<string, any>>(\n filter: SurfaceFilter<T>,\n): { role: string | string[]; guard: (data: Record<string, unknown>, role?: string) => data is T } => {\n const bindings = filter.bindings;\n const roles = Array.from(new Set(bindings.map((binding) => binding.role)));\n const guard = (data: Record<string, unknown>, role?: string): data is T => {\n if (role != null) {\n // Multiple bindings may share a role (e.g. via `oneOf` of same-role filters);\n // the role matches if ANY of them passes.\n return bindings.some((entry) => entry.role === role && entry.guard(data));\n }\n return bindings.some((entry) => entry.guard(data));\n };\n return { role: roles.length === 1 ? roles[0] : roles, guard };\n};\n\n/**\n * Validates that a surface or extension local ID follows NSID conventions:\n * each dot-separated segment must be alphanumeric, and the final segment must\n * be camelCase (no hyphens). This mirrors the rule enforced when the id is\n * appended to a plugin's NSID to form a full DXN path.\n *\n * @example Valid: 'about', 'integrationArticle', 'article.journal'\n * @example Invalid: 'integration-article', 'plugin-spec'\n */\nconst validateLocalId = (id: string): void => {\n const segments = id.split('.');\n const finalSegment = segments[segments.length - 1];\n if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(finalSegment)) {\n throw new Error(\n `Invalid surface id: \"${id}\". The final segment \"${finalSegment}\" must be camelCase (letters and digits only, starting with a letter — no hyphens or underscores).`,\n );\n }\n};\n\n/**\n * Creates a React surface definition from a typed filter.\n */\nexport function create<T extends Record<string, any> = any>(definition: TypedReactDefinition<T>): ReactDefinition<T>;\nexport function create<T extends Record<string, any> = any>(definition: TypedReactDefinition<T>): ReactDefinition<T> {\n validateLocalId(definition.id);\n const { id, filter, component, position } = definition;\n const { role, guard } = expandBindings(filter);\n return { kind: 'react', id, role, position, component, filter: guard };\n}\n\n/**\n * Creates a Web Component surface definition from a typed filter.\n */\nexport function createWeb<T extends Record<string, any> = any>(\n definition: TypedWebComponentDefinition<T>,\n): WebComponentDefinition<T>;\nexport function createWeb<T extends Record<string, any> = any>(\n definition: TypedWebComponentDefinition<T>,\n): WebComponentDefinition<T> {\n validateLocalId(definition.id);\n const { id, filter, tagName, position } = definition;\n const { role, guard } = expandBindings(filter);\n return { kind: 'web-component', id, role, position, tagName, filter: guard };\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport type { DXN } from '@dxos/keys';\n\n// TODO(wittjosiah): Cleanup to avoid re-naming.\nimport { SurfaceContext } from './context';\nimport { SurfaceComponent, isSurfaceAvailable } from './SurfaceComponent';\nimport {\n SurfaceProfilerProvider,\n useSurfaceProfilerCallback,\n useSurfaceProfilerClear,\n useSurfaceProfilerEntries,\n useSurfaceProfilerStats,\n} from './SurfaceProfilerContext';\nimport {\n type SurfaceBinding as SurfaceBindingType,\n type Definition as SurfaceDefinition,\n type SurfaceFilter as SurfaceFilterType,\n type RoleToken as SurfaceRoleToken,\n type TokenData as SurfaceTokenData,\n type TypedProps as SurfaceTypedProps,\n create as createSurface,\n createWeb as createWebSurface,\n isSurfaceFilter as isSurfaceFilterFn,\n makeFilter as makeFilterFn,\n makeType as makeTypeFn,\n} from './types';\n\nexport namespace Surface {\n export type Definition = SurfaceDefinition;\n export const create = createSurface;\n export const createWeb = createWebSurface;\n\n export type Context = SurfaceContext;\n export const Context = SurfaceContext;\n\n export const Surface = SurfaceComponent;\n export const isAvailable = isSurfaceAvailable;\n\n export type RoleToken<TData> = SurfaceRoleToken<TData>;\n export type Binding = SurfaceBindingType;\n export type Filter<TData> = SurfaceFilterType<TData>;\n export type TokenData<T> = SurfaceTokenData<T>;\n export type TypedProps<TToken extends SurfaceRoleToken<any>> = SurfaceTypedProps<TToken>;\n\n /** Mints a typed role token. The NSID is validated at compile time via {@link DXN.Name}. */\n export const makeType: {\n <TData = unknown, T extends string = string>(\n nsid: [DXN.Name<T>] extends [never] ? `Invalid NSID \"${T}\": final segment must be camelCase (no hyphens)` : T,\n ): SurfaceRoleToken<TData>;\n } = makeTypeFn;\n\n export const makeFilter = makeFilterFn;\n export const isFilter = isSurfaceFilterFn;\n\n export const ProfilerProvider = SurfaceProfilerProvider;\n export const useProfilerCallback = useSurfaceProfilerCallback;\n export const useProfilerEntries = useSurfaceProfilerEntries;\n export const useProfilerStats = useSurfaceProfilerStats;\n export const useProfilerClear = useSurfaceProfilerClear;\n}\n\nexport type { SurfaceProfilerEntry, SurfaceProfilerStats } from './SurfaceProfilerContext';\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["topologicalSort", "nodes", "getDependencies", "nodeId", "seen", "Set", "path", "has", "Error", "node", "find", "n", "id", "newPath", "newSeen", "dependsOn", "flatMap", "depId", "allDependencies", "map", "filter", "index", "self", "indexOf", "undefined", "useContext", "raise", "createContext", "useContext", "raise", "PluginManagerContext", "undefined", "usePluginManager", "Error", "useOptionalPluginManager", "PluginManagerProvider", "Provider", "createContext", "SurfaceContext", "undefined", "useAtomValue", "React", "Fragment", "Profiler", "Suspense", "forwardRef", "memo", "useEffect", "useMemo", "useRef", "log", "ErrorBoundary", "useDefaultValue", "Position", "React", "cloneElement", "forwardRef", "useCallback", "useLayoutEffect", "useState", "createPortal", "addEventListener", "combine", "useMergeRefs", "SurfaceInfo", "forwardRef", "children", "forwardedRef", "rect", "setRect", "useState", "expand", "setExpand", "info", "useSurface", "root", "setRoot", "measureRef", "useCallback", "node", "mergedRef", "useMergeRefs", "childWithRef", "cloneElement", "ref", "useLayoutEffect", "measure", "getBoundingClientRect", "observer", "ResizeObserver", "observe", "combine", "addEventListener", "window", "disconnect", "padding", "createPortal", "div", "className", "style", "top", "left", "width", "height", "onPointerDown", "ev", "stopPropagation", "onClick", "pre", "JSON", "stringify", "span", "title", "id", "document", "body", "React", "createContext", "useContext", "useMemo", "useRef", "useSyncExternalStore", "MAX_ENTRIES", "SurfaceProfilerStore", "_entries", "_listeners", "Set", "_snapshot", "_pendingNotify", "record", "entry", "push", "length", "slice", "_scheduleNotify", "clear", "_notifySync", "subscribe", "listener", "add", "delete", "getSnapshot", "requestAnimationFrame", "SurfaceProfilerContext", "undefined", "SurfaceProfilerProvider", "children", "storeRef", "current", "Provider", "value", "store", "useSurfaceProfilerCallback", "id", "phase", "actualDuration", "baseDuration", "startTime", "commitTime", "timestamp", "Date", "now", "useSurfaceProfilerEntries", "context", "noop", "emptySnapshot", "useSurfaceProfilerStats", "entries", "statsMap", "Map", "stats", "get", "mountCount", "updateCount", "totalRenders", "avgActualDuration", "maxActualDuration", "avgBaseDuration", "lastActualDuration", "lastCommitTime", "set", "Math", "max", "values", "sort", "a", "b", "useSurfaceProfilerClear", "EMPTY_SNAPSHOT", "WebComponentWrapper", "React", "forwardRef", "propsRef", "useRef", "id", "role", "data", "limit", "useEffect", "Object", "assign", "element", "containerRef", "current", "appendChild", "forwardedRef", "elementRef", "definition", "div", "FallbackComponent", "value", "contextValue", "ref", "debug", "DEBUG", "name", "className", "data-role", "SurfaceInfo", "onProfilerRender", "includes", "profilerId", "Component", "SurfaceContextProvider", "effectiveRole", "log", "SurfaceComponent", "ErrorFallback", "String", "error", "message", "findCandidates", "surfacesByModule", "useAtomValue", "useMemo", "_moduleId", "def", "result", "surfaces", "candidates", "log", "__dxlog_file", "nsid", "guard", "data", "catch", "err", "role", "Array", "from", "Set", "bindings", "entry", "finalSegment", "segments", "filter", "position", "expandBindings", "kind", "id", "component", "tagName", "Surface", "create", "createSurface", "createWeb", "createWebSurface", "Context", "SurfaceContext", "SurfaceComponent", "isAvailable", "isSurfaceAvailable", "makeType", "makeTypeFn", "makeFilter", "makeFilterFn", "isFilter", "isSurfaceFilterFn", "ProfilerProvider", "SurfaceProfilerProvider", "useProfilerCallback", "useSurfaceProfilerCallback", "useProfilerEntries", "useSurfaceProfilerEntries", "useProfilerStats", "useSurfaceProfilerStats", "useProfilerClear", "useSurfaceProfilerClear", "useSurface", "useContext", "Surface", "Context", "raise", "Error"]
|
|
7
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
isPlugin
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4SE7SX7N.mjs";
|
|
5
5
|
import {
|
|
6
6
|
__export
|
|
7
7
|
} from "./chunk-HSLMI22Q.mjs";
|
|
@@ -428,4 +428,4 @@ export {
|
|
|
428
428
|
uninstall,
|
|
429
429
|
url_loader_exports
|
|
430
430
|
};
|
|
431
|
-
//# sourceMappingURL=chunk-
|
|
431
|
+
//# sourceMappingURL=chunk-FKMVORZN.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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 */\n// TODO(dmaretskyi): Make the return type non-generic so capabilities are non-discernable.\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): Capability<I> => {\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;
|
|
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
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
7
|
}
|
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
Service as Service2,
|
|
11
11
|
isLazy,
|
|
12
12
|
resolveLazy
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-4SE7SX7N.mjs";
|
|
14
14
|
import {
|
|
15
15
|
Service
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-GLH4LGHZ.mjs";
|
|
17
17
|
import {
|
|
18
18
|
__export
|
|
19
19
|
} from "./chunk-HSLMI22Q.mjs";
|
|
@@ -1469,4 +1469,4 @@ export {
|
|
|
1469
1469
|
make5 as make,
|
|
1470
1470
|
plugin_manager_exports
|
|
1471
1471
|
};
|
|
1472
|
-
//# sourceMappingURL=chunk-
|
|
1472
|
+
//# sourceMappingURL=chunk-IL7O7IRX.mjs.map
|
|
@@ -4,19 +4,19 @@ import {
|
|
|
4
4
|
topologicalSort,
|
|
5
5
|
useOptionalPluginManager,
|
|
6
6
|
usePluginManager
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-DRT75WGD.mjs";
|
|
8
8
|
import {
|
|
9
9
|
PluginManagerContext
|
|
10
10
|
} from "./chunk-37Z53PXZ.mjs";
|
|
11
11
|
import {
|
|
12
12
|
capabilities_exports
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-XSZMX53L.mjs";
|
|
14
14
|
import {
|
|
15
15
|
activation_events_exports
|
|
16
16
|
} from "./chunk-TLKYZKPW.mjs";
|
|
17
17
|
import {
|
|
18
18
|
plugin_manager_exports
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-IL7O7IRX.mjs";
|
|
20
20
|
|
|
21
21
|
// src/ui/components/App/App.tsx
|
|
22
22
|
import React2, { useEffect as useEffect3, useLayoutEffect } from "react";
|
|
@@ -249,13 +249,14 @@ import { useCallback as useCallback2 } from "react";
|
|
|
249
249
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
250
250
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/sdk/app-framework/src/ui/hooks/useCapabilities.ts";
|
|
251
251
|
var emptyCapabilities = Atom.make(() => []);
|
|
252
|
+
var emptyAtomValue = Atom.make(() => void 0);
|
|
252
253
|
var useCapabilities = (interfaceDef) => {
|
|
253
254
|
const manager = usePluginManager();
|
|
254
255
|
return useAtomValue(manager.capabilities.atom(interfaceDef));
|
|
255
256
|
};
|
|
256
257
|
var useCapability = (interfaceDef) => {
|
|
257
258
|
const capabilities = useCapabilities(interfaceDef);
|
|
258
|
-
invariant2(capabilities.length > 0, `No capability found for ${interfaceDef.identifier}`, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L:
|
|
259
|
+
invariant2(capabilities.length > 0, `No capability found for ${interfaceDef.identifier}`, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 26, S: void 0, A: ["capabilities.length > 0", "`No capability found for ${interfaceDef.identifier}`"] });
|
|
259
260
|
return capabilities[0];
|
|
260
261
|
};
|
|
261
262
|
var useOptionalCapabilities = (interfaceDef) => {
|
|
@@ -282,6 +283,23 @@ var useAtomCapabilityState = (atomCapability) => {
|
|
|
282
283
|
update
|
|
283
284
|
];
|
|
284
285
|
};
|
|
286
|
+
var useOptionalAtomCapabilityState = (atomCapability) => {
|
|
287
|
+
const registry = useOptionalCapability(capabilities_exports.AtomRegistry);
|
|
288
|
+
const atom = useOptionalCapability(atomCapability);
|
|
289
|
+
const value = useAtomValue(atom ?? emptyAtomValue);
|
|
290
|
+
const update = useCallback2((fn) => {
|
|
291
|
+
if (registry && atom) {
|
|
292
|
+
registry.set(atom, fn(registry.get(atom)));
|
|
293
|
+
}
|
|
294
|
+
}, [
|
|
295
|
+
registry,
|
|
296
|
+
atom
|
|
297
|
+
]);
|
|
298
|
+
return [
|
|
299
|
+
value,
|
|
300
|
+
update
|
|
301
|
+
];
|
|
302
|
+
};
|
|
285
303
|
var useOperationInvoker = () => useCapability(capabilities_exports.OperationInvoker);
|
|
286
304
|
|
|
287
305
|
// src/ui/hooks/useLoading.tsx
|
|
@@ -475,6 +493,7 @@ export {
|
|
|
475
493
|
useOptionalCapability,
|
|
476
494
|
useAtomCapability,
|
|
477
495
|
useAtomCapabilityState,
|
|
496
|
+
useOptionalAtomCapabilityState,
|
|
478
497
|
useOperationInvoker,
|
|
479
498
|
LoadingState,
|
|
480
499
|
useLoading,
|
|
@@ -484,4 +503,4 @@ export {
|
|
|
484
503
|
useSettingsState,
|
|
485
504
|
App
|
|
486
505
|
};
|
|
487
|
-
//# sourceMappingURL=chunk-
|
|
506
|
+
//# sourceMappingURL=chunk-ND2HETHD.mjs.map
|