pulse-framework 0.1.46__py3-none-any.whl → 0.1.48__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pulse/__init__.py +9 -23
- pulse/app.py +6 -25
- pulse/cli/processes.py +1 -0
- pulse/codegen/codegen.py +43 -88
- pulse/codegen/js.py +35 -5
- pulse/codegen/templates/route.py +341 -254
- pulse/form.py +1 -1
- pulse/helpers.py +51 -27
- pulse/hooks/core.py +2 -2
- pulse/hooks/effects.py +1 -1
- pulse/hooks/init.py +2 -1
- pulse/hooks/setup.py +1 -1
- pulse/hooks/stable.py +2 -2
- pulse/hooks/states.py +2 -2
- pulse/html/props.py +3 -2
- pulse/html/tags.py +135 -0
- pulse/html/tags.pyi +4 -0
- pulse/js/__init__.py +110 -0
- pulse/js/__init__.pyi +95 -0
- pulse/js/_types.py +297 -0
- pulse/js/array.py +253 -0
- pulse/js/console.py +47 -0
- pulse/js/date.py +113 -0
- pulse/js/document.py +138 -0
- pulse/js/error.py +139 -0
- pulse/js/json.py +62 -0
- pulse/js/map.py +84 -0
- pulse/js/math.py +66 -0
- pulse/js/navigator.py +76 -0
- pulse/js/number.py +54 -0
- pulse/js/object.py +173 -0
- pulse/js/promise.py +150 -0
- pulse/js/regexp.py +54 -0
- pulse/js/set.py +109 -0
- pulse/js/string.py +35 -0
- pulse/js/weakmap.py +50 -0
- pulse/js/weakset.py +45 -0
- pulse/js/window.py +199 -0
- pulse/messages.py +22 -3
- pulse/proxy.py +21 -8
- pulse/react_component.py +167 -14
- pulse/reactive_extensions.py +5 -5
- pulse/render_session.py +144 -34
- pulse/renderer.py +80 -115
- pulse/routing.py +1 -18
- pulse/transpiler/__init__.py +131 -0
- pulse/transpiler/builtins.py +731 -0
- pulse/transpiler/constants.py +110 -0
- pulse/transpiler/context.py +26 -0
- pulse/transpiler/errors.py +2 -0
- pulse/transpiler/function.py +250 -0
- pulse/transpiler/ids.py +16 -0
- pulse/transpiler/imports.py +409 -0
- pulse/transpiler/js_module.py +274 -0
- pulse/transpiler/modules/__init__.py +30 -0
- pulse/transpiler/modules/asyncio.py +38 -0
- pulse/transpiler/modules/json.py +20 -0
- pulse/transpiler/modules/math.py +320 -0
- pulse/transpiler/modules/re.py +466 -0
- pulse/transpiler/modules/tags.py +268 -0
- pulse/transpiler/modules/typing.py +59 -0
- pulse/transpiler/nodes.py +1216 -0
- pulse/transpiler/py_module.py +119 -0
- pulse/transpiler/transpiler.py +938 -0
- pulse/transpiler/utils.py +4 -0
- pulse/vdom.py +112 -6
- {pulse_framework-0.1.46.dist-info → pulse_framework-0.1.48.dist-info}/METADATA +1 -1
- pulse_framework-0.1.48.dist-info/RECORD +119 -0
- pulse/codegen/imports.py +0 -204
- pulse/css.py +0 -155
- pulse_framework-0.1.46.dist-info/RECORD +0 -80
- {pulse_framework-0.1.46.dist-info → pulse_framework-0.1.48.dist-info}/WHEEL +0 -0
- {pulse_framework-0.1.46.dist-info → pulse_framework-0.1.48.dist-info}/entry_points.txt +0 -0
pulse/js/object.py
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"""
|
|
2
|
+
JavaScript Object builtin module.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
import pulse.js.object as Object
|
|
6
|
+
Object.keys({"a": 1}) # -> Object.keys({"a": 1})
|
|
7
|
+
Object.assign({}, {"a": 1}) # -> Object.assign({}, {"a": 1})
|
|
8
|
+
Object.is(x, y) # -> Object.is(x, y)
|
|
9
|
+
|
|
10
|
+
# Note: For 'is' (Python keyword), use namespace import:
|
|
11
|
+
# import pulse.js.object as Object; Object.is(...)
|
|
12
|
+
# Or use the underscore version for direct import:
|
|
13
|
+
from pulse.js.object import keys, assign, is_
|
|
14
|
+
keys({"a": 1}) # -> Object.keys({"a": 1})
|
|
15
|
+
assign({}, {"a": 1}) # -> Object.assign({}, {"a": 1})
|
|
16
|
+
is_(x, y) # -> Object.is(x, y)
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from collections.abc import Iterable as _Iterable
|
|
20
|
+
from typing import Any as _Any
|
|
21
|
+
from typing import TypedDict as _TypedDict
|
|
22
|
+
from typing import TypeVar as _TypeVar
|
|
23
|
+
|
|
24
|
+
from pulse.transpiler.js_module import register_js_module as _register_js_module
|
|
25
|
+
|
|
26
|
+
T = _TypeVar("T")
|
|
27
|
+
K = _TypeVar("K", bound=str) # Object keys are always strings in JS
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# Property descriptor type - JS uses a plain object with specific keys
|
|
31
|
+
class PropertyDescriptor(_TypedDict, total=False):
|
|
32
|
+
"""Type for Object.defineProperty descriptor."""
|
|
33
|
+
|
|
34
|
+
value: _Any
|
|
35
|
+
writable: bool
|
|
36
|
+
get: _Any # Callable[[], T] but we use _Any for flexibility
|
|
37
|
+
set: _Any # Callable[[T], None]
|
|
38
|
+
configurable: bool
|
|
39
|
+
enumerable: bool
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class Object:
|
|
43
|
+
"""JavaScript Object namespace - static methods for object manipulation.
|
|
44
|
+
|
|
45
|
+
Note: Object is primarily used as a namespace for static methods.
|
|
46
|
+
The types here are as precise as JavaScript's dynamic nature allows.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def assign(target: T, *sources: _Any) -> T:
|
|
51
|
+
"""Copy properties from sources to target. Returns target."""
|
|
52
|
+
...
|
|
53
|
+
|
|
54
|
+
@staticmethod
|
|
55
|
+
def create(
|
|
56
|
+
proto: _Any | None,
|
|
57
|
+
propertiesObject: dict[str, PropertyDescriptor] | None = None,
|
|
58
|
+
) -> _Any:
|
|
59
|
+
"""Create a new object with the specified prototype."""
|
|
60
|
+
...
|
|
61
|
+
|
|
62
|
+
@staticmethod
|
|
63
|
+
def defineProperty(
|
|
64
|
+
obj: T, prop: str, descriptor: PropertyDescriptor | dict[str, _Any]
|
|
65
|
+
) -> T:
|
|
66
|
+
"""Define a property on an object. Returns the object."""
|
|
67
|
+
...
|
|
68
|
+
|
|
69
|
+
@staticmethod
|
|
70
|
+
def defineProperties(
|
|
71
|
+
obj: T, props: dict[str, PropertyDescriptor | dict[str, _Any]]
|
|
72
|
+
) -> T:
|
|
73
|
+
"""Define multiple properties on an object. Returns the object."""
|
|
74
|
+
...
|
|
75
|
+
|
|
76
|
+
@staticmethod
|
|
77
|
+
def entries(obj: dict[str, T]) -> list[tuple[str, T]]:
|
|
78
|
+
"""Return an array of [key, value] pairs."""
|
|
79
|
+
...
|
|
80
|
+
|
|
81
|
+
@staticmethod
|
|
82
|
+
def freeze(obj: T) -> T:
|
|
83
|
+
"""Freeze an object (prevent modifications). Returns the object."""
|
|
84
|
+
...
|
|
85
|
+
|
|
86
|
+
@staticmethod
|
|
87
|
+
def fromEntries(entries: _Iterable[tuple[str, T]]) -> dict[str, T]:
|
|
88
|
+
"""Create an object from an iterable of [key, value] pairs."""
|
|
89
|
+
...
|
|
90
|
+
|
|
91
|
+
@staticmethod
|
|
92
|
+
def getOwnPropertyDescriptor(obj: _Any, prop: str) -> PropertyDescriptor | None:
|
|
93
|
+
"""Return the property descriptor for a property."""
|
|
94
|
+
...
|
|
95
|
+
|
|
96
|
+
@staticmethod
|
|
97
|
+
def getOwnPropertyDescriptors(obj: _Any) -> dict[str, PropertyDescriptor]:
|
|
98
|
+
"""Return all own property descriptors."""
|
|
99
|
+
...
|
|
100
|
+
|
|
101
|
+
@staticmethod
|
|
102
|
+
def getOwnPropertyNames(obj: _Any) -> list[str]:
|
|
103
|
+
"""Return all own property names (including non-enumerable)."""
|
|
104
|
+
...
|
|
105
|
+
|
|
106
|
+
@staticmethod
|
|
107
|
+
def getOwnPropertySymbols(obj: _Any) -> list[_Any]:
|
|
108
|
+
"""Return all own Symbol properties."""
|
|
109
|
+
...
|
|
110
|
+
|
|
111
|
+
@staticmethod
|
|
112
|
+
def getPrototypeOf(obj: _Any) -> _Any | None:
|
|
113
|
+
"""Return the prototype of an object."""
|
|
114
|
+
...
|
|
115
|
+
|
|
116
|
+
@staticmethod
|
|
117
|
+
def hasOwn(obj: _Any, prop: str) -> bool:
|
|
118
|
+
"""Return True if the object has the specified own property."""
|
|
119
|
+
...
|
|
120
|
+
|
|
121
|
+
@staticmethod
|
|
122
|
+
def is_(value1: _Any, value2: _Any) -> bool:
|
|
123
|
+
"""Determine if two values are the same value (SameValue algorithm)."""
|
|
124
|
+
...
|
|
125
|
+
|
|
126
|
+
@staticmethod
|
|
127
|
+
def isExtensible(obj: _Any) -> bool:
|
|
128
|
+
"""Return True if the object is extensible."""
|
|
129
|
+
...
|
|
130
|
+
|
|
131
|
+
@staticmethod
|
|
132
|
+
def isFrozen(obj: _Any) -> bool:
|
|
133
|
+
"""Return True if the object is frozen."""
|
|
134
|
+
...
|
|
135
|
+
|
|
136
|
+
@staticmethod
|
|
137
|
+
def isSealed(obj: _Any) -> bool:
|
|
138
|
+
"""Return True if the object is sealed."""
|
|
139
|
+
...
|
|
140
|
+
|
|
141
|
+
@staticmethod
|
|
142
|
+
def keys(obj: dict[str, _Any]) -> list[str]:
|
|
143
|
+
"""Return an array of enumerable property names."""
|
|
144
|
+
...
|
|
145
|
+
|
|
146
|
+
@staticmethod
|
|
147
|
+
def preventExtensions(obj: T) -> T:
|
|
148
|
+
"""Prevent new properties from being added. Returns the object."""
|
|
149
|
+
...
|
|
150
|
+
|
|
151
|
+
@staticmethod
|
|
152
|
+
def seal(obj: T) -> T:
|
|
153
|
+
"""Seal an object (prevent adding/removing properties). Returns the object."""
|
|
154
|
+
...
|
|
155
|
+
|
|
156
|
+
@staticmethod
|
|
157
|
+
def setPrototypeOf(obj: T, prototype: _Any | None) -> T:
|
|
158
|
+
"""Set the prototype of an object. Returns the object."""
|
|
159
|
+
...
|
|
160
|
+
|
|
161
|
+
@staticmethod
|
|
162
|
+
def values(obj: dict[str, T]) -> list[T]:
|
|
163
|
+
"""Return an array of enumerable property values."""
|
|
164
|
+
...
|
|
165
|
+
|
|
166
|
+
@staticmethod
|
|
167
|
+
def groupBy(items: _Iterable[T], keyFn: _Any) -> dict[str, list[T]]:
|
|
168
|
+
"""Group items by key function result (ES2024)."""
|
|
169
|
+
...
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
# Self-register this module as a JS builtin
|
|
173
|
+
_register_js_module(name="Object", global_scope=True)
|
pulse/js/promise.py
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""
|
|
2
|
+
JavaScript Promise builtin module.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
import pulse.js.promise as Promise
|
|
6
|
+
Promise.resolve(value) # -> Promise.resolve(value)
|
|
7
|
+
Promise.reject(reason) # -> Promise.reject(reason)
|
|
8
|
+
|
|
9
|
+
from pulse.js.promise import resolve, reject, all, allSettled, race, any
|
|
10
|
+
resolve(value) # -> Promise.resolve(value)
|
|
11
|
+
reject(reason) # -> Promise.reject(reason)
|
|
12
|
+
|
|
13
|
+
The Promise class is generic and supports async/await via the Awaitable protocol.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from collections.abc import Callable as _Callable
|
|
17
|
+
from collections.abc import Generator as _Generator
|
|
18
|
+
from collections.abc import Iterable as _Iterable
|
|
19
|
+
from typing import Generic as _Generic
|
|
20
|
+
from typing import TypeVar as _TypeVar
|
|
21
|
+
|
|
22
|
+
from pulse.transpiler.js_module import register_js_module as _register_js_module
|
|
23
|
+
|
|
24
|
+
T = _TypeVar("T")
|
|
25
|
+
T_co = _TypeVar("T_co", covariant=True)
|
|
26
|
+
U = _TypeVar("U")
|
|
27
|
+
|
|
28
|
+
# Result types for allSettled
|
|
29
|
+
PromiseFulfilledResult = dict[str, T | str] # { status: "fulfilled", value: T }
|
|
30
|
+
PromiseRejectedResult = dict[str, str] # { status: "rejected", reason: any }
|
|
31
|
+
PromiseSettledResult = PromiseFulfilledResult[T] | PromiseRejectedResult
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Promise(_Generic[T_co]):
|
|
35
|
+
"""JavaScript Promise - a thenable that represents an async operation.
|
|
36
|
+
|
|
37
|
+
Promise is both generic over its resolved type and implements Awaitable,
|
|
38
|
+
allowing it to be used with Python's async/await syntax which transpiles
|
|
39
|
+
to JavaScript async/await.
|
|
40
|
+
|
|
41
|
+
Example:
|
|
42
|
+
@javascript
|
|
43
|
+
async def fetch_data() -> str:
|
|
44
|
+
response: Promise[Response] = fetch("/api/data")
|
|
45
|
+
data = await response # Awaits the promise
|
|
46
|
+
return data.text()
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def __init__(
|
|
50
|
+
self,
|
|
51
|
+
executor: _Callable[
|
|
52
|
+
[_Callable[[T_co], None], _Callable[[Exception], None]], None
|
|
53
|
+
]
|
|
54
|
+
| None = None,
|
|
55
|
+
) -> None:
|
|
56
|
+
"""Create a Promise.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
executor: Optional function receiving (resolve, reject) callbacks.
|
|
60
|
+
If omitted, creates a pending promise (for use with Promise.resolve/reject).
|
|
61
|
+
"""
|
|
62
|
+
...
|
|
63
|
+
|
|
64
|
+
def then(
|
|
65
|
+
self,
|
|
66
|
+
on_fulfilled: _Callable[[T_co], U | "Promise[U]"] | None = None,
|
|
67
|
+
on_rejected: _Callable[[Exception], U | "Promise[U]"] | None = None,
|
|
68
|
+
) -> "Promise[U]":
|
|
69
|
+
"""Attach callbacks to handle fulfillment and/or rejection."""
|
|
70
|
+
...
|
|
71
|
+
|
|
72
|
+
def catch(
|
|
73
|
+
self, on_rejected: _Callable[[Exception], U | "Promise[U]"]
|
|
74
|
+
) -> "Promise[T_co | U]":
|
|
75
|
+
"""Attach a rejection handler callback."""
|
|
76
|
+
...
|
|
77
|
+
|
|
78
|
+
def finally_(self, on_finally: _Callable[[], None]) -> "Promise[T_co]":
|
|
79
|
+
"""Attach a handler that is called when the promise settles (fulfilled or rejected)."""
|
|
80
|
+
...
|
|
81
|
+
|
|
82
|
+
def __await__(self) -> _Generator[None, None, T_co]:
|
|
83
|
+
"""Support await syntax - transpiles to JavaScript await."""
|
|
84
|
+
...
|
|
85
|
+
|
|
86
|
+
# Static methods for Promise construction
|
|
87
|
+
@staticmethod
|
|
88
|
+
def resolve(value: U | None = None) -> "Promise[U] | Promise[None]":
|
|
89
|
+
"""Create a Promise that resolves with the given value."""
|
|
90
|
+
...
|
|
91
|
+
|
|
92
|
+
@staticmethod
|
|
93
|
+
def reject(reason: Exception | str) -> "Promise[T]":
|
|
94
|
+
"""Create a Promise that rejects with the given reason."""
|
|
95
|
+
...
|
|
96
|
+
|
|
97
|
+
# Static methods for combining promises
|
|
98
|
+
@staticmethod
|
|
99
|
+
def all(iterable: _Iterable["Promise[T]"]) -> "Promise[list[T]]":
|
|
100
|
+
"""Wait for all promises to resolve, or reject on first rejection.
|
|
101
|
+
|
|
102
|
+
Returns a promise that resolves to a list of all resolved values.
|
|
103
|
+
"""
|
|
104
|
+
...
|
|
105
|
+
|
|
106
|
+
@staticmethod
|
|
107
|
+
def allSettled(
|
|
108
|
+
iterable: _Iterable["Promise[T]"],
|
|
109
|
+
) -> "Promise[list[PromiseSettledResult[T]]]":
|
|
110
|
+
"""Wait for all promises to settle (resolve or reject).
|
|
111
|
+
|
|
112
|
+
Returns a promise that resolves to a list of result objects.
|
|
113
|
+
"""
|
|
114
|
+
...
|
|
115
|
+
|
|
116
|
+
@staticmethod
|
|
117
|
+
def any(iterable: _Iterable["Promise[T]"]) -> "Promise[T]":
|
|
118
|
+
"""Return first fulfilled promise, or reject if all reject."""
|
|
119
|
+
...
|
|
120
|
+
|
|
121
|
+
@staticmethod
|
|
122
|
+
def race(iterable: _Iterable["Promise[T]"]) -> "Promise[T]":
|
|
123
|
+
"""Return first settled promise (fulfilled or rejected)."""
|
|
124
|
+
...
|
|
125
|
+
|
|
126
|
+
@staticmethod
|
|
127
|
+
def withResolvers() -> "PromiseWithResolvers[T]":
|
|
128
|
+
"""Create a promise with its resolve and reject functions exposed.
|
|
129
|
+
|
|
130
|
+
Returns an object with { promise, resolve, reject }.
|
|
131
|
+
ES2024 feature.
|
|
132
|
+
"""
|
|
133
|
+
...
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class PromiseWithResolvers(_Generic[T]):
|
|
137
|
+
"""Result type for Promise.withResolvers()."""
|
|
138
|
+
|
|
139
|
+
@property
|
|
140
|
+
def promise(self) -> Promise[T]: ...
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
def resolve(self) -> _Callable[[T], None]: ...
|
|
144
|
+
|
|
145
|
+
@property
|
|
146
|
+
def reject(self) -> _Callable[[Exception | str], None]: ...
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
# Self-register this module as a JS builtin
|
|
150
|
+
_register_js_module(name="Promise", global_scope=True)
|
pulse/js/regexp.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""
|
|
2
|
+
JavaScript RegExp builtin module.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
import pulse.js.regexp as RegExp
|
|
6
|
+
RegExp(pattern, flags) # -> new RegExp(pattern, flags)
|
|
7
|
+
|
|
8
|
+
from pulse.js.regexp import RegExp
|
|
9
|
+
RegExp(pattern, flags) # -> new RegExp(pattern, flags)
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from pulse.transpiler.js_module import register_js_module as _register_js_module
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class RegExp:
|
|
16
|
+
"""Class for JavaScript RegExp instances."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, pattern: str, flags: str | None = None): ...
|
|
19
|
+
|
|
20
|
+
def exec(self, string: str) -> list[str] | None: ...
|
|
21
|
+
def test(self, string: str) -> bool: ...
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def source(self) -> str: ...
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def flags(self) -> str: ...
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def glob(self) -> bool: ... # JavaScript 'global' property
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def ignoreCase(self) -> bool: ...
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def multiline(self) -> bool: ...
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def dotAll(self) -> bool: ...
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def unicode(self) -> bool: ...
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def sticky(self) -> bool: ...
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def lastIndex(self) -> int: ...
|
|
49
|
+
|
|
50
|
+
def toString(self) -> str: ...
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# Self-register this module as a JS builtin
|
|
54
|
+
_register_js_module(name="RegExp", global_scope=True)
|
pulse/js/set.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""
|
|
2
|
+
JavaScript Set builtin module.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
import pulse.js.set as Set
|
|
6
|
+
Set() # -> new Set()
|
|
7
|
+
Set([1, 2, 3]) # -> new Set([1, 2, 3])
|
|
8
|
+
|
|
9
|
+
from pulse.js.set import Set
|
|
10
|
+
Set() # -> new Set()
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from collections.abc import Callable as _Callable
|
|
14
|
+
from collections.abc import Iterable as _Iterable
|
|
15
|
+
from typing import Any as _Any
|
|
16
|
+
from typing import Generic as _Generic
|
|
17
|
+
from typing import TypeVar as _TypeVar
|
|
18
|
+
|
|
19
|
+
from pulse.transpiler.js_module import register_js_module as _register_js_module
|
|
20
|
+
|
|
21
|
+
T = _TypeVar("T")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Set(_Generic[T]):
|
|
25
|
+
"""JavaScript Set - a collection of unique values.
|
|
26
|
+
|
|
27
|
+
Set[T] stores unique values of type T in insertion order.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(self, iterable: _Iterable[T] | None = None) -> None: ...
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def size(self) -> int:
|
|
34
|
+
"""The number of values in the Set."""
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
def add(self, value: T) -> "Set[T]":
|
|
38
|
+
"""Add a value to the Set. Returns the Set for chaining."""
|
|
39
|
+
...
|
|
40
|
+
|
|
41
|
+
def clear(self) -> None:
|
|
42
|
+
"""Remove all values from the Set."""
|
|
43
|
+
...
|
|
44
|
+
|
|
45
|
+
def delete(self, value: T) -> bool:
|
|
46
|
+
"""Remove a value. Returns True if the value existed."""
|
|
47
|
+
...
|
|
48
|
+
|
|
49
|
+
def has(self, value: T) -> bool:
|
|
50
|
+
"""Return True if the value exists in the Set."""
|
|
51
|
+
...
|
|
52
|
+
|
|
53
|
+
def forEach(
|
|
54
|
+
self, callback: _Callable[[T, T, "Set[T]"], None], thisArg: _Any | None = None
|
|
55
|
+
) -> None:
|
|
56
|
+
"""Execute a function for each value.
|
|
57
|
+
|
|
58
|
+
Note: callback receives (value, value, set) for compatibility with Map.
|
|
59
|
+
"""
|
|
60
|
+
...
|
|
61
|
+
|
|
62
|
+
def keys(self) -> _Iterable[T]:
|
|
63
|
+
"""Return an iterator of values (same as values())."""
|
|
64
|
+
...
|
|
65
|
+
|
|
66
|
+
def values(self) -> _Iterable[T]:
|
|
67
|
+
"""Return an iterator of values."""
|
|
68
|
+
...
|
|
69
|
+
|
|
70
|
+
def entries(self) -> _Iterable[tuple[T, T]]:
|
|
71
|
+
"""Return an iterator of [value, value] pairs."""
|
|
72
|
+
...
|
|
73
|
+
|
|
74
|
+
def __iter__(self) -> _Iterable[T]:
|
|
75
|
+
"""Iterate over values."""
|
|
76
|
+
...
|
|
77
|
+
|
|
78
|
+
# ES2024 Set methods
|
|
79
|
+
def union(self, other: "Set[T]") -> "Set[T]":
|
|
80
|
+
"""Return a new Set with values from both sets (ES2024)."""
|
|
81
|
+
...
|
|
82
|
+
|
|
83
|
+
def intersection(self, other: "Set[T]") -> "Set[T]":
|
|
84
|
+
"""Return a new Set with values in both sets (ES2024)."""
|
|
85
|
+
...
|
|
86
|
+
|
|
87
|
+
def difference(self, other: "Set[T]") -> "Set[T]":
|
|
88
|
+
"""Return a new Set with values in this but not other (ES2024)."""
|
|
89
|
+
...
|
|
90
|
+
|
|
91
|
+
def symmetricDifference(self, other: "Set[T]") -> "Set[T]":
|
|
92
|
+
"""Return a new Set with values in either but not both (ES2024)."""
|
|
93
|
+
...
|
|
94
|
+
|
|
95
|
+
def isSubsetOf(self, other: "Set[T]") -> bool:
|
|
96
|
+
"""Return True if all values are in other (ES2024)."""
|
|
97
|
+
...
|
|
98
|
+
|
|
99
|
+
def isSupersetOf(self, other: "Set[T]") -> bool:
|
|
100
|
+
"""Return True if all values of other are in this (ES2024)."""
|
|
101
|
+
...
|
|
102
|
+
|
|
103
|
+
def isDisjointFrom(self, other: "Set[T]") -> bool:
|
|
104
|
+
"""Return True if no values are in common (ES2024)."""
|
|
105
|
+
...
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
# Self-register this module as a JS builtin in global scope
|
|
109
|
+
_register_js_module(name="Set", global_scope=True)
|
pulse/js/string.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""
|
|
2
|
+
JavaScript String builtin module.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
import pulse.js.string as String
|
|
6
|
+
String.fromCharCode(65) # -> String.fromCharCode(65)
|
|
7
|
+
String.fromCodePoint(0x1F600) # -> String.fromCodePoint(0x1F600)
|
|
8
|
+
|
|
9
|
+
from pulse.js.string import fromCharCode, fromCodePoint
|
|
10
|
+
fromCharCode(65) # -> String.fromCharCode(65)
|
|
11
|
+
fromCodePoint(0x1F600) # -> String.fromCodePoint(0x1F600)
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from typing import Any as _Any
|
|
15
|
+
|
|
16
|
+
from pulse.transpiler.js_module import register_js_module as _register_js_module
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class String:
|
|
20
|
+
"""JavaScript String constructor."""
|
|
21
|
+
|
|
22
|
+
def __init__(self, value: _Any) -> None: ...
|
|
23
|
+
|
|
24
|
+
@staticmethod
|
|
25
|
+
def fromCharCode(*codes: int) -> str: ...
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def fromCodePoint(*codePoints: int) -> str: ...
|
|
29
|
+
|
|
30
|
+
@staticmethod
|
|
31
|
+
def raw(template: str, *substitutions: str) -> str: ...
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# Self-register this module as a JS builtin
|
|
35
|
+
_register_js_module(name="String", global_scope=True)
|
pulse/js/weakmap.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""
|
|
2
|
+
JavaScript WeakMap builtin module.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
import pulse.js.weakmap as WeakMap
|
|
6
|
+
WeakMap() # -> new WeakMap()
|
|
7
|
+
WeakMap([[obj, "value"]]) # -> new WeakMap([[obj, "value"]])
|
|
8
|
+
|
|
9
|
+
from pulse.js.weakmap import WeakMap
|
|
10
|
+
WeakMap() # -> new WeakMap()
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from collections.abc import Iterable as _Iterable
|
|
14
|
+
from typing import Generic as _Generic
|
|
15
|
+
from typing import TypeVar as _TypeVar
|
|
16
|
+
|
|
17
|
+
from pulse.transpiler.js_module import register_js_module as _register_js_module
|
|
18
|
+
|
|
19
|
+
K = _TypeVar("K") # Keys must be objects in JS, but we can't enforce that statically
|
|
20
|
+
V = _TypeVar("V")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class WeakMap(_Generic[K, V]):
|
|
24
|
+
"""JavaScript WeakMap - a collection of key/value pairs with weak key references.
|
|
25
|
+
|
|
26
|
+
WeakMap[K, V] holds weak references to keys, allowing garbage collection.
|
|
27
|
+
Keys must be objects (not primitives).
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(self, iterable: _Iterable[tuple[K, V]] | None = None) -> None: ...
|
|
31
|
+
|
|
32
|
+
def delete(self, key: K) -> bool:
|
|
33
|
+
"""Remove a key and its value. Returns True if the key existed."""
|
|
34
|
+
...
|
|
35
|
+
|
|
36
|
+
def get(self, key: K) -> V | None:
|
|
37
|
+
"""Return the value for a key, or None if not present."""
|
|
38
|
+
...
|
|
39
|
+
|
|
40
|
+
def has(self, key: K) -> bool:
|
|
41
|
+
"""Return True if the key exists in the WeakMap."""
|
|
42
|
+
...
|
|
43
|
+
|
|
44
|
+
def set(self, key: K, value: V) -> "WeakMap[K, V]":
|
|
45
|
+
"""Set a key/value pair. Returns the WeakMap for chaining."""
|
|
46
|
+
...
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# Self-register this module as a JS builtin
|
|
50
|
+
_register_js_module(name="WeakMap", global_scope=True)
|
pulse/js/weakset.py
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""
|
|
2
|
+
JavaScript WeakSet builtin module.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
import pulse.js.weakset as WeakSet
|
|
6
|
+
WeakSet() # -> new WeakSet()
|
|
7
|
+
WeakSet([obj1, obj2]) # -> new WeakSet([obj1, obj2])
|
|
8
|
+
|
|
9
|
+
from pulse.js.weakset import WeakSet
|
|
10
|
+
WeakSet() # -> new WeakSet()
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from collections.abc import Iterable as _Iterable
|
|
14
|
+
from typing import Generic as _Generic
|
|
15
|
+
from typing import TypeVar as _TypeVar
|
|
16
|
+
|
|
17
|
+
from pulse.transpiler.js_module import register_js_module as _register_js_module
|
|
18
|
+
|
|
19
|
+
T = _TypeVar("T") # Values must be objects in JS, but we can't enforce that statically
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class WeakSet(_Generic[T]):
|
|
23
|
+
"""JavaScript WeakSet - a collection of objects with weak references.
|
|
24
|
+
|
|
25
|
+
WeakSet[T] holds weak references to values, allowing garbage collection.
|
|
26
|
+
Values must be objects (not primitives).
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(self, iterable: _Iterable[T] | None = None) -> None: ...
|
|
30
|
+
|
|
31
|
+
def add(self, value: T) -> "WeakSet[T]":
|
|
32
|
+
"""Add a value to the WeakSet. Returns the WeakSet for chaining."""
|
|
33
|
+
...
|
|
34
|
+
|
|
35
|
+
def delete(self, value: T) -> bool:
|
|
36
|
+
"""Remove a value. Returns True if the value existed."""
|
|
37
|
+
...
|
|
38
|
+
|
|
39
|
+
def has(self, value: T) -> bool:
|
|
40
|
+
"""Return True if the value exists in the WeakSet."""
|
|
41
|
+
...
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# Self-register this module as a JS builtin in global scope
|
|
45
|
+
_register_js_module(name="WeakSet", global_scope=True)
|