jac-client 0.2.3__tar.gz → 0.2.4__tar.gz
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-0.2.3 → jac_client-0.2.4}/PKG-INFO +28 -30
- {jac_client-0.2.3 → jac_client-0.2.4}/README.md +16 -13
- jac_client-0.2.4/jac_client/examples/all-in-one/assets/workers/worker.py +5 -0
- jac_client-0.2.4/jac_client/tests/conftest.py +281 -0
- jac_client-0.2.4/jac_client/tests/test_cli.py +755 -0
- jac_client-0.2.4/jac_client/tests/test_it.py +609 -0
- jac_client-0.2.4/jac_client.egg-info/PKG-INFO +188 -0
- jac_client-0.2.4/jac_client.egg-info/SOURCES.txt +13 -0
- jac_client-0.2.4/jac_client.egg-info/dependency_links.txt +1 -0
- jac_client-0.2.4/jac_client.egg-info/entry_points.txt +4 -0
- jac_client-0.2.4/jac_client.egg-info/requires.txt +5 -0
- jac_client-0.2.4/jac_client.egg-info/top_level.txt +1 -0
- jac_client-0.2.4/pyproject.toml +44 -0
- jac_client-0.2.4/setup.cfg +4 -0
- jac_client-0.2.3/jac_client/docs/README.md +0 -689
- jac_client-0.2.3/jac_client/docs/advanced-state.md +0 -1265
- jac_client-0.2.3/jac_client/docs/asset-serving/intro.md +0 -209
- jac_client-0.2.3/jac_client/docs/assets/pipe_line-v2.svg +0 -32
- jac_client-0.2.3/jac_client/docs/assets/pipe_line.png +0 -0
- jac_client-0.2.3/jac_client/docs/file-system/app.jac.md +0 -121
- jac_client-0.2.3/jac_client/docs/file-system/backend-frontend.md +0 -217
- jac_client-0.2.3/jac_client/docs/file-system/intro.md +0 -72
- jac_client-0.2.3/jac_client/docs/file-system/nested-imports.md +0 -348
- jac_client-0.2.3/jac_client/docs/guide-example/intro.md +0 -115
- jac_client-0.2.3/jac_client/docs/guide-example/step-01-setup.md +0 -270
- jac_client-0.2.3/jac_client/docs/guide-example/step-02-components.md +0 -416
- jac_client-0.2.3/jac_client/docs/guide-example/step-03-styling.md +0 -478
- jac_client-0.2.3/jac_client/docs/guide-example/step-04-todo-ui.md +0 -477
- jac_client-0.2.3/jac_client/docs/guide-example/step-05-local-state.md +0 -530
- jac_client-0.2.3/jac_client/docs/guide-example/step-06-events.md +0 -749
- jac_client-0.2.3/jac_client/docs/guide-example/step-07-effects.md +0 -468
- jac_client-0.2.3/jac_client/docs/guide-example/step-08-walkers.md +0 -534
- jac_client-0.2.3/jac_client/docs/guide-example/step-09-authentication.md +0 -586
- jac_client-0.2.3/jac_client/docs/guide-example/step-10-routing.md +0 -539
- jac_client-0.2.3/jac_client/docs/guide-example/step-11-final.md +0 -963
- jac_client-0.2.3/jac_client/docs/imports.md +0 -1141
- jac_client-0.2.3/jac_client/docs/lifecycle-hooks.md +0 -773
- jac_client-0.2.3/jac_client/docs/routing.md +0 -659
- jac_client-0.2.3/jac_client/docs/styling/intro.md +0 -249
- jac_client-0.2.3/jac_client/docs/styling/js-styling.md +0 -367
- jac_client-0.2.3/jac_client/docs/styling/material-ui.md +0 -341
- jac_client-0.2.3/jac_client/docs/styling/pure-css.md +0 -299
- jac_client-0.2.3/jac_client/docs/styling/sass.md +0 -403
- jac_client-0.2.3/jac_client/docs/styling/styled-components.md +0 -395
- jac_client-0.2.3/jac_client/docs/styling/tailwind.md +0 -298
- jac_client-0.2.3/jac_client/examples/all-in-one/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/all-in-one/README.md +0 -16
- jac_client-0.2.3/jac_client/examples/all-in-one/app.jac +0 -426
- jac_client-0.2.3/jac_client/examples/all-in-one/assets/burger.png +0 -0
- jac_client-0.2.3/jac_client/examples/all-in-one/button.jac +0 -7
- jac_client-0.2.3/jac_client/examples/all-in-one/components/button.jac +0 -7
- jac_client-0.2.3/jac_client/examples/all-in-one/package.json +0 -29
- jac_client-0.2.3/jac_client/examples/all-in-one/styles.css +0 -26
- jac_client-0.2.3/jac_client/examples/all-in-one/vite.config.js +0 -28
- jac_client-0.2.3/jac_client/examples/asset-serving/css-with-image/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/asset-serving/css-with-image/README.md +0 -91
- jac_client-0.2.3/jac_client/examples/asset-serving/css-with-image/app.jac +0 -88
- jac_client-0.2.3/jac_client/examples/asset-serving/css-with-image/assets/burger.png +0 -0
- jac_client-0.2.3/jac_client/examples/asset-serving/css-with-image/package.json +0 -28
- jac_client-0.2.3/jac_client/examples/asset-serving/css-with-image/styles.css +0 -26
- jac_client-0.2.3/jac_client/examples/asset-serving/css-with-image/vite.config.js +0 -28
- jac_client-0.2.3/jac_client/examples/asset-serving/image-asset/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/asset-serving/image-asset/README.md +0 -119
- jac_client-0.2.3/jac_client/examples/asset-serving/image-asset/app.jac +0 -55
- jac_client-0.2.3/jac_client/examples/asset-serving/image-asset/assets/burger.png +0 -0
- jac_client-0.2.3/jac_client/examples/asset-serving/image-asset/package.json +0 -28
- jac_client-0.2.3/jac_client/examples/asset-serving/image-asset/styles.css +0 -26
- jac_client-0.2.3/jac_client/examples/asset-serving/image-asset/vite.config.js +0 -28
- jac_client-0.2.3/jac_client/examples/asset-serving/import-alias/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/asset-serving/import-alias/README.md +0 -83
- jac_client-0.2.3/jac_client/examples/asset-serving/import-alias/app.jac +0 -111
- jac_client-0.2.3/jac_client/examples/asset-serving/import-alias/assets/burger.png +0 -0
- jac_client-0.2.3/jac_client/examples/asset-serving/import-alias/package.json +0 -28
- jac_client-0.2.3/jac_client/examples/asset-serving/import-alias/vite.config.js +0 -28
- jac_client-0.2.3/jac_client/examples/basic/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/basic/README.md +0 -16
- jac_client-0.2.3/jac_client/examples/basic/app.jac +0 -21
- jac_client-0.2.3/jac_client/examples/basic/package.json +0 -27
- jac_client-0.2.3/jac_client/examples/basic/vite.config.js +0 -27
- jac_client-0.2.3/jac_client/examples/basic-auth/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/basic-auth/README.md +0 -16
- jac_client-0.2.3/jac_client/examples/basic-auth/app.jac +0 -308
- jac_client-0.2.3/jac_client/examples/basic-auth/package.json +0 -27
- jac_client-0.2.3/jac_client/examples/basic-auth/vite.config.js +0 -27
- jac_client-0.2.3/jac_client/examples/basic-auth-with-router/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/basic-auth-with-router/README.md +0 -60
- jac_client-0.2.3/jac_client/examples/basic-auth-with-router/app.jac +0 -464
- jac_client-0.2.3/jac_client/examples/basic-auth-with-router/package.json +0 -28
- jac_client-0.2.3/jac_client/examples/basic-auth-with-router/vite.config.js +0 -27
- jac_client-0.2.3/jac_client/examples/basic-full-stack/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/basic-full-stack/README.md +0 -18
- jac_client-0.2.3/jac_client/examples/basic-full-stack/app.jac +0 -320
- jac_client-0.2.3/jac_client/examples/basic-full-stack/package.json +0 -28
- jac_client-0.2.3/jac_client/examples/basic-full-stack/vite.config.js +0 -27
- jac_client-0.2.3/jac_client/examples/css-styling/js-styling/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/css-styling/js-styling/README.md +0 -183
- jac_client-0.2.3/jac_client/examples/css-styling/js-styling/app.jac +0 -84
- jac_client-0.2.3/jac_client/examples/css-styling/js-styling/package.json +0 -28
- jac_client-0.2.3/jac_client/examples/css-styling/js-styling/styles.js +0 -100
- jac_client-0.2.3/jac_client/examples/css-styling/js-styling/vite.config.js +0 -27
- jac_client-0.2.3/jac_client/examples/css-styling/material-ui/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/css-styling/material-ui/README.md +0 -16
- jac_client-0.2.3/jac_client/examples/css-styling/material-ui/app.jac +0 -122
- jac_client-0.2.3/jac_client/examples/css-styling/material-ui/package.json +0 -32
- jac_client-0.2.3/jac_client/examples/css-styling/material-ui/vite.config.js +0 -27
- jac_client-0.2.3/jac_client/examples/css-styling/pure-css/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/css-styling/pure-css/README.md +0 -16
- jac_client-0.2.3/jac_client/examples/css-styling/pure-css/app.jac +0 -64
- jac_client-0.2.3/jac_client/examples/css-styling/pure-css/package.json +0 -28
- jac_client-0.2.3/jac_client/examples/css-styling/pure-css/styles.css +0 -111
- jac_client-0.2.3/jac_client/examples/css-styling/pure-css/vite.config.js +0 -27
- jac_client-0.2.3/jac_client/examples/css-styling/sass-example/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/css-styling/sass-example/README.md +0 -16
- jac_client-0.2.3/jac_client/examples/css-styling/sass-example/app.jac +0 -64
- jac_client-0.2.3/jac_client/examples/css-styling/sass-example/package.json +0 -29
- jac_client-0.2.3/jac_client/examples/css-styling/sass-example/styles.scss +0 -153
- jac_client-0.2.3/jac_client/examples/css-styling/sass-example/vite.config.js +0 -27
- jac_client-0.2.3/jac_client/examples/css-styling/styled-components/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/css-styling/styled-components/README.md +0 -16
- jac_client-0.2.3/jac_client/examples/css-styling/styled-components/app.jac +0 -71
- jac_client-0.2.3/jac_client/examples/css-styling/styled-components/package.json +0 -29
- jac_client-0.2.3/jac_client/examples/css-styling/styled-components/styled.js +0 -90
- jac_client-0.2.3/jac_client/examples/css-styling/styled-components/vite.config.js +0 -27
- jac_client-0.2.3/jac_client/examples/css-styling/tailwind-example/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/css-styling/tailwind-example/README.md +0 -16
- jac_client-0.2.3/jac_client/examples/css-styling/tailwind-example/app.jac +0 -63
- jac_client-0.2.3/jac_client/examples/css-styling/tailwind-example/global.css +0 -1
- jac_client-0.2.3/jac_client/examples/css-styling/tailwind-example/package.json +0 -30
- jac_client-0.2.3/jac_client/examples/css-styling/tailwind-example/vite.config.js +0 -29
- jac_client-0.2.3/jac_client/examples/full-stack-with-auth/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/full-stack-with-auth/README.md +0 -16
- jac_client-0.2.3/jac_client/examples/full-stack-with-auth/app.jac +0 -722
- jac_client-0.2.3/jac_client/examples/full-stack-with-auth/package.json +0 -28
- jac_client-0.2.3/jac_client/examples/full-stack-with-auth/vite.config.js +0 -29
- jac_client-0.2.3/jac_client/examples/little-x/app.jac +0 -724
- jac_client-0.2.3/jac_client/examples/little-x/package.json +0 -23
- jac_client-0.2.3/jac_client/examples/little-x/submit-button.jac +0 -8
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance/ButtonRoot.jac +0 -11
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance/README.md +0 -77
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance/app.jac +0 -35
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance/level1/ButtonSecondL.jac +0 -19
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance/level1/Card.jac +0 -43
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance/level1/level2/ButtonThirdL.jac +0 -25
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance/package.json +0 -29
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-advance/vite.config.js +0 -28
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic/README.md +0 -183
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic/app.jac +0 -13
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic/app.js +0 -7
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic/button.jac +0 -7
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic/components/button.jac +0 -7
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic/package.json +0 -28
- jac_client-0.2.3/jac_client/examples/nested-folders/nested-basic/vite.config.js +0 -27
- jac_client-0.2.3/jac_client/examples/with-router/.babelrc +0 -9
- jac_client-0.2.3/jac_client/examples/with-router/README.md +0 -17
- jac_client-0.2.3/jac_client/examples/with-router/app.jac +0 -323
- jac_client-0.2.3/jac_client/examples/with-router/package.json +0 -28
- jac_client-0.2.3/jac_client/examples/with-router/vite.config.js +0 -27
- jac_client-0.2.3/jac_client/plugin/cli.py +0 -244
- jac_client-0.2.3/jac_client/plugin/client.py +0 -152
- jac_client-0.2.3/jac_client/plugin/client_runtime.jac +0 -234
- jac_client-0.2.3/jac_client/plugin/vite_client_bundle.py +0 -503
- jac_client-0.2.3/jac_client/tests/fixtures/basic-app/app.jac +0 -23
- jac_client-0.2.3/jac_client/tests/fixtures/cl_file/app.cl.jac +0 -48
- jac_client-0.2.3/jac_client/tests/fixtures/cl_file/app.jac +0 -15
- jac_client-0.2.3/jac_client/tests/fixtures/client_app_with_antd/app.jac +0 -34
- jac_client-0.2.3/jac_client/tests/fixtures/js_import/app.jac +0 -34
- jac_client-0.2.3/jac_client/tests/fixtures/js_import/utils.js +0 -21
- jac_client-0.2.3/jac_client/tests/fixtures/package-lock.json +0 -329
- jac_client-0.2.3/jac_client/tests/fixtures/package.json +0 -11
- jac_client-0.2.3/jac_client/tests/fixtures/relative_import/app.jac +0 -11
- jac_client-0.2.3/jac_client/tests/fixtures/relative_import/button.jac +0 -7
- jac_client-0.2.3/jac_client/tests/fixtures/spawn_test/app.jac +0 -129
- jac_client-0.2.3/jac_client/tests/fixtures/test_fragments_spread/app.jac +0 -67
- jac_client-0.2.3/jac_client/tests/test_asset_examples.py +0 -322
- jac_client-0.2.3/jac_client/tests/test_cl.py +0 -530
- jac_client-0.2.3/jac_client/tests/test_create_jac_app.py +0 -131
- jac_client-0.2.3/jac_client/tests/test_it.py +0 -329
- jac_client-0.2.3/jac_client/tests/test_nested_file.py +0 -374
- jac_client-0.2.3/pyproject.toml +0 -36
- {jac_client-0.2.3 → jac_client-0.2.4}/jac_client/tests/__init__.py +0 -0
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jac-client
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Build full-stack web applications with Jac - one language for frontend and backend.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Author-email: jason@mars.ninja
|
|
9
|
-
Maintainer: Jason Mars
|
|
10
|
-
Maintainer-email: jason@mars.ninja
|
|
11
|
-
Requires-Python: >=3.12.0,<4.0.0
|
|
12
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
-
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
-
Requires-Dist: jaclang (==0.9.3)
|
|
18
|
-
Project-URL: Documentation, https://jac-lang.org
|
|
19
|
-
Project-URL: Homepage, https://jaseci.org
|
|
5
|
+
Author-email: Jason Mars <jason@mars.ninja>
|
|
6
|
+
Maintainer-email: Jason Mars <jason@mars.ninja>
|
|
7
|
+
License-Expression: MIT
|
|
20
8
|
Project-URL: Repository, https://github.com/Jaseci-Labs/jaseci
|
|
9
|
+
Project-URL: Homepage, https://jaseci.org
|
|
10
|
+
Project-URL: Documentation, https://jac-lang.org
|
|
11
|
+
Keywords: jac,jaclang,jaseci,frontend,full-stack,web-development
|
|
12
|
+
Requires-Python: >=3.12
|
|
21
13
|
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: jaclang==0.9.4
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: python-dotenv==1.0.1; extra == "dev"
|
|
17
|
+
Requires-Dist: pytest==8.3.5; extra == "dev"
|
|
22
18
|
|
|
23
19
|
# Jac Client
|
|
24
20
|
|
|
@@ -28,7 +24,7 @@ Jac Client enables you to write React-like components, manage state, and build i
|
|
|
28
24
|
|
|
29
25
|
---
|
|
30
26
|
|
|
31
|
-
##
|
|
27
|
+
## Features
|
|
32
28
|
|
|
33
29
|
- **Single Language**: Write frontend and backend in Jac
|
|
34
30
|
- **No HTTP Client**: Use `jacSpawn()` instead of fetch/axios
|
|
@@ -40,7 +36,7 @@ Jac Client enables you to write React-like components, manage state, and build i
|
|
|
40
36
|
|
|
41
37
|
---
|
|
42
38
|
|
|
43
|
-
##
|
|
39
|
+
## Quick Start
|
|
44
40
|
|
|
45
41
|
### Installation
|
|
46
42
|
|
|
@@ -51,16 +47,18 @@ pip install jac-client
|
|
|
51
47
|
### Create a New App
|
|
52
48
|
|
|
53
49
|
```bash
|
|
54
|
-
jac
|
|
50
|
+
jac create --cl my-app
|
|
55
51
|
cd my-app
|
|
56
|
-
jac serve app.jac
|
|
52
|
+
jac serve src/app.jac
|
|
57
53
|
```
|
|
58
54
|
|
|
59
55
|
Visit `http://localhost:8000/page/app` to see your app!
|
|
60
56
|
|
|
57
|
+
> **Note**: The `--cl` flag creates a client-side project with an organized folder structure. Without `--cl`, `jac create` creates a standard Jac project.
|
|
58
|
+
|
|
61
59
|
---
|
|
62
60
|
|
|
63
|
-
##
|
|
61
|
+
## Documentation
|
|
64
62
|
|
|
65
63
|
For detailed guides and tutorials, see the **[docs folder](jac_client/docs/)**:
|
|
66
64
|
|
|
@@ -72,7 +70,7 @@ For detailed guides and tutorials, see the **[docs folder](jac_client/docs/)**:
|
|
|
72
70
|
|
|
73
71
|
---
|
|
74
72
|
|
|
75
|
-
##
|
|
73
|
+
## Example
|
|
76
74
|
|
|
77
75
|
### Simple Counter with React Hooks
|
|
78
76
|
|
|
@@ -81,7 +79,7 @@ cl import from react { useState, useEffect }
|
|
|
81
79
|
|
|
82
80
|
cl {
|
|
83
81
|
def Counter() -> any {
|
|
84
|
-
|
|
82
|
+
[count, setCount] = useState(0);
|
|
85
83
|
|
|
86
84
|
useEffect(lambda -> None {
|
|
87
85
|
console.log("Count changed:", count);
|
|
@@ -132,7 +130,7 @@ walker read_todos {
|
|
|
132
130
|
# Frontend: React component
|
|
133
131
|
cl {
|
|
134
132
|
def app() -> any {
|
|
135
|
-
|
|
133
|
+
[todos, setTodos] = useState([]);
|
|
136
134
|
|
|
137
135
|
useEffect(lambda -> None {
|
|
138
136
|
async def loadTodos() -> None {
|
|
@@ -154,7 +152,7 @@ cl {
|
|
|
154
152
|
|
|
155
153
|
---
|
|
156
154
|
|
|
157
|
-
##
|
|
155
|
+
## Requirements
|
|
158
156
|
|
|
159
157
|
- Python: 3.12+
|
|
160
158
|
- Node.js: For npm and Vite
|
|
@@ -162,9 +160,10 @@ cl {
|
|
|
162
160
|
|
|
163
161
|
---
|
|
164
162
|
|
|
165
|
-
##
|
|
163
|
+
## ️ How It Works
|
|
166
164
|
|
|
167
165
|
Jac Client is a plugin that:
|
|
166
|
+
|
|
168
167
|
1. Compiles your `.jac` client code to JavaScript
|
|
169
168
|
2. Bundles dependencies with Vite for optimal performance
|
|
170
169
|
3. Provides a runtime for reactive state and components
|
|
@@ -172,7 +171,7 @@ Jac Client is a plugin that:
|
|
|
172
171
|
|
|
173
172
|
---
|
|
174
173
|
|
|
175
|
-
##
|
|
174
|
+
## Learn More
|
|
176
175
|
|
|
177
176
|
- **Full Documentation**: See [docs/](jac_client/docs/) for comprehensive guides
|
|
178
177
|
- **Examples**: Check `jac_client/examples/` for working examples
|
|
@@ -180,11 +179,10 @@ Jac Client is a plugin that:
|
|
|
180
179
|
|
|
181
180
|
---
|
|
182
181
|
|
|
183
|
-
##
|
|
182
|
+
## License
|
|
184
183
|
|
|
185
184
|
MIT License - see [LICENSE](../LICENSE) file.
|
|
186
185
|
|
|
187
186
|
---
|
|
188
187
|
|
|
189
|
-
**Happy coding with Jac!**
|
|
190
|
-
|
|
188
|
+
**Happy coding with Jac!**
|
|
@@ -6,7 +6,7 @@ Jac Client enables you to write React-like components, manage state, and build i
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Features
|
|
10
10
|
|
|
11
11
|
- **Single Language**: Write frontend and backend in Jac
|
|
12
12
|
- **No HTTP Client**: Use `jacSpawn()` instead of fetch/axios
|
|
@@ -18,7 +18,7 @@ Jac Client enables you to write React-like components, manage state, and build i
|
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## Quick Start
|
|
22
22
|
|
|
23
23
|
### Installation
|
|
24
24
|
|
|
@@ -29,16 +29,18 @@ pip install jac-client
|
|
|
29
29
|
### Create a New App
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
jac
|
|
32
|
+
jac create --cl my-app
|
|
33
33
|
cd my-app
|
|
34
|
-
jac serve app.jac
|
|
34
|
+
jac serve src/app.jac
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
Visit `http://localhost:8000/page/app` to see your app!
|
|
38
38
|
|
|
39
|
+
> **Note**: The `--cl` flag creates a client-side project with an organized folder structure. Without `--cl`, `jac create` creates a standard Jac project.
|
|
40
|
+
|
|
39
41
|
---
|
|
40
42
|
|
|
41
|
-
##
|
|
43
|
+
## Documentation
|
|
42
44
|
|
|
43
45
|
For detailed guides and tutorials, see the **[docs folder](jac_client/docs/)**:
|
|
44
46
|
|
|
@@ -50,7 +52,7 @@ For detailed guides and tutorials, see the **[docs folder](jac_client/docs/)**:
|
|
|
50
52
|
|
|
51
53
|
---
|
|
52
54
|
|
|
53
|
-
##
|
|
55
|
+
## Example
|
|
54
56
|
|
|
55
57
|
### Simple Counter with React Hooks
|
|
56
58
|
|
|
@@ -59,7 +61,7 @@ cl import from react { useState, useEffect }
|
|
|
59
61
|
|
|
60
62
|
cl {
|
|
61
63
|
def Counter() -> any {
|
|
62
|
-
|
|
64
|
+
[count, setCount] = useState(0);
|
|
63
65
|
|
|
64
66
|
useEffect(lambda -> None {
|
|
65
67
|
console.log("Count changed:", count);
|
|
@@ -110,7 +112,7 @@ walker read_todos {
|
|
|
110
112
|
# Frontend: React component
|
|
111
113
|
cl {
|
|
112
114
|
def app() -> any {
|
|
113
|
-
|
|
115
|
+
[todos, setTodos] = useState([]);
|
|
114
116
|
|
|
115
117
|
useEffect(lambda -> None {
|
|
116
118
|
async def loadTodos() -> None {
|
|
@@ -132,7 +134,7 @@ cl {
|
|
|
132
134
|
|
|
133
135
|
---
|
|
134
136
|
|
|
135
|
-
##
|
|
137
|
+
## Requirements
|
|
136
138
|
|
|
137
139
|
- Python: 3.12+
|
|
138
140
|
- Node.js: For npm and Vite
|
|
@@ -140,9 +142,10 @@ cl {
|
|
|
140
142
|
|
|
141
143
|
---
|
|
142
144
|
|
|
143
|
-
##
|
|
145
|
+
## ️ How It Works
|
|
144
146
|
|
|
145
147
|
Jac Client is a plugin that:
|
|
148
|
+
|
|
146
149
|
1. Compiles your `.jac` client code to JavaScript
|
|
147
150
|
2. Bundles dependencies with Vite for optimal performance
|
|
148
151
|
3. Provides a runtime for reactive state and components
|
|
@@ -150,7 +153,7 @@ Jac Client is a plugin that:
|
|
|
150
153
|
|
|
151
154
|
---
|
|
152
155
|
|
|
153
|
-
##
|
|
156
|
+
## Learn More
|
|
154
157
|
|
|
155
158
|
- **Full Documentation**: See [docs/](jac_client/docs/) for comprehensive guides
|
|
156
159
|
- **Examples**: Check `jac_client/examples/` for working examples
|
|
@@ -158,10 +161,10 @@ Jac Client is a plugin that:
|
|
|
158
161
|
|
|
159
162
|
---
|
|
160
163
|
|
|
161
|
-
##
|
|
164
|
+
## License
|
|
162
165
|
|
|
163
166
|
MIT License - see [LICENSE](../LICENSE) file.
|
|
164
167
|
|
|
165
168
|
---
|
|
166
169
|
|
|
167
|
-
**Happy coding with Jac!**
|
|
170
|
+
**Happy coding with Jac!**
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
"""Pytest configuration and shared fixtures for jac-client tests.
|
|
2
|
+
|
|
3
|
+
This module provides session-scoped fixtures to optimize test execution by:
|
|
4
|
+
1. Running npm install once per session and caching node_modules
|
|
5
|
+
2. Providing shared Vite build infrastructure
|
|
6
|
+
3. Mocking npm install for tests that only need jac.toml manipulation
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import contextlib
|
|
12
|
+
import os
|
|
13
|
+
import shutil
|
|
14
|
+
import subprocess
|
|
15
|
+
import sys
|
|
16
|
+
import tempfile
|
|
17
|
+
from collections.abc import Generator
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from unittest.mock import patch
|
|
20
|
+
|
|
21
|
+
import pytest
|
|
22
|
+
|
|
23
|
+
from jaclang.pycore.runtime import JacRuntime as Jac
|
|
24
|
+
from jaclang.pycore.runtime import JacRuntimeImpl, plugin_manager
|
|
25
|
+
|
|
26
|
+
# Store unregistered plugins globally for session-level management
|
|
27
|
+
_external_plugins: list = []
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def pytest_configure(config: pytest.Config) -> None:
|
|
31
|
+
"""Disable jac-scale plugin at the start of the test session.
|
|
32
|
+
|
|
33
|
+
jac-scale plugin is disabled during tests to avoid MongoDB connections
|
|
34
|
+
and other jac-scale specific dependencies. jac-client plugin is kept
|
|
35
|
+
enabled since we're testing it.
|
|
36
|
+
"""
|
|
37
|
+
global _external_plugins
|
|
38
|
+
for name, plugin in list(plugin_manager.list_name_plugin()):
|
|
39
|
+
# Keep core runtime and jac-client plugins
|
|
40
|
+
if plugin is JacRuntimeImpl or name == "JacRuntimeImpl":
|
|
41
|
+
continue
|
|
42
|
+
if "client" in name.lower() or "JacClient" in str(type(plugin)):
|
|
43
|
+
continue
|
|
44
|
+
# Disable jac-scale and other external plugins
|
|
45
|
+
_external_plugins.append((name, plugin))
|
|
46
|
+
plugin_manager.unregister(plugin=plugin, name=name)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def pytest_unconfigure(config: pytest.Config) -> None:
|
|
50
|
+
"""Re-register external plugins at the end of the test session."""
|
|
51
|
+
global _external_plugins
|
|
52
|
+
for name, plugin in _external_plugins:
|
|
53
|
+
with contextlib.suppress(ValueError):
|
|
54
|
+
plugin_manager.register(plugin, name=name)
|
|
55
|
+
_external_plugins.clear()
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _get_jac_command() -> list[str]:
|
|
59
|
+
"""Get the jac command with proper path handling."""
|
|
60
|
+
# Try to find jac in PATH or use python -m jaclang
|
|
61
|
+
jac_path = shutil.which("jac")
|
|
62
|
+
if jac_path:
|
|
63
|
+
return [jac_path]
|
|
64
|
+
# Fall back to running via python module
|
|
65
|
+
return [sys.executable, "-m", "jaclang"]
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _get_env_with_npm() -> dict[str, str]:
|
|
69
|
+
"""Get environment dict with npm in PATH."""
|
|
70
|
+
env = os.environ.copy()
|
|
71
|
+
# npm might be installed via nvm, ensure PATH includes common locations
|
|
72
|
+
npm_path = shutil.which("npm")
|
|
73
|
+
if npm_path:
|
|
74
|
+
npm_dir = str(Path(npm_path).parent)
|
|
75
|
+
current_path = env.get("PATH", "")
|
|
76
|
+
if npm_dir not in current_path:
|
|
77
|
+
env["PATH"] = f"{npm_dir}:{current_path}"
|
|
78
|
+
return env
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@pytest.fixture(autouse=True)
|
|
82
|
+
def reset_jac_machine() -> Generator[None, None, None]:
|
|
83
|
+
"""Reset Jac machine before and after each test."""
|
|
84
|
+
Jac.reset_machine()
|
|
85
|
+
yield
|
|
86
|
+
Jac.reset_machine()
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# Session-scoped cache for npm installation
|
|
90
|
+
_npm_cache_dir: Path | None = None
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _get_minimal_jac_toml() -> str:
|
|
94
|
+
"""Get minimal jac.toml content for npm cache setup."""
|
|
95
|
+
return """[project]
|
|
96
|
+
name = "npm-cache"
|
|
97
|
+
version = "0.0.1"
|
|
98
|
+
description = "Cached npm modules"
|
|
99
|
+
entry-point = "app.jac"
|
|
100
|
+
|
|
101
|
+
[plugins.client.vite.build]
|
|
102
|
+
minify = false
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@pytest.fixture(scope="session")
|
|
107
|
+
def npm_cache_dir() -> Generator[Path, None, None]:
|
|
108
|
+
"""Session-scoped fixture that provides a directory with npm packages installed.
|
|
109
|
+
|
|
110
|
+
This runs npm install once per test session and provides the path to the
|
|
111
|
+
.jac-client.configs directory containing node_modules.
|
|
112
|
+
"""
|
|
113
|
+
global _npm_cache_dir
|
|
114
|
+
|
|
115
|
+
if _npm_cache_dir is not None and _npm_cache_dir.exists():
|
|
116
|
+
yield _npm_cache_dir
|
|
117
|
+
return
|
|
118
|
+
|
|
119
|
+
# Create a persistent temp directory for the session
|
|
120
|
+
cache_dir = Path(tempfile.mkdtemp(prefix="jac_npm_cache_"))
|
|
121
|
+
|
|
122
|
+
# Create jac.toml
|
|
123
|
+
jac_toml = cache_dir / "jac.toml"
|
|
124
|
+
jac_toml.write_text(_get_minimal_jac_toml())
|
|
125
|
+
|
|
126
|
+
# Run jac add --cl to install packages
|
|
127
|
+
jac_cmd = _get_jac_command()
|
|
128
|
+
env = _get_env_with_npm()
|
|
129
|
+
result = subprocess.run(
|
|
130
|
+
[*jac_cmd, "add", "--cl"],
|
|
131
|
+
cwd=cache_dir,
|
|
132
|
+
capture_output=True,
|
|
133
|
+
text=True,
|
|
134
|
+
env=env,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
if result.returncode != 0:
|
|
138
|
+
# Clean up on failure
|
|
139
|
+
shutil.rmtree(cache_dir, ignore_errors=True)
|
|
140
|
+
pytest.skip(f"Failed to set up npm cache: {result.stderr}")
|
|
141
|
+
|
|
142
|
+
_npm_cache_dir = cache_dir
|
|
143
|
+
yield cache_dir
|
|
144
|
+
|
|
145
|
+
# Cleanup after all tests complete
|
|
146
|
+
shutil.rmtree(cache_dir, ignore_errors=True)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
@pytest.fixture
|
|
150
|
+
def vite_project_dir(npm_cache_dir: Path, tmp_path: Path) -> Path:
|
|
151
|
+
"""Fixture that provides a project directory with pre-installed node_modules.
|
|
152
|
+
|
|
153
|
+
This copies node_modules from the session cache instead of running npm install.
|
|
154
|
+
"""
|
|
155
|
+
# Create jac.toml in the temp directory
|
|
156
|
+
jac_toml = tmp_path / "jac.toml"
|
|
157
|
+
jac_toml.write_text(_get_minimal_jac_toml())
|
|
158
|
+
|
|
159
|
+
# Copy .jac-client.configs directory (contains package.json)
|
|
160
|
+
source_configs = npm_cache_dir / ".jac-client.configs"
|
|
161
|
+
dest_configs = tmp_path / ".jac-client.configs"
|
|
162
|
+
if source_configs.exists():
|
|
163
|
+
shutil.copytree(source_configs, dest_configs, symlinks=True)
|
|
164
|
+
|
|
165
|
+
# Copy node_modules from project root (npm installs there, not in .jac-client.configs)
|
|
166
|
+
source_node_modules = npm_cache_dir / "node_modules"
|
|
167
|
+
dest_node_modules = tmp_path / "node_modules"
|
|
168
|
+
if source_node_modules.exists():
|
|
169
|
+
shutil.copytree(source_node_modules, dest_node_modules, symlinks=True)
|
|
170
|
+
|
|
171
|
+
# Create required directories
|
|
172
|
+
(tmp_path / "dist").mkdir(exist_ok=True)
|
|
173
|
+
(tmp_path / "compiled").mkdir(exist_ok=True)
|
|
174
|
+
(tmp_path / "build").mkdir(exist_ok=True)
|
|
175
|
+
|
|
176
|
+
return tmp_path
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@pytest.fixture
|
|
180
|
+
def vite_project_with_antd(npm_cache_dir: Path, tmp_path: Path) -> Path:
|
|
181
|
+
"""Fixture that provides a project directory with antd pre-installed."""
|
|
182
|
+
# Create jac.toml with antd dependency
|
|
183
|
+
jac_toml_content = """[project]
|
|
184
|
+
name = "antd-test"
|
|
185
|
+
version = "0.0.1"
|
|
186
|
+
description = "Test project with antd"
|
|
187
|
+
entry-point = "app.jac"
|
|
188
|
+
|
|
189
|
+
[plugins.client.vite.build]
|
|
190
|
+
minify = false
|
|
191
|
+
|
|
192
|
+
[dependencies.npm]
|
|
193
|
+
antd = "^6.0.0"
|
|
194
|
+
"""
|
|
195
|
+
jac_toml = tmp_path / "jac.toml"
|
|
196
|
+
jac_toml.write_text(jac_toml_content)
|
|
197
|
+
|
|
198
|
+
# Copy base .jac-client.configs first for faster install
|
|
199
|
+
source_configs = npm_cache_dir / ".jac-client.configs"
|
|
200
|
+
dest_configs = tmp_path / ".jac-client.configs"
|
|
201
|
+
if source_configs.exists():
|
|
202
|
+
shutil.copytree(source_configs, dest_configs, symlinks=True)
|
|
203
|
+
|
|
204
|
+
# Copy base node_modules for faster install (npm will add antd on top)
|
|
205
|
+
source_node_modules = npm_cache_dir / "node_modules"
|
|
206
|
+
dest_node_modules = tmp_path / "node_modules"
|
|
207
|
+
if source_node_modules.exists():
|
|
208
|
+
shutil.copytree(source_node_modules, dest_node_modules, symlinks=True)
|
|
209
|
+
|
|
210
|
+
# Install antd on top (uses cached node_modules as base)
|
|
211
|
+
jac_cmd = _get_jac_command()
|
|
212
|
+
env = _get_env_with_npm()
|
|
213
|
+
result = subprocess.run(
|
|
214
|
+
[*jac_cmd, "add", "--cl"],
|
|
215
|
+
cwd=tmp_path,
|
|
216
|
+
capture_output=True,
|
|
217
|
+
text=True,
|
|
218
|
+
env=env,
|
|
219
|
+
)
|
|
220
|
+
if result.returncode != 0:
|
|
221
|
+
pytest.skip(f"Failed to install antd: {result.stderr}")
|
|
222
|
+
|
|
223
|
+
# Create required directories
|
|
224
|
+
(tmp_path / "dist").mkdir(exist_ok=True)
|
|
225
|
+
(tmp_path / "compiled").mkdir(exist_ok=True)
|
|
226
|
+
(tmp_path / "build").mkdir(exist_ok=True)
|
|
227
|
+
|
|
228
|
+
return tmp_path
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
@pytest.fixture
|
|
232
|
+
def mock_npm_install():
|
|
233
|
+
"""Fixture that mocks npm install for tests that only test jac.toml manipulation.
|
|
234
|
+
|
|
235
|
+
Use this for CLI tests (add/remove commands) that don't need actual npm packages.
|
|
236
|
+
"""
|
|
237
|
+
with patch(
|
|
238
|
+
"jac_client.plugin.src.package_installer.PackageInstaller._regenerate_and_install"
|
|
239
|
+
) as mock:
|
|
240
|
+
yield mock
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
@pytest.fixture
|
|
244
|
+
def cli_test_dir(tmp_path: Path) -> Path:
|
|
245
|
+
"""Fixture that provides a minimal test directory for CLI tests."""
|
|
246
|
+
return tmp_path
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def create_test_jac_toml(
|
|
250
|
+
path: Path,
|
|
251
|
+
deps: str = "",
|
|
252
|
+
dev_deps: str = "",
|
|
253
|
+
name: str = "test-project",
|
|
254
|
+
) -> Path:
|
|
255
|
+
"""Helper to create a jac.toml file for testing.
|
|
256
|
+
|
|
257
|
+
Args:
|
|
258
|
+
path: Directory to create jac.toml in
|
|
259
|
+
deps: Dependencies to add (TOML format, e.g., 'lodash = "^4.17.21"')
|
|
260
|
+
dev_deps: Dev dependencies to add (TOML format)
|
|
261
|
+
name: Project name
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
Path to the created jac.toml file
|
|
265
|
+
"""
|
|
266
|
+
deps_section = f"\n{deps}" if deps else ""
|
|
267
|
+
dev_deps_section = f"\n{dev_deps}" if dev_deps else ""
|
|
268
|
+
|
|
269
|
+
content = f"""[project]
|
|
270
|
+
name = "{name}"
|
|
271
|
+
version = "1.0.0"
|
|
272
|
+
description = "Test project"
|
|
273
|
+
entry-point = "app.jac"
|
|
274
|
+
|
|
275
|
+
[dependencies.npm]{deps_section}
|
|
276
|
+
|
|
277
|
+
[dev-dependencies.npm]{dev_deps_section}
|
|
278
|
+
"""
|
|
279
|
+
config_path = path / "jac.toml"
|
|
280
|
+
config_path.write_text(content)
|
|
281
|
+
return config_path
|