jac-client 0.2.10__py3-none-any.whl → 0.2.12__py3-none-any.whl

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 (85) hide show
  1. jac_client/examples/all-in-one/button.jac +4 -3
  2. jac_client/examples/all-in-one/components/CategoryFilter.jac +36 -24
  3. jac_client/examples/all-in-one/components/Header.jac +12 -8
  4. jac_client/examples/all-in-one/components/ProfitOverview.jac +49 -35
  5. jac_client/examples/all-in-one/components/Summary.jac +59 -36
  6. jac_client/examples/all-in-one/components/TransactionForm.jac +142 -112
  7. jac_client/examples/all-in-one/components/TransactionItem.jac +37 -30
  8. jac_client/examples/all-in-one/components/TransactionList.jac +33 -26
  9. jac_client/examples/all-in-one/components/button.jac +4 -3
  10. jac_client/examples/all-in-one/components/navigation.jac +111 -117
  11. jac_client/examples/all-in-one/constants/categories.jac +23 -24
  12. jac_client/examples/all-in-one/constants/clients.jac +7 -8
  13. jac_client/examples/all-in-one/context/BudgetContext.jac +9 -6
  14. jac_client/examples/all-in-one/hooks/useBudget.jac +18 -12
  15. jac_client/examples/all-in-one/hooks/useLocalStorage.jac +14 -13
  16. jac_client/examples/all-in-one/main.jac +340 -371
  17. jac_client/examples/all-in-one/pages/BudgetPlanner.jac +19 -12
  18. jac_client/examples/all-in-one/pages/FeaturesTest.jac +31 -15
  19. jac_client/examples/all-in-one/pages/LandingPage.jac +113 -90
  20. jac_client/examples/all-in-one/pages/budget_planner_ui.cl.jac +34 -39
  21. jac_client/examples/all-in-one/pages/features_test_ui.cl.jac +464 -352
  22. jac_client/examples/all-in-one/pages/loginPage.jac +114 -119
  23. jac_client/examples/all-in-one/pages/nestedDemo.jac +43 -50
  24. jac_client/examples/all-in-one/pages/notFound.jac +14 -15
  25. jac_client/examples/all-in-one/pages/signupPage.jac +113 -119
  26. jac_client/examples/all-in-one/utils/formatters.jac +5 -8
  27. jac_client/examples/asset-serving/css-with-image/main.jac +77 -73
  28. jac_client/examples/asset-serving/image-asset/main.jac +47 -46
  29. jac_client/examples/asset-serving/import-alias/main.jac +93 -95
  30. jac_client/examples/basic/main.jac +17 -15
  31. jac_client/examples/basic-auth/main.jac +246 -254
  32. jac_client/examples/basic-auth-with-router/main.jac +272 -285
  33. jac_client/examples/basic-full-stack/main.jac +245 -242
  34. jac_client/examples/css-styling/js-styling/main.jac +41 -62
  35. jac_client/examples/css-styling/material-ui/main.jac +90 -90
  36. jac_client/examples/css-styling/pure-css/main.jac +35 -44
  37. jac_client/examples/css-styling/sass-example/main.jac +35 -44
  38. jac_client/examples/css-styling/styled-components/main.jac +38 -47
  39. jac_client/examples/css-styling/tailwind-example/main.jac +54 -43
  40. jac_client/examples/full-stack-with-auth/main.jac +407 -433
  41. jac_client/examples/little-x/main.jac +306 -344
  42. jac_client/examples/little-x/src/submit-button.jac +15 -14
  43. jac_client/examples/nested-folders/nested-advance/main.jac +18 -27
  44. jac_client/examples/nested-folders/nested-advance/src/ButtonRoot.jac +4 -6
  45. jac_client/examples/nested-folders/nested-advance/src/level1/ButtonSecondL.jac +9 -13
  46. jac_client/examples/nested-folders/nested-advance/src/level1/Card.jac +29 -32
  47. jac_client/examples/nested-folders/nested-advance/src/level1/level2/ButtonThirdL.jac +12 -18
  48. jac_client/examples/nested-folders/nested-basic/main.jac +7 -5
  49. jac_client/examples/nested-folders/nested-basic/src/button.jac +4 -3
  50. jac_client/examples/nested-folders/nested-basic/src/components/button.jac +4 -3
  51. jac_client/examples/ts-support/main.jac +26 -26
  52. jac_client/examples/with-router/main.jac +186 -223
  53. jac_client/plugin/client_runtime.cl.jac +5 -3
  54. jac_client/plugin/impl/client_runtime.impl.jac +1 -1
  55. jac_client/plugin/plugin_config.jac +53 -99
  56. jac_client/plugin/src/__init__.jac +0 -2
  57. jac_client/plugin/src/compiler.jac +0 -1
  58. jac_client/plugin/src/impl/compiler.impl.jac +49 -17
  59. jac_client/plugin/src/impl/jac_to_js.impl.jac +5 -1
  60. jac_client/plugin/src/impl/package_installer.impl.jac +20 -20
  61. jac_client/plugin/src/impl/vite_bundler.impl.jac +146 -84
  62. jac_client/plugin/src/targets/impl/desktop_target.impl.jac +54 -41
  63. jac_client/plugin/utils/__init__.jac +3 -0
  64. jac_client/plugin/utils/bun_installer.jac +16 -0
  65. jac_client/plugin/utils/client_deps.jac +14 -0
  66. jac_client/plugin/utils/impl/bun_installer.impl.jac +99 -0
  67. jac_client/plugin/utils/impl/client_deps.impl.jac +73 -0
  68. jac_client/templates/client.jacpack +0 -4
  69. jac_client/templates/fullstack.jacpack +1 -5
  70. jac_client/tests/conftest.py +56 -41
  71. jac_client/tests/fixtures/spawn_test/app.jac +49 -52
  72. jac_client/tests/fixtures/with-ts/app.jac +27 -27
  73. jac_client/tests/test_cli.py +71 -6
  74. jac_client/tests/test_helpers.py +11 -18
  75. jac_client/tests/test_it.py +1 -1
  76. {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/METADATA +5 -5
  77. jac_client-0.2.12.dist-info/RECORD +115 -0
  78. {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/WHEEL +1 -1
  79. jac_client/plugin/src/babel_processor.jac +0 -18
  80. jac_client/plugin/src/impl/babel_processor.impl.jac +0 -89
  81. jac_client/plugin/utils/impl/node_installer.impl.jac +0 -249
  82. jac_client/plugin/utils/node_installer.jac +0 -41
  83. jac_client-0.2.10.dist-info/RECORD +0 -115
  84. {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/entry_points.txt +0 -0
  85. {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  # React Router HashRouter Example
2
2
  cl import from react { useEffect }
3
- cl import from "@jac-client/utils" {
3
+ cl import from "@jac/runtime" {
4
4
  Router,
5
5
  Routes,
6
6
  Route,
@@ -20,104 +20,104 @@ cl {
20
20
  navigate("/about");
21
21
  }
22
22
 
23
- return <div>
24
- <h1>
25
- 🏠 Home Page
26
- </h1>
27
- <p>
28
- Welcome to the home page!
29
- </p>
30
- <p>
31
- This example uses React Router's
32
- <strong>
33
- HashRouter
34
- </strong>
35
- # for client-side routing.
36
- </p>
37
- <p>
38
- Current path:
39
- <code>
40
- {location.pathname}
41
- </code>
42
- </p>
43
- <button
44
- onClick={goToAbout}
45
- >
46
- Go to About →
47
- </button>
48
- </div>;
23
+ return
24
+ <div>
25
+ <h1>
26
+ 🏠 Home Page
27
+ </h1>
28
+ <p>
29
+ Welcome to the home page!
30
+ </p>
31
+ <p>
32
+ This example uses React Router's
33
+ <strong>
34
+ HashRouter
35
+ </strong>
36
+ # for client-side routing.
37
+ </p>
38
+ <p>
39
+ Current path:
40
+ <code>
41
+ {location.pathname}
42
+ </code>
43
+ </p>
44
+ <button onClick={goToAbout}>
45
+ Go to About →
46
+ </button>
47
+ </div>;
49
48
  }
50
49
 
51
50
  # About Page Component
52
51
  def About -> any {
53
52
  location = useLocation();
54
53
 
55
- return <div>
56
- <h1>
57
- ℹ️ About Page
58
- </h1>
59
- <p>
60
- This is the about page.
61
- </p>
62
- <p>
63
- Learn more about our application here.
64
- </p>
65
- <p>
66
- Current path:
67
- <code>
68
- {location.pathname}
69
- </code>
70
- </p>
71
- <div
72
- style={{"marginTop": "1rem"}}
73
- >
74
- <Link to="/about/team">
75
- View Team →
76
- </Link>
77
- </div>
78
- </div>;
54
+ return
55
+ <div>
56
+ <h1>
57
+ ℹ️ About Page
58
+ </h1>
59
+ <p>
60
+ This is the about page.
61
+ </p>
62
+ <p>
63
+ Learn more about our application here.
64
+ </p>
65
+ <p>
66
+ Current path:
67
+ <code>
68
+ {location.pathname}
69
+ </code>
70
+ </p>
71
+ <div style={{"marginTop": "1rem"}}>
72
+ <Link to="/about/team">
73
+ View Team →
74
+ </Link>
75
+ </div>
76
+ </div>;
79
77
  }
80
78
 
81
79
  # Team Page Component (nested route example)
82
80
  def Team -> any {
83
- return <div>
84
- <h1>
85
- 👥 Our Team
86
- </h1>
87
- <p>
88
- Meet the amazing team behind this project!
89
- </p>
90
- <Link to="/about">
91
- Back to About
92
- </Link>
93
- </div>;
81
+ return
82
+ <div>
83
+ <h1>
84
+ 👥 Our Team
85
+ </h1>
86
+ <p>
87
+ Meet the amazing team behind this project!
88
+ </p>
89
+ <Link to="/about">
90
+ ← Back to About
91
+ </Link>
92
+ </div>;
94
93
  }
95
94
 
96
95
  # User Profile Component (with URL parameters)
97
96
  def UserProfile -> any {
98
97
  params = useParams();
99
- userId = params.id if params.id else "Unknown";
98
+ userId = params.id or "Unknown";
100
99
 
101
- return <div>
102
- <h1>
103
- 👤 User Profile
104
- </h1>
105
- <p>
106
- Viewing profile for user:
107
- <strong>
108
- {userId}
109
- </strong>
110
- </p>
111
- <p>
112
- This demonstrates URL parameters using
113
- <code>
114
- /user/:id
115
- </code>
116
- </p>
117
- <Link to="/">
118
- Back to Home
119
- </Link>
120
- </div>;
100
+ return
101
+ <div>
102
+ <h1>
103
+ 👤 User Profile
104
+ </h1>
105
+ <p>
106
+ Viewing profile for user:
107
+ <strong>
108
+ {userId}
109
+ </strong>
110
+ </p>
111
+ <p>
112
+ This demonstrates URL parameters using
113
+ <code>
114
+ /user/:id
115
+ </code>
116
+ </p>
117
+ <Link to="/">
118
+ ← Back to Home
119
+ </Link>
120
+ </div>;
121
121
  }
122
122
 
123
123
  # Contact Page Component
@@ -134,54 +134,50 @@ cl {
134
134
  }
135
135
 
136
136
  if submitted {
137
- return <div>
137
+ return
138
+ <div>
139
+ <h1>
140
+ 📧 Contact Page
141
+ </h1>
142
+ <div style={{"color": "green"}}>
143
+ <p>
144
+ ✓ Thank you! Your message has been sent.
145
+ </p>
146
+ <button onClick={resetForm}>
147
+ Send another
148
+ </button>
149
+ </div>
150
+ </div>;
151
+ }
152
+
153
+ return
154
+ <div>
138
155
  <h1>
139
156
  📧 Contact Page
140
157
  </h1>
141
- <div
142
- style={{"color": "green"}}
143
- >
144
- <p>
145
- ✓ Thank you! Your message has been sent.
146
- </p>
147
- <button
148
- onClick={resetForm}
149
- >
150
- Send another
158
+ <p>
159
+ Get in touch with us!
160
+ </p>
161
+ <form onSubmit={handleSubmit}>
162
+ <input
163
+ type="text"
164
+ placeholder="Your name"
165
+ style={{"margin": "0.5rem 0", "display": "block"}}
166
+ />
167
+ <input
168
+ type="text"
169
+ placeholder="Your username"
170
+ style={{"margin": "0.5rem 0", "display": "block"}}
171
+ />
172
+ <textarea
173
+ placeholder="Your message"
174
+ style={{"margin": "0.5rem 0", "display": "block"}}
175
+ ></textarea>
176
+ <button type="submit">
177
+ Send Message
151
178
  </button>
152
- </div>
179
+ </form>
153
180
  </div>;
154
- }
155
-
156
- return <div>
157
- <h1>
158
- 📧 Contact Page
159
- </h1>
160
- <p>
161
- Get in touch with us!
162
- </p>
163
- <form
164
- onSubmit={handleSubmit}
165
- >
166
- <input
167
- type="text"
168
- placeholder="Your name"
169
- style={{"margin": "0.5rem 0", "display": "block"}}
170
- />
171
- <input
172
- type="text"
173
- placeholder="Your username"
174
- style={{"margin": "0.5rem 0", "display": "block"}}
175
- />
176
- <textarea
177
- placeholder="Your message"
178
- style={{"margin": "0.5rem 0", "display": "block"}}
179
- ></textarea>
180
- <button type="submit">
181
- Send Message
182
- </button>
183
- </form>
184
- </div>;
185
181
  }
186
182
 
187
183
  # 404 Not Found Component
@@ -193,25 +189,22 @@ cl {
193
189
  navigate("/");
194
190
  }
195
191
 
196
- return <div
197
- style={{"textAlign": "center", "padding": "2rem"}}
198
- >
199
- <h1>
200
- 🔍 404 - Page Not Found
201
- </h1>
202
- <p>
203
- The page
204
- <code>
205
- {location.pathname}
206
- </code>
207
- does not exist.
208
- </p>
209
- <button
210
- onClick={goHome}
211
- >
212
- Go Home
213
- </button>
214
- </div>;
192
+ return
193
+ <div style={{"textAlign": "center", "padding": "2rem"}}>
194
+ <h1>
195
+ 🔍 404 - Page Not Found
196
+ </h1>
197
+ <p>
198
+ The page
199
+ <code>
200
+ {location.pathname}
201
+ </code>
202
+ does not exist.
203
+ </p>
204
+ <button onClick={goHome}>
205
+ Go Home
206
+ </button>
207
+ </div>;
215
208
  }
216
209
 
217
210
  # Navigation Component with active link styling
@@ -231,93 +224,63 @@ cl {
231
224
  };
232
225
  }
233
226
 
234
- return <nav
235
- style={{
236
- "padding": "1rem",
237
- "backgroundColor": "#f5f5f5",
238
- "marginBottom": "2rem",
239
- "boxShadow": "0 2px 4px rgba(0,0,0,0.1)"
240
- }}
241
- >
242
- <div
227
+ return
228
+ <nav
243
229
  style={{
244
- "maxWidth": "1200px",
245
- "margin": "0 auto",
246
- "display": "flex",
247
- "gap": "1rem",
248
- "alignItems": "center"
230
+ "padding": "1rem",
231
+ "backgroundColor": "#f5f5f5",
232
+ "marginBottom": "2rem",
233
+ "boxShadow": "0 2px 4px rgba(0,0,0,0.1)"
249
234
  }}
250
235
  >
251
- <Link
252
- to="/"
253
- style={linkStyle("/")}
254
- >
255
- Home
256
- </Link>
257
- <Link
258
- to="/about"
259
- style={linkStyle("/about")}
260
- >
261
- About
262
- </Link>
263
- <Link
264
- to="/contact"
265
- style={linkStyle("/contact")}
266
- >
267
- Contact
268
- </Link>
269
- <Link
270
- to="/user/123"
271
- style={linkStyle("/user/123")}
272
- >
273
- Profile Demo
274
- </Link>
275
- </div>
276
- </nav>;
277
- }
278
-
279
- # Main App Component with React Router HashRouter
280
- def:pub app -> any {
281
- return <Router>
282
- <div
283
- style={{"fontFamily": "system-ui, -apple-system, sans-serif"}}
284
- >
285
- <Navigation />
286
236
  <div
287
237
  style={{
288
238
  "maxWidth": "1200px",
289
239
  "margin": "0 auto",
290
- "padding": "0 1rem"
240
+ "display": "flex",
241
+ "gap": "1rem",
242
+ "alignItems": "center"
291
243
  }}
292
244
  >
293
- <Routes>
294
- <Route
295
- path="/"
296
- element={<Home />}
297
- />
298
- <Route
299
- path="/about"
300
- element={<About />}
301
- />
302
- <Route
303
- path="/about/team"
304
- element={<Team />}
305
- />
306
- <Route
307
- path="/contact"
308
- element={<Contact />}
309
- />
310
- <Route
311
- path="/user/:id"
312
- element={<UserProfile />}
313
- />
314
- <Route
315
- path="*"
316
- element={<NotFound />}
317
- />
318
- </Routes>
245
+ <Link to="/" style={linkStyle("/")}>
246
+ Home
247
+ </Link>
248
+ <Link to="/about" style={linkStyle("/about")}>
249
+ About
250
+ </Link>
251
+ <Link to="/contact" style={linkStyle("/contact")}>
252
+ Contact
253
+ </Link>
254
+ <Link to="/user/123" style={linkStyle("/user/123")}>
255
+ Profile Demo
256
+ </Link>
257
+ </div>
258
+ </nav>;
259
+ }
260
+
261
+ # Main App Component with React Router HashRouter
262
+ def:pub app -> any {
263
+ return
264
+ <Router>
265
+ <div style={{"fontFamily": "system-ui, -apple-system, sans-serif"}}>
266
+ <Navigation />
267
+ <div
268
+ style={{
269
+ "maxWidth": "1200px",
270
+ "margin": "0 auto",
271
+ "padding": "0 1rem"
272
+ }}
273
+ >
274
+ <Routes>
275
+ <Route path="/" element={<Home />} />
276
+ <Route path="/about" element={<About />} />
277
+ <Route path="/about/team" element={<Team />} />
278
+ <Route path="/contact" element={<Contact />} />
279
+ <Route path="/user/:id" element={<UserProfile />} />
280
+ <Route path="*" element={<NotFound />} />
281
+ </Routes>
282
+ </div>
319
283
  </div>
320
- </div>
321
- </Router>;
284
+ </Router>;
322
285
  }
323
286
  }
@@ -1,7 +1,7 @@
1
1
  """Client-side runtime for Jac JSX and walker interactions."""
2
2
 
3
3
  import from 'react' { * as React }
4
- import from 'react' { useState as reactUseState }
4
+ import from 'react' { useState as reactUseState, useEffect as reactUseEffect }
5
5
  import from 'react-dom/client' { * as ReactDOM }
6
6
  import from 'react-router-dom' {
7
7
  HashRouter as ReactRouterHashRouter,
@@ -17,8 +17,10 @@ import from 'react-error-boundary' { ErrorBoundary }
17
17
 
18
18
  def:pub __jacJsx(tag: any, props: dict = {}, children: any = []) -> any;
19
19
 
20
- # React hooks re-exported for auto-injection by `has` variables
21
- glob:pub useState = reactUseState,
20
+ # React hooks re-exported for auto-injection by `has` variables and `can with entry/exit` effects
21
+ glob:
22
+ pub useState = reactUseState,
23
+ useEffect = reactUseEffect,
22
24
  Router = ReactRouterHashRouter,
23
25
  Routes = ReactRouterRoutes,
24
26
  Route = ReactRouterRoute,
@@ -86,7 +86,7 @@ impl __jacCallFunction(function_name: str, args: dict = {}) -> any {
86
86
  "Content-Type": "application/json",
87
87
  "Authorization": f"Bearer {token}" if token else ""
88
88
  },
89
- "body": JSON.stringify({"args": args})
89
+ "body": JSON.stringify(args)
90
90
  }
91
91
  );
92
92
  payload = await response.json();