pulse-framework 0.1.51__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.
Files changed (84) hide show
  1. pulse/__init__.py +542 -562
  2. pulse/_examples.py +29 -0
  3. pulse/app.py +0 -14
  4. pulse/cli/cmd.py +96 -80
  5. pulse/cli/dependencies.py +10 -41
  6. pulse/cli/folder_lock.py +3 -3
  7. pulse/cli/helpers.py +40 -67
  8. pulse/cli/logging.py +102 -0
  9. pulse/cli/packages.py +16 -0
  10. pulse/cli/processes.py +40 -23
  11. pulse/codegen/codegen.py +70 -35
  12. pulse/codegen/js.py +2 -4
  13. pulse/codegen/templates/route.py +94 -146
  14. pulse/component.py +115 -0
  15. pulse/components/for_.py +1 -1
  16. pulse/components/if_.py +1 -1
  17. pulse/components/react_router.py +16 -22
  18. pulse/{html → dom}/events.py +1 -1
  19. pulse/{html → dom}/props.py +6 -6
  20. pulse/{html → dom}/tags.py +11 -11
  21. pulse/dom/tags.pyi +480 -0
  22. pulse/form.py +7 -6
  23. pulse/hooks/init.py +1 -13
  24. pulse/js/__init__.py +37 -41
  25. pulse/js/__init__.pyi +22 -2
  26. pulse/js/_types.py +5 -3
  27. pulse/js/array.py +121 -38
  28. pulse/js/console.py +9 -9
  29. pulse/js/date.py +22 -19
  30. pulse/js/document.py +8 -4
  31. pulse/js/error.py +12 -14
  32. pulse/js/json.py +4 -3
  33. pulse/js/map.py +17 -7
  34. pulse/js/math.py +2 -2
  35. pulse/js/navigator.py +4 -4
  36. pulse/js/number.py +8 -8
  37. pulse/js/object.py +9 -13
  38. pulse/js/promise.py +25 -9
  39. pulse/js/regexp.py +6 -6
  40. pulse/js/set.py +20 -8
  41. pulse/js/string.py +7 -7
  42. pulse/js/weakmap.py +6 -6
  43. pulse/js/weakset.py +6 -6
  44. pulse/js/window.py +17 -14
  45. pulse/messages.py +1 -4
  46. pulse/react_component.py +3 -1001
  47. pulse/render_session.py +74 -66
  48. pulse/renderer.py +311 -238
  49. pulse/routing.py +1 -10
  50. pulse/transpiler/__init__.py +84 -114
  51. pulse/transpiler/builtins.py +661 -343
  52. pulse/transpiler/errors.py +78 -2
  53. pulse/transpiler/function.py +463 -133
  54. pulse/transpiler/id.py +18 -0
  55. pulse/transpiler/imports.py +230 -325
  56. pulse/transpiler/js_module.py +218 -209
  57. pulse/transpiler/modules/__init__.py +16 -13
  58. pulse/transpiler/modules/asyncio.py +45 -26
  59. pulse/transpiler/modules/json.py +12 -8
  60. pulse/transpiler/modules/math.py +161 -216
  61. pulse/transpiler/modules/pulse/__init__.py +5 -0
  62. pulse/transpiler/modules/pulse/tags.py +231 -0
  63. pulse/transpiler/modules/typing.py +33 -28
  64. pulse/transpiler/nodes.py +1607 -923
  65. pulse/transpiler/py_module.py +118 -95
  66. pulse/transpiler/react_component.py +51 -0
  67. pulse/transpiler/transpiler.py +593 -437
  68. pulse/transpiler/vdom.py +255 -0
  69. {pulse_framework-0.1.51.dist-info → pulse_framework-0.1.52.dist-info}/METADATA +1 -1
  70. pulse_framework-0.1.52.dist-info/RECORD +120 -0
  71. pulse/html/tags.pyi +0 -470
  72. pulse/transpiler/constants.py +0 -110
  73. pulse/transpiler/context.py +0 -26
  74. pulse/transpiler/ids.py +0 -16
  75. pulse/transpiler/modules/re.py +0 -466
  76. pulse/transpiler/modules/tags.py +0 -268
  77. pulse/transpiler/utils.py +0 -4
  78. pulse/vdom.py +0 -599
  79. pulse_framework-0.1.51.dist-info/RECORD +0 -119
  80. /pulse/{html → dom}/__init__.py +0 -0
  81. /pulse/{html → dom}/elements.py +0 -0
  82. /pulse/{html → dom}/svg.py +0 -0
  83. {pulse_framework-0.1.51.dist-info → pulse_framework-0.1.52.dist-info}/WHEEL +0 -0
  84. {pulse_framework-0.1.51.dist-info → pulse_framework-0.1.52.dist-info}/entry_points.txt +0 -0
@@ -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
@@ -1,4 +0,0 @@
1
- from collections.abc import Callable
2
- from typing import Any
3
-
4
- AnyCallable = Callable[..., Any]