jsx_rosetta 0.4.0 → 0.5.1

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.
@@ -33,12 +33,19 @@ module JsxRosetta
33
33
  # inline arrows / const-bound arrows used in onX={...}.
34
34
  # When non-empty, backends should emit a sibling
35
35
  # Stimulus controller file alongside the .rb/.erb pair.
36
- # react_hooks : [ReactHookCall] — calls to React hooks (useState,
37
- # useEffect, useRef, useContext, useMemo, useCallback,
38
- # useReducer, useImperativeHandle, useLayoutEffect).
39
- # Surfaced as a distinct TODO block so the human
40
- # reviewer knows to translate behavior to Stimulus
41
- # and state to server-side rendering.
36
+ # react_hooks : [ReactHookCall] — every recognized hook invocation
37
+ # in the component body, regardless of library.
38
+ # Includes React's built-in hooks (useState, useEffect,
39
+ # useRef, useContext, useMemo, useCallback, useReducer,
40
+ # useImperativeHandle, useLayoutEffect), Apollo hooks
41
+ # (useQuery, useMutation, useLazyQuery, useSubscription,
42
+ # useApolloClient), and Next.js navigation hooks
43
+ # (useRouter, usePathname, useSearchParams, useParams,
44
+ # useSelectedLayoutSegment(s)). Each call carries a
45
+ # `library` tag so backends can group them and emit a
46
+ # library-specific TODO pointing at the right Rails
47
+ # analog (Stimulus/server-render for React; controller
48
+ # fetch for Apollo; request.path/params for Next.js).
42
49
  # module_bindings : [LocalBinding] — top-level `const`/`let` declarations
43
50
  # outside the component function that aren't themselves
44
51
  # components. Captured so backends can either translate
@@ -47,10 +54,24 @@ module JsxRosetta
47
54
  # Without this capture, references to module-level
48
55
  # constants from inside the JSX silently drop and
49
56
  # produce unbacked snake_case references at render time.
57
+ # render_methods : [RenderMethod] — local arrow bindings that return JSX
58
+ # and are invoked from the JSX body (`const renderHeader
59
+ # = () => <div/>; ... {renderHeader()}`). Backends emit
60
+ # each as a private method on the generated class and
61
+ # reference it from a LocalRenderCall at the use site.
62
+ # mode : Symbol — `:view` for a normal Phlex/ViewComponent component
63
+ # whose body is rendered as JSX (the default); `:data_factory`
64
+ # for column-descriptor / option-list modules whose top-level
65
+ # export is a function returning an array of object literals.
66
+ # When `:data_factory`, the backend emits a snake_case method
67
+ # that returns the translated data, instead of `view_template`.
68
+ # JSX inside object properties still extracts to private
69
+ # methods on the class via the IR::Lambda path.
50
70
  Component = Data.define(:name, :props, :body, :rest_prop_name,
51
71
  :local_bindings, :local_binding_names,
52
72
  :module_bindings,
53
- :stimulus_methods, :react_hooks) do
73
+ :stimulus_methods, :react_hooks,
74
+ :render_methods, :mode) do
54
75
  include Node
55
76
  end
56
77
 
@@ -64,22 +85,37 @@ module JsxRosetta
64
85
  include Node
65
86
  end
66
87
 
67
- # A React hook invocation detected in the component body (`useState`,
68
- # `useEffect`, …). Surfaced separately from local_bindings so backends
69
- # can emit a more specific TODO that points at the Stimulus / Hotwire
70
- # / server-render alternative, instead of a generic "translate this JS".
88
+ # A hook invocation detected in the component body. Covers React's
89
+ # built-in hooks plus framework hooks we recognize (Apollo's `useQuery`/
90
+ # `useMutation`/etc., Next.js's `useRouter`/`usePathname`/etc.).
91
+ # Surfaced separately from local_bindings so backends can emit a more
92
+ # specific TODO pointing at the Rails equivalent for each library,
93
+ # instead of a generic "translate this JS".
71
94
  #
72
- # hook : String — hook function name (`"useState"`, `"useEffect"`, …)
73
- # source : String — verbatim JS of the entire statement.
74
- ReactHookCall = Data.define(:hook, :source) do
95
+ # hook : String — hook function name (`"useState"`, `"useQuery"`, …)
96
+ # source : String — verbatim JS of the entire statement.
97
+ # library : Symbol — `:react`, `:apollo`, or `:next_js`. Backends
98
+ # group hooks by library and emit one TODO block per group,
99
+ # since each library maps to a different Rails analog.
100
+ # operation : String | nil — for Apollo hooks called with a bare-Identifier
101
+ # first argument (`useQuery(GET_USERS_QUERY, …)`), the
102
+ # captured operation name. nil when the first argument is
103
+ # not a simple Identifier, or when the hook isn't Apollo.
104
+ # Backends echo it in the TODO so the reviewer can match
105
+ # the operation back to its GraphQL document and to the
106
+ # Rails controller / model fetch it should become.
107
+ ReactHookCall = Data.define(:hook, :source, :library, :operation) do
75
108
  include Node
76
109
  end
77
110
 
78
111
  # A component prop, possibly with a default value.
79
112
  #
80
- # name : String
81
- # default : Interpolation | nil
82
- Prop = Data.define(:name, :default) do
113
+ # name : String — the prop name on the parent (e.g. "data-testid").
114
+ # default : Interpolation | nil
115
+ # alias_name : String | nil — the local binding name inside the body when
116
+ # the destructure renames it (`"data-testid": dataTestId`).
117
+ # Use sites of the alias resolve to the prop's ivar.
118
+ Prop = Data.define(:name, :default, :alias_name) do
83
119
  include Node
84
120
  end
85
121
 
@@ -343,5 +379,30 @@ module JsxRosetta
343
379
  RenderProp = Data.define(:params, :body) do
344
380
  include Node
345
381
  end
382
+
383
+ # A locally-declared JSX-returning arrow that's invoked inside the
384
+ # render body: `const renderHeader = (count) => <h1>{count}</h1>;
385
+ # ... {renderHeader(headerCount)}`. Backends emit one private method
386
+ # per RenderMethod on the generated class and reference it via a
387
+ # LocalRenderCall at each use site.
388
+ #
389
+ # name : String — snake_case method name on the class.
390
+ # params : [String] — arrow param names (camelCase preserved; backends
391
+ # snake_case to form Ruby parameter names).
392
+ # body : Node — the lowered IR node produced by the arrow's body.
393
+ RenderMethod = Data.define(:name, :params, :body) do
394
+ include Node
395
+ end
396
+
397
+ # A call to a locally-declared JSX-returning arrow at its use site.
398
+ # Pairs with a sibling RenderMethod on Component#render_methods.
399
+ #
400
+ # method_name : String — snake_case method name (matches RenderMethod#name).
401
+ # args : [Interpolation] — argument expressions captured verbatim
402
+ # (each Interpolation's expression is translated by the
403
+ # backend's ExpressionTranslator at emission time).
404
+ LocalRenderCall = Data.define(:method_name, :args) do
405
+ include Node
406
+ end
346
407
  end
347
408
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JsxRosetta
4
- VERSION = "0.4.0"
4
+ VERSION = "0.5.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsx_rosetta
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean McCleary
@@ -28,6 +28,7 @@ files:
28
28
  - LICENSE.txt
29
29
  - PLAN.md
30
30
  - README.md
31
+ - ROADMAP.md
31
32
  - Rakefile
32
33
  - exe/jsx_rosetta
33
34
  - lib/jsx_rosetta.rb