@dxos/app-framework 0.9.0 → 0.9.1-staging.ee54ba693a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/{capability-BOPAKKWG.mjs → capability-S44TE2H7.mjs} +9 -9
- package/dist/lib/browser/{chunk-66IXTIVK.mjs → chunk-3NQLTQCP.mjs} +6 -7
- package/dist/lib/browser/chunk-3NQLTQCP.mjs.map +7 -0
- package/dist/lib/browser/chunk-53HJHMS5.mjs +7 -0
- package/dist/lib/browser/chunk-53HJHMS5.mjs.map +7 -0
- package/dist/lib/browser/{chunk-Y66ELD4U.mjs → chunk-KRJ4KK2W.mjs} +36 -7
- package/dist/lib/browser/chunk-KRJ4KK2W.mjs.map +7 -0
- package/dist/lib/browser/{chunk-KZUDO43J.mjs → chunk-LUH4Y5F2.mjs} +31 -23
- package/dist/lib/browser/chunk-LUH4Y5F2.mjs.map +7 -0
- package/dist/lib/browser/{chunk-CO3XLNUX.mjs → chunk-NKVRSMFN.mjs} +18 -18
- package/dist/lib/browser/chunk-NKVRSMFN.mjs.map +7 -0
- package/dist/lib/browser/{chunk-DC3WRPBV.mjs → chunk-OO53M5UK.mjs} +45 -12
- package/dist/lib/browser/chunk-OO53M5UK.mjs.map +7 -0
- package/dist/lib/browser/{chunk-IW44C7UL.mjs → chunk-OPTS3ZSN.mjs} +1 -1
- package/dist/lib/browser/chunk-OPTS3ZSN.mjs.map +7 -0
- package/dist/lib/browser/{chunk-HFLKXMT7.mjs → chunk-U5MESPM5.mjs} +61 -45
- package/dist/lib/browser/chunk-U5MESPM5.mjs.map +7 -0
- package/dist/lib/browser/{chunk-XHS5KDNX.mjs → chunk-UGYCLOXE.mjs} +25 -25
- package/dist/lib/browser/chunk-UGYCLOXE.mjs.map +7 -0
- package/dist/lib/browser/{chunk-5GY3YOEL.mjs → chunk-VF37YTXJ.mjs} +5 -5
- package/dist/lib/browser/chunk-VF37YTXJ.mjs.map +7 -0
- package/dist/lib/browser/{chunk-FO3IYSLV.mjs → chunk-YUVQIOTB.mjs} +29 -37
- package/dist/lib/browser/chunk-YUVQIOTB.mjs.map +7 -0
- package/dist/lib/browser/cli/index.mjs +9 -9
- package/dist/lib/browser/cli/index.mjs.map +2 -2
- package/dist/lib/browser/common/activation-events.mjs +7 -7
- package/dist/lib/browser/common/capabilities.mjs +7 -7
- package/dist/lib/browser/config/index.mjs +8 -0
- package/dist/lib/browser/config/index.mjs.map +7 -0
- package/dist/lib/browser/core/activation-event.mjs +1 -1
- package/dist/lib/browser/core/capability.mjs +1 -1
- package/dist/lib/browser/core/plugin-manager.mjs +4 -4
- package/dist/lib/browser/core/plugin.mjs +12 -2
- package/dist/lib/browser/core/url-loader.mjs +3 -3
- package/dist/lib/browser/index.mjs +14 -10
- package/dist/lib/browser/index.mjs.map +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{process-manager-capability-GXNUO7AR.mjs → process-manager-capability-QK4BMKMN.mjs} +9 -9
- package/dist/lib/browser/testing/index.mjs +15 -15
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/testing/react.mjs +11 -11
- package/dist/lib/browser/testing/react.mjs.map +3 -3
- package/dist/lib/browser/ui/index.mjs +18 -10
- package/dist/lib/node-esm/{capability-KZWRTX7R.mjs → capability-3YRF77LV.mjs} +9 -9
- package/dist/lib/node-esm/chunk-2UPUZXGU.mjs +9 -0
- package/dist/lib/node-esm/chunk-2UPUZXGU.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-XIGPWXCQ.mjs → chunk-4SE7SX7N.mjs} +45 -12
- package/dist/lib/node-esm/chunk-4SE7SX7N.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-XOCUANHO.mjs → chunk-BMW6P6QA.mjs} +6 -7
- package/dist/lib/node-esm/chunk-BMW6P6QA.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-A5CHGAZE.mjs → chunk-DRT75WGD.mjs} +61 -45
- package/dist/lib/node-esm/chunk-DRT75WGD.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-XGBUKRCK.mjs → chunk-FKMVORZN.mjs} +31 -23
- package/dist/lib/node-esm/chunk-FKMVORZN.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-CTKEZHKF.mjs → chunk-GLH4LGHZ.mjs} +1 -1
- package/dist/lib/node-esm/chunk-GLH4LGHZ.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-SX5NVETP.mjs → chunk-IL7O7IRX.mjs} +25 -25
- package/dist/lib/node-esm/chunk-IL7O7IRX.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-FSVGKTF6.mjs → chunk-ND2HETHD.mjs} +36 -7
- package/dist/lib/node-esm/chunk-ND2HETHD.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-KFZEB6BV.mjs → chunk-TLKYZKPW.mjs} +5 -5
- package/dist/lib/node-esm/chunk-TLKYZKPW.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-WK7OIQKI.mjs → chunk-VCPGX7WN.mjs} +29 -37
- package/dist/lib/node-esm/chunk-VCPGX7WN.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-NULBHQYS.mjs → chunk-XSZMX53L.mjs} +18 -18
- package/dist/lib/node-esm/chunk-XSZMX53L.mjs.map +7 -0
- package/dist/lib/node-esm/cli/index.mjs +9 -9
- package/dist/lib/node-esm/cli/index.mjs.map +2 -2
- package/dist/lib/node-esm/common/activation-events.mjs +7 -7
- package/dist/lib/node-esm/common/capabilities.mjs +7 -7
- package/dist/lib/node-esm/config/index.mjs +9 -0
- package/dist/lib/node-esm/config/index.mjs.map +7 -0
- package/dist/lib/node-esm/core/activation-event.mjs +1 -1
- package/dist/lib/node-esm/core/capability.mjs +1 -1
- package/dist/lib/node-esm/core/plugin-manager.mjs +4 -4
- package/dist/lib/node-esm/core/plugin.mjs +12 -2
- package/dist/lib/node-esm/core/url-loader.mjs +3 -3
- package/dist/lib/node-esm/index.mjs +14 -10
- package/dist/lib/node-esm/index.mjs.map +1 -1
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{process-manager-capability-TX5TA6YN.mjs → process-manager-capability-5S7WZ2JR.mjs} +9 -9
- package/dist/lib/node-esm/testing/index.mjs +15 -15
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/testing/react.mjs +11 -11
- package/dist/lib/node-esm/testing/react.mjs.map +3 -3
- package/dist/lib/node-esm/ui/index.mjs +18 -10
- package/dist/plugin/node-esm/index.mjs +414 -81
- package/dist/plugin/node-esm/index.mjs.map +4 -4
- package/dist/plugin/node-esm/meta.json +1 -1
- package/dist/types/src/cli/cli.d.ts +1 -1
- package/dist/types/src/common/activation-events.d.ts.map +1 -1
- package/dist/types/src/common/capabilities.d.ts +2 -2
- package/dist/types/src/common/capabilities.d.ts.map +1 -1
- package/dist/types/src/config/index.d.ts +2 -0
- package/dist/types/src/config/index.d.ts.map +1 -0
- package/dist/types/src/core/activation-event.d.ts +9 -6
- package/dist/types/src/core/activation-event.d.ts.map +1 -1
- package/dist/types/src/core/capability.d.ts +9 -3
- package/dist/types/src/core/capability.d.ts.map +1 -1
- package/dist/types/src/core/edge-registry-plugin-provider.d.ts +6 -11
- package/dist/types/src/core/edge-registry-plugin-provider.d.ts.map +1 -1
- package/dist/types/src/core/plugin-manager.d.ts.map +1 -1
- package/dist/types/src/core/plugin-manifest.d.ts +25 -7
- package/dist/types/src/core/plugin-manifest.d.ts.map +1 -1
- package/dist/types/src/core/plugin.d.ts +89 -91
- package/dist/types/src/core/plugin.d.ts.map +1 -1
- package/dist/types/src/core/registry.d.ts +17 -57
- package/dist/types/src/core/registry.d.ts.map +1 -1
- package/dist/types/src/core/url-loader.d.ts +2 -2
- package/dist/types/src/core/url-loader.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/plugin-process-manager/history/capability.d.ts +1 -3
- package/dist/types/src/plugin-process-manager/history/capability.d.ts.map +1 -1
- package/dist/types/src/plugin-process-manager/meta.d.ts +32 -2
- package/dist/types/src/plugin-process-manager/meta.d.ts.map +1 -1
- package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts +1 -4
- package/dist/types/src/plugin-process-manager/process-manager-capability.d.ts.map +1 -1
- package/dist/types/src/testing/harness.d.ts +1 -1
- package/dist/types/src/testing/harness.d.ts.map +1 -1
- package/dist/types/src/testing/react.d.ts +6 -5
- package/dist/types/src/testing/react.d.ts.map +1 -1
- package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
- package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/App/App.stories.d.ts +2 -2
- package/dist/types/src/ui/components/App/App.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts +6 -0
- package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts +6 -10
- package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceProfilerContext.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/context.d.ts +6 -2
- package/dist/types/src/ui/components/Surface/context.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/index.d.ts +11 -4
- package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/types.d.ts +52 -72
- package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -1
- package/dist/types/src/ui/hooks/useApp.d.ts +1 -1
- package/dist/types/src/ui/hooks/useCapabilities.d.ts +17 -1
- package/dist/types/src/ui/hooks/useCapabilities.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/composer/index.d.ts +11 -4
- package/dist/types/src/vite-plugin/composer/index.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/import-map/index.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/index.d.ts +1 -0
- package/dist/types/src/vite-plugin/index.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/load.d.ts +16 -0
- package/dist/types/src/vite-plugin/load.d.ts.map +1 -0
- package/dist/types/src/vite-plugin/manifest.d.ts +16 -4
- package/dist/types/src/vite-plugin/manifest.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/packages.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/docs/registry-spec.md +331 -0
- package/moon.yml +1 -0
- package/package.json +50 -39
- package/src/cli/cli.ts +2 -2
- package/src/common/activation-events.ts +3 -3
- package/src/common/capabilities.ts +18 -18
- package/src/config/index.ts +5 -0
- package/src/core/activation-event.ts +15 -8
- package/src/core/capability.ts +18 -6
- package/src/core/edge-registry-plugin-provider.ts +41 -42
- package/src/core/plugin-manager.test.ts +133 -137
- package/src/core/plugin-manager.ts +25 -19
- package/src/core/plugin-manifest.test.ts +5 -5
- package/src/core/plugin-manifest.ts +13 -10
- package/src/core/plugin.ts +58 -114
- package/src/core/registry.ts +20 -60
- package/src/core/url-loader.test.ts +2 -2
- package/src/core/url-loader.ts +23 -19
- package/src/index.ts +1 -0
- package/src/testing/harness.ts +5 -3
- package/src/testing/react.test.tsx +4 -2
- package/src/testing/react.tsx +10 -9
- package/src/testing/service.ts +2 -2
- package/src/testing/withPluginManager.stories.tsx +4 -2
- package/src/testing/withPluginManager.tsx +3 -1
- package/src/ui/components/App/App.stories.tsx +2 -2
- package/src/ui/components/PluginManager/PluginManagerProvider.ts +7 -0
- package/src/ui/components/Surface/SurfaceComponent.stories.tsx +22 -22
- package/src/ui/components/Surface/SurfaceComponent.tsx +90 -79
- package/src/ui/components/Surface/SurfaceProfilerContext.tsx +1 -1
- package/src/ui/components/Surface/context.ts +6 -4
- package/src/ui/components/Surface/index.ts +14 -3
- package/src/ui/components/Surface/types.test.ts +43 -51
- package/src/ui/components/Surface/types.ts +99 -64
- package/src/ui/hooks/useApp.test.tsx +1 -1
- package/src/ui/hooks/useApp.tsx +2 -2
- package/src/ui/hooks/useCapabilities.ts +49 -2
- package/src/vite-plugin/boot-loader/BootLoader.solid-stories.tsx +11 -11
- package/src/vite-plugin/boot-loader/loader.ts +3 -3
- package/src/vite-plugin/composer/index.ts +134 -61
- package/src/vite-plugin/import-map/index.ts +23 -7
- package/src/vite-plugin/index.ts +1 -0
- package/src/vite-plugin/load.ts +57 -0
- package/src/vite-plugin/manifest.test.ts +3 -3
- package/src/vite-plugin/manifest.ts +21 -10
- package/src/vite-plugin/packages.ts +0 -2
- package/tsconfig.json +5 -2
- package/dist/lib/browser/chunk-5GY3YOEL.mjs.map +0 -7
- package/dist/lib/browser/chunk-66IXTIVK.mjs.map +0 -7
- package/dist/lib/browser/chunk-CO3XLNUX.mjs.map +0 -7
- package/dist/lib/browser/chunk-DC3WRPBV.mjs.map +0 -7
- package/dist/lib/browser/chunk-FO3IYSLV.mjs.map +0 -7
- package/dist/lib/browser/chunk-HFLKXMT7.mjs.map +0 -7
- package/dist/lib/browser/chunk-IW44C7UL.mjs.map +0 -7
- package/dist/lib/browser/chunk-KZUDO43J.mjs.map +0 -7
- package/dist/lib/browser/chunk-XHS5KDNX.mjs.map +0 -7
- package/dist/lib/browser/chunk-Y66ELD4U.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-A5CHGAZE.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-CTKEZHKF.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-FSVGKTF6.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-KFZEB6BV.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-NULBHQYS.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-SX5NVETP.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-WK7OIQKI.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XGBUKRCK.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XIGPWXCQ.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XOCUANHO.mjs.map +0 -7
- /package/dist/lib/browser/{capability-BOPAKKWG.mjs.map → capability-S44TE2H7.mjs.map} +0 -0
- /package/dist/lib/browser/{process-manager-capability-GXNUO7AR.mjs.map → process-manager-capability-QK4BMKMN.mjs.map} +0 -0
- /package/dist/lib/node-esm/{capability-KZWRTX7R.mjs.map → capability-3YRF77LV.mjs.map} +0 -0
- /package/dist/lib/node-esm/{process-manager-capability-TX5TA6YN.mjs.map → process-manager-capability-5S7WZ2JR.mjs.map} +0 -0
|
@@ -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) => {
|
|
@@ -43,6 +43,7 @@ import { createContext, useContext } from "react";
|
|
|
43
43
|
import { raise } from "@dxos/debug";
|
|
44
44
|
var PluginManagerContext = createContext(void 0);
|
|
45
45
|
var usePluginManager = () => useContext(PluginManagerContext) ?? raise(new Error("Missing PluginManagerContext"));
|
|
46
|
+
var useOptionalPluginManager = () => useContext(PluginManagerContext);
|
|
46
47
|
var PluginManagerProvider = PluginManagerContext.Provider;
|
|
47
48
|
|
|
48
49
|
// src/ui/components/Surface/context.ts
|
|
@@ -55,7 +56,7 @@ import React3, { Fragment, Profiler, Suspense, forwardRef as forwardRef2, memo,
|
|
|
55
56
|
import { log } from "@dxos/log";
|
|
56
57
|
import { ErrorBoundary } from "@dxos/react-error-boundary";
|
|
57
58
|
import { useDefaultValue } from "@dxos/react-hooks";
|
|
58
|
-
import {
|
|
59
|
+
import { Position } from "@dxos/util";
|
|
59
60
|
|
|
60
61
|
// src/ui/components/Surface/SurfaceInfo.tsx
|
|
61
62
|
import React, { cloneElement, forwardRef, useCallback, useLayoutEffect, useState } from "react";
|
|
@@ -264,7 +265,7 @@ var emptySnapshot = () => EMPTY_SNAPSHOT;
|
|
|
264
265
|
|
|
265
266
|
// src/ui/components/Surface/SurfaceComponent.tsx
|
|
266
267
|
var __dxlog_file = "/__w/dxos/dxos/packages/sdk/app-framework/src/ui/components/Surface/SurfaceComponent.tsx";
|
|
267
|
-
var DEBUG = import.meta.env
|
|
268
|
+
var DEBUG = import.meta.env?.VITE_DEBUG;
|
|
268
269
|
var DEFAULT_PLACEHOLDER = /* @__PURE__ */ React3.createElement(Fragment, null);
|
|
269
270
|
var WebComponentWrapper = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef2(({ id, role, data, limit, definition, ...rest }, forwardedRef) => {
|
|
270
271
|
const containerRef = useRef2(null);
|
|
@@ -410,15 +411,15 @@ var SurfaceContextProvider = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef2(({
|
|
|
410
411
|
}))));
|
|
411
412
|
}));
|
|
412
413
|
SurfaceContextProvider.displayName = "SurfaceContextProvider";
|
|
413
|
-
var SurfaceComponent = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef2(({ id: _id,
|
|
414
|
+
var SurfaceComponent = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef2(({ id: _id, type, data: dataProp, limit, placeholder = DEFAULT_PLACEHOLDER, ...rest }, forwardedRef) => {
|
|
414
415
|
const data = useDefaultValue(dataProp, () => ({}));
|
|
415
416
|
const surfaces = useSurfaces();
|
|
416
|
-
const effectiveRole =
|
|
417
|
+
const effectiveRole = type?.role;
|
|
417
418
|
if (effectiveRole == null) {
|
|
418
419
|
if (DEBUG) {
|
|
419
|
-
log.warn("Surface
|
|
420
|
+
log.warn("Surface is missing required `type` prop", {
|
|
420
421
|
id: _id
|
|
421
|
-
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L:
|
|
422
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 193, S: void 0 });
|
|
422
423
|
}
|
|
423
424
|
return null;
|
|
424
425
|
}
|
|
@@ -431,7 +432,7 @@ var SurfaceComponent = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef2(({ id: _
|
|
|
431
432
|
log.warn("no candidates for surface", {
|
|
432
433
|
role: effectiveRole,
|
|
433
434
|
data
|
|
434
|
-
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L:
|
|
435
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 206, S: void 0 });
|
|
435
436
|
return null;
|
|
436
437
|
}
|
|
437
438
|
return /* @__PURE__ */ React3.createElement(Suspense, {
|
|
@@ -460,14 +461,14 @@ var ErrorFallback = ({ error }) => {
|
|
|
460
461
|
}, message));
|
|
461
462
|
};
|
|
462
463
|
var findCandidates = (surfaces, { role, data }) => {
|
|
463
|
-
return Object.values(surfaces).filter((definition) => Array.isArray(definition.role) ? definition.role.includes(role) : definition.role === role).filter(({ filter }) => filter ? filter(data ?? {}, role) : true).toSorted(
|
|
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);
|
|
464
465
|
};
|
|
465
466
|
var useSurfaces = () => {
|
|
466
467
|
const manager = usePluginManager();
|
|
467
468
|
const surfacesByModule = useAtomValue(manager.capabilities.atomByModule(capabilities_exports.ReactSurface));
|
|
468
469
|
return useMemo2(() => {
|
|
469
470
|
const result = [];
|
|
470
|
-
for (const [
|
|
471
|
+
for (const [_moduleId, surfaces] of Object.entries(surfacesByModule)) {
|
|
471
472
|
for (const def of surfaces.flat()) {
|
|
472
473
|
result.push(def);
|
|
473
474
|
}
|
|
@@ -477,24 +478,49 @@ var useSurfaces = () => {
|
|
|
477
478
|
surfacesByModule
|
|
478
479
|
]);
|
|
479
480
|
};
|
|
480
|
-
function isSurfaceAvailable(capabilityManager,
|
|
481
|
-
const effectiveRole =
|
|
481
|
+
function isSurfaceAvailable(capabilityManager, args) {
|
|
482
|
+
const effectiveRole = args.type?.role;
|
|
482
483
|
if (effectiveRole == null) {
|
|
483
484
|
return false;
|
|
484
485
|
}
|
|
485
486
|
const surfaces = capabilityManager.getAll(capabilities_exports.ReactSurface);
|
|
486
487
|
const candidates = findCandidates(surfaces.flat(), {
|
|
487
488
|
role: effectiveRole,
|
|
488
|
-
data
|
|
489
|
+
data: args.data
|
|
489
490
|
});
|
|
490
491
|
return candidates.length > 0;
|
|
491
492
|
}
|
|
492
493
|
|
|
493
494
|
// src/ui/components/Surface/types.ts
|
|
495
|
+
import { log as log2 } from "@dxos/log";
|
|
496
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/sdk/app-framework/src/ui/components/Surface/types.ts";
|
|
494
497
|
var isSurfaceFilter = (value) => typeof value === "object" && value !== null && Array.isArray(value.bindings);
|
|
495
|
-
var makeType = (
|
|
496
|
-
|
|
497
|
-
});
|
|
498
|
+
var makeType = (nsid) => {
|
|
499
|
+
if (typeof nsid !== "string" || !/^[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(\.[a-zA-Z][a-zA-Z0-9]{0,62})$/.test(nsid)) {
|
|
500
|
+
throw new Error(`Invalid role NSID: "${nsid}". Must be a dotted name with a camelCase final segment (no hyphens in the last segment).`);
|
|
501
|
+
}
|
|
502
|
+
return {
|
|
503
|
+
role: nsid
|
|
504
|
+
};
|
|
505
|
+
};
|
|
506
|
+
var makeFilter = (token, guard) => {
|
|
507
|
+
const boundGuard = guard == null ? () => true : (data) => {
|
|
508
|
+
try {
|
|
509
|
+
return guard(data);
|
|
510
|
+
} catch (err) {
|
|
511
|
+
log2.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 39, S: void 0 });
|
|
512
|
+
return false;
|
|
513
|
+
}
|
|
514
|
+
};
|
|
515
|
+
return {
|
|
516
|
+
bindings: [
|
|
517
|
+
{
|
|
518
|
+
role: token.role,
|
|
519
|
+
guard: boundGuard
|
|
520
|
+
}
|
|
521
|
+
]
|
|
522
|
+
};
|
|
523
|
+
};
|
|
498
524
|
var expandBindings = (filter) => {
|
|
499
525
|
const bindings = filter.bindings;
|
|
500
526
|
const roles = Array.from(new Set(bindings.map((binding) => binding.role)));
|
|
@@ -518,40 +544,28 @@ var validateLocalId = (id) => {
|
|
|
518
544
|
};
|
|
519
545
|
function create(definition) {
|
|
520
546
|
validateLocalId(definition.id);
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
const { role, guard } = expandBindings(filter);
|
|
524
|
-
return {
|
|
525
|
-
kind: "react",
|
|
526
|
-
id,
|
|
527
|
-
role,
|
|
528
|
-
position,
|
|
529
|
-
component,
|
|
530
|
-
filter: guard
|
|
531
|
-
};
|
|
532
|
-
}
|
|
547
|
+
const { id, filter, component, position } = definition;
|
|
548
|
+
const { role, guard } = expandBindings(filter);
|
|
533
549
|
return {
|
|
534
|
-
|
|
535
|
-
|
|
550
|
+
kind: "react",
|
|
551
|
+
id,
|
|
552
|
+
role,
|
|
553
|
+
position,
|
|
554
|
+
component,
|
|
555
|
+
filter: guard
|
|
536
556
|
};
|
|
537
557
|
}
|
|
538
558
|
function createWeb(definition) {
|
|
539
559
|
validateLocalId(definition.id);
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
const { role, guard } = expandBindings(filter);
|
|
543
|
-
return {
|
|
544
|
-
kind: "web-component",
|
|
545
|
-
id,
|
|
546
|
-
role,
|
|
547
|
-
position,
|
|
548
|
-
tagName,
|
|
549
|
-
filter: guard
|
|
550
|
-
};
|
|
551
|
-
}
|
|
560
|
+
const { id, filter, tagName, position } = definition;
|
|
561
|
+
const { role, guard } = expandBindings(filter);
|
|
552
562
|
return {
|
|
553
|
-
|
|
554
|
-
|
|
563
|
+
kind: "web-component",
|
|
564
|
+
id,
|
|
565
|
+
role,
|
|
566
|
+
position,
|
|
567
|
+
tagName,
|
|
568
|
+
filter: guard
|
|
555
569
|
};
|
|
556
570
|
}
|
|
557
571
|
|
|
@@ -563,6 +577,7 @@ function createWeb(definition) {
|
|
|
563
577
|
Surface2.Surface = SurfaceComponent;
|
|
564
578
|
Surface2.isAvailable = isSurfaceAvailable;
|
|
565
579
|
Surface2.makeType = makeType;
|
|
580
|
+
Surface2.makeFilter = makeFilter;
|
|
566
581
|
Surface2.isFilter = isSurfaceFilter;
|
|
567
582
|
Surface2.ProfilerProvider = SurfaceProfilerProvider;
|
|
568
583
|
Surface2.useProfilerCallback = useSurfaceProfilerCallback;
|
|
@@ -581,8 +596,9 @@ export {
|
|
|
581
596
|
topologicalSort,
|
|
582
597
|
useSurface,
|
|
583
598
|
usePluginManager,
|
|
599
|
+
useOptionalPluginManager,
|
|
584
600
|
PluginManagerProvider,
|
|
585
601
|
SurfaceComponent,
|
|
586
602
|
Surface
|
|
587
603
|
};
|
|
588
|
-
//# 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";
|
|
@@ -56,26 +56,34 @@ import * as HttpClientResponse from "@effect/platform/HttpClientResponse";
|
|
|
56
56
|
import * as Effect2 from "effect/Effect";
|
|
57
57
|
import * as Schema from "effect/Schema";
|
|
58
58
|
import { BaseError as BaseError2 } from "@dxos/errors";
|
|
59
|
-
import { PLUGIN_ENTRY_FILENAME } from "@dxos/protocols";
|
|
59
|
+
import { PLUGIN_ENTRY_FILENAME, PluginManifestSchema } from "@dxos/protocols";
|
|
60
60
|
var PLUGIN_DEV_SERVER_PORT = 3967;
|
|
61
61
|
var PluginManifestError = class extends BaseError2.extend("PluginManifestError", "Plugin manifest is invalid") {
|
|
62
62
|
};
|
|
63
63
|
var Manifest = Schema.Struct({
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
// Reuse the build manifest field definitions from `@dxos/protocols` (the shape `composerPlugin`
|
|
65
|
+
// emits), minus `assets` which we relax below, plus the dev-only `devEntry`.
|
|
66
|
+
...PluginManifestSchema.omit("assets").fields,
|
|
67
|
+
/**
|
|
68
|
+
* Relative asset paths. Relaxed vs the build `PluginManifestSchema` (which requires >= 1) because
|
|
69
|
+
* dev-server manifests list no assets — chunks/styles flow through the dev server on demand.
|
|
70
|
+
*/
|
|
67
71
|
assets: Schema.Array(Schema.String),
|
|
68
|
-
|
|
72
|
+
/** Present only for dev-server manifests; points at the unbundled source entry. */
|
|
73
|
+
devEntry: Schema.optional(Schema.String)
|
|
69
74
|
});
|
|
70
75
|
var resolve = (manifestUrl, manifest) => {
|
|
71
76
|
const dev = manifest.devEntry !== void 0;
|
|
72
77
|
return {
|
|
73
|
-
|
|
78
|
+
key: manifest.key,
|
|
74
79
|
name: manifest.name,
|
|
75
80
|
version: manifest.version,
|
|
76
81
|
entryUrl: new URL(dev ? manifest.devEntry : PLUGIN_ENTRY_FILENAME, manifestUrl).toString(),
|
|
77
82
|
assetUrls: manifest.assets.map((asset) => new URL(asset, manifestUrl).toString()),
|
|
78
|
-
dev
|
|
83
|
+
dev,
|
|
84
|
+
...manifest.dependencies !== void 0 ? {
|
|
85
|
+
dependencies: manifest.dependencies
|
|
86
|
+
} : {}
|
|
79
87
|
};
|
|
80
88
|
};
|
|
81
89
|
var parse = (manifestUrl, payload) => {
|
|
@@ -136,7 +144,7 @@ var getPersistedRemotePlugins = (storage, key) => {
|
|
|
136
144
|
if (!Array.isArray(parsed)) {
|
|
137
145
|
return [];
|
|
138
146
|
}
|
|
139
|
-
return parsed.filter((entry) => typeof entry === "object" && entry !== null && typeof entry.id === "string" && typeof entry.url === "string");
|
|
147
|
+
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"));
|
|
140
148
|
} catch {
|
|
141
149
|
return [];
|
|
142
150
|
}
|
|
@@ -231,14 +239,14 @@ var loadStylesheets = (manifest, cache) => Effect3.gen(function* () {
|
|
|
231
239
|
}
|
|
232
240
|
const cssUrls = manifest.assetUrls.filter((url) => url.endsWith(".css"));
|
|
233
241
|
for (const url of cssUrls) {
|
|
234
|
-
const resolved = yield* cache.resolve(manifest.
|
|
235
|
-
if (document.querySelector(`link[data-dxos-plugin-id="${manifest.
|
|
242
|
+
const resolved = yield* cache.resolve(manifest.key, url);
|
|
243
|
+
if (document.querySelector(`link[data-dxos-plugin-id="${manifest.key}"][href="${resolved}"]`)) {
|
|
236
244
|
continue;
|
|
237
245
|
}
|
|
238
246
|
const link = document.createElement("link");
|
|
239
247
|
link.rel = "stylesheet";
|
|
240
248
|
link.href = resolved;
|
|
241
|
-
link.dataset.dxosPluginId = manifest.
|
|
249
|
+
link.dataset.dxosPluginId = manifest.key;
|
|
242
250
|
document.head.appendChild(link);
|
|
243
251
|
}
|
|
244
252
|
});
|
|
@@ -265,9 +273,9 @@ var loadFromManifest = (manifestUrl, cache) => Effect3.gen(function* () {
|
|
|
265
273
|
manifestUrl,
|
|
266
274
|
...manifest.assetUrls
|
|
267
275
|
] : manifest.assetUrls;
|
|
268
|
-
yield* cache.cache(manifest.
|
|
276
|
+
yield* cache.cache(manifest.key, cachedUrls).pipe(wrapCacheError);
|
|
269
277
|
}
|
|
270
|
-
const entryUrl = manifest.dev ? manifest.entryUrl : yield* cache.resolve(manifest.
|
|
278
|
+
const entryUrl = manifest.dev ? manifest.entryUrl : yield* cache.resolve(manifest.key, manifest.entryUrl).pipe(wrapCacheError);
|
|
271
279
|
const mod = yield* Effect3.tryPromise({
|
|
272
280
|
try: () => import(
|
|
273
281
|
/* @vite-ignore */
|
|
@@ -282,7 +290,7 @@ var loadFromManifest = (manifestUrl, cache) => Effect3.gen(function* () {
|
|
|
282
290
|
})
|
|
283
291
|
});
|
|
284
292
|
const plugin = normalizePluginExport(mod);
|
|
285
|
-
if (!plugin.meta.
|
|
293
|
+
if (!plugin.meta.profile.key || !plugin.meta.profile.name) {
|
|
286
294
|
return yield* Effect3.fail(new RemotePluginLoadError({
|
|
287
295
|
context: {
|
|
288
296
|
locator: manifestUrl,
|
|
@@ -290,13 +298,13 @@ var loadFromManifest = (manifestUrl, cache) => Effect3.gen(function* () {
|
|
|
290
298
|
}
|
|
291
299
|
}));
|
|
292
300
|
}
|
|
293
|
-
if (plugin.meta.
|
|
301
|
+
if (plugin.meta.profile.key !== manifest.key) {
|
|
294
302
|
return yield* Effect3.fail(new RemotePluginLoadError({
|
|
295
303
|
context: {
|
|
296
304
|
locator: manifestUrl,
|
|
297
305
|
reason: "meta-mismatch",
|
|
298
|
-
metaId: plugin.meta.
|
|
299
|
-
manifestId: manifest.
|
|
306
|
+
metaId: plugin.meta.profile.key,
|
|
307
|
+
manifestId: manifest.key
|
|
300
308
|
}
|
|
301
309
|
}));
|
|
302
310
|
}
|
|
@@ -355,7 +363,7 @@ var make = (builtinPlugins, options = {}) => {
|
|
|
355
363
|
const key = options.key ?? DEFAULT_KEY;
|
|
356
364
|
const cache = options.cache ?? noop();
|
|
357
365
|
return (locator) => Effect3.gen(function* () {
|
|
358
|
-
const builtin = builtinPlugins.find((plugin2) => plugin2.meta.
|
|
366
|
+
const builtin = builtinPlugins.find((plugin2) => plugin2.meta.profile.key === locator);
|
|
359
367
|
if (builtin) {
|
|
360
368
|
return {
|
|
361
369
|
plugin: builtin
|
|
@@ -371,18 +379,18 @@ var make = (builtinPlugins, options = {}) => {
|
|
|
371
379
|
}
|
|
372
380
|
const { plugin, manifest } = yield* loadFromManifest(locator, cache);
|
|
373
381
|
if (!manifest.dev) {
|
|
374
|
-
const duplicate = builtinPlugins.find((existing) => existing.meta.
|
|
382
|
+
const duplicate = builtinPlugins.find((existing) => existing.meta.profile.key === plugin.meta.profile.key);
|
|
375
383
|
if (duplicate) {
|
|
376
384
|
return yield* Effect3.fail(new RemotePluginLoadError({
|
|
377
385
|
context: {
|
|
378
386
|
locator,
|
|
379
387
|
reason: "duplicate-id",
|
|
380
|
-
id: plugin.meta.
|
|
388
|
+
id: plugin.meta.profile.key
|
|
381
389
|
}
|
|
382
390
|
}));
|
|
383
391
|
}
|
|
384
392
|
persistRemotePlugin(storage, key, {
|
|
385
|
-
id: plugin.meta.
|
|
393
|
+
id: plugin.meta.profile.key,
|
|
386
394
|
url: locator
|
|
387
395
|
});
|
|
388
396
|
}
|
|
@@ -420,4 +428,4 @@ export {
|
|
|
420
428
|
uninstall,
|
|
421
429
|
url_loader_exports
|
|
422
430
|
};
|
|
423
|
-
//# sourceMappingURL=chunk-
|
|
431
|
+
//# sourceMappingURL=chunk-FKMVORZN.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
|
+
}
|