@unocss/core 0.50.8 → 0.51.1

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 CHANGED
@@ -2,15 +2,9 @@
2
2
 
3
3
  The core engine of [UnoCSS](https://github.com/unocss/unocss) without any presets. It can be used as the engine of your own atomic CSS framework.
4
4
 
5
- ## Usage
5
+ ## Documentation
6
6
 
7
- ```ts
8
- import { createGenerator } from '@unocss/core'
9
-
10
- const generator = createGenerator({ /* user options */ }, { /* default options */ })
11
-
12
- const { css } = await generator.generate(code)
13
- ```
7
+ Please refer to the [documentation](https://unocss.dev/tools/core).
14
8
 
15
9
  ## License
16
10
 
package/dist/index.cjs CHANGED
@@ -83,16 +83,20 @@ function entriesToCss(arr) {
83
83
  function isObject(item) {
84
84
  return item && typeof item === "object" && !Array.isArray(item);
85
85
  }
86
- function mergeDeep(original, patch) {
86
+ function mergeDeep(original, patch, mergeArray = false) {
87
87
  const o = original;
88
88
  const p = patch;
89
- if (Array.isArray(o))
90
- return [...p];
89
+ if (Array.isArray(p)) {
90
+ if (mergeArray && Array.isArray(p))
91
+ return [...o, ...p];
92
+ else
93
+ return [...p];
94
+ }
91
95
  const output = { ...o };
92
96
  if (isObject(o) && isObject(p)) {
93
97
  Object.keys(p).forEach((key) => {
94
98
  if (isObject(o[key]) && isObject(p[key]) || Array.isArray(o[key]) && Array.isArray(p[key]))
95
- output[key] = mergeDeep(o[key], p[key]);
99
+ output[key] = mergeDeep(o[key], p[key], mergeArray);
96
100
  else
97
101
  Object.assign(output, { [key]: p[key] });
98
102
  });
@@ -328,47 +332,17 @@ function createValueHandler(handlers) {
328
332
 
329
333
  const defaultSplitRE = /[\\:]?[\s'"`;{}]+/g;
330
334
  const splitWithVariantGroupRE = /([\\:]?[\s"'`;<>*]|:\(|\)"|\)\s)/g;
331
- const quotedArbitraryValuesRE = /(?:[\w&:[\]-]|\[\S+=\S+\])+\[\\?['"]?\S+?['"]\]\]?[\w:-]*/g;
332
- const arbitraryPropertyRE = /\[(\\\W|[\w-])+:[^\s:]*?("\S+?"|'\S+?'|`\S+?`|[^\s:]+?)[^\s:]*?\)?\]/g;
333
- const arbitraryPropertyCandidateRE = /^\[(\\\W|[\w-])+:['"]?\S+?['"]?\]$/;
334
335
  function splitCode(code) {
335
- const result = /* @__PURE__ */ new Set();
336
- for (const match of code.matchAll(arbitraryPropertyRE)) {
337
- if (!code[match.index - 1]?.match(/^[\s'"`]/))
338
- continue;
339
- result.add(match[0]);
340
- }
341
- for (const match of code.matchAll(quotedArbitraryValuesRE))
342
- result.add(match[0]);
343
- code.split(defaultSplitRE).forEach((match) => {
344
- if (isValidSelector(match) && !arbitraryPropertyCandidateRE.test(match))
345
- result.add(match);
346
- });
347
- return [...result];
336
+ return [...new Set(code.split(defaultSplitRE))];
348
337
  }
349
338
  const extractorSplit = {
350
- name: "split",
339
+ name: "@unocss/core/extractor-split",
351
340
  order: 0,
352
341
  extract({ code }) {
353
342
  return splitCode(code);
354
343
  }
355
344
  };
356
345
 
357
- const rightTrimRe = /=$/;
358
- const extractorSvelte = {
359
- name: "svelte",
360
- order: 0,
361
- extract({ code, id }) {
362
- let result = splitCode(code);
363
- if (id && id.endsWith(".svelte")) {
364
- result = result.map((r) => {
365
- return r.startsWith("class:") ? r.slice(6).replace(rightTrimRe, "") : r;
366
- });
367
- }
368
- return new Set(result);
369
- }
370
- };
371
-
372
346
  function createNanoEvents() {
373
347
  return {
374
348
  events: {},
@@ -398,7 +372,15 @@ function resolveShortcuts(shortcuts) {
398
372
  return Object.entries(s);
399
373
  });
400
374
  }
375
+ const __RESOLVED = "_uno_resolved";
401
376
  function resolvePreset(preset) {
377
+ if (__RESOLVED in preset)
378
+ return preset;
379
+ preset = { ...preset };
380
+ Object.defineProperty(preset, __RESOLVED, {
381
+ value: true,
382
+ enumerable: false
383
+ });
402
384
  const shortcuts = preset.shortcuts ? resolveShortcuts(preset.shortcuts) : void 0;
403
385
  preset.shortcuts = shortcuts;
404
386
  if (preset.prefix || preset.layer) {
@@ -416,9 +398,16 @@ function resolvePreset(preset) {
416
398
  }
417
399
  return preset;
418
400
  }
401
+ function resolvePresets(preset) {
402
+ const root = resolvePreset(preset);
403
+ if (!root.presets)
404
+ return [root];
405
+ const nested = (root.presets || []).flatMap(toArray).flatMap(resolvePresets);
406
+ return [root, ...nested];
407
+ }
419
408
  function resolveConfig(userConfig = {}, defaults = {}) {
420
409
  const config = Object.assign({}, defaults, userConfig);
421
- const rawPresets = (config.presets || []).flatMap(toArray).map(resolvePreset);
410
+ const rawPresets = uniq((config.presets || []).flatMap(toArray).flatMap(resolvePresets));
422
411
  const sortedPresets = [
423
412
  ...rawPresets.filter((p) => p.enforce === "pre"),
424
413
  ...rawPresets.filter((p) => !p.enforce),
@@ -432,8 +421,11 @@ function resolveConfig(userConfig = {}, defaults = {}) {
432
421
  ]);
433
422
  }
434
423
  const extractors = mergePresets("extractors");
435
- if (!extractors.length)
436
- extractors.push(extractorSplit);
424
+ let extractorDefault = [...sortedPresets, config].reverse().find((i) => i.extractorDefault !== void 0)?.extractorDefault;
425
+ if (extractorDefault === void 0)
426
+ extractorDefault = extractorSplit;
427
+ if (extractorDefault && !extractors.includes(extractorDefault))
428
+ extractors.unshift(extractorDefault);
437
429
  extractors.sort((a, b) => (a.order || 0) - (b.order || 0));
438
430
  const rules = mergePresets("rules");
439
431
  const rulesStaticMap = {};
@@ -448,11 +440,13 @@ function resolveConfig(userConfig = {}, defaults = {}) {
448
440
  }
449
441
  return [i, ...rule];
450
442
  }).filter(Boolean).reverse();
451
- const theme = clone([
443
+ let theme = clone([
452
444
  ...sortedPresets.map((p) => p.theme || {}),
453
445
  config.theme || {}
454
446
  ].reduce((a, p) => mergeDeep(a, p), {}));
455
- mergePresets("extendTheme").forEach((extendTheme) => extendTheme(theme));
447
+ const extendThemes = toArray(mergePresets("extendTheme"));
448
+ for (const extendTheme of extendThemes)
449
+ theme = extendTheme(theme) || theme;
456
450
  const autocomplete = {
457
451
  templates: uniq(sortedPresets.map((p) => toArray(p.autocomplete?.templates)).flat()),
458
452
  extractors: sortedPresets.map((p) => toArray(p.autocomplete?.extractors)).flat().sort((a, b) => (a.order || 0) - (b.order || 0))
@@ -490,7 +484,7 @@ function resolveConfig(userConfig = {}, defaults = {}) {
490
484
  return resolved;
491
485
  }
492
486
 
493
- const version = "0.50.8";
487
+ const version = "0.51.1";
494
488
 
495
489
  class UnoGenerator {
496
490
  constructor(userConfig = {}, defaults = {}) {
@@ -516,22 +510,21 @@ class UnoGenerator {
516
510
  this.config = resolveConfig(userConfig, this.defaults);
517
511
  this.events.emit("config", this.config);
518
512
  }
519
- async applyExtractors(code, id, set = /* @__PURE__ */ new Set()) {
513
+ async applyExtractors(code, id, extracted = /* @__PURE__ */ new Set()) {
520
514
  const context = {
521
- get original() {
522
- return code;
523
- },
515
+ original: code,
524
516
  code,
525
- id
517
+ id,
518
+ extracted
526
519
  };
527
520
  for (const extractor of this.config.extractors) {
528
- const result = await extractor.extract(context);
521
+ const result = await extractor.extract?.(context);
529
522
  if (result) {
530
523
  for (const token of result)
531
- set.add(token);
524
+ extracted.add(token);
532
525
  }
533
526
  }
534
- return set;
527
+ return extracted;
535
528
  }
536
529
  makeContext(raw, applied) {
537
530
  const context = {
@@ -979,7 +972,6 @@ exports.BetterMap = BetterMap;
979
972
  exports.CONTROL_SHORTCUT_NO_MERGE = CONTROL_SHORTCUT_NO_MERGE;
980
973
  exports.TwoKeyMap = TwoKeyMap;
981
974
  exports.UnoGenerator = UnoGenerator;
982
- exports.arbitraryPropertyRE = arbitraryPropertyRE;
983
975
  exports.attributifyRE = attributifyRE;
984
976
  exports.clearIdenticalEntries = clearIdenticalEntries;
985
977
  exports.clone = clone;
@@ -993,8 +985,8 @@ exports.entriesToCss = entriesToCss;
993
985
  exports.escapeRegExp = escapeRegExp;
994
986
  exports.escapeSelector = escapeSelector;
995
987
  exports.expandVariantGroup = expandVariantGroup;
988
+ exports.extractorDefault = extractorSplit;
996
989
  exports.extractorSplit = extractorSplit;
997
- exports.extractorSvelte = extractorSvelte;
998
990
  exports.hasScopePlaceholder = hasScopePlaceholder;
999
991
  exports.isAttributifySelector = isAttributifySelector;
1000
992
  exports.isObject = isObject;
@@ -1011,7 +1003,6 @@ exports.normalizeCSSValues = normalizeCSSValues;
1011
1003
  exports.normalizeVariant = normalizeVariant;
1012
1004
  exports.notNull = notNull;
1013
1005
  exports.parseVariantGroup = parseVariantGroup;
1014
- exports.quotedArbitraryValuesRE = quotedArbitraryValuesRE;
1015
1006
  exports.regexScopePlaceholder = regexScopePlaceholder;
1016
1007
  exports.splitWithVariantGroupRE = splitWithVariantGroupRE;
1017
1008
  exports.toArray = toArray;
package/dist/index.d.ts CHANGED
@@ -64,7 +64,7 @@ declare class UnoGenerator<Theme extends {} = {}> {
64
64
  }>;
65
65
  constructor(userConfig?: UserConfig<Theme>, defaults?: UserConfigDefaults<Theme>);
66
66
  setConfig(userConfig?: UserConfig<Theme>, defaults?: UserConfigDefaults<Theme>): void;
67
- applyExtractors(code: string, id?: string, set?: Set<string>): Promise<Set<string>>;
67
+ applyExtractors(code: string, id?: string, extracted?: Set<string>): Promise<Set<string>>;
68
68
  makeContext(raw: string, applied: VariantMatchedResult<Theme>): RuleContext<Theme>;
69
69
  parseToken(raw: string, alias?: string): Promise<StringifiedUtil<Theme>[] | null | undefined>;
70
70
  generate(input: string | Set<string> | string[], options?: GenerateOptions): Promise<GenerateResult>;
@@ -94,7 +94,10 @@ declare function normalizeCSSValues(obj: CSSValue | string | (CSSValue | string)
94
94
  declare function clearIdenticalEntries(entry: CSSEntries): CSSEntries;
95
95
  declare function entriesToCss(arr?: CSSEntries): string;
96
96
  declare function isObject(item: any): item is Record<string, any>;
97
- declare function mergeDeep<T>(original: T, patch: DeepPartial<T>): T;
97
+ /**
98
+ * Deep merge two objects
99
+ */
100
+ declare function mergeDeep<T>(original: T, patch: DeepPartial<T>, mergeArray?: boolean): T;
98
101
  declare function clone<T>(val: T): T;
99
102
  declare function isStaticRule(rule: Rule<any>): rule is StaticRule;
100
103
  declare function isStaticShortcut(sc: Shortcut<any>): sc is StaticShortcut;
@@ -263,6 +266,7 @@ interface ExtractorContext {
263
266
  readonly original: string;
264
267
  code: string;
265
268
  id?: string;
269
+ extracted: Set<string>;
266
270
  }
267
271
  interface PreflightContext<Theme extends {} = {}> {
268
272
  /**
@@ -276,8 +280,13 @@ interface PreflightContext<Theme extends {} = {}> {
276
280
  }
277
281
  interface Extractor {
278
282
  name: string;
279
- extract(ctx: ExtractorContext): Awaitable<Set<string> | string[] | undefined>;
280
283
  order?: number;
284
+ /**
285
+ * Extract the code and return a list of selectors.
286
+ *
287
+ * Return `undefined` to skip this extractor.
288
+ */
289
+ extract?(ctx: ExtractorContext): Awaitable<Set<string> | string[] | undefined | void>;
281
290
  }
282
291
  interface RuleMeta {
283
292
  /**
@@ -428,7 +437,7 @@ interface VariantObject<Theme extends {} = {}> {
428
437
  type Variant<Theme extends {} = {}> = VariantFunction<Theme> | VariantObject<Theme>;
429
438
  type Preprocessor = (matcher: string) => string | undefined;
430
439
  type Postprocessor = (util: UtilObject) => void;
431
- type ThemeExtender<T> = (theme: T) => void;
440
+ type ThemeExtender<T> = (theme: T) => T | void;
432
441
  interface ConfigBase<Theme extends {} = {}> {
433
442
  /**
434
443
  * Rules to generate CSS utilities.
@@ -468,6 +477,20 @@ interface ConfigBase<Theme extends {} = {}> {
468
477
  * Can be language-aware.
469
478
  */
470
479
  extractors?: Extractor[];
480
+ /**
481
+ * Default extractor that are always applied.
482
+ * By default it split the source code by whitespace and quotes.
483
+ *
484
+ * It maybe be replaced by preset or user config,
485
+ * only one default extractor can be presented,
486
+ * later one will override the previous one.
487
+ *
488
+ * Pass `null` or `false` to disable the default extractor.
489
+ *
490
+ * @see https://github.com/antfu/unocss/blob/main/packages/core/src/extractors/split.ts
491
+ * @default import('@unocss/core').defaultExtractor
492
+ */
493
+ extractorDefault?: Extractor | null | false;
471
494
  /**
472
495
  * Raw CSS injections.
473
496
  */
@@ -493,9 +516,15 @@ interface ConfigBase<Theme extends {} = {}> {
493
516
  */
494
517
  postprocess?: Arrayable<Postprocessor>;
495
518
  /**
496
- * Custom functions to extend the theme object
519
+ * Custom functions mutate the theme object.
520
+ *
521
+ * It's also possible to return a new theme object to completely replace the original one.
497
522
  */
498
523
  extendTheme?: Arrayable<ThemeExtender<Theme>>;
524
+ /**
525
+ * Presets
526
+ */
527
+ presets?: (Preset<Theme> | Preset<Theme>[])[];
499
528
  /**
500
529
  * Additional options for auto complete
501
530
  */
@@ -620,10 +649,6 @@ interface UserOnlyOptions<Theme extends {} = {}> {
620
649
  * @default 'shortcuts'
621
650
  */
622
651
  shortcutsLayer?: string;
623
- /**
624
- * Presets
625
- */
626
- presets?: (Preset<Theme> | Preset<Theme>[])[];
627
652
  /**
628
653
  * Environment mode
629
654
  *
@@ -836,10 +861,6 @@ interface GenerateOptions {
836
861
 
837
862
  declare const defaultSplitRE: RegExp;
838
863
  declare const splitWithVariantGroupRE: RegExp;
839
- declare const quotedArbitraryValuesRE: RegExp;
840
- declare const arbitraryPropertyRE: RegExp;
841
864
  declare const extractorSplit: Extractor;
842
865
 
843
- declare const extractorSvelte: Extractor;
844
-
845
- export { ArgumentType, Arrayable, AutoCompleteExtractor, AutoCompleteExtractorContext, AutoCompleteExtractorResult, AutoCompleteFunction, AutoCompleteTemplate, Awaitable, BetterMap, BlocklistRule, CONTROL_SHORTCUT_NO_MERGE, CSSColorValue, CSSEntries, CSSObject, CSSValue, CSSValues, CliEntryItem, CliOptions, ConfigBase, DeepPartial, DynamicMatcher, DynamicRule, DynamicShortcut, DynamicShortcutMatcher, ExtraContentOptions, Extractor, ExtractorContext, FilterPattern, FlatObjectTuple, GenerateOptions, GenerateResult, GeneratorOptions, ParsedColorValue, ParsedUtil, PartialByKeys, PluginOptions, Postprocessor, Preflight, PreflightContext, PreparedRule, Preprocessor, Preset, PresetOptions, RGBAColorValue, RawUtil, Replacement, RequiredByKey, ResolvedConfig, RestArgs, Rule, RuleContext, RuleMeta, Shift, Shortcut, ShortcutValue, SourceCodeTransformer, SourceCodeTransformerEnforce, SourceMap, StaticRule, StaticShortcut, StaticShortcutMap, StringifiedUtil, SuggestResult, ThemeExtender, TransformResult, TwoKeyMap, UnoGenerator, UnocssPluginContext, UserConfig, UserConfigDefaults, UserOnlyOptions, UserShortcuts, UtilObject, ValueHandler, ValueHandlerCallback, Variant, VariantContext, VariantFunction, VariantHandler, VariantHandlerContext, VariantMatchedResult, VariantObject, arbitraryPropertyRE, attributifyRE, clearIdenticalEntries, clone, collapseVariantGroup, createGenerator, createValueHandler, cssIdRE, defaultSplitRE, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit, extractorSvelte, hasScopePlaceholder, isAttributifySelector, isObject, isRawUtil, isStaticRule, isStaticShortcut, isString, isValidSelector, makeRegexClassGroup, mergeDeep, noop, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, parseVariantGroup, quotedArbitraryValuesRE, regexScopePlaceholder, splitWithVariantGroupRE, toArray, toEscapedSelector, uniq, validateFilterRE, warnOnce, withLayer };
866
+ export { ArgumentType, Arrayable, AutoCompleteExtractor, AutoCompleteExtractorContext, AutoCompleteExtractorResult, AutoCompleteFunction, AutoCompleteTemplate, Awaitable, BetterMap, BlocklistRule, CONTROL_SHORTCUT_NO_MERGE, CSSColorValue, CSSEntries, CSSObject, CSSValue, CSSValues, CliEntryItem, CliOptions, ConfigBase, DeepPartial, DynamicMatcher, DynamicRule, DynamicShortcut, DynamicShortcutMatcher, ExtraContentOptions, Extractor, ExtractorContext, FilterPattern, FlatObjectTuple, GenerateOptions, GenerateResult, GeneratorOptions, ParsedColorValue, ParsedUtil, PartialByKeys, PluginOptions, Postprocessor, Preflight, PreflightContext, PreparedRule, Preprocessor, Preset, PresetOptions, RGBAColorValue, RawUtil, Replacement, RequiredByKey, ResolvedConfig, RestArgs, Rule, RuleContext, RuleMeta, Shift, Shortcut, ShortcutValue, SourceCodeTransformer, SourceCodeTransformerEnforce, SourceMap, StaticRule, StaticShortcut, StaticShortcutMap, StringifiedUtil, SuggestResult, ThemeExtender, TransformResult, TwoKeyMap, UnoGenerator, UnocssPluginContext, UserConfig, UserConfigDefaults, UserOnlyOptions, UserShortcuts, UtilObject, ValueHandler, ValueHandlerCallback, Variant, VariantContext, VariantFunction, VariantHandler, VariantHandlerContext, VariantMatchedResult, VariantObject, attributifyRE, clearIdenticalEntries, clone, collapseVariantGroup, createGenerator, createValueHandler, cssIdRE, defaultSplitRE, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit as extractorDefault, extractorSplit, hasScopePlaceholder, isAttributifySelector, isObject, isRawUtil, isStaticRule, isStaticShortcut, isString, isValidSelector, makeRegexClassGroup, mergeDeep, noop, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, parseVariantGroup, regexScopePlaceholder, splitWithVariantGroupRE, toArray, toEscapedSelector, uniq, validateFilterRE, warnOnce, withLayer };
package/dist/index.mjs CHANGED
@@ -79,16 +79,20 @@ function entriesToCss(arr) {
79
79
  function isObject(item) {
80
80
  return item && typeof item === "object" && !Array.isArray(item);
81
81
  }
82
- function mergeDeep(original, patch) {
82
+ function mergeDeep(original, patch, mergeArray = false) {
83
83
  const o = original;
84
84
  const p = patch;
85
- if (Array.isArray(o))
86
- return [...p];
85
+ if (Array.isArray(p)) {
86
+ if (mergeArray && Array.isArray(p))
87
+ return [...o, ...p];
88
+ else
89
+ return [...p];
90
+ }
87
91
  const output = { ...o };
88
92
  if (isObject(o) && isObject(p)) {
89
93
  Object.keys(p).forEach((key) => {
90
94
  if (isObject(o[key]) && isObject(p[key]) || Array.isArray(o[key]) && Array.isArray(p[key]))
91
- output[key] = mergeDeep(o[key], p[key]);
95
+ output[key] = mergeDeep(o[key], p[key], mergeArray);
92
96
  else
93
97
  Object.assign(output, { [key]: p[key] });
94
98
  });
@@ -324,47 +328,17 @@ function createValueHandler(handlers) {
324
328
 
325
329
  const defaultSplitRE = /[\\:]?[\s'"`;{}]+/g;
326
330
  const splitWithVariantGroupRE = /([\\:]?[\s"'`;<>*]|:\(|\)"|\)\s)/g;
327
- const quotedArbitraryValuesRE = /(?:[\w&:[\]-]|\[\S+=\S+\])+\[\\?['"]?\S+?['"]\]\]?[\w:-]*/g;
328
- const arbitraryPropertyRE = /\[(\\\W|[\w-])+:[^\s:]*?("\S+?"|'\S+?'|`\S+?`|[^\s:]+?)[^\s:]*?\)?\]/g;
329
- const arbitraryPropertyCandidateRE = /^\[(\\\W|[\w-])+:['"]?\S+?['"]?\]$/;
330
331
  function splitCode(code) {
331
- const result = /* @__PURE__ */ new Set();
332
- for (const match of code.matchAll(arbitraryPropertyRE)) {
333
- if (!code[match.index - 1]?.match(/^[\s'"`]/))
334
- continue;
335
- result.add(match[0]);
336
- }
337
- for (const match of code.matchAll(quotedArbitraryValuesRE))
338
- result.add(match[0]);
339
- code.split(defaultSplitRE).forEach((match) => {
340
- if (isValidSelector(match) && !arbitraryPropertyCandidateRE.test(match))
341
- result.add(match);
342
- });
343
- return [...result];
332
+ return [...new Set(code.split(defaultSplitRE))];
344
333
  }
345
334
  const extractorSplit = {
346
- name: "split",
335
+ name: "@unocss/core/extractor-split",
347
336
  order: 0,
348
337
  extract({ code }) {
349
338
  return splitCode(code);
350
339
  }
351
340
  };
352
341
 
353
- const rightTrimRe = /=$/;
354
- const extractorSvelte = {
355
- name: "svelte",
356
- order: 0,
357
- extract({ code, id }) {
358
- let result = splitCode(code);
359
- if (id && id.endsWith(".svelte")) {
360
- result = result.map((r) => {
361
- return r.startsWith("class:") ? r.slice(6).replace(rightTrimRe, "") : r;
362
- });
363
- }
364
- return new Set(result);
365
- }
366
- };
367
-
368
342
  function createNanoEvents() {
369
343
  return {
370
344
  events: {},
@@ -394,7 +368,15 @@ function resolveShortcuts(shortcuts) {
394
368
  return Object.entries(s);
395
369
  });
396
370
  }
371
+ const __RESOLVED = "_uno_resolved";
397
372
  function resolvePreset(preset) {
373
+ if (__RESOLVED in preset)
374
+ return preset;
375
+ preset = { ...preset };
376
+ Object.defineProperty(preset, __RESOLVED, {
377
+ value: true,
378
+ enumerable: false
379
+ });
398
380
  const shortcuts = preset.shortcuts ? resolveShortcuts(preset.shortcuts) : void 0;
399
381
  preset.shortcuts = shortcuts;
400
382
  if (preset.prefix || preset.layer) {
@@ -412,9 +394,16 @@ function resolvePreset(preset) {
412
394
  }
413
395
  return preset;
414
396
  }
397
+ function resolvePresets(preset) {
398
+ const root = resolvePreset(preset);
399
+ if (!root.presets)
400
+ return [root];
401
+ const nested = (root.presets || []).flatMap(toArray).flatMap(resolvePresets);
402
+ return [root, ...nested];
403
+ }
415
404
  function resolveConfig(userConfig = {}, defaults = {}) {
416
405
  const config = Object.assign({}, defaults, userConfig);
417
- const rawPresets = (config.presets || []).flatMap(toArray).map(resolvePreset);
406
+ const rawPresets = uniq((config.presets || []).flatMap(toArray).flatMap(resolvePresets));
418
407
  const sortedPresets = [
419
408
  ...rawPresets.filter((p) => p.enforce === "pre"),
420
409
  ...rawPresets.filter((p) => !p.enforce),
@@ -428,8 +417,11 @@ function resolveConfig(userConfig = {}, defaults = {}) {
428
417
  ]);
429
418
  }
430
419
  const extractors = mergePresets("extractors");
431
- if (!extractors.length)
432
- extractors.push(extractorSplit);
420
+ let extractorDefault = [...sortedPresets, config].reverse().find((i) => i.extractorDefault !== void 0)?.extractorDefault;
421
+ if (extractorDefault === void 0)
422
+ extractorDefault = extractorSplit;
423
+ if (extractorDefault && !extractors.includes(extractorDefault))
424
+ extractors.unshift(extractorDefault);
433
425
  extractors.sort((a, b) => (a.order || 0) - (b.order || 0));
434
426
  const rules = mergePresets("rules");
435
427
  const rulesStaticMap = {};
@@ -444,11 +436,13 @@ function resolveConfig(userConfig = {}, defaults = {}) {
444
436
  }
445
437
  return [i, ...rule];
446
438
  }).filter(Boolean).reverse();
447
- const theme = clone([
439
+ let theme = clone([
448
440
  ...sortedPresets.map((p) => p.theme || {}),
449
441
  config.theme || {}
450
442
  ].reduce((a, p) => mergeDeep(a, p), {}));
451
- mergePresets("extendTheme").forEach((extendTheme) => extendTheme(theme));
443
+ const extendThemes = toArray(mergePresets("extendTheme"));
444
+ for (const extendTheme of extendThemes)
445
+ theme = extendTheme(theme) || theme;
452
446
  const autocomplete = {
453
447
  templates: uniq(sortedPresets.map((p) => toArray(p.autocomplete?.templates)).flat()),
454
448
  extractors: sortedPresets.map((p) => toArray(p.autocomplete?.extractors)).flat().sort((a, b) => (a.order || 0) - (b.order || 0))
@@ -486,7 +480,7 @@ function resolveConfig(userConfig = {}, defaults = {}) {
486
480
  return resolved;
487
481
  }
488
482
 
489
- const version = "0.50.8";
483
+ const version = "0.51.1";
490
484
 
491
485
  class UnoGenerator {
492
486
  constructor(userConfig = {}, defaults = {}) {
@@ -512,22 +506,21 @@ class UnoGenerator {
512
506
  this.config = resolveConfig(userConfig, this.defaults);
513
507
  this.events.emit("config", this.config);
514
508
  }
515
- async applyExtractors(code, id, set = /* @__PURE__ */ new Set()) {
509
+ async applyExtractors(code, id, extracted = /* @__PURE__ */ new Set()) {
516
510
  const context = {
517
- get original() {
518
- return code;
519
- },
511
+ original: code,
520
512
  code,
521
- id
513
+ id,
514
+ extracted
522
515
  };
523
516
  for (const extractor of this.config.extractors) {
524
- const result = await extractor.extract(context);
517
+ const result = await extractor.extract?.(context);
525
518
  if (result) {
526
519
  for (const token of result)
527
- set.add(token);
520
+ extracted.add(token);
528
521
  }
529
522
  }
530
- return set;
523
+ return extracted;
531
524
  }
532
525
  makeContext(raw, applied) {
533
526
  const context = {
@@ -971,4 +964,4 @@ function defaultVariantHandler(input, next) {
971
964
  return next(input);
972
965
  }
973
966
 
974
- export { BetterMap, CONTROL_SHORTCUT_NO_MERGE, TwoKeyMap, UnoGenerator, arbitraryPropertyRE, attributifyRE, clearIdenticalEntries, clone, collapseVariantGroup, createGenerator, createValueHandler, cssIdRE, defaultSplitRE, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit, extractorSvelte, hasScopePlaceholder, isAttributifySelector, isObject, isRawUtil, isStaticRule, isStaticShortcut, isString, isValidSelector, makeRegexClassGroup, mergeDeep, noop, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, parseVariantGroup, quotedArbitraryValuesRE, regexScopePlaceholder, splitWithVariantGroupRE, toArray, toEscapedSelector, uniq, validateFilterRE, warnOnce, withLayer };
967
+ export { BetterMap, CONTROL_SHORTCUT_NO_MERGE, TwoKeyMap, UnoGenerator, attributifyRE, clearIdenticalEntries, clone, collapseVariantGroup, createGenerator, createValueHandler, cssIdRE, defaultSplitRE, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit as extractorDefault, extractorSplit, hasScopePlaceholder, isAttributifySelector, isObject, isRawUtil, isStaticRule, isStaticShortcut, isString, isValidSelector, makeRegexClassGroup, mergeDeep, noop, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, parseVariantGroup, regexScopePlaceholder, splitWithVariantGroupRE, toArray, toEscapedSelector, uniq, validateFilterRE, warnOnce, withLayer };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unocss/core",
3
- "version": "0.50.8",
3
+ "version": "0.51.1",
4
4
  "description": "The instant on-demand Atomic CSS engine.",
5
5
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
6
6
  "license": "MIT",