jac-client 0.2.0__py3-none-any.whl → 0.2.2__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/docs/README.md +50 -20
- jac_client/docs/advanced-state.md +13 -14
- jac_client/docs/asset-serving/intro.md +209 -0
- jac_client/docs/assets/pipe_line-v2.svg +32 -0
- jac_client/docs/file-system/app.jac.md +121 -0
- jac_client/docs/file-system/backend-frontend.md +217 -0
- jac_client/docs/file-system/intro.md +72 -0
- jac_client/docs/file-system/nested-imports.md +348 -0
- jac_client/docs/guide-example/intro.md +11 -13
- jac_client/docs/guide-example/step-01-setup.md +30 -20
- jac_client/docs/guide-example/step-02-components.md +24 -24
- jac_client/docs/guide-example/step-03-styling.md +24 -24
- jac_client/docs/guide-example/step-04-todo-ui.md +17 -17
- jac_client/docs/guide-example/step-05-local-state.md +23 -23
- jac_client/docs/guide-example/step-06-events.md +23 -24
- jac_client/docs/guide-example/step-07-effects.md +27 -28
- jac_client/docs/guide-example/step-08-walkers.md +23 -23
- jac_client/docs/guide-example/step-09-authentication.md +18 -18
- jac_client/docs/guide-example/step-10-routing.md +20 -21
- jac_client/docs/guide-example/step-11-final.md +34 -35
- jac_client/docs/imports.md +4 -5
- jac_client/docs/lifecycle-hooks.md +12 -13
- jac_client/docs/routing.md +21 -22
- jac_client/docs/styling/intro.md +249 -0
- jac_client/docs/styling/js-styling.md +367 -0
- jac_client/docs/styling/material-ui.md +341 -0
- jac_client/docs/styling/pure-css.md +299 -0
- jac_client/docs/styling/sass.md +403 -0
- jac_client/docs/styling/styled-components.md +395 -0
- jac_client/docs/styling/tailwind.md +298 -0
- jac_client/examples/all-in-one/.babelrc +9 -0
- jac_client/examples/all-in-one/README.md +16 -0
- jac_client/examples/all-in-one/app.jac +426 -0
- jac_client/examples/all-in-one/assets/burger.png +0 -0
- jac_client/examples/all-in-one/button.jac +7 -0
- jac_client/examples/all-in-one/components/button.jac +7 -0
- jac_client/examples/all-in-one/package.json +29 -0
- jac_client/examples/all-in-one/styles.css +26 -0
- jac_client/examples/all-in-one/vite.config.js +28 -0
- jac_client/examples/asset-serving/css-with-image/.babelrc +9 -0
- jac_client/examples/asset-serving/css-with-image/README.md +91 -0
- jac_client/examples/asset-serving/css-with-image/app.jac +88 -0
- jac_client/examples/asset-serving/css-with-image/assets/burger.png +0 -0
- jac_client/examples/asset-serving/css-with-image/package.json +28 -0
- jac_client/examples/asset-serving/css-with-image/styles.css +26 -0
- jac_client/examples/asset-serving/css-with-image/vite.config.js +28 -0
- jac_client/examples/asset-serving/image-asset/.babelrc +9 -0
- jac_client/examples/asset-serving/image-asset/README.md +119 -0
- jac_client/examples/asset-serving/image-asset/app.jac +55 -0
- jac_client/examples/asset-serving/image-asset/assets/burger.png +0 -0
- jac_client/examples/asset-serving/image-asset/package.json +28 -0
- jac_client/examples/asset-serving/image-asset/styles.css +26 -0
- jac_client/examples/asset-serving/image-asset/vite.config.js +28 -0
- jac_client/examples/asset-serving/import-alias/.babelrc +9 -0
- jac_client/examples/asset-serving/import-alias/README.md +83 -0
- jac_client/examples/asset-serving/import-alias/app.jac +111 -0
- jac_client/examples/asset-serving/import-alias/assets/burger.png +0 -0
- jac_client/examples/asset-serving/import-alias/package.json +28 -0
- jac_client/examples/asset-serving/import-alias/vite.config.js +28 -0
- jac_client/examples/basic/app.jac +14 -9
- jac_client/examples/basic/package.json +1 -1
- jac_client/examples/basic/vite.config.js +0 -1
- jac_client/examples/basic-auth/package.json +1 -1
- jac_client/examples/basic-auth/vite.config.js +0 -1
- jac_client/examples/basic-auth-with-router/package.json +1 -1
- jac_client/examples/basic-auth-with-router/vite.config.js +0 -1
- jac_client/examples/basic-full-stack/package.json +1 -1
- jac_client/examples/basic-full-stack/vite.config.js +0 -1
- jac_client/examples/css-styling/js-styling/.babelrc +9 -0
- jac_client/examples/css-styling/js-styling/README.md +183 -0
- jac_client/examples/css-styling/js-styling/app.jac +84 -0
- jac_client/examples/css-styling/js-styling/package.json +28 -0
- jac_client/examples/css-styling/js-styling/styles.js +100 -0
- jac_client/examples/css-styling/js-styling/vite.config.js +27 -0
- jac_client/examples/css-styling/material-ui/.babelrc +9 -0
- jac_client/examples/css-styling/material-ui/README.md +16 -0
- jac_client/examples/css-styling/material-ui/app.jac +122 -0
- jac_client/examples/css-styling/material-ui/package.json +32 -0
- jac_client/examples/css-styling/material-ui/vite.config.js +27 -0
- jac_client/examples/css-styling/pure-css/.babelrc +9 -0
- jac_client/examples/css-styling/pure-css/README.md +16 -0
- jac_client/examples/css-styling/pure-css/app.jac +64 -0
- jac_client/examples/css-styling/pure-css/package.json +28 -0
- jac_client/examples/css-styling/pure-css/styles.css +111 -0
- jac_client/examples/css-styling/pure-css/vite.config.js +27 -0
- jac_client/examples/css-styling/sass-example/.babelrc +9 -0
- jac_client/examples/css-styling/sass-example/README.md +16 -0
- jac_client/examples/css-styling/sass-example/app.jac +64 -0
- jac_client/examples/css-styling/sass-example/package.json +29 -0
- jac_client/examples/css-styling/sass-example/styles.scss +153 -0
- jac_client/examples/css-styling/sass-example/vite.config.js +27 -0
- jac_client/examples/css-styling/styled-components/.babelrc +9 -0
- jac_client/examples/css-styling/styled-components/README.md +16 -0
- jac_client/examples/css-styling/styled-components/app.jac +71 -0
- jac_client/examples/css-styling/styled-components/package.json +29 -0
- jac_client/examples/css-styling/styled-components/styled.js +90 -0
- jac_client/examples/css-styling/styled-components/vite.config.js +27 -0
- jac_client/examples/css-styling/tailwind-example/.babelrc +9 -0
- jac_client/examples/css-styling/tailwind-example/README.md +16 -0
- jac_client/examples/css-styling/tailwind-example/app.jac +63 -0
- jac_client/examples/css-styling/tailwind-example/global.css +1 -0
- jac_client/examples/css-styling/tailwind-example/package.json +30 -0
- jac_client/examples/css-styling/tailwind-example/vite.config.js +29 -0
- jac_client/examples/full-stack-with-auth/app.jac +20 -33
- jac_client/examples/full-stack-with-auth/package.json +1 -1
- jac_client/examples/full-stack-with-auth/vite.config.js +0 -1
- jac_client/examples/little-x/app.jac +327 -218
- jac_client/examples/little-x/submit-button.jac +1 -1
- jac_client/examples/nested-folders/nested-advance/.babelrc +9 -0
- jac_client/examples/nested-folders/nested-advance/ButtonRoot.jac +11 -0
- jac_client/examples/nested-folders/nested-advance/README.md +77 -0
- jac_client/examples/nested-folders/nested-advance/app.jac +35 -0
- jac_client/examples/nested-folders/nested-advance/level1/ButtonSecondL.jac +19 -0
- jac_client/examples/nested-folders/nested-advance/level1/Card.jac +43 -0
- jac_client/examples/nested-folders/nested-advance/level1/level2/ButtonThirdL.jac +25 -0
- jac_client/examples/nested-folders/nested-advance/package.json +29 -0
- jac_client/examples/nested-folders/nested-advance/vite.config.js +28 -0
- jac_client/examples/nested-folders/nested-basic/.babelrc +9 -0
- jac_client/examples/nested-folders/nested-basic/README.md +183 -0
- jac_client/examples/nested-folders/nested-basic/app.jac +13 -0
- jac_client/examples/nested-folders/nested-basic/app.js +7 -0
- jac_client/examples/nested-folders/nested-basic/button.jac +7 -0
- jac_client/examples/nested-folders/nested-basic/components/button.jac +7 -0
- jac_client/examples/nested-folders/nested-basic/package.json +28 -0
- jac_client/examples/nested-folders/nested-basic/vite.config.js +27 -0
- jac_client/examples/with-router/app.jac +1 -1
- jac_client/examples/with-router/package.json +1 -1
- jac_client/examples/with-router/vite.config.js +0 -1
- jac_client/plugin/cli.py +7 -2
- jac_client/plugin/client.py +68 -5
- jac_client/plugin/client_runtime.jac +1 -1
- jac_client/plugin/vite_client_bundle.py +162 -14
- jac_client/tests/__init__.py +0 -1
- jac_client/tests/fixtures/basic-app/app.jac +7 -2
- jac_client/tests/fixtures/cl_file/app.cl.jac +48 -0
- jac_client/tests/fixtures/cl_file/app.jac +15 -0
- jac_client/tests/fixtures/client_app_with_antd/app.jac +14 -8
- jac_client/tests/fixtures/js_import/app.jac +19 -15
- jac_client/tests/fixtures/js_import/utils.js +0 -1
- jac_client/tests/fixtures/package.json +1 -1
- jac_client/tests/fixtures/relative_import/app.jac +4 -6
- jac_client/tests/fixtures/relative_import/button.jac +7 -6
- jac_client/tests/fixtures/spawn_test/app.jac +1 -5
- jac_client/tests/fixtures/test_fragments_spread/app.jac +24 -10
- jac_client/tests/test_asset_examples.py +322 -0
- jac_client/tests/test_cl.py +480 -426
- jac_client/tests/test_create_jac_app.py +125 -133
- jac_client/tests/test_it.py +329 -0
- jac_client/tests/test_nested_file.py +374 -0
- {jac_client-0.2.0.dist-info → jac_client-0.2.2.dist-info}/METADATA +2 -2
- jac_client-0.2.2.dist-info/RECORD +171 -0
- jac_client-0.2.0.dist-info/RECORD +0 -72
- {jac_client-0.2.0.dist-info → jac_client-0.2.2.dist-info}/WHEEL +0 -0
- {jac_client-0.2.0.dist-info → jac_client-0.2.2.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Pages
|
|
2
|
+
cl import from react { useState, useEffect }
|
|
3
|
+
cl import ".styles.css";
|
|
4
|
+
|
|
5
|
+
cl {
|
|
6
|
+
def app() -> any {
|
|
7
|
+
let [count, setCount] = useState(0);
|
|
8
|
+
useEffect(lambda -> None{ console.log("Count: ", count);} , [count]);
|
|
9
|
+
return <div
|
|
10
|
+
style={{
|
|
11
|
+
padding: "20px",
|
|
12
|
+
textAlign: "center",
|
|
13
|
+
fontFamily: "Arial, sans-serif"
|
|
14
|
+
}}
|
|
15
|
+
>
|
|
16
|
+
<h1>
|
|
17
|
+
🍔 Burger Counter App
|
|
18
|
+
</h1>
|
|
19
|
+
<img
|
|
20
|
+
src="/static/assets/burger.png"
|
|
21
|
+
alt="Delicious Burger"
|
|
22
|
+
style={{
|
|
23
|
+
width: "200px",
|
|
24
|
+
height: "auto",
|
|
25
|
+
margin: "20px 0",
|
|
26
|
+
borderRadius: "10px",
|
|
27
|
+
boxShadow: "0 4px 8px rgba(0,0,0,0.2)"
|
|
28
|
+
}}
|
|
29
|
+
/>
|
|
30
|
+
<p
|
|
31
|
+
style={{fontSize: "18px", margin: "20px 0"}}
|
|
32
|
+
>
|
|
33
|
+
You've clicked the burger
|
|
34
|
+
<strong>
|
|
35
|
+
{count}
|
|
36
|
+
</strong>
|
|
37
|
+
times!
|
|
38
|
+
</p>
|
|
39
|
+
<button
|
|
40
|
+
onClick={lambda e: any -> None{ setCount(count + 1);} }
|
|
41
|
+
style={{
|
|
42
|
+
padding: "10px 20px",
|
|
43
|
+
fontSize: "16px",
|
|
44
|
+
backgroundColor: "#ff6b35",
|
|
45
|
+
color: "white",
|
|
46
|
+
border: "none",
|
|
47
|
+
borderRadius: "5px",
|
|
48
|
+
cursor: "pointer",
|
|
49
|
+
boxShadow: "0 2px 4px rgba(0,0,0,0.2)"
|
|
50
|
+
}}
|
|
51
|
+
>
|
|
52
|
+
Click the Burger! 🍔
|
|
53
|
+
</button>
|
|
54
|
+
<h2
|
|
55
|
+
style={{marginTop: "40px", marginBottom: "20px"}}
|
|
56
|
+
>
|
|
57
|
+
CSS Asset Examples
|
|
58
|
+
</h2>
|
|
59
|
+
<div className="container">
|
|
60
|
+
<h3
|
|
61
|
+
style={{color: "white", textShadow: "2px 2px 4px rgba(0,0,0,0.5)"}}
|
|
62
|
+
>
|
|
63
|
+
Background Image Example
|
|
64
|
+
</h3>
|
|
65
|
+
<p
|
|
66
|
+
style={{color: "white", textShadow: "2px 2px 4px rgba(0,0,0,0.5)"}}
|
|
67
|
+
>
|
|
68
|
+
This container uses the burger image as a background via CSS
|
|
69
|
+
</p>
|
|
70
|
+
</div>
|
|
71
|
+
<div className="card">
|
|
72
|
+
<h3>
|
|
73
|
+
Image in Card
|
|
74
|
+
</h3>
|
|
75
|
+
<img
|
|
76
|
+
src="/static/assets/burger.png"
|
|
77
|
+
alt="Burger in Card"
|
|
78
|
+
className="burgerImage"
|
|
79
|
+
/>
|
|
80
|
+
<p
|
|
81
|
+
style={{marginTop: "15px", color: "#666"}}
|
|
82
|
+
>
|
|
83
|
+
This image is displayed within a styled card using CSS classes
|
|
84
|
+
</p>
|
|
85
|
+
</div>
|
|
86
|
+
</div>;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "relative-imports",
|
|
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: relative-imports",
|
|
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
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
background-image: url('/static/assets/burger.png');
|
|
3
|
+
background-size: cover;
|
|
4
|
+
background-position: center;
|
|
5
|
+
min-height: 300px;
|
|
6
|
+
border-radius: 10px;
|
|
7
|
+
padding: 20px;
|
|
8
|
+
margin: 20px 0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.card {
|
|
12
|
+
background: white;
|
|
13
|
+
border-radius: 10px;
|
|
14
|
+
padding: 20px;
|
|
15
|
+
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
|
|
16
|
+
max-width: 400px;
|
|
17
|
+
margin: 20px auto;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.burgerImage {
|
|
21
|
+
width: 200px;
|
|
22
|
+
height: auto;
|
|
23
|
+
border-radius: 10px;
|
|
24
|
+
display: block;
|
|
25
|
+
margin: 0 auto;
|
|
26
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
"@jac-client/assets": path.resolve(__dirname, "src/assets"),
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
});
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Static Path Example
|
|
2
|
+
|
|
3
|
+
This example demonstrates how to serve static assets using direct `/static/` path references.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Direct path references using `/static/assets/` URLs
|
|
8
|
+
- Simple and straightforward approach
|
|
9
|
+
- No build configuration required
|
|
10
|
+
- Works immediately without imports
|
|
11
|
+
|
|
12
|
+
## Project Structure
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
image-asset/
|
|
16
|
+
├── app.jac # Main application file
|
|
17
|
+
├── assets/ # Static assets directory
|
|
18
|
+
│ └── burger.png # Burger image
|
|
19
|
+
├── src/ # Source files (generated)
|
|
20
|
+
├── build/ # Build output (generated)
|
|
21
|
+
└── dist/ # Distribution output (generated)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Running the Example
|
|
25
|
+
|
|
26
|
+
1. Make sure node modules are installed:
|
|
27
|
+
```bash
|
|
28
|
+
npm install
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
2. Run the Jac server:
|
|
32
|
+
```bash
|
|
33
|
+
jac serve app.jac
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
3. Open your browser and navigate to:
|
|
37
|
+
```
|
|
38
|
+
http://localhost:8000/page/app
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## How It Works
|
|
42
|
+
|
|
43
|
+
### Static Path Syntax
|
|
44
|
+
|
|
45
|
+
```jac
|
|
46
|
+
<img src="/static/assets/burger.png" alt="Burger" />
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Server Configuration
|
|
50
|
+
|
|
51
|
+
The server automatically serves files from:
|
|
52
|
+
- `dist/` directory (Vite-bundled assets)
|
|
53
|
+
- `assets/` directory (user-provided static assets)
|
|
54
|
+
|
|
55
|
+
Both directories are checked when serving `/static/*` requests.
|
|
56
|
+
|
|
57
|
+
### Path Resolution
|
|
58
|
+
|
|
59
|
+
1. Request: `/static/assets/burger.png`
|
|
60
|
+
2. Server checks `dist/assets/burger.png` first
|
|
61
|
+
3. If not found, checks `assets/burger.png`
|
|
62
|
+
4. Serves file with appropriate MIME type
|
|
63
|
+
5. Sets cache headers for optimal performance
|
|
64
|
+
|
|
65
|
+
### Benefits
|
|
66
|
+
|
|
67
|
+
- **Simplicity**: No imports or build configuration needed
|
|
68
|
+
- **Immediate**: Works right away without build step
|
|
69
|
+
- **Flexible**: Easy to reference assets from anywhere
|
|
70
|
+
- **Quick Prototyping**: Perfect for rapid development
|
|
71
|
+
|
|
72
|
+
### Use Cases
|
|
73
|
+
|
|
74
|
+
**Direct Image References:**
|
|
75
|
+
```jac
|
|
76
|
+
<img src="/static/assets/logo.png" alt="Logo" />
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**CSS Background Images:**
|
|
80
|
+
```jac
|
|
81
|
+
<div style={{backgroundImage: "url('/static/assets/hero.jpg')"}} />
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Dynamic Asset Paths:**
|
|
85
|
+
```jac
|
|
86
|
+
let imagePath = `/static/assets/${imageName}.png`;
|
|
87
|
+
<img src={imagePath} />
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Best Practices
|
|
91
|
+
|
|
92
|
+
1. Use this method for quick prototypes
|
|
93
|
+
2. Organize assets in the `assets/` folder
|
|
94
|
+
3. Use descriptive file names
|
|
95
|
+
4. Keep assets reasonably sized
|
|
96
|
+
5. Consider using imports for production apps
|
|
97
|
+
|
|
98
|
+
## Limitations
|
|
99
|
+
|
|
100
|
+
- No automatic optimization
|
|
101
|
+
- No hash-based cache busting
|
|
102
|
+
- Manual cache control required
|
|
103
|
+
- No type safety for asset paths
|
|
104
|
+
|
|
105
|
+
## When to Use
|
|
106
|
+
|
|
107
|
+
**Choose Static Path if:**
|
|
108
|
+
- Building a quick prototype
|
|
109
|
+
- Assets don't need optimization
|
|
110
|
+
- Want immediate results
|
|
111
|
+
- Working with simple, small assets
|
|
112
|
+
|
|
113
|
+
**Consider Import Methods if:**
|
|
114
|
+
- Building for production
|
|
115
|
+
- Need automatic optimization
|
|
116
|
+
- Want cache busting
|
|
117
|
+
- Prefer type-safe references
|
|
118
|
+
|
|
119
|
+
Happy coding with Jac! 🍔
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Pages
|
|
2
|
+
cl import from react { useState, useEffect }
|
|
3
|
+
|
|
4
|
+
cl {
|
|
5
|
+
def app() -> any {
|
|
6
|
+
let [count, setCount] = useState(0);
|
|
7
|
+
useEffect(lambda -> None{ console.log("Count: ", count);} , [count]);
|
|
8
|
+
return <div
|
|
9
|
+
style={{
|
|
10
|
+
padding: "20px",
|
|
11
|
+
textAlign: "center",
|
|
12
|
+
fontFamily: "Arial, sans-serif"
|
|
13
|
+
}}
|
|
14
|
+
>
|
|
15
|
+
<h1>
|
|
16
|
+
🍔 Burger Counter App
|
|
17
|
+
</h1>
|
|
18
|
+
<img
|
|
19
|
+
src="/static/assets/burger.png"
|
|
20
|
+
alt="Delicious Burger"
|
|
21
|
+
style={{
|
|
22
|
+
width: "200px",
|
|
23
|
+
height: "auto",
|
|
24
|
+
margin: "20px 0",
|
|
25
|
+
borderRadius: "10px",
|
|
26
|
+
boxShadow: "0 4px 8px rgba(0,0,0,0.2)"
|
|
27
|
+
}}
|
|
28
|
+
/>
|
|
29
|
+
<p
|
|
30
|
+
style={{fontSize: "18px", margin: "20px 0"}}
|
|
31
|
+
>
|
|
32
|
+
You've clicked the burger
|
|
33
|
+
<strong>
|
|
34
|
+
{count}
|
|
35
|
+
</strong>
|
|
36
|
+
times!
|
|
37
|
+
</p>
|
|
38
|
+
<button
|
|
39
|
+
onClick={lambda e: any -> None{ setCount(count + 1);} }
|
|
40
|
+
style={{
|
|
41
|
+
padding: "10px 20px",
|
|
42
|
+
fontSize: "16px",
|
|
43
|
+
backgroundColor: "#ff6b35",
|
|
44
|
+
color: "white",
|
|
45
|
+
border: "none",
|
|
46
|
+
borderRadius: "5px",
|
|
47
|
+
cursor: "pointer",
|
|
48
|
+
boxShadow: "0 2px 4px rgba(0,0,0,0.2)"
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
Click the Burger! 🍔
|
|
52
|
+
</button>
|
|
53
|
+
</div>;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "image-asset",
|
|
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: image-asset",
|
|
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
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
background-image: url('/static/assets/burger.png');
|
|
3
|
+
background-size: cover;
|
|
4
|
+
background-position: center;
|
|
5
|
+
min-height: 300px;
|
|
6
|
+
border-radius: 10px;
|
|
7
|
+
padding: 20px;
|
|
8
|
+
margin: 20px 0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.card {
|
|
12
|
+
background: white;
|
|
13
|
+
border-radius: 10px;
|
|
14
|
+
padding: 20px;
|
|
15
|
+
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
|
|
16
|
+
max-width: 400px;
|
|
17
|
+
margin: 20px auto;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.burgerImage {
|
|
21
|
+
width: 200px;
|
|
22
|
+
height: auto;
|
|
23
|
+
border-radius: 10px;
|
|
24
|
+
display: block;
|
|
25
|
+
margin: 0 auto;
|
|
26
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
"@jac-client/assets": path.resolve(__dirname, "src/assets"),
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Import Alias Example
|
|
2
|
+
|
|
3
|
+
This example demonstrates how to import static assets using the `@jac-client/assets` alias pattern.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Imports image using `@jac-client/assets` alias
|
|
8
|
+
- Vite processes and optimizes the asset
|
|
9
|
+
- Automatic hash generation for cache busting
|
|
10
|
+
- Type-safe asset references
|
|
11
|
+
|
|
12
|
+
## Project Structure
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
import-alias/
|
|
16
|
+
├── app.jac # Main application file
|
|
17
|
+
├── assets/ # Static assets directory
|
|
18
|
+
│ └── burger.png # Burger image
|
|
19
|
+
├── src/ # Source files (generated)
|
|
20
|
+
├── build/ # Build output (generated)
|
|
21
|
+
└── dist/ # Distribution output (generated)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Running the Example
|
|
25
|
+
|
|
26
|
+
1. Make sure node modules are installed:
|
|
27
|
+
```bash
|
|
28
|
+
npm install
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
2. Run the Jac server:
|
|
32
|
+
```bash
|
|
33
|
+
jac serve app.jac
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
3. Open your browser and navigate to:
|
|
37
|
+
```
|
|
38
|
+
http://localhost:8000/page/app
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## How It Works
|
|
42
|
+
|
|
43
|
+
### Import Syntax
|
|
44
|
+
|
|
45
|
+
```jac
|
|
46
|
+
cl import from "@jac-client/assets/burger.png" { default as burgerImage }
|
|
47
|
+
<img src={burgerImage} />
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Configuration
|
|
51
|
+
|
|
52
|
+
The alias is configured in `vite.config.js`:
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
resolve: {
|
|
56
|
+
alias: {
|
|
57
|
+
"@jac-client/assets": path.resolve(__dirname, "src/assets"),
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Build Process
|
|
63
|
+
|
|
64
|
+
1. Assets from root `assets/` folder are copied to `src/assets/` during build
|
|
65
|
+
2. Vite processes the import and generates optimized asset URLs
|
|
66
|
+
3. Assets are bundled with hash-based filenames for cache invalidation
|
|
67
|
+
4. The imported variable contains the processed asset URL
|
|
68
|
+
|
|
69
|
+
### Benefits
|
|
70
|
+
|
|
71
|
+
- **Type Safety**: Import errors caught at build time
|
|
72
|
+
- **Optimization**: Vite automatically optimizes assets
|
|
73
|
+
- **Cache Busting**: Hash-based filenames prevent stale cache
|
|
74
|
+
- **Code Splitting**: Assets can be code-split automatically
|
|
75
|
+
|
|
76
|
+
## Best Practices
|
|
77
|
+
|
|
78
|
+
1. Use this method for production applications
|
|
79
|
+
2. Organize assets in the `assets/` folder
|
|
80
|
+
3. Let Vite handle optimization and caching
|
|
81
|
+
4. Use descriptive variable names for imported assets
|
|
82
|
+
|
|
83
|
+
Happy coding with Jac! 🍔
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Pages
|
|
2
|
+
cl import from react { useState, useEffect }
|
|
3
|
+
# Import image using the @jac-client/assets alias
|
|
4
|
+
cl import from "@jac-client/assets/burger.png" {
|
|
5
|
+
default as burgerImage
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
cl {
|
|
9
|
+
def app() -> any {
|
|
10
|
+
let [count, setCount] = useState(0);
|
|
11
|
+
useEffect(lambda -> None{ console.log("Count: ", count);} , [count]);
|
|
12
|
+
return <div
|
|
13
|
+
style={{
|
|
14
|
+
padding: "20px",
|
|
15
|
+
textAlign: "center",
|
|
16
|
+
fontFamily: "Arial, sans-serif"
|
|
17
|
+
}}
|
|
18
|
+
>
|
|
19
|
+
<h1>
|
|
20
|
+
🍔 Import Alias Example
|
|
21
|
+
</h1>
|
|
22
|
+
<p
|
|
23
|
+
style={{color: "#666", marginBottom: "20px"}}
|
|
24
|
+
>
|
|
25
|
+
Using
|
|
26
|
+
<code>
|
|
27
|
+
@jac-client/assets
|
|
28
|
+
</code>
|
|
29
|
+
alias to import assets
|
|
30
|
+
</p>
|
|
31
|
+
<img
|
|
32
|
+
src={burgerImage}
|
|
33
|
+
alt="Delicious Burger"
|
|
34
|
+
style={{
|
|
35
|
+
width: "200px",
|
|
36
|
+
height: "auto",
|
|
37
|
+
margin: "20px 0",
|
|
38
|
+
borderRadius: "10px",
|
|
39
|
+
boxShadow: "0 4px 8px rgba(0,0,0,0.2)"
|
|
40
|
+
}}
|
|
41
|
+
/>
|
|
42
|
+
<p
|
|
43
|
+
style={{fontSize: "18px", margin: "20px 0"}}
|
|
44
|
+
>
|
|
45
|
+
You've clicked the burger
|
|
46
|
+
<strong>
|
|
47
|
+
{count}
|
|
48
|
+
</strong>
|
|
49
|
+
times!
|
|
50
|
+
</p>
|
|
51
|
+
<button
|
|
52
|
+
onClick={lambda e: any -> None{ setCount(count + 1);} }
|
|
53
|
+
style={{
|
|
54
|
+
padding: "10px 20px",
|
|
55
|
+
fontSize: "16px",
|
|
56
|
+
backgroundColor: "#ff6b35",
|
|
57
|
+
color: "white",
|
|
58
|
+
border: "none",
|
|
59
|
+
borderRadius: "5px",
|
|
60
|
+
cursor: "pointer",
|
|
61
|
+
boxShadow: "0 2px 4px rgba(0,0,0,0.2)"
|
|
62
|
+
}}
|
|
63
|
+
>
|
|
64
|
+
Click the Burger! 🍔
|
|
65
|
+
</button>
|
|
66
|
+
<div
|
|
67
|
+
style={{
|
|
68
|
+
marginTop: "30px",
|
|
69
|
+
padding: "15px",
|
|
70
|
+
backgroundColor: "#f5f5f5",
|
|
71
|
+
borderRadius: "5px",
|
|
72
|
+
fontSize: "12px",
|
|
73
|
+
textAlign: "left",
|
|
74
|
+
maxWidth: "600px",
|
|
75
|
+
margin: "30px auto"
|
|
76
|
+
}}
|
|
77
|
+
>
|
|
78
|
+
<strong>
|
|
79
|
+
How it works:
|
|
80
|
+
</strong>
|
|
81
|
+
<ul
|
|
82
|
+
style={{marginTop: "10px", paddingLeft: "20px"}}
|
|
83
|
+
>
|
|
84
|
+
<li>
|
|
85
|
+
Import using:
|
|
86
|
+
<code>
|
|
87
|
+
cl import from '@jac-client/assets/burger.png'
|
|
88
|
+
</code>
|
|
89
|
+
</li>
|
|
90
|
+
<li>
|
|
91
|
+
Vite processes the import and generates optimized URLs
|
|
92
|
+
</li>
|
|
93
|
+
<li>
|
|
94
|
+
Assets are automatically copied from
|
|
95
|
+
<code>
|
|
96
|
+
assets/
|
|
97
|
+
</code>
|
|
98
|
+
to
|
|
99
|
+
<code>
|
|
100
|
+
src/assets/
|
|
101
|
+
</code>
|
|
102
|
+
during build
|
|
103
|
+
</li>
|
|
104
|
+
<li>
|
|
105
|
+
Automatic hash generation for cache busting
|
|
106
|
+
</li>
|
|
107
|
+
</ul>
|
|
108
|
+
</div>
|
|
109
|
+
</div>;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "import-alias",
|
|
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: import-alias",
|
|
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
|
+
}
|