@menapo/vicss 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vite.js CHANGED
@@ -1,14 +1,78 @@
1
- import { Et as mergeIdOf, G as minLengthWarning, H as hasPlaceholders, J as renameClasses, O as layerStatement, Q as isPaletteAtom, St as isArbitrary, V as createNamer, W as minLengthOf, _t as VicssError, c as printAtoms, l as printBase, o as outerLayers, t as baseTokens, u as printSheet, yt as compareStrings } from "./print-Ds6fkgio.js";
2
- import { u as baseAtoms } from "./theme-C-0LpsJx.js";
3
- import { S as originalLines, _ as isSfc, d as FRAMEWORKS, f as SFC_SCRIPT_ID, h as extractScripts, i as poolSize, l as resolveFile, m as detectFramework, o as compile, p as configuredJsxSource, r as configShape, s as createParseCache, t as CompilePool, u as resolvesAlike, x as SourceEdits } from "./pool-BGXMhLfL.js";
4
- import { C as CompileCache, D as generateTypes, E as readHash, O as createManifest, S as report, T as hashCode, _ as critical, a as ScanConflict, b as hashesJson, c as scan, d as libraryOf, f as loadLibraries, g as SheetCache, h as withLibraries, i as writeIfChanged, k as codeFrame, l as escapeRegExp, m as renameCustomProperties, n as snapshotRoot, o as estimateStyled, p as ownPackageName, r as typesFile, s as listFiles, t as snapshotFile, u as findLibraries, v as criticalPage, w as compiledOf, y as criticalSettings } from "./types-file-R_knFzME.js";
5
- import { r as snapshotText } from "./snapshot-BQb8ZmSV.js";
6
- import { n as loadSystem, t as CONFIG_FILES } from "./config-loader-DzP68Snn.js";
1
+ import { $ as isPaletteAtom, Ct as isArbitrary, Dt as mergeIdOf, G as minLengthOf, H as createNamer, J as placeholdersIn, K as minLengthWarning, U as hasPlaceholders, Y as renameClasses, _t as VicssError, bt as compareStrings, d as printSheet, k as layerStatement, l as printAtoms, n as chainSelectors, q as placeholder, s as outerLayers, t as baseTokens, u as printBase } from "./print-B_mn7wBu.js";
2
+ import { S as originalLines, _ as isSfc, d as FRAMEWORKS, f as SFC_SCRIPT_ID, h as extractScripts, i as poolSize, l as resolveFile, m as detectFramework, o as compile, p as configuredJsxSource, r as configShape, s as createParseCache, t as CompilePool, u as resolvesAlike, x as SourceEdits } from "./pool-F3qb30Fy.js";
3
+ import { C as createLocator, u as baseAtoms } from "./theme-zBcr5DHi.js";
4
+ import { C as CompileCache, D as generateTypes, E as readHash, O as createManifest, S as report, T as hashCode, _ as critical, a as ScanConflict, b as hashesJson, c as scan, d as libraryOf, f as loadLibraries, g as SheetCache, h as withLibraries, i as writeIfChanged, k as codeFrame, l as escapeRegExp, m as renameCustomProperties, n as snapshotRoot, o as estimateStyled, p as ownPackageName, r as typesFile, s as listFiles, t as snapshotFile, u as findLibraries, v as criticalPage, w as compiledOf, y as criticalSettings } from "./types-file-D6Iu4kzv.js";
5
+ import { r as snapshotText } from "./snapshot-DAJ8FLU4.js";
6
+ import { n as loadSystem, t as CONFIG_FILES } from "./config-loader-1kWS0cRU.js";
7
7
  import { existsSync, readFileSync, readdirSync } from "node:fs";
8
8
  import { readFile } from "node:fs/promises";
9
9
  import path from "node:path";
10
10
  import { gzipSync } from "node:zlib";
11
- import { createIdResolver, isFileLoadingAllowed, normalizePath } from "vite";
11
+ import { createIdResolver, isFileLoadingAllowed, normalizePath, parseSync } from "vite";
12
+ //#region src/core/literals.ts
13
+ /**
14
+ * Literal declarations (the plugin's `api.literals()`, email PLAN D4): each
15
+ * atom with its tokens resolved to the values they stand for, for a renderer
16
+ * that cannot read custom properties. Mail clients drop `var()` and cascade
17
+ * layers, so `@menapo/email` inlines these instead of linking the sheet.
18
+ */
19
+ const VAR = /var\((--[\w-]+)\)/g;
20
+ const SCHEMES = /* @__PURE__ */ new Set(["dark", "light"]);
21
+ function tokenIndex(system) {
22
+ const index = /* @__PURE__ */ new Map();
23
+ for (const table of system.tokens.values()) for (const token of table.values()) index.set(token.cssVar, token);
24
+ return index;
25
+ }
26
+ /** `value` with every token's `var()` replaced by its value in `mode` (its base value without one). */
27
+ function resolve(value, index, mode) {
28
+ return value.replace(VAR, (match, name) => {
29
+ const token = index.get(name);
30
+ if (!token) return match;
31
+ return resolve((mode && token.modes?.[mode]) ?? token.value, index, mode);
32
+ });
33
+ }
34
+ /**
35
+ * Every class of `atoms` and of the flattened bases in `rules`, by identity,
36
+ * with its declarations in literal form. A flattened base is one class with
37
+ * many declarations; an atom is one with one.
38
+ */
39
+ function literalsOf(atoms, rules, system) {
40
+ const index = tokenIndex(system);
41
+ const modes = [...system.modes].filter((mode) => system.conditions.get(mode)?.scope);
42
+ const literal = (atom) => {
43
+ const value = resolve(atom.value, index);
44
+ const switched = {};
45
+ let any = false;
46
+ for (const mode of modes) {
47
+ const there = resolve(atom.value, index, mode);
48
+ if (there !== value) {
49
+ switched[mode] = there;
50
+ any = true;
51
+ }
52
+ }
53
+ const conditions = atom.chain.filter((name) => !SCHEMES.has(name));
54
+ return {
55
+ property: atom.property,
56
+ value,
57
+ tier: atom.tier,
58
+ chain: atom.chain,
59
+ rules: chainSelectors(conditions, "&", system),
60
+ ...any && { modes: switched }
61
+ };
62
+ };
63
+ const out = /* @__PURE__ */ new Map();
64
+ for (const atom of atoms) if (!out.has(atom.className)) out.set(atom.className, [literal(atom)]);
65
+ for (const rule of rules) if (rule.kind === "base" && rule.atoms) out.set(rule.id, rule.atoms.map(literal));
66
+ return out;
67
+ }
68
+ const STRINGS = /(["'`])((?:\\.|(?!\1)[^\\\n])*)\1/g;
69
+ /** The classes of `known` that string literals in `code` name (dev code writes classes as they are). */
70
+ function classesIn(code, known) {
71
+ const found = /* @__PURE__ */ new Set();
72
+ for (const match of code.matchAll(STRINGS)) for (const word of match[2].split(/\s+/)) if (known.has(word)) found.add(word);
73
+ return [...found];
74
+ }
75
+ //#endregion
12
76
  //#region src/vite/css.ts
13
77
  /**
14
78
  * The CSS modules the plugin serves (PLAN §5.10, D13, D14) and the ids they
@@ -106,6 +170,166 @@ function buildCss(scan, options, tokensFile) {
106
170
  };
107
171
  }
108
172
  //#endregion
173
+ //#region src/vite/attributes.ts
174
+ /**
175
+ * What every compiled component and JSX module gets for `class=` and
176
+ * `style=` (PLAN §5.16), whether it imports vicss or not: a style it
177
+ * receives may come from anywhere.
178
+ *
179
+ * - Vue's `normalizeClass` and Svelte's `clsx` read an object as a map from
180
+ * class to condition, so `class={card}` would write the merge ids. The
181
+ * compiled component's calls go through `__vxClassWith`, which passes a
182
+ * compiled style as its class string (runtime/style.ts), and the calls
183
+ * that normalise a props object's `class` (spreads, a root element's
184
+ * attributes) through `__vxPropsWith` and `__vxEffectWith`.
185
+ * - In dev, a `style=` value the compiler could not write as an inline
186
+ * style goes through `__vxStyleCheck`, which fails on a compiled style
187
+ * and names the fix (runtime/dev.ts): in JSX attributes and template
188
+ * literals here, in Vue's, Svelte's and Astro's style setters through
189
+ * `__vxStyleWith`.
190
+ */
191
+ const RUNTIME = "@menapo/vicss";
192
+ /** Vue's and Svelte's class calls, and in dev the style setters of all three compilers. */
193
+ function rewriteComponent(code, id, options) {
194
+ const edits = new SourceEdits(code);
195
+ const helpers = /* @__PURE__ */ new Set();
196
+ const consts = [];
197
+ let n = 0;
198
+ const src = JSON.stringify(options.src);
199
+ const named = /import\s*\{([^}]*)\}\s*from\s*(["'])([^"']+)\2;?/g;
200
+ const WRAPS = {
201
+ normalizeClass: (local) => `__vxClassWith(${local})`,
202
+ ssrRenderClass: (local) => `__vxClassWith(${local})`,
203
+ mergeProps: (local) => `__vxPropsWith(${local})`,
204
+ normalizeProps: (local) => `__vxPropsWith(${local})`,
205
+ ssrRenderAttrs: (local) => `__vxPropsWith(${local})`,
206
+ normalizeStyle: (local) => options.dev ? `__vxStyleWith(${local}, 0, ${src})` : void 0,
207
+ ssrRenderStyle: (local) => options.dev ? `__vxStyleWith(${local}, 0, ${src})` : void 0,
208
+ addAttribute: (local) => options.dev ? `__vxStyleWith(${local}, 0, ${src}, "style")` : void 0
209
+ };
210
+ const SOURCES = /^(?:vue|vue\/server-renderer|@vue\/server-renderer|astro\/(?:runtime\/server(?:\/index\.js)?|compiler-runtime))$/;
211
+ for (const match of code.matchAll(named)) {
212
+ if (!SOURCES.test(match[3])) continue;
213
+ const listStart = match.index + match[0].indexOf("{") + 1;
214
+ for (const spec of match[1].matchAll(/(\w+)(?:\s+as\s+([\w$]+))?/g)) {
215
+ const wrap = WRAPS[spec[1]];
216
+ const local = spec[2] ?? spec[1];
217
+ const inner = `__vxOwn${++n}`;
218
+ const text = wrap?.(inner);
219
+ if (!text) continue;
220
+ edits.overwrite(listStart + spec.index, listStart + spec.index + spec[0].length, `${spec[1]} as ${inner}`);
221
+ for (const helper of text.match(/__vx(?:ClassWith|StyleWith|PropsWith)/g)) helpers.add(helper);
222
+ consts.push({
223
+ at: match.index + match[0].length,
224
+ text: `const ${local} = ${text};`
225
+ });
226
+ }
227
+ }
228
+ for (const match of code.matchAll(/import\s*\*\s*as\s+([\w$]+)\s+from\s*(["'])svelte\/internal\/(client|server)\2;?/g)) {
229
+ const ns = match[1];
230
+ const calls = {
231
+ clsx: "__vxClassWith",
232
+ attribute_effect: "__vxEffectWith",
233
+ attributes: "__vxPropsWith",
234
+ set_style: options.dev ? "__vxStyleWith" : void 0,
235
+ attr_style: options.dev ? "__vxStyleWith" : void 0
236
+ };
237
+ for (const [name, helper] of Object.entries(calls)) {
238
+ if (!helper) continue;
239
+ const pattern = new RegExp(`(?<![\\w$.])${ns.replace(/\$/g, "\\$")}\\.${name}(?=\\s*\\()`, "g");
240
+ const local = `__vx_${name}`;
241
+ let used = false;
242
+ for (const call of code.matchAll(pattern)) {
243
+ edits.overwrite(call.index, call.index + call[0].length, local);
244
+ used = true;
245
+ }
246
+ if (!used) continue;
247
+ helpers.add(helper);
248
+ const at = name === "set_style" ? `, 1, ${src}` : name === "attr_style" ? `, 0, ${src}` : "";
249
+ consts.push({
250
+ at: match.index + match[0].length,
251
+ text: `const ${local} = ${helper}(${ns}.${name}${at});`
252
+ });
253
+ }
254
+ }
255
+ if (consts.length === 0) return null;
256
+ for (const { at, text } of consts) edits.insert(at, `\n${text}`);
257
+ edits.prepend(`import { ${[...helpers].join(", ")} } from "${RUNTIME}";\n`);
258
+ const file = id.replace(/[?#].*$/, "");
259
+ return {
260
+ code: edits.toString(),
261
+ map: edits.generateMap({
262
+ source: file,
263
+ file,
264
+ includeContent: true,
265
+ hires: true
266
+ })
267
+ };
268
+ }
269
+ /** Values whose type is plainly not a compiled style: no check. */
270
+ const PLAIN = /* @__PURE__ */ new Set([
271
+ "ObjectExpression",
272
+ "Literal",
273
+ "TemplateLiteral",
274
+ "ArrowFunctionExpression",
275
+ "FunctionExpression"
276
+ ]);
277
+ /**
278
+ * Dev: `style={x}` in JSX, and `style=${x}` in a template literal, where
279
+ * `x` is anything the compiler left: checked when it renders.
280
+ */
281
+ function checkStyles(code, id, src) {
282
+ const file = id.replace(/[?#].*$/, "");
283
+ const lang = /\.([cm]?[jt]sx?)$/.exec(file)?.[1]?.replace(/^[cm]/, "");
284
+ let program;
285
+ try {
286
+ const parsed = parseSync(file, code, {
287
+ lang: lang ?? "js",
288
+ sourceType: "module"
289
+ });
290
+ if (parsed.errors.length > 0) return null;
291
+ program = parsed.program;
292
+ } catch {
293
+ return null;
294
+ }
295
+ const values = [];
296
+ const visit = (node) => {
297
+ if (!node || typeof node !== "object") return;
298
+ if (Array.isArray(node)) {
299
+ for (const item of node) visit(item);
300
+ return;
301
+ }
302
+ const current = node;
303
+ if (typeof current.type !== "string") return;
304
+ if (current.type === "JSXAttribute" && current.name.type === "JSXIdentifier" && current.name.name === "style" && current.value?.type === "JSXExpressionContainer" && current.value.expression.type !== "JSXEmptyExpression" && !PLAIN.has(current.value.expression.type)) values.push(current.value.expression);
305
+ else if (current.type === "TemplateLiteral") current.quasis.forEach((quasi, i) => {
306
+ const expression = current.expressions[i];
307
+ if (expression && /\sstyle="?$/.test(quasi.value.raw) && !PLAIN.has(expression.type)) values.push(expression);
308
+ });
309
+ for (const key in current) if (key !== "parent" && key !== "range") visit(current[key]);
310
+ };
311
+ visit(program);
312
+ if (values.length === 0) return null;
313
+ const edits = new SourceEdits(code, { keepLines: true });
314
+ const locate = createLocator(code);
315
+ for (const value of values) {
316
+ const at = JSON.stringify(`${src}:${locate(value.start).line}`);
317
+ edits.insert(value.start, "__vxStyleCheck(");
318
+ edits.insert(value.end, `, ${at})`);
319
+ }
320
+ const first = program.body.find((node) => !(node.type === "ExpressionStatement" && typeof node.directive === "string"));
321
+ edits.insert(first?.start ?? 0, `import { __vxStyleCheck } from "${RUNTIME}"; `);
322
+ return {
323
+ code: edits.toString(),
324
+ map: edits.generateMap({
325
+ source: file,
326
+ file,
327
+ includeContent: true,
328
+ hires: true
329
+ })
330
+ };
331
+ }
332
+ //#endregion
109
333
  //#region src/vite/html.ts
110
334
  /**
111
335
  * The SPA tokens file (PLAN D13). Tokens change on a theme-only deploy and
@@ -416,6 +640,22 @@ const RUNTIME_PACKAGE = "@menapo/vicss";
416
640
  const MANIFEST_FILE = "vicss.json";
417
641
  const LIBRARY_SHEET_FILE = "vicss.css";
418
642
  const SCRIPT_ID = /\.[cm]?[jt]sx?$/;
643
+ /** The calls `vicss:attributes` rewrites: a module with none is left alone. */
644
+ const COMPONENT_CALLS = [
645
+ "normalizeClass",
646
+ "ssrRenderClass",
647
+ "mergeProps",
648
+ "normalizeProps",
649
+ "ssrRenderAttrs",
650
+ "clsx",
651
+ "attribute_effect",
652
+ "attributes",
653
+ "normalizeStyle",
654
+ "ssrRenderStyle",
655
+ "set_style",
656
+ "attr_style",
657
+ "addAttribute"
658
+ ];
419
659
  /** Declaration files: never styled, and the generated `vicss.d.ts` names the runtime. */
420
660
  const DECLARATION_ID = /\.d\.[cm]?ts$/;
421
661
  /**
@@ -447,6 +687,8 @@ function vicss(options = {}) {
447
687
  let session = newSession();
448
688
  /** The CSS each scan's result prints with the libraries, its atom count and its classes. */
449
689
  const sheets = /* @__PURE__ */ new WeakMap();
690
+ /** Each scan's classes in literal form, for `api.literals()`. */
691
+ const literalTables = /* @__PURE__ */ new WeakMap();
450
692
  /** A scan whose sheet failed to print (a library's atoms conflict with the app's). */
451
693
  const sheetErrors = /* @__PURE__ */ new WeakMap();
452
694
  /** Scan failures a hook has reported (`sheetFor`). */
@@ -1140,7 +1382,60 @@ function vicss(options = {}) {
1140
1382
  name: "vicss",
1141
1383
  enforce: "pre",
1142
1384
  sharedDuringBuild: true,
1143
- api: { options },
1385
+ api: {
1386
+ options,
1387
+ /**
1388
+ * The app's whole stylesheet as one string, for a renderer outside the
1389
+ * browser (`@menapo/og` hands it to takumi, og PLAN D3): in a build,
1390
+ * what the scan prints, so it needs the hook's context; in dev, the
1391
+ * base and every compiled module's atoms, as the dev server serves them.
1392
+ */
1393
+ async stylesheet(ctx) {
1394
+ const s = ready();
1395
+ if (s.dev) return [
1396
+ devBaseCss(registry, s.print, s.loaded.libraries),
1397
+ ...s.loaded.libraries.map((library) => moduleCss(library, s.loaded.system, s.print.names)),
1398
+ ...registry.ids().map((id) => moduleCss(registry.get(id), s.loaded.system, s.print.names))
1399
+ ].join("\n");
1400
+ if (!ctx) throw new Error("vicss: api.stylesheet() needs a plugin hook's context in a build.");
1401
+ const printed = await sheetFor(ctx);
1402
+ return [printed?.css.tokens ?? "", printed?.css.sheet ?? ""].join("\n");
1403
+ },
1404
+ /**
1405
+ * The literal declarations (core/literals.ts) of the classes `code`, a
1406
+ * module as this plugin's transform left it, names: for a renderer
1407
+ * that cannot read custom properties (`@menapo/email` inlines them,
1408
+ * email PLAN D4). Keyed as the code writes each class, so a key written
1409
+ * back into the module is named with the module's own classes: a build
1410
+ * writes placeholders that `renderChunk` names, dev the class itself.
1411
+ * A build needs a hook's context, as `stylesheet()` does.
1412
+ */
1413
+ async literals(code, ctx) {
1414
+ const s = ready();
1415
+ const out = {};
1416
+ if (s.dev) {
1417
+ const table = literalsOf([...s.loaded.libraries.flatMap((library) => library.atoms), ...registry.ids().flatMap((id) => registry.get(id).atoms)], [...s.loaded.libraries.flatMap((library) => library.rules), ...registry.rules()], s.loaded.system);
1418
+ const byName = /* @__PURE__ */ new Map();
1419
+ for (const [identity, list] of table) byName.set(s.print.names.name(identity), list);
1420
+ for (const name of classesIn(code, new Set(byName.keys()))) out[name] = byName.get(name);
1421
+ return out;
1422
+ }
1423
+ if (!ctx) throw new Error("vicss: api.literals() needs a plugin hook's context in a build.");
1424
+ const sheet = await sheetFor(ctx);
1425
+ if (!sheet) return out;
1426
+ let table = literalTables.get(sheet.scan);
1427
+ if (!table) {
1428
+ const all = withLibraries(sheet.scan, s.loaded.libraries, s.loaded.system);
1429
+ table = literalsOf(all.atoms, all.rules, s.loaded.system);
1430
+ literalTables.set(sheet.scan, table);
1431
+ }
1432
+ for (const identity of placeholdersIn(code)) {
1433
+ const list = table.get(identity);
1434
+ if (list) out[placeholder(identity)] = list;
1435
+ }
1436
+ return out;
1437
+ }
1438
+ },
1144
1439
  async configResolved(config) {
1145
1440
  if (state && !state.dev && config.command === "build" && !session.started) {
1146
1441
  session.configs++;
@@ -1348,6 +1643,7 @@ function vicss(options = {}) {
1348
1643
  }
1349
1644
  },
1350
1645
  transform: {
1646
+ order: "pre",
1351
1647
  filter: transformFilter,
1352
1648
  handler(code, id) {
1353
1649
  if (isSfc(id)) return null;
@@ -1569,68 +1865,110 @@ function vicss(options = {}) {
1569
1865
  const criticalPages = /* @__PURE__ */ new Map();
1570
1866
  /** Build: each bundle's CSS files, parsed once for all of its pages. */
1571
1867
  const criticalSheets = /* @__PURE__ */ new WeakMap();
1868
+ const criticalCss = {
1869
+ name: "vicss:critical",
1870
+ apply: "build",
1871
+ enforce: "post",
1872
+ sharedDuringBuild: true,
1873
+ transformIndexHtml: {
1874
+ order: "post",
1875
+ handler(html, ctx) {
1876
+ const settings = criticalSettings(options.critical);
1877
+ const bundle = ctx.bundle;
1878
+ if (!settings || !bundle || state?.dev !== false) return void 0;
1879
+ let output = criticalSheets.get(bundle);
1880
+ if (!output) {
1881
+ const assets = Object.values(bundle).flatMap((file) => file.type === "asset" && file.fileName.endsWith(".css") ? [file] : []);
1882
+ const sources = new Map(assets.map((asset) => [asset.fileName, asset.source]));
1883
+ const { publicDir } = state.config;
1884
+ const own = publicDir && existsSync(publicDir) ? publicStylesheets(publicDir) : [];
1885
+ const names = session.scan && printed(session.scan).names;
1886
+ const sheets = new SheetCache((file) => {
1887
+ const source = sources.get(file);
1888
+ if (source !== void 0) return typeof source === "string" ? source : Buffer.from(source).toString();
1889
+ return own.includes(file) ? readFileSync(path.join(publicDir, file), "utf8") : void 0;
1890
+ }, names ? (cls) => names.relates(cls) : void 0);
1891
+ output = {
1892
+ files: [...sources.keys(), ...own],
1893
+ sheets
1894
+ };
1895
+ criticalSheets.set(bundle, output);
1896
+ }
1897
+ const result = criticalPage({
1898
+ page: ctx.path.replace(/^\//, ""),
1899
+ html,
1900
+ ...output,
1901
+ requireClasses: true
1902
+ });
1903
+ criticalPages.set(result.page, result);
1904
+ return result.html;
1905
+ }
1906
+ },
1907
+ generateBundle(_options, bundle) {
1908
+ const settings = criticalSettings(options.critical);
1909
+ const pages = [...criticalPages.values()].filter((page) => bundle[page.page]?.type === "asset");
1910
+ if (!settings || pages.length === 0) return;
1911
+ for (const page of pages) criticalPages.delete(page.page);
1912
+ const inlined = pages.some((page) => page.html !== void 0);
1913
+ if (settings.hashes !== false && inlined) this.emitFile({
1914
+ type: "asset",
1915
+ fileName: settings.hashes,
1916
+ source: hashesJson(pages, settings.budget)
1917
+ });
1918
+ const { logger } = this.environment.config;
1919
+ const result = report(pages, settings.budget, inlined && settings.hashes ? settings.hashes : void 0);
1920
+ logger.info(result.summary);
1921
+ for (const warning of result.warnings) logger.warn(`vicss: ${warning}`);
1922
+ for (const page of pages) if (page.skipped !== void 0 && !page.warning) logger.info(`vicss: ${page.page}: left as it was: ${page.skipped}`);
1923
+ }
1924
+ };
1925
+ /** Where a check names the module: relative to the root, as `data-vx-src` does. */
1926
+ const sourceName = (id) => {
1927
+ const file = id.replace(/[?#].*$/, "");
1928
+ const root = ready().root.replace(/\/+$/, "");
1929
+ return file.startsWith(`${root}/`) ? file.slice(root.length + 1) : file;
1930
+ };
1572
1931
  return [
1573
1932
  main,
1933
+ {
1934
+ name: "vicss:style-checks",
1935
+ enforce: "pre",
1936
+ apply: "serve",
1937
+ sharedDuringBuild: true,
1938
+ transform: {
1939
+ order: "pre",
1940
+ filter: {
1941
+ id: SCRIPT_ID,
1942
+ code: "style="
1943
+ },
1944
+ handler(code, id) {
1945
+ if (id.includes("/node_modules/") || DECLARATION_ID.test(id)) return null;
1946
+ return checkStyles(code, id, sourceName(id));
1947
+ }
1948
+ }
1949
+ },
1574
1950
  libraries,
1575
1951
  frameworks,
1576
- html,
1577
1952
  {
1578
- name: "vicss:critical",
1579
- apply: "build",
1953
+ name: "vicss:attributes",
1580
1954
  enforce: "post",
1581
1955
  sharedDuringBuild: true,
1582
- transformIndexHtml: {
1583
- order: "post",
1584
- handler(html, ctx) {
1585
- const settings = criticalSettings(options.critical);
1586
- const bundle = ctx.bundle;
1587
- if (!settings || !bundle || state?.dev !== false) return void 0;
1588
- let output = criticalSheets.get(bundle);
1589
- if (!output) {
1590
- const assets = Object.values(bundle).flatMap((file) => file.type === "asset" && file.fileName.endsWith(".css") ? [file] : []);
1591
- const sources = new Map(assets.map((asset) => [asset.fileName, asset.source]));
1592
- const { publicDir } = state.config;
1593
- const own = publicDir && existsSync(publicDir) ? publicStylesheets(publicDir) : [];
1594
- const names = session.scan && printed(session.scan).names;
1595
- const sheets = new SheetCache((file) => {
1596
- const source = sources.get(file);
1597
- if (source !== void 0) return typeof source === "string" ? source : Buffer.from(source).toString();
1598
- return own.includes(file) ? readFileSync(path.join(publicDir, file), "utf8") : void 0;
1599
- }, names ? (cls) => names.relates(cls) : void 0);
1600
- output = {
1601
- files: [...sources.keys(), ...own],
1602
- sheets
1603
- };
1604
- criticalSheets.set(bundle, output);
1605
- }
1606
- const result = criticalPage({
1607
- page: ctx.path.replace(/^\//, ""),
1608
- html,
1609
- ...output,
1610
- requireClasses: true
1956
+ transform: {
1957
+ filter: {
1958
+ id: SFC_SCRIPT_ID,
1959
+ code: COMPONENT_CALLS
1960
+ },
1961
+ handler(code, id) {
1962
+ if (id.includes("/node_modules/")) return null;
1963
+ return rewriteComponent(code, id, {
1964
+ dev: ready().dev,
1965
+ src: sourceName(id)
1611
1966
  });
1612
- criticalPages.set(result.page, result);
1613
- return result.html;
1614
1967
  }
1615
- },
1616
- generateBundle(_options, bundle) {
1617
- const settings = criticalSettings(options.critical);
1618
- const pages = [...criticalPages.values()].filter((page) => bundle[page.page]?.type === "asset");
1619
- if (!settings || pages.length === 0) return;
1620
- for (const page of pages) criticalPages.delete(page.page);
1621
- const inlined = pages.some((page) => page.html !== void 0);
1622
- if (settings.hashes !== false && inlined) this.emitFile({
1623
- type: "asset",
1624
- fileName: settings.hashes,
1625
- source: hashesJson(pages, settings.budget)
1626
- });
1627
- const { logger } = this.environment.config;
1628
- const result = report(pages, settings.budget, inlined && settings.hashes ? settings.hashes : void 0);
1629
- logger.info(result.summary);
1630
- for (const warning of result.warnings) logger.warn(`vicss: ${warning}`);
1631
- for (const page of pages) if (page.skipped !== void 0 && !page.warning) logger.info(`vicss: ${page.page}: left as it was: ${page.skipped}`);
1632
1968
  }
1633
- }
1969
+ },
1970
+ html,
1971
+ criticalCss
1634
1972
  ];
1635
1973
  }
1636
1974
  /** The `.css` files under the public directory, relative to it, as Vite copies them to the output. */
package/dist/worker.js CHANGED
@@ -1,5 +1,5 @@
1
- import { y as resolveSystem } from "./print-Ds6fkgio.js";
2
- import { a as toErrorData, b as setParser, o as compile, r as configShape, s as createParseCache } from "./pool-BGXMhLfL.js";
1
+ import { b as resolveSystem } from "./print-B_mn7wBu.js";
2
+ import { a as toErrorData, b as setParser, o as compile, r as configShape, s as createParseCache } from "./pool-F3qb30Fy.js";
3
3
  import { createRequire } from "node:module";
4
4
  import path from "node:path";
5
5
  import { pathToFileURL } from "node:url";
@@ -46,7 +46,7 @@ const context = (async () => {
46
46
  let system;
47
47
  if ("data" in setup.config) system = resolveSystem(setup.config.data);
48
48
  else {
49
- const { loadSystem } = await import("./config-loader-pLzP9par.js");
49
+ const { loadSystem } = await import("./config-loader-CG76KA50.js");
50
50
  system = (await loadSystem(setup.root, setup.config.file, () => {}, void 0, { native: true })).system;
51
51
  if (configShape(system.config) === setup.config.shape) system = {
52
52
  ...system,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@menapo/vicss",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Typed, design-system-first atomic CSS for Vite: style objects compiled to short hashed class names, recipes with slots and responsive variants, one order-proof stylesheet",
5
5
  "keywords": [
6
6
  "atomic-css",
@@ -14,14 +14,14 @@
14
14
  "vite-plugin",
15
15
  "zero-runtime"
16
16
  ],
17
- "homepage": "https://github.com/menapo/vite-plugins/blob/main/packages/vicss/README.md",
17
+ "homepage": "https://github.com/menapo/kit/blob/main/packages/vicss/README.md",
18
18
  "bugs": {
19
- "url": "https://github.com/menapo/vite-plugins/issues"
19
+ "url": "https://github.com/menapo/kit/issues"
20
20
  },
21
21
  "license": "MIT",
22
22
  "repository": {
23
23
  "type": "git",
24
- "url": "git+https://github.com/menapo/vite-plugins.git",
24
+ "url": "git+https://github.com/menapo/kit.git",
25
25
  "directory": "packages/vicss"
26
26
  },
27
27
  "bin": {
@@ -1 +0,0 @@
1
- export { n as loadSystem } from "./config-loader-DzP68Snn.js";