dars-framework 1.2.3__tar.gz → 1.2.5__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.
- dars_framework-1.2.5/PKG-INFO +245 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/README.md +6 -1
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/cli/doctor/doctor.py +15 -31
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/cli/doctor/ui.py +13 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/cli/main.py +1131 -1107
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/config.py +1 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/core/js_bridge.py +60 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/js_lib.py +1 -1
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/security.py +16 -4
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/version.py +2 -2
- dars_framework-1.2.5/dars_framework.egg-info/PKG-INFO +245 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/pyproject.toml +3 -5
- dars_framework-1.2.3/PKG-INFO +0 -15
- dars_framework-1.2.3/dars_framework.egg-info/PKG-INFO +0 -15
- {dars_framework-1.2.3 → dars_framework-1.2.5}/LICENSE +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/MANIFEST.in +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/all.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/cli/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/cli/doctor/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/cli/doctor/detect.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/cli/doctor/installers.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/cli/doctor/persist.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/cli/doctor/preflight.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/cli/hot_reload.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/cli/preview.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/cli/translations.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/advanced/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/advanced/accordion.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/advanced/card.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/advanced/modal.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/advanced/navbar.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/advanced/table.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/advanced/tabs.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/button.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/checkbox.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/container.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/datepicker.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/image.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/input.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/link.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/markdown.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/page.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/progressbar.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/radiobutton.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/select.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/slider.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/spinner.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/text.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/textarea.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/basic/tooltip.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/layout/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/layout/anchor.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/layout/flex.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/components/layout/grid.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/core/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/core/app.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/core/component.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/core/events.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/core/properties.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/core/state.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/dars_tests/apps_test/health_check.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/dars_tests/run_tests.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/dars_tests/tests/test_advanced_components.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/dars_tests/tests/test_basic_components.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/dars_tests/tests/test_core_and_cli.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/dars_tests/tests/test_layout_components.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/dars_tests/tests/test_version_check.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/docs/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/docs/app.md +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/docs/cli.md +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/docs/components.md +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/docs/custom_components.md +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/docs/events.md +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/docs/exporters.md +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/docs/getting_started.md +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/docs/index.md +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/docs/scripts.md +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/docs/state_management.md +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/exporters/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/exporters/base.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/exporters/web/OLD/html_css_js_OLD4.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/exporters/web/OLD/html_css_js_old.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/exporters/web/OLD/html_css_js_old2.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/exporters/web/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/exporters/web/html_css_js.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/exporters/web/vdom.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/scripts/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/scripts/dscript.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/scripts/script.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/__pycache__/__init__.cpython-311.pyc +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/README.md +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/__pycache__/dynamic_event_demo.cpython-311.pyc +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/advanced/Modal_Demo/advanced_modal_demo.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/advanced/SimpleDashboard/dashboard.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/advanced/SimpleModermWeb/modern_web_app.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/advanced/VariousComponents/all_components_demo.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/advanced/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/advanced/dState/state_mods_demo.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/basic/Forms/form_components.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/basic/Forms/simple_form.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/basic/HelloWorld/hello_world.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/basic/Layouts/flex_layout_responsive.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/basic/Layouts/grid_layout_responsive.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/basic/Layouts/layout_multipage_demo.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/basic/Multipage/multipage_example.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/basic/PWA/icon-192x192.png +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/basic/PWA/icon-512x512.png +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/basic/PWA/pwa_custom_icons.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/basic/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/demo/__pycache__/complete_app.cpython-311.pyc +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/demo/complete_app.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/markdown/MarkdownTemplate/README.md +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/markdown/MarkdownTemplate/markdown_template.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/markdown/MarkdownTemplate/other_docs.md +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/examples/markdown/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars/templates/html/__init__.py +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars_framework.egg-info/SOURCES.txt +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars_framework.egg-info/dependency_links.txt +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars_framework.egg-info/entry_points.txt +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars_framework.egg-info/requires.txt +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/dars_framework.egg-info/top_level.txt +0 -0
- {dars_framework-1.2.3 → dars_framework-1.2.5}/setup.cfg +0 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dars_framework
|
|
3
|
+
Version: 1.2.5
|
|
4
|
+
Summary: Dars is a Python UI framework for building modern, interactive web apps with only Python code. Write your interface in Python, export it to static HTML/CSS/JS, and deploy anywhere.
|
|
5
|
+
Author-email: ztamdev <ztadevs@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: rich==14.2.0
|
|
10
|
+
Requires-Dist: bs4==0.0.2
|
|
11
|
+
Requires-Dist: uvicorn==0.35.0
|
|
12
|
+
Requires-Dist: fastapi==0.116.1
|
|
13
|
+
Requires-Dist: markdown2==2.5.4
|
|
14
|
+
Requires-Dist: requests==2.32.5
|
|
15
|
+
Requires-Dist: rjsmin==1.2.5
|
|
16
|
+
Dynamic: license-file
|
|
17
|
+
|
|
18
|
+
<h1 align="center">Dars Framework</h1>
|
|
19
|
+
|
|
20
|
+
<p align="center">
|
|
21
|
+
<img src="./Dars-logo.png" alt="Dars Framework Logo" width="200" />
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
<p align="center">
|
|
25
|
+
<em>Dars is a Python UI framework for building modern, interactive web apps with Python code. Write your interface in Python, export it to static HTML/CSS/JS, and deploy anywhere.</em>
|
|
26
|
+
</p>
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install dars-framework
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
> Some Javascript or frontend stack required.
|
|
33
|
+
|
|
34
|
+
Try dars without installing nothing just visit the [Dars Playground](https://dars-playground.vercel.app/)
|
|
35
|
+
|
|
36
|
+
## How It Works
|
|
37
|
+
- Build your UI using Python classes and components (like Text, Button, Container, Page, etc).
|
|
38
|
+
- Preview instantly with hot-reload using `app.rTimeCompile()`.
|
|
39
|
+
- Export your app to static web files with a single CLI command.
|
|
40
|
+
- Use multipage, layouts, scripts, and more—see docs for advanced features.
|
|
41
|
+
- For more information visit the [Documentation](https://ztamdev.github.io/Dars-Framework/documentation.html)
|
|
42
|
+
|
|
43
|
+
## Quick Example: Your First App
|
|
44
|
+
```python
|
|
45
|
+
from dars.all import *
|
|
46
|
+
|
|
47
|
+
app = App(title="Hello World", theme="dark")
|
|
48
|
+
# Crear componentes
|
|
49
|
+
index = Page(
|
|
50
|
+
Text(
|
|
51
|
+
text="Hello World",
|
|
52
|
+
style={
|
|
53
|
+
'font-size': '48px',
|
|
54
|
+
'color': '#2c3e50',
|
|
55
|
+
'margin-bottom': '20px',
|
|
56
|
+
'font-weight': 'bold',
|
|
57
|
+
'text-align': 'center'
|
|
58
|
+
}
|
|
59
|
+
),
|
|
60
|
+
Text(
|
|
61
|
+
text="Hello World",
|
|
62
|
+
style={
|
|
63
|
+
'font-size': '20px',
|
|
64
|
+
'color': '#7f8c8d',
|
|
65
|
+
'margin-bottom': '40px',
|
|
66
|
+
'text-align': 'center'
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
|
|
70
|
+
Button(
|
|
71
|
+
text="Click Me!",
|
|
72
|
+
on_click= dScript("alert('Hello World')"),
|
|
73
|
+
on_mouse_enter=dScript("this.style.backgroundColor = '#2980b9';"),
|
|
74
|
+
on_mouse_leave=dScript("this.style.backgroundColor = '#3498db';"),
|
|
75
|
+
style={
|
|
76
|
+
'background-color': '#3498db',
|
|
77
|
+
'color': 'white',
|
|
78
|
+
'padding': '15px 30px',
|
|
79
|
+
'border': 'none',
|
|
80
|
+
'border-radius': '8px',
|
|
81
|
+
'font-size': '18px',
|
|
82
|
+
'cursor': 'pointer',
|
|
83
|
+
'transition': 'background-color 0.3s'
|
|
84
|
+
}
|
|
85
|
+
),
|
|
86
|
+
style={
|
|
87
|
+
'display': 'flex',
|
|
88
|
+
'flex-direction': 'column',
|
|
89
|
+
'align-items': 'center',
|
|
90
|
+
'justify-content': 'center',
|
|
91
|
+
'min-height': '100vh',
|
|
92
|
+
'background-color': '#f0f2f5',
|
|
93
|
+
'font-family': 'Arial, sans-serif'
|
|
94
|
+
}
|
|
95
|
+
)
|
|
96
|
+
index.attr()
|
|
97
|
+
app.add_page("index", index, title="Hello World", index=True)
|
|
98
|
+
|
|
99
|
+
if __name__ == "__main__":
|
|
100
|
+
app.rTimeCompile()
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Reactivity and State System
|
|
107
|
+
|
|
108
|
+
**Dars Framework** includes a built-in **reactive state system** (`dState` / `cState`) that allows dynamic and modular DOM updates directly from Python.
|
|
109
|
+
It enables fully event-driven interfaces without requiring manual JavaScript.
|
|
110
|
+
|
|
111
|
+
### Key Concepts
|
|
112
|
+
|
|
113
|
+
* **`dState(name, component, states)`**
|
|
114
|
+
Creates a reactive state controller bound to a specific component and a list of possible states.
|
|
115
|
+
|
|
116
|
+
* **`cState(idx, mods=[...])`**
|
|
117
|
+
Defines rules (modifications) that are automatically applied when entering a specific state.
|
|
118
|
+
|
|
119
|
+
* **`Mod` Helpers**
|
|
120
|
+
A compact way to modify DOM elements on state changes: `inc`, `dec`, `set`, `toggle_class`, `append_text`, `prepend_text`, `goto`, and more.
|
|
121
|
+
|
|
122
|
+
* **Deferred Mutations**
|
|
123
|
+
Using `component.attr(..., defer=True)` or `component.mod(...)` inside a `cComp=True` state defers HTML updates until an event occurs, preventing authoring-time mutations.
|
|
124
|
+
|
|
125
|
+
### Example Template
|
|
126
|
+
|
|
127
|
+
A complete example demonstrating `dState`, `cState`, `Mod`, and deferred updates is available [here](https://github.com/ZtaMDev/Dars-Framework/blob/CrystalMain/dars/templates/examples/advanced/dState/state_mods_demo.py)
|
|
128
|
+
|
|
129
|
+
<img width="384" height="187" alt="imagen" src="https://github.com/user-attachments/assets/7750ee7f-768f-48da-94df-2fa00339a99c" /> <img width="361" height="215" alt="imagen" src="https://github.com/user-attachments/assets/9b8a3e67-2424-49b4-aee0-9f1c0f747d66" />
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
### Features
|
|
134
|
+
|
|
135
|
+
* Reactive Mod system with compact `Mod` helpers
|
|
136
|
+
* Unified event model — any component can use `on_*` props (`on_click`, `on_input`, `on_change`, etc.)
|
|
137
|
+
* Deferred rendering for safer, predictable state transitions (`cComp=True`)
|
|
138
|
+
* Navigation between states using `goto`, including relative moves (`'+1'`, `'-1'`)
|
|
139
|
+
* Consistent, event-time mutation flow for reliable behavior
|
|
140
|
+
* Secure minification for production bundles (strong JS/CSS minifier integrated into the build pipeline)
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## CLI Usage
|
|
145
|
+
| Command | What it does |
|
|
146
|
+
|-----------------------------------------|--------------------------------------------|
|
|
147
|
+
| `dars export my_app.py --format html` | Export app to HTML/CSS/JS in `./my_app_web` |
|
|
148
|
+
| `dars preview ./my_app_web` | Preview exported app locally |
|
|
149
|
+
| `dars init my_project` | Create a new Dars project (also creates dars.config.json) |
|
|
150
|
+
| `dars init --update` | Create/Update dars.config.json in current dir |
|
|
151
|
+
| `dars build` | Build using dars.config.json (entry/outdir/format) |
|
|
152
|
+
| `dars config validate` | Validate dars.config.json and print report |
|
|
153
|
+
| `dars info my_app.py` | Show info about your app |
|
|
154
|
+
| `dars formats` | List supported export formats |
|
|
155
|
+
| `dars --help` | Show help and all CLI options |
|
|
156
|
+
|
|
157
|
+
Tip: use `dars doctor` to review optional tooling that can enhance bundling/minification.
|
|
158
|
+
|
|
159
|
+
## More
|
|
160
|
+
|
|
161
|
+
- Visit dars [official website](https://ztamdev.github.io/Dars-Framework/)
|
|
162
|
+
- Visit the dars official [Documentation](https://ztamdev.github.io/Dars-Framework/documentation.html) now on separate website.
|
|
163
|
+
- Try dars without installing nothing just visit the [Dars Playground](https://dars-playground.vercel.app/)
|
|
164
|
+
|
|
165
|
+
## Local Execution and Live Preview
|
|
166
|
+
|
|
167
|
+
To test your app locally before exporting, use the hot-reload preview from any Python file that defines your app:
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
if __name__ == "__main__":
|
|
171
|
+
app.rTimeCompile()
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Then run your file directly:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
python my_app.py
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
This will start a local server at http://localhost:8000 so you can view your app in the browser—no manual export needed. You can change the port with:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
python my_app.py --port 8088
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
You can also use the CLI preview command on an exported app:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
dars preview ./my_exported_app
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
This will start a local server at http://localhost:8000 to view your exported app in the browser.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Project Configuration (dars.config.json)
|
|
199
|
+
|
|
200
|
+
Dars can read build/export settings from a `dars.config.json` at your project root. It is created automatically by `dars init`, and you can add it to existing projects with `dars init --update`.
|
|
201
|
+
|
|
202
|
+
Example default:
|
|
203
|
+
|
|
204
|
+
```json
|
|
205
|
+
{
|
|
206
|
+
"entry": "main.py",
|
|
207
|
+
"format": "html",
|
|
208
|
+
"outdir": "dist",
|
|
209
|
+
"publicDir": null,
|
|
210
|
+
"include": [],
|
|
211
|
+
"exclude": ["**/__pycache__", ".git", ".venv", "node_modules"],
|
|
212
|
+
"bundle": true,
|
|
213
|
+
"viteMinify": true
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
- `entry`: Python entry file. Used by `dars build` and `dars export config`.
|
|
218
|
+
- `format`: Export format. Currently only `html` is supported.
|
|
219
|
+
- `outdir`: Output directory. Used by `dars build` and default for `dars export` when not overridden.
|
|
220
|
+
- `publicDir`: Folder (e.g., `public/` or `assets/`) copied into the output. If null, it is autodetected.
|
|
221
|
+
- `include`/`exclude`: Basic filters for copying from `publicDir`.
|
|
222
|
+
- `bundle`: Reserved for future use. CLI exports and build already bundle appropriately.
|
|
223
|
+
- `viteMinify`: Toggle the Vite-based minifier for JS. When `false`, the build uses esbuild-based minification. If neither is available, a conservative Python fallback is used.
|
|
224
|
+
|
|
225
|
+
Validate your config:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
dars config validate
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Build using config:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
dars build
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Export using the config entry and outdir:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
dars export config --format html
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
See LandingPage docs for details: state_management.md, events.md, scripts.md.
|
|
@@ -120,6 +120,7 @@ A complete example demonstrating `dState`, `cState`, `Mod`, and deferred updates
|
|
|
120
120
|
* Deferred rendering for safer, predictable state transitions (`cComp=True`)
|
|
121
121
|
* Navigation between states using `goto`, including relative moves (`'+1'`, `'-1'`)
|
|
122
122
|
* Consistent, event-time mutation flow for reliable behavior
|
|
123
|
+
* Secure minification for production bundles (strong JS/CSS minifier integrated into the build pipeline)
|
|
123
124
|
|
|
124
125
|
---
|
|
125
126
|
|
|
@@ -136,6 +137,8 @@ A complete example demonstrating `dState`, `cState`, `Mod`, and deferred updates
|
|
|
136
137
|
| `dars formats` | List supported export formats |
|
|
137
138
|
| `dars --help` | Show help and all CLI options |
|
|
138
139
|
|
|
140
|
+
Tip: use `dars doctor` to review optional tooling that can enhance bundling/minification.
|
|
141
|
+
|
|
139
142
|
## More
|
|
140
143
|
|
|
141
144
|
- Visit dars [official website](https://ztamdev.github.io/Dars-Framework/)
|
|
@@ -189,7 +192,8 @@ Example default:
|
|
|
189
192
|
"publicDir": null,
|
|
190
193
|
"include": [],
|
|
191
194
|
"exclude": ["**/__pycache__", ".git", ".venv", "node_modules"],
|
|
192
|
-
"bundle":
|
|
195
|
+
"bundle": true,
|
|
196
|
+
"viteMinify": true
|
|
193
197
|
}
|
|
194
198
|
```
|
|
195
199
|
|
|
@@ -199,6 +203,7 @@ Example default:
|
|
|
199
203
|
- `publicDir`: Folder (e.g., `public/` or `assets/`) copied into the output. If null, it is autodetected.
|
|
200
204
|
- `include`/`exclude`: Basic filters for copying from `publicDir`.
|
|
201
205
|
- `bundle`: Reserved for future use. CLI exports and build already bundle appropriately.
|
|
206
|
+
- `viteMinify`: Toggle the Vite-based minifier for JS. When `false`, the build uses esbuild-based minification. If neither is available, a conservative Python fallback is used.
|
|
202
207
|
|
|
203
208
|
Validate your config:
|
|
204
209
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import os, sys
|
|
2
2
|
from typing import Dict, List
|
|
3
3
|
from .detect import detect_node, detect_bun, detect_esbuild, detect_vite, read_pyproject_deps, check_python_deps
|
|
4
|
-
from .installers import
|
|
4
|
+
from .installers import install_bun
|
|
5
5
|
from .persist import load_config, save_config
|
|
6
6
|
from .ui import render_report, prompt_action, confirm_install
|
|
7
7
|
from rich.console import Console
|
|
@@ -23,11 +23,13 @@ def run_doctor(check_only: bool = False, auto_yes: bool = False, install_all: bo
|
|
|
23
23
|
|
|
24
24
|
render_report(node, bun, py, esb, vit)
|
|
25
25
|
|
|
26
|
+
# Mandatory only for doctor purposes: Python deps
|
|
26
27
|
missing_items: List[str] = []
|
|
27
|
-
if not node.get('ok'): missing_items.append('Node.js LTS')
|
|
28
|
-
if not bun.get('ok'): missing_items.append('Bun stable')
|
|
29
28
|
if py.get('missing'): missing_items.append('Python deps')
|
|
29
|
+
# Node, Bun, esbuild, vite treated as optional. Bun can be auto-installed if user wants.
|
|
30
30
|
optional_missing: List[str] = []
|
|
31
|
+
if not node.get('ok'): optional_missing.append('Node.js (optional)')
|
|
32
|
+
if not bun.get('ok'): optional_missing.append('Bun (optional)')
|
|
31
33
|
if not esb.get('ok'): optional_missing.append('esbuild (optional)')
|
|
32
34
|
if not vit.get('ok'): optional_missing.append('vite (optional)')
|
|
33
35
|
|
|
@@ -73,37 +75,21 @@ def run_doctor(check_only: bool = False, auto_yes: bool = False, install_all: bo
|
|
|
73
75
|
|
|
74
76
|
# choice == '1' => Install ALL missing
|
|
75
77
|
summary: List[str] = []
|
|
76
|
-
|
|
77
|
-
if not bun.get('ok'): summary.append('Bun (winget)')
|
|
78
|
+
# Only Bun and Python deps are installable from doctor; Node/esbuild/vite show links in the report
|
|
79
|
+
if not bun.get('ok'): summary.append('Bun (winget/installer)')
|
|
78
80
|
if py.get('missing'): summary.append(f"Python deps: {', '.join(py['missing'])}")
|
|
79
|
-
|
|
80
|
-
summary.extend(optional_missing)
|
|
81
|
+
# Do not include other optional tools in install summary
|
|
81
82
|
|
|
82
83
|
if not auto_yes:
|
|
83
84
|
if not confirm_install(summary):
|
|
84
85
|
return 1
|
|
85
86
|
|
|
86
|
-
# Installers:
|
|
87
|
+
# Installers: only Bun, optionally Python deps
|
|
87
88
|
with console.status("[cyan]Installing selected items...[/cyan]"):
|
|
88
|
-
try:
|
|
89
|
-
install_node()
|
|
90
|
-
except Exception:
|
|
91
|
-
pass
|
|
92
89
|
try:
|
|
93
90
|
install_bun()
|
|
94
91
|
except Exception:
|
|
95
92
|
pass
|
|
96
|
-
# Optional developer tools
|
|
97
|
-
try:
|
|
98
|
-
if not esb.get('ok'):
|
|
99
|
-
install_esbuild()
|
|
100
|
-
except Exception:
|
|
101
|
-
pass
|
|
102
|
-
try:
|
|
103
|
-
if not vit.get('ok'):
|
|
104
|
-
install_vite()
|
|
105
|
-
except Exception:
|
|
106
|
-
pass
|
|
107
93
|
|
|
108
94
|
# Python deps via pip
|
|
109
95
|
if py.get('missing'):
|
|
@@ -124,11 +110,12 @@ def run_doctor(check_only: bool = False, auto_yes: bool = False, install_all: bo
|
|
|
124
110
|
|
|
125
111
|
render_report(node2, bun2, py2, esb2, vit2)
|
|
126
112
|
|
|
127
|
-
all_ok =
|
|
113
|
+
all_ok = not py2.get('missing')
|
|
128
114
|
|
|
129
115
|
cfg['requirements']['node'].update({'ok': bool(node2.get('ok')), 'version': node2.get('version')})
|
|
130
116
|
cfg['requirements']['bun'].update({'ok': bool(bun2.get('ok')), 'version': bun2.get('version')})
|
|
131
117
|
cfg['python_deps'] = {'ok': not bool(py2.get('missing')), 'missing': py2.get('missing') or []}
|
|
118
|
+
# doctor satisfaction now tied only to Python deps
|
|
132
119
|
cfg['satisfied'] = bool(all_ok)
|
|
133
120
|
save_config(cfg)
|
|
134
121
|
|
|
@@ -137,16 +124,12 @@ def run_doctor(check_only: bool = False, auto_yes: bool = False, install_all: bo
|
|
|
137
124
|
|
|
138
125
|
def run_forcedev() -> int:
|
|
139
126
|
"""Force-install everything without initial verification or prompts.
|
|
140
|
-
- Attempts
|
|
127
|
+
- Attempts Bun installer unconditionally (best-effort)
|
|
141
128
|
- Installs/updates all Python deps from pyproject.toml
|
|
142
129
|
- Re-checks and persists satisfied state
|
|
143
130
|
Returns 0 if environment ends OK, else 1.
|
|
144
131
|
"""
|
|
145
132
|
# Best-effort installs (no UI)
|
|
146
|
-
try:
|
|
147
|
-
install_node()
|
|
148
|
-
except Exception:
|
|
149
|
-
pass
|
|
150
133
|
try:
|
|
151
134
|
install_bun()
|
|
152
135
|
except Exception:
|
|
@@ -163,11 +146,12 @@ def run_forcedev() -> int:
|
|
|
163
146
|
|
|
164
147
|
# Re-check and persist
|
|
165
148
|
cfg = load_config()
|
|
166
|
-
node2 = detect_node()
|
|
167
149
|
bun2 = detect_bun()
|
|
168
150
|
py2 = check_python_deps(read_pyproject_deps())
|
|
169
|
-
all_ok =
|
|
151
|
+
all_ok = bun2.get('ok') and not py2.get('missing')
|
|
170
152
|
|
|
153
|
+
# keep node state updated for UI even if not installed by forcedev
|
|
154
|
+
node2 = detect_node()
|
|
171
155
|
cfg['requirements']['node'].update({'ok': bool(node2.get('ok')), 'version': node2.get('version')})
|
|
172
156
|
cfg['requirements']['bun'].update({'ok': bool(bun2.get('ok')), 'version': bun2.get('version')})
|
|
173
157
|
cfg['python_deps'] = {'ok': not bool(py2.get('missing')), 'missing': py2.get('missing') or []}
|
|
@@ -31,6 +31,19 @@ def render_report(node: Dict, bun: Dict, py: Dict, esb: Dict = None, vit: Dict =
|
|
|
31
31
|
bullets = "\n".join([f" • {req}" for req in p_missing])
|
|
32
32
|
console.print(Panel(bullets or "", title="Missing Python packages", border_style="yellow"))
|
|
33
33
|
|
|
34
|
+
# Helpful links for optional tools
|
|
35
|
+
tips: List[str] = []
|
|
36
|
+
if node is not None and not node.get("ok"):
|
|
37
|
+
tips.append("Node.js LTS (manual): https://nodejs.org/en/download")
|
|
38
|
+
if bun is not None and not bun.get("ok"):
|
|
39
|
+
tips.append("Bun (auto-install available) — Windows: winget / PS: irm bun.sh/install.ps1 | iex — macOS/Linux: curl -fsSL https://bun.sh/install | bash")
|
|
40
|
+
if esb is not None and not esb.get("ok"):
|
|
41
|
+
tips.append("esbuild (optional): https://esbuild.github.io/getting-started/")
|
|
42
|
+
if vit is not None and not vit.get("ok"):
|
|
43
|
+
tips.append("Vite (optional): https://vite.dev/guide/")
|
|
44
|
+
if tips:
|
|
45
|
+
console.print(Panel("\n".join([f" • {t}" for t in tips]), title="How to install (optional)", border_style="cyan"))
|
|
46
|
+
|
|
34
47
|
|
|
35
48
|
def prompt_action(has_missing: bool) -> str:
|
|
36
49
|
console.print(Panel("Select an action", border_style="cyan"))
|