@animus-ui/vite-plugin 0.1.0-next.49 → 0.1.0-next.59

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/index.d.ts CHANGED
@@ -2,8 +2,8 @@ import type { Plugin } from 'vite';
2
2
  export interface AnimusExtractOptions {
3
3
  /**
4
4
  * Path to a module exporting a SystemInstance from `@animus-ui/system`.
5
- * The module is loaded via a single bun subprocess at build start.
6
- * It provides prop config, group registry, theme tokens, transforms,
5
+ * The module is loaded via Rust NAPI (OXC + rquickjs) at build start.
6
+ * It provides prop config, group registry, theme tokens, selector aliases,
7
7
  * and global styles — everything the extraction pipeline needs.
8
8
  */
9
9
  system: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAU,MAAM,EAAE,MAAM,MAAM,CAAC;AAI3C,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,qGAAqG;IACrG,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AA6ID,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAihCnE;AAED,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAU,MAAM,EAAE,MAAM,MAAM,CAAC;AAE3C,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,qGAAqG;IACrG,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AA6ID,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CA8+BnE;AAED,eAAe,aAAa,CAAC"}
package/dist/index.mjs CHANGED
@@ -1,18 +1,14 @@
1
1
  import { createRequire } from "node:module";
2
- import { execSync } from "child_process";
3
2
  import { createHash } from "crypto";
4
- import { existsSync, readFileSync, readdirSync, statSync, unlinkSync, writeFileSync } from "fs";
5
- import { tmpdir } from "os";
3
+ import { existsSync, readFileSync, readdirSync, statSync } from "fs";
6
4
  import { dirname, extname, join, relative, resolve } from "path";
7
- import { fileURLToPath } from "url";
8
- import { applyUnitFallback, assembleStylesheet, detectRuntime, execSubprocess, extractSystemFilePackages, validateLayerOrder } from "@animus-ui/extract/pipeline";
5
+ import { applyUnitFallback, assembleStylesheet, extractSystemFilePackages, validateLayerOrder } from "@animus-ui/extract/pipeline";
9
6
  import browserslist from "browserslist";
10
7
  import { browserslistToTargets, transform } from "lightningcss";
11
8
  //#region \0rolldown/runtime.js
12
9
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
13
10
  //#endregion
14
11
  //#region src/index.ts
15
- const __pluginDir = dirname(fileURLToPath(import.meta.url));
16
12
  const VIRTUAL_CSS_ID = "virtual:animus/styles.css";
17
13
  const RESOLVED_CSS_ID = "\0virtual:animus/styles.css";
18
14
  const VIRTUAL_COMPONENTS_ID = "virtual:animus/components.js";
@@ -125,14 +121,38 @@ function animusExtract(options) {
125
121
  function warn(msg) {
126
122
  (logger ?? console).warn(`[animus] ${msg}`);
127
123
  }
124
+ function logTimingWaterfall(timing) {
125
+ if (!verbose) return;
126
+ for (const [key, label] of [
127
+ ["parseAndWalk", "parse+walk"],
128
+ ["importResolution", "imports"],
129
+ ["extensionProvenance", "provenance"],
130
+ ["topologicalSort", "topo-sort"],
131
+ ["chainEvaluation", "chains"],
132
+ ["jsxScanning", "jsx-scan"],
133
+ ["systemPropAggregation", "sys-props"],
134
+ ["usageLedger", "usage"],
135
+ ["reconciliation", "reconcile"],
136
+ ["cssGeneration", "css-gen"],
137
+ ["manifestSerialization", "serialize"]
138
+ ]) {
139
+ const ms = timing[key] ?? 0;
140
+ const pad = " ".repeat(Math.max(0, 15 - label.length));
141
+ const extra = key === "parseAndWalk" ? ` (${timing.fileCount ?? 0} files, ${timing.cacheHits ?? 0} cached)` : "";
142
+ log(` ${label}${pad}${String(ms).padStart(5)}ms${extra}`);
143
+ }
144
+ }
128
145
  let lcssTargets = {};
129
146
  let variableCss = "";
130
147
  let globalCss = "";
148
+ let globalStyleBlocksJson = null;
149
+ let pathAliasesJson = null;
131
150
  let storedManifest = null;
132
151
  let storedManifestJson = "";
133
152
  let resolvedComponentCss = "";
134
- let systemResolveScript = null;
135
153
  let storedSheets = null;
154
+ let fragmentCache = /* @__PURE__ */ new Map();
155
+ let reverseProvenance = {};
136
156
  let storedSystemPropMapJson = "{}";
137
157
  let storedDynamicPropsJson = "{}";
138
158
  let storedTransformsSource = "{}";
@@ -144,74 +164,25 @@ function animusExtract(options) {
144
164
  let bridgeInjected = false;
145
165
  let resolvedSystemPath = null;
146
166
  /**
147
- * Load a SystemInstance via single bun subprocess.
148
- * The subprocess imports the module and calls .serialize() to provide
149
- * prop config, group registry, tokens, transforms, and global styles.
167
+ * Load a SystemInstance via Rust NAPI (rquickjs bundled eval).
168
+ * The Rust crate reads the system file, strips TS types via OXC, resolves
169
+ * workspace package dependencies, bundles all modules, evaluates with
170
+ * rquickjs, and returns serialized config directly — no subprocess needed.
150
171
  */
151
172
  function loadSystem() {
152
173
  resolvedSystemPath = resolve(rootDir, options.system);
153
174
  try {
154
- const ts = Date.now();
155
- const tmpOut = join(tmpdir(), `animus-system-${ts}.json`);
156
- execSubprocess(`const m = require(${JSON.stringify(resolvedSystemPath)});\nconst exportNames = Object.keys(m);\nconst candidates = exportNames.filter(k => m[k] && typeof m[k].toConfig === 'function');\nif (candidates.length === 0) {\n throw new Error('[animus-extract] No SystemInstance found. Exports: [' + exportNames.join(', ') + ']. None have a .toConfig() method. A SystemInstance is created by: export const ds = createSystem().build()');\n}\nif (candidates.length > 1) {\n throw new Error('[animus-extract] Multiple SystemInstance candidates found: [' + candidates.join(', ') + ']. Specify which one to use.');\n}\nconst ds = m[candidates[0]];\nconst cfg = ds.toConfig();\nconst tokens = m.tokens || m.theme || null;\nconst serialized = tokens && typeof tokens.serialize === 'function' ? tokens.serialize() : null;\nconst globalStyleBlocks = {};\nfor (const [key, val] of Object.entries(m)) {\n if (val && typeof val === 'object' && val.__brand === 'GlobalStyleBlock') {\n globalStyleBlocks[key] = val.styles;\n }\n}\nrequire('fs').writeFileSync(${JSON.stringify(tmpOut)}, JSON.stringify({\n propConfig: cfg.propConfig,\n groupRegistry: cfg.groupRegistry,\n serialized: serialized,\n transformNames: Object.keys(cfg.transforms || {}),\n selectorAliases: cfg.selectorAliases || null,\n selectorOrder: cfg.selectorOrder || null,\n globalStyleBlocks: Object.keys(globalStyleBlocks).length > 0 ? globalStyleBlocks : null\n}));\n`, rootDir);
157
- const result = readFileSync(tmpOut, "utf-8");
158
- try {
159
- unlinkSync(tmpOut);
160
- } catch {}
161
- const parsed = JSON.parse(result);
162
- configJson = parsed.propConfig;
163
- groupRegistryJson = parsed.groupRegistry;
164
- selectorAliasesJson = parsed.selectorAliases || null;
165
- selectorOrderJson = parsed.selectorOrder || null;
166
- if (parsed.serialized) {
167
- themeJson = parsed.serialized.scalesJson;
168
- variableMapJson = parsed.serialized.variableMapJson;
169
- variableCss = parsed.serialized.variableCss;
170
- contextualVarsJson = parsed.serialized.contextualVarsJson;
171
- } else throw new Error("[animus-extract] Theme must be built with createTheme().build(). No .serialize() method found on tokens export.");
172
- if (parsed.globalStyleBlocks) {
173
- if (Object.keys(parsed.globalStyleBlocks).length > 0) try {
174
- const gsTmp = Date.now();
175
- const gsThemeFile = join(tmpdir(), `animus-gs-theme-${gsTmp}.json`);
176
- const gsOut = join(tmpdir(), `animus-global-${gsTmp}.json`);
177
- writeFileSync(gsThemeFile, themeJson);
178
- const gsNames = [
179
- "resolve-global-styles.mjs",
180
- "resolve-global-styles.js",
181
- "resolve-global-styles.ts"
182
- ];
183
- const gsCandidates = gsNames.map((n) => join(__pluginDir, n));
184
- try {
185
- const pkgDir = dirname(__require.resolve("@animus-ui/vite-plugin/package.json", { paths: [rootDir] }));
186
- for (const n of gsNames) {
187
- gsCandidates.push(join(pkgDir, "dist", n));
188
- gsCandidates.push(join(pkgDir, "src", n));
189
- }
190
- } catch {}
191
- const gsScriptPath = gsCandidates.find((p) => existsSync(p));
192
- if (!gsScriptPath) throw new Error(`resolve-global-styles not found in: ${gsCandidates.join(", ")}`);
193
- execSync(`${detectRuntime()} run "${gsScriptPath}" "${resolvedSystemPath}" "${gsThemeFile}" "${gsOut}"`, {
194
- cwd: rootDir,
195
- encoding: "utf-8"
196
- });
197
- const gsResult = JSON.parse(readFileSync(gsOut, "utf-8"));
198
- const parts = Object.values(gsResult).filter(Boolean);
199
- if (parts.length > 0) globalCss = `@layer anm-global {\n${parts.join("\n\n")}\n}`;
200
- try {
201
- unlinkSync(gsThemeFile);
202
- unlinkSync(gsOut);
203
- } catch {}
204
- } catch (e) {
205
- if (options.strict) throw new Error(`[animus-extract] Global styles resolution failed: ${e?.message || e}`);
206
- console.warn("[animus-extract] Global styles resolution failed:", e?.message || e);
207
- }
208
- }
209
- if (parsed.transformNames && parsed.transformNames.length > 0) {
210
- const tsTmp = Date.now();
211
- const tmpResolve = join(tmpdir(), `animus-transforms-resolve-${tsTmp}.js`);
212
- writeFileSync(tmpResolve, `const m = require(${JSON.stringify(resolvedSystemPath)});\nconst ds = m.ds || m.default || m.system;\nconst cfg = ds.toConfig();\nconst css = require('fs').readFileSync(process.argv[2], 'utf-8');\nconst resolved = css.replace(/__TRANSFORM__(\\w+)__(.+?)__/g, (_, name, rawValue) => {\n const fn = cfg.transforms[name];\n if (!fn) return rawValue;\n const value = rawValue !== '' && !isNaN(Number(rawValue)) ? Number(rawValue) : rawValue;\n const result = fn(value);\n return typeof result === 'object' ? JSON.stringify(result) : String(result);\n});\nrequire('fs').writeFileSync(process.argv[3], resolved);\n`);
213
- systemResolveScript = tmpResolve;
214
- }
175
+ const { loadSystemModule } = __require("@animus-ui/extract");
176
+ const config = loadSystemModule(resolvedSystemPath, rootDir);
177
+ configJson = config.propConfig;
178
+ groupRegistryJson = config.groupRegistry;
179
+ selectorAliasesJson = config.selectorAliases || null;
180
+ selectorOrderJson = config.selectorOrder || null;
181
+ themeJson = config.scalesJson;
182
+ variableMapJson = config.variableMapJson;
183
+ variableCss = config.variableCss;
184
+ contextualVarsJson = config.contextualVarsJson;
185
+ globalStyleBlocksJson = config.globalStyleBlocks || null;
215
186
  } catch (e) {
216
187
  if (options.strict) throw new Error(`[animus-extract] Failed to load system from ${resolvedSystemPath}: ${e}`);
217
188
  console.warn(`[animus-extract] Failed to load system from ${resolvedSystemPath}:`, e);
@@ -220,9 +191,9 @@ function animusExtract(options) {
220
191
  /**
221
192
  * Run project analysis and update the manifest.
222
193
  *
223
- * Pipeline: NAPI analyzeProject → transform resolution (subprocess) → unit fallback.
224
- * NAPI and unit fallback use @animus-ui/extract. Transform resolution stays as
225
- * subprocess because it needs live JS functions from the system module (ESM isolation).
194
+ * Pipeline: NAPI analyzeProject → unit fallback.
195
+ * Transforms are resolved in-process via boa_engine during Rust extraction.
196
+ * No subprocess needed.
226
197
  */
227
198
  function runAnalysis(fileEntries) {
228
199
  try {
@@ -231,7 +202,7 @@ function animusExtract(options) {
231
202
  runtime_import: "@animus-ui/system",
232
203
  css_module_id: "virtual:animus/styles.css"
233
204
  });
234
- const manifestJson = analyzeProject(JSON.stringify(fileEntries), themeJson, variableMapJson, contextualVarsJson || null, configJson, groupRegistryJson, JSON.stringify(packageMap), !isProd, emitterConfig, selectorAliasesJson, selectorOrderJson);
205
+ const manifestJson = analyzeProject(JSON.stringify(fileEntries), themeJson, variableMapJson, contextualVarsJson || null, configJson, groupRegistryJson, JSON.stringify(packageMap), !isProd, emitterConfig, selectorAliasesJson, selectorOrderJson, globalStyleBlocksJson, pathAliasesJson);
235
206
  storedManifest = JSON.parse(manifestJson);
236
207
  storedManifestJson = manifestJson;
237
208
  storedSystemPropMapJson = JSON.stringify(storedManifest?.system_prop_map ?? {});
@@ -250,28 +221,15 @@ function animusExtract(options) {
250
221
  storedTransformsSource = "{}";
251
222
  }
252
223
  bridgeInjected = false;
253
- storedSheets = storedManifest?.sheets ?? null;
254
- const rawCss = storedManifest?.css || "";
255
- if (systemResolveScript && rawCss.includes("__TRANSFORM__")) try {
256
- const tsTmp = Date.now();
257
- const tmpIn = join(tmpdir(), `animus-css-${tsTmp}.css`);
258
- const tmpOut = join(tmpdir(), `animus-css-${tsTmp}.out.css`);
259
- writeFileSync(tmpIn, rawCss);
260
- execSync(`${detectRuntime()} run "${systemResolveScript}" "${tmpIn}" "${tmpOut}"`, {
261
- cwd: rootDir,
262
- encoding: "utf-8"
263
- });
264
- resolvedComponentCss = readFileSync(tmpOut, "utf-8");
265
- try {
266
- unlinkSync(tmpIn);
267
- unlinkSync(tmpOut);
268
- } catch {}
269
- } catch (e) {
270
- if (options.strict) throw new Error(`[animus-extract] Transform resolution failed: ${e?.message}`);
271
- console.warn("[animus-extract] Transform resolution failed:", e?.message);
272
- resolvedComponentCss = rawCss;
224
+ const newFragments = storedManifest?.component_fragments;
225
+ if (newFragments && typeof newFragments === "object") {
226
+ fragmentCache.clear();
227
+ for (const [id, sheets] of Object.entries(newFragments)) fragmentCache.set(id, sheets);
273
228
  }
274
- else resolvedComponentCss = rawCss;
229
+ reverseProvenance = storedManifest?.reverse_provenance ?? {};
230
+ storedSheets = storedManifest?.sheets ?? null;
231
+ globalCss = storedManifest?.sheets?.global || "";
232
+ resolvedComponentCss = storedManifest?.css || "";
275
233
  resolvedComponentCss = applyUnitFallback(resolvedComponentCss);
276
234
  } catch (e) {
277
235
  if (options.strict) throw new Error(`[animus-extract] analyzeProject failed: ${e}`);
@@ -290,6 +248,39 @@ function animusExtract(options) {
290
248
  logger = config.logger;
291
249
  lcssTargets = resolveLightningTargets(options.targets, rootDir);
292
250
  log(`Lightning CSS targets resolved (${Object.keys(lcssTargets).length} browsers)`);
251
+ const rawAlias = config.resolve?.alias;
252
+ if (rawAlias) {
253
+ const entries = [];
254
+ if (Array.isArray(rawAlias)) {
255
+ for (const entry of rawAlias) if (typeof entry.find === "string" && typeof entry.replacement === "string") {
256
+ const replacement = entry.replacement.startsWith(rootDir) ? entry.replacement.slice(rootDir.length + 1) : entry.replacement;
257
+ entries.push({
258
+ pattern: entry.find.endsWith("/") ? entry.find : entry.find + "/",
259
+ replacement: replacement.endsWith("/") ? replacement : replacement + "/",
260
+ type: "prefix"
261
+ });
262
+ }
263
+ } else if (typeof rawAlias === "object" && rawAlias !== null) {
264
+ for (const [key, value] of Object.entries(rawAlias)) if (typeof value === "string") {
265
+ const replacement = value.startsWith(rootDir) ? value.slice(rootDir.length + 1) : value;
266
+ if (/\.\w+$/.test(replacement)) entries.push({
267
+ pattern: key,
268
+ replacement,
269
+ type: "exact"
270
+ });
271
+ else entries.push({
272
+ pattern: key.endsWith("/") ? key : key + "/",
273
+ replacement: replacement.endsWith("/") ? replacement : replacement + "/",
274
+ type: "prefix"
275
+ });
276
+ }
277
+ }
278
+ entries.sort((a, b) => b.pattern.length - a.pattern.length);
279
+ if (entries.length > 0) {
280
+ pathAliasesJson = JSON.stringify({ aliases: entries });
281
+ log(`Path aliases forwarded: ${entries.length} entries`);
282
+ }
283
+ }
293
284
  },
294
285
  async buildStart() {
295
286
  try {
@@ -390,6 +381,7 @@ function animusExtract(options) {
390
381
  const report = storedManifest.report;
391
382
  if (report) {
392
383
  log(`Extracted ${report.components_extracted}/${report.components_total} components (${Math.round(performance.now() - t0)}ms)`);
384
+ logTimingWaterfall(storedManifest.timing ?? {});
393
385
  log(`Reconciliation: ${report.components_extracted} kept, ${report.variants_eliminated} variants pruned, ${report.states_eliminated} states pruned`);
394
386
  const details = report.eliminated_details || [];
395
387
  for (const d of details) if (d.kind === "component") warn(`⚠ ${d.component} eliminated: ${d.reason}`);
@@ -610,6 +602,20 @@ if (import.meta.hot) {
610
602
  const hmrStart = performance.now();
611
603
  const prevReplacements = /* @__PURE__ */ new Map();
612
604
  if (storedManifest?.components) for (const [id, desc] of Object.entries(storedManifest.components)) prevReplacements.set(id, desc.replacement ?? "");
605
+ const directComponentIds = storedManifest?.files?.[relPath] ?? [];
606
+ const invalidatedIds = new Set(directComponentIds);
607
+ const queue = [...directComponentIds];
608
+ while (queue.length > 0) {
609
+ const parentId = queue.shift();
610
+ const children = reverseProvenance[parentId];
611
+ if (children) {
612
+ for (const childId of children) if (!invalidatedIds.has(childId)) {
613
+ invalidatedIds.add(childId);
614
+ queue.push(childId);
615
+ }
616
+ }
617
+ }
618
+ if (verbose && invalidatedIds.size > directComponentIds.length) log(`HMR: ${directComponentIds.length} direct + ${invalidatedIds.size - directComponentIds.length} transitive components invalidated`);
613
619
  const analysisStart = performance.now();
614
620
  runAnalysis(buildFileEntriesFromCache(fileCache, relPath));
615
621
  const analysisMs = Math.round(performance.now() - analysisStart);
@@ -640,6 +646,7 @@ if (import.meta.hot) {
640
646
  }
641
647
  const hmrMs = Math.round(performance.now() - hmrStart);
642
648
  log(`HMR update: ${relPath} — analysis ${analysisMs}ms, ${modulesToUpdate.length - modules.length} modules invalidated, total ${hmrMs}ms`);
649
+ logTimingWaterfall(storedManifest?.timing ?? {});
643
650
  if (modulesToUpdate.length > modules.length) return modulesToUpdate;
644
651
  }
645
652
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@animus-ui/vite-plugin",
3
- "version": "0.1.0-next.49",
3
+ "version": "0.1.0-next.59",
4
4
  "description": "Animus static CSS extraction Vite plugin",
5
5
  "author": "codecaaron <airrobb@gmail.com>",
6
6
  "license": "MIT",
@@ -37,8 +37,8 @@
37
37
  "vite": ">=5.0.0"
38
38
  },
39
39
  "dependencies": {
40
- "@animus-ui/extract": "0.1.0-next.49",
41
- "@animus-ui/system": "0.1.0-next.49",
40
+ "@animus-ui/extract": "0.1.0-next.59",
41
+ "@animus-ui/system": "0.1.0-next.59",
42
42
  "browserslist": "^4.24.0",
43
43
  "lightningcss": "^1.29.0"
44
44
  }
@@ -1,10 +0,0 @@
1
- /**
2
- * Standalone script executed via `bun run` to resolve global styles.
3
- *
4
- * Usage: bun run resolve-global-styles.ts <system-path> <theme-json-path> <output-file>
5
- *
6
- * Imports the system module for live transform functions (ESM isolation),
7
- * then delegates all resolution logic to @animus-ui/extract/pipeline.
8
- */
9
- export {};
10
- //# sourceMappingURL=resolve-global-styles.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resolve-global-styles.d.ts","sourceRoot":"","sources":["../src/resolve-global-styles.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAkEH,OAAO,EAAE,CAAC"}
@@ -1,31 +0,0 @@
1
- import { readFileSync, writeFileSync } from "fs";
2
- import { resolveGlobalStyles } from "@animus-ui/extract/pipeline";
3
- //#region src/resolve-global-styles.ts
4
- /**
5
- * Standalone script executed via `bun run` to resolve global styles.
6
- *
7
- * Usage: bun run resolve-global-styles.ts <system-path> <theme-json-path> <output-file>
8
- *
9
- * Imports the system module for live transform functions (ESM isolation),
10
- * then delegates all resolution logic to @animus-ui/extract/pipeline.
11
- */
12
- const [systemPath, themeJsonPath, outputFile] = process.argv.slice(2);
13
- if (!systemPath || !themeJsonPath || !outputFile) {
14
- process.stderr.write("Usage: bun run resolve-global-styles.ts <system-path> <theme-json-path> <output-file>\n");
15
- process.exit(1);
16
- }
17
- const mod = await import(systemPath);
18
- const ds = mod.ds || mod.default || mod.system;
19
- if (!ds || !ds.toConfig) throw new Error("Module does not export a SystemInstance with .serialize()");
20
- const cfg = ds.toConfig();
21
- const flat = JSON.parse(readFileSync(themeJsonPath, "utf-8"));
22
- const propConfig = JSON.parse(cfg.propConfig);
23
- const transforms = cfg.transforms || {};
24
- const globalStyleBlocks = {};
25
- for (const [key, val] of Object.entries(mod)) if (val && typeof val === "object" && val.__brand === "GlobalStyleBlock") globalStyleBlocks[key] = val.styles;
26
- const variableMap = {};
27
- for (const [tokenPath, value] of Object.entries(flat)) if (typeof value === "string" && value.startsWith("var(") && value.endsWith(")")) variableMap[tokenPath] = value.slice(4, -1);
28
- const result = resolveGlobalStyles(globalStyleBlocks, propConfig, flat, variableMap, transforms);
29
- writeFileSync(outputFile, JSON.stringify(result));
30
- //#endregion
31
- export {};