teloce-py 0.1.0__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.
- teloce_py-0.1.0/LICENSE +22 -0
- teloce_py-0.1.0/PKG-INFO +192 -0
- teloce_py-0.1.0/README.md +143 -0
- teloce_py-0.1.0/pyproject.toml +84 -0
- teloce_py-0.1.0/setup.cfg +4 -0
- teloce_py-0.1.0/src/teloce/__init__.py +17 -0
- teloce_py-0.1.0/src/teloce/__main__.py +13 -0
- teloce_py-0.1.0/src/teloce/ast/__init__.py +87 -0
- teloce_py-0.1.0/src/teloce/ast/components.py +77 -0
- teloce_py-0.1.0/src/teloce/ast/elements.py +84 -0
- teloce_py-0.1.0/src/teloce/ast/expressions.py +151 -0
- teloce_py-0.1.0/src/teloce/ast/nodes.py +271 -0
- teloce_py-0.1.0/src/teloce/ast/visitors.py +246 -0
- teloce_py-0.1.0/src/teloce/build/__init__.py +37 -0
- teloce_py-0.1.0/src/teloce/build/assets.py +128 -0
- teloce_py-0.1.0/src/teloce/build/builder.py +292 -0
- teloce_py-0.1.0/src/teloce/build/bundler.py +153 -0
- teloce_py-0.1.0/src/teloce/build/manifest.py +89 -0
- teloce_py-0.1.0/src/teloce/build/writer.py +86 -0
- teloce_py-0.1.0/src/teloce/cli/__init__.py +25 -0
- teloce_py-0.1.0/src/teloce/cli/benchmark.py +62 -0
- teloce_py-0.1.0/src/teloce/cli/build.py +81 -0
- teloce_py-0.1.0/src/teloce/cli/create.py +281 -0
- teloce_py-0.1.0/src/teloce/cli/debug.py +72 -0
- teloce_py-0.1.0/src/teloce/cli/dev.py +101 -0
- teloce_py-0.1.0/src/teloce/cli/doctor.py +99 -0
- teloce_py-0.1.0/src/teloce/cli/lint.py +148 -0
- teloce_py-0.1.0/src/teloce/cli/main.py +223 -0
- teloce_py-0.1.0/src/teloce/cli/server.py +176 -0
- teloce_py-0.1.0/src/teloce/cli/watch.py +98 -0
- teloce_py-0.1.0/src/teloce/compiler/__init__.py +31 -0
- teloce_py-0.1.0/src/teloce/compiler/compiler.py +266 -0
- teloce_py-0.1.0/src/teloce/compiler/diagnostics.py +129 -0
- teloce_py-0.1.0/src/teloce/compiler/generator.py +518 -0
- teloce_py-0.1.0/src/teloce/compiler/lexer.py +515 -0
- teloce_py-0.1.0/src/teloce/compiler/optimizer.py +115 -0
- teloce_py-0.1.0/src/teloce/compiler/parser.py +329 -0
- teloce_py-0.1.0/src/teloce/compiler/source_map.py +79 -0
- teloce_py-0.1.0/src/teloce/compiler/transformer.py +71 -0
- teloce_py-0.1.0/src/teloce/components/__init__.py +17 -0
- teloce_py-0.1.0/src/teloce/components/dependency_graph.py +177 -0
- teloce_py-0.1.0/src/teloce/components/imports.py +118 -0
- teloce_py-0.1.0/src/teloce/components/registry.py +108 -0
- teloce_py-0.1.0/src/teloce/components/resolver.py +107 -0
- teloce_py-0.1.0/src/teloce/css/__init__.py +20 -0
- teloce_py-0.1.0/src/teloce/css/generator.py +160 -0
- teloce_py-0.1.0/src/teloce/css/hashing.py +73 -0
- teloce_py-0.1.0/src/teloce/css/modules.py +30 -0
- teloce_py-0.1.0/src/teloce/css/parser.py +395 -0
- teloce_py-0.1.0/src/teloce/css/scoped.py +179 -0
- teloce_py-0.1.0/src/teloce/debug/__init__.py +18 -0
- teloce_py-0.1.0/src/teloce/debug/errors.py +195 -0
- teloce_py-0.1.0/src/teloce/debug/formatter.py +185 -0
- teloce_py-0.1.0/src/teloce/debug/suggestions.py +230 -0
- teloce_py-0.1.0/src/teloce/directives/__init__.py +27 -0
- teloce_py-0.1.0/src/teloce/directives/base.py +135 -0
- teloce_py-0.1.0/src/teloce/directives/bind.py +502 -0
- teloce_py-0.1.0/src/teloce/directives/events.py +126 -0
- teloce_py-0.1.0/src/teloce/directives/for_.py +95 -0
- teloce_py-0.1.0/src/teloce/directives/if_.py +105 -0
- teloce_py-0.1.0/src/teloce/directives/model.py +52 -0
- teloce_py-0.1.0/src/teloce/directives/registry.py +69 -0
- teloce_py-0.1.0/src/teloce/directives/show.py +62 -0
- teloce_py-0.1.0/src/teloce/expressions/__init__.py +41 -0
- teloce_py-0.1.0/src/teloce/expressions/ast.py +118 -0
- teloce_py-0.1.0/src/teloce/expressions/generator.py +132 -0
- teloce_py-0.1.0/src/teloce/expressions/lexer.py +530 -0
- teloce_py-0.1.0/src/teloce/expressions/parser.py +488 -0
- teloce_py-0.1.0/src/teloce/filters/__init__.py +22 -0
- teloce_py-0.1.0/src/teloce/filters/arrays.py +112 -0
- teloce_py-0.1.0/src/teloce/filters/dates.py +142 -0
- teloce_py-0.1.0/src/teloce/filters/numbers.py +98 -0
- teloce_py-0.1.0/src/teloce/filters/objects.py +89 -0
- teloce_py-0.1.0/src/teloce/filters/registry.py +98 -0
- teloce_py-0.1.0/src/teloce/filters/strings.py +171 -0
- teloce_py-0.1.0/src/teloce/javascript/__init__.py +21 -0
- teloce_py-0.1.0/src/teloce/javascript/dom.py +140 -0
- teloce_py-0.1.0/src/teloce/javascript/exports.py +49 -0
- teloce_py-0.1.0/src/teloce/javascript/generator.py +250 -0
- teloce_py-0.1.0/src/teloce/javascript/helpers.py +218 -0
- teloce_py-0.1.0/src/teloce/javascript/imports.py +95 -0
- teloce_py-0.1.0/src/teloce/javascript/module.py +63 -0
- teloce_py-0.1.0/src/teloce/plugins/__init__.py +21 -0
- teloce_py-0.1.0/src/teloce/plugins/api.py +120 -0
- teloce_py-0.1.0/src/teloce/plugins/directives.py +42 -0
- teloce_py-0.1.0/src/teloce/plugins/filters.py +41 -0
- teloce_py-0.1.0/src/teloce/plugins/hooks.py +81 -0
- teloce_py-0.1.0/src/teloce/plugins/registry.py +113 -0
- teloce_py-0.1.0/src/teloce/project/__init__.py +17 -0
- teloce_py-0.1.0/src/teloce/project/configuration.py +142 -0
- teloce_py-0.1.0/src/teloce/project/discovery.py +160 -0
- teloce_py-0.1.0/src/teloce/project/paths.py +122 -0
- teloce_py-0.1.0/src/teloce/project/scanner.py +126 -0
- teloce_py-0.1.0/src/teloce/router/__init__.py +13 -0
- teloce_py-0.1.0/src/teloce/router/compiler.py +161 -0
- teloce_py-0.1.0/src/teloce/router/generator.py +166 -0
- teloce_py-0.1.0/src/teloce/runtime/__init__.py +8 -0
- teloce_py-0.1.0/src/teloce/runtime/component.js +21 -0
- teloce_py-0.1.0/src/teloce/runtime/computed.js +2 -0
- teloce_py-0.1.0/src/teloce/runtime/dom.js +119 -0
- teloce_py-0.1.0/src/teloce/runtime/effects.js +2 -0
- teloce_py-0.1.0/src/teloce/runtime/events.js +4 -0
- teloce_py-0.1.0/src/teloce/runtime/lifecycle.js +3 -0
- teloce_py-0.1.0/src/teloce/runtime/props.js +7 -0
- teloce_py-0.1.0/src/teloce/runtime/reactivity.js +16 -0
- teloce_py-0.1.0/src/teloce/runtime/runtime.js +11 -0
- teloce_py-0.1.0/src/teloce/runtime/scheduler.js +40 -0
- teloce_py-0.1.0/src/teloce/runtime/signals.js +131 -0
- teloce_py-0.1.0/src/teloce/runtime/slots.js +4 -0
- teloce_py-0.1.0/src/teloce/runtime/standalone.js +221 -0
- teloce_py-0.1.0/src/teloce/sfc/__init__.py +25 -0
- teloce_py-0.1.0/src/teloce/sfc/component.py +95 -0
- teloce_py-0.1.0/src/teloce/sfc/parser.py +289 -0
- teloce_py-0.1.0/src/teloce/sfc/script.py +1009 -0
- teloce_py-0.1.0/src/teloce/sfc/sections.py +46 -0
- teloce_py-0.1.0/src/teloce/sfc/style.py +582 -0
- teloce_py-0.1.0/src/teloce/sfc/template.py +66 -0
- teloce_py-0.1.0/src/teloce/template/__init__.py +29 -0
- teloce_py-0.1.0/src/teloce/template/components.py +122 -0
- teloce_py-0.1.0/src/teloce/template/conditions.py +75 -0
- teloce_py-0.1.0/src/teloce/template/directives.py +111 -0
- teloce_py-0.1.0/src/teloce/template/expressions.py +398 -0
- teloce_py-0.1.0/src/teloce/template/interpolation.py +74 -0
- teloce_py-0.1.0/src/teloce/template/lexer.py +421 -0
- teloce_py-0.1.0/src/teloce/template/loops.py +92 -0
- teloce_py-0.1.0/src/teloce/template/parser.py +101 -0
- teloce_py-0.1.0/src/teloce/template/slots.py +66 -0
- teloce_py-0.1.0/src/teloce/version.py +6 -0
- teloce_py-0.1.0/src/teloce/watcher/__init__.py +13 -0
- teloce_py-0.1.0/src/teloce/watcher/watcher.py +174 -0
- teloce_py-0.1.0/src/teloce_py.egg-info/PKG-INFO +192 -0
- teloce_py-0.1.0/src/teloce_py.egg-info/SOURCES.txt +133 -0
- teloce_py-0.1.0/src/teloce_py.egg-info/dependency_links.txt +1 -0
- teloce_py-0.1.0/src/teloce_py.egg-info/entry_points.txt +2 -0
- teloce_py-0.1.0/src/teloce_py.egg-info/top_level.txt +1 -0
teloce_py-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
MIT License
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2026 Aldane Hutchinson
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
teloce_py-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: teloce-py
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Python compiler for Teloce .vel Single File Components
|
|
5
|
+
Author: Teloce Contributors
|
|
6
|
+
Maintainer-email: Teloce Contributors <team@teloce.dev>
|
|
7
|
+
License:
|
|
8
|
+
MIT License
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2026 Aldane Hutchinson
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
29
|
+
Project-URL: Homepage, https://teloce.dev
|
|
30
|
+
Project-URL: Documentation, https://docs.teloce.dev
|
|
31
|
+
Project-URL: Repository, https://github.com/aldanedev-create/telonce
|
|
32
|
+
Project-URL: Issues, https://github.com/aldanedev-create/telonce/issues
|
|
33
|
+
Project-URL: Changelog, https://github.com/aldanedev-create/telonce/blob/main/CHANGELOG.md
|
|
34
|
+
Keywords: teloce,compiler,sfc,template-engine,python,flask,django,fastapi,flaxon
|
|
35
|
+
Classifier: Development Status :: 3 - Alpha
|
|
36
|
+
Classifier: Intended Audience :: Developers
|
|
37
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
38
|
+
Classifier: Programming Language :: Python :: 3
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
42
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
43
|
+
Classifier: Topic :: Software Development :: Compilers
|
|
44
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
45
|
+
Requires-Python: >=3.10
|
|
46
|
+
Description-Content-Type: text/markdown
|
|
47
|
+
License-File: LICENSE
|
|
48
|
+
Dynamic: license-file
|
|
49
|
+
|
|
50
|
+
# Teloce-Py
|
|
51
|
+
|
|
52
|
+
A Python compiler for Teloce `.vel` Single File Components.
|
|
53
|
+
|
|
54
|
+
## Overview
|
|
55
|
+
|
|
56
|
+
Teloce-Py is a **100% Python compiler** that transforms `.vel` Single File Components into **self-contained vanilla JavaScript**. It works with any Python web framework (Flask, Flaxon, Django, FastAPI) without requiring Node.js, npm, or a CDN.
|
|
57
|
+
|
|
58
|
+
## Philosophy
|
|
59
|
+
|
|
60
|
+
> **"Write components in Python, run them in the browser — no npm required."**
|
|
61
|
+
|
|
62
|
+
- **100% Python** — The compiler is written entirely in Python
|
|
63
|
+
- **Self-contained JavaScript** — The output includes everything needed to run in the browser
|
|
64
|
+
- **No npm/Node.js** — Python developers don't need JavaScript tooling
|
|
65
|
+
- **Framework Agnostic** — Works with Flask, Flaxon, Django, FastAPI, and more
|
|
66
|
+
|
|
67
|
+
## Quick Start
|
|
68
|
+
|
|
69
|
+
### Installation
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install teloce-py
|
|
73
|
+
Create a .vel Component
|
|
74
|
+
html
|
|
75
|
+
<!-- static/js/App.vel -->
|
|
76
|
+
<template>
|
|
77
|
+
<div class="app">
|
|
78
|
+
<h1>{{ title }}</h1>
|
|
79
|
+
<button @click="increment">{{ count }}</button>
|
|
80
|
+
</div>
|
|
81
|
+
</template>
|
|
82
|
+
|
|
83
|
+
<script>
|
|
84
|
+
export default {
|
|
85
|
+
data() {
|
|
86
|
+
return {
|
|
87
|
+
title: "Hello Teloce",
|
|
88
|
+
count: 0
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
methods: {
|
|
92
|
+
increment() {
|
|
93
|
+
this.count++;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
</script>
|
|
98
|
+
|
|
99
|
+
<style scoped>
|
|
100
|
+
.app { padding: 20px; }
|
|
101
|
+
button { background: #6366f1; color: white; border: none; padding: 8px 16px; }
|
|
102
|
+
</style>
|
|
103
|
+
Run Your Python App
|
|
104
|
+
python
|
|
105
|
+
# app.py
|
|
106
|
+
from flask import Flask, render_template
|
|
107
|
+
|
|
108
|
+
app = Flask(__name__)
|
|
109
|
+
|
|
110
|
+
@app.route('/')
|
|
111
|
+
def home():
|
|
112
|
+
return render_template('index.html')
|
|
113
|
+
|
|
114
|
+
if __name__ == '__main__':
|
|
115
|
+
app.run()
|
|
116
|
+
The compiler automatically discovers .vel files and generates JavaScript.
|
|
117
|
+
|
|
118
|
+
What Happens
|
|
119
|
+
text
|
|
120
|
+
static/js/App.vel
|
|
121
|
+
↓
|
|
122
|
+
Teloce-Py Compiler
|
|
123
|
+
↓
|
|
124
|
+
static/js/App.js (self-contained)
|
|
125
|
+
↓
|
|
126
|
+
Browser executes App.js
|
|
127
|
+
No npm. No Node.js. No CDN. Just Python and vanilla JavaScript.
|
|
128
|
+
|
|
129
|
+
### npm/CDN-style standalone usage
|
|
130
|
+
|
|
131
|
+
For existing Flask, Django, FastAPI, Jinja, or static HTML pages that do not
|
|
132
|
+
use `.vel` files, serve `src/teloce/runtime/standalone.js` (also available as
|
|
133
|
+
`teloce.runtime.STANDALONE_RUNTIME`) and initialize the existing markup:
|
|
134
|
+
|
|
135
|
+
```html
|
|
136
|
+
<div id="app"><h1>{{ name }}</h1><button @click="count++">{{ count }}</button></div>
|
|
137
|
+
<script src="/static/teloce.js"></script>
|
|
138
|
+
<script>teloce.createApp('#app', { name: 'Python', count: 0 });</script>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
This provides the npm-compatible `teloce.createApp()`/`mount()` entry point,
|
|
142
|
+
interpolation, events, bindings, loops, conditions, filters, and plugins
|
|
143
|
+
without requiring Node.js or a CDN.
|
|
144
|
+
|
|
145
|
+
### CSS and template coordination
|
|
146
|
+
|
|
147
|
+
Scoped component styles and generated markup use the same deterministic
|
|
148
|
+
`data-v-*` scope attribute. Compiled components also install their CSS once
|
|
149
|
+
when mounted, so a page that loads `App.js` does not need a separate CSS tag.
|
|
150
|
+
The build still emits `App.css`; pass `inline_css=False` to `compile()` or the
|
|
151
|
+
compiler options when you want to serve the stylesheet separately for caching.
|
|
152
|
+
|
|
153
|
+
Features
|
|
154
|
+
Single File Components — Template, script, and style in one .vel file
|
|
155
|
+
|
|
156
|
+
Scoped CSS — Styles are automatically scoped to the component
|
|
157
|
+
|
|
158
|
+
Reactive Signals — Fine-grained reactivity without a Virtual DOM
|
|
159
|
+
|
|
160
|
+
Keyed Loops — Fast list rendering with DOM node reuse
|
|
161
|
+
|
|
162
|
+
Human-Friendly Errors — Clear error messages with suggestions
|
|
163
|
+
|
|
164
|
+
Framework Agnostic — Works with any Python web server
|
|
165
|
+
|
|
166
|
+
Development Server — Auto-compile on file changes
|
|
167
|
+
|
|
168
|
+
Production Build — Optimized output for deployment
|
|
169
|
+
|
|
170
|
+
Documentation
|
|
171
|
+
Architecture
|
|
172
|
+
|
|
173
|
+
Compiler Design
|
|
174
|
+
|
|
175
|
+
.vel Syntax
|
|
176
|
+
|
|
177
|
+
Template Syntax
|
|
178
|
+
|
|
179
|
+
Directives
|
|
180
|
+
|
|
181
|
+
Reactivity
|
|
182
|
+
|
|
183
|
+
License
|
|
184
|
+
MIT
|
|
185
|
+
|
|
186
|
+
Contributing
|
|
187
|
+
Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.
|
|
188
|
+
|
|
189
|
+
Support
|
|
190
|
+
GitHub Issues
|
|
191
|
+
|
|
192
|
+
Discord
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Teloce-Py
|
|
2
|
+
|
|
3
|
+
A Python compiler for Teloce `.vel` Single File Components.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Teloce-Py is a **100% Python compiler** that transforms `.vel` Single File Components into **self-contained vanilla JavaScript**. It works with any Python web framework (Flask, Flaxon, Django, FastAPI) without requiring Node.js, npm, or a CDN.
|
|
8
|
+
|
|
9
|
+
## Philosophy
|
|
10
|
+
|
|
11
|
+
> **"Write components in Python, run them in the browser — no npm required."**
|
|
12
|
+
|
|
13
|
+
- **100% Python** — The compiler is written entirely in Python
|
|
14
|
+
- **Self-contained JavaScript** — The output includes everything needed to run in the browser
|
|
15
|
+
- **No npm/Node.js** — Python developers don't need JavaScript tooling
|
|
16
|
+
- **Framework Agnostic** — Works with Flask, Flaxon, Django, FastAPI, and more
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
### Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install teloce-py
|
|
24
|
+
Create a .vel Component
|
|
25
|
+
html
|
|
26
|
+
<!-- static/js/App.vel -->
|
|
27
|
+
<template>
|
|
28
|
+
<div class="app">
|
|
29
|
+
<h1>{{ title }}</h1>
|
|
30
|
+
<button @click="increment">{{ count }}</button>
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script>
|
|
35
|
+
export default {
|
|
36
|
+
data() {
|
|
37
|
+
return {
|
|
38
|
+
title: "Hello Teloce",
|
|
39
|
+
count: 0
|
|
40
|
+
};
|
|
41
|
+
},
|
|
42
|
+
methods: {
|
|
43
|
+
increment() {
|
|
44
|
+
this.count++;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<style scoped>
|
|
51
|
+
.app { padding: 20px; }
|
|
52
|
+
button { background: #6366f1; color: white; border: none; padding: 8px 16px; }
|
|
53
|
+
</style>
|
|
54
|
+
Run Your Python App
|
|
55
|
+
python
|
|
56
|
+
# app.py
|
|
57
|
+
from flask import Flask, render_template
|
|
58
|
+
|
|
59
|
+
app = Flask(__name__)
|
|
60
|
+
|
|
61
|
+
@app.route('/')
|
|
62
|
+
def home():
|
|
63
|
+
return render_template('index.html')
|
|
64
|
+
|
|
65
|
+
if __name__ == '__main__':
|
|
66
|
+
app.run()
|
|
67
|
+
The compiler automatically discovers .vel files and generates JavaScript.
|
|
68
|
+
|
|
69
|
+
What Happens
|
|
70
|
+
text
|
|
71
|
+
static/js/App.vel
|
|
72
|
+
↓
|
|
73
|
+
Teloce-Py Compiler
|
|
74
|
+
↓
|
|
75
|
+
static/js/App.js (self-contained)
|
|
76
|
+
↓
|
|
77
|
+
Browser executes App.js
|
|
78
|
+
No npm. No Node.js. No CDN. Just Python and vanilla JavaScript.
|
|
79
|
+
|
|
80
|
+
### npm/CDN-style standalone usage
|
|
81
|
+
|
|
82
|
+
For existing Flask, Django, FastAPI, Jinja, or static HTML pages that do not
|
|
83
|
+
use `.vel` files, serve `src/teloce/runtime/standalone.js` (also available as
|
|
84
|
+
`teloce.runtime.STANDALONE_RUNTIME`) and initialize the existing markup:
|
|
85
|
+
|
|
86
|
+
```html
|
|
87
|
+
<div id="app"><h1>{{ name }}</h1><button @click="count++">{{ count }}</button></div>
|
|
88
|
+
<script src="/static/teloce.js"></script>
|
|
89
|
+
<script>teloce.createApp('#app', { name: 'Python', count: 0 });</script>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
This provides the npm-compatible `teloce.createApp()`/`mount()` entry point,
|
|
93
|
+
interpolation, events, bindings, loops, conditions, filters, and plugins
|
|
94
|
+
without requiring Node.js or a CDN.
|
|
95
|
+
|
|
96
|
+
### CSS and template coordination
|
|
97
|
+
|
|
98
|
+
Scoped component styles and generated markup use the same deterministic
|
|
99
|
+
`data-v-*` scope attribute. Compiled components also install their CSS once
|
|
100
|
+
when mounted, so a page that loads `App.js` does not need a separate CSS tag.
|
|
101
|
+
The build still emits `App.css`; pass `inline_css=False` to `compile()` or the
|
|
102
|
+
compiler options when you want to serve the stylesheet separately for caching.
|
|
103
|
+
|
|
104
|
+
Features
|
|
105
|
+
Single File Components — Template, script, and style in one .vel file
|
|
106
|
+
|
|
107
|
+
Scoped CSS — Styles are automatically scoped to the component
|
|
108
|
+
|
|
109
|
+
Reactive Signals — Fine-grained reactivity without a Virtual DOM
|
|
110
|
+
|
|
111
|
+
Keyed Loops — Fast list rendering with DOM node reuse
|
|
112
|
+
|
|
113
|
+
Human-Friendly Errors — Clear error messages with suggestions
|
|
114
|
+
|
|
115
|
+
Framework Agnostic — Works with any Python web server
|
|
116
|
+
|
|
117
|
+
Development Server — Auto-compile on file changes
|
|
118
|
+
|
|
119
|
+
Production Build — Optimized output for deployment
|
|
120
|
+
|
|
121
|
+
Documentation
|
|
122
|
+
Architecture
|
|
123
|
+
|
|
124
|
+
Compiler Design
|
|
125
|
+
|
|
126
|
+
.vel Syntax
|
|
127
|
+
|
|
128
|
+
Template Syntax
|
|
129
|
+
|
|
130
|
+
Directives
|
|
131
|
+
|
|
132
|
+
Reactivity
|
|
133
|
+
|
|
134
|
+
License
|
|
135
|
+
MIT
|
|
136
|
+
|
|
137
|
+
Contributing
|
|
138
|
+
Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.
|
|
139
|
+
|
|
140
|
+
Support
|
|
141
|
+
GitHub Issues
|
|
142
|
+
|
|
143
|
+
Discord
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "teloce-py"
|
|
7
|
+
description = "A Python compiler for Teloce .vel Single File Components"
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
license = { file = "LICENSE" }
|
|
10
|
+
authors = [
|
|
11
|
+
{ name = "Teloce Contributors" }
|
|
12
|
+
]
|
|
13
|
+
maintainers = [
|
|
14
|
+
{ name = "Teloce Contributors", email = "team@teloce.dev" }
|
|
15
|
+
]
|
|
16
|
+
keywords = [
|
|
17
|
+
"teloce",
|
|
18
|
+
"compiler",
|
|
19
|
+
"sfc",
|
|
20
|
+
"template-engine",
|
|
21
|
+
"python",
|
|
22
|
+
"flask",
|
|
23
|
+
"django",
|
|
24
|
+
"fastapi",
|
|
25
|
+
"flaxon"
|
|
26
|
+
]
|
|
27
|
+
classifiers = [
|
|
28
|
+
"Development Status :: 3 - Alpha",
|
|
29
|
+
"Intended Audience :: Developers",
|
|
30
|
+
"License :: OSI Approved :: MIT License",
|
|
31
|
+
"Programming Language :: Python :: 3",
|
|
32
|
+
"Programming Language :: Python :: 3.9",
|
|
33
|
+
"Programming Language :: Python :: 3.10",
|
|
34
|
+
"Programming Language :: Python :: 3.11",
|
|
35
|
+
"Programming Language :: Python :: 3.12",
|
|
36
|
+
"Topic :: Software Development :: Compilers",
|
|
37
|
+
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
|
|
38
|
+
]
|
|
39
|
+
requires-python = ">=3.10"
|
|
40
|
+
dependencies = []
|
|
41
|
+
dynamic = ["version"]
|
|
42
|
+
|
|
43
|
+
[project.urls]
|
|
44
|
+
Homepage = "https://teloce.dev"
|
|
45
|
+
Documentation = "https://docs.teloce.dev"
|
|
46
|
+
Repository = "https://github.com/aldanedev-create/telonce"
|
|
47
|
+
Issues = "https://github.com/aldanedev-create/telonce/issues"
|
|
48
|
+
Changelog = "https://github.com/aldanedev-create/telonce/blob/main/CHANGELOG.md"
|
|
49
|
+
|
|
50
|
+
[project.scripts]
|
|
51
|
+
teloce = "teloce.cli.main:main"
|
|
52
|
+
|
|
53
|
+
[tool.setuptools]
|
|
54
|
+
package-dir = { "" = "src" }
|
|
55
|
+
packages = { find = { where = ["src"] } }
|
|
56
|
+
include-package-data = true
|
|
57
|
+
|
|
58
|
+
[tool.setuptools.package-data]
|
|
59
|
+
"teloce.runtime" = ["*.js"]
|
|
60
|
+
|
|
61
|
+
[tool.setuptools.dynamic]
|
|
62
|
+
version = { attr = "teloce.version.__version__" }
|
|
63
|
+
|
|
64
|
+
[tool.black]
|
|
65
|
+
line-length = 88
|
|
66
|
+
target-version = ["py39"]
|
|
67
|
+
|
|
68
|
+
[tool.isort]
|
|
69
|
+
profile = "black"
|
|
70
|
+
line_length = 88
|
|
71
|
+
|
|
72
|
+
[tool.mypy]
|
|
73
|
+
python_version = "3.9"
|
|
74
|
+
warn_return_any = true
|
|
75
|
+
warn_unused_configs = true
|
|
76
|
+
ignore_missing_imports = true
|
|
77
|
+
|
|
78
|
+
[tool.pytest.ini_options]
|
|
79
|
+
testpaths = ["tests"]
|
|
80
|
+
pythonpath = ["src"]
|
|
81
|
+
python_files = "test_*.py"
|
|
82
|
+
python_classes = "Test*"
|
|
83
|
+
python_functions = "test_*"
|
|
84
|
+
addopts = "-v --tb=short"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Teloce-Py - A Python compiler for Teloce .vel Single File Components
|
|
3
|
+
|
|
4
|
+
Teloce-Py transforms .vel files into self-contained vanilla JavaScript
|
|
5
|
+
without requiring Node.js, npm, or a CDN.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from teloce.version import __version__
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"__version__",
|
|
12
|
+
"compile",
|
|
13
|
+
"compile_file",
|
|
14
|
+
"compile_project",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
from teloce.compiler.compiler import compile, compile_file, compile_project
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AST (Abstract Syntax Tree) package.
|
|
3
|
+
|
|
4
|
+
Defines AST nodes for Teloce templates.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from teloce.ast.nodes import (
|
|
8
|
+
ASTNode,
|
|
9
|
+
NodeType,
|
|
10
|
+
ElementNode,
|
|
11
|
+
TextNode,
|
|
12
|
+
InterpolationNode,
|
|
13
|
+
ForNode,
|
|
14
|
+
IfNode,
|
|
15
|
+
ElseNode,
|
|
16
|
+
EventNode,
|
|
17
|
+
BindingNode,
|
|
18
|
+
ComponentNode,
|
|
19
|
+
SlotNode,
|
|
20
|
+
FragmentNode,
|
|
21
|
+
AttributeNode,
|
|
22
|
+
CommentNode,
|
|
23
|
+
DoctypeNode,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
from teloce.ast.expressions import (
|
|
27
|
+
ExpressionNode,
|
|
28
|
+
IdentifierNode,
|
|
29
|
+
LiteralNode,
|
|
30
|
+
BinaryNode,
|
|
31
|
+
UnaryNode,
|
|
32
|
+
CallNode,
|
|
33
|
+
MemberNode,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
from teloce.ast.elements import (
|
|
37
|
+
ElementFactory,
|
|
38
|
+
VoidElement,
|
|
39
|
+
ContainerElement,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
from teloce.ast.components import (
|
|
43
|
+
ComponentReference,
|
|
44
|
+
ComponentSlot,
|
|
45
|
+
ComponentProp,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
from teloce.ast.visitors import (
|
|
49
|
+
ASTVisitor,
|
|
50
|
+
ASTTransformer,
|
|
51
|
+
ASTPrinter,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
__all__ = [
|
|
55
|
+
"ASTNode",
|
|
56
|
+
"NodeType",
|
|
57
|
+
"ElementNode",
|
|
58
|
+
"TextNode",
|
|
59
|
+
"InterpolationNode",
|
|
60
|
+
"ForNode",
|
|
61
|
+
"IfNode",
|
|
62
|
+
"ElseNode",
|
|
63
|
+
"EventNode",
|
|
64
|
+
"BindingNode",
|
|
65
|
+
"ComponentNode",
|
|
66
|
+
"SlotNode",
|
|
67
|
+
"FragmentNode",
|
|
68
|
+
"AttributeNode",
|
|
69
|
+
"CommentNode",
|
|
70
|
+
"DoctypeNode",
|
|
71
|
+
"ExpressionNode",
|
|
72
|
+
"IdentifierNode",
|
|
73
|
+
"LiteralNode",
|
|
74
|
+
"BinaryNode",
|
|
75
|
+
"UnaryNode",
|
|
76
|
+
"CallNode",
|
|
77
|
+
"MemberNode",
|
|
78
|
+
"ElementFactory",
|
|
79
|
+
"VoidElement",
|
|
80
|
+
"ContainerElement",
|
|
81
|
+
"ComponentReference",
|
|
82
|
+
"ComponentSlot",
|
|
83
|
+
"ComponentProp",
|
|
84
|
+
"ASTVisitor",
|
|
85
|
+
"ASTTransformer",
|
|
86
|
+
"ASTPrinter",
|
|
87
|
+
]
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Component AST nodes.
|
|
3
|
+
|
|
4
|
+
Defines nodes for custom components and component-related structures.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass, field
|
|
8
|
+
from typing import List, Optional, Dict, Any
|
|
9
|
+
|
|
10
|
+
from teloce.ast.nodes import ASTNode, NodeType
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(init=False)
|
|
14
|
+
class ComponentReference(ASTNode):
|
|
15
|
+
"""
|
|
16
|
+
Reference to a custom component.
|
|
17
|
+
"""
|
|
18
|
+
name: str
|
|
19
|
+
props: Dict[str, str] = field(default_factory=dict)
|
|
20
|
+
children: List[ASTNode] = field(default_factory=list)
|
|
21
|
+
slots: Dict[str, List[ASTNode]] = field(default_factory=dict)
|
|
22
|
+
|
|
23
|
+
def __init__(self, name: str, props: Dict[str, str] = None,
|
|
24
|
+
children: List[ASTNode] = None,
|
|
25
|
+
slots: Dict[str, List[ASTNode]] = None,
|
|
26
|
+
line: int = 0, column: int = 0):
|
|
27
|
+
super().__init__(NodeType.COMPONENT, line, column)
|
|
28
|
+
self.name = name
|
|
29
|
+
self.props = props or {}
|
|
30
|
+
self.children = children or []
|
|
31
|
+
self.slots = slots or {}
|
|
32
|
+
|
|
33
|
+
def accept(self, visitor):
|
|
34
|
+
return visitor.visit_component(self)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass(init=False)
|
|
38
|
+
class ComponentSlot(ASTNode):
|
|
39
|
+
"""
|
|
40
|
+
Slot definition inside a component.
|
|
41
|
+
"""
|
|
42
|
+
name: str = "default"
|
|
43
|
+
fallback: List[ASTNode] = field(default_factory=list)
|
|
44
|
+
|
|
45
|
+
def __init__(self, name: str = "default", fallback: List[ASTNode] = None,
|
|
46
|
+
line: int = 0, column: int = 0):
|
|
47
|
+
super().__init__(NodeType.SLOT, line, column)
|
|
48
|
+
self.name = name
|
|
49
|
+
self.fallback = fallback or []
|
|
50
|
+
|
|
51
|
+
def accept(self, visitor):
|
|
52
|
+
return visitor.visit_slot(self)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@dataclass(init=False)
|
|
56
|
+
class ComponentProp(ASTNode):
|
|
57
|
+
"""
|
|
58
|
+
Prop definition for a component.
|
|
59
|
+
"""
|
|
60
|
+
name: str
|
|
61
|
+
type: Optional[str] = None
|
|
62
|
+
required: bool = False
|
|
63
|
+
default: Any = None
|
|
64
|
+
validator: Optional[str] = None
|
|
65
|
+
|
|
66
|
+
def __init__(self, name: str, type: str = None, required: bool = False,
|
|
67
|
+
default: Any = None, validator: str = None,
|
|
68
|
+
line: int = 0, column: int = 0):
|
|
69
|
+
super().__init__(NodeType.ATTRIBUTE, line, column)
|
|
70
|
+
self.name = name
|
|
71
|
+
self.type = type
|
|
72
|
+
self.required = required
|
|
73
|
+
self.default = default
|
|
74
|
+
self.validator = validator
|
|
75
|
+
|
|
76
|
+
def accept(self, visitor):
|
|
77
|
+
return visitor.visit_attribute(self)
|