@teacss/engine 0.9.3 → 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.
- package/LICENSE +22 -0
- package/README.md +28 -109
- package/binding-header.d.ts +9 -0
- package/binding.d.ts +29 -0
- package/binding.js +56 -55
- package/contract.d.ts +121 -16
- package/dist/entry.d.ts +20 -0
- package/dist/entry.js +279 -0
- package/dist/errors.d.ts +1 -7
- package/dist/errors.js +1 -13
- package/dist/fonts.d.ts +21 -0
- package/dist/fonts.js +32 -0
- package/dist/index.d.ts +3 -4
- package/dist/index.js +4 -7
- package/dist/project.d.ts +80 -0
- package/dist/project.js +136 -0
- package/package.json +19 -49
- package/dist/config-view.d.ts +0 -36
- package/dist/config-view.js +0 -135
- package/dist/constants.d.ts +0 -22
- package/dist/constants.js +0 -23
- package/dist/countable-set.d.ts +0 -57
- package/dist/countable-set.js +0 -205
- package/dist/generator.d.ts +0 -163
- package/dist/generator.js +0 -893
- package/dist/result.d.ts +0 -83
- package/dist/result.js +0 -142
- package/dist/select.d.ts +0 -183
- package/dist/select.js +0 -741
- package/dist/transformer.d.ts +0 -44
- package/dist/transformer.js +0 -59
- package/dist/ts-fallback.d.ts +0 -41
- package/dist/ts-fallback.js +0 -79
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teacss/engine",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "In-process Rust engine for TeaCSS
|
|
3
|
+
"version": "0.10.2",
|
|
4
|
+
"description": "In-process Rust engine for TeaCSS (napi-rs binding, contract types and the project helper the shells share)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"repository": {
|
|
@@ -21,14 +21,6 @@
|
|
|
21
21
|
"types": "./binding.d.ts",
|
|
22
22
|
"default": "./binding.js"
|
|
23
23
|
},
|
|
24
|
-
"./facade": {
|
|
25
|
-
"types": "./dist/index.d.ts",
|
|
26
|
-
"default": "./dist/index.js"
|
|
27
|
-
},
|
|
28
|
-
"./select": {
|
|
29
|
-
"types": "./dist/select.d.ts",
|
|
30
|
-
"default": "./dist/select.js"
|
|
31
|
-
},
|
|
32
24
|
"./package.json": "./package.json"
|
|
33
25
|
},
|
|
34
26
|
"imports": {
|
|
@@ -41,11 +33,12 @@
|
|
|
41
33
|
"binding-header.d.ts",
|
|
42
34
|
"dist/**/*.js",
|
|
43
35
|
"dist/**/*.d.ts",
|
|
44
|
-
"README.md"
|
|
36
|
+
"README.md",
|
|
37
|
+
"LICENSE"
|
|
45
38
|
],
|
|
46
39
|
"sideEffects": false,
|
|
47
40
|
"engines": {
|
|
48
|
-
"node": ">=
|
|
41
|
+
"node": ">=26"
|
|
49
42
|
},
|
|
50
43
|
"napi": {
|
|
51
44
|
"binaryName": "teacss-engine",
|
|
@@ -59,45 +52,23 @@
|
|
|
59
52
|
"aarch64-unknown-linux-gnu",
|
|
60
53
|
"aarch64-unknown-linux-musl",
|
|
61
54
|
"x86_64-pc-windows-msvc",
|
|
62
|
-
"aarch64-pc-windows-msvc"
|
|
63
|
-
"wasm32-wasip1-threads"
|
|
55
|
+
"aarch64-pc-windows-msvc"
|
|
64
56
|
]
|
|
65
57
|
},
|
|
66
|
-
"engineCompat": {
|
|
67
|
-
"core": ">=0.8.5 <0.10.0",
|
|
68
|
-
"defaultMode": "auto",
|
|
69
|
-
"oracle": {
|
|
70
|
-
"teacssTs": "0.8.5",
|
|
71
|
-
"commit": "786b4d40"
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
58
|
"optionalDependencies": {
|
|
75
|
-
"@teacss/engine-darwin-arm64": "0.
|
|
76
|
-
"@teacss/engine-darwin-x64": "0.
|
|
77
|
-
"@teacss/engine-linux-arm64-gnu": "0.
|
|
78
|
-
"@teacss/engine-linux-arm64-musl": "0.
|
|
79
|
-
"@teacss/engine-linux-x64-gnu": "0.
|
|
80
|
-
"@teacss/engine-linux-x64-musl": "0.
|
|
81
|
-
"@teacss/engine-win32-arm64-msvc": "0.
|
|
82
|
-
"@teacss/engine-win32-x64-msvc": "0.
|
|
83
|
-
},
|
|
84
|
-
"peerDependencies": {
|
|
85
|
-
"@teacss/config": ">=0.8.5 <0.10.0 || >=0.9.0-alpha.0 <0.10.0",
|
|
86
|
-
"@teacss/core": ">=0.8.5 <0.10.0 || >=0.9.0-alpha.0 <0.10.0"
|
|
87
|
-
},
|
|
88
|
-
"peerDependenciesMeta": {
|
|
89
|
-
"@teacss/core": {
|
|
90
|
-
"optional": true
|
|
91
|
-
},
|
|
92
|
-
"@teacss/config": {
|
|
93
|
-
"optional": true
|
|
94
|
-
}
|
|
59
|
+
"@teacss/engine-darwin-arm64": "0.10.2",
|
|
60
|
+
"@teacss/engine-darwin-x64": "0.10.2",
|
|
61
|
+
"@teacss/engine-linux-arm64-gnu": "0.10.2",
|
|
62
|
+
"@teacss/engine-linux-arm64-musl": "0.10.2",
|
|
63
|
+
"@teacss/engine-linux-x64-gnu": "0.10.2",
|
|
64
|
+
"@teacss/engine-linux-x64-musl": "0.10.2",
|
|
65
|
+
"@teacss/engine-win32-arm64-msvc": "0.10.2",
|
|
66
|
+
"@teacss/engine-win32-x64-msvc": "0.10.2"
|
|
95
67
|
},
|
|
96
68
|
"devDependencies": {
|
|
97
69
|
"@napi-rs/cli": "3.10.8",
|
|
98
70
|
"@types/node": "^22.20.5",
|
|
99
71
|
"emnapi": "1.11.3",
|
|
100
|
-
"magic-string": "^0.30.17",
|
|
101
72
|
"typescript": "^5.9.3"
|
|
102
73
|
},
|
|
103
74
|
"scripts": {
|
|
@@ -107,12 +78,12 @@
|
|
|
107
78
|
"artifacts": "napi artifacts --output-dir ../../artifacts --npm-dir npm",
|
|
108
79
|
"create-npm-dirs": "napi create-npm-dirs",
|
|
109
80
|
"prepublishOnly": "npm run build:ts && node build/scripts/check-publish.js",
|
|
110
|
-
"test": "npm run build:ts && npm run check:types && node --expose-gc --test \"build/
|
|
81
|
+
"test": "npm run build:ts && npm run check:types && node --expose-gc --test \"build/tests/**/*.test.js\"",
|
|
111
82
|
"check:version": "npm run build:ts && node build/scripts/sync-version.js --check",
|
|
112
83
|
"check:size": "node build/scripts/size-budget.js",
|
|
113
|
-
"version": "napi version && npm run build:ts && node build/scripts/sync-version.js --write && git add npm/*/package.json package-lock.json ../../Cargo.toml ../../Cargo.lock ../../package-lock.json",
|
|
114
|
-
"build:ts": "tsc -p tsconfig.json && tsc -p tsconfig.test.json",
|
|
115
|
-
"check:types": "tsc -p
|
|
84
|
+
"version": "napi version && npm run build:ts && node build/scripts/sync-version.js --write && git add -- npm/*/package.json package-lock.json ../*/package.json ../*/npm/*/package.json ../*/package-lock.json ../../Cargo.toml ../../Cargo.lock ../../extensions/zed/Cargo.toml ../../extensions/zed/extension.toml ../../extensions/zed/Cargo.lock ../../package-lock.json",
|
|
85
|
+
"build:ts": "node -e \"require('fs').rmSync('build',{recursive:true,force:true})\" && tsc -p tsconfig.json && tsc -p tsconfig.test.json",
|
|
86
|
+
"check:types": "tsc -p tests/consumer/tsconfig.json --noEmit",
|
|
116
87
|
"check:publish": "node build/scripts/check-publish.js",
|
|
117
88
|
"check:tag": "node build/scripts/check-tag.js",
|
|
118
89
|
"inspect-binding": "node build/scripts/inspect-binding.js",
|
|
@@ -122,8 +93,7 @@
|
|
|
122
93
|
"release:evidence": "node build/scripts/release-evidence.js",
|
|
123
94
|
"publish:npm": "node build/scripts/publish.js",
|
|
124
95
|
"dist-tag": "node build/scripts/dist-tag.js",
|
|
125
|
-
"qualify": "node build/scripts/qualify.js"
|
|
126
|
-
"setup-wasi-sdk": "node build/scripts/setup-wasi-sdk.js"
|
|
96
|
+
"qualify": "node build/scripts/qualify.js"
|
|
127
97
|
},
|
|
128
98
|
"publishConfig": {
|
|
129
99
|
"access": "public",
|
package/dist/config-view.d.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/** Fields the TypeScript generator provides; reading one before materialize throws `E_TS_REQUIRED`. */
|
|
2
|
-
export declare const TS_ONLY_FIELDS: readonly string[];
|
|
3
|
-
/** Fields copied from the Rust `ResolvedConfigView`. */
|
|
4
|
-
export declare const VIEW_FIELDS: readonly string[];
|
|
5
|
-
export interface ConfigViewArgs {
|
|
6
|
-
view: Record<string, any>;
|
|
7
|
-
request: object;
|
|
8
|
-
presets: object[];
|
|
9
|
-
/** The merged config (`mergeDefinedConfig(defaults, userConfig)`, config.ts:210) the oracle spreads. */
|
|
10
|
-
merged: Record<string, unknown>;
|
|
11
|
-
transformers: object[];
|
|
12
|
-
host: {
|
|
13
|
-
core?: {
|
|
14
|
-
extractorSplit: object;
|
|
15
|
-
} | undefined;
|
|
16
|
-
};
|
|
17
|
-
fallback: {
|
|
18
|
-
peek(): {
|
|
19
|
-
config: Record<string, unknown>;
|
|
20
|
-
} | null;
|
|
21
|
-
};
|
|
22
|
-
engine?: {
|
|
23
|
-
compileClassShortcuts(): unknown[];
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* The merged `content.pipeline` of the presets and the config, as `mergeContentOptions`
|
|
28
|
-
* (core/config.ts) builds it: `false` anywhere disables it, otherwise includes and excludes
|
|
29
|
-
* concatenate in source order without duplicates. The runtime builds its module filter from it.
|
|
30
|
-
*/
|
|
31
|
-
export declare function mergePipeline(sources: readonly unknown[]): false | {
|
|
32
|
-
include?: Array<string | RegExp>;
|
|
33
|
-
exclude?: Array<string | RegExp>;
|
|
34
|
-
} | undefined;
|
|
35
|
-
export declare function createConfigView({ view, presets, merged, transformers, host, fallback, engine }: ConfigViewArgs): Record<string, unknown>;
|
|
36
|
-
//# sourceMappingURL=config-view.d.ts.map
|
package/dist/config-view.js
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
// The facade's `generator.config`: a plain object whose keys follow the oracle `resolveConfig`
|
|
2
|
-
// (core/config.ts:260-288), which spreads the merged config and then sets its own fields.
|
|
3
|
-
import { tsNotReadyError } from "./errors.js";
|
|
4
|
-
/** Fields the TypeScript generator provides; reading one before materialize throws `E_TS_REQUIRED`. */
|
|
5
|
-
export const TS_ONLY_FIELDS = Object.freeze(["configResolved", "extendTheme", "preprocess", "postprocess", "preflights", "autocomplete", "rules", "rulesDynamic", "rulesStaticMap", "variants"]);
|
|
6
|
-
/** Fields copied from the Rust `ResolvedConfigView`. */
|
|
7
|
-
export const VIEW_FIELDS = Object.freeze(["layers", "theme", "shortcuts", "safelist", "blocklist", "separators", "envMode", "unmatched", "shortcutsLayer", "virtualModulePrefix", "mergeSelectors", "warn", "details", "outputToCssLayers", "rulesSize"]);
|
|
8
|
-
/**
|
|
9
|
-
* The keys `resolveConfig` always sets, in its order (config.ts:262-288); `configResolved`,
|
|
10
|
-
* `extendTheme`, `extractorDefault` and `virtualModulePrefix` appear only through the spread.
|
|
11
|
-
*/
|
|
12
|
-
const RESOLVED_KEYS = Object.freeze([
|
|
13
|
-
"mergeSelectors",
|
|
14
|
-
"warn",
|
|
15
|
-
"unmatched",
|
|
16
|
-
"outputToCssLayers",
|
|
17
|
-
"sortLayers",
|
|
18
|
-
"blocklist",
|
|
19
|
-
"presets",
|
|
20
|
-
"envMode",
|
|
21
|
-
"shortcutsLayer",
|
|
22
|
-
"layers",
|
|
23
|
-
"theme",
|
|
24
|
-
"rules",
|
|
25
|
-
"rulesSize",
|
|
26
|
-
"rulesDynamic",
|
|
27
|
-
"rulesStaticMap",
|
|
28
|
-
"preprocess",
|
|
29
|
-
"postprocess",
|
|
30
|
-
"preflights",
|
|
31
|
-
"autocomplete",
|
|
32
|
-
"variants",
|
|
33
|
-
"shortcuts",
|
|
34
|
-
"extractors",
|
|
35
|
-
"safelist",
|
|
36
|
-
"separators",
|
|
37
|
-
"details",
|
|
38
|
-
"content",
|
|
39
|
-
"transformers",
|
|
40
|
-
]);
|
|
41
|
-
const ownValue = (source, key) => (source !== null && typeof source === "object" && Object.hasOwn(source, key) ? source[key] : undefined);
|
|
42
|
-
const flattenPatterns = (patterns) => [...new Set(patterns.flatMap((pattern) => (Array.isArray(pattern) ? pattern : pattern ? [pattern] : [])))];
|
|
43
|
-
/**
|
|
44
|
-
* The merged `content.pipeline` of the presets and the config, as `mergeContentOptions`
|
|
45
|
-
* (core/config.ts) builds it: `false` anywhere disables it, otherwise includes and excludes
|
|
46
|
-
* concatenate in source order without duplicates. The runtime builds its module filter from it.
|
|
47
|
-
*/
|
|
48
|
-
export function mergePipeline(sources) {
|
|
49
|
-
const includes = [];
|
|
50
|
-
const excludes = [];
|
|
51
|
-
let configured = false;
|
|
52
|
-
for (const content of new Set(sources.map((source) => ownValue(source, "content")).filter((content) => content !== undefined && content !== null))) {
|
|
53
|
-
const pipeline = ownValue(content, "pipeline");
|
|
54
|
-
if (pipeline === false)
|
|
55
|
-
return false;
|
|
56
|
-
if (pipeline === undefined)
|
|
57
|
-
continue;
|
|
58
|
-
configured = true;
|
|
59
|
-
const include = pipeline && ownValue(pipeline, "include");
|
|
60
|
-
const exclude = pipeline && ownValue(pipeline, "exclude");
|
|
61
|
-
if (include)
|
|
62
|
-
includes.push(include);
|
|
63
|
-
if (exclude)
|
|
64
|
-
excludes.push(exclude);
|
|
65
|
-
}
|
|
66
|
-
if (!configured)
|
|
67
|
-
return undefined;
|
|
68
|
-
const merged = {};
|
|
69
|
-
if (includes.length)
|
|
70
|
-
merged.include = flattenPatterns(includes);
|
|
71
|
-
if (excludes.length)
|
|
72
|
-
merged.exclude = flattenPatterns(excludes);
|
|
73
|
-
return merged;
|
|
74
|
-
}
|
|
75
|
-
export function createConfigView({ view, presets, merged, transformers, host, fallback, engine }) {
|
|
76
|
-
const config = {};
|
|
77
|
-
const data = (key, value) => Object.defineProperty(config, key, { value, enumerable: true, configurable: true, writable: true });
|
|
78
|
-
const tsOnly = (key) => Object.defineProperty(config, key, {
|
|
79
|
-
enumerable: true,
|
|
80
|
-
configurable: true,
|
|
81
|
-
get() {
|
|
82
|
-
const ts = fallback.peek();
|
|
83
|
-
if (!ts)
|
|
84
|
-
throw tsNotReadyError(`config.${key}`);
|
|
85
|
-
return ts.config[key];
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
const extractors = host.core ? [host.core.extractorSplit] : [{ name: view.extractors?.[0]?.name ?? "@teacss/core/extractor-split" }];
|
|
89
|
-
const fields = {
|
|
90
|
-
presets: () => data("presets", presets),
|
|
91
|
-
content: () => {
|
|
92
|
-
const pipeline = mergePipeline([...presets, merged]);
|
|
93
|
-
data("content", pipeline === undefined ? (view.content ?? {}) : { pipeline, ...view.content });
|
|
94
|
-
},
|
|
95
|
-
transformers: () => data("transformers", transformers),
|
|
96
|
-
extractors: () => data("extractors", extractors),
|
|
97
|
-
extractorDefault: () => data("extractorDefault", extractors[0]),
|
|
98
|
-
sortLayers: () => data("sortLayers", (layers) => layers),
|
|
99
|
-
};
|
|
100
|
-
for (const key of VIEW_FIELDS)
|
|
101
|
-
fields[key] = () => data(key, view[key]);
|
|
102
|
-
// config.ts:263. Rust never warns, so its view does not carry the option.
|
|
103
|
-
fields.warn = () => data("warn", (Object.hasOwn(merged, "warn") ? merged.warn : undefined) ?? true);
|
|
104
|
-
if (engine) {
|
|
105
|
-
// compile-class.ts:84-106 pushes each definition onto `config.shortcuts` and splices it out
|
|
106
|
-
// when its last module drops it; the definitions live in the Engine, so one array is kept in
|
|
107
|
-
// step on every read.
|
|
108
|
-
const shortcuts = [...(view.shortcuts ?? [])];
|
|
109
|
-
const configured = shortcuts.length;
|
|
110
|
-
fields.shortcuts = () => Object.defineProperty(config, "shortcuts", {
|
|
111
|
-
enumerable: true,
|
|
112
|
-
configurable: true,
|
|
113
|
-
get() {
|
|
114
|
-
shortcuts.length = configured;
|
|
115
|
-
shortcuts.push(...engine.compileClassShortcuts());
|
|
116
|
-
return shortcuts;
|
|
117
|
-
},
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
for (const key of TS_ONLY_FIELDS)
|
|
121
|
-
fields[key] = () => tsOnly(key);
|
|
122
|
-
for (const key of Object.keys(merged)) {
|
|
123
|
-
if (key === "engine")
|
|
124
|
-
continue;
|
|
125
|
-
if (Object.hasOwn(fields, key))
|
|
126
|
-
fields[key]();
|
|
127
|
-
else
|
|
128
|
-
data(key, merged[key]);
|
|
129
|
-
}
|
|
130
|
-
// Redefining a spread key keeps its position, as the object literal does.
|
|
131
|
-
for (const key of RESOLVED_KEYS)
|
|
132
|
-
fields[key]();
|
|
133
|
-
return config;
|
|
134
|
-
}
|
|
135
|
-
//# sourceMappingURL=config-view.js.map
|
package/dist/constants.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/** `@teacss/engine`'s own package.json version; the facade `generator.version` without a host. */
|
|
2
|
-
export declare const ENGINE_PACKAGE_VERSION: string;
|
|
3
|
-
/** `package.json#engineCompat` (v02.11 §7.3); without it `core` is unrestricted and `defaultMode` is `"auto"`. */
|
|
4
|
-
export declare const ENGINE_COMPAT: Readonly<{
|
|
5
|
-
core: string | undefined;
|
|
6
|
-
defaultMode: "opt-in" | "auto";
|
|
7
|
-
oracle: {
|
|
8
|
-
teacssTs: string;
|
|
9
|
-
commit: string;
|
|
10
|
-
} | undefined;
|
|
11
|
-
}>;
|
|
12
|
-
export declare const ENGINE_INSTANCE: unique symbol;
|
|
13
|
-
export declare const ENGINE_MATERIALIZE: unique symbol;
|
|
14
|
-
export declare const ENGINE_STATS: unique symbol;
|
|
15
|
-
export declare const PRESET_OPTIONS: Readonly<{
|
|
16
|
-
standard: symbol;
|
|
17
|
-
icons: symbol;
|
|
18
|
-
official: symbol;
|
|
19
|
-
}>;
|
|
20
|
-
export declare const CONFIG_SOURCE_DECLARATIONS: unique symbol;
|
|
21
|
-
export declare const CONFIG_ENTRY_PROVENANCE: unique symbol;
|
|
22
|
-
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
// The facade's symbols and package constants. It imports nothing from the facade, so every
|
|
2
|
-
// facade module can import it without a cycle through `index.ts`.
|
|
3
|
-
import { createRequire } from "node:module";
|
|
4
|
-
const pkg = createRequire(import.meta.url)("../package.json");
|
|
5
|
-
/** `@teacss/engine`'s own package.json version; the facade `generator.version` without a host. */
|
|
6
|
-
export const ENGINE_PACKAGE_VERSION = pkg.version;
|
|
7
|
-
/** `package.json#engineCompat` (v02.11 §7.3); without it `core` is unrestricted and `defaultMode` is `"auto"`. */
|
|
8
|
-
export const ENGINE_COMPAT = Object.freeze({
|
|
9
|
-
core: pkg.engineCompat?.core,
|
|
10
|
-
defaultMode: pkg.engineCompat?.defaultMode ?? "auto",
|
|
11
|
-
oracle: pkg.engineCompat?.oracle,
|
|
12
|
-
});
|
|
13
|
-
export const ENGINE_INSTANCE = Symbol.for("@teacss/engine/instance");
|
|
14
|
-
export const ENGINE_MATERIALIZE = Symbol.for("@teacss/engine/materialize");
|
|
15
|
-
export const ENGINE_STATS = Symbol.for("@teacss/engine/stats");
|
|
16
|
-
export const PRESET_OPTIONS = Object.freeze({
|
|
17
|
-
standard: Symbol.for("@teacss/preset-standard/options"),
|
|
18
|
-
icons: Symbol.for("@teacss/preset-icons/options"),
|
|
19
|
-
official: Symbol.for("@teacss/preset-official/options"),
|
|
20
|
-
});
|
|
21
|
-
export const CONFIG_SOURCE_DECLARATIONS = Symbol.for("@teacss/config/source-declarations");
|
|
22
|
-
export const CONFIG_ENTRY_PROVENANCE = Symbol.for("@teacss/config/entry-provenance");
|
|
23
|
-
//# sourceMappingURL=constants.js.map
|
package/dist/countable-set.d.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
export declare const MAX_RUNTIME_CACHE_ENTRIES = 10000;
|
|
2
|
-
export declare class CountableSet<K> extends Set<K> {
|
|
3
|
-
_map: Map<K, number>;
|
|
4
|
-
constructor(values?: Iterable<K>);
|
|
5
|
-
add(key: K): this;
|
|
6
|
-
delete(key: K): boolean;
|
|
7
|
-
clear(): void;
|
|
8
|
-
getCount(key: K): number;
|
|
9
|
-
setCount(key: K, count: number): this;
|
|
10
|
-
}
|
|
11
|
-
export declare function isCountableSet(value: unknown): value is CountableSet<string>;
|
|
12
|
-
export declare function copyCountableSet<K>(input: CountableSet<K>): CountableSet<K>;
|
|
13
|
-
/**
|
|
14
|
-
* Expands the tokens holding a `{…}` group in place; the parts go to the end, and a counted
|
|
15
|
-
* group's count carries over to each part.
|
|
16
|
-
*/
|
|
17
|
-
export declare function expandInputGroups<T extends Set<string>>(tokens: T): T;
|
|
18
|
-
/**
|
|
19
|
-
* The part of the oracle `BoundedMap` the facade uses: ordinary keys are evicted oldest first,
|
|
20
|
-
* retained keys never count toward the limit. An entry can be pending (`setPending`,
|
|
21
|
-
* `replaceRetainedPending`): its value is `resolve(token)`, computed on the first read through
|
|
22
|
-
* `get`, `forEach` or iteration and kept in place; `has`, `size`, `delete` and eviction never
|
|
23
|
-
* resolve.
|
|
24
|
-
*/
|
|
25
|
-
export declare class BoundedTokenCache<V> extends Map<string, V> {
|
|
26
|
-
#private;
|
|
27
|
-
maxEntries: number;
|
|
28
|
-
retained: Set<string>;
|
|
29
|
-
/** Ordinary keys in insertion order, the order the native map iterates them. */
|
|
30
|
-
order: Set<string>;
|
|
31
|
-
/** The value of a pending entry, called once per entry on its first read. */
|
|
32
|
-
resolve: (token: string) => V;
|
|
33
|
-
constructor(maxEntries?: number, resolve?: (token: string) => V);
|
|
34
|
-
get retainedSize(): number;
|
|
35
|
-
isRetained(key: string): boolean;
|
|
36
|
-
get(key: string): V | undefined;
|
|
37
|
-
entries(): MapIterator<[string, V]>;
|
|
38
|
-
values(): MapIterator<V>;
|
|
39
|
-
[Symbol.iterator](): MapIterator<[string, V]>;
|
|
40
|
-
forEach(callback: (value: V, key: string, map: Map<string, V>) => void, thisArg?: unknown): void;
|
|
41
|
-
set(key: string, value: V): this;
|
|
42
|
-
/** Caches `key` with the value `resolve` supplies on its first read. */
|
|
43
|
-
setPending(key: string): this;
|
|
44
|
-
delete(key: string): boolean;
|
|
45
|
-
clear(): void;
|
|
46
|
-
/** Replaces the retained entries (bounded-cache.ts:188-205 without the revision check). */
|
|
47
|
-
replaceRetained(entries: Iterable<readonly [string, V]>): void;
|
|
48
|
-
/** `replaceRetained` with every value pending. */
|
|
49
|
-
replaceRetainedPending(keys: Iterable<string>): void;
|
|
50
|
-
}
|
|
51
|
-
/** FIFO bounded Set (the oracle `BoundedSet` without its `assumeNoPrototypeBypass` fast path). */
|
|
52
|
-
export declare class BoundedSet extends Set<string> {
|
|
53
|
-
maxEntries: number;
|
|
54
|
-
constructor(maxEntries?: number, values?: Iterable<string>);
|
|
55
|
-
add(value: string): this;
|
|
56
|
-
}
|
|
57
|
-
//# sourceMappingURL=countable-set.d.ts.map
|
package/dist/countable-set.js
DELETED
|
@@ -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
|