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
pulse/html/tags.pyi DELETED
@@ -1,470 +0,0 @@
1
- from typing import Any, Protocol, Unpack
2
-
3
- from pulse.html.elements import GenericHTMLElement
4
- from pulse.html.props import (
5
- HTMLAnchorProps,
6
- HTMLAreaProps,
7
- HTMLAudioProps,
8
- HTMLBaseProps,
9
- HTMLBlockquoteProps,
10
- HTMLButtonProps,
11
- HTMLCanvasProps,
12
- HTMLColgroupProps,
13
- HTMLColProps,
14
- HTMLDataProps,
15
- HTMLDelProps,
16
- HTMLDetailsProps,
17
- HTMLDialogProps,
18
- HTMLEmbedProps,
19
- HTMLFieldsetProps,
20
- HTMLFormProps,
21
- HTMLHtmlProps,
22
- HTMLIframeProps,
23
- HTMLImgProps,
24
- HTMLInputProps,
25
- HTMLInsProps,
26
- HTMLLabelProps,
27
- HTMLLinkProps,
28
- HTMLLiProps,
29
- HTMLMapProps,
30
- HTMLMenuProps,
31
- HTMLMetaProps,
32
- HTMLMeterProps,
33
- HTMLObjectProps,
34
- HTMLOlProps,
35
- HTMLOptgroupProps,
36
- HTMLOptionProps,
37
- HTMLOutputProps,
38
- HTMLParamProps,
39
- HTMLProgressProps,
40
- HTMLProps,
41
- HTMLQuoteProps,
42
- HTMLScriptProps,
43
- HTMLSelectProps,
44
- HTMLSourceProps,
45
- HTMLStyleProps,
46
- HTMLSVGProps,
47
- HTMLTableProps,
48
- HTMLTdProps,
49
- HTMLTextareaProps,
50
- HTMLThProps,
51
- HTMLTimeProps,
52
- HTMLTrackProps,
53
- HTMLVideoProps,
54
- )
55
- from pulse.vdom import Child, Node
56
-
57
- class Tag(Protocol):
58
- def __call__(self, *children: Child, **props: Any) -> Node: ...
59
-
60
- def define_tag(
61
- name: str,
62
- default_props: dict[str, Any] | None = None,
63
- ) -> Tag: ...
64
- def define_self_closing_tag(
65
- name: str,
66
- default_props: dict[str, Any] | None = None,
67
- ) -> Tag: ...
68
-
69
- # --- Self-closing tags ----
70
- def area(*, key: str | None = None, **props: Unpack[HTMLAreaProps]) -> Node: ...
71
- def base(*, key: str | None = None, **props: Unpack[HTMLBaseProps]) -> Node: ...
72
- def br(*, key: str | None = None, **props: Unpack[HTMLProps]) -> Node: ...
73
- def col(*, key: str | None = None, **props: Unpack[HTMLColProps]) -> Node: ...
74
- def embed(*, key: str | None = None, **props: Unpack[HTMLEmbedProps]) -> Node: ...
75
- def hr(*, key: str | None = None, **props: Unpack[HTMLProps]) -> Node: ...
76
- def img(*, key: str | None = None, **props: Unpack[HTMLImgProps]) -> Node: ...
77
- def input(*, key: str | None = None, **props: Unpack[HTMLInputProps]) -> Node: ...
78
- def link(*, key: str | None = None, **props: Unpack[HTMLLinkProps]) -> Node: ...
79
- def meta(*, key: str | None = None, **props: Unpack[HTMLMetaProps]) -> Node: ...
80
- def param(*, key: str | None = None, **props: Unpack[HTMLParamProps]) -> Node: ...
81
- def source(*, key: str | None = None, **props: Unpack[HTMLSourceProps]) -> Node: ...
82
- def track(*, key: str | None = None, **props: Unpack[HTMLTrackProps]) -> Node: ...
83
- def wbr(*, key: str | None = None, **props: Unpack[HTMLProps]) -> Node: ...
84
-
85
- # --- Regular tags ---
86
-
87
- def a(
88
- *children: Child, key: str | None = None, **props: Unpack[HTMLAnchorProps]
89
- ) -> Node: ...
90
- def abbr(
91
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
92
- ) -> Node: ...
93
- def address(
94
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
95
- ) -> Node: ...
96
- def article(
97
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
98
- ) -> Node: ...
99
- def aside(
100
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
101
- ) -> Node: ...
102
- def audio(
103
- *children: Child, key: str | None = None, **props: Unpack[HTMLAudioProps]
104
- ) -> Node: ...
105
- def b(*children: Child, key: str | None = None, **props: Unpack[HTMLProps]) -> Node: ...
106
- def bdi(
107
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
108
- ) -> Node: ...
109
- def bdo(
110
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
111
- ) -> Node: ...
112
- def blockquote(
113
- *children: Child,
114
- key: str | None = None,
115
- **props: Unpack[HTMLBlockquoteProps],
116
- ) -> Node: ...
117
- def body(
118
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
119
- ) -> Node: ...
120
- def button(
121
- *children: Child, key: str | None = None, **props: Unpack[HTMLButtonProps]
122
- ) -> Node: ...
123
- def canvas(
124
- *children: Child, key: str | None = None, **props: Unpack[HTMLCanvasProps]
125
- ) -> Node: ...
126
- def caption(
127
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
128
- ) -> Node: ...
129
- def cite(
130
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
131
- ) -> Node: ...
132
- def code(
133
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
134
- ) -> Node: ...
135
- def colgroup(
136
- *children: Child,
137
- key: str | None = None,
138
- **props: Unpack[HTMLColgroupProps],
139
- ) -> Node: ...
140
- def data(
141
- *children: Child, key: str | None = None, **props: Unpack[HTMLDataProps]
142
- ) -> Node: ...
143
- def datalist(
144
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
145
- ) -> Node: ...
146
- def dd(
147
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
148
- ) -> Node: ...
149
- def del_(
150
- *children: Child, key: str | None = None, **props: Unpack[HTMLDelProps]
151
- ) -> Node: ...
152
- def details(
153
- *children: Child,
154
- key: str | None = None,
155
- **props: Unpack[HTMLDetailsProps],
156
- ) -> Node: ...
157
- def dfn(
158
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
159
- ) -> Node: ...
160
- def dialog(
161
- *children: Child, key: str | None = None, **props: Unpack[HTMLDialogProps]
162
- ) -> Node: ...
163
- def div(
164
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
165
- ) -> Node: ...
166
- def dl(
167
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
168
- ) -> Node: ...
169
- def dt(
170
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
171
- ) -> Node: ...
172
- def em(
173
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
174
- ) -> Node: ...
175
- def fieldset(
176
- *children: Child,
177
- key: str | None = None,
178
- **props: Unpack[HTMLFieldsetProps],
179
- ) -> Node: ...
180
- def figcaption(
181
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
182
- ) -> Node: ...
183
- def figure(
184
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
185
- ) -> Node: ...
186
- def footer(
187
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
188
- ) -> Node: ...
189
- def form(
190
- *children: Child, key: str | None = None, **props: Unpack[HTMLFormProps]
191
- ) -> Node: ...
192
- def h1(
193
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
194
- ) -> Node: ...
195
- def h2(
196
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
197
- ) -> Node: ...
198
- def h3(
199
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
200
- ) -> Node: ...
201
- def h4(
202
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
203
- ) -> Node: ...
204
- def h5(
205
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
206
- ) -> Node: ...
207
- def h6(
208
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
209
- ) -> Node: ...
210
- def head(
211
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
212
- ) -> Node: ...
213
- def header(
214
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
215
- ) -> Node: ...
216
- def hgroup(
217
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
218
- ) -> Node: ...
219
- def html(
220
- *children: Child, key: str | None = None, **props: Unpack[HTMLHtmlProps]
221
- ) -> Node: ...
222
- def i(*children: Child, key: str | None = None, **props: Unpack[HTMLProps]) -> Node: ...
223
- def iframe(
224
- *children: Child, key: str | None = None, **props: Unpack[HTMLIframeProps]
225
- ) -> Node: ...
226
- def ins(
227
- *children: Child, key: str | None = None, **props: Unpack[HTMLInsProps]
228
- ) -> Node: ...
229
- def kbd(
230
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
231
- ) -> Node: ...
232
- def label(
233
- *children: Child, key: str | None = None, **props: Unpack[HTMLLabelProps]
234
- ) -> Node: ...
235
- def legend(
236
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
237
- ) -> Node: ...
238
- def li(
239
- *children: Child, key: str | None = None, **props: Unpack[HTMLLiProps]
240
- ) -> Node: ...
241
- def main(
242
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
243
- ) -> Node: ...
244
- def map_(
245
- *children: Child, key: str | None = None, **props: Unpack[HTMLMapProps]
246
- ) -> Node: ...
247
- def mark(
248
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
249
- ) -> Node: ...
250
- def menu(
251
- *children: Child, key: str | None = None, **props: Unpack[HTMLMenuProps]
252
- ) -> Node: ...
253
- def meter(
254
- *children: Child, key: str | None = None, **props: Unpack[HTMLMeterProps]
255
- ) -> Node: ...
256
- def nav(
257
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
258
- ) -> Node: ...
259
- def noscript(
260
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
261
- ) -> Node: ...
262
- def object_(
263
- *children: Child, key: str | None = None, **props: Unpack[HTMLObjectProps]
264
- ) -> Node: ...
265
- def ol(
266
- *children: Child, key: str | None = None, **props: Unpack[HTMLOlProps]
267
- ) -> Node: ...
268
- def optgroup(
269
- *children: Child,
270
- key: str | None = None,
271
- **props: Unpack[HTMLOptgroupProps],
272
- ) -> Node: ...
273
- def option(
274
- *children: Child, key: str | None = None, **props: Unpack[HTMLOptionProps]
275
- ) -> Node: ...
276
- def output(
277
- *children: Child, key: str | None = None, **props: Unpack[HTMLOutputProps]
278
- ) -> Node: ...
279
- def p(*children: Child, key: str | None = None, **props: Unpack[HTMLProps]) -> Node: ...
280
- def picture(
281
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
282
- ) -> Node: ...
283
- def pre(
284
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
285
- ) -> Node: ...
286
- def progress(
287
- *children: Child,
288
- key: str | None = None,
289
- **props: Unpack[HTMLProgressProps],
290
- ) -> Node: ...
291
- def q(
292
- *children: Child, key: str | None = None, **props: Unpack[HTMLQuoteProps]
293
- ) -> Node: ...
294
- def rp(
295
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
296
- ) -> Node: ...
297
- def rt(
298
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
299
- ) -> Node: ...
300
- def ruby(
301
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
302
- ) -> Node: ...
303
- def s(*children: Child, key: str | None = None, **props: Unpack[HTMLProps]) -> Node: ...
304
- def samp(
305
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
306
- ) -> Node: ...
307
- def script(
308
- *children: Child, key: str | None = None, **props: Unpack[HTMLScriptProps]
309
- ) -> Node: ...
310
- def section(
311
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
312
- ) -> Node: ...
313
- def select(
314
- *children: Child, key: str | None = None, **props: Unpack[HTMLSelectProps]
315
- ) -> Node: ...
316
- def small(
317
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
318
- ) -> Node: ...
319
- def span(
320
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
321
- ) -> Node: ...
322
- def strong(
323
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
324
- ) -> Node: ...
325
- def style(
326
- *children: Child, key: str | None = None, **props: Unpack[HTMLStyleProps]
327
- ) -> Node: ...
328
- def sub(
329
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
330
- ) -> Node: ...
331
- def summary(
332
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
333
- ) -> Node: ...
334
- def sup(
335
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
336
- ) -> Node: ...
337
- def table(
338
- *children: Child, key: str | None = None, **props: Unpack[HTMLTableProps]
339
- ) -> Node: ...
340
- def tbody(
341
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
342
- ) -> Node: ...
343
- def td(
344
- *children: Child, key: str | None = None, **props: Unpack[HTMLTdProps]
345
- ) -> Node: ...
346
- def template(
347
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
348
- ) -> Node: ...
349
- def textarea(
350
- *children: Child,
351
- key: str | None = None,
352
- **props: Unpack[HTMLTextareaProps],
353
- ) -> Node: ...
354
- def tfoot(
355
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
356
- ) -> Node: ...
357
- def th(
358
- *children: Child, key: str | None = None, **props: Unpack[HTMLThProps]
359
- ) -> Node: ...
360
- def thead(
361
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
362
- ) -> Node: ...
363
- def time(
364
- *children: Child, key: str | None = None, **props: Unpack[HTMLTimeProps]
365
- ) -> Node: ...
366
- def title(
367
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
368
- ) -> Node: ...
369
- def tr(
370
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
371
- ) -> Node: ...
372
- def u(*children: Child, key: str | None = None, **props: Unpack[HTMLProps]) -> Node: ...
373
- def ul(
374
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
375
- ) -> Node: ...
376
- def var(
377
- *children: Child, key: str | None = None, **props: Unpack[HTMLProps]
378
- ) -> Node: ...
379
- def video(
380
- *children: Child, key: str | None = None, **props: Unpack[HTMLVideoProps]
381
- ) -> Node: ...
382
-
383
- # -- React Fragment ---
384
- def fragment(*children: Child, key: str | None = None) -> Node: ...
385
-
386
- # -- SVG --
387
- def svg(
388
- *children: Child,
389
- key: str | None = None,
390
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
391
- ) -> Node: ...
392
- def circle(
393
- *children: Child,
394
- key: str | None = None,
395
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
396
- ) -> Node: ...
397
- def ellipse(
398
- *children: Child,
399
- key: str | None = None,
400
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
401
- ) -> Node: ...
402
- def g(
403
- *children: Child,
404
- key: str | None = None,
405
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
406
- ) -> Node: ...
407
- def line(
408
- *children: Child,
409
- key: str | None = None,
410
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
411
- ) -> Node: ...
412
- def path(
413
- *children: Child,
414
- key: str | None = None,
415
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
416
- ) -> Node: ...
417
- def polygon(
418
- *children: Child,
419
- key: str | None = None,
420
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
421
- ) -> Node: ...
422
- def polyline(
423
- *children: Child,
424
- key: str | None = None,
425
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
426
- ) -> Node: ...
427
- def rect(
428
- *children: Child,
429
- key: str | None = None,
430
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
431
- ) -> Node: ...
432
- def text(
433
- *children: Child,
434
- key: str | None = None,
435
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
436
- ) -> Node: ...
437
- def tspan(
438
- *children: Child,
439
- key: str | None = None,
440
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
441
- ) -> Node: ...
442
- def defs(
443
- *children: Child,
444
- key: str | None = None,
445
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
446
- ) -> Node: ...
447
- def clipPath(
448
- *children: Child,
449
- key: str | None = None,
450
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
451
- ) -> Node: ...
452
- def mask(
453
- *children: Child,
454
- key: str | None = None,
455
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
456
- ) -> Node: ...
457
- def pattern(
458
- *children: Child,
459
- key: str | None = None,
460
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
461
- ) -> Node: ...
462
- def use(
463
- *children: Child,
464
- key: str | None = None,
465
- **props: Unpack[HTMLSVGProps[GenericHTMLElement]],
466
- ) -> Node: ...
467
-
468
- # Lists exported for JS transpiler
469
- TAGS: list[tuple[str, dict[str, Any] | None]]
470
- SELF_CLOSING_TAGS: list[tuple[str, dict[str, Any] | None]]
@@ -1,110 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import ClassVar, TypeAlias, override
4
-
5
- from pulse.transpiler.context import is_interpreted_mode
6
- from pulse.transpiler.errors import JSCompilationError
7
- from pulse.transpiler.ids import generate_id
8
- from pulse.transpiler.nodes import (
9
- JSArray,
10
- JSBoolean,
11
- JSExpr,
12
- JSIdentifier,
13
- JSNew,
14
- JSNumber,
15
- JSString,
16
- )
17
-
18
- JsPrimitive: TypeAlias = bool | int | float | str | None
19
- JsValue: TypeAlias = "JsPrimitive | list[JsValue] | tuple[JsValue, ...] | set[JsValue] | frozenset[JsValue] | dict[str, JsValue]"
20
- JsVar: TypeAlias = "JsValue | JSExpr"
21
-
22
- # Global cache for deduplication across all transpiled functions
23
- CONSTANTS_CACHE: dict[int, "JsConstant"] = {} # id(value) -> JsConstant
24
-
25
-
26
- class JsConstant(JSExpr):
27
- """Wrapper for constant values used in transpiled JS functions."""
28
-
29
- is_primary: ClassVar[bool] = True
30
-
31
- value: object
32
- expr: JSExpr
33
- id: str
34
- name: str # Original Python variable name (set by codegen)
35
-
36
- def __init__(self, value: object, expr: JSExpr, name: str = "") -> None:
37
- self.value = value
38
- self.expr = expr
39
- self.id = generate_id()
40
- self.name = name
41
-
42
- @property
43
- def js_name(self) -> str:
44
- """Unique JS identifier for this constant."""
45
- return f"{self.name}_{self.id}" if self.name else f"_const_{self.id}"
46
-
47
- @override
48
- def emit(self) -> str:
49
- """Emit JS code for this constant.
50
-
51
- In normal mode: returns the unique JS name (e.g., "CONSTANT_1")
52
- In interpreted mode: returns a get_object call (e.g., "get_object('CONSTANT_1')")
53
- """
54
- base = self.js_name
55
- if is_interpreted_mode():
56
- return f"get_object('{base}')"
57
- return base
58
-
59
-
60
- def _value_to_expr(value: JsValue) -> JSExpr:
61
- """Convert a Python value to a JSExpr (no caching)."""
62
- if value is None:
63
- return JSIdentifier("undefined")
64
- elif isinstance(value, bool):
65
- return JSBoolean(value)
66
- elif isinstance(value, (int, float)):
67
- return JSNumber(value)
68
- elif isinstance(value, str):
69
- return JSString(value)
70
- elif isinstance(value, (list, tuple)):
71
- return JSArray([_value_to_expr(v) for v in value])
72
- elif isinstance(value, (set, frozenset)):
73
- return JSNew(
74
- JSIdentifier("Set"),
75
- [JSArray([_value_to_expr(v) for v in value])],
76
- )
77
- elif isinstance(value, dict):
78
- entries: list[JSExpr] = []
79
- for k, v in value.items():
80
- if not isinstance(k, str):
81
- raise JSCompilationError("Only string keys supported in constant dicts")
82
- entries.append(JSArray([JSString(k), _value_to_expr(v)]))
83
- return JSNew(JSIdentifier("Map"), [JSArray(entries)])
84
- else:
85
- raise JSCompilationError(
86
- f"Unsupported global constant: {type(value).__name__} (value: {value!r})"
87
- )
88
-
89
-
90
- def const_to_js(value: JsValue, name: str = "") -> JsConstant:
91
- """Convert a Python value to a JsConstant (cached by identity)."""
92
- value_id = id(value)
93
- if value_id in CONSTANTS_CACHE:
94
- return CONSTANTS_CACHE[value_id]
95
-
96
- expr = _value_to_expr(value)
97
- result = JsConstant(value, expr, name)
98
- CONSTANTS_CACHE[value_id] = result
99
- return result
100
-
101
-
102
- def jsify(value: JsVar) -> JSExpr:
103
- if not isinstance(value, JSExpr):
104
- return const_to_js(value).expr
105
- return value
106
-
107
-
108
- def registered_constants() -> list[JsConstant]:
109
- """Get all registered JS constants."""
110
- return list(CONSTANTS_CACHE.values())
@@ -1,26 +0,0 @@
1
- """Context for JSExpr emit mode."""
2
-
3
- from collections.abc import Iterator
4
- from contextlib import contextmanager
5
- from contextvars import ContextVar
6
-
7
- # When True, JSExpr.emit() returns code suitable for client-side interpretation
8
- # (e.g., "get_object('Button_1')" instead of "Button_1")
9
- _interpreted_mode: ContextVar[bool] = ContextVar(
10
- "jsexpr_interpreted_mode", default=False
11
- )
12
-
13
-
14
- def is_interpreted_mode() -> bool:
15
- """Check if we're in interpreted mode."""
16
- return _interpreted_mode.get()
17
-
18
-
19
- @contextmanager
20
- def interpreted_mode() -> Iterator[None]:
21
- """Context manager to enable interpreted mode for JSExpr.emit()."""
22
- token = _interpreted_mode.set(True)
23
- try:
24
- yield
25
- finally:
26
- _interpreted_mode.reset(token)
pulse/transpiler/ids.py DELETED
@@ -1,16 +0,0 @@
1
- """Unique ID generator for JavaScript codegen."""
2
-
3
- from itertools import count
4
-
5
- _counter = count(1)
6
-
7
-
8
- def generate_id() -> str:
9
- """Generate unique hex ID like '1', '2', 'a', 'ff', etc."""
10
- return f"{next(_counter):x}"
11
-
12
-
13
- def reset_id_counter() -> None:
14
- """Reset counter (for testing)."""
15
- global _counter
16
- _counter = count(1)