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.
- jac_client/examples/all-in-one/button.jac +4 -3
- jac_client/examples/all-in-one/components/CategoryFilter.jac +36 -24
- jac_client/examples/all-in-one/components/Header.jac +12 -8
- jac_client/examples/all-in-one/components/ProfitOverview.jac +49 -35
- jac_client/examples/all-in-one/components/Summary.jac +59 -36
- jac_client/examples/all-in-one/components/TransactionForm.jac +142 -112
- jac_client/examples/all-in-one/components/TransactionItem.jac +37 -30
- jac_client/examples/all-in-one/components/TransactionList.jac +33 -26
- jac_client/examples/all-in-one/components/button.jac +4 -3
- jac_client/examples/all-in-one/components/navigation.jac +111 -117
- jac_client/examples/all-in-one/constants/categories.jac +23 -24
- jac_client/examples/all-in-one/constants/clients.jac +7 -8
- jac_client/examples/all-in-one/context/BudgetContext.jac +9 -6
- jac_client/examples/all-in-one/hooks/useBudget.jac +18 -12
- jac_client/examples/all-in-one/hooks/useLocalStorage.jac +14 -13
- jac_client/examples/all-in-one/main.jac +340 -371
- jac_client/examples/all-in-one/pages/BudgetPlanner.jac +19 -12
- jac_client/examples/all-in-one/pages/FeaturesTest.jac +31 -15
- jac_client/examples/all-in-one/pages/LandingPage.jac +113 -90
- jac_client/examples/all-in-one/pages/budget_planner_ui.cl.jac +34 -39
- jac_client/examples/all-in-one/pages/features_test_ui.cl.jac +464 -352
- jac_client/examples/all-in-one/pages/loginPage.jac +114 -119
- jac_client/examples/all-in-one/pages/nestedDemo.jac +43 -50
- jac_client/examples/all-in-one/pages/notFound.jac +14 -15
- jac_client/examples/all-in-one/pages/signupPage.jac +113 -119
- jac_client/examples/all-in-one/utils/formatters.jac +5 -8
- jac_client/examples/asset-serving/css-with-image/main.jac +77 -73
- jac_client/examples/asset-serving/image-asset/main.jac +47 -46
- jac_client/examples/asset-serving/import-alias/main.jac +93 -95
- jac_client/examples/basic/main.jac +17 -15
- jac_client/examples/basic-auth/main.jac +246 -254
- jac_client/examples/basic-auth-with-router/main.jac +272 -285
- jac_client/examples/basic-full-stack/main.jac +245 -242
- jac_client/examples/css-styling/js-styling/main.jac +41 -62
- jac_client/examples/css-styling/material-ui/main.jac +90 -90
- jac_client/examples/css-styling/pure-css/main.jac +35 -44
- jac_client/examples/css-styling/sass-example/main.jac +35 -44
- jac_client/examples/css-styling/styled-components/main.jac +38 -47
- jac_client/examples/css-styling/tailwind-example/main.jac +54 -43
- jac_client/examples/full-stack-with-auth/main.jac +407 -433
- jac_client/examples/little-x/main.jac +306 -344
- jac_client/examples/little-x/src/submit-button.jac +15 -14
- jac_client/examples/nested-folders/nested-advance/main.jac +18 -27
- jac_client/examples/nested-folders/nested-advance/src/ButtonRoot.jac +4 -6
- jac_client/examples/nested-folders/nested-advance/src/level1/ButtonSecondL.jac +9 -13
- jac_client/examples/nested-folders/nested-advance/src/level1/Card.jac +29 -32
- jac_client/examples/nested-folders/nested-advance/src/level1/level2/ButtonThirdL.jac +12 -18
- jac_client/examples/nested-folders/nested-basic/main.jac +7 -5
- jac_client/examples/nested-folders/nested-basic/src/button.jac +4 -3
- jac_client/examples/nested-folders/nested-basic/src/components/button.jac +4 -3
- jac_client/examples/ts-support/main.jac +26 -26
- jac_client/examples/with-router/main.jac +186 -223
- jac_client/plugin/client_runtime.cl.jac +5 -3
- jac_client/plugin/impl/client_runtime.impl.jac +1 -1
- jac_client/plugin/plugin_config.jac +53 -99
- jac_client/plugin/src/__init__.jac +0 -2
- jac_client/plugin/src/compiler.jac +0 -1
- jac_client/plugin/src/impl/compiler.impl.jac +49 -17
- jac_client/plugin/src/impl/jac_to_js.impl.jac +5 -1
- jac_client/plugin/src/impl/package_installer.impl.jac +20 -20
- jac_client/plugin/src/impl/vite_bundler.impl.jac +146 -84
- jac_client/plugin/src/targets/impl/desktop_target.impl.jac +54 -41
- jac_client/plugin/utils/__init__.jac +3 -0
- jac_client/plugin/utils/bun_installer.jac +16 -0
- jac_client/plugin/utils/client_deps.jac +14 -0
- jac_client/plugin/utils/impl/bun_installer.impl.jac +99 -0
- jac_client/plugin/utils/impl/client_deps.impl.jac +73 -0
- jac_client/templates/client.jacpack +0 -4
- jac_client/templates/fullstack.jacpack +1 -5
- jac_client/tests/conftest.py +56 -41
- jac_client/tests/fixtures/spawn_test/app.jac +49 -52
- jac_client/tests/fixtures/with-ts/app.jac +27 -27
- jac_client/tests/test_cli.py +71 -6
- jac_client/tests/test_helpers.py +11 -18
- jac_client/tests/test_it.py +1 -1
- {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/METADATA +5 -5
- jac_client-0.2.12.dist-info/RECORD +115 -0
- {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/WHEEL +1 -1
- jac_client/plugin/src/babel_processor.jac +0 -18
- jac_client/plugin/src/impl/babel_processor.impl.jac +0 -89
- jac_client/plugin/utils/impl/node_installer.impl.jac +0 -249
- jac_client/plugin/utils/node_installer.jac +0 -41
- jac_client-0.2.10.dist-info/RECORD +0 -115
- {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/entry_points.txt +0 -0
- {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/top_level.txt +0 -0
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
# # Features Test Page - Client-side UI
|
|
2
2
|
# # Demonstrates: props, exports, cl files, TypeScript imports, string methods,
|
|
3
3
|
# # imports from JAC/JS/TS, spawning walkers from cl file
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import from "@jac/runtime" {
|
|
5
|
+
Link,
|
|
6
|
+
useNavigate
|
|
7
|
+
}
|
|
8
|
+
import from react { useState }
|
|
7
9
|
|
|
8
10
|
# # Import TypeScript component
|
|
9
11
|
# import from ..components.PieChart { PieChart }
|
|
10
12
|
|
|
11
13
|
# # Import JavaScript helpers
|
|
12
|
-
import from ..utils.helpers {
|
|
14
|
+
import from ..utils.helpers {
|
|
15
|
+
generateId,
|
|
16
|
+
calculatePercentage,
|
|
17
|
+
sumBy
|
|
18
|
+
}
|
|
13
19
|
|
|
14
20
|
# # Import from other JAC files
|
|
15
21
|
import from ..utils.formatters { formatCurrency }
|
|
@@ -29,12 +35,15 @@ sv import from .FeaturesTest {
|
|
|
29
35
|
# REUSABLE COMPONENTS WITH PROPS
|
|
30
36
|
# ============================================================================
|
|
31
37
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
# Button component demonstrating props - NEW PATTERN: Direct parameters
|
|
39
|
+
def:pub TestButton(
|
|
40
|
+
text: str, onClick: any, variant: str
|
|
41
|
+
) -> any {
|
|
42
|
+
bg_color = "#3b82f6" if variant == "primary" else "#6b7280";
|
|
43
|
+
hover_color = "#2563eb" if variant == "primary" else "#4b5563";
|
|
36
44
|
|
|
37
|
-
|
|
45
|
+
return
|
|
46
|
+
<button
|
|
38
47
|
onClick={onClick}
|
|
39
48
|
style={{
|
|
40
49
|
"padding": "10px 20px",
|
|
@@ -47,302 +56,334 @@ sv import from .FeaturesTest {
|
|
|
47
56
|
"fontWeight": "600",
|
|
48
57
|
"transition": "all 0.2s"
|
|
49
58
|
}}
|
|
50
|
-
onMouseOver={lambda e: any
|
|
51
|
-
|
|
52
|
-
}}
|
|
53
|
-
onMouseOut={lambda e: any -> None {
|
|
54
|
-
e.target.style.backgroundColor = bg_color;
|
|
55
|
-
}}
|
|
59
|
+
onMouseOver={lambda e: any -> None { e.target.style.backgroundColor = hover_color;}}
|
|
60
|
+
onMouseOut={lambda e: any -> None { e.target.style.backgroundColor = bg_color;}}
|
|
56
61
|
>
|
|
57
62
|
{text}
|
|
58
63
|
</button>;
|
|
59
|
-
|
|
64
|
+
}
|
|
60
65
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
}}
|
|
66
|
+
# # Card component with props - NEW PATTERN: Direct parameters
|
|
67
|
+
def:pub TestCard(
|
|
68
|
+
title: str, children: any, color: str
|
|
69
|
+
) -> any {
|
|
70
|
+
return
|
|
71
|
+
<div
|
|
72
|
+
style={{
|
|
73
|
+
"backgroundColor": "white",
|
|
74
|
+
"border": "1px solid #e5e7eb",
|
|
75
|
+
"borderRadius": "8px",
|
|
76
|
+
"padding": "20px",
|
|
77
|
+
"marginBottom": "20px",
|
|
78
|
+
"boxShadow": "0 1px 3px rgba(0,0,0,0.1)"
|
|
79
|
+
}}
|
|
80
|
+
>
|
|
81
|
+
<div
|
|
82
|
+
style={{
|
|
83
|
+
"backgroundColor": color,
|
|
84
|
+
"padding": "10px",
|
|
85
|
+
"borderRadius": "6px",
|
|
86
|
+
"marginBottom": "15px"
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
<h3
|
|
90
|
+
style={{
|
|
91
|
+
"margin": "0",
|
|
92
|
+
"fontSize": "18px",
|
|
93
|
+
"fontWeight": "600",
|
|
94
|
+
"color": "#1f2937"
|
|
95
|
+
}}
|
|
96
|
+
>
|
|
97
|
+
{title}
|
|
98
|
+
</h3>
|
|
99
|
+
</div>
|
|
100
|
+
<div>
|
|
101
|
+
{children}
|
|
83
102
|
</div>
|
|
84
|
-
<div>{children}</div>
|
|
85
103
|
</div>;
|
|
86
|
-
|
|
104
|
+
}
|
|
87
105
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
106
|
+
# Result display component - NEW PATTERN: Direct parameters
|
|
107
|
+
def:pub ResultDisplay(
|
|
108
|
+
data: any, label: str
|
|
109
|
+
) -> any {
|
|
110
|
+
if not data {
|
|
111
|
+
return
|
|
112
|
+
<div style={{"color": "#9ca3af", "fontStyle": "italic"}}>
|
|
92
113
|
No data to display
|
|
93
114
|
</div>;
|
|
94
|
-
|
|
115
|
+
}
|
|
95
116
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
117
|
+
return
|
|
118
|
+
<div
|
|
119
|
+
style={{
|
|
120
|
+
"backgroundColor": "#f9fafb",
|
|
121
|
+
"padding": "15px",
|
|
122
|
+
"borderRadius": "6px",
|
|
123
|
+
"border": "1px solid #e5e7eb"
|
|
124
|
+
}}
|
|
125
|
+
>
|
|
126
|
+
<strong style={{"color": "#374151"}}>
|
|
127
|
+
{label}:
|
|
128
|
+
</strong>
|
|
129
|
+
<pre
|
|
130
|
+
style={{
|
|
131
|
+
"marginTop": "10px",
|
|
132
|
+
"padding": "10px",
|
|
133
|
+
"backgroundColor": "#1f2937",
|
|
134
|
+
"color": "#10b981",
|
|
135
|
+
"borderRadius": "4px",
|
|
136
|
+
"overflow": "auto",
|
|
137
|
+
"fontSize": "12px",
|
|
138
|
+
"fontFamily": "monospace"
|
|
139
|
+
}}
|
|
140
|
+
>
|
|
113
141
|
{JSON.stringify(data, None, 2)}
|
|
114
142
|
</pre>
|
|
115
143
|
</div>;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
# ============================================================================
|
|
119
|
-
# MAIN PAGE COMPONENT
|
|
120
|
-
# ============================================================================
|
|
121
|
-
|
|
122
|
-
def:pub FeaturesTest() -> any {
|
|
123
|
-
navigate = useNavigate();
|
|
124
|
-
|
|
125
|
-
# State management
|
|
126
|
-
has testMessage: str = "";
|
|
127
|
-
has testData: list = [];
|
|
128
|
-
has stringInput: str = "Hello JAC World!";
|
|
129
|
-
has stringResult: any = None;
|
|
130
|
-
has numberList: str = "1,2,3,4,5";
|
|
131
|
-
has listResult: any = None;
|
|
132
|
-
has complexResult: any = None;
|
|
133
|
-
has loading: bool = false;
|
|
134
|
-
|
|
135
|
-
# Load test data on mount
|
|
136
|
-
useEffect(lambda -> None {
|
|
137
|
-
async def loadData() -> None {
|
|
138
|
-
try {
|
|
139
|
-
result = root spawn read_test_data();
|
|
140
|
-
testData = result.reports if result.reports[0] else [];
|
|
141
|
-
} except Exception as e {
|
|
142
|
-
console.log("Error loading data:", e);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
loadData();
|
|
146
|
-
}, []);
|
|
147
|
-
|
|
148
|
-
# ========================================================================
|
|
149
|
-
# EVENT HANDLERS - Demonstrating Walker Spawning from CL
|
|
150
|
-
# ========================================================================
|
|
151
|
-
|
|
152
|
-
# Create test data
|
|
153
|
-
async def handleCreate() -> None {
|
|
154
|
-
if not testMessage.trim() {
|
|
155
|
-
alert("Please enter a message");
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
144
|
+
}
|
|
158
145
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
146
|
+
# ============================================================================
|
|
147
|
+
# MAIN PAGE COMPONENT
|
|
148
|
+
# ============================================================================
|
|
149
|
+
def:pub FeaturesTest -> any {
|
|
150
|
+
navigate = useNavigate();
|
|
151
|
+
|
|
152
|
+
# State management
|
|
153
|
+
has testMessage: str = "",
|
|
154
|
+
testData: list = [],
|
|
155
|
+
stringInput: str = "Hello JAC World!",
|
|
156
|
+
stringResult: any = None,
|
|
157
|
+
numberList: str = "1,2,3,4,5",
|
|
158
|
+
listResult: any = None,
|
|
159
|
+
complexResult: any = None,
|
|
160
|
+
loading: bool = false;
|
|
161
|
+
|
|
162
|
+
# Load test data on mount
|
|
163
|
+
async can with entry {
|
|
164
|
+
try {
|
|
165
|
+
result = root spawn read_test_data();
|
|
166
|
+
testData = result.reports if result.reports[0] else [];
|
|
167
|
+
} except Exception as e {
|
|
168
|
+
console.log("Error loading data:", e);
|
|
171
169
|
}
|
|
170
|
+
}
|
|
172
171
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
if not new_msg {
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
172
|
+
# ========================================================================
|
|
173
|
+
# EVENT HANDLERS - Demonstrating Walker Spawning from CL
|
|
174
|
+
# ========================================================================
|
|
179
175
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
testData = result.reports if result.reports[0] else [];
|
|
186
|
-
alert("Data updated successfully!");
|
|
187
|
-
} except Exception as e {
|
|
188
|
-
console.error("Error updating data:", e);
|
|
189
|
-
alert("Error updating data: " + e.toString());
|
|
190
|
-
}
|
|
191
|
-
loading = false;
|
|
176
|
+
# Create test data
|
|
177
|
+
async def handleCreate -> None {
|
|
178
|
+
if not testMessage.trim() {
|
|
179
|
+
alert("Please enter a message");
|
|
180
|
+
return;
|
|
192
181
|
}
|
|
193
182
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
testData = testData.filter(lambda item: any -> bool {
|
|
205
|
-
return item._jac_id != item_id;
|
|
206
|
-
});
|
|
207
|
-
alert("Data deleted successfully!");
|
|
208
|
-
} except Exception as e {
|
|
209
|
-
console.error("Error deleting data:", e);
|
|
210
|
-
alert("Error deleting data: " + e.toString());
|
|
211
|
-
}
|
|
212
|
-
loading = false;
|
|
183
|
+
loading = true;
|
|
184
|
+
try {
|
|
185
|
+
response = root spawn create_test_data(message=testMessage.trim());
|
|
186
|
+
new_item = response.reports[0][0];
|
|
187
|
+
testData = testData.concat([new_item]);
|
|
188
|
+
testMessage = "";
|
|
189
|
+
alert("Data created successfully!");
|
|
190
|
+
} except Exception as e {
|
|
191
|
+
console.error("Error creating data:", e);
|
|
192
|
+
alert("Error creating data: " + e.toString());
|
|
213
193
|
}
|
|
194
|
+
loading = false;
|
|
195
|
+
}
|
|
214
196
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
result = response.reports[0];
|
|
221
|
-
stringResult = result;
|
|
222
|
-
} except Exception as e {
|
|
223
|
-
console.error("Error testing strings:", e);
|
|
224
|
-
alert("Error testing strings: " + e.toString());
|
|
225
|
-
}
|
|
226
|
-
loading = false;
|
|
197
|
+
# Update test data
|
|
198
|
+
async def handleUpdate(item_id: any) -> None {
|
|
199
|
+
new_msg = prompt("Enter new message:");
|
|
200
|
+
if not new_msg {
|
|
201
|
+
return;
|
|
227
202
|
}
|
|
228
203
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
response = root spawn test_list_operations(numbers=numbers);
|
|
241
|
-
result = response.reports[0];
|
|
242
|
-
listResult = result;
|
|
243
|
-
} except Exception as e {
|
|
244
|
-
console.error("Error testing lists:", e);
|
|
245
|
-
alert("Error testing lists: " + e.toString());
|
|
246
|
-
}
|
|
247
|
-
loading = false;
|
|
204
|
+
loading = true;
|
|
205
|
+
try {
|
|
206
|
+
item_id spawn update_test_data(new_message=new_msg);
|
|
207
|
+
# Reload data
|
|
208
|
+
result = root spawn read_test_data();
|
|
209
|
+
testData = result.reports if result.reports[0] else [];
|
|
210
|
+
alert("Data updated successfully!");
|
|
211
|
+
} except Exception as e {
|
|
212
|
+
console.error("Error updating data:", e);
|
|
213
|
+
alert("Error updating data: " + e.toString());
|
|
248
214
|
}
|
|
215
|
+
loading = false;
|
|
216
|
+
}
|
|
249
217
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
# Generate sample data using JS helper
|
|
255
|
-
sample_items = [
|
|
256
|
-
{"id": generateId(), "name": "apple", "value": 10},
|
|
257
|
-
{"id": generateId(), "name": "banana", "value": 20},
|
|
258
|
-
{"id": generateId(), "name": "cherry", "value": 30}
|
|
259
|
-
];
|
|
260
|
-
|
|
261
|
-
response = root spawn process_complex_data(items=sample_items);
|
|
262
|
-
result = response.reports[0];
|
|
263
|
-
complexResult = result;
|
|
264
|
-
} except Exception as e {
|
|
265
|
-
console.error("Error processing complex data:", e);
|
|
266
|
-
alert("Error processing complex data: " + e.toString());
|
|
267
|
-
}
|
|
268
|
-
loading = false;
|
|
218
|
+
# Delete test data
|
|
219
|
+
async def handleDelete(item_id: any) -> None {
|
|
220
|
+
if not confirm("Are you sure you want to delete this item?") {
|
|
221
|
+
return;
|
|
269
222
|
}
|
|
270
223
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
"
|
|
279
|
-
|
|
280
|
-
"
|
|
281
|
-
|
|
224
|
+
loading = true;
|
|
225
|
+
try {
|
|
226
|
+
item_id spawn delete_test_data();
|
|
227
|
+
# Remove from local state
|
|
228
|
+
testData = testData.filter(
|
|
229
|
+
lambda item: any -> bool { return item._jac_id != item_id; }
|
|
230
|
+
);
|
|
231
|
+
alert("Data deleted successfully!");
|
|
232
|
+
} except Exception as e {
|
|
233
|
+
console.error("Error deleting data:", e);
|
|
234
|
+
alert("Error deleting data: " + e.toString());
|
|
235
|
+
}
|
|
236
|
+
loading = false;
|
|
237
|
+
}
|
|
282
238
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
239
|
+
# Test string methods via walker
|
|
240
|
+
async def handleStringTest -> None {
|
|
241
|
+
loading = true;
|
|
242
|
+
try {
|
|
243
|
+
response = root spawn test_string_methods(input_text=stringInput);
|
|
244
|
+
result = response.reports[0];
|
|
245
|
+
stringResult = result;
|
|
246
|
+
} except Exception as e {
|
|
247
|
+
console.error("Error testing strings:", e);
|
|
248
|
+
alert("Error testing strings: " + e.toString());
|
|
249
|
+
}
|
|
250
|
+
loading = false;
|
|
251
|
+
}
|
|
290
252
|
|
|
291
|
-
|
|
292
|
-
|
|
253
|
+
# Test list operations via walker
|
|
254
|
+
async def handleListTest -> None {
|
|
255
|
+
loading = true;
|
|
256
|
+
try {
|
|
257
|
+
# Parse number list
|
|
258
|
+
numbers = numberList.split(",").map(
|
|
259
|
+
lambda x: str -> int { return parseInt(x.trim()); }
|
|
260
|
+
).filter(
|
|
261
|
+
lambda x: any -> bool { return not isNaN(x); }
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
response = root spawn test_list_operations(numbers=numbers);
|
|
265
|
+
result = response.reports[0];
|
|
266
|
+
listResult = result;
|
|
267
|
+
} except Exception as e {
|
|
268
|
+
console.error("Error testing lists:", e);
|
|
269
|
+
alert("Error testing lists: " + e.toString());
|
|
270
|
+
}
|
|
271
|
+
loading = false;
|
|
272
|
+
}
|
|
293
273
|
|
|
274
|
+
# Test complex data processing
|
|
275
|
+
async def handleComplexTest -> None {
|
|
276
|
+
loading = true;
|
|
277
|
+
try {
|
|
278
|
+
# Generate sample data using JS helper
|
|
279
|
+
sample_items = [
|
|
280
|
+
{"id": generateId(), "name": "apple", "value": 10},
|
|
281
|
+
{"id": generateId(), "name": "banana", "value": 20},
|
|
282
|
+
{"id": generateId(), "name": "cherry", "value": 30}
|
|
283
|
+
];
|
|
284
|
+
|
|
285
|
+
response = root spawn process_complex_data(items=sample_items);
|
|
286
|
+
result = response.reports[0];
|
|
287
|
+
complexResult = result;
|
|
288
|
+
} except Exception as e {
|
|
289
|
+
console.error("Error processing complex data:", e);
|
|
290
|
+
alert("Error processing complex data: " + e.toString());
|
|
291
|
+
}
|
|
292
|
+
loading = false;
|
|
293
|
+
}
|
|
294
294
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
295
|
+
# ========================================================================
|
|
296
|
+
# DEMONSTRATION OF STRING METHODS (CLIENT-SIDE)
|
|
297
|
+
# ========================================================================
|
|
298
|
+
demo_text = "JAC Language Features";
|
|
299
|
+
string_demos = {
|
|
300
|
+
"Original": demo_text,
|
|
301
|
+
"Uppercase": demo_text.toUpperCase(),
|
|
302
|
+
"Lowercase": demo_text.toLowerCase(),
|
|
303
|
+
"Length": demo_text.length.toString(),
|
|
304
|
+
"Split by space": demo_text.split(" ").join(", ")
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
# Demo chart data for TypeScript component
|
|
308
|
+
chart_data = [
|
|
309
|
+
{"name": "Walker Tests", "value": 5},
|
|
310
|
+
{"name": "String Methods", "value": 8},
|
|
311
|
+
{"name": "List Operations", "value": 7},
|
|
312
|
+
{"name": "Components", "value": 4}
|
|
313
|
+
];
|
|
314
|
+
|
|
315
|
+
# Calculate total using JS helper
|
|
316
|
+
total_tests = sumBy(chart_data, "value");
|
|
317
|
+
|
|
318
|
+
# ========================================================================
|
|
319
|
+
# RENDER
|
|
320
|
+
# ========================================================================
|
|
321
|
+
return
|
|
322
|
+
<div
|
|
323
|
+
style={{
|
|
324
|
+
"maxWidth": "1200px",
|
|
325
|
+
"margin": "0 auto",
|
|
326
|
+
"padding": "20px",
|
|
327
|
+
"fontFamily": "system-ui, -apple-system, sans-serif"
|
|
328
|
+
}}
|
|
329
|
+
>
|
|
304
330
|
# Header
|
|
305
|
-
<div
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
331
|
+
<div
|
|
332
|
+
style={{
|
|
333
|
+
"display": "flex",
|
|
334
|
+
"justifyContent": "space-between",
|
|
335
|
+
"alignItems": "center",
|
|
336
|
+
"marginBottom": "30px"
|
|
337
|
+
}}
|
|
338
|
+
>
|
|
311
339
|
<h1 style={{"color": "#1f2937", "margin": "0"}}>
|
|
312
340
|
JAC Features Test Suite
|
|
313
341
|
</h1>
|
|
314
342
|
<Link to="/">
|
|
315
|
-
<TestButton
|
|
343
|
+
<TestButton
|
|
344
|
+
text="← Back Home"
|
|
345
|
+
onClick={lambda -> None { }}
|
|
346
|
+
variant="secondary"
|
|
347
|
+
/>
|
|
316
348
|
</Link>
|
|
317
349
|
</div>
|
|
318
|
-
|
|
319
350
|
# Loading indicator
|
|
320
|
-
{loading
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
351
|
+
{loading
|
|
352
|
+
and <div
|
|
353
|
+
style={{
|
|
354
|
+
"position": "fixed",
|
|
355
|
+
"top": "20px",
|
|
356
|
+
"right": "20px",
|
|
357
|
+
"backgroundColor": "#3b82f6",
|
|
358
|
+
"color": "white",
|
|
359
|
+
"padding": "10px 20px",
|
|
360
|
+
"borderRadius": "6px",
|
|
361
|
+
"boxShadow": "0 4px 6px rgba(0,0,0,0.2)",
|
|
362
|
+
"zIndex": "1000"
|
|
363
|
+
}}
|
|
364
|
+
>
|
|
331
365
|
Processing...
|
|
332
366
|
</div>}
|
|
333
|
-
|
|
334
367
|
# Section 1: Walker CRUD Operations
|
|
335
|
-
<TestCard
|
|
368
|
+
<TestCard
|
|
369
|
+
title="1. Walker CRUD Operations (Spawn from CL)"
|
|
370
|
+
color="#dbeafe"
|
|
371
|
+
>
|
|
336
372
|
<div style={{"marginBottom": "15px"}}>
|
|
337
373
|
<p style={{"color": "#4b5563", "marginBottom": "10px"}}>
|
|
338
374
|
Test creating, reading, updating, and deleting data using walkers spawned from client code.
|
|
339
375
|
</p>
|
|
340
|
-
|
|
341
|
-
|
|
376
|
+
<div
|
|
377
|
+
style={{
|
|
378
|
+
"display": "flex",
|
|
379
|
+
"gap": "10px",
|
|
380
|
+
"marginBottom": "15px"
|
|
381
|
+
}}
|
|
382
|
+
>
|
|
342
383
|
<input
|
|
343
384
|
type="text"
|
|
344
385
|
value={testMessage}
|
|
345
|
-
onChange={lambda e: any
|
|
386
|
+
onChange={lambda e: any -> None { testMessage = e.target.value;}}
|
|
346
387
|
placeholder="Enter test message..."
|
|
347
388
|
style={{
|
|
348
389
|
"flex": "1",
|
|
@@ -354,87 +395,117 @@ sv import from .FeaturesTest {
|
|
|
354
395
|
/>
|
|
355
396
|
<TestButton
|
|
356
397
|
text="Create"
|
|
357
|
-
onClick={lambda -> None { handleCreate();
|
|
398
|
+
onClick={lambda -> None { handleCreate();}}
|
|
358
399
|
variant="primary"
|
|
359
400
|
/>
|
|
360
401
|
</div>
|
|
361
|
-
|
|
362
402
|
<div style={{"marginTop": "20px"}}>
|
|
363
|
-
<strong style={{"color": "#374151"}}>
|
|
364
|
-
|
|
403
|
+
<strong style={{"color": "#374151"}}>
|
|
404
|
+
Stored Data ({testData.length}items):
|
|
405
|
+
</strong>
|
|
406
|
+
{testData.length == 0
|
|
407
|
+
and <p style={{"color": "#9ca3af", "fontStyle": "italic"}}>
|
|
365
408
|
No data yet. Create some!
|
|
366
409
|
</p>}
|
|
367
|
-
{testData.map(
|
|
368
|
-
return
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
<div
|
|
382
|
-
|
|
410
|
+
{testData.map(
|
|
411
|
+
lambda item: any -> any { return
|
|
412
|
+
<div
|
|
413
|
+
key={item._jac_id}
|
|
414
|
+
style={{
|
|
415
|
+
"backgroundColor": "#f9fafb",
|
|
416
|
+
"padding": "12px",
|
|
417
|
+
"borderRadius": "6px",
|
|
418
|
+
"marginTop": "8px",
|
|
419
|
+
"display": "flex",
|
|
420
|
+
"justifyContent": "space-between",
|
|
421
|
+
"alignItems": "center"
|
|
422
|
+
}}
|
|
423
|
+
>
|
|
424
|
+
<div>
|
|
425
|
+
<div
|
|
426
|
+
style={{
|
|
427
|
+
"fontWeight": "600",
|
|
428
|
+
"color": "#1f2937"
|
|
429
|
+
}}
|
|
430
|
+
>
|
|
431
|
+
{item.message}
|
|
432
|
+
</div>
|
|
433
|
+
<div
|
|
434
|
+
style={{
|
|
435
|
+
"fontSize": "12px",
|
|
436
|
+
"color": "#6b7280"
|
|
437
|
+
}}
|
|
438
|
+
>
|
|
439
|
+
Count: {item.count}| Created: {item.created_at}
|
|
440
|
+
</div>
|
|
383
441
|
</div>
|
|
384
|
-
<div style={{"
|
|
385
|
-
|
|
442
|
+
<div style={{"display": "flex", "gap": "8px"}}>
|
|
443
|
+
<TestButton
|
|
444
|
+
text="Edit"
|
|
445
|
+
onClick={lambda -> None { handleUpdate(
|
|
446
|
+
item._jac_id
|
|
447
|
+
);}}
|
|
448
|
+
variant="secondary"
|
|
449
|
+
/>
|
|
450
|
+
<TestButton
|
|
451
|
+
text="Delete"
|
|
452
|
+
onClick={lambda -> None { handleDelete(
|
|
453
|
+
item._jac_id
|
|
454
|
+
);}}
|
|
455
|
+
variant="secondary"
|
|
456
|
+
/>
|
|
386
457
|
</div>
|
|
387
|
-
</div
|
|
388
|
-
|
|
389
|
-
<TestButton
|
|
390
|
-
text="Edit"
|
|
391
|
-
onClick={lambda -> None { handleUpdate(item._jac_id); }}
|
|
392
|
-
variant="secondary"
|
|
393
|
-
/>
|
|
394
|
-
<TestButton
|
|
395
|
-
text="Delete"
|
|
396
|
-
onClick={lambda -> None { handleDelete(item._jac_id); }}
|
|
397
|
-
variant="secondary"
|
|
398
|
-
/>
|
|
399
|
-
</div>
|
|
400
|
-
</div>;
|
|
401
|
-
})}
|
|
458
|
+
</div>; }
|
|
459
|
+
)}
|
|
402
460
|
</div>
|
|
403
461
|
</div>
|
|
404
462
|
</TestCard>
|
|
405
|
-
|
|
406
463
|
# # Section 2: String Methods
|
|
407
464
|
<TestCard title="2. String Methods (Client & Walker)" color="#fce7f3">
|
|
408
465
|
<div>
|
|
409
466
|
<p style={{"color": "#4b5563", "marginBottom": "10px"}}>
|
|
410
467
|
Client-side string manipulation and walker-based string processing.
|
|
411
468
|
</p>
|
|
412
|
-
|
|
413
469
|
# Client-side demo
|
|
414
470
|
<div style={{"marginBottom": "20px"}}>
|
|
415
|
-
<strong style={{"color": "#374151"}}>
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
471
|
+
<strong style={{"color": "#374151"}}>
|
|
472
|
+
Client-side String Demo:
|
|
473
|
+
</strong>
|
|
474
|
+
<div
|
|
475
|
+
style={{
|
|
476
|
+
"backgroundColor": "#fef3c7",
|
|
477
|
+
"padding": "10px",
|
|
478
|
+
"borderRadius": "6px",
|
|
479
|
+
"marginTop": "8px"
|
|
480
|
+
}}
|
|
481
|
+
>
|
|
482
|
+
{Object.keys(string_demos).map(
|
|
483
|
+
lambda key: str -> any { return
|
|
484
|
+
<div key={key} style={{"marginBottom": "5px"}}>
|
|
485
|
+
<span style={{"fontWeight": "600"}}>
|
|
486
|
+
{key}:
|
|
487
|
+
</span>
|
|
488
|
+
{string_demos[key]}
|
|
489
|
+
</div>; }
|
|
490
|
+
)}
|
|
427
491
|
</div>
|
|
428
492
|
</div>
|
|
429
|
-
|
|
430
493
|
# Walker-based test
|
|
431
494
|
<div>
|
|
432
|
-
<strong style={{"color": "#374151"}}>
|
|
433
|
-
|
|
495
|
+
<strong style={{"color": "#374151"}}>
|
|
496
|
+
Walker String Processing:
|
|
497
|
+
</strong>
|
|
498
|
+
<div
|
|
499
|
+
style={{
|
|
500
|
+
"display": "flex",
|
|
501
|
+
"gap": "10px",
|
|
502
|
+
"marginTop": "10px"
|
|
503
|
+
}}
|
|
504
|
+
>
|
|
434
505
|
<input
|
|
435
506
|
type="text"
|
|
436
507
|
value={stringInput}
|
|
437
|
-
onChange={lambda e: any
|
|
508
|
+
onChange={lambda e: any -> None { stringInput = e.target.value;}}
|
|
438
509
|
style={{
|
|
439
510
|
"flex": "1",
|
|
440
511
|
"padding": "10px",
|
|
@@ -445,27 +516,28 @@ sv import from .FeaturesTest {
|
|
|
445
516
|
/>
|
|
446
517
|
<TestButton
|
|
447
518
|
text="Process with Walker"
|
|
448
|
-
onClick={lambda -> None { handleStringTest();
|
|
519
|
+
onClick={lambda -> None { handleStringTest();}}
|
|
449
520
|
variant="primary"
|
|
450
521
|
/>
|
|
451
522
|
</div>
|
|
452
|
-
{stringResult
|
|
523
|
+
{stringResult
|
|
524
|
+
and <ResultDisplay data={stringResult} label="Walker Result" />}
|
|
453
525
|
</div>
|
|
454
526
|
</div>
|
|
455
527
|
</TestCard>
|
|
456
|
-
|
|
457
528
|
# # Section 3: List Operations
|
|
458
529
|
<TestCard title="3. List/Array Operations" color="#ddd6fe">
|
|
459
530
|
<div>
|
|
460
531
|
<p style={{"color": "#4b5563", "marginBottom": "10px"}}>
|
|
461
532
|
Process arrays/lists using walker operations.
|
|
462
533
|
</p>
|
|
463
|
-
|
|
464
|
-
|
|
534
|
+
<div
|
|
535
|
+
style={{"display": "flex", "gap": "10px", "marginTop": "10px"}}
|
|
536
|
+
>
|
|
465
537
|
<input
|
|
466
538
|
type="text"
|
|
467
539
|
value={numberList}
|
|
468
|
-
onChange={lambda e: any
|
|
540
|
+
onChange={lambda e: any -> None { numberList = e.target.value;}}
|
|
469
541
|
placeholder="Enter numbers (comma-separated)"
|
|
470
542
|
style={{
|
|
471
543
|
"flex": "1",
|
|
@@ -477,14 +549,17 @@ sv import from .FeaturesTest {
|
|
|
477
549
|
/>
|
|
478
550
|
<TestButton
|
|
479
551
|
text="Process List"
|
|
480
|
-
onClick={lambda -> None { handleListTest();
|
|
552
|
+
onClick={lambda -> None { handleListTest();}}
|
|
481
553
|
variant="primary"
|
|
482
554
|
/>
|
|
483
555
|
</div>
|
|
484
|
-
{listResult
|
|
556
|
+
{listResult
|
|
557
|
+
and <ResultDisplay
|
|
558
|
+
data={listResult}
|
|
559
|
+
label="List Operations Result"
|
|
560
|
+
/>}
|
|
485
561
|
</div>
|
|
486
562
|
</TestCard>
|
|
487
|
-
|
|
488
563
|
# # Section 4: TypeScript Component Integration
|
|
489
564
|
# <TestCard title="4. TypeScript Component (PieChart.tsx)" color="#ccfbf1">
|
|
490
565
|
# <div>
|
|
@@ -504,60 +579,97 @@ sv import from .FeaturesTest {
|
|
|
504
579
|
<p style={{"color": "#4b5563", "marginBottom": "15px"}}>
|
|
505
580
|
This page demonstrates various import types:
|
|
506
581
|
</p>
|
|
507
|
-
|
|
508
582
|
<ul style={{"color": "#374151", "lineHeight": "1.8"}}>
|
|
509
|
-
<li
|
|
510
|
-
|
|
583
|
+
<li>
|
|
584
|
+
<strong>
|
|
585
|
+
JAC-Client Utils:
|
|
586
|
+
</strong>
|
|
587
|
+
Router components (Link, useNavigate)
|
|
588
|
+
</li>
|
|
589
|
+
<li>
|
|
590
|
+
<strong>
|
|
591
|
+
React:
|
|
592
|
+
</strong>
|
|
593
|
+
Hooks (useState, useEffect)
|
|
594
|
+
</li>
|
|
511
595
|
# <li><strong>TypeScript:</strong> PieChart component from .tsx file</li>
|
|
512
|
-
<li
|
|
513
|
-
|
|
596
|
+
<li>
|
|
597
|
+
<strong>
|
|
598
|
+
JavaScript:
|
|
599
|
+
</strong>
|
|
600
|
+
Helper functions from .js file (generateId, sumBy)
|
|
601
|
+
</li>
|
|
602
|
+
<li>
|
|
603
|
+
<strong>
|
|
604
|
+
JAC Files:
|
|
605
|
+
</strong>
|
|
606
|
+
for
|
|
607
|
+
matCurrency from utils/formatters.jac
|
|
608
|
+
</li>
|
|
514
609
|
</ul>
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
<
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
610
|
+
<div
|
|
611
|
+
style={{
|
|
612
|
+
"backgroundColor": "#f0fdf4",
|
|
613
|
+
"padding": "15px",
|
|
614
|
+
"borderRadius": "6px",
|
|
615
|
+
"marginTop": "15px"
|
|
616
|
+
}}
|
|
617
|
+
>
|
|
618
|
+
<strong style={{"color": "#065f46"}}>
|
|
619
|
+
Examples:
|
|
620
|
+
</strong>
|
|
621
|
+
<div
|
|
622
|
+
style={{
|
|
623
|
+
"marginTop": "8px",
|
|
624
|
+
"fontSize": "14px",
|
|
625
|
+
"color": "#047857"
|
|
626
|
+
}}
|
|
627
|
+
>
|
|
628
|
+
<div>
|
|
629
|
+
Generated ID: {generateId()}
|
|
630
|
+
</div>
|
|
631
|
+
<div>
|
|
632
|
+
Formatted Currency: {formatCurrency(1234.56)}
|
|
633
|
+
</div>
|
|
634
|
+
<div>
|
|
635
|
+
Percentage Calc: {calculatePercentage(75, 100)}%
|
|
636
|
+
</div>
|
|
527
637
|
</div>
|
|
528
638
|
</div>
|
|
529
639
|
</div>
|
|
530
640
|
</TestCard>
|
|
531
|
-
|
|
532
641
|
# # Section 6: Complex Data Processing
|
|
533
642
|
<TestCard title="6. Complex Data Processing" color="#e0e7ff">
|
|
534
643
|
<div>
|
|
535
644
|
<p style={{"color": "#4b5563", "marginBottom": "10px"}}>
|
|
536
645
|
Process complex nested data structures with walkers.
|
|
537
646
|
</p>
|
|
538
|
-
|
|
539
647
|
<TestButton
|
|
540
648
|
text="Process Sample Data"
|
|
541
|
-
onClick={lambda -> None { handleComplexTest();
|
|
649
|
+
onClick={lambda -> None { handleComplexTest();}}
|
|
542
650
|
variant="primary"
|
|
543
651
|
/>
|
|
544
|
-
|
|
545
|
-
|
|
652
|
+
{complexResult
|
|
653
|
+
and <ResultDisplay
|
|
654
|
+
data={complexResult}
|
|
655
|
+
label="Complex Processing Result"
|
|
656
|
+
/>}
|
|
546
657
|
</div>
|
|
547
658
|
</TestCard>
|
|
548
|
-
|
|
549
659
|
# Footer
|
|
550
|
-
<div
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
660
|
+
<div
|
|
661
|
+
style={{
|
|
662
|
+
"marginTop": "30px",
|
|
663
|
+
"padding": "20px",
|
|
664
|
+
"backgroundColor": "#f9fafb",
|
|
665
|
+
"borderRadius": "8px",
|
|
666
|
+
"textAlign": "center",
|
|
667
|
+
"color": "#6b7280"
|
|
668
|
+
}}
|
|
669
|
+
>
|
|
558
670
|
<p style={{"margin": "0"}}>
|
|
559
671
|
✅ All features tested: Props, Exports, CL Files, TypeScript, JavaScript, JAC Imports, String Methods, Walker Spawning
|
|
560
672
|
</p>
|
|
561
673
|
</div>
|
|
562
674
|
</div>;
|
|
563
|
-
|
|
675
|
+
}
|