@dxos/app-framework 0.8.4-staging.60fe92afc8 → 0.9.1-main.c7dcc2e112
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/{capability-BOPAKKWG.mjs → capability-Z4MRP3CP.mjs} +9 -9
- package/dist/lib/browser/{chunk-CO3XLNUX.mjs → chunk-37PG7XJC.mjs} +18 -18
- package/dist/lib/browser/chunk-37PG7XJC.mjs.map +7 -0
- package/dist/lib/browser/{chunk-66IXTIVK.mjs → chunk-3NQLTQCP.mjs} +6 -7
- package/dist/lib/browser/chunk-3NQLTQCP.mjs.map +7 -0
- package/dist/lib/browser/{chunk-KZUDO43J.mjs → chunk-3UTDRCKX.mjs} +31 -23
- package/dist/lib/browser/chunk-3UTDRCKX.mjs.map +7 -0
- package/dist/lib/browser/chunk-53HJHMS5.mjs +7 -0
- package/dist/lib/browser/chunk-53HJHMS5.mjs.map +7 -0
- package/dist/lib/browser/{chunk-IW44C7UL.mjs → chunk-CMINFVA5.mjs} +1 -1
- package/dist/lib/browser/chunk-CMINFVA5.mjs.map +7 -0
- package/dist/lib/browser/{chunk-Y66ELD4U.mjs → chunk-DFVSOBV2.mjs} +17 -7
- package/dist/lib/browser/chunk-DFVSOBV2.mjs.map +7 -0
- package/dist/lib/browser/{chunk-DC3WRPBV.mjs → chunk-S2ZBYQPI.mjs} +45 -12
- package/dist/lib/browser/chunk-S2ZBYQPI.mjs.map +7 -0
- package/dist/lib/browser/{chunk-HFLKXMT7.mjs → chunk-SWECIICH.mjs} +57 -41
- package/dist/lib/browser/chunk-SWECIICH.mjs.map +7 -0
- package/dist/lib/browser/{chunk-5GY3YOEL.mjs → chunk-VF37YTXJ.mjs} +5 -5
- package/dist/lib/browser/chunk-VF37YTXJ.mjs.map +7 -0
- package/dist/lib/browser/{chunk-XHS5KDNX.mjs → chunk-W4BHZING.mjs} +25 -25
- package/dist/lib/browser/chunk-W4BHZING.mjs.map +7 -0
- package/dist/lib/browser/{chunk-FO3IYSLV.mjs → chunk-YUVQIOTB.mjs} +29 -37
- package/dist/lib/browser/chunk-YUVQIOTB.mjs.map +7 -0
- package/dist/lib/browser/cli/index.mjs +9 -9
- package/dist/lib/browser/cli/index.mjs.map +2 -2
- package/dist/lib/browser/common/activation-events.mjs +7 -7
- package/dist/lib/browser/common/capabilities.mjs +7 -7
- package/dist/lib/browser/config/index.mjs +8 -0
- package/dist/lib/browser/config/index.mjs.map +7 -0
- package/dist/lib/browser/core/activation-event.mjs +1 -1
- package/dist/lib/browser/core/capability.mjs +1 -1
- package/dist/lib/browser/core/plugin-manager.mjs +4 -4
- package/dist/lib/browser/core/plugin.mjs +12 -2
- package/dist/lib/browser/core/url-loader.mjs +3 -3
- package/dist/lib/browser/index.mjs +14 -10
- package/dist/lib/browser/index.mjs.map +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{process-manager-capability-GXNUO7AR.mjs → process-manager-capability-RDROCCQD.mjs} +9 -9
- package/dist/lib/browser/testing/index.mjs +15 -15
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/testing/react.mjs +11 -11
- package/dist/lib/browser/testing/react.mjs.map +3 -3
- package/dist/lib/browser/ui/index.mjs +16 -10
- package/dist/lib/node-esm/{capability-KZWRTX7R.mjs → capability-34Z6NPVR.mjs} +9 -9
- package/dist/lib/node-esm/chunk-2UPUZXGU.mjs +9 -0
- package/dist/lib/node-esm/chunk-2UPUZXGU.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-FSVGKTF6.mjs → chunk-A4O42ZO3.mjs} +17 -7
- package/dist/lib/node-esm/chunk-A4O42ZO3.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-CTKEZHKF.mjs → chunk-AIDZMJ3U.mjs} +1 -1
- package/dist/lib/node-esm/chunk-AIDZMJ3U.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-XOCUANHO.mjs → chunk-BMW6P6QA.mjs} +6 -7
- package/dist/lib/node-esm/chunk-BMW6P6QA.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-A5CHGAZE.mjs → chunk-H7T7XXLS.mjs} +57 -41
- package/dist/lib/node-esm/chunk-H7T7XXLS.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-NULBHQYS.mjs → chunk-LUK3FCTH.mjs} +18 -18
- package/dist/lib/node-esm/chunk-LUK3FCTH.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-XGBUKRCK.mjs → chunk-TEQSMP2O.mjs} +31 -23
- package/dist/lib/node-esm/chunk-TEQSMP2O.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-KFZEB6BV.mjs → chunk-TLKYZKPW.mjs} +5 -5
- package/dist/lib/node-esm/chunk-TLKYZKPW.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-WK7OIQKI.mjs → chunk-VCPGX7WN.mjs} +29 -37
- package/dist/lib/node-esm/chunk-VCPGX7WN.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-XIGPWXCQ.mjs → chunk-WERVO5EK.mjs} +45 -12
- package/dist/lib/node-esm/chunk-WERVO5EK.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-SX5NVETP.mjs → chunk-ZRTG4TSS.mjs} +25 -25
- package/dist/lib/node-esm/chunk-ZRTG4TSS.mjs.map +7 -0
- package/dist/lib/node-esm/cli/index.mjs +9 -9
- package/dist/lib/node-esm/cli/index.mjs.map +2 -2
- package/dist/lib/node-esm/common/activation-events.mjs +7 -7
- package/dist/lib/node-esm/common/capabilities.mjs +7 -7
- package/dist/lib/node-esm/config/index.mjs +9 -0
- package/dist/lib/node-esm/config/index.mjs.map +7 -0
- package/dist/lib/node-esm/core/activation-event.mjs +1 -1
- package/dist/lib/node-esm/core/capability.mjs +1 -1
- package/dist/lib/node-esm/core/plugin-manager.mjs +4 -4
- package/dist/lib/node-esm/core/plugin.mjs +12 -2
- package/dist/lib/node-esm/core/url-loader.mjs +3 -3
- package/dist/lib/node-esm/index.mjs +14 -10
- package/dist/lib/node-esm/index.mjs.map +1 -1
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{process-manager-capability-TX5TA6YN.mjs → process-manager-capability-6OCXSKUW.mjs} +9 -9
- package/dist/lib/node-esm/testing/index.mjs +15 -15
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/testing/react.mjs +11 -11
- package/dist/lib/node-esm/testing/react.mjs.map +3 -3
- package/dist/lib/node-esm/ui/index.mjs +16 -10
- package/dist/plugin/node-esm/index.mjs +406 -71
- package/dist/plugin/node-esm/index.mjs.map +4 -4
- package/dist/plugin/node-esm/meta.json +1 -1
- package/dist/types/src/cli/cli.d.ts +1 -1
- package/dist/types/src/common/activation-events.d.ts.map +1 -1
- package/dist/types/src/common/capabilities.d.ts.map +1 -1
- package/dist/types/src/config/index.d.ts +2 -0
- package/dist/types/src/config/index.d.ts.map +1 -0
- package/dist/types/src/core/activation-event.d.ts +9 -6
- package/dist/types/src/core/activation-event.d.ts.map +1 -1
- package/dist/types/src/core/capability.d.ts +6 -2
- package/dist/types/src/core/capability.d.ts.map +1 -1
- package/dist/types/src/core/edge-registry-plugin-provider.d.ts +6 -11
- package/dist/types/src/core/edge-registry-plugin-provider.d.ts.map +1 -1
- package/dist/types/src/core/plugin-manager.d.ts.map +1 -1
- package/dist/types/src/core/plugin-manifest.d.ts +25 -7
- package/dist/types/src/core/plugin-manifest.d.ts.map +1 -1
- package/dist/types/src/core/plugin.d.ts +81 -91
- package/dist/types/src/core/plugin.d.ts.map +1 -1
- package/dist/types/src/core/registry.d.ts +17 -57
- package/dist/types/src/core/registry.d.ts.map +1 -1
- package/dist/types/src/core/url-loader.d.ts +2 -2
- package/dist/types/src/core/url-loader.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/plugin-process-manager/meta.d.ts +28 -2
- package/dist/types/src/plugin-process-manager/meta.d.ts.map +1 -1
- package/dist/types/src/testing/harness.d.ts +1 -1
- package/dist/types/src/testing/harness.d.ts.map +1 -1
- package/dist/types/src/testing/react.d.ts +6 -5
- package/dist/types/src/testing/react.d.ts.map +1 -1
- package/dist/types/src/testing/withPluginManager.d.ts.map +1 -1
- package/dist/types/src/testing/withPluginManager.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts +6 -0
- package/dist/types/src/ui/components/PluginManager/PluginManagerProvider.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts +6 -10
- package/dist/types/src/ui/components/Surface/SurfaceComponent.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/SurfaceComponent.stories.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/context.d.ts +6 -2
- package/dist/types/src/ui/components/Surface/context.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/index.d.ts +10 -3
- package/dist/types/src/ui/components/Surface/index.d.ts.map +1 -1
- package/dist/types/src/ui/components/Surface/types.d.ts +50 -70
- package/dist/types/src/ui/components/Surface/types.d.ts.map +1 -1
- package/dist/types/src/ui/hooks/useApp.d.ts +1 -1
- package/dist/types/src/ui/hooks/useCapabilities.d.ts +11 -1
- package/dist/types/src/ui/hooks/useCapabilities.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/composer/index.d.ts +11 -4
- package/dist/types/src/vite-plugin/composer/index.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/index.d.ts +1 -0
- package/dist/types/src/vite-plugin/index.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/load.d.ts +16 -0
- package/dist/types/src/vite-plugin/load.d.ts.map +1 -0
- package/dist/types/src/vite-plugin/manifest.d.ts +16 -4
- package/dist/types/src/vite-plugin/manifest.d.ts.map +1 -1
- package/dist/types/src/vite-plugin/packages.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/docs/registry-spec.md +331 -0
- package/moon.yml +1 -0
- package/package.json +32 -27
- package/src/cli/cli.ts +2 -2
- package/src/common/activation-events.ts +3 -3
- package/src/common/capabilities.ts +16 -16
- package/src/config/index.ts +5 -0
- package/src/core/activation-event.ts +15 -8
- package/src/core/capability.ts +15 -4
- package/src/core/edge-registry-plugin-provider.ts +41 -42
- package/src/core/plugin-manager.test.ts +133 -137
- package/src/core/plugin-manager.ts +25 -19
- package/src/core/plugin-manifest.test.ts +5 -5
- package/src/core/plugin-manifest.ts +13 -10
- package/src/core/plugin.ts +58 -114
- package/src/core/registry.ts +20 -60
- package/src/core/url-loader.test.ts +2 -2
- package/src/core/url-loader.ts +23 -19
- package/src/index.ts +1 -0
- package/src/testing/harness.ts +5 -3
- package/src/testing/react.test.tsx +4 -2
- package/src/testing/react.tsx +9 -8
- package/src/testing/service.ts +2 -2
- package/src/testing/withPluginManager.stories.tsx +4 -2
- package/src/testing/withPluginManager.tsx +3 -1
- package/src/ui/components/PluginManager/PluginManagerProvider.ts +7 -0
- package/src/ui/components/Surface/SurfaceComponent.stories.tsx +11 -14
- package/src/ui/components/Surface/SurfaceComponent.tsx +84 -74
- package/src/ui/components/Surface/context.ts +6 -3
- package/src/ui/components/Surface/index.ts +12 -1
- package/src/ui/components/Surface/types.test.ts +39 -49
- package/src/ui/components/Surface/types.ts +95 -60
- package/src/ui/hooks/useApp.test.tsx +1 -1
- package/src/ui/hooks/useApp.tsx +2 -2
- package/src/ui/hooks/useCapabilities.ts +24 -2
- package/src/vite-plugin/composer/index.ts +134 -61
- package/src/vite-plugin/index.ts +1 -0
- package/src/vite-plugin/load.ts +57 -0
- package/src/vite-plugin/manifest.test.ts +3 -3
- package/src/vite-plugin/manifest.ts +21 -10
- package/src/vite-plugin/packages.ts +0 -1
- package/dist/lib/browser/chunk-5GY3YOEL.mjs.map +0 -7
- package/dist/lib/browser/chunk-66IXTIVK.mjs.map +0 -7
- package/dist/lib/browser/chunk-CO3XLNUX.mjs.map +0 -7
- package/dist/lib/browser/chunk-DC3WRPBV.mjs.map +0 -7
- package/dist/lib/browser/chunk-FO3IYSLV.mjs.map +0 -7
- package/dist/lib/browser/chunk-HFLKXMT7.mjs.map +0 -7
- package/dist/lib/browser/chunk-IW44C7UL.mjs.map +0 -7
- package/dist/lib/browser/chunk-KZUDO43J.mjs.map +0 -7
- package/dist/lib/browser/chunk-XHS5KDNX.mjs.map +0 -7
- package/dist/lib/browser/chunk-Y66ELD4U.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-A5CHGAZE.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-CTKEZHKF.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-FSVGKTF6.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-KFZEB6BV.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-NULBHQYS.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-SX5NVETP.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-WK7OIQKI.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XGBUKRCK.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XIGPWXCQ.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-XOCUANHO.mjs.map +0 -7
- /package/dist/lib/browser/{capability-BOPAKKWG.mjs.map → capability-Z4MRP3CP.mjs.map} +0 -0
- /package/dist/lib/browser/{process-manager-capability-GXNUO7AR.mjs.map → process-manager-capability-RDROCCQD.mjs.map} +0 -0
- /package/dist/lib/node-esm/{capability-KZWRTX7R.mjs.map → capability-34Z6NPVR.mjs.map} +0 -0
- /package/dist/lib/node-esm/{process-manager-capability-TX5TA6YN.mjs.map → process-manager-capability-6OCXSKUW.mjs.map} +0 -0
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name in all)
|
|
5
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
|
+
};
|
|
2
7
|
|
|
3
8
|
// src/vite-plugin/boot-loader/loader.ts
|
|
4
9
|
import * as babel from "@babel/core";
|
|
@@ -8,25 +13,25 @@ import { build } from "esbuild";
|
|
|
8
13
|
import { basename, dirname } from "node:path";
|
|
9
14
|
import { fileURLToPath } from "node:url";
|
|
10
15
|
|
|
11
|
-
// raw-loader:/__w/dxos/dxos/packages/sdk/app-framework/src/vite-plugin/boot-loader/loader-app/boot-loader.css
|
|
16
|
+
// raw-loader:/__w/dxos/dxos/packages/sdk/app-framework/src/vite-plugin/boot-loader/loader-app/boot-loader.css
|
|
12
17
|
var boot_loader_default = "/*\n * Boot loader stylesheet \u2014 injected into the host's `<head>` by `bootLoaderPlugin`\n * so the full-screen backdrop paints before any JS bundle is fetched. The Solid\n * `Loader` renders the ring + status into the `#boot-loader` backdrop; this\n * sheet styles both. Class/id names here form a contract with `Loader.tsx`,\n * guarded by `BootLoader.solid-stories.tsx` (it mounts the real component).\n */\n\nbody {\n margin: 0;\n overflow: hidden;\n}\n\n/*\n * Defaults match `@dxos/ui-theme`'s `--color-base-surface`, which resolves to\n * Tailwind's `neutral-50` / `neutral-950` in light / dark mode respectively\n * (see `packages/ui/ui-theme/src/css/theme/semantic.css`). Hosts can override\n * with the `--boot-loader-bg-*` / `--boot-loader-fg-*` custom properties on\n * `:root` if they need a different palette. Keeping the boot loader's\n * background identical to the app's `body` eliminates the flash on handoff\n * to the rendered React shell.\n */\n#boot-loader {\n --color-composer-100: rgb(5 40 61);\n --color-composer-200: rgb(10 75 105);\n --color-composer-300: rgb(1 122 183);\n --color-composer-400: rgb(6 197 253);\n\n /*\n * Caps the disc / mark at the design pixel sizes on roomy viewports while\n * shrinking proportionally on narrow ones (`vmin` follows the smaller of\n * width / height) so neither the ring nor the mark crops on phones.\n */\n --boot-loader-disc-size: min(384px, 80vmin);\n /*\n * Match the React `Placeholder`'s logo box (`h-[300px] w-[300px]` at the\n * `stage >= 1` keyframe) so the brand mark doesn't visibly jump size when\n * the loader hands off \u2014 the responsive cap keeps the same 300/384 ratio\n * (\u224878%) at any viewport width.\n */\n --boot-loader-mark-size: min(300px, 62.5vmin);\n --boot-loader-status-gap: 32px;\n\n position: fixed;\n inset: 0;\n z-index: 10;\n font-size: 13px;\n font-family:\n ui-sans-serif,\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n 'Segoe UI',\n sans-serif;\n /*\n * Dismissal outro \u2014 `mountLoader` toggles `data-dismissing` on this element\n * when the host calls `__bootLoader.ready()`; the loader cross-fades out over\n * the real app shell rendering beneath it, and removes itself once this\n * opacity transition completes (a fallback timer covers reduced-motion).\n */\n transition: opacity 500ms ease-out;\n}\n\n#boot-loader {\n background: var(--boot-loader-bg-light, #fafafa);\n color: var(--boot-loader-fg-light, #0a0a0a);\n --boot-loader-accent: var(--boot-loader-accent-light, var(--color-composer-200));\n}\n\n@media (prefers-color-scheme: dark) {\n #boot-loader {\n background: var(--boot-loader-bg-dark, #0a0a0a);\n color: var(--boot-loader-fg-dark, #f0f0f0);\n --boot-loader-accent: var(--boot-loader-accent-dark, var(--color-composer-300));\n }\n}\n\n#boot-loader[data-dismissing] {\n opacity: 0;\n}\n\n/* Gently shrink the disc + mark as the loader fades, echoing the prior handoff. */\n#boot-loader[data-dismissing] #boot-loader-disc {\n transform: translate(-50%, -50%) scale(0.92);\n transition: transform 500ms ease-out;\n}\n\n/*\n * Stack the ring (the SVG `#boot-loader-ring`) and the brand mark in the same\n * grid cell so the mark sits centered inside the circle.\n */\n#boot-loader-disc {\n position: absolute;\n top: 50%;\n left: 50%;\n display: grid;\n place-items: center;\n width: var(--boot-loader-disc-size);\n height: var(--boot-loader-disc-size);\n transform: translate(-50%, -50%);\n}\n\n#boot-loader-disc > * {\n grid-column: 1;\n grid-row: 1;\n}\n\n/*\n * Default to grayscale so the mark reads as a quiet monochrome silhouette\n * before any host-driven progress lands; the brand palette swaps in once\n * `Loader.tsx` sets `data-host-driven` on the disc (the first\n * `__bootLoader.progress()` call). Hover keeps a parallel reveal affordance\n * for inspection in the storybook. The 1000ms ease lets the grayscale \u2192 color\n * transition play through the activation phase rather than snapping.\n */\n#boot-loader-mark {\n width: var(--boot-loader-mark-size);\n height: var(--boot-loader-mark-size);\n display: flex;\n align-items: center;\n justify-content: center;\n filter: grayscale(100%);\n transition: filter 1000ms ease-out;\n}\n\n/*\n * `grayscale(0%)` (identity) rather than `none` \u2014 `filter: none` changes\n * the filter function list and most engines treat that as a discrete\n * transition (snap, not ease). Keeping `grayscale(...)` on both sides of\n * the rule lets the browser interpolate the percentage smoothly.\n */\n#boot-loader-disc[data-host-driven] #boot-loader-mark,\n#boot-loader-mark:hover {\n filter: grayscale(0%);\n}\n\n#boot-loader-mark svg {\n width: 100%;\n height: 100%;\n /*\n * The host SVG carries its own brand-palette fills, so we don't apply a\n * `color` cascade here. SVGs that intentionally use `fill=\"currentColor\"`\n * still pick up the loader's text colour via `#boot-loader`'s `color`.\n */\n}\n\n/*\n * Circular determinate progress \u2014 a single SVG `<path>` arc that sweeps\n * anticlockwise from 12 o'clock, its angle growing with progress (the `d` is\n * recomputed by the component each tick). There is no static track;\n * `stroke-linecap: round` rounds the trailing edge, and `marker-end` paints the\n * leading-edge dot. Stroke width is in viewBox units so it scales with the disc.\n */\n#boot-loader-ring {\n width: var(--boot-loader-disc-size);\n height: var(--boot-loader-disc-size);\n overflow: visible;\n /*\n * Fade the arc linearly from the head (the marker, fully opaque) back to the\n * tail (12 o'clock, transparent). A conic-gradient mask does this along the\n * curve \u2014 `Loader.tsx` writes the eased progress into `--boot-loader-arc`\n * (0\u2013100), and the arc occupies the conic range `(100 - arc)%`\u2026`100%`, so the\n * head sits at `(100 - arc)%` (opaque) and the tail at `100%` (transparent).\n * NOTE: We start at -1.16deg so that we don't mask the marker.\n */\n --boot-loader-arc: 0;\n mask: conic-gradient(\n from -1.16deg at 50% 50%,\n transparent 0,\n transparent calc((100 - var(--boot-loader-arc)) * 1%),\n #000 calc((100 - var(--boot-loader-arc)) * 1%),\n transparent 100%\n );\n -webkit-mask: conic-gradient(\n from -1.16deg at 50% 50%,\n transparent 0,\n transparent calc((100 - var(--boot-loader-arc)) * 1%),\n #000 calc((100 - var(--boot-loader-arc)) * 1%),\n transparent 100%\n );\n}\n\n/*\n * The leading-edge dot's layer \u2014 same geometry as `#boot-loader-ring` but with no\n * mask, so the dot renders as a full circle (the ring's conic fade mask would\n * otherwise bisect it where it sits on the mask's transparent\u2192opaque edge).\n */\n#boot-loader-ring-head {\n width: var(--boot-loader-disc-size);\n height: var(--boot-loader-disc-size);\n overflow: visible;\n}\n\n.boot-loader-ring-progress {\n fill: none;\n stroke: var(--boot-loader-accent);\n /* viewBox units: ~1.9px on the 384px disc, scaling down on smaller viewports. */\n stroke-width: 0.5;\n opacity: 0.5;\n stroke-linecap: butt;\n overflow: visible;\n /* Dashed line: dash + gap lengths in viewBox units (~2 units \u2248 7.7px @384px). */\n /* stroke-dasharray: 2 1; */\n}\n\n/* The `marker-end` dot at the arc's leading edge. */\n.boot-loader-ring-marker {\n fill: var(--boot-loader-accent);\n stroke: none;\n overflow: visible;\n /* opacity: 0.5; */\n}\n\n#boot-loader-status {\n position: absolute;\n top: 50%;\n left: 0;\n right: 0;\n /* \n * Sit just below the centered disc \u2014 half the disc plus the configured gap.\n */\n transform: translate(0, calc(var(--boot-loader-disc-size) / 2 + var(--boot-loader-status-gap)));\n /*\n * Slightly de-emphasised vs body text so the brand mark + ring stay the\n * dominant focus, but high enough to remain legible on both light and dark\n * backgrounds without a custom palette.\n */\n opacity: 0.5;\n /*\n * Terminal-style log viewport (3 rows at the default `line-height`) over\n * a vertically-stacked track of every status the driver has emitted. The\n * track is bottom-anchored via `justify-content: flex-end` so the newest\n * line always sits on the last visible row, older lines stack above it,\n * and anything that doesn't fit is clipped at the top by\n * `overflow: hidden`. The driver runs a FLIP-style transform animation\n * per append so each new line slides up from below the bottom edge \u2014\n * independent of any `scroll-behavior` smooth-scroll support, which\n * Playwright/headless Chrome strips even from spec-compliant\n * `scrollTo({ behavior: 'smooth' })` calls.\n */\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n height: 4.5em;\n line-height: 1.5;\n letter-spacing: 0.01em;\n /* \n * Fixed-width digits so the `(i/n)` counter on range-bearing status\n * updates (\"Loading plugins (12/80)\") doesn't jitter as the index\n * ticks through different glyph widths. \n */\n font-variant-numeric: tabular-nums;\n text-align: center;\n overflow: hidden;\n}\n\n#boot-loader-status-fade {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 32px;\n background: linear-gradient(to bottom, var(--boot-loader-bg-light, #fafafa), transparent);\n z-index: 1;\n}\n@media (prefers-color-scheme: dark) {\n #boot-loader-status-fade {\n background: linear-gradient(to bottom, var(--boot-loader-bg-dark, #0a0a0a), transparent);\n }\n}\n\n#boot-loader-rss {\n background: var(--boot-loader-bg-light, #fafafa);\n text-wrap: balance;\n}\n@media (prefers-color-scheme: dark) {\n #boot-loader-rss {\n background: var(--boot-loader-bg-dark, #0a0a0a);\n }\n}\n\n/*\n * Track of every appended `.boot-loader-status-line`.\n */\n#boot-loader-status-track {\n display: flex;\n flex-direction: column;\n /*\n * Resting transform is `translateY(0)` \u2014 the bottom-anchored flex parent\n * already positions the newest line on the last visible row. On each append\n * `Loader.tsx` runs a one-shot FLIP: snap to `translateY(<lineHeight>px)` with\n * no transition (placing the new line just below the viewport), force a\n * reflow, then animate back to 0 so the track rises by one line-height and the\n * new entry slides up into the bottom row.\n */\n transform: translateY(0);\n transition: transform 500ms ease-out;\n}\n\n/* Honour reduced-motion preferences explicitly \u2014 `transition` doesn't auto-respect it. */\n@media (prefers-reduced-motion: reduce) {\n #boot-loader-status-track {\n transition: none;\n }\n}\n\n.boot-loader-status-line {\n flex: 0 0 auto;\n height: 1.5em;\n white-space: nowrap;\n}\n";
|
|
13
18
|
|
|
14
|
-
// raw-loader:/__w/dxos/dxos/packages/sdk/app-framework/src/vite-plugin/boot-loader/loader-app/bridge.ts
|
|
19
|
+
// raw-loader:/__w/dxos/dxos/packages/sdk/app-framework/src/vite-plugin/boot-loader/loader-app/bridge.ts
|
|
15
20
|
var bridge_default = "//\n// Copyright 2026 DXOS.org\n//\n\nimport { type LoaderStore } from './store';\nimport { type BootLoaderApi } from './types';\n\n/**\n * Wrap a reactive {@link LoaderStore} as the imperative `window.__bootLoader`\n * facade the host app drives. `status` / `progress` write into the store;\n * `ready` plays the graceful dismissal outro; `dismiss` is the immediate-remove\n * backstop for the fast-load path (and a no-op once an outro is already in\n * flight, so a late `dismiss()` from the framework never cuts the animation).\n */\nexport const createBridge = (store: LoaderStore, dismissNow: () => void): BootLoaderApi => ({\n status: (payload) => store.pushStatus(payload),\n progress: (fraction) => store.setProgress(fraction),\n ready: () => store.ready(),\n dismiss: () => {\n if (store.phase() === 'dismissing') {\n return;\n }\n dismissNow();\n },\n});\n";
|
|
16
21
|
|
|
17
|
-
// raw-loader:/__w/dxos/dxos/packages/sdk/app-framework/src/vite-plugin/boot-loader/loader-app/entry.tsx
|
|
22
|
+
// raw-loader:/__w/dxos/dxos/packages/sdk/app-framework/src/vite-plugin/boot-loader/loader-app/entry.tsx
|
|
18
23
|
var entry_default = "//\n// Copyright 2026 DXOS.org\n//\n\nimport { mountLoader } from './mount';\nimport { DEFAULT_ROOT_ID } from './types';\n\n//\n// Production entry \u2014 bundled to a self-contained IIFE by `bootLoaderPlugin` and\n// inlined into `index.html` ahead of the app bundle. Mounts the loader into the\n// static backdrop using the config the plugin baked in just before this script\n// (including the backdrop id, so the id has a single source). The storybook\n// does NOT use this entry; it imports `mountLoader` directly so Vite compiles\n// the Solid source with HMR.\n//\n\nconst config = window.__BOOT_LOADER_CONFIG__ ?? {};\nconst el = document.getElementById(config.rootId ?? DEFAULT_ROOT_ID);\nif (el) {\n mountLoader(el, config);\n}\n";
|
|
19
24
|
|
|
20
|
-
// raw-loader:/__w/dxos/dxos/packages/sdk/app-framework/src/vite-plugin/boot-loader/loader-app/Loader.tsx
|
|
25
|
+
// raw-loader:/__w/dxos/dxos/packages/sdk/app-framework/src/vite-plugin/boot-loader/loader-app/Loader.tsx
|
|
21
26
|
var Loader_default = "//\n// Copyright 2026 DXOS.org\n//\n\nimport { type Component, For, createEffect, createSignal, onCleanup, onMount } from 'solid-js';\n\nimport { type LoaderStore } from './store';\n\n// Ring geometry in the SVG's `0 0 100 100` viewBox. The radius leaves a couple\n// of units of padding so the stroke, its round cap, and the end marker aren't\n// clipped at the viewBox edge.\nconst RING_RADIUS = 48;\nconst RING_CENTER = 50;\n// Leading-edge marker: a small dot drawn at the arc's head in an unmasked layer.\nconst MARKER_RADIUS = 1; // viewBox units \u2192 ~3.8px on the 384px disc\n\n/**\n * Read an element's *current animated* translateY (px) from its live transform\n * matrix \u2014 the interpolated value mid-transition, not the last-written property.\n * Used by the status FLIP so successive appends chain off the in-flight position\n * instead of yanking the track back to a fixed invert target.\n */\nconst readTranslateY = (element: HTMLElement): number => {\n const computed = getComputedStyle(element).transform;\n if (!computed || computed === 'none') {\n return 0;\n }\n const match = computed.match(/matrix.*\\(([^)]+)\\)/);\n if (!match) {\n return 0;\n }\n const values = match[1].split(',');\n // 2D `matrix(a, b, c, d, tx, ty)` \u2192 ty at index 5; 3D `matrix3d(...)` \u2192 ty at 13.\n if (values.length === 6) {\n return Number.parseFloat(values[5]) || 0;\n }\n if (values.length === 16) {\n return Number.parseFloat(values[13]) || 0;\n }\n return 0;\n};\n\nexport type LoaderProps = {\n /** Reactive source of truth for progress, status lines, and lifecycle phase. */\n store: LoaderStore;\n /** Inline SVG markup for the brand mark rendered inside the ring. */\n markSvg?: string;\n};\n\n/**\n * The boot loader, authored as a single Solid component \u2014 the one source of\n * truth for the loader DOM. `bootLoaderPlugin` bundles this (Solid runtime\n * inlined) into `index.html`; the storybook mounts the very same component, so\n * the two can no longer drift. The DOM structure, ids, and classes mirror\n * `boot-loader.css`.\n *\n * The full-screen backdrop (`#boot-loader`) is injected as static markup so it\n * paints from CSS before this bundle executes; this component renders the disc\n * and status log *into* that backdrop. The dismissal outro (fading `#boot-loader`)\n * and its teardown are owned by {@link mountLoader}, which has the host element.\n */\nexport const Loader: Component<LoaderProps> = (props) => {\n let trackRef: HTMLDivElement | undefined;\n let previousCount = props.store.lines().length;\n\n // FLIP-style slide on each appended line: snap the track down by one\n // line-height (chained off any in-flight translate) with no transition, force\n // a reflow, then animate back to translateY(0) so the new entry rises from\n // below the bottom-anchored viewport. Range ticks (length unchanged) skip it.\n createEffect(() => {\n const count = props.store.lines().length;\n const track = trackRef;\n if (track && count > previousCount) {\n const currentY = readTranslateY(track);\n const lineHeight = track.lastElementChild?.getBoundingClientRect().height ?? 0;\n track.style.transition = 'none';\n track.style.transform = `translateY(${currentY + lineHeight}px)`;\n void track.offsetHeight;\n track.style.transition = '';\n track.style.transform = 'translateY(0)';\n }\n previousCount = count;\n });\n\n // Eased display progress. A `<path>`'s `d` can't be CSS-transitioned, so the\n // arc would snap on every store tick; instead we ease a displayed value toward\n // the store's progress with a requestAnimationFrame loop (~per-frame lerp) and\n // recompute the path each frame. This restores the compositor-smooth growth\n // the old `transition: stroke-dashoffset` gave, while keeping the path +\n // `marker-end` (the marker rides the arc's recomputed end automatically).\n const [shown, setShown] = createSignal(props.store.progress());\n let raf: number | undefined;\n const animate = () => {\n const target = props.store.progress();\n const current = shown();\n // Snap when within a hair to settle; otherwise lerp ~18% of the gap/frame.\n const next = Math.abs(target - current) < 0.05 ? target : current + (target - current) * 0.18;\n if (next !== current) {\n setShown(next);\n }\n raf = requestAnimationFrame(animate);\n };\n\n onMount(() => {\n raf = requestAnimationFrame(animate);\n });\n\n onCleanup(() => {\n if (raf != null) {\n cancelAnimationFrame(raf);\n }\n });\n\n // Determinate ring as an SVG `<path>` arc: an anticlockwise sweep starting at\n // 12 o'clock whose angle grows with the eased `shown()` progress. The sweep is\n // capped just shy of a full turn so the single arc command never degenerates at\n // 100%. The leading-edge dot is its `head` point, rendered separately (below) in\n // an *unmasked* layer \u2014 drawing it via `marker-end` on this path would put it\n // under the ring's conic fade mask, whose hard edge bisects the dot into a\n // half-circle.\n const arc = () => {\n const fraction = Math.min(shown() / 100, 0.9999);\n const sweep = fraction * 2 * Math.PI;\n const start = -Math.PI / 2; // 12 o'clock\n const end = start - sweep; // anticlockwise (decreasing angle)\n const x0 = RING_CENTER + RING_RADIUS * Math.cos(start);\n const y0 = RING_CENTER + RING_RADIUS * Math.sin(start);\n const headX = RING_CENTER + RING_RADIUS * Math.cos(end);\n const headY = RING_CENTER + RING_RADIUS * Math.sin(end);\n const largeArc = sweep > Math.PI ? 1 : 0;\n // sweep-flag 0 = anticlockwise (negative-angle) direction.\n return { d: `M ${x0} ${y0} A ${RING_RADIUS} ${RING_RADIUS} 0 ${largeArc} 0 ${headX} ${headY}`, headX, headY };\n };\n\n // Once host-driven, the brand mark eases grayscale \u2192 colour and stays there.\n const isHostDriven = () => props.store.phase() !== 'creep';\n\n return (\n <>\n <div id='boot-loader-disc' data-host-driven={isHostDriven() ? '' : undefined}>\n <svg\n id='boot-loader-ring'\n viewBox='0 0 100 100'\n aria-hidden='true'\n style={{ '--boot-loader-arc': String(shown()) }}\n >\n {shown() > 0 ? <path class='boot-loader-ring-progress' d={arc().d} /> : null}\n </svg>\n {/* Leading-edge dot in its own unmasked layer (see `arc()`), so the ring's fade mask\n never clips it. Stacked over `#boot-loader-ring` via the disc grid. */}\n {shown() > 0 ? (\n <svg id='boot-loader-ring-head' viewBox='0 0 100 100' aria-hidden='true'>\n <circle class='boot-loader-ring-marker' cx={arc().headX} cy={arc().headY} r={MARKER_RADIUS} />\n </svg>\n ) : null}\n {props.markSvg ? <div id='boot-loader-mark' innerHTML={props.markSvg} /> : null}\n </div>\n <div id='boot-loader-status'>\n <div id='boot-loader-status-fade' />\n <div id='boot-loader-status-track' ref={trackRef}>\n <For each={props.store.lines()}>{(line) => <div class='boot-loader-status-line'>{line.text}</div>}</For>\n </div>\n </div>\n </>\n );\n};\n";
|
|
22
27
|
|
|
23
|
-
// raw-loader:/__w/dxos/dxos/packages/sdk/app-framework/src/vite-plugin/boot-loader/loader-app/mount.tsx
|
|
28
|
+
// raw-loader:/__w/dxos/dxos/packages/sdk/app-framework/src/vite-plugin/boot-loader/loader-app/mount.tsx
|
|
24
29
|
var mount_default = "//\n// Copyright 2026 DXOS.org\n//\n\nimport { createEffect } from 'solid-js';\nimport { render } from 'solid-js/web';\n\nimport { createBridge } from './bridge';\nimport { Loader } from './Loader';\nimport { createLoaderStore } from './store';\nimport { type BootLoaderConfig } from './types';\n\n/** Fallback teardown if the outro's `transitionend` never fires (e.g. no opacity transition). */\nconst OUTRO_FALLBACK_MS = 800;\n\n/**\n * Mount the boot loader into a host element (`#boot-loader`, the static backdrop\n * the plugin injects \u2014 or any container in the storybook) and install the\n * `window.__bootLoader` facade. Renders the disc + status into the host, toggles\n * `data-dismissing` on it for the outro, and removes everything once the outro\n * completes.\n *\n * Returns a disposer that tears the loader down immediately (idempotent).\n */\nexport const mountLoader = (el: HTMLElement, config: BootLoaderConfig = {}): (() => void) => {\n const store = createLoaderStore(config.status);\n\n let removed = false;\n // Forward-declared so `remove` can dispose the Solid render created below.\n let disposeRender: (() => void) | undefined;\n\n const remove = (): void => {\n if (removed) {\n return;\n }\n removed = true;\n el.removeEventListener('transitionend', handleTransitionEnd);\n store.dispose();\n disposeRender?.();\n el.remove();\n if (window.__bootLoader === api) {\n delete window.__bootLoader;\n }\n };\n\n const handleTransitionEnd = (event: TransitionEvent): void => {\n if (event.propertyName === 'opacity' && store.phase() === 'dismissing') {\n remove();\n }\n };\n el.addEventListener('transitionend', handleTransitionEnd);\n\n disposeRender = render(() => {\n // Drive the backdrop's outro from the host element (Solid owns the host's\n // children; the host attribute is toggled imperatively within this owner).\n createEffect(() => {\n const dismissing = store.phase() === 'dismissing';\n el.toggleAttribute('data-dismissing', dismissing);\n if (dismissing) {\n setTimeout(remove, OUTRO_FALLBACK_MS);\n }\n });\n return <Loader store={store} markSvg={config.markSvg} />;\n }, el);\n\n const api = createBridge(store, remove);\n window.__bootLoader = api;\n\n return remove;\n};\n";
|
|
25
30
|
|
|
26
|
-
// raw-loader:/__w/dxos/dxos/packages/sdk/app-framework/src/vite-plugin/boot-loader/loader-app/store.ts
|
|
31
|
+
// raw-loader:/__w/dxos/dxos/packages/sdk/app-framework/src/vite-plugin/boot-loader/loader-app/store.ts
|
|
27
32
|
var store_default = "//\n// Copyright 2026 DXOS.org\n//\n\nimport { type Accessor, createSignal } from 'solid-js';\n\nimport { type StatusPayload } from './types';\n\n//\n// Creep tuning. The ring auto-creeps toward a moving ceiling so a long\n// activation silence never reads as a frozen disc. See the original\n// hand-written driver for the rationale behind each constant.\n//\n\n/** Creep timer cadence, in milliseconds. */\nexport const CREEP_TICK_MS = 100;\n/** State-1 ease rate \u2014 a gentle \"we're alive\" hint before real progress lands. */\nexport const STATE_1_RATE = 0.05;\n/** State-1 asymptote (percent) the creep eases toward before host progress. */\nexport const STATE_1_ASYMPTOTE = 40;\n/** State-2 ease rate \u2014 bridges the gap between sparse host `progress()` calls. */\nexport const STATE_2_RATE = 0.05;\n/** State-2 lead (percent) the ceiling sits ahead of the last host value. */\nexport const STATE_2_BUMP = 15;\n/** Hard ceiling the auto-creep never crosses (host must drive the rest). */\nexport const ABSOLUTE_CEILING = 90;\n\n/** Loader lifecycle phase. */\nexport type Phase = 'creep' | 'host' | 'dismissing';\n\n/** A single rendered status line; `id` keys the `<For>` and survives in-place range ticks. */\nexport type StatusLine = {\n id: number;\n text: string;\n event?: string;\n module?: string;\n};\n\n/**\n * Asymptotic ease \u2014 `next = raw + (ceiling - raw) * rate`, clamped so it never\n * overshoots (or regresses past) the ceiling. Pure; unit-tested.\n */\nexport const easeToward = (raw: number, ceiling: number, rate: number): number =>\n raw >= ceiling - 0.1 ? raw : raw + (ceiling - raw) * rate;\n\n/**\n * Clamp a host-supplied fraction to a percent in [0, 100]. Invalid / negative /\n * non-finite values collapse to 0 rather than poisoning the CSS var. Pure;\n * unit-tested.\n */\nexport const clampPercent = (fraction?: number): number =>\n typeof fraction !== 'number' || !Number.isFinite(fraction) || fraction < 0 ? 0 : Math.min(1, fraction) * 100;\n\n/** Display text for a payload \u2014 appends the `(index/total)` suffix when a range is present. */\nexport const displayText = (payload: StatusPayload): string =>\n payload.range ? `${payload.humanized} (${payload.range.index}/${payload.range.total})` : payload.humanized;\n\n/**\n * Reactive loader store \u2014 owns the progress percent, the status-line log, and\n * the lifecycle phase, plus the auto-creep timer. All DOM-free, so the creep\n * math and status reduction are testable as plain functions; `Loader.tsx` binds\n * the accessors to the DOM and `bridge.ts` wraps the mutators as the imperative\n * `window.__bootLoader` facade.\n */\nexport type LoaderStore = {\n /** Progress as a percent in [0, 100] (the CSS `--boot-loader-bar-progress` value). */\n progress: Accessor<number>;\n /** Appended status lines, newest last. */\n lines: Accessor<StatusLine[]>;\n /** Current lifecycle phase. */\n phase: Accessor<Phase>;\n /** Apply a status update (append, or replace-in-place for range ticks). */\n pushStatus: (payload: StatusPayload) => void;\n /** Enter host-driven progress with `fraction` \u2208 [0, 1]; never regresses. */\n setProgress: (fraction?: number) => void;\n /** Snap to 100%, stop the creep, and enter the dismissing phase. */\n ready: () => void;\n /** Stop the creep timer (call on teardown). */\n dispose: () => void;\n};\n\nexport const createLoaderStore = (initialStatus?: string): LoaderStore => {\n const [progress, setProgressPct] = createSignal(0);\n const [lines, setLines] = createSignal<StatusLine[]>(initialStatus ? [{ id: 0, text: initialStatus }] : []);\n const [phase, setPhase] = createSignal<Phase>('creep');\n\n let creepCeiling = STATE_1_ASYMPTOTE;\n let creepRate = STATE_1_RATE;\n let nextId = initialStatus ? 1 : 0;\n let timer: ReturnType<typeof setInterval> | null = null;\n\n const startCreep = (): void => {\n if (timer == null) {\n timer = setInterval(() => setProgressPct((raw) => easeToward(raw, creepCeiling, creepRate)), CREEP_TICK_MS);\n }\n };\n\n const stopCreep = (): void => {\n if (timer != null) {\n clearInterval(timer);\n timer = null;\n }\n };\n\n const pushStatus = (payload: StatusPayload): void => {\n const text = displayText(payload);\n setLines((current) => {\n const previous = current.at(-1);\n // Dedup back-to-back identical transitions (same text + structured fields).\n if (\n previous &&\n previous.text === text &&\n (previous.event ?? null) === (payload.event ?? null) &&\n (previous.module ?? null) === (payload.module ?? null)\n ) {\n return current;\n }\n // Range tick \u2014 replace the current line in place rather than appending,\n // so a counted phase produces one entry with an updating suffix.\n if (payload.range && previous) {\n return [...current.slice(0, -1), { ...previous, text }];\n }\n return [...current, { id: nextId++, text, event: payload.event, module: payload.module }];\n });\n };\n\n const setProgress = (fraction?: number): void => {\n setPhase('host');\n const pct = clampPercent(fraction);\n // The ring never regresses: hold the current value if the host reports lower.\n setProgressPct((current) => Math.max(current, pct));\n // Switch the creep to its state-2 cadence and lead the host value by a bump.\n creepRate = STATE_2_RATE;\n creepCeiling = Math.min(Math.max(creepCeiling, pct + STATE_2_BUMP), ABSOLUTE_CEILING);\n startCreep();\n };\n\n const ready = (): void => {\n stopCreep();\n setProgressPct(100);\n setPhase('dismissing');\n };\n\n const dispose = (): void => stopCreep();\n\n startCreep();\n\n return { progress, lines, phase, pushStatus, setProgress, ready, dispose };\n};\n";
|
|
28
33
|
|
|
29
|
-
// raw-loader:/__w/dxos/dxos/packages/sdk/app-framework/src/vite-plugin/boot-loader/loader-app/types.ts
|
|
34
|
+
// raw-loader:/__w/dxos/dxos/packages/sdk/app-framework/src/vite-plugin/boot-loader/loader-app/types.ts
|
|
30
35
|
var types_default = "//\n// Copyright 2026 DXOS.org\n//\n\n/**\n * Status payload accepted by `window.__bootLoader.status(...)`. The caller owns\n * formatting \u2014 `humanized` is the exact text rendered \u2014 while `event` / `module`\n * carry the structured activation ids for the boot trace, and `range` drives an\n * in-place `(index/total)` counter for long counted phases.\n */\nexport type StatusPayload = {\n /**\n * Raw activation event key (e.g. `dxos.org/plugin/observability/activate`)\n * when the transition is event-level.\n */\n event?: string;\n\n /**\n * Raw module id (e.g. `org.dxos.plugin.observability.module.ReactSurface`)\n * when the transition is module-level.\n */\n module?: string;\n\n /** Exact text to display (e.g. \"Activating Observability: react-surface\"). */\n humanized: string;\n\n /**\n * Optional `(index/total)` tick. When present the loader replaces the current\n * line in place (\"Loading plugins (12/80)\") instead of appending a new entry \u2014\n * keeps the visible log compact during long counted phases.\n */\n range?: { index: number; total: number };\n};\n\n/**\n * Imperative facade exposed on `window.__bootLoader`, installed by the inlined\n * loader bundle and driven by the host app (the React relay forwards `useApp`'s\n * startup progress through it).\n */\nexport type BootLoaderApi = {\n /** Update the visible status line. */\n status: (payload: StatusPayload) => void;\n /** Enter host-driven progress \u2014 `fraction` \u2208 [0, 1]. */\n progress: (fraction?: number) => void;\n /** Play the dismissal outro, then remove the loader DOM (graceful path). */\n ready: () => void;\n /** Remove the loader DOM immediately (fast-load backstop / terminal). */\n dismiss: () => void;\n};\n\n/**\n * Config baked into `index.html` by `bootLoaderPlugin` ahead of the loader\n * bundle, so the compiled app stays static (compiled once, independent of the\n * host's brand mark / initial status).\n */\nexport type BootLoaderConfig = {\n /**\n * Id of the static backdrop element the plugin injects and the loader mounts\n * into \u2014 the single coupling between `transformIndexHtml` and the app. The\n * plugin owns the authoritative value and passes it here so `entry.tsx` reads\n * it rather than hardcoding (the CSS selector mirrors it \u2014 see `boot-loader.css`).\n */\n rootId?: string;\n /** Inline SVG markup for the brand mark rendered inside the ring. */\n markSvg?: string;\n /** Initial status text rendered before the host fires its first `status(...)`. */\n status?: string;\n};\n\n/** Fallback backdrop id when no config is present (kept in sync with `loader.ts` + the CSS). */\nexport const DEFAULT_ROOT_ID = 'boot-loader';\n\ndeclare global {\n interface Window {\n __bootLoader?: BootLoaderApi;\n __BOOT_LOADER_CONFIG__?: BootLoaderConfig;\n }\n}\n";
|
|
31
36
|
|
|
32
37
|
// src/vite-plugin/boot-loader/loader.ts
|
|
@@ -181,34 +186,329 @@ var bootLoaderPlugin = ({ status, markSvg, include = [
|
|
|
181
186
|
};
|
|
182
187
|
};
|
|
183
188
|
|
|
189
|
+
// src/vite-plugin/composer/index.ts
|
|
190
|
+
import { readFileSync } from "node:fs";
|
|
191
|
+
import { join as join2 } from "node:path";
|
|
192
|
+
|
|
193
|
+
// src/core/capability.ts
|
|
194
|
+
import * as Context from "effect/Context";
|
|
195
|
+
import * as Effect from "effect/Effect";
|
|
196
|
+
import * as Layer from "effect/Layer";
|
|
197
|
+
var Service = class extends Context.Tag("@dxos/app-framework/CapabilityManager")() {
|
|
198
|
+
};
|
|
199
|
+
var ModuleTag = /* @__PURE__ */ Symbol.for("@dxos/app-framework/ModuleTag");
|
|
200
|
+
var getModuleTag = (capability) => {
|
|
201
|
+
return capability && typeof capability === "function" && ModuleTag in capability ? String(capability[ModuleTag]) : void 0;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
// src/core/plugin.ts
|
|
205
|
+
var plugin_exports = {};
|
|
206
|
+
__export(plugin_exports, {
|
|
207
|
+
LazyPluginError: () => LazyPluginError,
|
|
208
|
+
Meta: () => Meta,
|
|
209
|
+
PluginDependencyError: () => PluginDependencyError,
|
|
210
|
+
PluginModuleTypeId: () => PluginModuleTypeId,
|
|
211
|
+
PluginTypeId: () => PluginTypeId,
|
|
212
|
+
Profile: () => Profile,
|
|
213
|
+
Release: () => Release,
|
|
214
|
+
Service: () => Service2,
|
|
215
|
+
activate: () => activate,
|
|
216
|
+
addModule: () => addModule,
|
|
217
|
+
define: () => define,
|
|
218
|
+
getMetaFromConfig: () => getMetaFromConfig,
|
|
219
|
+
getURI: () => getURI,
|
|
220
|
+
isLazy: () => isLazy,
|
|
221
|
+
isPlugin: () => isPlugin,
|
|
222
|
+
isPluginModule: () => isPluginModule,
|
|
223
|
+
lazy: () => lazy,
|
|
224
|
+
make: () => make,
|
|
225
|
+
makeMeta: () => makeMeta,
|
|
226
|
+
reset: () => reset,
|
|
227
|
+
resolveLazy: () => resolveLazy,
|
|
228
|
+
shutdown: () => shutdown
|
|
229
|
+
});
|
|
230
|
+
import * as Context2 from "effect/Context";
|
|
231
|
+
import * as Effect2 from "effect/Effect";
|
|
232
|
+
import * as Option from "effect/Option";
|
|
233
|
+
import * as Pipeable from "effect/Pipeable";
|
|
234
|
+
import * as Schema from "effect/Schema";
|
|
235
|
+
import { BaseError } from "@dxos/errors";
|
|
236
|
+
import { invariant } from "@dxos/invariant";
|
|
237
|
+
import { DXN } from "@dxos/keys";
|
|
238
|
+
import { PluginProfileSchema, PluginReleaseSchema } from "@dxos/protocols";
|
|
239
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/sdk/app-framework/src/core/plugin.ts";
|
|
240
|
+
var Service2 = class extends Context2.Tag("@dxos/app-framework/PluginManager")() {
|
|
241
|
+
};
|
|
242
|
+
var activate = (event) => Effect2.flatMap(Service2, (manager) => manager.activate(event));
|
|
243
|
+
var reset = (event) => Effect2.flatMap(Service2, (manager) => manager.reset(event));
|
|
244
|
+
var shutdown = () => Effect2.flatMap(Service2, (manager) => manager.shutdown());
|
|
245
|
+
var computeModuleId = (pluginId, moduleName) => {
|
|
246
|
+
return `${pluginId}.module.${moduleName}`;
|
|
247
|
+
};
|
|
248
|
+
var PluginModuleTypeId = /* @__PURE__ */ Symbol.for("@dxos/app-framework/PluginModule");
|
|
249
|
+
var isPluginModule = (value) => {
|
|
250
|
+
return typeof value === "object" && value !== null && PluginModuleTypeId in value;
|
|
251
|
+
};
|
|
252
|
+
var PluginModuleImpl = class {
|
|
253
|
+
[PluginModuleTypeId] = PluginModuleTypeId;
|
|
254
|
+
id;
|
|
255
|
+
activatesOn;
|
|
256
|
+
firesBeforeActivation;
|
|
257
|
+
firesAfterActivation;
|
|
258
|
+
activate;
|
|
259
|
+
constructor(options) {
|
|
260
|
+
this.id = options.id;
|
|
261
|
+
this.activatesOn = options.activatesOn;
|
|
262
|
+
this.firesBeforeActivation = options.firesBeforeActivation;
|
|
263
|
+
this.firesAfterActivation = options.firesAfterActivation;
|
|
264
|
+
this.activate = options.activate;
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
var Profile = Schema.Struct({
|
|
268
|
+
...PluginProfileSchema.fields,
|
|
269
|
+
author: Schema.optional(Schema.String)
|
|
270
|
+
});
|
|
271
|
+
var Release = PluginReleaseSchema;
|
|
272
|
+
var Meta = Schema.Struct({
|
|
273
|
+
profile: Profile,
|
|
274
|
+
release: Schema.optional(Release)
|
|
275
|
+
});
|
|
276
|
+
var makeMeta = (options) => {
|
|
277
|
+
const { key, ...rest } = options;
|
|
278
|
+
return {
|
|
279
|
+
profile: {
|
|
280
|
+
...rest,
|
|
281
|
+
key: DXN.getName(key)
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
};
|
|
285
|
+
var getURI = (meta) => DXN.make(meta.profile.key, meta.release?.version);
|
|
286
|
+
var getMetaFromConfig = ({ plugin }) => {
|
|
287
|
+
const { key, ...rest } = plugin;
|
|
288
|
+
return makeMeta({
|
|
289
|
+
key: DXN.make(key),
|
|
290
|
+
...rest
|
|
291
|
+
});
|
|
292
|
+
};
|
|
293
|
+
var PluginTypeId = /* @__PURE__ */ Symbol.for("@dxos/app-framework/Plugin");
|
|
294
|
+
var isPlugin = (value) => {
|
|
295
|
+
return typeof value === "object" && value !== null && PluginTypeId in value;
|
|
296
|
+
};
|
|
297
|
+
var PluginImpl = class {
|
|
298
|
+
_meta;
|
|
299
|
+
_modules;
|
|
300
|
+
[PluginTypeId] = PluginTypeId;
|
|
301
|
+
constructor(_meta, _modules) {
|
|
302
|
+
this._meta = _meta;
|
|
303
|
+
this._modules = _modules;
|
|
304
|
+
}
|
|
305
|
+
get meta() {
|
|
306
|
+
return this._meta;
|
|
307
|
+
}
|
|
308
|
+
get modules() {
|
|
309
|
+
return this._modules;
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
var PluginBuilderImpl = class {
|
|
313
|
+
meta;
|
|
314
|
+
_modules = [];
|
|
315
|
+
constructor(meta) {
|
|
316
|
+
this.meta = meta;
|
|
317
|
+
}
|
|
318
|
+
get modules() {
|
|
319
|
+
return this._modules;
|
|
320
|
+
}
|
|
321
|
+
addModule(moduleOptions) {
|
|
322
|
+
this._modules.push(moduleOptions);
|
|
323
|
+
return this;
|
|
324
|
+
}
|
|
325
|
+
pipe() {
|
|
326
|
+
return Pipeable.pipeArguments(this, arguments);
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
var define = (meta) => new PluginBuilderImpl(meta);
|
|
330
|
+
function addModule(moduleOptionsOrBuilder, moduleOptions) {
|
|
331
|
+
if (moduleOptions !== void 0) {
|
|
332
|
+
return moduleOptionsOrBuilder.addModule(moduleOptions);
|
|
333
|
+
}
|
|
334
|
+
const moduleOpts = moduleOptionsOrBuilder;
|
|
335
|
+
return (builder) => builder.addModule(moduleOpts);
|
|
336
|
+
}
|
|
337
|
+
var resolveModule = (meta, module, options) => {
|
|
338
|
+
const moduleOptions = typeof module === "function" ? module(options) : module;
|
|
339
|
+
const pluginName = meta.profile.key;
|
|
340
|
+
const id = Option.fromNullable(moduleOptions.id).pipe(Option.match({
|
|
341
|
+
onNone: () => {
|
|
342
|
+
const exportName = getModuleTag(moduleOptions.activate);
|
|
343
|
+
invariant(exportName, `Plugin module missing name. Plugin: ${meta.profile.key}`, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 174, S: void 0, A: ["exportName", "`Plugin module missing name. Plugin: ${meta.profile.key}`"] });
|
|
344
|
+
return computeModuleId(pluginName, exportName);
|
|
345
|
+
},
|
|
346
|
+
onSome: (id2) => computeModuleId(pluginName, id2)
|
|
347
|
+
}));
|
|
348
|
+
return new PluginModuleImpl({
|
|
349
|
+
...moduleOptions,
|
|
350
|
+
id
|
|
351
|
+
});
|
|
352
|
+
};
|
|
353
|
+
function make(builder) {
|
|
354
|
+
const meta = builder.meta;
|
|
355
|
+
invariant(!meta.profile.dependsOn?.includes(meta.profile.key), `Plugin ${meta.profile.key} declares itself as a dependency.`, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 187, S: this, A: ["!meta.profile.dependsOn?.includes(meta.profile.key)", "`Plugin ${meta.profile.key} declares itself as a dependency.`"] });
|
|
356
|
+
const factory = (options) => {
|
|
357
|
+
const modules = builder.modules.map((module) => resolveModule(meta, module, options));
|
|
358
|
+
return new PluginImpl(meta, modules);
|
|
359
|
+
};
|
|
360
|
+
return Object.assign(factory, {
|
|
361
|
+
meta
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
var LazyTag = /* @__PURE__ */ Symbol.for("@dxos/app-framework/Plugin/Lazy");
|
|
365
|
+
var lazy = (meta, loader) => {
|
|
366
|
+
const factory = (options) => {
|
|
367
|
+
const stub = new PluginImpl(meta, []);
|
|
368
|
+
Object.defineProperty(stub, LazyTag, {
|
|
369
|
+
value: {
|
|
370
|
+
loader,
|
|
371
|
+
options
|
|
372
|
+
},
|
|
373
|
+
enumerable: false
|
|
374
|
+
});
|
|
375
|
+
return stub;
|
|
376
|
+
};
|
|
377
|
+
return Object.assign(factory, {
|
|
378
|
+
meta
|
|
379
|
+
});
|
|
380
|
+
};
|
|
381
|
+
var isLazy = (plugin) => LazyTag in plugin;
|
|
382
|
+
var LazyPluginError = class extends BaseError.extend("LazyPluginError", "Failed to resolve lazy plugin") {
|
|
383
|
+
};
|
|
384
|
+
var PluginDependencyError = class extends BaseError.extend("PluginDependencyError", "Plugin dependency resolution failed") {
|
|
385
|
+
};
|
|
386
|
+
var resolveLazy = (plugin) => Effect2.gen(function* () {
|
|
387
|
+
if (!isLazy(plugin)) {
|
|
388
|
+
return plugin;
|
|
389
|
+
}
|
|
390
|
+
const id = plugin.meta.profile.key;
|
|
391
|
+
const { loader, options } = plugin[LazyTag];
|
|
392
|
+
const mod = yield* Effect2.tryPromise({
|
|
393
|
+
try: loader,
|
|
394
|
+
catch: (error) => new LazyPluginError({
|
|
395
|
+
context: {
|
|
396
|
+
id,
|
|
397
|
+
reason: "load-failed"
|
|
398
|
+
},
|
|
399
|
+
cause: error
|
|
400
|
+
})
|
|
401
|
+
});
|
|
402
|
+
if (!mod || typeof mod.default !== "function") {
|
|
403
|
+
return yield* Effect2.fail(new LazyPluginError({
|
|
404
|
+
context: {
|
|
405
|
+
id,
|
|
406
|
+
reason: "missing-default"
|
|
407
|
+
}
|
|
408
|
+
}));
|
|
409
|
+
}
|
|
410
|
+
const result = mod.default(options);
|
|
411
|
+
if (!isPlugin(result)) {
|
|
412
|
+
return yield* Effect2.fail(new LazyPluginError({
|
|
413
|
+
context: {
|
|
414
|
+
id,
|
|
415
|
+
reason: "invalid-plugin"
|
|
416
|
+
}
|
|
417
|
+
}));
|
|
418
|
+
}
|
|
419
|
+
if (result.meta.profile.key !== id) {
|
|
420
|
+
return yield* Effect2.fail(new LazyPluginError({
|
|
421
|
+
context: {
|
|
422
|
+
id,
|
|
423
|
+
reason: "meta-mismatch",
|
|
424
|
+
returnedId: result.meta.profile.key
|
|
425
|
+
}
|
|
426
|
+
}));
|
|
427
|
+
}
|
|
428
|
+
return result;
|
|
429
|
+
});
|
|
430
|
+
|
|
184
431
|
// src/core/plugin-manifest.ts
|
|
185
432
|
import * as FetchHttpClient from "@effect/platform/FetchHttpClient";
|
|
186
433
|
import * as HttpClient from "@effect/platform/HttpClient";
|
|
187
434
|
import * as HttpClientRequest from "@effect/platform/HttpClientRequest";
|
|
188
435
|
import * as HttpClientResponse from "@effect/platform/HttpClientResponse";
|
|
189
|
-
import * as
|
|
190
|
-
import * as
|
|
191
|
-
import { BaseError } from "@dxos/errors";
|
|
192
|
-
import { PLUGIN_ENTRY_FILENAME } from "@dxos/protocols";
|
|
436
|
+
import * as Effect3 from "effect/Effect";
|
|
437
|
+
import * as Schema2 from "effect/Schema";
|
|
438
|
+
import { BaseError as BaseError2 } from "@dxos/errors";
|
|
439
|
+
import { PLUGIN_ENTRY_FILENAME, PluginManifestSchema } from "@dxos/protocols";
|
|
193
440
|
var PLUGIN_DEV_SERVER_PORT = 3967;
|
|
194
|
-
var PluginManifestError = class extends
|
|
195
|
-
};
|
|
196
|
-
var Manifest =
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
441
|
+
var PluginManifestError = class extends BaseError2.extend("PluginManifestError", "Plugin manifest is invalid") {
|
|
442
|
+
};
|
|
443
|
+
var Manifest = Schema2.Struct({
|
|
444
|
+
// Reuse the build manifest field definitions from `@dxos/protocols` (the shape `composerPlugin`
|
|
445
|
+
// emits), minus `assets` which we relax below, plus the dev-only `devEntry`.
|
|
446
|
+
...PluginManifestSchema.omit("assets").fields,
|
|
447
|
+
/**
|
|
448
|
+
* Relative asset paths. Relaxed vs the build `PluginManifestSchema` (which requires >= 1) because
|
|
449
|
+
* dev-server manifests list no assets — chunks/styles flow through the dev server on demand.
|
|
450
|
+
*/
|
|
451
|
+
assets: Schema2.Array(Schema2.String),
|
|
452
|
+
/** Present only for dev-server manifests; points at the unbundled source entry. */
|
|
453
|
+
devEntry: Schema2.optional(Schema2.String)
|
|
202
454
|
});
|
|
203
455
|
|
|
456
|
+
// src/vite-plugin/load.ts
|
|
457
|
+
import * as Schema3 from "effect/Schema";
|
|
458
|
+
import { build as build2 } from "esbuild";
|
|
459
|
+
import { randomUUID } from "node:crypto";
|
|
460
|
+
import { existsSync } from "node:fs";
|
|
461
|
+
import { rm, writeFile } from "node:fs/promises";
|
|
462
|
+
import { join } from "node:path";
|
|
463
|
+
import { pathToFileURL } from "node:url";
|
|
464
|
+
import { Config2 } from "@dxos/protocols";
|
|
465
|
+
var CONFIG_BASENAMES = [
|
|
466
|
+
"dx.config.ts",
|
|
467
|
+
"dx.config.mjs",
|
|
468
|
+
"dx.config.js"
|
|
469
|
+
];
|
|
470
|
+
var decodeConfig2 = Schema3.decodeUnknownSync(Config2.Config);
|
|
471
|
+
var findDxConfigFile = (dir) => CONFIG_BASENAMES.map((basename2) => join(dir, basename2)).find((candidate) => existsSync(candidate));
|
|
472
|
+
var loadDxConfig = async (filePath) => {
|
|
473
|
+
const result = await build2({
|
|
474
|
+
entryPoints: [
|
|
475
|
+
filePath
|
|
476
|
+
],
|
|
477
|
+
bundle: true,
|
|
478
|
+
format: "esm",
|
|
479
|
+
platform: "node",
|
|
480
|
+
write: false,
|
|
481
|
+
// Leave node_modules (incl. @dxos/*) as runtime imports so the temp module below resolves them
|
|
482
|
+
// from the project's node_modules rather than inlining heavy deps (effect, etc.) on every load.
|
|
483
|
+
packages: "external",
|
|
484
|
+
logLevel: "silent"
|
|
485
|
+
});
|
|
486
|
+
const tempPath = join(filePath, "..", `.dx.config.${randomUUID()}.mjs`);
|
|
487
|
+
try {
|
|
488
|
+
await writeFile(tempPath, result.outputFiles[0].text, "utf-8");
|
|
489
|
+
const module = await import(pathToFileURL(tempPath).href);
|
|
490
|
+
return decodeConfig2(module.default);
|
|
491
|
+
} finally {
|
|
492
|
+
await rm(tempPath, {
|
|
493
|
+
force: true
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
|
|
204
498
|
// src/vite-plugin/manifest.ts
|
|
205
499
|
import { PLUGIN_ENTRY_FILENAME as PLUGIN_ENTRY_FILENAME2 } from "@dxos/protocols";
|
|
206
500
|
var MANIFEST_ASSET_NAME = "manifest.json";
|
|
207
501
|
var ENTRY_FILENAME = PLUGIN_ENTRY_FILENAME2;
|
|
502
|
+
var toBuildMeta = (meta, version, dependencies) => ({
|
|
503
|
+
...meta.profile,
|
|
504
|
+
version,
|
|
505
|
+
...dependencies ? {
|
|
506
|
+
dependencies
|
|
507
|
+
} : {}
|
|
508
|
+
});
|
|
208
509
|
var serializeManifest = (meta, { assets, devEntry }) => {
|
|
209
|
-
const { key: _key, ...rest } = meta;
|
|
210
510
|
return JSON.stringify({
|
|
211
|
-
...
|
|
511
|
+
...meta,
|
|
212
512
|
assets,
|
|
213
513
|
...devEntry !== void 0 ? {
|
|
214
514
|
devEntry
|
|
@@ -341,7 +641,6 @@ var DEFAULT_PACKAGES = [
|
|
|
341
641
|
"@dxos/react-ui-syntax-highlighter",
|
|
342
642
|
"@dxos/react-ui-table",
|
|
343
643
|
"@dxos/react-ui-tabs",
|
|
344
|
-
"@dxos/react-ui-text-tooltip",
|
|
345
644
|
"@dxos/react-ui-thread",
|
|
346
645
|
"@dxos/solid-ui",
|
|
347
646
|
"@dxos/solid-ui-geo",
|
|
@@ -356,6 +655,33 @@ var isSharedPackage = (id) => DEFAULT_PACKAGES.some((pkg) => id === pkg || id.st
|
|
|
356
655
|
|
|
357
656
|
// src/vite-plugin/composer/index.ts
|
|
358
657
|
var JSX_DEV_RUNTIME = "react/jsx-dev-runtime";
|
|
658
|
+
var readPackageVersion = (dir) => {
|
|
659
|
+
try {
|
|
660
|
+
return JSON.parse(readFileSync(join2(dir, "package.json"), "utf-8")).version ?? "0.0.0";
|
|
661
|
+
} catch {
|
|
662
|
+
return "0.0.0";
|
|
663
|
+
}
|
|
664
|
+
};
|
|
665
|
+
var readResolvedDependencies = (dir) => {
|
|
666
|
+
try {
|
|
667
|
+
const declared = JSON.parse(readFileSync(join2(dir, "package.json"), "utf-8")).dependencies;
|
|
668
|
+
if (!declared) {
|
|
669
|
+
return void 0;
|
|
670
|
+
}
|
|
671
|
+
const resolved = {};
|
|
672
|
+
for (const name of Object.keys(declared)) {
|
|
673
|
+
try {
|
|
674
|
+
const version = JSON.parse(readFileSync(join2(dir, "node_modules", name, "package.json"), "utf-8")).version;
|
|
675
|
+
resolved[name] = typeof version === "string" ? version : declared[name];
|
|
676
|
+
} catch {
|
|
677
|
+
resolved[name] = declared[name];
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
return Object.keys(resolved).length > 0 ? resolved : void 0;
|
|
681
|
+
} catch {
|
|
682
|
+
return void 0;
|
|
683
|
+
}
|
|
684
|
+
};
|
|
359
685
|
var isExternal = (id) => id !== JSX_DEV_RUNTIME && isSharedPackage(id);
|
|
360
686
|
var REQUIRE_SHIM_BANNER = [
|
|
361
687
|
"// --- composer-plugin: CJS require shim ---",
|
|
@@ -381,7 +707,8 @@ var REQUIRE_SHIM_BANNER = [
|
|
|
381
707
|
var composerPlugin = (options) => {
|
|
382
708
|
const entry = options?.entry ?? "src/plugin.tsx";
|
|
383
709
|
const port = options?.port ?? PLUGIN_DEV_SERVER_PORT;
|
|
384
|
-
const
|
|
710
|
+
const projectRoot = process.cwd();
|
|
711
|
+
const metaPromise = options?.meta ? Promise.resolve(options.meta) : Promise.resolve(options?.config ?? findDxConfigFile(projectRoot)).then((configFile) => configFile ? loadDxConfig(configFile).then((config) => toBuildMeta(plugin_exports.getMetaFromConfig(config), readPackageVersion(projectRoot), readResolvedDependencies(projectRoot))) : void 0);
|
|
385
712
|
const resolved = /* @__PURE__ */ new Set();
|
|
386
713
|
let base = "/";
|
|
387
714
|
const plugins = [
|
|
@@ -533,53 +860,59 @@ var composerPlugin = (options) => {
|
|
|
533
860
|
}
|
|
534
861
|
}
|
|
535
862
|
];
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
type: "asset",
|
|
549
|
-
fileName: MANIFEST_ASSET_NAME,
|
|
550
|
-
source: serializeManifest(meta, {
|
|
551
|
-
assets
|
|
552
|
-
})
|
|
553
|
-
});
|
|
863
|
+
plugins.push({
|
|
864
|
+
name: "composer-plugin:emit-manifest",
|
|
865
|
+
apply: "build",
|
|
866
|
+
// `enforce: 'post'` is load-bearing: vite's CSS extraction plugin emits sibling
|
|
867
|
+
// `.css` assets in its own `generateBundle` hook. Without `post`, ours runs first
|
|
868
|
+
// and sees only the JS chunks — the manifest then omits CSS, so the host can't
|
|
869
|
+
// inject `<link>` tags for the plugin's stylesheet at install time.
|
|
870
|
+
enforce: "post",
|
|
871
|
+
async generateBundle(_options, bundle) {
|
|
872
|
+
const meta = await metaPromise;
|
|
873
|
+
if (!meta) {
|
|
874
|
+
return;
|
|
554
875
|
}
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
res.end(body);
|
|
573
|
-
});
|
|
876
|
+
const assets = Object.keys(bundle).filter((name) => name !== MANIFEST_ASSET_NAME && !name.endsWith(".map")).sort();
|
|
877
|
+
this.emitFile({
|
|
878
|
+
type: "asset",
|
|
879
|
+
fileName: MANIFEST_ASSET_NAME,
|
|
880
|
+
source: serializeManifest(meta, {
|
|
881
|
+
assets
|
|
882
|
+
})
|
|
883
|
+
});
|
|
884
|
+
}
|
|
885
|
+
});
|
|
886
|
+
plugins.push({
|
|
887
|
+
name: "composer-plugin:serve-manifest",
|
|
888
|
+
apply: "serve",
|
|
889
|
+
async configureServer(server) {
|
|
890
|
+
const meta = await metaPromise;
|
|
891
|
+
if (!meta) {
|
|
892
|
+
return;
|
|
574
893
|
}
|
|
575
|
-
|
|
576
|
-
|
|
894
|
+
const body = serializeManifest(meta, {
|
|
895
|
+
assets: [],
|
|
896
|
+
devEntry: entry.replace(/^\.?\//, "")
|
|
897
|
+
});
|
|
898
|
+
server.middlewares.use(`/${MANIFEST_ASSET_NAME}`, (req, res, next) => {
|
|
899
|
+
if (req.url && req.url !== "/" && req.url !== "") {
|
|
900
|
+
return next();
|
|
901
|
+
}
|
|
902
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
903
|
+
res.setHeader("Content-Type", "application/json");
|
|
904
|
+
res.setHeader("Cache-Control", "no-store");
|
|
905
|
+
res.statusCode = 200;
|
|
906
|
+
res.end(body);
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
});
|
|
577
910
|
return plugins;
|
|
578
911
|
};
|
|
579
912
|
|
|
580
913
|
// src/vite-plugin/import-map/index.ts
|
|
581
914
|
import { init as initCjsLexer, parse as parseCjs } from "cjs-module-lexer";
|
|
582
|
-
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
915
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync, statSync } from "node:fs";
|
|
583
916
|
import { createRequire as nodeCreateRequire } from "node:module";
|
|
584
917
|
import path from "node:path";
|
|
585
918
|
var require2 = nodeCreateRequire(import.meta.url);
|
|
@@ -595,9 +928,9 @@ var resolvedIdIsEsmModule = (resolvedId) => {
|
|
|
595
928
|
let directory = path.dirname(file);
|
|
596
929
|
while (directory !== path.dirname(directory)) {
|
|
597
930
|
const packageJsonPath = path.join(directory, "package.json");
|
|
598
|
-
if (
|
|
931
|
+
if (existsSync2(packageJsonPath)) {
|
|
599
932
|
try {
|
|
600
|
-
const pkg = JSON.parse(
|
|
933
|
+
const pkg = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
|
|
601
934
|
return pkg.type === "module";
|
|
602
935
|
} catch {
|
|
603
936
|
return false;
|
|
@@ -611,9 +944,9 @@ var findPackageJsonPath = (resolvedId, packageName) => {
|
|
|
611
944
|
let directory = path.dirname(trimQueryString(resolvedId));
|
|
612
945
|
while (directory !== path.dirname(directory)) {
|
|
613
946
|
const packageJsonPath = path.join(directory, "package.json");
|
|
614
|
-
if (
|
|
947
|
+
if (existsSync2(packageJsonPath)) {
|
|
615
948
|
try {
|
|
616
|
-
const packageJson = JSON.parse(
|
|
949
|
+
const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
|
|
617
950
|
if (packageJson.name === packageName) {
|
|
618
951
|
return packageJsonPath;
|
|
619
952
|
}
|
|
@@ -685,7 +1018,7 @@ var BUILD_TOOL_SUBPATH = /^(vite-plugin|esbuild-plugin|rollup-plugin|plugin)$/;
|
|
|
685
1018
|
var ASSET_SUBPATH = /\.(css|pcss|scss|sass|less|json|node|wasm|html|svg|png|jpe?g|gif|webp|ico)$/;
|
|
686
1019
|
var isAssetSubpath = (specifier) => ASSET_SUBPATH.test(specifier);
|
|
687
1020
|
var walkDirectoryForExtension = (baseDir, extension) => {
|
|
688
|
-
if (!
|
|
1021
|
+
if (!existsSync2(baseDir)) {
|
|
689
1022
|
return [];
|
|
690
1023
|
}
|
|
691
1024
|
const results = [];
|
|
@@ -743,7 +1076,7 @@ var expandWildcardExport = (packageName, packageJsonDir, exportKey, exportValue)
|
|
|
743
1076
|
return files.map((relativeNoExt) => `${packageName}/${keyPrefix}${relativeNoExt}`);
|
|
744
1077
|
};
|
|
745
1078
|
var getPackageEntrypoints = (packageName, packageJsonPath) => {
|
|
746
|
-
const packageJson = JSON.parse(
|
|
1079
|
+
const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
|
|
747
1080
|
const exportsField = packageJson.exports;
|
|
748
1081
|
if (!exportsField || typeof exportsField === "string" || Array.isArray(exportsField)) {
|
|
749
1082
|
return [
|
|
@@ -792,7 +1125,7 @@ var getCjsNamedExports = (filePath, seen = /* @__PURE__ */ new Set()) => {
|
|
|
792
1125
|
}
|
|
793
1126
|
seen.add(normalized);
|
|
794
1127
|
try {
|
|
795
|
-
const source =
|
|
1128
|
+
const source = readFileSync2(normalized, "utf8");
|
|
796
1129
|
const { exports: directExports, reexports } = parseCjs(source);
|
|
797
1130
|
const reexportedNames = reexports.flatMap((reexport) => {
|
|
798
1131
|
const resolved = path.resolve(path.dirname(normalized), reexport);
|
|
@@ -801,7 +1134,7 @@ var getCjsNamedExports = (filePath, seen = /* @__PURE__ */ new Set()) => {
|
|
|
801
1134
|
`${resolved}.js`,
|
|
802
1135
|
`${resolved}.cjs`
|
|
803
1136
|
];
|
|
804
|
-
const found = candidates.find((candidate) =>
|
|
1137
|
+
const found = candidates.find((candidate) => existsSync2(candidate));
|
|
805
1138
|
return found ? getCjsNamedExports(found, seen) : [];
|
|
806
1139
|
});
|
|
807
1140
|
return [
|
|
@@ -970,8 +1303,10 @@ export {
|
|
|
970
1303
|
MANIFEST_ASSET_NAME,
|
|
971
1304
|
bootLoaderPlugin,
|
|
972
1305
|
composerPlugin,
|
|
1306
|
+
findDxConfigFile,
|
|
973
1307
|
importMapPlugin,
|
|
974
1308
|
isSharedPackage,
|
|
1309
|
+
loadDxConfig,
|
|
975
1310
|
serializeManifest
|
|
976
1311
|
};
|
|
977
1312
|
//# sourceMappingURL=index.mjs.map
|