@barefootjs/jsx 0.5.2 → 0.5.3

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 (37) hide show
  1. package/dist/combine-client-js.d.ts.map +1 -1
  2. package/dist/index.js +176 -51
  3. package/dist/ir-to-client-js/collect-elements.d.ts +26 -14
  4. package/dist/ir-to-client-js/collect-elements.d.ts.map +1 -1
  5. package/dist/ir-to-client-js/control-flow/plan/build-loop.d.ts.map +1 -1
  6. package/dist/ir-to-client-js/control-flow/plan/event-delegation.d.ts +8 -3
  7. package/dist/ir-to-client-js/control-flow/plan/event-delegation.d.ts.map +1 -1
  8. package/dist/ir-to-client-js/emit-reactive.d.ts.map +1 -1
  9. package/dist/ir-to-client-js/html-template.d.ts.map +1 -1
  10. package/dist/ir-to-client-js/imports.d.ts +2 -2
  11. package/dist/ir-to-client-js/imports.d.ts.map +1 -1
  12. package/dist/ir-to-client-js/plan/static-array-child-init.d.ts +3 -3
  13. package/dist/ir-to-client-js/plan/static-array-child-init.d.ts.map +1 -1
  14. package/dist/ir-to-client-js/types.d.ts +26 -4
  15. package/dist/ir-to-client-js/types.d.ts.map +1 -1
  16. package/dist/ir-to-client-js/utils.d.ts +19 -1
  17. package/dist/ir-to-client-js/utils.d.ts.map +1 -1
  18. package/package.json +2 -2
  19. package/src/__tests__/__snapshots__/doc-examples.test.ts.snap +203 -203
  20. package/src/__tests__/child-components-in-map.test.ts +333 -0
  21. package/src/__tests__/combine-client-js.test.ts +47 -0
  22. package/src/__tests__/dangerously-set-inner-html.test.ts +82 -0
  23. package/src/__tests__/static-loop-csr-materialize.test.ts +6 -4
  24. package/src/__tests__/text-slot-escaping.test.ts +56 -0
  25. package/src/combine-client-js.ts +66 -22
  26. package/src/ir-to-client-js/collect-elements.ts +170 -32
  27. package/src/ir-to-client-js/control-flow/plan/build-event-delegation.ts +1 -1
  28. package/src/ir-to-client-js/control-flow/plan/build-loop.ts +2 -1
  29. package/src/ir-to-client-js/control-flow/plan/event-delegation.ts +8 -3
  30. package/src/ir-to-client-js/control-flow/stringify/event-delegation.ts +3 -3
  31. package/src/ir-to-client-js/emit-reactive.ts +9 -0
  32. package/src/ir-to-client-js/html-template.ts +82 -10
  33. package/src/ir-to-client-js/imports.ts +1 -1
  34. package/src/ir-to-client-js/plan/build-static-array-child-init.ts +4 -8
  35. package/src/ir-to-client-js/plan/static-array-child-init.ts +3 -3
  36. package/src/ir-to-client-js/types.ts +27 -4
  37. package/src/ir-to-client-js/utils.ts +41 -1
@@ -75,7 +75,7 @@ export interface OuterNestedInitPlan {
75
75
  arrayExpr: string
76
76
  param: string
77
77
  indexParam: string
78
- /** `indexParam` or `${indexParam} + ${siblingOffset}` — already substituted. */
78
+ /** `indexParam` plus any sibling-offset terms (`+ 1 + (arr).length`) — already substituted. */
79
79
  offsetExpr: string
80
80
  /**
81
81
  * Outer `.map()` callback preamble locals (#1064), emitted inside the
@@ -99,7 +99,7 @@ export interface InnerLoopNestedInitPlan {
99
99
  outerArrayExpr: string
100
100
  outerParam: string
101
101
  outerIndexParam: string
102
- /** Outer offset — `outerIndexParam` or `${outerIndexParam} + ${siblingOffset}`. */
102
+ /** Outer offset — `outerIndexParam` plus any sibling-offset terms. */
103
103
  outerOffsetExpr: string
104
104
  /**
105
105
  * Outer `.map()` callback preamble locals, emitted after the
@@ -115,7 +115,7 @@ export interface InnerLoopNestedInitPlan {
115
115
  innerContainerSlotId: string | null
116
116
  innerArrayExpr: string
117
117
  innerParam: string
118
- /** Inner offset — `__innerIdx` or `__innerIdx + ${siblingOffset}`. */
118
+ /** Inner offset — `__innerIdx` plus any sibling-offset terms. */
119
119
  innerOffsetExpr: string
120
120
  /**
121
121
  * Inner `.map()` callback preamble locals, emitted after the
@@ -166,6 +166,29 @@ export interface ConditionalBranchReactiveAttr extends AttrMeta {
166
166
  expression: string
167
167
  }
168
168
 
169
+ /**
170
+ * How many element children precede a loop's items in its container — the
171
+ * offset applied to `container.children[idx]` so each item resolves to the
172
+ * right element during hydration.
173
+ *
174
+ * Two contributions, kept distinct because they codegen differently:
175
+ * - `staticCount`: siblings of statically-known element count, folded to a
176
+ * compile-time integer (`+ 1`).
177
+ * - `dynamicTerms`: one JS expression per sibling whose element count is
178
+ * only known at runtime — a preceding `.map()` (`(arr).length`) or a
179
+ * preceding conditional (`(cond ? 1 : 0)`) — each added as `+ <term>`.
180
+ *
181
+ * Carried as one value object end-to-end (collect → IR loop → plan → codegen)
182
+ * so a future offset contributor is added in one place, not threaded as a new
183
+ * field through every layer (#1693).
184
+ */
185
+ export interface LoopOffset {
186
+ /** Folded element count of statically-sized preceding siblings. `0` = none. */
187
+ staticCount: number
188
+ /** Runtime element-count expressions of dynamic preceding siblings; `[]` = none. */
189
+ dynamicTerms: readonly string[]
190
+ }
191
+
169
192
  /**
170
193
  * Fields shared by every flavour of collected loop (top-level, branch-scoped, nested).
171
194
  * The three loop-info variants (`TopLevelLoop`, `BranchLoop`, `NestedLoop`) each extend
@@ -363,8 +386,8 @@ export interface NestedLoop extends LoopCore {
363
386
  childComponents?: import('../types').IRLoopChildComponent[]
364
387
  /** True when this loop is inside a conditional branch (handled by insert() bindEvents instead) */
365
388
  insideConditional?: boolean
366
- /** Number of non-loop DOM siblings before this loop in its container element */
367
- siblingOffset?: number
389
+ /** Offset of this loop's items past its preceding container siblings (#1693). */
390
+ offset?: LoopOffset
368
391
  // Per-item bindings (events / reactiveAttrs / reactiveTexts / refs / conditionals)
369
392
  // now live on `LoopCore.bindings` — see issue #1244 §B.
370
393
  }
@@ -468,8 +491,8 @@ export interface TopLevelLoop extends LoopCore {
468
491
  useElementReconciliation?: boolean // True: reconcileElements + composite rendering (native root with child components)
469
492
  /** Inner loop metadata for composite element reconciliation (array, param, key, container) */
470
493
  innerLoops?: NestedLoop[]
471
- /** Number of non-loop DOM siblings before this loop in its parent element. Used to offset children[idx] access. */
472
- siblingOffset?: number
494
+ /** Offset of this loop's items past its preceding container siblings (#1693). */
495
+ offset?: LoopOffset
473
496
  filterPredicate?: {
474
497
  param: string
475
498
  raw: string // Original filter predicate expression or block body
@@ -5,7 +5,7 @@
5
5
 
6
6
  import ts from 'typescript'
7
7
  import type { AttrValue, IRTemplatePart, LoopParamBinding, FreeReference, IRNode } from '../types'
8
- import type { TopLevelLoop, BranchLoop } from './types'
8
+ import type { TopLevelLoop, BranchLoop, LoopOffset } from './types'
9
9
  import { buildLoopChainExpr } from '../loop-chain'
10
10
  import {
11
11
  iterateJsTokens,
@@ -145,6 +145,46 @@ export function buildChainedArrayExpr(elem: TopLevelLoop | BranchLoop): string {
145
145
  })
146
146
  }
147
147
 
148
+ /**
149
+ * The single source of truth for what contributes to a loop's child-index
150
+ * offset: the static sibling count (a folded integer) followed by one
151
+ * `(arr).length` term per preceding sibling loop. The additive and
152
+ * subtractive forms below are thin projections over this list, so they can
153
+ * never drift in which terms they include, and a new offset contributor is
154
+ * added here once rather than in every consumer (#1693).
155
+ */
156
+ function loopOffsetTerms(offset: LoopOffset | undefined): string[] {
157
+ if (!offset) return []
158
+ const terms: string[] = []
159
+ if (offset.staticCount) terms.push(String(offset.staticCount))
160
+ terms.push(...offset.dynamicTerms)
161
+ return terms
162
+ }
163
+
164
+ /**
165
+ * Build the additive `children[idx]` access expression for a loop's items —
166
+ * `indexParam` plus every offset term.
167
+ *
168
+ * Examples:
169
+ * - no offset → `__idx`
170
+ * - one static sibling → `__idx + 1`
171
+ * - one preceding `.map()` → `__idx + (arr).length`
172
+ * - static sibling + 2 `.map()`→ `__idx + 1 + (a).length + (b).length`
173
+ */
174
+ export function buildLoopChildIndexExpr(indexParam: string, offset: LoopOffset | undefined): string {
175
+ return [indexParam, ...loopOffsetTerms(offset)].join(' + ')
176
+ }
177
+
178
+ /**
179
+ * Build the subtractive counterpart of `buildLoopChildIndexExpr` — used by
180
+ * event delegation to recover a loop item's array index from its DOM child
181
+ * index. Returns the trailing `` - <static> - (arr).length …`` suffix (empty
182
+ * when there is no offset) appended after `…indexOf(__el)`.
183
+ */
184
+ export function buildLoopChildIndexSubtraction(offset: LoopOffset | undefined): string {
185
+ return loopOffsetTerms(offset).map(term => ` - ${term}`).join('')
186
+ }
187
+
148
188
  /**
149
189
  * Map of JSX event names to DOM event property names.
150
190
  * JSX uses React-style naming (e.g., onDoubleClick) which gets converted to