@teacss/engine 0.8.5-alpha.4 → 0.9.0-alpha.3

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.
@@ -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";
@@ -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
- }