@pikacss/core 0.0.44 → 0.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +8277 -112
- package/dist/index.mjs +140 -54
- package/package.json +2 -4
package/dist/index.mjs
CHANGED
|
@@ -60,6 +60,7 @@ function numberToChars(num) {
|
|
|
60
60
|
}
|
|
61
61
|
const UPPER_CASE = /[A-Z]/g;
|
|
62
62
|
function toKebab(str) {
|
|
63
|
+
if (str.startsWith("--")) return str;
|
|
63
64
|
return str.replace(UPPER_CASE, (c) => `-${c.toLowerCase()}`);
|
|
64
65
|
}
|
|
65
66
|
function isNotNullish(value) {
|
|
@@ -69,9 +70,9 @@ function isNotString(value) {
|
|
|
69
70
|
return typeof value !== "string";
|
|
70
71
|
}
|
|
71
72
|
function isPropertyValue(v) {
|
|
72
|
-
if (Array.isArray(v)) return v.length === 2 &&
|
|
73
|
+
if (Array.isArray(v)) return v.length === 2 && typeof v[0] === "string" && Array.isArray(v[1]) && v[1].every((i) => typeof i === "string");
|
|
73
74
|
if (v == null) return true;
|
|
74
|
-
if (typeof v === "string"
|
|
75
|
+
if (typeof v === "string") return true;
|
|
75
76
|
return false;
|
|
76
77
|
}
|
|
77
78
|
function serialize(value) {
|
|
@@ -135,7 +136,22 @@ function normalizeSelectors({ selectors, defaultSelector }) {
|
|
|
135
136
|
}
|
|
136
137
|
function normalizeValue(value) {
|
|
137
138
|
if (value == null) return value;
|
|
138
|
-
|
|
139
|
+
if (Array.isArray(value)) {
|
|
140
|
+
const [primary, fallbacks] = value;
|
|
141
|
+
const p = primary.trim();
|
|
142
|
+
const seen = new Set([p]);
|
|
143
|
+
const result = [];
|
|
144
|
+
for (const v of fallbacks) {
|
|
145
|
+
const s = v.trim();
|
|
146
|
+
if (!seen.has(s)) {
|
|
147
|
+
seen.add(s);
|
|
148
|
+
result.push(s);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
result.push(p);
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
return [value.trim()];
|
|
139
155
|
}
|
|
140
156
|
async function extract({ styleDefinition, levels = [], result = [], defaultSelector, transformSelectors, transformStyleItems, transformStyleDefinitions }) {
|
|
141
157
|
for (const definition of await transformStyleDefinitions([styleDefinition])) for (const [k, v] of Object.entries(definition)) if (isPropertyValue(v)) {
|
|
@@ -183,35 +199,41 @@ function createExtractFn(options) {
|
|
|
183
199
|
//#region src/internal/plugin.ts
|
|
184
200
|
async function execAsyncHook(plugins, hook, payload) {
|
|
185
201
|
log.debug(`Executing async hook: ${hook}`);
|
|
202
|
+
let current = payload;
|
|
186
203
|
for (const plugin of plugins) {
|
|
187
|
-
|
|
204
|
+
const pluginRecord = plugin;
|
|
205
|
+
if (pluginRecord[hook] == null) continue;
|
|
188
206
|
try {
|
|
189
207
|
log.debug(` - Plugin "${plugin.name}" executing ${hook}`);
|
|
190
|
-
const
|
|
191
|
-
|
|
208
|
+
const hookFn = pluginRecord[hook];
|
|
209
|
+
const newPayload = await hookFn(current);
|
|
210
|
+
if (newPayload != null) current = newPayload;
|
|
192
211
|
log.debug(` - Plugin "${plugin.name}" completed ${hook}`);
|
|
193
212
|
} catch (error) {
|
|
194
|
-
log.error(`Plugin "${plugin.name}" failed to execute hook "${hook}": ${error.message}`, error);
|
|
213
|
+
log.error(`Plugin "${plugin.name}" failed to execute hook "${hook}": ${error instanceof Error ? error.message : error}`, error);
|
|
195
214
|
}
|
|
196
215
|
}
|
|
197
216
|
log.debug(`Async hook "${hook}" completed`);
|
|
198
|
-
return
|
|
217
|
+
return current;
|
|
199
218
|
}
|
|
200
219
|
function execSyncHook(plugins, hook, payload) {
|
|
201
220
|
log.debug(`Executing sync hook: ${hook}`);
|
|
221
|
+
let current = payload;
|
|
202
222
|
for (const plugin of plugins) {
|
|
203
|
-
|
|
223
|
+
const pluginRecord = plugin;
|
|
224
|
+
if (pluginRecord[hook] == null) continue;
|
|
204
225
|
try {
|
|
205
226
|
log.debug(` - Plugin "${plugin.name}" executing ${hook}`);
|
|
206
|
-
const
|
|
207
|
-
|
|
227
|
+
const hookFn = pluginRecord[hook];
|
|
228
|
+
const newPayload = hookFn(current);
|
|
229
|
+
if (newPayload != null) current = newPayload;
|
|
208
230
|
log.debug(` - Plugin "${plugin.name}" completed ${hook}`);
|
|
209
231
|
} catch (error) {
|
|
210
|
-
log.error(`Plugin "${plugin.name}" failed to execute hook "${hook}": ${error.message}`, error);
|
|
232
|
+
log.error(`Plugin "${plugin.name}" failed to execute hook "${hook}": ${error instanceof Error ? error.message : error}`, error);
|
|
211
233
|
}
|
|
212
234
|
}
|
|
213
235
|
log.debug(`Sync hook "${hook}" completed`);
|
|
214
|
-
return
|
|
236
|
+
return current;
|
|
215
237
|
}
|
|
216
238
|
const hooks = {
|
|
217
239
|
configureRawConfig: (plugins, config) => execAsyncHook(plugins, "configureRawConfig", config),
|
|
@@ -231,7 +253,7 @@ const orderMap = new Map([
|
|
|
231
253
|
["post", 2]
|
|
232
254
|
]);
|
|
233
255
|
function resolvePlugins(plugins) {
|
|
234
|
-
return plugins.sort((a, b) => orderMap.get(a.order) - orderMap.get(b.order));
|
|
256
|
+
return [...plugins].sort((a, b) => orderMap.get(a.order) - orderMap.get(b.order));
|
|
235
257
|
}
|
|
236
258
|
/* c8 ignore start */
|
|
237
259
|
function defineEnginePlugin(plugin) {
|
|
@@ -241,10 +263,13 @@ function defineEnginePlugin(plugin) {
|
|
|
241
263
|
|
|
242
264
|
//#endregion
|
|
243
265
|
//#region src/internal/plugins/important.ts
|
|
266
|
+
function appendImportant(v) {
|
|
267
|
+
return v.endsWith("!important") ? v : `${v} !important`;
|
|
268
|
+
}
|
|
244
269
|
function modifyPropertyValue(value) {
|
|
245
270
|
if (value == null) return null;
|
|
246
|
-
if (Array.isArray(value)) return [
|
|
247
|
-
return
|
|
271
|
+
if (Array.isArray(value)) return [appendImportant(value[0]), value[1].map((i) => appendImportant(i))];
|
|
272
|
+
return appendImportant(value);
|
|
248
273
|
}
|
|
249
274
|
function important() {
|
|
250
275
|
let defaultValue;
|
|
@@ -301,7 +326,7 @@ function keyframes() {
|
|
|
301
326
|
engine.addPreflight((engine) => {
|
|
302
327
|
const maybeUsedName = /* @__PURE__ */ new Set();
|
|
303
328
|
engine.store.atomicStyles.forEach(({ content: { property, value } }) => {
|
|
304
|
-
if (property === "
|
|
329
|
+
if (property === "animation-name") {
|
|
305
330
|
value.forEach((name) => maybeUsedName.add(name));
|
|
306
331
|
return;
|
|
307
332
|
}
|
|
@@ -350,6 +375,10 @@ function createResolveConfigFn({ pruneUnused: defaultPruneUnused = true } = {})
|
|
|
350
375
|
|
|
351
376
|
//#endregion
|
|
352
377
|
//#region src/internal/resolver.ts
|
|
378
|
+
function stripGlobalFlag(re) {
|
|
379
|
+
if (!re.global) return re;
|
|
380
|
+
return new RegExp(re.source, re.flags.replace("g", ""));
|
|
381
|
+
}
|
|
353
382
|
var AbstractResolver = class {
|
|
354
383
|
_resolvedResultsMap = /* @__PURE__ */ new Map();
|
|
355
384
|
staticRulesMap = /* @__PURE__ */ new Map();
|
|
@@ -389,7 +418,10 @@ var AbstractResolver = class {
|
|
|
389
418
|
return this;
|
|
390
419
|
}
|
|
391
420
|
log.debug(`Removing dynamic rule: ${key}`);
|
|
392
|
-
const matchedResolvedStringList = Array.from(this._resolvedResultsMap.keys()).filter((string) =>
|
|
421
|
+
const matchedResolvedStringList = Array.from(this._resolvedResultsMap.keys()).filter((string) => {
|
|
422
|
+
rule.stringPattern.lastIndex = 0;
|
|
423
|
+
return rule.stringPattern.test(string);
|
|
424
|
+
});
|
|
393
425
|
this.dynamicRulesMap.delete(key);
|
|
394
426
|
matchedResolvedStringList.forEach((string) => this._resolvedResultsMap.delete(string));
|
|
395
427
|
log.debug(` - Cleared ${matchedResolvedStringList.length} cached results`);
|
|
@@ -412,7 +444,8 @@ var AbstractResolver = class {
|
|
|
412
444
|
let dynamicRule;
|
|
413
445
|
let matched;
|
|
414
446
|
for (const rule of this.dynamicRulesMap.values()) {
|
|
415
|
-
|
|
447
|
+
rule.stringPattern.lastIndex = 0;
|
|
448
|
+
matched = rule.stringPattern.exec(string);
|
|
416
449
|
if (matched != null) {
|
|
417
450
|
dynamicRule = rule;
|
|
418
451
|
break;
|
|
@@ -437,13 +470,19 @@ var AbstractResolver = class {
|
|
|
437
470
|
}
|
|
438
471
|
};
|
|
439
472
|
var RecursiveResolver = class extends AbstractResolver {
|
|
440
|
-
async resolve(string) {
|
|
473
|
+
async resolve(string, _visited) {
|
|
474
|
+
const visited = _visited ?? /* @__PURE__ */ new Set();
|
|
475
|
+
if (visited.has(string)) {
|
|
476
|
+
log.warn(`Circular reference detected for "${string}", returning as-is`);
|
|
477
|
+
return [string];
|
|
478
|
+
}
|
|
479
|
+
visited.add(string);
|
|
441
480
|
const resolved = await this._resolve(string).catch((error) => {
|
|
442
481
|
log.warn(`Failed to resolve "${string}": ${error.message}`, error);
|
|
443
482
|
});
|
|
444
483
|
if (resolved == null) return [string];
|
|
445
484
|
const result = [];
|
|
446
|
-
for (const partial of resolved.value) if (typeof partial === "string") result.push(...await this.resolve(partial));
|
|
485
|
+
for (const partial of resolved.value) if (typeof partial === "string") result.push(...await this.resolve(partial, new Set(visited)));
|
|
447
486
|
else result.push(partial);
|
|
448
487
|
this._setResolvedResult(string, result);
|
|
449
488
|
return result;
|
|
@@ -467,7 +506,7 @@ function resolveRuleConfig(config, keyName) {
|
|
|
467
506
|
type: "dynamic",
|
|
468
507
|
rule: {
|
|
469
508
|
key: config[0].source,
|
|
470
|
-
stringPattern: config[0],
|
|
509
|
+
stringPattern: stripGlobalFlag(config[0]),
|
|
471
510
|
createResolved: async (match) => [await fn(match)].flat(1)
|
|
472
511
|
},
|
|
473
512
|
autocomplete: config[2] != null ? [config[2]].flat(1) : []
|
|
@@ -492,7 +531,7 @@ function resolveRuleConfig(config, keyName) {
|
|
|
492
531
|
type: "dynamic",
|
|
493
532
|
rule: {
|
|
494
533
|
key: configKey.source,
|
|
495
|
-
stringPattern: configKey,
|
|
534
|
+
stringPattern: stripGlobalFlag(configKey),
|
|
496
535
|
createResolved: async (match) => [await fn(match)].flat(1)
|
|
497
536
|
},
|
|
498
537
|
autocomplete: "autocomplete" in config && config.autocomplete != null ? [config.autocomplete].flat(1) : []
|
|
@@ -645,23 +684,46 @@ function variables() {
|
|
|
645
684
|
}
|
|
646
685
|
};
|
|
647
686
|
rawVariables.forEach((variables) => engine.variables.add(variables));
|
|
648
|
-
engine.addPreflight(
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
current[s] ||= {};
|
|
660
|
-
current = current[s];
|
|
687
|
+
engine.addPreflight({
|
|
688
|
+
id: "core:variables",
|
|
689
|
+
preflight: async (engine) => {
|
|
690
|
+
const used = /* @__PURE__ */ new Set();
|
|
691
|
+
engine.store.atomicStyles.forEach(({ content: { value } }) => {
|
|
692
|
+
value.flatMap(extractUsedVarNames).forEach((name) => used.add(normalizeVariableName(name)));
|
|
693
|
+
});
|
|
694
|
+
const otherPreflights = engine.config.preflights.filter((p) => p.id !== "core:variables");
|
|
695
|
+
(await Promise.all(otherPreflights.map(({ fn }) => Promise.resolve(fn(engine, false)).catch(() => null)))).forEach((result) => {
|
|
696
|
+
if (result == null) return;
|
|
697
|
+
extractUsedVarNamesFromPreflightResult(result).forEach((name) => used.add(name));
|
|
661
698
|
});
|
|
662
|
-
|
|
699
|
+
const varMap = /* @__PURE__ */ new Map();
|
|
700
|
+
for (const [name, list] of engine.variables.store.entries()) varMap.set(name, list);
|
|
701
|
+
const queue = Array.from(used);
|
|
702
|
+
while (queue.length > 0) {
|
|
703
|
+
const name = queue.pop();
|
|
704
|
+
const entries = varMap.get(name);
|
|
705
|
+
if (!entries) continue;
|
|
706
|
+
for (const { value } of entries) {
|
|
707
|
+
if (value == null) continue;
|
|
708
|
+
for (const refName of extractUsedVarNames(String(value)).map(normalizeVariableName)) if (!used.has(refName)) {
|
|
709
|
+
used.add(refName);
|
|
710
|
+
queue.push(refName);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
const usedVariables = Array.from(engine.variables.store.values()).flat().filter(({ name, pruneUnused, value }) => (safeSet.has(name) || pruneUnused === false || used.has(name)) && value != null);
|
|
715
|
+
const preflightDefinition = {};
|
|
716
|
+
for (const { name, value, selector: _selector } of usedVariables) {
|
|
717
|
+
const selector = await engine.pluginHooks.transformSelectors(engine.config.plugins, _selector);
|
|
718
|
+
let current = preflightDefinition;
|
|
719
|
+
selector.forEach((s) => {
|
|
720
|
+
current[s] ||= {};
|
|
721
|
+
current = current[s];
|
|
722
|
+
});
|
|
723
|
+
Object.assign(current, { [name]: value });
|
|
724
|
+
}
|
|
725
|
+
return preflightDefinition;
|
|
663
726
|
}
|
|
664
|
-
return preflightDefinition;
|
|
665
727
|
});
|
|
666
728
|
}
|
|
667
729
|
});
|
|
@@ -689,17 +751,26 @@ function createResolveVariablesFn({ pruneUnused: defaultPruneUnused = true } = {
|
|
|
689
751
|
}
|
|
690
752
|
const VAR_NAME_RE = /var\((--[\w-]+)/g;
|
|
691
753
|
function extractUsedVarNames(input) {
|
|
692
|
-
|
|
693
|
-
if (!matched) return [];
|
|
694
|
-
return matched.map((match) => {
|
|
695
|
-
const varNameMatch = match.match(/--[^,)]+/);
|
|
696
|
-
return varNameMatch ? varNameMatch[0] : "";
|
|
697
|
-
}).filter(Boolean);
|
|
754
|
+
return Array.from(input.matchAll(VAR_NAME_RE), (m) => m[1]);
|
|
698
755
|
}
|
|
699
756
|
function normalizeVariableName(name) {
|
|
700
757
|
if (name.startsWith("--")) return name;
|
|
701
758
|
return `--${name}`;
|
|
702
759
|
}
|
|
760
|
+
/**
|
|
761
|
+
* Recursively extract all CSS variable names referenced inside a preflight
|
|
762
|
+
* result (either a plain CSS string or a `PreflightDefinition` object).
|
|
763
|
+
*/
|
|
764
|
+
function extractUsedVarNamesFromPreflightResult(result) {
|
|
765
|
+
if (typeof result === "string") return extractUsedVarNames(result).map(normalizeVariableName);
|
|
766
|
+
const names = [];
|
|
767
|
+
for (const value of Object.values(result)) {
|
|
768
|
+
if (value == null) continue;
|
|
769
|
+
if (typeof value === "string" || typeof value === "number") extractUsedVarNames(String(value)).forEach((n) => names.push(normalizeVariableName(n)));
|
|
770
|
+
else if (typeof value === "object") extractUsedVarNamesFromPreflightResult(value).forEach((n) => names.push(n));
|
|
771
|
+
}
|
|
772
|
+
return names;
|
|
773
|
+
}
|
|
703
774
|
|
|
704
775
|
//#endregion
|
|
705
776
|
//#region src/internal/engine.ts
|
|
@@ -720,10 +791,13 @@ async function createEngine(config = {}) {
|
|
|
720
791
|
];
|
|
721
792
|
log.debug("Core plugins loaded:", corePlugins.length);
|
|
722
793
|
const plugins = resolvePlugins([...corePlugins, ...config.plugins || []]);
|
|
723
|
-
config
|
|
794
|
+
config = {
|
|
795
|
+
...config,
|
|
796
|
+
plugins
|
|
797
|
+
};
|
|
724
798
|
log.debug(`Total plugins resolved: ${plugins.length}`);
|
|
725
799
|
config = await hooks.configureRawConfig(config.plugins, config);
|
|
726
|
-
hooks.rawConfigConfigured(resolvePlugins(config.plugins
|
|
800
|
+
hooks.rawConfigConfigured(resolvePlugins(config.plugins ?? []), config);
|
|
727
801
|
let resolvedConfig = await resolveEngineConfig(config);
|
|
728
802
|
log.debug("Engine config resolved with prefix:", resolvedConfig.prefix);
|
|
729
803
|
resolvedConfig = await hooks.configureResolvedConfig(resolvedConfig.plugins, resolvedConfig);
|
|
@@ -886,18 +960,29 @@ function sortLayerNames(layers) {
|
|
|
886
960
|
function isWithLayer(p) {
|
|
887
961
|
if (typeof p !== "object" || p === null) return false;
|
|
888
962
|
const record = p;
|
|
889
|
-
return typeof record.layer === "string" &&
|
|
963
|
+
return typeof record.layer === "string" && record.preflight !== void 0;
|
|
964
|
+
}
|
|
965
|
+
function isWithId(p) {
|
|
966
|
+
if (typeof p !== "object" || p === null) return false;
|
|
967
|
+
const record = p;
|
|
968
|
+
return typeof record.id === "string" && record.preflight !== void 0;
|
|
890
969
|
}
|
|
891
970
|
function resolvePreflight(preflight) {
|
|
971
|
+
let layer;
|
|
972
|
+
let id;
|
|
892
973
|
if (isWithLayer(preflight)) {
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
974
|
+
layer = preflight.layer;
|
|
975
|
+
preflight = preflight.preflight;
|
|
976
|
+
}
|
|
977
|
+
if (isWithId(preflight)) {
|
|
978
|
+
id = preflight.id;
|
|
979
|
+
preflight = preflight.preflight;
|
|
899
980
|
}
|
|
900
|
-
return {
|
|
981
|
+
return {
|
|
982
|
+
layer,
|
|
983
|
+
id,
|
|
984
|
+
fn: typeof preflight === "function" ? preflight : () => preflight
|
|
985
|
+
};
|
|
901
986
|
}
|
|
902
987
|
async function resolveEngineConfig(config) {
|
|
903
988
|
const { prefix = "", defaultSelector = `.${ATOMIC_STYLE_ID_PLACEHOLDER}`, plugins = [], preflights = [] } = config;
|
|
@@ -1063,6 +1148,7 @@ async function _renderPreflightDefinition({ engine, preflightDefinition, blocks
|
|
|
1063
1148
|
selectors: await hooks.transformSelectors(engine.config.plugins, [selector]),
|
|
1064
1149
|
defaultSelector: ""
|
|
1065
1150
|
}).filter(Boolean);
|
|
1151
|
+
if (selectors.length === 0) continue;
|
|
1066
1152
|
let currentBlocks = blocks;
|
|
1067
1153
|
let currentBlockBody = null;
|
|
1068
1154
|
selectors.forEach((s, i) => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikacss/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.46",
|
|
5
5
|
"author": "DevilTea <ch19980814@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -34,10 +34,8 @@
|
|
|
34
34
|
"files": [
|
|
35
35
|
"dist"
|
|
36
36
|
],
|
|
37
|
-
"dependencies": {
|
|
38
|
-
"csstype": "^3.2.3"
|
|
39
|
-
},
|
|
40
37
|
"scripts": {
|
|
38
|
+
"generate:csstype": "tsx ./scripts/generate-csstype.ts",
|
|
41
39
|
"build": "tsdown && pnpm exec publint",
|
|
42
40
|
"build:watch": "tsdown --watch",
|
|
43
41
|
"typecheck": "pnpm typecheck:package && pnpm typecheck:test",
|