@animus-ui/vite-plugin 0.1.32 → 0.1.35

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 CHANGED
@@ -96,6 +96,45 @@ supplies either `cspHash` or a per-request nonce. Worked App Router and Pages
96
96
  Router examples live in the
97
97
  [`@animus-ui/next-plugin` README](https://github.com/codecaaron/animus/tree/main/packages/next-plugin#appearance-bootstrap-no-fouc-color-mode).
98
98
 
99
+ ## Font preloads
100
+
101
+ A font face declared with `preload: true` gets a
102
+ `<link rel="preload" as="font" crossorigin>` at the start of `<head>`, ahead
103
+ of every stylesheet reference, with a `preconnect` for a file on another
104
+ origin. Its href is the URL the stylesheet's `url()` loads: the hashed asset
105
+ in a build, the dev server's URL in development. A root-relative or
106
+ absolute URL that `index.html` already preloads gets no second preload; an
107
+ `asset()` file's preload is not compared with one written in the HTML.
108
+
109
+ ## Third-party stylesheets
110
+
111
+ A library's plain CSS outside any `@layer` beats every Animus layer. With
112
+ `quarantine`, [`@animus-ui/layergate`](../layergate/README.md) loads it into
113
+ `anm-vendor`, a layer below all of Animus's, so Animus's styles win and the
114
+ library's still apply where Animus sets nothing:
115
+
116
+ ```sh
117
+ bun add -D @animus-ui/layergate
118
+ ```
119
+
120
+ ```ts
121
+ animusExtract({
122
+ system: './src/ds.ts',
123
+ quarantine: {
124
+ sheets: ['react-grid-layout/css/styles.css'], // delivered ahead of Animus's own CSS
125
+ dependencies: ['react-datepicker'], // CSS these packages' modules import
126
+ optOut: [], // exact files whose own rules stay unlayered
127
+ },
128
+ });
129
+ ```
130
+
131
+ `sheets` arrive at the head of Animus's own stylesheet, wherever it is
132
+ imported, so no extra import is needed. Their fonts and images keep
133
+ resolving, files outside the project root included.
134
+ `!important` declarations and animations still win, and are reported. App
135
+ CSS keeps its own rules unlayered; where it imports a vendor file, that file
136
+ is layered. CSS Modules are left alone.
137
+
99
138
  ## MDX
100
139
 
101
140
  Animus reads each `.mdx` file as the JSX it renders: its imports, exports,
@@ -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,CA4EN"}
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,CA+EN"}
package/dist/context.d.ts CHANGED
@@ -29,9 +29,11 @@ export declare class PluginContext {
29
29
  pathAliasesJson: string | null;
30
30
  /** Vite's export conditions, so the loader reads the files Vite serves. */
31
31
  resolveConditions: string[];
32
+ private viteExtensionPolicy;
32
33
  /** Vite's resolved extension order; the built-in policy until
33
34
  * `configResolved`. */
34
- extensionPolicy: HostExtensionPolicy;
35
+ get extensionPolicy(): HostExtensionPolicy;
36
+ set extensionPolicy(policy: HostExtensionPolicy);
35
37
  /** Vite's asset classification, captured at `configResolved`. */
36
38
  assetClassification: HostAssetClassification;
37
39
  /** How Vite's build expands computed loads, captured at
@@ -85,6 +87,12 @@ export declare class PluginContext {
85
87
  /** Coalesces a burst of invalidations into one full reload. */
86
88
  private readonly reloadWindow;
87
89
  base: string;
90
+ /** Vite's root and `server.origin`, which a dev asset URL is served
91
+ * under. */
92
+ viteRoot: string;
93
+ serverOrigin: string;
94
+ /** Vite's resolved public directory; empty when it serves none. */
95
+ publicDir: string;
88
96
  assetUrlBySpecifier: Map<string, string>;
89
97
  /** Where dev asset() copies live, immutable and content-named; null in a
90
98
  * build, or when the dev server does not serve the directory, which
@@ -162,7 +170,16 @@ export declare class PluginContext {
162
170
  /** A build-strictness check that failed: a build throws `message`, and
163
171
  * development reports it at error level and takes the non-strict path. */
164
172
  strictFailure(message: string, cause?: unknown): void;
165
- devFsUrl(absPath: string): string;
173
+ /** The URL Vite's dev server serves `absPath` at, the form its dev CSS
174
+ * pass writes (`fileToDevUrl`): root-relative inside its root, `/@fs/`
175
+ * outside, under `server.origin` and the base. Every consumer, the
176
+ * stylesheet that pass rewrites, component CSS it does not, and a font
177
+ * preload, then names one URL, and the browser fetches the file once. */
178
+ devServedUrl(absPath: string): string;
179
+ /** A root-relative URL a face names as written, as Vite's dev CSS pass
180
+ * writes it: under `server.origin` and the base where it names a public
181
+ * file or a file under the root, else unchanged. */
182
+ devRootRelativeUrl(href: string): string;
166
183
  /** A dev asset() URL: an immutable content-named copy of `absPath`, so an
167
184
  * edit gets a new URL, or the live file where copies are not served. */
168
185
  devAssetUrl(specifier: string, absPath: string): string;
@@ -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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"}
@@ -2,7 +2,8 @@ import type { PluginContext } from './context';
2
2
  import type { HtmlTagDescriptor } from 'vite';
3
3
  /**
4
4
  * Vite serializes one `head-prepend` bucket in array order, so the bootstrap
5
- * script precedes the layer declaration and every stylesheet reference.
5
+ * script precedes the font preloads, the layer declaration and every
6
+ * stylesheet reference.
6
7
  */
7
- export declare function buildIndexHtmlTags(ctx: PluginContext): HtmlTagDescriptor[];
8
+ export declare function buildIndexHtmlTags(ctx: PluginContext, html?: string): HtmlTagDescriptor[];
8
9
  //# sourceMappingURL=index-html.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-html.d.ts","sourceRoot":"","sources":["../src/index-html.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAE9C;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,iBAAiB,EAAE,CAqC1E"}
1
+ {"version":3,"file":"index-html.d.ts","sourceRoot":"","sources":["../src/index-html.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAuD9C;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,aAAa,EAClB,IAAI,SAAK,GACR,iBAAiB,EAAE,CAuCrB"}
package/dist/index.cjs CHANGED
@@ -4,10 +4,10 @@ Object.defineProperties(exports, {
4
4
  });
5
5
  let _animus_ui_extract_pipeline = require("@animus-ui/extract/pipeline");
6
6
  let path = require("path");
7
+ let vite = require("vite");
7
8
  let fs = require("fs");
8
9
  let _animus_ui_extract_session = require("@animus-ui/extract/session");
9
10
  let child_process = require("child_process");
10
- let vite = require("vite");
11
11
  let crypto = require("crypto");
12
12
  //#region src/asset-copy-dirs.ts
13
13
  /**
@@ -192,7 +192,7 @@ function applyResolvedConfig(ctx, config) {
192
192
  const copyDir = (0, path.resolve)(config.cacheDir, "animus-assets", processCopyDir());
193
193
  const served = (0, vite.isFileLoadingAllowed)(config, (0, path.join)(copyDir, "asset"));
194
194
  ctx.assetCopyDir = served ? copyDir : null;
195
- ctx.servesFile = (path$9) => (0, vite.isFileLoadingAllowed)(config, path$9);
195
+ ctx.servesFile = (path$11) => (0, vite.isFileLoadingAllowed)(config, path$11);
196
196
  if (!served) ctx.warn(`[animus-extract] asset() copies in ${copyDir} are not served under server.fs; serving the live files instead, so an edited asset keeps its URL`);
197
197
  }
198
198
  ctx.outputExcludes = (0, _animus_ui_extract_pipeline.outputExclusions)(config.root, (0, _animus_ui_extract_pipeline.viteOutputTargets)(config));
@@ -204,6 +204,9 @@ 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.viteRoot = config.root;
208
+ ctx.serverOrigin = config.server.origin ?? "";
209
+ ctx.publicDir = config.publicDir;
207
210
  ctx.lcssTargets = (0, _animus_ui_extract_pipeline.resolveLightningTargets)(ctx.options.targets, ctx.rootDir);
208
211
  ctx.log(`Lightning CSS targets resolved (${Object.keys(ctx.lcssTargets).length} browsers)`);
209
212
  const pairs = [];
@@ -348,9 +351,15 @@ var PluginContext = class {
348
351
  pathAliasesJson = null;
349
352
  /** Vite's export conditions, so the loader reads the files Vite serves. */
350
353
  resolveConditions = [];
354
+ viteExtensionPolicy;
351
355
  /** Vite's resolved extension order; the built-in policy until
352
356
  * `configResolved`. */
353
- extensionPolicy = _animus_ui_extract_pipeline.BUILT_IN_EXTENSION_POLICY;
357
+ get extensionPolicy() {
358
+ return this.viteExtensionPolicy ?? (0, _animus_ui_extract_pipeline.builtInExtensionPolicy)();
359
+ }
360
+ set extensionPolicy(policy) {
361
+ this.viteExtensionPolicy = policy;
362
+ }
354
363
  /** Vite's asset classification, captured at `configResolved`. */
355
364
  assetClassification = (0, _animus_ui_extract_pipeline.builtInAssetClassification)("noHost");
356
365
  /** How Vite's build expands computed loads, captured at
@@ -436,6 +445,12 @@ var PluginContext = class {
436
445
  this.devServer?.hot?.send({ type: "full-reload" });
437
446
  });
438
447
  base = "/";
448
+ /** Vite's root and `server.origin`, which a dev asset URL is served
449
+ * under. */
450
+ viteRoot = "";
451
+ serverOrigin = "";
452
+ /** Vite's resolved public directory; empty when it serves none. */
453
+ publicDir = "";
439
454
  assetUrlBySpecifier = /* @__PURE__ */ new Map();
440
455
  /** Where dev asset() copies live, immutable and content-named; null in a
441
456
  * build, or when the dev server does not serve the directory, which
@@ -555,7 +570,7 @@ var PluginContext = class {
555
570
  * between sees one generation. */
556
571
  observeOutcome(session, outcome) {
557
572
  let systemPropsChanged = false;
558
- if (outcome.kind === "held") for (const [path$6, hash] of outcome.abortedOriginals) this.abortedParseHashes.set(path$6, hash);
573
+ if (outcome.kind === "held") for (const [path$7, hash] of outcome.abortedOriginals) this.abortedParseHashes.set(path$7, hash);
559
574
  else {
560
575
  this.abortedParseHashes.clear();
561
576
  const before = this.systemPropsModule;
@@ -646,13 +661,36 @@ var PluginContext = class {
646
661
  if (!report) throw new Error(message, cause === void 0 ? void 0 : { cause });
647
662
  report(message);
648
663
  }
649
- devFsUrl(absPath) {
650
- return `${this.base.endsWith("/") ? this.base.slice(0, -1) : this.base}/@fs${absPath}`;
664
+ /** The URL Vite's dev server serves `absPath` at, the form its dev CSS
665
+ * pass writes (`fileToDevUrl`): root-relative inside its root, `/@fs/`
666
+ * outside, under `server.origin` and the base. Every consumer, the
667
+ * stylesheet that pass rewrites, component CSS it does not, and a font
668
+ * preload, then names one URL, and the browser fetches the file once. */
669
+ devServedUrl(absPath) {
670
+ const base = this.base.endsWith("/") ? this.base.slice(0, -1) : this.base;
671
+ const root = this.viteRoot.endsWith("/") ? this.viteRoot : `${this.viteRoot}/`;
672
+ const path$8 = this.viteRoot !== "" && absPath.startsWith(root) ? `/${absPath.slice(root.length)}` : `/@fs${absPath}`;
673
+ return `${this.serverOrigin}${base}${path$8}`;
674
+ }
675
+ /** A root-relative URL a face names as written, as Vite's dev CSS pass
676
+ * writes it: under `server.origin` and the base where it names a public
677
+ * file or a file under the root, else unchanged. */
678
+ devRootRelativeUrl(href) {
679
+ if (!href.startsWith("/") || href.startsWith("//")) return href;
680
+ let path$6;
681
+ try {
682
+ path$6 = decodeURI(href.split(/[?#]/)[0]);
683
+ } catch {
684
+ return href;
685
+ }
686
+ if (![this.publicDir, this.viteRoot].some((dir) => dir !== "" && (0, fs.existsSync)((0, path.join)(dir, path$6)))) return href;
687
+ const base = this.base.endsWith("/") ? this.base.slice(0, -1) : this.base;
688
+ return `${this.serverOrigin}${base}${href}`;
651
689
  }
652
690
  /** A dev asset() URL: an immutable content-named copy of `absPath`, so an
653
691
  * edit gets a new URL, or the live file where copies are not served. */
654
692
  devAssetUrl(specifier, absPath) {
655
- if (this.assetCopyDir === null) return this.devFsUrl(absPath);
693
+ if (this.assetCopyDir === null) return this.devServedUrl(absPath);
656
694
  const { fileName } = (0, _animus_ui_extract_pipeline.writeAssetCopy)(absPath, this.assetCopyDir);
657
695
  const copyPath = (0, path.join)(this.assetCopyDir, fileName);
658
696
  if (!this.servesFile(copyPath)) {
@@ -660,12 +698,12 @@ var PluginContext = class {
660
698
  this.unservedAssetCopies.add(specifier);
661
699
  this.warn(`[animus-extract] the copy of asset() ${specifier} is not served under server.fs; serving the live file instead, so an edit keeps its URL`);
662
700
  }
663
- return this.devFsUrl(absPath);
701
+ return this.devServedUrl(absPath);
664
702
  }
665
703
  if (this.assetSourceBySpecifier.get(specifier) !== absPath) this.devServer?.watcher?.add(absPath);
666
704
  this.assetSourceBySpecifier.set(specifier, absPath);
667
705
  this.retainAssetCopy(absPath, fileName);
668
- return this.devFsUrl(copyPath);
706
+ return this.devServedUrl(copyPath);
669
707
  }
670
708
  /** Keeps each source's current copy and the one before it; an asset
671
709
  * edit reloads the page, so an older URL is never fetched again. A copy
@@ -773,8 +811,8 @@ var PluginContext = class {
773
811
  plan.missing,
774
812
  directories
775
813
  ]) {
776
- const added = paths.filter((path$7) => !registered.has(path$7));
777
- for (const path$8 of added) registered.add(path$8);
814
+ const added = paths.filter((path$9) => !registered.has(path$9));
815
+ for (const path$10 of added) registered.add(path$10);
778
816
  if (added.length > 0) watcher.add(added);
779
817
  }
780
818
  }
@@ -1283,11 +1321,60 @@ function invalidateStaleModules(ctx, environment, modules, analyzed) {
1283
1321
  }
1284
1322
  //#endregion
1285
1323
  //#region src/index-html.ts
1324
+ const LINK_TAG_RE = /<link\b[^>]*>/gi;
1325
+ const REL_RE = /\srel\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/i;
1326
+ const HREF_RE = /\shref\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/i;
1327
+ function attribute(tag, re) {
1328
+ const match = re.exec(tag);
1329
+ return match ? match[1] ?? match[2] ?? match[3] : void 0;
1330
+ }
1331
+ /** The hrefs the document already preloads. */
1332
+ function preloadedHrefs(html) {
1333
+ const hrefs = /* @__PURE__ */ new Set();
1334
+ for (const [tag] of html.matchAll(LINK_TAG_RE)) {
1335
+ const rel = attribute(tag, REL_RE)?.toLowerCase().split(/\s+/) ?? [];
1336
+ const href = attribute(tag, HREF_RE);
1337
+ if (rel.includes("preload") && href !== void 0) hrefs.add(href);
1338
+ }
1339
+ return hrefs;
1340
+ }
1341
+ /** The preconnects and preloads for the faces that ask for one, by the
1342
+ * URL the stylesheet's own `url()` gets; one the document already
1343
+ * preloads is left out. */
1344
+ function fontPreloadTags(ctx, html) {
1345
+ const published = ctx.served?.fontPreloads ?? [];
1346
+ if (published.length === 0) return [];
1347
+ const existing = preloadedHrefs(html);
1348
+ const preloads = (0, _animus_ui_extract_pipeline.substituteFontPreloads)(published, ctx.assetUrlBySpecifier).map((preload) => ctx.isProd ? preload : {
1349
+ ...preload,
1350
+ href: ctx.devRootRelativeUrl(preload.href)
1351
+ }).filter(({ href }) => !existing.has(href));
1352
+ return [...(0, _animus_ui_extract_pipeline.fontPreloadOrigins)(preloads.map(({ href }) => href)).map((origin) => ({
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: {
1363
+ rel: "preload",
1364
+ href,
1365
+ as: "font",
1366
+ type,
1367
+ crossorigin: true
1368
+ },
1369
+ injectTo: "head-prepend"
1370
+ }))];
1371
+ }
1286
1372
  /**
1287
1373
  * Vite serializes one `head-prepend` bucket in array order, so the bootstrap
1288
- * script precedes the layer declaration and every stylesheet reference.
1374
+ * script precedes the font preloads, the layer declaration and every
1375
+ * stylesheet reference.
1289
1376
  */
1290
- function buildIndexHtmlTags(ctx) {
1377
+ function buildIndexHtmlTags(ctx, html = "") {
1291
1378
  const tags = [];
1292
1379
  const bootstrap = ctx.options.appearanceBootstrap;
1293
1380
  if (bootstrap?.code) tags.push({
@@ -1296,6 +1383,7 @@ function buildIndexHtmlTags(ctx) {
1296
1383
  children: bootstrap.code,
1297
1384
  injectTo: "head-prepend"
1298
1385
  });
1386
+ tags.push(...fontPreloadTags(ctx, html));
1299
1387
  if (ctx.layerDeclaration) tags.push({
1300
1388
  tag: "style",
1301
1389
  attrs: { "data-animus-layers": "" },
@@ -1314,6 +1402,32 @@ function buildIndexHtmlTags(ctx) {
1314
1402
  return tags;
1315
1403
  }
1316
1404
  //#endregion
1405
+ //#region src/quarantine-plugin.ts
1406
+ /**
1407
+ * layergate's Vite plugin for the `quarantine` option, loaded on first use:
1408
+ * layergate is an optional peer.
1409
+ */
1410
+ function quarantinePlugin(options, layers) {
1411
+ const order = (0, _animus_ui_extract_pipeline.withVendorLayer)(layers);
1412
+ let plugin;
1413
+ return {
1414
+ order,
1415
+ plugin: () => plugin ??= load(options, order)
1416
+ };
1417
+ }
1418
+ async function load(options, order) {
1419
+ let layergate;
1420
+ try {
1421
+ ({layergate} = await import("@animus-ui/layergate/vite"));
1422
+ } catch (cause) {
1423
+ throw (0, _animus_ui_extract_pipeline.layergateMissing)("@animus-ui/vite-plugin", cause);
1424
+ }
1425
+ return layergate({
1426
+ ...(0, _animus_ui_extract_pipeline.layergateOptions)(options, order),
1427
+ declaredBy: VIRTUAL_CSS_ID
1428
+ });
1429
+ }
1430
+ //#endregion
1317
1431
  //#region src/virtual-modules.ts
1318
1432
  /**
1319
1433
  * Keyed on the whole option record: two instances sharing a key means the
@@ -1427,6 +1541,27 @@ if (import.meta.hot) {
1427
1541
  return null;
1428
1542
  }
1429
1543
  //#endregion
1544
+ //#region src/watch-ignored.ts
1545
+ /** A path as a glob that matches only itself. Each special character
1546
+ * goes in a bracket: the watcher turns every backslash in an ignored
1547
+ * glob into a slash, so a backslash escape would split the path. */
1548
+ function literal(path) {
1549
+ return path.replace(/\\/g, "/").replace(/[()[\]{}*?!+@|]/g, "[$&]");
1550
+ }
1551
+ /**
1552
+ * `server.watch.ignored` entries that watch installed kits. Vite always
1553
+ * ignores every `node_modules` path, where an installed kit lives, and
1554
+ * watches what a negated glob names. Each glob names a kit root and the
1555
+ * paths under it that ingestion would read: a segment holding an excluded
1556
+ * name, the kit's own `node_modules` among them, stays ignored, so the
1557
+ * watcher never walks into it. The segment test is a regex lookahead,
1558
+ * which picomatch keeps as written.
1559
+ */
1560
+ function kitWatchNegations(roots) {
1561
+ const excluded = _animus_ui_extract_pipeline.PACKAGE_SRC_EXCLUDES.map((name) => `*${literal(name)}`).join("|");
1562
+ return roots.map((root) => `!${literal(root)}*(/(?!${excluded})*)`);
1563
+ }
1564
+ //#endregion
1430
1565
  //#region src/index.ts
1431
1566
  async function sourceKitConfig(rootDir, systemPath, engine) {
1432
1567
  const kits = /* @__PURE__ */ new Map();
@@ -1438,45 +1573,64 @@ async function sourceKitConfig(rootDir, systemPath, engine) {
1438
1573
  exclude: names,
1439
1574
  include: [...kits.values()].flatMap((kit) => kit.dependencies.map((dependency) => `${kit.name} > ${dependency}`))
1440
1575
  },
1441
- ssr: { noExternal: names }
1576
+ ssr: { noExternal: names },
1577
+ roots: [...kits.values()].map((kit) => kit.root)
1442
1578
  };
1443
1579
  }
1444
1580
  function animusExtract(options) {
1445
1581
  (0, _animus_ui_extract_pipeline.assertSupportedEngine)(options.engine);
1446
- (0, _animus_ui_extract_pipeline.assertKnownOptionKeys)(options, ["verify", "appearanceBootstrap"], [{
1582
+ (0, _animus_ui_extract_pipeline.assertKnownOptionKeys)(options, [
1583
+ "verify",
1584
+ "appearanceBootstrap",
1585
+ "quarantine"
1586
+ ], [{
1447
1587
  key: "root",
1448
1588
  reason: "the Vite driver derives its root from the resolved Vite config"
1449
1589
  }], {
1450
1590
  onUnknownKey: "warn",
1451
1591
  warn: (message) => console.warn(`[animus-extract] ${message}`)
1452
1592
  });
1453
- const ctx = new PluginContext(options);
1593
+ const vendor = options.quarantine ? quarantinePlugin(options.quarantine, options.layers) : null;
1594
+ const ctx = new PluginContext(vendor ? {
1595
+ ...options,
1596
+ layers: vendor.order
1597
+ } : options);
1454
1598
  return {
1455
1599
  name: "animus-extract",
1456
1600
  enforce: "pre",
1457
1601
  async config(userConfig, env) {
1602
+ const vendorConfig = await (await vendor?.plugin())?.config.call(this, userConfig, env);
1603
+ const withVendor = (own) => vendorConfig ? (0, vite.mergeConfig)(own, vendorConfig) : own;
1458
1604
  const { mode } = (0, _animus_ui_extract_pipeline.resolveMode)(options.mode, () => env.command === "build" ? "production" : "development");
1459
1605
  const define = { __ANIMUS_DEV__: mode === "development" };
1460
1606
  const root = (0, path.resolve)(userConfig.root ?? process.cwd());
1461
1607
  const kits = await sourceKitConfig(root, (0, path.resolve)(root, options.system), ctx.kitEngine());
1462
- return kits ? {
1608
+ if (!kits) return withVendor({ define });
1609
+ const { roots, ...config } = kits;
1610
+ const watched = env.command === "serve" && userConfig.server?.watch !== null ? { server: { watch: { ignored: kitWatchNegations(roots) } } } : {};
1611
+ return withVendor({
1463
1612
  define,
1464
- ...kits
1465
- } : { define };
1613
+ ...config,
1614
+ ...watched
1615
+ });
1466
1616
  },
1467
- configureServer(server) {
1617
+ async configureServer(server) {
1618
+ await (await vendor?.plugin())?.configureServer.call(this, server);
1468
1619
  ctx.devServer = server;
1469
1620
  ctx.registerSystemWatchPaths();
1470
1621
  },
1471
- configResolved(config) {
1622
+ async configResolved(config) {
1472
1623
  applyResolvedConfig(ctx, config);
1624
+ (await vendor?.plugin())?.configResolved.call(this, config);
1473
1625
  },
1474
- buildEnd() {
1626
+ async buildEnd() {
1627
+ (await vendor?.plugin())?.buildEnd.call(this);
1475
1628
  if (!ctx.builds.end(this.environment ?? ctx.builds.single)) return;
1476
1629
  cancelSystemReload(ctx);
1477
1630
  ctx.close();
1478
1631
  },
1479
1632
  async buildStart() {
1633
+ await (await vendor?.plugin())?.buildStart.call(this);
1480
1634
  await ctx.builds.open(this.environment ?? ctx.builds.single);
1481
1635
  await runBuildStart(ctx, async (specifier, importer) => {
1482
1636
  return (await this.resolve(specifier, importer))?.id ?? null;
@@ -1486,7 +1640,9 @@ function animusExtract(options) {
1486
1640
  source
1487
1641
  }) : void 0);
1488
1642
  },
1489
- async resolveId(id, importer) {
1643
+ async resolveId(id, importer, resolveOptions) {
1644
+ const owned = await (await vendor?.plugin())?.resolveId.call(this, id, importer, resolveOptions);
1645
+ if (owned) return owned;
1490
1646
  const virtual = resolveVirtualId(ctx, id);
1491
1647
  if (virtual !== null || !id.startsWith(".") || importer === void 0) return virtual;
1492
1648
  const importerPath = importer.split("?")[0];
@@ -1498,20 +1654,31 @@ function animusExtract(options) {
1498
1654
  moduleSideEffects: true
1499
1655
  };
1500
1656
  },
1501
- load(id) {
1502
- return loadVirtualModule(ctx, id);
1657
+ async load(id) {
1658
+ const layergate = await vendor?.plugin();
1659
+ const loaded = await layergate?.load.call(this, id);
1660
+ if (loaded) return loaded;
1661
+ const own = loadVirtualModule(ctx, id);
1662
+ if (layergate && id === RESOLVED_CSS_ID && own !== null) return await layergate.stylesheetHead.call(this, id) + own;
1663
+ return own;
1503
1664
  },
1504
- transform(code, id) {
1665
+ async transform(code, id) {
1666
+ if (vendor && /\.css(?:$|\?)/.test(id)) return (await vendor.plugin()).transform.call(this, code, id);
1505
1667
  return transformSource(ctx, code, id);
1506
1668
  },
1507
1669
  transformIndexHtml: {
1508
1670
  order: "pre",
1509
- handler() {
1510
- return buildIndexHtmlTags(ctx);
1671
+ handler(html) {
1672
+ return buildIndexHtmlTags(ctx, html);
1511
1673
  }
1512
1674
  },
1513
1675
  async hotUpdate(hmr) {
1514
- return handleHotUpdate(ctx, this.environment, hmr);
1676
+ const vendorModules = (await vendor?.plugin())?.hotUpdate.call(this, hmr);
1677
+ const next = vendorModules ? {
1678
+ ...hmr,
1679
+ modules: vendorModules
1680
+ } : hmr;
1681
+ return await handleHotUpdate(ctx, this.environment, next) ?? vendorModules;
1515
1682
  }
1516
1683
  };
1517
1684
  }
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- import type { ClosedDynamicImport, DiagnosticLevels, StaticCssConfig } from '@animus-ui/extract/pipeline';
1
+ import type { AnimusQuarantineOptions, ClosedDynamicImport, DiagnosticLevels, StaticCssConfig } 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
5
  export interface AnimusExtractOptions {
5
6
  /** Path to a module exporting a SystemInstance from `@animus-ui/system`. */
6
7
  system: string;
@@ -107,6 +108,15 @@ export interface AnimusExtractOptions {
107
108
  code: string;
108
109
  cspHash: string;
109
110
  };
111
+ /**
112
+ * Load third-party stylesheets into `anm-vendor`, a layer below every
113
+ * Animus layer, so their normal rules never beat Animus's. Needs
114
+ * `@animus-ui/layergate`. `sheets` are delivered with Animus's stylesheet,
115
+ * ahead of it; `dependencies` also covers `.css` your modules import from
116
+ * packages; `optOut` keeps a file's own rules outside the layer. App CSS
117
+ * and CSS Modules are left alone.
118
+ */
119
+ quarantine?: AnimusQuarantineOptions;
110
120
  }
111
121
  export declare function animusExtract(options: AnimusExtractOptions): Plugin;
112
122
  export default animusExtract;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EACV,mBAAmB,EACnB,gBAAgB,EAEhB,eAAe,EAChB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AA4C5D,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;;;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;CACzD;AAMD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAkInE;eAEc,aAAa"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EACV,uBAAuB,EACvB,mBAAmB,EACnB,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;;;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;AAMD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAoLnE;eAEc,aAAa"}
@@ -0,0 +1,10 @@
1
+ import type { AnimusQuarantineOptions } from '@animus-ui/extract/pipeline';
2
+ import type { LayergatePlugin } from '@animus-ui/layergate/vite';
3
+ export interface Quarantine {
4
+ /** The layer order, `anm-vendor` first, Animus's stylesheet declares. */
5
+ order: string[];
6
+ /** layergate's plugin, whose hooks Animus's own run. */
7
+ plugin(): Promise<LayergatePlugin>;
8
+ }
9
+ export declare function quarantinePlugin(options: AnimusQuarantineOptions, layers: readonly string[] | undefined): Quarantine;
10
+ //# sourceMappingURL=quarantine-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quarantine-plugin.d.ts","sourceRoot":"","sources":["../src/quarantine-plugin.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,WAAW,UAAU;IACzB,yEAAyE;IACzE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,wDAAwD;IACxD,MAAM,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;CACpC;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,uBAAuB,EAChC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACpC,UAAU,CAIZ"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * `server.watch.ignored` entries that watch installed kits. Vite always
3
+ * ignores every `node_modules` path, where an installed kit lives, and
4
+ * watches what a negated glob names. Each glob names a kit root and the
5
+ * paths under it that ingestion would read: a segment holding an excluded
6
+ * name, the kit's own `node_modules` among them, stays ignored, so the
7
+ * watcher never walks into it. The segment test is a regex lookahead,
8
+ * which picomatch keeps as written.
9
+ */
10
+ export declare function kitWatchNegations(roots: readonly string[]): string[];
11
+ //# sourceMappingURL=watch-ignored.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-ignored.d.ts","sourceRoot":"","sources":["../src/watch-ignored.ts"],"names":[],"mappings":"AASA;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAKpE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@animus-ui/vite-plugin",
3
- "version": "0.1.32",
3
+ "version": "0.1.35",
4
4
  "description": "Animus static CSS extraction Vite plugin",
5
5
  "keywords": [
6
6
  "animus",
@@ -39,16 +39,23 @@
39
39
  "compile": "bun check"
40
40
  },
41
41
  "dependencies": {
42
- "@animus-ui/extract": "0.1.32",
42
+ "@animus-ui/extract": "0.1.35",
43
43
  "browserslist": "^4.28.8",
44
44
  "lightningcss": "^1.33.0"
45
45
  },
46
46
  "devDependencies": {
47
- "@animus-ui/assertions": "0.1.32"
47
+ "@animus-ui/assertions": "0.1.35",
48
+ "@animus-ui/layergate": "0.1.35"
48
49
  },
49
50
  "peerDependencies": {
51
+ "@animus-ui/layergate": "0.1.35",
50
52
  "vite": ">=8 <9"
51
53
  },
54
+ "peerDependenciesMeta": {
55
+ "@animus-ui/layergate": {
56
+ "optional": true
57
+ }
58
+ },
52
59
  "engines": {
53
60
  "node": ">=22.12.0"
54
61
  }