@csszyx/runtime 0.10.11 → 0.10.12

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.
Files changed (2) hide show
  1. package/README.md +98 -197
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # @csszyx/runtime
2
2
 
3
- Runtime package for CSSzyx - provides zero-allocation className helpers, recovery token verification, and hydration guards.
3
+ Runtime helpers for [CSSzyx](https://github.com/nguyennhutien/csszyx) className
4
+ composition, mangle-aware merging, variant authoring, box-model class routing,
5
+ and SSR hydration guards.
4
6
 
5
- ## Features
6
-
7
- - **Zero-Allocation Helpers**: Efficient className concatenation with `_sz()` and variants
8
- - **Token Verification**: Runtime validation of recovery tokens
9
- - **Hydration Guards**: SSR/CSR consistency with abort protocol
10
- - **Type Safety**: Full TypeScript support with strict types
7
+ Most CSSzyx styling is **zero-runtime**: the build plugin compiles `sz` props to
8
+ static class strings. This package is what runs in the browser for the parts
9
+ that can't be static resolving variant factories, merging overrides, routing
10
+ classes to nested elements, and verifying the mangle map during hydration.
11
11
 
12
12
  ## Installation
13
13
 
@@ -15,238 +15,139 @@ Runtime package for CSSzyx - provides zero-allocation className helpers, recover
15
15
  pnpm add @csszyx/runtime
16
16
  ```
17
17
 
18
- ## Usage
18
+ Keep it a **direct** dependency: the build transform injects bare
19
+ `@csszyx/runtime` imports into your modules, which strict package managers
20
+ (pnpm) only resolve for direct dependencies.
19
21
 
20
- ### Basic Concatenation
22
+ ## The helpers you author with
21
23
 
22
- ```typescript
23
- import { _sz } from "@csszyx/runtime";
24
+ > Helpers with a `_` prefix (`_sz`, `_szMerge`, …) are **compiler-injected** —
25
+ > the build transform emits calls to them. Don't hand-author them; use the
26
+ > public names below.
24
27
 
25
- // Basic usage
26
- const className = _sz("a", "b", "c");
27
- // Returns: "a b c"
28
+ ### `szr(...inputs)` — resolve to a className
28
29
 
29
- // With conditionals
30
- const className = _sz("base", isActive && "active", hasError && "error");
31
- // Returns: "base active" (if isActive is true, hasError is false)
30
+ Resolves sz objects and/or class strings into one mangle-aware className.
31
+ Concatenates, filters falsy the hand-written name for what the compiler
32
+ injects as `_sz`.
32
33
 
33
- // Filters out falsy values
34
- const className = _sz("a", null, "b", undefined, false, "c");
35
- // Returns: "a b c"
36
- ```
34
+ ```tsx
35
+ import { szr, szv } from "@csszyx/runtime";
37
36
 
38
- ### Conditional Classes
37
+ const cardSz = szv({ variants: { pad: { lg: { p: 8 } } } });
39
38
 
40
- Plain JS conditionals compose with `_sz` no dedicated helper needed:
39
+ <div className={szr(cardSz({ pad: "lg" }), isActive && "active")} />;
40
+ ```
41
41
 
42
- ```typescript
43
- import { _sz } from "@csszyx/runtime";
42
+ ### `szcn(...classes)` — merge with last-wins override
44
43
 
45
- // Simple conditional
46
- _sz("base", isActive && "active");
44
+ Merges className strings so a later class **overrides** an earlier one of the
45
+ same utility the merge for the single resolution point of a layered
46
+ component, and for combining a part's defaults with a consumer override.
47
47
 
48
- // With fallback
49
- _sz("base", isActive ? "active" : "inactive");
48
+ ```ts
49
+ import { szcn } from "@csszyx/runtime";
50
50
 
51
- // Switch-like a plain object lookup
52
- const className =
53
- {
54
- success: "text-green-500",
55
- error: "text-red-500",
56
- warning: "text-yellow-500",
57
- }[status] ?? "text-gray-500";
51
+ szcn("gap-2 p-4", "gap-8"); // 'p-4 gap-8' (gap-8 wins)
52
+ szcn("pb-4", "p-8"); // → 'p-8' (shorthand covers the longhand)
53
+ szcn("text-base", "text-sm"); // → 'text-sm' (same property group)
54
+ szcn("text-red-500", "text-sm"); // → 'text-red-500 text-sm' (color vs size co-exist)
58
55
  ```
59
56
 
60
- ### Merging Classes
57
+ Unlike `tailwind-merge`, `szcn` keeps working in production builds where CSSzyx
58
+ **mangles** class names — it decodes tokens through the runtime mangle map
59
+ before grouping. Fail-safe contract: a class it cannot confidently group is
60
+ kept, never dropped.
61
61
 
62
- ```typescript
63
- import { _szMerge } from "@csszyx/runtime";
62
+ Custom `@theme` tokens join the merge groups automatically when the build
63
+ plugin scans your CSS (`build.scanCss`); for utility-shaped classes written in
64
+ plain CSS, register them once with `registerSzcnGroups({ colors: [...] })`.
64
65
 
65
- // Merge with duplicate removal
66
- _szMerge("a b", "b c", "c d");
67
- // Returns: "a b c d"
68
- ```
66
+ ### `szv(config)` variant authoring
69
67
 
70
- ### Runtime Initialization
68
+ Type-safe variant factory (the CVA equivalent for sz objects). Every variant
69
+ combination is extracted and safelisted at build time.
71
70
 
72
- ```typescript
73
- import { initRuntime } from "@csszyx/runtime";
71
+ ```tsx
72
+ import { szv } from "@csszyx/runtime";
74
73
 
75
- // Initialize at app startup
76
- initRuntime({
77
- development: process.env.NODE_ENV === "development",
78
- strictHydration: true,
79
- debug: false,
74
+ const buttonSz = szv({
75
+ base: { display: "inline-flex", rounded: "md" },
76
+ variants: {
77
+ intent: {
78
+ primary: { bg: "blue-500", color: "white" },
79
+ danger: { bg: "red-500", color: "white" },
80
+ },
81
+ },
82
+ defaultVariants: { intent: "primary" },
80
83
  });
81
- ```
82
-
83
- Per-element CSR recovery is opted in via the `szRecover` JSX attribute
84
- on individual elements (`"csr"` or `"dev-only"`) rather than a global
85
- runtime flag. See `@csszyx/runtime/verify` for token verification helpers.
86
-
87
- ### Recovery Token Verification
88
-
89
- ```typescript
90
- import { verifyRecoveryToken, loadManifestFromDOM } from "@csszyx/runtime";
91
84
 
92
- // Load manifest from embedded script
93
- const manifest = loadManifestFromDOM();
94
-
95
- if (manifest) {
96
- const element = document.querySelector("[data-sz-recovery-token]");
97
- const result = verifyRecoveryToken(element, manifest);
98
-
99
- if (result.valid) {
100
- console.log("Token verified:", result.tokenData);
101
- } else {
102
- console.error("Invalid token:", result.error);
103
- }
104
- }
85
+ <button sz={buttonSz({ intent: "danger" })} />;
105
86
  ```
106
87
 
107
- ### Hydration Guard
88
+ ### `splitBox(className)` — route one className to nested elements
108
89
 
109
- ```typescript
110
- import {
111
- guardHydration,
112
- loadManifestFromDOM,
113
- enableCSRRecovery,
114
- } from "@csszyx/runtime";
90
+ Partitions a flat className at the CSS box-model border line: margin/position
91
+ onto the outer element, padding/overflow/text onto the inner one. Comes with a
92
+ class toolkit — `classify`, `has`, `pick`, `omit` — and sz-object analogs
93
+ (`splitBoxSz`, `hasSz`, `pickSz`, `omitSz`).
115
94
 
116
- // Enable CSR recovery in development
117
- if (process.env.NODE_ENV === "development") {
118
- enableCSRRecovery();
119
- }
95
+ ```ts
96
+ import { splitBox } from "@csszyx/runtime";
120
97
 
121
- // Guard hydration process
122
- const manifest = loadManifestFromDOM();
123
- if (manifest && !guardHydration(manifest)) {
124
- console.error("Hydration guard failed - mangle map mismatch");
125
- }
98
+ const { outer, inner } = splitBox("m-4 px-2 md:flex");
99
+ // outer: "m-4" inner: "px-2 md:flex"
126
100
  ```
127
101
 
128
- ## API Reference
129
-
130
- ### Concatenation Helpers
131
-
132
- #### `_sz(...classes): string`
133
-
134
- Zero-allocation className concatenation. Filters out falsy values.
135
-
136
- #### `_sz2(a, b): string`
137
-
138
- Optimized two-argument version.
139
-
140
- #### `_sz3(a, b, c): string`
141
-
142
- Optimized three-argument version.
143
-
144
- #### `_szMerge(...classes): string`
145
-
146
- Merge className strings with duplicate removal.
147
-
148
- ### Verification
149
-
150
- #### `verifyRecoveryToken(element, manifest): VerificationResult`
151
-
152
- Verifies a recovery token against the manifest.
153
-
154
- #### `loadManifestFromDOM(): RecoveryManifest | null`
155
-
156
- Loads the recovery manifest from the DOM.
157
-
158
- #### `hasRecoveryToken(element): boolean`
159
-
160
- Checks if an element has a recovery token.
102
+ ### `szsClass(slot)` — narrow a compiled `szs` slot
161
103
 
162
- #### `getRecoveryMode(element): RecoveryMode | null`
104
+ Slots of the `szs` prop are authored as sz values but compiled to class strings
105
+ at build time. `szsClass` narrows a slot to `string | undefined`, fail-safe
106
+ against uncompiled values.
163
107
 
164
- Gets the recovery mode from an element.
108
+ ```tsx
109
+ import { szcn, szsClass } from "@csszyx/runtime";
165
110
 
166
- #### `verifyAllTokens(root, manifest): VerificationResult[]`
167
-
168
- Verifies all tokens in a subtree.
169
-
170
- ### Hydration
171
-
172
- #### `guardHydration(manifest): boolean`
173
-
174
- Guards the hydration process by verifying mangle map integrity.
175
-
176
- #### `loadMangleMapFromDOM(): MangleMap | null`
177
-
178
- Loads the checksum mangle map from `#__CSSZYX_MANGLE_MAP__`, with a fallback
179
- for the legacy `#__SZ_MANGLE_MAP__` id.
180
-
181
- #### `verifyMangleChecksum(expectedChecksum): boolean`
182
-
183
- Verifies the mangle map checksum.
184
-
185
- #### `abortHydration(element, error): void`
186
-
187
- Executes the hydration abort protocol for a subtree.
188
-
189
- #### `isHydrationAborted(element): boolean`
190
-
191
- Checks if a subtree has been aborted.
192
-
193
- #### `attemptCSRRecovery(element): boolean`
194
-
195
- Attempts client-side recovery for an aborted subtree.
196
-
197
- #### `enableCSRRecovery(): void`
198
-
199
- Enables CSR recovery mode (development only).
200
-
201
- #### `disableCSRRecovery(): void`
202
-
203
- Disables CSR recovery mode.
204
-
205
- #### `isCSRRecoveryAllowed(): boolean`
206
-
207
- Checks if CSR recovery is allowed.
208
-
209
- #### `getHydrationErrors(): HydrationError[]`
210
-
211
- Gets all hydration errors.
212
-
213
- #### `getAbortedSubtreeCount(): number`
214
-
215
- Gets the count of aborted subtrees.
216
-
217
- ### Runtime Initialization
218
-
219
- #### `initRuntime(config?): void`
220
-
221
- Initializes the CSSzyx runtime with optional configuration.
111
+ <h3 className={szcn("text-base font-medium", szsClass(szs?.title))} />;
112
+ ```
222
113
 
223
- #### `getRuntimeConfig(): RuntimeConfig`
114
+ ### `stripSzProps(props)` — safe prop forwarding
224
115
 
225
- Gets the current runtime configuration.
116
+ Removes `sz`/`szs`/`szRecover` from a props object before spreading onto a DOM
117
+ element, so wrappers don't leak framework props into the DOM.
226
118
 
227
- #### `isRuntimeInitialized(): boolean`
119
+ ## SSR hydration guards
228
120
 
229
- Checks if the runtime has been initialized.
121
+ In production, CSSzyx injects a mangle map and SHA-256 checksum into the HTML.
122
+ These helpers verify integrity during hydration and abort — preserving the
123
+ server-rendered HTML — instead of hydrating against a mismatched map:
230
124
 
231
- ## Configuration Options
125
+ ```ts
126
+ import { guardHydration, loadManifestFromDOM } from "@csszyx/runtime";
232
127
 
233
- ```typescript
234
- interface RuntimeConfig {
235
- development?: boolean; // Enable development mode features
236
- strictHydration?: boolean; // Enable strict hydration checks
237
- debug?: boolean; // Enable debug logging
128
+ const manifest = loadManifestFromDOM();
129
+ if (manifest && !guardHydration(manifest)) {
130
+ console.error("Hydration guard failed mangle map mismatch");
238
131
  }
239
132
  ```
240
133
 
241
- ## Performance
134
+ The full surface — `verifyMangleChecksum` / `verifyMangleChecksumAsync`,
135
+ `abortHydration`, `isHydrationAborted`, `attemptCSRRecovery`,
136
+ `verifyRecoveryToken`, `getHydrationErrors` — is documented in the
137
+ [runtime reference](https://csszyx.com/docs/reference/runtime/). Per-element
138
+ recovery is opted in via the `szRecover` JSX attribute (`"csr"` or
139
+ `"dev-only"`), not a global flag.
140
+
141
+ ## Lite entry
242
142
 
243
- The `_sz()` family of functions are optimized for zero-allocation concatenation:
143
+ `@csszyx/runtime/lite` ships only the injected concatenation helpers (`_sz`,
144
+ `_sz2`, `_sz3`, `_szMerge`, `__szColorVar`) with no hydration machinery — for
145
+ edge/serverless bundles that only need the compiled output to run.
244
146
 
245
- - `_sz()` - Variadic version for any number of arguments
246
- - `_sz2()` - 10-15% faster for exactly 2 arguments
247
- - `_sz3()` - 10-15% faster for exactly 3 arguments
147
+ ## Documentation
248
148
 
249
- Use the optimized versions in hot paths when the argument count is known at compile time.
149
+ Full API reference with worked examples:
150
+ <https://csszyx.com/docs/reference/runtime/>
250
151
 
251
152
  ## License
252
153
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@csszyx/runtime",
3
- "version": "0.10.11",
3
+ "version": "0.10.12",
4
4
  "description": "Runtime helpers and hydration guards for csszyx",
5
5
  "keywords": [
6
6
  "csszyx",
@@ -49,8 +49,8 @@
49
49
  "dist"
50
50
  ],
51
51
  "dependencies": {
52
- "@csszyx/compiler": "0.10.11",
53
- "@csszyx/core": "0.10.11"
52
+ "@csszyx/core": "0.10.12",
53
+ "@csszyx/compiler": "0.10.12"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/node": "^20.11.0",