pulse-framework 0.1.55__py3-none-any.whl → 0.1.57__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 +5 -6
- pulse/app.py +144 -57
- pulse/channel.py +139 -7
- pulse/cli/cmd.py +16 -2
- pulse/codegen/codegen.py +43 -12
- pulse/component.py +104 -0
- pulse/components/for_.py +30 -4
- pulse/components/if_.py +28 -5
- pulse/components/react_router.py +61 -3
- pulse/context.py +39 -5
- pulse/cookies.py +108 -4
- pulse/decorators.py +193 -24
- pulse/env.py +56 -2
- pulse/form.py +198 -5
- pulse/helpers.py +7 -1
- pulse/hooks/core.py +135 -5
- pulse/hooks/effects.py +61 -77
- pulse/hooks/init.py +60 -1
- pulse/hooks/runtime.py +241 -0
- pulse/hooks/setup.py +77 -0
- pulse/hooks/stable.py +58 -1
- pulse/hooks/state.py +107 -20
- pulse/js/__init__.py +40 -24
- pulse/js/array.py +9 -6
- pulse/js/console.py +15 -12
- pulse/js/date.py +9 -6
- pulse/js/document.py +5 -2
- pulse/js/error.py +7 -4
- pulse/js/json.py +9 -6
- pulse/js/map.py +8 -5
- pulse/js/math.py +9 -6
- pulse/js/navigator.py +5 -2
- pulse/js/number.py +9 -6
- pulse/js/obj.py +16 -13
- pulse/js/object.py +9 -6
- pulse/js/promise.py +19 -13
- pulse/js/pulse.py +28 -25
- pulse/js/react.py +94 -55
- pulse/js/regexp.py +7 -4
- pulse/js/set.py +8 -5
- pulse/js/string.py +9 -6
- pulse/js/weakmap.py +8 -5
- pulse/js/weakset.py +8 -5
- pulse/js/window.py +6 -3
- pulse/messages.py +5 -0
- pulse/middleware.py +147 -76
- pulse/plugin.py +76 -5
- pulse/queries/client.py +186 -39
- pulse/queries/common.py +52 -3
- pulse/queries/infinite_query.py +154 -2
- pulse/queries/mutation.py +127 -7
- pulse/queries/query.py +112 -11
- pulse/react_component.py +66 -3
- pulse/reactive.py +314 -30
- pulse/reactive_extensions.py +106 -26
- pulse/render_session.py +304 -173
- pulse/request.py +46 -11
- pulse/routing.py +140 -4
- pulse/serializer.py +71 -0
- pulse/state.py +177 -9
- pulse/test_helpers.py +15 -0
- pulse/transpiler/__init__.py +0 -3
- pulse/transpiler/py_module.py +1 -7
- pulse/user_session.py +119 -18
- {pulse_framework-0.1.55.dist-info → pulse_framework-0.1.57.dist-info}/METADATA +5 -5
- pulse_framework-0.1.57.dist-info/RECORD +127 -0
- pulse/transpiler/react_component.py +0 -44
- pulse_framework-0.1.55.dist-info/RECORD +0 -127
- {pulse_framework-0.1.55.dist-info → pulse_framework-0.1.57.dist-info}/WHEEL +0 -0
- {pulse_framework-0.1.55.dist-info → pulse_framework-0.1.57.dist-info}/entry_points.txt +0 -0
pulse/js/react.py
CHANGED
|
@@ -2,14 +2,17 @@
|
|
|
2
2
|
JavaScript React module.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
|
|
6
|
+
```python
|
|
7
|
+
from pulse.js.react import useState, useEffect, useRef
|
|
8
|
+
state, setState = useState(0) # -> const [state, setState] = useState(0)
|
|
9
|
+
useEffect(lambda: print("hi"), []) # -> useEffect(() => console.log("hi"), [])
|
|
10
|
+
ref = useRef(None) # -> const ref = useRef(null)
|
|
11
|
+
|
|
12
|
+
# Also available as namespace:
|
|
13
|
+
import pulse.js.react as React
|
|
14
|
+
React.useState(0) # -> React.useState(0)
|
|
15
|
+
```
|
|
13
16
|
"""
|
|
14
17
|
|
|
15
18
|
import ast as _ast
|
|
@@ -116,9 +119,12 @@ def useState(
|
|
|
116
119
|
"""Returns a stateful value and a function to update it.
|
|
117
120
|
|
|
118
121
|
Example:
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
count, set_count = useState(0)
|
|
125
|
+
set_count(count + 1)
|
|
126
|
+
set_count(lambda prev: prev + 1)
|
|
127
|
+
```
|
|
122
128
|
"""
|
|
123
129
|
...
|
|
124
130
|
|
|
@@ -128,16 +134,19 @@ def useReducer(
|
|
|
128
134
|
initial_arg: S,
|
|
129
135
|
init: _Callable[[S], S] | None = None,
|
|
130
136
|
) -> tuple[S, Dispatch[A]]:
|
|
131
|
-
"""An alternative to useState for complex state logic.
|
|
137
|
+
"""An alternative to `useState` for complex state logic.
|
|
132
138
|
|
|
133
139
|
Example:
|
|
134
|
-
def reducer(state, action):
|
|
135
|
-
if action['type'] == 'increment':
|
|
136
|
-
return {'count': state['count'] + 1}
|
|
137
|
-
return state
|
|
138
140
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
+
```python
|
|
142
|
+
def reducer(state, action):
|
|
143
|
+
if action['type'] == 'increment':
|
|
144
|
+
return {'count': state['count'] + 1}
|
|
145
|
+
return state
|
|
146
|
+
|
|
147
|
+
state, dispatch = useReducer(reducer, {'count': 0})
|
|
148
|
+
dispatch({'type': 'increment'})
|
|
149
|
+
```
|
|
141
150
|
"""
|
|
142
151
|
...
|
|
143
152
|
|
|
@@ -154,8 +163,11 @@ def useEffect(
|
|
|
154
163
|
"""Accepts a function that contains imperative, possibly effectful code.
|
|
155
164
|
|
|
156
165
|
Example:
|
|
157
|
-
|
|
158
|
-
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
useEffect(lambda: print("mounted"), [])
|
|
169
|
+
useEffect(lambda: (print("update"), lambda: print("cleanup"))[-1], [dep])
|
|
170
|
+
```
|
|
159
171
|
"""
|
|
160
172
|
...
|
|
161
173
|
|
|
@@ -164,10 +176,13 @@ def useLayoutEffect(
|
|
|
164
176
|
effect: _Callable[[], None | _Callable[[], None]],
|
|
165
177
|
deps: list[_Any] | None = None,
|
|
166
178
|
) -> None:
|
|
167
|
-
"""Like useEffect
|
|
179
|
+
"""Like `useEffect`, but fires synchronously after all DOM mutations.
|
|
168
180
|
|
|
169
181
|
Example:
|
|
170
|
-
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
useLayoutEffect(lambda: measure_element(), [])
|
|
185
|
+
```
|
|
171
186
|
"""
|
|
172
187
|
...
|
|
173
188
|
|
|
@@ -191,9 +206,12 @@ def useRef(initial_value: T) -> MutableRefObject[T]:
|
|
|
191
206
|
"""Returns a mutable ref object.
|
|
192
207
|
|
|
193
208
|
Example:
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
input_ref = useRef(None)
|
|
212
|
+
# In JSX: <input ref={input_ref} />
|
|
213
|
+
input_ref.current.focus()
|
|
214
|
+
```
|
|
197
215
|
"""
|
|
198
216
|
...
|
|
199
217
|
|
|
@@ -216,7 +234,10 @@ def useMemo(factory: _Callable[[], T], deps: list[_Any]) -> T:
|
|
|
216
234
|
"""Returns a memoized value.
|
|
217
235
|
|
|
218
236
|
Example:
|
|
219
|
-
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
expensive = useMemo(lambda: compute_expensive(a, b), [a, b])
|
|
240
|
+
```
|
|
220
241
|
"""
|
|
221
242
|
...
|
|
222
243
|
|
|
@@ -225,7 +246,10 @@ def useCallback(callback: T, deps: list[_Any]) -> T:
|
|
|
225
246
|
"""Returns a memoized callback.
|
|
226
247
|
|
|
227
248
|
Example:
|
|
228
|
-
|
|
249
|
+
|
|
250
|
+
```python
|
|
251
|
+
handle_click = useCallback(lambda e: print(e), [])
|
|
252
|
+
```
|
|
229
253
|
"""
|
|
230
254
|
...
|
|
231
255
|
|
|
@@ -239,8 +263,11 @@ def useTransition() -> tuple[bool, TransitionStartFunction]:
|
|
|
239
263
|
"""Returns a stateful value for pending state and a function to start transition.
|
|
240
264
|
|
|
241
265
|
Example:
|
|
242
|
-
|
|
243
|
-
|
|
266
|
+
|
|
267
|
+
```python
|
|
268
|
+
is_pending, start_transition = useTransition()
|
|
269
|
+
start_transition(lambda: set_state(new_value))
|
|
270
|
+
```
|
|
244
271
|
"""
|
|
245
272
|
...
|
|
246
273
|
|
|
@@ -254,7 +281,10 @@ def useContext(context: Context[T]) -> T:
|
|
|
254
281
|
"""Returns the current context value for the given context.
|
|
255
282
|
|
|
256
283
|
Example:
|
|
257
|
-
|
|
284
|
+
|
|
285
|
+
```python
|
|
286
|
+
theme = useContext(ThemeContext)
|
|
287
|
+
```
|
|
258
288
|
"""
|
|
259
289
|
...
|
|
260
290
|
|
|
@@ -268,9 +298,12 @@ def useId() -> str:
|
|
|
268
298
|
"""Generates a unique ID that is stable across server and client.
|
|
269
299
|
|
|
270
300
|
Example:
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
301
|
+
|
|
302
|
+
```python
|
|
303
|
+
id = useId()
|
|
304
|
+
# <label htmlFor={id}>Name</label>
|
|
305
|
+
# <input id={id} />
|
|
306
|
+
```
|
|
274
307
|
"""
|
|
275
308
|
...
|
|
276
309
|
|
|
@@ -288,10 +321,13 @@ def useSyncExternalStore(
|
|
|
288
321
|
"""Subscribe to an external store.
|
|
289
322
|
|
|
290
323
|
Example:
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
324
|
+
|
|
325
|
+
```python
|
|
326
|
+
width = useSyncExternalStore(
|
|
327
|
+
subscribe_to_resize,
|
|
328
|
+
lambda: window.innerWidth
|
|
329
|
+
)
|
|
330
|
+
```
|
|
295
331
|
"""
|
|
296
332
|
...
|
|
297
333
|
|
|
@@ -337,27 +373,30 @@ def forwardRef(
|
|
|
337
373
|
|
|
338
374
|
|
|
339
375
|
class _LazyComponentFactory(_Expr):
|
|
340
|
-
"""React.lazy binding that works both at definition time and in
|
|
376
|
+
"""React.lazy binding that works both at definition time and in `@javascript`.
|
|
341
377
|
|
|
342
|
-
This Expr represents React's lazy function. It can be:
|
|
343
|
-
- Called at Python definition time: lazy(factory) → Jsx(Constant(...))
|
|
344
|
-
- Used as a reference in
|
|
345
|
-
- Called inside
|
|
378
|
+
This Expr represents React's `lazy` function. It can be:
|
|
379
|
+
- Called at Python definition time: `lazy(factory)` → `Jsx(Constant(...))`
|
|
380
|
+
- Used as a reference in `@javascript`: `some_fn(lazy)` → `some_fn(lazy)`
|
|
381
|
+
- Called inside `@javascript`: `lazy(factory)` → creates `Constant+Jsx`
|
|
346
382
|
|
|
347
383
|
Usage:
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
384
|
+
|
|
385
|
+
```python
|
|
386
|
+
# At definition time (Python executes this)
|
|
387
|
+
LazyChart = lazy(Import("Chart", "./Chart", lazy=True))
|
|
388
|
+
|
|
389
|
+
# As reference in transpiled code
|
|
390
|
+
@javascript
|
|
391
|
+
def foo():
|
|
392
|
+
return higher_order_fn(lazy) # → higher_order_fn(lazy)
|
|
393
|
+
|
|
394
|
+
# Called in transpiled code
|
|
395
|
+
@javascript
|
|
396
|
+
def bar():
|
|
397
|
+
LazyComp = lazy(factory) # → const LazyComp_1 = lazy(factory)
|
|
398
|
+
return LazyComp()
|
|
399
|
+
```
|
|
361
400
|
"""
|
|
362
401
|
|
|
363
402
|
__slots__: tuple[str, ...] = ("_lazy_import",)
|
pulse/js/regexp.py
CHANGED
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
JavaScript RegExp builtin module.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
|
-
from pulse.js import RegExp
|
|
6
|
-
RegExp(pattern, flags) # -> new RegExp(pattern, flags)
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
```python
|
|
7
|
+
from pulse.js import RegExp
|
|
8
|
+
RegExp(pattern, flags) # -> new RegExp(pattern, flags)
|
|
9
|
+
|
|
10
|
+
# Or import from module directly:
|
|
11
|
+
from pulse.js.regexp import RegExp
|
|
12
|
+
```
|
|
10
13
|
"""
|
|
11
14
|
|
|
12
15
|
from pulse.transpiler.js_module import JsModule
|
pulse/js/set.py
CHANGED
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
JavaScript Set builtin module.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
|
-
from pulse.js import Set
|
|
6
|
-
Set() # -> new Set()
|
|
7
|
-
Set([1, 2, 3]) # -> new Set([1, 2, 3])
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
```python
|
|
7
|
+
from pulse.js import Set
|
|
8
|
+
Set() # -> new Set()
|
|
9
|
+
Set([1, 2, 3]) # -> new Set([1, 2, 3])
|
|
10
|
+
|
|
11
|
+
# Or import from module directly:
|
|
12
|
+
from pulse.js.set import Set
|
|
13
|
+
```
|
|
11
14
|
"""
|
|
12
15
|
|
|
13
16
|
from collections.abc import Callable as _Callable
|
pulse/js/string.py
CHANGED
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
JavaScript String builtin module.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
|
-
from pulse.js import String
|
|
6
|
-
String(x) # -> new String(x)
|
|
7
|
-
String.fromCharCode(65) # -> String.fromCharCode(65)
|
|
8
|
-
String.fromCodePoint(0x1F600) # -> String.fromCodePoint(0x1F600)
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
```python
|
|
7
|
+
from pulse.js import String
|
|
8
|
+
String(x) # -> new String(x)
|
|
9
|
+
String.fromCharCode(65) # -> String.fromCharCode(65)
|
|
10
|
+
String.fromCodePoint(0x1F600) # -> String.fromCodePoint(0x1F600)
|
|
11
|
+
|
|
12
|
+
# Or import from module directly:
|
|
13
|
+
from pulse.js.string import String
|
|
14
|
+
```
|
|
12
15
|
"""
|
|
13
16
|
|
|
14
17
|
from typing import Any as _Any
|
pulse/js/weakmap.py
CHANGED
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
JavaScript WeakMap builtin module.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
|
-
from pulse.js import WeakMap
|
|
6
|
-
WeakMap() # -> new WeakMap()
|
|
7
|
-
WeakMap([[obj, "value"]]) # -> new WeakMap([[obj, "value"]])
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
```python
|
|
7
|
+
from pulse.js import WeakMap
|
|
8
|
+
WeakMap() # -> new WeakMap()
|
|
9
|
+
WeakMap([[obj, "value"]]) # -> new WeakMap([[obj, "value"]])
|
|
10
|
+
|
|
11
|
+
# Or import from module directly:
|
|
12
|
+
from pulse.js.weakmap import WeakMap
|
|
13
|
+
```
|
|
11
14
|
"""
|
|
12
15
|
|
|
13
16
|
from collections.abc import Iterable as _Iterable
|
pulse/js/weakset.py
CHANGED
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
JavaScript WeakSet builtin module.
|
|
3
3
|
|
|
4
4
|
Usage:
|
|
5
|
-
from pulse.js import WeakSet
|
|
6
|
-
WeakSet() # -> new WeakSet()
|
|
7
|
-
WeakSet([obj1, obj2]) # -> new WeakSet([obj1, obj2])
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
```python
|
|
7
|
+
from pulse.js import WeakSet
|
|
8
|
+
WeakSet() # -> new WeakSet()
|
|
9
|
+
WeakSet([obj1, obj2]) # -> new WeakSet([obj1, obj2])
|
|
10
|
+
|
|
11
|
+
# Or import from module directly:
|
|
12
|
+
from pulse.js.weakset import WeakSet
|
|
13
|
+
```
|
|
11
14
|
"""
|
|
12
15
|
|
|
13
16
|
from collections.abc import Iterable as _Iterable
|
pulse/js/window.py
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"""Browser window global object.
|
|
2
2
|
|
|
3
3
|
Usage:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
from pulse.js import window
|
|
7
|
+
window.alert("Hello!") # -> window.alert("Hello!")
|
|
8
|
+
window.innerWidth # -> window.innerWidth
|
|
9
|
+
```
|
|
7
10
|
"""
|
|
8
11
|
|
|
9
12
|
from collections.abc import Callable as _Callable
|
pulse/messages.py
CHANGED
|
@@ -48,6 +48,10 @@ class ServerNavigateToMessage(TypedDict):
|
|
|
48
48
|
hard: bool
|
|
49
49
|
|
|
50
50
|
|
|
51
|
+
class ServerReloadMessage(TypedDict):
|
|
52
|
+
type: Literal["reload"]
|
|
53
|
+
|
|
54
|
+
|
|
51
55
|
class ServerApiCallMessage(TypedDict):
|
|
52
56
|
type: Literal["api_call"]
|
|
53
57
|
# Correlation id to match request/response
|
|
@@ -158,6 +162,7 @@ ServerMessage = (
|
|
|
158
162
|
| ServerErrorMessage
|
|
159
163
|
| ServerApiCallMessage
|
|
160
164
|
| ServerNavigateToMessage
|
|
165
|
+
| ServerReloadMessage
|
|
161
166
|
| ServerChannelMessage
|
|
162
167
|
| ServerJsExecMessage
|
|
163
168
|
)
|