pulse-framework 0.1.70__py3-none-any.whl → 0.1.72__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 +7 -0
- pulse/app.py +27 -24
- pulse/cli/cmd.py +1 -1
- pulse/cli/folder_lock.py +25 -6
- pulse/codegen/templates/layout.py +3 -1
- pulse/hooks/effects.py +15 -1
- pulse/proxy.py +719 -185
- pulse/queries/client.py +64 -56
- pulse/queries/common.py +66 -3
- pulse/queries/infinite_query.py +59 -18
- pulse/queries/query.py +30 -11
- pulse/queries/store.py +13 -11
- pulse/render_session.py +5 -2
- {pulse_framework-0.1.70.dist-info → pulse_framework-0.1.72.dist-info}/METADATA +3 -3
- {pulse_framework-0.1.70.dist-info → pulse_framework-0.1.72.dist-info}/RECORD +17 -17
- {pulse_framework-0.1.70.dist-info → pulse_framework-0.1.72.dist-info}/WHEEL +0 -0
- {pulse_framework-0.1.70.dist-info → pulse_framework-0.1.72.dist-info}/entry_points.txt +0 -0
pulse/queries/query.py
CHANGED
|
@@ -26,11 +26,13 @@ from pulse.queries.common import (
|
|
|
26
26
|
ActionError,
|
|
27
27
|
ActionResult,
|
|
28
28
|
ActionSuccess,
|
|
29
|
+
Key,
|
|
29
30
|
OnErrorFn,
|
|
30
31
|
OnSuccessFn,
|
|
31
32
|
QueryKey,
|
|
32
33
|
QueryStatus,
|
|
33
34
|
bind_state,
|
|
35
|
+
normalize_key,
|
|
34
36
|
)
|
|
35
37
|
from pulse.queries.effect import AsyncQueryEffect
|
|
36
38
|
from pulse.reactive import Computed, Effect, Signal, Untrack
|
|
@@ -239,7 +241,8 @@ async def run_fetch_with_retries(
|
|
|
239
241
|
result = await fetch_fn()
|
|
240
242
|
state.set_success(result)
|
|
241
243
|
if on_success:
|
|
242
|
-
|
|
244
|
+
with Untrack():
|
|
245
|
+
await maybe_await(call_flexible(on_success, result))
|
|
243
246
|
return
|
|
244
247
|
except asyncio.CancelledError:
|
|
245
248
|
raise
|
|
@@ -252,7 +255,8 @@ async def run_fetch_with_retries(
|
|
|
252
255
|
state.retry_reason.write(e)
|
|
253
256
|
state.apply_error(e)
|
|
254
257
|
if on_error:
|
|
255
|
-
|
|
258
|
+
with Untrack():
|
|
259
|
+
await maybe_await(call_flexible(on_error, e))
|
|
256
260
|
return
|
|
257
261
|
|
|
258
262
|
|
|
@@ -263,7 +267,7 @@ class KeyedQuery(Generic[T], Disposable):
|
|
|
263
267
|
Multiple observers can share the same query.
|
|
264
268
|
"""
|
|
265
269
|
|
|
266
|
-
key:
|
|
270
|
+
key: Key
|
|
267
271
|
state: QueryState[T]
|
|
268
272
|
observers: "list[KeyedQueryResult[T]]"
|
|
269
273
|
_task: asyncio.Task[None] | None
|
|
@@ -283,7 +287,7 @@ class KeyedQuery(Generic[T], Disposable):
|
|
|
283
287
|
gc_time: float = 300.0,
|
|
284
288
|
on_dispose: Callable[[Any], None] | None = None,
|
|
285
289
|
):
|
|
286
|
-
self.key = key
|
|
290
|
+
self.key = normalize_key(key)
|
|
287
291
|
self.state = QueryState(
|
|
288
292
|
name=str(key),
|
|
289
293
|
retries=retries,
|
|
@@ -559,7 +563,8 @@ class KeyedQuery(Generic[T], Disposable):
|
|
|
559
563
|
)
|
|
560
564
|
|
|
561
565
|
if len(self.observers) == 0:
|
|
562
|
-
self.
|
|
566
|
+
if not self.__disposed__:
|
|
567
|
+
self.schedule_gc()
|
|
563
568
|
|
|
564
569
|
def schedule_gc(self):
|
|
565
570
|
self.cancel_gc()
|
|
@@ -1055,7 +1060,7 @@ class QueryProperty(Generic[T, TState], InitializableProperty):
|
|
|
1055
1060
|
_initial_data_updated_at: float | dt.datetime | None
|
|
1056
1061
|
_enabled: bool
|
|
1057
1062
|
_initial_data: T | Callable[[TState], T] | Missing | None
|
|
1058
|
-
_key:
|
|
1063
|
+
_key: Key | Callable[[TState], Key] | None
|
|
1059
1064
|
# Not using OnSuccessFn and OnErrorFn since unions of callables are not well
|
|
1060
1065
|
# supported in the type system. We just need to be careful to use
|
|
1061
1066
|
# call_flexible to invoke these functions.
|
|
@@ -1081,7 +1086,17 @@ class QueryProperty(Generic[T, TState], InitializableProperty):
|
|
|
1081
1086
|
):
|
|
1082
1087
|
self.name = name
|
|
1083
1088
|
self._fetch_fn = fetch_fn
|
|
1084
|
-
|
|
1089
|
+
if key is None:
|
|
1090
|
+
self._key = None
|
|
1091
|
+
elif callable(key):
|
|
1092
|
+
key_fn = key
|
|
1093
|
+
|
|
1094
|
+
def normalized_key(state: TState) -> Key:
|
|
1095
|
+
return normalize_key(key_fn(state))
|
|
1096
|
+
|
|
1097
|
+
self._key = normalized_key
|
|
1098
|
+
else:
|
|
1099
|
+
self._key = normalize_key(key)
|
|
1085
1100
|
self._on_success_fn = None
|
|
1086
1101
|
self._on_error_fn = None
|
|
1087
1102
|
self._keep_previous_data = keep_previous_data
|
|
@@ -1102,7 +1117,11 @@ class QueryProperty(Generic[T, TState], InitializableProperty):
|
|
|
1102
1117
|
raise RuntimeError(
|
|
1103
1118
|
f"Cannot use @{self.name}.key decorator when a key is already provided to @query(key=...)."
|
|
1104
1119
|
)
|
|
1105
|
-
|
|
1120
|
+
|
|
1121
|
+
def normalized_key(state: TState) -> Key:
|
|
1122
|
+
return normalize_key(fn(state))
|
|
1123
|
+
|
|
1124
|
+
self._key = normalized_key
|
|
1106
1125
|
return fn
|
|
1107
1126
|
|
|
1108
1127
|
# Decorator to attach a function providing initial data
|
|
@@ -1270,6 +1289,7 @@ class QueryProperty(Generic[T, TState], InitializableProperty):
|
|
|
1270
1289
|
def query(
|
|
1271
1290
|
fn: Callable[[TState], Awaitable[T]],
|
|
1272
1291
|
*,
|
|
1292
|
+
key: QueryKey | Callable[[TState], QueryKey] | None = None,
|
|
1273
1293
|
stale_time: float = 0.0,
|
|
1274
1294
|
gc_time: float | None = 300.0,
|
|
1275
1295
|
refetch_interval: float | None = None,
|
|
@@ -1279,7 +1299,6 @@ def query(
|
|
|
1279
1299
|
initial_data_updated_at: float | dt.datetime | None = None,
|
|
1280
1300
|
enabled: bool = True,
|
|
1281
1301
|
fetch_on_mount: bool = True,
|
|
1282
|
-
key: QueryKey | None = None,
|
|
1283
1302
|
) -> QueryProperty[T, TState]: ...
|
|
1284
1303
|
|
|
1285
1304
|
|
|
@@ -1287,6 +1306,7 @@ def query(
|
|
|
1287
1306
|
def query(
|
|
1288
1307
|
fn: None = None,
|
|
1289
1308
|
*,
|
|
1309
|
+
key: QueryKey | Callable[[TState], QueryKey] | None = None,
|
|
1290
1310
|
stale_time: float = 0.0,
|
|
1291
1311
|
gc_time: float | None = 300.0,
|
|
1292
1312
|
refetch_interval: float | None = None,
|
|
@@ -1296,13 +1316,13 @@ def query(
|
|
|
1296
1316
|
initial_data_updated_at: float | dt.datetime | None = None,
|
|
1297
1317
|
enabled: bool = True,
|
|
1298
1318
|
fetch_on_mount: bool = True,
|
|
1299
|
-
key: QueryKey | None = None,
|
|
1300
1319
|
) -> Callable[[Callable[[TState], Awaitable[T]]], QueryProperty[T, TState]]: ...
|
|
1301
1320
|
|
|
1302
1321
|
|
|
1303
1322
|
def query(
|
|
1304
1323
|
fn: Callable[[TState], Awaitable[T]] | None = None,
|
|
1305
1324
|
*,
|
|
1325
|
+
key: QueryKey | Callable[[TState], QueryKey] | None = None,
|
|
1306
1326
|
stale_time: float = 0.0,
|
|
1307
1327
|
gc_time: float | None = 300.0,
|
|
1308
1328
|
refetch_interval: float | None = None,
|
|
@@ -1312,7 +1332,6 @@ def query(
|
|
|
1312
1332
|
initial_data_updated_at: float | dt.datetime | None = None,
|
|
1313
1333
|
enabled: bool = True,
|
|
1314
1334
|
fetch_on_mount: bool = True,
|
|
1315
|
-
key: QueryKey | None = None,
|
|
1316
1335
|
) -> (
|
|
1317
1336
|
QueryProperty[T, TState]
|
|
1318
1337
|
| Callable[[Callable[[TState], Awaitable[T]]], QueryProperty[T, TState]]
|
pulse/queries/store.py
CHANGED
|
@@ -3,7 +3,7 @@ from collections.abc import Callable
|
|
|
3
3
|
from typing import Any, TypeVar, cast
|
|
4
4
|
|
|
5
5
|
from pulse.helpers import MISSING, Missing
|
|
6
|
-
from pulse.queries.common import QueryKey
|
|
6
|
+
from pulse.queries.common import Key, QueryKey, normalize_key
|
|
7
7
|
from pulse.queries.infinite_query import InfiniteQuery, Page
|
|
8
8
|
from pulse.queries.query import RETRY_DELAY_DEFAULT, KeyedQuery
|
|
9
9
|
|
|
@@ -16,7 +16,7 @@ class QueryStore:
|
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
18
|
def __init__(self):
|
|
19
|
-
self._entries: dict[
|
|
19
|
+
self._entries: dict[Key, KeyedQuery[Any] | InfiniteQuery[Any, Any]] = {}
|
|
20
20
|
|
|
21
21
|
def items(self):
|
|
22
22
|
"""Iterate over all (key, query) pairs in the store."""
|
|
@@ -24,7 +24,7 @@ class QueryStore:
|
|
|
24
24
|
|
|
25
25
|
def get_any(self, key: QueryKey):
|
|
26
26
|
"""Get any query (regular or infinite) by key, or None if not found."""
|
|
27
|
-
return self._entries.get(key)
|
|
27
|
+
return self._entries.get(normalize_key(key))
|
|
28
28
|
|
|
29
29
|
def ensure(
|
|
30
30
|
self,
|
|
@@ -35,8 +35,9 @@ class QueryStore:
|
|
|
35
35
|
retries: int = 3,
|
|
36
36
|
retry_delay: float = RETRY_DELAY_DEFAULT,
|
|
37
37
|
) -> KeyedQuery[T]:
|
|
38
|
+
nkey = normalize_key(key)
|
|
38
39
|
# Return existing entry if present
|
|
39
|
-
existing = self._entries.get(
|
|
40
|
+
existing = self._entries.get(nkey)
|
|
40
41
|
if existing:
|
|
41
42
|
if isinstance(existing, InfiniteQuery):
|
|
42
43
|
raise TypeError(
|
|
@@ -49,7 +50,7 @@ class QueryStore:
|
|
|
49
50
|
del self._entries[e.key]
|
|
50
51
|
|
|
51
52
|
entry = KeyedQuery(
|
|
52
|
-
|
|
53
|
+
nkey,
|
|
53
54
|
initial_data=initial_data,
|
|
54
55
|
initial_data_updated_at=initial_data_updated_at,
|
|
55
56
|
gc_time=gc_time,
|
|
@@ -57,14 +58,14 @@ class QueryStore:
|
|
|
57
58
|
retry_delay=retry_delay,
|
|
58
59
|
on_dispose=_on_dispose,
|
|
59
60
|
)
|
|
60
|
-
self._entries[
|
|
61
|
+
self._entries[nkey] = entry
|
|
61
62
|
return entry
|
|
62
63
|
|
|
63
64
|
def get(self, key: QueryKey) -> KeyedQuery[Any] | None:
|
|
64
65
|
"""
|
|
65
66
|
Get an existing regular query by key, or None if not found.
|
|
66
67
|
"""
|
|
67
|
-
existing = self._entries.get(key)
|
|
68
|
+
existing = self._entries.get(normalize_key(key))
|
|
68
69
|
if existing and isinstance(existing, InfiniteQuery):
|
|
69
70
|
return None
|
|
70
71
|
return existing
|
|
@@ -73,7 +74,7 @@ class QueryStore:
|
|
|
73
74
|
"""
|
|
74
75
|
Get an existing infinite query by key, or None if not found.
|
|
75
76
|
"""
|
|
76
|
-
existing = self._entries.get(key)
|
|
77
|
+
existing = self._entries.get(normalize_key(key))
|
|
77
78
|
if existing and isinstance(existing, InfiniteQuery):
|
|
78
79
|
return existing
|
|
79
80
|
return None
|
|
@@ -93,7 +94,8 @@ class QueryStore:
|
|
|
93
94
|
retries: int = 3,
|
|
94
95
|
retry_delay: float = RETRY_DELAY_DEFAULT,
|
|
95
96
|
) -> InfiniteQuery[Any, Any]:
|
|
96
|
-
|
|
97
|
+
nkey = normalize_key(key)
|
|
98
|
+
existing = self._entries.get(nkey)
|
|
97
99
|
if existing:
|
|
98
100
|
if not isinstance(existing, InfiniteQuery):
|
|
99
101
|
raise TypeError(
|
|
@@ -106,7 +108,7 @@ class QueryStore:
|
|
|
106
108
|
del self._entries[e.key]
|
|
107
109
|
|
|
108
110
|
entry = InfiniteQuery(
|
|
109
|
-
|
|
111
|
+
nkey,
|
|
110
112
|
initial_page_param=initial_page_param,
|
|
111
113
|
get_next_page_param=get_next_page_param,
|
|
112
114
|
get_previous_page_param=get_previous_page_param,
|
|
@@ -118,7 +120,7 @@ class QueryStore:
|
|
|
118
120
|
retry_delay=retry_delay,
|
|
119
121
|
on_dispose=_on_dispose,
|
|
120
122
|
)
|
|
121
|
-
self._entries[
|
|
123
|
+
self._entries[nkey] = entry
|
|
122
124
|
return entry
|
|
123
125
|
|
|
124
126
|
def dispose_all(self) -> None:
|
pulse/render_session.py
CHANGED
|
@@ -285,7 +285,6 @@ class RenderSession:
|
|
|
285
285
|
self._send_message = None
|
|
286
286
|
self._global_states = {}
|
|
287
287
|
self._global_queue = []
|
|
288
|
-
self.query_store = QueryStore()
|
|
289
288
|
self.connected = False
|
|
290
289
|
self.channels = ChannelsManager(self)
|
|
291
290
|
self.forms = FormRegistry(self)
|
|
@@ -293,6 +292,7 @@ class RenderSession:
|
|
|
293
292
|
self._pending_js_results = {}
|
|
294
293
|
self._tasks = TaskRegistry(name=f"render:{id}")
|
|
295
294
|
self._timers = TimerRegistry(tasks=self._tasks, name=f"render:{id}")
|
|
295
|
+
self.query_store = QueryStore()
|
|
296
296
|
self.prerender_queue_timeout = prerender_queue_timeout
|
|
297
297
|
self.detach_queue_timeout = detach_queue_timeout
|
|
298
298
|
self.disconnect_queue_timeout = disconnect_queue_timeout
|
|
@@ -574,9 +574,10 @@ class RenderSession:
|
|
|
574
574
|
# ---- Helpers ----
|
|
575
575
|
|
|
576
576
|
def close(self):
|
|
577
|
+
# Close all pending timers at the start, to avoid anything firing while we clean up
|
|
578
|
+
self._timers.cancel_all()
|
|
577
579
|
self.forms.dispose()
|
|
578
580
|
self._tasks.cancel_all()
|
|
579
|
-
self._timers.cancel_all()
|
|
580
581
|
for path in list(self.route_mounts.keys()):
|
|
581
582
|
self.detach(path, timeout=0)
|
|
582
583
|
self.route_mounts.clear()
|
|
@@ -597,6 +598,8 @@ class RenderSession:
|
|
|
597
598
|
if not fut.done():
|
|
598
599
|
fut.cancel()
|
|
599
600
|
self._pending_js_results.clear()
|
|
601
|
+
# Close any timer that may have been scheduled during cleanup (ex: query GC)
|
|
602
|
+
self._timers.cancel_all()
|
|
600
603
|
self._global_queue = []
|
|
601
604
|
self._send_message = None
|
|
602
605
|
self.connected = False
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pulse-framework
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.72
|
|
4
4
|
Summary: Pulse - Full-stack framework for building real-time React applications in Python
|
|
5
|
-
Requires-Dist: websockets>=12.0
|
|
6
5
|
Requires-Dist: fastapi>=0.128.0
|
|
7
6
|
Requires-Dist: uvicorn>=0.24.0
|
|
8
7
|
Requires-Dist: mako>=1.3.10
|
|
9
8
|
Requires-Dist: typer>=0.16.0
|
|
10
9
|
Requires-Dist: python-socketio>=5.16.0
|
|
11
10
|
Requires-Dist: rich>=13.7.1
|
|
12
|
-
Requires-Dist: python-multipart>=0.0.
|
|
11
|
+
Requires-Dist: python-multipart>=0.0.22
|
|
13
12
|
Requires-Dist: python-dateutil>=2.9.0.post0
|
|
14
13
|
Requires-Dist: starlette>=0.50.0,<0.51.0
|
|
15
14
|
Requires-Dist: urllib3>=2.6.3
|
|
16
15
|
Requires-Dist: watchfiles>=1.1.0
|
|
17
16
|
Requires-Dist: httpx>=0.28.1
|
|
17
|
+
Requires-Dist: aiohttp>=3.12.0
|
|
18
18
|
Requires-Python: >=3.11
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
20
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
pulse/__init__.py,sha256=
|
|
1
|
+
pulse/__init__.py,sha256=VV1oD_y0xnhQ_yBj1XqGWjIaw4Hi-xGHYQfEMv-Z1Bo,32453
|
|
2
2
|
pulse/_examples.py,sha256=dFuhD2EVXsbvAeexoG57s4VuN4gWLaTMOEMNYvlPm9A,561
|
|
3
|
-
pulse/app.py,sha256=
|
|
3
|
+
pulse/app.py,sha256=Bi94rYG-MoldkGa-_CscLMstjTEV8BHVAgDbvapRGzI,36167
|
|
4
4
|
pulse/channel.py,sha256=ePpvD2mDbddt_LMxxxDjNRgOLbVi8Ed6TmJFgkrALB0,15790
|
|
5
5
|
pulse/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
pulse/cli/cmd.py,sha256=
|
|
6
|
+
pulse/cli/cmd.py,sha256=LQK_B6iANOAqcQCM0KMTfRbpqGYRaPDkEBvvaAS3qNI,15985
|
|
7
7
|
pulse/cli/dependencies.py,sha256=qU-rF7QyP0Rl1Fl0YKQubrGNBzj84BAbH1uUT3ehxik,4283
|
|
8
|
-
pulse/cli/folder_lock.py,sha256
|
|
8
|
+
pulse/cli/folder_lock.py,sha256=CGJCovbSxZ59dllwNUqtPDx6YCED8k3ct5ZsEL0gzfw,4035
|
|
9
9
|
pulse/cli/helpers.py,sha256=XXRRXeGFgeq-jbp0QGFFVq_aGg_Kp7_AkYsTK8LfSdg,7810
|
|
10
10
|
pulse/cli/logging.py,sha256=3uuB1dqI-lHJkodNUURN6UMWdKF5UQ9spNG-hBG7bA4,2516
|
|
11
11
|
pulse/cli/models.py,sha256=NBV5byBDNoAQSk0vKwibLjoxuA85XBYIyOVJn64L8oU,858
|
|
@@ -17,7 +17,7 @@ pulse/code_analysis.py,sha256=NBba_7VtOxZYMyfku_p-bWkG0O_1pi1AxcaNyVM1nmY,1024
|
|
|
17
17
|
pulse/codegen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
18
|
pulse/codegen/codegen.py,sha256=Zw55vzevg_17hFtSi6KLl-EWSiABKRfZe6fB-cWpLAk,10330
|
|
19
19
|
pulse/codegen/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
-
pulse/codegen/templates/layout.py,sha256=
|
|
20
|
+
pulse/codegen/templates/layout.py,sha256=nJ9k0MDUHOGjtwbt8QAo9XdCPR06rqJSU9E8Qi4Uot4,4597
|
|
21
21
|
pulse/codegen/templates/route.py,sha256=UjBrb3e_8tMkd1OjBjEsnYmK6PCQqOYZBWDuU59FcrI,9234
|
|
22
22
|
pulse/codegen/templates/routes_ts.py,sha256=nPgKCvU0gzue2k6KlOL1TJgrBqqRLmyy7K_qKAI8zAE,1129
|
|
23
23
|
pulse/codegen/utils.py,sha256=QoXcV-h-DLLmq_t03hDNUePS0fNnofUQLoR-TXzDFCY,539
|
|
@@ -41,7 +41,7 @@ pulse/forms.py,sha256=0irpErCMJk8-YO1BrxjMkFb8dnvSz3rfzTywmMeib7g,14042
|
|
|
41
41
|
pulse/helpers.py,sha256=imVA9XzkYrYmdeqEdD7ot0g99adL1SVKv5bQGkKb-aQ,9504
|
|
42
42
|
pulse/hooks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
43
|
pulse/hooks/core.py,sha256=tDEcB_CTD4yI5bNKn7CtB40sRKIanGNqPD5_qLgSzf4,10982
|
|
44
|
-
pulse/hooks/effects.py,sha256=
|
|
44
|
+
pulse/hooks/effects.py,sha256=IRb37K9p0egBqlPvAnlW5dPohPvQGzmcyLSgbuNk5FU,3005
|
|
45
45
|
pulse/hooks/init.py,sha256=PhjVBLlHpodPzVrRcx_QfEUrsx_6gEX_NuVhe6ojiYI,17834
|
|
46
46
|
pulse/hooks/runtime.py,sha256=nxqwl8ByclIh5i3ZcCN6L3f0X3ZpwOBWajLb_FSbcDw,11839
|
|
47
47
|
pulse/hooks/setup.py,sha256=ILbn2v6UFJPFBOWnJef1X2A9JLpIagEHN9Mx0d9947I,6925
|
|
@@ -74,21 +74,21 @@ pulse/js/window.py,sha256=yC1BjyH2jqp1x-CXJCUFta-ASyZ5668ozQ0AmAjZcxA,4097
|
|
|
74
74
|
pulse/messages.py,sha256=hz5EUFVHbzXHkcByZcV_Y199vb-M9cGjMMBL1HXPctE,4024
|
|
75
75
|
pulse/middleware.py,sha256=2syzmJ0r9fEa0k1pD7zC_1DHUMs9qLSWRzo5XXtKqsA,10896
|
|
76
76
|
pulse/plugin.py,sha256=bu90qaUVFtZsIsW41dpshVK1vvIGHUsg6mFoiF0Wfso,2370
|
|
77
|
-
pulse/proxy.py,sha256=
|
|
77
|
+
pulse/proxy.py,sha256=c13b0fE3sq82sFo46vv0emWLQ_ePwRkI7hiPZrnQDCE,22780
|
|
78
78
|
pulse/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
79
79
|
pulse/queries/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
80
|
-
pulse/queries/client.py,sha256=
|
|
81
|
-
pulse/queries/common.py,sha256=
|
|
80
|
+
pulse/queries/client.py,sha256=KMGT92dESMrzpLlhd701fyh7Wrs3VKmM5cZoRQ0AEzg,18994
|
|
81
|
+
pulse/queries/common.py,sha256=tjW5pqpWvRYUy3gsj-KxhUB9c5KBOgBqRKIuKJkob9A,4278
|
|
82
82
|
pulse/queries/effect.py,sha256=1ePUi2TwP49L9LhlkKI2qV_HhIO4jKj1r5jyPaWiUn8,1508
|
|
83
|
-
pulse/queries/infinite_query.py,sha256=
|
|
83
|
+
pulse/queries/infinite_query.py,sha256=QZmXN2G8r0FA7cCez5bjPxEEvWZTB2Sl5_Pob3d5E6E,50489
|
|
84
84
|
pulse/queries/mutation.py,sha256=fhEpOZ7CuHImH4Y02QapYdTJrwe6K52-keb0d67wmms,8274
|
|
85
85
|
pulse/queries/protocol.py,sha256=TOrUiI4QK55xuh0i4ch1u96apNl12QeYafkf6RVDd08,3544
|
|
86
|
-
pulse/queries/query.py,sha256=
|
|
87
|
-
pulse/queries/store.py,sha256=
|
|
86
|
+
pulse/queries/query.py,sha256=Ap1PRKoc1U1ddhnnHgBOuNX9oUcYD9nInpq87uTLnb8,41849
|
|
87
|
+
pulse/queries/store.py,sha256=iw05_EFpyfiXv5_FV_x4aHtCo00mk0dDPFD461cajcg,3850
|
|
88
88
|
pulse/react_component.py,sha256=8RLg4Bi7IcjqbnbEnp4hJpy8t1UsE7mG0UR1Q655LDk,2332
|
|
89
89
|
pulse/reactive.py,sha256=GSh9wSH3THCBjDTafwWttyx7djeKBWV_KqjaKRYUNsA,31393
|
|
90
90
|
pulse/reactive_extensions.py,sha256=yQ1PpdAh4kMvll7R15T72FOg8NFdG_HGBsGc63dawYk,33754
|
|
91
|
-
pulse/render_session.py,sha256=
|
|
91
|
+
pulse/render_session.py,sha256=65mhbKZ9o1vIDSRrM2p3VNPmo6Z5vn1Aoz7we5mw7P8,23417
|
|
92
92
|
pulse/renderer.py,sha256=fjSsUvCqV12jyN7Y5XspKUfjQJJzKX-Chha5oF5PrAk,16001
|
|
93
93
|
pulse/request.py,sha256=N0oFOLiGxpbgSgxznjvu64lG3YyOcZPKC8JFyKx6X7w,6023
|
|
94
94
|
pulse/requirements.py,sha256=nMnE25Uu-TUuQd88jW7m2xwus6fD-HvXxQ9UNb7OOGc,1254
|
|
@@ -122,7 +122,7 @@ pulse/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
122
122
|
pulse/types/event_handler.py,sha256=psQCydj-WEtBcFU5JU4mDwvyzkW8V2O0g_VFRU2EOHI,1618
|
|
123
123
|
pulse/user_session.py,sha256=nsnsMgqq2xGJZLpbHRMHUHcLrElMP8WcA4gjGMrcoBk,10208
|
|
124
124
|
pulse/version.py,sha256=711vaM1jVIQPgkisGgKZqwmw019qZIsc_QTae75K2pg,1895
|
|
125
|
-
pulse_framework-0.1.
|
|
126
|
-
pulse_framework-0.1.
|
|
127
|
-
pulse_framework-0.1.
|
|
128
|
-
pulse_framework-0.1.
|
|
125
|
+
pulse_framework-0.1.72.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
|
|
126
|
+
pulse_framework-0.1.72.dist-info/entry_points.txt,sha256=i7aohd3QaPu5IcuGKKvsQQEiMYMe5HcF56QEsaLVO64,46
|
|
127
|
+
pulse_framework-0.1.72.dist-info/METADATA,sha256=Vn_d62C23dTizl4uuQ05BAkhQUDrBmnELQI3OrHkkE8,8299
|
|
128
|
+
pulse_framework-0.1.72.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|