pulse-framework 0.1.62__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.62/PKG-INFO +198 -0
  2. pulse_framework-0.1.62/README.md +178 -0
  3. pulse_framework-0.1.62/pyproject.toml +37 -0
  4. pulse_framework-0.1.62/src/pulse/__init__.py +1493 -0
  5. pulse_framework-0.1.62/src/pulse/_examples.py +29 -0
  6. pulse_framework-0.1.62/src/pulse/app.py +1086 -0
  7. pulse_framework-0.1.62/src/pulse/channel.py +607 -0
  8. pulse_framework-0.1.62/src/pulse/cli/__init__.py +0 -0
  9. pulse_framework-0.1.62/src/pulse/cli/cmd.py +575 -0
  10. pulse_framework-0.1.62/src/pulse/cli/dependencies.py +181 -0
  11. pulse_framework-0.1.62/src/pulse/cli/folder_lock.py +134 -0
  12. pulse_framework-0.1.62/src/pulse/cli/helpers.py +271 -0
  13. pulse_framework-0.1.62/src/pulse/cli/logging.py +102 -0
  14. pulse_framework-0.1.62/src/pulse/cli/models.py +35 -0
  15. pulse_framework-0.1.62/src/pulse/cli/packages.py +262 -0
  16. pulse_framework-0.1.62/src/pulse/cli/processes.py +292 -0
  17. pulse_framework-0.1.62/src/pulse/cli/secrets.py +39 -0
  18. pulse_framework-0.1.62/src/pulse/cli/uvicorn_log_config.py +87 -0
  19. pulse_framework-0.1.62/src/pulse/code_analysis.py +38 -0
  20. pulse_framework-0.1.62/src/pulse/codegen/__init__.py +0 -0
  21. pulse_framework-0.1.62/src/pulse/codegen/codegen.py +359 -0
  22. pulse_framework-0.1.62/src/pulse/codegen/templates/__init__.py +0 -0
  23. pulse_framework-0.1.62/src/pulse/codegen/templates/layout.py +106 -0
  24. pulse_framework-0.1.62/src/pulse/codegen/templates/route.py +345 -0
  25. pulse_framework-0.1.62/src/pulse/codegen/templates/routes_ts.py +42 -0
  26. pulse_framework-0.1.62/src/pulse/codegen/utils.py +20 -0
  27. pulse_framework-0.1.62/src/pulse/component.py +237 -0
  28. pulse_framework-0.1.62/src/pulse/components/__init__.py +0 -0
  29. pulse_framework-0.1.62/src/pulse/components/for_.py +83 -0
  30. pulse_framework-0.1.62/src/pulse/components/if_.py +86 -0
  31. pulse_framework-0.1.62/src/pulse/components/react_router.py +94 -0
  32. pulse_framework-0.1.62/src/pulse/context.py +108 -0
  33. pulse_framework-0.1.62/src/pulse/cookies.py +322 -0
  34. pulse_framework-0.1.62/src/pulse/decorators.py +344 -0
  35. pulse_framework-0.1.62/src/pulse/dom/__init__.py +0 -0
  36. pulse_framework-0.1.62/src/pulse/dom/elements.py +1024 -0
  37. pulse_framework-0.1.62/src/pulse/dom/events.py +445 -0
  38. pulse_framework-0.1.62/src/pulse/dom/props.py +1250 -0
  39. pulse_framework-0.1.62/src/pulse/dom/svg.py +0 -0
  40. pulse_framework-0.1.62/src/pulse/dom/tags.py +328 -0
  41. pulse_framework-0.1.62/src/pulse/dom/tags.pyi +480 -0
  42. pulse_framework-0.1.62/src/pulse/env.py +178 -0
  43. pulse_framework-0.1.62/src/pulse/form.py +538 -0
  44. pulse_framework-0.1.62/src/pulse/helpers.py +541 -0
  45. pulse_framework-0.1.62/src/pulse/hooks/__init__.py +0 -0
  46. pulse_framework-0.1.62/src/pulse/hooks/core.py +452 -0
  47. pulse_framework-0.1.62/src/pulse/hooks/effects.py +88 -0
  48. pulse_framework-0.1.62/src/pulse/hooks/init.py +668 -0
  49. pulse_framework-0.1.62/src/pulse/hooks/runtime.py +464 -0
  50. pulse_framework-0.1.62/src/pulse/hooks/setup.py +254 -0
  51. pulse_framework-0.1.62/src/pulse/hooks/stable.py +138 -0
  52. pulse_framework-0.1.62/src/pulse/hooks/state.py +192 -0
  53. pulse_framework-0.1.62/src/pulse/js/__init__.py +125 -0
  54. pulse_framework-0.1.62/src/pulse/js/__init__.pyi +115 -0
  55. pulse_framework-0.1.62/src/pulse/js/_types.py +299 -0
  56. pulse_framework-0.1.62/src/pulse/js/array.py +339 -0
  57. pulse_framework-0.1.62/src/pulse/js/console.py +50 -0
  58. pulse_framework-0.1.62/src/pulse/js/date.py +119 -0
  59. pulse_framework-0.1.62/src/pulse/js/document.py +145 -0
  60. pulse_framework-0.1.62/src/pulse/js/error.py +140 -0
  61. pulse_framework-0.1.62/src/pulse/js/json.py +66 -0
  62. pulse_framework-0.1.62/src/pulse/js/map.py +97 -0
  63. pulse_framework-0.1.62/src/pulse/js/math.py +69 -0
  64. pulse_framework-0.1.62/src/pulse/js/navigator.py +79 -0
  65. pulse_framework-0.1.62/src/pulse/js/number.py +57 -0
  66. pulse_framework-0.1.62/src/pulse/js/obj.py +81 -0
  67. pulse_framework-0.1.62/src/pulse/js/object.py +172 -0
  68. pulse_framework-0.1.62/src/pulse/js/promise.py +172 -0
  69. pulse_framework-0.1.62/src/pulse/js/pulse.py +115 -0
  70. pulse_framework-0.1.62/src/pulse/js/react.py +495 -0
  71. pulse_framework-0.1.62/src/pulse/js/regexp.py +57 -0
  72. pulse_framework-0.1.62/src/pulse/js/set.py +124 -0
  73. pulse_framework-0.1.62/src/pulse/js/string.py +38 -0
  74. pulse_framework-0.1.62/src/pulse/js/weakmap.py +53 -0
  75. pulse_framework-0.1.62/src/pulse/js/weakset.py +48 -0
  76. pulse_framework-0.1.62/src/pulse/js/window.py +205 -0
  77. pulse_framework-0.1.62/src/pulse/messages.py +202 -0
  78. pulse_framework-0.1.62/src/pulse/middleware.py +471 -0
  79. pulse_framework-0.1.62/src/pulse/plugin.py +96 -0
  80. pulse_framework-0.1.62/src/pulse/proxy.py +242 -0
  81. pulse_framework-0.1.62/src/pulse/py.typed +0 -0
  82. pulse_framework-0.1.62/src/pulse/queries/__init__.py +0 -0
  83. pulse_framework-0.1.62/src/pulse/queries/client.py +609 -0
  84. pulse_framework-0.1.62/src/pulse/queries/common.py +101 -0
  85. pulse_framework-0.1.62/src/pulse/queries/effect.py +55 -0
  86. pulse_framework-0.1.62/src/pulse/queries/infinite_query.py +1418 -0
  87. pulse_framework-0.1.62/src/pulse/queries/mutation.py +295 -0
  88. pulse_framework-0.1.62/src/pulse/queries/protocol.py +136 -0
  89. pulse_framework-0.1.62/src/pulse/queries/query.py +1314 -0
  90. pulse_framework-0.1.62/src/pulse/queries/store.py +120 -0
  91. pulse_framework-0.1.62/src/pulse/react_component.py +88 -0
  92. pulse_framework-0.1.62/src/pulse/reactive.py +1208 -0
  93. pulse_framework-0.1.62/src/pulse/reactive_extensions.py +1172 -0
  94. pulse_framework-0.1.62/src/pulse/render_session.py +768 -0
  95. pulse_framework-0.1.62/src/pulse/renderer.py +584 -0
  96. pulse_framework-0.1.62/src/pulse/request.py +205 -0
  97. pulse_framework-0.1.62/src/pulse/routing.py +598 -0
  98. pulse_framework-0.1.62/src/pulse/serializer.py +279 -0
  99. pulse_framework-0.1.62/src/pulse/state.py +556 -0
  100. pulse_framework-0.1.62/src/pulse/test_helpers.py +15 -0
  101. pulse_framework-0.1.62/src/pulse/transpiler/__init__.py +111 -0
  102. pulse_framework-0.1.62/src/pulse/transpiler/assets.py +81 -0
  103. pulse_framework-0.1.62/src/pulse/transpiler/builtins.py +1029 -0
  104. pulse_framework-0.1.62/src/pulse/transpiler/dynamic_import.py +130 -0
  105. pulse_framework-0.1.62/src/pulse/transpiler/emit_context.py +49 -0
  106. pulse_framework-0.1.62/src/pulse/transpiler/errors.py +96 -0
  107. pulse_framework-0.1.62/src/pulse/transpiler/function.py +611 -0
  108. pulse_framework-0.1.62/src/pulse/transpiler/id.py +18 -0
  109. pulse_framework-0.1.62/src/pulse/transpiler/imports.py +341 -0
  110. pulse_framework-0.1.62/src/pulse/transpiler/js_module.py +336 -0
  111. pulse_framework-0.1.62/src/pulse/transpiler/modules/__init__.py +33 -0
  112. pulse_framework-0.1.62/src/pulse/transpiler/modules/asyncio.py +57 -0
  113. pulse_framework-0.1.62/src/pulse/transpiler/modules/json.py +24 -0
  114. pulse_framework-0.1.62/src/pulse/transpiler/modules/math.py +265 -0
  115. pulse_framework-0.1.62/src/pulse/transpiler/modules/pulse/__init__.py +5 -0
  116. pulse_framework-0.1.62/src/pulse/transpiler/modules/pulse/tags.py +250 -0
  117. pulse_framework-0.1.62/src/pulse/transpiler/modules/typing.py +63 -0
  118. pulse_framework-0.1.62/src/pulse/transpiler/nodes.py +1987 -0
  119. pulse_framework-0.1.62/src/pulse/transpiler/py_module.py +135 -0
  120. pulse_framework-0.1.62/src/pulse/transpiler/transpiler.py +1100 -0
  121. pulse_framework-0.1.62/src/pulse/transpiler/vdom.py +256 -0
  122. pulse_framework-0.1.62/src/pulse/types/__init__.py +0 -0
  123. pulse_framework-0.1.62/src/pulse/types/event_handler.py +50 -0
  124. pulse_framework-0.1.62/src/pulse/user_session.py +386 -0
  125. pulse_framework-0.1.62/src/pulse/version.py +69 -0
@@ -0,0 +1,198 @@
1
+ Metadata-Version: 2.3
2
+ Name: pulse-framework
3
+ Version: 0.1.62
4
+ Summary: Pulse - Full-stack framework for building real-time React applications in Python
5
+ Requires-Dist: websockets>=12.0
6
+ Requires-Dist: fastapi>=0.128.0
7
+ Requires-Dist: uvicorn>=0.24.0
8
+ Requires-Dist: mako>=1.3.10
9
+ Requires-Dist: typer>=0.16.0
10
+ Requires-Dist: python-socketio>=5.16.0
11
+ Requires-Dist: rich>=13.7.1
12
+ Requires-Dist: python-multipart>=0.0.20
13
+ Requires-Dist: python-dateutil>=2.9.0.post0
14
+ Requires-Dist: starlette>=0.50.0,<0.51.0
15
+ Requires-Dist: urllib3>=2.6.3
16
+ Requires-Dist: watchfiles>=1.1.0
17
+ Requires-Dist: httpx>=0.28.1
18
+ Requires-Python: >=3.11
19
+ Description-Content-Type: text/markdown
20
+
21
+ # Pulse Python
22
+
23
+ Core Python framework for building full-stack reactive web apps with React frontends.
24
+
25
+ ## Architecture
26
+
27
+ Server-driven UI model: Python components render to VDOM, synced to React via WebSocket. State changes trigger re-renders; diffs are sent to client.
28
+
29
+ ```
30
+ ┌─────────────────────────────────────────────────────────────────┐
31
+ │ Python Server │
32
+ │ ┌──────────┐ ┌───────────────┐ ┌──────────────────────────┐ │
33
+ │ │ App │──│ RenderSession │──│ VDOM Renderer │ │
34
+ │ │ (FastAPI)│ │ (per browser) │ │ (diff & serialize) │ │
35
+ │ └──────────┘ └───────────────┘ └──────────────────────────┘ │
36
+ │ │ │ │ │
37
+ │ │ ┌──────┴───────┐ │ │
38
+ │ │ │ Hooks │ │ │
39
+ │ │ │ (state/setup)│ │ │
40
+ │ │ └──────────────┘ │ │
41
+ └───────┼───────────────────────────────────────┼─────────────────┘
42
+ │ Socket.IO │ VDOM updates
43
+ ▼ ▼
44
+ ┌─────────────────────────────────────────────────────────────────┐
45
+ │ Browser (React) │
46
+ └─────────────────────────────────────────────────────────────────┘
47
+ ```
48
+
49
+ ## Folder Structure
50
+
51
+ ```
52
+ src/pulse/
53
+ ├── app.py # Main App class, FastAPI + Socket.IO setup
54
+ ├── channel.py # Bidirectional real-time channels
55
+ ├── routing.py # Route/Layout definitions, URL matching
56
+ ├── vdom.py # VDOM node types (Element, Component, Node)
57
+ ├── renderer.py # VDOM rendering and diffing
58
+ ├── render_session.py # Per-browser session, manages mounted routes
59
+ ├── reactive.py # Signal/Computed/Effect primitives
60
+ ├── reactive_extensions.py # ReactiveList, ReactiveDict, ReactiveSet
61
+ ├── state.py # State management
62
+ ├── serializer.py # Python<->JSON serialization
63
+ ├── middleware.py # Request middleware (prerender, connect, message)
64
+ ├── plugin.py # Plugin interface for extensions
65
+ ├── form.py # Form handling
66
+ ├── context.py # PulseContext (request/session context)
67
+ ├── cookies.py # Cookie management
68
+ ├── request.py # PulseRequest abstraction
69
+ ├── user_session.py # User session storage
70
+ ├── helpers.py # Utilities (CSSProperties, later, repeat)
71
+ ├── decorators.py # @computed, @effect decorators
72
+ ├── messages.py # Client<->server message types
73
+ ├── react_component.py # ReactComponent wrapper for JS libraries
74
+
75
+ ├── hooks/ # Server-side hooks (like React hooks)
76
+ │ ├── core.py # Hook registry, HooksAPI
77
+ │ ├── runtime.py # session(), route(), navigate(), redirect()
78
+ │ ├── states.py # Reactive state hook
79
+ │ ├── effects.py # Side effects hook
80
+ │ ├── setup.py # Initialization hook
81
+ │ ├── init.py # One-time setup hook
82
+ │ └── stable.py # Memoization hook
83
+
84
+ ├── queries/ # Data fetching (like TanStack Query)
85
+ │ ├── query.py # @query decorator
86
+ │ ├── mutation.py # @mutation decorator
87
+ │ ├── infinite_query.py # Pagination support
88
+ │ ├── client.py # QueryClient for cache management
89
+ │ └── store.py # Query state store
90
+
91
+ ├── components/ # Built-in components
92
+ │ ├── for_.py # <For> loop component
93
+ │ ├── if_.py # <If> conditional component
94
+ │ └── react_router.py # Link, Outlet for routing
95
+
96
+ ├── html/ # HTML element bindings
97
+ │ ├── tags.py # div, span, button, etc.
98
+ │ ├── props.py # Typed props for HTML elements
99
+ │ ├── events.py # Event types (MouseEvent, etc.)
100
+ │ └── elements.py # Element type definitions
101
+
102
+ ├── transpiler/ # Python->JS transpilation
103
+ │ ├── function.py # JsFunction, @javascript decorator
104
+ │ └── imports.py # Import/CssImport for client-side JS
105
+
106
+ ├── codegen/ # Code generation for React Router
107
+ │ ├── codegen.py # Generates routes.ts, loaders
108
+ │ └── templates/ # Mako templates for generated code
109
+
110
+ ├── cli/ # Command-line interface
111
+ │ ├── cmd.py # pulse run, pulse build
112
+ │ └── processes.py # Dev server process management
113
+
114
+ └── js/ # JS API stubs for transpilation
115
+ ├── window.py, document.py, navigator.py
116
+ ├── array.py, object.py, string.py
117
+ └── ...
118
+ ```
119
+
120
+ ## Key Concepts
121
+
122
+ ### App
123
+
124
+ Entry point defining routes, middleware, plugins.
125
+
126
+ ```python
127
+ import pulse as ps
128
+
129
+ app = ps.App(routes=[
130
+ ps.Route("/", home),
131
+ ps.Layout("/dashboard", layout, children=[
132
+ ps.Route("/", dashboard),
133
+ ]),
134
+ ])
135
+ ```
136
+
137
+ ### Components
138
+
139
+ Functions returning VDOM. Use `@ps.component` for stateful components.
140
+
141
+ ```python
142
+ def greeting(name: str):
143
+ return ps.div(f"Hello, {name}!")
144
+
145
+ @ps.component
146
+ def counter():
147
+ count = ps.states.use(0)
148
+ return ps.button(f"Count: {count()}", onClick=lambda _: count.set(count() + 1))
149
+ ```
150
+
151
+ ### Reactivity
152
+
153
+ - `Signal[T]` - reactive value
154
+ - `Computed[T]` - derived value
155
+ - `Effect` - side effect on change
156
+
157
+ ### Hooks
158
+
159
+ Server-side hooks via `ps.state`, `ps.effect`, `ps.setup`:
160
+ - `ps.state(StateClass)` - reactive state (auto-keyed by callsite; use `key=` for manual control)
161
+ - `@ps.effect` - side effects decorator
162
+ - `ps.setup(fn)` - one-time initialization
163
+
164
+ ### Queries
165
+
166
+ Data fetching with caching:
167
+
168
+ ```python
169
+ @ps.query
170
+ async def fetch_user(id: str):
171
+ return await db.get_user(id)
172
+ ```
173
+
174
+ ### Channels
175
+
176
+ Bidirectional real-time messaging:
177
+
178
+ ```python
179
+ ch = ps.channel("chat")
180
+
181
+ @ch.on("message")
182
+ def handle_message(data):
183
+ ch.broadcast("new_message", data)
184
+ ```
185
+
186
+ ## Main Exports
187
+
188
+ - `App`, `Route`, `Layout` - app/routing
189
+ - `component` - server-side component decorator
190
+ - `states`, `effects`, `setup`, `init` - hooks
191
+ - `query`, `mutation`, `infinite_query` - data fetching
192
+ - `channel` - real-time channels
193
+ - `State`, `@computed`, `@effect` - reactivity
194
+ - `ReactiveList`, `ReactiveDict`, `ReactiveSet` - reactive containers
195
+ - `div`, `span`, `button`, ... - HTML elements
196
+ - `For`, `If`, `Link`, `Outlet` - built-in components
197
+ - `@react_component` - wrap JS components
198
+ - `@javascript` - transpile Python to JS
@@ -0,0 +1,178 @@
1
+ # Pulse Python
2
+
3
+ Core Python framework for building full-stack reactive web apps with React frontends.
4
+
5
+ ## Architecture
6
+
7
+ Server-driven UI model: Python components render to VDOM, synced to React via WebSocket. State changes trigger re-renders; diffs are sent to client.
8
+
9
+ ```
10
+ ┌─────────────────────────────────────────────────────────────────┐
11
+ │ Python Server │
12
+ │ ┌──────────┐ ┌───────────────┐ ┌──────────────────────────┐ │
13
+ │ │ App │──│ RenderSession │──│ VDOM Renderer │ │
14
+ │ │ (FastAPI)│ │ (per browser) │ │ (diff & serialize) │ │
15
+ │ └──────────┘ └───────────────┘ └──────────────────────────┘ │
16
+ │ │ │ │ │
17
+ │ │ ┌──────┴───────┐ │ │
18
+ │ │ │ Hooks │ │ │
19
+ │ │ │ (state/setup)│ │ │
20
+ │ │ └──────────────┘ │ │
21
+ └───────┼───────────────────────────────────────┼─────────────────┘
22
+ │ Socket.IO │ VDOM updates
23
+ ▼ ▼
24
+ ┌─────────────────────────────────────────────────────────────────┐
25
+ │ Browser (React) │
26
+ └─────────────────────────────────────────────────────────────────┘
27
+ ```
28
+
29
+ ## Folder Structure
30
+
31
+ ```
32
+ src/pulse/
33
+ ├── app.py # Main App class, FastAPI + Socket.IO setup
34
+ ├── channel.py # Bidirectional real-time channels
35
+ ├── routing.py # Route/Layout definitions, URL matching
36
+ ├── vdom.py # VDOM node types (Element, Component, Node)
37
+ ├── renderer.py # VDOM rendering and diffing
38
+ ├── render_session.py # Per-browser session, manages mounted routes
39
+ ├── reactive.py # Signal/Computed/Effect primitives
40
+ ├── reactive_extensions.py # ReactiveList, ReactiveDict, ReactiveSet
41
+ ├── state.py # State management
42
+ ├── serializer.py # Python<->JSON serialization
43
+ ├── middleware.py # Request middleware (prerender, connect, message)
44
+ ├── plugin.py # Plugin interface for extensions
45
+ ├── form.py # Form handling
46
+ ├── context.py # PulseContext (request/session context)
47
+ ├── cookies.py # Cookie management
48
+ ├── request.py # PulseRequest abstraction
49
+ ├── user_session.py # User session storage
50
+ ├── helpers.py # Utilities (CSSProperties, later, repeat)
51
+ ├── decorators.py # @computed, @effect decorators
52
+ ├── messages.py # Client<->server message types
53
+ ├── react_component.py # ReactComponent wrapper for JS libraries
54
+
55
+ ├── hooks/ # Server-side hooks (like React hooks)
56
+ │ ├── core.py # Hook registry, HooksAPI
57
+ │ ├── runtime.py # session(), route(), navigate(), redirect()
58
+ │ ├── states.py # Reactive state hook
59
+ │ ├── effects.py # Side effects hook
60
+ │ ├── setup.py # Initialization hook
61
+ │ ├── init.py # One-time setup hook
62
+ │ └── stable.py # Memoization hook
63
+
64
+ ├── queries/ # Data fetching (like TanStack Query)
65
+ │ ├── query.py # @query decorator
66
+ │ ├── mutation.py # @mutation decorator
67
+ │ ├── infinite_query.py # Pagination support
68
+ │ ├── client.py # QueryClient for cache management
69
+ │ └── store.py # Query state store
70
+
71
+ ├── components/ # Built-in components
72
+ │ ├── for_.py # <For> loop component
73
+ │ ├── if_.py # <If> conditional component
74
+ │ └── react_router.py # Link, Outlet for routing
75
+
76
+ ├── html/ # HTML element bindings
77
+ │ ├── tags.py # div, span, button, etc.
78
+ │ ├── props.py # Typed props for HTML elements
79
+ │ ├── events.py # Event types (MouseEvent, etc.)
80
+ │ └── elements.py # Element type definitions
81
+
82
+ ├── transpiler/ # Python->JS transpilation
83
+ │ ├── function.py # JsFunction, @javascript decorator
84
+ │ └── imports.py # Import/CssImport for client-side JS
85
+
86
+ ├── codegen/ # Code generation for React Router
87
+ │ ├── codegen.py # Generates routes.ts, loaders
88
+ │ └── templates/ # Mako templates for generated code
89
+
90
+ ├── cli/ # Command-line interface
91
+ │ ├── cmd.py # pulse run, pulse build
92
+ │ └── processes.py # Dev server process management
93
+
94
+ └── js/ # JS API stubs for transpilation
95
+ ├── window.py, document.py, navigator.py
96
+ ├── array.py, object.py, string.py
97
+ └── ...
98
+ ```
99
+
100
+ ## Key Concepts
101
+
102
+ ### App
103
+
104
+ Entry point defining routes, middleware, plugins.
105
+
106
+ ```python
107
+ import pulse as ps
108
+
109
+ app = ps.App(routes=[
110
+ ps.Route("/", home),
111
+ ps.Layout("/dashboard", layout, children=[
112
+ ps.Route("/", dashboard),
113
+ ]),
114
+ ])
115
+ ```
116
+
117
+ ### Components
118
+
119
+ Functions returning VDOM. Use `@ps.component` for stateful components.
120
+
121
+ ```python
122
+ def greeting(name: str):
123
+ return ps.div(f"Hello, {name}!")
124
+
125
+ @ps.component
126
+ def counter():
127
+ count = ps.states.use(0)
128
+ return ps.button(f"Count: {count()}", onClick=lambda _: count.set(count() + 1))
129
+ ```
130
+
131
+ ### Reactivity
132
+
133
+ - `Signal[T]` - reactive value
134
+ - `Computed[T]` - derived value
135
+ - `Effect` - side effect on change
136
+
137
+ ### Hooks
138
+
139
+ Server-side hooks via `ps.state`, `ps.effect`, `ps.setup`:
140
+ - `ps.state(StateClass)` - reactive state (auto-keyed by callsite; use `key=` for manual control)
141
+ - `@ps.effect` - side effects decorator
142
+ - `ps.setup(fn)` - one-time initialization
143
+
144
+ ### Queries
145
+
146
+ Data fetching with caching:
147
+
148
+ ```python
149
+ @ps.query
150
+ async def fetch_user(id: str):
151
+ return await db.get_user(id)
152
+ ```
153
+
154
+ ### Channels
155
+
156
+ Bidirectional real-time messaging:
157
+
158
+ ```python
159
+ ch = ps.channel("chat")
160
+
161
+ @ch.on("message")
162
+ def handle_message(data):
163
+ ch.broadcast("new_message", data)
164
+ ```
165
+
166
+ ## Main Exports
167
+
168
+ - `App`, `Route`, `Layout` - app/routing
169
+ - `component` - server-side component decorator
170
+ - `states`, `effects`, `setup`, `init` - hooks
171
+ - `query`, `mutation`, `infinite_query` - data fetching
172
+ - `channel` - real-time channels
173
+ - `State`, `@computed`, `@effect` - reactivity
174
+ - `ReactiveList`, `ReactiveDict`, `ReactiveSet` - reactive containers
175
+ - `div`, `span`, `button`, ... - HTML elements
176
+ - `For`, `If`, `Link`, `Outlet` - built-in components
177
+ - `@react_component` - wrap JS components
178
+ - `@javascript` - transpile Python to JS
@@ -0,0 +1,37 @@
1
+ [project]
2
+ name = "pulse-framework"
3
+ version = "0.1.62"
4
+ description = "Pulse - Full-stack framework for building real-time React applications in Python"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ dependencies = [
8
+ "websockets>=12.0",
9
+ "fastapi>=0.128.0",
10
+ "uvicorn>=0.24.0",
11
+ "mako>=1.3.10",
12
+ "typer>=0.16.0",
13
+ "python-socketio>=5.16.0",
14
+ "rich>=13.7.1",
15
+ "python-multipart>=0.0.20",
16
+ "python-dateutil>=2.9.0.post0",
17
+ "starlette>=0.50.0,<0.51.0",
18
+ "urllib3>=2.6.3",
19
+ "watchfiles>=1.1.0",
20
+ "httpx>=0.28.1",
21
+ ]
22
+
23
+ [tool.uv]
24
+ package = true
25
+
26
+ [tool.uv.build-backend]
27
+ module-name = "pulse"
28
+
29
+ [project.scripts]
30
+ pulse = "pulse.cli.cmd:main"
31
+
32
+ [dependency-groups]
33
+ dev = ["mypy>=1.17.0", "pytest>=8.3.4", "pytest-asyncio>=1.1.0"]
34
+
35
+ [build-system]
36
+ requires = ["uv_build>=0.8.13,<0.9.0"]
37
+ build-backend = "uv_build"