pulse-framework 0.1.50__py3-none-any.whl → 0.1.52__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.
- pulse/__init__.py +542 -562
- pulse/_examples.py +29 -0
- pulse/app.py +0 -14
- pulse/cli/cmd.py +96 -80
- pulse/cli/dependencies.py +10 -41
- pulse/cli/folder_lock.py +3 -3
- pulse/cli/helpers.py +40 -67
- pulse/cli/logging.py +102 -0
- pulse/cli/packages.py +16 -0
- pulse/cli/processes.py +40 -23
- pulse/codegen/codegen.py +70 -35
- pulse/codegen/js.py +2 -4
- pulse/codegen/templates/route.py +94 -146
- pulse/component.py +115 -0
- pulse/components/for_.py +1 -1
- pulse/components/if_.py +1 -1
- pulse/components/react_router.py +16 -22
- pulse/{html → dom}/events.py +1 -1
- pulse/{html → dom}/props.py +6 -6
- pulse/{html → dom}/tags.py +11 -11
- pulse/dom/tags.pyi +480 -0
- pulse/form.py +7 -6
- pulse/hooks/init.py +1 -13
- pulse/js/__init__.py +37 -41
- pulse/js/__init__.pyi +22 -2
- pulse/js/_types.py +5 -3
- pulse/js/array.py +121 -38
- pulse/js/console.py +9 -9
- pulse/js/date.py +22 -19
- pulse/js/document.py +8 -4
- pulse/js/error.py +12 -14
- pulse/js/json.py +4 -3
- pulse/js/map.py +17 -7
- pulse/js/math.py +2 -2
- pulse/js/navigator.py +4 -4
- pulse/js/number.py +8 -8
- pulse/js/object.py +9 -13
- pulse/js/promise.py +25 -9
- pulse/js/regexp.py +6 -6
- pulse/js/set.py +20 -8
- pulse/js/string.py +7 -7
- pulse/js/weakmap.py +6 -6
- pulse/js/weakset.py +6 -6
- pulse/js/window.py +17 -14
- pulse/messages.py +1 -4
- pulse/react_component.py +3 -999
- pulse/render_session.py +74 -66
- pulse/renderer.py +311 -238
- pulse/routing.py +1 -10
- pulse/serializer.py +11 -1
- pulse/transpiler/__init__.py +84 -114
- pulse/transpiler/builtins.py +661 -343
- pulse/transpiler/errors.py +78 -2
- pulse/transpiler/function.py +463 -133
- pulse/transpiler/id.py +18 -0
- pulse/transpiler/imports.py +230 -325
- pulse/transpiler/js_module.py +218 -209
- pulse/transpiler/modules/__init__.py +16 -13
- pulse/transpiler/modules/asyncio.py +45 -26
- pulse/transpiler/modules/json.py +12 -8
- pulse/transpiler/modules/math.py +161 -216
- pulse/transpiler/modules/pulse/__init__.py +5 -0
- pulse/transpiler/modules/pulse/tags.py +231 -0
- pulse/transpiler/modules/typing.py +33 -28
- pulse/transpiler/nodes.py +1607 -923
- pulse/transpiler/py_module.py +118 -95
- pulse/transpiler/react_component.py +51 -0
- pulse/transpiler/transpiler.py +593 -437
- pulse/transpiler/vdom.py +255 -0
- {pulse_framework-0.1.50.dist-info → pulse_framework-0.1.52.dist-info}/METADATA +1 -1
- pulse_framework-0.1.52.dist-info/RECORD +120 -0
- pulse/html/tags.pyi +0 -470
- pulse/transpiler/constants.py +0 -110
- pulse/transpiler/context.py +0 -26
- pulse/transpiler/ids.py +0 -16
- pulse/transpiler/modules/re.py +0 -466
- pulse/transpiler/modules/tags.py +0 -268
- pulse/transpiler/utils.py +0 -4
- pulse/vdom.py +0 -667
- pulse_framework-0.1.50.dist-info/RECORD +0 -119
- /pulse/{html → dom}/__init__.py +0 -0
- /pulse/{html → dom}/elements.py +0 -0
- /pulse/{html → dom}/svg.py +0 -0
- {pulse_framework-0.1.50.dist-info → pulse_framework-0.1.52.dist-info}/WHEEL +0 -0
- {pulse_framework-0.1.50.dist-info → pulse_framework-0.1.52.dist-info}/entry_points.txt +0 -0
pulse/transpiler/modules/tags.py
DELETED
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
"""HTML tag function transpilation to JSX elements.
|
|
2
|
-
|
|
3
|
-
This module provides transpilation from pulse.html.tags (like div, span, etc.)
|
|
4
|
-
to JSX elements. Tag functions can be called with props and subscripted with children:
|
|
5
|
-
|
|
6
|
-
# Python
|
|
7
|
-
div(className="container")[span("Hello"), p("World")]
|
|
8
|
-
|
|
9
|
-
# JavaScript
|
|
10
|
-
<div className="container"><span>Hello</span><p>World</p></div>
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
# pyright: reportUnannotatedClassAttribute=false
|
|
14
|
-
|
|
15
|
-
from __future__ import annotations
|
|
16
|
-
|
|
17
|
-
from collections.abc import Sequence
|
|
18
|
-
from dataclasses import dataclass, field
|
|
19
|
-
from typing import Any, ClassVar, override
|
|
20
|
-
|
|
21
|
-
from pulse.transpiler.errors import JSCompilationError
|
|
22
|
-
from pulse.transpiler.nodes import (
|
|
23
|
-
JSArray,
|
|
24
|
-
JSExpr,
|
|
25
|
-
JSSpread,
|
|
26
|
-
JSString,
|
|
27
|
-
JSXElement,
|
|
28
|
-
JSXFragment,
|
|
29
|
-
JSXProp,
|
|
30
|
-
JSXSpreadProp,
|
|
31
|
-
)
|
|
32
|
-
from pulse.transpiler.py_module import PyModule
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def _flatten_children(items: list[Any], out: list[JSExpr | JSXElement | str]) -> None:
|
|
36
|
-
"""Flatten arrays and handle spreads in children list."""
|
|
37
|
-
for it in items:
|
|
38
|
-
# Convert raw values first
|
|
39
|
-
it = JSExpr.of(it) if not isinstance(it, JSExpr) else it
|
|
40
|
-
if isinstance(it, JSArray):
|
|
41
|
-
_flatten_children(list(it.elements), out)
|
|
42
|
-
elif isinstance(it, JSSpread):
|
|
43
|
-
# Spread children: pass the inner expression; React handles arrays
|
|
44
|
-
out.append(it.expr)
|
|
45
|
-
elif isinstance(it, JSString):
|
|
46
|
-
out.append(it.value)
|
|
47
|
-
else:
|
|
48
|
-
out.append(it)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def _build_jsx_props(kwargs: dict[str, Any]) -> list[JSXProp | JSXSpreadProp]:
|
|
52
|
-
"""Build JSX props list from kwargs dict.
|
|
53
|
-
|
|
54
|
-
Kwargs maps:
|
|
55
|
-
- "propName" -> value for named props
|
|
56
|
-
- "__spread_N" -> JSSpread(expr) for spread props
|
|
57
|
-
|
|
58
|
-
Dict order is preserved, so iteration order matches source order.
|
|
59
|
-
"""
|
|
60
|
-
props: list[JSXProp | JSXSpreadProp] = []
|
|
61
|
-
|
|
62
|
-
for key, value in kwargs.items():
|
|
63
|
-
if isinstance(value, JSSpread):
|
|
64
|
-
# Spread prop: {...expr}
|
|
65
|
-
props.append(JSXSpreadProp(value.expr))
|
|
66
|
-
else:
|
|
67
|
-
# Named prop - convert to JSExpr
|
|
68
|
-
props.append(JSXProp(key, JSExpr.of(value)))
|
|
69
|
-
|
|
70
|
-
return props
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def _create_tag_function(tag_name: str):
|
|
74
|
-
"""Create a tag function that returns JSXCallExpr when called."""
|
|
75
|
-
|
|
76
|
-
@staticmethod
|
|
77
|
-
def tag_func(*args: Any, **kwargs: Any) -> JSExpr:
|
|
78
|
-
"""Tag function that creates JSXCallExpr with props and children."""
|
|
79
|
-
props_list = _build_jsx_props(kwargs)
|
|
80
|
-
children_list: list[JSExpr | JSXElement | str] = []
|
|
81
|
-
_flatten_children(list(args), children_list)
|
|
82
|
-
return JSXCallExpr(tag_name, tuple(props_list), tuple(children_list))
|
|
83
|
-
|
|
84
|
-
return tag_func
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
@dataclass
|
|
88
|
-
class JSXCallExpr(JSExpr):
|
|
89
|
-
"""Expression representing a called tag with props (but possibly more children).
|
|
90
|
-
|
|
91
|
-
When subscripted, adds children to produce the final JSXElement.
|
|
92
|
-
Calling again is an error (can't call an element).
|
|
93
|
-
"""
|
|
94
|
-
|
|
95
|
-
tag_name: str
|
|
96
|
-
props: Sequence[JSXProp | JSXSpreadProp] = field(default_factory=tuple)
|
|
97
|
-
children: Sequence[str | JSExpr | JSXElement] = field(default_factory=tuple)
|
|
98
|
-
is_jsx: ClassVar[bool] = True
|
|
99
|
-
|
|
100
|
-
@override
|
|
101
|
-
def emit(self) -> str:
|
|
102
|
-
# Emit as final JSXElement
|
|
103
|
-
return JSXElement(self.tag_name, self.props, self.children).emit()
|
|
104
|
-
|
|
105
|
-
@override
|
|
106
|
-
def emit_subscript(self, indices: list[Any]) -> JSExpr:
|
|
107
|
-
"""Handle tag(props...)[children] -> JSXElement."""
|
|
108
|
-
extra_children: list[JSExpr | JSXElement | str] = []
|
|
109
|
-
_flatten_children(indices, extra_children)
|
|
110
|
-
all_children = list(self.children) + extra_children
|
|
111
|
-
return JSXElement(self.tag_name, self.props, all_children)
|
|
112
|
-
|
|
113
|
-
@override
|
|
114
|
-
def emit_call(self, args: list[Any], kwargs: dict[str, Any]) -> JSExpr:
|
|
115
|
-
"""Calling an already-called tag is an error."""
|
|
116
|
-
from pulse.transpiler.errors import JSCompilationError
|
|
117
|
-
|
|
118
|
-
raise JSCompilationError(
|
|
119
|
-
f"Cannot call JSX element <{self.tag_name}> - already called. "
|
|
120
|
-
+ "Use subscript for children: tag(props...)[children]"
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
class PyTags(PyModule):
|
|
125
|
-
"""Provides transpilation for pulse.html.tags to JSX elements."""
|
|
126
|
-
|
|
127
|
-
# Regular tags - each is a function that returns JSXCallExpr when called
|
|
128
|
-
a = _create_tag_function("a")
|
|
129
|
-
abbr = _create_tag_function("abbr")
|
|
130
|
-
address = _create_tag_function("address")
|
|
131
|
-
article = _create_tag_function("article")
|
|
132
|
-
aside = _create_tag_function("aside")
|
|
133
|
-
audio = _create_tag_function("audio")
|
|
134
|
-
b = _create_tag_function("b")
|
|
135
|
-
bdi = _create_tag_function("bdi")
|
|
136
|
-
bdo = _create_tag_function("bdo")
|
|
137
|
-
blockquote = _create_tag_function("blockquote")
|
|
138
|
-
body = _create_tag_function("body")
|
|
139
|
-
button = _create_tag_function("button")
|
|
140
|
-
canvas = _create_tag_function("canvas")
|
|
141
|
-
caption = _create_tag_function("caption")
|
|
142
|
-
cite = _create_tag_function("cite")
|
|
143
|
-
code = _create_tag_function("code")
|
|
144
|
-
colgroup = _create_tag_function("colgroup")
|
|
145
|
-
data = _create_tag_function("data")
|
|
146
|
-
datalist = _create_tag_function("datalist")
|
|
147
|
-
dd = _create_tag_function("dd")
|
|
148
|
-
del_ = _create_tag_function("del")
|
|
149
|
-
details = _create_tag_function("details")
|
|
150
|
-
dfn = _create_tag_function("dfn")
|
|
151
|
-
dialog = _create_tag_function("dialog")
|
|
152
|
-
div = _create_tag_function("div")
|
|
153
|
-
dl = _create_tag_function("dl")
|
|
154
|
-
dt = _create_tag_function("dt")
|
|
155
|
-
em = _create_tag_function("em")
|
|
156
|
-
fieldset = _create_tag_function("fieldset")
|
|
157
|
-
figcaption = _create_tag_function("figcaption")
|
|
158
|
-
figure = _create_tag_function("figure")
|
|
159
|
-
footer = _create_tag_function("footer")
|
|
160
|
-
form = _create_tag_function("form")
|
|
161
|
-
h1 = _create_tag_function("h1")
|
|
162
|
-
h2 = _create_tag_function("h2")
|
|
163
|
-
h3 = _create_tag_function("h3")
|
|
164
|
-
h4 = _create_tag_function("h4")
|
|
165
|
-
h5 = _create_tag_function("h5")
|
|
166
|
-
h6 = _create_tag_function("h6")
|
|
167
|
-
head = _create_tag_function("head")
|
|
168
|
-
header = _create_tag_function("header")
|
|
169
|
-
hgroup = _create_tag_function("hgroup")
|
|
170
|
-
html = _create_tag_function("html")
|
|
171
|
-
i = _create_tag_function("i")
|
|
172
|
-
iframe = _create_tag_function("iframe")
|
|
173
|
-
ins = _create_tag_function("ins")
|
|
174
|
-
kbd = _create_tag_function("kbd")
|
|
175
|
-
label = _create_tag_function("label")
|
|
176
|
-
legend = _create_tag_function("legend")
|
|
177
|
-
li = _create_tag_function("li")
|
|
178
|
-
main = _create_tag_function("main")
|
|
179
|
-
map_ = _create_tag_function("map")
|
|
180
|
-
mark = _create_tag_function("mark")
|
|
181
|
-
menu = _create_tag_function("menu")
|
|
182
|
-
meter = _create_tag_function("meter")
|
|
183
|
-
nav = _create_tag_function("nav")
|
|
184
|
-
noscript = _create_tag_function("noscript")
|
|
185
|
-
object_ = _create_tag_function("object")
|
|
186
|
-
ol = _create_tag_function("ol")
|
|
187
|
-
optgroup = _create_tag_function("optgroup")
|
|
188
|
-
option = _create_tag_function("option")
|
|
189
|
-
output = _create_tag_function("output")
|
|
190
|
-
p = _create_tag_function("p")
|
|
191
|
-
picture = _create_tag_function("picture")
|
|
192
|
-
pre = _create_tag_function("pre")
|
|
193
|
-
progress = _create_tag_function("progress")
|
|
194
|
-
q = _create_tag_function("q")
|
|
195
|
-
rp = _create_tag_function("rp")
|
|
196
|
-
rt = _create_tag_function("rt")
|
|
197
|
-
ruby = _create_tag_function("ruby")
|
|
198
|
-
s = _create_tag_function("s")
|
|
199
|
-
samp = _create_tag_function("samp")
|
|
200
|
-
script = _create_tag_function("script")
|
|
201
|
-
section = _create_tag_function("section")
|
|
202
|
-
select = _create_tag_function("select")
|
|
203
|
-
small = _create_tag_function("small")
|
|
204
|
-
span = _create_tag_function("span")
|
|
205
|
-
strong = _create_tag_function("strong")
|
|
206
|
-
style = _create_tag_function("style")
|
|
207
|
-
sub = _create_tag_function("sub")
|
|
208
|
-
summary = _create_tag_function("summary")
|
|
209
|
-
sup = _create_tag_function("sup")
|
|
210
|
-
table = _create_tag_function("table")
|
|
211
|
-
tbody = _create_tag_function("tbody")
|
|
212
|
-
td = _create_tag_function("td")
|
|
213
|
-
template = _create_tag_function("template")
|
|
214
|
-
textarea = _create_tag_function("textarea")
|
|
215
|
-
tfoot = _create_tag_function("tfoot")
|
|
216
|
-
th = _create_tag_function("th")
|
|
217
|
-
thead = _create_tag_function("thead")
|
|
218
|
-
time = _create_tag_function("time")
|
|
219
|
-
title = _create_tag_function("title")
|
|
220
|
-
tr = _create_tag_function("tr")
|
|
221
|
-
u = _create_tag_function("u")
|
|
222
|
-
ul = _create_tag_function("ul")
|
|
223
|
-
var = _create_tag_function("var")
|
|
224
|
-
video = _create_tag_function("video")
|
|
225
|
-
|
|
226
|
-
# Self-closing tags
|
|
227
|
-
area = _create_tag_function("area")
|
|
228
|
-
base = _create_tag_function("base")
|
|
229
|
-
br = _create_tag_function("br")
|
|
230
|
-
col = _create_tag_function("col")
|
|
231
|
-
embed = _create_tag_function("embed")
|
|
232
|
-
hr = _create_tag_function("hr")
|
|
233
|
-
img = _create_tag_function("img")
|
|
234
|
-
input = _create_tag_function("input")
|
|
235
|
-
link = _create_tag_function("link")
|
|
236
|
-
meta = _create_tag_function("meta")
|
|
237
|
-
param = _create_tag_function("param")
|
|
238
|
-
source = _create_tag_function("source")
|
|
239
|
-
track = _create_tag_function("track")
|
|
240
|
-
wbr = _create_tag_function("wbr")
|
|
241
|
-
|
|
242
|
-
# SVG tags
|
|
243
|
-
svg = _create_tag_function("svg")
|
|
244
|
-
circle = _create_tag_function("circle")
|
|
245
|
-
ellipse = _create_tag_function("ellipse")
|
|
246
|
-
g = _create_tag_function("g")
|
|
247
|
-
line = _create_tag_function("line")
|
|
248
|
-
path = _create_tag_function("path")
|
|
249
|
-
polygon = _create_tag_function("polygon")
|
|
250
|
-
polyline = _create_tag_function("polyline")
|
|
251
|
-
rect = _create_tag_function("rect")
|
|
252
|
-
text = _create_tag_function("text")
|
|
253
|
-
tspan = _create_tag_function("tspan")
|
|
254
|
-
defs = _create_tag_function("defs")
|
|
255
|
-
clipPath = _create_tag_function("clipPath")
|
|
256
|
-
mask = _create_tag_function("mask")
|
|
257
|
-
pattern = _create_tag_function("pattern")
|
|
258
|
-
use = _create_tag_function("use")
|
|
259
|
-
|
|
260
|
-
# React fragment
|
|
261
|
-
@staticmethod
|
|
262
|
-
def fragment(*args: Any, **kwargs: Any) -> JSExpr:
|
|
263
|
-
"""Fragment function that creates JSXFragment with children."""
|
|
264
|
-
if kwargs:
|
|
265
|
-
raise JSCompilationError("React fragments cannot have props")
|
|
266
|
-
children_list: list[JSExpr | JSXElement | str] = []
|
|
267
|
-
_flatten_children(list(args), children_list)
|
|
268
|
-
return JSXFragment(children_list)
|
pulse/transpiler/utils.py
DELETED