jac-client 0.2.3__py3-none-any.whl → 0.2.4__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 (176) hide show
  1. jac_client/examples/all-in-one/assets/workers/worker.py +5 -0
  2. jac_client/tests/conftest.py +281 -0
  3. jac_client/tests/test_cli.py +755 -0
  4. jac_client/tests/test_it.py +347 -67
  5. {jac_client-0.2.3.dist-info → jac_client-0.2.4.dist-info}/METADATA +28 -30
  6. jac_client-0.2.4.dist-info/RECORD +10 -0
  7. {jac_client-0.2.3.dist-info → jac_client-0.2.4.dist-info}/WHEEL +2 -1
  8. jac_client-0.2.4.dist-info/entry_points.txt +4 -0
  9. jac_client-0.2.4.dist-info/top_level.txt +1 -0
  10. jac_client/docs/README.md +0 -689
  11. jac_client/docs/advanced-state.md +0 -1265
  12. jac_client/docs/asset-serving/intro.md +0 -209
  13. jac_client/docs/assets/pipe_line-v2.svg +0 -32
  14. jac_client/docs/assets/pipe_line.png +0 -0
  15. jac_client/docs/file-system/app.jac.md +0 -121
  16. jac_client/docs/file-system/backend-frontend.md +0 -217
  17. jac_client/docs/file-system/intro.md +0 -72
  18. jac_client/docs/file-system/nested-imports.md +0 -348
  19. jac_client/docs/guide-example/intro.md +0 -115
  20. jac_client/docs/guide-example/step-01-setup.md +0 -270
  21. jac_client/docs/guide-example/step-02-components.md +0 -416
  22. jac_client/docs/guide-example/step-03-styling.md +0 -478
  23. jac_client/docs/guide-example/step-04-todo-ui.md +0 -477
  24. jac_client/docs/guide-example/step-05-local-state.md +0 -530
  25. jac_client/docs/guide-example/step-06-events.md +0 -749
  26. jac_client/docs/guide-example/step-07-effects.md +0 -468
  27. jac_client/docs/guide-example/step-08-walkers.md +0 -534
  28. jac_client/docs/guide-example/step-09-authentication.md +0 -586
  29. jac_client/docs/guide-example/step-10-routing.md +0 -539
  30. jac_client/docs/guide-example/step-11-final.md +0 -963
  31. jac_client/docs/imports.md +0 -1141
  32. jac_client/docs/lifecycle-hooks.md +0 -773
  33. jac_client/docs/routing.md +0 -659
  34. jac_client/docs/styling/intro.md +0 -249
  35. jac_client/docs/styling/js-styling.md +0 -367
  36. jac_client/docs/styling/material-ui.md +0 -341
  37. jac_client/docs/styling/pure-css.md +0 -299
  38. jac_client/docs/styling/sass.md +0 -403
  39. jac_client/docs/styling/styled-components.md +0 -395
  40. jac_client/docs/styling/tailwind.md +0 -298
  41. jac_client/examples/all-in-one/.babelrc +0 -9
  42. jac_client/examples/all-in-one/README.md +0 -16
  43. jac_client/examples/all-in-one/app.jac +0 -426
  44. jac_client/examples/all-in-one/assets/burger.png +0 -0
  45. jac_client/examples/all-in-one/button.jac +0 -7
  46. jac_client/examples/all-in-one/components/button.jac +0 -7
  47. jac_client/examples/all-in-one/package.json +0 -29
  48. jac_client/examples/all-in-one/styles.css +0 -26
  49. jac_client/examples/all-in-one/vite.config.js +0 -28
  50. jac_client/examples/asset-serving/css-with-image/.babelrc +0 -9
  51. jac_client/examples/asset-serving/css-with-image/README.md +0 -91
  52. jac_client/examples/asset-serving/css-with-image/app.jac +0 -88
  53. jac_client/examples/asset-serving/css-with-image/assets/burger.png +0 -0
  54. jac_client/examples/asset-serving/css-with-image/package.json +0 -28
  55. jac_client/examples/asset-serving/css-with-image/styles.css +0 -26
  56. jac_client/examples/asset-serving/css-with-image/vite.config.js +0 -28
  57. jac_client/examples/asset-serving/image-asset/.babelrc +0 -9
  58. jac_client/examples/asset-serving/image-asset/README.md +0 -119
  59. jac_client/examples/asset-serving/image-asset/app.jac +0 -55
  60. jac_client/examples/asset-serving/image-asset/assets/burger.png +0 -0
  61. jac_client/examples/asset-serving/image-asset/package.json +0 -28
  62. jac_client/examples/asset-serving/image-asset/styles.css +0 -26
  63. jac_client/examples/asset-serving/image-asset/vite.config.js +0 -28
  64. jac_client/examples/asset-serving/import-alias/.babelrc +0 -9
  65. jac_client/examples/asset-serving/import-alias/README.md +0 -83
  66. jac_client/examples/asset-serving/import-alias/app.jac +0 -111
  67. jac_client/examples/asset-serving/import-alias/assets/burger.png +0 -0
  68. jac_client/examples/asset-serving/import-alias/package.json +0 -28
  69. jac_client/examples/asset-serving/import-alias/vite.config.js +0 -28
  70. jac_client/examples/basic/.babelrc +0 -9
  71. jac_client/examples/basic/README.md +0 -16
  72. jac_client/examples/basic/app.jac +0 -21
  73. jac_client/examples/basic/package.json +0 -27
  74. jac_client/examples/basic/vite.config.js +0 -27
  75. jac_client/examples/basic-auth/.babelrc +0 -9
  76. jac_client/examples/basic-auth/README.md +0 -16
  77. jac_client/examples/basic-auth/app.jac +0 -308
  78. jac_client/examples/basic-auth/package.json +0 -27
  79. jac_client/examples/basic-auth/vite.config.js +0 -27
  80. jac_client/examples/basic-auth-with-router/.babelrc +0 -9
  81. jac_client/examples/basic-auth-with-router/README.md +0 -60
  82. jac_client/examples/basic-auth-with-router/app.jac +0 -464
  83. jac_client/examples/basic-auth-with-router/package.json +0 -28
  84. jac_client/examples/basic-auth-with-router/vite.config.js +0 -27
  85. jac_client/examples/basic-full-stack/.babelrc +0 -9
  86. jac_client/examples/basic-full-stack/README.md +0 -18
  87. jac_client/examples/basic-full-stack/app.jac +0 -320
  88. jac_client/examples/basic-full-stack/package.json +0 -28
  89. jac_client/examples/basic-full-stack/vite.config.js +0 -27
  90. jac_client/examples/css-styling/js-styling/.babelrc +0 -9
  91. jac_client/examples/css-styling/js-styling/README.md +0 -183
  92. jac_client/examples/css-styling/js-styling/app.jac +0 -84
  93. jac_client/examples/css-styling/js-styling/package.json +0 -28
  94. jac_client/examples/css-styling/js-styling/styles.js +0 -100
  95. jac_client/examples/css-styling/js-styling/vite.config.js +0 -27
  96. jac_client/examples/css-styling/material-ui/.babelrc +0 -9
  97. jac_client/examples/css-styling/material-ui/README.md +0 -16
  98. jac_client/examples/css-styling/material-ui/app.jac +0 -122
  99. jac_client/examples/css-styling/material-ui/package.json +0 -32
  100. jac_client/examples/css-styling/material-ui/vite.config.js +0 -27
  101. jac_client/examples/css-styling/pure-css/.babelrc +0 -9
  102. jac_client/examples/css-styling/pure-css/README.md +0 -16
  103. jac_client/examples/css-styling/pure-css/app.jac +0 -64
  104. jac_client/examples/css-styling/pure-css/package.json +0 -28
  105. jac_client/examples/css-styling/pure-css/styles.css +0 -111
  106. jac_client/examples/css-styling/pure-css/vite.config.js +0 -27
  107. jac_client/examples/css-styling/sass-example/.babelrc +0 -9
  108. jac_client/examples/css-styling/sass-example/README.md +0 -16
  109. jac_client/examples/css-styling/sass-example/app.jac +0 -64
  110. jac_client/examples/css-styling/sass-example/package.json +0 -29
  111. jac_client/examples/css-styling/sass-example/styles.scss +0 -153
  112. jac_client/examples/css-styling/sass-example/vite.config.js +0 -27
  113. jac_client/examples/css-styling/styled-components/.babelrc +0 -9
  114. jac_client/examples/css-styling/styled-components/README.md +0 -16
  115. jac_client/examples/css-styling/styled-components/app.jac +0 -71
  116. jac_client/examples/css-styling/styled-components/package.json +0 -29
  117. jac_client/examples/css-styling/styled-components/styled.js +0 -90
  118. jac_client/examples/css-styling/styled-components/vite.config.js +0 -27
  119. jac_client/examples/css-styling/tailwind-example/.babelrc +0 -9
  120. jac_client/examples/css-styling/tailwind-example/README.md +0 -16
  121. jac_client/examples/css-styling/tailwind-example/app.jac +0 -63
  122. jac_client/examples/css-styling/tailwind-example/global.css +0 -1
  123. jac_client/examples/css-styling/tailwind-example/package.json +0 -30
  124. jac_client/examples/css-styling/tailwind-example/vite.config.js +0 -29
  125. jac_client/examples/full-stack-with-auth/.babelrc +0 -9
  126. jac_client/examples/full-stack-with-auth/README.md +0 -16
  127. jac_client/examples/full-stack-with-auth/app.jac +0 -722
  128. jac_client/examples/full-stack-with-auth/package.json +0 -28
  129. jac_client/examples/full-stack-with-auth/vite.config.js +0 -29
  130. jac_client/examples/little-x/app.jac +0 -724
  131. jac_client/examples/little-x/package.json +0 -23
  132. jac_client/examples/little-x/submit-button.jac +0 -8
  133. jac_client/examples/nested-folders/nested-advance/.babelrc +0 -9
  134. jac_client/examples/nested-folders/nested-advance/ButtonRoot.jac +0 -11
  135. jac_client/examples/nested-folders/nested-advance/README.md +0 -77
  136. jac_client/examples/nested-folders/nested-advance/app.jac +0 -35
  137. jac_client/examples/nested-folders/nested-advance/level1/ButtonSecondL.jac +0 -19
  138. jac_client/examples/nested-folders/nested-advance/level1/Card.jac +0 -43
  139. jac_client/examples/nested-folders/nested-advance/level1/level2/ButtonThirdL.jac +0 -25
  140. jac_client/examples/nested-folders/nested-advance/package.json +0 -29
  141. jac_client/examples/nested-folders/nested-advance/vite.config.js +0 -28
  142. jac_client/examples/nested-folders/nested-basic/.babelrc +0 -9
  143. jac_client/examples/nested-folders/nested-basic/README.md +0 -183
  144. jac_client/examples/nested-folders/nested-basic/app.jac +0 -13
  145. jac_client/examples/nested-folders/nested-basic/app.js +0 -7
  146. jac_client/examples/nested-folders/nested-basic/button.jac +0 -7
  147. jac_client/examples/nested-folders/nested-basic/components/button.jac +0 -7
  148. jac_client/examples/nested-folders/nested-basic/package.json +0 -28
  149. jac_client/examples/nested-folders/nested-basic/vite.config.js +0 -27
  150. jac_client/examples/with-router/.babelrc +0 -9
  151. jac_client/examples/with-router/README.md +0 -17
  152. jac_client/examples/with-router/app.jac +0 -323
  153. jac_client/examples/with-router/package.json +0 -28
  154. jac_client/examples/with-router/vite.config.js +0 -27
  155. jac_client/plugin/cli.py +0 -244
  156. jac_client/plugin/client.py +0 -152
  157. jac_client/plugin/client_runtime.jac +0 -234
  158. jac_client/plugin/vite_client_bundle.py +0 -503
  159. jac_client/tests/fixtures/basic-app/app.jac +0 -23
  160. jac_client/tests/fixtures/cl_file/app.cl.jac +0 -48
  161. jac_client/tests/fixtures/cl_file/app.jac +0 -15
  162. jac_client/tests/fixtures/client_app_with_antd/app.jac +0 -34
  163. jac_client/tests/fixtures/js_import/app.jac +0 -34
  164. jac_client/tests/fixtures/js_import/utils.js +0 -21
  165. jac_client/tests/fixtures/package-lock.json +0 -329
  166. jac_client/tests/fixtures/package.json +0 -11
  167. jac_client/tests/fixtures/relative_import/app.jac +0 -11
  168. jac_client/tests/fixtures/relative_import/button.jac +0 -7
  169. jac_client/tests/fixtures/spawn_test/app.jac +0 -129
  170. jac_client/tests/fixtures/test_fragments_spread/app.jac +0 -67
  171. jac_client/tests/test_asset_examples.py +0 -322
  172. jac_client/tests/test_cl.py +0 -530
  173. jac_client/tests/test_create_jac_app.py +0 -131
  174. jac_client/tests/test_nested_file.py +0 -374
  175. jac_client-0.2.3.dist-info/RECORD +0 -171
  176. jac_client-0.2.3.dist-info/entry_points.txt +0 -4
@@ -1,323 +0,0 @@
1
- # React Router HashRouter Example
2
- cl import from react { useState, useEffect }
3
- cl import from "@jac-client/utils" {
4
- Router,
5
- Routes,
6
- Route,
7
- Link,
8
- useNavigate,
9
- useLocation,
10
- useParams
11
- }
12
-
13
- cl {
14
- # Home Page Component
15
- def Home() -> any {
16
- location = useLocation();
17
- navigate = useNavigate();
18
-
19
- def goToAbout(e: any) -> None {
20
- navigate("/about");
21
- }
22
-
23
- return <div>
24
- <h1>
25
- 🏠 Home Page
26
- </h1>
27
- <p>
28
- Welcome to the home page!
29
- </p>
30
- <p>
31
- This example uses React Router's
32
- <strong>
33
- HashRouter
34
- </strong>
35
- # for client-side routing.
36
- </p>
37
- <p>
38
- Current path:
39
- <code>
40
- {location.pathname}
41
- </code>
42
- </p>
43
- <button
44
- onClick={goToAbout}
45
- >
46
- Go to About →
47
- </button>
48
- </div>;
49
- }
50
-
51
- # About Page Component
52
- def About() -> any {
53
- location = useLocation();
54
-
55
- return <div>
56
- <h1>
57
- ℹ️ About Page
58
- </h1>
59
- <p>
60
- This is the about page.
61
- </p>
62
- <p>
63
- Learn more about our application here.
64
- </p>
65
- <p>
66
- Current path:
67
- <code>
68
- {location.pathname}
69
- </code>
70
- </p>
71
- <div
72
- style={{"marginTop": "1rem"}}
73
- >
74
- <Link to="/about/team">
75
- View Team →
76
- </Link>
77
- </div>
78
- </div>;
79
- }
80
-
81
- # Team Page Component (nested route example)
82
- def Team() -> any {
83
- return <div>
84
- <h1>
85
- 👥 Our Team
86
- </h1>
87
- <p>
88
- Meet the amazing team behind this project!
89
- </p>
90
- <Link to="/about">
91
- ← Back to About
92
- </Link>
93
- </div>;
94
- }
95
-
96
- # User Profile Component (with URL parameters)
97
- def UserProfile() -> any {
98
- params = useParams();
99
- userId = params.id if params.id else "Unknown";
100
-
101
- return <div>
102
- <h1>
103
- 👤 User Profile
104
- </h1>
105
- <p>
106
- Viewing profile for user:
107
- <strong>
108
- {userId}
109
- </strong>
110
- </p>
111
- <p>
112
- This demonstrates URL parameters using
113
- <code>
114
- /user/:id
115
- </code>
116
- </p>
117
- <Link to="/">
118
- ← Back to Home
119
- </Link>
120
- </div>;
121
- }
122
-
123
- # Contact Page Component
124
- def Contact() -> any {
125
- [submitted, setSubmitted] = useState(False);
126
-
127
- def handleSubmit(e: any) -> None {
128
- e.preventDefault();
129
- setSubmitted(True);
130
- }
131
-
132
- def resetForm(e: any) -> None {
133
- setSubmitted(False);
134
- }
135
-
136
- if submitted {
137
- return <div>
138
- <h1>
139
- 📧 Contact Page
140
- </h1>
141
- <div
142
- style={{"color": "green"}}
143
- >
144
- <p>
145
- ✓ Thank you! Your message has been sent.
146
- </p>
147
- <button
148
- onClick={resetForm}
149
- >
150
- Send another
151
- </button>
152
- </div>
153
- </div>;
154
- }
155
-
156
- return <div>
157
- <h1>
158
- 📧 Contact Page
159
- </h1>
160
- <p>
161
- Get in touch with us!
162
- </p>
163
- <form
164
- onSubmit={handleSubmit}
165
- >
166
- <input
167
- type="text"
168
- placeholder="Your name"
169
- style={{"margin": "0.5rem 0", "display": "block"}}
170
- />
171
- <input
172
- type="email"
173
- placeholder="Your email"
174
- style={{"margin": "0.5rem 0", "display": "block"}}
175
- />
176
- <textarea
177
- placeholder="Your message"
178
- style={{"margin": "0.5rem 0", "display": "block"}}
179
- ></textarea>
180
- <button type="submit">
181
- Send Message
182
- </button>
183
- </form>
184
- </div>;
185
- }
186
-
187
- # 404 Not Found Component
188
- def NotFound() -> any {
189
- location = useLocation();
190
- navigate = useNavigate();
191
-
192
- def goHome(e: any) -> None {
193
- navigate("/");
194
- }
195
-
196
- return <div
197
- style={{"textAlign": "center", "padding": "2rem"}}
198
- >
199
- <h1>
200
- 🔍 404 - Page Not Found
201
- </h1>
202
- <p>
203
- The page
204
- <code>
205
- {location.pathname}
206
- </code>
207
- does not exist.
208
- </p>
209
- <button
210
- onClick={goHome}
211
- >
212
- Go Home
213
- </button>
214
- </div>;
215
- }
216
-
217
- # Navigation Component with active link styling
218
- def Navigation() -> any {
219
- location = useLocation();
220
-
221
- def linkStyle(path: str) -> dict {
222
- isActive = location.pathname == path;
223
- return {
224
- "padding": "0.5rem 1rem",
225
- "textDecoration": "none",
226
- "color": "#0066cc" if isActive else "#333",
227
- "fontWeight": "bold" if isActive else "normal",
228
- "backgroundColor": "#e3f2fd" if isActive else "transparent",
229
- "borderRadius": "4px",
230
- "display": "inline-block"
231
- };
232
- }
233
-
234
- return <nav
235
- style={{
236
- "padding": "1rem",
237
- "backgroundColor": "#f5f5f5",
238
- "marginBottom": "2rem",
239
- "boxShadow": "0 2px 4px rgba(0,0,0,0.1)"
240
- }}
241
- >
242
- <div
243
- style={{
244
- "maxWidth": "1200px",
245
- "margin": "0 auto",
246
- "display": "flex",
247
- "gap": "1rem",
248
- "alignItems": "center"
249
- }}
250
- >
251
- <Link
252
- to="/"
253
- style={linkStyle("/")}
254
- >
255
- Home
256
- </Link>
257
- <Link
258
- to="/about"
259
- style={linkStyle("/about")}
260
- >
261
- About
262
- </Link>
263
- <Link
264
- to="/contact"
265
- style={linkStyle("/contact")}
266
- >
267
- Contact
268
- </Link>
269
- <Link
270
- to="/user/123"
271
- style={linkStyle("/user/123")}
272
- >
273
- Profile Demo
274
- </Link>
275
- </div>
276
- </nav>;
277
- }
278
-
279
- # Main App Component with React Router HashRouter
280
- def app() -> any {
281
- return <Router>
282
- <div
283
- style={{"fontFamily": "system-ui, -apple-system, sans-serif"}}
284
- >
285
- <Navigation />
286
- <div
287
- style={{
288
- "maxWidth": "1200px",
289
- "margin": "0 auto",
290
- "padding": "0 1rem"
291
- }}
292
- >
293
- <Routes>
294
- <Route
295
- path="/"
296
- element={<Home />}
297
- />
298
- <Route
299
- path="/about"
300
- element={<About />}
301
- />
302
- <Route
303
- path="/about/team"
304
- element={<Team />}
305
- />
306
- <Route
307
- path="/contact"
308
- element={<Contact />}
309
- />
310
- <Route
311
- path="/user/:id"
312
- element={<UserProfile />}
313
- />
314
- <Route
315
- path="*"
316
- element={<NotFound />}
317
- />
318
- </Routes>
319
- </div>
320
- </div>
321
- </Router>;
322
- }
323
- }
@@ -1,28 +0,0 @@
1
- {
2
- "name": "my-app",
3
- "version": "1.0.0",
4
- "main": "index.js",
5
- "scripts": {
6
- "build": "npm run compile && vite build",
7
- "dev": "vite dev",
8
- "preview": "vite preview",
9
- "compile": "babel src --out-dir build --extensions \".jsx,.js\" --out-file-extension .js"
10
- },
11
- "keywords": [],
12
- "author": "",
13
- "license": "ISC",
14
- "description": "Jac application: my-app",
15
- "type": "module",
16
- "devDependencies": {
17
- "vite": "^6.4.1",
18
- "@babel/cli": "^7.28.3",
19
- "@babel/core": "^7.28.5",
20
- "@babel/preset-env": "^7.28.5",
21
- "@babel/preset-react": "^7.28.5"
22
- },
23
- "dependencies": {
24
- "react": "^19.2.0",
25
- "react-dom": "^19.2.0",
26
- "react-router-dom": "^6.30.1"
27
- }
28
- }
@@ -1,27 +0,0 @@
1
-
2
- import { defineConfig } from "vite";
3
- import path from "path";
4
- import { fileURLToPath } from "url";
5
-
6
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
-
8
- export default defineConfig({
9
- root: ".", // base folder
10
- build: {
11
- rollupOptions: {
12
- input: "build/main.js", // your compiled entry file
13
- output: {
14
- entryFileNames: "client.[hash].js", // name of the final js file
15
- assetFileNames: "[name].[ext]",
16
- },
17
- },
18
- outDir: "dist", // final bundled output
19
- emptyOutDir: true,
20
- },
21
- publicDir: false,
22
- resolve: {
23
- alias: {
24
- "@jac-client/utils": path.resolve(__dirname, "src/client_runtime.js"),
25
- },
26
- },
27
- });
jac_client/plugin/cli.py DELETED
@@ -1,244 +0,0 @@
1
- """Command line interface tool for the Jac Client."""
2
-
3
- import json
4
- import os
5
- import re
6
- import subprocess
7
- import sys
8
-
9
- from jaclang.cli.cmdreg import cmd_registry
10
- from jaclang.runtimelib.runtime import hookimpl
11
-
12
-
13
- class JacCmd:
14
- """Jac CLI."""
15
-
16
- @staticmethod
17
- @hookimpl
18
- def create_cmd() -> None:
19
- """Create Jac CLI cmds."""
20
-
21
- @cmd_registry.register
22
- def create_jac_app(name: str) -> None:
23
- """Create a new Jac application with npm and Vite setup.
24
-
25
- Bootstraps a new Jac project by creating a temporary directory, initializing
26
- npm, installing Vite, and setting up the basic project structure.
27
-
28
- Args:
29
- name: Name of the project to create
30
-
31
- Examples:
32
- jac create_jac_app my-app
33
- jac create_jac_app my-jac-project
34
- """
35
- if not name:
36
- print(
37
- "Error: Project name is required. Use --name=your-project-name",
38
- file=sys.stderr,
39
- )
40
- exit(1)
41
-
42
- # Validate project name (basic npm package name validation)
43
- if not re.match(r"^[a-zA-Z0-9_-]+$", name):
44
- print(
45
- "Error: Project name must contain only letters, numbers, hyphens, and underscores",
46
- file=sys.stderr,
47
- )
48
- exit(1)
49
-
50
- print(f"Creating new Jac application: {name}")
51
-
52
- # Create project directory in current working directory
53
- project_path = os.path.join(os.getcwd(), name)
54
-
55
- if os.path.exists(project_path):
56
- print(
57
- f"Error: Directory '{name}' already exists in current location",
58
- file=sys.stderr,
59
- )
60
- exit(1)
61
-
62
- os.makedirs(project_path, exist_ok=True)
63
-
64
- try:
65
- # Change to project directory
66
- original_cwd = os.getcwd()
67
- os.chdir(project_path)
68
-
69
- # Initialize npm package
70
- print("Initializing npm package...")
71
- npm_init_cmd = ["npm", "init", "-y"]
72
- subprocess.run(npm_init_cmd, capture_output=True, text=True, check=True)
73
-
74
- # Read the generated package.json
75
- package_json_path = os.path.join(project_path, "package.json")
76
- with open(package_json_path) as f:
77
- package_data = json.load(f)
78
-
79
- # create temp folder
80
- src_folder = os.path.join(project_path, "src")
81
- os.makedirs(src_folder, exist_ok=True)
82
-
83
- # create build folder
84
- build_folder = os.path.join(project_path, "build")
85
- os.makedirs(build_folder, exist_ok=True)
86
-
87
- # create assets folder for static assets (images, fonts, etc.)
88
- assets_folder = os.path.join(project_path, "assets")
89
- os.makedirs(assets_folder, exist_ok=True)
90
-
91
- # Update package.json with Jac-specific configuration
92
- package_data.update(
93
- {
94
- "name": name,
95
- "description": f"Jac application: {name}",
96
- "type": "module",
97
- "scripts": {
98
- "build": "npm run compile && vite build",
99
- "dev": "vite dev",
100
- "preview": "vite preview",
101
- "compile": 'babel src --out-dir build --extensions ".jsx,.js" --out-file-extension .js',
102
- },
103
- "devDependencies": {
104
- "vite": "^6.4.1",
105
- "@babel/cli": "^7.28.3",
106
- "@babel/core": "^7.28.5",
107
- "@babel/preset-env": "^7.28.5",
108
- "@babel/preset-react": "^7.28.5",
109
- },
110
- "dependencies": {
111
- "react": "^19.2.0",
112
- "react-dom": "^19.2.0",
113
- "react-router-dom": "^6.30.1",
114
- },
115
- }
116
- )
117
-
118
- # Write updated package.json
119
- with open(package_json_path, "w") as f:
120
- json.dump(package_data, f, indent=2)
121
-
122
- print("Installing Vite...")
123
- # Install Vite
124
- npm_install_cmd = ["npm", "install"]
125
- subprocess.run(
126
- npm_install_cmd, capture_output=True, text=True, check=True
127
- )
128
-
129
- # Create basic project structure
130
- print("Setting up project structure...")
131
-
132
- # Create a basic Jac file
133
- main_jac_content = """
134
- # Pages
135
- cl import from react {useState, useEffect}
136
- cl {
137
- def app() -> any {
138
- let [count, setCount] = useState(0);
139
- useEffect(lambda -> None {
140
- console.log("Count: ", count);
141
- }, [count]);
142
- return <div>
143
- <h1>Hello, World!</h1>
144
- <p>Count: {count}</p>
145
- <button onClick={lambda e: any -> None {setCount(count + 1);}}>Increment</button>
146
- </div>;
147
- }
148
- }
149
- """
150
-
151
- with open(os.path.join(project_path, "app.jac"), "w") as f:
152
- f.write(main_jac_content)
153
-
154
- # create .babelrc file
155
- babel_config_content = """
156
- {
157
- "presets": [[
158
- "@babel/preset-env",
159
- {
160
- "modules": false
161
- }
162
- ], "@babel/preset-react"]
163
- }
164
- """
165
- with open(os.path.join(project_path, ".babelrc"), "w") as f:
166
- f.write(babel_config_content)
167
-
168
- # create vite.config.js file
169
- vite_config_content = """
170
- import { defineConfig } from "vite";
171
- import path from "path";
172
- import { fileURLToPath } from "url";
173
-
174
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
175
-
176
- export default defineConfig({
177
- root: ".", // base folder
178
- build: {
179
- rollupOptions: {
180
- input: "build/main.js", // your compiled entry file
181
- output: {
182
- entryFileNames: "client.[hash].js", // name of the final js file
183
- assetFileNames: "[name].[ext]",
184
- },
185
- },
186
- outDir: "dist", // final bundled output
187
- emptyOutDir: true,
188
- },
189
- publicDir: false,
190
- resolve: {
191
- alias: {
192
- "@jac-client/utils": path.resolve(__dirname, "src/client_runtime.js"),
193
- "@jac-client/assets": path.resolve(__dirname, "src/assets"),
194
- },
195
- },
196
- });
197
-
198
- """
199
- with open(os.path.join(project_path, "vite.config.js"), "w") as f:
200
- f.write(vite_config_content)
201
-
202
- # Create README.md
203
- readme_content = f"""# {name}
204
-
205
- ## Running Jac Code
206
-
207
- make sure node modules are installed:
208
- ```bash
209
- npm install
210
- ```
211
-
212
- To run your Jac code, use the Jac CLI:
213
-
214
- ```bash
215
- jac serve app.jac
216
- ```
217
-
218
- Happy coding with Jac!
219
- """
220
-
221
- with open(os.path.join(project_path, "README.md"), "w") as f:
222
- f.write(readme_content)
223
-
224
- # Return to original directory
225
- os.chdir(original_cwd)
226
-
227
- print(f"✅ Successfully created Jac application '{name}'!")
228
- print(f"📁 Project location: {os.path.abspath(project_path)}")
229
- print("\nNext steps:")
230
- print(f" cd {name}")
231
- print(" jac serve app.jac")
232
-
233
- except subprocess.CalledProcessError as e:
234
- # Return to original directory on error
235
- os.chdir(original_cwd)
236
- print(f"Error running npm command: {e}", file=sys.stderr)
237
- print(f"Command output: {e.stdout}", file=sys.stderr)
238
- print(f"Command error: {e.stderr}", file=sys.stderr)
239
- exit(1)
240
- except Exception as e:
241
- # Return to original directory on error
242
- os.chdir(original_cwd)
243
- print(f"Error creating project: {e}", file=sys.stderr)
244
- exit(1)