pulse-framework 0.1.49__py3-none-any.whl → 0.1.51__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/hooks/runtime.py +4 -2
- pulse/messages.py +1 -0
- pulse/react_component.py +5 -3
- pulse/render_session.py +9 -2
- pulse/serializer.py +11 -1
- pulse/vdom.py +18 -88
- {pulse_framework-0.1.49.dist-info → pulse_framework-0.1.51.dist-info}/METADATA +1 -1
- {pulse_framework-0.1.49.dist-info → pulse_framework-0.1.51.dist-info}/RECORD +10 -10
- {pulse_framework-0.1.49.dist-info → pulse_framework-0.1.51.dist-info}/WHEEL +0 -0
- {pulse_framework-0.1.49.dist-info → pulse_framework-0.1.51.dist-info}/entry_points.txt +0 -0
pulse/hooks/runtime.py
CHANGED
|
@@ -103,11 +103,13 @@ async def set_cookie(
|
|
|
103
103
|
)
|
|
104
104
|
|
|
105
105
|
|
|
106
|
-
def navigate(path: str, *, replace: bool = False) -> None:
|
|
106
|
+
def navigate(path: str, *, replace: bool = False, hard: bool = False) -> None:
|
|
107
107
|
ctx = PulseContext.get()
|
|
108
108
|
if ctx.render is None:
|
|
109
109
|
raise RuntimeError("navigate() must be invoked inside a Pulse callback context")
|
|
110
|
-
ctx.render.send(
|
|
110
|
+
ctx.render.send(
|
|
111
|
+
{"type": "navigate_to", "path": path, "replace": replace, "hard": hard}
|
|
112
|
+
)
|
|
111
113
|
|
|
112
114
|
|
|
113
115
|
def redirect(path: str, *, replace: bool = False) -> NoReturn:
|
pulse/messages.py
CHANGED
pulse/react_component.py
CHANGED
|
@@ -37,7 +37,7 @@ from pulse.transpiler.nodes import (
|
|
|
37
37
|
JSXProp,
|
|
38
38
|
JSXSpreadProp,
|
|
39
39
|
)
|
|
40
|
-
from pulse.vdom import Child, Element, Node
|
|
40
|
+
from pulse.vdom import Child, Element, Node, clean_element_name
|
|
41
41
|
|
|
42
42
|
T = TypeVar("T")
|
|
43
43
|
P = ParamSpec("P")
|
|
@@ -205,7 +205,8 @@ class PropSpec:
|
|
|
205
205
|
unknown_keys = props.keys() - known_keys - {"key"}
|
|
206
206
|
if not self.allow_unspecified and unknown_keys:
|
|
207
207
|
bad = ", ".join(repr(k) for k in sorted(unknown_keys))
|
|
208
|
-
|
|
208
|
+
clean_tag = clean_element_name(comp_tag)
|
|
209
|
+
raise ValueError(f"Unexpected prop(s) for component '{clean_tag}': {bad}")
|
|
209
210
|
if self.allow_unspecified:
|
|
210
211
|
for k in unknown_keys:
|
|
211
212
|
v = props[k]
|
|
@@ -290,8 +291,9 @@ class PropSpec:
|
|
|
290
291
|
errors.append(
|
|
291
292
|
f"Multiple props map to '{js_key}': {', '.join(py_keys)}"
|
|
292
293
|
)
|
|
294
|
+
clean_tag = clean_element_name(comp_tag)
|
|
293
295
|
raise ValueError(
|
|
294
|
-
f"Invalid props for component '{
|
|
296
|
+
f"Invalid props for component '{clean_tag}': {'; '.join(errors)}"
|
|
295
297
|
)
|
|
296
298
|
|
|
297
299
|
return result or None
|
pulse/render_session.py
CHANGED
|
@@ -440,6 +440,7 @@ class RenderSession:
|
|
|
440
440
|
type="navigate_to",
|
|
441
441
|
path=msg["path"],
|
|
442
442
|
replace=msg["replace"],
|
|
443
|
+
hard=msg.get("hard", False),
|
|
443
444
|
)
|
|
444
445
|
|
|
445
446
|
prev_sender = self._send_message
|
|
@@ -563,14 +564,20 @@ class RenderSession:
|
|
|
563
564
|
# Prefer client-side navigation over emitting VDOM operations
|
|
564
565
|
self.send(
|
|
565
566
|
ServerNavigateToMessage(
|
|
566
|
-
type="navigate_to",
|
|
567
|
+
type="navigate_to",
|
|
568
|
+
path=r.path,
|
|
569
|
+
replace=r.replace,
|
|
570
|
+
hard=False,
|
|
567
571
|
)
|
|
568
572
|
)
|
|
569
573
|
except NotFoundInterrupt:
|
|
570
574
|
# Use app-configured not-found path; fallback to '/404'
|
|
571
575
|
self.send(
|
|
572
576
|
ServerNavigateToMessage(
|
|
573
|
-
type="navigate_to",
|
|
577
|
+
type="navigate_to",
|
|
578
|
+
path=ctx.app.not_found,
|
|
579
|
+
replace=True,
|
|
580
|
+
hard=False,
|
|
574
581
|
)
|
|
575
582
|
)
|
|
576
583
|
|
pulse/serializer.py
CHANGED
|
@@ -29,6 +29,7 @@ containing primitives, lists/tuples, ``dict``/plain objects, ``set`` and
|
|
|
29
29
|
from __future__ import annotations
|
|
30
30
|
|
|
31
31
|
import datetime as dt
|
|
32
|
+
import math
|
|
32
33
|
import types
|
|
33
34
|
from dataclasses import fields, is_dataclass
|
|
34
35
|
from typing import Any
|
|
@@ -56,7 +57,16 @@ def serialize(data: Any) -> Serialized:
|
|
|
56
57
|
|
|
57
58
|
def process(value: Any) -> PlainJSON:
|
|
58
59
|
nonlocal global_index
|
|
59
|
-
if value is None or isinstance(value, (bool, int,
|
|
60
|
+
if value is None or isinstance(value, (bool, int, str)):
|
|
61
|
+
return value
|
|
62
|
+
if isinstance(value, float):
|
|
63
|
+
if math.isnan(value):
|
|
64
|
+
return None # NaN → None (matches pandas None ↔ NaN semantics)
|
|
65
|
+
if math.isinf(value):
|
|
66
|
+
raise ValueError(
|
|
67
|
+
f"Cannot serialize {value}: Infinity is not valid JSON. "
|
|
68
|
+
+ "Replace with None or a sentinel value."
|
|
69
|
+
)
|
|
60
70
|
return value
|
|
61
71
|
|
|
62
72
|
idx = global_index
|
pulse/vdom.py
CHANGED
|
@@ -6,7 +6,6 @@ the TypeScript UINode format exactly, eliminating the need for translation.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
import functools
|
|
9
|
-
import math
|
|
10
9
|
import re
|
|
11
10
|
import warnings
|
|
12
11
|
from collections.abc import Callable, Iterable, Sequence
|
|
@@ -30,56 +29,6 @@ from pulse.env import env
|
|
|
30
29
|
from pulse.hooks.core import HookContext
|
|
31
30
|
from pulse.hooks.init import rewrite_init_blocks
|
|
32
31
|
|
|
33
|
-
# ============================================================================
|
|
34
|
-
# Validation helpers (dev mode only)
|
|
35
|
-
# ============================================================================
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def _check_json_safe_float(value: float, context: str) -> None:
|
|
39
|
-
"""Raise ValueError if a float is NaN or Infinity."""
|
|
40
|
-
if math.isnan(value):
|
|
41
|
-
raise ValueError(
|
|
42
|
-
f"Cannot use nan in {context}. "
|
|
43
|
-
+ "NaN and Infinity are not supported in Pulse because they cannot be serialized to JSON. "
|
|
44
|
-
+ "Replace with None or a sentinel value before passing to components."
|
|
45
|
-
)
|
|
46
|
-
if math.isinf(value):
|
|
47
|
-
kind = "inf" if value > 0 else "-inf"
|
|
48
|
-
raise ValueError(
|
|
49
|
-
f"Cannot use {kind} in {context}. "
|
|
50
|
-
+ "NaN and Infinity are not supported in Pulse because they cannot be serialized to JSON. "
|
|
51
|
-
+ "Replace with None or a sentinel value before passing to components."
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def _validate_value(value: Any, context: str) -> None:
|
|
56
|
-
"""Recursively validate a value for JSON-unsafe floats (NaN, Infinity)."""
|
|
57
|
-
if isinstance(value, float):
|
|
58
|
-
_check_json_safe_float(value, context)
|
|
59
|
-
elif isinstance(value, dict):
|
|
60
|
-
for v in value.values():
|
|
61
|
-
_validate_value(v, context)
|
|
62
|
-
elif isinstance(value, (list, tuple)):
|
|
63
|
-
for item in value:
|
|
64
|
-
_validate_value(item, context)
|
|
65
|
-
# Skip other types - they'll be handled by the serializer
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def _validate_props(props: dict[str, Any] | None, parent_name: str) -> None:
|
|
69
|
-
"""Validate all props for JSON-unsafe values."""
|
|
70
|
-
if not props:
|
|
71
|
-
return
|
|
72
|
-
for key, value in props.items():
|
|
73
|
-
_validate_value(value, f"{parent_name} prop '{key}'")
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def _validate_children(children: "Sequence[Element]", parent_name: str) -> None:
|
|
77
|
-
"""Validate primitive children for JSON-unsafe values."""
|
|
78
|
-
for child in children:
|
|
79
|
-
if isinstance(child, float):
|
|
80
|
-
_check_json_safe_float(child, f"{parent_name} children")
|
|
81
|
-
|
|
82
|
-
|
|
83
32
|
# ============================================================================
|
|
84
33
|
# Core VDOM
|
|
85
34
|
# ============================================================================
|
|
@@ -109,7 +58,7 @@ class Node:
|
|
|
109
58
|
|
|
110
59
|
tag: str
|
|
111
60
|
props: dict[str, Any] | None
|
|
112
|
-
children: "
|
|
61
|
+
children: "list[Element] | None"
|
|
113
62
|
allow_children: bool
|
|
114
63
|
key: str | None
|
|
115
64
|
|
|
@@ -122,7 +71,6 @@ class Node:
|
|
|
122
71
|
allow_children: bool = True,
|
|
123
72
|
):
|
|
124
73
|
self.tag = tag
|
|
125
|
-
# Normalize to None
|
|
126
74
|
self.props = props or None
|
|
127
75
|
self.children = (
|
|
128
76
|
_flatten_children(children, parent_name=f"<{self.tag}>")
|
|
@@ -134,13 +82,8 @@ class Node:
|
|
|
134
82
|
if key is not None and not isinstance(key, str):
|
|
135
83
|
raise ValueError("key must be a string or None")
|
|
136
84
|
if not self.allow_children and children:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if env.pulse_env == "dev":
|
|
140
|
-
parent_name = f"<{self.tag}>"
|
|
141
|
-
_validate_props(self.props, parent_name)
|
|
142
|
-
if self.children:
|
|
143
|
-
_validate_children(self.children, parent_name)
|
|
85
|
+
clean_tag = clean_element_name(self.tag)
|
|
86
|
+
raise ValueError(f"{clean_tag} cannot have children")
|
|
144
87
|
|
|
145
88
|
# --- Pretty printing helpers -------------------------------------------------
|
|
146
89
|
@override
|
|
@@ -265,7 +208,7 @@ class Component(Generic[P]):
|
|
|
265
208
|
if key is not None and not isinstance(key, str):
|
|
266
209
|
raise ValueError("key must be a string or None")
|
|
267
210
|
|
|
268
|
-
# Flatten children if component
|
|
211
|
+
# Flatten children if component accepts them via `*children` parameter
|
|
269
212
|
if self._takes_children and args:
|
|
270
213
|
flattened = _flatten_children(
|
|
271
214
|
args, # pyright: ignore[reportArgumentType]
|
|
@@ -332,17 +275,6 @@ class ComponentNode:
|
|
|
332
275
|
# Used for rendering
|
|
333
276
|
self.contents = None
|
|
334
277
|
self.hooks = HookContext()
|
|
335
|
-
# Dev-only validation for JSON-unsafe values
|
|
336
|
-
if env.pulse_env == "dev":
|
|
337
|
-
parent_name = f"<{self.name}>"
|
|
338
|
-
# Validate kwargs (props)
|
|
339
|
-
_validate_props(self.kwargs, parent_name)
|
|
340
|
-
# Validate args (children passed positionally)
|
|
341
|
-
for arg in self.args:
|
|
342
|
-
if isinstance(arg, float):
|
|
343
|
-
_check_json_safe_float(arg, f"{parent_name} children")
|
|
344
|
-
elif isinstance(arg, (dict, list, tuple)):
|
|
345
|
-
_validate_value(arg, f"{parent_name} children")
|
|
346
278
|
|
|
347
279
|
def __getitem__(self, children_arg: "Child | tuple[Child, ...]"):
|
|
348
280
|
if not self.takes_children:
|
|
@@ -356,11 +288,11 @@ class ComponentNode:
|
|
|
356
288
|
)
|
|
357
289
|
if not isinstance(children_arg, tuple):
|
|
358
290
|
children_arg = (children_arg,)
|
|
359
|
-
# Flatten children
|
|
291
|
+
# Flatten children when component accepts them via `*children` parameter
|
|
360
292
|
flattened_children = _flatten_children(
|
|
361
293
|
children_arg, parent_name=f"<{self.name}>", warn_stacklevel=4
|
|
362
294
|
)
|
|
363
|
-
|
|
295
|
+
return ComponentNode(
|
|
364
296
|
fn=self.fn,
|
|
365
297
|
args=tuple(flattened_children),
|
|
366
298
|
kwargs=self.kwargs,
|
|
@@ -368,7 +300,6 @@ class ComponentNode:
|
|
|
368
300
|
key=self.key,
|
|
369
301
|
takes_children=self.takes_children,
|
|
370
302
|
)
|
|
371
|
-
return result
|
|
372
303
|
|
|
373
304
|
@override
|
|
374
305
|
def __repr__(self) -> str:
|
|
@@ -486,7 +417,7 @@ VDOMOperation: TypeAlias = (
|
|
|
486
417
|
# ----------------------------------------------------------------------------
|
|
487
418
|
|
|
488
419
|
|
|
489
|
-
def
|
|
420
|
+
def clean_element_name(parent_name: str) -> str:
|
|
490
421
|
"""Strip $$ prefix and hexadecimal suffix from ReactComponent tags in warning messages.
|
|
491
422
|
|
|
492
423
|
ReactComponent tags are in the format <$$ComponentName_1a2b> or <$$ComponentName_1a2b.prop>.
|
|
@@ -500,7 +431,7 @@ def _clean_parent_name_for_warning(parent_name: str) -> str:
|
|
|
500
431
|
|
|
501
432
|
def _flatten_children(
|
|
502
433
|
children: Children, *, parent_name: str, warn_stacklevel: int = 5
|
|
503
|
-
) ->
|
|
434
|
+
) -> list[Element]:
|
|
504
435
|
"""Flatten children and emit warnings for unkeyed iterables (dev mode only).
|
|
505
436
|
|
|
506
437
|
Args:
|
|
@@ -511,7 +442,6 @@ def _flatten_children(
|
|
|
511
442
|
- 4 for ComponentNode.__getitem__ or Component.__call__ (user -> method -> _flatten_children -> visit -> warn)
|
|
512
443
|
"""
|
|
513
444
|
flat: list[Element] = []
|
|
514
|
-
return_tuple = isinstance(children, tuple)
|
|
515
445
|
is_dev = env.pulse_env == "dev"
|
|
516
446
|
|
|
517
447
|
def visit(item: Child) -> None:
|
|
@@ -529,7 +459,7 @@ def _flatten_children(
|
|
|
529
459
|
visit(sub)
|
|
530
460
|
if missing_key:
|
|
531
461
|
# Warn once per iterable without keys on its elements.
|
|
532
|
-
clean_name =
|
|
462
|
+
clean_name = clean_element_name(parent_name)
|
|
533
463
|
warnings.warn(
|
|
534
464
|
(
|
|
535
465
|
f"[Pulse] Iterable children of {clean_name} contain elements without 'key'. "
|
|
@@ -548,13 +478,14 @@ def _flatten_children(
|
|
|
548
478
|
for child in flat:
|
|
549
479
|
if isinstance(child, (Node, ComponentNode)) and child.key is not None:
|
|
550
480
|
if child.key in seen_keys:
|
|
481
|
+
clean_name = clean_element_name(parent_name)
|
|
551
482
|
raise ValueError(
|
|
552
|
-
f"[Pulse] Duplicate key '{child.key}' found among children of {
|
|
483
|
+
f"[Pulse] Duplicate key '{child.key}' found among children of {clean_name}. "
|
|
553
484
|
+ "Keys must be unique per sibling set."
|
|
554
485
|
)
|
|
555
486
|
seen_keys.add(child.key)
|
|
556
487
|
|
|
557
|
-
return
|
|
488
|
+
return flat
|
|
558
489
|
|
|
559
490
|
|
|
560
491
|
def _short_args(args: tuple[Any, ...], max_items: int = 4) -> list[str] | str:
|
|
@@ -606,19 +537,18 @@ def _callable_qualname(fn: Callable[..., Any]) -> str:
|
|
|
606
537
|
|
|
607
538
|
|
|
608
539
|
def _takes_children(fn: Callable[..., Any]) -> bool:
|
|
609
|
-
|
|
610
|
-
|
|
540
|
+
"""Return True if function accepts children via `*children` parameter.
|
|
541
|
+
|
|
542
|
+
Convention: A component accepts children if and only if it has a VAR_POSITIONAL
|
|
543
|
+
parameter named "children". This convention should be documented in user-facing docs.
|
|
544
|
+
"""
|
|
611
545
|
try:
|
|
612
546
|
sig = signature(fn)
|
|
613
547
|
except (ValueError, TypeError):
|
|
614
548
|
# Builtins or callables without inspectable signature: assume no children
|
|
615
549
|
return False
|
|
616
550
|
for p in sig.parameters.values():
|
|
617
|
-
if p.kind
|
|
618
|
-
Parameter.VAR_POSITIONAL,
|
|
619
|
-
Parameter.POSITIONAL_ONLY,
|
|
620
|
-
Parameter.POSITIONAL_OR_KEYWORD,
|
|
621
|
-
):
|
|
551
|
+
if p.kind is Parameter.VAR_POSITIONAL and p.name == "children":
|
|
622
552
|
return True
|
|
623
553
|
return False
|
|
624
554
|
|
|
@@ -33,7 +33,7 @@ pulse/hooks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
33
33
|
pulse/hooks/core.py,sha256=QfYRz2O8-drNSQx_xnv8mK8ksWcw3LNM1H2hoInT0Rk,7457
|
|
34
34
|
pulse/hooks/effects.py,sha256=pVq5OndlhFLHLpM9Pn9Bp5rEpnpmJEpbIp2UaHHyJFQ,2428
|
|
35
35
|
pulse/hooks/init.py,sha256=iTNmEcFgZCXsLImPONbSNwc5asT7NQRz04b1Jopgzxs,11960
|
|
36
|
-
pulse/hooks/runtime.py,sha256=
|
|
36
|
+
pulse/hooks/runtime.py,sha256=61CGZ9B0ScwCx8bwUrXIWYPAJIZtGCp3GcdBqa33dgo,5145
|
|
37
37
|
pulse/hooks/setup.py,sha256=c_uVi0S0HPioEvjdWUaSdAGT9M3Cxpw8J-llvtmDOGo,4496
|
|
38
38
|
pulse/hooks/stable.py,sha256=mLNS6WyA4tC-65gNybPOE0DLEz1YlxOCddD9odElArU,1772
|
|
39
39
|
pulse/hooks/states.py,sha256=fFqN3gf7v7rY6QmieKWN1hVCQRRnL-5H4TeG9LTnKSc,6778
|
|
@@ -65,7 +65,7 @@ pulse/js/string.py,sha256=fBd_CKq5nhc300mRa3YgNw0jpTEgGyaXRmGBiJgeu5w,928
|
|
|
65
65
|
pulse/js/weakmap.py,sha256=Q7kgPQx6rFqYfhIDyRfhuC12JmlKmO2n-OGSpl3g9ZY,1473
|
|
66
66
|
pulse/js/weakset.py,sha256=FJoVR0WtaOaHL7AXzJOb29F_sqG1K2mWxvR0RJk3mS0,1333
|
|
67
67
|
pulse/js/window.py,sha256=ayx3lBl54hTVanlkiC2wCVGNh0IDJqzPO7OlO11YUtI,4081
|
|
68
|
-
pulse/messages.py,sha256=
|
|
68
|
+
pulse/messages.py,sha256=8SrGVPQ674DPMm-FUNNrEfVonFmcvQdb8B_z6K_dQbw,3991
|
|
69
69
|
pulse/middleware.py,sha256=9uyAhVUEGMSwqWC3WXqs7x5JMMNEcSTTu3g7DjsR8w8,9812
|
|
70
70
|
pulse/plugin.py,sha256=RfGl6Vtr7VRHb8bp4Ob4dOX9dVzvc4Riu7HWnStMPpk,580
|
|
71
71
|
pulse/proxy.py,sha256=jv2IdOEbF-qbtN5hmSqnyhZedOX1597XBye8cerWIyE,7253
|
|
@@ -79,14 +79,14 @@ pulse/queries/mutation.py,sha256=px1fprFL-RxNfbRSoRtdsOLkEbjSsMrJxGHKBIPYQTM,495
|
|
|
79
79
|
pulse/queries/protocol.py,sha256=R8n238Ex9DbYIAVKB83a8FAPtnCiPNhWar-F01K2fTo,3345
|
|
80
80
|
pulse/queries/query.py,sha256=G8eXCaT5wuvVcstlqWU8VBxuuUUS7K1R5Y-VtDpMIG0,35065
|
|
81
81
|
pulse/queries/store.py,sha256=Ct7a-h1-Cq07zEfe9vw-LM85Fm7jIJx7CLAIlsiznlU,3444
|
|
82
|
-
pulse/react_component.py,sha256=
|
|
82
|
+
pulse/react_component.py,sha256=7_7gNYiWnLqwta5TBG8GhWN29IH1aH9wRmGCm4pRJzI,30713
|
|
83
83
|
pulse/reactive.py,sha256=v8a9IttkabeWwYrrHAx33zqzW9WC4WlS4iXbIh2KQkU,24374
|
|
84
84
|
pulse/reactive_extensions.py,sha256=T1V3AasHtvJkmGO55miC9RVPxDFIj7qrooMsn89x5SI,32076
|
|
85
|
-
pulse/render_session.py,sha256=
|
|
85
|
+
pulse/render_session.py,sha256=kGskm6NNhQ2u4vBRXOeIeCoXsyP81O2Q4Fr93nA6q-4,18222
|
|
86
86
|
pulse/renderer.py,sha256=kUwrI5v9XMerVCjBmnYZSyfkDu8B8cW8jFjVnM93TS4,15702
|
|
87
87
|
pulse/request.py,sha256=sPsSRWi5KvReSPBLIs_kzqomn1wlRk1BTLZ5s0chQr4,4979
|
|
88
88
|
pulse/routing.py,sha256=XZdq4gjfYeuz1wKtjPza6YA8ya76_cQ58b2l4dBDbr4,13243
|
|
89
|
-
pulse/serializer.py,sha256=
|
|
89
|
+
pulse/serializer.py,sha256=7YF8ZjDZYgA5Wmxd9CT-lPvakSb4zjUI1YbTd9m4jQM,5733
|
|
90
90
|
pulse/state.py,sha256=ikQbK4R8PieV96qd4uWREUvs0jXo9sCapawY7i6oCYo,10776
|
|
91
91
|
pulse/transpiler/__init__.py,sha256=sgfHxLwZEPj3rBBMtzD4997qx7GTr5Wt22-296e-uC8,6492
|
|
92
92
|
pulse/transpiler/builtins.py,sha256=V_H3bpgU22Yb_GzM6YvOutZ65O36xHLzRANl7uHRqUI,22401
|
|
@@ -111,9 +111,9 @@ pulse/transpiler/utils.py,sha256=W5PAOWvmYdJCEw1eY7QEJRQFmNLVjFTdlCyWzmnTrCc,94
|
|
|
111
111
|
pulse/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
112
112
|
pulse/types/event_handler.py,sha256=psQCydj-WEtBcFU5JU4mDwvyzkW8V2O0g_VFRU2EOHI,1618
|
|
113
113
|
pulse/user_session.py,sha256=FITxLSEl3JU-jod6UWuUYC6EpnPG2rbaLCnIOdkQPtg,7803
|
|
114
|
-
pulse/vdom.py,sha256=
|
|
114
|
+
pulse/vdom.py,sha256=BQov3TqjrEoLwgMTYHHiB4hhbAxeNHxeOFZPv6eKB1o,16075
|
|
115
115
|
pulse/version.py,sha256=711vaM1jVIQPgkisGgKZqwmw019qZIsc_QTae75K2pg,1895
|
|
116
|
-
pulse_framework-0.1.
|
|
117
|
-
pulse_framework-0.1.
|
|
118
|
-
pulse_framework-0.1.
|
|
119
|
-
pulse_framework-0.1.
|
|
116
|
+
pulse_framework-0.1.51.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
|
|
117
|
+
pulse_framework-0.1.51.dist-info/entry_points.txt,sha256=i7aohd3QaPu5IcuGKKvsQQEiMYMe5HcF56QEsaLVO64,46
|
|
118
|
+
pulse_framework-0.1.51.dist-info/METADATA,sha256=eHobxGSJSHVYV0jn6LtVABYkSnhxxcBHiFvi3N2HTSI,580
|
|
119
|
+
pulse_framework-0.1.51.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|