@bamboocss/extractor 1.17.2 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +146 -53
- package/dist/index.mjs +146 -53
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -306,76 +306,169 @@ const box = {
|
|
|
306
306
|
}
|
|
307
307
|
};
|
|
308
308
|
//#endregion
|
|
309
|
-
//#region src/
|
|
310
|
-
|
|
311
|
-
|
|
309
|
+
//#region src/resolve-imported-value.ts
|
|
310
|
+
/**
|
|
311
|
+
* The values an expression borrows from other modules, resolved by reading the imports.
|
|
312
|
+
*
|
|
313
|
+
* A call to a helper in a neighbouring file has to resolve, or its declarations are silently
|
|
314
|
+
* absent from the stylesheet — and for a recipe that is not a partial loss but a different
|
|
315
|
+
* hash and an element with no styles at all.
|
|
316
|
+
*
|
|
317
|
+
* The evaluator can be handed a TypeScript type checker to follow the import itself, and was
|
|
318
|
+
* for a while. That is far more than the job needs: asking for one symbol makes TypeScript
|
|
319
|
+
* bind and check the whole program, every reachable `.d.ts` included. Measured on a 400-file
|
|
320
|
+
* project it cost **+38% CPU and +30% peak RSS**, and because the expense is the checker
|
|
321
|
+
* existing rather than how often it is consulted, it grows with the size of the codebase
|
|
322
|
+
* rather than with the number of style calls — a large project reported a 5.4x extraction
|
|
323
|
+
* slowdown and an OOM in CI.
|
|
324
|
+
*
|
|
325
|
+
* Following an import is two cheap steps this package already had: resolve the specifier to
|
|
326
|
+
* a file (`ts.resolveModuleName`, path lookup, no checker), then read that file's exported
|
|
327
|
+
* declaration. Crossing the import boundary is the only thing the checker was doing here.
|
|
328
|
+
*
|
|
329
|
+
* The evaluator resolves everything *within* a module by walking scopes, so a helper that
|
|
330
|
+
* refers to another binding in its own file needs nothing from us.
|
|
331
|
+
*/
|
|
332
|
+
/** How far a chain of helpers importing helpers is followed. */
|
|
333
|
+
const MAX_DEPTH = 4;
|
|
334
|
+
/** Evaluated once per declaration, however many call sites reach it. */
|
|
335
|
+
const evaluatedValues = /* @__PURE__ */ new WeakMap();
|
|
312
336
|
/**
|
|
313
|
-
*
|
|
337
|
+
* Local name to the name and declaration it was imported from.
|
|
314
338
|
*
|
|
315
|
-
*
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
*
|
|
319
|
-
*
|
|
339
|
+
* Deliberately not cached per file. The nodes are invalidated whenever a file is reloaded —
|
|
340
|
+
* a watch rebuild does exactly that — and a cache holding them hands back nodes ts-morph has
|
|
341
|
+
* forgotten, which throws rather than merely going stale. Rebuilding is a syntactic walk of
|
|
342
|
+
* the import statements, and it only happens for an expression that already failed to
|
|
343
|
+
* evaluate, so it is not on the ordinary path.
|
|
344
|
+
*/
|
|
345
|
+
const importBindingsFor = (sourceFile) => {
|
|
346
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
347
|
+
for (const declaration of sourceFile.getImportDeclarations()) {
|
|
348
|
+
for (const specifier of declaration.getNamedImports()) {
|
|
349
|
+
const local = (specifier.getAliasNode() ?? specifier.getNameNode()).getText();
|
|
350
|
+
bindings.set(local, {
|
|
351
|
+
declaration,
|
|
352
|
+
exportedName: specifier.getNameNode().getText()
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
const defaultImport = declaration.getDefaultImport();
|
|
356
|
+
if (defaultImport) bindings.set(defaultImport.getText(), {
|
|
357
|
+
declaration,
|
|
358
|
+
exportedName: "default"
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
return bindings;
|
|
362
|
+
};
|
|
363
|
+
/** What an imported name refers to, or nothing if it cannot be reached safely. */
|
|
364
|
+
const valueForBinding = (binding, ctx, stack, depth, evaluateExpression) => {
|
|
365
|
+
const sourceFile = getModuleSpecifierSourceFile(binding.declaration);
|
|
366
|
+
if (!sourceFile) return;
|
|
367
|
+
if (sourceFile.isInNodeModules()) return;
|
|
368
|
+
const declaration = getExportedVarDeclarationWithName(binding.exportedName, sourceFile, stack, ctx);
|
|
369
|
+
if (!declaration) return;
|
|
370
|
+
if (evaluatedValues.has(declaration)) return { value: evaluatedValues.get(declaration) };
|
|
371
|
+
const initializer = declaration.getInitializer();
|
|
372
|
+
if (!initializer) return;
|
|
373
|
+
const value = evaluateExpression(initializer, stack, ctx, depth + 1);
|
|
374
|
+
if (value === void 0) return;
|
|
375
|
+
evaluatedValues.set(declaration, value);
|
|
376
|
+
return { value };
|
|
377
|
+
};
|
|
378
|
+
/**
|
|
379
|
+
* Bindings for the names this expression takes from other modules, or nothing if it takes
|
|
380
|
+
* none that can be reached.
|
|
320
381
|
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
382
|
+
* Called only after an evaluation has already failed. Everything that resolves today does so
|
|
383
|
+
* without this, and an expression that reaches an unresolvable import used to be dropped
|
|
384
|
+
* outright — so nothing that works pays for it, and nothing that pays for it was working.
|
|
324
385
|
*/
|
|
325
|
-
const
|
|
326
|
-
if (
|
|
327
|
-
const
|
|
328
|
-
if (
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
386
|
+
const importedEnvironmentFor = (node, ctx, stack, depth, evaluateExpression) => {
|
|
387
|
+
if (depth >= MAX_DEPTH) return;
|
|
388
|
+
const calls = node.getDescendantsOfKind(ts_morph.SyntaxKind.CallExpression);
|
|
389
|
+
if (ts_morph.Node.isCallExpression(node)) calls.unshift(node);
|
|
390
|
+
if (!calls.length) return;
|
|
391
|
+
const bindings = importBindingsFor(node.getSourceFile());
|
|
392
|
+
if (!bindings.size) return;
|
|
393
|
+
let environment;
|
|
394
|
+
for (const call of calls) {
|
|
395
|
+
const callee = call.getExpression();
|
|
396
|
+
const binding = bindings.get(callee.getText());
|
|
397
|
+
if (!binding || environment?.[callee.getText()] !== void 0) continue;
|
|
398
|
+
const resolved = valueForBinding(binding, ctx, stack, depth, evaluateExpression);
|
|
399
|
+
if (!resolved) continue;
|
|
400
|
+
environment ??= {};
|
|
401
|
+
environment[callee.getText()] = resolved.value;
|
|
402
|
+
}
|
|
403
|
+
return environment;
|
|
332
404
|
};
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
const
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
405
|
+
//#endregion
|
|
406
|
+
//#region src/evaluate-node.ts
|
|
407
|
+
const TsEvalError = Symbol("EvalError");
|
|
408
|
+
const cacheMap$2 = /* @__PURE__ */ new WeakMap();
|
|
409
|
+
/** @see https://github.com/wessberg/ts-evaluator#setting-up-policies */
|
|
410
|
+
const POLICY = {
|
|
411
|
+
console: false,
|
|
412
|
+
deterministic: true,
|
|
413
|
+
io: {
|
|
414
|
+
read: true,
|
|
415
|
+
write: false
|
|
416
|
+
},
|
|
417
|
+
maxOpDuration: 1e3,
|
|
418
|
+
maxOps: Number.POSITIVE_INFINITY,
|
|
419
|
+
network: false,
|
|
420
|
+
process: {
|
|
421
|
+
exit: false,
|
|
422
|
+
spawnChild: false
|
|
341
423
|
}
|
|
342
|
-
return checker;
|
|
343
424
|
};
|
|
344
425
|
/**
|
|
345
|
-
* Evaluates a node with strict
|
|
346
|
-
*
|
|
426
|
+
* Evaluates a node with strict policy restrictions.
|
|
427
|
+
*
|
|
428
|
+
* No type checker is passed. The evaluator accepts one, and it is the obvious way to let a
|
|
429
|
+
* call reach a helper in another module — but asking TypeScript for a single symbol makes it
|
|
430
|
+
* bind and check the entire program, `.d.ts` files included. That cost is paid by every
|
|
431
|
+
* project on every build, scales with the size of the codebase rather than with the number
|
|
432
|
+
* of style calls, and does not show up in a benchmark small enough to have no program to
|
|
433
|
+
* check. See `resolve-imported-value.ts`, which crosses the import boundary directly for the
|
|
434
|
+
* few expressions that need it.
|
|
347
435
|
*/
|
|
348
|
-
const evaluateNode = (node, stack, ctx) => {
|
|
436
|
+
const evaluateNode = (node, stack, ctx, depth = 0) => {
|
|
349
437
|
if (ctx.flags?.skipEvaluate) return;
|
|
350
438
|
if (ctx.canEval && !ctx.canEval?.(node, stack)) return;
|
|
351
|
-
if (cacheMap$2.has(node)) return cacheMap$2.get(node);
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
policy: {
|
|
355
|
-
deterministic: true,
|
|
356
|
-
network: false,
|
|
357
|
-
console: false,
|
|
358
|
-
maxOps: Number.POSITIVE_INFINITY,
|
|
359
|
-
maxOpDuration: 1e3,
|
|
360
|
-
io: {
|
|
361
|
-
read: true,
|
|
362
|
-
write: false
|
|
363
|
-
},
|
|
364
|
-
process: {
|
|
365
|
-
exit: false,
|
|
366
|
-
spawnChild: false
|
|
367
|
-
}
|
|
368
|
-
},
|
|
439
|
+
if (depth === 0 && cacheMap$2.has(node)) return cacheMap$2.get(node);
|
|
440
|
+
const options = {
|
|
441
|
+
policy: { ...POLICY },
|
|
369
442
|
...ctx.getEvaluateOptions?.(node, stack),
|
|
370
443
|
node: node.compilerNode,
|
|
371
444
|
typescript: ts_morph.ts
|
|
372
|
-
}
|
|
445
|
+
};
|
|
446
|
+
let result = (0, ts_evaluator.evaluate)(options);
|
|
447
|
+
/**
|
|
448
|
+
* Retried only on failure, with whatever this expression imports put in scope.
|
|
449
|
+
*
|
|
450
|
+
* The order matters for cost. Everything that resolves today does so on the first attempt,
|
|
451
|
+
* so no working call pays anything for this — and an expression that reaches an
|
|
452
|
+
* unresolvable import was dropped outright before, so nothing that pays for it was
|
|
453
|
+
* working. Resolving imports up front instead would put a walk of every style object on
|
|
454
|
+
* the path of every build.
|
|
455
|
+
*/
|
|
456
|
+
if (!result.success) {
|
|
457
|
+
const imported = importedEnvironmentFor(node, ctx, stack, depth, safeEvaluateNode);
|
|
458
|
+
if (imported) result = (0, ts_evaluator.evaluate)({
|
|
459
|
+
...options,
|
|
460
|
+
environment: {
|
|
461
|
+
...options.environment,
|
|
462
|
+
extra: imported
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
}
|
|
373
466
|
const expr = result.success ? result.value : TsEvalError;
|
|
374
|
-
cacheMap$2.set(node, expr);
|
|
467
|
+
if (depth === 0) cacheMap$2.set(node, expr);
|
|
375
468
|
return expr;
|
|
376
469
|
};
|
|
377
|
-
const safeEvaluateNode = (node, stack, ctx) => {
|
|
378
|
-
const result = evaluateNode(node, stack, ctx);
|
|
470
|
+
const safeEvaluateNode = (node, stack, ctx, depth = 0) => {
|
|
471
|
+
const result = evaluateNode(node, stack, ctx, depth);
|
|
379
472
|
if (result === TsEvalError) return;
|
|
380
473
|
return result;
|
|
381
474
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -305,76 +305,169 @@ const box = {
|
|
|
305
305
|
}
|
|
306
306
|
};
|
|
307
307
|
//#endregion
|
|
308
|
-
//#region src/
|
|
309
|
-
|
|
310
|
-
|
|
308
|
+
//#region src/resolve-imported-value.ts
|
|
309
|
+
/**
|
|
310
|
+
* The values an expression borrows from other modules, resolved by reading the imports.
|
|
311
|
+
*
|
|
312
|
+
* A call to a helper in a neighbouring file has to resolve, or its declarations are silently
|
|
313
|
+
* absent from the stylesheet — and for a recipe that is not a partial loss but a different
|
|
314
|
+
* hash and an element with no styles at all.
|
|
315
|
+
*
|
|
316
|
+
* The evaluator can be handed a TypeScript type checker to follow the import itself, and was
|
|
317
|
+
* for a while. That is far more than the job needs: asking for one symbol makes TypeScript
|
|
318
|
+
* bind and check the whole program, every reachable `.d.ts` included. Measured on a 400-file
|
|
319
|
+
* project it cost **+38% CPU and +30% peak RSS**, and because the expense is the checker
|
|
320
|
+
* existing rather than how often it is consulted, it grows with the size of the codebase
|
|
321
|
+
* rather than with the number of style calls — a large project reported a 5.4x extraction
|
|
322
|
+
* slowdown and an OOM in CI.
|
|
323
|
+
*
|
|
324
|
+
* Following an import is two cheap steps this package already had: resolve the specifier to
|
|
325
|
+
* a file (`ts.resolveModuleName`, path lookup, no checker), then read that file's exported
|
|
326
|
+
* declaration. Crossing the import boundary is the only thing the checker was doing here.
|
|
327
|
+
*
|
|
328
|
+
* The evaluator resolves everything *within* a module by walking scopes, so a helper that
|
|
329
|
+
* refers to another binding in its own file needs nothing from us.
|
|
330
|
+
*/
|
|
331
|
+
/** How far a chain of helpers importing helpers is followed. */
|
|
332
|
+
const MAX_DEPTH = 4;
|
|
333
|
+
/** Evaluated once per declaration, however many call sites reach it. */
|
|
334
|
+
const evaluatedValues = /* @__PURE__ */ new WeakMap();
|
|
311
335
|
/**
|
|
312
|
-
*
|
|
336
|
+
* Local name to the name and declaration it was imported from.
|
|
313
337
|
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
*
|
|
338
|
+
* Deliberately not cached per file. The nodes are invalidated whenever a file is reloaded —
|
|
339
|
+
* a watch rebuild does exactly that — and a cache holding them hands back nodes ts-morph has
|
|
340
|
+
* forgotten, which throws rather than merely going stale. Rebuilding is a syntactic walk of
|
|
341
|
+
* the import statements, and it only happens for an expression that already failed to
|
|
342
|
+
* evaluate, so it is not on the ordinary path.
|
|
343
|
+
*/
|
|
344
|
+
const importBindingsFor = (sourceFile) => {
|
|
345
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
346
|
+
for (const declaration of sourceFile.getImportDeclarations()) {
|
|
347
|
+
for (const specifier of declaration.getNamedImports()) {
|
|
348
|
+
const local = (specifier.getAliasNode() ?? specifier.getNameNode()).getText();
|
|
349
|
+
bindings.set(local, {
|
|
350
|
+
declaration,
|
|
351
|
+
exportedName: specifier.getNameNode().getText()
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
const defaultImport = declaration.getDefaultImport();
|
|
355
|
+
if (defaultImport) bindings.set(defaultImport.getText(), {
|
|
356
|
+
declaration,
|
|
357
|
+
exportedName: "default"
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
return bindings;
|
|
361
|
+
};
|
|
362
|
+
/** What an imported name refers to, or nothing if it cannot be reached safely. */
|
|
363
|
+
const valueForBinding = (binding, ctx, stack, depth, evaluateExpression) => {
|
|
364
|
+
const sourceFile = getModuleSpecifierSourceFile(binding.declaration);
|
|
365
|
+
if (!sourceFile) return;
|
|
366
|
+
if (sourceFile.isInNodeModules()) return;
|
|
367
|
+
const declaration = getExportedVarDeclarationWithName(binding.exportedName, sourceFile, stack, ctx);
|
|
368
|
+
if (!declaration) return;
|
|
369
|
+
if (evaluatedValues.has(declaration)) return { value: evaluatedValues.get(declaration) };
|
|
370
|
+
const initializer = declaration.getInitializer();
|
|
371
|
+
if (!initializer) return;
|
|
372
|
+
const value = evaluateExpression(initializer, stack, ctx, depth + 1);
|
|
373
|
+
if (value === void 0) return;
|
|
374
|
+
evaluatedValues.set(declaration, value);
|
|
375
|
+
return { value };
|
|
376
|
+
};
|
|
377
|
+
/**
|
|
378
|
+
* Bindings for the names this expression takes from other modules, or nothing if it takes
|
|
379
|
+
* none that can be reached.
|
|
319
380
|
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
381
|
+
* Called only after an evaluation has already failed. Everything that resolves today does so
|
|
382
|
+
* without this, and an expression that reaches an unresolvable import used to be dropped
|
|
383
|
+
* outright — so nothing that works pays for it, and nothing that pays for it was working.
|
|
323
384
|
*/
|
|
324
|
-
const
|
|
325
|
-
if (
|
|
326
|
-
const
|
|
327
|
-
if (
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
385
|
+
const importedEnvironmentFor = (node, ctx, stack, depth, evaluateExpression) => {
|
|
386
|
+
if (depth >= MAX_DEPTH) return;
|
|
387
|
+
const calls = node.getDescendantsOfKind(SyntaxKind.CallExpression);
|
|
388
|
+
if (Node.isCallExpression(node)) calls.unshift(node);
|
|
389
|
+
if (!calls.length) return;
|
|
390
|
+
const bindings = importBindingsFor(node.getSourceFile());
|
|
391
|
+
if (!bindings.size) return;
|
|
392
|
+
let environment;
|
|
393
|
+
for (const call of calls) {
|
|
394
|
+
const callee = call.getExpression();
|
|
395
|
+
const binding = bindings.get(callee.getText());
|
|
396
|
+
if (!binding || environment?.[callee.getText()] !== void 0) continue;
|
|
397
|
+
const resolved = valueForBinding(binding, ctx, stack, depth, evaluateExpression);
|
|
398
|
+
if (!resolved) continue;
|
|
399
|
+
environment ??= {};
|
|
400
|
+
environment[callee.getText()] = resolved.value;
|
|
401
|
+
}
|
|
402
|
+
return environment;
|
|
331
403
|
};
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
404
|
+
//#endregion
|
|
405
|
+
//#region src/evaluate-node.ts
|
|
406
|
+
const TsEvalError = Symbol("EvalError");
|
|
407
|
+
const cacheMap$2 = /* @__PURE__ */ new WeakMap();
|
|
408
|
+
/** @see https://github.com/wessberg/ts-evaluator#setting-up-policies */
|
|
409
|
+
const POLICY = {
|
|
410
|
+
console: false,
|
|
411
|
+
deterministic: true,
|
|
412
|
+
io: {
|
|
413
|
+
read: true,
|
|
414
|
+
write: false
|
|
415
|
+
},
|
|
416
|
+
maxOpDuration: 1e3,
|
|
417
|
+
maxOps: Number.POSITIVE_INFINITY,
|
|
418
|
+
network: false,
|
|
419
|
+
process: {
|
|
420
|
+
exit: false,
|
|
421
|
+
spawnChild: false
|
|
340
422
|
}
|
|
341
|
-
return checker;
|
|
342
423
|
};
|
|
343
424
|
/**
|
|
344
|
-
* Evaluates a node with strict
|
|
345
|
-
*
|
|
425
|
+
* Evaluates a node with strict policy restrictions.
|
|
426
|
+
*
|
|
427
|
+
* No type checker is passed. The evaluator accepts one, and it is the obvious way to let a
|
|
428
|
+
* call reach a helper in another module — but asking TypeScript for a single symbol makes it
|
|
429
|
+
* bind and check the entire program, `.d.ts` files included. That cost is paid by every
|
|
430
|
+
* project on every build, scales with the size of the codebase rather than with the number
|
|
431
|
+
* of style calls, and does not show up in a benchmark small enough to have no program to
|
|
432
|
+
* check. See `resolve-imported-value.ts`, which crosses the import boundary directly for the
|
|
433
|
+
* few expressions that need it.
|
|
346
434
|
*/
|
|
347
|
-
const evaluateNode = (node, stack, ctx) => {
|
|
435
|
+
const evaluateNode = (node, stack, ctx, depth = 0) => {
|
|
348
436
|
if (ctx.flags?.skipEvaluate) return;
|
|
349
437
|
if (ctx.canEval && !ctx.canEval?.(node, stack)) return;
|
|
350
|
-
if (cacheMap$2.has(node)) return cacheMap$2.get(node);
|
|
351
|
-
const
|
|
352
|
-
|
|
353
|
-
policy: {
|
|
354
|
-
deterministic: true,
|
|
355
|
-
network: false,
|
|
356
|
-
console: false,
|
|
357
|
-
maxOps: Number.POSITIVE_INFINITY,
|
|
358
|
-
maxOpDuration: 1e3,
|
|
359
|
-
io: {
|
|
360
|
-
read: true,
|
|
361
|
-
write: false
|
|
362
|
-
},
|
|
363
|
-
process: {
|
|
364
|
-
exit: false,
|
|
365
|
-
spawnChild: false
|
|
366
|
-
}
|
|
367
|
-
},
|
|
438
|
+
if (depth === 0 && cacheMap$2.has(node)) return cacheMap$2.get(node);
|
|
439
|
+
const options = {
|
|
440
|
+
policy: { ...POLICY },
|
|
368
441
|
...ctx.getEvaluateOptions?.(node, stack),
|
|
369
442
|
node: node.compilerNode,
|
|
370
443
|
typescript: ts
|
|
371
|
-
}
|
|
444
|
+
};
|
|
445
|
+
let result = evaluate(options);
|
|
446
|
+
/**
|
|
447
|
+
* Retried only on failure, with whatever this expression imports put in scope.
|
|
448
|
+
*
|
|
449
|
+
* The order matters for cost. Everything that resolves today does so on the first attempt,
|
|
450
|
+
* so no working call pays anything for this — and an expression that reaches an
|
|
451
|
+
* unresolvable import was dropped outright before, so nothing that pays for it was
|
|
452
|
+
* working. Resolving imports up front instead would put a walk of every style object on
|
|
453
|
+
* the path of every build.
|
|
454
|
+
*/
|
|
455
|
+
if (!result.success) {
|
|
456
|
+
const imported = importedEnvironmentFor(node, ctx, stack, depth, safeEvaluateNode);
|
|
457
|
+
if (imported) result = evaluate({
|
|
458
|
+
...options,
|
|
459
|
+
environment: {
|
|
460
|
+
...options.environment,
|
|
461
|
+
extra: imported
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
}
|
|
372
465
|
const expr = result.success ? result.value : TsEvalError;
|
|
373
|
-
cacheMap$2.set(node, expr);
|
|
466
|
+
if (depth === 0) cacheMap$2.set(node, expr);
|
|
374
467
|
return expr;
|
|
375
468
|
};
|
|
376
|
-
const safeEvaluateNode = (node, stack, ctx) => {
|
|
377
|
-
const result = evaluateNode(node, stack, ctx);
|
|
469
|
+
const safeEvaluateNode = (node, stack, ctx, depth = 0) => {
|
|
470
|
+
const result = evaluateNode(node, stack, ctx, depth);
|
|
378
471
|
if (result === TsEvalError) return;
|
|
379
472
|
return result;
|
|
380
473
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bamboocss/extractor",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
4
4
|
"description": "The css extractor for css bamboo",
|
|
5
5
|
"homepage": "https://bamboocss.com",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"ts-evaluator": "1.2.0",
|
|
37
37
|
"ts-morph": "28.0.0",
|
|
38
|
-
"@bamboocss/shared": "1.
|
|
38
|
+
"@bamboocss/shared": "1.18.0"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "tsdown src/index.ts --format=cjs,esm --shims --dts",
|