jac-client 0.2.12__py3-none-any.whl → 0.2.14__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 (51) hide show
  1. jac_client/examples/all-in-one/components/Header.jac +1 -1
  2. jac_client/examples/all-in-one/components/ProfitOverview.jac +1 -1
  3. jac_client/examples/all-in-one/components/Summary.jac +1 -1
  4. jac_client/examples/all-in-one/components/TransactionList.jac +2 -2
  5. jac_client/examples/all-in-one/components/navigation.jac +3 -9
  6. jac_client/examples/all-in-one/context/BudgetContext.jac +1 -1
  7. jac_client/examples/all-in-one/main.jac +5 -386
  8. jac_client/examples/all-in-one/pages/(auth)/index.jac +299 -0
  9. jac_client/examples/all-in-one/pages/{nestedDemo.jac → (auth)/nested.jac} +3 -13
  10. jac_client/examples/all-in-one/pages/{loginPage.jac → (public)/login.jac} +1 -1
  11. jac_client/examples/all-in-one/pages/{signupPage.jac → (public)/signup.jac} +1 -1
  12. jac_client/examples/all-in-one/pages/{notFound.jac → [...notFound].jac} +2 -1
  13. jac_client/examples/all-in-one/pages/budget.jac +11 -0
  14. jac_client/examples/all-in-one/pages/budget_planner_ui.cl.jac +1 -1
  15. jac_client/examples/all-in-one/pages/features.jac +8 -0
  16. jac_client/examples/all-in-one/pages/features_test_ui.cl.jac +7 -7
  17. jac_client/examples/all-in-one/pages/{LandingPage.jac → landing.jac} +4 -9
  18. jac_client/examples/all-in-one/pages/layout.jac +20 -0
  19. jac_client/examples/nested-folders/nested-advance/src/ButtonRoot.jac +1 -1
  20. jac_client/examples/nested-folders/nested-advance/src/level1/ButtonSecondL.jac +1 -1
  21. jac_client/examples/nested-folders/nested-advance/src/level1/level2/ButtonThirdL.jac +1 -1
  22. jac_client/plugin/cli.jac +3 -3
  23. jac_client/plugin/client_runtime.cl.jac +7 -4
  24. jac_client/plugin/impl/client_runtime.impl.jac +29 -7
  25. jac_client/plugin/plugin_config.jac +4 -11
  26. jac_client/plugin/src/compiler.jac +19 -1
  27. jac_client/plugin/src/config_loader.jac +1 -0
  28. jac_client/plugin/src/impl/compiler.impl.jac +232 -62
  29. jac_client/plugin/src/impl/config_loader.impl.jac +8 -0
  30. jac_client/plugin/src/impl/package_installer.impl.jac +3 -2
  31. jac_client/plugin/src/impl/route_scanner.impl.jac +201 -0
  32. jac_client/plugin/src/impl/vite_bundler.impl.jac +54 -15
  33. jac_client/plugin/src/route_scanner.jac +44 -0
  34. jac_client/plugin/src/targets/desktop/sidecar/main.py +42 -23
  35. jac_client/plugin/src/targets/desktop_target.jac +4 -2
  36. jac_client/plugin/src/targets/impl/desktop_target.impl.jac +324 -112
  37. jac_client/plugin/src/vite_bundler.jac +18 -3
  38. jac_client/plugin/utils/impl/bun_installer.impl.jac +16 -19
  39. jac_client/plugin/utils/impl/client_deps.impl.jac +12 -16
  40. jac_client/templates/fullstack.jacpack +3 -2
  41. jac_client/tests/test_cli.py +74 -0
  42. jac_client/tests/test_desktop_api_url.py +854 -0
  43. jac_client/tests/test_e2e.py +31 -40
  44. jac_client/tests/test_it.py +209 -11
  45. {jac_client-0.2.12.dist-info → jac_client-0.2.14.dist-info}/METADATA +2 -2
  46. {jac_client-0.2.12.dist-info → jac_client-0.2.14.dist-info}/RECORD +49 -44
  47. jac_client/examples/all-in-one/pages/BudgetPlanner.jac +0 -140
  48. jac_client/examples/all-in-one/pages/FeaturesTest.jac +0 -157
  49. {jac_client-0.2.12.dist-info → jac_client-0.2.14.dist-info}/WHEEL +0 -0
  50. {jac_client-0.2.12.dist-info → jac_client-0.2.14.dist-info}/entry_points.txt +0 -0
  51. {jac_client-0.2.12.dist-info → jac_client-0.2.14.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  # Header component
2
2
  # Demonstrates: simple component, CSS classes
3
3
  cl {
4
- def:pub Header -> any {
4
+ def:pub Header -> JsxElement {
5
5
  return
6
6
  <header className="header">
7
7
  <div className="header-content">
@@ -6,7 +6,7 @@ cl import from ..context.BudgetContext {
6
6
  cl import from ..utils.formatters { formatCurrency }
7
7
 
8
8
  cl {
9
- def:pub ProfitOverview -> any {
9
+ def:pub ProfitOverview -> JsxElement {
10
10
  budget = useBudgetContext();
11
11
 
12
12
  businessIncome = budget["businessIncome"];
@@ -6,7 +6,7 @@ cl import from ..context.BudgetContext {
6
6
  cl import from ..utils.formatters { formatCurrency }
7
7
 
8
8
  cl {
9
- def:pub Summary -> any {
9
+ def:pub Summary -> JsxElement {
10
10
  budget = useBudgetContext();
11
11
 
12
12
  # Business/Personal breakdown
@@ -6,7 +6,7 @@ cl import from .TransactionItem {
6
6
 
7
7
  cl {
8
8
  # Props: transactions list and delete handler
9
- def:pub TransactionList(transactions: list, onDelete: any) -> any {
9
+ def:pub TransactionList(transactions: list, onDelete: any) -> JsxElement {
10
10
  if transactions.length == 0 {
11
11
  return
12
12
  <div className="empty-state">
@@ -25,7 +25,7 @@ cl {
25
25
  Transactions ({transactions.length})
26
26
  </h3>
27
27
  {transactions.map(
28
- lambda tx: dict -> any { return
28
+ lambda tx: dict -> JsxElement { return
29
29
  <TransactionItem
30
30
  key={tx["id"]}
31
31
  id={tx["id"]}
@@ -7,7 +7,7 @@ cl import from "@jac/runtime" {
7
7
  }
8
8
 
9
9
  cl {
10
- def:pub Navigation -> any {
10
+ def:pub Navigation -> JsxElement {
11
11
  location = useLocation();
12
12
  isLoggedIn = jacIsLoggedIn();
13
13
  navigate = useNavigate();
@@ -93,19 +93,13 @@ cl {
93
93
  <Link to="/nested" style={linkStyle("/nested")}>
94
94
  Nested Imports
95
95
  </Link>
96
- <Link
97
- to="/features-test"
98
- style={linkStyle("/features-test")}
99
- >
96
+ <Link to="/features" style={linkStyle("/features")}>
100
97
  Features Test
101
98
  </Link>
102
99
  <Link to="/landing" style={linkStyle("/landing")}>
103
100
  Landing Page
104
101
  </Link>
105
- <Link
106
- to="/budget-planner"
107
- style={linkStyle("/budget-planner")}
108
- >
102
+ <Link to="/budget" style={linkStyle("/budget")}>
109
103
  Budget Planner
110
104
  </Link>
111
105
  </>
@@ -11,7 +11,7 @@ cl {
11
11
  glob:pub BudgetContext = createContext(None);
12
12
 
13
13
  # Provider component - wraps app and provides budget state
14
- def:pub BudgetProvider(children: any) -> any {
14
+ def:pub BudgetProvider(children: any) -> JsxElement {
15
15
  budget = useBudget();
16
16
 
17
17
  return
@@ -29,16 +29,7 @@ walker:pub get_server_message {
29
29
  }
30
30
  }
31
31
 
32
- # Features Test Page - Backend Logic
33
- # This file is intentionally kept empty to demonstrate the separation of concerns
34
- # where UI logic resides in .cl.jac files and backend walker logic in app.jac
35
-
36
- # All walker implementations for this feature are in main.jac
37
- # This demonstrates that you can have separate .jac files for different purposes
38
32
  # Features Test - Backend Walkers
39
- # This file demonstrates walker functionality for testing various JAC features
40
-
41
- # Node definition for storing test data
42
33
  node TestData {
43
34
  has message: str,
44
35
  count: int = 0,
@@ -156,387 +147,15 @@ walker process_complex_data {
156
147
  }
157
148
  }
158
149
 
159
- #
160
- # Combined example: auth + routing + CSS styling + asset serving + nested folder imports
161
- #
162
- cl import from react { useEffect, useRef }
163
- cl import from "@jac/runtime" {
164
- Router,
165
- Routes,
166
- Route,
167
- Link,
168
- useNavigate,
169
- Navigate,
170
- jacIsLoggedIn
171
- }
172
-
173
- # Pure CSS + asset-in-CSS example
150
+ # Global CSS styles
174
151
  cl import ".styles/styles.css";
175
152
 
176
- # Login Page
177
- cl import from .pages.loginPage { LoginPage }
178
-
179
- # Signup Page
180
- cl import from .pages.signupPage { SignupPage }
181
-
182
- # Simple 404 page
183
- cl import from .pages.notFound { NotFound }
184
-
185
- # Navigation component with active link styling and auth
186
- cl import from .components.navigation {
187
- Navigation
188
- }
189
-
190
- # Page showing nested imports from different folders
191
- cl import from .pages.nestedDemo {
192
- NestedImportsDemo
193
- }
194
-
195
- cl import from .pages.FeaturesTest { FeaturesTest }
196
-
197
- cl import from .pages.LandingPage { LandingPage }
198
-
199
- cl import from .pages.BudgetPlanner { BudgetPlanner }
200
-
201
- # Context provider
202
- cl import from .context.BudgetContext { BudgetProvider }
203
-
204
- # TypeScript component import
205
- cl import from ".components/Card.tsx" { Card }
206
-
207
- # Main app wrapped in Router (same API as with-router/ example)
153
+ # App wrapper -- file-based routing is handled automatically via pages/ directory
208
154
  cl {
209
- def:pub HomePage -> any {
210
- # Check if user is logged in, redirect if not
211
- if not jacIsLoggedIn() {
212
- return
213
- <Navigate to="/login" />;
214
- }
215
- has count: int = 0,
216
- pingResult: str = "",
217
- serverMessage: str = "",
218
- lastTodoMessage: str = "";
219
-
220
- can with count entry {
221
- console.log("Home count changed: ", count);
222
- }
223
-
224
- # Call simple backend walkers
225
- async def handlePing -> None {
226
- result = root spawn ping_server();
227
- if result.reports and result.reports.length > 0 {
228
- pingResult = result.reports[0][0];
229
- }
230
- }
231
-
232
- async def loadServerMessage -> None {
233
- result = root spawn get_server_message();
234
- if result.reports and result.reports.length > 0 {
235
- serverMessage = result.reports[0][0];
236
- }
237
- }
238
-
239
- # Create a sample Todo node in the graph with a hardcoded payload
240
- async def handleCreateSampleTodo -> None {
241
- result = root spawn create_todo(text="Sample todo from all-in-one app");
242
- if result.reports and result.reports.length > 0 {
243
- todo = result.reports[0][0];
244
- lastTodoMessage = "Created Todo: " + todo.text;
245
- console.log("Created Todo node:", todo);
246
- }
247
- }
248
-
249
- async can with entry {
250
- await loadServerMessage();
251
- }
252
-
253
- # Initialize a Web Worker and handle message-based communication
254
- workerRef = useRef(None);
255
- has message: str = "";
256
-
257
- useEffect(
258
- lambda -> None { workerRef.current = Reflect.construct(
259
- Worker, ["/workers/worker.js"]
260
- );workerRef.current.onmessage = lambda event: any -> None { console.log(
261
- "Message received from worker:", event.data
262
- );message = event.data;};return (
263
- lambda -> None { workerRef.current.terminate();}
264
- ); },
265
- []
266
- );
267
- handleClick = lambda -> None { workerRef.current.postMessage("");};
268
-
155
+ def:pub app(children: any = None) -> any {
269
156
  return
270
- <div
271
- style={{
272
- "padding": "2rem",
273
- "fontFamily": "system-ui, -apple-system, sans-serif"
274
- }}
275
- >
276
- <h1>
277
- 🍔 Router + Styling + Assets Demo
278
- </h1>
279
- <p>
280
- This home page combines
281
- {" "}
282
- <strong>
283
- React Router,
284
- </strong>
285
- {" "}
286
- <strong>
287
- pure CSS styling,
288
- </strong>
289
- {" "}
290
- <strong>
291
- staticassets
292
- </strong>
293
- {" "}
294
- and
295
- {" "}
296
- <strong>
297
- nested folder imports
298
- </strong>
299
- </p>
300
- <div className="container">
301
- <h2
302
- style={{
303
- "color": "white",
304
- "textShadow": "2px 2px 4px rgba(0,0,0,0.6)"
305
- }}
306
- >
307
- CSS Background Image
308
- </h2>
309
- <p
310
- style={{
311
- "color": "white",
312
- "maxWidth": "480px",
313
- "textShadow": "1px 1px 3px rgba(0,0,0,0.7)"
314
- }}
315
- >
316
- This section uses the burger image as a background via CSS, just like the
317
- {" "}
318
- <code>
319
- asset-serving/css-with-image
320
- </code>
321
- {" "}
322
- example.
323
- </p>
324
- </div>
325
- <Card
326
- title="TypeScript Card Component"
327
- description="This card is built with TypeScript and demonstrates type-safe component usage in Jac"
328
- variant="highlighted"
329
- >
330
- <p style={{"margin": "0.5rem 0", "color": "#374151"}}>
331
- This is a TypeScript component imported and used in Jac code!
332
- </p>
333
- </Card>
334
- <div className="card">
335
- <h3>
336
- Direct &lt;img&gt; asset
337
- </h3>
338
- <img
339
- src="/static/assets/burger.png"
340
- alt="Burger asset served by Jac"
341
- className="burgerImage"
342
- />
343
- <p style={{"marginTop": "0.75rem", "color": "#555"}}>
344
- This image is served from the project
345
- {" "}
346
- <code>
347
- assets/
348
- </code>
349
- {" "}
350
- folder using the
351
- {" "}
352
- <code>
353
- /static/assets/
354
- </code>
355
- {" "}
356
- path.
357
- </p>
358
- </div>
359
- <div style={{"marginTop": "2rem"}}>
360
- <h3>
361
- Counter with pure CSS classes
362
- </h3>
363
- <p>
364
- You've clicked the burger
365
- {" "}
366
- <strong>
367
- {count}
368
- </strong>
369
- {" "}
370
- times.
371
- </p>
372
- <button
373
- onClick={lambda e: any -> None { count = count + 1;}}
374
- style={{
375
- "padding": "0.6rem 1.4rem",
376
- "fontSize": "1rem",
377
- "backgroundColor": "#ff6b35",
378
- "color": "white",
379
- "border": "none",
380
- "borderRadius": "6px",
381
- "cursor": "pointer",
382
- "boxShadow": "0 2px 4px rgba(0,0,0,0.2)"
383
- }}
384
- >
385
- Click the Burger! 🍔
386
- </button>
387
- </div>
388
- <div style={{"marginTop": "2rem"}}>
389
- <h3>
390
- Backend Walkers
391
- </h3>
392
- <p>
393
- Basic example walkers:
394
- {" "}
395
- <code>
396
- ping_server
397
- </code>
398
- {" "}
399
- and
400
- {" "}
401
- <code>
402
- get_server_message
403
- </code>
404
- </p>
405
- <button
406
- onClick={lambda e: any -> None { handlePing();}}
407
- style={{
408
- "padding": "0.5rem 1.2rem",
409
- "marginRight": "0.75rem",
410
- "backgroundColor": "#3b82f6",
411
- "color": "white",
412
- "border": "none",
413
- "borderRadius": "6px",
414
- "cursor": "pointer"
415
- }}
416
- >
417
- Ping Backend
418
- </button>
419
- <button
420
- onClick={lambda e: any -> None { handleCreateSampleTodo();}}
421
- style={{
422
- "padding": "0.5rem 1.2rem",
423
- "backgroundColor": "#10b981",
424
- "color": "white",
425
- "border": "none",
426
- "borderRadius": "6px",
427
- "cursor": "pointer"
428
- }}
429
- >
430
- Create Sample Todo
431
- </button>
432
- {pingResult
433
- and (
434
- <span style={{"marginLeft": "0.5rem", "color": "#374151"}}>
435
- Result:
436
- {" "}
437
- <code>
438
- {pingResult}
439
- </code>
440
- </span>
441
- )}
442
- {serverMessage
443
- and (
444
- <p style={{"marginTop": "0.75rem", "color": "#374151"}}>
445
- Message:
446
- {" "}
447
- <code>
448
- {serverMessage}
449
- </code>
450
- </p>
451
- )}
452
- {lastTodoMessage
453
- and (
454
- <p style={{"marginTop": "0.5rem", "color": "#111827"}}>
455
- {lastTodoMessage}
456
- </p>
457
- )}
458
- </div>
459
- <div style={{"marginTop": "2rem"}}>
460
- <h3>
461
- Web Worker
462
- </h3>
463
- <p>
464
- This demonstrates how to communicate with a
465
- {" "}
466
- <strong>
467
- Python backend worker
468
- </strong>
469
- {" "}
470
- using Web Workers for asynchronous processing.
471
- </p>
472
- <p
473
- style={{
474
- "fontSize": "0.9rem",
475
- "color": "#666",
476
- "marginTop": "0.5rem"
477
- }}
478
- >
479
- File:
480
- {" "}
481
- <code>
482
- worker.py
483
- </code>
484
- {" "}
485
- — Runs in a separate thread to avoid blocking the UI.
486
- </p>
487
- <button
488
- onClick={lambda -> None { handleClick();}}
489
- style={{
490
- "padding": "0.5rem 1.2rem",
491
- "marginRight": "0.75rem",
492
- "backgroundColor": "#d73bf6ff",
493
- "color": "white",
494
- "border": "none",
495
- "borderRadius": "6px",
496
- "cursor": "pointer"
497
- }}
498
- >
499
- Call Python Worker
500
- </button>
501
- {message
502
- && (
503
- <p style={{marginTop: "1rem", fontWeight: "bold"}}>
504
- {message}
505
- </p>
506
- )}
507
- </div>
157
+ <div style={{"fontFamily": "system-ui, -apple-system, sans-serif"}}>
158
+ {children}
508
159
  </div>;
509
160
  }
510
-
511
- def:pub app -> any {
512
- return
513
- <Router>
514
- <div style={{"fontFamily": "system-ui, -apple-system, sans-serif"}}>
515
- <Navigation />
516
- <div
517
- style={{
518
- "maxWidth": "960px",
519
- "margin": "0 auto",
520
- "padding": "0 1rem 3rem 1rem"
521
- }}
522
- >
523
- <Routes>
524
- <Route path="/" element={<HomePage />} />
525
- <Route path="/login" element={<LoginPage />} />
526
- <Route path="/signup" element={<SignupPage />} />
527
- <Route path="/nested" element={<NestedImportsDemo />} />
528
- <Route path="/features-test" element={<FeaturesTest />} />
529
- <Route path="/landing" element={<LandingPage />} />
530
- <Route
531
- path="/budget-planner"
532
- element={<BudgetProvider>
533
- <BudgetPlanner />
534
- </BudgetProvider>}
535
- />
536
- <Route path="*" element={<NotFound />} />
537
- </Routes>
538
- </div>
539
- </div>
540
- </Router>;
541
- }
542
161
  }