@animus-ui/vite-plugin 0.1.37 → 0.1.39
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/README.md +34 -0
- package/client.d.ts +29 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +17 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/context.d.ts +13 -2
- package/dist/context.d.ts.map +1 -1
- package/dist/index-html.d.ts +12 -1
- package/dist/index-html.d.ts.map +1 -1
- package/dist/index.cjs +228 -52
- package/dist/index.d.ts +14 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/virtual-modules.d.ts +6 -0
- package/dist/virtual-modules.d.ts.map +1 -1
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -23,6 +23,8 @@ export default defineConfig({
|
|
|
23
23
|
|
|
24
24
|
The `system` option points to the file that exports your built system instance. The plugin loads this file in a subprocess to serialize the prop config and theme data for the Rust extraction pipeline.
|
|
25
25
|
|
|
26
|
+
TypeScript apps get the plugin's virtual modules (`virtual:animus/styles.css`, `virtual:animus/font-preloads`) typed with `/// <reference types="@animus-ui/vite-plugin/client" />` or `"types": ["@animus-ui/vite-plugin/client"]` in `tsconfig.json`.
|
|
27
|
+
|
|
26
28
|
## What It Does
|
|
27
29
|
|
|
28
30
|
1. **Build time**: Analyzes all files importing from `@animus-ui/system`, extracts static styles into CSS with `@layer` ordering
|
|
@@ -137,6 +139,38 @@ file can delay first paint by seconds on a slow link. A preloaded file that
|
|
|
137
139
|
is not WOFF2 or WOFF, or an `asset()` file over 150 KB, reports
|
|
138
140
|
`animus.style.font-face-preload-costly`.
|
|
139
141
|
|
|
142
|
+
## Split stylesheets
|
|
143
|
+
|
|
144
|
+
`stylesheets: 'split'` builds the stylesheet as three files instead of one,
|
|
145
|
+
each a consecutive slice of the single sheet, in its order:
|
|
146
|
+
|
|
147
|
+
1. foundation: theme variables and color modes, `@property` registrations,
|
|
148
|
+
and `anm-global` (resets, `@font-face`, keyframes), with any
|
|
149
|
+
`quarantine` sheets;
|
|
150
|
+
2. components: `anm-base`, `anm-variants`, `anm-compounds`, `anm-states`;
|
|
151
|
+
3. utilities: `anm-system`, `anm-custom`.
|
|
152
|
+
|
|
153
|
+
Each page links them in that order exactly where Vite places the single sheet
|
|
154
|
+
among the app's own CSS, as ordinary render-blocking stylesheets: app CSS
|
|
155
|
+
bundled with it keeps its place before or after the three files. They hold
|
|
156
|
+
the single sheet's rules in its order, so the cascade is unchanged; Vite
|
|
157
|
+
minifies each file on its own, which leaves its bytes the same apart from
|
|
158
|
+
the newline ending each file. Their URLs are the ones Vite gives its own
|
|
159
|
+
links, through `base` and `experimental.renderBuiltUrl`.
|
|
160
|
+
Each file is named by its content, so a browser keeps its cached copy of a
|
|
161
|
+
file an edit leaves alone: an edit to a component's styles changes only the
|
|
162
|
+
components file. The three files compress slightly worse than one (about
|
|
163
|
+
0.1% more gzip on a large app).
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
animusExtract({ system: './src/ds.ts', stylesheets: 'split' });
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
A split build needs a page Vite builds from HTML that links the stylesheet,
|
|
170
|
+
which is where the links go: one with no page, or whose stylesheet only a lazy
|
|
171
|
+
chunk loads, fails. The dev server keeps one sheet. `'single'` (the default)
|
|
172
|
+
is one sheet the bundle imports.
|
|
173
|
+
|
|
140
174
|
## Third-party stylesheets
|
|
141
175
|
|
|
142
176
|
A library's plain CSS outside any `@layer` beats every Animus layer. With
|
package/client.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// The modules @animus-ui/vite-plugin serves to app code. Reference them with
|
|
2
|
+
// `/// <reference types="@animus-ui/vite-plugin/client" />`, or with
|
|
3
|
+
// `"types": ["@animus-ui/vite-plugin/client"]` in tsconfig.json. Free of the
|
|
4
|
+
// plugin's own (Node) types, so a browser tsconfig needs nothing more.
|
|
5
|
+
|
|
6
|
+
/** Animus's stylesheet: import it once, from the app's entry. */
|
|
7
|
+
declare module 'virtual:animus/styles.css' {}
|
|
8
|
+
|
|
9
|
+
/** Each font file this build preloads, at the URL index.html preloads it,
|
|
10
|
+
* with the faces that preload it. */
|
|
11
|
+
declare module 'virtual:animus/font-preloads' {
|
|
12
|
+
/** A face that preloads a file: its family, as `fontPreloads` matches
|
|
13
|
+
* it, and the descriptors it declares. */
|
|
14
|
+
interface PreloadedFontFace {
|
|
15
|
+
family: string;
|
|
16
|
+
weight?: string;
|
|
17
|
+
style?: string;
|
|
18
|
+
unicodeRange?: string;
|
|
19
|
+
}
|
|
20
|
+
/** A preloaded font file: the plugin's `FontPreload`. */
|
|
21
|
+
interface FontPreload {
|
|
22
|
+
href: string;
|
|
23
|
+
/** The file's MIME type, where its format names a known one. */
|
|
24
|
+
type?: string;
|
|
25
|
+
faces?: PreloadedFontFace[];
|
|
26
|
+
}
|
|
27
|
+
const preloads: ReadonlyArray<FontPreload>;
|
|
28
|
+
export default preloads;
|
|
29
|
+
}
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAE3C,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,cAAc,GACrB,IAAI,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAE3C,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,cAAc,GACrB,IAAI,CAkFN"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { StylesheetSlice } from '@animus-ui/extract/pipeline';
|
|
1
2
|
/**
|
|
2
3
|
* The namespace every virtual module here lives under; the `transform` guard
|
|
3
4
|
* matches on this same string so a rename cannot strand it.
|
|
@@ -5,6 +6,18 @@
|
|
|
5
6
|
export declare const VIRTUAL_PREFIX = "virtual:animus/";
|
|
6
7
|
export declare const VIRTUAL_CSS_ID = "virtual:animus/styles.css";
|
|
7
8
|
export declare const RESOLVED_CSS_ID = "\0virtual:animus/styles.css";
|
|
9
|
+
/** A slice of the stylesheet, which `stylesheets: 'split'` builds emit as
|
|
10
|
+
* a file of its own. */
|
|
11
|
+
export declare const sliceStylesheetId: (slice: StylesheetSlice) => string;
|
|
12
|
+
export declare const RESOLVED_SLICE_IDS: ReadonlyMap<string, StylesheetSlice>;
|
|
13
|
+
/**
|
|
14
|
+
* What the stylesheet module holds in a split build: one rule that keeps
|
|
15
|
+
* the stylesheet's place in Vite's CSS, where the page's links to the
|
|
16
|
+
* slices then go. Its own property, so no minifier merges or drops it.
|
|
17
|
+
*/
|
|
18
|
+
export declare const SPLIT_STYLESHEET_MARKER = ".animus-split-stylesheet{--animus-split-stylesheet:1}";
|
|
19
|
+
/** The marker as a built stylesheet spells it, minified or not. */
|
|
20
|
+
export declare const SPLIT_STYLESHEET_MARKER_RE: RegExp;
|
|
8
21
|
export declare const VIRTUAL_COMPONENTS_ID = "virtual:animus/components.js";
|
|
9
22
|
export declare const RESOLVED_COMPONENTS_ID = "\0virtual:animus/components.js";
|
|
10
23
|
export declare const VIRTUAL_BRIDGE_ID = "virtual:animus/hmr-bridge.js";
|
|
@@ -16,5 +29,9 @@ export declare const RESOLVED_BRIDGE_ID = "\0virtual:animus/hmr-bridge.js";
|
|
|
16
29
|
export declare const BRIDGE_SCRIPT_SRC = "/@id/virtual:animus/hmr-bridge.js";
|
|
17
30
|
export declare const VIRTUAL_SYSTEM_PROPS_ID = "virtual:animus/system-props";
|
|
18
31
|
export declare const RESOLVED_SYSTEM_PROPS_ID = "\0virtual:animus/system-props";
|
|
32
|
+
/** The faces this build preloads, with the URL each file is preloaded at:
|
|
33
|
+
* the module every host serves under this id. */
|
|
34
|
+
export declare const VIRTUAL_FONT_PRELOADS_ID = "virtual:animus/font-preloads";
|
|
35
|
+
export declare const RESOLVED_FONT_PRELOADS_ID = "\0virtual:animus/font-preloads";
|
|
19
36
|
export { DEFAULT_EXCLUDE } from '@animus-ui/extract/pipeline';
|
|
20
37
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE;;;GAGG;AACH,eAAO,MAAM,cAAc,oBAAoB,CAAC;AAEhD,eAAO,MAAM,cAAc,8BAAgC,CAAC;AAC5D,eAAO,MAAM,eAAe,gCAAwB,CAAC;AAErD;yBACyB;AACzB,eAAO,MAAM,iBAAiB,UAAW,eAAe,KAAG,MACnB,CAAC;AACzC,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAEnE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,0DACqB,CAAC;AAC1D,mEAAmE;AACnE,eAAO,MAAM,0BAA0B,QAC4C,CAAC;AAEpF,eAAO,MAAM,qBAAqB,iCAAmC,CAAC;AACtE,eAAO,MAAM,sBAAsB,mCAA+B,CAAC;AAEnE,eAAO,MAAM,iBAAiB,iCAAmC,CAAC;AAClE,eAAO,MAAM,kBAAkB,mCAA2B,CAAC;AAE3D;;;GAGG;AACH,eAAO,MAAM,iBAAiB,sCAA8B,CAAC;AAE7D,eAAO,MAAM,uBAAuB,gCAAkC,CAAC;AACvE,eAAO,MAAM,wBAAwB,kCAAiC,CAAC;AAEvE;kDACkD;AAClD,eAAO,MAAM,wBAAwB,iCAA0B,CAAC;AAChE,eAAO,MAAM,yBAAyB,mCAAkC,CAAC;AAIzE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC"}
|
package/dist/context.d.ts
CHANGED
|
@@ -2,9 +2,9 @@ import { EnvironmentBuilds, ExtractionSession } from '@animus-ui/extract/session
|
|
|
2
2
|
import { HotUpdateEvents } from './hot-update-events';
|
|
3
3
|
import type { LightningTargets } from './css';
|
|
4
4
|
import type { AnimusExtractOptions } from './index';
|
|
5
|
-
import type { ExcludeMatcher, ExternalPackageOutcome, HostAssetClassification, HostExtensionPolicy, HostLoadExpander, ProjectManifest, SystemConfig } from '@animus-ui/extract/pipeline';
|
|
5
|
+
import type { ExcludeMatcher, ExternalPackageOutcome, FontPreload, HostAssetClassification, HostExtensionPolicy, HostLoadExpander, ProjectManifest, SystemConfig } from '@animus-ui/extract/pipeline';
|
|
6
6
|
import type { SessionOutcome, SessionPublication, WatchChanges } from '@animus-ui/extract/session';
|
|
7
|
-
import type { Logger } from 'vite';
|
|
7
|
+
import type { Logger, ResolvedConfig } from 'vite';
|
|
8
8
|
/** A Session outcome, and whether its publication changed the served
|
|
9
9
|
* system-props module. */
|
|
10
10
|
export interface ObservedOutcome {
|
|
@@ -23,6 +23,9 @@ export declare class PluginContext {
|
|
|
23
23
|
/** Emission mode (the explicit `mode` option wins over the command); feeds
|
|
24
24
|
* engine devMode and the minify default. Lifecycle stays on `isProd`. */
|
|
25
25
|
emissionProd: boolean;
|
|
26
|
+
/** A build that links the stylesheet's slices from each page, in place of
|
|
27
|
+
* the one sheet the CSS module carries; the dev server keeps one sheet. */
|
|
28
|
+
get splitsStylesheet(): boolean;
|
|
26
29
|
rootDir: string;
|
|
27
30
|
logger: Logger | null;
|
|
28
31
|
lcssTargets: LightningTargets;
|
|
@@ -73,6 +76,10 @@ export declare class PluginContext {
|
|
|
73
76
|
* without re-analysis. */
|
|
74
77
|
get globalCss(): string;
|
|
75
78
|
get resolvedComponentCss(): string;
|
|
79
|
+
/** The published font preloads, each by the URL the stylesheet's own
|
|
80
|
+
* `url()` gets: what index.html preloads and the font-preloads module
|
|
81
|
+
* exports. */
|
|
82
|
+
get fontPreloads(): FontPreload[];
|
|
76
83
|
private analysisSheets;
|
|
77
84
|
private substitutedSheets;
|
|
78
85
|
layerDeclaration: string;
|
|
@@ -87,6 +94,7 @@ export declare class PluginContext {
|
|
|
87
94
|
/** Coalesces a burst of invalidations into one full reload. */
|
|
88
95
|
private readonly reloadWindow;
|
|
89
96
|
base: string;
|
|
97
|
+
renderBuiltUrl: ResolvedConfig['experimental']['renderBuiltUrl'];
|
|
90
98
|
/** Vite's root and `server.origin`, which a dev asset URL is served
|
|
91
99
|
* under. */
|
|
92
100
|
viteRoot: string;
|
|
@@ -179,6 +187,9 @@ export declare class PluginContext {
|
|
|
179
187
|
/** A root-relative URL a face names as written, as Vite's dev CSS pass
|
|
180
188
|
* writes it: under `server.origin` and the base where it names a public
|
|
181
189
|
* file or a file under the root, else unchanged. */
|
|
190
|
+
/** Whether `href` is a root-relative URL of a file Vite serves, from its
|
|
191
|
+
* public directory or its root. */
|
|
192
|
+
servesRootRelative(href: string): boolean;
|
|
182
193
|
devRootRelativeUrl(href: string): string;
|
|
183
194
|
/** A dev asset() URL: an immutable content-named copy of `absPath`, so an
|
|
184
195
|
* edit gets a new URL, or the live file where copies are not served. */
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
|
package/dist/index-html.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PluginContext } from './context';
|
|
2
|
-
import type { HtmlTagDescriptor } from 'vite';
|
|
2
|
+
import type { HtmlTagDescriptor, Rolldown } from 'vite';
|
|
3
3
|
/**
|
|
4
4
|
* The hrefs a finished document preloads both through Animus's tag and
|
|
5
5
|
* through another, which the page wrote or a hook running after Animus's
|
|
@@ -21,4 +21,15 @@ export declare function injectHeadTags(html: string, tags: HtmlTagDescriptor[]):
|
|
|
21
21
|
* the font preloads, then the development bridge.
|
|
22
22
|
*/
|
|
23
23
|
export declare function buildIndexHtmlTags(ctx: PluginContext, html?: string): HtmlTagDescriptor[];
|
|
24
|
+
/**
|
|
25
|
+
* Puts a split build's slices where the single stylesheet would have been.
|
|
26
|
+
* The stylesheet module held only a marker rule, so it kept its place in
|
|
27
|
+
* Vite's CSS: the file holding the marker is cut there, and each page's
|
|
28
|
+
* link to it becomes the file's CSS before the marker, the slices in
|
|
29
|
+
* order, then its CSS after the marker, in a file of its own when CSS
|
|
30
|
+
* precedes the marker too. A carrier left empty is kept, unlinked, for a
|
|
31
|
+
* lazy chunk that names it. The build fails when no page links the
|
|
32
|
+
* carrier: its stylesheet loads with a lazy chunk, or no page is built.
|
|
33
|
+
*/
|
|
34
|
+
export declare function placeStylesheetSlices(ctx: PluginContext, bundle: Rolldown.OutputBundle, sliceIds: readonly string[], emitAsset: (name: string, source: string) => string): void;
|
|
24
35
|
//# sourceMappingURL=index-html.d.ts.map
|
package/dist/index-html.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-html.d.ts","sourceRoot":"","sources":["../src/index-html.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index-html.d.ts","sourceRoot":"","sources":["../src/index-html.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AA0CxD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,MAAM,EAAE,CAeV;AAsED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,iBAAiB,EAAE,GACxB,MAAM,GAAG,iBAAiB,EAAE,CAU9B;AA0BD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,aAAa,EAClB,IAAI,SAAK,GACR,iBAAiB,EAAE,CAuCrB;AAsCD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,QAAQ,CAAC,YAAY,EAC7B,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,GAClD,IAAI,CAuFN"}
|
package/dist/index.cjs
CHANGED
|
@@ -204,6 +204,7 @@ function applyResolvedConfig(ctx, config) {
|
|
|
204
204
|
ctx.log(`extension order: ${ctx.extensionPolicy.resolverVersion}`);
|
|
205
205
|
ctx.logger = config.logger;
|
|
206
206
|
ctx.base = config.base ?? "/";
|
|
207
|
+
ctx.renderBuiltUrl = config.experimental.renderBuiltUrl;
|
|
207
208
|
ctx.viteRoot = config.root;
|
|
208
209
|
ctx.serverOrigin = config.server.origin ?? "";
|
|
209
210
|
ctx.publicDir = config.publicDir;
|
|
@@ -235,6 +236,18 @@ function applyResolvedConfig(ctx, config) {
|
|
|
235
236
|
const VIRTUAL_PREFIX = "virtual:animus/";
|
|
236
237
|
const VIRTUAL_CSS_ID = `${VIRTUAL_PREFIX}styles.css`;
|
|
237
238
|
const RESOLVED_CSS_ID = `\0${VIRTUAL_CSS_ID}`;
|
|
239
|
+
/** A slice of the stylesheet, which `stylesheets: 'split'` builds emit as
|
|
240
|
+
* a file of its own. */
|
|
241
|
+
const sliceStylesheetId = (slice) => `${VIRTUAL_PREFIX}styles.${slice}.css`;
|
|
242
|
+
const RESOLVED_SLICE_IDS = new Map(_animus_ui_extract_pipeline.STYLESHEET_SLICES.map((slice) => [`\0${sliceStylesheetId(slice)}`, slice]));
|
|
243
|
+
/**
|
|
244
|
+
* What the stylesheet module holds in a split build: one rule that keeps
|
|
245
|
+
* the stylesheet's place in Vite's CSS, where the page's links to the
|
|
246
|
+
* slices then go. Its own property, so no minifier merges or drops it.
|
|
247
|
+
*/
|
|
248
|
+
const SPLIT_STYLESHEET_MARKER = ".animus-split-stylesheet{--animus-split-stylesheet:1}";
|
|
249
|
+
/** The marker as a built stylesheet spells it, minified or not. */
|
|
250
|
+
const SPLIT_STYLESHEET_MARKER_RE = /\.animus-split-stylesheet\s*\{\s*--animus-split-stylesheet\s*:\s*1\s*;?\s*\}\n?/;
|
|
238
251
|
const VIRTUAL_COMPONENTS_ID = `${VIRTUAL_PREFIX}components.js`;
|
|
239
252
|
const RESOLVED_COMPONENTS_ID = `\0${VIRTUAL_COMPONENTS_ID}`;
|
|
240
253
|
const VIRTUAL_BRIDGE_ID = `${VIRTUAL_PREFIX}hmr-bridge.js`;
|
|
@@ -246,6 +259,10 @@ const RESOLVED_BRIDGE_ID = `\0${VIRTUAL_BRIDGE_ID}`;
|
|
|
246
259
|
const BRIDGE_SCRIPT_SRC = `/@id/${VIRTUAL_BRIDGE_ID}`;
|
|
247
260
|
const VIRTUAL_SYSTEM_PROPS_ID = `${VIRTUAL_PREFIX}system-props`;
|
|
248
261
|
const RESOLVED_SYSTEM_PROPS_ID = `\0${VIRTUAL_SYSTEM_PROPS_ID}`;
|
|
262
|
+
/** The faces this build preloads, with the URL each file is preloaded at:
|
|
263
|
+
* the module every host serves under this id. */
|
|
264
|
+
const VIRTUAL_FONT_PRELOADS_ID = _animus_ui_extract_session.FONT_PRELOADS_MODULE_ID;
|
|
265
|
+
const RESOLVED_FONT_PRELOADS_ID = `\0${VIRTUAL_FONT_PRELOADS_ID}`;
|
|
249
266
|
//#endregion
|
|
250
267
|
//#region src/hot-update-events.ts
|
|
251
268
|
/**
|
|
@@ -345,6 +362,11 @@ var PluginContext = class {
|
|
|
345
362
|
/** Emission mode (the explicit `mode` option wins over the command); feeds
|
|
346
363
|
* engine devMode and the minify default. Lifecycle stays on `isProd`. */
|
|
347
364
|
emissionProd = false;
|
|
365
|
+
/** A build that links the stylesheet's slices from each page, in place of
|
|
366
|
+
* the one sheet the CSS module carries; the dev server keeps one sheet. */
|
|
367
|
+
get splitsStylesheet() {
|
|
368
|
+
return this.isProd && this.options.stylesheets === "split";
|
|
369
|
+
}
|
|
348
370
|
rootDir = "";
|
|
349
371
|
logger = null;
|
|
350
372
|
lcssTargets = {};
|
|
@@ -419,6 +441,15 @@ var PluginContext = class {
|
|
|
419
441
|
get resolvedComponentCss() {
|
|
420
442
|
return this.substitutedSheets().componentCss;
|
|
421
443
|
}
|
|
444
|
+
/** The published font preloads, each by the URL the stylesheet's own
|
|
445
|
+
* `url()` gets: what index.html preloads and the font-preloads module
|
|
446
|
+
* exports. */
|
|
447
|
+
get fontPreloads() {
|
|
448
|
+
return (0, _animus_ui_extract_pipeline.substituteFontPreloads)(this.served?.fontPreloads, this.assetUrlBySpecifier).map((preload) => this.isProd ? preload : {
|
|
449
|
+
...preload,
|
|
450
|
+
href: this.devRootRelativeUrl(preload.href)
|
|
451
|
+
});
|
|
452
|
+
}
|
|
422
453
|
analysisSheets() {
|
|
423
454
|
return {
|
|
424
455
|
...NO_SHEETS,
|
|
@@ -445,6 +476,7 @@ var PluginContext = class {
|
|
|
445
476
|
this.devServer?.hot?.send({ type: "full-reload" });
|
|
446
477
|
});
|
|
447
478
|
base = "/";
|
|
479
|
+
renderBuiltUrl;
|
|
448
480
|
/** Vite's root and `server.origin`, which a dev asset URL is served
|
|
449
481
|
* under. */
|
|
450
482
|
viteRoot = "";
|
|
@@ -676,15 +708,20 @@ var PluginContext = class {
|
|
|
676
708
|
/** A root-relative URL a face names as written, as Vite's dev CSS pass
|
|
677
709
|
* writes it: under `server.origin` and the base where it names a public
|
|
678
710
|
* file or a file under the root, else unchanged. */
|
|
679
|
-
|
|
680
|
-
|
|
711
|
+
/** Whether `href` is a root-relative URL of a file Vite serves, from its
|
|
712
|
+
* public directory or its root. */
|
|
713
|
+
servesRootRelative(href) {
|
|
714
|
+
if (!href.startsWith("/") || href.startsWith("//")) return false;
|
|
681
715
|
let path$6;
|
|
682
716
|
try {
|
|
683
717
|
path$6 = decodeURI(href.split(/[?#]/)[0]);
|
|
684
718
|
} catch {
|
|
685
|
-
return
|
|
719
|
+
return false;
|
|
686
720
|
}
|
|
687
|
-
|
|
721
|
+
return [this.publicDir, this.viteRoot].some((dir) => dir !== "" && (0, fs.existsSync)((0, path.join)(dir, path$6)));
|
|
722
|
+
}
|
|
723
|
+
devRootRelativeUrl(href) {
|
|
724
|
+
if (!this.servesRootRelative(href)) return href;
|
|
688
725
|
const base = this.base.endsWith("/") ? this.base.slice(0, -1) : this.base;
|
|
689
726
|
return `${this.serverOrigin}${base}${href}`;
|
|
690
727
|
}
|
|
@@ -778,7 +815,8 @@ var PluginContext = class {
|
|
|
778
815
|
for (const moduleId of [
|
|
779
816
|
RESOLVED_CSS_ID,
|
|
780
817
|
RESOLVED_COMPONENTS_ID,
|
|
781
|
-
RESOLVED_SYSTEM_PROPS_ID
|
|
818
|
+
RESOLVED_SYSTEM_PROPS_ID,
|
|
819
|
+
RESOLVED_FONT_PRELOADS_ID
|
|
782
820
|
]) {
|
|
783
821
|
const mod = server.moduleGraph.getModuleById(moduleId);
|
|
784
822
|
if (mod) server.moduleGraph.invalidateModule(mod);
|
|
@@ -1429,17 +1467,12 @@ function injectHeadTags(html, tags) {
|
|
|
1429
1467
|
const inserted = tags.map((tag) => `\n${indent}${serializeTag(tag)}`).join("");
|
|
1430
1468
|
return html.slice(0, offset) + inserted + html.slice(offset);
|
|
1431
1469
|
}
|
|
1432
|
-
/** The preloads for the faces that ask for one,
|
|
1433
|
-
*
|
|
1434
|
-
* preloads is left out. */
|
|
1470
|
+
/** The preloads for the faces that ask for one, each marked as Animus's;
|
|
1471
|
+
* one the document already preloads is left out. */
|
|
1435
1472
|
function fontPreloadTags(ctx, html) {
|
|
1436
|
-
|
|
1437
|
-
if (published.length === 0) return [];
|
|
1473
|
+
if (!ctx.served?.fontPreloads.length) return [];
|
|
1438
1474
|
const existing = preloadedHrefs(html);
|
|
1439
|
-
return (
|
|
1440
|
-
...preload,
|
|
1441
|
-
href: ctx.devRootRelativeUrl(preload.href)
|
|
1442
|
-
}).filter(({ href }) => !existing.has(href)).map(({ href, type }) => {
|
|
1475
|
+
return ctx.fontPreloads.filter(({ href }) => !existing.has(href)).map(({ href, type }) => {
|
|
1443
1476
|
const attrs = {
|
|
1444
1477
|
rel: "preload",
|
|
1445
1478
|
href,
|
|
@@ -1487,6 +1520,92 @@ function buildIndexHtmlTags(ctx, html = "") {
|
|
|
1487
1520
|
});
|
|
1488
1521
|
return tags;
|
|
1489
1522
|
}
|
|
1523
|
+
/**
|
|
1524
|
+
* A built file's URL in a page, as Vite writes its own links: the host's
|
|
1525
|
+
* `renderBuiltUrl` first, then relative to the page under a relative base,
|
|
1526
|
+
* else under the base.
|
|
1527
|
+
*/
|
|
1528
|
+
function builtUrl(ctx, page, fileName) {
|
|
1529
|
+
let relative = ctx.base === "" || ctx.base === "./";
|
|
1530
|
+
const rendered = ctx.renderBuiltUrl?.(fileName, {
|
|
1531
|
+
hostId: page,
|
|
1532
|
+
hostType: "html",
|
|
1533
|
+
type: "asset",
|
|
1534
|
+
ssr: false
|
|
1535
|
+
});
|
|
1536
|
+
if (rendered instanceof Object) {
|
|
1537
|
+
if (rendered.runtime !== void 0) throw new Error(`[animus-extract] renderBuiltUrl returned { runtime } for ${fileName}, which a page's <link> cannot load`);
|
|
1538
|
+
if (rendered.relative !== void 0) relative = rendered.relative;
|
|
1539
|
+
} else if (rendered) return rendered;
|
|
1540
|
+
if (relative) return `${path.posix.join(path.posix.relative(page, "").slice(0, -2), "./")}${fileName}`;
|
|
1541
|
+
return `${decodeURI(ctx.base).replace(/\/$/, "")}/${fileName}`;
|
|
1542
|
+
}
|
|
1543
|
+
/** `tag`, a stylesheet link, linking `href` instead, with `attributes`. */
|
|
1544
|
+
function linkingInstead(tag, href, attributes = "") {
|
|
1545
|
+
return tag.replace(HREF_RE, ` href="${escapeHtml(href)}"`).replace(/\s*\/?>$/, `${attributes}>`);
|
|
1546
|
+
}
|
|
1547
|
+
/**
|
|
1548
|
+
* Puts a split build's slices where the single stylesheet would have been.
|
|
1549
|
+
* The stylesheet module held only a marker rule, so it kept its place in
|
|
1550
|
+
* Vite's CSS: the file holding the marker is cut there, and each page's
|
|
1551
|
+
* link to it becomes the file's CSS before the marker, the slices in
|
|
1552
|
+
* order, then its CSS after the marker, in a file of its own when CSS
|
|
1553
|
+
* precedes the marker too. A carrier left empty is kept, unlinked, for a
|
|
1554
|
+
* lazy chunk that names it. The build fails when no page links the
|
|
1555
|
+
* carrier: its stylesheet loads with a lazy chunk, or no page is built.
|
|
1556
|
+
*/
|
|
1557
|
+
function placeStylesheetSlices(ctx, bundle, sliceIds, emitAsset) {
|
|
1558
|
+
const fileOf = /* @__PURE__ */ new Map();
|
|
1559
|
+
const pages = [];
|
|
1560
|
+
const carriers = [];
|
|
1561
|
+
for (const file of Object.values(bundle)) {
|
|
1562
|
+
if (file.type !== "asset") continue;
|
|
1563
|
+
if (file.fileName.endsWith(".html")) pages.push(file);
|
|
1564
|
+
if (file.fileName.endsWith(".css") && SPLIT_STYLESHEET_MARKER_RE.test(String(file.source))) carriers.push(file);
|
|
1565
|
+
const id = sliceIds.find((slice) => file.originalFileNames.some((name) => name.endsWith(slice)));
|
|
1566
|
+
if (id !== void 0) fileOf.set(id, file.fileName);
|
|
1567
|
+
}
|
|
1568
|
+
const slices = sliceIds.map((id) => {
|
|
1569
|
+
const fileName = fileOf.get(id);
|
|
1570
|
+
if (fileName === void 0) throw new Error(`[animus-extract] stylesheets: 'split' emitted ${id}, and the bundle holds no file for it, so the stylesheet would load without it.`);
|
|
1571
|
+
return fileName;
|
|
1572
|
+
});
|
|
1573
|
+
if (carriers.length === 0) {
|
|
1574
|
+
for (const fileName of slices) delete bundle[fileName];
|
|
1575
|
+
return;
|
|
1576
|
+
}
|
|
1577
|
+
if (carriers.length > 1) throw new Error(`[animus-extract] stylesheets: 'split' found Animus's stylesheet in ${carriers.map((file) => file.fileName).join(" and ")}, and places it once.`);
|
|
1578
|
+
const carrier = carriers[0];
|
|
1579
|
+
const text = String(carrier.source);
|
|
1580
|
+
const marker = SPLIT_STYLESHEET_MARKER_RE.exec(text);
|
|
1581
|
+
const before = text.slice(0, marker.index);
|
|
1582
|
+
const after = text.slice(marker.index + marker[0].length);
|
|
1583
|
+
const precedes = before.trim() !== "";
|
|
1584
|
+
const follows = after.trim() !== "";
|
|
1585
|
+
carrier.source = precedes ? before : after;
|
|
1586
|
+
const rest = precedes && follows ? emitAsset(carrier.names[0] ?? "index.css", after) : null;
|
|
1587
|
+
const sequence = [
|
|
1588
|
+
...precedes ? [null] : [],
|
|
1589
|
+
...slices,
|
|
1590
|
+
...follows ? [rest] : []
|
|
1591
|
+
];
|
|
1592
|
+
let linked = false;
|
|
1593
|
+
for (const page of pages) {
|
|
1594
|
+
const html = Buffer.from(page.source).toString("utf8");
|
|
1595
|
+
const carrierUrl = builtUrl(ctx, page.fileName, carrier.fileName);
|
|
1596
|
+
page.source = html.replace(LINK_TAG_RE, (tag, offset) => {
|
|
1597
|
+
const rel = attribute(tag, REL_RE)?.toLowerCase().split(/\s+/) ?? [];
|
|
1598
|
+
const href = attribute(tag, HREF_RE);
|
|
1599
|
+
if (!rel.includes("stylesheet") || href === void 0) return tag;
|
|
1600
|
+
if (attributeText(href) !== carrierUrl) return tag;
|
|
1601
|
+
linked = true;
|
|
1602
|
+
const lineStart = html.lastIndexOf("\n", offset - 1) + 1;
|
|
1603
|
+
const indent = /^[ \t]*/.exec(html.slice(lineStart))[0];
|
|
1604
|
+
return sequence.map((fileName) => fileName === null ? tag : linkingInstead(tag, builtUrl(ctx, page.fileName, fileName), fileName === rest ? "" : " data-animus-stylesheet")).join(`\n${indent}`);
|
|
1605
|
+
});
|
|
1606
|
+
}
|
|
1607
|
+
if (!linked) throw new Error(`[animus-extract] stylesheets: 'split' links the stylesheet's files where a page links ${carrier.fileName}, which holds Animus's stylesheet, and no page links it: it loads with a lazy chunk, or the build has no HTML page. Import Animus's components from the page's entry, or leave \`stylesheets\` unset for one sheet.`);
|
|
1608
|
+
}
|
|
1490
1609
|
//#endregion
|
|
1491
1610
|
//#region src/quarantine-plugin.ts
|
|
1492
1611
|
/**
|
|
@@ -1524,9 +1643,11 @@ function sheetRegistryHash(ctx) {
|
|
|
1524
1643
|
}
|
|
1525
1644
|
function resolveVirtualId(ctx, id) {
|
|
1526
1645
|
if (id === VIRTUAL_CSS_ID) return RESOLVED_CSS_ID;
|
|
1646
|
+
if (id.startsWith("virtual:animus/") && RESOLVED_SLICE_IDS.has(`\0${id}`)) return `\0${id}`;
|
|
1527
1647
|
if (id === VIRTUAL_COMPONENTS_ID) return RESOLVED_COMPONENTS_ID;
|
|
1528
1648
|
if (id === VIRTUAL_BRIDGE_ID) return RESOLVED_BRIDGE_ID;
|
|
1529
1649
|
if (id === VIRTUAL_SYSTEM_PROPS_ID) return RESOLVED_SYSTEM_PROPS_ID;
|
|
1650
|
+
if (id === VIRTUAL_FONT_PRELOADS_ID) return RESOLVED_FONT_PRELOADS_ID;
|
|
1530
1651
|
const srcEntry = ctx.externalSourceEntries.get(id);
|
|
1531
1652
|
if (srcEntry) {
|
|
1532
1653
|
const moduleSideEffects = ctx.externalSourceSideEffects.get(id);
|
|
@@ -1537,47 +1658,46 @@ function resolveVirtualId(ctx, id) {
|
|
|
1537
1658
|
}
|
|
1538
1659
|
return null;
|
|
1539
1660
|
}
|
|
1540
|
-
function
|
|
1541
|
-
|
|
1661
|
+
function lightningOptions(ctx) {
|
|
1662
|
+
return {
|
|
1542
1663
|
minify: ctx.options.minify ?? ctx.emissionProd,
|
|
1543
1664
|
targets: ctx.lcssTargets,
|
|
1544
1665
|
warnFn: (msg) => ctx.warn(msg)
|
|
1545
1666
|
};
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
}
|
|
1667
|
+
}
|
|
1668
|
+
function checked(ctx, css) {
|
|
1669
|
+
(0, _animus_ui_extract_pipeline.reportSurvivingAssetPlaceholders)(css, {
|
|
1670
|
+
strict: ctx.options.strict,
|
|
1671
|
+
warn: (message) => ctx.warn(message),
|
|
1672
|
+
reportErrors: ctx.reportErrors(),
|
|
1673
|
+
prefix: "[animus-extract]"
|
|
1674
|
+
});
|
|
1675
|
+
return css;
|
|
1676
|
+
}
|
|
1677
|
+
/**
|
|
1678
|
+
* The stylesheet `virtual:animus/styles.css` serves: the variables, then
|
|
1679
|
+
* the post-processed body. In development the component layers arrive
|
|
1680
|
+
* through the bridge's sheet instead, unminified.
|
|
1681
|
+
*/
|
|
1682
|
+
function stylesheetSource(ctx) {
|
|
1683
|
+
const bridged = !ctx.isProd && Boolean(ctx.storedManifest);
|
|
1684
|
+
const { variables, body } = (0, _animus_ui_extract_pipeline.assembleStylesheet)({
|
|
1685
|
+
layers: ctx.options.layers,
|
|
1686
|
+
variableCss: ctx.variableCss,
|
|
1687
|
+
globalCss: ctx.globalCss,
|
|
1688
|
+
componentCss: bridged ? void 0 : ctx.resolvedComponentCss,
|
|
1689
|
+
split: true
|
|
1690
|
+
});
|
|
1691
|
+
const lcssOpts = lightningOptions(ctx);
|
|
1692
|
+
if (bridged) lcssOpts.minify = false;
|
|
1693
|
+
return checked(ctx, [variables, (0, _animus_ui_extract_pipeline.postProcessCss)(body, lcssOpts)].filter(Boolean).join("\n"));
|
|
1694
|
+
}
|
|
1695
|
+
function loadVirtualModule(ctx, id) {
|
|
1696
|
+
if (id === RESOLVED_CSS_ID) return ctx.splitsStylesheet ? SPLIT_STYLESHEET_MARKER : stylesheetSource(ctx);
|
|
1577
1697
|
if (id === RESOLVED_COMPONENTS_ID) {
|
|
1578
1698
|
const strippedCss = (0, _animus_ui_extract_pipeline.stripLeadingLayerDeclaration)(ctx.resolvedComponentCss || "");
|
|
1579
|
-
return `export default \`${checked((0, _animus_ui_extract_pipeline.postProcessCss)(strippedCss, {
|
|
1580
|
-
...
|
|
1699
|
+
return `export default \`${checked(ctx, (0, _animus_ui_extract_pipeline.postProcessCss)(strippedCss, {
|
|
1700
|
+
...lightningOptions(ctx),
|
|
1581
1701
|
minify: false
|
|
1582
1702
|
})).replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$")}\`;`;
|
|
1583
1703
|
}
|
|
@@ -1624,8 +1744,29 @@ if (import.meta.hot) {
|
|
|
1624
1744
|
`;
|
|
1625
1745
|
}
|
|
1626
1746
|
if (id === RESOLVED_SYSTEM_PROPS_ID) return ctx.systemPropsModule;
|
|
1747
|
+
if (id === RESOLVED_FONT_PRELOADS_ID) return fontPreloadsSource(ctx);
|
|
1627
1748
|
return null;
|
|
1628
1749
|
}
|
|
1750
|
+
/**
|
|
1751
|
+
* The font-preloads module: each preload at the href index.html preloads it.
|
|
1752
|
+
* A build's asset placeholder becomes the emitted file's URL here as it does
|
|
1753
|
+
* in the page. A build imports a root-relative file Vite serves with `?url`,
|
|
1754
|
+
* so Vite applies its `base` here as it does to the page's preload. Not
|
|
1755
|
+
* `fontPreloadsModule`, which reads a `./` href against the module.
|
|
1756
|
+
*/
|
|
1757
|
+
function fontPreloadsSource(ctx) {
|
|
1758
|
+
const imports = [];
|
|
1759
|
+
const entries = ctx.fontPreloads.map(({ href, ...rest }) => {
|
|
1760
|
+
if (!ctx.isProd || !ctx.servesRootRelative(href) || /[?#]/.test(href)) return JSON.stringify({
|
|
1761
|
+
href,
|
|
1762
|
+
...rest
|
|
1763
|
+
});
|
|
1764
|
+
const name = `href${imports.length}`;
|
|
1765
|
+
imports.push(`import ${name} from ${JSON.stringify(`${href}?url`)};\n`);
|
|
1766
|
+
return `{ href: ${name}, ...${JSON.stringify(rest)} }`;
|
|
1767
|
+
});
|
|
1768
|
+
return `${imports.join("")}export default [${entries.join(", ")}];\n`;
|
|
1769
|
+
}
|
|
1629
1770
|
//#endregion
|
|
1630
1771
|
//#region src/watch-ignored.ts
|
|
1631
1772
|
/** A path as a glob that matches only itself. Each special character
|
|
@@ -1666,6 +1807,11 @@ async function sourceKitConfig(rootDir, systemPath, engine) {
|
|
|
1666
1807
|
/** The URL a build's root is served at, for resolving a page's hrefs: an
|
|
1667
1808
|
* absolute `base`, a root-relative one on a stand-in origin, or the root
|
|
1668
1809
|
* for a relative one, which every page resolves from its own location. */
|
|
1810
|
+
/** Whether a hook runs for the browser's environment; a host without
|
|
1811
|
+
* environments builds only that one. */
|
|
1812
|
+
function isClient(context) {
|
|
1813
|
+
return (context.environment?.config.consumer ?? "client") === "client";
|
|
1814
|
+
}
|
|
1669
1815
|
function servedBase(base) {
|
|
1670
1816
|
const origin = "https://animus.invalid/";
|
|
1671
1817
|
if (/^[a-z][a-z\d+.-]*:/i.test(base)) return new URL(base.replace(/\/?$/, "/"));
|
|
@@ -1690,6 +1836,14 @@ function animusExtract(options) {
|
|
|
1690
1836
|
...options,
|
|
1691
1837
|
layers: vendor.order
|
|
1692
1838
|
} : options);
|
|
1839
|
+
/** The stylesheet with the declared vendor sheets at its head, so they
|
|
1840
|
+
* arrive wherever it does, whatever imports it. */
|
|
1841
|
+
async function withVendorHead(context, sheet) {
|
|
1842
|
+
const layergate = await vendor?.plugin();
|
|
1843
|
+
return layergate ? await layergate.stylesheetHead.call(context, RESOLVED_CSS_ID) + sheet : sheet;
|
|
1844
|
+
}
|
|
1845
|
+
let slices = /* @__PURE__ */ new Map();
|
|
1846
|
+
let linkedSlices = [];
|
|
1693
1847
|
return {
|
|
1694
1848
|
name: "animus-extract",
|
|
1695
1849
|
enforce: "pre",
|
|
@@ -1734,6 +1888,22 @@ function animusExtract(options) {
|
|
|
1734
1888
|
name: fileName,
|
|
1735
1889
|
source
|
|
1736
1890
|
}) : void 0);
|
|
1891
|
+
if (ctx.splitsStylesheet && isClient(this)) {
|
|
1892
|
+
const sheet = await withVendorHead(this, stylesheetSource(ctx));
|
|
1893
|
+
const cut = (0, _animus_ui_extract_pipeline.splitStylesheet)(sheet);
|
|
1894
|
+
slices = new Map(cut.map(({ slice, css }) => [slice, css]));
|
|
1895
|
+
linkedSlices = [];
|
|
1896
|
+
for (const { slice, css } of cut) {
|
|
1897
|
+
if (css === "") continue;
|
|
1898
|
+
const id = sliceStylesheetId(slice);
|
|
1899
|
+
this.emitFile({
|
|
1900
|
+
type: "chunk",
|
|
1901
|
+
id,
|
|
1902
|
+
name: `animus-${slice}`
|
|
1903
|
+
});
|
|
1904
|
+
linkedSlices.push(id);
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1737
1907
|
},
|
|
1738
1908
|
async resolveId(id, importer, resolveOptions) {
|
|
1739
1909
|
const owned = await (await vendor?.plugin())?.resolveId.call(this, id, importer, resolveOptions);
|
|
@@ -1750,11 +1920,12 @@ function animusExtract(options) {
|
|
|
1750
1920
|
};
|
|
1751
1921
|
},
|
|
1752
1922
|
async load(id) {
|
|
1753
|
-
const
|
|
1754
|
-
const loaded = await layergate?.load.call(this, id);
|
|
1923
|
+
const loaded = await (await vendor?.plugin())?.load.call(this, id);
|
|
1755
1924
|
if (loaded) return loaded;
|
|
1925
|
+
const slice = RESOLVED_SLICE_IDS.get(id);
|
|
1926
|
+
if (slice !== void 0) return slices.get(slice) ?? "";
|
|
1756
1927
|
const own = loadVirtualModule(ctx, id);
|
|
1757
|
-
if (
|
|
1928
|
+
if (id === RESOLVED_CSS_ID && own !== null && !ctx.splitsStylesheet) return withVendorHead(this, own);
|
|
1758
1929
|
return own;
|
|
1759
1930
|
},
|
|
1760
1931
|
async transform(code, id) {
|
|
@@ -1764,6 +1935,11 @@ function animusExtract(options) {
|
|
|
1764
1935
|
generateBundle: {
|
|
1765
1936
|
order: "post",
|
|
1766
1937
|
handler(_output, bundle) {
|
|
1938
|
+
if (linkedSlices.length > 0 && isClient(this)) placeStylesheetSlices(ctx, bundle, linkedSlices, (name, source) => this.getFileName(this.emitFile({
|
|
1939
|
+
type: "asset",
|
|
1940
|
+
name,
|
|
1941
|
+
source
|
|
1942
|
+
})));
|
|
1767
1943
|
if (!ctx.served?.fontPreloads.length) return;
|
|
1768
1944
|
for (const file of Object.values(bundle)) {
|
|
1769
1945
|
if (file.type !== "asset" || !file.fileName.endsWith(".html")) continue;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import type { AnimusQuarantineOptions, ClosedDynamicImport, FontPreloadEntry, DiagnosticLevels, StaticCssConfig } from '@animus-ui/extract/pipeline';
|
|
1
|
+
import type { AnimusQuarantineOptions, ClosedDynamicImport, FontPreloadEntry, DiagnosticLevels, StaticCssConfig, StylesheetDelivery } from '@animus-ui/extract/pipeline';
|
|
2
2
|
import type { Plugin } from 'vite';
|
|
3
3
|
export { discoverFiles } from '@animus-ui/extract/pipeline';
|
|
4
|
-
export type { AnimusQuarantineOptions } from '@animus-ui/extract/pipeline';
|
|
4
|
+
export type { AnimusQuarantineOptions, StylesheetDelivery, } from '@animus-ui/extract/pipeline';
|
|
5
|
+
/** The entries `virtual:animus/font-preloads` exports by default: each file
|
|
6
|
+
* this build preloads, the URL it is preloaded at, and its faces. */
|
|
7
|
+
export type { FontPreload, PreloadedFontFace, } from '@animus-ui/extract/pipeline';
|
|
5
8
|
export interface AnimusExtractOptions {
|
|
6
9
|
/** Path to a module exporting a SystemInstance from `@animus-ui/system`. */
|
|
7
10
|
system: string;
|
|
@@ -31,6 +34,15 @@ export interface AnimusExtractOptions {
|
|
|
31
34
|
* where the app renders it: family names, or `{ family, weight?, style? }`
|
|
32
35
|
* (see `FontPreloadEntry`). `[]` preloads none. */
|
|
33
36
|
fontPreloads?: FontPreloadEntry[];
|
|
37
|
+
/** `'split'` builds the stylesheet as three consecutive files, each page
|
|
38
|
+
* linking them in order where it would link the one sheet `'single'`
|
|
39
|
+
* (the default) builds: foundation (variables, `@property`,
|
|
40
|
+
* `anm-global`), components (base through states), then utilities
|
|
41
|
+
* (`anm-system`, `anm-custom`). In order they hold that sheet's rules,
|
|
42
|
+
* so the cascade is unchanged, and a file an edit leaves alone keeps its
|
|
43
|
+
* hash. Needs a page Vite builds from HTML to link the stylesheet; the
|
|
44
|
+
* dev server keeps one sheet. */
|
|
45
|
+
stylesheets?: StylesheetDelivery;
|
|
34
46
|
/**
|
|
35
47
|
* Substrings, or globs when `*`/`?` present. Replaces the defaults `dist`,
|
|
36
48
|
* `.test.`, `.spec.`; `node_modules`, `.next`, `.animus` always apply.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EACV,uBAAuB,EACvB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAEhB,eAAe,EACf,kBAAkB,EAEnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAe,MAAM,EAAwB,MAAM,MAAM,CAAC;AAEtE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,YAAY,EACV,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AACrC;sEACsE;AACtE,YAAY,EACV,WAAW,EACX,iBAAiB,GAClB,MAAM,6BAA6B,CAAC;AA+CrC,MAAM,WAAW,oBAAoB;IACnC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf;;;0DAGsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAC7C;;;wDAGoD;IACpD,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAClC;;;;;;;sCAOkC;IAClC,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;+CAE2C;IAC3C,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,IAAI,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC;IACpC;;sDAEkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;gBAEY;IACZ,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC;IACd;;;OAGG;IACH,mBAAmB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,uBAAuB,CAAC;CACtC;AAuBD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAiPnE;eAEc,aAAa"}
|
|
@@ -3,5 +3,11 @@ export declare function resolveVirtualId(ctx: PluginContext, id: string): string
|
|
|
3
3
|
id: string;
|
|
4
4
|
moduleSideEffects: boolean;
|
|
5
5
|
} | null;
|
|
6
|
+
/**
|
|
7
|
+
* The stylesheet `virtual:animus/styles.css` serves: the variables, then
|
|
8
|
+
* the post-processed body. In development the component layers arrive
|
|
9
|
+
* through the bridge's sheet instead, unminified.
|
|
10
|
+
*/
|
|
11
|
+
export declare function stylesheetSource(ctx: PluginContext): string;
|
|
6
12
|
export declare function loadVirtualModule(ctx: PluginContext, id: string): string | null;
|
|
7
13
|
//# sourceMappingURL=virtual-modules.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtual-modules.d.ts","sourceRoot":"","sources":["../src/virtual-modules.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"virtual-modules.d.ts","sourceRoot":"","sources":["../src/virtual-modules.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAa/C,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,aAAa,EAClB,EAAE,EAAE,MAAM,GACT,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAuB5D;AAoBD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAa3D;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,aAAa,EAClB,EAAE,EAAE,MAAM,GACT,MAAM,GAAG,IAAI,CAgFf"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@animus-ui/vite-plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.39",
|
|
4
4
|
"description": "Animus static CSS extraction Vite plugin",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"animus",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"directory": "packages/vite-plugin"
|
|
21
21
|
},
|
|
22
22
|
"files": [
|
|
23
|
+
"client.d.ts",
|
|
23
24
|
"dist"
|
|
24
25
|
],
|
|
25
26
|
"main": "./dist/index.cjs",
|
|
@@ -28,6 +29,9 @@
|
|
|
28
29
|
".": {
|
|
29
30
|
"types": "./dist/index.d.ts",
|
|
30
31
|
"default": "./dist/index.cjs"
|
|
32
|
+
},
|
|
33
|
+
"./client": {
|
|
34
|
+
"types": "./client.d.ts"
|
|
31
35
|
}
|
|
32
36
|
},
|
|
33
37
|
"publishConfig": {
|
|
@@ -39,16 +43,16 @@
|
|
|
39
43
|
"compile": "bun check"
|
|
40
44
|
},
|
|
41
45
|
"dependencies": {
|
|
42
|
-
"@animus-ui/extract": "0.1.
|
|
46
|
+
"@animus-ui/extract": "0.1.39",
|
|
43
47
|
"browserslist": "^4.28.8",
|
|
44
48
|
"lightningcss": "^1.33.0"
|
|
45
49
|
},
|
|
46
50
|
"devDependencies": {
|
|
47
|
-
"@animus-ui/assertions": "0.1.
|
|
48
|
-
"@animus-ui/layergate": "0.1.
|
|
51
|
+
"@animus-ui/assertions": "0.1.39",
|
|
52
|
+
"@animus-ui/layergate": "0.1.39"
|
|
49
53
|
},
|
|
50
54
|
"peerDependencies": {
|
|
51
|
-
"@animus-ui/layergate": "0.1.
|
|
55
|
+
"@animus-ui/layergate": "0.1.39",
|
|
52
56
|
"vite": ">=8 <9"
|
|
53
57
|
},
|
|
54
58
|
"peerDependenciesMeta": {
|