@hanzogui/static 8.1.0 → 8.2.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/exports.cjs CHANGED
@@ -35,6 +35,7 @@ __reExport(exports_exports, require("./types.cjs"), module.exports);
35
35
  var import_createExtractor = require("./extractor/createExtractor.cjs");
36
36
  var import_literalToAst = require("./extractor/literalToAst.cjs");
37
37
  __reExport(exports_exports, require("./constants.cjs"), module.exports);
38
+ __reExport(exports_exports, require("./extractor/extractablePath.cjs"), module.exports);
38
39
  __reExport(exports_exports, require("./extractor/extractToClassNames.cjs"), module.exports);
39
40
  __reExport(exports_exports, require("./extractor/concatClassName.cjs"), module.exports);
40
41
  __reExport(exports_exports, require("./extractor/extractToNative.cjs"), module.exports);
@@ -47,6 +47,7 @@ var import_typescript = require("typescript");
47
47
  var import_constants = require("../constants.cjs");
48
48
  var import_requireGuiCore = require("../helpers/requireGuiCore.cjs");
49
49
  var import_createEvaluator = require("./createEvaluator.cjs");
50
+ var import_extractablePath = require("./extractablePath.cjs");
50
51
  var import_evaluateAstNode = require("./evaluateAstNode.cjs");
51
52
  var import_extractHelpers = require("./extractHelpers.cjs");
52
53
  var import_findTopmostFunction = require("./findTopmostFunction.cjs");
@@ -294,7 +295,7 @@ function createExtractor({
294
295
  throw new Error(`Must provide components`);
295
296
  }
296
297
  }
297
- if (sourcePath && includeExtensions && !includeExtensions.some(ext => sourcePath.endsWith(ext))) {
298
+ if (sourcePath && includeExtensions && !(0, import_extractablePath.installedPackageOf)(sourcePath) && !includeExtensions.some(ext => sourcePath.endsWith(ext))) {
298
299
  if (shouldPrintDebug) {
299
300
  logger.info(`Ignoring file due to includeExtensions: ${sourcePath}, includeExtensions: ${includeExtensions.join(", ")}`);
300
301
  }
@@ -43,6 +43,7 @@ var path = __toESM(require("node:path"));
43
43
  var util = __toESM(require("node:util"));
44
44
  var import_requireGuiCore = require("../helpers/requireGuiCore.cjs");
45
45
  var import_babelParse = require("./babelParse.cjs");
46
+ var import_extractablePath = require("./extractablePath.cjs");
46
47
  var import_createLogger = require("./createLogger.cjs");
47
48
  var import_extractMediaStyle = require("./extractMediaStyle.cjs");
48
49
  var import_normalizeTernaries = require("./normalizeTernaries.cjs");
@@ -64,7 +65,7 @@ async function extractToClassNames({
64
65
  getCSSStylesAtomic,
65
66
  createMediaStyle
66
67
  } = (0, import_requireGuiCore.requireGuiCore)("web");
67
- if (sourcePath.includes("node_modules")) {
68
+ if (!(0, import_extractablePath.isExtractable)(sourcePath, options.extractPackages)) {
68
69
  return null;
69
70
  }
70
71
  if (shouldPrintDebug) {
@@ -0,0 +1,51 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all) __defProp(target, name, {
7
+ get: all[name],
8
+ enumerable: true
9
+ });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
14
+ get: () => from[key],
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
21
+ value: true
22
+ }), mod);
23
+ var extractablePath_exports = {};
24
+ __export(extractablePath_exports, {
25
+ DEFAULT_EXTRACT_PACKAGES: () => DEFAULT_EXTRACT_PACKAGES,
26
+ installedPackageOf: () => installedPackageOf,
27
+ isExtractable: () => isExtractable
28
+ });
29
+ module.exports = __toCommonJS(extractablePath_exports);
30
+ const DEFAULT_EXTRACT_PACKAGES = ["@hanzo/ui", "@hanzo/gui", "@hanzogui/*"];
31
+ const NEVER_EXTRACT = ["lucide-icons"];
32
+ const NODE_MODULES = "node_modules/";
33
+ function installedPackageOf(sourcePath) {
34
+ const normalized = sourcePath.replace(/\\/g, "/");
35
+ const at = normalized.lastIndexOf(NODE_MODULES);
36
+ if (at === -1) return "";
37
+ const rest = normalized.slice(at + NODE_MODULES.length);
38
+ const parts = rest.split("/");
39
+ if (!parts[0]) return "";
40
+ return parts[0].startsWith("@") ? parts.slice(0, 2).join("/") : parts[0];
41
+ }
42
+ function matches(entry, pkg) {
43
+ const prefix = entry.endsWith("/*") ? entry.slice(0, -1) : entry.endsWith("/") ? entry : "";
44
+ return prefix ? pkg.startsWith(prefix) : pkg === entry;
45
+ }
46
+ function isExtractable(sourcePath, extractPackages = []) {
47
+ if (NEVER_EXTRACT.some(name => sourcePath.includes(name))) return false;
48
+ const pkg = installedPackageOf(sourcePath);
49
+ if (!pkg) return true;
50
+ return extractPackages.some(entry => matches(entry, pkg));
51
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzogui/static",
3
- "version": "8.1.0",
3
+ "version": "8.2.0",
4
4
  "gitHead": "a49cc7ea6b93ba384e77a4880ae48ac4a5635c14",
5
5
  "license": "MIT",
6
6
  "source": "src/index.ts",
@@ -22,6 +22,10 @@
22
22
  "types": "./types/worker.d.ts",
23
23
  "default": "./dist/worker.cjs"
24
24
  },
25
+ "./extractablePath": {
26
+ "types": "./types/extractor/extractablePath.d.ts",
27
+ "default": "./dist/extractor/extractablePath.cjs"
28
+ },
25
29
  "./checkDeps": {
26
30
  "types": "./types/checkDeps.d.ts",
27
31
  "default": "./dist/checkDeps.cjs"
@@ -50,19 +54,19 @@
50
54
  "@babel/template": "^7.25.0",
51
55
  "@babel/traverse": "^7.25.4",
52
56
  "@babel/types": "^7.25.4",
53
- "@hanzogui/cli-color": "8.1.0",
54
- "@hanzogui/config-default": "8.1.0",
55
- "@hanzogui/core": "8.1.0",
56
- "@hanzogui/fake-react-native": "8.1.0",
57
- "@hanzogui/generate-themes": "8.1.0",
58
- "@hanzogui/helpers": "8.1.0",
59
- "@hanzogui/helpers-node": "8.1.0",
60
- "@hanzogui/proxy-worm": "8.1.0",
61
- "@hanzogui/react-native-web-internals": "8.1.0",
62
- "@hanzogui/react-native-web-lite": "8.1.0",
63
- "@hanzogui/shorthands": "8.1.0",
64
- "@hanzogui/types": "8.1.0",
65
- "@hanzogui/web": "8.1.0",
57
+ "@hanzogui/cli-color": "8.2.0",
58
+ "@hanzogui/config-default": "8.2.0",
59
+ "@hanzogui/core": "8.2.0",
60
+ "@hanzogui/fake-react-native": "8.2.0",
61
+ "@hanzogui/generate-themes": "8.2.0",
62
+ "@hanzogui/helpers": "8.2.0",
63
+ "@hanzogui/helpers-node": "8.2.0",
64
+ "@hanzogui/proxy-worm": "8.2.0",
65
+ "@hanzogui/react-native-web-internals": "8.2.0",
66
+ "@hanzogui/react-native-web-lite": "8.2.0",
67
+ "@hanzogui/shorthands": "8.2.0",
68
+ "@hanzogui/types": "8.2.0",
69
+ "@hanzogui/web": "8.2.0",
66
70
  "babel-literal-to-ast": "^2.1.0",
67
71
  "browserslist": "^4.28.1",
68
72
  "check-dependency-version-consistency": "^4.1.0",
@@ -79,7 +83,7 @@
79
83
  },
80
84
  "devDependencies": {
81
85
  "@babel/plugin-syntax-typescript": "^7.25.4",
82
- "@hanzogui/build": "8.1.0",
86
+ "@hanzogui/build": "8.2.0",
83
87
  "@types/babel__core": "^7.20.5",
84
88
  "@types/find-root": "^1.1.2",
85
89
  "@types/node": "^22.1.0",
package/src/exports.ts CHANGED
@@ -3,6 +3,7 @@ export * from './types'
3
3
  export { createExtractor } from './extractor/createExtractor'
4
4
  export { literalToAst } from './extractor/literalToAst'
5
5
  export * from './constants'
6
+ export * from './extractor/extractablePath'
6
7
  export * from './extractor/extractToClassNames'
7
8
  export * from './extractor/concatClassName'
8
9
  export * from './extractor/extractToNative'
@@ -30,6 +30,7 @@ import type {
30
30
  } from '../types'
31
31
  import type { LoadedComponents, GuiProjectInfo } from './bundleConfig'
32
32
  import { createEvaluator, createSafeEvaluator } from './createEvaluator'
33
+ import { installedPackageOf } from './extractablePath'
33
34
  import { evaluateAstNode } from './evaluateAstNode'
34
35
  import {
35
36
  attrStr,
@@ -351,9 +352,15 @@ export function createExtractor(
351
352
  }
352
353
  }
353
354
 
355
+ // includeExtensions describes the app's OWN source, where the author picks
356
+ // the extension. An installed package ships whatever its build emits —
357
+ // .mjs, .js — and it already passed the package allowlist to get here, so
358
+ // holding it to ['.ts', '.tsx', '.jsx'] rejected every design-system file
359
+ // the allowlist had just admitted.
354
360
  if (
355
361
  sourcePath &&
356
362
  includeExtensions &&
363
+ !installedPackageOf(sourcePath) &&
357
364
  !includeExtensions.some((ext) => sourcePath.endsWith(ext))
358
365
  ) {
359
366
  if (shouldPrintDebug) {
@@ -7,6 +7,7 @@ import * as util from 'node:util'
7
7
  import { requireGuiCore } from '../helpers/requireGuiCore'
8
8
  import type { StyleObject, GuiOptions, Ternary } from '../types'
9
9
  import { babelParse } from './babelParse'
10
+ import { isExtractable } from './extractablePath'
10
11
  import type { Extractor } from './createExtractor'
11
12
  import { createLogger } from './createLogger'
12
13
  import { extractMediaStyle } from './extractMediaStyle'
@@ -57,7 +58,7 @@ export async function extractToClassNames({
57
58
  const tm = timer()
58
59
  const { getCSSStylesAtomic, createMediaStyle } = requireGuiCore('web')
59
60
 
60
- if (sourcePath.includes('node_modules')) {
61
+ if (!isExtractable(sourcePath, options.extractPackages)) {
61
62
  return null
62
63
  }
63
64
 
@@ -0,0 +1,88 @@
1
+ /**
2
+ * One place decides which files the compiler may read styles out of.
3
+ *
4
+ * The compiler used to answer this with `sourcePath.includes('node_modules')`,
5
+ * in two places that had to agree by hand — the webpack loader and
6
+ * extractToClassNames. That answer was right about the cost and wrong about
7
+ * the design system: for a *consumer*, `@hanzo/ui` and every `@hanzogui/*`
8
+ * package IS node_modules, so no app could ask the compiler to look at them
9
+ * even if it wanted to.
10
+ *
11
+ * So this is a policy with a knob, not a hardcoded skip. The knob is
12
+ * `extractPackages`, and it is EMPTY by default, which is exactly the old
13
+ * behavior. What turning it on buys, measured on hanzo.one (Vite 5, @hanzo/ui
14
+ * 8.0.63 on @hanzo/gui 8.1, 5026 modules):
15
+ *
16
+ * extracted files 4 -> 54
17
+ * cached sheet 150,172 -> 151,151 B (+979)
18
+ * CSS injected at runtime 27,376 -> 27,376 B (unchanged, 356 rules both)
19
+ *
20
+ * Every one of those 979 bytes is a `styled()` DEFINITION rule, and the
21
+ * compiler deliberately leaves the definition in place ("the runtime needs
22
+ * real values for animations, context, and group styles"), so the runtime
23
+ * mints the same class again. 10 of the 20 new rules are delivered twice on
24
+ * the home route; the rest are for components that route never renders. The
25
+ * saving that would justify the cost — flattening a `<YStack p={10}>` usage
26
+ * site down to a className — cannot happen inside an installed package at all,
27
+ * because `module:jsx` currently emits the same JSX-lowered output as the ESM
28
+ * build (byte-identical, hardlinked), so there is no JSX left to flatten.
29
+ *
30
+ * Fix that, and turning this on becomes a real win. Until then, an app can opt
31
+ * in with `extractPackages: DEFAULT_EXTRACT_PACKAGES` and get a slightly
32
+ * bigger sheet for its trouble.
33
+ */
34
+
35
+ /** The design-system allowlist an app can opt into. Not the default. */
36
+ export const DEFAULT_EXTRACT_PACKAGES = ['@hanzo/ui', '@hanzo/gui', '@hanzogui/*']
37
+
38
+ /**
39
+ * Generated icon sets: 1760 modules of react-native-svg elements wrapped in
40
+ * `themed()`, holding no `styled()` between them. Parsing them costs a full
41
+ * babel pass each and yields no CSS, installed or in a workspace — which is
42
+ * why the path is skipped rather than the package name. Measured on the same
43
+ * build: 1761 files that the allowlist would otherwise have to reject one at
44
+ * a time.
45
+ */
46
+ const NEVER_EXTRACT = ['lucide-icons']
47
+
48
+ const NODE_MODULES = 'node_modules/'
49
+
50
+ /**
51
+ * The installed package a file belongs to, or '' when the file is app or
52
+ * workspace source. Reads the LAST `node_modules/` segment, so a nested
53
+ * install and pnpm's `.pnpm/<pkg>@<ver>/node_modules/<pkg>` both name the
54
+ * package that actually owns the file.
55
+ */
56
+ export function installedPackageOf(sourcePath: string): string {
57
+ const normalized = sourcePath.replace(/\\/g, '/')
58
+ const at = normalized.lastIndexOf(NODE_MODULES)
59
+ if (at === -1) return ''
60
+ const rest = normalized.slice(at + NODE_MODULES.length)
61
+ const parts = rest.split('/')
62
+ if (!parts[0]) return ''
63
+ return parts[0].startsWith('@') ? parts.slice(0, 2).join('/') : parts[0]
64
+ }
65
+
66
+ /**
67
+ * An entry names one package (`@hanzo/ui`) or a whole scope (`@hanzogui/*`,
68
+ * or the equivalent `@hanzogui/`).
69
+ */
70
+ function matches(entry: string, pkg: string): boolean {
71
+ const prefix = entry.endsWith('/*')
72
+ ? entry.slice(0, -1)
73
+ : entry.endsWith('/')
74
+ ? entry
75
+ : ''
76
+ return prefix ? pkg.startsWith(prefix) : pkg === entry
77
+ }
78
+
79
+ /** May the compiler read styles out of this file? */
80
+ export function isExtractable(
81
+ sourcePath: string,
82
+ extractPackages: string[] = []
83
+ ): boolean {
84
+ if (NEVER_EXTRACT.some((name) => sourcePath.includes(name))) return false
85
+ const pkg = installedPackageOf(sourcePath)
86
+ if (!pkg) return true
87
+ return extractPackages.some((entry) => matches(entry, pkg))
88
+ }
@@ -3,6 +3,7 @@ export * from './types';
3
3
  export { createExtractor } from './extractor/createExtractor';
4
4
  export { literalToAst } from './extractor/literalToAst';
5
5
  export * from './constants';
6
+ export * from './extractor/extractablePath';
6
7
  export * from './extractor/extractToClassNames';
7
8
  export * from './extractor/concatClassName';
8
9
  export * from './extractor/extractToNative';
@@ -1 +1 @@
1
- {"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACvD,cAAc,aAAa,CAAA;AAC3B,cAAc,iCAAiC,CAAA;AAC/C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,qBAAqB,CAAA;AACnC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,cAAc,oBAAoB,CAAA"}
1
+ {"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACvD,cAAc,aAAa,CAAA;AAC3B,cAAc,6BAA6B,CAAA;AAC3C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,qBAAqB,CAAA;AACnC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,cAAc,oBAAoB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"createExtractor.d.ts","sourceRoot":"","sources":["../../src/extractor/createExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,iBAAiB,CAAA;AAEhE,OAAO,KAAK,CAAC,MAAM,cAAc,CAAA;AAmBjC,OAAO,KAAK,EAGV,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,EAGX,MAAM,UAAU,CAAA;AACjB,OAAO,KAAK,EAAoB,cAAc,EAAE,MAAM,gBAAgB,CAAA;AActE,OAAO,EAAE,iBAAiB,EAA6B,MAAM,6BAA6B,CAAA;AAwB1F,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAA;AAE1D,KAAK,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAA;AA6C9C,wBAAgB,eAAe,CAC7B,EAAE,MAAgB,EAAE,QAAgB,EAAE,GAAE,gBAAsC;;;;;qBAsJnD,UAAU;yBAPZ,UAAU;;mBAwBlB,UAAU,SAAS,mBAAmB;;;;;;;eAKpC,UAAU,SAAS,mBAAmB;;;;;;;EA8iF1D"}
1
+ {"version":3,"file":"createExtractor.d.ts","sourceRoot":"","sources":["../../src/extractor/createExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,iBAAiB,CAAA;AAEhE,OAAO,KAAK,CAAC,MAAM,cAAc,CAAA;AAmBjC,OAAO,KAAK,EAGV,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,EAGX,MAAM,UAAU,CAAA;AACjB,OAAO,KAAK,EAAoB,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAetE,OAAO,EAAE,iBAAiB,EAA6B,MAAM,6BAA6B,CAAA;AAwB1F,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAA;AAE1D,KAAK,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAA;AA6C9C,wBAAgB,eAAe,CAC7B,EAAE,MAAgB,EAAE,QAAgB,EAAE,GAAE,gBAAsC;;;;;qBAsJnD,UAAU;yBAPZ,UAAU;;mBAwBlB,UAAU,SAAS,mBAAmB;;;;;;;eAKpC,UAAU,SAAS,mBAAmB;;;;;;;EAojF1D"}
@@ -1 +1 @@
1
- {"version":3,"file":"extractToClassNames.d.ts","sourceRoot":"","sources":["../../src/extractor/extractToClassNames.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAA;AAKjC,OAAO,KAAK,EAAe,UAAU,EAAW,MAAM,UAAU,CAAA;AAEhE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAYlD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,GAAG,EAAE,CAAC,CAAC,IAAI,CAAA;IACX,GAAG,EAAE,GAAG,CAAA;IACR,KAAK,EAAE;QACL,MAAM,EAAE,MAAM,CAAA;QACd,SAAS,EAAE,MAAM,CAAA;QACjB,SAAS,EAAE,MAAM,CAAA;QACjB,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;CACF,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,SAAS,CAAA;IACpB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,UAAU,CAAA;IACnB,gBAAgB,EAAE,OAAO,GAAG,SAAS,CAAA;CACtC,CAAA;AAQD,wBAAsB,mBAAmB,CAAC,EACxC,SAAS,EACT,MAAM,EACN,UAAe,EACf,OAAO,EACP,gBAAgB,GACjB,EAAE,wBAAwB,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAknB9D"}
1
+ {"version":3,"file":"extractToClassNames.d.ts","sourceRoot":"","sources":["../../src/extractor/extractToClassNames.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAA;AAKjC,OAAO,KAAK,EAAe,UAAU,EAAW,MAAM,UAAU,CAAA;AAGhE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAYlD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,GAAG,EAAE,CAAC,CAAC,IAAI,CAAA;IACX,GAAG,EAAE,GAAG,CAAA;IACR,KAAK,EAAE;QACL,MAAM,EAAE,MAAM,CAAA;QACd,SAAS,EAAE,MAAM,CAAA;QACjB,SAAS,EAAE,MAAM,CAAA;QACjB,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;CACF,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,SAAS,CAAA;IACpB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,UAAU,CAAA;IACnB,gBAAgB,EAAE,OAAO,GAAG,SAAS,CAAA;CACtC,CAAA;AAQD,wBAAsB,mBAAmB,CAAC,EACxC,SAAS,EACT,MAAM,EACN,UAAe,EACf,OAAO,EACP,gBAAgB,GACjB,EAAE,wBAAwB,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAknB9D"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * One place decides which files the compiler may read styles out of.
3
+ *
4
+ * The compiler used to answer this with `sourcePath.includes('node_modules')`,
5
+ * in two places that had to agree by hand — the webpack loader and
6
+ * extractToClassNames. That answer was right about the cost and wrong about
7
+ * the design system: for a *consumer*, `@hanzo/ui` and every `@hanzogui/*`
8
+ * package IS node_modules, so no app could ask the compiler to look at them
9
+ * even if it wanted to.
10
+ *
11
+ * So this is a policy with a knob, not a hardcoded skip. The knob is
12
+ * `extractPackages`, and it is EMPTY by default, which is exactly the old
13
+ * behavior. What turning it on buys, measured on hanzo.one (Vite 5, @hanzo/ui
14
+ * 8.0.63 on @hanzo/gui 8.1, 5026 modules):
15
+ *
16
+ * extracted files 4 -> 54
17
+ * cached sheet 150,172 -> 151,151 B (+979)
18
+ * CSS injected at runtime 27,376 -> 27,376 B (unchanged, 356 rules both)
19
+ *
20
+ * Every one of those 979 bytes is a `styled()` DEFINITION rule, and the
21
+ * compiler deliberately leaves the definition in place ("the runtime needs
22
+ * real values for animations, context, and group styles"), so the runtime
23
+ * mints the same class again. 10 of the 20 new rules are delivered twice on
24
+ * the home route; the rest are for components that route never renders. The
25
+ * saving that would justify the cost — flattening a `<YStack p={10}>` usage
26
+ * site down to a className — cannot happen inside an installed package at all,
27
+ * because `module:jsx` currently emits the same JSX-lowered output as the ESM
28
+ * build (byte-identical, hardlinked), so there is no JSX left to flatten.
29
+ *
30
+ * Fix that, and turning this on becomes a real win. Until then, an app can opt
31
+ * in with `extractPackages: DEFAULT_EXTRACT_PACKAGES` and get a slightly
32
+ * bigger sheet for its trouble.
33
+ */
34
+ /** The design-system allowlist an app can opt into. Not the default. */
35
+ export declare const DEFAULT_EXTRACT_PACKAGES: string[];
36
+ /**
37
+ * The installed package a file belongs to, or '' when the file is app or
38
+ * workspace source. Reads the LAST `node_modules/` segment, so a nested
39
+ * install and pnpm's `.pnpm/<pkg>@<ver>/node_modules/<pkg>` both name the
40
+ * package that actually owns the file.
41
+ */
42
+ export declare function installedPackageOf(sourcePath: string): string;
43
+ /** May the compiler read styles out of this file? */
44
+ export declare function isExtractable(sourcePath: string, extractPackages?: string[]): boolean;
45
+ //# sourceMappingURL=extractablePath.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractablePath.d.ts","sourceRoot":"","sources":["../../src/extractor/extractablePath.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,UAA6C,CAAA;AAclF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAQ7D;AAeD,qDAAqD;AACrD,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,EAClB,eAAe,GAAE,MAAM,EAAO,GAC7B,OAAO,CAKT"}