pulse-framework 0.1.60__tar.gz → 0.1.61__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 (125) hide show
  1. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/PKG-INFO +1 -1
  2. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/pyproject.toml +1 -1
  3. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/renderer.py +7 -15
  4. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/vdom.py +2 -1
  5. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/README.md +0 -0
  6. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/__init__.py +0 -0
  7. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/_examples.py +0 -0
  8. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/app.py +0 -0
  9. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/channel.py +0 -0
  10. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/cli/__init__.py +0 -0
  11. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/cli/cmd.py +0 -0
  12. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/cli/dependencies.py +0 -0
  13. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/cli/folder_lock.py +0 -0
  14. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/cli/helpers.py +0 -0
  15. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/cli/logging.py +0 -0
  16. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/cli/models.py +0 -0
  17. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/cli/packages.py +0 -0
  18. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/cli/processes.py +0 -0
  19. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/cli/secrets.py +0 -0
  20. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/cli/uvicorn_log_config.py +0 -0
  21. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/code_analysis.py +0 -0
  22. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/codegen/__init__.py +0 -0
  23. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/codegen/codegen.py +0 -0
  24. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/codegen/templates/__init__.py +0 -0
  25. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/codegen/templates/layout.py +0 -0
  26. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/codegen/templates/route.py +0 -0
  27. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/codegen/templates/routes_ts.py +0 -0
  28. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/codegen/utils.py +0 -0
  29. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/component.py +0 -0
  30. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/components/__init__.py +0 -0
  31. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/components/for_.py +0 -0
  32. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/components/if_.py +0 -0
  33. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/components/react_router.py +0 -0
  34. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/context.py +0 -0
  35. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/cookies.py +0 -0
  36. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/decorators.py +0 -0
  37. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/dom/__init__.py +0 -0
  38. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/dom/elements.py +0 -0
  39. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/dom/events.py +0 -0
  40. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/dom/props.py +0 -0
  41. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/dom/svg.py +0 -0
  42. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/dom/tags.py +0 -0
  43. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/dom/tags.pyi +0 -0
  44. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/env.py +0 -0
  45. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/form.py +0 -0
  46. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/helpers.py +0 -0
  47. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/hooks/__init__.py +0 -0
  48. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/hooks/core.py +0 -0
  49. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/hooks/effects.py +0 -0
  50. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/hooks/init.py +0 -0
  51. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/hooks/runtime.py +0 -0
  52. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/hooks/setup.py +0 -0
  53. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/hooks/stable.py +0 -0
  54. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/hooks/state.py +0 -0
  55. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/__init__.py +0 -0
  56. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/__init__.pyi +0 -0
  57. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/_types.py +0 -0
  58. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/array.py +0 -0
  59. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/console.py +0 -0
  60. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/date.py +0 -0
  61. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/document.py +0 -0
  62. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/error.py +0 -0
  63. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/json.py +0 -0
  64. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/map.py +0 -0
  65. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/math.py +0 -0
  66. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/navigator.py +0 -0
  67. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/number.py +0 -0
  68. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/obj.py +0 -0
  69. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/object.py +0 -0
  70. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/promise.py +0 -0
  71. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/pulse.py +0 -0
  72. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/react.py +0 -0
  73. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/regexp.py +0 -0
  74. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/set.py +0 -0
  75. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/string.py +0 -0
  76. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/weakmap.py +0 -0
  77. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/weakset.py +0 -0
  78. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/js/window.py +0 -0
  79. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/messages.py +0 -0
  80. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/middleware.py +0 -0
  81. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/plugin.py +0 -0
  82. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/proxy.py +0 -0
  83. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/py.typed +0 -0
  84. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/queries/__init__.py +0 -0
  85. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/queries/client.py +0 -0
  86. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/queries/common.py +0 -0
  87. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/queries/effect.py +0 -0
  88. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/queries/infinite_query.py +0 -0
  89. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/queries/mutation.py +0 -0
  90. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/queries/protocol.py +0 -0
  91. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/queries/query.py +0 -0
  92. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/queries/store.py +0 -0
  93. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/react_component.py +0 -0
  94. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/reactive.py +0 -0
  95. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/reactive_extensions.py +0 -0
  96. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/render_session.py +0 -0
  97. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/request.py +0 -0
  98. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/routing.py +0 -0
  99. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/serializer.py +0 -0
  100. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/state.py +0 -0
  101. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/test_helpers.py +0 -0
  102. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/__init__.py +0 -0
  103. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/assets.py +0 -0
  104. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/builtins.py +0 -0
  105. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/dynamic_import.py +0 -0
  106. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/emit_context.py +0 -0
  107. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/errors.py +0 -0
  108. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/function.py +0 -0
  109. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/id.py +0 -0
  110. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/imports.py +0 -0
  111. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/js_module.py +0 -0
  112. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/modules/__init__.py +0 -0
  113. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/modules/asyncio.py +0 -0
  114. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/modules/json.py +0 -0
  115. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/modules/math.py +0 -0
  116. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/modules/pulse/__init__.py +0 -0
  117. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/modules/pulse/tags.py +0 -0
  118. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/modules/typing.py +0 -0
  119. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/nodes.py +0 -0
  120. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/py_module.py +0 -0
  121. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/transpiler/transpiler.py +0 -0
  122. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/types/__init__.py +0 -0
  123. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/types/event_handler.py +0 -0
  124. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/src/pulse/user_session.py +0 -0
  125. {pulse_framework-0.1.60 → pulse_framework-0.1.61}/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.60
3
+ Version: 0.1.61
4
4
  Summary: Pulse - Full-stack framework for building real-time React applications in Python
5
5
  Requires-Dist: websockets>=12.0
6
6
  Requires-Dist: fastapi>=0.128.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pulse-framework"
3
- version = "0.1.60"
3
+ version = "0.1.61"
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.11"
@@ -27,6 +27,7 @@ from pulse.transpiler.vdom import (
27
27
  UpdatePropsDelta,
28
28
  UpdatePropsOperation,
29
29
  VDOMElement,
30
+ VDOMExpr,
30
31
  VDOMNode,
31
32
  VDOMOperation,
32
33
  VDOMPropValue,
@@ -441,26 +442,17 @@ class Renderer:
441
442
  # Expression + tag rendering
442
443
  # ------------------------------------------------------------------
443
444
 
444
- def render_tag(self, tag: str | Expr) -> str:
445
+ def render_tag(self, tag: str | Expr) -> str | VDOMExpr:
445
446
  if isinstance(tag, str):
446
447
  return tag
447
448
 
448
- key = self.register_component_expr(tag)
449
- return f"{MOUNT_PREFIX}{key}"
449
+ return self.register_component_expr(tag)
450
450
 
451
- def register_component_expr(self, expr: Expr) -> str:
451
+ def register_component_expr(self, expr: Expr) -> str | VDOMExpr:
452
452
  ref = registry_ref(expr)
453
- if ref is None:
454
- expr_type = type(expr).__name__
455
- expr_repr = repr(expr)
456
- if len(expr_repr) > 200:
457
- expr_repr = f"{expr_repr[:197]}..."
458
- raise TypeError(
459
- "Component tag expressions must be registry-backed Expr values "
460
- + "(Import/JsFunction/Constant/JsxFunction). "
461
- + f"Got {expr_type}: {expr_repr}"
462
- )
463
- return ref["key"]
453
+ if ref is not None:
454
+ return f"{MOUNT_PREFIX}{ref['key']}"
455
+ return expr.render()
464
456
 
465
457
  # ------------------------------------------------------------------
466
458
  # Unmount helper
@@ -177,9 +177,10 @@ class VDOMElement(TypedDict):
177
177
  Special tags:
178
178
  - "": React Fragment
179
179
  - "$$<ComponentKey>": mount point for client component registry
180
+ - Expr object (VDOMExpr): evaluated on the client for dynamic component tags
180
181
  """
181
182
 
182
- tag: str
183
+ tag: str | VDOMExpr
183
184
  key: NotRequired[str]
184
185
  # Default: plain JSON props (no interpretation).
185
186
  # When `eval` is present, listed keys may contain VDOMExpr / VDOMElement / "$cb:...".