domflax 0.1.0

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 (44) hide show
  1. package/LICENSE +214 -0
  2. package/dist/chunk-4HHISSMR.js +2227 -0
  3. package/dist/chunk-4HHISSMR.js.map +1 -0
  4. package/dist/chunk-6WVVF6AD.js +55 -0
  5. package/dist/chunk-6WVVF6AD.js.map +1 -0
  6. package/dist/chunk-77SLHRN6.js +2047 -0
  7. package/dist/chunk-77SLHRN6.js.map +1 -0
  8. package/dist/chunk-ZJ2S36GY.js +175 -0
  9. package/dist/chunk-ZJ2S36GY.js.map +1 -0
  10. package/dist/cli.cjs +5207 -0
  11. package/dist/cli.cjs.map +1 -0
  12. package/dist/cli.d.cts +1 -0
  13. package/dist/cli.d.ts +1 -0
  14. package/dist/cli.js +1310 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/index.cjs +4383 -0
  17. package/dist/index.cjs.map +1 -0
  18. package/dist/index.d.cts +539 -0
  19. package/dist/index.d.ts +539 -0
  20. package/dist/index.js +110 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/pattern-CX6iBzTD.d.ts +237 -0
  23. package/dist/pattern-P4FIKAUB.d.cts +237 -0
  24. package/dist/pattern-kit.cjs +630 -0
  25. package/dist/pattern-kit.cjs.map +1 -0
  26. package/dist/pattern-kit.d.cts +80 -0
  27. package/dist/pattern-kit.d.ts +80 -0
  28. package/dist/pattern-kit.js +55 -0
  29. package/dist/pattern-kit.js.map +1 -0
  30. package/dist/types-BQ7l6dVe.d.cts +749 -0
  31. package/dist/types-BQ7l6dVe.d.ts +749 -0
  32. package/dist/verify.cjs +2747 -0
  33. package/dist/verify.cjs.map +1 -0
  34. package/dist/verify.d.cts +245 -0
  35. package/dist/verify.d.ts +245 -0
  36. package/dist/verify.js +2700 -0
  37. package/dist/verify.js.map +1 -0
  38. package/dist/webpack-loader.cjs +4149 -0
  39. package/dist/webpack-loader.cjs.map +1 -0
  40. package/dist/webpack-loader.d.cts +21 -0
  41. package/dist/webpack-loader.d.ts +21 -0
  42. package/dist/webpack-loader.js +30 -0
  43. package/dist/webpack-loader.js.map +1 -0
  44. package/package.json +99 -0
@@ -0,0 +1,539 @@
1
+ import { n as IRDocument, J as ApplyResult, K as RewriteGroup, L as ApplyContext, O as RewriteOp, Q as FixpointConfig, T as StyleResolver, U as SelectorIndex, W as Pass, X as PassManager, x as RewriteFactory, Y as PhaseRunResult, Z as Pipeline, _ as SyntheticSink, c as StyleNormalizer, w as Captures, P as Pattern, v as SafetyLevel, $ as EncodedSourceMap } from './types-BQ7l6dVe.cjs';
2
+ export { a0 as AppliedOp, A as AttrMap, a1 as AttrValue, a2 as Backend, a3 as BackendContext, k as Backref, B as BackrefTable, a4 as Brand, g as ClassList, a5 as ClassListForm, a6 as ClassSegment, a7 as ClassToken, a8 as CodegenResult, a9 as CommentSpec, e as ConditionKey, C as CssProperty, aa as CssValue, ab as DeclSignature, ac as DeepReadonly, H as Diagnostic, ad as DiagnosticCode, ae as DistributiveOmit, af as EditPlan, E as ElementLike, ag as ElementSpec, ah as EmitContext, ai as EmitResult, aj as ExprKind, ak as ExprRecord, p as ExprRef, r as ExprRegistry, al as ExprSpec, am as FileKind, an as FragmentSpec, ao as Frontend, ap as FrontendConfig, F as FrontendKind, aq as FrontendParseContext, ar as HaltReason, m as IRComment, o as IRElement, q as IRExpr, s as IRFragment, f as IRNamespace, l as IRNode, as as IRNodeBase, I as IRNodeId, at as IRNodeKind, u as IRText, t as IdAllocator, au as InheritedPropertyTable, h as InlineStyle, M as MatchContext, y as MatchResult, N as NodeLike, j as NodeMeta, av as NodeRefSpec, b as NodeSpec, aw as OpOrigin, ax as OpValidationIssue, ay as OpaqueReason, az as OpaqueToken, aA as ParentLayoutContext, aB as ParseResult, z as PassCategory, aC as PassPhase, aD as PassTraceEntry, G as PatternDoc, aE as PatternName, aF as PipelineConfig, aG as PipelineInput, aH as PipelineOutput, aI as PipelineStats, aJ as Position, D as PreconditionSketch, aK as ReindentSpec, aL as Reporter, aM as ResolveInput, aN as ResolveResult, aO as ResolverDiagnostic, aP as RewriteContext, R as RewriteOpDraft, aQ as SelectorUsage, aR as Severity, aS as SkippedOpGroup, aT as SourceFile, aU as SourceFileId, i as SourceSpan, aV as StructuralInverse, aW as StyleBlock, d as StyleCondition, a as StyleConflictPolicy, aX as StyleDecl, S as StyleMap, aY as StyleOrigin, aZ as StylePredicate, a_ as SyntheticClass, a$ as TextEdit, b0 as TextSpec, b1 as TreeShapeSketch, b2 as VisitContext, b3 as VisitSignal, V as Visitor } from './types-BQ7l6dVe.cjs';
3
+ import { A as AuthoredPattern } from './pattern-P4FIKAUB.cjs';
4
+ export { B as BASE_CONDITION, u as BASE_CONDITION_KEY, v as ElementInit, w as MutableBackrefTable, x as childIds, y as conditionKey, z as createBackrefTable, C as createComment, G as createDocument, H as createElement, I as createExpr, J as createExprRegistry, K as createFragment, L as createIdAllocator, N as createText, O as defaultMeta, Q as elementIds, S as emptyAttrMap, T as emptyClassList, U as emptyInlineStyle, i as emptyStyleMap, V as getElement, W as getNode, X as walk } from './pattern-P4FIKAUB.cjs';
5
+
6
+ /**
7
+ * @domflax/core — the pure applier (the one trusted mutator).
8
+ *
9
+ * {@link applyOps} takes an {@link IRDocument} plus a flat list of {@link RewriteOp}s and returns
10
+ * a NEW, mutated document (the input document is left untouched — "pure" in the input-immutability
11
+ * sense). Every op is validated against the safety ceiling and node-local safety floor before it
12
+ * runs; rejected ops are collected into {@link ApplyResult.skipped} with {@link Diagnostic}s rather
13
+ * than throwing. Dependency-free: only the `./types` contract and `./builders` runtime helpers.
14
+ */
15
+
16
+ interface ApplyOutcome {
17
+ /** The new document (the input doc is never mutated). */
18
+ readonly doc: IRDocument;
19
+ readonly result: ApplyResult;
20
+ }
21
+ /** Shallow-immutable clone: input doc and its node objects are never mutated. */
22
+ declare function cloneDocument(doc: IRDocument): IRDocument;
23
+ /**
24
+ * Apply a flat list of ops to a copy of `doc`. The input document is never mutated.
25
+ * Each op is independently validated; failing ops are skipped (collected in
26
+ * {@link ApplyResult.skipped}) instead of throwing.
27
+ */
28
+ declare function applyOps(doc: IRDocument, ops: readonly RewriteOp[], ctx?: Partial<ApplyContext>): ApplyOutcome;
29
+ /**
30
+ * Apply pre-grouped ops (each {@link RewriteGroup} is committed atomically: if ANY op in the group
31
+ * fails validation, the whole group is skipped and none of its ops mutate the tree).
32
+ */
33
+ declare function applyGroups(doc: IRDocument, groups: readonly RewriteGroup[], ctx?: Partial<ApplyContext>): ApplyOutcome;
34
+
35
+ /**
36
+ * @domflax/core — pass manager + supporting contexts.
37
+ *
38
+ * Runs {@link Pattern}s grouped by {@link PassCategory} in declared order, driving the `flatten`
39
+ * phase to a fixpoint under a max-iteration budget, and isolating per-node pattern errors into
40
+ * {@link Diagnostic}s (a thrown pattern never aborts the run — it becomes `DF_PATTERN_THREW`).
41
+ *
42
+ * Dependency-free: only the `./types` contract plus `./builders` + `./ops` runtime helpers.
43
+ */
44
+
45
+ declare const DEFAULT_FIXPOINT: FixpointConfig;
46
+ /** A no-op resolver: owns nothing, resolves to empty styles. Useful as an injection default. */
47
+ declare function createNullResolver(): StyleResolver;
48
+ /** A SelectorIndex that reports zero CSS-targeting (no combinator/structural coupling). */
49
+ declare function createNullSelectorIndex(): SelectorIndex;
50
+ /**
51
+ * Build a real {@link SelectorIndex} from the active resolver.
52
+ *
53
+ * For a resolver that reports project COMPLEX selectors — anything with a combinator (`>`/`+`/`~`/
54
+ * descendant) or a structural pseudo, i.e. the custom-CSS resolver — every element whose static class
55
+ * participates in such a selector is flagged so the flatten/compress guards (`targetedByCombinator` /
56
+ * `affectsSelectorMatching`) fire and a wrapper a selector depends on is NOT flattened. An element is
57
+ * combinator-coupled when one of its classes is used as a descendant/child ancestor, as a sibling
58
+ * subject, or as a `:has()` argument; structural-coupled when used in `:nth-child(...)` etc.
59
+ *
60
+ * For a combinator-free resolver (Tailwind utilities — no `complexSelectors()`), this degrades to the
61
+ * null index so behaviour is unchanged.
62
+ */
63
+ declare function buildSelectorIndex(doc: IRDocument, resolver: StyleResolver): SelectorIndex;
64
+ /** The pattern-kit factory: produces op DRAFTS and detached NodeSpecs without any allocation. */
65
+ declare function createRewriteFactory(): RewriteFactory;
66
+ /**
67
+ * Runs `passes` over `doc` to a per-phase fixpoint. This is the concrete entry the pipeline calls
68
+ * (the {@link PassManager} interface keeps passes on the call site; we accept them explicitly here
69
+ * so the manager stays stateless).
70
+ */
71
+ declare function runPasses(doc: IRDocument, passes: readonly Pass[], ctx: ApplyContext, config?: FixpointConfig): {
72
+ readonly doc: IRDocument;
73
+ readonly results: readonly PhaseRunResult[];
74
+ };
75
+ /** A {@link PassManager} that runs the given passes (carried on the manager instance). */
76
+ declare function createPassManager(passes: readonly Pass[]): PassManager;
77
+
78
+ /**
79
+ * @domflax/core — the pure, single-file pipeline.
80
+ *
81
+ * Wires injected interfaces together: {@link Frontend} → resolve → {@link PassManager} →
82
+ * {@link Backend}. Core itself stays dependency-free; the resolver, frontend, and backend are all
83
+ * supplied by the caller, so no heavy third-party libs ever reach this package.
84
+ */
85
+
86
+ /** A minimal in-memory {@link SyntheticSink}: dedupes by className, drains in insertion order. */
87
+ declare function createSyntheticSink(): SyntheticSink;
88
+ /** Build the pure single-file {@link Pipeline}. */
89
+ declare function createPipeline(): Pipeline;
90
+
91
+ /**
92
+ * @domflax/core — the shared reverse-emit step (computed → className).
93
+ *
94
+ * The backend re-prints `className` from each element's {@link ClassList}, but the pass manager
95
+ * records optimized styles on `computed`. This module folds those optimized computed styles back
96
+ * into the element's static class tokens, and is the SINGLE source of truth shared by every
97
+ * orchestrator (the `domflax` meta package, `@domflax/cli`, and the pattern auto-test harness) so
98
+ * their pipelines cannot diverge.
99
+ *
100
+ * ## REPLACE, not append
101
+ *
102
+ * For every TOUCHED, rewritable (non-opaque, non-dynamic) element we ask the resolver for the
103
+ * MINIMAL class set reproducing the element's FULL computed style (`resolver.emit(el.computed)`),
104
+ * then REPLACE the element's static tokens with it — rather than appending. Replacing is what lets
105
+ * a compress pass actually shorten output: `px-4 py-4` collapses to `p-4`, equal `w/h` to `size-*`,
106
+ * the four insets to `inset-0`, and fully-overridden duplicates simply disappear.
107
+ *
108
+ * ## Droppability gate (never lose a load-bearing class)
109
+ *
110
+ * A token is only removed when `resolver.selectorUsage(token).droppable` is true — i.e. it is a
111
+ * plain, resolver-owned utility whose entire contribution is reproducible from `computed`. Tokens
112
+ * that are unknown to the resolver, opaque (combinator/at-rule utilities whose effect never folds
113
+ * onto the element's own box), variant-bound, or referenced by a custom-CSS selector are NOT
114
+ * droppable and are preserved verbatim. As a safety net, if `emit` produces nothing at all we leave
115
+ * the element's tokens untouched (a resolver that failed to load must never erase classes).
116
+ */
117
+
118
+ /**
119
+ * Fold every TOUCHED, rewritable element's optimized computed style back into the MINIMAL static
120
+ * class-token set (see module docs). Mutates `doc` in place.
121
+ */
122
+ declare function syncClassesFromComputed(doc: IRDocument, resolver: StyleResolver, norm: StyleNormalizer): void;
123
+
124
+ /**
125
+ * @domflax/patterns — flatten pattern: `empty-style-div`.
126
+ *
127
+ * Collapses the most common piece of structural noise of all: a `<div>` whose ONLY role is to wrap
128
+ * a single child while contributing nothing to layout or paint —
129
+ *
130
+ * <div><Child/></div> (no styles at all)
131
+ * <div style="display:block"><Child/></div> (the default; still a no-op box)
132
+ *
133
+ * Such a div is layout-neutral: it is a plain block box with no own visual style, establishes no
134
+ * box / formatting / stacking context, is not a containing block, and declares no custom properties
135
+ * a descendant might read. Its box is therefore indistinguishable from "not being there", so it can
136
+ * be unwrapped into its sole child.
137
+ *
138
+ * Authored with the declarative {@link pattern} API. The opacity-barrier + selector-safety guards
139
+ * (ref/handlers/dynamic-children/raw-html/combinator/reparent-impact) are applied automatically for
140
+ * every `flatten/*` pattern; the `where` predicates below add the LAYOUT-neutrality requirements
141
+ * specific to this pattern (no non-block display, no box/formatting/stacking context, no containing
142
+ * block, no custom-property coupling, no structural-pseudo targeting).
143
+ */
144
+ /**
145
+ * Flatten a layout-neutral, style-free `<div>` wrapper into its sole element child.
146
+ */
147
+ declare const emptyStyleDiv: AuthoredPattern<Captures>;
148
+
149
+ /**
150
+ * @domflax/patterns — flatten pattern: `flex-center-wrapper`.
151
+ *
152
+ * Collapses the ubiquitous "centering wrapper" idiom
153
+ *
154
+ * <div style="display:flex; align-items:center; justify-content:center"><Child/></div>
155
+ *
156
+ * into its sole child, pushing the centering intent down onto the child as `place-self: center`.
157
+ * The wrapper only exists to center one element; once `place-self:center` lives on the child the
158
+ * wrapper is pure structural noise and can go.
159
+ *
160
+ * Authored with the declarative {@link pattern} API: the match is the flex-centering computed-style
161
+ * signature on a single-element-child `<div>` that paints nothing of its own; the recipe folds
162
+ * inheritable styles onto the child, grants it `place-self:center`, then unwraps the wrapper
163
+ * (id-preserving). The opacity-barrier + selector-safety guards are applied automatically by the
164
+ * `pattern()` factory for every `flatten/*` pattern.
165
+ */
166
+ /**
167
+ * Flatten a flex-centering `<div>` wrapper into its sole element child, granting the child
168
+ * `place-self:center`.
169
+ */
170
+ declare const flexCenterWrapper: AuthoredPattern<Captures>;
171
+
172
+ /**
173
+ * @domflax/patterns — flatten pattern: `nested-flex-merge`.
174
+ *
175
+ * Collapses a redundant nesting of two flex containers
176
+ *
177
+ * <div style="display:flex; align-items:center; gap:8px">
178
+ * <div style="display:flex; flex-direction:column"> … </div>
179
+ * </div>
180
+ *
181
+ * where the OUTER flex container's sole element child is ITSELF a flex container, into a single
182
+ * flex container that carries the union of both elements' flex declarations. The outer wrapper's
183
+ * box is then structural noise (it paints nothing and only establishes a flex context that the
184
+ * merged child now also establishes), so it is removed.
185
+ *
186
+ * Authored with the declarative {@link pattern} API: the match is a flex `<div>` with a single
187
+ * element child painting nothing of its own (auto-guarded against opacity barriers / combinator
188
+ * targeting like every `flatten/*` pattern). The value-relational reasoning — the child must also
189
+ * be a (non-combinator) flex container, the wrapper must carry only transferable flex/inheritable
190
+ * declarations, and the two must not conflict on any shared flex property — lives in the `rewrite`
191
+ * op-draft factory escape hatch, which folds inherited styles, transfers the wrapper's flex
192
+ * declarations onto the child (target-wins), then unwraps the wrapper.
193
+ */
194
+ /**
195
+ * Flatten a flex container whose sole child is a compatible flex container into a single container.
196
+ */
197
+ declare const nestedFlexMerge: AuthoredPattern<Captures>;
198
+
199
+ /**
200
+ * @domflax/patterns — flatten pattern: `passthrough-wrapper`.
201
+ *
202
+ * Collapses a purely-structural wrapper that exists for no reason at all:
203
+ *
204
+ * <div><Child/></div>
205
+ *
206
+ * The wrapper paints nothing, establishes no box / formatting / stacking context, carries no
207
+ * attributes beyond an (optional) inert class, holds exactly one element child, and is free of every
208
+ * opacity barrier (ref / event-handlers / dynamic children / dangerous html / spread / component).
209
+ * Such a `<div>` is pure DOM noise: removing it and hoisting the child is invisible to both paint
210
+ * and layout.
211
+ *
212
+ * Authored with the declarative {@link pattern} API. The opacity-barrier + selector-safety guards
213
+ * (ref/handlers/dynamic-children/raw-html/combinator/reparent-impact) are applied automatically for
214
+ * every `flatten/*` pattern; the `where` predicates add the passthrough-specific requirements (no
215
+ * box/formatting/stacking context, no own attrs, no dynamic/spread classes, not a component, not a
216
+ * structural-pseudo subject).
217
+ */
218
+ /**
219
+ * Flatten a do-nothing `<div>` wrapper into its sole element child, folding any inheritable styles
220
+ * down first so inherited values survive the box removal.
221
+ */
222
+ declare const passthroughWrapper: AuthoredPattern<Captures>;
223
+
224
+ /**
225
+ * @domflax/patterns — flatten pattern: `redundant-fragment`.
226
+ *
227
+ * Collapses a fragment that wraps exactly one child
228
+ *
229
+ * <><Child/></> → <Child/>
230
+ *
231
+ * A fragment renders no box of its own, so a fragment whose sole purpose is to wrap a single node
232
+ * is pure structural noise: splicing the child up into the fragment's slot is invisible in both
233
+ * the rendered DOM and the project's CSS cascade.
234
+ *
235
+ * Anchoring: the pass manager only visits ELEMENT nodes (see core's `elementIds`), never fragments,
236
+ * so this pattern is anchored on the fragment's sole *element* child and removes the PARENT fragment.
237
+ * Because the match is PARENT-anchored (and reads a fragment's `meta`, which the element-only
238
+ * combinator vocabulary cannot inspect), it uses the declarative API's two escape hatches: a raw
239
+ * `match` predicate and a raw `rewrite` op-draft factory.
240
+ */
241
+ /**
242
+ * Flatten a fragment that wraps exactly one child into that child.
243
+ *
244
+ * Safety level 1 (`safe`): a purely structural, style-free, selector-transparent cleanup.
245
+ */
246
+ declare const redundantFragment: AuthoredPattern<Captures>;
247
+
248
+ /**
249
+ * @domflax/patterns — compress pattern: `dedupe-classes`.
250
+ *
251
+ * Removes duplicate / fully-overridden class tokens that resolve to the same property where a
252
+ * LATER token wins, leaving the minimal set of tokens with an IDENTICAL computed style. The
253
+ * canonical case:
254
+ *
255
+ * <p class="text-sm text-lg">…</p> → <p class="text-lg">…</p>
256
+ *
257
+ * Both `text-sm` and `text-lg` set `font-size`; resolution already made `text-lg` win, so the
258
+ * computed `font-size` is `text-lg`'s value and `text-sm` contributes NOTHING to the final
259
+ * computed style. The earlier token is pure noise and can be dropped without changing a pixel.
260
+ *
261
+ * How redundancy is detected (purely from the already-resolved, normalized computed StyleMap):
262
+ * • every declaration carries provenance — `origin` (the winning token) and `shadowed`
263
+ * (the tokens it overrode);
264
+ * • a class token is FULLY OVERRIDDEN iff it appears in some declaration's `shadowed` list but
265
+ * is NOT the winning `origin` of any declaration across ANY style condition. Such a token can
266
+ * be deleted with zero effect on the computed style.
267
+ *
268
+ * Authored with the declarative {@link pattern} API: the `where` guards exclude opacity barriers,
269
+ * dynamic/opaque class lists, and combinator subjects; the `dropClasses` recipe returns the set of
270
+ * fully-overridden, resolver-droppable tokens to delete (their `shadowed` provenance is pruned
271
+ * automatically before the minimal class StyleMap is re-installed).
272
+ */
273
+ /**
274
+ * Collapse a class list to the minimal token set that yields an identical computed style, by
275
+ * dropping tokens whose declarations are fully overridden by later tokens.
276
+ */
277
+ declare const dedupeClasses: AuthoredPattern<Captures>;
278
+
279
+ /**
280
+ * @domflax/patterns — compress pattern: `inset-shorthand`.
281
+ *
282
+ * Recompacts the four physical inset longhands (`top`/`right`/`bottom`/`left`) on an element's
283
+ * computed style back into the tightest CSS shorthand the values allow:
284
+ *
285
+ * • all four equal → `inset: <v>`
286
+ * • top == bottom (a matching pair) → `inset-block: <v>` (Tailwind `inset-y-*`)
287
+ * • left == right (a matching pair) → `inset-inline: <v>` (Tailwind `inset-x-*`)
288
+ *
289
+ * The two axis collapses are independent: an element whose `top == bottom` but `left != right`
290
+ * collapses only the block axis and keeps the `left`/`right` longhands verbatim. When nothing
291
+ * collapses (all four distinct, or fewer than a full pair present) the pattern declines.
292
+ *
293
+ * Authored with the declarative {@link pattern} API: the `where` guards exclude opacity barriers,
294
+ * dynamic class lists, and combinator subjects; the `rewriteClasses` recipe rebuilds the class
295
+ * StyleMap, declining (`null`) unless at least one inset axis collapses.
296
+ */
297
+ /**
298
+ * Collapse equal/paired physical inset longhands into the `inset` / `inset-block` / `inset-inline`
299
+ * shorthands on an element's computed style.
300
+ */
301
+ declare const insetShorthand: AuthoredPattern<Captures>;
302
+
303
+ /**
304
+ * @domflax/patterns — compress pattern: `margin-shorthand`.
305
+ *
306
+ * Collapses the four explicit margin longhands
307
+ *
308
+ * margin-top / margin-right / margin-bottom / margin-left
309
+ *
310
+ * back into a single CSS `margin` shorthand declaration on the SAME element (the margin analogue of
311
+ * `padding-shorthand`, covering the `m` / `mx` / `my` collapse), choosing the shortest legal
312
+ * 1–4-value form:
313
+ *
314
+ * • all four equal → `margin: <v>` (the `m` case)
315
+ * • top==bottom and left==right → `margin: <y> <x>` (the `my`/`mx` case)
316
+ * • left==right (top!=bottom) → `margin: <t> <x> <b>`
317
+ * • otherwise → `margin: <t> <r> <b> <l>`
318
+ *
319
+ * It is a pure representation change: the resolved box model is identical, only the declaration
320
+ * count shrinks from four to one, which the backend can then re-emit as a single shorthand utility.
321
+ *
322
+ * Authored with the declarative {@link pattern} API: the `where` guards exclude opacity barriers,
323
+ * dynamic class lists, and combinator subjects; the `rewriteClasses` recipe rebuilds the class
324
+ * StyleMap, declining (`null`) unless all four margin longhands are present with a uniform
325
+ * (non-)`!important` flag.
326
+ */
327
+ /**
328
+ * Fold four margin longhands into one `margin` shorthand on the element's base style block.
329
+ */
330
+ declare const marginShorthand: AuthoredPattern<Captures>;
331
+
332
+ /**
333
+ * @domflax/patterns — compress pattern: `padding-shorthand`.
334
+ *
335
+ * Collapses an element whose four padding sides are expressed as separate longhand declarations
336
+ * back into the shortest equivalent shorthand:
337
+ *
338
+ * padding-top:16px; padding-right:16px; padding-bottom:16px; padding-left:16px
339
+ * ⇒ padding:16px (Tailwind `p-4`)
340
+ *
341
+ * padding-top:8px; padding-bottom:8px; padding-left:16px; padding-right:16px
342
+ * ⇒ padding:8px 16px (Tailwind `px-4 py-2`)
343
+ *
344
+ * The IR's computed StyleMap is canonically LONGHAND (the shared normalizer expands every box
345
+ * shorthand at parse time). This pass runs the expansion in reverse on the computed map ONLY when
346
+ * the four sides fold cleanly into a 1- or 2-value form — i.e. `top===bottom` AND `left===right`.
347
+ *
348
+ * Authored with the declarative {@link pattern} API: the `where` guards exclude opacity barriers,
349
+ * dynamic class lists, spread/component identity, and combinator subjects; the `rewriteClasses`
350
+ * recipe rebuilds the class StyleMap, declining (`null`) unless the four sides fold cleanly.
351
+ */
352
+ /**
353
+ * Compress an element's four equal/paired padding longhands into the shortest `padding` shorthand.
354
+ */
355
+ declare const paddingShorthand: AuthoredPattern<Captures>;
356
+
357
+ /**
358
+ * @domflax/patterns — compress pattern: `size-shorthand`.
359
+ *
360
+ * Collapses an element whose computed `width` and `height` are EQUAL into the single Tailwind
361
+ * `size-*` utility:
362
+ *
363
+ * <div style="width:1rem; height:1rem"/> → <div class="size-4"/>
364
+ *
365
+ * At the IR level we work over the normalized computed StyleMap (CSS longhands), so the pattern
366
+ * recognizes the `width === height` shape in the BASE condition and rebuilds the element's class
367
+ * StyleMap with a single `size` declaration (the resolver reverse-emits the concrete `size-*` token
368
+ * at codegen). Both longhands are removed and replaced by the merged `size` decl, so the rewrite is
369
+ * idempotent — once collapsed there is no `width`+`height` pair left to re-match.
370
+ *
371
+ * Authored with the declarative {@link pattern} API: the `where` guards exclude opacity barriers,
372
+ * dynamic class lists, and combinator subjects (compress patterns get NO auto-guards); the
373
+ * `rewriteClasses` recipe rebuilds the class StyleMap, returning `null` (decline) unless the BASE
374
+ * width/height are equal, concrete, and share an `!important` flag.
375
+ */
376
+ /** Fold equal `width`/`height` into the `size-*` utility. */
377
+ declare const sizeShorthand: AuthoredPattern<Captures>;
378
+
379
+ /**
380
+ * AUTO-GENERATED by `scripts/gen-registry.mjs` — DO NOT EDIT BY HAND.
381
+ *
382
+ * Regenerate with `npm run generate` (also runs automatically before build/typecheck/test).
383
+ * Patterns are discovered by the `*.pattern.ts` file convention under `src/flatten` and
384
+ * `src/compress`; the array below is sorted flatten-before-compress.
385
+ */
386
+
387
+ /** Every built-in pattern, in registration order (flatten patterns before compress). */
388
+ declare const builtinPatterns: readonly Pattern[];
389
+
390
+ /**
391
+ * domflax — public meta package.
392
+ *
393
+ * Re-exports the entire `@domflax/core` public API (types + reference runtime) and the built-in
394
+ * `@domflax/patterns` library, then layers thin, framework-agnostic build adapters on top
395
+ * (`vite()` / `webpack()`) plus a programmatic `createDomflax()` factory.
396
+ *
397
+ * Each adapter runs the SAME single-file engine as {@link createDomflax} (JSX/TSX frontend + lazy
398
+ * Tailwind/CSS resolver → core pass manager → reverse-emit → JSX backend). The adapters are
399
+ * structurally typed against their bundlers — they never hard-depend on `vite` or `webpack`.
400
+ *
401
+ * Future deps (intentionally NOT imported yet — they land in a later stage):
402
+ * - `@domflax/frontend-html` — HTML / Astro-static frontend feeding the pipeline.
403
+ * - `@domflax/backend-*` — additional surgical codegen backends.
404
+ */
405
+
406
+ /** How class names resolve to computed styles. */
407
+ type DomflaxProvider = 'auto' | 'tailwind' | 'custom';
408
+ /** Public adapter/factory options (mirrors the documented `domflax({...})` surface). */
409
+ interface DomflaxOptions {
410
+ /** Resolution strategy. Defaults to `'auto'`. */
411
+ readonly provider?: DomflaxProvider;
412
+ /** Stylesheets to parse when `provider` is `'custom'`. */
413
+ readonly cssFiles?: readonly string[];
414
+ /** Preview changes without rewriting source. */
415
+ readonly dryRun?: boolean;
416
+ /** Optimization aggressiveness handed to the pass manager (0 lint … 3 aggressive). */
417
+ readonly safety?: SafetyLevel;
418
+ /** File globs/extensions the adapters should consider. Defaults to jsx/tsx/html. */
419
+ readonly include?: readonly string[];
420
+ }
421
+ /** Fully-resolved options with defaults applied. */
422
+ interface ResolvedDomflaxOptions {
423
+ readonly provider: DomflaxProvider;
424
+ readonly cssFiles: readonly string[];
425
+ readonly dryRun: boolean;
426
+ readonly safety: SafetyLevel;
427
+ readonly include: readonly string[];
428
+ }
429
+ /** Result of a single-file transform. `map` is null until codegen lands. */
430
+ interface DomflaxTransformResult {
431
+ readonly code: string;
432
+ readonly map: EncodedSourceMap | null;
433
+ }
434
+ /**
435
+ * A configured domflax engine. Holds the wired core {@link Pipeline}, the passthrough
436
+ * {@link StyleResolver}, and the built-in {@link Pattern} set, and exposes a single-file
437
+ * `transform`.
438
+ */
439
+ interface Domflax {
440
+ readonly options: ResolvedDomflaxOptions;
441
+ readonly pipeline: Pipeline;
442
+ readonly resolver: StyleResolver;
443
+ readonly patterns: readonly Pattern[];
444
+ /**
445
+ * Transform one file. For `.jsx`/`.tsx` this runs the full pipeline (parse → resolve → flatten →
446
+ * reverse-emit → print); every other (or unsupported) file is returned unchanged.
447
+ */
448
+ transform(code: string, id: string): DomflaxTransformResult;
449
+ }
450
+ declare function createDomflax(options?: DomflaxOptions): Domflax;
451
+ /**
452
+ * Minimal Vite-plugin shape. Declared locally so this adapter does NOT depend on `vite`'s types
453
+ * (an optional, type-only peer). Structurally compatible with Vite's `Plugin` for the hooks domflax
454
+ * uses: `enforce: 'pre'` runs domflax before Vite's JSX→`createElement` transform, and `transform`
455
+ * is Vite's per-file source hook. Returning `null` is Vite's "no change" signal.
456
+ */
457
+ interface DomflaxVitePlugin {
458
+ readonly name: string;
459
+ readonly enforce: 'pre';
460
+ transform(code: string, id: string): DomflaxTransformResult | null;
461
+ }
462
+ /**
463
+ * Vite adapter. Returns a real Vite `Plugin` (`enforce: 'pre'`) whose `transform` runs the domflax
464
+ * engine on `.jsx`/`.tsx` modules — strips any bundler query suffix (e.g. `App.tsx?used`) before
465
+ * matching, returns `{ code, map }` when the source changed, and `null` (Vite's unchanged signal)
466
+ * for unchanged sources and for any non-jsx/tsx module.
467
+ *
468
+ * @example
469
+ * ```js
470
+ * // vite.config.js
471
+ * import domflax from 'domflax';
472
+ * export default { plugins: [domflax.vite({ provider: 'tailwind' })] };
473
+ * ```
474
+ */
475
+ declare function vite(options?: DomflaxOptions): DomflaxVitePlugin;
476
+ /** Anything carrying a `module.rules` array — both a webpack `Compiler.options` and Next's bare config. */
477
+ interface DomflaxWebpackModuleHost {
478
+ module?: {
479
+ rules?: unknown[];
480
+ };
481
+ }
482
+ /**
483
+ * Minimal webpack-compiler shape. Declared locally so this adapter does NOT depend on `webpack`'s
484
+ * types. domflax only needs to push a rule onto the host's `module.rules`.
485
+ *
486
+ * `apply` accepts BOTH shapes: a real webpack `Compiler` (rules live under `compiler.options.module`)
487
+ * AND the bare `config` object Next.js hands you from `webpack(config)` (rules live directly under
488
+ * `config.module`). It duck-types `compiler.options ?? compiler` to find the right host.
489
+ */
490
+ interface DomflaxWebpackCompiler extends DomflaxWebpackModuleHost {
491
+ options?: DomflaxWebpackModuleHost;
492
+ }
493
+ /**
494
+ * Minimal webpack-plugin shape. `apply(compiler)` is the webpack plugin entry point.
495
+ */
496
+ interface DomflaxWebpackPlugin {
497
+ readonly name: string;
498
+ apply(compiler: DomflaxWebpackCompiler): void;
499
+ }
500
+ /**
501
+ * webpack adapter (also the Next.js path). Returns a plugin whose `apply(compiler)` injects a
502
+ * pre-enforced `module.rule` that invokes the domflax {@link ./webpack-loader loader} on every
503
+ * `.jsx`/`.tsx` module. The loader runs the SAME lazy engine as {@link createDomflax} (no eager
504
+ * Tailwind/postcss load).
505
+ *
506
+ * Next.js wiring (`next.config.js`) — Next exposes the underlying webpack config via `webpack(config)`:
507
+ * ```js
508
+ * // next.config.js
509
+ * const domflax = require('domflax');
510
+ * module.exports = {
511
+ * webpack(config) {
512
+ * domflax.webpack({ provider: 'tailwind' }).apply(config);
513
+ * return config;
514
+ * },
515
+ * };
516
+ * ```
517
+ * `apply(compiler)` is intentionally duck-typed on `compiler.options.module.rules`, so it accepts
518
+ * both a real webpack `Compiler` and the bare `config` object Next.js hands you.
519
+ *
520
+ * Caveat: this targets the webpack builder only. **Turbopack is not yet supported** — it does not
521
+ * accept arbitrary webpack loaders, so the `next.config.js` wiring above is a no-op under
522
+ * `next dev --turbopack`. Run domflax through the webpack builder until Turbopack exposes a loader API.
523
+ */
524
+ declare function webpack(options?: DomflaxOptions): DomflaxWebpackPlugin;
525
+ /**
526
+ * The default-export namespace. Exposes the build adapters and the programmatic factory as an OBJECT
527
+ * so the documented `import domflax from 'domflax'; domflax.vite()` / `domflax.webpack()` works (and a
528
+ * CommonJS `const domflax = require('domflax'); domflax.vite()` too). The named exports
529
+ * (`createDomflax`, `vite`, `webpack`, …) remain available for direct import.
530
+ */
531
+ interface DomflaxDefault {
532
+ createDomflax(options?: DomflaxOptions): Domflax;
533
+ vite(options?: DomflaxOptions): DomflaxVitePlugin;
534
+ webpack(options?: DomflaxOptions): DomflaxWebpackPlugin;
535
+ }
536
+ /** Default export: an object exposing `vite`, `webpack`, and the programmatic `createDomflax`. */
537
+ declare const domflax: DomflaxDefault;
538
+
539
+ export { ApplyContext, type ApplyOutcome, ApplyResult, Captures, DEFAULT_FIXPOINT, type Domflax, type DomflaxDefault, type DomflaxOptions, type DomflaxProvider, type DomflaxTransformResult, type DomflaxVitePlugin, type DomflaxWebpackCompiler, type DomflaxWebpackPlugin, EncodedSourceMap, FixpointConfig, IRDocument, Pass, PassManager, Pattern, PhaseRunResult, Pipeline, type ResolvedDomflaxOptions, RewriteFactory, RewriteGroup, RewriteOp, SafetyLevel, SelectorIndex, StyleNormalizer, StyleResolver, SyntheticSink, applyGroups, applyOps, buildSelectorIndex, builtinPatterns, cloneDocument, createDomflax, createNullResolver, createNullSelectorIndex, createPassManager, createPipeline, createRewriteFactory, createSyntheticSink, dedupeClasses, domflax as default, emptyStyleDiv, flexCenterWrapper, insetShorthand, marginShorthand, nestedFlexMerge, paddingShorthand, passthroughWrapper, redundantFragment, runPasses, sizeShorthand, syncClassesFromComputed, vite, webpack };