jac-client 0.2.0__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 (72) hide show
  1. jac_client/docs/README.md +659 -0
  2. jac_client/docs/advanced-state.md +1266 -0
  3. jac_client/docs/assets/pipe_line.png +0 -0
  4. jac_client/docs/guide-example/intro.md +117 -0
  5. jac_client/docs/guide-example/step-01-setup.md +260 -0
  6. jac_client/docs/guide-example/step-02-components.md +416 -0
  7. jac_client/docs/guide-example/step-03-styling.md +478 -0
  8. jac_client/docs/guide-example/step-04-todo-ui.md +477 -0
  9. jac_client/docs/guide-example/step-05-local-state.md +530 -0
  10. jac_client/docs/guide-example/step-06-events.md +750 -0
  11. jac_client/docs/guide-example/step-07-effects.md +469 -0
  12. jac_client/docs/guide-example/step-08-walkers.md +534 -0
  13. jac_client/docs/guide-example/step-09-authentication.md +586 -0
  14. jac_client/docs/guide-example/step-10-routing.md +540 -0
  15. jac_client/docs/guide-example/step-11-final.md +964 -0
  16. jac_client/docs/imports.md +1142 -0
  17. jac_client/docs/lifecycle-hooks.md +774 -0
  18. jac_client/docs/routing.md +660 -0
  19. jac_client/examples/basic/.babelrc +9 -0
  20. jac_client/examples/basic/README.md +16 -0
  21. jac_client/examples/basic/app.jac +16 -0
  22. jac_client/examples/basic/package.json +27 -0
  23. jac_client/examples/basic/vite.config.js +28 -0
  24. jac_client/examples/basic-auth/.babelrc +9 -0
  25. jac_client/examples/basic-auth/README.md +16 -0
  26. jac_client/examples/basic-auth/app.jac +308 -0
  27. jac_client/examples/basic-auth/package.json +27 -0
  28. jac_client/examples/basic-auth/vite.config.js +28 -0
  29. jac_client/examples/basic-auth-with-router/.babelrc +9 -0
  30. jac_client/examples/basic-auth-with-router/README.md +60 -0
  31. jac_client/examples/basic-auth-with-router/app.jac +464 -0
  32. jac_client/examples/basic-auth-with-router/package.json +28 -0
  33. jac_client/examples/basic-auth-with-router/vite.config.js +28 -0
  34. jac_client/examples/basic-full-stack/.babelrc +9 -0
  35. jac_client/examples/basic-full-stack/README.md +18 -0
  36. jac_client/examples/basic-full-stack/app.jac +320 -0
  37. jac_client/examples/basic-full-stack/package.json +28 -0
  38. jac_client/examples/basic-full-stack/vite.config.js +28 -0
  39. jac_client/examples/full-stack-with-auth/.babelrc +9 -0
  40. jac_client/examples/full-stack-with-auth/README.md +16 -0
  41. jac_client/examples/full-stack-with-auth/app.jac +735 -0
  42. jac_client/examples/full-stack-with-auth/package.json +28 -0
  43. jac_client/examples/full-stack-with-auth/vite.config.js +30 -0
  44. jac_client/examples/little-x/app.jac +615 -0
  45. jac_client/examples/little-x/package.json +23 -0
  46. jac_client/examples/little-x/submit-button.jac +8 -0
  47. jac_client/examples/with-router/.babelrc +9 -0
  48. jac_client/examples/with-router/README.md +17 -0
  49. jac_client/examples/with-router/app.jac +323 -0
  50. jac_client/examples/with-router/package.json +28 -0
  51. jac_client/examples/with-router/vite.config.js +28 -0
  52. jac_client/plugin/cli.py +239 -0
  53. jac_client/plugin/client.py +89 -0
  54. jac_client/plugin/client_runtime.jac +234 -0
  55. jac_client/plugin/vite_client_bundle.py +355 -0
  56. jac_client/tests/__init__.py +2 -0
  57. jac_client/tests/fixtures/basic-app/app.jac +18 -0
  58. jac_client/tests/fixtures/client_app_with_antd/app.jac +28 -0
  59. jac_client/tests/fixtures/js_import/app.jac +30 -0
  60. jac_client/tests/fixtures/js_import/utils.js +22 -0
  61. jac_client/tests/fixtures/package-lock.json +329 -0
  62. jac_client/tests/fixtures/package.json +11 -0
  63. jac_client/tests/fixtures/relative_import/app.jac +13 -0
  64. jac_client/tests/fixtures/relative_import/button.jac +6 -0
  65. jac_client/tests/fixtures/spawn_test/app.jac +133 -0
  66. jac_client/tests/fixtures/test_fragments_spread/app.jac +53 -0
  67. jac_client/tests/test_cl.py +476 -0
  68. jac_client/tests/test_create_jac_app.py +139 -0
  69. jac_client-0.2.0.dist-info/METADATA +182 -0
  70. jac_client-0.2.0.dist-info/RECORD +72 -0
  71. jac_client-0.2.0.dist-info/WHEEL +4 -0
  72. jac_client-0.2.0.dist-info/entry_points.txt +4 -0
@@ -0,0 +1,28 @@
1
+ """Sample Jac module using Ant Design components."""
2
+
3
+ cl import from antd {
4
+ Button
5
+ }
6
+ cl let APP_NAME: str = "Ant Design Test";
7
+
8
+ cl def ButtonTest() {
9
+ return <div>
10
+ <h1>{APP_NAME}</h1>
11
+ <p>Testing Ant Design integration</p>
12
+ <Button>Click Me</Button>
13
+ </div>;
14
+ }
15
+
16
+ cl def CardTest() {
17
+ return <div class="card-wrapper">
18
+ <h2>Card Component</h2>
19
+ </div>;
20
+ }
21
+
22
+ cl def app() {
23
+ return <div>
24
+ <ButtonTest />
25
+ <CardTest />
26
+ </div>;
27
+ }
28
+
@@ -0,0 +1,30 @@
1
+ """Test module that imports JavaScript functions."""
2
+
3
+ cl import from .utils {
4
+ formatMessage,
5
+ calculateSum,
6
+ JS_CONSTANT,
7
+ MessageFormatter
8
+ }
9
+
10
+ cl let JS_IMPORT_LABEL: str = "JavaScript Import Test";
11
+
12
+ cl def JsImportTest() -> any {
13
+ let greeting = formatMessage("Jac");
14
+ let sum = calculateSum(5, 3);
15
+ let formatter = MessageFormatter("JS");
16
+ let formatted = formatter.format("Hello from JS class");
17
+
18
+ return <div class="js-import-test">
19
+ <h1>{JS_IMPORT_LABEL}</h1>
20
+ <p>Greeting: {greeting}</p>
21
+ <p>Sum (5 + 3): {sum}</p>
22
+ <p>Constant: {JS_CONSTANT}</p>
23
+ <p>Formatted: {formatted}</p>
24
+ </div>;
25
+ }
26
+
27
+ cl def app() -> any {
28
+ return <JsImportTest />;
29
+ }
30
+
@@ -0,0 +1,22 @@
1
+ // JavaScript utility functions for testing JS imports in Jac
2
+
3
+ export function formatMessage(name) {
4
+ return `Hello, ${name}!`;
5
+ }
6
+
7
+ export function calculateSum(a, b) {
8
+ return a + b;
9
+ }
10
+
11
+ export const JS_CONSTANT = "Imported from JavaScript";
12
+
13
+ export class MessageFormatter {
14
+ constructor(prefix) {
15
+ this.prefix = prefix;
16
+ }
17
+
18
+ format(text) {
19
+ return `${this.prefix}: ${text}`;
20
+ }
21
+ }
22
+
@@ -0,0 +1,329 @@
1
+ {
2
+ "name": "test-client",
3
+ "version": "0.0.1",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "test-client",
9
+ "version": "0.0.1",
10
+ "dependencies": {
11
+ "react": "^18.0.0",
12
+ "react-dom": "^18.0.0"
13
+ },
14
+ "devDependencies": {
15
+ "vite": "^5.0.0"
16
+ }
17
+ },
18
+ "node_modules/@esbuild/linux-x64": {
19
+ "version": "0.21.5",
20
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
21
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
22
+ "cpu": [
23
+ "x64"
24
+ ],
25
+ "dev": true,
26
+ "license": "MIT",
27
+ "optional": true,
28
+ "os": [
29
+ "linux"
30
+ ],
31
+ "engines": {
32
+ "node": ">=12"
33
+ }
34
+ },
35
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
36
+ "version": "4.52.5",
37
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz",
38
+ "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==",
39
+ "cpu": [
40
+ "x64"
41
+ ],
42
+ "dev": true,
43
+ "license": "MIT",
44
+ "optional": true,
45
+ "os": [
46
+ "linux"
47
+ ]
48
+ },
49
+ "node_modules/@rollup/rollup-linux-x64-musl": {
50
+ "version": "4.52.5",
51
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz",
52
+ "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==",
53
+ "cpu": [
54
+ "x64"
55
+ ],
56
+ "dev": true,
57
+ "license": "MIT",
58
+ "optional": true,
59
+ "os": [
60
+ "linux"
61
+ ]
62
+ },
63
+ "node_modules/@types/estree": {
64
+ "version": "1.0.8",
65
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
66
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
67
+ "dev": true,
68
+ "license": "MIT"
69
+ },
70
+ "node_modules/esbuild": {
71
+ "version": "0.21.5",
72
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
73
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
74
+ "dev": true,
75
+ "hasInstallScript": true,
76
+ "license": "MIT",
77
+ "bin": {
78
+ "esbuild": "bin/esbuild"
79
+ },
80
+ "engines": {
81
+ "node": ">=12"
82
+ },
83
+ "optionalDependencies": {
84
+ "@esbuild/aix-ppc64": "0.21.5",
85
+ "@esbuild/android-arm": "0.21.5",
86
+ "@esbuild/android-arm64": "0.21.5",
87
+ "@esbuild/android-x64": "0.21.5",
88
+ "@esbuild/darwin-arm64": "0.21.5",
89
+ "@esbuild/darwin-x64": "0.21.5",
90
+ "@esbuild/freebsd-arm64": "0.21.5",
91
+ "@esbuild/freebsd-x64": "0.21.5",
92
+ "@esbuild/linux-arm": "0.21.5",
93
+ "@esbuild/linux-arm64": "0.21.5",
94
+ "@esbuild/linux-ia32": "0.21.5",
95
+ "@esbuild/linux-loong64": "0.21.5",
96
+ "@esbuild/linux-mips64el": "0.21.5",
97
+ "@esbuild/linux-ppc64": "0.21.5",
98
+ "@esbuild/linux-riscv64": "0.21.5",
99
+ "@esbuild/linux-s390x": "0.21.5",
100
+ "@esbuild/linux-x64": "0.21.5",
101
+ "@esbuild/netbsd-x64": "0.21.5",
102
+ "@esbuild/openbsd-x64": "0.21.5",
103
+ "@esbuild/sunos-x64": "0.21.5",
104
+ "@esbuild/win32-arm64": "0.21.5",
105
+ "@esbuild/win32-ia32": "0.21.5",
106
+ "@esbuild/win32-x64": "0.21.5"
107
+ }
108
+ },
109
+ "node_modules/js-tokens": {
110
+ "version": "4.0.0",
111
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
112
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
113
+ "license": "MIT"
114
+ },
115
+ "node_modules/loose-envify": {
116
+ "version": "1.4.0",
117
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
118
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
119
+ "license": "MIT",
120
+ "dependencies": {
121
+ "js-tokens": "^3.0.0 || ^4.0.0"
122
+ },
123
+ "bin": {
124
+ "loose-envify": "cli.js"
125
+ }
126
+ },
127
+ "node_modules/nanoid": {
128
+ "version": "3.3.11",
129
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
130
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
131
+ "dev": true,
132
+ "funding": [
133
+ {
134
+ "type": "github",
135
+ "url": "https://github.com/sponsors/ai"
136
+ }
137
+ ],
138
+ "license": "MIT",
139
+ "bin": {
140
+ "nanoid": "bin/nanoid.cjs"
141
+ },
142
+ "engines": {
143
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
144
+ }
145
+ },
146
+ "node_modules/picocolors": {
147
+ "version": "1.1.1",
148
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
149
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
150
+ "dev": true,
151
+ "license": "ISC"
152
+ },
153
+ "node_modules/postcss": {
154
+ "version": "8.5.6",
155
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
156
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
157
+ "dev": true,
158
+ "funding": [
159
+ {
160
+ "type": "opencollective",
161
+ "url": "https://opencollective.com/postcss/"
162
+ },
163
+ {
164
+ "type": "tidelift",
165
+ "url": "https://tidelift.com/funding/github/npm/postcss"
166
+ },
167
+ {
168
+ "type": "github",
169
+ "url": "https://github.com/sponsors/ai"
170
+ }
171
+ ],
172
+ "license": "MIT",
173
+ "dependencies": {
174
+ "nanoid": "^3.3.11",
175
+ "picocolors": "^1.1.1",
176
+ "source-map-js": "^1.2.1"
177
+ },
178
+ "engines": {
179
+ "node": "^10 || ^12 || >=14"
180
+ }
181
+ },
182
+ "node_modules/react": {
183
+ "version": "18.3.1",
184
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
185
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
186
+ "license": "MIT",
187
+ "dependencies": {
188
+ "loose-envify": "^1.1.0"
189
+ },
190
+ "engines": {
191
+ "node": ">=0.10.0"
192
+ }
193
+ },
194
+ "node_modules/react-dom": {
195
+ "version": "18.3.1",
196
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
197
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
198
+ "license": "MIT",
199
+ "dependencies": {
200
+ "loose-envify": "^1.1.0",
201
+ "scheduler": "^0.23.2"
202
+ },
203
+ "peerDependencies": {
204
+ "react": "^18.3.1"
205
+ }
206
+ },
207
+ "node_modules/rollup": {
208
+ "version": "4.52.5",
209
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz",
210
+ "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==",
211
+ "dev": true,
212
+ "license": "MIT",
213
+ "dependencies": {
214
+ "@types/estree": "1.0.8"
215
+ },
216
+ "bin": {
217
+ "rollup": "dist/bin/rollup"
218
+ },
219
+ "engines": {
220
+ "node": ">=18.0.0",
221
+ "npm": ">=8.0.0"
222
+ },
223
+ "optionalDependencies": {
224
+ "@rollup/rollup-android-arm-eabi": "4.52.5",
225
+ "@rollup/rollup-android-arm64": "4.52.5",
226
+ "@rollup/rollup-darwin-arm64": "4.52.5",
227
+ "@rollup/rollup-darwin-x64": "4.52.5",
228
+ "@rollup/rollup-freebsd-arm64": "4.52.5",
229
+ "@rollup/rollup-freebsd-x64": "4.52.5",
230
+ "@rollup/rollup-linux-arm-gnueabihf": "4.52.5",
231
+ "@rollup/rollup-linux-arm-musleabihf": "4.52.5",
232
+ "@rollup/rollup-linux-arm64-gnu": "4.52.5",
233
+ "@rollup/rollup-linux-arm64-musl": "4.52.5",
234
+ "@rollup/rollup-linux-loong64-gnu": "4.52.5",
235
+ "@rollup/rollup-linux-ppc64-gnu": "4.52.5",
236
+ "@rollup/rollup-linux-riscv64-gnu": "4.52.5",
237
+ "@rollup/rollup-linux-riscv64-musl": "4.52.5",
238
+ "@rollup/rollup-linux-s390x-gnu": "4.52.5",
239
+ "@rollup/rollup-linux-x64-gnu": "4.52.5",
240
+ "@rollup/rollup-linux-x64-musl": "4.52.5",
241
+ "@rollup/rollup-openharmony-arm64": "4.52.5",
242
+ "@rollup/rollup-win32-arm64-msvc": "4.52.5",
243
+ "@rollup/rollup-win32-ia32-msvc": "4.52.5",
244
+ "@rollup/rollup-win32-x64-gnu": "4.52.5",
245
+ "@rollup/rollup-win32-x64-msvc": "4.52.5",
246
+ "fsevents": "~2.3.2"
247
+ }
248
+ },
249
+ "node_modules/scheduler": {
250
+ "version": "0.23.2",
251
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
252
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
253
+ "license": "MIT",
254
+ "dependencies": {
255
+ "loose-envify": "^1.1.0"
256
+ }
257
+ },
258
+ "node_modules/source-map-js": {
259
+ "version": "1.2.1",
260
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
261
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
262
+ "dev": true,
263
+ "license": "BSD-3-Clause",
264
+ "engines": {
265
+ "node": ">=0.10.0"
266
+ }
267
+ },
268
+ "node_modules/vite": {
269
+ "version": "5.4.21",
270
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz",
271
+ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==",
272
+ "dev": true,
273
+ "license": "MIT",
274
+ "dependencies": {
275
+ "esbuild": "^0.21.3",
276
+ "postcss": "^8.4.43",
277
+ "rollup": "^4.20.0"
278
+ },
279
+ "bin": {
280
+ "vite": "bin/vite.js"
281
+ },
282
+ "engines": {
283
+ "node": "^18.0.0 || >=20.0.0"
284
+ },
285
+ "funding": {
286
+ "url": "https://github.com/vitejs/vite?sponsor=1"
287
+ },
288
+ "optionalDependencies": {
289
+ "fsevents": "~2.3.3"
290
+ },
291
+ "peerDependencies": {
292
+ "@types/node": "^18.0.0 || >=20.0.0",
293
+ "less": "*",
294
+ "lightningcss": "^1.21.0",
295
+ "sass": "*",
296
+ "sass-embedded": "*",
297
+ "stylus": "*",
298
+ "sugarss": "*",
299
+ "terser": "^5.4.0"
300
+ },
301
+ "peerDependenciesMeta": {
302
+ "@types/node": {
303
+ "optional": true
304
+ },
305
+ "less": {
306
+ "optional": true
307
+ },
308
+ "lightningcss": {
309
+ "optional": true
310
+ },
311
+ "sass": {
312
+ "optional": true
313
+ },
314
+ "sass-embedded": {
315
+ "optional": true
316
+ },
317
+ "stylus": {
318
+ "optional": true
319
+ },
320
+ "sugarss": {
321
+ "optional": true
322
+ },
323
+ "terser": {
324
+ "optional": true
325
+ }
326
+ }
327
+ }
328
+ }
329
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "test-client",
3
+ "version": "0.0.1",
4
+ "dependencies": {
5
+ "react": "^18.0.0",
6
+ "react-dom": "^18.0.0"
7
+ },
8
+ "devDependencies": {
9
+ "vite": "^5.0.0"
10
+ }
11
+ }
@@ -0,0 +1,13 @@
1
+ cl import from .button {
2
+ CustomButton
3
+ }
4
+
5
+ cl def RelativeImport() -> any {
6
+ return <div>
7
+ <CustomButton />
8
+ </div>;
9
+ }
10
+
11
+ cl def app() -> any {
12
+ return <RelativeImport />;
13
+ }
@@ -0,0 +1,6 @@
1
+ cl import from antd {
2
+ Button
3
+ }
4
+ cl def CustomButton() -> any {
5
+ return <Button>Click Me</Button>;
6
+ }
@@ -0,0 +1,133 @@
1
+ """Test module for spawn operator in both standard and reverse order."""
2
+
3
+ # Server-side node and walker definitions
4
+ node TestNode {
5
+ has value: int = 0;
6
+ }
7
+
8
+ walker test_walker {
9
+ has message: str = "Hello from walker";
10
+
11
+ can execute with `root entry {
12
+ report {"result": self.message} ;
13
+ }
14
+ }
15
+
16
+ walker parameterized_walker {
17
+ has value: int;
18
+
19
+ can execute with `root entry {
20
+ report {"computed": self.value * 2} ;
21
+ }
22
+ }
23
+
24
+ walker positional_walker {
25
+ has label: str;
26
+ has count: int;
27
+ has metadata: dict = {};
28
+
29
+ can execute with `root entry {
30
+ report {
31
+ "label": self.label,
32
+ "count": self.count,
33
+ "meta": self.metadata
34
+ } ;
35
+ }
36
+ }
37
+
38
+ # Client-side code testing both spawn orderings
39
+ cl import from react {
40
+ useState,
41
+ useEffect
42
+ }
43
+
44
+ cl {
45
+ def app() -> any {
46
+ let [standardResult, setStandardResult] = useState(None);
47
+ let [standardComputed, setStandardComputed] = useState(None);
48
+ let [reverseResult, setReverseResult] = useState(None);
49
+ let [uuidResult, setUuidResult] = useState(None);
50
+ let [reverseUuidResult, setReverseUuidResult] = useState(None);
51
+ let [positionalResult, setPositionalResult] = useState(None);
52
+ let [spreadResult, setSpreadResult] = useState(None);
53
+
54
+ async def loadData() -> None {
55
+ # Test standard spawn order: node spawn walker()
56
+ data1 = root spawn test_walker();
57
+ setStandardResult(data1);
58
+
59
+ data2 = root spawn parameterized_walker(value=42);
60
+ setStandardComputed(data2);
61
+
62
+ # Test reverse spawn order: walker() spawn node
63
+ data3 = test_walker(message="Reverse spawn!") spawn root;
64
+ setReverseResult(data3);
65
+
66
+ # Test spawn with UUID string: uuid_string spawn walker()
67
+ node_id = "550e8400-e29b-41d4-a716-446655440000";
68
+ data4 = node_id spawn test_walker();
69
+ setUuidResult(data4);
70
+
71
+ # Test reverse spawn with UUID string: walker() spawn uuid_string
72
+ another_node_id = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
73
+ data5 = parameterized_walker(value=100) spawn another_node_id;
74
+ setReverseUuidResult(data5);
75
+
76
+ # Test positional walker arguments inferred from has fields
77
+ data6 = node_id spawn positional_walker("Node positional", 2);
78
+ setPositionalResult(data6);
79
+
80
+ # Test **kwargs via spread when walker is on left-hand side
81
+ extra_fields = {"metadata": {"source": "client-side"}};
82
+ data7 = positional_walker("Spread order", 5, **extra_fields) spawn root;
83
+ setSpreadResult(data7);
84
+ }
85
+
86
+ useEffect(lambda -> None{ loadData();} , []);
87
+
88
+ return <div>
89
+ <h1>
90
+ Spawn Operator Test
91
+ </h1>
92
+ <h2>
93
+ Standard Order (node spawn walker)
94
+ </h2>
95
+ <div>
96
+ Result: {JSON.stringify(standardResult)}
97
+ </div>
98
+ <div>
99
+ Computed: {JSON.stringify(standardComputed)}
100
+ </div>
101
+ <h2>
102
+ Reverse Order (walker spawn node)
103
+ </h2>
104
+ <div>
105
+ Result: {JSON.stringify(reverseResult)}
106
+ </div>
107
+ <h2>
108
+ UUID Spawn (uuid spawn walker)
109
+ </h2>
110
+ <div>
111
+ Result: {JSON.stringify(uuidResult)}
112
+ </div>
113
+ <h2>
114
+ Reverse UUID Spawn (walker spawn uuid)
115
+ </h2>
116
+ <div>
117
+ Result: {JSON.stringify(reverseUuidResult)}
118
+ </div>
119
+ <h2>
120
+ Positional Walker Arguments
121
+ </h2>
122
+ <div>
123
+ Result: {JSON.stringify(positionalResult)}
124
+ </div>
125
+ <h2>
126
+ Spread Walker Arguments
127
+ </h2>
128
+ <div>
129
+ Result: {JSON.stringify(spreadResult)}
130
+ </div>
131
+ </div>;
132
+ }
133
+ }
@@ -0,0 +1,53 @@
1
+ """Test fixture for JSX fragments and spread props functionality."""
2
+
3
+ cl def FragmentTest() {
4
+ # Test that fragments work
5
+ return <>
6
+ <h1>{"Fragment Title"}</h1>
7
+ <p>{"Fragment content"}</p>
8
+ </>;
9
+ }
10
+
11
+ cl def SpreadPropsTest() {
12
+ # Test spread props
13
+ unwrapped = {"id": "my-div", "class": "container", "data-role": "main"};
14
+
15
+ return <div {...unwrapped}>
16
+ <span>{"Spread props work!"}</span>
17
+ </div>;
18
+ }
19
+
20
+ cl def MixedTest() {
21
+ # Test mixing spread props with regular props
22
+ baseStyle = {"id": "base-id", "color": "blue"};
23
+
24
+ return <>
25
+ <div {...baseStyle} class="override">
26
+ {"Mixed test"}
27
+ </div>
28
+ <div class="normal">
29
+ {"No spread"}
30
+ </div>
31
+ </>;
32
+ }
33
+
34
+ cl def NestedFragments() {
35
+ return <div class="wrapper">
36
+ <>
37
+ <h2>{"Nested Fragment 1"}</h2>
38
+ </>
39
+ <>
40
+ <p>{"Nested Fragment 2"}</p>
41
+ </>
42
+ </div>;
43
+ }
44
+
45
+ cl def app() {
46
+ return <div>
47
+ <FragmentTest />
48
+ <SpreadPropsTest />
49
+ <MixedTest />
50
+ <NestedFragments />
51
+ </div>;
52
+ }
53
+