@barefootjs/jsx 0.33.2 → 0.33.4

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 (61) hide show
  1. package/dist/analyzer.d.ts +17 -0
  2. package/dist/analyzer.d.ts.map +1 -1
  3. package/dist/compiler.d.ts +21 -5
  4. package/dist/compiler.d.ts.map +1 -1
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +804 -445
  8. package/dist/ir-to-client-js/build-references.d.ts.map +1 -1
  9. package/dist/ir-to-client-js/collect-elements.d.ts.map +1 -1
  10. package/dist/ir-to-client-js/control-flow/plan/build-component-loop.d.ts.map +1 -1
  11. package/dist/ir-to-client-js/control-flow/plan/loop.d.ts +2 -4
  12. package/dist/ir-to-client-js/control-flow/plan/loop.d.ts.map +1 -1
  13. package/dist/ir-to-client-js/control-flow/stringify/component-loop.d.ts.map +1 -1
  14. package/dist/ir-to-client-js/control-flow/stringify/loop-child-arm.d.ts.map +1 -1
  15. package/dist/ir-to-client-js/control-flow.d.ts.map +1 -1
  16. package/dist/ir-to-client-js/html-template.d.ts.map +1 -1
  17. package/dist/ir-to-client-js/imports.d.ts +60 -2
  18. package/dist/ir-to-client-js/imports.d.ts.map +1 -1
  19. package/dist/ir-to-client-js/prop-handling.d.ts +4 -7
  20. package/dist/ir-to-client-js/prop-handling.d.ts.map +1 -1
  21. package/dist/ir-to-client-js/utils.d.ts +26 -2
  22. package/dist/ir-to-client-js/utils.d.ts.map +1 -1
  23. package/dist/jsx-to-ir.d.ts.map +1 -1
  24. package/dist/props-binding.d.ts +35 -0
  25. package/dist/props-binding.d.ts.map +1 -1
  26. package/dist/types.d.ts +63 -13
  27. package/dist/types.d.ts.map +1 -1
  28. package/package.json +2 -2
  29. package/src/__tests__/__snapshots__/doc-examples.test.ts.snap +145 -97
  30. package/src/__tests__/child-component-ref-not-mirrored.test.ts +90 -0
  31. package/src/__tests__/fragment-body-loop-key.test.ts +95 -0
  32. package/src/__tests__/ir-to-client-js/imports.test.ts +107 -0
  33. package/src/__tests__/ir-to-client-js/merge-compiled-client-js-imports.test.ts +138 -0
  34. package/src/__tests__/issue-2754-rest-spread-needs-slot.test.ts +85 -0
  35. package/src/__tests__/issue-2756-loop-row-honors-client-only.test.ts +173 -0
  36. package/src/__tests__/merge-template-imports.test.ts +41 -1
  37. package/src/__tests__/multi-component-shared-default-import.test.ts +55 -0
  38. package/src/__tests__/multi-root-loop-body.test.ts +7 -3
  39. package/src/__tests__/preamble-declarations.test.ts +42 -0
  40. package/src/__tests__/root-key-relay.test.ts +170 -0
  41. package/src/__tests__/signal-getter-not-called.test.ts +149 -0
  42. package/src/__tests__/state-only-file-default-import.test.ts +47 -0
  43. package/src/analyzer.ts +36 -0
  44. package/src/compiler.ts +94 -104
  45. package/src/index.ts +1 -1
  46. package/src/ir-to-client-js/build-references.ts +7 -0
  47. package/src/ir-to-client-js/collect-elements.ts +27 -5
  48. package/src/ir-to-client-js/control-flow/plan/build-component-loop.ts +19 -1
  49. package/src/ir-to-client-js/control-flow/plan/loop.ts +2 -4
  50. package/src/ir-to-client-js/control-flow/stringify/component-loop.ts +7 -0
  51. package/src/ir-to-client-js/control-flow/stringify/inner-loop.ts +6 -2
  52. package/src/ir-to-client-js/control-flow/stringify/loop-child-arm.ts +5 -2
  53. package/src/ir-to-client-js/control-flow.ts +12 -0
  54. package/src/ir-to-client-js/html-template.ts +174 -23
  55. package/src/ir-to-client-js/imports.ts +178 -5
  56. package/src/ir-to-client-js/index.ts +5 -0
  57. package/src/ir-to-client-js/prop-handling.ts +6 -17
  58. package/src/ir-to-client-js/utils.ts +30 -2
  59. package/src/jsx-to-ir.ts +592 -58
  60. package/src/props-binding.ts +51 -0
  61. package/src/types.ts +60 -13
@@ -5,6 +5,7 @@
5
5
  import type { ParamInfo, SignalInfo } from '../types.ts'
6
6
  import type { ClientJsContext } from './types.ts'
7
7
  import type { BindingScope } from '../scope/binding-scope.ts'
8
+ import { resolveRestSpreadOriginCore } from '../props-binding.ts'
8
9
 
9
10
  /**
10
11
  * Which of the component's two "forwards the caller's leftover props"
@@ -29,25 +30,13 @@ import type { BindingScope } from '../scope/binding-scope.ts'
29
30
  * `spreadAttrs({...})` call keyed by the alias name instead of the
30
31
  * runtime-visible one.
31
32
  *
32
- * Walks the chain hop by hop (not a precomputed set) so a multi-hop alias
33
- * (`const p2 = props; const p3 = p2`) resolves through every link; `visited`
34
- * guards a constant cycle (`const a = b; const b = a`) the same way
35
- * `free-refs.ts`'s `resolveConstantInitializerRefs` does. A constant whose
36
- * value isn't a bare identifier already on the chain (e.g. a real computed
37
- * object) stops the walk, so a genuinely different spread expression is
38
- * never mistaken for the rest object.
33
+ * The walk itself lives in `props-binding.ts`'s `resolveRestSpreadOriginCore`,
34
+ * shared with Phase 1's slot-id decision so both phases agree on which
35
+ * spreads forward the caller's leftover props (#2754). This wrapper only
36
+ * supplies the `ClientJsContext`-shaped inputs.
39
37
  */
40
38
  export function resolveRestSpreadOrigin(ctx: ClientJsContext, name: string): 'rest' | 'props' | null {
41
- const byName = localConstantValues(ctx)
42
- const visited = new Set<string>()
43
- let current: string | undefined = name.trim()
44
- while (current !== undefined && !visited.has(current)) {
45
- if (ctx.restPropsName && current === ctx.restPropsName) return 'rest'
46
- if (ctx.propsObjectName && current === ctx.propsObjectName) return 'props'
47
- visited.add(current)
48
- current = byName.get(current)?.trim()
49
- }
50
- return null
39
+ return resolveRestSpreadOriginCore(ctx, localConstantValues(ctx), name)
51
40
  }
52
41
 
53
42
  /**
@@ -25,6 +25,7 @@ import {
25
25
  loopEndMarker,
26
26
  loopItemMarker,
27
27
  toHTMLAttrName as toHtmlAttrName,
28
+ keyAttrName as sharedKeyAttrName,
28
29
  } from '@barefootjs/shared'
29
30
 
30
31
  export { DATA_KEY, DATA_KEY_PREFIX, DATA_BF_PH, BF_LOOP_START, BF_LOOP_END, loopStartMarker, loopEndMarker, loopItemMarker, toHtmlAttrName }
@@ -39,9 +40,36 @@ export const PROPS_PARAM = '_p'
39
40
  * Get the data-key attribute name for a given loop depth.
40
41
  * Outer loop (depth 0): 'data-key'
41
42
  * Nested loops (depth N): 'data-key-N'
43
+ *
44
+ * Re-exported from `@barefootjs/shared` (the single source of truth also
45
+ * used by `jsx-to-ir.ts`'s `IRElement.keyAttr` resolution) so existing
46
+ * imports of this module keep working.
42
47
  */
43
- export function keyAttrName(loopDepth: number): string {
44
- return loopDepth > 0 ? `${DATA_KEY_PREFIX}${loopDepth}` : DATA_KEY
48
+ export const keyAttrName = sharedKeyAttrName
49
+
50
+ /**
51
+ * Build the trailing `, <bfId>, <keyAttrName>` arguments for a NESTED
52
+ * (`loopDepth > 0`) `mapArray(...)` call — `inner-loop.ts` / `loop-child-arm.ts`,
53
+ * the only two stringify sites whose loop can be nested (#2753 Shape B: the
54
+ * runtime otherwise has no way to know it isn't the outermost loop, and
55
+ * always stamped the plain `data-key` name).
56
+ *
57
+ * A depth-0 (or unkeyed) loop needs no change at all: `mapArray`'s own
58
+ * default (`BF_KEY`, `'data-key'`) is already correct there, and an unkeyed
59
+ * loop's runtime never stamps a key attribute regardless of the name — so
60
+ * this returns `bfIdArg` UNCHANGED, keeping every other call site (and every
61
+ * existing depth-0 call here) byte-identical.
62
+ *
63
+ * `bfIdArg` is the existing profiling-id suffix (e.g. `profileBindingId(...)`,
64
+ * either `''` or `, "<id>"`) already threaded through these two call sites —
65
+ * an empty one is widened to an explicit `, undefined` placeholder so the
66
+ * name lands in the right positional slot (`mapArray`'s 6th parameter is
67
+ * `bfId`, not `keyAttrName`).
68
+ */
69
+ export function mapArrayKeyArgs(bfIdArg: string, keyed: boolean, loopDepth: number): string {
70
+ if (!keyed || loopDepth <= 0) return bfIdArg
71
+ const bfIdSlot = bfIdArg || ', undefined'
72
+ return `${bfIdSlot}, ${JSON.stringify(keyAttrName(loopDepth))}`
45
73
  }
46
74
 
47
75
  /**