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.
- jac_client/examples/all-in-one/components/Header.jac +1 -1
- jac_client/examples/all-in-one/components/ProfitOverview.jac +1 -1
- jac_client/examples/all-in-one/components/Summary.jac +1 -1
- jac_client/examples/all-in-one/components/TransactionList.jac +2 -2
- jac_client/examples/all-in-one/components/navigation.jac +3 -9
- jac_client/examples/all-in-one/context/BudgetContext.jac +1 -1
- jac_client/examples/all-in-one/main.jac +5 -386
- jac_client/examples/all-in-one/pages/(auth)/index.jac +299 -0
- jac_client/examples/all-in-one/pages/{nestedDemo.jac → (auth)/nested.jac} +3 -13
- jac_client/examples/all-in-one/pages/{loginPage.jac → (public)/login.jac} +1 -1
- jac_client/examples/all-in-one/pages/{signupPage.jac → (public)/signup.jac} +1 -1
- jac_client/examples/all-in-one/pages/{notFound.jac → [...notFound].jac} +2 -1
- jac_client/examples/all-in-one/pages/budget.jac +11 -0
- jac_client/examples/all-in-one/pages/budget_planner_ui.cl.jac +1 -1
- jac_client/examples/all-in-one/pages/features.jac +8 -0
- jac_client/examples/all-in-one/pages/features_test_ui.cl.jac +7 -7
- jac_client/examples/all-in-one/pages/{LandingPage.jac → landing.jac} +4 -9
- jac_client/examples/all-in-one/pages/layout.jac +20 -0
- jac_client/examples/nested-folders/nested-advance/src/ButtonRoot.jac +1 -1
- jac_client/examples/nested-folders/nested-advance/src/level1/ButtonSecondL.jac +1 -1
- jac_client/examples/nested-folders/nested-advance/src/level1/level2/ButtonThirdL.jac +1 -1
- jac_client/plugin/cli.jac +3 -3
- jac_client/plugin/client_runtime.cl.jac +7 -4
- jac_client/plugin/impl/client_runtime.impl.jac +29 -7
- jac_client/plugin/plugin_config.jac +4 -11
- jac_client/plugin/src/compiler.jac +19 -1
- jac_client/plugin/src/config_loader.jac +1 -0
- jac_client/plugin/src/impl/compiler.impl.jac +232 -62
- jac_client/plugin/src/impl/config_loader.impl.jac +8 -0
- jac_client/plugin/src/impl/package_installer.impl.jac +3 -2
- jac_client/plugin/src/impl/route_scanner.impl.jac +201 -0
- jac_client/plugin/src/impl/vite_bundler.impl.jac +54 -15
- jac_client/plugin/src/route_scanner.jac +44 -0
- jac_client/plugin/src/targets/desktop/sidecar/main.py +42 -23
- jac_client/plugin/src/targets/desktop_target.jac +4 -2
- jac_client/plugin/src/targets/impl/desktop_target.impl.jac +324 -112
- jac_client/plugin/src/vite_bundler.jac +18 -3
- jac_client/plugin/utils/impl/bun_installer.impl.jac +16 -19
- jac_client/plugin/utils/impl/client_deps.impl.jac +12 -16
- jac_client/templates/fullstack.jacpack +3 -2
- jac_client/tests/test_cli.py +74 -0
- jac_client/tests/test_desktop_api_url.py +854 -0
- jac_client/tests/test_e2e.py +31 -40
- jac_client/tests/test_it.py +209 -11
- {jac_client-0.2.12.dist-info → jac_client-0.2.14.dist-info}/METADATA +2 -2
- {jac_client-0.2.12.dist-info → jac_client-0.2.14.dist-info}/RECORD +49 -44
- jac_client/examples/all-in-one/pages/BudgetPlanner.jac +0 -140
- jac_client/examples/all-in-one/pages/FeaturesTest.jac +0 -157
- {jac_client-0.2.12.dist-info → jac_client-0.2.14.dist-info}/WHEEL +0 -0
- {jac_client-0.2.12.dist-info → jac_client-0.2.14.dist-info}/entry_points.txt +0 -0
- {jac_client-0.2.12.dist-info → jac_client-0.2.14.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
cl import from react { useEffect, useRef }
|
|
2
|
+
cl import from ...components.Card.tsx { Card }
|
|
3
|
+
sv import from ...main { ping_server, get_server_message, create_todo }
|
|
4
|
+
|
|
5
|
+
cl {
|
|
6
|
+
def:pub page -> JsxElement {
|
|
7
|
+
has count: int = 0,
|
|
8
|
+
pingResult: str = "",
|
|
9
|
+
serverMessage: str = "",
|
|
10
|
+
lastTodoMessage: str = "";
|
|
11
|
+
|
|
12
|
+
can with count entry {
|
|
13
|
+
console.log("Home count changed: ", count);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async def handlePing -> None {
|
|
17
|
+
result = root spawn ping_server();
|
|
18
|
+
if result.reports and result.reports.length > 0 {
|
|
19
|
+
pingResult = result.reports[0][0];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async def loadServerMessage -> None {
|
|
24
|
+
result = root spawn get_server_message();
|
|
25
|
+
if result.reports and result.reports.length > 0 {
|
|
26
|
+
serverMessage = result.reports[0][0];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async def handleCreateSampleTodo -> None {
|
|
31
|
+
result = root spawn create_todo(text="Sample todo from all-in-one app");
|
|
32
|
+
if result.reports and result.reports.length > 0 {
|
|
33
|
+
todo = result.reports[0][0];
|
|
34
|
+
lastTodoMessage = "Created Todo: " + todo.text;
|
|
35
|
+
console.log("Created Todo node:", todo);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async can with entry {
|
|
40
|
+
await loadServerMessage();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
workerRef = useRef(None);
|
|
44
|
+
has message: str = "";
|
|
45
|
+
|
|
46
|
+
useEffect(
|
|
47
|
+
lambda -> None { workerRef.current = Reflect.construct(
|
|
48
|
+
Worker, ["/workers/worker.js"]
|
|
49
|
+
);workerRef.current.onmessage = lambda event: any -> None { console.log(
|
|
50
|
+
"Message received from worker:", event.data
|
|
51
|
+
);message = event.data;};return (
|
|
52
|
+
lambda -> None { workerRef.current.terminate();}
|
|
53
|
+
); },
|
|
54
|
+
[]
|
|
55
|
+
);
|
|
56
|
+
handleClick = lambda -> None { workerRef.current.postMessage("");};
|
|
57
|
+
|
|
58
|
+
return
|
|
59
|
+
<div
|
|
60
|
+
style={{
|
|
61
|
+
"padding": "2rem",
|
|
62
|
+
"fontFamily": "system-ui, -apple-system, sans-serif"
|
|
63
|
+
}}
|
|
64
|
+
>
|
|
65
|
+
<h1>
|
|
66
|
+
🍔 Router + Styling + Assets Demo
|
|
67
|
+
</h1>
|
|
68
|
+
<p>
|
|
69
|
+
This home page combines
|
|
70
|
+
{" "}
|
|
71
|
+
<strong>
|
|
72
|
+
React Router,
|
|
73
|
+
</strong>
|
|
74
|
+
{" "}
|
|
75
|
+
<strong>
|
|
76
|
+
pure CSS styling,
|
|
77
|
+
</strong>
|
|
78
|
+
{" "}
|
|
79
|
+
<strong>
|
|
80
|
+
staticassets
|
|
81
|
+
</strong>
|
|
82
|
+
{" "}
|
|
83
|
+
and
|
|
84
|
+
{" "}
|
|
85
|
+
<strong>
|
|
86
|
+
nested folder imports
|
|
87
|
+
</strong>
|
|
88
|
+
</p>
|
|
89
|
+
<div className="container">
|
|
90
|
+
<h2
|
|
91
|
+
style={{
|
|
92
|
+
"color": "white",
|
|
93
|
+
"textShadow": "2px 2px 4px rgba(0,0,0,0.6)"
|
|
94
|
+
}}
|
|
95
|
+
>
|
|
96
|
+
CSS Background Image
|
|
97
|
+
</h2>
|
|
98
|
+
<p
|
|
99
|
+
style={{
|
|
100
|
+
"color": "white",
|
|
101
|
+
"maxWidth": "480px",
|
|
102
|
+
"textShadow": "1px 1px 3px rgba(0,0,0,0.7)"
|
|
103
|
+
}}
|
|
104
|
+
>
|
|
105
|
+
This section uses the burger image as a background via CSS, just like the
|
|
106
|
+
{" "}
|
|
107
|
+
<code>
|
|
108
|
+
asset-serving/css-with-image
|
|
109
|
+
</code>
|
|
110
|
+
{" "}
|
|
111
|
+
example.
|
|
112
|
+
</p>
|
|
113
|
+
</div>
|
|
114
|
+
<Card
|
|
115
|
+
title="TypeScript Card Component"
|
|
116
|
+
description="This card is built with TypeScript and demonstrates type-safe component usage in Jac"
|
|
117
|
+
variant="highlighted"
|
|
118
|
+
>
|
|
119
|
+
<p style={{"margin": "0.5rem 0", "color": "#374151"}}>
|
|
120
|
+
This is a TypeScript component imported and used in Jac code!
|
|
121
|
+
</p>
|
|
122
|
+
</Card>
|
|
123
|
+
<div className="card">
|
|
124
|
+
<h3>
|
|
125
|
+
Direct <img> asset
|
|
126
|
+
</h3>
|
|
127
|
+
<img
|
|
128
|
+
src="/static/assets/burger.png"
|
|
129
|
+
alt="Burger asset served by Jac"
|
|
130
|
+
className="burgerImage"
|
|
131
|
+
/>
|
|
132
|
+
<p style={{"marginTop": "0.75rem", "color": "#555"}}>
|
|
133
|
+
This image is served from the project
|
|
134
|
+
{" "}
|
|
135
|
+
<code>
|
|
136
|
+
assets/
|
|
137
|
+
</code>
|
|
138
|
+
{" "}
|
|
139
|
+
folder using the
|
|
140
|
+
{" "}
|
|
141
|
+
<code>
|
|
142
|
+
/static/assets/
|
|
143
|
+
</code>
|
|
144
|
+
{" "}
|
|
145
|
+
path.
|
|
146
|
+
</p>
|
|
147
|
+
</div>
|
|
148
|
+
<div style={{"marginTop": "2rem"}}>
|
|
149
|
+
<h3>
|
|
150
|
+
Counter with pure CSS classes
|
|
151
|
+
</h3>
|
|
152
|
+
<p>
|
|
153
|
+
You've clicked the burger
|
|
154
|
+
{" "}
|
|
155
|
+
<strong>
|
|
156
|
+
{count}
|
|
157
|
+
</strong>
|
|
158
|
+
{" "}
|
|
159
|
+
times.
|
|
160
|
+
</p>
|
|
161
|
+
<button
|
|
162
|
+
onClick={lambda e: any -> None { count = count + 1;}}
|
|
163
|
+
style={{
|
|
164
|
+
"padding": "0.6rem 1.4rem",
|
|
165
|
+
"fontSize": "1rem",
|
|
166
|
+
"backgroundColor": "#ff6b35",
|
|
167
|
+
"color": "white",
|
|
168
|
+
"border": "none",
|
|
169
|
+
"borderRadius": "6px",
|
|
170
|
+
"cursor": "pointer",
|
|
171
|
+
"boxShadow": "0 2px 4px rgba(0,0,0,0.2)"
|
|
172
|
+
}}
|
|
173
|
+
>
|
|
174
|
+
Click the Burger! 🍔
|
|
175
|
+
</button>
|
|
176
|
+
</div>
|
|
177
|
+
<div style={{"marginTop": "2rem"}}>
|
|
178
|
+
<h3>
|
|
179
|
+
Backend Walkers
|
|
180
|
+
</h3>
|
|
181
|
+
<p>
|
|
182
|
+
Basic example walkers:
|
|
183
|
+
{" "}
|
|
184
|
+
<code>
|
|
185
|
+
ping_server
|
|
186
|
+
</code>
|
|
187
|
+
{" "}
|
|
188
|
+
and
|
|
189
|
+
{" "}
|
|
190
|
+
<code>
|
|
191
|
+
get_server_message
|
|
192
|
+
</code>
|
|
193
|
+
</p>
|
|
194
|
+
<button
|
|
195
|
+
onClick={lambda e: any -> None { handlePing();}}
|
|
196
|
+
style={{
|
|
197
|
+
"padding": "0.5rem 1.2rem",
|
|
198
|
+
"marginRight": "0.75rem",
|
|
199
|
+
"backgroundColor": "#3b82f6",
|
|
200
|
+
"color": "white",
|
|
201
|
+
"border": "none",
|
|
202
|
+
"borderRadius": "6px",
|
|
203
|
+
"cursor": "pointer"
|
|
204
|
+
}}
|
|
205
|
+
>
|
|
206
|
+
Ping Backend
|
|
207
|
+
</button>
|
|
208
|
+
<button
|
|
209
|
+
onClick={lambda e: any -> None { handleCreateSampleTodo();}}
|
|
210
|
+
style={{
|
|
211
|
+
"padding": "0.5rem 1.2rem",
|
|
212
|
+
"backgroundColor": "#10b981",
|
|
213
|
+
"color": "white",
|
|
214
|
+
"border": "none",
|
|
215
|
+
"borderRadius": "6px",
|
|
216
|
+
"cursor": "pointer"
|
|
217
|
+
}}
|
|
218
|
+
>
|
|
219
|
+
Create Sample Todo
|
|
220
|
+
</button>
|
|
221
|
+
{pingResult
|
|
222
|
+
and (
|
|
223
|
+
<span style={{"marginLeft": "0.5rem", "color": "#374151"}}>
|
|
224
|
+
Result:
|
|
225
|
+
{" "}
|
|
226
|
+
<code>
|
|
227
|
+
{pingResult}
|
|
228
|
+
</code>
|
|
229
|
+
</span>
|
|
230
|
+
)}
|
|
231
|
+
{serverMessage
|
|
232
|
+
and (
|
|
233
|
+
<p style={{"marginTop": "0.75rem", "color": "#374151"}}>
|
|
234
|
+
Message:
|
|
235
|
+
{" "}
|
|
236
|
+
<code>
|
|
237
|
+
{serverMessage}
|
|
238
|
+
</code>
|
|
239
|
+
</p>
|
|
240
|
+
)}
|
|
241
|
+
{lastTodoMessage
|
|
242
|
+
and (
|
|
243
|
+
<p style={{"marginTop": "0.5rem", "color": "#111827"}}>
|
|
244
|
+
{lastTodoMessage}
|
|
245
|
+
</p>
|
|
246
|
+
)}
|
|
247
|
+
</div>
|
|
248
|
+
<div style={{"marginTop": "2rem"}}>
|
|
249
|
+
<h3>
|
|
250
|
+
Web Worker
|
|
251
|
+
</h3>
|
|
252
|
+
<p>
|
|
253
|
+
This demonstrates how to communicate with a
|
|
254
|
+
{" "}
|
|
255
|
+
<strong>
|
|
256
|
+
Python backend worker
|
|
257
|
+
</strong>
|
|
258
|
+
{" "}
|
|
259
|
+
using Web Workers for asynchronous processing.
|
|
260
|
+
</p>
|
|
261
|
+
<p
|
|
262
|
+
style={{
|
|
263
|
+
"fontSize": "0.9rem",
|
|
264
|
+
"color": "#666",
|
|
265
|
+
"marginTop": "0.5rem"
|
|
266
|
+
}}
|
|
267
|
+
>
|
|
268
|
+
File:
|
|
269
|
+
{" "}
|
|
270
|
+
<code>
|
|
271
|
+
worker.py
|
|
272
|
+
</code>
|
|
273
|
+
{" "}
|
|
274
|
+
— Runs in a separate thread to avoid blocking the UI.
|
|
275
|
+
</p>
|
|
276
|
+
<button
|
|
277
|
+
onClick={lambda -> None { handleClick();}}
|
|
278
|
+
style={{
|
|
279
|
+
"padding": "0.5rem 1.2rem",
|
|
280
|
+
"marginRight": "0.75rem",
|
|
281
|
+
"backgroundColor": "#d73bf6ff",
|
|
282
|
+
"color": "white",
|
|
283
|
+
"border": "none",
|
|
284
|
+
"borderRadius": "6px",
|
|
285
|
+
"cursor": "pointer"
|
|
286
|
+
}}
|
|
287
|
+
>
|
|
288
|
+
Call Python Worker
|
|
289
|
+
</button>
|
|
290
|
+
{message
|
|
291
|
+
&& (
|
|
292
|
+
<p style={{marginTop: "1rem", fontWeight: "bold"}}>
|
|
293
|
+
{message}
|
|
294
|
+
</p>
|
|
295
|
+
)}
|
|
296
|
+
</div>
|
|
297
|
+
</div>;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
@@ -1,18 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
cl import from
|
|
3
|
-
CustomButton
|
|
4
|
-
}
|
|
5
|
-
cl import from ..button { CustomButtonRoot }
|
|
6
|
-
cl import from "@jac/runtime" { Navigate, jacIsLoggedIn }
|
|
1
|
+
cl import from ...components.nestedDemo.CustomButton.tsx { CustomButton }
|
|
2
|
+
cl import from ...button { CustomButtonRoot }
|
|
7
3
|
|
|
8
4
|
cl {
|
|
9
|
-
def:pub
|
|
10
|
-
# Check if user is logged in, redirect if not
|
|
11
|
-
if not jacIsLoggedIn() {
|
|
12
|
-
return
|
|
13
|
-
<Navigate to="/login" />;
|
|
14
|
-
}
|
|
15
|
-
|
|
5
|
+
def:pub page -> JsxElement {
|
|
16
6
|
return
|
|
17
7
|
<div
|
|
18
8
|
style={{
|
|
@@ -12,7 +12,7 @@ cl import from ..components.CategoryFilter { CategoryFilter }
|
|
|
12
12
|
cl import from ..constants.categories { CATEGORY_COLORS }
|
|
13
13
|
|
|
14
14
|
# cl import from "..components.PieChart.tsx" { PieChart }
|
|
15
|
-
cl def:pub BudgetPlanner ->
|
|
15
|
+
cl def:pub BudgetPlanner -> JsxElement {
|
|
16
16
|
[filter, setFilter] = useState("ALL");
|
|
17
17
|
budget = useBudgetContext();
|
|
18
18
|
|
|
@@ -21,7 +21,7 @@ import from ..utils.helpers {
|
|
|
21
21
|
import from ..utils.formatters { formatCurrency }
|
|
22
22
|
|
|
23
23
|
# Import walkers from server module
|
|
24
|
-
sv import from
|
|
24
|
+
sv import from ..main {
|
|
25
25
|
create_test_data,
|
|
26
26
|
read_test_data,
|
|
27
27
|
update_test_data,
|
|
@@ -38,7 +38,7 @@ sv import from .FeaturesTest {
|
|
|
38
38
|
# Button component demonstrating props - NEW PATTERN: Direct parameters
|
|
39
39
|
def:pub TestButton(
|
|
40
40
|
text: str, onClick: any, variant: str
|
|
41
|
-
) ->
|
|
41
|
+
) -> JsxElement {
|
|
42
42
|
bg_color = "#3b82f6" if variant == "primary" else "#6b7280";
|
|
43
43
|
hover_color = "#2563eb" if variant == "primary" else "#4b5563";
|
|
44
44
|
|
|
@@ -66,7 +66,7 @@ def:pub TestButton(
|
|
|
66
66
|
# # Card component with props - NEW PATTERN: Direct parameters
|
|
67
67
|
def:pub TestCard(
|
|
68
68
|
title: str, children: any, color: str
|
|
69
|
-
) ->
|
|
69
|
+
) -> JsxElement {
|
|
70
70
|
return
|
|
71
71
|
<div
|
|
72
72
|
style={{
|
|
@@ -106,7 +106,7 @@ def:pub TestCard(
|
|
|
106
106
|
# Result display component - NEW PATTERN: Direct parameters
|
|
107
107
|
def:pub ResultDisplay(
|
|
108
108
|
data: any, label: str
|
|
109
|
-
) ->
|
|
109
|
+
) -> JsxElement {
|
|
110
110
|
if not data {
|
|
111
111
|
return
|
|
112
112
|
<div style={{"color": "#9ca3af", "fontStyle": "italic"}}>
|
|
@@ -146,7 +146,7 @@ def:pub ResultDisplay(
|
|
|
146
146
|
# ============================================================================
|
|
147
147
|
# MAIN PAGE COMPONENT
|
|
148
148
|
# ============================================================================
|
|
149
|
-
def:pub FeaturesTest ->
|
|
149
|
+
def:pub FeaturesTest -> JsxElement {
|
|
150
150
|
navigate = useNavigate();
|
|
151
151
|
|
|
152
152
|
# State management
|
|
@@ -408,7 +408,7 @@ def:pub FeaturesTest -> any {
|
|
|
408
408
|
No data yet. Create some!
|
|
409
409
|
</p>}
|
|
410
410
|
{testData.map(
|
|
411
|
-
lambda item: any ->
|
|
411
|
+
lambda item: any -> JsxElement { return
|
|
412
412
|
<div
|
|
413
413
|
key={item._jac_id}
|
|
414
414
|
style={{
|
|
@@ -480,7 +480,7 @@ def:pub FeaturesTest -> any {
|
|
|
480
480
|
}}
|
|
481
481
|
>
|
|
482
482
|
{Object.keys(string_demos).map(
|
|
483
|
-
lambda key: str ->
|
|
483
|
+
lambda key: str -> JsxElement { return
|
|
484
484
|
<div key={key} style={{"marginBottom": "5px"}}>
|
|
485
485
|
<span style={{"fontWeight": "600"}}>
|
|
486
486
|
{key}:
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
# Professional landing page with hero, features, and CTA sections
|
|
3
|
-
# Demonstrates: routing with Link, dark theme design, responsive layout
|
|
4
|
-
cl import from "@jac/runtime" {
|
|
5
|
-
Link,
|
|
6
|
-
}
|
|
1
|
+
cl import from "@jac/runtime" { Link }
|
|
7
2
|
|
|
8
3
|
cl {
|
|
9
|
-
def:pub
|
|
4
|
+
def:pub page -> JsxElement {
|
|
10
5
|
return
|
|
11
6
|
<div className="landing-container">
|
|
12
7
|
<section className="hero-section">
|
|
@@ -29,7 +24,7 @@ cl {
|
|
|
29
24
|
"justifyContent": "center"
|
|
30
25
|
}}
|
|
31
26
|
>
|
|
32
|
-
<Link to="/
|
|
27
|
+
<Link to="/budget">
|
|
33
28
|
<button className="cta-button">
|
|
34
29
|
Let's Plan
|
|
35
30
|
</button>
|
|
@@ -101,7 +96,7 @@ cl {
|
|
|
101
96
|
"justifyContent": "center"
|
|
102
97
|
}}
|
|
103
98
|
>
|
|
104
|
-
<Link to="/
|
|
99
|
+
<Link to="/budget">
|
|
105
100
|
<button className="cta-button">
|
|
106
101
|
Get Started Free
|
|
107
102
|
</button>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
cl import from "@jac/runtime" { Outlet }
|
|
2
|
+
cl import from ..components.navigation { Navigation }
|
|
3
|
+
|
|
4
|
+
cl {
|
|
5
|
+
def:pub layout -> JsxElement {
|
|
6
|
+
return
|
|
7
|
+
<>
|
|
8
|
+
<Navigation />
|
|
9
|
+
<div
|
|
10
|
+
style={{
|
|
11
|
+
"maxWidth": "960px",
|
|
12
|
+
"margin": "0 auto",
|
|
13
|
+
"padding": "0 1rem 3rem 1rem"
|
|
14
|
+
}}
|
|
15
|
+
>
|
|
16
|
+
<Outlet />
|
|
17
|
+
</div>
|
|
18
|
+
</>;
|
|
19
|
+
}
|
|
20
|
+
}
|
jac_client/plugin/cli.jac
CHANGED
|
@@ -426,15 +426,15 @@ def _handle_start_target(ctx: HookContext) -> None {
|
|
|
426
426
|
ctx.set_data("cancel_return_code", 1);
|
|
427
427
|
return;
|
|
428
428
|
}
|
|
429
|
-
# Check if --dev flag is set
|
|
430
429
|
dev_mode = ctx.get_arg("dev", False);
|
|
430
|
+
api_port = ctx.get_arg("port", 8000);
|
|
431
431
|
try {
|
|
432
432
|
if dev_mode {
|
|
433
433
|
# Desktop target with --dev: launch Tauri dev mode (hot reload)
|
|
434
|
-
target.dev(entry_path, project_dir);
|
|
434
|
+
target.dev(entry_path, project_dir, api_port=api_port);
|
|
435
435
|
} else {
|
|
436
436
|
# Desktop target without --dev: build web bundle and launch Tauri with built bundle
|
|
437
|
-
target.start(entry_path, project_dir);
|
|
437
|
+
target.start(entry_path, project_dir, api_port=api_port);
|
|
438
438
|
}
|
|
439
439
|
ctx.set_data("cancel_execution", True);
|
|
440
440
|
ctx.set_data("cancel_return_code", 0);
|
|
@@ -4,24 +4,25 @@ import from 'react' { * as React }
|
|
|
4
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
|
+
BrowserRouter as ReactRouterBrowserRouter,
|
|
8
8
|
Routes as ReactRouterRoutes,
|
|
9
9
|
Route as ReactRouterRoute,
|
|
10
10
|
Link as ReactRouterLink,
|
|
11
11
|
Navigate as ReactRouterNavigate,
|
|
12
|
+
Outlet as ReactRouterOutlet,
|
|
12
13
|
useNavigate as reactRouterUseNavigate,
|
|
13
14
|
useLocation as reactRouterUseLocation,
|
|
14
15
|
useParams as reactRouterUseParams
|
|
15
16
|
}
|
|
16
17
|
import from 'react-error-boundary' { ErrorBoundary }
|
|
17
18
|
|
|
18
|
-
def:pub __jacJsx(tag: any, props: dict = {}, children: any = []) ->
|
|
19
|
+
def:pub __jacJsx(tag: any, props: dict = {}, children: any = []) -> JsxElement;
|
|
19
20
|
|
|
20
21
|
# React hooks re-exported for auto-injection by `has` variables and `can with entry/exit` effects
|
|
21
22
|
glob:
|
|
22
23
|
pub useState = reactUseState,
|
|
23
24
|
useEffect = reactUseEffect,
|
|
24
|
-
Router =
|
|
25
|
+
Router = ReactRouterBrowserRouter,
|
|
25
26
|
Routes = ReactRouterRoutes,
|
|
26
27
|
Route = ReactRouterRoute,
|
|
27
28
|
Link = ReactRouterLink,
|
|
@@ -29,6 +30,7 @@ glob:
|
|
|
29
30
|
useNavigate = reactRouterUseNavigate,
|
|
30
31
|
useLocation = reactRouterUseLocation,
|
|
31
32
|
useParams = reactRouterUseParams,
|
|
33
|
+
Outlet = ReactRouterOutlet,
|
|
32
34
|
JacClientErrorBoundary = ErrorBoundary;
|
|
33
35
|
|
|
34
36
|
def:pub useRouter -> dict;
|
|
@@ -40,9 +42,10 @@ async def:pub jacSignup(username: str, password: str) -> dict;
|
|
|
40
42
|
async def:pub jacLogin(username: str, password: str) -> bool;
|
|
41
43
|
def:pub jacLogout -> None;
|
|
42
44
|
def:pub jacIsLoggedIn -> bool;
|
|
45
|
+
def:pub __getApiBaseUrl -> str;
|
|
43
46
|
def:pub __getLocalStorage(key: str) -> str;
|
|
44
47
|
def:pub __setLocalStorage(key: str, value: str) -> None;
|
|
45
48
|
def:pub __removeLocalStorage(key: str) -> None;
|
|
49
|
+
def:pub AuthGuard(redirect: str = "/login") -> any;
|
|
46
50
|
def:pub ErrorFallback(error: str, resetErrorBoundary: any) -> any;
|
|
47
51
|
def:pub errorOverlay(filePath: str, errors: str) -> any;
|
|
48
|
-
# React Router components
|