jac-client 0.2.8__py3-none-any.whl → 0.2.11__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 (119) 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 +542 -0
  17. jac_client/examples/all-in-one/pages/BudgetPlanner.jac +26 -12
  18. jac_client/examples/all-in-one/pages/FeaturesTest.jac +43 -12
  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 +65 -0
  21. jac_client/examples/all-in-one/pages/features_test_ui.cl.jac +675 -0
  22. jac_client/examples/all-in-one/pages/loginPage.jac +114 -119
  23. jac_client/examples/all-in-one/pages/nestedDemo.jac +44 -51
  24. jac_client/examples/all-in-one/pages/notFound.jac +15 -21
  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 +92 -0
  28. jac_client/examples/asset-serving/image-asset/main.jac +56 -0
  29. jac_client/examples/asset-serving/import-alias/main.jac +109 -0
  30. jac_client/examples/basic/main.jac +23 -0
  31. jac_client/examples/basic-auth/main.jac +363 -0
  32. jac_client/examples/basic-auth-with-router/main.jac +451 -0
  33. jac_client/examples/basic-full-stack/main.jac +362 -0
  34. jac_client/examples/css-styling/js-styling/main.jac +63 -0
  35. jac_client/examples/css-styling/material-ui/main.jac +122 -0
  36. jac_client/examples/css-styling/pure-css/main.jac +55 -0
  37. jac_client/examples/css-styling/sass-example/main.jac +55 -0
  38. jac_client/examples/css-styling/styled-components/main.jac +62 -0
  39. jac_client/examples/css-styling/tailwind-example/main.jac +74 -0
  40. jac_client/examples/full-stack-with-auth/main.jac +696 -0
  41. jac_client/examples/little-x/main.jac +681 -0
  42. jac_client/examples/little-x/src/submit-button.jac +15 -14
  43. jac_client/examples/nested-folders/nested-advance/main.jac +26 -0
  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/{src/app.jac → 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 +35 -0
  52. jac_client/examples/with-router/main.jac +286 -0
  53. jac_client/plugin/cli.jac +491 -411
  54. jac_client/plugin/client.jac +25 -0
  55. jac_client/plugin/client_runtime.cl.jac +10 -4
  56. jac_client/plugin/impl/client.impl.jac +96 -55
  57. jac_client/plugin/impl/client_runtime.impl.jac +155 -1
  58. jac_client/plugin/plugin_config.jac +211 -29
  59. jac_client/plugin/src/__init__.jac +0 -2
  60. jac_client/plugin/src/compiler.jac +0 -1
  61. jac_client/plugin/src/config_loader.jac +1 -0
  62. jac_client/plugin/src/desktop_config.jac +31 -0
  63. jac_client/plugin/src/impl/compiler.impl.jac +49 -17
  64. jac_client/plugin/src/impl/config_loader.impl.jac +8 -0
  65. jac_client/plugin/src/impl/desktop_config.impl.jac +191 -0
  66. jac_client/plugin/src/impl/jac_to_js.impl.jac +5 -1
  67. jac_client/plugin/src/impl/package_installer.impl.jac +20 -20
  68. jac_client/plugin/src/impl/vite_bundler.impl.jac +191 -64
  69. jac_client/plugin/src/targets/desktop/sidecar/main.py +144 -0
  70. jac_client/plugin/src/targets/desktop_target.jac +37 -0
  71. jac_client/plugin/src/targets/impl/desktop_target.impl.jac +2347 -0
  72. jac_client/plugin/src/targets/impl/registry.impl.jac +64 -0
  73. jac_client/plugin/src/targets/impl/web_target.impl.jac +157 -0
  74. jac_client/plugin/src/targets/register.jac +21 -0
  75. jac_client/plugin/src/targets/registry.jac +87 -0
  76. jac_client/plugin/src/targets/web_target.jac +35 -0
  77. jac_client/plugin/src/vite_bundler.jac +6 -0
  78. jac_client/plugin/utils/__init__.jac +3 -0
  79. jac_client/plugin/utils/bun_installer.jac +16 -0
  80. jac_client/plugin/utils/impl/bun_installer.impl.jac +99 -0
  81. jac_client/templates/client.jacpack +72 -0
  82. jac_client/templates/fullstack.jacpack +61 -0
  83. jac_client/tests/conftest.py +103 -47
  84. jac_client/tests/fixtures/spawn_test/app.jac +49 -52
  85. jac_client/tests/fixtures/with-ts/app.jac +27 -27
  86. jac_client/tests/test_cli.py +182 -71
  87. jac_client/tests/test_e2e.py +232 -0
  88. jac_client/tests/test_helpers.py +58 -0
  89. jac_client/tests/test_it.py +91 -135
  90. jac_client/tests/test_it_desktop.py +891 -0
  91. {jac_client-0.2.8.dist-info → jac_client-0.2.11.dist-info}/METADATA +6 -6
  92. jac_client-0.2.11.dist-info/RECORD +113 -0
  93. {jac_client-0.2.8.dist-info → jac_client-0.2.11.dist-info}/WHEEL +1 -1
  94. jac_client/examples/all-in-one/app.jac +0 -573
  95. jac_client/examples/all-in-one/pages/BudgetPlanner.cl.jac +0 -70
  96. jac_client/examples/all-in-one/pages/FeaturesTest.cl.jac +0 -552
  97. jac_client/examples/asset-serving/css-with-image/src/app.jac +0 -88
  98. jac_client/examples/asset-serving/image-asset/src/app.jac +0 -55
  99. jac_client/examples/asset-serving/import-alias/src/app.jac +0 -111
  100. jac_client/examples/basic/src/app.jac +0 -21
  101. jac_client/examples/basic-auth/src/app.jac +0 -371
  102. jac_client/examples/basic-auth-with-router/src/app.jac +0 -464
  103. jac_client/examples/basic-full-stack/src/app.jac +0 -359
  104. jac_client/examples/css-styling/js-styling/src/app.jac +0 -84
  105. jac_client/examples/css-styling/material-ui/src/app.jac +0 -122
  106. jac_client/examples/css-styling/pure-css/src/app.jac +0 -64
  107. jac_client/examples/css-styling/sass-example/src/app.jac +0 -64
  108. jac_client/examples/css-styling/styled-components/src/app.jac +0 -71
  109. jac_client/examples/css-styling/tailwind-example/src/app.jac +0 -63
  110. jac_client/examples/full-stack-with-auth/src/app.jac +0 -722
  111. jac_client/examples/little-x/src/app.jac +0 -719
  112. jac_client/examples/nested-folders/nested-advance/src/app.jac +0 -35
  113. jac_client/examples/ts-support/src/app.jac +0 -35
  114. jac_client/examples/with-router/src/app.jac +0 -323
  115. jac_client/plugin/src/babel_processor.jac +0 -18
  116. jac_client/plugin/src/impl/babel_processor.impl.jac +0 -89
  117. jac_client-0.2.8.dist-info/RECORD +0 -97
  118. {jac_client-0.2.8.dist-info → jac_client-0.2.11.dist-info}/entry_points.txt +0 -0
  119. {jac_client-0.2.8.dist-info → jac_client-0.2.11.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,451 @@
1
+ # Simple Authentication App with React Router
2
+ cl import from react {
3
+ useState,
4
+ useEffect
5
+ }
6
+ cl import from "@jac/runtime" {
7
+ Router,
8
+ Routes,
9
+ Route,
10
+ Link,
11
+ Navigate,
12
+ useNavigate,
13
+ useLocation,
14
+ jacSignup,
15
+ jacLogin,
16
+ jacLogout,
17
+ jacIsLoggedIn
18
+ }
19
+
20
+ cl {
21
+ # Navigation Component
22
+ def Navigation -> any {
23
+ isLoggedIn = jacIsLoggedIn();
24
+ navigate = useNavigate();
25
+
26
+ def handleLogout(e: any) -> None {
27
+ e.preventDefault();
28
+ jacLogout();
29
+ navigate("/login");
30
+ }
31
+
32
+ if isLoggedIn {
33
+ return
34
+ <nav
35
+ style={{
36
+ "padding": "16px 24px",
37
+ "background": "#667eea",
38
+ "display": "flex",
39
+ "justifyContent": "space-between",
40
+ "alignItems": "center"
41
+ }}
42
+ >
43
+ <div
44
+ style={{
45
+ "fontSize": "1.25rem",
46
+ "fontWeight": "600",
47
+ "color": "#ffffff"
48
+ }}
49
+ >
50
+ MyApp
51
+ </div>
52
+ <div style={{"display": "flex", "gap": "16px"}}>
53
+ <Link
54
+ to="/dashboard"
55
+ style={{"color": "#ffffff", "textDecoration": "none"}}
56
+ >
57
+ Dashboard
58
+ </Link>
59
+ <button
60
+ onClick={handleLogout}
61
+ style={{
62
+ "background": "none",
63
+ "color": "#ffffff",
64
+ "border": "1px solid #ffffff",
65
+ "padding": "4px 12px",
66
+ "borderRadius": "4px",
67
+ "cursor": "pointer"
68
+ }}
69
+ >
70
+ Logout
71
+ </button>
72
+ </div>
73
+ </nav>;
74
+ }
75
+
76
+ return
77
+ <nav
78
+ style={{
79
+ "padding": "16px 24px",
80
+ "background": "#667eea",
81
+ "display": "flex",
82
+ "justifyContent": "space-between",
83
+ "alignItems": "center"
84
+ }}
85
+ >
86
+ <div
87
+ style={{
88
+ "fontSize": "1.25rem",
89
+ "fontWeight": "600",
90
+ "color": "#ffffff"
91
+ }}
92
+ >
93
+ MyApp
94
+ </div>
95
+ <div style={{"display": "flex", "gap": "16px"}}>
96
+ <Link
97
+ to="/login"
98
+ style={{"color": "#ffffff", "textDecoration": "none"}}
99
+ >
100
+ Login
101
+ </Link>
102
+ <Link
103
+ to="/signup"
104
+ style={{"color": "#ffffff", "textDecoration": "none"}}
105
+ >
106
+ Sign Up
107
+ </Link>
108
+ </div>
109
+ </nav>;
110
+ }
111
+
112
+ # Login Page
113
+ def LoginPage -> any {
114
+ has username: str = "",
115
+ password: str = "",
116
+ error: str = "";
117
+
118
+ navigate = useNavigate();
119
+
120
+ async def handleLogin(e: any) -> None {
121
+ e.preventDefault();
122
+ error = "";
123
+ if not username or not password {
124
+ error = "Please fill in all fields";
125
+ return;
126
+ }
127
+ success = await jacLogin(username, password);
128
+ if success {
129
+ navigate("/dashboard");
130
+ } else {
131
+ error = "Invalid credentials";
132
+ }
133
+ }
134
+
135
+ def handleUsernameChange(e: any) -> None {
136
+ username = e.target.value;
137
+ }
138
+
139
+ def handlePasswordChange(e: any) -> None {
140
+ password = e.target.value;
141
+ }
142
+
143
+ errorDisplay = None;
144
+ if error {
145
+ errorDisplay = <div
146
+ style={{"color": "#dc2626", "fontSize": "14px", "marginBottom": "12px"}}
147
+ >
148
+ {error}
149
+ </div>;
150
+ }
151
+
152
+ return
153
+ <div
154
+ style={{
155
+ "minHeight": "calc(100vh - 56px)",
156
+ "display": "flex",
157
+ "alignItems": "center",
158
+ "justifyContent": "center",
159
+ "background": "#f5f5f5"
160
+ }}
161
+ >
162
+ <div
163
+ style={{
164
+ "background": "#ffffff",
165
+ "padding": "32px",
166
+ "borderRadius": "8px",
167
+ "width": "300px",
168
+ "boxShadow": "0 2px 8px rgba(0,0,0,0.1)"
169
+ }}
170
+ >
171
+ <h2 style={{"marginBottom": "24px", "textAlign": "center"}}>
172
+ Login
173
+ </h2>
174
+ <form onSubmit={handleLogin}>
175
+ <input
176
+ type="text"
177
+ value={username}
178
+ onChange={handleUsernameChange}
179
+ placeholder="Username"
180
+ style={{
181
+ "width": "100%",
182
+ "padding": "10px",
183
+ "marginBottom": "12px",
184
+ "border": "1px solid #ddd",
185
+ "borderRadius": "4px",
186
+ "boxSizing": "border-box"
187
+ }}
188
+ />
189
+ <input
190
+ type="password"
191
+ value={password}
192
+ onChange={handlePasswordChange}
193
+ placeholder="Password"
194
+ style={{
195
+ "width": "100%",
196
+ "padding": "10px",
197
+ "marginBottom": "12px",
198
+ "border": "1px solid #ddd",
199
+ "borderRadius": "4px",
200
+ "boxSizing": "border-box"
201
+ }}
202
+ />
203
+ {errorDisplay}
204
+ <button
205
+ type="submit"
206
+ style={{
207
+ "width": "100%",
208
+ "padding": "10px",
209
+ "background": "#667eea",
210
+ "color": "#ffffff",
211
+ "border": "none",
212
+ "borderRadius": "4px",
213
+ "cursor": "pointer",
214
+ "fontWeight": "600"
215
+ }}
216
+ >
217
+ Login
218
+ </button>
219
+ </form>
220
+ <p
221
+ style={{
222
+ "textAlign": "center",
223
+ "marginTop": "16px",
224
+ "fontSize": "14px"
225
+ }}
226
+ >
227
+ Need an account?
228
+ <Link to="/signup">
229
+ Sign up
230
+ </Link>
231
+ </p>
232
+ </div>
233
+ </div>;
234
+ }
235
+
236
+ # Signup Page
237
+ def SignupPage -> any {
238
+ has username: str = "",
239
+ password: str = "",
240
+ error: str = "";
241
+
242
+ navigate = useNavigate();
243
+
244
+ async def handleSignup(e: any) -> None {
245
+ e.preventDefault();
246
+ error = "";
247
+ if not username or not password {
248
+ error = "Please fill in all fields";
249
+ return;
250
+ }
251
+ result = await jacSignup(username, password);
252
+ if result["success"] {
253
+ navigate("/dashboard");
254
+ } else {
255
+ error = result["error"] if result["error"] else "Signup failed";
256
+ }
257
+ }
258
+
259
+ def handleUsernameChange(e: any) -> None {
260
+ username = e.target.value;
261
+ }
262
+
263
+ def handlePasswordChange(e: any) -> None {
264
+ password = e.target.value;
265
+ }
266
+
267
+ errorDisplay = None;
268
+ if error {
269
+ errorDisplay = <div
270
+ style={{"color": "#dc2626", "fontSize": "14px", "marginBottom": "12px"}}
271
+ >
272
+ {error}
273
+ </div>;
274
+ }
275
+
276
+ return
277
+ <div
278
+ style={{
279
+ "minHeight": "calc(100vh - 56px)",
280
+ "display": "flex",
281
+ "alignItems": "center",
282
+ "justifyContent": "center",
283
+ "background": "#f5f5f5"
284
+ }}
285
+ >
286
+ <div
287
+ style={{
288
+ "background": "#ffffff",
289
+ "padding": "32px",
290
+ "borderRadius": "8px",
291
+ "width": "300px",
292
+ "boxShadow": "0 2px 8px rgba(0,0,0,0.1)"
293
+ }}
294
+ >
295
+ <h2 style={{"marginBottom": "24px", "textAlign": "center"}}>
296
+ Sign Up
297
+ </h2>
298
+ <form onSubmit={handleSignup}>
299
+ <input
300
+ type="text"
301
+ value={username}
302
+ onChange={handleUsernameChange}
303
+ placeholder="Username"
304
+ style={{
305
+ "width": "100%",
306
+ "padding": "10px",
307
+ "marginBottom": "12px",
308
+ "border": "1px solid #ddd",
309
+ "borderRadius": "4px",
310
+ "boxSizing": "border-box"
311
+ }}
312
+ />
313
+ <input
314
+ type="password"
315
+ value={password}
316
+ onChange={handlePasswordChange}
317
+ placeholder="Password"
318
+ style={{
319
+ "width": "100%",
320
+ "padding": "10px",
321
+ "marginBottom": "12px",
322
+ "border": "1px solid #ddd",
323
+ "borderRadius": "4px",
324
+ "boxSizing": "border-box"
325
+ }}
326
+ />
327
+ {errorDisplay}
328
+ <button
329
+ type="submit"
330
+ style={{
331
+ "width": "100%",
332
+ "padding": "10px",
333
+ "background": "#667eea",
334
+ "color": "#ffffff",
335
+ "border": "none",
336
+ "borderRadius": "4px",
337
+ "cursor": "pointer",
338
+ "fontWeight": "600"
339
+ }}
340
+ >
341
+ Sign Up
342
+ </button>
343
+ </form>
344
+ <p
345
+ style={{
346
+ "textAlign": "center",
347
+ "marginTop": "16px",
348
+ "fontSize": "14px"
349
+ }}
350
+ >
351
+ Have an account?
352
+ <Link to="/login">
353
+ Login
354
+ </Link>
355
+ </p>
356
+ </div>
357
+ </div>;
358
+ }
359
+
360
+ # Dashboard Page (Protected Route)
361
+ def DashboardPage -> any {
362
+ # Check if user is logged in, redirect if not
363
+ if not jacIsLoggedIn() {
364
+ return
365
+ <Navigate to="/login" />;
366
+ }
367
+
368
+ return
369
+ <div
370
+ style={{
371
+ "minHeight": "calc(100vh - 56px)",
372
+ "padding": "40px 20px",
373
+ "background": "#f5f5f5"
374
+ }}
375
+ >
376
+ <div
377
+ style={{
378
+ "maxWidth": "800px",
379
+ "margin": "0 auto",
380
+ "background": "#ffffff",
381
+ "padding": "40px",
382
+ "borderRadius": "8px",
383
+ "boxShadow": "0 2px 8px rgba(0,0,0,0.1)"
384
+ }}
385
+ >
386
+ <h1 style={{"marginBottom": "16px"}}>
387
+ 🎉 Welcome to Your Dashboard
388
+ </h1>
389
+ <p style={{"color": "#666", "lineHeight": "1.6"}}>
390
+ You are now logged in and can access protected content.
391
+ </p>
392
+ <p
393
+ style={{
394
+ "color": "#666",
395
+ "lineHeight": "1.6",
396
+ "marginTop": "16px"
397
+ }}
398
+ >
399
+ This is a simple dashboard page demonstrating authenticationwith React Router in Jac. You can add your own content and functionality here.
400
+ </p>
401
+ <div
402
+ style={{
403
+ "marginTop": "24px",
404
+ "padding": "16px",
405
+ "background": "#f0f9ff",
406
+ "borderRadius": "4px",
407
+ "border": "1px solid #bae6fd"
408
+ }}
409
+ >
410
+ <h3 style={{"marginBottom": "8px", "color": "#0369a1"}}>
411
+ Protected Route Demo
412
+ </h3>
413
+ <p style={{"color": "#0c4a6e", "fontSize": "14px"}}>
414
+ This page is only accessible to authenticated users. Try logging outand accessing this page - you'll be redirected to the login page!
415
+ </p>
416
+ </div>
417
+ </div>
418
+ </div>;
419
+ }
420
+
421
+ # Home/Landing Page - auto-redirect based on auth status
422
+ def HomePage -> any {
423
+ if jacIsLoggedIn() {
424
+ return
425
+ <Navigate to="/dashboard" />;
426
+ }
427
+ return
428
+ <Navigate to="/login" />;
429
+ }
430
+
431
+ # Main App with React Router
432
+ def:pub app -> any {
433
+ return
434
+ <Router>
435
+ <div
436
+ style={{
437
+ "fontFamily": "system-ui, -apple-system, sans-serif",
438
+ "minHeight": "100vh"
439
+ }}
440
+ >
441
+ <Navigation />
442
+ <Routes>
443
+ <Route path="/" element={<HomePage />} />
444
+ <Route path="/login" element={<LoginPage />} />
445
+ <Route path="/signup" element={<SignupPage />} />
446
+ <Route path="/dashboard" element={<DashboardPage />} />
447
+ </Routes>
448
+ </div>
449
+ </Router>;
450
+ }
451
+ }