jac-client 0.2.10__py3-none-any.whl → 0.2.12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jac_client/examples/all-in-one/button.jac +4 -3
- jac_client/examples/all-in-one/components/CategoryFilter.jac +36 -24
- jac_client/examples/all-in-one/components/Header.jac +12 -8
- jac_client/examples/all-in-one/components/ProfitOverview.jac +49 -35
- jac_client/examples/all-in-one/components/Summary.jac +59 -36
- jac_client/examples/all-in-one/components/TransactionForm.jac +142 -112
- jac_client/examples/all-in-one/components/TransactionItem.jac +37 -30
- jac_client/examples/all-in-one/components/TransactionList.jac +33 -26
- jac_client/examples/all-in-one/components/button.jac +4 -3
- jac_client/examples/all-in-one/components/navigation.jac +111 -117
- jac_client/examples/all-in-one/constants/categories.jac +23 -24
- jac_client/examples/all-in-one/constants/clients.jac +7 -8
- jac_client/examples/all-in-one/context/BudgetContext.jac +9 -6
- jac_client/examples/all-in-one/hooks/useBudget.jac +18 -12
- jac_client/examples/all-in-one/hooks/useLocalStorage.jac +14 -13
- jac_client/examples/all-in-one/main.jac +340 -371
- jac_client/examples/all-in-one/pages/BudgetPlanner.jac +19 -12
- jac_client/examples/all-in-one/pages/FeaturesTest.jac +31 -15
- jac_client/examples/all-in-one/pages/LandingPage.jac +113 -90
- jac_client/examples/all-in-one/pages/budget_planner_ui.cl.jac +34 -39
- jac_client/examples/all-in-one/pages/features_test_ui.cl.jac +464 -352
- jac_client/examples/all-in-one/pages/loginPage.jac +114 -119
- jac_client/examples/all-in-one/pages/nestedDemo.jac +43 -50
- jac_client/examples/all-in-one/pages/notFound.jac +14 -15
- jac_client/examples/all-in-one/pages/signupPage.jac +113 -119
- jac_client/examples/all-in-one/utils/formatters.jac +5 -8
- jac_client/examples/asset-serving/css-with-image/main.jac +77 -73
- jac_client/examples/asset-serving/image-asset/main.jac +47 -46
- jac_client/examples/asset-serving/import-alias/main.jac +93 -95
- jac_client/examples/basic/main.jac +17 -15
- jac_client/examples/basic-auth/main.jac +246 -254
- jac_client/examples/basic-auth-with-router/main.jac +272 -285
- jac_client/examples/basic-full-stack/main.jac +245 -242
- jac_client/examples/css-styling/js-styling/main.jac +41 -62
- jac_client/examples/css-styling/material-ui/main.jac +90 -90
- jac_client/examples/css-styling/pure-css/main.jac +35 -44
- jac_client/examples/css-styling/sass-example/main.jac +35 -44
- jac_client/examples/css-styling/styled-components/main.jac +38 -47
- jac_client/examples/css-styling/tailwind-example/main.jac +54 -43
- jac_client/examples/full-stack-with-auth/main.jac +407 -433
- jac_client/examples/little-x/main.jac +306 -344
- jac_client/examples/little-x/src/submit-button.jac +15 -14
- jac_client/examples/nested-folders/nested-advance/main.jac +18 -27
- jac_client/examples/nested-folders/nested-advance/src/ButtonRoot.jac +4 -6
- jac_client/examples/nested-folders/nested-advance/src/level1/ButtonSecondL.jac +9 -13
- jac_client/examples/nested-folders/nested-advance/src/level1/Card.jac +29 -32
- jac_client/examples/nested-folders/nested-advance/src/level1/level2/ButtonThirdL.jac +12 -18
- jac_client/examples/nested-folders/nested-basic/main.jac +7 -5
- jac_client/examples/nested-folders/nested-basic/src/button.jac +4 -3
- jac_client/examples/nested-folders/nested-basic/src/components/button.jac +4 -3
- jac_client/examples/ts-support/main.jac +26 -26
- jac_client/examples/with-router/main.jac +186 -223
- jac_client/plugin/client_runtime.cl.jac +5 -3
- jac_client/plugin/impl/client_runtime.impl.jac +1 -1
- jac_client/plugin/plugin_config.jac +53 -99
- jac_client/plugin/src/__init__.jac +0 -2
- jac_client/plugin/src/compiler.jac +0 -1
- jac_client/plugin/src/impl/compiler.impl.jac +49 -17
- jac_client/plugin/src/impl/jac_to_js.impl.jac +5 -1
- jac_client/plugin/src/impl/package_installer.impl.jac +20 -20
- jac_client/plugin/src/impl/vite_bundler.impl.jac +146 -84
- jac_client/plugin/src/targets/impl/desktop_target.impl.jac +54 -41
- jac_client/plugin/utils/__init__.jac +3 -0
- jac_client/plugin/utils/bun_installer.jac +16 -0
- jac_client/plugin/utils/client_deps.jac +14 -0
- jac_client/plugin/utils/impl/bun_installer.impl.jac +99 -0
- jac_client/plugin/utils/impl/client_deps.impl.jac +73 -0
- jac_client/templates/client.jacpack +0 -4
- jac_client/templates/fullstack.jacpack +1 -5
- jac_client/tests/conftest.py +56 -41
- jac_client/tests/fixtures/spawn_test/app.jac +49 -52
- jac_client/tests/fixtures/with-ts/app.jac +27 -27
- jac_client/tests/test_cli.py +71 -6
- jac_client/tests/test_helpers.py +11 -18
- jac_client/tests/test_it.py +1 -1
- {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/METADATA +5 -5
- jac_client-0.2.12.dist-info/RECORD +115 -0
- {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/WHEEL +1 -1
- jac_client/plugin/src/babel_processor.jac +0 -18
- jac_client/plugin/src/impl/babel_processor.impl.jac +0 -89
- jac_client/plugin/utils/impl/node_installer.impl.jac +0 -249
- jac_client/plugin/utils/node_installer.jac +0 -41
- jac_client-0.2.10.dist-info/RECORD +0 -115
- {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/entry_points.txt +0 -0
- {jac_client-0.2.10.dist-info → jac_client-0.2.12.dist-info}/top_level.txt +0 -0
|
@@ -6,14 +6,16 @@
|
|
|
6
6
|
# This demonstrates that you can have separate .jac files for different purposes
|
|
7
7
|
# Features Test - Backend Walkers
|
|
8
8
|
# This file demonstrates walker functionality for testing various JAC features
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
import from datetime {
|
|
10
|
+
datetime,
|
|
11
|
+
timedelta
|
|
12
|
+
}
|
|
11
13
|
|
|
12
14
|
# Node definition for storing test data
|
|
13
15
|
node TestData {
|
|
14
|
-
has message: str
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
has message: str,
|
|
17
|
+
count: int = 0,
|
|
18
|
+
created_at: str = "";
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
# Walker: Create test data
|
|
@@ -106,12 +108,14 @@ walker process_complex_data {
|
|
|
106
108
|
can process with `root entry {
|
|
107
109
|
processed = [];
|
|
108
110
|
for item in self.items {
|
|
109
|
-
processed.append(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
processed.append(
|
|
112
|
+
{
|
|
113
|
+
"id": item.get("id", 0),
|
|
114
|
+
"name": item.get("name", "").upper(),
|
|
115
|
+
"value": item.get("value", 0) * 2,
|
|
116
|
+
"processed_at": datetime.now().strftime("%H:%M:%S")
|
|
117
|
+
}
|
|
118
|
+
);
|
|
115
119
|
}
|
|
116
120
|
|
|
117
121
|
result = {
|
|
@@ -129,5 +133,8 @@ walker process_complex_data {
|
|
|
129
133
|
cl {
|
|
130
134
|
import from .budget_planner_ui { BudgetPlanner as BudgetPlannerUI }
|
|
131
135
|
|
|
132
|
-
def:pub BudgetPlanner -> any {
|
|
136
|
+
def:pub BudgetPlanner -> any {
|
|
137
|
+
return
|
|
138
|
+
<BudgetPlannerUI />;
|
|
139
|
+
}
|
|
133
140
|
}
|
|
@@ -6,14 +6,16 @@
|
|
|
6
6
|
# This demonstrates that you can have separate .jac files for different purposes
|
|
7
7
|
# Features Test - Backend Walkers
|
|
8
8
|
# This file demonstrates walker functionality for testing various JAC features
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
import from datetime {
|
|
10
|
+
datetime,
|
|
11
|
+
timedelta
|
|
12
|
+
}
|
|
11
13
|
|
|
12
14
|
# Node definition for storing test data
|
|
13
15
|
node TestData {
|
|
14
|
-
has message: str
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
has message: str,
|
|
17
|
+
count: int = 0,
|
|
18
|
+
created_at: str = "";
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
# Walker: Create test data
|
|
@@ -106,12 +108,14 @@ walker process_complex_data {
|
|
|
106
108
|
can process with `root entry {
|
|
107
109
|
processed = [];
|
|
108
110
|
for item in self.items {
|
|
109
|
-
processed.append(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
processed.append(
|
|
112
|
+
{
|
|
113
|
+
"id": item.get("id", 0),
|
|
114
|
+
"name": item.get("name", "").upper(),
|
|
115
|
+
"value": item.get("value", 0) * 2,
|
|
116
|
+
"processed_at": datetime.now().strftime("%H:%M:%S")
|
|
117
|
+
}
|
|
118
|
+
);
|
|
115
119
|
}
|
|
116
120
|
|
|
117
121
|
result = {
|
|
@@ -134,8 +138,20 @@ cl {
|
|
|
134
138
|
ResultDisplay as ResultDisplayUI
|
|
135
139
|
}
|
|
136
140
|
|
|
137
|
-
def:pub FeaturesTest -> any {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
+
def:pub FeaturesTest -> any {
|
|
142
|
+
return
|
|
143
|
+
<FeaturesTestUI />;
|
|
144
|
+
}
|
|
145
|
+
def:pub TestButton(text: str, onClick: any, variant: str) -> any {
|
|
146
|
+
return
|
|
147
|
+
<TestButtonUI text={text} onClick={onClick} variant={variant} />;
|
|
148
|
+
}
|
|
149
|
+
def:pub TestCard(title: str, children: any, color: str) -> any {
|
|
150
|
+
return
|
|
151
|
+
<TestCardUI title={title} children={children} color={color} />;
|
|
152
|
+
}
|
|
153
|
+
def:pub ResultDisplay(data: any, label: str) -> any {
|
|
154
|
+
return
|
|
155
|
+
<ResultDisplayUI data={data} label={label} />;
|
|
156
|
+
}
|
|
141
157
|
}
|
|
@@ -1,101 +1,124 @@
|
|
|
1
1
|
# Landing Page - Ledgerly Brand
|
|
2
2
|
# Professional landing page with hero, features, and CTA sections
|
|
3
3
|
# Demonstrates: routing with Link, dark theme design, responsive layout
|
|
4
|
-
cl import from "@jac
|
|
4
|
+
cl import from "@jac/runtime" {
|
|
5
5
|
Link,
|
|
6
|
-
|
|
7
6
|
}
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
8
|
cl {
|
|
12
|
-
def:pub LandingPage
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
<p className="subheadline">
|
|
22
|
-
Built for freelancers who need to see their true income
|
|
23
|
-
after taxes and business expenses.
|
|
24
|
-
</p>
|
|
25
|
-
|
|
26
|
-
<div style={{"display": "flex", "gap": "15px", "justifyContent": "center"}}>
|
|
27
|
-
<Link to="/app">
|
|
28
|
-
<button className="cta-button">
|
|
29
|
-
Let's Plan
|
|
30
|
-
</button>
|
|
31
|
-
</Link>
|
|
32
|
-
<Link to="/features">
|
|
33
|
-
<button className="cta-button" style={{
|
|
34
|
-
"backgroundColor": "#8b5cf6",
|
|
35
|
-
"border": "2px solid #8b5cf6"
|
|
36
|
-
}}>
|
|
37
|
-
Test Features
|
|
38
|
-
</button>
|
|
39
|
-
</Link>
|
|
40
|
-
</div>
|
|
41
|
-
</section>
|
|
42
|
-
|
|
43
|
-
<section className="features-section">
|
|
44
|
-
<h2 className="features-title">Built for Freelancers</h2>
|
|
45
|
-
|
|
46
|
-
<div className="features-grid">
|
|
47
|
-
<div className="feature-card">
|
|
48
|
-
<div className="feature-icon">💼</div>
|
|
49
|
-
<h3 className="feature-title">Business vs Personal</h3>
|
|
50
|
-
<p className="feature-description">
|
|
51
|
-
Tag every transaction as business or personal.
|
|
52
|
-
See your income streams separately and understand where your money really comes from.
|
|
9
|
+
def:pub LandingPage -> any {
|
|
10
|
+
return
|
|
11
|
+
<div className="landing-container">
|
|
12
|
+
<section className="hero-section">
|
|
13
|
+
<h1 className="brand-name">
|
|
14
|
+
Ledgerly
|
|
15
|
+
</h1>
|
|
16
|
+
<p className="tagline">
|
|
17
|
+
Know your real income
|
|
53
18
|
</p>
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
<
|
|
58
|
-
|
|
59
|
-
<p className="feature-description">
|
|
60
|
-
Automatically calculate 20% tax reserve on business income.
|
|
61
|
-
Know your true net profit after taxes without surprises.
|
|
19
|
+
<h2 className="headline">
|
|
20
|
+
Track Business & Personal Finances Separately
|
|
21
|
+
</h2>
|
|
22
|
+
<p className="subheadline">
|
|
23
|
+
Built for freelancers who need to see their true incomeafter taxes and business expenses.
|
|
62
24
|
</p>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
25
|
+
<div
|
|
26
|
+
style={{
|
|
27
|
+
"display": "flex",
|
|
28
|
+
"gap": "15px",
|
|
29
|
+
"justifyContent": "center"
|
|
30
|
+
}}
|
|
31
|
+
>
|
|
32
|
+
<Link to="/app">
|
|
33
|
+
<button className="cta-button">
|
|
34
|
+
Let's Plan
|
|
35
|
+
</button>
|
|
36
|
+
</Link>
|
|
37
|
+
<Link to="/features">
|
|
38
|
+
<button
|
|
39
|
+
className="cta-button"
|
|
40
|
+
style={{
|
|
41
|
+
"backgroundColor": "#8b5cf6",
|
|
42
|
+
"border": "2px solid #8b5cf6"
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
Test Features
|
|
46
|
+
</button>
|
|
47
|
+
</Link>
|
|
48
|
+
</div>
|
|
49
|
+
</section>
|
|
50
|
+
<section className="features-section">
|
|
51
|
+
<h2 className="features-title">
|
|
52
|
+
Built for Freelancers
|
|
53
|
+
</h2>
|
|
54
|
+
<div className="features-grid">
|
|
55
|
+
<div className="feature-card">
|
|
56
|
+
<div className="feature-icon">
|
|
57
|
+
💼
|
|
58
|
+
</div>
|
|
59
|
+
<h3 className="feature-title">
|
|
60
|
+
Business vs Personal
|
|
61
|
+
</h3>
|
|
62
|
+
<p className="feature-description">
|
|
63
|
+
Tag every transaction as business or personal.See your income streams separately and understand where your money really comes from.
|
|
64
|
+
</p>
|
|
65
|
+
</div>
|
|
66
|
+
<div className="feature-card">
|
|
67
|
+
<div className="feature-icon">
|
|
68
|
+
📊
|
|
69
|
+
</div>
|
|
70
|
+
<h3 className="feature-title">
|
|
71
|
+
Auto Tax Reserve
|
|
72
|
+
</h3>
|
|
73
|
+
<p className="feature-description">
|
|
74
|
+
Automatically calculate 20% tax reserve on business income.Know your true net profit after taxes without surprises.
|
|
75
|
+
</p>
|
|
76
|
+
</div>
|
|
77
|
+
<div className="feature-card">
|
|
78
|
+
<div className="feature-icon">
|
|
79
|
+
🏷️
|
|
80
|
+
</div>
|
|
81
|
+
<h3 className="feature-title">
|
|
82
|
+
Client Tagging
|
|
83
|
+
</h3>
|
|
84
|
+
<p className="feature-description">
|
|
85
|
+
Tag business income by client name. Track which clientsare generating the most revenue for your business.
|
|
86
|
+
</p>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</section>
|
|
90
|
+
<section className="cta-section">
|
|
91
|
+
<h2 className="cta-section-title">
|
|
92
|
+
Ready to know your real income?
|
|
93
|
+
</h2>
|
|
94
|
+
<p className="cta-section-text">
|
|
95
|
+
Start tracking your freelance finances the smart way.
|
|
71
96
|
</p>
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
|
|
97
|
+
<div
|
|
98
|
+
style={{
|
|
99
|
+
"display": "flex",
|
|
100
|
+
"gap": "15px",
|
|
101
|
+
"justifyContent": "center"
|
|
102
|
+
}}
|
|
103
|
+
>
|
|
104
|
+
<Link to="/app">
|
|
105
|
+
<button className="cta-button">
|
|
106
|
+
Get Started Free
|
|
107
|
+
</button>
|
|
108
|
+
</Link>
|
|
109
|
+
<Link to="/features">
|
|
110
|
+
<button
|
|
111
|
+
className="cta-button"
|
|
112
|
+
style={{
|
|
113
|
+
"backgroundColor": "#8b5cf6",
|
|
114
|
+
"border": "2px solid #8b5cf6"
|
|
115
|
+
}}
|
|
116
|
+
>
|
|
117
|
+
Explore Features
|
|
118
|
+
</button>
|
|
119
|
+
</Link>
|
|
120
|
+
</div>
|
|
121
|
+
</section>
|
|
122
|
+
</div>;
|
|
123
|
+
}
|
|
101
124
|
}
|
|
@@ -12,59 +12,54 @@ cl import from ..components.CategoryFilter { CategoryFilter }
|
|
|
12
12
|
cl import from ..constants.categories { CATEGORY_COLORS }
|
|
13
13
|
|
|
14
14
|
# cl import from "..components.PieChart.tsx" { PieChart }
|
|
15
|
+
cl def:pub BudgetPlanner -> any {
|
|
16
|
+
[filter, setFilter] = useState("ALL");
|
|
17
|
+
budget = useBudgetContext();
|
|
15
18
|
|
|
19
|
+
# Filter transactions based on selected category
|
|
20
|
+
filtered = budget["transactions"];
|
|
21
|
+
if filter != "ALL" {
|
|
22
|
+
filtered = filtered.filter(
|
|
23
|
+
lambda tx: dict -> bool { return tx["category"] == filter; }
|
|
24
|
+
);
|
|
25
|
+
}
|
|
16
26
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if filter != "ALL" {
|
|
24
|
-
filtered = filtered.filter(lambda tx: dict -> bool {
|
|
25
|
-
return tx["category"] == filter;
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
# Sort by date (newest first)
|
|
30
|
-
sorted = filtered.slice().sort(lambda a: dict, b: dict -> int {
|
|
31
|
-
return Reflect.construct(Date, [b["date"]]).getTime() - Reflect.construct(Date, [a["date"]]).getTime();
|
|
32
|
-
});
|
|
27
|
+
# Sort by date (newest first)
|
|
28
|
+
sorted = filtered.slice().sort(
|
|
29
|
+
lambda a: dict , b: dict -> int { return Reflect.construct(Date, [b["date"]]).getTime() - Reflect.construct(
|
|
30
|
+
Date, [a["date"]]
|
|
31
|
+
).getTime(); }
|
|
32
|
+
);
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
# Prepare chart data with colors
|
|
35
|
+
chartData = budget["expensesByCategory"].map(
|
|
36
|
+
lambda item: dict -> dict { return {
|
|
37
|
+
"name": item["name"],
|
|
38
|
+
"value": item["value"],
|
|
39
|
+
"color": CATEGORY_COLORS[item["name"]]
|
|
40
|
+
}; }
|
|
41
|
+
);
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
return
|
|
44
|
+
<div className="app-container">
|
|
44
45
|
<Header />
|
|
45
|
-
|
|
46
46
|
<main className="main-content">
|
|
47
47
|
<div className="left-panel">
|
|
48
48
|
<Summary />
|
|
49
49
|
<ProfitOverview />
|
|
50
50
|
<TransactionForm />
|
|
51
|
-
<CategoryFilter
|
|
52
|
-
selectedCategory={filter}
|
|
53
|
-
onSelect={setFilter}
|
|
54
|
-
/>
|
|
51
|
+
<CategoryFilter selectedCategory={filter} onSelect={setFilter} />
|
|
55
52
|
<TransactionList
|
|
56
53
|
transactions={sorted}
|
|
57
54
|
onDelete={budget["deleteTransaction"]}
|
|
58
55
|
/>
|
|
59
56
|
</div>
|
|
60
|
-
|
|
61
|
-
<div className="right-panel">
|
|
62
|
-
# <PieChart
|
|
63
|
-
# data={chartData}
|
|
64
|
-
# title="Expense Breakdown"
|
|
65
|
-
# colors={CATEGORY_COLORS}
|
|
66
|
-
# />
|
|
67
|
-
</div>
|
|
57
|
+
<div className="right-panel"></div>
|
|
68
58
|
</main>
|
|
69
59
|
</div>;
|
|
70
|
-
|
|
60
|
+
}
|
|
61
|
+
# <PieChart
|
|
62
|
+
# data={chartData}
|
|
63
|
+
# title="Expense Breakdown"
|
|
64
|
+
# colors={CATEGORY_COLORS}
|
|
65
|
+
# />
|