@teacss/engine 0.9.1 → 0.9.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/README.md +49 -5
- package/binding.js +54 -54
- package/contract.d.ts +1 -1
- package/dist/config-view.d.ts +9 -0
- package/dist/config-view.js +38 -1
- package/dist/errors.d.ts +2 -0
- package/dist/errors.js +4 -0
- package/dist/generator.d.ts +10 -2
- package/dist/generator.js +39 -7
- package/dist/select.d.ts +1 -1
- package/dist/select.js +16 -4
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -22,19 +22,63 @@ Every package needs Node.js 22.12.0 or later; the wasm package needs `>=22.13.0
|
|
|
22
22
|
|
|
23
23
|
## Engine selection
|
|
24
24
|
|
|
25
|
-
- `TEACSS_ENGINE=auto|rust|ts` overrides
|
|
26
|
-
- Otherwise the integration's `engine` option decides
|
|
27
|
-
- `package.json#engineCompat.defaultMode` sets what the option `"auto"` means.
|
|
28
|
-
- With `"auto"`, a configuration Rust cannot serve falls back to TypeScript with a machine-readable reason; with `"rust"`, the
|
|
25
|
+
- `TEACSS_ENGINE=auto|rust|ts` overrides the `engine` option. An unrecognized value is ignored, and the selection result carries it as `invalidEnv`.
|
|
26
|
+
- Otherwise the integration's `engine` option decides. `selectEngineRequest` with no option returns TypeScript; what an unset `engine` means is the teacss-ts hook's call.
|
|
27
|
+
- `package.json#engineCompat.defaultMode` sets what the option `"auto"` means. It is `"auto"`: `engine: "auto"`, which the first-party integrations pass, tries Rust and falls back to TypeScript when the configuration cannot run there. Releases up to 0.9.1 shipped `"opt-in"`, under which the option `"auto"` stayed on TypeScript and only `TEACSS_ENGINE=rust|auto` or `engine: "rust"` tried Rust.
|
|
28
|
+
- With `"auto"`, a configuration Rust cannot serve falls back to TypeScript with a machine-readable reason (see [Fallback reasons](#fallback-reasons)); with `"rust"`, the teacss-ts hook prints the same fallback as a warning, and throws instead when `TEACSS_ENGINE_STRICT=1` is set.
|
|
29
29
|
|
|
30
30
|
`selectEngineRequest` from `@teacss/engine/select` (which does not load the binding) stays on TypeScript in three cases: `mode: "ts"` (TypeScript chosen explicitly), `resolvedBy: "opt-in"` (the option `"auto"` while `defaultMode` is `"opt-in"`), and `reason: "engine-compat"` (the host `@teacss/core` is outside `engineCompat.core`).
|
|
31
31
|
|
|
32
|
+
## Fallback reasons
|
|
33
|
+
|
|
34
|
+
A fallback prints one line per reason and path per process: `[teacss] engine: falling back to the TypeScript engine (<reason> at <path>)`. In teacss-ts, `TEACSS_ENGINE_STATS=1` prints on exit how many generators ran on each engine and which reasons fell back. `TEACSS_ENGINE_DEBUG=1` makes this package print the translated request or the first failure to stderr. The facade stops at the first item it cannot translate, so fixing one reason can reveal the next.
|
|
35
|
+
|
|
36
|
+
To keep TypeScript for any configuration, set `TEACSS_ENGINE=ts` (it covers every integration), or write `engine: "ts"` in the configuration or in the host's defaults, for example `pluginTeacss(config, { engine: "ts" })`. A fallback is not an error: the TypeScript engine produces the same CSS it always has.
|
|
37
|
+
|
|
38
|
+
`<i>` is the preset's index after nested presets are flattened and ordered by `enforce`.
|
|
39
|
+
|
|
40
|
+
| Reason | Path | What it means and why | To run on Rust |
|
|
41
|
+
| --- | --- | --- | --- |
|
|
42
|
+
| `engine-unavailable` | `@teacss/engine` | Reported by the teacss-ts hook, not by this package: importing the facade failed, usually because no platform package matches the machine or the native binding did not load. | Install the platform package for your machine; see [Troubleshooting](#troubleshooting). `TEACSS_ENGINE=rust` throws with the loader's error instead of falling back. |
|
|
43
|
+
| `engine-compat` | `@teacss/core` | The host `@teacss/core` is outside `engineCompat.core`, so the pair was not tested together. `TEACSS_ENGINE=rust` throws `E_ENGINE_COMPAT` instead. | Align `@teacss/core` and `@teacss/engine`; check the lockfile for a second copy of either. |
|
|
44
|
+
| `unknown-key` | the key | A top-level config key the facade does not know, such as a typo or an option from a newer core. Rust cannot know what it means. | Remove or correct the key. |
|
|
45
|
+
| `rules`, `variants`, `extractors`, `extractorDefault`, `preflights`, `preprocess`, `postprocess`, `extendTheme`, `configResolved`, `autocomplete`, `cli` | the key | The key has a non-empty value. These hold functions or matchers that only JavaScript can run, and Rust does not execute JavaScript. | Remove the key from the configuration the integration loads, or express it statically with `shortcuts`, `theme`, `safelist` or a preset option. |
|
|
46
|
+
| `separators` | `separators` | Separators other than the default `[":", "-"]`; Rust parses only the default. | Remove `separators`. |
|
|
47
|
+
| `mergeSelectors` | `mergeSelectors` | `mergeSelectors: false`; Rust always merges selectors. | Remove it. |
|
|
48
|
+
| `details` | `details` | `details` is set; Rust does not support it. | Remove it. |
|
|
49
|
+
| `sortLayers` | `sortLayers` | A `sortLayers` function. | Remove it and order layers with `layers`. |
|
|
50
|
+
| `content` | `content` or `content.filesystem` | `content` is not an object, or `content.filesystem` is not an array of strings. | Use an array of glob strings. |
|
|
51
|
+
| `content.inline` | `content.inline` | Inline content sources, which only the TypeScript engine reads. | Move the content into files matched by `content.filesystem`. |
|
|
52
|
+
| `envMode` | `envMode` | A value other than `"dev"` or `"build"`. | Use one of the two. |
|
|
53
|
+
| `unmatched` | `unmatched` | A value other than `"warn"`, `"error"` or `"off"`. | Use one of the three. |
|
|
54
|
+
| `outputToCssLayers` | `outputToCssLayers` | Neither a boolean nor an object. | Use `true`, `false` or `{ allLayers }`. |
|
|
55
|
+
| `outputToCssLayers.cssLayerName` | `outputToCssLayers.cssLayerName` | A `cssLayerName` value; Rust does not support it. | Remove it. |
|
|
56
|
+
| `transformers` | `transformers` or `transformers[<n>]` | A transformer other than `@teacss/transformer-compile-class` and `@teacss/directives`, or a `transformers` value that is not an array. Other transformers run JavaScript over the source. | Remove the transformer, or keep TypeScript. |
|
|
57
|
+
| `shortcuts`, `safelist`, `blocklist`, `theme`, `layers` | the key and the item inside it | A value that is not static data: a shortcut whose expansion is not a string, or that has a regular expression or meta; a `safelist` or `blocklist` item that is not a string; a theme leaf that is not a string or number, or the removed `rolePalettes` theme key; a layer order that is not a number. | Replace the item with static data. |
|
|
58
|
+
| `preset-not-instantiated` | `presets[<n>]` | A preset that is a function, a promise or not an object. | Call the factory (`presetStandard()`, not `presetStandard`) and await it before passing it. |
|
|
59
|
+
| `preset-cycle` | `presets[<n>]…` | A preset that contains itself through nested `presets`. | Break the cycle. |
|
|
60
|
+
| `accessor` | the key | A getter or setter on the config, the defaults or a preset. Translation would run it once and the TypeScript engine again. | Use plain data properties. |
|
|
61
|
+
| `standard.unknown-option` | `presets[<i>].options.<key>` | A Standard option other than `modeSelectors`, `containers`, `preflight`, `variablePrefix` and `compileClass`. | Remove the option. |
|
|
62
|
+
| `standard.compileClass.hashFn`, `standard.compileClass.trigger` | `presets[<i>].options.compileClass.…` | A custom hash function or trigger for compiled classes. | Remove it; `classPrefix`, `alwaysHash`, `keepUnknown` and `layer` are supported. |
|
|
63
|
+
| `icons.collections` | `presets[<i>].options.collections.<name>` | An icon collection other than the bundled `carbon`, `crypto`, `flagpack`, `logo` and `lucide`. | Use a bundled collection, or keep TypeScript. |
|
|
64
|
+
| `icons.customizations`, `icons.processor` | `presets[<i>].options.…` | Icon customizations or a processor, which run JavaScript. | Remove them. |
|
|
65
|
+
| `role-palettes-without-entry` | `presets[<i>]` | The `@teacss/config/role-palettes` preset in a configuration that did not come from an entry stylesheet. On Rust the preset needs the entry. | Load the configuration from its entry stylesheet through `@teacss/config`. |
|
|
66
|
+
| `preset.name` | `presets[<i>].name` | A preset without a string `name`. | Give the preset a name. |
|
|
67
|
+
| `preset.rules`, `preset.variants`, `preset.extractors`, `preset.preflights`, `preset.preprocess`, `preset.postprocess`, `preset.extendTheme`, `preset.configResolved`, `preset.transformers`, `preset.autocomplete`, `preset.extractorDefault` | `presets[<i>].<key>` | A preset that is not one of the built-in presets carries a dynamic field, as for the top-level keys above. | Remove the field from the preset, or keep TypeScript. |
|
|
68
|
+
| `preset.content` | `presets[<i>].content` | A preset's `content` holds something other than `pipeline`, such as `filesystem` or `inline`; Rust reads content globs only from the configuration. | Move the globs to the configuration's `content.filesystem`. |
|
|
69
|
+
| `preset.shortcuts`, `preset.safelist`, `preset.blocklist`, `preset.theme`, `preset.layers` | `presets[<i>].<key>…` | A preset field that is not static data, as for the top-level keys above. | Replace the item with static data. |
|
|
70
|
+
| `preset.enforce`, `preset.layer` | `presets[<i>].<key>` | `enforce` other than `"pre"` or `"post"`, or a `layer` that is not a string. | Correct the value. |
|
|
71
|
+
| `declarations-unsaved` | the declaration file | A declaration file whose text came from an unsaved editor buffer. Rust reads declaration files from disk. | Save the file. |
|
|
72
|
+
| `declarations-unavailable` | `content.filesystem` | Finding declaration files under `content.filesystem` failed: the `@teacss/config` source scanner could not be loaded, or it threw. | Install `@teacss/config`. |
|
|
73
|
+
|
|
74
|
+
`content.pipeline` never falls back, in the configuration or in a preset, whatever it holds (RegExp, functions or `false`). It only decides which modules the integration feeds in, so it stays on the facade's `config.content` and is not sent to Rust.
|
|
75
|
+
|
|
32
76
|
## Compatibility
|
|
33
77
|
|
|
34
78
|
| `engineCompat` field | Meaning |
|
|
35
79
|
| --- | --- |
|
|
36
80
|
| `core` | The `@teacss/core` versions this engine accepts, written as `>=A.B.C <X.Y.Z`; prereleases compare by SemVer, so `0.9.0-alpha.1 < 0.9.0` |
|
|
37
|
-
| `defaultMode` | What the option `"auto"` means: `"opt-in"` keeps TypeScript, `"auto"` tries Rust |
|
|
81
|
+
| `defaultMode` | What the option `"auto"` means: `"opt-in"` keeps TypeScript, `"auto"` (the current value) tries Rust |
|
|
38
82
|
| `oracle.teacssTs` / `oracle.commit` | The teacss-ts version and commit this release was compared against byte for byte |
|
|
39
83
|
|
|
40
84
|
| `@teacss/core` | `@teacss/engine` | `engineCompat.core` | Result |
|
package/binding.js
CHANGED
|
@@ -92,8 +92,8 @@ function requireNative() {
|
|
|
92
92
|
try {
|
|
93
93
|
const binding = require('@teacss/engine-android-arm64')
|
|
94
94
|
const bindingPackageVersion = require('@teacss/engine-android-arm64/package.json').version
|
|
95
|
-
if (bindingPackageVersion !== '0.9.
|
|
96
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
95
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
96
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
97
97
|
}
|
|
98
98
|
return binding
|
|
99
99
|
} catch (e) {
|
|
@@ -108,8 +108,8 @@ function requireNative() {
|
|
|
108
108
|
try {
|
|
109
109
|
const binding = require('@teacss/engine-android-arm-eabi')
|
|
110
110
|
const bindingPackageVersion = require('@teacss/engine-android-arm-eabi/package.json').version
|
|
111
|
-
if (bindingPackageVersion !== '0.9.
|
|
112
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
111
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
112
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
113
113
|
}
|
|
114
114
|
return binding
|
|
115
115
|
} catch (e) {
|
|
@@ -129,8 +129,8 @@ function requireNative() {
|
|
|
129
129
|
try {
|
|
130
130
|
const binding = require('@teacss/engine-win32-x64-gnu')
|
|
131
131
|
const bindingPackageVersion = require('@teacss/engine-win32-x64-gnu/package.json').version
|
|
132
|
-
if (bindingPackageVersion !== '0.9.
|
|
133
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
132
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
133
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
134
134
|
}
|
|
135
135
|
return binding
|
|
136
136
|
} catch (e) {
|
|
@@ -145,8 +145,8 @@ function requireNative() {
|
|
|
145
145
|
try {
|
|
146
146
|
const binding = require('@teacss/engine-win32-x64-msvc')
|
|
147
147
|
const bindingPackageVersion = require('@teacss/engine-win32-x64-msvc/package.json').version
|
|
148
|
-
if (bindingPackageVersion !== '0.9.
|
|
149
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
148
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
149
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
150
150
|
}
|
|
151
151
|
return binding
|
|
152
152
|
} catch (e) {
|
|
@@ -162,8 +162,8 @@ function requireNative() {
|
|
|
162
162
|
try {
|
|
163
163
|
const binding = require('@teacss/engine-win32-ia32-msvc')
|
|
164
164
|
const bindingPackageVersion = require('@teacss/engine-win32-ia32-msvc/package.json').version
|
|
165
|
-
if (bindingPackageVersion !== '0.9.
|
|
166
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
165
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
166
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
167
167
|
}
|
|
168
168
|
return binding
|
|
169
169
|
} catch (e) {
|
|
@@ -178,8 +178,8 @@ function requireNative() {
|
|
|
178
178
|
try {
|
|
179
179
|
const binding = require('@teacss/engine-win32-arm64-msvc')
|
|
180
180
|
const bindingPackageVersion = require('@teacss/engine-win32-arm64-msvc/package.json').version
|
|
181
|
-
if (bindingPackageVersion !== '0.9.
|
|
182
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
181
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
182
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
183
183
|
}
|
|
184
184
|
return binding
|
|
185
185
|
} catch (e) {
|
|
@@ -197,8 +197,8 @@ function requireNative() {
|
|
|
197
197
|
try {
|
|
198
198
|
const binding = require('@teacss/engine-darwin-universal')
|
|
199
199
|
const bindingPackageVersion = require('@teacss/engine-darwin-universal/package.json').version
|
|
200
|
-
if (bindingPackageVersion !== '0.9.
|
|
201
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
200
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
201
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
202
202
|
}
|
|
203
203
|
return binding
|
|
204
204
|
} catch (e) {
|
|
@@ -213,8 +213,8 @@ function requireNative() {
|
|
|
213
213
|
try {
|
|
214
214
|
const binding = require('@teacss/engine-darwin-x64')
|
|
215
215
|
const bindingPackageVersion = require('@teacss/engine-darwin-x64/package.json').version
|
|
216
|
-
if (bindingPackageVersion !== '0.9.
|
|
217
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
216
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
217
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
218
218
|
}
|
|
219
219
|
return binding
|
|
220
220
|
} catch (e) {
|
|
@@ -229,8 +229,8 @@ function requireNative() {
|
|
|
229
229
|
try {
|
|
230
230
|
const binding = require('@teacss/engine-darwin-arm64')
|
|
231
231
|
const bindingPackageVersion = require('@teacss/engine-darwin-arm64/package.json').version
|
|
232
|
-
if (bindingPackageVersion !== '0.9.
|
|
233
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
232
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
233
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
234
234
|
}
|
|
235
235
|
return binding
|
|
236
236
|
} catch (e) {
|
|
@@ -249,8 +249,8 @@ function requireNative() {
|
|
|
249
249
|
try {
|
|
250
250
|
const binding = require('@teacss/engine-freebsd-x64')
|
|
251
251
|
const bindingPackageVersion = require('@teacss/engine-freebsd-x64/package.json').version
|
|
252
|
-
if (bindingPackageVersion !== '0.9.
|
|
253
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
252
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
253
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
254
254
|
}
|
|
255
255
|
return binding
|
|
256
256
|
} catch (e) {
|
|
@@ -265,8 +265,8 @@ function requireNative() {
|
|
|
265
265
|
try {
|
|
266
266
|
const binding = require('@teacss/engine-freebsd-arm64')
|
|
267
267
|
const bindingPackageVersion = require('@teacss/engine-freebsd-arm64/package.json').version
|
|
268
|
-
if (bindingPackageVersion !== '0.9.
|
|
269
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
268
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
269
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
270
270
|
}
|
|
271
271
|
return binding
|
|
272
272
|
} catch (e) {
|
|
@@ -286,8 +286,8 @@ function requireNative() {
|
|
|
286
286
|
try {
|
|
287
287
|
const binding = require('@teacss/engine-linux-x64-musl')
|
|
288
288
|
const bindingPackageVersion = require('@teacss/engine-linux-x64-musl/package.json').version
|
|
289
|
-
if (bindingPackageVersion !== '0.9.
|
|
290
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
289
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
290
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
291
291
|
}
|
|
292
292
|
return binding
|
|
293
293
|
} catch (e) {
|
|
@@ -302,8 +302,8 @@ function requireNative() {
|
|
|
302
302
|
try {
|
|
303
303
|
const binding = require('@teacss/engine-linux-x64-gnu')
|
|
304
304
|
const bindingPackageVersion = require('@teacss/engine-linux-x64-gnu/package.json').version
|
|
305
|
-
if (bindingPackageVersion !== '0.9.
|
|
306
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
305
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
306
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
307
307
|
}
|
|
308
308
|
return binding
|
|
309
309
|
} catch (e) {
|
|
@@ -320,8 +320,8 @@ function requireNative() {
|
|
|
320
320
|
try {
|
|
321
321
|
const binding = require('@teacss/engine-linux-arm64-musl')
|
|
322
322
|
const bindingPackageVersion = require('@teacss/engine-linux-arm64-musl/package.json').version
|
|
323
|
-
if (bindingPackageVersion !== '0.9.
|
|
324
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
323
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
324
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
325
325
|
}
|
|
326
326
|
return binding
|
|
327
327
|
} catch (e) {
|
|
@@ -336,8 +336,8 @@ function requireNative() {
|
|
|
336
336
|
try {
|
|
337
337
|
const binding = require('@teacss/engine-linux-arm64-gnu')
|
|
338
338
|
const bindingPackageVersion = require('@teacss/engine-linux-arm64-gnu/package.json').version
|
|
339
|
-
if (bindingPackageVersion !== '0.9.
|
|
340
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
339
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
340
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
341
341
|
}
|
|
342
342
|
return binding
|
|
343
343
|
} catch (e) {
|
|
@@ -354,8 +354,8 @@ function requireNative() {
|
|
|
354
354
|
try {
|
|
355
355
|
const binding = require('@teacss/engine-linux-arm-musleabihf')
|
|
356
356
|
const bindingPackageVersion = require('@teacss/engine-linux-arm-musleabihf/package.json').version
|
|
357
|
-
if (bindingPackageVersion !== '0.9.
|
|
358
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
357
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
358
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
359
359
|
}
|
|
360
360
|
return binding
|
|
361
361
|
} catch (e) {
|
|
@@ -370,8 +370,8 @@ function requireNative() {
|
|
|
370
370
|
try {
|
|
371
371
|
const binding = require('@teacss/engine-linux-arm-gnueabihf')
|
|
372
372
|
const bindingPackageVersion = require('@teacss/engine-linux-arm-gnueabihf/package.json').version
|
|
373
|
-
if (bindingPackageVersion !== '0.9.
|
|
374
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
373
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
374
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
375
375
|
}
|
|
376
376
|
return binding
|
|
377
377
|
} catch (e) {
|
|
@@ -388,8 +388,8 @@ function requireNative() {
|
|
|
388
388
|
try {
|
|
389
389
|
const binding = require('@teacss/engine-linux-loong64-musl')
|
|
390
390
|
const bindingPackageVersion = require('@teacss/engine-linux-loong64-musl/package.json').version
|
|
391
|
-
if (bindingPackageVersion !== '0.9.
|
|
392
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
391
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
392
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
393
393
|
}
|
|
394
394
|
return binding
|
|
395
395
|
} catch (e) {
|
|
@@ -404,8 +404,8 @@ function requireNative() {
|
|
|
404
404
|
try {
|
|
405
405
|
const binding = require('@teacss/engine-linux-loong64-gnu')
|
|
406
406
|
const bindingPackageVersion = require('@teacss/engine-linux-loong64-gnu/package.json').version
|
|
407
|
-
if (bindingPackageVersion !== '0.9.
|
|
408
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
407
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
408
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
409
409
|
}
|
|
410
410
|
return binding
|
|
411
411
|
} catch (e) {
|
|
@@ -422,8 +422,8 @@ function requireNative() {
|
|
|
422
422
|
try {
|
|
423
423
|
const binding = require('@teacss/engine-linux-riscv64-musl')
|
|
424
424
|
const bindingPackageVersion = require('@teacss/engine-linux-riscv64-musl/package.json').version
|
|
425
|
-
if (bindingPackageVersion !== '0.9.
|
|
426
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
425
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
426
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
427
427
|
}
|
|
428
428
|
return binding
|
|
429
429
|
} catch (e) {
|
|
@@ -438,8 +438,8 @@ function requireNative() {
|
|
|
438
438
|
try {
|
|
439
439
|
const binding = require('@teacss/engine-linux-riscv64-gnu')
|
|
440
440
|
const bindingPackageVersion = require('@teacss/engine-linux-riscv64-gnu/package.json').version
|
|
441
|
-
if (bindingPackageVersion !== '0.9.
|
|
442
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
441
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
442
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
443
443
|
}
|
|
444
444
|
return binding
|
|
445
445
|
} catch (e) {
|
|
@@ -455,8 +455,8 @@ function requireNative() {
|
|
|
455
455
|
try {
|
|
456
456
|
const binding = require('@teacss/engine-linux-ppc64-gnu')
|
|
457
457
|
const bindingPackageVersion = require('@teacss/engine-linux-ppc64-gnu/package.json').version
|
|
458
|
-
if (bindingPackageVersion !== '0.9.
|
|
459
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
458
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
459
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
460
460
|
}
|
|
461
461
|
return binding
|
|
462
462
|
} catch (e) {
|
|
@@ -471,8 +471,8 @@ function requireNative() {
|
|
|
471
471
|
try {
|
|
472
472
|
const binding = require('@teacss/engine-linux-s390x-gnu')
|
|
473
473
|
const bindingPackageVersion = require('@teacss/engine-linux-s390x-gnu/package.json').version
|
|
474
|
-
if (bindingPackageVersion !== '0.9.
|
|
475
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
474
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
475
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
476
476
|
}
|
|
477
477
|
return binding
|
|
478
478
|
} catch (e) {
|
|
@@ -491,8 +491,8 @@ function requireNative() {
|
|
|
491
491
|
try {
|
|
492
492
|
const binding = require('@teacss/engine-openharmony-arm64')
|
|
493
493
|
const bindingPackageVersion = require('@teacss/engine-openharmony-arm64/package.json').version
|
|
494
|
-
if (bindingPackageVersion !== '0.9.
|
|
495
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
494
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
495
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
496
496
|
}
|
|
497
497
|
return binding
|
|
498
498
|
} catch (e) {
|
|
@@ -507,8 +507,8 @@ function requireNative() {
|
|
|
507
507
|
try {
|
|
508
508
|
const binding = require('@teacss/engine-openharmony-x64')
|
|
509
509
|
const bindingPackageVersion = require('@teacss/engine-openharmony-x64/package.json').version
|
|
510
|
-
if (bindingPackageVersion !== '0.9.
|
|
511
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
510
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
511
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
512
512
|
}
|
|
513
513
|
return binding
|
|
514
514
|
} catch (e) {
|
|
@@ -523,8 +523,8 @@ function requireNative() {
|
|
|
523
523
|
try {
|
|
524
524
|
const binding = require('@teacss/engine-openharmony-arm')
|
|
525
525
|
const bindingPackageVersion = require('@teacss/engine-openharmony-arm/package.json').version
|
|
526
|
-
if (bindingPackageVersion !== '0.9.
|
|
527
|
-
throw new Error(`Native binding package version mismatch, expected 0.9.
|
|
526
|
+
if (bindingPackageVersion !== '0.9.2' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
527
|
+
throw new Error(`Native binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
528
528
|
}
|
|
529
529
|
return binding
|
|
530
530
|
} catch (e) {
|
|
@@ -664,8 +664,8 @@ if (!nativeBinding || forceWasi) {
|
|
|
664
664
|
if (!candidateFailed) {
|
|
665
665
|
if (process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
|
|
666
666
|
const bindingPackageVersion = require('@teacss/engine-wasm32-wasi/package.json').version
|
|
667
|
-
if (bindingPackageVersion !== '0.9.
|
|
668
|
-
throw new Error(`WASI binding package version mismatch, expected 0.9.
|
|
667
|
+
if (bindingPackageVersion !== '0.9.2') {
|
|
668
|
+
throw new Error(`WASI binding package version mismatch, expected 0.9.2 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
|
|
669
669
|
}
|
|
670
670
|
}
|
|
671
671
|
wasiBinding = require('@teacss/engine-wasm32-wasi')
|
package/contract.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Mirror of docs/specs/v02.2-engine-contract.md §3 (spec-revision
|
|
1
|
+
// Mirror of docs/specs/v02.2-engine-contract.md §3 (spec-revision 13). Do not edit without bumping the spec revision.
|
|
2
2
|
export interface InspectEntryRequest {
|
|
3
3
|
/** 项目根(绝对路径)。相对 @source 以声明它的文件所在目录为基准。 */
|
|
4
4
|
root: string;
|
package/dist/config-view.d.ts
CHANGED
|
@@ -23,5 +23,14 @@ export interface ConfigViewArgs {
|
|
|
23
23
|
compileClassShortcuts(): unknown[];
|
|
24
24
|
};
|
|
25
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;
|
|
26
35
|
export declare function createConfigView({ view, presets, merged, transformers, host, fallback, engine }: ConfigViewArgs): Record<string, unknown>;
|
|
27
36
|
//# sourceMappingURL=config-view.d.ts.map
|
package/dist/config-view.js
CHANGED
|
@@ -38,6 +38,40 @@ const RESOLVED_KEYS = Object.freeze([
|
|
|
38
38
|
"content",
|
|
39
39
|
"transformers",
|
|
40
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
|
+
}
|
|
41
75
|
export function createConfigView({ view, presets, merged, transformers, host, fallback, engine }) {
|
|
42
76
|
const config = {};
|
|
43
77
|
const data = (key, value) => Object.defineProperty(config, key, { value, enumerable: true, configurable: true, writable: true });
|
|
@@ -54,7 +88,10 @@ export function createConfigView({ view, presets, merged, transformers, host, fa
|
|
|
54
88
|
const extractors = host.core ? [host.core.extractorSplit] : [{ name: view.extractors?.[0]?.name ?? "@teacss/core/extractor-split" }];
|
|
55
89
|
const fields = {
|
|
56
90
|
presets: () => data("presets", presets),
|
|
57
|
-
content: () =>
|
|
91
|
+
content: () => {
|
|
92
|
+
const pipeline = mergePipeline([...presets, merged]);
|
|
93
|
+
data("content", pipeline === undefined ? (view.content ?? {}) : { pipeline, ...view.content });
|
|
94
|
+
},
|
|
58
95
|
transformers: () => data("transformers", transformers),
|
|
59
96
|
extractors: () => data("extractors", extractors),
|
|
60
97
|
extractorDefault: () => data("extractorDefault", extractors[0]),
|
package/dist/errors.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export declare class TeacssEngineError extends Error {
|
|
|
6
6
|
}
|
|
7
7
|
/** v02.9 §2.1: the member needs `@teacss/core`, which is not installed. */
|
|
8
8
|
export declare function tsRequiredError(member: string): TeacssEngineError;
|
|
9
|
+
/** The generator was disposed; the native Engine reports the same code after its own `dispose()`. */
|
|
10
|
+
export declare function disposedError(member: string): TeacssEngineError;
|
|
9
11
|
/** v02.9 §3.3: the member needs the TypeScript engine, which has not been materialized. */
|
|
10
12
|
export declare function tsNotReadyError(member: string): TeacssEngineError;
|
|
11
13
|
//# sourceMappingURL=errors.d.ts.map
|
package/dist/errors.js
CHANGED
|
@@ -11,6 +11,10 @@ export class TeacssEngineError extends Error {
|
|
|
11
11
|
export function tsRequiredError(member) {
|
|
12
12
|
return new TeacssEngineError("E_TS_REQUIRED", `[@teacss/engine] ${member} requires @teacss/core (optional peer) to be installed`, { member });
|
|
13
13
|
}
|
|
14
|
+
/** The generator was disposed; the native Engine reports the same code after its own `dispose()`. */
|
|
15
|
+
export function disposedError(member) {
|
|
16
|
+
return new TeacssEngineError("E_DISPOSED", `[@teacss/engine] ${member} called after dispose()`);
|
|
17
|
+
}
|
|
14
18
|
/** v02.9 §3.3: the member needs the TypeScript engine, which has not been materialized. */
|
|
15
19
|
export function tsNotReadyError(member) {
|
|
16
20
|
return new TeacssEngineError("E_TS_REQUIRED", `[@teacss/engine] ${member} needs the TypeScript engine; await generator[Symbol.for('@teacss/engine/materialize')]() first or set engine: 'ts'`, { member });
|
package/dist/generator.d.ts
CHANGED
|
@@ -19,7 +19,8 @@ export declare function engineStats(): {
|
|
|
19
19
|
};
|
|
20
20
|
/**
|
|
21
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)` (
|
|
22
|
+
* host `report(reason, path, level)` (core's `reportFallback`) gets every call and does both
|
|
23
|
+
* itself, so the counter is not touched here.
|
|
23
24
|
*/
|
|
24
25
|
export declare function reportFallback(reason: string, path: string, host?: FacadeHost, level?: "info" | "warn"): void;
|
|
25
26
|
export declare class FacadeGenerator {
|
|
@@ -121,6 +122,13 @@ export declare class FacadeGenerator {
|
|
|
121
122
|
userConfig: Record<string, unknown>;
|
|
122
123
|
version: number;
|
|
123
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;
|
|
124
132
|
}
|
|
125
133
|
/**
|
|
126
134
|
* v02.9 §3.1: a Rust facade, or the reason the configuration needs TypeScript. Errors from
|
|
@@ -140,7 +148,7 @@ export interface FacadeHost {
|
|
|
140
148
|
/** core/utils/warn.ts 的 warnOnce;传入时 shortcut 警告与 TS 引擎共用一个去重集合。 */
|
|
141
149
|
warnOnce?: (message: string) => void;
|
|
142
150
|
} | undefined;
|
|
143
|
-
/**
|
|
151
|
+
/** 挂钩注入的回退出口(core 的 reportFallback):每次回退都调用,由它计数并按 reason 与 path 去重打印;缺省时 facade 自己计数并写 process.stderr。 */
|
|
144
152
|
report?: (reason: string, path: string, level: "info" | "warn") => void;
|
|
145
153
|
}
|
|
146
154
|
export type FacadeCreateResult = {
|
package/dist/generator.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Engine } from "../binding.js";
|
|
|
6
6
|
import { createConfigView } from "./config-view.js";
|
|
7
7
|
import { ENGINE_INSTANCE, ENGINE_MATERIALIZE, ENGINE_PACKAGE_VERSION, ENGINE_STATS } from "./constants.js";
|
|
8
8
|
import { BoundedSet, BoundedTokenCache, CountableSet, copyCountableSet, expandInputGroups, isCountableSet, MAX_RUNTIME_CACHE_ENTRIES } from "./countable-set.js";
|
|
9
|
-
import { tsNotReadyError } from "./errors.js";
|
|
9
|
+
import { disposedError, tsNotReadyError } from "./errors.js";
|
|
10
10
|
import { buildMatched, createFacadeResult, describeUnmatched, fallbackIsTokenShaped, formatUnmatchedError, shortcutWarningMessages, splitMatched, toTuple } from "./result.js";
|
|
11
11
|
import { mergeDefinedConfig, translateConfig } from "./select.js";
|
|
12
12
|
import { createCompileClassTransformer } from "./transformer.js";
|
|
@@ -232,19 +232,21 @@ export function engineStats() {
|
|
|
232
232
|
const reported = new Set();
|
|
233
233
|
/**
|
|
234
234
|
* v02.9 §9: each reason and path prints once per process; the counter grows on every call. A
|
|
235
|
-
* host `report(reason, path, level)` (
|
|
235
|
+
* host `report(reason, path, level)` (core's `reportFallback`) gets every call and does both
|
|
236
|
+
* itself, so the counter is not touched here.
|
|
236
237
|
*/
|
|
237
238
|
export function reportFallback(reason, path, host = {}, level = "info") {
|
|
239
|
+
if (typeof host.report === "function") {
|
|
240
|
+
host.report(reason, path, level);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
238
243
|
const stats = engineStats();
|
|
239
244
|
stats.fallbacks[reason] = (stats.fallbacks[reason] ?? 0) + 1;
|
|
240
245
|
const key = `${reason}\0${path}`;
|
|
241
246
|
if (reported.has(key))
|
|
242
247
|
return;
|
|
243
248
|
reported.add(key);
|
|
244
|
-
|
|
245
|
-
host.report(reason, path, level);
|
|
246
|
-
else
|
|
247
|
-
process.stderr.write(`[teacss] engine: falling back to the TypeScript engine (${reason} at ${path})\n`);
|
|
249
|
+
process.stderr.write(`[teacss] engine: falling back to the TypeScript engine (${reason} at ${path})\n`);
|
|
248
250
|
}
|
|
249
251
|
/** array-internal.ts:7-13: ownership is rechecked before each read. */
|
|
250
252
|
function* ownArrayValues(array) {
|
|
@@ -301,6 +303,7 @@ export class FacadeGenerator {
|
|
|
301
303
|
disposeEngine(held.engine);
|
|
302
304
|
});
|
|
303
305
|
#backend;
|
|
306
|
+
#disposed = false;
|
|
304
307
|
#held = null;
|
|
305
308
|
#host;
|
|
306
309
|
#tsFallback;
|
|
@@ -410,6 +413,7 @@ export class FacadeGenerator {
|
|
|
410
413
|
* tokens; a counted set adds each token's occurrences.
|
|
411
414
|
*/
|
|
412
415
|
async applyExtractors(code, id, extracted = new Set()) {
|
|
416
|
+
this.#assertLive("applyExtractors");
|
|
413
417
|
await Promise.resolve();
|
|
414
418
|
const backend = this.#backend;
|
|
415
419
|
if (backend.kind === "ts")
|
|
@@ -447,6 +451,7 @@ export class FacadeGenerator {
|
|
|
447
451
|
* runs `applyExtractors` on it, generator.ts:2378).
|
|
448
452
|
*/
|
|
449
453
|
async generate(input, options = {}) {
|
|
454
|
+
this.#assertLive("generate");
|
|
450
455
|
const backend = this.#backend;
|
|
451
456
|
if (backend.kind === "ts") {
|
|
452
457
|
// A rule may commit a new configuration through this facade while the TS backend runs; the
|
|
@@ -610,6 +615,7 @@ export class FacadeGenerator {
|
|
|
610
615
|
* already cached reads back as `null`. With an `alias` nothing is cached.
|
|
611
616
|
*/
|
|
612
617
|
async parseToken(raw, alias) {
|
|
618
|
+
this.#assertLive("parseToken");
|
|
613
619
|
await Promise.resolve();
|
|
614
620
|
const backend = this.#backend;
|
|
615
621
|
if (backend.kind === "ts")
|
|
@@ -727,6 +733,7 @@ export class FacadeGenerator {
|
|
|
727
733
|
* one. A configuration Rust cannot serve gets a TypeScript candidate.
|
|
728
734
|
*/
|
|
729
735
|
async prepareConfig(userConfig, defaults) {
|
|
736
|
+
this.#assertLive("prepareConfig");
|
|
730
737
|
await Promise.resolve();
|
|
731
738
|
const version = ++this.#configVersion;
|
|
732
739
|
const nextDefaults = defaults ?? this.defaults;
|
|
@@ -747,7 +754,7 @@ export class FacadeGenerator {
|
|
|
747
754
|
this.#prepared.add(prepared);
|
|
748
755
|
const held = candidate.#backend.kind === "rust" ? { kind: "rust", engine: candidate.#backend.engine, committed: false } : { kind: "ts", committed: false };
|
|
749
756
|
candidate.#held = held;
|
|
750
|
-
FacadeGenerator.#registry.register(candidate, held);
|
|
757
|
+
FacadeGenerator.#registry.register(candidate, held, candidate);
|
|
751
758
|
return prepared;
|
|
752
759
|
}
|
|
753
760
|
/**
|
|
@@ -755,6 +762,7 @@ export class FacadeGenerator {
|
|
|
755
762
|
* superseded Rust candidate is disposed; so is the previous Engine once it is replaced.
|
|
756
763
|
*/
|
|
757
764
|
commitConfig(prepared) {
|
|
765
|
+
this.#assertLive("commitConfig");
|
|
758
766
|
if (!this.#prepared.delete(prepared))
|
|
759
767
|
return false;
|
|
760
768
|
const candidate = prepared.generator;
|
|
@@ -777,6 +785,30 @@ export class FacadeGenerator {
|
|
|
777
785
|
this.#dispatchConfig(this.config);
|
|
778
786
|
return true;
|
|
779
787
|
}
|
|
788
|
+
/**
|
|
789
|
+
* Releases the Engine this generator owns; later `generate`, `parseToken`, `applyExtractors`,
|
|
790
|
+
* `prepareConfig` and `commitConfig` throw `E_DISPOSED`, and a second call does nothing. A
|
|
791
|
+
* candidate committed into another generator handed its Engine over and leaves it alone.
|
|
792
|
+
*/
|
|
793
|
+
dispose() {
|
|
794
|
+
if (this.#disposed)
|
|
795
|
+
return;
|
|
796
|
+
this.#disposed = true;
|
|
797
|
+
FacadeGenerator.#registry.unregister(this);
|
|
798
|
+
const backend = this.#backend;
|
|
799
|
+
if (backend.kind !== "rust")
|
|
800
|
+
return;
|
|
801
|
+
const handedOver = this.#held?.committed === true && this.#held.engine === backend.engine;
|
|
802
|
+
if (!handedOver)
|
|
803
|
+
disposeEngine(backend.engine);
|
|
804
|
+
}
|
|
805
|
+
[Symbol.dispose]() {
|
|
806
|
+
this.dispose();
|
|
807
|
+
}
|
|
808
|
+
#assertLive(member) {
|
|
809
|
+
if (this.#disposed)
|
|
810
|
+
throw disposedError(member);
|
|
811
|
+
}
|
|
780
812
|
/** An explicit `engine: "rust"` asked for Rust, so its fallback is a warning. */
|
|
781
813
|
#reportFallback(failure) {
|
|
782
814
|
const explicit = this.defaults?.engine === "rust" || this.userConfig?.engine === "rust";
|
package/dist/select.d.ts
CHANGED
|
@@ -54,7 +54,7 @@ export declare function pick(obj: Record<string, unknown>, keys: Iterable<string
|
|
|
54
54
|
export declare function translateTaggedPreset(preset: object, path: string, ctx: {
|
|
55
55
|
hasEntry: boolean;
|
|
56
56
|
}): Success<object | null> | Failure | undefined;
|
|
57
|
-
/** Keys of an unmarked preset whose non-empty value means fallback
|
|
57
|
+
/** Keys of an unmarked preset whose non-empty value means fallback; `content` is checked by `hasContentBeyondPipeline`. */
|
|
58
58
|
export declare const PRESET_DYNAMIC_KEYS: readonly string[];
|
|
59
59
|
/**
|
|
60
60
|
* v02.9 §4.5: the static shortcut forms as `[name, expansion]` pairs. A shortcut meta (`[n, e, meta]`)
|
package/dist/select.js
CHANGED
|
@@ -223,11 +223,23 @@ export function translateTaggedPreset(preset, path, ctx) {
|
|
|
223
223
|
return ctx.hasEntry ? ok(null) : fail("role-palettes-without-entry", path);
|
|
224
224
|
return undefined;
|
|
225
225
|
}
|
|
226
|
-
/** Keys of an unmarked preset whose non-empty value means fallback
|
|
227
|
-
export const PRESET_DYNAMIC_KEYS = Object.freeze(["rules", "variants", "extractors", "preflights", "preprocess", "postprocess", "extendTheme", "configResolved", "transformers", "autocomplete", "extractorDefault"
|
|
226
|
+
/** Keys of an unmarked preset whose non-empty value means fallback; `content` is checked by `hasContentBeyondPipeline`. */
|
|
227
|
+
export const PRESET_DYNAMIC_KEYS = Object.freeze(["rules", "variants", "extractors", "preflights", "preprocess", "postprocess", "extendTheme", "configResolved", "transformers", "autocomplete", "extractorDefault"]);
|
|
228
228
|
const isPlainObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
229
229
|
/** Values `undefined` are left out. */
|
|
230
230
|
const defined = (entries) => Object.fromEntries(Object.entries(entries).filter(([, value]) => value !== undefined));
|
|
231
|
+
/**
|
|
232
|
+
* `content.pipeline` only filters the modules an integration feeds in; generation never reads it
|
|
233
|
+
* (v02.2 §4), so it stays in the config view and never reaches Rust. Any other content field of a
|
|
234
|
+
* preset is not translated.
|
|
235
|
+
*/
|
|
236
|
+
function hasContentBeyondPipeline(content) {
|
|
237
|
+
if (!isNonEmpty(content))
|
|
238
|
+
return false;
|
|
239
|
+
if (!isPlainObject(content))
|
|
240
|
+
return true;
|
|
241
|
+
return Object.keys(content).some((key) => key !== "pipeline" && isNonEmpty(content[key]));
|
|
242
|
+
}
|
|
231
243
|
/**
|
|
232
244
|
* v02.9 §4.5: the static shortcut forms as `[name, expansion]` pairs. A shortcut meta (`[n, e, meta]`)
|
|
233
245
|
* has no place in `StaticPreset.shortcuts`, so any meta key falls back.
|
|
@@ -354,6 +366,8 @@ export function translateStaticPreset(preset, path) {
|
|
|
354
366
|
if (isNonEmpty(preset[key]))
|
|
355
367
|
return fail(`preset.${key}`, `${path}.${key}`);
|
|
356
368
|
}
|
|
369
|
+
if (hasContentBeyondPipeline(preset.content))
|
|
370
|
+
return fail("preset.content", `${path}.content`);
|
|
357
371
|
const shortcuts = translateShortcuts(preset.shortcuts, `${path}.shortcuts`, "preset.shortcuts");
|
|
358
372
|
if (!shortcuts.ok)
|
|
359
373
|
return shortcuts;
|
|
@@ -401,8 +415,6 @@ export function translateInline(merged) {
|
|
|
401
415
|
if (merged.content !== undefined) {
|
|
402
416
|
if (!isPlainObject(merged.content))
|
|
403
417
|
return fail("content", "content");
|
|
404
|
-
if (Object.hasOwn(merged.content, "pipeline") && merged.content.pipeline !== undefined)
|
|
405
|
-
return fail("content.pipeline", "content.pipeline");
|
|
406
418
|
if (isNonEmpty(merged.content.inline))
|
|
407
419
|
return fail("content.inline", "content.inline");
|
|
408
420
|
const filesystem = merged.content.filesystem;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teacss/engine",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "In-process Rust engine for TeaCSS 0.9 (napi-rs binding and 0.8.x-compatible facade)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -65,21 +65,21 @@
|
|
|
65
65
|
},
|
|
66
66
|
"engineCompat": {
|
|
67
67
|
"core": ">=0.8.5 <0.10.0",
|
|
68
|
-
"defaultMode": "
|
|
68
|
+
"defaultMode": "auto",
|
|
69
69
|
"oracle": {
|
|
70
70
|
"teacssTs": "0.8.5",
|
|
71
71
|
"commit": "786b4d40"
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
74
|
"optionalDependencies": {
|
|
75
|
-
"@teacss/engine-darwin-arm64": "0.9.
|
|
76
|
-
"@teacss/engine-darwin-x64": "0.9.
|
|
77
|
-
"@teacss/engine-linux-arm64-gnu": "0.9.
|
|
78
|
-
"@teacss/engine-linux-arm64-musl": "0.9.
|
|
79
|
-
"@teacss/engine-linux-x64-gnu": "0.9.
|
|
80
|
-
"@teacss/engine-linux-x64-musl": "0.9.
|
|
81
|
-
"@teacss/engine-win32-arm64-msvc": "0.9.
|
|
82
|
-
"@teacss/engine-win32-x64-msvc": "0.9.
|
|
75
|
+
"@teacss/engine-darwin-arm64": "0.9.2",
|
|
76
|
+
"@teacss/engine-darwin-x64": "0.9.2",
|
|
77
|
+
"@teacss/engine-linux-arm64-gnu": "0.9.2",
|
|
78
|
+
"@teacss/engine-linux-arm64-musl": "0.9.2",
|
|
79
|
+
"@teacss/engine-linux-x64-gnu": "0.9.2",
|
|
80
|
+
"@teacss/engine-linux-x64-musl": "0.9.2",
|
|
81
|
+
"@teacss/engine-win32-arm64-msvc": "0.9.2",
|
|
82
|
+
"@teacss/engine-win32-x64-msvc": "0.9.2"
|
|
83
83
|
},
|
|
84
84
|
"peerDependencies": {
|
|
85
85
|
"@teacss/config": ">=0.8.5 <0.10.0 || >=0.9.0-alpha.0 <0.10.0",
|