@teacss/engine 0.0.0-stage → 0.8.5-alpha.1

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 CHANGED
@@ -1,3 +1,105 @@
1
- # Temporary Holding Version
1
+ # @teacss/engine
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ ## What this package is
4
+
5
+ `@teacss/engine` is the in-process Rust engine for TeaCSS 0.9: a napi-rs binding plus a facade that mirrors the 0.8.x `TeacssGenerator` API, so the TypeScript integrations can hand a build to Rust and get byte-identical CSS back. You do not install it yourself. The teacss-ts 0.9 integration packages (`@teacss/vite`, `@teacss/rsbuild` and the others) depend on it, and npm installs the platform package that matches your machine through `optionalDependencies`. Each `@teacss/engine@0.9.N` is paired with `@teacss/core@0.9.N`.
6
+
7
+ ## Supported platforms
8
+
9
+ | Package | os / cpu / libc | Status | Minimum |
10
+ | --- | --- | --- | --- |
11
+ | @teacss/engine-darwin-arm64 | darwin / arm64 / - | required | macOS 11.0 |
12
+ | @teacss/engine-darwin-x64 | darwin / x64 / - | required | macOS 11.0 |
13
+ | @teacss/engine-linux-x64-gnu | linux / x64 / glibc | required | glibc 2.17 |
14
+ | @teacss/engine-linux-x64-musl | linux / x64 / musl | required | - |
15
+ | @teacss/engine-linux-arm64-gnu | linux / arm64 / glibc | required | glibc 2.17 |
16
+ | @teacss/engine-linux-arm64-musl | linux / arm64 / musl | optional | - |
17
+ | @teacss/engine-win32-x64-msvc | win32 / x64 / - | required | - |
18
+ | @teacss/engine-win32-arm64-msvc | win32 / arm64 / - | optional | - |
19
+ | @teacss/engine-wasm32-wasi | - / - / - | optional | - |
20
+
21
+ Every package needs Node.js 22.12.0 or later; the wasm package needs `>=22.13.0 <23.0.0-0 || >=23.5.0`. A required platform blocks a release when it fails to build or test; an optional one is published later if it fails. The wasm fallback runs on any host, so it is not in `optionalDependencies` and is never installed by default. Install it explicitly with `npm i @teacss/engine-wasm32-wasi` when no native package fits your platform.
22
+
23
+ ## Engine selection
24
+
25
+ - `TEACSS_ENGINE=auto|rust|ts` overrides everything else. An unrecognized value is ignored, and the selection result carries it as `invalidEnv`.
26
+ - Otherwise the integration's `engine` option decides, and without it TeaCSS uses the TypeScript engine.
27
+ - `package.json#engineCompat.defaultMode` sets what the option `"auto"` means. While it is `"opt-in"` (the alpha releases), `engine: "auto"` stays on TypeScript, and only `TEACSS_ENGINE=rust` or `auto`, or `engine: "rust"`, tries Rust. From the beta, `"auto"` tries Rust and falls back when a configuration cannot run there.
28
+ - With `"auto"`, a configuration Rust cannot serve falls back to TypeScript with a machine-readable reason; with `"rust"`, the same failure throws. The full list of fallback reasons is in [docs/specs/v02.9-facade-and-hook.md](../../docs/specs/v02.9-facade-and-hook.md) §4.6.
29
+
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
+
32
+ ## Compatibility
33
+
34
+ | `engineCompat` field | Meaning |
35
+ | --- | --- |
36
+ | `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 |
38
+ | `oracle.teacssTs` / `oracle.commit` | The teacss-ts version and commit this release was compared against byte for byte |
39
+
40
+ | `@teacss/core` | `@teacss/engine` | `engineCompat.core` | Result |
41
+ | --- | --- | --- | --- |
42
+ | 0.9.0-alpha.3 | 0.9.0-alpha.3 | `>=0.9.0-alpha.0 <0.10.0` | Paired; selected by `defaultMode` |
43
+ | 0.9.1 | 0.9.0 | `>=0.9.0 <0.10.0` | Allowed; the comparison baseline may lag one 0.8.x release, and diagnostics print `oracle.teacssTs` |
44
+ | 0.10.0 | 0.9.4 | `>=0.9.0 <0.10.0` | Falls back to TypeScript with `engine-compat` |
45
+ | 0.8.2 | any 0.9.x | - | 0.8.2 has no engine hook, so the engine is never loaded |
46
+
47
+ The teacss-ts version this release is compared against is `package.json#engineCompat.oracle`.
48
+
49
+ ## Direct use of the binding
50
+
51
+ ```js
52
+ import { Engine, version } from "@teacss/engine/binding";
53
+ ```
54
+
55
+ The types are in `index.d.ts`. The binding is a tooling-level API and is not part of the 0.9 stability promise; integrations should go through `@teacss/core`.
56
+
57
+ ## Troubleshooting
58
+
59
+ | Symptom | Cause | Fix |
60
+ | --- | --- | --- |
61
+ | `Failed to load native binding`, and the detail lists `Cannot find module '@teacss/engine-linux-x64-gnu'` | Optional dependencies were skipped at install time (`--omit=optional`, `--no-optional`, or a CI cache holding another platform's `node_modules`) | Run `npm ci` again without the omit, or install `@teacss/engine-<platform>` explicitly; pnpm users check `supportedArchitectures` |
62
+ | The same, but on Alpine with the detail trying a `-gnu` package | musl detection failed: gcompat makes `process.report.getReport()` report a glibc version, so the loader picked the gnu package | Remove gcompat, or install `@teacss/engine-linux-x64-musl` explicitly and set `TEACSS_ENGINE=rust` to see the detail; if that does not help, set `NAPI_RS_FORCE_WASI=1` with the wasm package installed and report the detection case to napi-rs |
63
+ | `Module did not self-register` or a `NODE_MODULE_VERSION` mismatch | Cannot happen with a Node-API binary; it means the loaded `.node` is not this package's (for example an Electron with a Node-API version below 9, or an old Bun) | Upgrade the runtime |
64
+ | `dlopen` reports `GLIBC_2.xx not found` | glibc is older than the 2.17 build baseline | Not supported; use the wasm fallback or `TEACSS_ENGINE=ts` |
65
+ | macOS reports "code signature invalid" | The `.node` was copied from outside npm and carries the quarantine attribute | `xattr -d com.apple.quarantine <file>`; files installed by npm do not carry it |
66
+ | `TEACSS_ENGINE=rust` throws instead of falling back | Expected: `rust` never falls back | Use `auto`, or fix the load problem |
67
+ | An `engine-compat` fallback | `@teacss/core` and `@teacss/engine` are not a matching pair | Align the two versions; check the lockfile for more than one `@teacss/engine` |
68
+ | teacss-ts still uses TypeScript after a local `build:debug` | `bun link` points at an old directory, or `node_modules/@teacss/engine` is a registry copy | Check with `ls -l node_modules/@teacss/engine` that it is a symlink |
69
+
70
+ ## Verifying a release
71
+
72
+ ```sh
73
+ shasum -a 256 -c SHA256SUMS # Linux: sha256sum -c SHA256SUMS
74
+ npm view @teacss/engine --json | jq .dist.attestations
75
+ gh attestation verify teacss-engine.<platform>.node --owner teacss
76
+ ```
77
+
78
+ ## Development
79
+
80
+ ```sh
81
+ npm --prefix packages/engine ci
82
+ npm --prefix packages/engine run build:debug # teacss-engine.<platform>.node, binding.js, binding.d.ts
83
+ npm --prefix packages/engine test
84
+ npm --prefix packages/engine run check:dts
85
+ node -e 'import("./packages/engine/index.js").then(m => console.log(m.version()))'
86
+ ```
87
+
88
+ `build:debug` uses the `dev` profile and rebuilds incrementally in seconds. `npm run build` uses the release profile with `lto = "fat"`; use it only to reproduce the size budget or the import checks locally.
89
+
90
+ To try a local build inside a teacss-ts checkout (bun 1.4.3 workspaces), link it one of two ways, preferring the first:
91
+
92
+ ```sh
93
+ # A: bun link (preferred)
94
+ cd /path/to/teacss-rs/packages/engine && bun link
95
+ cd /path/to/teacss-ts && bun link @teacss/engine
96
+ TEACSS_ENGINE=rust bun test packages-engine/core
97
+ ```
98
+
99
+ ```sh
100
+ # B: file: override (temporary; revert with git checkout package.json bun.lock)
101
+ cd /path/to/teacss-ts
102
+ bun add --dev @teacss/engine@file:../teacss-rs/packages/engine
103
+ ```
104
+
105
+ Either way the loader finds the `.node` next to `binding.js` first, so no platform package is needed. After a Rust change, run `build:debug` again; there is no need to link again.
package/binding.d.ts ADDED
@@ -0,0 +1,50 @@
1
+ /* auto-generated by NAPI-RS */
2
+ /* eslint-disable */
3
+
4
+ /**
5
+ * Which binding artifact the generated loader actually loaded: `'native'` for
6
+ * a native addon, otherwise the `platformArchABI` of the WASI flavor. Every
7
+ * flavor napi-rs can build is listed, because `NAPI_RS_NATIVE_LIBRARY_PATH`
8
+ * can point the loader at a WASI artifact this package does not build itself.
9
+ */
10
+ export declare const __napiBindingTarget: 'native' | 'wasm32-wasi' | 'wasm32-wasip1'
11
+
12
+ export declare class Engine {
13
+ constructor()
14
+ inspectEntry(request: InspectEntryRequest): InspectEntryResult
15
+ loadProject(request: LoadProjectRequest): LoadProjectResult
16
+ programKey(): string
17
+ configView(): ResolvedConfigView
18
+ configFiles(): string[]
19
+ customThemeKeys(): string[]
20
+ updateModule(id: string, code: string): ModuleUpdateResult
21
+ removeModule(id: string): boolean
22
+ clearModuleDefinitions(id: string): boolean
23
+ moduleTokens(id: string): string[] | null
24
+ allTokens(): string[]
25
+ extract(code: string, id?: string | undefined | null): string[]
26
+ extractCounted(code: string, id?: string | undefined | null): Array<{ token: string; count: number }>
27
+ extractFiles(paths: string[]): ExtractFileResult[]
28
+ transformSource(id: string, code: string): TransformResult | null
29
+ transformStylesheet(id: string, code: string): TransformResult | null
30
+ generate(input: GenerateInput, options?: GenerateOptions | undefined | null): GenerateResult
31
+ parseToken(raw: string, alias?: string | undefined | null): StringifiedUtil[] | null
32
+ isBlocked(raw: string): boolean
33
+ diagnoseUnmatched(tokens: string[]): UnmatchedDiagnostic[]
34
+ themeValue(path: string): string | null
35
+ dispose(): void
36
+ }
37
+
38
+ export declare function diagnoseCustom(css: string, themeKeys: string[]): CustomDiagnostic[]
39
+
40
+ export declare function diagnoseEntry(css: string): EntryDiagnostic[]
41
+
42
+ export declare function expandClassGroups(code: string): string
43
+
44
+ export declare function hash(input: string): string
45
+
46
+ export declare function parseEntry(css: string, file?: string | undefined | null): EntryConfig
47
+
48
+ export declare function splitClassTokens(body: string): string[]
49
+
50
+ export declare function version(): string