pulse-framework 0.1.75__tar.gz → 0.1.76__tar.gz

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.
Files changed (150) hide show
  1. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/PKG-INFO +1 -1
  2. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/pyproject.toml +1 -1
  3. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/__init__.py +12 -0
  4. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/channel.py +6 -3
  5. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/dom/props.py +2 -0
  6. pulse_framework-0.1.76/src/pulse/refs.py +893 -0
  7. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/render_session.py +27 -0
  8. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/renderer.py +23 -1
  9. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/vdom.py +12 -1
  10. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/README.md +0 -0
  11. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/_examples.py +0 -0
  12. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/app.py +0 -0
  13. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/cli/__init__.py +0 -0
  14. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/cli/cmd.py +0 -0
  15. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/cli/dependencies.py +0 -0
  16. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/cli/folder_lock.py +0 -0
  17. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/cli/helpers.py +0 -0
  18. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/cli/logging.py +0 -0
  19. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/cli/models.py +0 -0
  20. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/cli/packages.py +0 -0
  21. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/cli/processes.py +0 -0
  22. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/cli/secrets.py +0 -0
  23. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/cli/uvicorn_log_config.py +0 -0
  24. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/code_analysis.py +0 -0
  25. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/codegen/__init__.py +0 -0
  26. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/codegen/codegen.py +0 -0
  27. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/codegen/templates/__init__.py +0 -0
  28. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/codegen/templates/layout.py +0 -0
  29. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/codegen/templates/route.py +0 -0
  30. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/codegen/templates/routes_ts.py +0 -0
  31. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/codegen/utils.py +0 -0
  32. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/component.py +0 -0
  33. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/components/__init__.py +0 -0
  34. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/components/for_.py +0 -0
  35. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/components/if_.py +0 -0
  36. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/components/react_router.py +0 -0
  37. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/context.py +0 -0
  38. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/cookies.py +0 -0
  39. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/debounce.py +0 -0
  40. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/decorators.py +0 -0
  41. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/dom/__init__.py +0 -0
  42. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/dom/elements.py +0 -0
  43. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/dom/events.py +0 -0
  44. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/dom/svg.py +0 -0
  45. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/dom/tags.py +0 -0
  46. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/dom/tags.pyi +0 -0
  47. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/env.py +0 -0
  48. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/forms.py +0 -0
  49. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/helpers.py +0 -0
  50. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/hooks/__init__.py +0 -0
  51. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/hooks/core.py +0 -0
  52. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/hooks/effects.py +0 -0
  53. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/hooks/init.py +0 -0
  54. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/hooks/runtime.py +0 -0
  55. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/hooks/setup.py +0 -0
  56. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/hooks/stable.py +0 -0
  57. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/hooks/state.py +0 -0
  58. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/__init__.py +0 -0
  59. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/__init__.pyi +0 -0
  60. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/_types.py +0 -0
  61. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/abort_controller.py +0 -0
  62. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/array.py +0 -0
  63. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/array_buffer.py +0 -0
  64. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/blob.py +0 -0
  65. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/console.py +0 -0
  66. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/crypto.py +0 -0
  67. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/custom_event.py +0 -0
  68. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/date.py +0 -0
  69. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/document.py +0 -0
  70. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/dom_parser.py +0 -0
  71. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/error.py +0 -0
  72. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/fetch_api.py +0 -0
  73. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/file.py +0 -0
  74. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/file_reader.py +0 -0
  75. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/form_data.py +0 -0
  76. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/intersection_observer.py +0 -0
  77. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/intl.py +0 -0
  78. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/json.py +0 -0
  79. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/map.py +0 -0
  80. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/math.py +0 -0
  81. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/mutation_observer.py +0 -0
  82. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/navigator.py +0 -0
  83. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/number.py +0 -0
  84. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/obj.py +0 -0
  85. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/object.py +0 -0
  86. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/performance_observer.py +0 -0
  87. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/promise.py +0 -0
  88. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/pulse.py +0 -0
  89. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/react.py +0 -0
  90. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/regexp.py +0 -0
  91. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/resize_observer.py +0 -0
  92. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/set.py +0 -0
  93. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/string.py +0 -0
  94. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/text_encoding.py +0 -0
  95. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/url.py +0 -0
  96. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/weakmap.py +0 -0
  97. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/weakset.py +0 -0
  98. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/js/window.py +0 -0
  99. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/messages.py +0 -0
  100. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/middleware.py +0 -0
  101. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/plugin.py +0 -0
  102. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/proxy.py +0 -0
  103. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/py.typed +0 -0
  104. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/queries/__init__.py +0 -0
  105. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/queries/client.py +0 -0
  106. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/queries/common.py +0 -0
  107. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/queries/effect.py +0 -0
  108. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/queries/infinite_query.py +0 -0
  109. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/queries/mutation.py +0 -0
  110. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/queries/protocol.py +0 -0
  111. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/queries/query.py +0 -0
  112. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/queries/store.py +0 -0
  113. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/react_component.py +0 -0
  114. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/reactive.py +0 -0
  115. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/reactive_extensions.py +0 -0
  116. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/request.py +0 -0
  117. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/requirements.py +0 -0
  118. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/routing.py +0 -0
  119. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/scheduling.py +0 -0
  120. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/serializer.py +0 -0
  121. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/state/__init__.py +0 -0
  122. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/state/property.py +0 -0
  123. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/state/query_param.py +0 -0
  124. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/state/state.py +0 -0
  125. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/test_helpers.py +0 -0
  126. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/__init__.py +0 -0
  127. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/assets.py +0 -0
  128. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/builtins.py +0 -0
  129. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/dynamic_import.py +0 -0
  130. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/emit_context.py +0 -0
  131. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/errors.py +0 -0
  132. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/function.py +0 -0
  133. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/id.py +0 -0
  134. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/imports.py +0 -0
  135. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/js_module.py +0 -0
  136. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/modules/__init__.py +0 -0
  137. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/modules/asyncio.py +0 -0
  138. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/modules/json.py +0 -0
  139. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/modules/math.py +0 -0
  140. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/modules/pulse/__init__.py +0 -0
  141. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/modules/pulse/tags.py +0 -0
  142. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/modules/typing.py +0 -0
  143. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/nodes.py +0 -0
  144. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/parse.py +0 -0
  145. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/py_module.py +0 -0
  146. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/transpiler/transpiler.py +0 -0
  147. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/types/__init__.py +0 -0
  148. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/types/event_handler.py +0 -0
  149. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/user_session.py +0 -0
  150. {pulse_framework-0.1.75 → pulse_framework-0.1.76}/src/pulse/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pulse-framework
3
- Version: 0.1.75
3
+ Version: 0.1.76
4
4
  Summary: Pulse - Full-stack framework for building real-time React applications in Python
5
5
  Requires-Dist: fastapi>=0.128.0
6
6
  Requires-Dist: uvicorn>=0.24.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pulse-framework"
3
- version = "0.1.75"
3
+ version = "0.1.76"
4
4
  description = "Pulse - Full-stack framework for building real-time React applications in Python"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -1409,6 +1409,18 @@ from pulse.reactive_extensions import (
1409
1409
  from pulse.reactive_extensions import (
1410
1410
  unwrap as unwrap,
1411
1411
  )
1412
+ from pulse.refs import (
1413
+ RefHandle as RefHandle,
1414
+ )
1415
+ from pulse.refs import (
1416
+ RefNotMounted as RefNotMounted,
1417
+ )
1418
+ from pulse.refs import (
1419
+ RefTimeout as RefTimeout,
1420
+ )
1421
+ from pulse.refs import (
1422
+ ref as ref,
1423
+ )
1412
1424
 
1413
1425
  # JavaScript execution
1414
1426
  from pulse.render_session import JsExecError as JsExecError
@@ -81,7 +81,9 @@ class ChannelsManager:
81
81
  self.pending_requests = {}
82
82
 
83
83
  # ------------------------------------------------------------------
84
- def create(self, identifier: str | None = None) -> "Channel":
84
+ def create(
85
+ self, identifier: str | None = None, *, bind_route: bool = True
86
+ ) -> "Channel":
85
87
  ctx = PulseContext.get()
86
88
  render = ctx.render
87
89
  session = ctx.session
@@ -93,7 +95,7 @@ class ChannelsManager:
93
95
  raise ValueError(f"Channel id '{channel_id}' is already in use")
94
96
 
95
97
  route_path: str | None = None
96
- if ctx.route is not None:
98
+ if bind_route and ctx.route is not None:
97
99
  # unique_path() returns absolute path, use as-is for keys
98
100
  route_path = ctx.route.pulse_route.unique_path()
99
101
 
@@ -129,7 +131,8 @@ class ChannelsManager:
129
131
  if not response_to:
130
132
  return
131
133
 
132
- if error := message.get("error") is not None:
134
+ error = message.get("error")
135
+ if error is not None:
133
136
  self.resolve_pending_error(response_to, error)
134
137
  else:
135
138
  self._resolve_pending_success(response_to, message.get("payload"))
@@ -68,6 +68,7 @@ from pulse.dom.events import (
68
68
  TextAreaDOMEvents,
69
69
  )
70
70
  from pulse.helpers import CSSProperties
71
+ from pulse.refs import RefHandle
71
72
  from pulse.transpiler.nodes import Expr
72
73
 
73
74
  Booleanish = Literal[True, False, "true", "false"]
@@ -82,6 +83,7 @@ class BaseHTMLProps(TypedDict, total=False):
82
83
  defaultValue: str | int | list[str]
83
84
  suppressContentEditableWarning: bool
84
85
  suppressHydrationWarning: bool
86
+ ref: RefHandle[Any]
85
87
 
86
88
  # Standard HTML Attributes
87
89
  accessKey: str