@dxos/app-framework 0.9.0 → 0.9.1-main.c7dcc2e112
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-Z4MRP3CP.mjs} +9 -9
- package/dist/lib/browser/{chunk-CO3XLNUX.mjs → chunk-37PG7XJC.mjs} +18 -18
- package/dist/lib/browser/chunk-37PG7XJC.mjs.map +7 -0
- 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-KZUDO43J.mjs → chunk-3UTDRCKX.mjs} +31 -23
- package/dist/lib/browser/chunk-3UTDRCKX.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-IW44C7UL.mjs → chunk-CMINFVA5.mjs} +1 -1
- package/dist/lib/browser/chunk-CMINFVA5.mjs.map +7 -0
- package/dist/lib/browser/{chunk-Y66ELD4U.mjs → chunk-DFVSOBV2.mjs} +17 -7
- package/dist/lib/browser/chunk-DFVSOBV2.mjs.map +7 -0
- package/dist/lib/browser/{chunk-DC3WRPBV.mjs → chunk-S2ZBYQPI.mjs} +45 -12
- package/dist/lib/browser/chunk-S2ZBYQPI.mjs.map +7 -0
- package/dist/lib/browser/{chunk-HFLKXMT7.mjs → chunk-SWECIICH.mjs} +57 -41
- package/dist/lib/browser/chunk-SWECIICH.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-XHS5KDNX.mjs → chunk-W4BHZING.mjs} +25 -25
- package/dist/lib/browser/chunk-W4BHZING.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-RDROCCQD.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 +16 -10
- package/dist/lib/node-esm/{capability-KZWRTX7R.mjs → capability-34Z6NPVR.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-FSVGKTF6.mjs → chunk-A4O42ZO3.mjs} +17 -7
- package/dist/lib/node-esm/chunk-A4O42ZO3.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-CTKEZHKF.mjs → chunk-AIDZMJ3U.mjs} +1 -1
- package/dist/lib/node-esm/chunk-AIDZMJ3U.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-H7T7XXLS.mjs} +57 -41
- package/dist/lib/node-esm/chunk-H7T7XXLS.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-NULBHQYS.mjs → chunk-LUK3FCTH.mjs} +18 -18
- package/dist/lib/node-esm/chunk-LUK3FCTH.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-XGBUKRCK.mjs → chunk-TEQSMP2O.mjs} +31 -23
- package/dist/lib/node-esm/chunk-TEQSMP2O.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-XIGPWXCQ.mjs → chunk-WERVO5EK.mjs} +45 -12
- package/dist/lib/node-esm/chunk-WERVO5EK.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-SX5NVETP.mjs → chunk-ZRTG4TSS.mjs} +25 -25
- package/dist/lib/node-esm/chunk-ZRTG4TSS.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-6OCXSKUW.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 +16 -10
- package/dist/plugin/node-esm/index.mjs +406 -71
- 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.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 +6 -2
- 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 +81 -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/meta.d.ts +28 -2
- package/dist/types/src/plugin-process-manager/meta.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/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/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 +10 -3
- package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/types.d.ts +50 -70
- 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 +11 -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/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 +32 -27
- package/src/cli/cli.ts +2 -2
- package/src/common/activation-events.ts +3 -3
- package/src/common/capabilities.ts +16 -16
- package/src/config/index.ts +5 -0
- package/src/core/activation-event.ts +15 -8
- package/src/core/capability.ts +15 -4
- 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 +9 -8
- 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/PluginManager/PluginManagerProvider.ts +7 -0
- package/src/ui/components/Surface/SurfaceComponent.stories.tsx +11 -14
- package/src/ui/components/Surface/SurfaceComponent.tsx +84 -74
- package/src/ui/components/Surface/context.ts +6 -3
- package/src/ui/components/Surface/index.ts +12 -1
- package/src/ui/components/Surface/types.test.ts +39 -49
- package/src/ui/components/Surface/types.ts +95 -60
- package/src/ui/hooks/useApp.test.tsx +1 -1
- package/src/ui/hooks/useApp.tsx +2 -2
- package/src/ui/hooks/useCapabilities.ts +24 -2
- package/src/vite-plugin/composer/index.ts +134 -61
- 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 -1
- 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-Z4MRP3CP.mjs.map} +0 -0
- /package/dist/lib/browser/{process-manager-capability-GXNUO7AR.mjs.map → process-manager-capability-RDROCCQD.mjs.map} +0 -0
- /package/dist/lib/node-esm/{capability-KZWRTX7R.mjs.map → capability-34Z6NPVR.mjs.map} +0 -0
- /package/dist/lib/node-esm/{process-manager-capability-TX5TA6YN.mjs.map → process-manager-capability-6OCXSKUW.mjs.map} +0 -0
|
@@ -5,16 +5,16 @@ import {
|
|
|
5
5
|
import "./chunk-Q2GLJTVV.mjs";
|
|
6
6
|
import {
|
|
7
7
|
capabilities_exports
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-37PG7XJC.mjs";
|
|
9
|
+
import "./chunk-VF37YTXJ.mjs";
|
|
10
|
+
import "./chunk-YUVQIOTB.mjs";
|
|
11
|
+
import "./chunk-3UTDRCKX.mjs";
|
|
12
|
+
import "./chunk-W4BHZING.mjs";
|
|
13
|
+
import "./chunk-3NQLTQCP.mjs";
|
|
14
|
+
import "./chunk-S2ZBYQPI.mjs";
|
|
15
15
|
import {
|
|
16
16
|
capability_exports
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-CMINFVA5.mjs";
|
|
18
18
|
import "./chunk-J5LGTIGS.mjs";
|
|
19
19
|
|
|
20
20
|
// src/plugin-process-manager/history/capability.ts
|
|
@@ -32,4 +32,4 @@ var capability_default = capability_exports.makeModule(Effect.fnUntraced(functio
|
|
|
32
32
|
export {
|
|
33
33
|
capability_default as default
|
|
34
34
|
};
|
|
35
|
-
//# sourceMappingURL=capability-
|
|
35
|
+
//# sourceMappingURL=capability-Z4MRP3CP.mjs.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
capability_exports
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CMINFVA5.mjs";
|
|
4
4
|
import {
|
|
5
5
|
__export
|
|
6
6
|
} from "./chunk-J5LGTIGS.mjs";
|
|
@@ -33,24 +33,24 @@ __export(capabilities_exports, {
|
|
|
33
33
|
});
|
|
34
34
|
import * as Effect from "effect/Effect";
|
|
35
35
|
var Null = capability_exports.make("org.dxos.app-framework.capability.null");
|
|
36
|
-
var PluginManager = capability_exports.make("org.dxos.app-framework.capability.
|
|
37
|
-
var AtomRegistry = capability_exports.make("org.dxos.app-framework.capability.
|
|
38
|
-
var ReactContext = capability_exports.make("org.dxos.app-framework.capability.
|
|
39
|
-
var ReactRoot = capability_exports.make("org.dxos.app-framework.capability.
|
|
40
|
-
var ReactSurface = capability_exports.make("org.dxos.app-framework.
|
|
36
|
+
var PluginManager = capability_exports.make("org.dxos.app-framework.capability.pluginManager");
|
|
37
|
+
var AtomRegistry = capability_exports.make("org.dxos.app-framework.capability.atomRegistry");
|
|
38
|
+
var ReactContext = capability_exports.make("org.dxos.app-framework.capability.reactContext");
|
|
39
|
+
var ReactRoot = capability_exports.make("org.dxos.app-framework.capability.reactRoot");
|
|
40
|
+
var ReactSurface = capability_exports.make("org.dxos.app-framework.capability.reactSurface");
|
|
41
41
|
var Command = capability_exports.make("org.dxos.app-framework.capability.command");
|
|
42
42
|
var Layer = capability_exports.make("org.dxos.app-framework.capability.layer");
|
|
43
|
-
var LayerSpec = capability_exports.make("org.dxos.app-framework.capability.
|
|
44
|
-
var TraceSink = capability_exports.make("org.dxos.app-framework.capability.
|
|
45
|
-
var ServiceResolver = capability_exports.make("org.dxos.app-framework.capability.
|
|
46
|
-
var ProcessMonitor = capability_exports.make("org.dxos.app-framework.capability.
|
|
47
|
-
var ProcessManagerRuntime = capability_exports.make("org.dxos.app-framework.capability.
|
|
48
|
-
var ManagedRuntime = capability_exports.make("org.dxos.app-framework.capability.
|
|
49
|
-
var OperationHandler = capability_exports.make("org.dxos.app-framework.capability.
|
|
50
|
-
var UndoMapping = capability_exports.make("org.dxos.app-framework.capability.
|
|
51
|
-
var OperationInvoker = capability_exports.make("org.dxos.app-framework.capability.
|
|
52
|
-
var UndoRegistry = capability_exports.make("org.dxos.app-framework.capability.
|
|
53
|
-
var HistoryTracker = capability_exports.make("org.dxos.app-framework.capability.
|
|
43
|
+
var LayerSpec = capability_exports.make("org.dxos.app-framework.capability.layerSpec");
|
|
44
|
+
var TraceSink = capability_exports.make("org.dxos.app-framework.capability.traceSink");
|
|
45
|
+
var ServiceResolver = capability_exports.make("org.dxos.app-framework.capability.serviceResolver");
|
|
46
|
+
var ProcessMonitor = capability_exports.make("org.dxos.app-framework.capability.processMonitor");
|
|
47
|
+
var ProcessManagerRuntime = capability_exports.make("org.dxos.app-framework.capability.processManagerRuntime");
|
|
48
|
+
var ManagedRuntime = capability_exports.make("org.dxos.app-framework.capability.managedRuntime");
|
|
49
|
+
var OperationHandler = capability_exports.make("org.dxos.app-framework.capability.operationHandler");
|
|
50
|
+
var UndoMapping = capability_exports.make("org.dxos.app-framework.capability.undoMapping");
|
|
51
|
+
var OperationInvoker = capability_exports.make("org.dxos.app-framework.capability.operationInvoker");
|
|
52
|
+
var UndoRegistry = capability_exports.make("org.dxos.app-framework.capability.undoRegistry");
|
|
53
|
+
var HistoryTracker = capability_exports.make("org.dxos.app-framework.capability.historyTracker");
|
|
54
54
|
var getAtomValue = (atomCapability) => Effect.gen(function* () {
|
|
55
55
|
const registry = yield* capability_exports.get(AtomRegistry);
|
|
56
56
|
const atom = yield* capability_exports.get(atomCapability);
|
|
@@ -92,4 +92,4 @@ export {
|
|
|
92
92
|
subscribeAtom,
|
|
93
93
|
capabilities_exports
|
|
94
94
|
};
|
|
95
|
-
//# sourceMappingURL=chunk-
|
|
95
|
+
//# sourceMappingURL=chunk-37PG7XJC.mjs.map
|
|
@@ -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 LayerSpec as LayerSpec$,\n Operation as Operation$,\n OperationHandlerSet,\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, Feed.FeedService).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
|
+
}
|
|
@@ -13,13 +13,12 @@ __export(activation_event_exports, {
|
|
|
13
13
|
make: () => make,
|
|
14
14
|
oneOf: () => oneOf
|
|
15
15
|
});
|
|
16
|
+
import { DXN } from "@dxos/keys";
|
|
16
17
|
import { compositeKey } from "@dxos/util";
|
|
17
|
-
var make = (
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
};
|
|
22
|
-
};
|
|
18
|
+
var make = (nsid, specifier) => ({
|
|
19
|
+
id: DXN.make(nsid),
|
|
20
|
+
specifier
|
|
21
|
+
});
|
|
23
22
|
var eventKey = (event) => event.specifier ? compositeKey(event.id, event.specifier) : event.id;
|
|
24
23
|
var oneOf = (...events) => ({
|
|
25
24
|
type: "one-of",
|
|
@@ -45,4 +44,4 @@ export {
|
|
|
45
44
|
getEvents,
|
|
46
45
|
activation_event_exports
|
|
47
46
|
};
|
|
48
|
-
//# sourceMappingURL=chunk-
|
|
47
|
+
//# sourceMappingURL=chunk-3NQLTQCP.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/core/activation-event.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { DXN } from '@dxos/keys';\nimport { compositeKey } from '@dxos/util';\n\n/**\n * A unique DXN identifier representing an event.\n *\n * @example dxn:org.dxos.plugin.example.event.ready\n */\nexport type ActivationEvent = {\n id: DXN.DXN;\n specifier?: string;\n};\n\n/**\n * An activation event that can be a single event, or a combination of events.\n */\nexport type Events =\n | ActivationEvent\n | { type: 'one-of'; events: ActivationEvent[] }\n | { type: 'all-of'; events: ActivationEvent[] };\n\n/**\n * Helper to define an activation event from an NSID.\n * Static NSID strings are validated at compile time via {@link DXN.Name}.\n */\nexport const make: {\n <T extends string>(\n nsid: [DXN.Name<T>] extends [never] ? `Invalid NSID \"${T}\": final segment must be camelCase (no hyphens)` : T,\n specifier?: string,\n ): ActivationEvent;\n} = (nsid: string, specifier?: string): ActivationEvent => ({\n id: DXN.make(nsid),\n specifier,\n});\n\n/**\n * Helper to create an activation event key.\n */\nexport const eventKey = (event: ActivationEvent) =>\n event.specifier ? compositeKey(event.id, event.specifier) : event.id;\n\n/**\n * Helper to create an activation event that triggers when any of the given events are activated.\n */\nexport const oneOf = (...events: ActivationEvent[]) => ({ type: 'one-of' as const, events });\n\n/**\n * Helper to create an activation event that triggers when all of the given events are activated.\n */\nexport const allOf = (...events: ActivationEvent[]) => ({ type: 'all-of' as const, events });\n\n/**\n * Helper to check if an activation event is a one-of event.\n */\nexport const isOneOf = (events: Events): events is { type: 'one-of'; events: ActivationEvent[] } =>\n 'type' in events && events.type === 'one-of';\n\n/**\n * Helper to check if an activation event is an all-of event.\n */\nexport const isAllOf = (events: Events): events is { type: 'all-of'; events: ActivationEvent[] } =>\n 'type' in events && events.type === 'all-of';\n\n/**\n * Helper to get the events from an activation event.\n */\nexport const getEvents = (events: Events) => ('type' in events ? events.events : [events]);\n"],
|
|
5
|
+
"mappings": ";;;;;AAAA;;;;;;;;;;AAIA,SAASA,WAAW;AACpB,SAASC,oBAAoB;AAwBtB,IAAMC,OAKT,CAACC,MAAcC,eAAyC;EAC1DC,IAAIL,IAAIE,KAAKC,IAAAA;EACbC;AACF;AAKO,IAAME,WAAW,CAACC,UACvBA,MAAMH,YAAYH,aAAaM,MAAMF,IAAIE,MAAMH,SAAS,IAAIG,MAAMF;AAK7D,IAAMG,QAAQ,IAAIC,YAA+B;EAAEC,MAAM;EAAmBD;AAAO;AAKnF,IAAME,QAAQ,IAAIF,YAA+B;EAAEC,MAAM;EAAmBD;AAAO;AAKnF,IAAMG,UAAU,CAACH,WACtB,UAAUA,UAAUA,OAAOC,SAAS;AAK/B,IAAMG,UAAU,CAACJ,WACtB,UAAUA,UAAUA,OAAOC,SAAS;AAK/B,IAAMI,YAAY,CAACL,WAAoB,UAAUA,SAASA,OAAOA,SAAS;EAACA;;",
|
|
6
|
+
"names": ["DXN", "compositeKey", "make", "nsid", "specifier", "id", "eventKey", "event", "oneOf", "events", "type", "allOf", "isOneOf", "isAllOf", "getEvents"]
|
|
7
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isPlugin
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-S2ZBYQPI.mjs";
|
|
4
4
|
import {
|
|
5
5
|
__export
|
|
6
6
|
} from "./chunk-J5LGTIGS.mjs";
|
|
@@ -55,26 +55,34 @@ import * as HttpClientResponse from "@effect/platform/HttpClientResponse";
|
|
|
55
55
|
import * as Effect2 from "effect/Effect";
|
|
56
56
|
import * as Schema from "effect/Schema";
|
|
57
57
|
import { BaseError as BaseError2 } from "@dxos/errors";
|
|
58
|
-
import { PLUGIN_ENTRY_FILENAME } from "@dxos/protocols";
|
|
58
|
+
import { PLUGIN_ENTRY_FILENAME, PluginManifestSchema } from "@dxos/protocols";
|
|
59
59
|
var PLUGIN_DEV_SERVER_PORT = 3967;
|
|
60
60
|
var PluginManifestError = class extends BaseError2.extend("PluginManifestError", "Plugin manifest is invalid") {
|
|
61
61
|
};
|
|
62
62
|
var Manifest = Schema.Struct({
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
// Reuse the build manifest field definitions from `@dxos/protocols` (the shape `composerPlugin`
|
|
64
|
+
// emits), minus `assets` which we relax below, plus the dev-only `devEntry`.
|
|
65
|
+
...PluginManifestSchema.omit("assets").fields,
|
|
66
|
+
/**
|
|
67
|
+
* Relative asset paths. Relaxed vs the build `PluginManifestSchema` (which requires >= 1) because
|
|
68
|
+
* dev-server manifests list no assets — chunks/styles flow through the dev server on demand.
|
|
69
|
+
*/
|
|
66
70
|
assets: Schema.Array(Schema.String),
|
|
67
|
-
|
|
71
|
+
/** Present only for dev-server manifests; points at the unbundled source entry. */
|
|
72
|
+
devEntry: Schema.optional(Schema.String)
|
|
68
73
|
});
|
|
69
74
|
var resolve = (manifestUrl, manifest) => {
|
|
70
75
|
const dev = manifest.devEntry !== void 0;
|
|
71
76
|
return {
|
|
72
|
-
|
|
77
|
+
key: manifest.key,
|
|
73
78
|
name: manifest.name,
|
|
74
79
|
version: manifest.version,
|
|
75
80
|
entryUrl: new URL(dev ? manifest.devEntry : PLUGIN_ENTRY_FILENAME, manifestUrl).toString(),
|
|
76
81
|
assetUrls: manifest.assets.map((asset) => new URL(asset, manifestUrl).toString()),
|
|
77
|
-
dev
|
|
82
|
+
dev,
|
|
83
|
+
...manifest.dependencies !== void 0 ? {
|
|
84
|
+
dependencies: manifest.dependencies
|
|
85
|
+
} : {}
|
|
78
86
|
};
|
|
79
87
|
};
|
|
80
88
|
var parse = (manifestUrl, payload) => {
|
|
@@ -135,7 +143,7 @@ var getPersistedRemotePlugins = (storage, key) => {
|
|
|
135
143
|
if (!Array.isArray(parsed)) {
|
|
136
144
|
return [];
|
|
137
145
|
}
|
|
138
|
-
return parsed.filter((entry) => typeof entry === "object" && entry !== null && typeof entry.id === "string" && typeof entry.url === "string");
|
|
146
|
+
return parsed.filter((entry) => typeof entry === "object" && entry !== null && typeof entry.id === "string" && typeof entry.url === "string" && (entry.version === void 0 || typeof entry.version === "string"));
|
|
139
147
|
} catch {
|
|
140
148
|
return [];
|
|
141
149
|
}
|
|
@@ -230,14 +238,14 @@ var loadStylesheets = (manifest, cache) => Effect3.gen(function* () {
|
|
|
230
238
|
}
|
|
231
239
|
const cssUrls = manifest.assetUrls.filter((url) => url.endsWith(".css"));
|
|
232
240
|
for (const url of cssUrls) {
|
|
233
|
-
const resolved = yield* cache.resolve(manifest.
|
|
234
|
-
if (document.querySelector(`link[data-dxos-plugin-id="${manifest.
|
|
241
|
+
const resolved = yield* cache.resolve(manifest.key, url);
|
|
242
|
+
if (document.querySelector(`link[data-dxos-plugin-id="${manifest.key}"][href="${resolved}"]`)) {
|
|
235
243
|
continue;
|
|
236
244
|
}
|
|
237
245
|
const link = document.createElement("link");
|
|
238
246
|
link.rel = "stylesheet";
|
|
239
247
|
link.href = resolved;
|
|
240
|
-
link.dataset.dxosPluginId = manifest.
|
|
248
|
+
link.dataset.dxosPluginId = manifest.key;
|
|
241
249
|
document.head.appendChild(link);
|
|
242
250
|
}
|
|
243
251
|
});
|
|
@@ -264,9 +272,9 @@ var loadFromManifest = (manifestUrl, cache) => Effect3.gen(function* () {
|
|
|
264
272
|
manifestUrl,
|
|
265
273
|
...manifest.assetUrls
|
|
266
274
|
] : manifest.assetUrls;
|
|
267
|
-
yield* cache.cache(manifest.
|
|
275
|
+
yield* cache.cache(manifest.key, cachedUrls).pipe(wrapCacheError);
|
|
268
276
|
}
|
|
269
|
-
const entryUrl = manifest.dev ? manifest.entryUrl : yield* cache.resolve(manifest.
|
|
277
|
+
const entryUrl = manifest.dev ? manifest.entryUrl : yield* cache.resolve(manifest.key, manifest.entryUrl).pipe(wrapCacheError);
|
|
270
278
|
const mod = yield* Effect3.tryPromise({
|
|
271
279
|
try: () => import(
|
|
272
280
|
/* @vite-ignore */
|
|
@@ -281,7 +289,7 @@ var loadFromManifest = (manifestUrl, cache) => Effect3.gen(function* () {
|
|
|
281
289
|
})
|
|
282
290
|
});
|
|
283
291
|
const plugin = normalizePluginExport(mod);
|
|
284
|
-
if (!plugin.meta.
|
|
292
|
+
if (!plugin.meta.profile.key || !plugin.meta.profile.name) {
|
|
285
293
|
return yield* Effect3.fail(new RemotePluginLoadError({
|
|
286
294
|
context: {
|
|
287
295
|
locator: manifestUrl,
|
|
@@ -289,13 +297,13 @@ var loadFromManifest = (manifestUrl, cache) => Effect3.gen(function* () {
|
|
|
289
297
|
}
|
|
290
298
|
}));
|
|
291
299
|
}
|
|
292
|
-
if (plugin.meta.
|
|
300
|
+
if (plugin.meta.profile.key !== manifest.key) {
|
|
293
301
|
return yield* Effect3.fail(new RemotePluginLoadError({
|
|
294
302
|
context: {
|
|
295
303
|
locator: manifestUrl,
|
|
296
304
|
reason: "meta-mismatch",
|
|
297
|
-
metaId: plugin.meta.
|
|
298
|
-
manifestId: manifest.
|
|
305
|
+
metaId: plugin.meta.profile.key,
|
|
306
|
+
manifestId: manifest.key
|
|
299
307
|
}
|
|
300
308
|
}));
|
|
301
309
|
}
|
|
@@ -354,7 +362,7 @@ var make = (builtinPlugins, options = {}) => {
|
|
|
354
362
|
const key = options.key ?? DEFAULT_KEY;
|
|
355
363
|
const cache = options.cache ?? noop();
|
|
356
364
|
return (locator) => Effect3.gen(function* () {
|
|
357
|
-
const builtin = builtinPlugins.find((plugin2) => plugin2.meta.
|
|
365
|
+
const builtin = builtinPlugins.find((plugin2) => plugin2.meta.profile.key === locator);
|
|
358
366
|
if (builtin) {
|
|
359
367
|
return {
|
|
360
368
|
plugin: builtin
|
|
@@ -370,18 +378,18 @@ var make = (builtinPlugins, options = {}) => {
|
|
|
370
378
|
}
|
|
371
379
|
const { plugin, manifest } = yield* loadFromManifest(locator, cache);
|
|
372
380
|
if (!manifest.dev) {
|
|
373
|
-
const duplicate = builtinPlugins.find((existing) => existing.meta.
|
|
381
|
+
const duplicate = builtinPlugins.find((existing) => existing.meta.profile.key === plugin.meta.profile.key);
|
|
374
382
|
if (duplicate) {
|
|
375
383
|
return yield* Effect3.fail(new RemotePluginLoadError({
|
|
376
384
|
context: {
|
|
377
385
|
locator,
|
|
378
386
|
reason: "duplicate-id",
|
|
379
|
-
id: plugin.meta.
|
|
387
|
+
id: plugin.meta.profile.key
|
|
380
388
|
}
|
|
381
389
|
}));
|
|
382
390
|
}
|
|
383
391
|
persistRemotePlugin(storage, key, {
|
|
384
|
-
id: plugin.meta.
|
|
392
|
+
id: plugin.meta.profile.key,
|
|
385
393
|
url: locator
|
|
386
394
|
});
|
|
387
395
|
}
|
|
@@ -419,4 +427,4 @@ export {
|
|
|
419
427
|
uninstall,
|
|
420
428
|
url_loader_exports
|
|
421
429
|
};
|
|
422
|
-
//# sourceMappingURL=chunk-
|
|
430
|
+
//# sourceMappingURL=chunk-3UTDRCKX.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/core/url-loader.ts", "../../../src/core/plugin-asset-cache.ts", "../../../src/core/plugin-manifest.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Option from 'effect/Option';\n\nimport { BaseError } from '@dxos/errors';\nimport { log } from '@dxos/log';\n\nimport * as Plugin from './plugin';\nimport * as PluginAssetCache from './plugin-asset-cache';\nimport * as PluginManifest from './plugin-manifest';\n\nconst DEFAULT_KEY = 'org.dxos.composer.remote-plugins';\n\n/**\n * Tagged error for any failure during remote plugin loading. Construction sites\n * set `context.locator` and `context.reason` (one of `'invalid-locator' |\n * 'manifest-error' | 'cache-error' | 'import-failed' | 'meta-missing' |\n * 'meta-mismatch' | 'duplicate-id'`) so handlers can route on the failure mode.\n */\nexport class RemotePluginLoadError extends BaseError.extend('RemotePluginLoadError', 'Failed to load remote plugin') {}\n\n/**\n * Abstraction over key-value storage (defaults to localStorage).\n */\nexport type Storage = {\n get(key: string): string | null;\n set(key: string, value: string): void;\n};\n\n/**\n * Options for configuring the URL loader.\n */\nexport type Options = {\n storage?: Storage;\n key?: string;\n /**\n * Per-platform offline asset cache. Defaults to a no-op cache (no offline support).\n */\n cache?: PluginAssetCache.Cache;\n};\n\n/**\n * Options for the preload entry point. Adds an optional progress hook so hosts\n * can drive a boot-loader counter (`Loading plugins (3/12)…`) as remote plugin\n * manifests resolve. Resolution order is *not* deterministic — each entry races\n * its own network fetch — so callers should treat `loaded` as a count, not an\n * index. Failures are still swallowed; `loaded` advances on both success and\n * recoverable failure so the counter always reaches `total`.\n */\nexport type PreloadOptions = Options & {\n onPluginLoaded?: (loaded: number, total: number) => void;\n};\n\n/**\n * Persisted record of a remote plugin that has been loaded previously.\n *\n * `url` is the URL of the plugin manifest (`plugin.json`), not the entry module.\n */\nexport type RemotePluginView = {\n id: string;\n url: string;\n /** Installed version string, e.g. `v1.0.0`. Populated after install from a community catalog entry. */\n version?: string;\n};\n\nconst defaultStorage = (): Storage => ({\n get: (key) => localStorage.getItem(key),\n set: (key, value) => localStorage.setItem(key, value),\n});\n\nconst getPersistedRemotePlugins = (storage: Storage, key: string): RemotePluginView[] => {\n try {\n const parsed: unknown = JSON.parse(storage.get(key) ?? '[]');\n if (!Array.isArray(parsed)) {\n return [];\n }\n return parsed.filter(\n (entry): entry is RemotePluginView =>\n typeof entry === 'object' &&\n entry !== null &&\n typeof entry.id === 'string' &&\n typeof entry.url === 'string' &&\n (entry.version === undefined || typeof entry.version === 'string'),\n );\n } catch {\n return [];\n }\n};\n\nconst persistRemotePlugin = (storage: Storage, key: string, entry: RemotePluginView): void => {\n try {\n const entries = getPersistedRemotePlugins(storage, key).filter((existing) => existing.id !== entry.id);\n entries.push(entry);\n storage.set(key, JSON.stringify(entries));\n } catch (error) {\n log.warn('failed to persist remote plugin entry', { entry, error });\n }\n};\n\nconst removePersistedRemotePlugin = (storage: Storage, key: string, pluginId: string): void => {\n try {\n const entries = getPersistedRemotePlugins(storage, key).filter((existing) => existing.id !== pluginId);\n storage.set(key, JSON.stringify(entries));\n } catch (error) {\n log.warn('failed to remove remote plugin entry', { pluginId, error });\n }\n};\n\nconst isUrl = (locator: string): boolean => {\n try {\n const url = new URL(locator);\n return url.protocol === 'http:' || url.protocol === 'https:';\n } catch {\n return false;\n }\n};\n\n/**\n * Returns true when the URL's hostname is the local host (localhost, 127.0.0.1, or ::1).\n */\nexport const isLocalUrl = (locator: string): boolean => {\n try {\n const hostname = new URL(locator).hostname.toLowerCase();\n // WHATWG URL returns '::1' without brackets in Node; some browsers return '[::1]'.\n return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1' || hostname === '[::1]';\n } catch {\n return false;\n }\n};\n\n/**\n * Returns the list of remote plugin entries previously persisted by {@link make}.\n * Useful for UI code that needs to know which loaded plugins were installed from a URL\n * (e.g. to surface a tag on remote or localhost-hosted plugins).\n */\nexport const getRemoteEntries = (options: Options = {}): readonly RemotePluginView[] => {\n const storage = options.storage ?? defaultStorage();\n const key = options.key ?? DEFAULT_KEY;\n return getPersistedRemotePlugins(storage, key);\n};\n\n/**\n * Updates the persisted installed version for an already-stored remote plugin entry.\n * Does nothing if the plugin has not been persisted yet.\n */\nexport const setInstalledVersion = (id: string, version: string, options: Options = {}): void => {\n const storage = options.storage ?? defaultStorage();\n const key = options.key ?? DEFAULT_KEY;\n const entries = getPersistedRemotePlugins(storage, key);\n const index = entries.findIndex((entry) => entry.id === id);\n if (index === -1) {\n return;\n }\n entries[index] = { ...entries[index], version };\n try {\n storage.set(key, JSON.stringify(entries));\n } catch (error) {\n log.warn('failed to update installed version for remote plugin', { id, version, error });\n }\n};\n\n/**\n * Returns the installed version string for the given plugin id, or `undefined` if\n * the plugin was installed without version tracking (legacy install) or is not found.\n */\nexport const getInstalledVersion = (id: string, options: Options = {}): string | undefined => {\n const storage = options.storage ?? defaultStorage();\n const key = options.key ?? DEFAULT_KEY;\n return getPersistedRemotePlugins(storage, key).find((entry) => entry.id === id)?.version;\n};\n\nconst normalizePluginExport = (mod: Record<string, unknown>): Plugin.Plugin => {\n const exported = mod.default;\n if (Plugin.isPlugin(exported)) {\n return exported;\n }\n if (typeof exported === 'function') {\n const result = (exported as () => unknown)();\n if (Plugin.isPlugin(result)) {\n return result;\n }\n }\n throw new Error('Remote module default export is not a Plugin or a zero-arg plugin factory.');\n};\n\n/**\n * Loads stylesheets declared in the manifest by appending `<link rel=\"stylesheet\">` elements to the host document.\n * Each link is tagged with `data-dxos-plugin-id` so `uninstall` can clean them up.\n */\nconst loadStylesheets = (\n manifest: PluginManifest.ResolvedManifest,\n cache: PluginAssetCache.Cache,\n): Effect.Effect<void, PluginAssetCache.PluginAssetCacheError> =>\n Effect.gen(function* () {\n if (typeof document === 'undefined') {\n return;\n }\n const cssUrls = manifest.assetUrls.filter((url) => url.endsWith('.css'));\n for (const url of cssUrls) {\n const resolved = yield* cache.resolve(manifest.key, url);\n if (document.querySelector(`link[data-dxos-plugin-id=\"${manifest.key}\"][href=\"${resolved}\"]`)) {\n continue;\n }\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = resolved;\n link.dataset.dxosPluginId = manifest.key;\n document.head.appendChild(link);\n }\n });\n\nconst loadFromManifest = (\n manifestUrl: string,\n cache: PluginAssetCache.Cache,\n): Effect.Effect<{ plugin: Plugin.Plugin; manifest: PluginManifest.ResolvedManifest }, RemotePluginLoadError> =>\n Effect.gen(function* () {\n log.info('loading remote plugin', { manifestUrl });\n const manifest = yield* PluginManifest.fetchManifest(manifestUrl).pipe(\n Effect.mapError(\n (cause) => new RemotePluginLoadError({ context: { locator: manifestUrl, reason: 'manifest-error' }, cause }),\n ),\n );\n const wrapCacheError = Effect.mapError(\n (cause: PluginAssetCache.PluginAssetCacheError) =>\n new RemotePluginLoadError({ context: { locator: manifestUrl, reason: 'cache-error' }, cause }),\n );\n // Dev-mode manifests (served by `vite dev` via composerPlugin) skip the offline\n // cache: chunks resolve on demand through the dev server, the asset list isn't\n // enumerable up-front, and CSS arrives via runtime <style> injection rather than\n // static <link> tags.\n if (!manifest.dev) {\n // Cache the manifest URL alongside its declared assets. Without it, `preload` on a\n // subsequent reload would fetch the manifest from the network — and fail when the\n // plugin's host is offline, dropping the plugin from the runtime.\n const cachedUrls =\n manifest.assetUrls.indexOf(manifestUrl) === -1 ? [manifestUrl, ...manifest.assetUrls] : manifest.assetUrls;\n yield* cache.cache(manifest.key, cachedUrls).pipe(wrapCacheError);\n }\n const entryUrl = manifest.dev\n ? manifest.entryUrl\n : yield* cache.resolve(manifest.key, manifest.entryUrl).pipe(wrapCacheError);\n const mod = yield* Effect.tryPromise({\n try: () => import(/* @vite-ignore */ entryUrl),\n catch: (cause) =>\n new RemotePluginLoadError({ context: { locator: manifestUrl, reason: 'import-failed' }, cause }),\n });\n const plugin = normalizePluginExport(mod);\n if (!plugin.meta.profile.key || !plugin.meta.profile.name) {\n return yield* Effect.fail(\n new RemotePluginLoadError({ context: { locator: manifestUrl, reason: 'meta-missing' } }),\n );\n }\n if (plugin.meta.profile.key !== manifest.key) {\n return yield* Effect.fail(\n new RemotePluginLoadError({\n context: {\n locator: manifestUrl,\n reason: 'meta-mismatch',\n metaId: plugin.meta.profile.key,\n manifestId: manifest.key,\n },\n }),\n );\n }\n // Append stylesheets only after the entry imports cleanly and meta validation\n // passes. If we did this earlier and the import or meta checks failed, the\n // `<link>` tags would leak into the host DOM with no plugin to own their\n // teardown — `uninstall` only runs for plugins the manager actually accepted.\n // In dev mode, Vite injects styles at runtime via the module graph, so static\n // <link> tags would duplicate (or 404, since CSS chunks aren't pre-built).\n if (!manifest.dev) {\n yield* loadStylesheets(manifest, cache).pipe(wrapCacheError);\n }\n return { plugin, manifest };\n });\n\n/**\n * Preloads previously persisted remote plugins from storage. Per-entry failures\n * are logged and swallowed — the returned effect always succeeds with whichever\n * plugins loaded cleanly, so a single bad entry can't block the host's startup.\n */\nexport const preload = (options: PreloadOptions = {}): Effect.Effect<Plugin.Plugin[], never> =>\n Effect.gen(function* () {\n const storage = options.storage ?? defaultStorage();\n const key = options.key ?? DEFAULT_KEY;\n const cache = options.cache ?? PluginAssetCache.noop();\n const onPluginLoaded = options.onPluginLoaded;\n\n const entries = getPersistedRemotePlugins(storage, key);\n if (entries.length === 0) {\n return [];\n }\n log.info('preloading remote plugins', { count: entries.length });\n const total = entries.length;\n let loaded = 0;\n const results = yield* Effect.all(\n entries.map((entry) =>\n loadFromManifest(entry.url, cache).pipe(\n Effect.tapError((error) => Effect.sync(() => log.warn('failed to preload remote plugin', { entry, error }))),\n Effect.option,\n // Tick the progress hook on both success and recoverable failure so\n // the counter monotonically reaches `total`. The host-supplied\n // callback is best-effort: any synchronous throw flows through\n // `Effect.try` and gets logged + ignored so a buggy hook can't\n // derail the preload.\n Effect.tap(() =>\n Effect.sync(() => {\n loaded += 1;\n }).pipe(\n Effect.andThen(Effect.try(() => onPluginLoaded?.(loaded, total))),\n Effect.tapError((error) => Effect.sync(() => log.warn('onPluginLoaded threw', { loaded, total, error }))),\n Effect.ignore,\n ),\n ),\n ),\n ),\n { concurrency: 'unbounded' },\n );\n return results.flatMap((result) =>\n Option.match(result, {\n onNone: () => [],\n onSome: ({ plugin }) => [plugin],\n }),\n );\n });\n\n/**\n * Creates a plugin loader that resolves built-in plugins by ID or loads remote plugins from URLs.\n *\n * Remote URLs must point at a plugin manifest (`plugin.json`). The loader fetches the manifest,\n * eagerly persists every declared asset via the configured `PluginAssetCache`, then dynamic-imports\n * the entry module.\n */\nexport const make = (builtinPlugins: Plugin.Plugin[], options: Options = {}) => {\n const storage = options.storage ?? defaultStorage();\n const key = options.key ?? DEFAULT_KEY;\n const cache = options.cache ?? PluginAssetCache.noop();\n\n return (locator: string): Effect.Effect<{ plugin: Plugin.Plugin; dev?: boolean }, RemotePluginLoadError> =>\n Effect.gen(function* () {\n const builtin = builtinPlugins.find((plugin) => plugin.meta.profile.key === locator);\n if (builtin) {\n return { plugin: builtin };\n }\n if (!isUrl(locator)) {\n return yield* Effect.fail(new RemotePluginLoadError({ context: { locator, reason: 'invalid-locator' } }));\n }\n const { plugin, manifest } = yield* loadFromManifest(locator, cache);\n // Production manifests can't collide with a builtin id — that would make\n // the registered plugin permanently inaccessible. Dev manifests are\n // allowed to collide because the manager shadow primitive handles the\n // overlap (dev plugin takes the id slot for the session, original is\n // restored on uninstall or page reload).\n if (!manifest.dev) {\n const duplicate = builtinPlugins.find((existing) => existing.meta.profile.key === plugin.meta.profile.key);\n if (duplicate) {\n return yield* Effect.fail(\n new RemotePluginLoadError({ context: { locator, reason: 'duplicate-id', id: plugin.meta.profile.key } }),\n );\n }\n persistRemotePlugin(storage, key, { id: plugin.meta.profile.key, url: locator });\n }\n return { plugin, dev: manifest.dev };\n });\n};\n\n/**\n * Removes a previously installed remote plugin: drops the persisted entry, evicts cached\n * assets, and removes any stylesheet `<link>` tags that {@link loadFromManifest} appended.\n *\n * Cache eviction failures are logged and swallowed — the persisted entry has already been\n * dropped so the user-visible state is consistent regardless of whether the platform\n * cache cooperated.\n */\nexport const uninstall = (pluginId: string, options: Options = {}): Effect.Effect<void, never> =>\n Effect.gen(function* () {\n const storage = options.storage ?? defaultStorage();\n const key = options.key ?? DEFAULT_KEY;\n const cache = options.cache ?? PluginAssetCache.noop();\n\n removePersistedRemotePlugin(storage, key, pluginId);\n if (typeof document !== 'undefined') {\n document.querySelectorAll(`link[data-dxos-plugin-id=\"${pluginId}\"]`).forEach((node) => node.remove());\n }\n yield* cache.evict(pluginId).pipe(\n Effect.tapError((error) => Effect.sync(() => log.warn('failed to evict plugin assets', { pluginId, error }))),\n Effect.ignore,\n );\n });\n", "//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { BaseError } from '@dxos/errors';\n\n/**\n * Tagged error for cache operations. Construction sites supply `context.operation`\n * (one of `'cache' | 'evict' | 'resolve' | 'list'`) and `context.pluginId` so\n * downstream handlers can route on the failed call without scanning the message.\n */\nexport class PluginAssetCacheError extends BaseError.extend(\n 'PluginAssetCacheError',\n 'Plugin asset cache operation failed',\n) {}\n\n/**\n * Per-platform offline cache for third-party plugin assets.\n *\n * Implementations live alongside their platform glue (composer-app's\n * `asset-cache/{tauri,service-worker}.ts`); the no-op default is for tests\n * and unsupported environments.\n */\nexport interface Cache {\n /**\n * Persist all listed URLs under the namespace of `pluginId`. Idempotent.\n * The order of `urls` is significant — the first entry is treated as the entry module.\n */\n cache(pluginId: string, urls: readonly string[]): Effect.Effect<void, PluginAssetCacheError>;\n\n /**\n * Drop all assets for a plugin (uninstall).\n */\n evict(pluginId: string): Effect.Effect<void, PluginAssetCacheError>;\n\n /**\n * Resolves a plugin asset URL to a platform-specific cached URL when one is available.\n * Returns the original URL when no cached copy exists or the platform serves cached\n * responses transparently (e.g. service worker fetch interception on web).\n */\n resolve(pluginId: string, url: string): Effect.Effect<string, PluginAssetCacheError>;\n\n /**\n * List currently cached plugin ids (diagnostic).\n */\n list(): Effect.Effect<readonly string[], PluginAssetCacheError>;\n}\n\n/**\n * No-op implementation. Used when no platform cache is registered (tests, unsupported environments).\n * Plugins still load — they just have no offline guarantee.\n */\nexport const noop = (): Cache => ({\n cache: () => Effect.void,\n evict: () => Effect.void,\n resolve: (_pluginId, url) => Effect.succeed(url),\n list: () => Effect.succeed([] as readonly string[]),\n});\n", "//\n// Copyright 2026 DXOS.org\n//\n\nimport * as FetchHttpClient from '@effect/platform/FetchHttpClient';\nimport * as HttpClient from '@effect/platform/HttpClient';\nimport * as HttpClientRequest from '@effect/platform/HttpClientRequest';\nimport * as HttpClientResponse from '@effect/platform/HttpClientResponse';\nimport * as Effect from 'effect/Effect';\nimport * as Schema from 'effect/Schema';\n\nimport { BaseError } from '@dxos/errors';\nimport { PLUGIN_ENTRY_FILENAME, PluginManifestSchema } from '@dxos/protocols';\n\n/**\n * Default port the Vite plugin (`composerPlugin`) binds the dev server to.\n *\n * Shared single source of truth — `composerPlugin` reads it as the default\n * port, and the host's \"Load Dev Plugin\" affordance pre-fills the manifest URL\n * with `http://localhost:${PLUGIN_DEV_SERVER_PORT}/manifest.json`. Lives in\n * app-framework rather than `@dxos/protocols` because the constant is a\n * client-side convention (host loader + Vite plugin) rather than a wire-level\n * protocol.\n */\nexport const PLUGIN_DEV_SERVER_PORT = 3967;\n\n/**\n * Tagged error for manifest fetch / parse failures. Construction sites set\n * `context.manifestUrl` and `context.reason` (one of `'fetch-failed' |\n * 'http-error' | 'parse-failed' | 'invalid'`) so handlers can route on the\n * specific failure mode.\n */\nexport class PluginManifestError extends BaseError.extend('PluginManifestError', 'Plugin manifest is invalid') {}\n\n/**\n * Schema for a third-party plugin manifest.\n *\n * Production manifests are published as a sibling of the plugin's entry module\n * ({@link PLUGIN_ENTRY_FILENAME}) and advertise every file the plugin needs at\n * runtime so the host can eagerly cache them for offline use.\n *\n * Dev manifests (served by `vite dev` via {@link composerPlugin}) set `devEntry`\n * to point at the unbundled source entry. The host's loader treats the presence\n * of `devEntry` as the dev-mode signal: it imports the entry directly from the\n * dev server, skips eager asset caching, and skips static stylesheet injection\n * (Vite handles CSS via runtime `<style>` injection during HMR). `assets` is not\n * required to enumerate every file in dev mode — chunks and styles flow through\n * the dev server on demand.\n */\nexport const Manifest = Schema.Struct({\n // Reuse the build manifest field definitions from `@dxos/protocols` (the shape `composerPlugin`\n // emits), minus `assets` which we relax below, plus the dev-only `devEntry`.\n ...PluginManifestSchema.omit('assets').fields,\n /**\n * Relative asset paths. Relaxed vs the build `PluginManifestSchema` (which requires >= 1) because\n * dev-server manifests list no assets — chunks/styles flow through the dev server on demand.\n */\n assets: Schema.Array(Schema.String),\n /** Present only for dev-server manifests; points at the unbundled source entry. */\n devEntry: Schema.optional(Schema.String),\n});\n\nexport type Manifest = Schema.Schema.Type<typeof Manifest>;\n\n/**\n * Resolved manifest with all asset paths converted to absolute URLs.\n *\n * `dev` reflects whether the source manifest declared a `devEntry`. Loaders branch\n * on this to skip offline caching and stylesheet injection — both are no-ops (or\n * actively wrong) when the plugin is being served by a Vite dev server.\n */\nexport type ResolvedManifest = Pick<Manifest, 'key' | 'name' | 'version' | 'dependencies'> & {\n entryUrl: string;\n assetUrls: readonly string[];\n dev: boolean;\n};\n\n/**\n * Resolves a parsed manifest's relative asset paths against the manifest's URL.\n * In dev mode the entry comes from `devEntry`; otherwise it's the canonical\n * {@link PLUGIN_ENTRY_FILENAME} sitting next to the manifest.\n */\nconst resolve = (manifestUrl: string, manifest: Manifest): ResolvedManifest => {\n const dev = manifest.devEntry !== undefined;\n return {\n key: manifest.key,\n name: manifest.name,\n version: manifest.version,\n entryUrl: new URL(dev ? manifest.devEntry! : PLUGIN_ENTRY_FILENAME, manifestUrl).toString(),\n assetUrls: manifest.assets.map((asset) => new URL(asset, manifestUrl).toString()),\n dev,\n ...(manifest.dependencies !== undefined ? { dependencies: manifest.dependencies } : {}),\n };\n};\n\n/**\n * Synchronous decode + validate + resolve for an in-memory manifest payload. Used\n * by tests and tooling that have the manifest body already loaded; the runtime\n * path goes through {@link fetchManifest}.\n */\nexport const parse = (manifestUrl: string, payload: unknown): ResolvedManifest => {\n const manifest = Schema.decodeUnknownSync(Manifest)(payload);\n if (manifest.devEntry === undefined && !manifest.assets.includes(PLUGIN_ENTRY_FILENAME)) {\n throw new Error(`Manifest at ${manifestUrl} does not list ${PLUGIN_ENTRY_FILENAME} in assets.`);\n }\n return resolve(manifestUrl, manifest);\n};\n\n/**\n * Fetches and parses a manifest from the given URL via Effect's HTTP client and\n * Schema-driven JSON decoding. All failure modes surface as a single tagged\n * {@link PluginManifestError}; callers route on `error.context.reason`.\n */\nexport const fetchManifest = (manifestUrl: string): Effect.Effect<ResolvedManifest, PluginManifestError> =>\n Effect.gen(function* () {\n const response = yield* HttpClientRequest.get(manifestUrl).pipe(\n HttpClient.execute,\n Effect.mapError((cause) => new PluginManifestError({ context: { manifestUrl, reason: 'fetch-failed' }, cause })),\n );\n if (response.status >= 400) {\n return yield* Effect.fail(\n new PluginManifestError({ context: { manifestUrl, reason: 'http-error', status: response.status } }),\n );\n }\n const manifest = yield* HttpClientResponse.schemaBodyJson(Manifest)(response).pipe(\n Effect.mapError((cause) => new PluginManifestError({ context: { manifestUrl, reason: 'parse-failed' }, cause })),\n );\n if (manifest.devEntry === undefined && !manifest.assets.includes(PLUGIN_ENTRY_FILENAME)) {\n return yield* Effect.fail(\n new PluginManifestError({\n context: { manifestUrl, reason: 'invalid' },\n cause: `assets does not include ${PLUGIN_ENTRY_FILENAME}`,\n }),\n );\n }\n return resolve(manifestUrl, manifest);\n }).pipe(Effect.scoped, Effect.provide(FetchHttpClient.layer));\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Effect", "Option", "BaseError", "log", "Effect", "BaseError", "PluginAssetCacheError", "extend", "noop", "cache", "void", "evict", "resolve", "_pluginId", "url", "succeed", "list", "FetchHttpClient", "HttpClient", "HttpClientRequest", "HttpClientResponse", "Effect", "Schema", "BaseError", "PLUGIN_ENTRY_FILENAME", "PluginManifestSchema", "PLUGIN_DEV_SERVER_PORT", "PluginManifestError", "extend", "Manifest", "Struct", "omit", "fields", "assets", "Array", "String", "devEntry", "optional", "resolve", "manifestUrl", "manifest", "dev", "undefined", "key", "name", "version", "entryUrl", "URL", "toString", "assetUrls", "map", "asset", "dependencies", "parse", "payload", "decodeUnknownSync", "includes", "Error", "fetchManifest", "gen", "response", "get", "pipe", "execute", "mapError", "cause", "context", "reason", "status", "fail", "schemaBodyJson", "scoped", "provide", "layer", "DEFAULT_KEY", "defaultStorage", "BaseError", "value", "localStorage", "getPersistedRemotePlugins", "storage", "key", "get", "parsed", "entries", "error", "log", "entry", "pluginId", "url", "URL", "hostname", "locator", "options", "index", "findIndex", "version", "id", "find", "normalizePluginExport", "mod", "exported", "Plugin", "result", "resolved", "resolve", "manifest", "document", "querySelector", "link", "href", "dataset", "head", "loadFromManifest", "manifestUrl", "context", "reason", "cause", "wrapCacheError", "assetUrls", "cache", "entryUrl", "try", "catch", "RemotePluginLoadError", "plugin", "metaId", "manifestId", "PluginAssetCache", "noop", "onPluginLoaded", "info", "total", "results", "pipe", "andThen", "Effect", "loaded", "flatMap", "onSome", "gen", "builtin", "duplicate", "persistRemotePlugin", "dev", "removePersistedRemotePlugin", "querySelectorAll", "evict", "sync", "warn"]
|
|
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 */\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;AAmCO,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,20 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PluginManagerProvider,
|
|
3
3
|
topologicalSort,
|
|
4
|
+
useOptionalPluginManager,
|
|
4
5
|
usePluginManager
|
|
5
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-SWECIICH.mjs";
|
|
6
7
|
import {
|
|
7
8
|
PluginManagerContext
|
|
8
9
|
} from "./chunk-FJ4765WW.mjs";
|
|
9
10
|
import {
|
|
10
11
|
capabilities_exports
|
|
11
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-37PG7XJC.mjs";
|
|
12
13
|
import {
|
|
13
14
|
activation_events_exports
|
|
14
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-VF37YTXJ.mjs";
|
|
15
16
|
import {
|
|
16
17
|
plugin_manager_exports
|
|
17
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-W4BHZING.mjs";
|
|
18
19
|
|
|
19
20
|
// src/ui/components/App/App.tsx
|
|
20
21
|
import React2, { useEffect as useEffect3, useLayoutEffect } from "react";
|
|
@@ -39,7 +40,7 @@ var useApp = ({ pluginManager, pluginLoader: pluginLoaderProp, onPluginRemove, p
|
|
|
39
40
|
const defaults = useDefaultValue(defaultsProp, () => []);
|
|
40
41
|
const setupEvents = useDefaultValue(setupEventsProp, () => []);
|
|
41
42
|
const pluginLoader = useMemo(() => pluginLoaderProp ?? ((id) => Effect.sync(() => {
|
|
42
|
-
const plugin = plugins.find((plugin2) => plugin2.meta.
|
|
43
|
+
const plugin = plugins.find((plugin2) => plugin2.meta.profile.key === id);
|
|
43
44
|
invariant(plugin, `Plugin not found: ${id}`, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 48, S: void 0, A: ["plugin", "`Plugin not found: ${id}`"] });
|
|
44
45
|
return {
|
|
45
46
|
plugin
|
|
@@ -241,19 +242,26 @@ var humanizeEventKey = (eventKey) => {
|
|
|
241
242
|
};
|
|
242
243
|
|
|
243
244
|
// src/ui/hooks/useCapabilities.ts
|
|
245
|
+
import { Atom } from "@effect-atom/atom";
|
|
244
246
|
import { useAtomValue } from "@effect-atom/atom-react";
|
|
245
247
|
import { useCallback as useCallback2 } from "react";
|
|
246
248
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
247
249
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/sdk/app-framework/src/ui/hooks/useCapabilities.ts";
|
|
250
|
+
var emptyCapabilities = Atom.make(() => []);
|
|
248
251
|
var useCapabilities = (interfaceDef) => {
|
|
249
252
|
const manager = usePluginManager();
|
|
250
253
|
return useAtomValue(manager.capabilities.atom(interfaceDef));
|
|
251
254
|
};
|
|
252
255
|
var useCapability = (interfaceDef) => {
|
|
253
256
|
const capabilities = useCapabilities(interfaceDef);
|
|
254
|
-
invariant2(capabilities.length > 0, `No capability found for ${interfaceDef.identifier}`, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L:
|
|
257
|
+
invariant2(capabilities.length > 0, `No capability found for ${interfaceDef.identifier}`, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 25, S: void 0, A: ["capabilities.length > 0", "`No capability found for ${interfaceDef.identifier}`"] });
|
|
255
258
|
return capabilities[0];
|
|
256
259
|
};
|
|
260
|
+
var useOptionalCapabilities = (interfaceDef) => {
|
|
261
|
+
const manager = useOptionalPluginManager();
|
|
262
|
+
return useAtomValue(manager ? manager.capabilities.atom(interfaceDef) : emptyCapabilities);
|
|
263
|
+
};
|
|
264
|
+
var useOptionalCapability = (interfaceDef) => useOptionalCapabilities(interfaceDef)[0];
|
|
257
265
|
var useAtomCapability = (atomCapability) => {
|
|
258
266
|
const atom = useCapability(atomCapability);
|
|
259
267
|
return useAtomValue(atom);
|
|
@@ -462,6 +470,8 @@ export {
|
|
|
462
470
|
useApp,
|
|
463
471
|
useCapabilities,
|
|
464
472
|
useCapability,
|
|
473
|
+
useOptionalCapabilities,
|
|
474
|
+
useOptionalCapability,
|
|
465
475
|
useAtomCapability,
|
|
466
476
|
useAtomCapabilityState,
|
|
467
477
|
useOperationInvoker,
|
|
@@ -473,4 +483,4 @@ export {
|
|
|
473
483
|
useSettingsState,
|
|
474
484
|
App
|
|
475
485
|
};
|
|
476
|
-
//# sourceMappingURL=chunk-
|
|
486
|
+
//# sourceMappingURL=chunk-DFVSOBV2.mjs.map
|