@animus-ui/vite-plugin 0.1.35 → 0.1.36
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 +38 -7
- package/dist/context.d.ts.map +1 -1
- package/dist/index-html.d.ts +18 -3
- package/dist/index-html.d.ts.map +1 -1
- package/dist/index.cjs +138 -31
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -60,7 +60,8 @@ export default defineConfig({
|
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
The plugin is **delivery-only**: it injects `artifact.code` verbatim as an inline
|
|
63
|
-
`<script data-animus-bootstrap>`
|
|
63
|
+
`<script data-animus-bootstrap>` in `<head>`, after the charset and viewport
|
|
64
|
+
metas (so the charset stays within the first 1024 bytes) and ahead of every
|
|
64
65
|
stylesheet reference, and interprets no appearance semantics. Omit the option and
|
|
65
66
|
the built HTML is byte-for-byte what it was before.
|
|
66
67
|
|
|
@@ -99,12 +100,42 @@ Router examples live in the
|
|
|
99
100
|
## Font preloads
|
|
100
101
|
|
|
101
102
|
A font face declared with `preload: true` gets a
|
|
102
|
-
`<link rel="preload" as="font" crossorigin>`
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
`<link rel="preload" as="font" crossorigin data-animus-preload>` in `<head>`,
|
|
104
|
+
after the charset and viewport metas and ahead of every stylesheet link. Its
|
|
105
|
+
href is the URL the stylesheet's `url()` loads: the hashed asset in a build,
|
|
106
|
+
the dev server's URL in development. A root-relative or absolute URL that
|
|
107
|
+
`index.html` already preloads gets no second preload. A build warns, naming
|
|
108
|
+
the HTML page, when the finished page preloads the same file through another
|
|
109
|
+
tag: one written in the page for an `asset()` file, or one a plugin adds from
|
|
110
|
+
an `index.html` hook that runs after Animus's.
|
|
111
|
+
|
|
112
|
+
`fontPreloads` selects the faces that preload in place of their `preload`
|
|
113
|
+
flags, for an app that renders only some of a system's faces. A family name
|
|
114
|
+
selects every face of the family; `{ family, weight?, style? }` selects the
|
|
115
|
+
faces whose declared weight contains `weight` (a variable face's range
|
|
116
|
+
`'100 900'` contains 600) and whose style is `style` (`'normal'` when
|
|
117
|
+
omitted):
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
animusExtract({
|
|
121
|
+
system: './src/ds.ts',
|
|
122
|
+
fontPreloads: [
|
|
123
|
+
{ family: 'Apercu', weight: 400 },
|
|
124
|
+
{ family: 'Apercu', weight: 'bold' },
|
|
125
|
+
{ family: 'Suisse', weight: 700 },
|
|
126
|
+
],
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`[]` preloads none. An entry no face matches reports
|
|
131
|
+
`animus.style.font-preload-unmatched`; a malformed one, such as a weight
|
|
132
|
+
range, reports `animus.style.font-preload-invalid`.
|
|
133
|
+
|
|
134
|
+
A preload competes with the critical CSS and JavaScript for first paint, so
|
|
135
|
+
preload WOFF2 and only the faces the first screen needs: a large TrueType
|
|
136
|
+
file can delay first paint by seconds on a slow link. A preloaded file that
|
|
137
|
+
is not WOFF2 or WOFF, or an `asset()` file over 150 KB, reports
|
|
138
|
+
`animus.style.font-face-preload-costly`.
|
|
108
139
|
|
|
109
140
|
## Third-party stylesheets
|
|
110
141
|
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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
|
|
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,9 +1,24 @@
|
|
|
1
1
|
import type { PluginContext } from './context';
|
|
2
2
|
import type { HtmlTagDescriptor } from 'vite';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* The hrefs a finished document preloads both through Animus's tag and
|
|
5
|
+
* through another, which the page wrote or a hook running after Animus's
|
|
6
|
+
* added: the browser may then fetch the file twice. Each href is compared
|
|
7
|
+
* as the browser resolves it against `pageUrl`, the URL the page is served
|
|
8
|
+
* at, and reported as Animus wrote it.
|
|
9
|
+
*/
|
|
10
|
+
export declare function duplicatedFontPreloads(html: string, pageUrl: string): string[];
|
|
11
|
+
/**
|
|
12
|
+
* The hook's result: the tags written after the charset and viewport metas,
|
|
13
|
+
* each on its own line indented as the element it follows, so the charset
|
|
14
|
+
* stays in the first 1024 bytes however long the tags are; as `head-prepend`
|
|
15
|
+
* tags for a document without a `<head>`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function injectHeadTags(html: string, tags: HtmlTagDescriptor[]): string | HtmlTagDescriptor[];
|
|
18
|
+
/**
|
|
19
|
+
* Animus's head tags in document order: the bootstrap script, so it runs
|
|
20
|
+
* before first paint and ahead of every stylesheet, the layer declaration,
|
|
21
|
+
* the font preloads, then the development bridge.
|
|
7
22
|
*/
|
|
8
23
|
export declare function buildIndexHtmlTags(ctx: PluginContext, html?: string): HtmlTagDescriptor[];
|
|
9
24
|
//# 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":"
|
|
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;AA0C9C;;;;;;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;AAkCD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,aAAa,EAClB,IAAI,SAAK,GACR,iBAAiB,EAAE,CAuCrB"}
|
package/dist/index.cjs
CHANGED
|
@@ -535,6 +535,7 @@ var PluginContext = class {
|
|
|
535
535
|
engine: options.engine,
|
|
536
536
|
runtimeImport: options.runtimeImport,
|
|
537
537
|
closedDynamicImports: options.closedDynamicImports,
|
|
538
|
+
fontPreloads: options.fontPreloads,
|
|
538
539
|
mode: this.emissionProd ? "production" : "development"
|
|
539
540
|
}, {
|
|
540
541
|
build: this.build,
|
|
@@ -1322,57 +1323,142 @@ function invalidateStaleModules(ctx, environment, modules, analyzed) {
|
|
|
1322
1323
|
//#endregion
|
|
1323
1324
|
//#region src/index-html.ts
|
|
1324
1325
|
const LINK_TAG_RE = /<link\b[^>]*>/gi;
|
|
1326
|
+
/** Marks the preloads Animus writes, so another preload of the same file
|
|
1327
|
+
* can be told from Animus's own. */
|
|
1328
|
+
const ANIMUS_PRELOAD_MARKER = "data-animus-preload";
|
|
1329
|
+
const MARKER_RE = /\sdata-animus-preload(?=[\s=/>])/i;
|
|
1325
1330
|
const REL_RE = /\srel\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/i;
|
|
1326
1331
|
const HREF_RE = /\shref\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/i;
|
|
1327
1332
|
function attribute(tag, re) {
|
|
1328
1333
|
const match = re.exec(tag);
|
|
1329
1334
|
return match ? match[1] ?? match[2] ?? match[3] : void 0;
|
|
1330
1335
|
}
|
|
1331
|
-
/**
|
|
1332
|
-
function
|
|
1333
|
-
const hrefs = /* @__PURE__ */ new Set();
|
|
1336
|
+
/** Each `<link rel="preload">` in `html`, with its href. */
|
|
1337
|
+
function* preloadLinks(html) {
|
|
1334
1338
|
for (const [tag] of html.matchAll(LINK_TAG_RE)) {
|
|
1335
1339
|
const rel = attribute(tag, REL_RE)?.toLowerCase().split(/\s+/) ?? [];
|
|
1336
1340
|
const href = attribute(tag, HREF_RE);
|
|
1337
|
-
if (rel.includes("preload") && href !== void 0)
|
|
1341
|
+
if (rel.includes("preload") && href !== void 0) yield [tag, href];
|
|
1338
1342
|
}
|
|
1339
|
-
return hrefs;
|
|
1340
1343
|
}
|
|
1341
|
-
|
|
1342
|
-
|
|
1344
|
+
const ENTITY_RE = /&(?:#x([0-9a-f]+)|#(\d+)|(amp|lt|gt|quot|apos));/gi;
|
|
1345
|
+
const NAMED_ENTITIES = /* @__PURE__ */ new Map([
|
|
1346
|
+
["amp", "&"],
|
|
1347
|
+
["lt", "<"],
|
|
1348
|
+
["gt", ">"],
|
|
1349
|
+
["quot", "\""],
|
|
1350
|
+
["apos", "'"]
|
|
1351
|
+
]);
|
|
1352
|
+
/** An attribute value as the browser reads it: character references decoded. */
|
|
1353
|
+
function attributeText(value) {
|
|
1354
|
+
return value.replace(ENTITY_RE, (_, hex, decimal, named) => named === void 0 ? String.fromCodePoint(Number.parseInt(hex ?? decimal, hex ? 16 : 10)) : NAMED_ENTITIES.get(named.toLowerCase()));
|
|
1355
|
+
}
|
|
1356
|
+
/**
|
|
1357
|
+
* The hrefs a finished document preloads both through Animus's tag and
|
|
1358
|
+
* through another, which the page wrote or a hook running after Animus's
|
|
1359
|
+
* added: the browser may then fetch the file twice. Each href is compared
|
|
1360
|
+
* as the browser resolves it against `pageUrl`, the URL the page is served
|
|
1361
|
+
* at, and reported as Animus wrote it.
|
|
1362
|
+
*/
|
|
1363
|
+
function duplicatedFontPreloads(html, pageUrl) {
|
|
1364
|
+
const resolved = (href) => {
|
|
1365
|
+
try {
|
|
1366
|
+
return new URL(attributeText(href), pageUrl).href;
|
|
1367
|
+
} catch {
|
|
1368
|
+
return href;
|
|
1369
|
+
}
|
|
1370
|
+
};
|
|
1371
|
+
const ours = /* @__PURE__ */ new Map();
|
|
1372
|
+
const others = /* @__PURE__ */ new Set();
|
|
1373
|
+
for (const [tag, href] of preloadLinks(html)) if (MARKER_RE.test(tag)) ours.set(resolved(href), href);
|
|
1374
|
+
else others.add(resolved(href));
|
|
1375
|
+
return [...ours].filter(([url]) => others.has(url)).map(([, href]) => href);
|
|
1376
|
+
}
|
|
1377
|
+
/** The hrefs the document already preloads. */
|
|
1378
|
+
function preloadedHrefs(html) {
|
|
1379
|
+
return new Set([...preloadLinks(html)].map(([, href]) => href));
|
|
1380
|
+
}
|
|
1381
|
+
/** The head elements Animus's tags go after (the charset and viewport
|
|
1382
|
+
* metas), the stylesheets they go before, and what holds neither. */
|
|
1383
|
+
const HEAD_SCAN_RE = /<!--[\s\S]*?-->|<script\b[\s\S]*?<\/script\s*>|<\/head\s*>|<style\b|<(?:meta|link)\b[^>]*>/gi;
|
|
1384
|
+
/** Where Animus's head tags go: after the head's charset and viewport
|
|
1385
|
+
* metas, so they cannot push the charset past the 1024 bytes a browser
|
|
1386
|
+
* sniffs for it, and before its first stylesheet; -1 without a `<head>`. */
|
|
1387
|
+
function headTagOffset(html) {
|
|
1388
|
+
const open = /<head\b[^>]*>/i.exec(html);
|
|
1389
|
+
if (open === null) return -1;
|
|
1390
|
+
const start = open.index + open[0].length;
|
|
1391
|
+
let offset = start;
|
|
1392
|
+
for (const match of html.slice(start).matchAll(HEAD_SCAN_RE)) {
|
|
1393
|
+
const [element] = match;
|
|
1394
|
+
const lower = element.toLowerCase();
|
|
1395
|
+
if (lower.startsWith("</head") || lower.startsWith("<style")) break;
|
|
1396
|
+
if (lower.startsWith("<link")) {
|
|
1397
|
+
if ((attribute(element, REL_RE)?.toLowerCase().split(/\s+/))?.includes("stylesheet")) break;
|
|
1398
|
+
} else if (lower.startsWith("<meta") && (/\scharset\s*=/i.test(element) || /\shttp-equiv\s*=\s*["']?content-type\b/i.test(element) || /\sname\s*=\s*["']?viewport\b/i.test(element))) offset = start + match.index + element.length;
|
|
1399
|
+
}
|
|
1400
|
+
return offset;
|
|
1401
|
+
}
|
|
1402
|
+
/** As `escape-html` escapes, which Vite applies to attribute values. */
|
|
1403
|
+
function escapeHtml(value) {
|
|
1404
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1405
|
+
}
|
|
1406
|
+
/** A tag as Vite serializes it, `children` as written, except that an
|
|
1407
|
+
* undefined attribute is left out rather than written "undefined". */
|
|
1408
|
+
function serializeTag({ tag, attrs = {}, children }) {
|
|
1409
|
+
const serialized = Object.entries(attrs).map(([key, value]) => {
|
|
1410
|
+
if (value === true) return ` ${key}`;
|
|
1411
|
+
if (value === false || value === void 0) return "";
|
|
1412
|
+
return ` ${key}="${escapeHtml(value)}"`;
|
|
1413
|
+
}).join("");
|
|
1414
|
+
if (tag === "link" || tag === "meta" || tag === "base") return `<${tag}${serialized}>`;
|
|
1415
|
+
return `<${tag}${serialized}>${Array.isArray(children) ? "" : children ?? ""}</${tag}>`;
|
|
1416
|
+
}
|
|
1417
|
+
/**
|
|
1418
|
+
* The hook's result: the tags written after the charset and viewport metas,
|
|
1419
|
+
* each on its own line indented as the element it follows, so the charset
|
|
1420
|
+
* stays in the first 1024 bytes however long the tags are; as `head-prepend`
|
|
1421
|
+
* tags for a document without a `<head>`.
|
|
1422
|
+
*/
|
|
1423
|
+
function injectHeadTags(html, tags) {
|
|
1424
|
+
const offset = headTagOffset(html);
|
|
1425
|
+
if (offset === -1) return tags;
|
|
1426
|
+
if (tags.length === 0) return html;
|
|
1427
|
+
const lineStart = html.lastIndexOf("\n", offset - 1) + 1;
|
|
1428
|
+
const indent = /^[ \t]*/.exec(html.slice(lineStart))[0];
|
|
1429
|
+
const inserted = tags.map((tag) => `\n${indent}${serializeTag(tag)}`).join("");
|
|
1430
|
+
return html.slice(0, offset) + inserted + html.slice(offset);
|
|
1431
|
+
}
|
|
1432
|
+
/** The preloads for the faces that ask for one, by the URL the stylesheet's
|
|
1433
|
+
* own `url()` gets, each marked as Animus's; one the document already
|
|
1343
1434
|
* preloads is left out. */
|
|
1344
1435
|
function fontPreloadTags(ctx, html) {
|
|
1345
1436
|
const published = ctx.served?.fontPreloads ?? [];
|
|
1346
1437
|
if (published.length === 0) return [];
|
|
1347
1438
|
const existing = preloadedHrefs(html);
|
|
1348
|
-
|
|
1439
|
+
return (0, _animus_ui_extract_pipeline.substituteFontPreloads)(published, ctx.assetUrlBySpecifier).map((preload) => ctx.isProd ? preload : {
|
|
1349
1440
|
...preload,
|
|
1350
1441
|
href: ctx.devRootRelativeUrl(preload.href)
|
|
1351
|
-
}).filter(({ href }) => !existing.has(href))
|
|
1352
|
-
|
|
1353
|
-
tag: "link",
|
|
1354
|
-
attrs: {
|
|
1355
|
-
rel: "preconnect",
|
|
1356
|
-
href: origin,
|
|
1357
|
-
crossorigin: true
|
|
1358
|
-
},
|
|
1359
|
-
injectTo: "head-prepend"
|
|
1360
|
-
})), ...preloads.map(({ href, type }) => ({
|
|
1361
|
-
tag: "link",
|
|
1362
|
-
attrs: {
|
|
1442
|
+
}).filter(({ href }) => !existing.has(href)).map(({ href, type }) => {
|
|
1443
|
+
const attrs = {
|
|
1363
1444
|
rel: "preload",
|
|
1364
1445
|
href,
|
|
1365
|
-
as: "font"
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1446
|
+
as: "font"
|
|
1447
|
+
};
|
|
1448
|
+
if (type !== void 0) attrs.type = type;
|
|
1449
|
+
attrs.crossorigin = true;
|
|
1450
|
+
attrs[ANIMUS_PRELOAD_MARKER] = true;
|
|
1451
|
+
return {
|
|
1452
|
+
tag: "link",
|
|
1453
|
+
attrs,
|
|
1454
|
+
injectTo: "head-prepend"
|
|
1455
|
+
};
|
|
1456
|
+
});
|
|
1371
1457
|
}
|
|
1372
1458
|
/**
|
|
1373
|
-
*
|
|
1374
|
-
*
|
|
1375
|
-
*
|
|
1459
|
+
* Animus's head tags in document order: the bootstrap script, so it runs
|
|
1460
|
+
* before first paint and ahead of every stylesheet, the layer declaration,
|
|
1461
|
+
* the font preloads, then the development bridge.
|
|
1376
1462
|
*/
|
|
1377
1463
|
function buildIndexHtmlTags(ctx, html = "") {
|
|
1378
1464
|
const tags = [];
|
|
@@ -1383,13 +1469,13 @@ function buildIndexHtmlTags(ctx, html = "") {
|
|
|
1383
1469
|
children: bootstrap.code,
|
|
1384
1470
|
injectTo: "head-prepend"
|
|
1385
1471
|
});
|
|
1386
|
-
tags.push(...fontPreloadTags(ctx, html));
|
|
1387
1472
|
if (ctx.layerDeclaration) tags.push({
|
|
1388
1473
|
tag: "style",
|
|
1389
1474
|
attrs: { "data-animus-layers": "" },
|
|
1390
1475
|
children: ctx.layerDeclaration,
|
|
1391
1476
|
injectTo: "head-prepend"
|
|
1392
1477
|
});
|
|
1478
|
+
tags.push(...fontPreloadTags(ctx, html));
|
|
1393
1479
|
if (!ctx.isProd) tags.push({
|
|
1394
1480
|
tag: "script",
|
|
1395
1481
|
attrs: {
|
|
@@ -1577,6 +1663,15 @@ async function sourceKitConfig(rootDir, systemPath, engine) {
|
|
|
1577
1663
|
roots: [...kits.values()].map((kit) => kit.root)
|
|
1578
1664
|
};
|
|
1579
1665
|
}
|
|
1666
|
+
/** The URL a build's root is served at, for resolving a page's hrefs: an
|
|
1667
|
+
* absolute `base`, a root-relative one on a stand-in origin, or the root
|
|
1668
|
+
* for a relative one, which every page resolves from its own location. */
|
|
1669
|
+
function servedBase(base) {
|
|
1670
|
+
const origin = "https://animus.invalid/";
|
|
1671
|
+
if (/^[a-z][a-z\d+.-]*:/i.test(base)) return new URL(base.replace(/\/?$/, "/"));
|
|
1672
|
+
if (base.startsWith("/")) return new URL(base.replace(/\/?$/, "/"), origin);
|
|
1673
|
+
return new URL(origin);
|
|
1674
|
+
}
|
|
1580
1675
|
function animusExtract(options) {
|
|
1581
1676
|
(0, _animus_ui_extract_pipeline.assertSupportedEngine)(options.engine);
|
|
1582
1677
|
(0, _animus_ui_extract_pipeline.assertKnownOptionKeys)(options, [
|
|
@@ -1666,10 +1761,22 @@ function animusExtract(options) {
|
|
|
1666
1761
|
if (vendor && /\.css(?:$|\?)/.test(id)) return (await vendor.plugin()).transform.call(this, code, id);
|
|
1667
1762
|
return transformSource(ctx, code, id);
|
|
1668
1763
|
},
|
|
1764
|
+
generateBundle: {
|
|
1765
|
+
order: "post",
|
|
1766
|
+
handler(_output, bundle) {
|
|
1767
|
+
if (!ctx.served?.fontPreloads.length) return;
|
|
1768
|
+
for (const file of Object.values(bundle)) {
|
|
1769
|
+
if (file.type !== "asset" || !file.fileName.endsWith(".html")) continue;
|
|
1770
|
+
const html = Buffer.from(file.source).toString("utf8");
|
|
1771
|
+
if (!html.includes("data-animus-preload")) continue;
|
|
1772
|
+
for (const href of duplicatedFontPreloads(html, new URL(file.fileName, servedBase(ctx.base)).href)) ctx.warn(`[animus-extract] ${file.fileName} preloads ${href} twice: Animus's font preload and another preload tag, written in the page or added by a plugin whose index.html hook runs after Animus's, so the browser may fetch it twice. Remove the other preload; Animus's names the URL the stylesheet's url() loads.`);
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
},
|
|
1669
1776
|
transformIndexHtml: {
|
|
1670
1777
|
order: "pre",
|
|
1671
1778
|
handler(html) {
|
|
1672
|
-
return buildIndexHtmlTags(ctx, html);
|
|
1779
|
+
return injectHeadTags(html, buildIndexHtmlTags(ctx, html));
|
|
1673
1780
|
}
|
|
1674
1781
|
},
|
|
1675
1782
|
async hotUpdate(hmr) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AnimusQuarantineOptions, ClosedDynamicImport, DiagnosticLevels, StaticCssConfig } from '@animus-ui/extract/pipeline';
|
|
1
|
+
import type { AnimusQuarantineOptions, ClosedDynamicImport, FontPreloadEntry, DiagnosticLevels, StaticCssConfig } from '@animus-ui/extract/pipeline';
|
|
2
2
|
import type { Plugin } from 'vite';
|
|
3
3
|
export { discoverFiles } from '@animus-ui/extract/pipeline';
|
|
4
4
|
export type { AnimusQuarantineOptions } from '@animus-ui/extract/pipeline';
|
|
@@ -26,6 +26,11 @@ export interface AnimusExtractOptions {
|
|
|
26
26
|
* still load any module.
|
|
27
27
|
*/
|
|
28
28
|
closedDynamicImports?: ClosedDynamicImport[];
|
|
29
|
+
/** The font faces this app preloads, in place of each typed face's own
|
|
30
|
+
* `preload` flag, so a face declared once for every product preloads only
|
|
31
|
+
* where the app renders it: family names, or `{ family, weight?, style? }`
|
|
32
|
+
* (see `FontPreloadEntry`). `[]` preloads none. */
|
|
33
|
+
fontPreloads?: FontPreloadEntry[];
|
|
29
34
|
/**
|
|
30
35
|
* Substrings, or globs when `*`/`?` present. Replaces the defaults `dist`,
|
|
31
36
|
* `.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":"AA2BA,OAAO,KAAK,EACV,uBAAuB,EACvB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAEhB,eAAe,EAChB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,MAAM,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,YAAY,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AA+C3E,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;;;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;AAiBD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CA4MnE;eAEc,aAAa"}
|
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.36",
|
|
4
4
|
"description": "Animus static CSS extraction Vite plugin",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"animus",
|
|
@@ -39,16 +39,16 @@
|
|
|
39
39
|
"compile": "bun check"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@animus-ui/extract": "0.1.
|
|
42
|
+
"@animus-ui/extract": "0.1.36",
|
|
43
43
|
"browserslist": "^4.28.8",
|
|
44
44
|
"lightningcss": "^1.33.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@animus-ui/assertions": "0.1.
|
|
48
|
-
"@animus-ui/layergate": "0.1.
|
|
47
|
+
"@animus-ui/assertions": "0.1.36",
|
|
48
|
+
"@animus-ui/layergate": "0.1.36"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"@animus-ui/layergate": "0.1.
|
|
51
|
+
"@animus-ui/layergate": "0.1.36",
|
|
52
52
|
"vite": ">=8 <9"
|
|
53
53
|
},
|
|
54
54
|
"peerDependenciesMeta": {
|