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.
- pulse/__init__.py +542 -562
- pulse/_examples.py +29 -0
- pulse/app.py +0 -14
- pulse/cli/cmd.py +96 -80
- pulse/cli/dependencies.py +10 -41
- pulse/cli/folder_lock.py +3 -3
- pulse/cli/helpers.py +40 -67
- pulse/cli/logging.py +102 -0
- pulse/cli/packages.py +16 -0
- pulse/cli/processes.py +40 -23
- pulse/codegen/codegen.py +70 -35
- pulse/codegen/js.py +2 -4
- pulse/codegen/templates/route.py +94 -146
- pulse/component.py +115 -0
- pulse/components/for_.py +1 -1
- pulse/components/if_.py +1 -1
- pulse/components/react_router.py +16 -22
- pulse/{html → dom}/events.py +1 -1
- pulse/{html → dom}/props.py +6 -6
- pulse/{html → dom}/tags.py +11 -11
- pulse/dom/tags.pyi +480 -0
- pulse/form.py +7 -6
- pulse/hooks/init.py +1 -13
- pulse/js/__init__.py +37 -41
- pulse/js/__init__.pyi +22 -2
- pulse/js/_types.py +5 -3
- pulse/js/array.py +121 -38
- pulse/js/console.py +9 -9
- pulse/js/date.py +22 -19
- pulse/js/document.py +8 -4
- pulse/js/error.py +12 -14
- pulse/js/json.py +4 -3
- pulse/js/map.py +17 -7
- pulse/js/math.py +2 -2
- pulse/js/navigator.py +4 -4
- pulse/js/number.py +8 -8
- pulse/js/object.py +9 -13
- pulse/js/promise.py +25 -9
- pulse/js/regexp.py +6 -6
- pulse/js/set.py +20 -8
- pulse/js/string.py +7 -7
- pulse/js/weakmap.py +6 -6
- pulse/js/weakset.py +6 -6
- pulse/js/window.py +17 -14
- pulse/messages.py +1 -4
- pulse/react_component.py +3 -999
- pulse/render_session.py +74 -66
- pulse/renderer.py +311 -238
- pulse/routing.py +1 -10
- pulse/serializer.py +11 -1
- pulse/transpiler/__init__.py +84 -114
- pulse/transpiler/builtins.py +661 -343
- pulse/transpiler/errors.py +78 -2
- pulse/transpiler/function.py +463 -133
- pulse/transpiler/id.py +18 -0
- pulse/transpiler/imports.py +230 -325
- pulse/transpiler/js_module.py +218 -209
- pulse/transpiler/modules/__init__.py +16 -13
- pulse/transpiler/modules/asyncio.py +45 -26
- pulse/transpiler/modules/json.py +12 -8
- pulse/transpiler/modules/math.py +161 -216
- pulse/transpiler/modules/pulse/__init__.py +5 -0
- pulse/transpiler/modules/pulse/tags.py +231 -0
- pulse/transpiler/modules/typing.py +33 -28
- pulse/transpiler/nodes.py +1607 -923
- pulse/transpiler/py_module.py +118 -95
- pulse/transpiler/react_component.py +51 -0
- pulse/transpiler/transpiler.py +593 -437
- pulse/transpiler/vdom.py +255 -0
- {pulse_framework-0.1.50.dist-info → pulse_framework-0.1.52.dist-info}/METADATA +1 -1
- pulse_framework-0.1.52.dist-info/RECORD +120 -0
- pulse/html/tags.pyi +0 -470
- pulse/transpiler/constants.py +0 -110
- pulse/transpiler/context.py +0 -26
- pulse/transpiler/ids.py +0 -16
- pulse/transpiler/modules/re.py +0 -466
- pulse/transpiler/modules/tags.py +0 -268
- pulse/transpiler/utils.py +0 -4
- pulse/vdom.py +0 -667
- pulse_framework-0.1.50.dist-info/RECORD +0 -119
- /pulse/{html → dom}/__init__.py +0 -0
- /pulse/{html → dom}/elements.py +0 -0
- /pulse/{html → dom}/svg.py +0 -0
- {pulse_framework-0.1.50.dist-info → pulse_framework-0.1.52.dist-info}/WHEEL +0 -0
- {pulse_framework-0.1.50.dist-info → pulse_framework-0.1.52.dist-info}/entry_points.txt +0 -0
pulse/js/json.py
CHANGED
|
@@ -15,7 +15,7 @@ from collections.abc import Callable as _Callable
|
|
|
15
15
|
from collections.abc import Sequence as _Sequence
|
|
16
16
|
from typing import TypeVar as _TypeVar
|
|
17
17
|
|
|
18
|
-
from pulse.transpiler.js_module import
|
|
18
|
+
from pulse.transpiler.js_module import JsModule
|
|
19
19
|
|
|
20
20
|
# JSON types
|
|
21
21
|
JSONValue = None | bool | int | float | str | list["JSONValue"] | dict[str, "JSONValue"]
|
|
@@ -25,7 +25,7 @@ JSONReviver = _Callable[[str, JSONValue], JSONValue]
|
|
|
25
25
|
T = _TypeVar("T")
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
def parse(text: str, reviver: JSONReviver | None = None) -> JSONValue:
|
|
28
|
+
def parse(text: str, reviver: JSONReviver | None = None, /) -> JSONValue:
|
|
29
29
|
"""Parse a JSON string into a JavaScript value.
|
|
30
30
|
|
|
31
31
|
Args:
|
|
@@ -43,6 +43,7 @@ def stringify(
|
|
|
43
43
|
value: JSONValue,
|
|
44
44
|
replacer: JSONReplacer | None = None,
|
|
45
45
|
space: int | str | None = None,
|
|
46
|
+
/,
|
|
46
47
|
) -> str:
|
|
47
48
|
"""Convert a JavaScript value to a JSON string.
|
|
48
49
|
|
|
@@ -59,4 +60,4 @@ def stringify(
|
|
|
59
60
|
|
|
60
61
|
|
|
61
62
|
# Self-register this module as a JS builtin
|
|
62
|
-
|
|
63
|
+
JsModule.register(name="JSON")
|
pulse/js/map.py
CHANGED
|
@@ -2,21 +2,22 @@
|
|
|
2
2
|
JavaScript Map builtin module.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
|
-
|
|
5
|
+
from pulse.js import Map
|
|
6
6
|
Map() # -> new Map()
|
|
7
7
|
Map([["a", 1]]) # -> new Map([["a", 1]])
|
|
8
8
|
|
|
9
|
+
# Or import from module directly:
|
|
9
10
|
from pulse.js.map import Map
|
|
10
|
-
Map() # -> new Map()
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
from collections.abc import Callable as _Callable
|
|
14
14
|
from collections.abc import Iterable as _Iterable
|
|
15
|
+
from collections.abc import Iterator as _Iterator
|
|
15
16
|
from typing import Any as _Any
|
|
16
17
|
from typing import Generic as _Generic
|
|
17
18
|
from typing import TypeVar as _TypeVar
|
|
18
19
|
|
|
19
|
-
from pulse.transpiler.js_module import
|
|
20
|
+
from pulse.transpiler.js_module import JsModule
|
|
20
21
|
|
|
21
22
|
K = _TypeVar("K")
|
|
22
23
|
V = _TypeVar("V")
|
|
@@ -28,7 +29,7 @@ class Map(_Generic[K, V]):
|
|
|
28
29
|
Map[K, V] preserves insertion order and allows keys of any type.
|
|
29
30
|
"""
|
|
30
31
|
|
|
31
|
-
def __init__(self, iterable: _Iterable[tuple[K, V]] | None = None) -> None: ...
|
|
32
|
+
def __init__(self, iterable: _Iterable[tuple[K, V]] | None = None, /) -> None: ...
|
|
32
33
|
|
|
33
34
|
@property
|
|
34
35
|
def size(self) -> int:
|
|
@@ -59,6 +60,7 @@ class Map(_Generic[K, V]):
|
|
|
59
60
|
self,
|
|
60
61
|
callback: _Callable[[V, K, "Map[K, V]"], None],
|
|
61
62
|
thisArg: _Any | None = None,
|
|
63
|
+
/,
|
|
62
64
|
) -> None:
|
|
63
65
|
"""Execute a function for each key/value pair."""
|
|
64
66
|
...
|
|
@@ -75,10 +77,18 @@ class Map(_Generic[K, V]):
|
|
|
75
77
|
"""Return an iterator of [key, value] pairs."""
|
|
76
78
|
...
|
|
77
79
|
|
|
78
|
-
def __iter__(self) ->
|
|
80
|
+
def __iter__(self) -> _Iterator[tuple[K, V]]:
|
|
79
81
|
"""Iterate over [key, value] pairs."""
|
|
80
82
|
...
|
|
81
83
|
|
|
84
|
+
def __len__(self) -> int:
|
|
85
|
+
"""Return the number of key/value pairs (same as size)."""
|
|
86
|
+
...
|
|
87
|
+
|
|
88
|
+
def __contains__(self, key: K) -> bool:
|
|
89
|
+
"""Check if key exists in the Map (same as has)."""
|
|
90
|
+
...
|
|
91
|
+
|
|
82
92
|
|
|
83
|
-
# Self-register this module as a JS builtin
|
|
84
|
-
|
|
93
|
+
# Self-register this module as a JS builtin (global identifiers)
|
|
94
|
+
JsModule.register(name=None)
|
pulse/js/math.py
CHANGED
|
@@ -11,7 +11,7 @@ Usage:
|
|
|
11
11
|
floor(3.7) # -> Math.floor(3.7)
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
-
from pulse.transpiler.js_module import
|
|
14
|
+
from pulse.transpiler.js_module import JsModule
|
|
15
15
|
|
|
16
16
|
# Constants (type stubs for IDE support)
|
|
17
17
|
PI: float
|
|
@@ -63,4 +63,4 @@ def trunc(x: float) -> int: ...
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
# Self-register this module as a JS builtin
|
|
66
|
-
|
|
66
|
+
JsModule.register(name="Math")
|
pulse/js/navigator.py
CHANGED
|
@@ -8,7 +8,7 @@ Usage:
|
|
|
8
8
|
from typing import Any as _Any
|
|
9
9
|
|
|
10
10
|
from pulse.js._types import Clipboard as _Clipboard
|
|
11
|
-
from pulse.transpiler.js_module import
|
|
11
|
+
from pulse.transpiler.js_module import JsModule
|
|
12
12
|
|
|
13
13
|
# User agent and browser info
|
|
14
14
|
userAgent: str
|
|
@@ -63,14 +63,14 @@ def share(data: dict[str, str]) -> _Any:
|
|
|
63
63
|
...
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
def sendBeacon(url: str, data: str | bytes | _Any | None = None) -> bool:
|
|
66
|
+
def sendBeacon(url: str, data: str | bytes | _Any | None = None, /) -> bool:
|
|
67
67
|
"""Send data to a URL asynchronously. Returns True if successful."""
|
|
68
68
|
...
|
|
69
69
|
|
|
70
70
|
|
|
71
|
-
def canShare(data: dict[str, str] | None = None) -> bool:
|
|
71
|
+
def canShare(data: dict[str, str] | None = None, /) -> bool:
|
|
72
72
|
"""Check if data can be shared via the Web Share API."""
|
|
73
73
|
...
|
|
74
74
|
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
JsModule.register(name="navigator")
|
pulse/js/number.py
CHANGED
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
JavaScript Number builtin module.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
|
-
|
|
5
|
+
from pulse.js import Number
|
|
6
6
|
Number.isFinite(42) # -> Number.isFinite(42)
|
|
7
7
|
Number.MAX_SAFE_INTEGER # -> Number.MAX_SAFE_INTEGER
|
|
8
|
+
Number(x) # -> new Number(x)
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
EPSILON # -> Number.EPSILON
|
|
10
|
+
# Or import from module directly:
|
|
11
|
+
from pulse.js.number import Number
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
14
|
from typing import Any as _Any
|
|
15
15
|
from typing import ClassVar as _ClassVar
|
|
16
16
|
|
|
17
|
-
from pulse.transpiler.js_module import
|
|
17
|
+
from pulse.transpiler.js_module import JsModule
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class Number:
|
|
@@ -47,8 +47,8 @@ class Number:
|
|
|
47
47
|
def parseFloat(string: str) -> float: ...
|
|
48
48
|
|
|
49
49
|
@staticmethod
|
|
50
|
-
def parseInt(string: str, radix: int = 10) -> int: ...
|
|
50
|
+
def parseInt(string: str, radix: int = 10, /) -> int: ...
|
|
51
51
|
|
|
52
52
|
|
|
53
|
-
# Self-register this module as a JS builtin
|
|
54
|
-
|
|
53
|
+
# Self-register this module as a JS builtin (global identifier)
|
|
54
|
+
JsModule.register(name=None)
|
pulse/js/object.py
CHANGED
|
@@ -2,18 +2,13 @@
|
|
|
2
2
|
JavaScript Object builtin module.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
|
-
|
|
5
|
+
from pulse.js import Object
|
|
6
6
|
Object.keys({"a": 1}) # -> Object.keys({"a": 1})
|
|
7
7
|
Object.assign({}, {"a": 1}) # -> Object.assign({}, {"a": 1})
|
|
8
|
-
Object.
|
|
9
|
-
|
|
10
|
-
#
|
|
11
|
-
|
|
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)
|
|
8
|
+
Object.is_(x, y) # -> Object.is(x, y)
|
|
9
|
+
|
|
10
|
+
# Or import from module directly:
|
|
11
|
+
from pulse.js.object import Object
|
|
17
12
|
"""
|
|
18
13
|
|
|
19
14
|
from collections.abc import Iterable as _Iterable
|
|
@@ -21,7 +16,7 @@ from typing import Any as _Any
|
|
|
21
16
|
from typing import TypedDict as _TypedDict
|
|
22
17
|
from typing import TypeVar as _TypeVar
|
|
23
18
|
|
|
24
|
-
from pulse.transpiler.js_module import
|
|
19
|
+
from pulse.transpiler.js_module import JsModule
|
|
25
20
|
|
|
26
21
|
T = _TypeVar("T")
|
|
27
22
|
K = _TypeVar("K", bound=str) # Object keys are always strings in JS
|
|
@@ -55,6 +50,7 @@ class Object:
|
|
|
55
50
|
def create(
|
|
56
51
|
proto: _Any | None,
|
|
57
52
|
propertiesObject: dict[str, PropertyDescriptor] | None = None,
|
|
53
|
+
/,
|
|
58
54
|
) -> _Any:
|
|
59
55
|
"""Create a new object with the specified prototype."""
|
|
60
56
|
...
|
|
@@ -169,5 +165,5 @@ class Object:
|
|
|
169
165
|
...
|
|
170
166
|
|
|
171
167
|
|
|
172
|
-
# Self-register this module as a JS builtin
|
|
173
|
-
|
|
168
|
+
# Self-register this module as a JS builtin (global identifier)
|
|
169
|
+
JsModule.register(name=None)
|
pulse/js/promise.py
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
JavaScript Promise builtin module.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
|
-
|
|
5
|
+
from pulse.js import Promise
|
|
6
|
+
Promise(executor) # -> new Promise(executor)
|
|
6
7
|
Promise.resolve(value) # -> Promise.resolve(value)
|
|
7
8
|
Promise.reject(reason) # -> Promise.reject(reason)
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
reject(reason) # -> Promise.reject(reason)
|
|
10
|
+
# Or import from module directly:
|
|
11
|
+
from pulse.js.promise import Promise
|
|
12
12
|
|
|
13
13
|
The Promise class is generic and supports async/await via the Awaitable protocol.
|
|
14
14
|
"""
|
|
@@ -16,10 +16,12 @@ The Promise class is generic and supports async/await via the Awaitable protocol
|
|
|
16
16
|
from collections.abc import Callable as _Callable
|
|
17
17
|
from collections.abc import Generator as _Generator
|
|
18
18
|
from collections.abc import Iterable as _Iterable
|
|
19
|
+
from typing import Any as _Any
|
|
19
20
|
from typing import Generic as _Generic
|
|
20
21
|
from typing import TypeVar as _TypeVar
|
|
22
|
+
from typing import overload as _overload
|
|
21
23
|
|
|
22
|
-
from pulse.transpiler.js_module import
|
|
24
|
+
from pulse.transpiler.js_module import JsModule
|
|
23
25
|
|
|
24
26
|
T = _TypeVar("T")
|
|
25
27
|
T_co = _TypeVar("T_co", covariant=True)
|
|
@@ -52,6 +54,7 @@ class Promise(_Generic[T_co]):
|
|
|
52
54
|
[_Callable[[T_co], None], _Callable[[Exception], None]], None
|
|
53
55
|
]
|
|
54
56
|
| None = None,
|
|
57
|
+
/,
|
|
55
58
|
) -> None:
|
|
56
59
|
"""Create a Promise.
|
|
57
60
|
|
|
@@ -65,6 +68,7 @@ class Promise(_Generic[T_co]):
|
|
|
65
68
|
self,
|
|
66
69
|
on_fulfilled: _Callable[[T_co], U | "Promise[U]"] | None = None,
|
|
67
70
|
on_rejected: _Callable[[Exception], U | "Promise[U]"] | None = None,
|
|
71
|
+
/,
|
|
68
72
|
) -> "Promise[U]":
|
|
69
73
|
"""Attach callbacks to handle fulfillment and/or rejection."""
|
|
70
74
|
...
|
|
@@ -85,12 +89,24 @@ class Promise(_Generic[T_co]):
|
|
|
85
89
|
|
|
86
90
|
# Static methods for Promise construction
|
|
87
91
|
@staticmethod
|
|
88
|
-
|
|
92
|
+
@_overload
|
|
93
|
+
def resolve() -> "Promise[None]":
|
|
94
|
+
"""Create a Promise that resolves with None."""
|
|
95
|
+
...
|
|
96
|
+
|
|
97
|
+
@staticmethod
|
|
98
|
+
@_overload
|
|
99
|
+
def resolve(value: U, /) -> "Promise[U]":
|
|
100
|
+
"""Create a Promise that resolves with the given value."""
|
|
101
|
+
...
|
|
102
|
+
|
|
103
|
+
@staticmethod
|
|
104
|
+
def resolve(value: U | None = None, /) -> "Promise[U] | Promise[None]":
|
|
89
105
|
"""Create a Promise that resolves with the given value."""
|
|
90
106
|
...
|
|
91
107
|
|
|
92
108
|
@staticmethod
|
|
93
|
-
def reject(reason: Exception | str) -> "Promise[
|
|
109
|
+
def reject(reason: Exception | str) -> "Promise[_Any]":
|
|
94
110
|
"""Create a Promise that rejects with the given reason."""
|
|
95
111
|
...
|
|
96
112
|
|
|
@@ -146,5 +162,5 @@ class PromiseWithResolvers(_Generic[T]):
|
|
|
146
162
|
def reject(self) -> _Callable[[Exception | str], None]: ...
|
|
147
163
|
|
|
148
164
|
|
|
149
|
-
# Self-register this module as a JS builtin
|
|
150
|
-
|
|
165
|
+
# Self-register this module as a JS builtin (global identifier)
|
|
166
|
+
JsModule.register(name=None)
|
pulse/js/regexp.py
CHANGED
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
JavaScript RegExp builtin module.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
|
-
|
|
5
|
+
from pulse.js import RegExp
|
|
6
6
|
RegExp(pattern, flags) # -> new RegExp(pattern, flags)
|
|
7
7
|
|
|
8
|
+
# Or import from module directly:
|
|
8
9
|
from pulse.js.regexp import RegExp
|
|
9
|
-
RegExp(pattern, flags) # -> new RegExp(pattern, flags)
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
|
-
from pulse.transpiler.js_module import
|
|
12
|
+
from pulse.transpiler.js_module import JsModule
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class RegExp:
|
|
16
16
|
"""Class for JavaScript RegExp instances."""
|
|
17
17
|
|
|
18
|
-
def __init__(self, pattern: str, flags: str | None = None): ...
|
|
18
|
+
def __init__(self, pattern: str, flags: str | None = None, /): ...
|
|
19
19
|
|
|
20
20
|
def exec(self, string: str) -> list[str] | None: ...
|
|
21
21
|
def test(self, string: str) -> bool: ...
|
|
@@ -50,5 +50,5 @@ class RegExp:
|
|
|
50
50
|
def toString(self) -> str: ...
|
|
51
51
|
|
|
52
52
|
|
|
53
|
-
# Self-register this module as a JS builtin
|
|
54
|
-
|
|
53
|
+
# Self-register this module as a JS builtin (global identifiers)
|
|
54
|
+
JsModule.register(name=None)
|
pulse/js/set.py
CHANGED
|
@@ -2,21 +2,22 @@
|
|
|
2
2
|
JavaScript Set builtin module.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
|
-
|
|
5
|
+
from pulse.js import Set
|
|
6
6
|
Set() # -> new Set()
|
|
7
7
|
Set([1, 2, 3]) # -> new Set([1, 2, 3])
|
|
8
8
|
|
|
9
|
+
# Or import from module directly:
|
|
9
10
|
from pulse.js.set import Set
|
|
10
|
-
Set() # -> new Set()
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
from collections.abc import Callable as _Callable
|
|
14
14
|
from collections.abc import Iterable as _Iterable
|
|
15
|
+
from collections.abc import Iterator as _Iterator
|
|
15
16
|
from typing import Any as _Any
|
|
16
17
|
from typing import Generic as _Generic
|
|
17
18
|
from typing import TypeVar as _TypeVar
|
|
18
19
|
|
|
19
|
-
from pulse.transpiler.js_module import
|
|
20
|
+
from pulse.transpiler.js_module import JsModule
|
|
20
21
|
|
|
21
22
|
T = _TypeVar("T")
|
|
22
23
|
|
|
@@ -27,7 +28,7 @@ class Set(_Generic[T]):
|
|
|
27
28
|
Set[T] stores unique values of type T in insertion order.
|
|
28
29
|
"""
|
|
29
30
|
|
|
30
|
-
def __init__(self, iterable: _Iterable[T] | None = None) -> None: ...
|
|
31
|
+
def __init__(self, iterable: _Iterable[T] | None = None, /) -> None: ...
|
|
31
32
|
|
|
32
33
|
@property
|
|
33
34
|
def size(self) -> int:
|
|
@@ -51,7 +52,10 @@ class Set(_Generic[T]):
|
|
|
51
52
|
...
|
|
52
53
|
|
|
53
54
|
def forEach(
|
|
54
|
-
self,
|
|
55
|
+
self,
|
|
56
|
+
callback: _Callable[[T, T, "Set[T]"], None],
|
|
57
|
+
thisArg: _Any | None = None,
|
|
58
|
+
/,
|
|
55
59
|
) -> None:
|
|
56
60
|
"""Execute a function for each value.
|
|
57
61
|
|
|
@@ -71,10 +75,18 @@ class Set(_Generic[T]):
|
|
|
71
75
|
"""Return an iterator of [value, value] pairs."""
|
|
72
76
|
...
|
|
73
77
|
|
|
74
|
-
def __iter__(self) ->
|
|
78
|
+
def __iter__(self) -> _Iterator[T]:
|
|
75
79
|
"""Iterate over values."""
|
|
76
80
|
...
|
|
77
81
|
|
|
82
|
+
def __len__(self) -> int:
|
|
83
|
+
"""Return the number of values (same as size)."""
|
|
84
|
+
...
|
|
85
|
+
|
|
86
|
+
def __contains__(self, value: T) -> bool:
|
|
87
|
+
"""Check if value exists in the Set (same as has)."""
|
|
88
|
+
...
|
|
89
|
+
|
|
78
90
|
# ES2024 Set methods
|
|
79
91
|
def union(self, other: "Set[T]") -> "Set[T]":
|
|
80
92
|
"""Return a new Set with values from both sets (ES2024)."""
|
|
@@ -105,5 +117,5 @@ class Set(_Generic[T]):
|
|
|
105
117
|
...
|
|
106
118
|
|
|
107
119
|
|
|
108
|
-
# Self-register this module as a JS builtin
|
|
109
|
-
|
|
120
|
+
# Self-register this module as a JS builtin (global identifiers)
|
|
121
|
+
JsModule.register(name=None)
|
pulse/js/string.py
CHANGED
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
JavaScript String builtin module.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
|
-
|
|
5
|
+
from pulse.js import String
|
|
6
|
+
String(x) # -> new String(x)
|
|
6
7
|
String.fromCharCode(65) # -> String.fromCharCode(65)
|
|
7
8
|
String.fromCodePoint(0x1F600) # -> String.fromCodePoint(0x1F600)
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
fromCodePoint(0x1F600) # -> String.fromCodePoint(0x1F600)
|
|
10
|
+
# Or import from module directly:
|
|
11
|
+
from pulse.js.string import String
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
14
|
from typing import Any as _Any
|
|
15
15
|
|
|
16
|
-
from pulse.transpiler.js_module import
|
|
16
|
+
from pulse.transpiler.js_module import JsModule
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class String:
|
|
@@ -31,5 +31,5 @@ class String:
|
|
|
31
31
|
def raw(template: str, *substitutions: str) -> str: ...
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
# Self-register this module as a JS builtin
|
|
35
|
-
|
|
34
|
+
# Self-register this module as a JS builtin (global identifier)
|
|
35
|
+
JsModule.register(name=None)
|
pulse/js/weakmap.py
CHANGED
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
JavaScript WeakMap builtin module.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
|
-
|
|
5
|
+
from pulse.js import WeakMap
|
|
6
6
|
WeakMap() # -> new WeakMap()
|
|
7
7
|
WeakMap([[obj, "value"]]) # -> new WeakMap([[obj, "value"]])
|
|
8
8
|
|
|
9
|
+
# Or import from module directly:
|
|
9
10
|
from pulse.js.weakmap import WeakMap
|
|
10
|
-
WeakMap() # -> new WeakMap()
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
from collections.abc import Iterable as _Iterable
|
|
14
14
|
from typing import Generic as _Generic
|
|
15
15
|
from typing import TypeVar as _TypeVar
|
|
16
16
|
|
|
17
|
-
from pulse.transpiler.js_module import
|
|
17
|
+
from pulse.transpiler.js_module import JsModule
|
|
18
18
|
|
|
19
19
|
K = _TypeVar("K") # Keys must be objects in JS, but we can't enforce that statically
|
|
20
20
|
V = _TypeVar("V")
|
|
@@ -27,7 +27,7 @@ class WeakMap(_Generic[K, V]):
|
|
|
27
27
|
Keys must be objects (not primitives).
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
|
-
def __init__(self, iterable: _Iterable[tuple[K, V]] | None = None) -> None: ...
|
|
30
|
+
def __init__(self, iterable: _Iterable[tuple[K, V]] | None = None, /) -> None: ...
|
|
31
31
|
|
|
32
32
|
def delete(self, key: K) -> bool:
|
|
33
33
|
"""Remove a key and its value. Returns True if the key existed."""
|
|
@@ -46,5 +46,5 @@ class WeakMap(_Generic[K, V]):
|
|
|
46
46
|
...
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
# Self-register this module as a JS builtin
|
|
50
|
-
|
|
49
|
+
# Self-register this module as a JS builtin (global identifiers)
|
|
50
|
+
JsModule.register(name=None)
|
pulse/js/weakset.py
CHANGED
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
JavaScript WeakSet builtin module.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
|
-
|
|
5
|
+
from pulse.js import WeakSet
|
|
6
6
|
WeakSet() # -> new WeakSet()
|
|
7
7
|
WeakSet([obj1, obj2]) # -> new WeakSet([obj1, obj2])
|
|
8
8
|
|
|
9
|
+
# Or import from module directly:
|
|
9
10
|
from pulse.js.weakset import WeakSet
|
|
10
|
-
WeakSet() # -> new WeakSet()
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
from collections.abc import Iterable as _Iterable
|
|
14
14
|
from typing import Generic as _Generic
|
|
15
15
|
from typing import TypeVar as _TypeVar
|
|
16
16
|
|
|
17
|
-
from pulse.transpiler.js_module import
|
|
17
|
+
from pulse.transpiler.js_module import JsModule
|
|
18
18
|
|
|
19
19
|
T = _TypeVar("T") # Values must be objects in JS, but we can't enforce that statically
|
|
20
20
|
|
|
@@ -26,7 +26,7 @@ class WeakSet(_Generic[T]):
|
|
|
26
26
|
Values must be objects (not primitives).
|
|
27
27
|
"""
|
|
28
28
|
|
|
29
|
-
def __init__(self, iterable: _Iterable[T] | None = None) -> None: ...
|
|
29
|
+
def __init__(self, iterable: _Iterable[T] | None = None, /) -> None: ...
|
|
30
30
|
|
|
31
31
|
def add(self, value: T) -> "WeakSet[T]":
|
|
32
32
|
"""Add a value to the WeakSet. Returns the WeakSet for chaining."""
|
|
@@ -41,5 +41,5 @@ class WeakSet(_Generic[T]):
|
|
|
41
41
|
...
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
# Self-register this module as a JS builtin
|
|
45
|
-
|
|
44
|
+
# Self-register this module as a JS builtin (global identifiers)
|
|
45
|
+
JsModule.register(name=None)
|
pulse/js/window.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Browser window global
|
|
1
|
+
"""Browser window global object.
|
|
2
2
|
|
|
3
3
|
Usage:
|
|
4
4
|
from pulse.js import window
|
|
@@ -11,7 +11,7 @@ from typing import Any as _Any
|
|
|
11
11
|
|
|
12
12
|
from pulse.js._types import Element as _Element
|
|
13
13
|
from pulse.js._types import Selection as _Selection
|
|
14
|
-
from pulse.transpiler.js_module import
|
|
14
|
+
from pulse.transpiler.js_module import JsModule
|
|
15
15
|
|
|
16
16
|
# Dimensions
|
|
17
17
|
innerWidth: int
|
|
@@ -43,33 +43,33 @@ performance: _Any
|
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
# Dialog methods
|
|
46
|
-
def alert(message: str = "") -> None:
|
|
46
|
+
def alert(message: str = "", /) -> None:
|
|
47
47
|
"""Display an alert dialog with the given message."""
|
|
48
48
|
...
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
def confirm(message: str = "") -> bool:
|
|
51
|
+
def confirm(message: str = "", /) -> bool:
|
|
52
52
|
"""Display a confirmation dialog. Returns True if user clicks OK."""
|
|
53
53
|
...
|
|
54
54
|
|
|
55
55
|
|
|
56
|
-
def prompt(message: str = "", default: str = "") -> str | None:
|
|
56
|
+
def prompt(message: str = "", default: str = "", /) -> str | None:
|
|
57
57
|
"""Display a prompt dialog. Returns input or None if cancelled."""
|
|
58
58
|
...
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
# Scroll methods
|
|
62
|
-
def scrollTo(x: float | dict[str, float], y: float | None = None) -> None:
|
|
62
|
+
def scrollTo(x: float | dict[str, float], y: float | None = None, /) -> None:
|
|
63
63
|
"""Scroll to the given position."""
|
|
64
64
|
...
|
|
65
65
|
|
|
66
66
|
|
|
67
|
-
def scrollBy(x: float | dict[str, float], y: float | None = None) -> None:
|
|
67
|
+
def scrollBy(x: float | dict[str, float], y: float | None = None, /) -> None:
|
|
68
68
|
"""Scroll by the given amount."""
|
|
69
69
|
...
|
|
70
70
|
|
|
71
71
|
|
|
72
|
-
def scroll(x: float | dict[str, float], y: float | None = None) -> None:
|
|
72
|
+
def scroll(x: float | dict[str, float], y: float | None = None, /) -> None:
|
|
73
73
|
"""Alias for scrollTo."""
|
|
74
74
|
...
|
|
75
75
|
|
|
@@ -80,7 +80,7 @@ def getSelection() -> _Selection | None:
|
|
|
80
80
|
...
|
|
81
81
|
|
|
82
82
|
|
|
83
|
-
def getComputedStyle(element: _Element, pseudoElt: str | None = None) -> _Any:
|
|
83
|
+
def getComputedStyle(element: _Element, pseudoElt: str | None = None, /) -> _Any:
|
|
84
84
|
"""Return the computed style of an element."""
|
|
85
85
|
...
|
|
86
86
|
|
|
@@ -101,8 +101,9 @@ def open(
|
|
|
101
101
|
url: str = "",
|
|
102
102
|
target: str = "_blank",
|
|
103
103
|
features: str = "",
|
|
104
|
+
/,
|
|
104
105
|
) -> _Any | None:
|
|
105
|
-
"""Open a new window. Returns the new window
|
|
106
|
+
"""Open a new window. Returns the new window object or None."""
|
|
106
107
|
...
|
|
107
108
|
|
|
108
109
|
|
|
@@ -112,7 +113,7 @@ def close() -> None:
|
|
|
112
113
|
|
|
113
114
|
|
|
114
115
|
# Timers (these return timer IDs)
|
|
115
|
-
def setTimeout(handler: _Callable[..., None], timeout: int = 0, *args: _Any) -> int:
|
|
116
|
+
def setTimeout(handler: _Callable[..., None], timeout: int = 0, /, *args: _Any) -> int:
|
|
116
117
|
"""Schedule a function to run after a delay. Returns timer ID."""
|
|
117
118
|
...
|
|
118
119
|
|
|
@@ -122,7 +123,7 @@ def clearTimeout(timeoutId: int) -> None:
|
|
|
122
123
|
...
|
|
123
124
|
|
|
124
125
|
|
|
125
|
-
def setInterval(handler: _Callable[..., None], timeout: int = 0, *args: _Any) -> int:
|
|
126
|
+
def setInterval(handler: _Callable[..., None], timeout: int = 0, /, *args: _Any) -> int:
|
|
126
127
|
"""Schedule a function to run repeatedly. Returns timer ID."""
|
|
127
128
|
...
|
|
128
129
|
|
|
@@ -148,6 +149,7 @@ def addEventListener(
|
|
|
148
149
|
type: str,
|
|
149
150
|
listener: _Callable[..., None],
|
|
150
151
|
options: bool | dict[str, bool] | None = None,
|
|
152
|
+
/,
|
|
151
153
|
) -> None:
|
|
152
154
|
"""Add an event listener to the window."""
|
|
153
155
|
...
|
|
@@ -157,6 +159,7 @@ def removeEventListener(
|
|
|
157
159
|
type: str,
|
|
158
160
|
listener: _Callable[..., None],
|
|
159
161
|
options: bool | dict[str, bool] | None = None,
|
|
162
|
+
/,
|
|
160
163
|
) -> None:
|
|
161
164
|
"""Remove an event listener from the window."""
|
|
162
165
|
...
|
|
@@ -190,10 +193,10 @@ def print_() -> None:
|
|
|
190
193
|
|
|
191
194
|
|
|
192
195
|
def postMessage(
|
|
193
|
-
message: _Any, targetOrigin: str, transfer: list[_Any] | None = None
|
|
196
|
+
message: _Any, targetOrigin: str, transfer: list[_Any] | None = None, /
|
|
194
197
|
) -> None:
|
|
195
198
|
"""Post a message to another window."""
|
|
196
199
|
...
|
|
197
200
|
|
|
198
201
|
|
|
199
|
-
|
|
202
|
+
JsModule.register(name="window")
|
pulse/messages.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Any, Literal, NotRequired, TypedDict
|
|
2
2
|
|
|
3
3
|
from pulse.routing import RouteInfo
|
|
4
|
-
from pulse.vdom import VDOM, VDOMOperation
|
|
4
|
+
from pulse.transpiler.vdom import VDOM, VDOMOperation
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
# ====================
|
|
@@ -11,9 +11,6 @@ class ServerInitMessage(TypedDict):
|
|
|
11
11
|
type: Literal["vdom_init"]
|
|
12
12
|
path: str
|
|
13
13
|
vdom: VDOM
|
|
14
|
-
callbacks: list[str]
|
|
15
|
-
render_props: list[str]
|
|
16
|
-
jsexpr_paths: list[str] # paths containing JS expressions
|
|
17
14
|
|
|
18
15
|
|
|
19
16
|
class ServerUpdateMessage(TypedDict):
|