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.
Files changed (85) 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 -999
  47. pulse/render_session.py +74 -66
  48. pulse/renderer.py +311 -238
  49. pulse/routing.py +1 -10
  50. pulse/serializer.py +11 -1
  51. pulse/transpiler/__init__.py +84 -114
  52. pulse/transpiler/builtins.py +661 -343
  53. pulse/transpiler/errors.py +78 -2
  54. pulse/transpiler/function.py +463 -133
  55. pulse/transpiler/id.py +18 -0
  56. pulse/transpiler/imports.py +230 -325
  57. pulse/transpiler/js_module.py +218 -209
  58. pulse/transpiler/modules/__init__.py +16 -13
  59. pulse/transpiler/modules/asyncio.py +45 -26
  60. pulse/transpiler/modules/json.py +12 -8
  61. pulse/transpiler/modules/math.py +161 -216
  62. pulse/transpiler/modules/pulse/__init__.py +5 -0
  63. pulse/transpiler/modules/pulse/tags.py +231 -0
  64. pulse/transpiler/modules/typing.py +33 -28
  65. pulse/transpiler/nodes.py +1607 -923
  66. pulse/transpiler/py_module.py +118 -95
  67. pulse/transpiler/react_component.py +51 -0
  68. pulse/transpiler/transpiler.py +593 -437
  69. pulse/transpiler/vdom.py +255 -0
  70. {pulse_framework-0.1.50.dist-info → pulse_framework-0.1.52.dist-info}/METADATA +1 -1
  71. pulse_framework-0.1.52.dist-info/RECORD +120 -0
  72. pulse/html/tags.pyi +0 -470
  73. pulse/transpiler/constants.py +0 -110
  74. pulse/transpiler/context.py +0 -26
  75. pulse/transpiler/ids.py +0 -16
  76. pulse/transpiler/modules/re.py +0 -466
  77. pulse/transpiler/modules/tags.py +0 -268
  78. pulse/transpiler/utils.py +0 -4
  79. pulse/vdom.py +0 -667
  80. pulse_framework-0.1.50.dist-info/RECORD +0 -119
  81. /pulse/{html → dom}/__init__.py +0 -0
  82. /pulse/{html → dom}/elements.py +0 -0
  83. /pulse/{html → dom}/svg.py +0 -0
  84. {pulse_framework-0.1.50.dist-info → pulse_framework-0.1.52.dist-info}/WHEEL +0 -0
  85. {pulse_framework-0.1.50.dist-info → pulse_framework-0.1.52.dist-info}/entry_points.txt +0 -0
pulse/js/__init__.pyi CHANGED
@@ -45,6 +45,15 @@ from pulse.js._types import (
45
45
  from pulse.js._types import (
46
46
  JSIteratorResult as JSIteratorResult,
47
47
  )
48
+ from pulse.js._types import (
49
+ JSONReplacer as JSONReplacer,
50
+ )
51
+ from pulse.js._types import (
52
+ JSONReviver as JSONReviver,
53
+ )
54
+ from pulse.js._types import (
55
+ JSONValue as JSONValue,
56
+ )
48
57
  from pulse.js._types import (
49
58
  NodeList as NodeList,
50
59
  )
@@ -76,7 +85,7 @@ from pulse.js.set import Set as Set
76
85
  from pulse.js.string import String as String
77
86
  from pulse.js.weakmap import WeakMap as WeakMap
78
87
  from pulse.js.weakset import WeakSet as WeakSet
79
- from pulse.transpiler.nodes import JSUndefined
88
+ from pulse.transpiler.nodes import Undefined
80
89
 
81
90
  # Re-export namespace modules
82
91
  console = pulse.js.console
@@ -91,5 +100,16 @@ def throw(x: _Any) -> _NoReturn:
91
100
  """Throw a JavaScript error."""
92
101
  ...
93
102
 
103
+ def obj(**kwargs: _Any) -> _Any:
104
+ """Create a plain JavaScript object literal.
105
+
106
+ Use this instead of dict() when you need a plain JS object (e.g., for React style prop).
107
+
108
+ Example:
109
+ style=obj(display="block", color="red")
110
+ # Transpiles to: style={{ display: "block", color: "red" }}
111
+ """
112
+ ...
113
+
94
114
  # Primitive values
95
- undefined: JSUndefined
115
+ undefined: Undefined
pulse/js/_types.py CHANGED
@@ -126,12 +126,14 @@ class Element(_Protocol):
126
126
  type: str,
127
127
  listener: _Callable[..., None],
128
128
  options: bool | dict[str, bool] | None = None,
129
+ /,
129
130
  ) -> None: ...
130
131
  def removeEventListener(
131
132
  self,
132
133
  type: str,
133
134
  listener: _Callable[..., None],
134
135
  options: bool | dict[str, bool] | None = None,
136
+ /,
135
137
  ) -> None: ...
136
138
  def remove(self) -> None: ...
137
139
  def append(self, *nodes: "Element | str") -> None: ...
@@ -163,7 +165,7 @@ class CSSStyleDeclaration(_Protocol):
163
165
  """Protocol for CSSStyleDeclaration."""
164
166
 
165
167
  def getPropertyValue(self, property: str) -> str: ...
166
- def setProperty(self, property: str, value: str, priority: str = "") -> None: ...
168
+ def setProperty(self, property: str, value: str, priority: str = "", /) -> None: ...
167
169
  def removeProperty(self, property: str) -> str: ...
168
170
 
169
171
 
@@ -212,7 +214,7 @@ class Selection(_Protocol):
212
214
  def rangeCount(self) -> int: ...
213
215
 
214
216
  def getRangeAt(self, index: int) -> "Range": ...
215
- def collapse(self, node: Element | None, offset: int = 0) -> None: ...
217
+ def collapse(self, node: Element | None, offset: int = 0, /) -> None: ...
216
218
  def selectAllChildren(self, node: Element) -> None: ...
217
219
  def removeAllRanges(self) -> None: ...
218
220
  def toString(self) -> str: ...
@@ -240,7 +242,7 @@ class Range(_Protocol):
240
242
  def setEnd(self, node: Element, offset: int) -> None: ...
241
243
  def selectNode(self, node: Element) -> None: ...
242
244
  def selectNodeContents(self, node: Element) -> None: ...
243
- def collapse(self, toStart: bool = False) -> None: ...
245
+ def collapse(self, toStart: bool = False, /) -> None: ...
244
246
  def cloneContents(self) -> Element: ...
245
247
  def deleteContents(self) -> None: ...
246
248
 
pulse/js/array.py CHANGED
@@ -2,29 +2,33 @@
2
2
  JavaScript Array builtin module.
3
3
 
4
4
  Usage:
5
- import pulse.js.array as Array
5
+ from pulse.js import Array
6
6
  Array.isArray([1, 2, 3]) # -> Array.isArray([1, 2, 3])
7
- Array.from([1, 2, 3]) # -> Array.from([1, 2, 3])
8
-
9
- # Note: For 'from' (Python keyword), use namespace import:
10
- # import pulse.js.array as Array; Array.from(...)
11
- # Or use the underscore version for direct import:
12
- from pulse.js.array import isArray, from_
13
- isArray([1, 2, 3]) # -> Array.isArray([1, 2, 3])
14
- from_([1, 2, 3]) # -> Array.from([1, 2, 3])
7
+ Array.from_([1, 2, 3]) # -> Array.from([1, 2, 3])
8
+ Array(10) # -> new Array(10)
9
+
10
+ # Or import from module directly:
11
+ from pulse.js.array import Array
15
12
  """
16
13
 
14
+ from __future__ import annotations
15
+
17
16
  from collections.abc import Callable as _Callable
18
17
  from collections.abc import Iterable as _Iterable
18
+ from collections.abc import Iterator as _Iterator
19
19
  from typing import Any as _Any
20
20
  from typing import Generic as _Generic
21
+ from typing import TypeGuard as _TypeGuard
21
22
  from typing import TypeVar as _TypeVar
23
+ from typing import overload as _overload
22
24
 
23
- from pulse.transpiler.js_module import register_js_module as _register_js_module
25
+ from pulse.transpiler.js_module import JsModule
24
26
 
25
27
  T = _TypeVar("T")
26
28
  U = _TypeVar("U")
27
- S = _TypeVar("S")
29
+ # TypeVars for static methods (can't use class-level T)
30
+ _T = _TypeVar("_T")
31
+ _U = _TypeVar("_U")
28
32
 
29
33
 
30
34
  class Array(_Generic[T]):
@@ -34,6 +38,21 @@ class Array(_Generic[T]):
34
38
  All instance methods preserve the expected generic types.
35
39
  """
36
40
 
41
+ @_overload
42
+ def __init__(self) -> None:
43
+ """Create an empty Array."""
44
+ ...
45
+
46
+ @_overload
47
+ def __init__(self, length: int, /) -> None:
48
+ """Create an Array with the specified length."""
49
+ ...
50
+
51
+ @_overload
52
+ def __init__(self, *elements: T) -> None:
53
+ """Create an Array with the given elements."""
54
+ ...
55
+
37
56
  def __init__(self, *args: T | int) -> None:
38
57
  """Create an Array.
39
58
 
@@ -45,21 +64,60 @@ class Array(_Generic[T]):
45
64
 
46
65
  # Static methods
47
66
  @staticmethod
48
- def isArray(value: _Any) -> bool:
67
+ @_overload
68
+ def isArray(value: list[_T], /) -> _TypeGuard["Array[_T]"]:
69
+ """Determine whether the passed value is an Array."""
70
+ ...
71
+
72
+ @staticmethod
73
+ @_overload
74
+ def isArray(value: "Array[_T]", /) -> _TypeGuard["Array[_T]"]:
75
+ """Determine whether the passed value is an Array."""
76
+ ...
77
+
78
+ @staticmethod
79
+ @_overload
80
+ def isArray(value: _Any, /) -> _TypeGuard["Array[_Any]"]:
49
81
  """Determine whether the passed value is an Array."""
50
82
  ...
51
83
 
52
84
  @staticmethod
85
+ def isArray(value: _Any, /) -> _TypeGuard["Array[_Any]"]:
86
+ """Determine whether the passed value is an Array."""
87
+ ...
88
+
89
+ @staticmethod
90
+ @_overload
53
91
  def from_(
54
- arrayLike: _Iterable[T],
55
- mapFn: _Callable[[T, int], U] | None = None,
92
+ arrayLike: _Iterable[_T] | "Array[_T]",
93
+ /,
94
+ ) -> "Array[_T]":
95
+ """Create a new Array from an array-like or iterable object."""
96
+ ...
97
+
98
+ @staticmethod
99
+ @_overload
100
+ def from_(
101
+ arrayLike: _Iterable[_T] | "Array[_T]",
102
+ mapFn: _Callable[[_T, int], _U],
56
103
  thisArg: _Any | None = None,
57
- ) -> "list[U] | list[T]":
104
+ /,
105
+ ) -> "Array[_U]":
106
+ """Create a new Array from an array-like or iterable object, mapping each element."""
107
+ ...
108
+
109
+ @staticmethod
110
+ def from_(
111
+ arrayLike: _Iterable[_T] | "Array[_T]",
112
+ mapFn: _Callable[[_T, int], _U] | None = None,
113
+ thisArg: _Any | None = None,
114
+ /,
115
+ ) -> "Array[_U] | Array[_T]":
58
116
  """Create a new Array from an array-like or iterable object."""
59
117
  ...
60
118
 
61
119
  @staticmethod
62
- def of(*elements: T) -> "list[T]":
120
+ def of(*elements: _T) -> "Array[_T]":
63
121
  """Create a new Array from a variable number of arguments."""
64
122
  ...
65
123
 
@@ -87,8 +145,8 @@ class Array(_Generic[T]):
87
145
  ...
88
146
 
89
147
  def splice(
90
- self, start: int, deleteCount: int | None = None, *items: T
91
- ) -> "list[T]":
148
+ self, start: int, deleteCount: int | None = None, /, *items: T
149
+ ) -> "Array[T]":
92
150
  """Remove/replace elements and optionally insert new ones."""
93
151
  ...
94
152
 
@@ -96,42 +154,42 @@ class Array(_Generic[T]):
96
154
  """Reverse the array in place."""
97
155
  ...
98
156
 
99
- def sort(self, compareFn: _Callable[[T, T], int] | None = None) -> "Array[T]":
157
+ def sort(self, compareFn: _Callable[[T, T], int] | None = None, /) -> "Array[T]":
100
158
  """Sort the array in place."""
101
159
  ...
102
160
 
103
- def fill(self, value: T, start: int = 0, end: int | None = None) -> "Array[T]":
161
+ def fill(self, value: T, start: int = 0, end: int | None = None, /) -> "Array[T]":
104
162
  """Fill all elements with a static value."""
105
163
  ...
106
164
 
107
165
  def copyWithin(
108
- self, target: int, start: int = 0, end: int | None = None
166
+ self, target: int, start: int = 0, end: int | None = None, /
109
167
  ) -> "Array[T]":
110
168
  """Copy part of the array to another location within it."""
111
169
  ...
112
170
 
113
171
  # Accessor methods (return new arrays or values)
114
- def concat(self, *items: T | "_Iterable[T]") -> "list[T]":
172
+ def concat(self, *items: T | "_Iterable[T]") -> "Array[T]":
115
173
  """Merge arrays and/or values into a new array."""
116
174
  ...
117
175
 
118
- def slice(self, start: int = 0, end: int | None = None) -> "list[T]":
176
+ def slice(self, start: int = 0, end: int | None = None, /) -> "Array[T]":
119
177
  """Return a shallow copy of a portion of the array."""
120
178
  ...
121
179
 
122
- def join(self, separator: str = ",") -> str:
180
+ def join(self, separator: str = ",", /) -> str:
123
181
  """Join all elements into a string."""
124
182
  ...
125
183
 
126
- def indexOf(self, searchElement: T, fromIndex: int = 0) -> int:
184
+ def indexOf(self, searchElement: T, fromIndex: int = 0, /) -> int:
127
185
  """Return first index of element, or -1 if not found."""
128
186
  ...
129
187
 
130
- def lastIndexOf(self, searchElement: T, fromIndex: int | None = None) -> int:
188
+ def lastIndexOf(self, searchElement: T, fromIndex: int | None = None, /) -> int:
131
189
  """Return last index of element, or -1 if not found."""
132
190
  ...
133
191
 
134
- def includes(self, searchElement: T, fromIndex: int = 0) -> bool:
192
+ def includes(self, searchElement: T, fromIndex: int = 0, /) -> bool:
135
193
  """Determine whether the array contains the element."""
136
194
  ...
137
195
 
@@ -139,31 +197,33 @@ class Array(_Generic[T]):
139
197
  """Return element at index (supports negative indexing)."""
140
198
  ...
141
199
 
142
- def flat(self, depth: int = 1) -> "list[_Any]":
200
+ def flat(self, depth: int = 1, /) -> "Array[_Any]":
143
201
  """Flatten nested arrays to the specified depth."""
144
202
  ...
145
203
 
146
204
  def flatMap(
147
205
  self, callback: _Callable[[T, int, "Array[T]"], _Iterable[U]]
148
- ) -> "list[U]":
206
+ ) -> "Array[U]":
149
207
  """Map then flatten the result by one level."""
150
208
  ...
151
209
 
152
- def toReversed(self) -> "list[T]":
210
+ def toReversed(self) -> "Array[T]":
153
211
  """Return a new reversed array (ES2023)."""
154
212
  ...
155
213
 
156
- def toSorted(self, compareFn: _Callable[[T, T], int] | None = None) -> "list[T]":
214
+ def toSorted(
215
+ self, compareFn: _Callable[[T, T], int] | None = None, /
216
+ ) -> "Array[T]":
157
217
  """Return a new sorted array (ES2023)."""
158
218
  ...
159
219
 
160
220
  def toSpliced(
161
- self, start: int, deleteCount: int | None = None, *items: T
162
- ) -> "list[T]":
221
+ self, start: int, deleteCount: int | None = None, /, *items: T
222
+ ) -> "Array[T]":
163
223
  """Return a new array with elements spliced (ES2023)."""
164
224
  ...
165
225
 
166
- def with_(self, index: int, value: T) -> "list[T]":
226
+ def with_(self, index: int, value: T) -> "Array[T]":
167
227
  """Return a new array with element at index replaced (ES2023)."""
168
228
  ...
169
229
 
@@ -172,11 +232,11 @@ class Array(_Generic[T]):
172
232
  """Execute a function for each element."""
173
233
  ...
174
234
 
175
- def map(self, callback: _Callable[[T, int, "Array[T]"], U]) -> "list[U]":
235
+ def map(self, callback: _Callable[[T, int, "Array[T]"], U]) -> "Array[U]":
176
236
  """Create a new array with results of calling callback on each element."""
177
237
  ...
178
238
 
179
- def filter(self, callback: _Callable[[T, int, "Array[T]"], bool]) -> "list[T]":
239
+ def filter(self, callback: _Callable[[T, int, "Array[T]"], bool]) -> "Array[T]":
180
240
  """Create a new array with elements that pass the test."""
181
241
  ...
182
242
 
@@ -184,6 +244,7 @@ class Array(_Generic[T]):
184
244
  self,
185
245
  callback: _Callable[[U, T, int, "Array[T]"], U],
186
246
  initialValue: U | None = None,
247
+ /,
187
248
  ) -> U:
188
249
  """Reduce array to a single value (left to right).
189
250
 
@@ -195,6 +256,7 @@ class Array(_Generic[T]):
195
256
  self,
196
257
  callback: _Callable[[U, T, int, "Array[T]"], U],
197
258
  initialValue: U | None = None,
259
+ /,
198
260
  ) -> U:
199
261
  """Reduce array to a single value (right to left).
200
262
 
@@ -248,6 +310,27 @@ class Array(_Generic[T]):
248
310
  """Return a localized string representing the array."""
249
311
  ...
250
312
 
313
+ # Python protocol methods
314
+ def __iter__(self) -> _Iterator[T]:
315
+ """Iterate over array elements."""
316
+ ...
317
+
318
+ def __getitem__(self, index: int) -> T:
319
+ """Get element at index."""
320
+ ...
321
+
322
+ def __setitem__(self, index: int, value: T) -> None:
323
+ """Set element at index."""
324
+ ...
325
+
326
+ def __len__(self) -> int:
327
+ """Return the number of elements (same as length)."""
328
+ ...
329
+
330
+ def __contains__(self, value: T) -> bool:
331
+ """Check if value exists in the array (same as includes)."""
332
+ ...
333
+
251
334
 
252
- # Self-register this module as a JS builtin
253
- _register_js_module(name="Array", global_scope=True)
335
+ # Self-register this module as a JS builtin (global identifier)
336
+ JsModule.register(name=None)
pulse/js/console.py CHANGED
@@ -18,16 +18,16 @@ Usage:
18
18
 
19
19
  from typing import Any as _Any
20
20
 
21
- from pulse.transpiler.js_module import register_js_module as _register_js_module
21
+ from pulse.transpiler.js_module import JsModule
22
22
 
23
23
 
24
24
  # Methods (type stubs for IDE support)
25
25
  def assert_(condition: bool, *data: _Any) -> None: ...
26
26
  def clear() -> None: ...
27
- def count(label: str | None = None) -> None: ...
28
- def countReset(label: str | None = None) -> None: ...
27
+ def count(label: str | None = None, /) -> None: ...
28
+ def countReset(label: str | None = None, /) -> None: ...
29
29
  def debug(*data: _Any) -> None: ...
30
- def dir(item: _Any, options: dict[str, _Any] | None = None) -> None: ...
30
+ def dir(item: _Any, options: dict[str, _Any] | None = None, /) -> None: ...
31
31
  def dirxml(*data: _Any) -> None: ...
32
32
  def error(*data: _Any) -> None: ...
33
33
  def group(*label: _Any) -> None: ...
@@ -35,13 +35,13 @@ def groupCollapsed(*label: _Any) -> None: ...
35
35
  def groupEnd() -> None: ...
36
36
  def info(*data: _Any) -> None: ...
37
37
  def log(*data: _Any) -> None: ...
38
- def table(tabularData: _Any, properties: list[str] | None = None) -> None: ...
39
- def time(label: str | None = None) -> None: ...
40
- def timeEnd(label: str | None = None) -> None: ...
41
- def timeLog(label: str | None = None, *data: _Any) -> None: ...
38
+ def table(tabularData: _Any, properties: list[str] | None = None, /) -> None: ...
39
+ def time(label: str | None = None, /) -> None: ...
40
+ def timeEnd(label: str | None = None, /) -> None: ...
41
+ def timeLog(label: str | None = None, /, *data: _Any) -> None: ...
42
42
  def trace(*data: _Any) -> None: ...
43
43
  def warn(*data: _Any) -> None: ...
44
44
 
45
45
 
46
46
  # Self-register this module as a JS builtin
47
- _register_js_module(name="console")
47
+ JsModule.register(name="console")
pulse/js/date.py CHANGED
@@ -2,24 +2,24 @@
2
2
  JavaScript Date builtin module.
3
3
 
4
4
  Usage:
5
- import pulse.js.date as Date
5
+ from pulse.js import Date
6
+ Date() # -> new Date()
6
7
  Date.now() # -> Date.now()
7
8
  Date.parse("2023-01-01") # -> Date.parse("2023-01-01")
8
9
 
9
- from pulse.js.date import now, parse
10
- now() # -> Date.now()
11
- parse("2023-01-01") # -> Date.parse("2023-01-01")
10
+ # Or import from module directly:
11
+ from pulse.js.date import Date
12
12
  """
13
13
 
14
14
  from typing import Any as _Any
15
15
 
16
- from pulse.transpiler.js_module import register_js_module as _register_js_module
16
+ from pulse.transpiler.js_module import JsModule
17
17
 
18
18
 
19
19
  class Date:
20
20
  """Class for JavaScript Date instances."""
21
21
 
22
- def __init__(self, value: int | str | None = None): ...
22
+ def __init__(self, value: int | str | None = None, /): ...
23
23
 
24
24
  @staticmethod
25
25
  def now() -> float: ...
@@ -36,6 +36,7 @@ class Date:
36
36
  minutes: int | None = None,
37
37
  seconds: int | None = None,
38
38
  ms: int | None = None,
39
+ /,
39
40
  ) -> float: ...
40
41
 
41
42
  def getDate(self) -> int: ...
@@ -58,7 +59,7 @@ class Date:
58
59
  def getUTCSeconds(self) -> int: ...
59
60
  def setDate(self, date: int) -> float: ...
60
61
  def setFullYear(
61
- self, year: int, month: int | None = None, date: int | None = None
62
+ self, year: int, month: int | None = None, date: int | None = None, /
62
63
  ) -> float: ...
63
64
  def setHours(
64
65
  self,
@@ -66,13 +67,14 @@ class Date:
66
67
  min: int | None = None,
67
68
  sec: int | None = None,
68
69
  ms: int | None = None,
70
+ /,
69
71
  ) -> float: ...
70
72
  def setMilliseconds(self, ms: int) -> float: ...
71
73
  def setMinutes(
72
- self, min: int, sec: int | None = None, ms: int | None = None
74
+ self, min: int, sec: int | None = None, ms: int | None = None, /
73
75
  ) -> float: ...
74
- def setMonth(self, month: int, date: int | None = None) -> float: ...
75
- def setSeconds(self, sec: int, ms: int | None = None) -> float: ...
76
+ def setMonth(self, month: int, date: int | None = None, /) -> float: ...
77
+ def setSeconds(self, sec: int, ms: int | None = None, /) -> float: ...
76
78
  def setTime(self, time: float) -> float: ...
77
79
  def setUTCDate(self, date: int) -> float: ...
78
80
  def setUTCFullYear(
@@ -84,24 +86,25 @@ class Date:
84
86
  min: int | None = None,
85
87
  sec: int | None = None,
86
88
  ms: int | None = None,
89
+ /,
87
90
  ) -> float: ...
88
91
  def setUTCMilliseconds(self, ms: int) -> float: ...
89
92
  def setUTCMinutes(
90
- self, min: int, sec: int | None = None, ms: int | None = None
93
+ self, min: int, sec: int | None = None, ms: int | None = None, /
91
94
  ) -> float: ...
92
- def setUTCMonth(self, month: int, date: int | None = None) -> float: ...
93
- def setUTCSeconds(self, sec: int, ms: int | None = None) -> float: ...
95
+ def setUTCMonth(self, month: int, date: int | None = None, /) -> float: ...
96
+ def setUTCSeconds(self, sec: int, ms: int | None = None, /) -> float: ...
94
97
  def toDateString(self) -> str: ...
95
98
  def toISOString(self) -> str: ...
96
- def toJSON(self, key: _Any | None = None) -> str: ...
99
+ def toJSON(self, key: _Any | None = None, /) -> str: ...
97
100
  def toLocaleDateString(
98
- self, locales: str | None = None, options: _Any | None = None
101
+ self, locales: str | None = None, options: _Any | None = None, /
99
102
  ) -> str: ...
100
103
  def toLocaleString(
101
- self, locales: str | None = None, options: _Any | None = None
104
+ self, locales: str | None = None, options: _Any | None = None, /
102
105
  ) -> str: ...
103
106
  def toLocaleTimeString(
104
- self, locales: str | None = None, options: _Any | None = None
107
+ self, locales: str | None = None, options: _Any | None = None, /
105
108
  ) -> str: ...
106
109
  def toString(self) -> str: ...
107
110
  def toTimeString(self) -> str: ...
@@ -109,5 +112,5 @@ class Date:
109
112
  def valueOf(self) -> float: ...
110
113
 
111
114
 
112
- # Self-register this module as a JS builtin
113
- _register_js_module(name="Date", global_scope=True)
115
+ # Self-register this module as a JS builtin (global identifier)
116
+ JsModule.register(name=None)
pulse/js/document.py CHANGED
@@ -12,7 +12,7 @@ from pulse.js._types import Element as _Element
12
12
  from pulse.js._types import HTMLCollection as _HTMLCollection
13
13
  from pulse.js._types import HTMLElement as _HTMLElement
14
14
  from pulse.js._types import NodeList as _NodeList
15
- from pulse.transpiler.js_module import register_js_module as _register_js_module
15
+ from pulse.transpiler.js_module import JsModule
16
16
 
17
17
  # Read-only properties
18
18
  body: _HTMLElement
@@ -59,7 +59,9 @@ def getElementsByName(elementName: str) -> _NodeList[_Element]:
59
59
 
60
60
 
61
61
  # Element creation
62
- def createElement(tagName: str, options: dict[str, str] | None = None) -> _HTMLElement:
62
+ def createElement(
63
+ tagName: str, options: dict[str, str] | None = None, /
64
+ ) -> _HTMLElement:
63
65
  """Create a new element with the given tag name."""
64
66
  ...
65
67
 
@@ -84,6 +86,7 @@ def addEventListener(
84
86
  type: str,
85
87
  listener: _Callable[..., None],
86
88
  options: bool | dict[str, bool] | None = None,
89
+ /,
87
90
  ) -> None:
88
91
  """Add an event listener to the document."""
89
92
  ...
@@ -93,6 +96,7 @@ def removeEventListener(
93
96
  type: str,
94
97
  listener: _Callable[..., None],
95
98
  options: bool | dict[str, bool] | None = None,
99
+ /,
96
100
  ) -> None:
97
101
  """Remove an event listener from the document."""
98
102
  ...
@@ -116,7 +120,7 @@ def getSelection() -> _Any:
116
120
 
117
121
 
118
122
  # Node tree methods
119
- def importNode(node: _Element, deep: bool = False) -> _Element:
123
+ def importNode(node: _Element, deep: bool = False, /) -> _Element:
120
124
  """Import a node from another document."""
121
125
  ...
122
126
 
@@ -135,4 +139,4 @@ def exitFullscreen() -> _Any:
135
139
  fullscreenElement: _Element | None
136
140
 
137
141
 
138
- _register_js_module(name="document")
142
+ JsModule.register(name="document")
pulse/js/error.py CHANGED
@@ -2,22 +2,20 @@
2
2
  JavaScript Error builtin module.
3
3
 
4
4
  Usage:
5
- import pulse.js.error as Error
5
+ from pulse.js import Error
6
6
  Error("message") # -> new Error("message")
7
- Error.RangeError("message") # -> new RangeError("message")
8
7
 
9
- from pulse.js.error import Error, TypeError, RangeError, ReferenceError
10
- Error("message") # -> new Error("message")
8
+ from pulse.js.error import TypeError, RangeError, ReferenceError
11
9
  TypeError("message") # -> new TypeError("message")
12
10
  """
13
11
 
14
- from pulse.transpiler.js_module import register_js_module as _register_js_module
12
+ from pulse.transpiler.js_module import JsModule
15
13
 
16
14
 
17
15
  class Error:
18
16
  """Class for JavaScript Error instances."""
19
17
 
20
- def __init__(self, message: str | None = None): ...
18
+ def __init__(self, message: str | None = None, /): ...
21
19
 
22
20
  @property
23
21
  def message(self) -> str: ...
@@ -36,7 +34,7 @@ class Error:
36
34
  class EvalError:
37
35
  """Class for JavaScript EvalError instances."""
38
36
 
39
- def __init__(self, message: str | None = None): ...
37
+ def __init__(self, message: str | None = None, /): ...
40
38
 
41
39
  @property
42
40
  def message(self) -> str: ...
@@ -53,7 +51,7 @@ class EvalError:
53
51
  class RangeError:
54
52
  """Class for JavaScript RangeError instances."""
55
53
 
56
- def __init__(self, message: str | None = None): ...
54
+ def __init__(self, message: str | None = None, /): ...
57
55
 
58
56
  @property
59
57
  def message(self) -> str: ...
@@ -70,7 +68,7 @@ class RangeError:
70
68
  class ReferenceError:
71
69
  """Class for JavaScript ReferenceError instances."""
72
70
 
73
- def __init__(self, message: str | None = None): ...
71
+ def __init__(self, message: str | None = None, /): ...
74
72
 
75
73
  @property
76
74
  def message(self) -> str: ...
@@ -87,7 +85,7 @@ class ReferenceError:
87
85
  class SyntaxError:
88
86
  """Class for JavaScript SyntaxError instances."""
89
87
 
90
- def __init__(self, message: str | None = None): ...
88
+ def __init__(self, message: str | None = None, /): ...
91
89
 
92
90
  @property
93
91
  def message(self) -> str: ...
@@ -104,7 +102,7 @@ class SyntaxError:
104
102
  class TypeError:
105
103
  """Class for JavaScript TypeError instances."""
106
104
 
107
- def __init__(self, message: str | None = None): ...
105
+ def __init__(self, message: str | None = None, /): ...
108
106
 
109
107
  @property
110
108
  def message(self) -> str: ...
@@ -121,7 +119,7 @@ class TypeError:
121
119
  class URIError:
122
120
  """Class for JavaScript URIError instances."""
123
121
 
124
- def __init__(self, message: str | None = None): ...
122
+ def __init__(self, message: str | None = None, /): ...
125
123
 
126
124
  @property
127
125
  def message(self) -> str: ...
@@ -135,5 +133,5 @@ class URIError:
135
133
  def toString(self) -> str: ...
136
134
 
137
135
 
138
- # Self-register this module as a JS builtin
139
- _register_js_module(name="Error", global_scope=True)
136
+ # Self-register this module as a JS builtin (global identifiers)
137
+ JsModule.register(name=None)