pulse-framework 0.1.62__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 (126) hide show
  1. pulse/__init__.py +1493 -0
  2. pulse/_examples.py +29 -0
  3. pulse/app.py +1086 -0
  4. pulse/channel.py +607 -0
  5. pulse/cli/__init__.py +0 -0
  6. pulse/cli/cmd.py +575 -0
  7. pulse/cli/dependencies.py +181 -0
  8. pulse/cli/folder_lock.py +134 -0
  9. pulse/cli/helpers.py +271 -0
  10. pulse/cli/logging.py +102 -0
  11. pulse/cli/models.py +35 -0
  12. pulse/cli/packages.py +262 -0
  13. pulse/cli/processes.py +292 -0
  14. pulse/cli/secrets.py +39 -0
  15. pulse/cli/uvicorn_log_config.py +87 -0
  16. pulse/code_analysis.py +38 -0
  17. pulse/codegen/__init__.py +0 -0
  18. pulse/codegen/codegen.py +359 -0
  19. pulse/codegen/templates/__init__.py +0 -0
  20. pulse/codegen/templates/layout.py +106 -0
  21. pulse/codegen/templates/route.py +345 -0
  22. pulse/codegen/templates/routes_ts.py +42 -0
  23. pulse/codegen/utils.py +20 -0
  24. pulse/component.py +237 -0
  25. pulse/components/__init__.py +0 -0
  26. pulse/components/for_.py +83 -0
  27. pulse/components/if_.py +86 -0
  28. pulse/components/react_router.py +94 -0
  29. pulse/context.py +108 -0
  30. pulse/cookies.py +322 -0
  31. pulse/decorators.py +344 -0
  32. pulse/dom/__init__.py +0 -0
  33. pulse/dom/elements.py +1024 -0
  34. pulse/dom/events.py +445 -0
  35. pulse/dom/props.py +1250 -0
  36. pulse/dom/svg.py +0 -0
  37. pulse/dom/tags.py +328 -0
  38. pulse/dom/tags.pyi +480 -0
  39. pulse/env.py +178 -0
  40. pulse/form.py +538 -0
  41. pulse/helpers.py +541 -0
  42. pulse/hooks/__init__.py +0 -0
  43. pulse/hooks/core.py +452 -0
  44. pulse/hooks/effects.py +88 -0
  45. pulse/hooks/init.py +668 -0
  46. pulse/hooks/runtime.py +464 -0
  47. pulse/hooks/setup.py +254 -0
  48. pulse/hooks/stable.py +138 -0
  49. pulse/hooks/state.py +192 -0
  50. pulse/js/__init__.py +125 -0
  51. pulse/js/__init__.pyi +115 -0
  52. pulse/js/_types.py +299 -0
  53. pulse/js/array.py +339 -0
  54. pulse/js/console.py +50 -0
  55. pulse/js/date.py +119 -0
  56. pulse/js/document.py +145 -0
  57. pulse/js/error.py +140 -0
  58. pulse/js/json.py +66 -0
  59. pulse/js/map.py +97 -0
  60. pulse/js/math.py +69 -0
  61. pulse/js/navigator.py +79 -0
  62. pulse/js/number.py +57 -0
  63. pulse/js/obj.py +81 -0
  64. pulse/js/object.py +172 -0
  65. pulse/js/promise.py +172 -0
  66. pulse/js/pulse.py +115 -0
  67. pulse/js/react.py +495 -0
  68. pulse/js/regexp.py +57 -0
  69. pulse/js/set.py +124 -0
  70. pulse/js/string.py +38 -0
  71. pulse/js/weakmap.py +53 -0
  72. pulse/js/weakset.py +48 -0
  73. pulse/js/window.py +205 -0
  74. pulse/messages.py +202 -0
  75. pulse/middleware.py +471 -0
  76. pulse/plugin.py +96 -0
  77. pulse/proxy.py +242 -0
  78. pulse/py.typed +0 -0
  79. pulse/queries/__init__.py +0 -0
  80. pulse/queries/client.py +609 -0
  81. pulse/queries/common.py +101 -0
  82. pulse/queries/effect.py +55 -0
  83. pulse/queries/infinite_query.py +1418 -0
  84. pulse/queries/mutation.py +295 -0
  85. pulse/queries/protocol.py +136 -0
  86. pulse/queries/query.py +1314 -0
  87. pulse/queries/store.py +120 -0
  88. pulse/react_component.py +88 -0
  89. pulse/reactive.py +1208 -0
  90. pulse/reactive_extensions.py +1172 -0
  91. pulse/render_session.py +768 -0
  92. pulse/renderer.py +584 -0
  93. pulse/request.py +205 -0
  94. pulse/routing.py +598 -0
  95. pulse/serializer.py +279 -0
  96. pulse/state.py +556 -0
  97. pulse/test_helpers.py +15 -0
  98. pulse/transpiler/__init__.py +111 -0
  99. pulse/transpiler/assets.py +81 -0
  100. pulse/transpiler/builtins.py +1029 -0
  101. pulse/transpiler/dynamic_import.py +130 -0
  102. pulse/transpiler/emit_context.py +49 -0
  103. pulse/transpiler/errors.py +96 -0
  104. pulse/transpiler/function.py +611 -0
  105. pulse/transpiler/id.py +18 -0
  106. pulse/transpiler/imports.py +341 -0
  107. pulse/transpiler/js_module.py +336 -0
  108. pulse/transpiler/modules/__init__.py +33 -0
  109. pulse/transpiler/modules/asyncio.py +57 -0
  110. pulse/transpiler/modules/json.py +24 -0
  111. pulse/transpiler/modules/math.py +265 -0
  112. pulse/transpiler/modules/pulse/__init__.py +5 -0
  113. pulse/transpiler/modules/pulse/tags.py +250 -0
  114. pulse/transpiler/modules/typing.py +63 -0
  115. pulse/transpiler/nodes.py +1987 -0
  116. pulse/transpiler/py_module.py +135 -0
  117. pulse/transpiler/transpiler.py +1100 -0
  118. pulse/transpiler/vdom.py +256 -0
  119. pulse/types/__init__.py +0 -0
  120. pulse/types/event_handler.py +50 -0
  121. pulse/user_session.py +386 -0
  122. pulse/version.py +69 -0
  123. pulse_framework-0.1.62.dist-info/METADATA +198 -0
  124. pulse_framework-0.1.62.dist-info/RECORD +126 -0
  125. pulse_framework-0.1.62.dist-info/WHEEL +4 -0
  126. pulse_framework-0.1.62.dist-info/entry_points.txt +3 -0
pulse/js/_types.py ADDED
@@ -0,0 +1,299 @@
1
+ """Common type definitions for JavaScript builtin bindings.
2
+
3
+ This module provides type aliases and protocols for proper typing of JS APIs.
4
+ These are purely for static type checking - they have no runtime effect.
5
+ """
6
+
7
+ from collections.abc import Awaitable as _Awaitable
8
+ from collections.abc import Callable as _Callable
9
+ from collections.abc import Iterator as _Iterator
10
+ from typing import Protocol as _Protocol
11
+ from typing import TypeVar as _TypeVar
12
+ from typing import overload as _overload
13
+
14
+ # Type variables
15
+ T = _TypeVar("T")
16
+ T_co = _TypeVar("T_co", covariant=True)
17
+ T_contra = _TypeVar("T_contra", contravariant=True)
18
+ K = _TypeVar("K")
19
+ V = _TypeVar("V")
20
+ R = _TypeVar("R")
21
+
22
+ # Promise result types
23
+ PromiseSettledResult = dict[
24
+ str, T | str
25
+ ] # { status: "fulfilled" | "rejected", value?: T, reason?: any }
26
+
27
+
28
+ # Callback type aliases for collection methods
29
+ # These mirror JavaScript's callback signatures
30
+
31
+ # Array callbacks
32
+ ArrayCallback = _Callable[[T, int, "JSArray[T]"], R]
33
+ ArrayCallbackNoIndex = _Callable[[T], R]
34
+ ArrayPredicate = _Callable[[T, int, "JSArray[T]"], bool]
35
+ ArrayReducer = _Callable[[R, T, int, "JSArray[T]"], R]
36
+ ArrayComparator = _Callable[[T, T], int]
37
+
38
+ # Map callbacks
39
+ MapForEachCallback = _Callable[[V, K, "JSMap[K, V]"], None]
40
+
41
+ # Set callbacks
42
+ SetForEachCallback = _Callable[[T, T, "JSSet[T]"], None]
43
+
44
+
45
+ # JavaScript Iterator protocol
46
+ class JSIterator(_Protocol[T_co]):
47
+ """Protocol for JavaScript Iterator objects."""
48
+
49
+ def next(self) -> "JSIteratorResult[T_co]": ...
50
+
51
+ def __iter__(self) -> "JSIterator[T_co]": ...
52
+
53
+
54
+ class JSIteratorResult(_Protocol[T_co]):
55
+ """Result from JavaScript Iterator.next()."""
56
+
57
+ @property
58
+ def value(self) -> T_co: ...
59
+
60
+ @property
61
+ def done(self) -> bool: ...
62
+
63
+
64
+ # JavaScript Iterable protocol
65
+ class JSIterable(_Protocol[T_co]):
66
+ """Protocol for JavaScript Iterable objects (has Symbol.iterator)."""
67
+
68
+ def __iter__(self) -> _Iterator[T_co]: ...
69
+
70
+
71
+ # Placeholder for forward references within this module
72
+ class JSArray(_Protocol[T_co]):
73
+ """Forward reference for Array type - actual implementation in array.py."""
74
+
75
+ ...
76
+
77
+
78
+ V_co = _TypeVar("V_co", covariant=True)
79
+
80
+
81
+ class JSMap(_Protocol[T_co, V_co]):
82
+ """Forward reference for Map type - actual implementation in map.py."""
83
+
84
+ ...
85
+
86
+
87
+ class JSSet(_Protocol[T_co]):
88
+ """Forward reference for Set type - actual implementation in set.py."""
89
+
90
+ ...
91
+
92
+
93
+ # DOM Element types (for document/window methods)
94
+ class Element(_Protocol):
95
+ """Protocol for DOM Element objects."""
96
+
97
+ @property
98
+ def tagName(self) -> str: ...
99
+
100
+ @property
101
+ def id(self) -> str: ...
102
+
103
+ @property
104
+ def className(self) -> str: ...
105
+
106
+ @property
107
+ def innerHTML(self) -> str: ...
108
+
109
+ @property
110
+ def textContent(self) -> str | None: ...
111
+
112
+ @property
113
+ def parentElement(self) -> "Element | None": ...
114
+
115
+ @property
116
+ def children(self) -> "NodeList[Element]": ...
117
+
118
+ def querySelector(self, selectors: str) -> "Element | None": ...
119
+ def querySelectorAll(self, selectors: str) -> "NodeList[Element]": ...
120
+ def getAttribute(self, name: str) -> str | None: ...
121
+ def setAttribute(self, name: str, value: str) -> None: ...
122
+ def removeAttribute(self, name: str) -> None: ...
123
+ def hasAttribute(self, name: str) -> bool: ...
124
+ def addEventListener(
125
+ self,
126
+ type: str,
127
+ listener: _Callable[..., None],
128
+ options: bool | dict[str, bool] | None = None,
129
+ /,
130
+ ) -> None: ...
131
+ def removeEventListener(
132
+ self,
133
+ type: str,
134
+ listener: _Callable[..., None],
135
+ options: bool | dict[str, bool] | None = None,
136
+ /,
137
+ ) -> None: ...
138
+ def remove(self) -> None: ...
139
+ def append(self, *nodes: "Element | str") -> None: ...
140
+ def prepend(self, *nodes: "Element | str") -> None: ...
141
+ def replaceWith(self, *nodes: "Element | str") -> None: ...
142
+
143
+
144
+ class HTMLElement(Element, _Protocol):
145
+ """Protocol for HTMLElement objects."""
146
+
147
+ @property
148
+ def style(self) -> "CSSStyleDeclaration": ...
149
+
150
+ @property
151
+ def dataset(self) -> dict[str, str]: ...
152
+
153
+ @property
154
+ def offsetWidth(self) -> int: ...
155
+
156
+ @property
157
+ def offsetHeight(self) -> int: ...
158
+
159
+ def focus(self) -> None: ...
160
+ def blur(self) -> None: ...
161
+ def click(self) -> None: ...
162
+
163
+
164
+ class CSSStyleDeclaration(_Protocol):
165
+ """Protocol for CSSStyleDeclaration."""
166
+
167
+ def getPropertyValue(self, property: str) -> str: ...
168
+ def setProperty(self, property: str, value: str, priority: str = "", /) -> None: ...
169
+ def removeProperty(self, property: str) -> str: ...
170
+
171
+
172
+ class NodeList(_Protocol[T]):
173
+ """Protocol for NodeList objects."""
174
+
175
+ @property
176
+ def length(self) -> int: ...
177
+
178
+ def item(self, index: int) -> T | None: ...
179
+ def __iter__(self) -> _Iterator[T]: ...
180
+ def __len__(self) -> int: ...
181
+
182
+ @_overload
183
+ def __getitem__(self, index: int) -> T: ...
184
+ @_overload
185
+ def __getitem__(self, index: slice) -> list[T]: ...
186
+
187
+
188
+ class HTMLCollection(_Protocol[T_co]):
189
+ """Protocol for HTMLCollection objects."""
190
+
191
+ @property
192
+ def length(self) -> int: ...
193
+
194
+ def item(self, index: int) -> T_co | None: ...
195
+ def namedItem(self, name: str) -> T_co | None: ...
196
+ def __iter__(self) -> _Iterator[T_co]: ...
197
+ def __len__(self) -> int: ...
198
+
199
+
200
+ # Selection API
201
+ class Selection(_Protocol):
202
+ """Protocol for window.getSelection() result."""
203
+
204
+ @property
205
+ def anchorNode(self) -> Element | None: ...
206
+
207
+ @property
208
+ def focusNode(self) -> Element | None: ...
209
+
210
+ @property
211
+ def isCollapsed(self) -> bool: ...
212
+
213
+ @property
214
+ def rangeCount(self) -> int: ...
215
+
216
+ def getRangeAt(self, index: int) -> "Range": ...
217
+ def collapse(self, node: Element | None, offset: int = 0, /) -> None: ...
218
+ def selectAllChildren(self, node: Element) -> None: ...
219
+ def removeAllRanges(self) -> None: ...
220
+ def toString(self) -> str: ...
221
+
222
+
223
+ class Range(_Protocol):
224
+ """Protocol for Range objects."""
225
+
226
+ @property
227
+ def startContainer(self) -> Element: ...
228
+
229
+ @property
230
+ def endContainer(self) -> Element: ...
231
+
232
+ @property
233
+ def startOffset(self) -> int: ...
234
+
235
+ @property
236
+ def endOffset(self) -> int: ...
237
+
238
+ @property
239
+ def collapsed(self) -> bool: ...
240
+
241
+ def setStart(self, node: Element, offset: int) -> None: ...
242
+ def setEnd(self, node: Element, offset: int) -> None: ...
243
+ def selectNode(self, node: Element) -> None: ...
244
+ def selectNodeContents(self, node: Element) -> None: ...
245
+ def collapse(self, toStart: bool = False, /) -> None: ...
246
+ def cloneContents(self) -> Element: ...
247
+ def deleteContents(self) -> None: ...
248
+
249
+
250
+ # Clipboard API
251
+ class Clipboard(_Protocol):
252
+ """Protocol for Navigator.clipboard."""
253
+
254
+ def read(self) -> _Awaitable[list["ClipboardItem"]]: ...
255
+ def readText(self) -> _Awaitable[str]: ...
256
+ def write(self, data: list["ClipboardItem"]) -> _Awaitable[None]: ...
257
+ def writeText(self, text: str) -> _Awaitable[None]: ...
258
+
259
+
260
+ class ClipboardItem(_Protocol):
261
+ """Protocol for ClipboardItem."""
262
+
263
+ @property
264
+ def types(self) -> list[str]: ...
265
+
266
+ def getType(self, type: str) -> _Awaitable[bytes]: ...
267
+
268
+
269
+ # Event types
270
+ class Event(_Protocol):
271
+ """Protocol for Event objects."""
272
+
273
+ @property
274
+ def type(self) -> str: ...
275
+
276
+ @property
277
+ def target(self) -> Element | None: ...
278
+
279
+ @property
280
+ def currentTarget(self) -> Element | None: ...
281
+
282
+ @property
283
+ def bubbles(self) -> bool: ...
284
+
285
+ @property
286
+ def cancelable(self) -> bool: ...
287
+
288
+ @property
289
+ def defaultPrevented(self) -> bool: ...
290
+
291
+ def preventDefault(self) -> None: ...
292
+ def stopPropagation(self) -> None: ...
293
+ def stopImmediatePropagation(self) -> None: ...
294
+
295
+
296
+ # JSON types
297
+ JSONValue = None | bool | int | float | str | list["JSONValue"] | dict[str, "JSONValue"]
298
+ JSONReplacer = list[str | int] | _Callable[[str, JSONValue], JSONValue]
299
+ JSONReviver = _Callable[[str, JSONValue], JSONValue]
pulse/js/array.py ADDED
@@ -0,0 +1,339 @@
1
+ """
2
+ JavaScript Array builtin module.
3
+
4
+ Usage:
5
+
6
+ ```python
7
+ from pulse.js import Array
8
+ Array.isArray([1, 2, 3]) # -> Array.isArray([1, 2, 3])
9
+ Array.from_([1, 2, 3]) # -> Array.from([1, 2, 3])
10
+ Array(10) # -> new Array(10)
11
+
12
+ # Or import from module directly:
13
+ from pulse.js.array import Array
14
+ ```
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ from collections.abc import Callable as _Callable
20
+ from collections.abc import Iterable as _Iterable
21
+ from collections.abc import Iterator as _Iterator
22
+ from typing import Any as _Any
23
+ from typing import Generic as _Generic
24
+ from typing import TypeGuard as _TypeGuard
25
+ from typing import TypeVar as _TypeVar
26
+ from typing import overload as _overload
27
+
28
+ from pulse.transpiler.js_module import JsModule
29
+
30
+ T = _TypeVar("T")
31
+ U = _TypeVar("U")
32
+ # TypeVars for static methods (can't use class-level T)
33
+ _T = _TypeVar("_T")
34
+ _U = _TypeVar("_U")
35
+
36
+
37
+ class Array(_Generic[T]):
38
+ """JavaScript Array - a generic indexed collection.
39
+
40
+ Array[T] represents a JavaScript array containing elements of type T.
41
+ All instance methods preserve the expected generic types.
42
+ """
43
+
44
+ @_overload
45
+ def __init__(self) -> None:
46
+ """Create an empty Array."""
47
+ ...
48
+
49
+ @_overload
50
+ def __init__(self, length: int, /) -> None:
51
+ """Create an Array with the specified length."""
52
+ ...
53
+
54
+ @_overload
55
+ def __init__(self, *elements: T) -> None:
56
+ """Create an Array with the given elements."""
57
+ ...
58
+
59
+ def __init__(self, *args: T | int) -> None:
60
+ """Create an Array.
61
+
62
+ - No arguments: empty array
63
+ - Single int: array with that length
64
+ - Multiple args: array with those elements
65
+ """
66
+ ...
67
+
68
+ # Static methods
69
+ @staticmethod
70
+ @_overload
71
+ def isArray(value: list[_T], /) -> _TypeGuard["Array[_T]"]:
72
+ """Determine whether the passed value is an Array."""
73
+ ...
74
+
75
+ @staticmethod
76
+ @_overload
77
+ def isArray(value: "Array[_T]", /) -> _TypeGuard["Array[_T]"]:
78
+ """Determine whether the passed value is an Array."""
79
+ ...
80
+
81
+ @staticmethod
82
+ @_overload
83
+ def isArray(value: _Any, /) -> _TypeGuard["Array[_Any]"]:
84
+ """Determine whether the passed value is an Array."""
85
+ ...
86
+
87
+ @staticmethod
88
+ def isArray(value: _Any, /) -> _TypeGuard["Array[_Any]"]:
89
+ """Determine whether the passed value is an Array."""
90
+ ...
91
+
92
+ @staticmethod
93
+ @_overload
94
+ def from_(
95
+ arrayLike: _Iterable[_T] | "Array[_T]",
96
+ /,
97
+ ) -> "Array[_T]":
98
+ """Create a new Array from an array-like or iterable object."""
99
+ ...
100
+
101
+ @staticmethod
102
+ @_overload
103
+ def from_(
104
+ arrayLike: _Iterable[_T] | "Array[_T]",
105
+ mapFn: _Callable[[_T, int], _U],
106
+ thisArg: _Any | None = None,
107
+ /,
108
+ ) -> "Array[_U]":
109
+ """Create a new Array from an array-like or iterable object, mapping each element."""
110
+ ...
111
+
112
+ @staticmethod
113
+ def from_(
114
+ arrayLike: _Iterable[_T] | "Array[_T]",
115
+ mapFn: _Callable[[_T, int], _U] | None = None,
116
+ thisArg: _Any | None = None,
117
+ /,
118
+ ) -> "Array[_U] | Array[_T]":
119
+ """Create a new Array from an array-like or iterable object."""
120
+ ...
121
+
122
+ @staticmethod
123
+ def of(*elements: _T) -> "Array[_T]":
124
+ """Create a new Array from a variable number of arguments."""
125
+ ...
126
+
127
+ # Accessor properties
128
+ @property
129
+ def length(self) -> int:
130
+ """The number of elements in the array."""
131
+ ...
132
+
133
+ # Mutator methods (modify the array in place)
134
+ def push(self, *items: T) -> int:
135
+ """Add elements to the end; returns new length."""
136
+ ...
137
+
138
+ def pop(self) -> T | None:
139
+ """Remove and return the last element."""
140
+ ...
141
+
142
+ def shift(self) -> T | None:
143
+ """Remove and return the first element."""
144
+ ...
145
+
146
+ def unshift(self, *items: T) -> int:
147
+ """Add elements to the beginning; returns new length."""
148
+ ...
149
+
150
+ def splice(
151
+ self, start: int, deleteCount: int | None = None, /, *items: T
152
+ ) -> "Array[T]":
153
+ """Remove/replace elements and optionally insert new ones."""
154
+ ...
155
+
156
+ def reverse(self) -> "Array[T]":
157
+ """Reverse the array in place."""
158
+ ...
159
+
160
+ def sort(self, compareFn: _Callable[[T, T], int] | None = None, /) -> "Array[T]":
161
+ """Sort the array in place."""
162
+ ...
163
+
164
+ def fill(self, value: T, start: int = 0, end: int | None = None, /) -> "Array[T]":
165
+ """Fill all elements with a static value."""
166
+ ...
167
+
168
+ def copyWithin(
169
+ self, target: int, start: int = 0, end: int | None = None, /
170
+ ) -> "Array[T]":
171
+ """Copy part of the array to another location within it."""
172
+ ...
173
+
174
+ # Accessor methods (return new arrays or values)
175
+ def concat(self, *items: T | "_Iterable[T]") -> "Array[T]":
176
+ """Merge arrays and/or values into a new array."""
177
+ ...
178
+
179
+ def slice(self, start: int = 0, end: int | None = None, /) -> "Array[T]":
180
+ """Return a shallow copy of a portion of the array."""
181
+ ...
182
+
183
+ def join(self, separator: str = ",", /) -> str:
184
+ """Join all elements into a string."""
185
+ ...
186
+
187
+ def indexOf(self, searchElement: T, fromIndex: int = 0, /) -> int:
188
+ """Return first index of element, or -1 if not found."""
189
+ ...
190
+
191
+ def lastIndexOf(self, searchElement: T, fromIndex: int | None = None, /) -> int:
192
+ """Return last index of element, or -1 if not found."""
193
+ ...
194
+
195
+ def includes(self, searchElement: T, fromIndex: int = 0, /) -> bool:
196
+ """Determine whether the array contains the element."""
197
+ ...
198
+
199
+ def at(self, index: int) -> T | None:
200
+ """Return element at index (supports negative indexing)."""
201
+ ...
202
+
203
+ def flat(self, depth: int = 1, /) -> "Array[_Any]":
204
+ """Flatten nested arrays to the specified depth."""
205
+ ...
206
+
207
+ def flatMap(
208
+ self, callback: _Callable[[T, int, "Array[T]"], _Iterable[U]]
209
+ ) -> "Array[U]":
210
+ """Map then flatten the result by one level."""
211
+ ...
212
+
213
+ def toReversed(self) -> "Array[T]":
214
+ """Return a new reversed array (ES2023)."""
215
+ ...
216
+
217
+ def toSorted(
218
+ self, compareFn: _Callable[[T, T], int] | None = None, /
219
+ ) -> "Array[T]":
220
+ """Return a new sorted array (ES2023)."""
221
+ ...
222
+
223
+ def toSpliced(
224
+ self, start: int, deleteCount: int | None = None, /, *items: T
225
+ ) -> "Array[T]":
226
+ """Return a new array with elements spliced (ES2023)."""
227
+ ...
228
+
229
+ def with_(self, index: int, value: T) -> "Array[T]":
230
+ """Return a new array with element at index replaced (ES2023)."""
231
+ ...
232
+
233
+ # Iteration methods
234
+ def forEach(self, callback: _Callable[[T, int, "Array[T]"], None]) -> None:
235
+ """Execute a function for each element."""
236
+ ...
237
+
238
+ def map(self, callback: _Callable[[T, int, "Array[T]"], U]) -> "Array[U]":
239
+ """Create a new array with results of calling callback on each element."""
240
+ ...
241
+
242
+ def filter(self, callback: _Callable[[T, int, "Array[T]"], bool]) -> "Array[T]":
243
+ """Create a new array with elements that pass the test."""
244
+ ...
245
+
246
+ def reduce(
247
+ self,
248
+ callback: _Callable[[U, T, int, "Array[T]"], U],
249
+ initialValue: U | None = None,
250
+ /,
251
+ ) -> U:
252
+ """Reduce array to a single value (left to right).
253
+
254
+ If no initialValue is provided, the first element is used.
255
+ """
256
+ ...
257
+
258
+ def reduceRight(
259
+ self,
260
+ callback: _Callable[[U, T, int, "Array[T]"], U],
261
+ initialValue: U | None = None,
262
+ /,
263
+ ) -> U:
264
+ """Reduce array to a single value (right to left).
265
+
266
+ If no initialValue is provided, the last element is used.
267
+ """
268
+ ...
269
+
270
+ def find(self, callback: _Callable[[T, int, "Array[T]"], bool]) -> T | None:
271
+ """Return first element satisfying the callback."""
272
+ ...
273
+
274
+ def findIndex(self, callback: _Callable[[T, int, "Array[T]"], bool]) -> int:
275
+ """Return index of first element satisfying the callback, or -1."""
276
+ ...
277
+
278
+ def findLast(self, callback: _Callable[[T, int, "Array[T]"], bool]) -> T | None:
279
+ """Return last element satisfying the callback (ES2023)."""
280
+ ...
281
+
282
+ def findLastIndex(self, callback: _Callable[[T, int, "Array[T]"], bool]) -> int:
283
+ """Return index of last element satisfying the callback, or -1 (ES2023)."""
284
+ ...
285
+
286
+ def every(self, callback: _Callable[[T, int, "Array[T]"], bool]) -> bool:
287
+ """Test whether all elements pass the callback."""
288
+ ...
289
+
290
+ def some(self, callback: _Callable[[T, int, "Array[T]"], bool]) -> bool:
291
+ """Test whether at least one element passes the callback."""
292
+ ...
293
+
294
+ # Iterator methods
295
+ def keys(self) -> _Iterable[int]:
296
+ """Return an iterator of array indices."""
297
+ ...
298
+
299
+ def values(self) -> _Iterable[T]:
300
+ """Return an iterator of array values."""
301
+ ...
302
+
303
+ def entries(self) -> _Iterable[tuple[int, T]]:
304
+ """Return an iterator of [index, value] pairs."""
305
+ ...
306
+
307
+ # String conversion
308
+ def toString(self) -> str:
309
+ """Return a string representing the array."""
310
+ ...
311
+
312
+ def toLocaleString(self) -> str:
313
+ """Return a localized string representing the array."""
314
+ ...
315
+
316
+ # Python protocol methods
317
+ def __iter__(self) -> _Iterator[T]:
318
+ """Iterate over array elements."""
319
+ ...
320
+
321
+ def __getitem__(self, index: int) -> T:
322
+ """Get element at index."""
323
+ ...
324
+
325
+ def __setitem__(self, index: int, value: T) -> None:
326
+ """Set element at index."""
327
+ ...
328
+
329
+ def __len__(self) -> int:
330
+ """Return the number of elements (same as length)."""
331
+ ...
332
+
333
+ def __contains__(self, value: T) -> bool:
334
+ """Check if value exists in the array (same as includes)."""
335
+ ...
336
+
337
+
338
+ # Self-register this module as a JS builtin (global identifier)
339
+ JsModule.register(name=None)
pulse/js/console.py ADDED
@@ -0,0 +1,50 @@
1
+ """
2
+ JavaScript Console builtin module.
3
+
4
+ Usage:
5
+
6
+ ```python
7
+ import pulse.js.console as console
8
+ console.log("Hello") # -> console.log("Hello")
9
+ console.error("Error") # -> console.error("Error")
10
+ console.assert(True, "msg") # -> console.assert(True, "msg")
11
+
12
+ # Note: For 'assert' (Python keyword), use namespace import:
13
+ # import pulse.js.console as console; console.assert(...)
14
+ # Or use the underscore version for direct import:
15
+ from pulse.js.console import log, error, warn, info, debug, assert_
16
+ log("Hello") # -> console.log("Hello")
17
+ error("Error") # -> console.error("Error")
18
+ assert_(True, "msg") # -> console.assert(True, "msg")
19
+ ```
20
+ """
21
+
22
+ from typing import Any as _Any
23
+
24
+ from pulse.transpiler.js_module import JsModule
25
+
26
+
27
+ # Methods (type stubs for IDE support)
28
+ def assert_(condition: bool, *data: _Any) -> None: ...
29
+ def clear() -> None: ...
30
+ def count(label: str | None = None, /) -> None: ...
31
+ def countReset(label: str | None = None, /) -> None: ...
32
+ def debug(*data: _Any) -> None: ...
33
+ def dir(item: _Any, options: dict[str, _Any] | None = None, /) -> None: ...
34
+ def dirxml(*data: _Any) -> None: ...
35
+ def error(*data: _Any) -> None: ...
36
+ def group(*label: _Any) -> None: ...
37
+ def groupCollapsed(*label: _Any) -> None: ...
38
+ def groupEnd() -> None: ...
39
+ def info(*data: _Any) -> None: ...
40
+ def log(*data: _Any) -> None: ...
41
+ def table(tabularData: _Any, properties: list[str] | None = None, /) -> None: ...
42
+ def time(label: str | None = None, /) -> None: ...
43
+ def timeEnd(label: str | None = None, /) -> None: ...
44
+ def timeLog(label: str | None = None, /, *data: _Any) -> None: ...
45
+ def trace(*data: _Any) -> None: ...
46
+ def warn(*data: _Any) -> None: ...
47
+
48
+
49
+ # Self-register this module as a JS builtin
50
+ JsModule.register(name="console")