@pikacss/core 0.0.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/dist/index.cjs ADDED
@@ -0,0 +1,931 @@
1
+ 'use strict';
2
+
3
+ const ATOMIC_STYLE_NAME_PLACEHOLDER = "&&";
4
+ const ATOMIC_STYLE_NAME_PLACEHOLDER_RE_GLOBAL = /&&/g;
5
+ const TEMP_ATOMIC_STYLE_NAME_PLACEHOLDER = "@@";
6
+ const TEMP_ATOMIC_STYLE_NAME_PLACEHOLDER_RE_GLOBAL = /@@/g;
7
+ const DEFAULT_SELECTOR_PLACEHOLDER = "&";
8
+ const DEFAULT_SELECTOR_PLACEHOLDER_RE_GLOBAL = /&/g;
9
+
10
+ const chars = [..."abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"];
11
+ const numOfChars = chars.length;
12
+ function numberToChars(num) {
13
+ if (num < numOfChars)
14
+ return chars[num];
15
+ let result = "";
16
+ let n = num;
17
+ while (n >= 0) {
18
+ result += chars[n % numOfChars];
19
+ n = Math.floor(n / numOfChars) - 1;
20
+ }
21
+ return result;
22
+ }
23
+ const UPPER_CASE = /[A-Z]/g;
24
+ function toKebab(str) {
25
+ return str.replace(UPPER_CASE, (c) => `-${c.toLowerCase()}`);
26
+ }
27
+ function isNotNullish(value) {
28
+ return value != null;
29
+ }
30
+ function isNotString(value) {
31
+ return typeof value !== "string";
32
+ }
33
+ function isPropertyValue(v) {
34
+ if (Array.isArray(v))
35
+ return v.length === 2 && isPropertyValue(v[0]) && Array.isArray(v[1]) && v[1].every(isPropertyValue);
36
+ if (v == null)
37
+ return true;
38
+ if (typeof v === "string" || typeof v === "number")
39
+ return true;
40
+ return false;
41
+ }
42
+ function serialize(value) {
43
+ return JSON.stringify(value);
44
+ }
45
+ function addToSet(set, ...values) {
46
+ values.forEach((value) => set.add(value));
47
+ }
48
+ function appendAutocompleteSelectors(config, ...selectors) {
49
+ addToSet(config.autocomplete.selectors, ...selectors);
50
+ }
51
+ function appendAutocompleteStyleItemStrings(config, ...styleItemStrings) {
52
+ addToSet(config.autocomplete.styleItemStrings, ...styleItemStrings);
53
+ }
54
+ function appendAutocompleteExtraProperties(config, ...properties) {
55
+ addToSet(config.autocomplete.extraProperties, ...properties);
56
+ }
57
+ function appendAutocompleteExtraCssProperties(config, ...properties) {
58
+ addToSet(config.autocomplete.extraCssProperties, ...properties);
59
+ }
60
+ function appendAutocompletePropertyValues(config, property, ...tsTypes) {
61
+ const current = config.autocomplete.properties.get(property) || [];
62
+ config.autocomplete.properties.set(property, [...current, ...tsTypes]);
63
+ }
64
+ function appendAutocompleteCssPropertyValues(config, property, ...values) {
65
+ const current = config.autocomplete.cssProperties.get(property) || [];
66
+ config.autocomplete.cssProperties.set(property, [...current, ...values]);
67
+ }
68
+
69
+ const RE_SPLIT = /\s*,\s*/;
70
+ function normalizeSelectors({
71
+ selectors,
72
+ defaultSelector
73
+ }) {
74
+ let normalized;
75
+ const lastSelector = selectors[selectors.length - 1];
76
+ if (selectors.length === 0) {
77
+ normalized = [DEFAULT_SELECTOR_PLACEHOLDER];
78
+ } else if (lastSelector.includes(ATOMIC_STYLE_NAME_PLACEHOLDER) || lastSelector.includes(DEFAULT_SELECTOR_PLACEHOLDER)) {
79
+ normalized = selectors;
80
+ } else {
81
+ normalized = [...selectors, DEFAULT_SELECTOR_PLACEHOLDER];
82
+ }
83
+ return normalized.map((s) => s.replace(ATOMIC_STYLE_NAME_PLACEHOLDER_RE_GLOBAL, TEMP_ATOMIC_STYLE_NAME_PLACEHOLDER).replace(DEFAULT_SELECTOR_PLACEHOLDER_RE_GLOBAL, defaultSelector).replace(TEMP_ATOMIC_STYLE_NAME_PLACEHOLDER_RE_GLOBAL, ATOMIC_STYLE_NAME_PLACEHOLDER).split(RE_SPLIT).join(","));
84
+ }
85
+ function normalizeValue(value) {
86
+ if (value == null)
87
+ return value;
88
+ return [...new Set([value].flat(2).map((v) => String(v).trim()))];
89
+ }
90
+ async function extract({
91
+ styleDefinition,
92
+ levels = [],
93
+ result = [],
94
+ defaultSelector,
95
+ transformSelectors,
96
+ transformStyleItems,
97
+ transformStyleDefinitions
98
+ }) {
99
+ const selector = normalizeSelectors({
100
+ selectors: await transformSelectors(levels),
101
+ defaultSelector
102
+ });
103
+ for (const definition of await transformStyleDefinitions([styleDefinition])) {
104
+ for (const [k, v] of Object.entries(definition)) {
105
+ if (isPropertyValue(v)) {
106
+ const property = toKebab(k);
107
+ const value = normalizeValue(v);
108
+ result.push({
109
+ selector,
110
+ property,
111
+ value
112
+ });
113
+ } else if (Array.isArray(v)) {
114
+ for (const styleItem of await transformStyleItems(v)) {
115
+ if (typeof styleItem === "string")
116
+ continue;
117
+ await extract({
118
+ styleDefinition: styleItem,
119
+ levels: [...levels, k],
120
+ result,
121
+ transformSelectors,
122
+ transformStyleItems,
123
+ transformStyleDefinitions,
124
+ defaultSelector
125
+ });
126
+ }
127
+ } else {
128
+ await extract({
129
+ styleDefinition: v,
130
+ levels: [...levels, k],
131
+ result,
132
+ transformSelectors,
133
+ transformStyleItems,
134
+ transformStyleDefinitions,
135
+ defaultSelector
136
+ });
137
+ }
138
+ }
139
+ }
140
+ return result;
141
+ }
142
+ function createExtractFn(options) {
143
+ return (styleDefinition) => extract({
144
+ styleDefinition,
145
+ ...options
146
+ });
147
+ }
148
+
149
+ async function execAsyncHook(plugins, hook, payload) {
150
+ for (const plugin of plugins) {
151
+ if (plugin[hook] == null)
152
+ continue;
153
+ const newPayload = await plugin[hook](payload);
154
+ if (newPayload != null)
155
+ payload = newPayload;
156
+ }
157
+ return payload;
158
+ }
159
+ function execSyncHook(plugins, hook, payload) {
160
+ for (const plugin of plugins) {
161
+ if (plugin[hook] == null)
162
+ continue;
163
+ const newPayload = plugin[hook](payload);
164
+ if (newPayload != null)
165
+ payload = newPayload;
166
+ }
167
+ return payload;
168
+ }
169
+ const hooks = {
170
+ config: (plugins, config) => execAsyncHook(plugins, "config", config),
171
+ beforeConfigResolving: (plugins, config) => execSyncHook(plugins, "beforeConfigResolving", config),
172
+ configResolved: (plugins, resolvedConfig) => execAsyncHook(plugins, "configResolved", resolvedConfig),
173
+ engineInitialized: (plugins, engine) => execSyncHook(plugins, "engineInitialized", engine),
174
+ transformSelectors: (plugins, selectors) => execAsyncHook(plugins, "transformSelectors", selectors),
175
+ transformStyleItems: (plugins, styleItems) => execAsyncHook(plugins, "transformStyleItems", styleItems),
176
+ transformStyleDefinitions: (plugins, styleDefinitions) => execAsyncHook(plugins, "transformStyleDefinitions", styleDefinitions),
177
+ preflightUpdated: (plugins) => execSyncHook(plugins, "preflightUpdated", void 0),
178
+ atomicRuleAdded: (plugins) => execSyncHook(plugins, "atomicRuleAdded", void 0),
179
+ autocompleteConfigUpdated: (plugins) => execSyncHook(plugins, "autocompleteConfigUpdated", void 0)
180
+ };
181
+ const orderMap = /* @__PURE__ */ new Map([
182
+ [void 0, 1],
183
+ ["pre", 0],
184
+ ["post", 2]
185
+ ]);
186
+ function resolvePlugins(plugins) {
187
+ return plugins.sort((a, b) => orderMap.get(a.order) - orderMap.get(b.order));
188
+ }
189
+ function defineEnginePlugin$1(plugin) {
190
+ return plugin;
191
+ }
192
+
193
+ function important() {
194
+ let _default;
195
+ return defineEnginePlugin$1({
196
+ name: "core:important",
197
+ beforeConfigResolving(config) {
198
+ _default = config.important?.default ?? false;
199
+ },
200
+ configResolved(resolvedConfig) {
201
+ appendAutocompleteExtraProperties(resolvedConfig, "__important");
202
+ appendAutocompletePropertyValues(resolvedConfig, "__important", "boolean");
203
+ },
204
+ transformStyleDefinitions(styleDefinitions) {
205
+ return styleDefinitions.map((styleDefinition) => {
206
+ const { __important, ...rest } = styleDefinition;
207
+ const theImportant = __important;
208
+ const important2 = theImportant == null ? _default : theImportant;
209
+ if (important2 === false)
210
+ return rest;
211
+ return Object.fromEntries(
212
+ Object.entries(rest).map(([k, v]) => {
213
+ if (isPropertyValue(v) === false || v == null)
214
+ return [k, v];
215
+ const modified = [v].flat(2).map((v2) => `${v2} !important`);
216
+ return [k, modified];
217
+ })
218
+ );
219
+ });
220
+ }
221
+ });
222
+ }
223
+
224
+ function resolveKeyframesConfig(config) {
225
+ if (typeof config === "string")
226
+ return { name: config, frames: null, autocomplete: [] };
227
+ if (Array.isArray(config)) {
228
+ const [name2, frames2, autocomplete2 = []] = config;
229
+ return { name: name2, frames: frames2, autocomplete: autocomplete2 };
230
+ }
231
+ const { name, frames, autocomplete = [] } = config;
232
+ return { name, frames, autocomplete };
233
+ }
234
+ function keyframes() {
235
+ const allKeyframes = /* @__PURE__ */ new Map();
236
+ let configList;
237
+ return defineEnginePlugin$1({
238
+ name: "core:keyframes",
239
+ beforeConfigResolving(config) {
240
+ configList = config.keyframes ?? [];
241
+ },
242
+ configResolved(resolvedConfig) {
243
+ const autocomplete = {
244
+ animationName: [],
245
+ animation: []
246
+ };
247
+ configList.forEach((config) => {
248
+ const { name, frames, autocomplete: autocompleteAnimation } = resolveKeyframesConfig(config);
249
+ if (frames != null) {
250
+ const css = [
251
+ `@keyframes ${name}{`,
252
+ ...Object.entries(frames).map(([frame, properties]) => (
253
+ // eslint-disable-next-line style/newline-per-chained-call
254
+ `${frame}{${Object.entries(properties).map(([property, value]) => `${property}:${value}`).join(";")}}`
255
+ )),
256
+ "}"
257
+ ].join("");
258
+ allKeyframes.set(name, css);
259
+ }
260
+ autocomplete.animationName.push(name);
261
+ autocomplete.animation.push(`${name} `);
262
+ if (autocompleteAnimation != null)
263
+ autocomplete.animation.push(...autocompleteAnimation);
264
+ });
265
+ appendAutocompleteCssPropertyValues(resolvedConfig, "animationName", ...autocomplete.animationName);
266
+ appendAutocompleteCssPropertyValues(resolvedConfig, "animation", ...autocomplete.animation);
267
+ resolvedConfig.preflights.push((engine) => {
268
+ const used = /* @__PURE__ */ new Set();
269
+ engine.store.atomicRules.forEach(({ content: { property, value } }) => {
270
+ if (property === "animationName") {
271
+ value.forEach((name) => used.add(name));
272
+ } else if (property === "animation") {
273
+ value.forEach((value2) => {
274
+ const animations = value2.split(",").map((v) => v.trim());
275
+ animations.forEach((animation) => {
276
+ const name = animation.split(" ")[0];
277
+ if (isNotNullish(name))
278
+ used.add(name);
279
+ });
280
+ });
281
+ }
282
+ });
283
+ const content = Array.from(allKeyframes.entries()).filter(([name]) => used.has(name)).map(([, css]) => css).join("");
284
+ return content;
285
+ });
286
+ }
287
+ });
288
+ }
289
+
290
+ class AbstractResolver {
291
+ _resolvedResultsMap = /* @__PURE__ */ new Map();
292
+ staticRulesMap = /* @__PURE__ */ new Map();
293
+ dynamicRulesMap = /* @__PURE__ */ new Map();
294
+ onResolved = () => {
295
+ };
296
+ get staticRules() {
297
+ return [...this.staticRulesMap.values()];
298
+ }
299
+ get dynamicRules() {
300
+ return [...this.dynamicRulesMap.values()];
301
+ }
302
+ addStaticRule(rule) {
303
+ this.staticRulesMap.set(rule.key, rule);
304
+ return this;
305
+ }
306
+ removeStaticRule(key) {
307
+ const rule = this.staticRulesMap.get(key);
308
+ if (rule == null)
309
+ return this;
310
+ this.staticRulesMap.delete(key);
311
+ this._resolvedResultsMap.delete(rule.string);
312
+ return this;
313
+ }
314
+ addDynamicRule(rule) {
315
+ this.dynamicRulesMap.set(rule.key, rule);
316
+ return this;
317
+ }
318
+ removeDynamicRule(key) {
319
+ const rule = this.dynamicRulesMap.get(key);
320
+ if (rule == null)
321
+ return this;
322
+ const matchedResolvedStringList = Array.from(this._resolvedResultsMap.keys()).filter((string) => rule.stringPattern.test(string));
323
+ this.dynamicRulesMap.delete(key);
324
+ matchedResolvedStringList.forEach((string) => this._resolvedResultsMap.delete(string));
325
+ return this;
326
+ }
327
+ async _resolve(string) {
328
+ const existedResult = this._resolvedResultsMap.get(string);
329
+ if (existedResult != null)
330
+ return existedResult;
331
+ const staticRule = Array.from(this.staticRulesMap.values()).find((rule) => rule.string === string);
332
+ if (staticRule != null) {
333
+ const resolvedResult = { value: staticRule.resolved };
334
+ this._resolvedResultsMap.set(string, resolvedResult);
335
+ this.onResolved(string, "static", resolvedResult);
336
+ return resolvedResult;
337
+ }
338
+ let dynamicRule;
339
+ let matched;
340
+ for (const rule of this.dynamicRulesMap.values()) {
341
+ matched = string.match(rule.stringPattern);
342
+ if (matched != null) {
343
+ dynamicRule = rule;
344
+ break;
345
+ }
346
+ }
347
+ if (dynamicRule != null && matched != null) {
348
+ const resolvedResult = { value: await dynamicRule.createResolved(matched) };
349
+ this._resolvedResultsMap.set(string, resolvedResult);
350
+ this.onResolved(string, "dynamic", resolvedResult);
351
+ return resolvedResult;
352
+ }
353
+ return void 0;
354
+ }
355
+ _setResolvedResult(string, resolved) {
356
+ const resolvedResult = this._resolvedResultsMap.get(string);
357
+ if (resolvedResult) {
358
+ resolvedResult.value = resolved;
359
+ return;
360
+ }
361
+ this._resolvedResultsMap.set(string, { value: resolved });
362
+ }
363
+ }
364
+
365
+ class SelectorResolver extends AbstractResolver {
366
+ async resolve(selector) {
367
+ const resolved = await this._resolve(selector);
368
+ if (resolved == null)
369
+ return [selector];
370
+ const result = [];
371
+ for (const s of resolved.value)
372
+ result.push(...await this.resolve(s));
373
+ this._setResolvedResult(selector, result);
374
+ return result;
375
+ }
376
+ }
377
+ function resolveSelectorConfig(config) {
378
+ if (typeof config === "string") {
379
+ return config;
380
+ } else if (Array.isArray(config)) {
381
+ if (typeof config[0] === "string" && typeof config[1] !== "function") {
382
+ return {
383
+ type: "static",
384
+ rule: {
385
+ key: config[0],
386
+ string: config[0],
387
+ resolved: [config[1]].flat(1)
388
+ },
389
+ autocomplete: [config[0]]
390
+ };
391
+ }
392
+ if (config[0] instanceof RegExp && typeof config[1] === "function") {
393
+ const fn = config[1];
394
+ return {
395
+ type: "dynamic",
396
+ rule: {
397
+ key: config[0].source,
398
+ stringPattern: config[0],
399
+ createResolved: async (match) => [await fn(match)].flat(1)
400
+ },
401
+ autocomplete: config[2] != null ? [config[2]].flat(1) : []
402
+ };
403
+ }
404
+ } else if (typeof config.selector === "string" && typeof config.value !== "function") {
405
+ return {
406
+ type: "static",
407
+ rule: {
408
+ key: config.selector,
409
+ string: config.selector,
410
+ resolved: [config.value].flat(1)
411
+ },
412
+ autocomplete: [config.selector]
413
+ };
414
+ } else if (config.selector instanceof RegExp && typeof config.value === "function") {
415
+ const fn = config.value;
416
+ return {
417
+ type: "dynamic",
418
+ rule: {
419
+ key: config.selector.source,
420
+ stringPattern: config.selector,
421
+ createResolved: async (match) => [await fn(match)].flat(1)
422
+ },
423
+ autocomplete: "autocomplete" in config && config.autocomplete != null ? [config.autocomplete].flat(1) : []
424
+ };
425
+ }
426
+ return void 0;
427
+ }
428
+ function selectors() {
429
+ const selectorResolver = new SelectorResolver();
430
+ let configList;
431
+ return defineEnginePlugin$1({
432
+ name: "core:selectors",
433
+ beforeConfigResolving(config) {
434
+ configList = config.selectors ?? [];
435
+ },
436
+ configResolved(resolvedConfig) {
437
+ configList.forEach((config) => {
438
+ const resolved = resolveSelectorConfig(config);
439
+ if (resolved == null)
440
+ return;
441
+ if (typeof resolved === "string") {
442
+ appendAutocompleteSelectors(resolvedConfig, resolved);
443
+ return;
444
+ }
445
+ if (resolved.type === "static")
446
+ selectorResolver.addStaticRule(resolved.rule);
447
+ else if (resolved.type === "dynamic")
448
+ selectorResolver.addDynamicRule(resolved.rule);
449
+ appendAutocompleteSelectors(resolvedConfig, ...resolved.autocomplete);
450
+ });
451
+ },
452
+ engineInitialized(engine) {
453
+ selectorResolver.onResolved = (string, type) => {
454
+ if (type === "dynamic") {
455
+ engine.appendAutocompleteSelectors(string);
456
+ }
457
+ };
458
+ },
459
+ async transformSelectors(selectors2) {
460
+ const result = [];
461
+ for (const selector of selectors2) {
462
+ result.push(...await selectorResolver.resolve(selector));
463
+ }
464
+ return result;
465
+ }
466
+ });
467
+ }
468
+
469
+ class ShortcutResolver extends AbstractResolver {
470
+ async resolve(shortcut) {
471
+ const resolved = await this._resolve(shortcut);
472
+ if (resolved == null)
473
+ return [shortcut];
474
+ const result = [];
475
+ for (const partial of resolved.value) {
476
+ if (typeof partial === "string")
477
+ result.push(...await this.resolve(partial));
478
+ else
479
+ result.push(partial);
480
+ }
481
+ this._setResolvedResult(shortcut, result);
482
+ return result;
483
+ }
484
+ }
485
+ function resolveShortcutConfig(config) {
486
+ if (typeof config === "string") {
487
+ return config;
488
+ } else if (Array.isArray(config)) {
489
+ if (typeof config[0] === "string" && typeof config[1] !== "function") {
490
+ return {
491
+ type: "static",
492
+ rule: {
493
+ key: config[0],
494
+ string: config[0],
495
+ resolved: [config[1]].flat(1)
496
+ },
497
+ autocomplete: [config[0]]
498
+ };
499
+ }
500
+ if (config[0] instanceof RegExp && typeof config[1] === "function") {
501
+ const fn = config[1];
502
+ return {
503
+ type: "dynamic",
504
+ rule: {
505
+ key: config[0].source,
506
+ stringPattern: config[0],
507
+ createResolved: async (match) => [await fn(match)].flat(1)
508
+ },
509
+ autocomplete: config[2] != null ? [config[2]].flat(1) : []
510
+ };
511
+ }
512
+ } else if (typeof config.shortcut === "string" && typeof config.value !== "function") {
513
+ return {
514
+ type: "static",
515
+ rule: {
516
+ key: config.shortcut,
517
+ string: config.shortcut,
518
+ resolved: [config.value].flat(1)
519
+ },
520
+ autocomplete: [config.shortcut]
521
+ };
522
+ } else if (config.shortcut instanceof RegExp && typeof config.value === "function") {
523
+ const fn = config.value;
524
+ return {
525
+ type: "dynamic",
526
+ rule: {
527
+ key: config.shortcut.source,
528
+ stringPattern: config.shortcut,
529
+ createResolved: async (match) => [await fn(match)].flat(1)
530
+ },
531
+ autocomplete: "autocomplete" in config && config.autocomplete != null ? [config.autocomplete].flat(1) : []
532
+ };
533
+ }
534
+ throw new Error("Invalid shortcut config");
535
+ }
536
+ function shortcuts() {
537
+ const shortcutResolver = new ShortcutResolver();
538
+ let configList;
539
+ return defineEnginePlugin$1({
540
+ name: "core:shortcuts",
541
+ beforeConfigResolving(config) {
542
+ configList = config.shortcuts ?? [];
543
+ },
544
+ configResolved(resolvedConfig) {
545
+ const autocompleteShortcuts = /* @__PURE__ */ new Set();
546
+ configList.forEach((config) => {
547
+ const resolved = resolveShortcutConfig(config);
548
+ if (typeof resolved === "string") {
549
+ addToSet(autocompleteShortcuts, resolved);
550
+ return;
551
+ }
552
+ if (resolved.type === "static")
553
+ shortcutResolver.addStaticRule(resolved.rule);
554
+ else if (resolved.type === "dynamic")
555
+ shortcutResolver.addDynamicRule(resolved.rule);
556
+ addToSet(autocompleteShortcuts, ...resolved.autocomplete);
557
+ });
558
+ appendAutocompleteStyleItemStrings(resolvedConfig, ...autocompleteShortcuts);
559
+ appendAutocompleteExtraProperties(resolvedConfig, "__shortcut");
560
+ const unionType = ["(string & {})", "Autocomplete['StyleItemString']"].join(" | ");
561
+ appendAutocompletePropertyValues(resolvedConfig, "__shortcut", unionType, `(${unionType})[]`);
562
+ },
563
+ engineInitialized(engine) {
564
+ shortcutResolver.onResolved = (string, type) => {
565
+ if (type === "dynamic") {
566
+ engine.appendAutocompleteStyleItemStrings(string);
567
+ }
568
+ };
569
+ },
570
+ async transformStyleItems(styleItems) {
571
+ const result = [];
572
+ for (const styleItem of styleItems) {
573
+ if (typeof styleItem === "string") {
574
+ result.push(...await shortcutResolver.resolve(styleItem));
575
+ continue;
576
+ }
577
+ result.push(styleItem);
578
+ }
579
+ return result;
580
+ },
581
+ async transformStyleDefinitions(styleDefinitions) {
582
+ const result = [];
583
+ for (const styleDefinition of styleDefinitions) {
584
+ if ("__shortcut" in styleDefinition) {
585
+ const { __shortcut, ...rest } = styleDefinition;
586
+ const applied = [];
587
+ for (const shortcut of __shortcut == null ? [] : [__shortcut].flat(1)) {
588
+ const resolved = (await shortcutResolver.resolve(shortcut)).filter(isNotString);
589
+ applied.push(...resolved);
590
+ }
591
+ result.push(...applied, rest);
592
+ } else {
593
+ result.push(styleDefinition);
594
+ }
595
+ }
596
+ return result;
597
+ }
598
+ });
599
+ }
600
+
601
+ function resolveVariableConfig(config) {
602
+ if (typeof config === "string")
603
+ return { name: config, value: null, autocomplete: { asValueOf: ["*"], asProperty: true } };
604
+ if (Array.isArray(config)) {
605
+ const [name2, value2, { asValueOf: asValueOf2 = "*", asProperty: asProperty2 = true } = {}] = config;
606
+ return { name: name2, value: value2, autocomplete: { asValueOf: [asValueOf2].flat(), asProperty: asProperty2 } };
607
+ }
608
+ const { name, value, autocomplete: { asValueOf = "*", asProperty = true } = {} } = config;
609
+ return { name, value, autocomplete: { asValueOf: [asValueOf].flat(), asProperty } };
610
+ }
611
+ const VAR_NAME_RE = /var\((--[\w-]+)/g;
612
+ function extractUsedVarNames(input) {
613
+ const matched = input.match(VAR_NAME_RE);
614
+ if (!matched)
615
+ return [];
616
+ return matched.map((match) => {
617
+ const varNameMatch = match.match(/--[^,)]+/);
618
+ return varNameMatch ? varNameMatch[0] : "";
619
+ }).filter(Boolean);
620
+ }
621
+ function normalizeVariableName(name, prefix) {
622
+ if (name.startsWith("--"))
623
+ return name;
624
+ if (prefix)
625
+ return `--${prefix}-${name}`;
626
+ return `--${name}`;
627
+ }
628
+ function variables() {
629
+ const allVariables = /* @__PURE__ */ new Map();
630
+ let prefix;
631
+ let configList;
632
+ return defineEnginePlugin$1({
633
+ name: "core:variables",
634
+ beforeConfigResolving(config) {
635
+ prefix = config.variablesPrefix;
636
+ configList = config.variables ?? [];
637
+ },
638
+ configResolved(resolvedConfig) {
639
+ configList.forEach((config) => {
640
+ const { name: _name, value, autocomplete: { asValueOf, asProperty } } = resolveVariableConfig(config);
641
+ const name = normalizeVariableName(_name, prefix);
642
+ asValueOf.forEach((p) => appendAutocompleteCssPropertyValues(resolvedConfig, p, `var(${name})`));
643
+ if (asProperty)
644
+ appendAutocompleteExtraCssProperties(resolvedConfig, name);
645
+ if (value != null)
646
+ allVariables.set(name, `${name}:${value}`);
647
+ });
648
+ resolvedConfig.preflights.push((engine) => {
649
+ const used = /* @__PURE__ */ new Set();
650
+ engine.store.atomicRules.forEach(({ content: { value } }) => {
651
+ value.flatMap(extractUsedVarNames).forEach((name) => used.add(normalizeVariableName(name)));
652
+ });
653
+ const content = Array.from(allVariables.entries()).filter(([name]) => used.has(name)).map(([, css]) => css).join(";");
654
+ return content === "" ? "" : `:root{${content}}`;
655
+ });
656
+ }
657
+ });
658
+ }
659
+
660
+ async function createEngine(config = {}) {
661
+ const corePlugins = [
662
+ important(),
663
+ variables(),
664
+ keyframes(),
665
+ selectors(),
666
+ shortcuts()
667
+ ];
668
+ const plugins = resolvePlugins([...corePlugins, ...config.plugins || []]);
669
+ config.plugins = plugins;
670
+ config = await hooks.config(
671
+ config.plugins,
672
+ config
673
+ );
674
+ hooks.beforeConfigResolving(
675
+ resolvePlugins(config.plugins || []),
676
+ config
677
+ );
678
+ let resolvedConfig = await resolveEngineConfig(config);
679
+ resolvedConfig = await hooks.configResolved(
680
+ resolvedConfig.plugins,
681
+ resolvedConfig
682
+ );
683
+ return new Engine(resolvedConfig);
684
+ }
685
+ class Engine {
686
+ config;
687
+ extract;
688
+ store = {
689
+ atomicNames: /* @__PURE__ */ new Map(),
690
+ atomicRules: /* @__PURE__ */ new Map()
691
+ };
692
+ constructor(config) {
693
+ this.config = config;
694
+ this.extract = createExtractFn({
695
+ defaultSelector: this.config.defaultSelector,
696
+ transformSelectors: (selectors2) => hooks.transformSelectors(this.config.plugins, selectors2),
697
+ transformStyleItems: (styleItems) => hooks.transformStyleItems(this.config.plugins, styleItems),
698
+ transformStyleDefinitions: (styleDefinitions) => hooks.transformStyleDefinitions(this.config.plugins, styleDefinitions)
699
+ });
700
+ hooks.engineInitialized(this.config.plugins, this);
701
+ }
702
+ notifyPreflightUpdated() {
703
+ hooks.preflightUpdated(this.config.plugins);
704
+ }
705
+ notifyAtomicRuleAdded() {
706
+ hooks.atomicRuleAdded(this.config.plugins);
707
+ }
708
+ notifyAutocompleteConfigUpdated() {
709
+ hooks.autocompleteConfigUpdated(this.config.plugins);
710
+ }
711
+ appendAutocompleteSelectors(...selectors2) {
712
+ appendAutocompleteSelectors(this.config, ...selectors2);
713
+ this.notifyAutocompleteConfigUpdated();
714
+ }
715
+ appendAutocompleteStyleItemStrings(...styleItemStrings) {
716
+ appendAutocompleteStyleItemStrings(this.config, ...styleItemStrings);
717
+ this.notifyAutocompleteConfigUpdated();
718
+ }
719
+ appendAutocompleteExtraProperties(...properties) {
720
+ appendAutocompleteExtraProperties(this.config, ...properties);
721
+ this.notifyAutocompleteConfigUpdated();
722
+ }
723
+ appendAutocompleteExtraCssProperties(...properties) {
724
+ appendAutocompleteExtraCssProperties(this.config, ...properties);
725
+ this.notifyAutocompleteConfigUpdated();
726
+ }
727
+ appendAutocompletePropertyValues(property, ...tsTypes) {
728
+ appendAutocompletePropertyValues(this.config, property, ...tsTypes);
729
+ this.notifyAutocompleteConfigUpdated();
730
+ }
731
+ appendAutocompleteCssPropertyValues(property, ...values) {
732
+ appendAutocompleteCssPropertyValues(this.config, property, ...values);
733
+ this.notifyAutocompleteConfigUpdated();
734
+ }
735
+ async use(...itemList) {
736
+ const {
737
+ unknown,
738
+ contents
739
+ } = await resolveStyleItemList({
740
+ itemList,
741
+ transformStyleItems: (styleItems) => hooks.transformStyleItems(this.config.plugins, styleItems),
742
+ extractStyleDefinition: (styleDefinition) => this.extract(styleDefinition)
743
+ });
744
+ const resolvedNames = [];
745
+ contents.forEach((content) => {
746
+ const name = getAtomicStyleName({
747
+ content,
748
+ prefix: this.config.prefix,
749
+ stored: this.store.atomicNames
750
+ });
751
+ resolvedNames.push(name);
752
+ if (!this.store.atomicRules.has(name)) {
753
+ const added = {
754
+ name,
755
+ content
756
+ };
757
+ this.store.atomicRules.set(name, added);
758
+ this.notifyAtomicRuleAdded();
759
+ }
760
+ });
761
+ return [...unknown, ...resolvedNames];
762
+ }
763
+ async renderPreviewStyles(...itemList) {
764
+ const nameList = await this.use(...itemList);
765
+ const targets = nameList.map((name) => this.store.atomicRules.get(name)).filter(isNotNullish);
766
+ return renderAtomicStyles({
767
+ atomicRules: targets,
768
+ isPreview: true
769
+ });
770
+ }
771
+ renderStyles() {
772
+ return [
773
+ this.renderPreflights(),
774
+ this.renderAtomicStyles()
775
+ ].join("");
776
+ }
777
+ renderPreflights() {
778
+ return this.config.preflights.map((p) => p(this)).join("");
779
+ }
780
+ renderAtomicStyles() {
781
+ return renderAtomicStyles({
782
+ atomicRules: [...this.store.atomicRules.values()],
783
+ isPreview: false
784
+ });
785
+ }
786
+ }
787
+ async function resolveEngineConfig(config) {
788
+ const {
789
+ prefix = "",
790
+ defaultSelector = `.${ATOMIC_STYLE_NAME_PLACEHOLDER}`,
791
+ plugins = [],
792
+ preflights = [],
793
+ autocomplete = {}
794
+ } = config;
795
+ const resolvedConfig = {
796
+ rawConfig: config,
797
+ plugins: resolvePlugins(plugins),
798
+ prefix,
799
+ defaultSelector,
800
+ preflights: [],
801
+ autocomplete: {
802
+ selectors: /* @__PURE__ */ new Set(),
803
+ styleItemStrings: /* @__PURE__ */ new Set(),
804
+ extraProperties: /* @__PURE__ */ new Set(),
805
+ extraCssProperties: /* @__PURE__ */ new Set(),
806
+ properties: /* @__PURE__ */ new Map(),
807
+ cssProperties: /* @__PURE__ */ new Map()
808
+ }
809
+ };
810
+ const resolvedPreflights = preflights.map((p) => typeof p === "function" ? p : () => p);
811
+ resolvedConfig.preflights.push(...resolvedPreflights);
812
+ appendAutocompleteSelectors(resolvedConfig, ...autocomplete.selectors || []);
813
+ appendAutocompleteStyleItemStrings(resolvedConfig, ...autocomplete.styleItemStrings || []);
814
+ appendAutocompleteExtraProperties(resolvedConfig, ...autocomplete.extraProperties || []);
815
+ appendAutocompleteExtraCssProperties(resolvedConfig, ...autocomplete.extraCssProperties || []);
816
+ autocomplete.properties?.forEach(([property, value]) => appendAutocompletePropertyValues(resolvedConfig, property, ...[value].flat()));
817
+ autocomplete.cssProperties?.forEach(([property, value]) => appendAutocompleteCssPropertyValues(resolvedConfig, property, ...[value].flat()));
818
+ return resolvedConfig;
819
+ }
820
+ function getAtomicStyleName({
821
+ content,
822
+ prefix,
823
+ stored
824
+ }) {
825
+ const key = serialize([content.selector, content.property, content.value]);
826
+ const cached = stored.get(key);
827
+ if (cached != null)
828
+ return cached;
829
+ const num = stored.size;
830
+ const name = `${prefix}${numberToChars(num)}`;
831
+ stored.set(key, name);
832
+ return name;
833
+ }
834
+ function optimizeAtomicStyleContents(list) {
835
+ const map = /* @__PURE__ */ new Map();
836
+ list.forEach((content) => {
837
+ const key = serialize([content.selector, content.property]);
838
+ map.delete(key);
839
+ if (content.value == null)
840
+ return;
841
+ map.set(key, content);
842
+ });
843
+ return [...map.values()];
844
+ }
845
+ async function resolveStyleItemList({
846
+ itemList,
847
+ transformStyleItems,
848
+ extractStyleDefinition
849
+ }) {
850
+ const unknown = /* @__PURE__ */ new Set();
851
+ const list = [];
852
+ for (const styleItem of await transformStyleItems(itemList)) {
853
+ if (typeof styleItem === "string")
854
+ unknown.add(styleItem);
855
+ else
856
+ list.push(...await extractStyleDefinition(styleItem));
857
+ }
858
+ return {
859
+ unknown,
860
+ contents: optimizeAtomicStyleContents(list)
861
+ };
862
+ }
863
+ function prepareAtomicStyleBlocks({
864
+ atomicRules,
865
+ isPreview
866
+ }) {
867
+ const blocks = /* @__PURE__ */ new Map();
868
+ atomicRules.forEach(({ name, content: { selector, property, value } }) => {
869
+ const isValidSelector = selector.some((s) => s.includes(ATOMIC_STYLE_NAME_PLACEHOLDER));
870
+ if (isValidSelector === false || value == null)
871
+ return;
872
+ const renderObject = {
873
+ selector: isPreview ? selector : selector.map((s) => s.replace(ATOMIC_STYLE_NAME_PLACEHOLDER_RE_GLOBAL, name)),
874
+ content: Array.isArray(value) ? value.map((v) => `${property}:${v}`).join(";") : `${property}:${value}`
875
+ };
876
+ let currentBlocks = blocks;
877
+ for (let i = 0; i < renderObject.selector.length; i++) {
878
+ const s = renderObject.selector[i];
879
+ const block = currentBlocks.get(s) || { content: [] };
880
+ const isLast = i === renderObject.selector.length - 1;
881
+ if (isLast) {
882
+ block.content.push(renderObject.content);
883
+ } else {
884
+ block.children ||= /* @__PURE__ */ new Map();
885
+ }
886
+ currentBlocks.set(s, block);
887
+ if (isLast === false)
888
+ currentBlocks = block.children;
889
+ }
890
+ });
891
+ return blocks;
892
+ }
893
+ function renderAtomicStyleBlocks(blocks) {
894
+ let rendered = "";
895
+ blocks.forEach((block, selector) => {
896
+ rendered += `${selector}{${block.content.join(";")}`;
897
+ if (block.children != null)
898
+ rendered += renderAtomicStyleBlocks(block.children);
899
+ rendered += "}";
900
+ });
901
+ return rendered;
902
+ }
903
+ function renderAtomicStyles(payload) {
904
+ const blocks = prepareAtomicStyleBlocks(payload);
905
+ return renderAtomicStyleBlocks(blocks);
906
+ }
907
+
908
+ function createDefineEnginePluginFn() {
909
+ return function defineEnginePlugin2(plugin) {
910
+ return plugin;
911
+ };
912
+ }
913
+ const defineEnginePlugin = createDefineEnginePluginFn();
914
+ function createDefineEngineConfigFn() {
915
+ return function defineEngineConfig2(config) {
916
+ return config;
917
+ };
918
+ }
919
+ const defineEngineConfig = createDefineEngineConfigFn();
920
+
921
+ exports.appendAutocompleteCssPropertyValues = appendAutocompleteCssPropertyValues;
922
+ exports.appendAutocompleteExtraCssProperties = appendAutocompleteExtraCssProperties;
923
+ exports.appendAutocompleteExtraProperties = appendAutocompleteExtraProperties;
924
+ exports.appendAutocompletePropertyValues = appendAutocompletePropertyValues;
925
+ exports.appendAutocompleteSelectors = appendAutocompleteSelectors;
926
+ exports.appendAutocompleteStyleItemStrings = appendAutocompleteStyleItemStrings;
927
+ exports.createDefineEngineConfigFn = createDefineEngineConfigFn;
928
+ exports.createDefineEnginePluginFn = createDefineEnginePluginFn;
929
+ exports.createEngine = createEngine;
930
+ exports.defineEngineConfig = defineEngineConfig;
931
+ exports.defineEnginePlugin = defineEnginePlugin;