@teacss/core 0.5.2 → 0.6.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 +66 -348
- package/dist/index.d.ts +8 -2
- package/dist/index.js +21 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
# @teacss/core
|
|
2
2
|
|
|
3
|
-
The framework-neutral TeaCSS parser and generator.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
matches preset rules, and emits layered CSS. It owns mechanism; presets own
|
|
7
|
-
utility vocabulary.
|
|
3
|
+
The framework-neutral TeaCSS parser and generator. Core parses colon-syntax
|
|
4
|
+
tokens, resolves trailing conditions, matches preset rules, and emits layered
|
|
5
|
+
CSS. Presets own the utility vocabulary.
|
|
8
6
|
|
|
9
7
|
```sh
|
|
10
8
|
bun add @teacss/core @teacss/preset-standard
|
|
@@ -18,362 +16,82 @@ const generator = await createGenerator({ presets: [presetStandard()] });
|
|
|
18
16
|
const { css } = await generator.generate("p:4 bg-color:red-500@hover");
|
|
19
17
|
```
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
Rule declaration tuples use `[property, value, operators?]`. The optional third
|
|
25
|
-
slot is retained for custom processors; Core does not interpret or execute it.
|
|
26
|
-
Only the property and value are serialized into CSS.
|
|
19
|
+
Applications normally use `teacss` and a build adapter. Use Core directly when
|
|
20
|
+
authoring presets, generators, or tooling. Core does not discover CSS entries,
|
|
21
|
+
manage a build tool, or compose runtime class strings.
|
|
27
22
|
|
|
28
23
|
## Key APIs
|
|
29
24
|
|
|
30
|
-
| API | Purpose
|
|
31
|
-
| ---------------------- |
|
|
32
|
-
| `createGenerator` |
|
|
33
|
-
| `splitClassTokens` |
|
|
34
|
-
| `expandGroups` |
|
|
35
|
-
| `expandClassGroups` |
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
`
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
and whitespace remain source boundaries; escaped punctuation cannot silently
|
|
67
|
-
turn a condition into a shorter selector.
|
|
68
|
-
Quoted attributes on structural conditions, such as `probe@_li[title="x"]`
|
|
69
|
-
and `probe@.active[title=""]`, also stay intact during scanning and group
|
|
70
|
-
expansion. Ordinary host arrays and decorator indexes remain extractable.
|
|
71
|
-
Structural selector conditions preserve NBSP-like Unicode spaces before group
|
|
72
|
-
expansion and attribute masking, including escaped forms and unquoted HTML
|
|
73
|
-
class values. Ordinary source whitespace and U+2028/U+2029 line separators
|
|
74
|
-
remain boundaries; named conditions do not gain Unicode-space continuation.
|
|
75
|
-
|
|
76
|
-
The compatibility helpers `parseVariantGroup()` and `expandVariantGroup()`
|
|
77
|
-
accept a `MagicStringLike` buffer. They check all target ranges against the
|
|
78
|
-
original source before writing, so a pre-existing overlapping edit or unreadable
|
|
79
|
-
range rejects without partially expanding earlier groups. Edits outside the
|
|
80
|
-
groups are preserved. This does not roll back failures from a custom `overwrite()`.
|
|
81
|
-
Compatibility group helpers snapshot only own separator and prefix entries,
|
|
82
|
-
rechecking ownership after earlier getters run. Deleted slots cannot introduce
|
|
83
|
-
inherited separators into matching or inherited prefixes into collapsing.
|
|
84
|
-
|
|
85
|
-
`getPath(id)` removes the first `?` and everything after it, including any line
|
|
86
|
-
terminators in the query. The path before it is preserved verbatim.
|
|
87
|
-
|
|
88
|
-
`applyExtractors()` returns the supplied accumulator. Passing a `CountableSet`
|
|
89
|
-
preserves its counting methods in the inferred return type; omitting the
|
|
90
|
-
accumulator or passing `undefined` creates and returns a plain `Set`.
|
|
91
|
-
It commits only changes made by successful extraction. Unchanged
|
|
92
|
-
`CountableSet` members and counts are left alone, including zero, infinite, and NaN counts
|
|
93
|
-
and caller changes made while asynchronous extraction is pending.
|
|
94
|
-
Explicit zero-count members returned or set by extractors are retained when the
|
|
95
|
-
combined count is zero. Deletions and concurrent decrements that exhaust a
|
|
96
|
-
positive source count still remove the member.
|
|
97
|
-
|
|
98
|
-
Programmatic `safelist` entries and callback results accept `{a;b}@condition`
|
|
99
|
-
groups, like explicit token lists. Expanded members respect the blocklist and
|
|
100
|
-
do not increase existing source occurrence counts. Pass `safelist: false` to
|
|
101
|
-
`generate()` to omit the configured safelist.
|
|
102
|
-
|
|
103
|
-
Large direct-input builds may set a positive `tokenConcurrency` limit:
|
|
25
|
+
| API | Purpose |
|
|
26
|
+
| ---------------------- | ----------------------------------------------------------------- |
|
|
27
|
+
| `createGenerator` | Resolve presets and create a CSS generator. |
|
|
28
|
+
| `splitClassTokens` | Split class whitespace while preserving attached `[]` literals. |
|
|
29
|
+
| `expandGroups` | Expand groups while scanning host source. |
|
|
30
|
+
| `expandClassGroups` | Expand groups in an isolated class list. |
|
|
31
|
+
| `applyExtractors` | Extract tokens into a supplied accumulator or a new `Set`. |
|
|
32
|
+
| `compareParentAtRules` | Apply the generator's deterministic parent-rule order. |
|
|
33
|
+
| `comparableWidth` | Normalize comparable media-query widths. |
|
|
34
|
+
|
|
35
|
+
Rule declaration tuples use `[property, value, operators?]`. Core serializes
|
|
36
|
+
the property and value; the optional third slot is available to custom
|
|
37
|
+
processors. The default extractor supports quoted and valid unquoted HTML class
|
|
38
|
+
attributes, along with JavaScript, TypeScript, JSX, TSX, and MDX source.
|
|
39
|
+
|
|
40
|
+
## Rule and shortcut names
|
|
41
|
+
|
|
42
|
+
Ordinary rules require declaration-shaped inputs (`property:value`). Static rule
|
|
43
|
+
names, including their configured prefix, are validated when indexes are built;
|
|
44
|
+
bare names throw `TypeError`. Dynamic rules receive only declaration inputs.
|
|
45
|
+
Preprocessors, variants, `internal` metadata, and output aliases do not bypass
|
|
46
|
+
this boundary.
|
|
47
|
+
|
|
48
|
+
Register bare compositions through `shortcuts`. Shortcut leaves may be other
|
|
49
|
+
shortcuts, declarations, or inline CSS objects. A registered prefixed shortcut
|
|
50
|
+
can complete its own stripped leaves with its matched prefix; public helper
|
|
51
|
+
arguments or edited expansion lists cannot grant that ownership. The parser
|
|
52
|
+
itself remains vocabulary-neutral, and arbitrary application class names remain
|
|
53
|
+
unmatched without warnings.
|
|
54
|
+
|
|
55
|
+
## Generation
|
|
56
|
+
|
|
57
|
+
`generate()` accepts tokens and configured safelist entries. Safelists support
|
|
58
|
+
group syntax such as `{p:4;m:2}@hover`; pass
|
|
59
|
+
`safelist: false` to omit them for a call. For a large direct token set, pass a
|
|
60
|
+
positive `tokenConcurrency` limit. Output order remains deterministic.
|
|
104
61
|
|
|
105
62
|
```ts
|
|
106
63
|
await generator.generate(tokens, { tokenConcurrency: 256 });
|
|
107
64
|
```
|
|
108
65
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
`generate()` infers `matched` as a `Map` when `extendedInfo: true` is required
|
|
113
|
-
by the supplied options type, and as a `Set` when known to be disabled or omitted. Runtime
|
|
114
|
-
booleans and optional `GenerateOptions<true>` return `Set | Map`; narrow with
|
|
115
|
-
`matched instanceof Map` before reading extended token information.
|
|
116
|
-
|
|
117
|
-
With `outputToCssLayers: { allLayers: true }`, the native layer-order declaration
|
|
118
|
-
includes both configured layers (even unused ones) and layers used by rules or
|
|
119
|
-
preflights. Custom layers retain their sorted cascade position, including when
|
|
120
|
-
`getLayers()` selects only part of the result. Aliases and `null` opt-outs apply
|
|
121
|
-
to this declaration as well as the layer blocks.
|
|
122
|
-
|
|
123
|
-
Adapters holding externally extracted tokens may pass
|
|
124
|
-
`isInputCurrent: () => sourceRevision === extractedRevision`. Core captures this
|
|
125
|
-
optional callback once per `generate()` call and checks it repeatedly across
|
|
126
|
-
generation boundaries, including config retries and diagnostic publication.
|
|
127
|
-
It must be synchronous and side-effect-free: `false` rejects with
|
|
128
|
-
`Error("[@teacss/core] Generation input is no longer current.")`; callback errors
|
|
129
|
-
propagate, and invalid callback types or non-boolean results reject with
|
|
130
|
-
`TypeError`. An accidentally asynchronous check's rejection is observed; it does
|
|
131
|
-
not become an additional unhandled rejection. Re-extract before starting another
|
|
132
|
-
call. Omitting it preserves existing behavior. This is not cancellation of
|
|
133
|
-
running hooks or rollback of diagnostics already delivered while the input was current.
|
|
66
|
+
With `extendedInfo: true`, `matched` is a `Map`; otherwise it is a `Set`. If
|
|
67
|
+
the option is a runtime boolean, narrow with `matched instanceof Map` before
|
|
68
|
+
reading extended token information.
|
|
134
69
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
Pseudo-like text inside escaped class names, comments, and attribute strings
|
|
140
|
-
can still merge.
|
|
70
|
+
`outputToCssLayers: { allLayers: true }` declares configured and emitted layers
|
|
71
|
+
in cascade order, including unused configured layers. The experimental `scope`
|
|
72
|
+
option accepts a selector or selector list and scopes generated utility
|
|
73
|
+
selectors, but not raw CSS or preflights. Rule metadata `noScope` bypasses it.
|
|
141
74
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
Pseudo-element names must start CSS identifiers: `@::5`, `@::-5`, and `@::-`
|
|
147
|
-
remain unmatched, including on subject and target conditions. Names are not
|
|
148
|
-
restricted to a preset vocabulary; non-ASCII and escaped starts are supported.
|
|
149
|
-
Escaped legacy names such as `:bef\ore` keep their pseudo-element role and
|
|
150
|
-
per-token limit. Functional `::part()` / `::slotted()` chains compare decoded
|
|
151
|
-
names too, while emitted selectors preserve the authored spelling. Identifier
|
|
152
|
-
hex escapes consume at most six digits and one optional CSS whitespace terminator
|
|
153
|
-
(CRLF counts as one); extra top-level whitespace remains invalid.
|
|
154
|
-
Comments may separate a class dot or pseudo-class colon from its name, and
|
|
155
|
-
the two pseudo-element colons: `./**/active`, `:/**/hover`, `:/**/:before`.
|
|
156
|
-
They cannot split a hash token (`#/**/id`), an identifier, or the name and opening
|
|
157
|
-
parenthesis of a function (`:not/**/(...)`). Part states follow the same rules.
|
|
158
|
-
Functional chain arguments preserve non-ASCII identifiers, including NBSP.
|
|
159
|
-
Between chained pseudo-elements, only comments or permitted part states are
|
|
160
|
-
allowed; neither CSS whitespace nor non-ASCII space-like characters are erased.
|
|
161
|
-
This chain check also applies to resolver-authored suffixes and pseudo-elements.
|
|
162
|
-
Structural identifiers preserve non-ASCII characters such as NBSP; JavaScript
|
|
163
|
-
whitespace is not interchangeable with CSS whitespace during selector validation.
|
|
164
|
-
Quoted structural strings reject raw LF, CR, and form-feed characters, while
|
|
165
|
-
preserving CSS escapes and backslash line continuations (including CRLF).
|
|
166
|
-
Outside quoted strings and comments, a backslash followed by LF, CR, or form-feed
|
|
167
|
-
is not a valid selector escape and leaves the structural condition unmatched.
|
|
168
|
-
|
|
169
|
-
The experimental `scope` generation option accepts a selector or selector list:
|
|
170
|
-
`{ scope: ".app-a, .app-b" }` scopes each generated selector to both roots,
|
|
171
|
-
preserving each scope arm's specificity. It does not style the roots themselves.
|
|
172
|
-
Rule metadata `noScope` bypasses scoping; raw CSS and preflights are not scoped.
|
|
173
|
-
An empty string disables scoping. Empty or comment-only list arms reject
|
|
174
|
-
`generate()` with a `TypeError`, even when there is no generated CSS; this
|
|
175
|
-
guards against accidental unscoped output, not all invalid selector syntax.
|
|
176
|
-
Selector-list cleanup preserves escaped whitespace, hexadecimal escape
|
|
177
|
-
terminators, and non-ASCII identifier characters such as NBSP.
|
|
178
|
-
Replacing an interior `$$` scope placeholder retains a separating space,
|
|
179
|
-
including after escaped commas or braces. Scoped and unscoped output therefore
|
|
180
|
-
preserve the authored descendant relationship instead of joining compounds.
|
|
181
|
-
Adjacent `$$` placeholders are all replaced, even when they share whitespace.
|
|
182
|
-
Each inserts the same scope independently; disabling scope removes them all.
|
|
75
|
+
Adapters that extract tokens outside Core can pass a synchronous
|
|
76
|
+
`isInputCurrent: () => boolean` check. If it returns `false`, generation rejects
|
|
77
|
+
so the adapter can re-extract before retrying. Running hooks and diagnostics
|
|
78
|
+
already delivered are not rolled back.
|
|
183
79
|
|
|
184
80
|
## Configuration lifecycle
|
|
185
81
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
Prefer `await createGenerator()`. The deprecated constructor initializes lazily:
|
|
192
|
-
concurrent calls share one attempt; after it fails, a later call can retry.
|
|
193
|
-
The failed calls still reject, and no automatic background retry is scheduled.
|
|
194
|
-
Initialization publishes config only after rule snapshots succeed. A snapshot
|
|
195
|
-
failure leaves initialization retryable; a replacement committed during snapshot
|
|
196
|
-
reads stays active without a duplicate config event.
|
|
197
|
-
An explicit replacement via `setConfig()` or `prepareConfig()` does not first
|
|
198
|
-
initialize the unrelated constructor config, so invalid initial configs can be
|
|
199
|
-
replaced without rerunning their failing hooks.
|
|
200
|
-
`setConfig()` without a replacement stays a no-op, even before initialization.
|
|
201
|
-
|
|
202
|
-
`prepareConfig(nextConfig)` creates an isolated candidate generator.
|
|
203
|
-
`commitConfig(prepared)` switches the live generator only when that candidate
|
|
204
|
-
is still current. A successful commit preserves generator identity and reports
|
|
205
|
-
observer failures as diagnostics.
|
|
206
|
-
If the diagnostic sink itself throws, that logging failure is ignored: the
|
|
207
|
-
committed configuration stays successful and async observers leave no unhandled
|
|
208
|
-
rejection. This does not suppress `configResolved()` failures before commit.
|
|
209
|
-
Commit validation rechecks candidate identity after reading mutable configuration;
|
|
210
|
-
if a getter reconfigures the candidate, the commit is rejected without touching
|
|
211
|
-
the live configuration or dispatching its observers.
|
|
212
|
-
|
|
213
|
-
`configResolved(config)` hooks may be synchronous or asynchronous. Core awaits
|
|
214
|
-
them sequentially in resolved preset order, then awaits the user hook, and
|
|
215
|
-
rebuilds rule indexes afterward. Return values are ignored; modify `config`
|
|
216
|
-
directly. A throw or rejection aborts resolution, so failed `setConfig()` calls
|
|
217
|
-
leave the live configuration unchanged. Config-event observers remain separate.
|
|
218
|
-
|
|
219
|
-
Content pipeline filters merge across presets without expanding the source list
|
|
220
|
-
into function arguments, so large compositions do not hit Node's argument limit.
|
|
221
|
-
Filter order, deduplication, and regular-expression identity are preserved.
|
|
222
|
-
|
|
223
|
-
Themes are deep-merged only while they are plain objects. A non-plain theme is
|
|
224
|
-
atomic; replace it, reset to a plain object with `{ $reset: true }`, or combine
|
|
225
|
-
it through `extendTheme`.
|
|
226
|
-
New plain-object branches also consume nested `$reset` markers, including when
|
|
227
|
-
replacing a scalar; the caller's patch is left unchanged.
|
|
228
|
-
`mergeDeep()` copies array-patch containers and retains only their own items,
|
|
229
|
-
including new fields and replacements of non-array values. Passing `true` as the
|
|
230
|
-
third argument concatenates only when both values are arrays.
|
|
231
|
-
|
|
232
|
-
`toArray()` treats optional `undefined` input as an empty array in its return
|
|
233
|
-
type, preserving array mutability and explicit `undefined` elements within arrays.
|
|
234
|
-
It captures array length once for both density checks and sparse compaction;
|
|
235
|
-
items appended by getters are not added to the current compacted result.
|
|
82
|
+
Prefer `await createGenerator()`. The constructor is deprecated and initializes
|
|
83
|
+
lazily. `prepareConfig(nextConfig)` creates an isolated candidate;
|
|
84
|
+
`commitConfig(prepared)` publishes it only while that candidate is current.
|
|
85
|
+
Failed preparation leaves the live configuration unchanged.
|
|
236
86
|
|
|
237
|
-
|
|
238
|
-
|
|
87
|
+
`configResolved(config)` hooks run sequentially in preset order, followed by the
|
|
88
|
+
user hook. Core awaits each hook and rebuilds rule indexes afterward. A throw or
|
|
89
|
+
rejection aborts resolution. Configuration observers are notified separately.
|
|
239
90
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
configuration resolution and prepared-config validation still run normally.
|
|
91
|
+
Themes deep-merge while both sides are plain objects. Use `{ $reset: true }` to
|
|
92
|
+
replace a branch, or `extendTheme` for explicit composition. Preset preflights
|
|
93
|
+
receive the current call's generated utilities through `context.generated`.
|
|
244
94
|
|
|
245
|
-
`
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
Rule callbacks receive `currentSelector` and `variantMatch` for their local parse
|
|
250
|
-
branch, including shortcut leaves; `rawSelector` remains the outer styled token.
|
|
251
|
-
`parseUtil()` does not rewrite its caller's matching context. Its rule and
|
|
252
|
-
`constructCSS()` callbacks use the same captured configuration even if an async
|
|
253
|
-
variant replaces the generator configuration in between.
|
|
254
|
-
Direct `parseUtil()` calls retry both results and failures made obsolete by
|
|
255
|
-
in-place edits to the current prepared config. Unchanged-config failures still
|
|
256
|
-
reject with their original value; contexts for replaced configs stay bound.
|
|
257
|
-
Rule activation checks both config identity and runtime revision, so an obsolete
|
|
258
|
-
async result cannot repopulate `activatedRules` after another call refreshes
|
|
259
|
-
prepared-config indexes.
|
|
260
|
-
Late branches from an obsolete parse also skip rule-detail recording, so they
|
|
261
|
-
cannot append retired rules to the shared `context.rules` after a retry.
|
|
262
|
-
Direct parsing with a retained older configuration still records its own details.
|
|
263
|
-
Retained contexts for an older configuration use a separate condition cache:
|
|
264
|
-
neither resolved nor unrecognized conditions can leak between old and live
|
|
265
|
-
configurations. Live configuration revisions still invalidate their cache.
|
|
266
|
-
Copied contexts exposed by `parseToken()`, extended-info data, and preflight
|
|
267
|
-
utilities retain that configuration binding when reused with Core methods.
|
|
268
|
-
Dynamic-rule prefix enumeration and dispatch buckets append own array entries,
|
|
269
|
-
so inherited numeric setters cannot discard prefixes or rules. Keyed and
|
|
270
|
-
fallback rule order remains identical to the ordinary scan.
|
|
271
|
-
Condition results, delimiter stacks, and pseudo-element chains use the same
|
|
272
|
-
own-entry writes, preserving both resolved and unresolved conditions.
|
|
273
|
-
Group expansion/collapse and unmatched-token suggestions likewise preserve
|
|
274
|
-
collected items and edit-distance rows through inherited numeric setters.
|
|
275
|
-
Unmatched-token indexing captures the static rule map once for both contents
|
|
276
|
-
and cache identity, ignoring absent or deleted static entries. Dynamic rule and
|
|
277
|
-
metadata-prefix traversal reads only own array items, so inherited entries do
|
|
278
|
-
not create diagnostic vocabulary or trigger matcher probes.
|
|
279
|
-
Event dispatch reads its event store once and snapshots only own listener slots,
|
|
280
|
-
rechecking each slot after earlier getters run. Subscription changes made by
|
|
281
|
-
listeners apply to subsequent dispatches, not the current snapshot.
|
|
282
|
-
Generator configuration notifications use the same single-store, own-slot
|
|
283
|
-
snapshot while retaining their separate observer-error isolation.
|
|
284
|
-
If reading that snapshot fails, the committed configuration remains successful:
|
|
285
|
-
the error is reported, that notification batch is skipped, and later notifications
|
|
286
|
-
can proceed after the listener storage is repaired.
|
|
287
|
-
Unsubscription uses the same own-slot snapshot before filtering, so deletions
|
|
288
|
-
by getters cannot retain inherited listeners. A failed snapshot leaves listener
|
|
289
|
-
storage unchanged and permits retrying the unsubscribe function.
|
|
290
|
-
`uniq()`, `uniqueBy()`, and `BetterMap.flatMap()` likewise check slot ownership
|
|
291
|
-
at each read, so getters and comparison callbacks cannot expose inherited values.
|
|
292
|
-
These traversals capture the initial array length; `toArray()` still preserves
|
|
293
|
-
the identity of dense arrays.
|
|
294
|
-
Array patches and recursive `$reset` cleanup also recheck ownership while reading,
|
|
295
|
-
so getter-driven deletions cannot promote inherited items into merged config.
|
|
296
|
-
CSS entry normalization checks ownership as entries are filtered. CSS value-list
|
|
297
|
-
normalization snapshots own items once before classification and conversion,
|
|
298
|
-
avoiding repeated top-level getters and retaining entry-tuple metadata.
|
|
299
|
-
`clone()` uses the same captured array length for allocation and copying, retaining
|
|
300
|
-
own `undefined` slots when source entries disappear during the reverse traversal.
|
|
301
|
-
Extractor, preprocessor, variant, and postprocessor traversal rechecks own slots
|
|
302
|
-
after earlier callbacks, including async waits. Extractor-returned arrays use
|
|
303
|
-
the same own-slot reads, so deleted entries cannot introduce inherited tokens.
|
|
304
|
-
Variant branch results, handler snapshots, postprocessor result arrays, and
|
|
305
|
-
preflight grouping also recheck ownership after earlier getters run, preserving
|
|
306
|
-
authored ordering without promoting inherited branches, selectors, or preflights.
|
|
307
|
-
Generation input arrays, safelist result arrays, sorted layer results, and
|
|
308
|
-
`getLayers()` include/exclude lists use the same own-slot reads, so getters cannot
|
|
309
|
-
expose inherited tokens or alter layer selection through deleted entries.
|
|
310
|
-
Condition parsing, resolver traversal, and selector assembly likewise recheck
|
|
311
|
-
own array entries after earlier getters or callbacks, excluding inherited
|
|
312
|
-
conditions and resolver hooks exposed by deletions.
|
|
313
|
-
`symbols.variants` snapshots only own handlers in callback inputs, callback
|
|
314
|
-
results, and array values. Shortcut expansion snapshots each own result slot
|
|
315
|
-
once before separating tokens from inline declarations.
|
|
316
|
-
|
|
317
|
-
Copied rule metadata uses own descriptor fields and prototype-free descriptors,
|
|
318
|
-
so ambient descriptor properties cannot replace accessors or redirect layers.
|
|
319
|
-
`withLayer()` rechecks metadata-slot ownership after reading its getter. A deleted
|
|
320
|
-
slot is recreated as an own property without invoking inherited setters; existing
|
|
321
|
-
readonly metadata slots still reject writes.
|
|
322
|
-
Metadata prefix/autocomplete arrays and copied context handler arrays also
|
|
323
|
-
recheck item ownership while reading, excluding inherited items exposed by getters.
|
|
324
|
-
Configuration shortcut parsing, preset and rule prefix copies, and rule-list
|
|
325
|
-
cloning use own-slot reads too, including rule-index rebuilds after config hooks.
|
|
326
|
-
Rule and shortcut tuple cloning validates each required slot immediately before
|
|
327
|
-
reading it. A matcher getter cannot expose an inherited body; already captured
|
|
328
|
-
matcher values remain valid if their getter removes its own source slot.
|
|
329
|
-
Top-level and child preset lists use own-slot flattening for both list and
|
|
330
|
-
group entries. `mergeConfigs()` rechecks input ownership after reading each
|
|
331
|
-
configuration, so earlier getters cannot introduce inherited presets or configs.
|
|
332
|
-
Merged configuration lists, autocomplete templates/extractors and shorthand
|
|
333
|
-
alternatives, content sources, and pipeline filters snapshot only own items
|
|
334
|
-
before flattening or joining, excluding inherited values exposed during reads.
|
|
335
|
-
Shorthand dictionary keys are rechecked before each read. Nested autocomplete
|
|
336
|
-
and CLI normalization uses captured values even if later getters delete their
|
|
337
|
-
source properties, preserving singleton entries when configurations are merged.
|
|
338
|
-
|
|
339
|
-
Variants and postprocessors may edit their declaration tuples in place without
|
|
340
|
-
rewriting source rule bodies. Core isolates those inputs, including inline
|
|
341
|
-
shortcut declarations and the body passed to `constructCSS`.
|
|
342
|
-
`normalizeVariant()` preserves the input variant's theme type for both function
|
|
343
|
-
and object forms; normalization does not loosen typed theme requirements.
|
|
344
|
-
For multi-result variants, each branch's matcher is checked against `blocklist`
|
|
345
|
-
before rules or shortcuts run. Allowed branches still emit CSS; an entirely
|
|
346
|
-
blocked result stays excluded from unmatched diagnostics.
|
|
347
|
-
Regular-expression matching invokes custom `exec` callbacks with the matcher
|
|
348
|
-
as receiver, without reading the function's `call` property. This also applies
|
|
349
|
-
to global, sticky, and frozen matchers, preserving their existing index handling.
|
|
350
|
-
Extractor `extract` and preflight `getCSS` hooks likewise ignore an own `call`
|
|
351
|
-
property, retain their owner as receiver, and await results or propagate errors.
|
|
352
|
-
Variant `match`, `body`, `selector`, and `handle` callbacks also ignore an own
|
|
353
|
-
`call` property while retaining their variant or original handler receiver.
|
|
354
|
-
Only `match` supports asynchronous results; CSS handler callbacks remain synchronous.
|
|
355
|
-
`sortLayers`, `outputToCssLayers.cssLayerName`, and synchronous/asynchronous
|
|
356
|
-
rule iterator methods follow the same receiver-preserving invocation contract.
|
|
357
|
-
Functional `symbols.variants` values receive an independent handler array per
|
|
358
|
-
rule output, so adding, removing, or reordering handlers does not change sibling
|
|
359
|
-
outputs. Handler objects themselves retain their identity and prototype hooks.
|
|
360
|
-
Handler fields, including both parent-tuple slots, are captured before applying
|
|
361
|
-
callbacks; callback edits cannot change the current application’s parent or order.
|
|
362
|
-
|
|
363
|
-
Shortcut prefix matching ignores ambient `Object.prototype.prefix` values.
|
|
364
|
-
Explicit metadata prefixes, including metadata prototype accessors in prepared
|
|
365
|
-
configurations, remain supported for static and dynamic shortcuts.
|
|
366
|
-
Direct shortcut expansion checks edits to the current prepared configuration
|
|
367
|
-
before lookup, including renamed matchers and mutated prefix arrays.
|
|
368
|
-
External lists passed to `expandConfiguredExpansions` are indexed from their
|
|
369
|
-
current contents on each lookup, without replacing the cached config index.
|
|
370
|
-
Contexts retained by extension hooks resume normal prepared-config checks after
|
|
371
|
-
their generation parsing finishes, including when it fails.
|
|
372
|
-
Missing-utility warnings inside shortcuts wait until that shortcut finishes
|
|
373
|
-
stringification, and are discarded if its config becomes obsolete. Failed
|
|
374
|
-
stringification does not consume warning deduplication for a later retry.
|
|
375
|
-
|
|
376
|
-
This package does not load filesystem configuration, manage build-tool
|
|
377
|
-
lifecycle, or provide runtime class composition.
|
|
378
|
-
|
|
379
|
-
Pre-1.0. Public engine APIs may change before the stable release.
|
|
95
|
+
The compatibility helpers `parseVariantGroup()` and `expandVariantGroup()`
|
|
96
|
+
accept a `MagicStringLike` buffer and reject overlapping or unreadable target
|
|
97
|
+
ranges before writing group edits.
|
package/dist/index.d.ts
CHANGED
|
@@ -398,6 +398,8 @@ declare class TeacssGeneratorInternal<Theme extends object = object> {
|
|
|
398
398
|
private _expansionIndex?;
|
|
399
399
|
private _contextConfigs;
|
|
400
400
|
private _expansionPrefixes;
|
|
401
|
+
/** Only engine-produced, unchanged leaves may complete a stripped declaration prefix. */
|
|
402
|
+
private _expansionOwnership;
|
|
401
403
|
private _generationContexts;
|
|
402
404
|
private _matchedStaticContexts;
|
|
403
405
|
/** Tagged empty cache payloads retain match evidence without retaining contexts or raw token keys. */
|
|
@@ -407,6 +409,9 @@ declare class TeacssGeneratorInternal<Theme extends object = object> {
|
|
|
407
409
|
private _preparedConfigs;
|
|
408
410
|
private _indexedRules?;
|
|
409
411
|
private _indexedRuleSnapshot?;
|
|
412
|
+
private _ruleObservation?;
|
|
413
|
+
private _indexedShortcuts?;
|
|
414
|
+
private _indexedShortcutSnapshot?;
|
|
410
415
|
private _preparedCacheSnapshot?;
|
|
411
416
|
private _preparedConfigMutable;
|
|
412
417
|
private _preparedCacheReliable;
|
|
@@ -486,13 +491,14 @@ declare class TeacssGeneratorInternal<Theme extends object = object> {
|
|
|
486
491
|
constructCustomCSS(context: Readonly<RuleContext<Theme>>, body: CSSObjectInput | CSSEntriesInput, overrideSelector?: string): string;
|
|
487
492
|
private constructNormalizedCSS;
|
|
488
493
|
parseUtil(input: string | VariantMatchedResult<Theme>, context: RuleContext<Theme>, internal?: boolean, shortcutPrefix?: string | string[] | undefined): Promise<(ParsedUtil | RawUtil)[] | undefined>;
|
|
494
|
+
private parseUtilWithOwnership;
|
|
489
495
|
private resolveCSSResult;
|
|
490
496
|
stringifyUtil(parsed?: ParsedUtil | RawUtil, context?: RuleContext<Theme>): StringifiedUtil<Theme>[] | undefined;
|
|
491
497
|
expandShortcut(input: string, context: RuleContext<Theme>, depth?: number): Promise<ExpansionResult | undefined>;
|
|
492
498
|
private expandMatchedShortcut;
|
|
493
499
|
expandConfiguredExpansions(input: string, context: RuleContext<Theme>, depth: number, entries: ExpansionEntry<Theme>[], label: "shortcut", fallback?: (input: string, context: RuleContext<Theme>, depth: number) => Promise<ExpansionResult | undefined>, inheritedPrefix?: string): Promise<ExpansionResult | undefined>;
|
|
494
500
|
private expandConfiguredExpansionsForInput;
|
|
495
|
-
stringifyShortcuts(parent: VariantMatchedResult<Theme>, context: RuleContext<Theme>, expanded: (string | ExpansionInlineValue)[], meta?: RuleMeta,
|
|
501
|
+
stringifyShortcuts(parent: VariantMatchedResult<Theme>, context: RuleContext<Theme>, expanded: (string | ExpansionInlineValue)[], meta?: RuleMeta, _matchedPrefixes?: ExpansionPrefixes): Promise<StringifiedUtil<Theme>[] | undefined>;
|
|
496
502
|
isBlocked(raw: string): boolean;
|
|
497
503
|
getBlocked(raw: string): [BlocklistValue, BlocklistMeta | undefined] | undefined;
|
|
498
504
|
private matchesBlocklist;
|
|
@@ -1650,7 +1656,7 @@ export declare const LAYER_MARK_ALL = "__ALL__";
|
|
|
1650
1656
|
* ```
|
|
1651
1657
|
*
|
|
1652
1658
|
* - A declaration is either `property:value` (split on the first depth-0 `:`) or
|
|
1653
|
-
* a bare keyword (no depth-0 `:`, e.g. `relative`, `sticky`, `truncate`).
|
|
1659
|
+
* a bare keyword (no depth-0 `:`, e.g. `relative`, `sticky`, `text-truncate`).
|
|
1654
1660
|
* - `()` and `[]` are literal regions; operators inside them (`:` `!` `@` …) do
|
|
1655
1661
|
* not participate in parsing.
|
|
1656
1662
|
* - `!` immediately after the value (before any `@`) is `!important`.
|