@animus-ui/vite-plugin 0.1.31 → 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
@@ -505,6 +520,7 @@ var PluginContext = class {
505
520
  const options = this.options;
506
521
  const session = new _animus_ui_extract_session.ExtractionSession({
507
522
  system: options.system,
523
+ systemExport: options.systemExport,
508
524
  exclude: options.exclude,
509
525
  extensions: options.extensions,
510
526
  strict: options.strict,
@@ -554,7 +570,7 @@ var PluginContext = class {
554
570
  * between sees one generation. */
555
571
  observeOutcome(session, outcome) {
556
572
  let systemPropsChanged = false;
557
- 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);
558
574
  else {
559
575
  this.abortedParseHashes.clear();
560
576
  const before = this.systemPropsModule;
@@ -645,13 +661,36 @@ var PluginContext = class {
645
661
  if (!report) throw new Error(message, cause === void 0 ? void 0 : { cause });
646
662
  report(message);
647
663
  }
648
- devFsUrl(absPath) {
649
- 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}`;
650
689
  }
651
690
  /** A dev asset() URL: an immutable content-named copy of `absPath`, so an
652
691
  * edit gets a new URL, or the live file where copies are not served. */
653
692
  devAssetUrl(specifier, absPath) {
654
- if (this.assetCopyDir === null) return this.devFsUrl(absPath);
693
+ if (this.assetCopyDir === null) return this.devServedUrl(absPath);
655
694
  const { fileName } = (0, _animus_ui_extract_pipeline.writeAssetCopy)(absPath, this.assetCopyDir);
656
695
  const copyPath = (0, path.join)(this.assetCopyDir, fileName);
657
696
  if (!this.servesFile(copyPath)) {
@@ -659,12 +698,12 @@ var PluginContext = class {
659
698
  this.unservedAssetCopies.add(specifier);
660
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`);
661
700
  }
662
- return this.devFsUrl(absPath);
701
+ return this.devServedUrl(absPath);
663
702
  }
664
703
  if (this.assetSourceBySpecifier.get(specifier) !== absPath) this.devServer?.watcher?.add(absPath);
665
704
  this.assetSourceBySpecifier.set(specifier, absPath);
666
705
  this.retainAssetCopy(absPath, fileName);
667
- return this.devFsUrl(copyPath);
706
+ return this.devServedUrl(copyPath);
668
707
  }
669
708
  /** Keeps each source's current copy and the one before it; an asset
670
709
  * edit reloads the page, so an older URL is never fetched again. A copy
@@ -772,8 +811,8 @@ var PluginContext = class {
772
811
  plan.missing,
773
812
  directories
774
813
  ]) {
775
- const added = paths.filter((path$7) => !registered.has(path$7));
776
- 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);
777
816
  if (added.length > 0) watcher.add(added);
778
817
  }
779
818
  }
@@ -1282,11 +1321,60 @@ function invalidateStaleModules(ctx, environment, modules, analyzed) {
1282
1321
  }
1283
1322
  //#endregion
1284
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
+ }
1285
1372
  /**
1286
1373
  * Vite serializes one `head-prepend` bucket in array order, so the bootstrap
1287
- * script precedes the layer declaration and every stylesheet reference.
1374
+ * script precedes the font preloads, the layer declaration and every
1375
+ * stylesheet reference.
1288
1376
  */
1289
- function buildIndexHtmlTags(ctx) {
1377
+ function buildIndexHtmlTags(ctx, html = "") {
1290
1378
  const tags = [];
1291
1379
  const bootstrap = ctx.options.appearanceBootstrap;
1292
1380
  if (bootstrap?.code) tags.push({
@@ -1295,6 +1383,7 @@ function buildIndexHtmlTags(ctx) {
1295
1383
  children: bootstrap.code,
1296
1384
  injectTo: "head-prepend"
1297
1385
  });
1386
+ tags.push(...fontPreloadTags(ctx, html));
1298
1387
  if (ctx.layerDeclaration) tags.push({
1299
1388
  tag: "style",
1300
1389
  attrs: { "data-animus-layers": "" },
@@ -1313,6 +1402,32 @@ function buildIndexHtmlTags(ctx) {
1313
1402
  return tags;
1314
1403
  }
1315
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
1316
1431
  //#region src/virtual-modules.ts
1317
1432
  /**
1318
1433
  * Keyed on the whole option record: two instances sharing a key means the
@@ -1426,6 +1541,27 @@ if (import.meta.hot) {
1426
1541
  return null;
1427
1542
  }
1428
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
1429
1565
  //#region src/index.ts
1430
1566
  async function sourceKitConfig(rootDir, systemPath, engine) {
1431
1567
  const kits = /* @__PURE__ */ new Map();
@@ -1437,45 +1573,64 @@ async function sourceKitConfig(rootDir, systemPath, engine) {
1437
1573
  exclude: names,
1438
1574
  include: [...kits.values()].flatMap((kit) => kit.dependencies.map((dependency) => `${kit.name} > ${dependency}`))
1439
1575
  },
1440
- ssr: { noExternal: names }
1576
+ ssr: { noExternal: names },
1577
+ roots: [...kits.values()].map((kit) => kit.root)
1441
1578
  };
1442
1579
  }
1443
1580
  function animusExtract(options) {
1444
1581
  (0, _animus_ui_extract_pipeline.assertSupportedEngine)(options.engine);
1445
- (0, _animus_ui_extract_pipeline.assertKnownOptionKeys)(options, ["verify", "appearanceBootstrap"], [{
1582
+ (0, _animus_ui_extract_pipeline.assertKnownOptionKeys)(options, [
1583
+ "verify",
1584
+ "appearanceBootstrap",
1585
+ "quarantine"
1586
+ ], [{
1446
1587
  key: "root",
1447
1588
  reason: "the Vite driver derives its root from the resolved Vite config"
1448
1589
  }], {
1449
1590
  onUnknownKey: "warn",
1450
1591
  warn: (message) => console.warn(`[animus-extract] ${message}`)
1451
1592
  });
1452
- 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);
1453
1598
  return {
1454
1599
  name: "animus-extract",
1455
1600
  enforce: "pre",
1456
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;
1457
1604
  const { mode } = (0, _animus_ui_extract_pipeline.resolveMode)(options.mode, () => env.command === "build" ? "production" : "development");
1458
1605
  const define = { __ANIMUS_DEV__: mode === "development" };
1459
1606
  const root = (0, path.resolve)(userConfig.root ?? process.cwd());
1460
1607
  const kits = await sourceKitConfig(root, (0, path.resolve)(root, options.system), ctx.kitEngine());
1461
- 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({
1462
1612
  define,
1463
- ...kits
1464
- } : { define };
1613
+ ...config,
1614
+ ...watched
1615
+ });
1465
1616
  },
1466
- configureServer(server) {
1617
+ async configureServer(server) {
1618
+ await (await vendor?.plugin())?.configureServer.call(this, server);
1467
1619
  ctx.devServer = server;
1468
1620
  ctx.registerSystemWatchPaths();
1469
1621
  },
1470
- configResolved(config) {
1622
+ async configResolved(config) {
1471
1623
  applyResolvedConfig(ctx, config);
1624
+ (await vendor?.plugin())?.configResolved.call(this, config);
1472
1625
  },
1473
- buildEnd() {
1626
+ async buildEnd() {
1627
+ (await vendor?.plugin())?.buildEnd.call(this);
1474
1628
  if (!ctx.builds.end(this.environment ?? ctx.builds.single)) return;
1475
1629
  cancelSystemReload(ctx);
1476
1630
  ctx.close();
1477
1631
  },
1478
1632
  async buildStart() {
1633
+ await (await vendor?.plugin())?.buildStart.call(this);
1479
1634
  await ctx.builds.open(this.environment ?? ctx.builds.single);
1480
1635
  await runBuildStart(ctx, async (specifier, importer) => {
1481
1636
  return (await this.resolve(specifier, importer))?.id ?? null;
@@ -1485,7 +1640,9 @@ function animusExtract(options) {
1485
1640
  source
1486
1641
  }) : void 0);
1487
1642
  },
1488
- 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;
1489
1646
  const virtual = resolveVirtualId(ctx, id);
1490
1647
  if (virtual !== null || !id.startsWith(".") || importer === void 0) return virtual;
1491
1648
  const importerPath = importer.split("?")[0];
@@ -1497,20 +1654,31 @@ function animusExtract(options) {
1497
1654
  moduleSideEffects: true
1498
1655
  };
1499
1656
  },
1500
- load(id) {
1501
- 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;
1502
1664
  },
1503
- transform(code, id) {
1665
+ async transform(code, id) {
1666
+ if (vendor && /\.css(?:$|\?)/.test(id)) return (await vendor.plugin()).transform.call(this, code, id);
1504
1667
  return transformSource(ctx, code, id);
1505
1668
  },
1506
1669
  transformIndexHtml: {
1507
1670
  order: "pre",
1508
- handler() {
1509
- return buildIndexHtmlTags(ctx);
1671
+ handler(html) {
1672
+ return buildIndexHtmlTags(ctx, html);
1510
1673
  }
1511
1674
  },
1512
1675
  async hotUpdate(hmr) {
1513
- 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;
1514
1682
  }
1515
1683
  };
1516
1684
  }
package/dist/index.d.ts CHANGED
@@ -1,9 +1,15 @@
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;
8
+ /** The system's export name in the `system` module. The loader runs only
9
+ * what that export reaches, and finds it itself when exactly one export
10
+ * is a sealed system (`.seal()`) and every other export is plainly not
11
+ * one; otherwise it asks for this option by name. */
12
+ systemExport?: string;
7
13
  /**
8
14
  * Module specifier for extracted runtime factories, default
9
15
  * `@animus-ui/system/runtime`, as every adapter emits. `@animus-ui/system`
@@ -102,6 +108,15 @@ export interface AnimusExtractOptions {
102
108
  code: string;
103
109
  cspHash: string;
104
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;
105
120
  }
106
121
  export declare function animusExtract(options: AnimusExtractOptions): Plugin;
107
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;;;;;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.31",
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.31",
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.31"
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
  }