@teacss/engine 0.9.4 → 0.10.2

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,205 +0,0 @@
1
- // Token collections the facade shares with `@teacss/core`: CountableSet (core/utils/countable-set.ts),
2
- // expandInputGroups (core/generator.ts:517-535) and the FIFO caches of core/bounded-cache.ts.
3
- import { expandClassGroups, splitClassTokens } from "../binding.js";
4
- export const MAX_RUNTIME_CACHE_ENTRIES = 10_000;
5
- export class CountableSet extends Set {
6
- _map = new Map();
7
- constructor(values) {
8
- super();
9
- if (values)
10
- for (const key of values)
11
- this.add(key);
12
- }
13
- add(key) {
14
- this._map.set(key, (this._map.get(key) ?? 0) + 1);
15
- return super.add(key);
16
- }
17
- delete(key) {
18
- if (!this._map.has(key))
19
- return false;
20
- this._map.delete(key);
21
- return super.delete(key);
22
- }
23
- clear() {
24
- this._map.clear();
25
- super.clear();
26
- }
27
- getCount(key) {
28
- return this._map.get(key) ?? 0;
29
- }
30
- setCount(key, count) {
31
- this._map.set(key, count);
32
- return super.add(key);
33
- }
34
- }
35
- export function isCountableSet(value) {
36
- return value instanceof CountableSet;
37
- }
38
- export function copyCountableSet(input) {
39
- const copied = new CountableSet();
40
- for (const key of input)
41
- copied.setCount(key, input.getCount(key));
42
- return copied;
43
- }
44
- /**
45
- * Expands the tokens holding a `{…}` group in place; the parts go to the end, and a counted
46
- * group's count carries over to each part.
47
- */
48
- export function expandInputGroups(tokens) {
49
- const expanded = [...tokens].filter((token) => token.includes("{"));
50
- if (expanded.length === 0)
51
- return tokens;
52
- for (const token of expanded) {
53
- const parts = splitClassTokens(expandClassGroups(token));
54
- if (parts.length === 1 && parts[0] === token)
55
- continue;
56
- const count = isCountableSet(tokens) ? tokens.getCount(token) : 1;
57
- tokens.delete(token);
58
- for (const part of parts) {
59
- if (isCountableSet(tokens))
60
- tokens.setCount(part, tokens.getCount(part) + count);
61
- else
62
- tokens.add(part);
63
- }
64
- }
65
- return tokens;
66
- }
67
- /** The value of an entry whose token has not been resolved yet; never a valid `V`. */
68
- const PENDING = Symbol("@teacss/engine/pending");
69
- function noResolver(token) {
70
- throw new TypeError(`[@teacss/engine] pending cache entry "${token}" has no resolver`);
71
- }
72
- /**
73
- * The part of the oracle `BoundedMap` the facade uses: ordinary keys are evicted oldest first,
74
- * retained keys never count toward the limit. An entry can be pending (`setPending`,
75
- * `replaceRetainedPending`): its value is `resolve(token)`, computed on the first read through
76
- * `get`, `forEach` or iteration and kept in place; `has`, `size`, `delete` and eviction never
77
- * resolve.
78
- */
79
- export class BoundedTokenCache extends Map {
80
- constructor(maxEntries = MAX_RUNTIME_CACHE_ENTRIES, resolve = noResolver) {
81
- super();
82
- this.maxEntries = maxEntries;
83
- this.retained = new Set();
84
- this.order = new Set();
85
- this.resolve = resolve;
86
- }
87
- get retainedSize() {
88
- return this.retained.size;
89
- }
90
- isRetained(key) {
91
- return this.retained.has(key);
92
- }
93
- get(key) {
94
- const stored = super.get(key);
95
- return stored === PENDING ? this.#materialize(key) : stored;
96
- }
97
- *entries() {
98
- for (const [key, stored] of super.entries())
99
- yield [key, this.#value(key, stored)];
100
- }
101
- *values() {
102
- for (const [key, stored] of super.entries())
103
- yield this.#value(key, stored);
104
- }
105
- [Symbol.iterator]() {
106
- return this.entries();
107
- }
108
- forEach(callback, thisArg) {
109
- for (const [key, value] of this.entries())
110
- callback.call(thisArg, value, key, this);
111
- }
112
- set(key, value) {
113
- return this.#insert(key, value);
114
- }
115
- /** Caches `key` with the value `resolve` supplies on its first read. */
116
- setPending(key) {
117
- return this.#insert(key, PENDING);
118
- }
119
- delete(key) {
120
- const deleted = super.delete(key);
121
- this.order.delete(key);
122
- this.retained.delete(key);
123
- return deleted;
124
- }
125
- clear() {
126
- super.clear();
127
- this.order.clear();
128
- this.retained.clear();
129
- }
130
- /** Replaces the retained entries (bounded-cache.ts:188-205 without the revision check). */
131
- replaceRetained(entries) {
132
- this.#replaceRetained(new Map(entries));
133
- }
134
- /** `replaceRetained` with every value pending. */
135
- replaceRetainedPending(keys) {
136
- const next = new Map();
137
- for (const key of keys)
138
- next.set(key, PENDING);
139
- this.#replaceRetained(next);
140
- }
141
- #value(key, stored) {
142
- return stored === PENDING ? this.#materialize(key) : stored;
143
- }
144
- #materialize(key) {
145
- const value = this.resolve(key);
146
- super.set(key, value);
147
- return value;
148
- }
149
- #insert(key, value) {
150
- const exists = super.has(key);
151
- this.#store(key, value);
152
- if (!exists && !this.retained.has(key))
153
- this.order.add(key);
154
- this.#enforceLimit();
155
- return this;
156
- }
157
- #replaceRetained(next) {
158
- for (const key of this.retained) {
159
- if (next.has(key))
160
- continue;
161
- super.delete(key);
162
- this.retained.delete(key);
163
- }
164
- for (const [key, value] of next) {
165
- this.order.delete(key);
166
- this.#store(key, value);
167
- this.retained.add(key);
168
- }
169
- this.#enforceLimit();
170
- }
171
- /** The marker is stored as a `V`; every read path above resolves it before a caller sees it. */
172
- #store(key, value) {
173
- super.set(key, value);
174
- }
175
- #enforceLimit() {
176
- while (this.size - this.retained.size > this.maxEntries) {
177
- const oldest = this.order.values().next();
178
- if (oldest.done)
179
- break;
180
- this.order.delete(oldest.value);
181
- super.delete(oldest.value);
182
- }
183
- }
184
- }
185
- /** FIFO bounded Set (the oracle `BoundedSet` without its `assumeNoPrototypeBypass` fast path). */
186
- export class BoundedSet extends Set {
187
- constructor(maxEntries = MAX_RUNTIME_CACHE_ENTRIES, values) {
188
- super();
189
- this.maxEntries = maxEntries;
190
- if (values)
191
- for (const value of values)
192
- this.add(value);
193
- }
194
- add(value) {
195
- super.add(value);
196
- while (this.size > this.maxEntries) {
197
- const oldest = this.values().next();
198
- if (oldest.done)
199
- break;
200
- super.delete(oldest.value);
201
- }
202
- return this;
203
- }
204
- }
205
- //# sourceMappingURL=countable-set.js.map
@@ -1,163 +0,0 @@
1
- import { ENGINE_INSTANCE, ENGINE_MATERIALIZE } from "./constants.js";
2
- /** Port of core/utils/events.ts:84-112. */
3
- export declare function createNanoEvents(): {
4
- events: any;
5
- emit(event: string, ...args: unknown[]): void;
6
- on(event: string, cb: Function): () => void;
7
- };
8
- /** Port of core/utils/escape.ts:10-72 (CSSOM "serialize an identifier"). */
9
- export declare function escapeSelector(str: string): string;
10
- /** generator.ts:3722. */
11
- export declare function toEscapedSelector(raw: string): string;
12
- /**
13
- * v02.9 §8.1: the process-wide counters, the same object the teacss-ts hook updates.
14
- */
15
- export declare function engineStats(): {
16
- rust: number;
17
- ts: number;
18
- fallbacks: Record<string, number>;
19
- };
20
- /**
21
- * v02.9 §9: each reason and path prints once per process; the counter grows on every call. A
22
- * host `report(reason, path, level)` (core's `reportFallback`) gets every call and does both
23
- * itself, so the counter is not touched here.
24
- */
25
- export declare function reportFallback(reason: string, path: string, host?: FacadeHost, level?: "info" | "warn"): void;
26
- export declare class FacadeGenerator {
27
- #private;
28
- /** The facade's own emitter; a TS backend's `events` are not forwarded. */
29
- events: {
30
- events: any;
31
- emit(event: string, ...args: unknown[]): void;
32
- on(event: string, cb: Function): () => void;
33
- };
34
- userConfig: Record<string, unknown>;
35
- defaults: Record<string, unknown>;
36
- /**
37
- * An `engine` gives a Rust backend and `ts` a TypeScript one.
38
- */
39
- constructor({ engine, request, presets, transformers, ts, userConfig, defaults, host, transformer, }: {
40
- engine?: any;
41
- request?: object;
42
- presets?: object[];
43
- transformers?: object[];
44
- ts?: any;
45
- userConfig?: Record<string, unknown>;
46
- defaults?: Record<string, unknown>;
47
- host?: {
48
- core?: any;
49
- };
50
- transformer?: object | null;
51
- });
52
- get version(): any;
53
- get config(): any;
54
- get cache(): any;
55
- get blocked(): any;
56
- get parentOrders(): any;
57
- get activatedRules(): any;
58
- set cache(value: any);
59
- set blocked(value: any);
60
- set parentOrders(value: any);
61
- set activatedRules(value: any);
62
- get [ENGINE_INSTANCE](): any;
63
- /**
64
- * The two overloads of generator.ts:2037-2040. With an `id` the Engine records the module's
65
- * tokens; a counted set adds each token's occurrences.
66
- */
67
- applyExtractors(code: string, id?: string, extracted?: Set<string>): Promise<any>;
68
- /**
69
- * The overloads of generator.ts:2316-2318. String input is extracted here, as Rust's
70
- * `{ kind: "code" }` would, so its tokens reach the cache and the unmatched check (the oracle
71
- * runs `applyExtractors` on it, generator.ts:2378).
72
- */
73
- generate(input: string | string[] | Set<string>, options?: Record<string, any>): Promise<any>;
74
- /**
75
- * generator.ts:2113-2286. A tuple array, or `undefined` for a miss or a blocked token; a miss
76
- * already cached reads back as `null`. With an `alias` nothing is cached.
77
- */
78
- parseToken(raw: string, alias?: string): Promise<any>;
79
- /** generator.ts:3611. */
80
- isBlocked(raw: string): any;
81
- /** generator.ts:3623; the blocklist holds strings only (anything else falls back). */
82
- getBlocked(raw: string): [string, undefined] | undefined;
83
- /** generator.ts:2304-2314: cached tokens that emit the same output as `raw`. */
84
- getCachedEquivalentTokens(raw: string): string[];
85
- /** The TypeScript generator behind the tooling members, created on first call; a TS backend returns itself. */
86
- [ENGINE_MATERIALIZE](): Promise<any>;
87
- /** generator.ts:2105. */
88
- makeContext(raw: string, applied: unknown): any;
89
- /** generator.ts:2809. */
90
- constructCustomCSS(context: unknown, body: unknown, overrideSelector?: string): any;
91
- /** generator.ts:3160. */
92
- stringifyUtil(parsed?: unknown, context?: unknown): any;
93
- /** generator.ts:2635. */
94
- matchVariants(raw: string, current?: string): Promise<any>;
95
- /** generator.ts:2866. */
96
- parseUtil(input: unknown, context: unknown, internal?: boolean, shortcutPrefix?: string | string[]): Promise<any>;
97
- /** generator.ts:3208. */
98
- expandShortcut(input: string, context: unknown, depth?: number): Promise<any>;
99
- /** generator.ts:3409. */
100
- stringifyShortcuts(parent: unknown, context: unknown, expanded: unknown[], meta?: unknown, matchedPrefixes?: unknown): Promise<any>;
101
- /** generator.ts:1976-1980: a falsy config keeps the current one. */
102
- setConfig(userConfig?: Record<string, unknown>, defaults?: Record<string, unknown>): Promise<void>;
103
- /**
104
- * generator.ts:1983-2008: a candidate generator for the configuration, without touching this
105
- * one. A configuration Rust cannot serve gets a TypeScript candidate.
106
- */
107
- prepareConfig(userConfig: Record<string, unknown>, defaults?: Record<string, unknown>): Promise<Readonly<{
108
- config: any;
109
- defaults: Record<string, unknown>;
110
- generator: FacadeGenerator;
111
- userConfig: Record<string, unknown>;
112
- version: number;
113
- }>>;
114
- /**
115
- * generator.ts:2010-2035: switch to the prepared backend if no newer request superseded it. A
116
- * superseded Rust candidate is disposed; so is the previous Engine once it is replaced.
117
- */
118
- commitConfig(prepared: {
119
- config: unknown;
120
- defaults: Record<string, unknown>;
121
- generator: FacadeGenerator;
122
- userConfig: Record<string, unknown>;
123
- version: number;
124
- }): boolean;
125
- /**
126
- * Releases the Engine this generator owns; later `generate`, `parseToken`, `applyExtractors`,
127
- * `prepareConfig` and `commitConfig` throw `E_DISPOSED`, and a second call does nothing. A
128
- * candidate committed into another generator handed its Engine over and leaves it alone.
129
- */
130
- dispose(): void;
131
- [Symbol.dispose](): void;
132
- }
133
- /**
134
- * v02.9 §3.1: a Rust facade, or the reason the configuration needs TypeScript. Errors from
135
- * `loadProject` (`E_*`) are thrown as they are, not turned into a fallback. The hook counts the
136
- * initial creation, so this does not.
137
- */
138
- export interface FacadeHost {
139
- /** 挂钩注入的 @teacss/core 绑定;缺省时 facade 按需动态 import。 */
140
- core?: {
141
- version: string;
142
- createGenerator: (config?: object, defaults?: object) => Promise<object>;
143
- createTsGenerator?: (config?: object, defaults?: object) => Promise<object>;
144
- extractorSplit: object;
145
- isCountableSet?: (value: unknown) => boolean;
146
- isTokenShaped?: (token: string) => boolean;
147
- toEscapedSelector?: (raw: string) => string;
148
- /** core/utils/warn.ts 的 warnOnce;传入时 shortcut 警告与 TS 引擎共用一个去重集合。 */
149
- warnOnce?: (message: string) => void;
150
- } | undefined;
151
- /** 挂钩注入的回退出口(core 的 reportFallback):每次回退都调用,由它计数并按 reason 与 path 去重打印;缺省时 facade 自己计数并写 process.stderr。 */
152
- report?: (reason: string, path: string, level: "info" | "warn") => void;
153
- }
154
- export type FacadeCreateResult = {
155
- ok: true;
156
- generator: FacadeGenerator;
157
- } | {
158
- ok: false;
159
- reason: string;
160
- path: string;
161
- };
162
- export declare function createGenerator(config?: Record<string, unknown>, defaults?: Record<string, unknown>, host?: FacadeHost): Promise<FacadeCreateResult>;
163
- //# sourceMappingURL=generator.d.ts.map