@animus-ui/extract 0.1.1-beta.2 → 0.1.2
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 +12 -11
- package/crates/extract-v2/animus-extract-v2.darwin-arm64.node +0 -0
- package/crates/extract-v2/animus-extract-v2.linux-arm64-gnu.node +0 -0
- package/crates/extract-v2/animus-extract-v2.linux-x64-gnu.node +0 -0
- package/crates/extract-v2/index.d.ts +22 -0
- package/dist/analyze-project-args.d.ts +50 -0
- package/dist/analyze-project-args.d.ts.map +1 -0
- package/dist/content-hash.d.ts +7 -0
- package/dist/content-hash.d.ts.map +1 -0
- package/dist/discover-files.d.ts +10 -0
- package/dist/discover-files.d.ts.map +1 -0
- package/dist/discover-packages.d.ts +94 -2
- package/dist/discover-packages.d.ts.map +1 -1
- package/dist/dynamic-prop-config.d.ts +23 -0
- package/dist/dynamic-prop-config.d.ts.map +1 -0
- package/dist/engine-adapter.d.ts +95 -0
- package/dist/engine-adapter.d.ts.map +1 -0
- package/dist/engine-retirement.d.ts +22 -0
- package/dist/engine-retirement.d.ts.map +1 -0
- package/dist/index.cjs +927 -179
- package/dist/index.d.ts +26 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +888 -177
- package/dist/manifest-diagnostics.d.ts +17 -0
- package/dist/manifest-diagnostics.d.ts.map +1 -0
- package/dist/path-aliases.d.ts +34 -0
- package/dist/path-aliases.d.ts.map +1 -0
- package/dist/post-process-css.d.ts +17 -0
- package/dist/post-process-css.d.ts.map +1 -0
- package/dist/run-analysis.d.ts +67 -0
- package/dist/run-analysis.d.ts.map +1 -0
- package/dist/static-css.d.ts +25 -0
- package/dist/static-css.d.ts.map +1 -0
- package/dist/system-config.d.ts +44 -0
- package/dist/system-config.d.ts.map +1 -0
- package/dist/system-props-module.d.ts +18 -0
- package/dist/system-props-module.d.ts.map +1 -0
- package/dist/timing-waterfall.d.ts +17 -0
- package/dist/timing-waterfall.d.ts.map +1 -0
- package/dist/tsconfig-paths.d.ts +8 -0
- package/dist/tsconfig-paths.d.ts.map +1 -0
- package/dist/watch-keys.d.ts +12 -0
- package/dist/watch-keys.d.ts.map +1 -0
- package/index-v2.js +6 -5
- package/package.json +14 -35
- package/animus-extract.darwin-arm64.node +0 -0
- package/animus-extract.linux-arm64-gnu.node +0 -0
- package/animus-extract.linux-x64-gnu.node +0 -0
- package/crates/extract-v2/index.js +0 -594
- package/dist/resolve-global-styles.d.ts +0 -25
- package/dist/resolve-global-styles.d.ts.map +0 -1
- package/dist/resolve-transforms.d.ts +0 -9
- package/dist/resolve-transforms.d.ts.map +0 -1
- package/index.d.ts +0 -65
- package/index.js +0 -594
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,35 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
+
value: mod,
|
|
21
|
+
enumerable: true
|
|
22
|
+
}) : target, mod));
|
|
23
|
+
//#endregion
|
|
24
|
+
let crypto = require("crypto");
|
|
2
25
|
let fs = require("fs");
|
|
26
|
+
let path = require("path");
|
|
27
|
+
let browserslist = require("browserslist");
|
|
28
|
+
browserslist = __toESM(browserslist);
|
|
29
|
+
let lightningcss = require("lightningcss");
|
|
3
30
|
let _animus_ui_properties = require("@animus-ui/properties");
|
|
31
|
+
let node_fs = require("node:fs");
|
|
32
|
+
let node_path = require("node:path");
|
|
4
33
|
//#region pipeline/assemble-stylesheet.ts
|
|
5
34
|
/**
|
|
6
35
|
* The 7 Animus cascade layers. Always prefixed with `anm-` to avoid
|
|
@@ -73,8 +102,319 @@ function assembleStylesheet(options) {
|
|
|
73
102
|
].filter(Boolean).join("\n");
|
|
74
103
|
}
|
|
75
104
|
//#endregion
|
|
105
|
+
//#region pipeline/analyze-project-args.ts
|
|
106
|
+
/** @internal */
|
|
107
|
+
function buildAnalyzeProjectArgs(inputs) {
|
|
108
|
+
return [
|
|
109
|
+
inputs.filesJson,
|
|
110
|
+
inputs.scalesJson,
|
|
111
|
+
inputs.variableMapJson,
|
|
112
|
+
inputs.contextualVarsJson,
|
|
113
|
+
inputs.propConfigJson,
|
|
114
|
+
inputs.groupRegistryJson,
|
|
115
|
+
inputs.packageResolutionJson,
|
|
116
|
+
inputs.devMode,
|
|
117
|
+
inputs.emitterConfigJson,
|
|
118
|
+
inputs.selectorAliasesJson,
|
|
119
|
+
null,
|
|
120
|
+
inputs.globalStyleBlocksJson,
|
|
121
|
+
inputs.pathAliasesJson,
|
|
122
|
+
inputs.keyframesJson,
|
|
123
|
+
inputs.staticCssJson,
|
|
124
|
+
inputs.conditionAliasesJson
|
|
125
|
+
];
|
|
126
|
+
}
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region pipeline/engine-adapter.ts
|
|
129
|
+
/**
|
|
130
|
+
* Build the engine-agnostic `engineApi()` both plugins call. Returns a function
|
|
131
|
+
* (invoked per call site) so `isV2()` and `loadNativeEngine()` re-evaluate each
|
|
132
|
+
* time — next reads its engine choice and native module dynamically from
|
|
133
|
+
* globalThis.
|
|
134
|
+
*/
|
|
135
|
+
function createV2EngineApi(deps) {
|
|
136
|
+
const { label, isV2, loadNativeEngine, store } = deps;
|
|
137
|
+
return () => {
|
|
138
|
+
if (!isV2()) return loadNativeEngine();
|
|
139
|
+
const native = loadNativeEngine();
|
|
140
|
+
return {
|
|
141
|
+
loadSystemModule: (...args) => native.loadSystemModule(...args),
|
|
142
|
+
analyzeProject: (filesJsonRaw, scalesJson, variableMapJson, contextualVarsJson, propConfigJson, groupRegistryJson, packageResolutionJson, devMode, emitterConfigJson, selectorAliasesJson, _selectorOrderJson, globalStyleBlocksJson, pathAliasesJson, keyframesJson, staticCssJson, conditionAliasesJson) => {
|
|
143
|
+
const filesJson = deps.rehydrateFilesJson ? deps.rehydrateFilesJson(filesJsonRaw) : filesJsonRaw;
|
|
144
|
+
const sent = /* @__PURE__ */ new Map();
|
|
145
|
+
for (const entry of JSON.parse(filesJson)) sent.set(entry.path, entry.source);
|
|
146
|
+
store.setSentSources(sent);
|
|
147
|
+
const emitterConfig = emitterConfigJson ? JSON.parse(emitterConfigJson) : {};
|
|
148
|
+
store.setEngine(null);
|
|
149
|
+
const config = {
|
|
150
|
+
runtimeImport: emitterConfig.runtime_import ?? void 0,
|
|
151
|
+
cssModuleId: emitterConfig.css_module_id ?? void 0,
|
|
152
|
+
systemPropsModuleId: emitterConfig.system_props_module_id ?? void 0,
|
|
153
|
+
themeJson: scalesJson,
|
|
154
|
+
variableMapJson,
|
|
155
|
+
contextualVarsJson: contextualVarsJson ?? void 0,
|
|
156
|
+
configJson: propConfigJson,
|
|
157
|
+
groupRegistryJson,
|
|
158
|
+
selectorAliasesJson: selectorAliasesJson ?? void 0,
|
|
159
|
+
conditionAliasesJson: conditionAliasesJson ?? void 0,
|
|
160
|
+
globalStyleBlocksJson: globalStyleBlocksJson ?? void 0,
|
|
161
|
+
keyframesJson: keyframesJson ?? void 0,
|
|
162
|
+
packageResolutionJson: packageResolutionJson ?? void 0,
|
|
163
|
+
pathAliasesJson: pathAliasesJson ?? void 0,
|
|
164
|
+
staticCssJson: staticCssJson ?? void 0,
|
|
165
|
+
devMode
|
|
166
|
+
};
|
|
167
|
+
const engine = new native.ExtractEngine(config);
|
|
168
|
+
store.setEngine(engine);
|
|
169
|
+
return engine.analyze(filesJson);
|
|
170
|
+
},
|
|
171
|
+
transformFile: (source, path, _manifest) => {
|
|
172
|
+
const engine = store.getEngine();
|
|
173
|
+
if (!engine) throw new Error(`[${label}] v2 transform before analyze — engine instance not initialized`);
|
|
174
|
+
const sentMap = store.getSentSources();
|
|
175
|
+
if (deps.passThroughUnknownPaths && sentMap && !sentMap.has(path)) return {
|
|
176
|
+
code: source,
|
|
177
|
+
hasComponents: false
|
|
178
|
+
};
|
|
179
|
+
const sent = sentMap?.get(path);
|
|
180
|
+
if (sent !== void 0 && sent !== source && !store.getDriftWarned()) {
|
|
181
|
+
store.setDriftWarned(true);
|
|
182
|
+
console.warn(`[${label}] v2: transform-time source for ${path} differs from analyze-time source — an upstream transform may be reverted`);
|
|
183
|
+
}
|
|
184
|
+
return JSON.parse(engine.transformFile(path));
|
|
185
|
+
},
|
|
186
|
+
clearAnalysisCache: () => {
|
|
187
|
+
const engine = store.getEngine();
|
|
188
|
+
if (engine) engine.clearCache();
|
|
189
|
+
store.setEngine(null);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
//#endregion
|
|
195
|
+
//#region pipeline/engine-retirement.ts
|
|
196
|
+
/**
|
|
197
|
+
* Loud rejection of the retired v1 extraction engine (openspec:
|
|
198
|
+
* retire-extract-v1).
|
|
199
|
+
*
|
|
200
|
+
* v2 is the only engine. Selecting v1 — via a plugin `engine: 'v1'` option or
|
|
201
|
+
* the `ANIMUS_ENGINE=v1` fixture env override — is a build-stopping error, never
|
|
202
|
+
* a silent upgrade to v2 (design D1: a silent flip would let a pinned consumer's
|
|
203
|
+
* build change engines without notice). Both extraction plugins call this before
|
|
204
|
+
* any engine selection so the rejection is uniform and the message is defined
|
|
205
|
+
* once.
|
|
206
|
+
*/
|
|
207
|
+
/** The one canonical retirement message, shared verbatim by both plugins and
|
|
208
|
+
* the env path (tasks.md cross-cutting: define once, reuse). */
|
|
209
|
+
const RETIRED_ENGINE_MESSAGE = "animus: extraction engine 'v1' was retired (openspec: retire-extract-v1) — v2 is the only engine; remove the engine option / ANIMUS_ENGINE override";
|
|
210
|
+
/**
|
|
211
|
+
* Throw the canonical retirement error when v1 is selected through either
|
|
212
|
+
* surface. Accepts the raw engine option as a string because the option type no
|
|
213
|
+
* longer admits `'v1'` — callers cast it so a stale `'v1'` config still fails
|
|
214
|
+
* loud at runtime instead of being silently coerced.
|
|
215
|
+
*/
|
|
216
|
+
function assertNoRetiredEngineSelection(engineOption) {
|
|
217
|
+
if (engineOption === "v1" || process.env.ANIMUS_ENGINE === "v1") throw new Error(RETIRED_ENGINE_MESSAGE);
|
|
218
|
+
}
|
|
219
|
+
//#endregion
|
|
220
|
+
//#region pipeline/content-hash.ts
|
|
221
|
+
/**
|
|
222
|
+
* MD5 content hash used for file-change detection (HMR diffing) by both
|
|
223
|
+
* extraction plugins. The algorithm/encoding is a cross-plugin contract:
|
|
224
|
+
* cache keys written by one build path must compare equal in the next.
|
|
225
|
+
*/
|
|
226
|
+
function contentHash(source) {
|
|
227
|
+
return (0, crypto.createHash)("md5").update(source).digest("hex");
|
|
228
|
+
}
|
|
229
|
+
//#endregion
|
|
230
|
+
//#region pipeline/discover-files.ts
|
|
231
|
+
/**
|
|
232
|
+
* Recursively discover source files under `dir`, skipping any path that
|
|
233
|
+
* contains one of `excludePatterns` (matched as substrings of both the full
|
|
234
|
+
* and root-relative path) and keeping files whose extension is in
|
|
235
|
+
* `extensionsSet`.
|
|
236
|
+
*
|
|
237
|
+
* Single authoritative copy for both extraction plugins.
|
|
238
|
+
*/
|
|
239
|
+
function discoverFiles(dir, rootDir, excludePatterns, extensionsSet) {
|
|
240
|
+
const results = [];
|
|
241
|
+
let entries;
|
|
242
|
+
try {
|
|
243
|
+
entries = (0, fs.readdirSync)(dir, { encoding: "utf8" });
|
|
244
|
+
} catch {
|
|
245
|
+
return results;
|
|
246
|
+
}
|
|
247
|
+
for (const entry of entries) {
|
|
248
|
+
const fullPath = (0, path.join)(dir, entry);
|
|
249
|
+
const relativePath = (0, path.relative)(rootDir, fullPath);
|
|
250
|
+
if (excludePatterns.some((pattern) => fullPath.includes(pattern) || relativePath.includes(pattern))) continue;
|
|
251
|
+
let stat;
|
|
252
|
+
try {
|
|
253
|
+
stat = (0, fs.statSync)(fullPath);
|
|
254
|
+
} catch {
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
if (stat.isDirectory()) results.push(...discoverFiles(fullPath, rootDir, excludePatterns, extensionsSet));
|
|
258
|
+
else if (extensionsSet.has((0, path.extname)(entry))) results.push(fullPath);
|
|
259
|
+
}
|
|
260
|
+
return results;
|
|
261
|
+
}
|
|
262
|
+
//#endregion
|
|
76
263
|
//#region pipeline/discover-packages.ts
|
|
77
264
|
/**
|
|
265
|
+
* Walk up from a resolved package entry file to the nearest directory
|
|
266
|
+
* containing a package.json (the package root). Stops at the filesystem
|
|
267
|
+
* root and returns it if no package.json is found on the way up.
|
|
268
|
+
*/
|
|
269
|
+
function findPackageRoot(absEntryPath) {
|
|
270
|
+
let pkgRoot = (0, path.dirname)(absEntryPath);
|
|
271
|
+
while (pkgRoot !== (0, path.dirname)(pkgRoot) && !(0, fs.existsSync)((0, path.join)(pkgRoot, "package.json"))) pkgRoot = (0, path.dirname)(pkgRoot);
|
|
272
|
+
return pkgRoot;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Exclusion fragments for discovery inside an external package's src/,
|
|
276
|
+
* matched against paths RELATIVE TO the src dir. Per spec
|
|
277
|
+
* external-package-file-discovery, the filters apply "within the package" —
|
|
278
|
+
* an npm-installed package whose own location is under node_modules (or a
|
|
279
|
+
* repo path containing 'dist') must still have its sources discovered.
|
|
280
|
+
*/
|
|
281
|
+
const PACKAGE_SRC_EXCLUDES = [
|
|
282
|
+
"dist",
|
|
283
|
+
"node_modules",
|
|
284
|
+
".test.",
|
|
285
|
+
".spec."
|
|
286
|
+
];
|
|
287
|
+
const isFile = (path$2) => {
|
|
288
|
+
try {
|
|
289
|
+
return (0, fs.statSync)(path$2).isFile();
|
|
290
|
+
} catch {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
/**
|
|
295
|
+
* Resolve an absolute-path specifier (a relative `includes` entry already
|
|
296
|
+
* resolved against the system file) without a bundler: the path itself when it
|
|
297
|
+
* is a file, otherwise the extension and directory-index candidates built from
|
|
298
|
+
* the caller's extension set. Used only as a fallback — a bundler resolver that
|
|
299
|
+
* answers first still wins, since it also knows aliases and `.js`→`.ts` mapping.
|
|
300
|
+
*/
|
|
301
|
+
function resolveAbsolutePathSpecifier(absSpecifier, extensionsSet) {
|
|
302
|
+
return [
|
|
303
|
+
absSpecifier,
|
|
304
|
+
...Array.from(extensionsSet, (ext) => absSpecifier + ext),
|
|
305
|
+
...Array.from(extensionsSet, (ext) => (0, path.join)(absSpecifier, `index${ext}`))
|
|
306
|
+
].find(isFile) ?? null;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Shared external-package source collection (spec:
|
|
310
|
+
* external-package-file-discovery), consumed by both extraction plugins.
|
|
311
|
+
* For each specifier: resolve to an absolute entry (null/throw → silently
|
|
312
|
+
* skip; an absolute-path specifier falls back to a filesystem probe), walk up
|
|
313
|
+
* to the package root, then either discover sources under src/ (redirecting
|
|
314
|
+
* module resolution to src/index.ts when present) or fall back to ingesting
|
|
315
|
+
* the resolved entry file itself.
|
|
316
|
+
*
|
|
317
|
+
* The only bundler-specific seams are callbacks: specifier resolution,
|
|
318
|
+
* dedup against already-ingested files, per-file preprocessing (MDX), and
|
|
319
|
+
* the unreadable-file warning. Hashing and caching stay in the plugins —
|
|
320
|
+
* their cache policies legitimately differ.
|
|
321
|
+
*
|
|
322
|
+
* Alongside the aggregates, one `ExternalPackageOutcome` per declared
|
|
323
|
+
* specifier records what that specifier produced. Collection never reports on
|
|
324
|
+
* them — any warning or gate is the caller's policy.
|
|
325
|
+
*/
|
|
326
|
+
async function collectExternalPackageSources(opts) {
|
|
327
|
+
const { specifiers, resolveSpecifier, rootDir, extensionsSet, hasEntry, preprocessFile, onUnreadable } = opts;
|
|
328
|
+
const entries = [];
|
|
329
|
+
const pushed = /* @__PURE__ */ new Set();
|
|
330
|
+
const packageMap = {};
|
|
331
|
+
const sourceEntries = /* @__PURE__ */ new Map();
|
|
332
|
+
const packageDirs = [];
|
|
333
|
+
const outcomes = [];
|
|
334
|
+
const alreadyIngested = (relPath) => hasEntry(relPath) || pushed.has(relPath);
|
|
335
|
+
for (const specifier of specifiers) {
|
|
336
|
+
let absEntry;
|
|
337
|
+
try {
|
|
338
|
+
absEntry = await resolveSpecifier(specifier);
|
|
339
|
+
} catch {
|
|
340
|
+
absEntry = null;
|
|
341
|
+
}
|
|
342
|
+
if (!absEntry && (0, path.isAbsolute)(specifier)) absEntry = resolveAbsolutePathSpecifier(specifier, extensionsSet);
|
|
343
|
+
if (!absEntry) {
|
|
344
|
+
outcomes.push({
|
|
345
|
+
specifier,
|
|
346
|
+
outcome: "unresolvable",
|
|
347
|
+
fileCount: 0
|
|
348
|
+
});
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
const srcDir = (0, path.join)(findPackageRoot(absEntry), "src");
|
|
352
|
+
let fileCount = 0;
|
|
353
|
+
if ((0, fs.existsSync)(srcDir)) {
|
|
354
|
+
packageDirs.push(srcDir);
|
|
355
|
+
const srcEntry = (0, path.join)(srcDir, "index.ts");
|
|
356
|
+
if ((0, fs.existsSync)(srcEntry)) {
|
|
357
|
+
packageMap[specifier] = (0, path.relative)(rootDir, srcEntry);
|
|
358
|
+
sourceEntries.set(specifier, srcEntry);
|
|
359
|
+
} else packageMap[specifier] = (0, path.relative)(rootDir, absEntry);
|
|
360
|
+
const pkgFiles = discoverFiles(srcDir, srcDir, [], extensionsSet).filter((absPath) => {
|
|
361
|
+
const inPkg = (0, path.relative)(srcDir, absPath);
|
|
362
|
+
return !PACKAGE_SRC_EXCLUDES.some((pattern) => inPkg.includes(pattern));
|
|
363
|
+
});
|
|
364
|
+
for (const pkgFile of pkgFiles) {
|
|
365
|
+
const relPath = (0, path.relative)(rootDir, pkgFile);
|
|
366
|
+
if (alreadyIngested(relPath)) {
|
|
367
|
+
fileCount++;
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
let source;
|
|
371
|
+
try {
|
|
372
|
+
source = (0, fs.readFileSync)(pkgFile, "utf-8");
|
|
373
|
+
} catch (err) {
|
|
374
|
+
onUnreadable(relPath, err);
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
const processed = await preprocessFile(source, relPath, pkgFile);
|
|
378
|
+
if (!processed) continue;
|
|
379
|
+
entries.push({
|
|
380
|
+
path: processed.relPath,
|
|
381
|
+
source: processed.source
|
|
382
|
+
});
|
|
383
|
+
pushed.add(processed.relPath);
|
|
384
|
+
fileCount++;
|
|
385
|
+
}
|
|
386
|
+
} else {
|
|
387
|
+
packageDirs.push((0, path.dirname)(absEntry));
|
|
388
|
+
const relPath = (0, path.relative)(rootDir, absEntry);
|
|
389
|
+
packageMap[specifier] = relPath;
|
|
390
|
+
if (alreadyIngested(relPath)) fileCount++;
|
|
391
|
+
else try {
|
|
392
|
+
const source = (0, fs.readFileSync)(absEntry, "utf-8");
|
|
393
|
+
entries.push({
|
|
394
|
+
path: relPath,
|
|
395
|
+
source
|
|
396
|
+
});
|
|
397
|
+
pushed.add(relPath);
|
|
398
|
+
fileCount++;
|
|
399
|
+
} catch (err) {
|
|
400
|
+
onUnreadable(relPath, err);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
outcomes.push({
|
|
404
|
+
specifier,
|
|
405
|
+
outcome: fileCount > 0 ? "resolved" : "empty",
|
|
406
|
+
fileCount
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
return {
|
|
410
|
+
entries,
|
|
411
|
+
packageMap,
|
|
412
|
+
sourceEntries,
|
|
413
|
+
packageDirs,
|
|
414
|
+
outcomes
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
78
418
|
* Extract external DS package names from `includes` declarations in the system file.
|
|
79
419
|
*
|
|
80
420
|
* Supports two forms:
|
|
@@ -82,8 +422,11 @@ function assembleStylesheet(options) {
|
|
|
82
422
|
* - Legacy: `.includes([identifier, ...])` chain method (RC migration fallback)
|
|
83
423
|
*
|
|
84
424
|
* For each identifier found, traces back to its import declaration and returns
|
|
85
|
-
* the import specifier
|
|
86
|
-
*
|
|
425
|
+
* the import specifier: a bare specifier normalized to its package name, a
|
|
426
|
+
* relative specifier resolved against the system file's directory into an
|
|
427
|
+
* absolute path (so a sibling package referenced by path contributes discovery
|
|
428
|
+
* too). Only packages explicitly declared via `includes` are treated as
|
|
429
|
+
* external DS dependencies.
|
|
87
430
|
*
|
|
88
431
|
* Falls back to empty array if no `includes` declaration is found.
|
|
89
432
|
*/
|
|
@@ -123,10 +466,13 @@ function extractSystemFilePackages(systemFilePath) {
|
|
|
123
466
|
if (localName) importMap.set(localName, specifier);
|
|
124
467
|
}
|
|
125
468
|
}
|
|
469
|
+
const systemFileDir = (0, path.dirname)(systemFilePath);
|
|
126
470
|
const packages = /* @__PURE__ */ new Set();
|
|
127
471
|
for (const id of identifiers) {
|
|
128
472
|
const specifier = importMap.get(id);
|
|
129
|
-
if (
|
|
473
|
+
if (!specifier) continue;
|
|
474
|
+
if (specifier.startsWith(".")) packages.add((0, path.resolve)(systemFileDir, specifier));
|
|
475
|
+
else {
|
|
130
476
|
const pkgName = specifier.startsWith("@") ? specifier.split("/").slice(0, 2).join("/") : specifier.split("/")[0];
|
|
131
477
|
packages.add(pkgName);
|
|
132
478
|
}
|
|
@@ -134,6 +480,525 @@ function extractSystemFilePackages(systemFilePath) {
|
|
|
134
480
|
return Array.from(packages);
|
|
135
481
|
}
|
|
136
482
|
//#endregion
|
|
483
|
+
//#region pipeline/path-aliases.ts
|
|
484
|
+
/**
|
|
485
|
+
* Normalize alias pairs: strip a `rootDir` prefix from targets, classify
|
|
486
|
+
* exact (file) vs prefix (directory) matches, force trailing slashes on
|
|
487
|
+
* prefix entries, and sort longest pattern first for correct matching
|
|
488
|
+
* priority. Returns null when no entries survive.
|
|
489
|
+
*/
|
|
490
|
+
function buildPathAliasesJson(pairs, rootDir) {
|
|
491
|
+
const entries = [];
|
|
492
|
+
for (const { pattern, target, kind } of pairs) {
|
|
493
|
+
const replacement = target.startsWith(rootDir) ? target.slice(rootDir.length + 1) : target;
|
|
494
|
+
if (kind ? kind === "exact" : /\.\w+$/.test(replacement)) entries.push({
|
|
495
|
+
pattern,
|
|
496
|
+
replacement,
|
|
497
|
+
type: "exact"
|
|
498
|
+
});
|
|
499
|
+
else entries.push({
|
|
500
|
+
pattern: pattern.endsWith("/") ? pattern : pattern + "/",
|
|
501
|
+
replacement: replacement.endsWith("/") ? replacement : replacement + "/",
|
|
502
|
+
type: "prefix"
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
entries.sort((a, b) => b.pattern.length - a.pattern.length);
|
|
506
|
+
if (entries.length === 0) return null;
|
|
507
|
+
return {
|
|
508
|
+
json: JSON.stringify({ aliases: entries }),
|
|
509
|
+
count: entries.length
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
//#endregion
|
|
513
|
+
//#region pipeline/post-process-css.ts
|
|
514
|
+
/**
|
|
515
|
+
* CSS post-processing (spec: css-post-processing) — Lightning CSS
|
|
516
|
+
* autoprefixing, syntax lowering, and optional minification against
|
|
517
|
+
* browserslist targets. The single implementation consumed by both the
|
|
518
|
+
* Vite plugin (virtual-module serve time) and the Next.js plugin
|
|
519
|
+
* (ExtractionSession artifact emission).
|
|
520
|
+
*/
|
|
521
|
+
/**
|
|
522
|
+
* Resolve browser targets for Lightning CSS.
|
|
523
|
+
* Priority: explicit config → project browserslist → 'defaults' fallback.
|
|
524
|
+
*/
|
|
525
|
+
function resolveLightningTargets(explicitTargets, rootDir) {
|
|
526
|
+
let queries;
|
|
527
|
+
if (explicitTargets) queries = Array.isArray(explicitTargets) ? explicitTargets : [explicitTargets];
|
|
528
|
+
else {
|
|
529
|
+
const detected = (0, browserslist.default)(void 0, { path: rootDir });
|
|
530
|
+
queries = detected.length > 0 ? detected : (0, browserslist.default)("defaults");
|
|
531
|
+
}
|
|
532
|
+
return (0, lightningcss.browserslistToTargets)(Array.isArray(queries) && typeof queries[0] === "string" && queries[0].includes(" ") ? (0, browserslist.default)(queries) : queries);
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Post-process CSS with Lightning CSS: autoprefixing + optional minification.
|
|
536
|
+
* On failure, returns the original CSS and logs a warning.
|
|
537
|
+
*/
|
|
538
|
+
function postProcessCss(css, opts) {
|
|
539
|
+
if (!css) return css;
|
|
540
|
+
try {
|
|
541
|
+
return (0, lightningcss.transform)({
|
|
542
|
+
filename: "animus-extracted.css",
|
|
543
|
+
code: Buffer.from(css),
|
|
544
|
+
minify: opts.minify,
|
|
545
|
+
targets: opts.targets
|
|
546
|
+
}).code.toString();
|
|
547
|
+
} catch (e) {
|
|
548
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
549
|
+
(opts.warnFn ?? console.warn)(`[animus] Lightning CSS post-processing failed: ${msg}`);
|
|
550
|
+
return css;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
//#endregion
|
|
554
|
+
//#region pipeline/manifest-diagnostics.ts
|
|
555
|
+
/**
|
|
556
|
+
* Surface extraction-manifest diagnostics through a plugin's warn channel.
|
|
557
|
+
*
|
|
558
|
+
* Single authoritative copy for both extraction plugins. Surfaces `bail`
|
|
559
|
+
* (component not extracted), `skip` (component skipped), and `warn` kinds;
|
|
560
|
+
* unknown kinds stay silent.
|
|
561
|
+
*/
|
|
562
|
+
function surfaceManifestDiagnostics(manifest, warn) {
|
|
563
|
+
for (const diagnostic of manifest.diagnostics ?? []) if (diagnostic.kind === "bail") warn(`⚠ ${diagnostic.component} not extracted: ${diagnostic.message}`);
|
|
564
|
+
else if (diagnostic.kind === "skip") warn(`⚠ ${diagnostic.component}: skipped ${diagnostic.message}`);
|
|
565
|
+
else if (diagnostic.kind === "warn") warn(`⚠ ${diagnostic.file}: ${diagnostic.component}: ${diagnostic.message}`);
|
|
566
|
+
}
|
|
567
|
+
//#endregion
|
|
568
|
+
//#region pipeline/unit-fallback.ts
|
|
569
|
+
/**
|
|
570
|
+
* Append `px` to bare numeric values in CSS declarations for properties
|
|
571
|
+
* that expect length units. Unitless properties are preserved as-is.
|
|
572
|
+
* Numbers inside CSS function calls (cubic-bezier, rgb, calc, etc.) are skipped.
|
|
573
|
+
*/
|
|
574
|
+
function applyUnitFallback(css) {
|
|
575
|
+
return css.replace(/([a-z-]+)\s*:\s*([^;{}]+);/g, (match, prop, value) => {
|
|
576
|
+
if (_animus_ui_properties.UNITLESS_PROPERTIES.has(prop)) return match;
|
|
577
|
+
let depth = 0;
|
|
578
|
+
let fixed = "";
|
|
579
|
+
let i = 0;
|
|
580
|
+
while (i < value.length) if (value[i] === "(") {
|
|
581
|
+
depth++;
|
|
582
|
+
fixed += value[i];
|
|
583
|
+
i++;
|
|
584
|
+
} else if (value[i] === ")") {
|
|
585
|
+
depth--;
|
|
586
|
+
fixed += value[i];
|
|
587
|
+
i++;
|
|
588
|
+
} else if (depth > 0) {
|
|
589
|
+
fixed += value[i];
|
|
590
|
+
i++;
|
|
591
|
+
} else {
|
|
592
|
+
const numMatch = value.slice(i).match(/^(-?\d+\.?\d*)/);
|
|
593
|
+
if (numMatch) {
|
|
594
|
+
const num = numMatch[1];
|
|
595
|
+
const after = value[i + num.length];
|
|
596
|
+
if (after && /[a-z%]/i.test(after)) fixed += num;
|
|
597
|
+
else fixed += num + "px";
|
|
598
|
+
i += num.length;
|
|
599
|
+
} else {
|
|
600
|
+
fixed += value[i];
|
|
601
|
+
i++;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
return fixed !== value ? `${prop}:${fixed};` : match;
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
//#endregion
|
|
608
|
+
//#region pipeline/run-analysis.ts
|
|
609
|
+
/**
|
|
610
|
+
* Build the named `analyzeProject` input set from analysis options. Also
|
|
611
|
+
* the persistence shape for `.animus/analysis-inputs.json` — an isolated
|
|
612
|
+
* process can replay the analysis from exactly this object
|
|
613
|
+
* (spec: next-turbopack-integration).
|
|
614
|
+
*/
|
|
615
|
+
function buildAnalysisInputs(opts) {
|
|
616
|
+
return {
|
|
617
|
+
filesJson: JSON.stringify(opts.fileEntries),
|
|
618
|
+
scalesJson: opts.system.scalesJson,
|
|
619
|
+
variableMapJson: opts.system.variableMapJson,
|
|
620
|
+
contextualVarsJson: opts.system.contextualVarsJson,
|
|
621
|
+
propConfigJson: opts.system.propConfigJson,
|
|
622
|
+
groupRegistryJson: opts.system.groupRegistryJson,
|
|
623
|
+
packageResolutionJson: JSON.stringify(opts.packageMap),
|
|
624
|
+
devMode: opts.devMode,
|
|
625
|
+
emitterConfigJson: JSON.stringify({
|
|
626
|
+
runtime_import: opts.emitter.runtimeImport,
|
|
627
|
+
css_module_id: opts.emitter.cssModuleId,
|
|
628
|
+
...opts.emitter.systemPropsModuleId ? { system_props_module_id: opts.emitter.systemPropsModuleId } : {}
|
|
629
|
+
}),
|
|
630
|
+
selectorAliasesJson: opts.system.selectorAliasesJson,
|
|
631
|
+
globalStyleBlocksJson: opts.system.globalStyleBlocksJson,
|
|
632
|
+
pathAliasesJson: opts.pathAliasesJson,
|
|
633
|
+
keyframesJson: opts.system.keyframesJson,
|
|
634
|
+
staticCssJson: opts.staticCssJson ?? null,
|
|
635
|
+
conditionAliasesJson: opts.system.conditionAliasesJson ?? null
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* The one analysis invocation both plugins share: build the emitter
|
|
640
|
+
* config, serialize inputs, call the NAPI `analyzeProject`, parse the
|
|
641
|
+
* manifest, surface its diagnostics, and resolve the CSS outputs.
|
|
642
|
+
*
|
|
643
|
+
* Error handling stays at the call site (strict-mode throw vs warn).
|
|
644
|
+
*/
|
|
645
|
+
function runProjectAnalysis(engineApi, opts) {
|
|
646
|
+
const { analyzeProject } = engineApi();
|
|
647
|
+
let t = performance.now();
|
|
648
|
+
const inputs = buildAnalysisInputs(opts);
|
|
649
|
+
const serializeMs = Math.round(performance.now() - t);
|
|
650
|
+
t = performance.now();
|
|
651
|
+
const manifestJson = analyzeProject(...buildAnalyzeProjectArgs(inputs));
|
|
652
|
+
const extractMs = Math.round(performance.now() - t);
|
|
653
|
+
t = performance.now();
|
|
654
|
+
const manifest = JSON.parse(manifestJson);
|
|
655
|
+
surfaceManifestDiagnostics(manifest, opts.warn);
|
|
656
|
+
const parseMs = Math.round(performance.now() - t);
|
|
657
|
+
return {
|
|
658
|
+
manifest,
|
|
659
|
+
manifestJson,
|
|
660
|
+
globalCss: manifest?.sheets?.global || "",
|
|
661
|
+
componentCss: applyUnitFallback(manifest?.css || ""),
|
|
662
|
+
inputs,
|
|
663
|
+
timings: {
|
|
664
|
+
serializeMs,
|
|
665
|
+
extractMs,
|
|
666
|
+
parseMs
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* Clear the engine's per-file analysis cache so stale results from a prior
|
|
672
|
+
* build never bleed into a fresh run. Tolerates engines without the
|
|
673
|
+
* capability (older builds) — the probe is benign.
|
|
674
|
+
*/
|
|
675
|
+
function clearEngineCache(engineApi) {
|
|
676
|
+
try {
|
|
677
|
+
const { clearAnalysisCache } = engineApi();
|
|
678
|
+
clearAnalysisCache();
|
|
679
|
+
} catch {}
|
|
680
|
+
}
|
|
681
|
+
//#endregion
|
|
682
|
+
//#region pipeline/static-css.ts
|
|
683
|
+
/** Key-sorted stringify so semantically identical configs serialize
|
|
684
|
+
* identically (stable analysis-inputs hashing). */
|
|
685
|
+
function stableStringify(value) {
|
|
686
|
+
if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
|
|
687
|
+
if (value !== null && typeof value === "object") return `{${Object.entries(value).filter(([, v]) => v !== void 0).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([k, v]) => `${JSON.stringify(k)}:${stableStringify(v)}`).join(",")}}`;
|
|
688
|
+
return JSON.stringify(value);
|
|
689
|
+
}
|
|
690
|
+
/** Serialize a staticCss option for the engine; null when absent/empty. */
|
|
691
|
+
function serializeStaticCss(config) {
|
|
692
|
+
if (!config) return null;
|
|
693
|
+
const json = stableStringify(config);
|
|
694
|
+
return json === "{}" ? null : json;
|
|
695
|
+
}
|
|
696
|
+
//#endregion
|
|
697
|
+
//#region pipeline/prefix.ts
|
|
698
|
+
/**
|
|
699
|
+
* Apply namespace prefix to a variable map, CSS variable declarations, and theme JSON.
|
|
700
|
+
*
|
|
701
|
+
* Variable map: `{ "colors.ember": "--color-ember" }` -> `{ "colors.ember": "--prefix-color-ember" }`
|
|
702
|
+
* Variable CSS: `--color-ember: #FF2800` -> `--prefix-color-ember: #FF2800`
|
|
703
|
+
* `var(--color-ember)` -> `var(--prefix-color-ember)`
|
|
704
|
+
* Theme JSON: `{ "colors.ember": "var(--color-ember)" }` -> `{ "colors.ember": "var(--prefix-color-ember)" }`
|
|
705
|
+
*/
|
|
706
|
+
function applyPrefix(prefix, variableMapJson, variableCss, themeJson, contextualVarsJson) {
|
|
707
|
+
if (!prefix) return {
|
|
708
|
+
variableMapJson,
|
|
709
|
+
variableCss,
|
|
710
|
+
themeJson,
|
|
711
|
+
contextualVarsJson
|
|
712
|
+
};
|
|
713
|
+
const varRefRe = /var\(--([a-zA-Z][\w-]*)\)/g;
|
|
714
|
+
const map = JSON.parse(variableMapJson);
|
|
715
|
+
const prefixed = {};
|
|
716
|
+
for (const [key, varName] of Object.entries(map)) prefixed[key] = varName.startsWith("--") ? `--${prefix}-${varName.slice(2)}` : varName;
|
|
717
|
+
let css = variableCss;
|
|
718
|
+
css = css.replace(/--([a-zA-Z][\w-]*)\s*:/g, `--${prefix}-$1:`);
|
|
719
|
+
css = css.replace(varRefRe, `var(--${prefix}-$1)`);
|
|
720
|
+
const result = {
|
|
721
|
+
variableMapJson: JSON.stringify(prefixed),
|
|
722
|
+
variableCss: css
|
|
723
|
+
};
|
|
724
|
+
if (themeJson) result.themeJson = themeJson.replace(varRefRe, `var(--${prefix}-$1)`);
|
|
725
|
+
if (contextualVarsJson) {
|
|
726
|
+
const ctxVars = JSON.parse(contextualVarsJson);
|
|
727
|
+
const prefixedCtx = {};
|
|
728
|
+
for (const [scale, names] of Object.entries(ctxVars)) prefixedCtx[scale] = names.map((name) => `${prefix}-${name}`);
|
|
729
|
+
result.contextualVarsJson = JSON.stringify(prefixedCtx);
|
|
730
|
+
}
|
|
731
|
+
return result;
|
|
732
|
+
}
|
|
733
|
+
//#endregion
|
|
734
|
+
//#region pipeline/system-config.ts
|
|
735
|
+
/**
|
|
736
|
+
* Load a SystemInstance via the engine's `loadSystemModule` and normalize
|
|
737
|
+
* it into a SystemConfig. When `prefix` is set, CSS variable names in the
|
|
738
|
+
* variable map/css (and theme + contextual vars when affected) are
|
|
739
|
+
* namespaced via the shared `applyPrefix`.
|
|
740
|
+
*
|
|
741
|
+
* Error handling stays at the call site — the Vite plugin warns (or throws
|
|
742
|
+
* in strict mode) and keeps its previous config, the Next plugin lets the
|
|
743
|
+
* failure propagate.
|
|
744
|
+
*/
|
|
745
|
+
function loadSystemConfig(engineApi, opts) {
|
|
746
|
+
const { loadSystemModule } = engineApi();
|
|
747
|
+
const config = loadSystemModule(opts.systemPath, opts.rootDir);
|
|
748
|
+
let scalesJson = config.scalesJson;
|
|
749
|
+
let variableMapJson = config.variableMapJson;
|
|
750
|
+
let variableCss = config.variableCss;
|
|
751
|
+
let contextualVarsJson = config.contextualVarsJson || null;
|
|
752
|
+
if (opts.prefix) {
|
|
753
|
+
const prefixed = applyPrefix(opts.prefix, variableMapJson, variableCss, scalesJson, contextualVarsJson || void 0);
|
|
754
|
+
variableMapJson = prefixed.variableMapJson;
|
|
755
|
+
variableCss = prefixed.variableCss;
|
|
756
|
+
if (prefixed.themeJson) scalesJson = prefixed.themeJson;
|
|
757
|
+
if (prefixed.contextualVarsJson) contextualVarsJson = prefixed.contextualVarsJson;
|
|
758
|
+
}
|
|
759
|
+
return {
|
|
760
|
+
propConfigJson: config.propConfig,
|
|
761
|
+
groupRegistryJson: config.groupRegistry,
|
|
762
|
+
scalesJson,
|
|
763
|
+
variableMapJson,
|
|
764
|
+
variableCss,
|
|
765
|
+
contextualVarsJson,
|
|
766
|
+
selectorAliasesJson: config.selectorAliases || null,
|
|
767
|
+
conditionAliasesJson: config.conditionAliases || null,
|
|
768
|
+
globalStyleBlocksJson: config.globalStyleBlocks || null,
|
|
769
|
+
keyframesJson: config.keyframesBlocks || null,
|
|
770
|
+
dependencies: config.dependencies ?? []
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
//#endregion
|
|
774
|
+
//#region pipeline/dynamic-prop-config.ts
|
|
775
|
+
function buildDynamicPropConfig(dynamicProps) {
|
|
776
|
+
const configEntries = {};
|
|
777
|
+
for (const [propName, meta] of Object.entries(dynamicProps)) configEntries[propName] = {
|
|
778
|
+
varName: meta.var_name,
|
|
779
|
+
slotClass: meta.slot_class,
|
|
780
|
+
...meta.transform_name ? { transformName: meta.transform_name } : {},
|
|
781
|
+
...meta.scale_values && Object.keys(meta.scale_values).length > 0 ? { scaleValues: meta.scale_values } : {}
|
|
782
|
+
};
|
|
783
|
+
return configEntries;
|
|
784
|
+
}
|
|
785
|
+
//#endregion
|
|
786
|
+
//#region pipeline/system-props-module.ts
|
|
787
|
+
/**
|
|
788
|
+
* Build the source of the runtime system-props module — served as
|
|
789
|
+
* `virtual:animus/system-props` by the Vite plugin and written to
|
|
790
|
+
* `.animus/system-props.js` by the Next plugin. One generator so the two
|
|
791
|
+
* runtimes can never drift.
|
|
792
|
+
*
|
|
793
|
+
* Runtime transform functions for dynamic props are not yet supported
|
|
794
|
+
* (transforms are resolved at extraction time via boa_engine in Rust), so
|
|
795
|
+
* `transforms` defaults to an empty object literal.
|
|
796
|
+
*/
|
|
797
|
+
function buildSystemPropsModule(opts) {
|
|
798
|
+
const dynamicPropConfig = buildDynamicPropConfig(opts.dynamicProps);
|
|
799
|
+
return `export const systemPropMap = ${opts.systemPropMapJson};\nexport const systemPropGroups = ${opts.groupRegistryJson};\nexport const dynamicPropConfig = ${JSON.stringify(dynamicPropConfig)};\nexport const transforms = ${opts.transformsSource ?? "{}"};\n`;
|
|
800
|
+
}
|
|
801
|
+
//#endregion
|
|
802
|
+
//#region pipeline/timing-waterfall.ts
|
|
803
|
+
/**
|
|
804
|
+
* Rust-side timing phases as reported in `manifest.timing`, in waterfall
|
|
805
|
+
* order, with their display labels. Mirrors the timing struct in the
|
|
806
|
+
* extract-v2 crate — a renamed or added Rust phase is updated here once,
|
|
807
|
+
* not per plugin.
|
|
808
|
+
*/
|
|
809
|
+
const RUST_TIMING_PHASES = [
|
|
810
|
+
["parseAndWalk", "parse+walk"],
|
|
811
|
+
["importResolution", "imports"],
|
|
812
|
+
["extensionProvenance", "provenance"],
|
|
813
|
+
["topologicalSort", "topo-sort"],
|
|
814
|
+
["chainEvaluation", "chains"],
|
|
815
|
+
["jsxScanning", "jsx-scan"],
|
|
816
|
+
["systemPropAggregation", "sys-props"],
|
|
817
|
+
["usageLedger", "usage"],
|
|
818
|
+
["reconciliation", "reconcile"],
|
|
819
|
+
["cssGeneration", "css-gen"],
|
|
820
|
+
["manifestSerialization", "serialize"]
|
|
821
|
+
];
|
|
822
|
+
/**
|
|
823
|
+
* Format the Rust timing waterfall as log lines. `indent` and `labelWidth`
|
|
824
|
+
* let each plugin keep its established column layout; the phase table and
|
|
825
|
+
* the `(N files, M cached)` suffix are shared.
|
|
826
|
+
*/
|
|
827
|
+
function formatRustTimingWaterfall(timing, opts) {
|
|
828
|
+
const lines = [];
|
|
829
|
+
for (const [key, label] of RUST_TIMING_PHASES) {
|
|
830
|
+
const ms = timing[key] ?? 0;
|
|
831
|
+
const pad = " ".repeat(Math.max(0, opts.labelWidth - label.length));
|
|
832
|
+
const extra = key === "parseAndWalk" ? ` (${timing.fileCount ?? 0} files, ${timing.cacheHits ?? 0} cached)` : "";
|
|
833
|
+
lines.push(`${opts.indent}${label}${pad}${String(ms).padStart(5)}ms${extra}`);
|
|
834
|
+
}
|
|
835
|
+
return lines;
|
|
836
|
+
}
|
|
837
|
+
//#endregion
|
|
838
|
+
//#region pipeline/tsconfig-paths.ts
|
|
839
|
+
/**
|
|
840
|
+
* tsconfig `paths` → alias pairs for the Rust `pathAliasesJson` contract
|
|
841
|
+
* (via `buildPathAliasesJson`). Used by drivers that cannot harvest aliases
|
|
842
|
+
* from a live bundler config — Turbopack exposes none.
|
|
843
|
+
*
|
|
844
|
+
* Semantics (deliberately the TypeScript subset that matters for import
|
|
845
|
+
* provenance): JSONC tolerated (comments + trailing commas); `extends`
|
|
846
|
+
* chains followed (string or array; missing parents and cycles skipped);
|
|
847
|
+
* the NEAREST config declaring `paths` wins wholesale (TS replaces the
|
|
848
|
+
* object, never merges); targets resolve against the nearest `baseUrl`
|
|
849
|
+
* (resolved from its declaring config's directory) or, absent one, the
|
|
850
|
+
* directory of the config declaring `paths`; first target per pattern.
|
|
851
|
+
* `x/*` patterns become prefix pairs, non-wildcard patterns exact pairs,
|
|
852
|
+
* bare `*` catch-alls and mid-pattern wildcards are skipped.
|
|
853
|
+
*/
|
|
854
|
+
/** String-aware JSONC → JSON: strips // and block comments + trailing commas. */
|
|
855
|
+
function stripJsonc(text) {
|
|
856
|
+
let out = "";
|
|
857
|
+
let inString = false;
|
|
858
|
+
let inLine = false;
|
|
859
|
+
let inBlock = false;
|
|
860
|
+
for (let i = 0; i < text.length; i++) {
|
|
861
|
+
const ch = text[i];
|
|
862
|
+
const next = text[i + 1];
|
|
863
|
+
if (inLine) {
|
|
864
|
+
if (ch === "\n") {
|
|
865
|
+
inLine = false;
|
|
866
|
+
out += ch;
|
|
867
|
+
}
|
|
868
|
+
continue;
|
|
869
|
+
}
|
|
870
|
+
if (inBlock) {
|
|
871
|
+
if (ch === "*" && next === "/") {
|
|
872
|
+
inBlock = false;
|
|
873
|
+
i++;
|
|
874
|
+
}
|
|
875
|
+
continue;
|
|
876
|
+
}
|
|
877
|
+
if (inString) {
|
|
878
|
+
out += ch;
|
|
879
|
+
if (ch === "\\") {
|
|
880
|
+
out += next ?? "";
|
|
881
|
+
i++;
|
|
882
|
+
} else if (ch === "\"") inString = false;
|
|
883
|
+
continue;
|
|
884
|
+
}
|
|
885
|
+
if (ch === "\"") {
|
|
886
|
+
inString = true;
|
|
887
|
+
out += ch;
|
|
888
|
+
continue;
|
|
889
|
+
}
|
|
890
|
+
if (ch === "/" && next === "/") {
|
|
891
|
+
inLine = true;
|
|
892
|
+
i++;
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
895
|
+
if (ch === "/" && next === "*") {
|
|
896
|
+
inBlock = true;
|
|
897
|
+
i++;
|
|
898
|
+
continue;
|
|
899
|
+
}
|
|
900
|
+
out += ch;
|
|
901
|
+
}
|
|
902
|
+
return out.replace(/,(\s*[}\]])/g, "$1");
|
|
903
|
+
}
|
|
904
|
+
function readConfig(path$1) {
|
|
905
|
+
let raw;
|
|
906
|
+
try {
|
|
907
|
+
raw = (0, fs.readFileSync)(path$1, "utf-8");
|
|
908
|
+
} catch {
|
|
909
|
+
return null;
|
|
910
|
+
}
|
|
911
|
+
try {
|
|
912
|
+
const json = JSON.parse(stripJsonc(raw));
|
|
913
|
+
return {
|
|
914
|
+
dir: (0, path.dirname)(path$1),
|
|
915
|
+
compilerOptions: json.compilerOptions ?? {},
|
|
916
|
+
extends: json.extends
|
|
917
|
+
};
|
|
918
|
+
} catch {
|
|
919
|
+
return null;
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
function resolveExtendsTarget(specifier, fromDir) {
|
|
923
|
+
if (specifier.startsWith(".") || (0, path.isAbsolute)(specifier)) {
|
|
924
|
+
const base = (0, path.resolve)(fromDir, specifier);
|
|
925
|
+
for (const candidate of [
|
|
926
|
+
base,
|
|
927
|
+
`${base}.json`,
|
|
928
|
+
(0, path.join)(base, "tsconfig.json")
|
|
929
|
+
]) if ((0, fs.existsSync)(candidate)) return candidate;
|
|
930
|
+
return null;
|
|
931
|
+
}
|
|
932
|
+
try {
|
|
933
|
+
return require.resolve(specifier.endsWith(".json") ? specifier : `${specifier}/tsconfig.json`, { paths: [fromDir] });
|
|
934
|
+
} catch {
|
|
935
|
+
try {
|
|
936
|
+
return require.resolve(specifier, { paths: [fromDir] });
|
|
937
|
+
} catch {
|
|
938
|
+
return null;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
/** Child-first flattened extends chain starting at `entryPath`. */
|
|
943
|
+
function loadChain(entryPath) {
|
|
944
|
+
const chain = [];
|
|
945
|
+
const visited = /* @__PURE__ */ new Set();
|
|
946
|
+
const queue = [entryPath];
|
|
947
|
+
while (queue.length > 0) {
|
|
948
|
+
const key = (0, path.resolve)(queue.shift());
|
|
949
|
+
if (visited.has(key)) continue;
|
|
950
|
+
visited.add(key);
|
|
951
|
+
const node = readConfig(key);
|
|
952
|
+
if (!node) continue;
|
|
953
|
+
chain.push(node);
|
|
954
|
+
const parents = Array.isArray(node.extends) ? node.extends : node.extends !== void 0 ? [node.extends] : [];
|
|
955
|
+
for (const parent of parents) {
|
|
956
|
+
if (typeof parent !== "string") continue;
|
|
957
|
+
const resolved = resolveExtendsTarget(parent, node.dir);
|
|
958
|
+
if (resolved) queue.push(resolved);
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
return chain;
|
|
962
|
+
}
|
|
963
|
+
/**
|
|
964
|
+
* Read the project's tsconfig path aliases as pairs consumable by
|
|
965
|
+
* `buildPathAliasesJson`. Returns an empty array when no readable tsconfig
|
|
966
|
+
* (or no usable `paths`) exists.
|
|
967
|
+
*/
|
|
968
|
+
function readTsconfigAliasPairs(rootDir) {
|
|
969
|
+
const chain = loadChain((0, path.join)(rootDir, "tsconfig.json"));
|
|
970
|
+
if (chain.length === 0) return [];
|
|
971
|
+
const pathsOwner = chain.find((node) => node.compilerOptions.paths && typeof node.compilerOptions.paths === "object");
|
|
972
|
+
if (!pathsOwner) return [];
|
|
973
|
+
const paths = pathsOwner.compilerOptions.paths;
|
|
974
|
+
const baseOwner = chain.find((node) => typeof node.compilerOptions.baseUrl === "string");
|
|
975
|
+
const base = baseOwner ? (0, path.resolve)(baseOwner.dir, baseOwner.compilerOptions.baseUrl) : pathsOwner.dir;
|
|
976
|
+
const pairs = [];
|
|
977
|
+
for (const [pattern, targets] of Object.entries(paths)) {
|
|
978
|
+
const target = Array.isArray(targets) ? targets[0] : void 0;
|
|
979
|
+
if (typeof target !== "string") continue;
|
|
980
|
+
const patternStars = pattern.split("*").length - 1;
|
|
981
|
+
const targetStars = target.split("*").length - 1;
|
|
982
|
+
if (pattern === "*" || patternStars > 1 || targetStars > 1) continue;
|
|
983
|
+
if (pattern.endsWith("/*")) {
|
|
984
|
+
if (!target.endsWith("/*")) continue;
|
|
985
|
+
pairs.push({
|
|
986
|
+
pattern: pattern.slice(0, -2),
|
|
987
|
+
target: (0, path.resolve)(base, target.slice(0, -2)),
|
|
988
|
+
kind: "prefix"
|
|
989
|
+
});
|
|
990
|
+
continue;
|
|
991
|
+
}
|
|
992
|
+
if (patternStars > 0 || targetStars > 0) continue;
|
|
993
|
+
pairs.push({
|
|
994
|
+
pattern,
|
|
995
|
+
target: (0, path.resolve)(base, target),
|
|
996
|
+
kind: "exact"
|
|
997
|
+
});
|
|
998
|
+
}
|
|
999
|
+
return pairs;
|
|
1000
|
+
}
|
|
1001
|
+
//#endregion
|
|
137
1002
|
//#region pipeline/mdx-preprocessor.ts
|
|
138
1003
|
/**
|
|
139
1004
|
* MDX source preprocessor for the extraction pipeline.
|
|
@@ -191,203 +1056,86 @@ async function preprocessMdx(source, filename) {
|
|
|
191
1056
|
}
|
|
192
1057
|
}
|
|
193
1058
|
//#endregion
|
|
194
|
-
//#region pipeline/prefix.ts
|
|
195
|
-
/**
|
|
196
|
-
* Apply namespace prefix to a variable map, CSS variable declarations, and theme JSON.
|
|
197
|
-
*
|
|
198
|
-
* Variable map: `{ "colors.ember": "--color-ember" }` -> `{ "colors.ember": "--prefix-color-ember" }`
|
|
199
|
-
* Variable CSS: `--color-ember: #FF2800` -> `--prefix-color-ember: #FF2800`
|
|
200
|
-
* `var(--color-ember)` -> `var(--prefix-color-ember)`
|
|
201
|
-
* Theme JSON: `{ "colors.ember": "var(--color-ember)" }` -> `{ "colors.ember": "var(--prefix-color-ember)" }`
|
|
202
|
-
*/
|
|
203
|
-
function applyPrefix(prefix, variableMapJson, variableCss, themeJson, contextualVarsJson) {
|
|
204
|
-
if (!prefix) return {
|
|
205
|
-
variableMapJson,
|
|
206
|
-
variableCss,
|
|
207
|
-
themeJson,
|
|
208
|
-
contextualVarsJson
|
|
209
|
-
};
|
|
210
|
-
const varRefRe = /var\(--([a-zA-Z][\w-]*)\)/g;
|
|
211
|
-
const map = JSON.parse(variableMapJson);
|
|
212
|
-
const prefixed = {};
|
|
213
|
-
for (const [key, varName] of Object.entries(map)) prefixed[key] = varName.startsWith("--") ? `--${prefix}-${varName.slice(2)}` : varName;
|
|
214
|
-
let css = variableCss;
|
|
215
|
-
css = css.replace(/--([a-zA-Z][\w-]*)\s*:/g, `--${prefix}-$1:`);
|
|
216
|
-
css = css.replace(varRefRe, `var(--${prefix}-$1)`);
|
|
217
|
-
const result = {
|
|
218
|
-
variableMapJson: JSON.stringify(prefixed),
|
|
219
|
-
variableCss: css
|
|
220
|
-
};
|
|
221
|
-
if (themeJson) result.themeJson = themeJson.replace(varRefRe, `var(--${prefix}-$1)`);
|
|
222
|
-
if (contextualVarsJson) {
|
|
223
|
-
const ctxVars = JSON.parse(contextualVarsJson);
|
|
224
|
-
const prefixedCtx = {};
|
|
225
|
-
for (const [scale, names] of Object.entries(ctxVars)) prefixedCtx[scale] = names.map((name) => `${prefix}-${name}`);
|
|
226
|
-
result.contextualVarsJson = JSON.stringify(prefixedCtx);
|
|
227
|
-
}
|
|
228
|
-
return result;
|
|
229
|
-
}
|
|
230
|
-
//#endregion
|
|
231
1059
|
//#region pipeline/utils.ts
|
|
232
1060
|
/** Convert camelCase CSS property names to kebab-case. */
|
|
233
1061
|
function camelToKebab(str) {
|
|
234
1062
|
return str.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
235
1063
|
}
|
|
236
1064
|
//#endregion
|
|
237
|
-
//#region pipeline/
|
|
238
|
-
/**
|
|
239
|
-
* Resolve {scale.path} and {scale.path/alpha} token aliases in a CSS value string.
|
|
240
|
-
* Mirrors the Rust theme_resolver's resolve_token_aliases logic.
|
|
241
|
-
*/
|
|
242
|
-
function resolveTokenAliases(value, flat, variableMap) {
|
|
243
|
-
if (!value.includes("{")) return value;
|
|
244
|
-
return value.replace(/\{([^}]+)\}/g, (_match, content) => {
|
|
245
|
-
const slashIdx = content.indexOf("/");
|
|
246
|
-
const tokenPath = slashIdx >= 0 ? content.slice(0, slashIdx) : content;
|
|
247
|
-
const alpha = slashIdx >= 0 ? Number.parseInt(content.slice(slashIdx + 1), 10) : null;
|
|
248
|
-
const flatKey = tokenPath;
|
|
249
|
-
let resolved;
|
|
250
|
-
if (variableMap[flatKey]) resolved = `var(${variableMap[flatKey]})`;
|
|
251
|
-
else if (flat[flatKey] != null) resolved = flat[flatKey];
|
|
252
|
-
else return `{${content}}`;
|
|
253
|
-
if (alpha === 0) return "transparent";
|
|
254
|
-
if (alpha != null && alpha !== 100) return `color-mix(in srgb, ${resolved} ${alpha}%, transparent)`;
|
|
255
|
-
return resolved;
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Resolve a single CSS value through prop config: scale lookup, transform, token aliases.
|
|
260
|
-
*/
|
|
261
|
-
function resolveValue(raw, config, flat, variableMap, transforms) {
|
|
262
|
-
let resolved = String(raw);
|
|
263
|
-
if (config?.scale) {
|
|
264
|
-
const key = config.scale + "." + raw;
|
|
265
|
-
if (flat[key] != null) resolved = flat[key];
|
|
266
|
-
}
|
|
267
|
-
if (config?.transform && transforms[config.transform]) {
|
|
268
|
-
const fn = transforms[config.transform];
|
|
269
|
-
const input = typeof resolved === "string" && !Number.isNaN(Number(resolved)) ? Number(resolved) : resolved;
|
|
270
|
-
resolved = String(fn(input));
|
|
271
|
-
}
|
|
272
|
-
return resolveTokenAliases(resolved, flat, variableMap);
|
|
273
|
-
}
|
|
274
|
-
/**
|
|
275
|
-
* Resolve a block of selectors -> style objects using prop config + theme.
|
|
276
|
-
* @keyframes selectors are resolved with full prop config support.
|
|
277
|
-
*/
|
|
278
|
-
function resolveBlock(selectors, propConfig, flat, variableMap, transforms) {
|
|
279
|
-
const rules = [];
|
|
280
|
-
for (const [selector, styleObj] of Object.entries(selectors)) {
|
|
281
|
-
if (selector.startsWith("@keyframes")) {
|
|
282
|
-
const frames = [];
|
|
283
|
-
for (const [pct, frameStyles] of Object.entries(styleObj)) if (typeof frameStyles === "object" && frameStyles !== null) {
|
|
284
|
-
const decls = [];
|
|
285
|
-
for (const [prop, raw] of Object.entries(frameStyles)) {
|
|
286
|
-
const cfg = propConfig[prop];
|
|
287
|
-
const cssProps = cfg?.properties?.length ? cfg.properties : cfg ? [cfg.property] : [prop];
|
|
288
|
-
const resolved = resolveValue(raw, cfg, flat, variableMap, transforms);
|
|
289
|
-
for (const cssProp of cssProps) decls.push(` ${camelToKebab(cssProp)}: ${resolved};`);
|
|
290
|
-
}
|
|
291
|
-
frames.push(` ${pct} {\n${decls.join("\n")}\n }`);
|
|
292
|
-
}
|
|
293
|
-
rules.push(`${selector} {\n${frames.join("\n")}\n}`);
|
|
294
|
-
continue;
|
|
295
|
-
}
|
|
296
|
-
const decls = [];
|
|
297
|
-
for (const [prop, raw] of Object.entries(styleObj)) {
|
|
298
|
-
const config = propConfig[prop];
|
|
299
|
-
const cssProps = config?.properties?.length ? config.properties : config ? [config.property] : [prop];
|
|
300
|
-
const resolved = resolveValue(raw, config, flat, variableMap, transforms);
|
|
301
|
-
for (const cssProp of cssProps) decls.push(` ${camelToKebab(cssProp)}: ${resolved};`);
|
|
302
|
-
}
|
|
303
|
-
if (decls.length) rules.push(`${selector} {\n${decls.join("\n")}\n}`);
|
|
304
|
-
}
|
|
305
|
-
return rules.join("\n\n");
|
|
306
|
-
}
|
|
1065
|
+
//#region pipeline/watch-keys.ts
|
|
307
1066
|
/**
|
|
308
|
-
*
|
|
1067
|
+
* Membership keys for a filesystem path in the system-dependency watch set.
|
|
309
1068
|
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
return
|
|
1069
|
+
* The loader reports symlink-resolved canonical paths; watcher events carry
|
|
1070
|
+
* lexical absolute paths that may traverse symlinks (bun workspace links) and
|
|
1071
|
+
* — for deletions — may no longer exist, so `realpathSync` on the event path
|
|
1072
|
+
* alone cannot produce the canonical form. Both insertion and lookup go
|
|
1073
|
+
* through this one normalizer: the lexical form plus a canonical form
|
|
1074
|
+
* reconstructed through the nearest existing ancestor.
|
|
1075
|
+
*/
|
|
1076
|
+
function toWatchKeys(input) {
|
|
1077
|
+
const lexical = (0, node_path.normalize)(input);
|
|
1078
|
+
const canonical = realpathThroughNearestExistingAncestor(lexical);
|
|
1079
|
+
return canonical === lexical ? [lexical] : [lexical, canonical];
|
|
321
1080
|
}
|
|
322
|
-
//#endregion
|
|
323
|
-
//#region pipeline/resolve-transforms.ts
|
|
324
1081
|
/**
|
|
325
|
-
*
|
|
1082
|
+
* Canonicalize a path that may not exist: walk up to the nearest existing
|
|
1083
|
+
* ancestor, realpath it, and re-append the missing suffix. Handles deleted
|
|
1084
|
+
* files under still-existing (possibly symlinked) directories and atomic
|
|
1085
|
+
* unlink/rename saves. Falls back to the input when no ancestor resolves.
|
|
326
1086
|
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
return css.replace(/__TRANSFORM__(\w+)__(.+?)__/g, (_, name, rawValue) => {
|
|
333
|
-
const fn = transforms[name];
|
|
334
|
-
if (!fn) return rawValue;
|
|
335
|
-
const result = fn(rawValue !== "" && !Number.isNaN(Number(rawValue)) ? Number(rawValue) : rawValue);
|
|
336
|
-
return typeof result === "object" ? JSON.stringify(result) : String(result);
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
//#endregion
|
|
340
|
-
//#region pipeline/unit-fallback.ts
|
|
341
|
-
/**
|
|
342
|
-
* Append `px` to bare numeric values in CSS declarations for properties
|
|
343
|
-
* that expect length units. Unitless properties are preserved as-is.
|
|
344
|
-
* Numbers inside CSS function calls (cubic-bezier, rgb, calc, etc.) are skipped.
|
|
1087
|
+
* Known limit: a symlink retargeted AFTER the system load canonicalizes to
|
|
1088
|
+
* the new target, which cannot match the recorded (old-target) dependency —
|
|
1089
|
+
* the membership test then fails open (no reset), identical to not having
|
|
1090
|
+
* this reconstruction at all. Retarget sensitivity is a resolution-input
|
|
1091
|
+
* concern, deliberately out of scope for the watch set.
|
|
345
1092
|
*/
|
|
346
|
-
function
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
fixed += value[i];
|
|
362
|
-
i++;
|
|
363
|
-
} else {
|
|
364
|
-
const numMatch = value.slice(i).match(/^(-?\d+\.?\d*)/);
|
|
365
|
-
if (numMatch) {
|
|
366
|
-
const num = numMatch[1];
|
|
367
|
-
const after = value[i + num.length];
|
|
368
|
-
if (after && /[a-z%]/i.test(after)) fixed += num;
|
|
369
|
-
else fixed += num + "px";
|
|
370
|
-
i += num.length;
|
|
371
|
-
} else {
|
|
372
|
-
fixed += value[i];
|
|
373
|
-
i++;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
return fixed !== value ? `${prop}:${fixed};` : match;
|
|
377
|
-
});
|
|
1093
|
+
function realpathThroughNearestExistingAncestor(path) {
|
|
1094
|
+
try {
|
|
1095
|
+
return (0, node_fs.realpathSync)(path);
|
|
1096
|
+
} catch {}
|
|
1097
|
+
const suffix = [];
|
|
1098
|
+
let current = path;
|
|
1099
|
+
for (;;) {
|
|
1100
|
+
const parent = (0, node_path.dirname)(current);
|
|
1101
|
+
if (parent === current) return path;
|
|
1102
|
+
suffix.unshift((0, node_path.basename)(current));
|
|
1103
|
+
current = parent;
|
|
1104
|
+
try {
|
|
1105
|
+
return (0, node_path.join)((0, node_fs.realpathSync)(current), ...suffix);
|
|
1106
|
+
} catch {}
|
|
1107
|
+
}
|
|
378
1108
|
}
|
|
379
1109
|
//#endregion
|
|
380
1110
|
exports.ANIMUS_LAYERS = ANIMUS_LAYERS;
|
|
381
1111
|
exports.DEFAULT_EXTENSIONS = DEFAULT_EXTENSIONS;
|
|
1112
|
+
exports.RETIRED_ENGINE_MESSAGE = RETIRED_ENGINE_MESSAGE;
|
|
382
1113
|
exports.applyPrefix = applyPrefix;
|
|
383
1114
|
exports.applyUnitFallback = applyUnitFallback;
|
|
384
1115
|
exports.assembleStylesheet = assembleStylesheet;
|
|
1116
|
+
exports.assertNoRetiredEngineSelection = assertNoRetiredEngineSelection;
|
|
1117
|
+
exports.buildAnalysisInputs = buildAnalysisInputs;
|
|
1118
|
+
exports.buildAnalyzeProjectArgs = buildAnalyzeProjectArgs;
|
|
1119
|
+
exports.buildDynamicPropConfig = buildDynamicPropConfig;
|
|
1120
|
+
exports.buildPathAliasesJson = buildPathAliasesJson;
|
|
1121
|
+
exports.buildSystemPropsModule = buildSystemPropsModule;
|
|
385
1122
|
exports.camelToKebab = camelToKebab;
|
|
1123
|
+
exports.clearEngineCache = clearEngineCache;
|
|
1124
|
+
exports.collectExternalPackageSources = collectExternalPackageSources;
|
|
1125
|
+
exports.contentHash = contentHash;
|
|
1126
|
+
exports.createV2EngineApi = createV2EngineApi;
|
|
1127
|
+
exports.discoverFiles = discoverFiles;
|
|
386
1128
|
exports.extractSystemFilePackages = extractSystemFilePackages;
|
|
1129
|
+
exports.findPackageRoot = findPackageRoot;
|
|
1130
|
+
exports.formatRustTimingWaterfall = formatRustTimingWaterfall;
|
|
1131
|
+
exports.loadSystemConfig = loadSystemConfig;
|
|
1132
|
+
exports.postProcessCss = postProcessCss;
|
|
387
1133
|
exports.preprocessMdx = preprocessMdx;
|
|
388
|
-
exports.
|
|
389
|
-
exports.
|
|
390
|
-
exports.
|
|
391
|
-
exports.
|
|
1134
|
+
exports.readTsconfigAliasPairs = readTsconfigAliasPairs;
|
|
1135
|
+
exports.resolveLightningTargets = resolveLightningTargets;
|
|
1136
|
+
exports.runProjectAnalysis = runProjectAnalysis;
|
|
1137
|
+
exports.serializeStaticCss = serializeStaticCss;
|
|
392
1138
|
exports.stripLeadingLayerDeclaration = stripLeadingLayerDeclaration;
|
|
1139
|
+
exports.surfaceManifestDiagnostics = surfaceManifestDiagnostics;
|
|
1140
|
+
exports.toWatchKeys = toWatchKeys;
|
|
393
1141
|
exports.validateLayerOrder = validateLayerOrder;
|