@teacss/engine 0.8.5-alpha.4 → 0.9.0-alpha.4
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 +4 -4
- package/binding-header.d.ts +23 -0
- package/binding.d.ts +26 -1
- package/binding.js +54 -54
- package/contract.d.ts +290 -0
- package/dist/config-view.d.ts +27 -0
- package/dist/config-view.js +98 -0
- package/dist/constants.d.ts +22 -0
- package/{src/facade/constants.mjs → dist/constants.js} +11 -12
- package/dist/countable-set.d.ts +57 -0
- package/dist/countable-set.js +205 -0
- package/dist/errors.d.ts +11 -0
- package/dist/errors.js +18 -0
- package/dist/generator.d.ts +155 -0
- package/dist/generator.js +818 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +10 -0
- package/dist/result.d.ts +83 -0
- package/dist/result.js +142 -0
- package/dist/select.d.ts +175 -0
- package/dist/select.js +680 -0
- package/dist/transformer.d.ts +44 -0
- package/dist/transformer.js +59 -0
- package/dist/ts-fallback.d.ts +32 -0
- package/dist/ts-fallback.js +78 -0
- package/package.json +46 -29
- package/index.d.ts +0 -387
- package/index.js +0 -2
- package/src/facade/config-view.mjs +0 -82
- package/src/facade/countable-set.mjs +0 -179
- package/src/facade/errors.mjs +0 -22
- package/src/facade/generator.mjs +0 -812
- package/src/facade/index.mjs +0 -19
- package/src/facade/result.mjs +0 -157
- package/src/facade/select.mjs +0 -635
- package/src/facade/transformer.mjs +0 -56
- package/src/facade/ts-fallback.mjs +0 -88
package/src/facade/index.mjs
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
// Facade modules import `Engine`, `expandClassGroups`, `splitClassTokens` and `version` from
|
|
3
|
-
// `../../binding.js`, never from `index.js`, which re-exports this file (a cycle otherwise).
|
|
4
|
-
// This file imports no peer (`@teacss/core`, `@teacss/config`).
|
|
5
|
-
export {
|
|
6
|
-
CONFIG_ENTRY_PROVENANCE,
|
|
7
|
-
CONFIG_SOURCE_DECLARATIONS,
|
|
8
|
-
ENGINE_COMPAT,
|
|
9
|
-
ENGINE_INSTANCE,
|
|
10
|
-
ENGINE_MATERIALIZE,
|
|
11
|
-
ENGINE_PACKAGE_VERSION,
|
|
12
|
-
ENGINE_STATS,
|
|
13
|
-
PRESET_OPTIONS,
|
|
14
|
-
} from "./constants.mjs";
|
|
15
|
-
export { translateConfig } from "./select.mjs";
|
|
16
|
-
export { TeacssEngineError } from "./errors.mjs";
|
|
17
|
-
export { selectEngineRequest } from "./select.mjs";
|
|
18
|
-
export { createGenerator, FacadeGenerator, engineStats, reportFallback } from "./generator.mjs";
|
|
19
|
-
export { createCompileClassTransformer } from "./transformer.mjs";
|
package/src/facade/result.mjs
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
// The facade's `generate` result, shaped like the 0.8.2 `GenerateResult` (core/generator.ts:1540-1575).
|
|
3
|
-
|
|
4
|
-
/** @typedef {{ index: number, selector: string | null, body: string, parent: string | null, meta: Record<string, unknown> | null, noMerge: boolean | null }} RustUtil */
|
|
5
|
-
/** @typedef {{ css: string, layers: Array<{ name: string, css: string }>, matched: string[], matchedInfo: Array<{ token: string, data: RustUtil[], count: number }> | null, programKey: string }} RustGenerateResult */
|
|
6
|
-
|
|
7
|
-
/** @param {string[]} items */
|
|
8
|
-
export function uniq(items) {
|
|
9
|
-
return [...new Set(items)];
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* By `configuredLayers[name] ?? 0`, ties by UTF-16 code units (generator.ts:1310-1312).
|
|
14
|
-
* @param {string[]} names @param {Record<string, number>} configuredLayers
|
|
15
|
-
*/
|
|
16
|
-
export function sortLayerNames(names, configuredLayers) {
|
|
17
|
-
/** @param {string} layer */
|
|
18
|
-
const order = (layer) => (Object.hasOwn(configuredLayers, layer) ? (configuredLayers[layer] ?? 0) : 0);
|
|
19
|
-
return [...names].sort((a, b) => order(a) - order(b) || (a < b ? -1 : a > b ? 1 : 0));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* A v02.2 `StringifiedUtil` as the oracle 7-tuple; `null` meta values are dropped and the
|
|
24
|
-
* context slot is always `undefined`.
|
|
25
|
-
* @param {RustUtil} util
|
|
26
|
-
*/
|
|
27
|
-
export function toTuple(util) {
|
|
28
|
-
/** @type {Record<string, unknown> | undefined} */
|
|
29
|
-
let meta;
|
|
30
|
-
if (util.meta) {
|
|
31
|
-
meta = {};
|
|
32
|
-
for (const [key, value] of Object.entries(util.meta)) if (value !== null && value !== undefined) meta[key] = value;
|
|
33
|
-
}
|
|
34
|
-
return [util.index, util.selector ?? undefined, util.body, util.parent ?? undefined, meta, undefined, util.noMerge ?? undefined];
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** @param {{ rust: RustGenerateResult, extendedInfo: boolean, countOf?: (token: string, rustCount: number) => number }} args */
|
|
38
|
-
export function buildMatched({ rust, extendedInfo, countOf }) {
|
|
39
|
-
if (!extendedInfo) return new Set(rust.matched);
|
|
40
|
-
return new Map((rust.matchedInfo ?? []).map(({ token, data, count }) => [token, { data: data.map(toTuple), count: countOf ? countOf(token, count) : count }]));
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/** @param {{ token: string, suggestions: string[] }} diagnostic */
|
|
44
|
-
export function describeUnmatched({ token, suggestions }) {
|
|
45
|
-
return suggestions.length ? `"${token}" (did you mean ${suggestions.map((s) => `"${s}"`).join(", ")}?)` : `"${token}"`;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** The `unmatched: "error"` message (generator.ts:2574). @param {Array<{ token: string, suggestions: string[] }>} diagnosed */
|
|
49
|
-
export function formatUnmatchedError(diagnosed) {
|
|
50
|
-
return `[@teacss/core] ${diagnosed.length} token${diagnosed.length === 1 ? "" : "s"} matched no rule: ${diagnosed.map(describeUnmatched).join("; ")}`;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const TOKEN_PREFIX_RE = /^[a-z][a-z0-9-]*$/;
|
|
54
|
-
const NON_TOKEN_SCHEMES = new Set(["about", "blob", "bun", "chrome", "data", "deno", "file", "ftp", "http", "https", "jsr", "mailto", "node", "npm", "tel", "urn", "vscode", "virtual", "ws", "wss"]);
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* `tokenConditionBase` (unmatched-diagnostics.ts:49): the token before its first depth-0 `@`, the
|
|
58
|
-
* `!` kept. As in `parseClassToken` (token.ts:54), only `()` and `[]` nest, and quotes, escapes
|
|
59
|
-
* and comments count inside them; an unclosed comment ends the scan.
|
|
60
|
-
* @param {string} raw
|
|
61
|
-
*/
|
|
62
|
-
function tokenConditionBase(raw) {
|
|
63
|
-
let closers = "";
|
|
64
|
-
/** @type {string | undefined} */
|
|
65
|
-
let quote;
|
|
66
|
-
for (let index = 0; index < raw.length; index++) {
|
|
67
|
-
const character = raw[index];
|
|
68
|
-
if (quote) {
|
|
69
|
-
if (character === "\\") index++;
|
|
70
|
-
else if (character === quote) quote = undefined;
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
if (closers.length > 0) {
|
|
74
|
-
if (character === "\\") {
|
|
75
|
-
index++;
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
if (character === '"' || character === "'") {
|
|
79
|
-
quote = character;
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
if (character === "/" && raw[index + 1] === "*") {
|
|
83
|
-
const close = raw.indexOf("*/", index + 2);
|
|
84
|
-
if (close < 0) break;
|
|
85
|
-
index = close + 1;
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
if (character === "(" || character === "[") closers += character === "(" ? ")" : "]";
|
|
90
|
-
else if (character === closers.at(-1)) closers = closers.slice(0, -1);
|
|
91
|
-
else if (closers.length === 0 && character === "@") return raw.slice(0, index);
|
|
92
|
-
}
|
|
93
|
-
return raw;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* `isTokenShaped` (unmatched-diagnostics.ts:59-70), for when no `@teacss/core` host is present.
|
|
98
|
-
* @param {string} token
|
|
99
|
-
*/
|
|
100
|
-
export function fallbackIsTokenShaped(token) {
|
|
101
|
-
const base = tokenConditionBase(token);
|
|
102
|
-
if (!base || base.startsWith("$") || base.startsWith("[")) return false;
|
|
103
|
-
const separator = base.indexOf(":");
|
|
104
|
-
if (separator <= 0 || separator === base.length - 1) return false;
|
|
105
|
-
const prefix = base.slice(0, separator);
|
|
106
|
-
if (!TOKEN_PREFIX_RE.test(prefix)) return false;
|
|
107
|
-
if (base.startsWith("//", separator + 1)) return false;
|
|
108
|
-
return !NON_TOKEN_SCHEMES.has(prefix);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* @param {{ rust: RustGenerateResult, matched: Set<string> | Map<string, unknown>, minify: boolean, outputToCssLayers: boolean | { allLayers?: boolean } | null | undefined, configuredLayers: Record<string, number>, resolveUnmatched: () => Array<{ token: string, suggestions: string[] }> }} args
|
|
113
|
-
*/
|
|
114
|
-
export function createFacadeResult({ rust, matched, minify, outputToCssLayers, configuredLayers, resolveUnmatched }) {
|
|
115
|
-
const nl = minify ? "" : "\n";
|
|
116
|
-
const orderedLayers = rust.layers.map((layer) => layer.name);
|
|
117
|
-
/** @type {Record<string, string>} */
|
|
118
|
-
const layerCache = Object.create(null);
|
|
119
|
-
for (const layer of rust.layers) layerCache[layer.name] = layer.css;
|
|
120
|
-
const allCssLayers = typeof outputToCssLayers === "object" && outputToCssLayers !== null && outputToCssLayers.allLayers ? sortLayerNames(uniq([...Object.keys(configuredLayers), ...orderedLayers]), configuredLayers) : undefined;
|
|
121
|
-
|
|
122
|
-
const getLayer = (layer = "utilities") => (Object.hasOwn(layerCache, layer) ? layerCache[layer] : "");
|
|
123
|
-
/** @param {string[]} [includes] @param {string[]} [excludes] */
|
|
124
|
-
const getLayers = (includes = orderedLayers, excludes) => {
|
|
125
|
-
const excluded = new Set(excludes ?? []);
|
|
126
|
-
const selected = [...includes].filter((layer) => !excluded.has(layer));
|
|
127
|
-
const css = selected.map((layer) => getLayer(layer)).filter(Boolean);
|
|
128
|
-
if (outputToCssLayers) {
|
|
129
|
-
const names = uniq(allCssLayers ?? selected);
|
|
130
|
-
if (names.length > 0) css.unshift(`@layer ${names.join(", ")};`);
|
|
131
|
-
}
|
|
132
|
-
return css.join(nl);
|
|
133
|
-
};
|
|
134
|
-
/** @param {string} layer @param {(content: string) => string | Promise<string>} callback */
|
|
135
|
-
const setLayer = async (layer, callback) => {
|
|
136
|
-
const content = await callback(getLayer(layer));
|
|
137
|
-
layerCache[layer] = content;
|
|
138
|
-
return content;
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
/** @type {{ unmatched: Array<{ token: string, suggestions: string[] }> } | undefined} */
|
|
142
|
-
let diagnostics;
|
|
143
|
-
return {
|
|
144
|
-
get css() {
|
|
145
|
-
return getLayers();
|
|
146
|
-
},
|
|
147
|
-
layers: [...orderedLayers],
|
|
148
|
-
matched,
|
|
149
|
-
getLayers,
|
|
150
|
-
getLayer,
|
|
151
|
-
setLayer,
|
|
152
|
-
get diagnostics() {
|
|
153
|
-
diagnostics ??= { unmatched: resolveUnmatched() };
|
|
154
|
-
return diagnostics;
|
|
155
|
-
},
|
|
156
|
-
};
|
|
157
|
-
}
|