@typestyles/build-runner 0.0.0-unstable.de79e3a17eb1 → 0.0.0-unstable.df708abe489f
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 +1 -1
- package/dist/index.cjs +114 -9
- package/dist/index.d.cts +35 -2
- package/dist/index.d.ts +35 -2
- package/dist/index.js +111 -9
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -164,7 +164,7 @@ Parses a file for typestyles registration calls. Returns `{ keys, prefixes }` fo
|
|
|
164
164
|
import { extractNamespaces } from '@typestyles/build-runner';
|
|
165
165
|
|
|
166
166
|
const { prefixes } = extractNamespaces(source);
|
|
167
|
-
//
|
|
167
|
+
// recipe('button', ...) → prefixes includes '.button-'
|
|
168
168
|
```
|
|
169
169
|
|
|
170
170
|
### `reportDuplicateNamespaces(map, fileId, prefixes, reporter)`
|
package/dist/index.cjs
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
DEFAULT_EXTRACT_MODULE_CANDIDATES: () => DEFAULT_EXTRACT_MODULE_CANDIDATES,
|
|
24
|
+
DEFAULT_REGISTERED_COMPONENTS_MODULE_BASES: () => DEFAULT_REGISTERED_COMPONENTS_MODULE_BASES,
|
|
24
25
|
TYPESTYLES_IMPORT_RE: () => TYPESTYLES_IMPORT_RE,
|
|
25
26
|
VerifyTypestylesBuildError: () => VerifyTypestylesBuildError,
|
|
26
27
|
buildManifestV2: () => buildManifestV2,
|
|
@@ -28,9 +29,11 @@ __export(index_exports, {
|
|
|
28
29
|
createModuleLoader: () => createModuleLoader,
|
|
29
30
|
discoverDefaultExtractModules: () => discoverDefaultExtractModules,
|
|
30
31
|
discoverNextAppRoutes: () => discoverNextAppRoutes,
|
|
32
|
+
discoverRegisteredComponentsModule: () => discoverRegisteredComponentsModule,
|
|
31
33
|
extractNamespaces: () => extractNamespaces,
|
|
32
34
|
getRouteCss: () => getRouteCss,
|
|
33
35
|
isManifestV2: () => isManifestV2,
|
|
36
|
+
moduleNeedsOverrideHmr: () => moduleNeedsOverrideHmr,
|
|
34
37
|
normalizeRoutePath: () => normalizeRoutePath,
|
|
35
38
|
pageRelPathToRoutePath: () => pageRelPathToRoutePath,
|
|
36
39
|
readCssFile: () => readCssFile,
|
|
@@ -59,6 +62,12 @@ var DISCOVERY_EXTENSIONS = [".ts", ".tsx", ".js", ".mjs"];
|
|
|
59
62
|
var DEFAULT_EXTRACT_MODULE_CANDIDATES = DEFAULT_EXTRACT_MODULE_BASES.map(
|
|
60
63
|
(base) => `${base}.ts`
|
|
61
64
|
);
|
|
65
|
+
var DEFAULT_REGISTERED_COMPONENTS_MODULE_BASES = [
|
|
66
|
+
"src/themeable-refs",
|
|
67
|
+
"src/typestyles/themeable-refs",
|
|
68
|
+
"src/typestyles-registry",
|
|
69
|
+
"styles/themeable-refs"
|
|
70
|
+
];
|
|
62
71
|
function discoverDefaultExtractModules(root) {
|
|
63
72
|
const absRoot = (0, import_node_path.resolve)(root);
|
|
64
73
|
for (const base of DEFAULT_EXTRACT_MODULE_BASES) {
|
|
@@ -71,16 +80,88 @@ function discoverDefaultExtractModules(root) {
|
|
|
71
80
|
}
|
|
72
81
|
return [];
|
|
73
82
|
}
|
|
83
|
+
function discoverRegisteredComponentsModule(root) {
|
|
84
|
+
const absRoot = (0, import_node_path.resolve)(root);
|
|
85
|
+
for (const base of DEFAULT_REGISTERED_COMPONENTS_MODULE_BASES) {
|
|
86
|
+
for (const ext of DISCOVERY_EXTENSIONS) {
|
|
87
|
+
const rel = `${base}${ext}`;
|
|
88
|
+
if ((0, import_node_fs.existsSync)((0, import_node_path.resolve)(absRoot, rel))) {
|
|
89
|
+
return rel.replace(/\\/g, "/");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return void 0;
|
|
94
|
+
}
|
|
74
95
|
|
|
75
96
|
// src/namespaces.ts
|
|
76
|
-
var STYLES_COMPONENT_RE = /styles\.component\(\s*['"]([^'"]+)['"]/g;
|
|
77
|
-
var STYLES_CLASS_RE = /styles\.class\(\s*['"]([^'"]+)['"]/g;
|
|
97
|
+
var STYLES_COMPONENT_RE = /(?:styles\.component|(?<![\w.])recipe)\(\s*['"]([^'"]+)['"]/g;
|
|
98
|
+
var STYLES_CLASS_RE = /(?:styles\.class|(?<![\w.])style)\(\s*['"]([^'"]+)['"]/g;
|
|
78
99
|
var TOKENS_CREATE_RE = /tokens\.create\(\s*['"]([^'"]+)['"]/g;
|
|
79
|
-
var
|
|
100
|
+
var CREATE_THEME_CALL_RE = /(?:tokens\.)?createTheme\s*\(/g;
|
|
80
101
|
var KEYFRAMES_CREATE_RE = /keyframes\.create\(\s*['"]([^'"]+)['"]/g;
|
|
81
|
-
var GLOBAL_STYLE_RE = /global\.style\(\s*['"]([^'"]+)['"]/g;
|
|
102
|
+
var GLOBAL_STYLE_RE = /global\.(?:rule|style)\(\s*['"]([^'"]+)['"]/g;
|
|
82
103
|
var GLOBAL_FONT_FACE_RE = /global\.fontFace\(\s*['"]([^'"]+)['"]/g;
|
|
104
|
+
var CREATE_THEME_ARG_SCAN = 4e3;
|
|
105
|
+
function extractCreateThemeNames(code) {
|
|
106
|
+
const names = [];
|
|
107
|
+
for (const match of code.matchAll(CREATE_THEME_CALL_RE)) {
|
|
108
|
+
const start = (match.index ?? 0) + match[0].length;
|
|
109
|
+
const args = code.slice(start, start + CREATE_THEME_ARG_SCAN);
|
|
110
|
+
const positional = args.match(/^\s*['"]([^'"]+)['"]/);
|
|
111
|
+
if (positional) {
|
|
112
|
+
names.push(positional[1]);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (!/^\s*\{/.test(args)) continue;
|
|
116
|
+
const named = args.match(/\bname\s*:\s*['"]([^'"]+)['"]/);
|
|
117
|
+
if (named) names.push(named[1]);
|
|
118
|
+
}
|
|
119
|
+
return names;
|
|
120
|
+
}
|
|
121
|
+
var OVERRIDE_HMR_EXPORT_NAMES = /* @__PURE__ */ new Set(["createDesignTheme", "overrideComponent"]);
|
|
83
122
|
var TYPESTYLES_IMPORT_RE = /(?:from\s+|import\s+|require\s*\(\s*)['"]typestyles['"]/;
|
|
123
|
+
function stripCommentsForHmrScan(code) {
|
|
124
|
+
return code.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/.*$/gm, "$1");
|
|
125
|
+
}
|
|
126
|
+
function collectOverrideHmrCallTargets(code) {
|
|
127
|
+
const locals = new Set(OVERRIDE_HMR_EXPORT_NAMES);
|
|
128
|
+
const namespaces = /* @__PURE__ */ new Set();
|
|
129
|
+
for (const match of code.matchAll(/import\s*{([^}]+)}\s*from\s*['"][^'"]+['"]/g)) {
|
|
130
|
+
for (const rawPart of match[1].split(",")) {
|
|
131
|
+
const part = rawPart.trim();
|
|
132
|
+
if (!part || part.startsWith("type ")) continue;
|
|
133
|
+
const asMatch = part.match(/^(\w+)\s+as\s+(\w+)$/);
|
|
134
|
+
if (asMatch) {
|
|
135
|
+
if (OVERRIDE_HMR_EXPORT_NAMES.has(asMatch[1])) {
|
|
136
|
+
locals.add(asMatch[2]);
|
|
137
|
+
}
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
const name = part.match(/^(\w+)$/)?.[1];
|
|
141
|
+
if (name && OVERRIDE_HMR_EXPORT_NAMES.has(name)) {
|
|
142
|
+
locals.add(name);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
for (const match of code.matchAll(/import\s*\*\s*as\s+(\w+)\s*from\s*['"][^'"]+['"]/g)) {
|
|
147
|
+
namespaces.add(match[1]);
|
|
148
|
+
}
|
|
149
|
+
return { locals, namespaces };
|
|
150
|
+
}
|
|
151
|
+
function moduleNeedsOverrideHmr(code) {
|
|
152
|
+
const scan = stripCommentsForHmrScan(code);
|
|
153
|
+
if (/\b(?:styles\.)?override\s*\(/.test(scan)) return true;
|
|
154
|
+
const { locals, namespaces } = collectOverrideHmrCallTargets(scan);
|
|
155
|
+
for (const name of locals) {
|
|
156
|
+
if (new RegExp(`\\b${name}\\s*\\(`).test(scan)) return true;
|
|
157
|
+
}
|
|
158
|
+
for (const ns of namespaces) {
|
|
159
|
+
if (new RegExp(`\\b${ns}\\.(?:createDesignTheme|overrideComponent)\\s*\\(`).test(scan)) {
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
84
165
|
function extractNamespaces(code) {
|
|
85
166
|
const keys = [];
|
|
86
167
|
const prefixes = [];
|
|
@@ -93,8 +174,8 @@ function extractNamespaces(code) {
|
|
|
93
174
|
for (const match of code.matchAll(TOKENS_CREATE_RE)) {
|
|
94
175
|
keys.push(`tokens:${match[1]}`);
|
|
95
176
|
}
|
|
96
|
-
for (const
|
|
97
|
-
keys.push(`theme:${
|
|
177
|
+
for (const themeName of extractCreateThemeNames(code)) {
|
|
178
|
+
keys.push(`theme:${themeName}`);
|
|
98
179
|
}
|
|
99
180
|
for (const match of code.matchAll(KEYFRAMES_CREATE_RE)) {
|
|
100
181
|
keys.push(`keyframes:${match[1]}`);
|
|
@@ -123,10 +204,20 @@ function reportDuplicateNamespaces(moduleNamespaces, id, prefixes, reporter) {
|
|
|
123
204
|
|
|
124
205
|
// src/resolve-extract.ts
|
|
125
206
|
function resolveExtractModules(root, extract) {
|
|
207
|
+
let modules;
|
|
126
208
|
if (extract?.modules !== void 0) {
|
|
127
|
-
|
|
209
|
+
modules = [...extract.modules];
|
|
210
|
+
} else {
|
|
211
|
+
modules = discoverDefaultExtractModules(root);
|
|
212
|
+
}
|
|
213
|
+
let registeredModule = extract?.registeredComponentsModule;
|
|
214
|
+
if (!registeredModule && extract?.include === "allRegisteredComponents") {
|
|
215
|
+
registeredModule = discoverRegisteredComponentsModule(root);
|
|
216
|
+
}
|
|
217
|
+
if (registeredModule && !modules.includes(registeredModule)) {
|
|
218
|
+
modules.push(registeredModule);
|
|
128
219
|
}
|
|
129
|
-
return
|
|
220
|
+
return modules;
|
|
130
221
|
}
|
|
131
222
|
function resolveExtractMode(explicitMode, resolvedModules) {
|
|
132
223
|
return explicitMode ?? (resolvedModules.length > 0 ? "build" : "runtime");
|
|
@@ -424,10 +515,11 @@ async function traceTypestylesModules(root, entryFiles) {
|
|
|
424
515
|
}
|
|
425
516
|
return [...traced].sort();
|
|
426
517
|
}
|
|
518
|
+
var moduleLoadNonce = 0;
|
|
427
519
|
function createModuleLoader(root, modulePath) {
|
|
428
520
|
const abs = (0, import_node_path4.resolve)(root, modulePath);
|
|
429
521
|
const href = (0, import_node_url.pathToFileURL)(abs).href;
|
|
430
|
-
return () => import(href);
|
|
522
|
+
return () => import(`${href}?typestyles-extract=${++moduleLoadNonce}`);
|
|
431
523
|
}
|
|
432
524
|
|
|
433
525
|
// src/route-css.ts
|
|
@@ -549,6 +641,16 @@ async function runTypestylesBuild({
|
|
|
549
641
|
// calls silently dropped as "unused". Disable tree shaking here so every
|
|
550
642
|
// registration in the extraction graph survives.
|
|
551
643
|
treeShaking: false,
|
|
644
|
+
// `treeShaking: false` only stops esbuild from pruning declarations
|
|
645
|
+
// *within* an already-included module. It's a separate esbuild behavior
|
|
646
|
+
// by the treeShaking option — that drops a plain bare import entirely
|
|
647
|
+
// (`import './some-lib'` with no binding at all) when it resolves to a
|
|
648
|
+
// module/package marked "sideEffects": false, before that module is ever
|
|
649
|
+
// considered for inclusion. A real extraction entry is exactly this
|
|
650
|
+
// shape: several side-effect-only imports, any one of which may point at
|
|
651
|
+
// a (correctly) tree-shakeable component library. Ignore both kinds of
|
|
652
|
+
// annotation so every import in the extraction graph is included.
|
|
653
|
+
ignoreAnnotations: true,
|
|
552
654
|
stdin: {
|
|
553
655
|
contents: importLines,
|
|
554
656
|
resolveDir: root,
|
|
@@ -593,6 +695,7 @@ ${result.stderr || result.stdout || "unknown error"}`
|
|
|
593
695
|
// Annotate the CommonJS export names for ESM import in node:
|
|
594
696
|
0 && (module.exports = {
|
|
595
697
|
DEFAULT_EXTRACT_MODULE_CANDIDATES,
|
|
698
|
+
DEFAULT_REGISTERED_COMPONENTS_MODULE_BASES,
|
|
596
699
|
TYPESTYLES_IMPORT_RE,
|
|
597
700
|
VerifyTypestylesBuildError,
|
|
598
701
|
buildManifestV2,
|
|
@@ -600,9 +703,11 @@ ${result.stderr || result.stdout || "unknown error"}`
|
|
|
600
703
|
createModuleLoader,
|
|
601
704
|
discoverDefaultExtractModules,
|
|
602
705
|
discoverNextAppRoutes,
|
|
706
|
+
discoverRegisteredComponentsModule,
|
|
603
707
|
extractNamespaces,
|
|
604
708
|
getRouteCss,
|
|
605
709
|
isManifestV2,
|
|
710
|
+
moduleNeedsOverrideHmr,
|
|
606
711
|
normalizeRoutePath,
|
|
607
712
|
pageRelPathToRoutePath,
|
|
608
713
|
readCssFile,
|
package/dist/index.d.cts
CHANGED
|
@@ -3,13 +3,33 @@
|
|
|
3
3
|
* Shared by bundler integrations and `@typestyles/next/build`.
|
|
4
4
|
*/
|
|
5
5
|
declare const DEFAULT_EXTRACT_MODULE_CANDIDATES: readonly string[];
|
|
6
|
+
/**
|
|
7
|
+
* Side-effect modules that import every recipe and export `getRegisteredComponentRefs(styles)`.
|
|
8
|
+
* Used when `extract.include` is `"allRegisteredComponents"`.
|
|
9
|
+
*/
|
|
10
|
+
declare const DEFAULT_REGISTERED_COMPONENTS_MODULE_BASES: readonly ["src/themeable-refs", "src/typestyles/themeable-refs", "src/typestyles-registry", "styles/themeable-refs"];
|
|
6
11
|
/**
|
|
7
12
|
* Resolve the default extraction module when the user did not pass explicit `modules`.
|
|
8
13
|
* Returns at most one path using `/` separators, relative to `root`.
|
|
9
14
|
*/
|
|
10
15
|
declare function discoverDefaultExtractModules(root: string): string[];
|
|
16
|
+
/**
|
|
17
|
+
* Convention registry module for `extract.include: 'allRegisteredComponents'`.
|
|
18
|
+
* The file should import all recipe modules and
|
|
19
|
+
* export `getRegisteredComponentRefs(styles)` from your `createTypeStyles` entry.
|
|
20
|
+
*/
|
|
21
|
+
declare function discoverRegisteredComponentsModule(root: string): string | undefined;
|
|
11
22
|
|
|
12
23
|
declare const TYPESTYLES_IMPORT_RE: RegExp;
|
|
24
|
+
/**
|
|
25
|
+
* True when this module may register `styles.override` rules and needs Vite HMR
|
|
26
|
+
* dispose tracking — including Var UI sugar (`createDesignTheme` / `overrideComponent`)
|
|
27
|
+
* that never spells `styles.override` in source.
|
|
28
|
+
*
|
|
29
|
+
* Detects renamed imports (`createDesignTheme as cdt`) and namespace imports
|
|
30
|
+
* (`Core.createDesignTheme(`), not only the canonical identifier spelling.
|
|
31
|
+
*/
|
|
32
|
+
declare function moduleNeedsOverrideHmr(code: string): boolean;
|
|
13
33
|
/**
|
|
14
34
|
* Extract namespace information from source code for invalidation and duplicate checks.
|
|
15
35
|
*/
|
|
@@ -39,6 +59,19 @@ interface TypestylesExtractOptions {
|
|
|
39
59
|
* Output CSS filename. Defaults to `typestyles.css`.
|
|
40
60
|
*/
|
|
41
61
|
fileName?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Additional module that re-exports {@link getRegisteredComponentRefs} (or an
|
|
64
|
+
* equivalent object of every themeable recipe handle) so extract bundles retain
|
|
65
|
+
* full design-system CSS without a hand-maintained registry object.
|
|
66
|
+
*/
|
|
67
|
+
registeredComponentsModule?: string;
|
|
68
|
+
/**
|
|
69
|
+
* When `"allRegisteredComponents"`, appends a convention registry module if present
|
|
70
|
+
* ({@link discoverRegisteredComponentsModule}) or {@link registeredComponentsModule}
|
|
71
|
+
* when set. That file must side-effect-import every recipe and reference
|
|
72
|
+
* `getRegisteredComponentRefs(styles)` — the extract entry alone is not enough.
|
|
73
|
+
*/
|
|
74
|
+
include?: 'allRegisteredComponents';
|
|
42
75
|
}
|
|
43
76
|
/**
|
|
44
77
|
* Resolve extraction modules from explicit config or convention entry discovery.
|
|
@@ -134,7 +167,7 @@ declare function discoverNextAppRoutes(root: string, appDir?: string): NextAppRo
|
|
|
134
167
|
* Paths are relative to `root` with `/` separators.
|
|
135
168
|
*/
|
|
136
169
|
declare function traceTypestylesModules(root: string, entryFiles: string[]): Promise<string[]>;
|
|
137
|
-
/** Load a traced module for style extraction. */
|
|
170
|
+
/** Load a traced module for style extraction (cache-busted so re-runs re-register styles). */
|
|
138
171
|
declare function createModuleLoader(root: string, modulePath: string): () => Promise<unknown>;
|
|
139
172
|
|
|
140
173
|
interface CollectRouteCssOptions {
|
|
@@ -194,4 +227,4 @@ interface RunTypestylesBuildOptions {
|
|
|
194
227
|
*/
|
|
195
228
|
declare function runTypestylesBuild({ root, modules, }: RunTypestylesBuildOptions): Promise<string>;
|
|
196
229
|
|
|
197
|
-
export { type CollectRouteCssOptions, type CollectRouteCssResult, DEFAULT_EXTRACT_MODULE_CANDIDATES, type DuplicateNamespaceReporter, type GetRouteCssOptions, type NextAppRoute, type RunTypestylesBuildOptions, TYPESTYLES_IMPORT_RE, type TypestylesExtractManifest, type TypestylesExtractManifestV1, type TypestylesExtractManifestV2, type TypestylesExtractOptions, type TypestylesIntegrationMode, type TypestylesRouteCssEntry, VerifyTypestylesBuildError, type VerifyTypestylesBuildOptions, type VerifyTypestylesBuildResult, buildManifestV2, collectAndWriteRouteCss, createModuleLoader, discoverDefaultExtractModules, discoverNextAppRoutes, extractNamespaces, getRouteCss, isManifestV2, normalizeRoutePath, pageRelPathToRoutePath, readCssFile, readTypestylesManifest, reportDuplicateNamespaces, resolveExtractMode, resolveExtractModules, runTypestylesBuild, traceTypestylesModules, verifyTypestylesBuild };
|
|
230
|
+
export { type CollectRouteCssOptions, type CollectRouteCssResult, DEFAULT_EXTRACT_MODULE_CANDIDATES, DEFAULT_REGISTERED_COMPONENTS_MODULE_BASES, type DuplicateNamespaceReporter, type GetRouteCssOptions, type NextAppRoute, type RunTypestylesBuildOptions, TYPESTYLES_IMPORT_RE, type TypestylesExtractManifest, type TypestylesExtractManifestV1, type TypestylesExtractManifestV2, type TypestylesExtractOptions, type TypestylesIntegrationMode, type TypestylesRouteCssEntry, VerifyTypestylesBuildError, type VerifyTypestylesBuildOptions, type VerifyTypestylesBuildResult, buildManifestV2, collectAndWriteRouteCss, createModuleLoader, discoverDefaultExtractModules, discoverNextAppRoutes, discoverRegisteredComponentsModule, extractNamespaces, getRouteCss, isManifestV2, moduleNeedsOverrideHmr, normalizeRoutePath, pageRelPathToRoutePath, readCssFile, readTypestylesManifest, reportDuplicateNamespaces, resolveExtractMode, resolveExtractModules, runTypestylesBuild, traceTypestylesModules, verifyTypestylesBuild };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,13 +3,33 @@
|
|
|
3
3
|
* Shared by bundler integrations and `@typestyles/next/build`.
|
|
4
4
|
*/
|
|
5
5
|
declare const DEFAULT_EXTRACT_MODULE_CANDIDATES: readonly string[];
|
|
6
|
+
/**
|
|
7
|
+
* Side-effect modules that import every recipe and export `getRegisteredComponentRefs(styles)`.
|
|
8
|
+
* Used when `extract.include` is `"allRegisteredComponents"`.
|
|
9
|
+
*/
|
|
10
|
+
declare const DEFAULT_REGISTERED_COMPONENTS_MODULE_BASES: readonly ["src/themeable-refs", "src/typestyles/themeable-refs", "src/typestyles-registry", "styles/themeable-refs"];
|
|
6
11
|
/**
|
|
7
12
|
* Resolve the default extraction module when the user did not pass explicit `modules`.
|
|
8
13
|
* Returns at most one path using `/` separators, relative to `root`.
|
|
9
14
|
*/
|
|
10
15
|
declare function discoverDefaultExtractModules(root: string): string[];
|
|
16
|
+
/**
|
|
17
|
+
* Convention registry module for `extract.include: 'allRegisteredComponents'`.
|
|
18
|
+
* The file should import all recipe modules and
|
|
19
|
+
* export `getRegisteredComponentRefs(styles)` from your `createTypeStyles` entry.
|
|
20
|
+
*/
|
|
21
|
+
declare function discoverRegisteredComponentsModule(root: string): string | undefined;
|
|
11
22
|
|
|
12
23
|
declare const TYPESTYLES_IMPORT_RE: RegExp;
|
|
24
|
+
/**
|
|
25
|
+
* True when this module may register `styles.override` rules and needs Vite HMR
|
|
26
|
+
* dispose tracking — including Var UI sugar (`createDesignTheme` / `overrideComponent`)
|
|
27
|
+
* that never spells `styles.override` in source.
|
|
28
|
+
*
|
|
29
|
+
* Detects renamed imports (`createDesignTheme as cdt`) and namespace imports
|
|
30
|
+
* (`Core.createDesignTheme(`), not only the canonical identifier spelling.
|
|
31
|
+
*/
|
|
32
|
+
declare function moduleNeedsOverrideHmr(code: string): boolean;
|
|
13
33
|
/**
|
|
14
34
|
* Extract namespace information from source code for invalidation and duplicate checks.
|
|
15
35
|
*/
|
|
@@ -39,6 +59,19 @@ interface TypestylesExtractOptions {
|
|
|
39
59
|
* Output CSS filename. Defaults to `typestyles.css`.
|
|
40
60
|
*/
|
|
41
61
|
fileName?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Additional module that re-exports {@link getRegisteredComponentRefs} (or an
|
|
64
|
+
* equivalent object of every themeable recipe handle) so extract bundles retain
|
|
65
|
+
* full design-system CSS without a hand-maintained registry object.
|
|
66
|
+
*/
|
|
67
|
+
registeredComponentsModule?: string;
|
|
68
|
+
/**
|
|
69
|
+
* When `"allRegisteredComponents"`, appends a convention registry module if present
|
|
70
|
+
* ({@link discoverRegisteredComponentsModule}) or {@link registeredComponentsModule}
|
|
71
|
+
* when set. That file must side-effect-import every recipe and reference
|
|
72
|
+
* `getRegisteredComponentRefs(styles)` — the extract entry alone is not enough.
|
|
73
|
+
*/
|
|
74
|
+
include?: 'allRegisteredComponents';
|
|
42
75
|
}
|
|
43
76
|
/**
|
|
44
77
|
* Resolve extraction modules from explicit config or convention entry discovery.
|
|
@@ -134,7 +167,7 @@ declare function discoverNextAppRoutes(root: string, appDir?: string): NextAppRo
|
|
|
134
167
|
* Paths are relative to `root` with `/` separators.
|
|
135
168
|
*/
|
|
136
169
|
declare function traceTypestylesModules(root: string, entryFiles: string[]): Promise<string[]>;
|
|
137
|
-
/** Load a traced module for style extraction. */
|
|
170
|
+
/** Load a traced module for style extraction (cache-busted so re-runs re-register styles). */
|
|
138
171
|
declare function createModuleLoader(root: string, modulePath: string): () => Promise<unknown>;
|
|
139
172
|
|
|
140
173
|
interface CollectRouteCssOptions {
|
|
@@ -194,4 +227,4 @@ interface RunTypestylesBuildOptions {
|
|
|
194
227
|
*/
|
|
195
228
|
declare function runTypestylesBuild({ root, modules, }: RunTypestylesBuildOptions): Promise<string>;
|
|
196
229
|
|
|
197
|
-
export { type CollectRouteCssOptions, type CollectRouteCssResult, DEFAULT_EXTRACT_MODULE_CANDIDATES, type DuplicateNamespaceReporter, type GetRouteCssOptions, type NextAppRoute, type RunTypestylesBuildOptions, TYPESTYLES_IMPORT_RE, type TypestylesExtractManifest, type TypestylesExtractManifestV1, type TypestylesExtractManifestV2, type TypestylesExtractOptions, type TypestylesIntegrationMode, type TypestylesRouteCssEntry, VerifyTypestylesBuildError, type VerifyTypestylesBuildOptions, type VerifyTypestylesBuildResult, buildManifestV2, collectAndWriteRouteCss, createModuleLoader, discoverDefaultExtractModules, discoverNextAppRoutes, extractNamespaces, getRouteCss, isManifestV2, normalizeRoutePath, pageRelPathToRoutePath, readCssFile, readTypestylesManifest, reportDuplicateNamespaces, resolveExtractMode, resolveExtractModules, runTypestylesBuild, traceTypestylesModules, verifyTypestylesBuild };
|
|
230
|
+
export { type CollectRouteCssOptions, type CollectRouteCssResult, DEFAULT_EXTRACT_MODULE_CANDIDATES, DEFAULT_REGISTERED_COMPONENTS_MODULE_BASES, type DuplicateNamespaceReporter, type GetRouteCssOptions, type NextAppRoute, type RunTypestylesBuildOptions, TYPESTYLES_IMPORT_RE, type TypestylesExtractManifest, type TypestylesExtractManifestV1, type TypestylesExtractManifestV2, type TypestylesExtractOptions, type TypestylesIntegrationMode, type TypestylesRouteCssEntry, VerifyTypestylesBuildError, type VerifyTypestylesBuildOptions, type VerifyTypestylesBuildResult, buildManifestV2, collectAndWriteRouteCss, createModuleLoader, discoverDefaultExtractModules, discoverNextAppRoutes, discoverRegisteredComponentsModule, extractNamespaces, getRouteCss, isManifestV2, moduleNeedsOverrideHmr, normalizeRoutePath, pageRelPathToRoutePath, readCssFile, readTypestylesManifest, reportDuplicateNamespaces, resolveExtractMode, resolveExtractModules, runTypestylesBuild, traceTypestylesModules, verifyTypestylesBuild };
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,12 @@ var DISCOVERY_EXTENSIONS = [".ts", ".tsx", ".js", ".mjs"];
|
|
|
13
13
|
var DEFAULT_EXTRACT_MODULE_CANDIDATES = DEFAULT_EXTRACT_MODULE_BASES.map(
|
|
14
14
|
(base) => `${base}.ts`
|
|
15
15
|
);
|
|
16
|
+
var DEFAULT_REGISTERED_COMPONENTS_MODULE_BASES = [
|
|
17
|
+
"src/themeable-refs",
|
|
18
|
+
"src/typestyles/themeable-refs",
|
|
19
|
+
"src/typestyles-registry",
|
|
20
|
+
"styles/themeable-refs"
|
|
21
|
+
];
|
|
16
22
|
function discoverDefaultExtractModules(root) {
|
|
17
23
|
const absRoot = resolvePath(root);
|
|
18
24
|
for (const base of DEFAULT_EXTRACT_MODULE_BASES) {
|
|
@@ -25,16 +31,88 @@ function discoverDefaultExtractModules(root) {
|
|
|
25
31
|
}
|
|
26
32
|
return [];
|
|
27
33
|
}
|
|
34
|
+
function discoverRegisteredComponentsModule(root) {
|
|
35
|
+
const absRoot = resolvePath(root);
|
|
36
|
+
for (const base of DEFAULT_REGISTERED_COMPONENTS_MODULE_BASES) {
|
|
37
|
+
for (const ext of DISCOVERY_EXTENSIONS) {
|
|
38
|
+
const rel = `${base}${ext}`;
|
|
39
|
+
if (existsSync(resolvePath(absRoot, rel))) {
|
|
40
|
+
return rel.replace(/\\/g, "/");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return void 0;
|
|
45
|
+
}
|
|
28
46
|
|
|
29
47
|
// src/namespaces.ts
|
|
30
|
-
var STYLES_COMPONENT_RE = /styles\.component\(\s*['"]([^'"]+)['"]/g;
|
|
31
|
-
var STYLES_CLASS_RE = /styles\.class\(\s*['"]([^'"]+)['"]/g;
|
|
48
|
+
var STYLES_COMPONENT_RE = /(?:styles\.component|(?<![\w.])recipe)\(\s*['"]([^'"]+)['"]/g;
|
|
49
|
+
var STYLES_CLASS_RE = /(?:styles\.class|(?<![\w.])style)\(\s*['"]([^'"]+)['"]/g;
|
|
32
50
|
var TOKENS_CREATE_RE = /tokens\.create\(\s*['"]([^'"]+)['"]/g;
|
|
33
|
-
var
|
|
51
|
+
var CREATE_THEME_CALL_RE = /(?:tokens\.)?createTheme\s*\(/g;
|
|
34
52
|
var KEYFRAMES_CREATE_RE = /keyframes\.create\(\s*['"]([^'"]+)['"]/g;
|
|
35
|
-
var GLOBAL_STYLE_RE = /global\.style\(\s*['"]([^'"]+)['"]/g;
|
|
53
|
+
var GLOBAL_STYLE_RE = /global\.(?:rule|style)\(\s*['"]([^'"]+)['"]/g;
|
|
36
54
|
var GLOBAL_FONT_FACE_RE = /global\.fontFace\(\s*['"]([^'"]+)['"]/g;
|
|
55
|
+
var CREATE_THEME_ARG_SCAN = 4e3;
|
|
56
|
+
function extractCreateThemeNames(code) {
|
|
57
|
+
const names = [];
|
|
58
|
+
for (const match of code.matchAll(CREATE_THEME_CALL_RE)) {
|
|
59
|
+
const start = (match.index ?? 0) + match[0].length;
|
|
60
|
+
const args = code.slice(start, start + CREATE_THEME_ARG_SCAN);
|
|
61
|
+
const positional = args.match(/^\s*['"]([^'"]+)['"]/);
|
|
62
|
+
if (positional) {
|
|
63
|
+
names.push(positional[1]);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (!/^\s*\{/.test(args)) continue;
|
|
67
|
+
const named = args.match(/\bname\s*:\s*['"]([^'"]+)['"]/);
|
|
68
|
+
if (named) names.push(named[1]);
|
|
69
|
+
}
|
|
70
|
+
return names;
|
|
71
|
+
}
|
|
72
|
+
var OVERRIDE_HMR_EXPORT_NAMES = /* @__PURE__ */ new Set(["createDesignTheme", "overrideComponent"]);
|
|
37
73
|
var TYPESTYLES_IMPORT_RE = /(?:from\s+|import\s+|require\s*\(\s*)['"]typestyles['"]/;
|
|
74
|
+
function stripCommentsForHmrScan(code) {
|
|
75
|
+
return code.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/.*$/gm, "$1");
|
|
76
|
+
}
|
|
77
|
+
function collectOverrideHmrCallTargets(code) {
|
|
78
|
+
const locals = new Set(OVERRIDE_HMR_EXPORT_NAMES);
|
|
79
|
+
const namespaces = /* @__PURE__ */ new Set();
|
|
80
|
+
for (const match of code.matchAll(/import\s*{([^}]+)}\s*from\s*['"][^'"]+['"]/g)) {
|
|
81
|
+
for (const rawPart of match[1].split(",")) {
|
|
82
|
+
const part = rawPart.trim();
|
|
83
|
+
if (!part || part.startsWith("type ")) continue;
|
|
84
|
+
const asMatch = part.match(/^(\w+)\s+as\s+(\w+)$/);
|
|
85
|
+
if (asMatch) {
|
|
86
|
+
if (OVERRIDE_HMR_EXPORT_NAMES.has(asMatch[1])) {
|
|
87
|
+
locals.add(asMatch[2]);
|
|
88
|
+
}
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const name = part.match(/^(\w+)$/)?.[1];
|
|
92
|
+
if (name && OVERRIDE_HMR_EXPORT_NAMES.has(name)) {
|
|
93
|
+
locals.add(name);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
for (const match of code.matchAll(/import\s*\*\s*as\s+(\w+)\s*from\s*['"][^'"]+['"]/g)) {
|
|
98
|
+
namespaces.add(match[1]);
|
|
99
|
+
}
|
|
100
|
+
return { locals, namespaces };
|
|
101
|
+
}
|
|
102
|
+
function moduleNeedsOverrideHmr(code) {
|
|
103
|
+
const scan = stripCommentsForHmrScan(code);
|
|
104
|
+
if (/\b(?:styles\.)?override\s*\(/.test(scan)) return true;
|
|
105
|
+
const { locals, namespaces } = collectOverrideHmrCallTargets(scan);
|
|
106
|
+
for (const name of locals) {
|
|
107
|
+
if (new RegExp(`\\b${name}\\s*\\(`).test(scan)) return true;
|
|
108
|
+
}
|
|
109
|
+
for (const ns of namespaces) {
|
|
110
|
+
if (new RegExp(`\\b${ns}\\.(?:createDesignTheme|overrideComponent)\\s*\\(`).test(scan)) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
38
116
|
function extractNamespaces(code) {
|
|
39
117
|
const keys = [];
|
|
40
118
|
const prefixes = [];
|
|
@@ -47,8 +125,8 @@ function extractNamespaces(code) {
|
|
|
47
125
|
for (const match of code.matchAll(TOKENS_CREATE_RE)) {
|
|
48
126
|
keys.push(`tokens:${match[1]}`);
|
|
49
127
|
}
|
|
50
|
-
for (const
|
|
51
|
-
keys.push(`theme:${
|
|
128
|
+
for (const themeName of extractCreateThemeNames(code)) {
|
|
129
|
+
keys.push(`theme:${themeName}`);
|
|
52
130
|
}
|
|
53
131
|
for (const match of code.matchAll(KEYFRAMES_CREATE_RE)) {
|
|
54
132
|
keys.push(`keyframes:${match[1]}`);
|
|
@@ -77,10 +155,20 @@ function reportDuplicateNamespaces(moduleNamespaces, id, prefixes, reporter) {
|
|
|
77
155
|
|
|
78
156
|
// src/resolve-extract.ts
|
|
79
157
|
function resolveExtractModules(root, extract) {
|
|
158
|
+
let modules;
|
|
80
159
|
if (extract?.modules !== void 0) {
|
|
81
|
-
|
|
160
|
+
modules = [...extract.modules];
|
|
161
|
+
} else {
|
|
162
|
+
modules = discoverDefaultExtractModules(root);
|
|
163
|
+
}
|
|
164
|
+
let registeredModule = extract?.registeredComponentsModule;
|
|
165
|
+
if (!registeredModule && extract?.include === "allRegisteredComponents") {
|
|
166
|
+
registeredModule = discoverRegisteredComponentsModule(root);
|
|
167
|
+
}
|
|
168
|
+
if (registeredModule && !modules.includes(registeredModule)) {
|
|
169
|
+
modules.push(registeredModule);
|
|
82
170
|
}
|
|
83
|
-
return
|
|
171
|
+
return modules;
|
|
84
172
|
}
|
|
85
173
|
function resolveExtractMode(explicitMode, resolvedModules) {
|
|
86
174
|
return explicitMode ?? (resolvedModules.length > 0 ? "build" : "runtime");
|
|
@@ -378,10 +466,11 @@ async function traceTypestylesModules(root, entryFiles) {
|
|
|
378
466
|
}
|
|
379
467
|
return [...traced].sort();
|
|
380
468
|
}
|
|
469
|
+
var moduleLoadNonce = 0;
|
|
381
470
|
function createModuleLoader(root, modulePath) {
|
|
382
471
|
const abs = resolve3(root, modulePath);
|
|
383
472
|
const href = pathToFileURL(abs).href;
|
|
384
|
-
return () => import(href);
|
|
473
|
+
return () => import(`${href}?typestyles-extract=${++moduleLoadNonce}`);
|
|
385
474
|
}
|
|
386
475
|
|
|
387
476
|
// src/route-css.ts
|
|
@@ -503,6 +592,16 @@ async function runTypestylesBuild({
|
|
|
503
592
|
// calls silently dropped as "unused". Disable tree shaking here so every
|
|
504
593
|
// registration in the extraction graph survives.
|
|
505
594
|
treeShaking: false,
|
|
595
|
+
// `treeShaking: false` only stops esbuild from pruning declarations
|
|
596
|
+
// *within* an already-included module. It's a separate esbuild behavior
|
|
597
|
+
// by the treeShaking option — that drops a plain bare import entirely
|
|
598
|
+
// (`import './some-lib'` with no binding at all) when it resolves to a
|
|
599
|
+
// module/package marked "sideEffects": false, before that module is ever
|
|
600
|
+
// considered for inclusion. A real extraction entry is exactly this
|
|
601
|
+
// shape: several side-effect-only imports, any one of which may point at
|
|
602
|
+
// a (correctly) tree-shakeable component library. Ignore both kinds of
|
|
603
|
+
// annotation so every import in the extraction graph is included.
|
|
604
|
+
ignoreAnnotations: true,
|
|
506
605
|
stdin: {
|
|
507
606
|
contents: importLines,
|
|
508
607
|
resolveDir: root,
|
|
@@ -546,6 +645,7 @@ ${result.stderr || result.stdout || "unknown error"}`
|
|
|
546
645
|
}
|
|
547
646
|
export {
|
|
548
647
|
DEFAULT_EXTRACT_MODULE_CANDIDATES,
|
|
648
|
+
DEFAULT_REGISTERED_COMPONENTS_MODULE_BASES,
|
|
549
649
|
TYPESTYLES_IMPORT_RE,
|
|
550
650
|
VerifyTypestylesBuildError,
|
|
551
651
|
buildManifestV2,
|
|
@@ -553,9 +653,11 @@ export {
|
|
|
553
653
|
createModuleLoader,
|
|
554
654
|
discoverDefaultExtractModules,
|
|
555
655
|
discoverNextAppRoutes,
|
|
656
|
+
discoverRegisteredComponentsModule,
|
|
556
657
|
extractNamespaces,
|
|
557
658
|
getRouteCss,
|
|
558
659
|
isManifestV2,
|
|
660
|
+
moduleNeedsOverrideHmr,
|
|
559
661
|
normalizeRoutePath,
|
|
560
662
|
pageRelPathToRoutePath,
|
|
561
663
|
readCssFile,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typestyles/build-runner",
|
|
3
|
-
"version": "0.0.0-unstable.
|
|
3
|
+
"version": "0.0.0-unstable.df708abe489f",
|
|
4
4
|
"description": "Shared module execution utilities for typestyles build integrations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"eslint": "^9.39.2",
|
|
30
30
|
"tsup": "^8.0.0",
|
|
31
31
|
"typescript": "^5.4.0",
|
|
32
|
-
"typestyles": "0.0.0-unstable.
|
|
32
|
+
"typestyles": "0.0.0-unstable.df708abe489f",
|
|
33
33
|
"vitest": "^3.0.0"
|
|
34
34
|
},
|
|
35
35
|
"license": "Apache-2.0",
|