### Start Development Server with npm
Source: https://github.com/erwinkn/pulse-ui/blob/main/examples/pulse-mantine/web/README.md
Starts the development server, allowing for live reloading and immediate feedback during development. This command is typically used for local development and testing.
```bash
npm run dev
```
--------------------------------
### Install Dependencies with npm
Source: https://github.com/erwinkn/pulse-ui/blob/main/examples/pulse-mantine/web/README.md
Installs all necessary project dependencies using the npm package manager. This is a prerequisite for running the development server or building the project.
```bash
npm install
```
--------------------------------
### Example Pulse App Initialization and Run
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/reference/pulse/app.mdx
Demonstrates how to create a Pulse application instance with defined routes and session timeout, and then run the development server. This example utilizes the `pulse` library for application setup.
```python
import pulse as ps
app = ps.App(
routes=[
ps.Route("/", render=home),
ps.Route("/users/:id", render=user_detail),
],
session_timeout=120.0,
)
if __name__ == "__main__":
app.run(port=8000)
```
--------------------------------
### Quick Start: Pulse App Initialization
Source: https://github.com/erwinkn/pulse-ui/blob/main/skills/pulse/SKILL.md
Demonstrates the basic structure of a Pulse application, including state management and component definition. This example shows how to initialize a stateful component and render it within a simple application structure.
```python
import pulse as ps
class Counter(ps.State):
count: int = 0
def increment(self):
self.count += 1
@ps.component
def App():
with ps.init():
state = Counter()
return ps.div(
ps.button("Click", onClick=state.increment),
ps.span(f"Count: {state.count}"),
)
app = ps.App([ps.Route("/", App)])
```
--------------------------------
### Quick Start: Pulse UI Client React App Setup
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/reference/pulse-client/index.mdx
This TypeScript example demonstrates a minimal React application setup using pulse-ui-client. It includes PulseProvider for connection management and PulseView for rendering UI components from a Pulse backend.
```tsx
import { PulseProvider, PulseView } from "pulse-ui-client";
import { BrowserRouter, Routes, Route } from "react-router";
// Component registry for custom mount points
const registry = {
MyButton: (props) => ,
};
function App() {
return (
} />
);
}
```
--------------------------------
### Initialize Python Project and Add Pulse Framework
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/(core)/setup.mdx
Commands to create a new directory, navigate into it, initialize a Python project using uv, add the pulse-framework, and sync dependencies.
```bash
mkdir my-pulse-app
cd my-pulse-app
uv init
uv add pulse-framework
uv sync
```
--------------------------------
### Run Pulse Application
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/(core)/setup.mdx
Command to start the Pulse development server. This command generates React routes based on Python components and launches the React Router development server.
```bash
uv run pulse run app.py
```
--------------------------------
### Scaffold React Router Frontend
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/(core)/setup.mdx
Commands to create a new React Router application in a 'web/' directory using 'create-react-router' with the 'react-router-serve' template, followed by installing dependencies.
```bash
bunx create-react-router@latest web --template react-router-serve
cd web
bun install
cd ..
```
--------------------------------
### Setup Pulse UI (`ps.setup`)
Source: https://github.com/erwinkn/pulse-ui/blob/main/skills/pulse/references/hooks.md
Performs one-time setup for Pulse UI, with support for re-running setup using a `setup_key`. Includes cleanup mechanisms.
```javascript
ps.setup();
// Or with a setup key
ps.setup(setup_key());
```
--------------------------------
### Full Application Routing Example in Python
Source: https://github.com/erwinkn/pulse-ui/blob/main/skills/pulse/references/routing.md
Presents a comprehensive example of setting up application-wide routing in Pulse UI. It includes layout components, nested routes with dynamic parameters, and basic navigation links.
```python
import pulse as ps
@ps.component
def AppLayout():
return ps.div(
ps.nav(
ps.Link("Home", to="/"),
ps.Link("Users", to="/users"),
),
ps.main(ps.Outlet()),
)
@ps.component
def home():
return ps.h1("Welcome")
@ps.component
def users_list():
return ps.div(
ps.h1("Users"),
ps.Link("View User 1", to="/users/1"),
ps.Outlet(),
)
@ps.component
def user_detail():
ctx = ps.route()
user_id = ctx.pathParams["id"]
tab = ctx.pathParams.get("tab", "profile")
return ps.div(f"User {user_id} - {tab}")
app = ps.App(
routes=[
ps.Layout(
render=AppLayout,
children=[
ps.Route("/", render=home),
ps.Route(
"/users",
render=users_list,
children=[
ps.Route(":id", render=user_detail),
ps.Route(":id/:tab", render=user_detail),
],
),
],
)
]
)
```
--------------------------------
### Multiple Middleware Example in Pulse UI (Python)
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/(core)/tutorial/12-sessions-middleware.mdx
Illustrates a more complex middleware setup with custom `TimingMiddleware` and `RateLimitMiddleware` classes. These custom middlewares inherit from `ps.PulseMiddleware` and demonstrate how middleware chains execute in a defined order.
```python
class TimingMiddleware(ps.PulseMiddleware):
async def connect(self, *, request, session, next):
import time
start = time.time()
result = await next()
elapsed = time.time() - start
print(f"Request took {elapsed:.2f}s")
return result
class RateLimitMiddleware(ps.PulseMiddleware):
async def connect(self, *, request, session, next):
# Simple rate limiting (you'd use a proper solution in production)
recent_requests = session.get("recent_requests", 0)
if recent_requests > 100:
return ps.Deny()
session["recent_requests"] = recent_requests + 1
return await next()
app = ps.App(
routes=[...],
middleware=[
TimingMiddleware(), # Runs first
RateLimitMiddleware(), # Runs second
AuthMiddleware(), # Runs third
],
)
```
--------------------------------
### Lower-level Setup with ps.setup() in Python
Source: https://github.com/erwinkn/pulse-ui/blob/main/skills/pulse/references/hooks.md
ps.setup() provides a lower-level mechanism for one-time setup that works everywhere, without relying on AST rewriting. It allows passing arguments, managing cleanup via return values, and re-initialization using a key.
```python
@ps.component
def Editor():
def init():
config = load_config()
return EditorState(config)
state = ps.setup(init)
return ps.div(state.content)
```
```python
def create_connection(host, port):
return DatabaseConnection(host, port)
@ps.component
def Dashboard():
conn = ps.setup(create_connection, "localhost", port=5432)
return ps.div(...)
```
```python
def init_with_cleanup():
ws = WebSocket("ws://server")
ws.connect()
# Cleanup happens when component unmounts
return ws # If ws has dispose(), it's called
state = ps.setup(init_with_cleanup)
```
```python
@ps.component
def UserProfile(user_id: str):
ps.setup_key(user_id) # Re-runs setup when user_id changes
data = ps.setup(lambda: fetch_user(user_id))
return ps.div(data.name)
```
--------------------------------
### Basic Form Setup with Pulse Mantine
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/packages/pulse-mantine/forms.mdx
Demonstrates the fundamental setup of a form using Pulse Mantine's MantineForm component. It includes initializing the form with initial values and validators, rendering the form, and defining input fields with names for data structure mapping. The example shows a signup form with email validation.
```python
import pulse as ps
from pulse_mantine import Button, Checkbox, Group, IsEmail, MantineForm, TextInput
@ps.component
def SignupForm():
with ps.init():
form = MantineForm(
initialValues={"email": "", "termsOfService": False},
validate={
"email": IsEmail("Invalid email")
},
)
return form.render(onSubmit=lambda values: print(values))[
TextInput(
name="email",
withAsterisk=True,
label="Email",
placeholder="your@email.com",
),
Checkbox(
name="termsOfService",
mt="md",
label="I agree to the terms of service",
),
Group(justify="flex-end", mt="md")[
Button("Submit", type="submit"),
],
]
```
--------------------------------
### Project Setup and Execution Commands
Source: https://github.com/erwinkn/pulse-ui/blob/main/CLAUDE.md
Provides essential commands for setting up, building, testing, and running the Pulse project. These commands cover initial setup, code formatting, linting, type checking, testing, and running Python scripts or Pulse applications.
```bash
make init # First-time setup in a new worktree
make all # Format, lint, typecheck, test
make format # Biome + Ruff
make lint-fix # Lint with auto-fix
make typecheck # Basedpyright + tsc
make test # pytest + bun test
```
```bash
uv run # Run Python
bun # Run JS/TS
uv run pulse run examples/app.py # Run a Pulse app (dev server on :8000)
```
--------------------------------
### Create a Basic Pulse Component in Python
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/(core)/setup.mdx
Defines a simple Pulse component using Python's decorator syntax and demonstrates creating a basic div element. It also shows how to configure the Pulse application with routes and a web directory for code generation.
```python
from pathlib import Path
import pulse as ps
@ps.component
def home():
return ps.div("Hello Pulse")
app = ps.App(
routes=[ps.Route("/", home)],
codegen=ps.CodegenConfig(web_dir=Path(__file__).parent / "web"),
)
```
--------------------------------
### Install Dependencies with uv and bun
Source: https://github.com/erwinkn/pulse-ui/blob/main/CONTRIBUTING.md
Installs Python development dependencies using uv and JavaScript dependencies using bun. Ensures the project has all necessary packages for development.
```bash
# Install Python dependencies
uv sync --dev --all-packages
# Install JavaScript dependencies
bun install
```
--------------------------------
### Install pulse-ui-client using npm or bun
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/reference/pulse-client/index.mdx
This snippet shows how to install the pulse-ui-client package using either npm or bun package managers. It's a direct command-line operation.
```bash
npm install pulse-ui-client
# or
bun add pulse-ui-client
```
--------------------------------
### Install pulse-aws using uv
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/packages/pulse-aws/index.mdx
Installs the `pulse-aws` package using the `uv` package manager. This command adds `pulse-aws` to your project's `pyproject.toml` file.
```bash
uv add pulse-aws
```
--------------------------------
### Setup Pulse App with Server Address
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/reference/pulse/app.mdx
Initializes the Pulse application with a server address. This method is typically called automatically by `asgi_factory` during the application setup process.
```python
def setup(self, server_address: str) -> None:
```
--------------------------------
### Complete Pulse App Example (Python)
Source: https://github.com/erwinkn/pulse-ui/blob/main/skills/pulse/references/app.md
A comprehensive example of a Pulse application, including middleware, routes, server address, mode, and session timeout configuration. It also shows how to run the application when the script is executed directly.
```python
import pulse as ps
class AuthMiddleware(ps.PulseMiddleware):
async def connect(self, *, request, session, next):
token = request.headers.get("authorization")
if token:
session["user"] = decode_token(token)
return await next()
app = ps.App(
routes=[
ps.Route("/", render=home),
ps.Route("/dashboard", render=dashboard),
ps.Route("/users/:id", render=user_detail),
],
middleware=[AuthMiddleware()],
server_address="https://api.example.com",
mode="subdomains",
session_timeout=120.0,
)
if __name__ == "__main__":
app.run()
```
--------------------------------
### Full Chat Example (Python)
Source: https://github.com/erwinkn/pulse-ui/blob/main/skills/pulse/references/channels.md
A comprehensive example demonstrating a chat application using Pulse UI channels. It includes server-side state management (`ChatRoom`), client-side UI components (`ChatWidget`), and integrates both server and client communication logic.
```python
import pulse as ps
from pulse.js.pulse import usePulseChannel
useState = ps.Import("useState", "react")
useEffect = ps.Import("useEffect", "react")
class ChatRoom(ps.State):
messages: list[dict] = []
def __init__(self):
self.channel = ps.channel()
self._handlers = [
self.channel.on("client:send", self._on_send),
]
def _on_send(self, payload: dict):
msg = {"user": "User", "text": payload["text"]}
self.messages.append(msg)
# Broadcast to client
self.channel.emit("server:message", msg)
def on_dispose(self):
for cleanup in self._handlers:
cleanup()
@ps.javascript(jsx=True)
def ChatWidget(*, channelId: str):
bridge = usePulseChannel(channelId)
messages, setMessages = useState([])
draft, setDraft = useState("")
def subscribe():
def onMessage(msg):
setMessages(lambda prev: [*prev, msg])
return bridge.on("server:message", onMessage)
useEffect(subscribe, [bridge])
def send():
if draft.strip():
bridge.emit("client:send", {"text": draft})
setDraft("")
return ps.div(className="chat")[
ps.div(className="messages")[
ps.For(
messages,
lambda m, i: ps.div(f"{m['user']}: {m['text']}", key=str(i)),
)
],
ps.input(
value=draft,
onChange=lambda e: setDraft(e.target.value),
placeholder="Type message...",
),
ps.button("Send", onClick=send),
]
@ps.component
def ChatApp():
with ps.init():
room = ChatRoom()
return ps.div(
ps.h1("Chat"),
# Server-rendered message list
ps.ul(
ps.For(
room.messages,
lambda m, _: ps.li(f"{m['user']}: {m['text']}"),
)
),
# Client widget with channel
ChatWidget(channelId=room.channel.id),
)
```
--------------------------------
### Complete Authentication Middleware Example in Python
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/(core)/advanced/middleware.mdx
This Python example shows a complete authentication middleware for Pulse UI. It handles public routes, protected routes requiring user authentication, and logs connection metadata.
```python
from pulse.middleware import Redirect, Deny, Ok
class AuthMiddleware(ps.PulseMiddleware):
# Routes that don't require authentication
PUBLIC_PATHS = {"/", "/login", "/signup", "/about"}
async def prerender_route(self, *, path, route_info, request, session, next):
# Public routes are always accessible
if path in self.PUBLIC_PATHS:
return await next()
# Protected routes require authentication
if not session.get("user_email"):
return Redirect("/login")
return await next()
async def connect(self, *, request, session, next):
# Store connection metadata for logging and debugging
session["user_agent"] = request.headers.get("user-agent")
session["ip"] = request.client[0] if request.client else None
return await next()
async def message(self, *, data, session, next):
# Log all user actions (useful for debugging and analytics)
if data.get("type") == "callback":
print(f"Action by {session.get('user_email')}")
return await next()
```
--------------------------------
### Build a Basic Todo List with Add/Remove Functionality in Pulse UI
Source: https://github.com/erwinkn/pulse-ui/blob/main/skills/pulse/references/examples.md
This example demonstrates how to create a functional todo list using Pulse UI. It includes state management for the list of items and a draft input, along with methods to add new todos and remove existing ones. The `ps.For` component is used for rendering the list dynamically.
```python
import pulse as ps
class Todos(ps.State):
items: list[str] = []
draft: str = ""
def update(self, value: str):
self.draft = value
def add(self):
if self.draft.strip():
self.items.append(self.draft.strip())
self.draft = ""
def remove(self, index: int):
self.items.pop(index)
@ps.component
def TodoApp():
with ps.init():
state = Todos()
return ps.div(className="p-4 space-y-4")[
ps.div(className="flex gap-2")[
ps.input(
value=state.draft,
onChange=lambda e: state.update(e["target"]["value"]),
placeholder="Add todo...",
className="input flex-1",
),
ps.button("Add", onClick=state.add, className="btn-primary"),
],
ps.ul(className="space-y-2")[
ps.For(
state.items,
lambda item, idx:
ps.li(className="flex justify-between")[
ps.span(item),
ps.button("x", onClick=lambda: state.remove(idx), className="btn-sm"),
],
),
],
]
app = ps.App([ps.Route("/", TodoApp)])
```
--------------------------------
### Complete Todo App Example with Pulse UI Queries and Mutations
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/(core)/tutorial/09-queries.mdx
A comprehensive example of a Todo application built with Pulse UI. It showcases the integration of queries for fetching data and mutations for modifying it, along with state management and UI components.
```python
import asyncio
import pulse as ps
from dataclasses import dataclass
@dataclass
class Todo:
id: int
text: str
done: bool
class TodoState(ps.State):
@ps.query
async def todos(self) -> list[Todo]:
await asyncio.sleep(0.5)
# In a real app, this would fetch from an API
return [
Todo(1, "Learn Pulse", False),
Todo(2, "Build an app", False),
Todo(3, "Ship it", False),
]
@ps.mutation
async def add_todo(self, text: str):
await asyncio.sleep(0.3)
# In a real app, this would POST to an API
# After adding, invalidate the list to refetch
self.todos.invalidate()
@ps.mutation
async def toggle_todo(self, todo_id: int):
await asyncio.sleep(0.2)
# In a real app, this would PATCH the API
self.todos.invalidate()
@ps.mutation
async def delete_todo(self, todo_id: int):
await asyncio.sleep(0.2)
# In a real app, this would DELETE via API
self.todos.invalidate()
@ps.component
def TodoApp():
with ps.init():
state = TodoState()
new_text = ""
def handle_add():
nonlocal new_text
if new_text.strip():
state.add_todo(new_text)
new_text = ""
return ps.div()[
ps.h1("Todo List"),
# Add new todo
ps.div()[
ps.input(
value=new_text,
onChange=lambda e: setattr(state, "new_text", e["target"]["value"]),
placeholder="What needs to be done?",
disabled=state.add_todo.is_loading,
),
ps.button(
"Adding..." if state.add_todo.is_loading else "Add",
onClick=handle_add,
disabled=state.add_todo.is_loading,
),
],
# Todo list
ps.div()[
ps.p("Loading...") if state.todos.is_loading else None,
ps.ul()[
ps.For(
state.todos.data or [],
lambda todo: ps.li(
ps.input(
type="checkbox",
checked=todo.done,
onChange=lambda: state.toggle_todo(todo.id),
),
ps.span(
todo.text,
style={"textDecoration": "line-through" if todo.done else "none"},
),
ps.button("Delete", onClick=lambda: state.delete_todo(todo.id)),
key=todo.id,
)
)
] if state.todos.data else None,
],
# Refresh button
ps.button("Refresh", onClick=state.todos.refetch),
]
```
--------------------------------
### Auth Middleware Example (Python)
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/reference/pulse/middleware.mdx
An example of an authentication middleware class 'AuthMiddleware' that extends 'ps.PulseMiddleware'. It implements 'prerender_route' to redirect non-admin users from '/admin' paths and 'connect' to deny requests if no user ID is found in the session.
```python
import pulse as ps
class AuthMiddleware(ps.PulseMiddleware):
async def prerender_route(
self,
*,
path: str,
request: ps.PulseRequest,
route_info: ps.RouteInfo,
session: dict[str, Any],
next,
):
if path.startswith("/admin") and not session.get("is_admin"):
return ps.Redirect("/login")
return await next()
async def connect(self, *, request, session, next):
if not session.get("user_id"):
return ps.Deny()
return await next()
```
--------------------------------
### Complete Example: Create Post Form (Python)
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/reference/pulse/forms.mdx
An example demonstrating how to create a post form using Pulse UI and Mantine components. It includes the logic for handling form submission, including file uploads to S3 and database interaction, and the form definition itself.
```python
import pulse as ps
from pulse_mantine import components as m
async def create_post(data: ps.FormData):
title = data.get("title", "")
body = data.get("body", "")
image = data.get("image")
if not isinstance(title, str) or not title:
raise ValueError("Title required")
image_url = None
if isinstance(image, ps.UploadFile) and image.filename:
content = await image.read()
image_url = await upload_to_s3(image.filename, content)
await db.posts.create(title=title, body=body, image_url=image_url)
ps.navigate("/posts")
def create_post_form():
return ps.Form(
m.Stack([
m.TextInput(name="title", label="Title", required=True),
m.Textarea(name="body", label="Body", rows=5),
m.FileInput(name="image", label="Image", accept="image/*"),
m.Button("Create Post", type="submit"),
]),
key="create-post",
onSubmit=create_post,
)
```
--------------------------------
### Plugin Base Class and Example (Python)
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/reference/pulse/app.mdx
Provides the base `Plugin` class for extending application functionality. Plugins can define routes, middleware, and lifecycle hooks like `on_setup`, `on_startup`, and `on_shutdown`. An example demonstrates creating an `AuthPlugin` to add authentication routes and middleware.
```python
class Plugin:
priority: int = 0
def routes(self) -> list[Route | Layout]:
"""Return routes to add to the app."""
return []
def middleware(self) -> list[PulseMiddleware]:
"""Return middleware to add to the app."""
return []
def on_setup(self, app: App) -> None:
"""Called after FastAPI routes are configured."""
...
def on_startup(self, app: App) -> None:
"""Called when the app starts."""
...
def on_shutdown(self, app: App) -> None:
"""Called when the app shuts down."""
...
# Example Usage:
class AuthPlugin(ps.Plugin):
priority = 10 # Higher priority runs first
def routes(self):
return [ps.Route("/login", render=login_page)]
def middleware(self):
return [AuthMiddleware()]
def on_startup(self, app):
print("Auth plugin started")
```
--------------------------------
### Practical Form Input Example with State Management (Python)
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/(core)/tutorial/03-events.mdx
A complete Pulse UI example showcasing a form with text input and submission. It utilizes state management to handle input changes and form submission, demonstrating a clean pattern for updating state methods via lambdas.
```python
import pulse as ps
class FormState(ps.State):
name: str = ""
submitted_name: str = ""
def update_name(self, value: str):
self.name = value
def submit(self):
self.submitted_name = self.name
self.name = ""
@ps.component
def greeting_form():
with ps.init():
st = FormState()
return ps.div(className="p-4 max-w-md")[
ps.h2("Enter Your Name", className="text-xl font-bold mb-4"),
ps.div(className="flex gap-2 mb-4")[
ps.input(
type="text",
value=st.name,
onChange=lambda evt: st.update_name(evt["target"]["value"]),
placeholder="Your name...",
className="border p-2 rounded flex-1",
),
ps.button(
"Submit",
onClick=st.submit,
className="px-4 py-2 bg-blue-500 text-white rounded",
),
],
ps.p(
f"Hello, {st.submitted_name}!" if st.submitted_name else "Enter a name above.",
className="text-lg",
),
]
app = ps.App([ps.Route("/", greeting_form)])
```
--------------------------------
### Customize Frontend Location in Python
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/(core)/setup.mdx
Example of how to configure the 'web_dir' in Pulse's CodegenConfig to point to a custom location for the React frontend application.
```python
codegen=ps.CodegenConfig(web_dir=Path("/path/to/your/react-app"))
```
--------------------------------
### Create Production Build with npm
Source: https://github.com/erwinkn/pulse-ui/blob/main/examples/pulse-mantine/web/README.md
Generates a production-ready build of the application. This process optimizes the code for deployment and typically includes minification and bundling.
```bash
npm run build
```
--------------------------------
### ps.setup() - Complex Initialization
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/(core)/concepts/state.mdx
Initializes components with side effects or multiple steps. It can take a function and optional arguments. The setup function is called only once.
```python
def create_connection():
print("Connecting to database...") # Only prints once!
config = load_config()
return DatabaseConnection(config.host, config.port)
@ps.component
def Dashboard():
conn = ps.setup(create_connection)
return ps.div(f"Connected to: {conn.host}")
```
--------------------------------
### Access PulseClient Instance
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/packages/pulse-js-client.mdx
Example of using the usePulseClient hook to get access to the client instance within a React component. This allows for advanced interactions with the Pulse client.
```tsx
import { usePulseClient } from "pulse-client";
function MyComponent() {
const client = usePulseClient();
// Access client methods
}
```
--------------------------------
### ps.init() as syntactic sugar for ps.setup() in Python
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/(core)/tutorial/06-hooks.mdx
ps.init() is a convenient shorthand for ps.setup(). The example demonstrates how a component using ps.init() for state and calculation can be refactored to use ps.setup() with a dedicated initialization function, achieving the same result.
```python
import pulse as ps
class CounterState:
def __init__(self):
self.count = 0
def expensive_calculation():
return "calculated_value"
@ps.component
def CounterWithInit():
with ps.init():
state = CounterState()
value = expensive_calculation()
return ps.div(f"Count: {state.count}")
@ps.component
def CounterWithSetup():
def init():
return CounterState(), expensive_calculation()
state, value = ps.setup(init)
return ps.div(f"Count: {state.count}")
```
--------------------------------
### Hook: ps.setup() for One-Time Initialization
Source: https://github.com/erwinkn/pulse-ui/blob/main/skills/pulse/SKILL.md
Illustrates the `ps.setup()` hook, which is used for one-time initialization of resources or computations within a component. It can accept arguments and will re-run if those arguments change.
```python
def create_api(user_id: int):
return {"user_id": user_id}
@ps.component
def UserView(user_id: int):
meta = ps.setup(create_api, user_id) # Re-runs if user_id changes
return ps.div(f"User: {meta['user_id']}")
```
--------------------------------
### Client-Side Channel Interaction (JavaScript/Python)
Source: https://github.com/erwinkn/pulse-ui/blob/main/skills/pulse/references/channels.md
Provides a Python example using `@ps.javascript` to define a React component that interacts with channels on the client-side. It utilizes `usePulseChannel` to get a bridge object for emitting events, making requests, and subscribing to server events.
```python
from pulse.js.pulse import usePulseChannel
@ps.javascript(jsx=True)
def ChatClient(*, channelId: str):
bridge = usePulseChannel(channelId)
# Send event to server
def sendMessage(text: str):
bridge.emit("client:message", {"text": text})
# Request with response
async def askServer():
response = await bridge.request("client:request", {"data": "..."})
print(response)
# Listen for server events
def setupListeners():
def onNotify(payload):
print("Server notified:", payload)
off = bridge.on("server:notify", onNotify)
return off # Cleanup
useEffect(setupListeners, [bridge])
return ps.div(...)
```
--------------------------------
### Quick Start: Basic Form with Validation (Python)
Source: https://github.com/erwinkn/pulse-ui/blob/main/packages/pulse-mantine/README.md
Demonstrates a basic form setup using Pulse Mantine in Python. It initializes a MantineForm with initial values and a validation rule for an email input, then renders the form with a submit button.
```python
from pulse_mantine import (
MantineProvider, Button, TextInput, Stack, MantineForm, IsEmail
)
@ps.component
def app():
form = ps.states(lambda: MantineForm(
initialValues={"email": ""},
validate={"email": IsEmail("Invalid email")},
))
return MantineProvider()[
form.render(onSubmit=lambda v: print(v))[
Stack()[
TextInput(name="email", label="Email"),
Button("Submit", type="submit"),
]
]
]
```
--------------------------------
### Run initialization function once with ps.setup() in Python
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/(core)/tutorial/06-hooks.mdx
ps.setup() allows running more complex initialization code once per component render. The function is executed only on the first render, and its return value is cached for subsequent renders. Arguments can be passed to the setup function.
```python
import pulse as ps
class EditorState:
def __init__(self, config):
self.config = config
print("EditorState initialized")
def load_config():
print("Loading config...")
return {"theme": "dark"}
def initialize_editor():
print("Setting up editor...")
config = load_config()
state = EditorState(config)
return state
@ps.component
def Editor():
state = ps.setup(initialize_editor)
return ps.div(f"Editor config: {state.config}")
class DatabaseConnection:
def __init__(self, host, port):
self.host = host
self.port = port
print(f"Connected to {host}:{port}")
def create_connection(host, port):
return DatabaseConnection(host, port)
@ps.component
def Dashboard():
conn = ps.setup(create_connection, "localhost", port=5432)
return ps.div(f"Dashboard connected to {conn.host}:{conn.port}")
```
--------------------------------
### Get Geolocation with Python and Promises
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/(core)/tutorial/14-js-interop.mdx
This example shows how to retrieve the user's current geographical location using the browser's Geolocation API through Pulse UI. It returns a JavaScript Promise, allowing for asynchronous handling of the location data or potential errors. This is essential for location-aware web applications.
```python
from pulse.js import window, navigator, Promise
@ps.javascript
def get_geolocation():
return Promise(lambda resolve, reject:
navigator.geolocation.getCurrentPosition(
lambda pos: resolve({"lat": pos.coords.latitude, "lng": pos.coords.longitude}),
lambda err: reject(err)
)
)
```
--------------------------------
### Data Querying with Loading and Error States in Pulse UI
Source: https://github.com/erwinkn/pulse-ui/blob/main/tutorial/README.md
Illustrates Pulse UI's data query primitive, featuring automatic dependency detection, keyed queries, initial data setting, and manual refetching. This example shows a simplified query demonstration with user data fetching.
```python
class QueryDemoState(ps.State):
user_id: int = 1
# Default mode: unkeyed, auto-tracks dependencies
@ps.query
async def user(self) -> dict:
# Simulate async work
await asyncio.sleep(1)
return {"id": self.user_id, "name": f"User {self.user_id}"}
@ps.component
def QueryDemo():
with ps.init():
state = QueryDemoState()
def prev():
state.user_id = max(1, state.user_id - 1)
def next_():
state.user_id = state.user_id + 1
return ps.div(
ps.h2("Query Demo", className="text-2xl font-bold mb-4"),
ps.p(f"User ID: {state.user_id}"),
ps.div(
ps.h3("Query", className="text-xl font-semibold mt-4"),
ps.p(
"Loading..."
if state.user.is_loading
else f"Data: {state.user.data}",
className="mb-2",
),
ps.div(
ps.button("Prev", onClick=prev, className="btn-secondary mr-2"),
ps.button("Next", onClick=next_, className="btn-secondary mr-2"),
ps.button(
"Refetch keyed",
onClick=state.user.refetch,
className="btn-primary",
),
className="mb-4",
),
className="mb-6 p-3 rounded bg-white shadow",
),
)
```
--------------------------------
### Install Pulse Mantine
Source: https://github.com/erwinkn/pulse-ui/blob/main/skills/pulse-mantine/SKILL.md
This command installs the pulse-mantine package using the 'uv' package manager. Ensure 'uv' is installed and configured in your environment.
```bash
uv add pulse-mantine
```
--------------------------------
### Pulse UI Hooks: State Initialization and Setup
Source: https://github.com/erwinkn/pulse-ui/blob/main/tutorial/README.md
This Python code demonstrates using ps.init() for creating persistent states and ps.setup() for initializing states with complex logic. It defines custom states (CounterState, DebugState) and components (render_counter, debug_toggle, HooksDemo) to manage and display counter values and debug flags. ps.init() captures variables on the first render, while ps.setup() executes a provided function once to initialize a state.
```python
from pathlib import Path
import pulse as ps
class CounterState(ps.State):
count: int = 0
def increment(self):
self.count += 1
def decrement(self):
self.count -= 1
class DebugState(ps.State):
enabled: bool = True
def __init__(self, enabled: bool):
self.enabled = enabled
def toggle(self):
self.enabled = not self.enabled
def setup_demo(arg, *, kwarg):
print(f"Received argument: {arg} and kwarg: {kwarg}")
# do anything else here
return DebugState(True)
def render_counter(label: str, state: CounterState):
return ps.div(className="flex items-center gap-2")[
ps.button(
"-",
onClick=state.decrement,
className="px-2 py-1 bg-red-500 text-white rounded",
),
ps.span(f"{label}: {state.count}"),
ps.button(
"+",
onClick=state.increment,
className="px-2 py-1 bg-green-500 text-white rounded",
),
]
def debug_toggle(label: str, state: DebugState):
return ps.label(className="flex items-center gap-2")[
ps.input(type="checkbox", checked=state.enabled, onChange=state.toggle),
f"{label}: {state.enabled}",
]
@ps.component
def HooksDemo():
# Use `ps.init()` to create state that persists across renders.
# Any variables assigned inside the block are captured on the first render
# and restored on subsequent renders.
with ps.init():
counter1 = CounterState()
counter2 = CounterState()
debug1 = DebugState(False)
# `ps.setup` can also be used to create states and perform anything else you
# need to set up on the first render. Note that the setup function has to be
# synchronous, it is not recommended to perform async operations, like
# network requests, there.
debug2 = ps.setup(setup_demo, "arg", kwarg="kwarg")
return ps.div(
className="w-xl mx-auto h-screen flex flex-col justify-center items-start"
)[
ps.h3("Setup + States demo", className="text-2xl font-bold mb-4"),
ps.div(className="space-y-4")[
render_counter("Counter 1", counter1),
render_counter("Counter 2", counter2),
ps.div(className="flex flex-col gap-2")[
debug_toggle("Debug 1", debug1), debug_toggle("Debug 2", debug2)
],
],
]
app = ps.App(
routes=[ps.Route("/", HooksDemo)],
codegen=ps.CodegenConfig(web_dir=Path(__file__).parent.parent / "web"),
)
```
--------------------------------
### Set Up Real-time Channels in Python
Source: https://github.com/erwinkn/pulse-ui/blob/main/packages/pulse/python/README.md
Illustrates the setup and usage of real-time bidirectional messaging channels. It shows how to create a channel, listen for events, and broadcast messages to connected clients.
```python
ch = ps.channel("chat")
@ch.on("message")
def handle_message(data):
ch.broadcast("new_message", data)
```
--------------------------------
### Alternative state initialization with ps.setup() in Pulse
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/(core)/concepts/state.mdx
This Python snippet presents `ps.setup()` as an alternative to `ps.init()` for initializing state within Pulse components. It achieves the same goal of state persistence across renders by accepting a factory function that creates the state object.
```python
@ps.component
def Counter():
state = ps.setup(lambda: CounterState())
return ps.div(f"Count: {state.count}")
```
--------------------------------
### Example Custom Timer Hook
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/reference/pulse/hooks.mdx
An example of creating a custom hook `use_timer` that tracks the elapsed time since its initialization.
```python
class TimerHookState(ps.hooks.State):
def __init__(self):
self.start_time = time.time()
def elapsed(self) -> float:
return time.time() - self.start_time
def dispose(self) -> None:
pass
_timer_hook = ps.hooks.create("my_app:timer", lambda: TimerHookState())
def use_timer() -> TimerHookState:
return _timer_hook()
```
--------------------------------
### Initialize ps.State with Constructor Arguments
Source: https://github.com/erwinkn/pulse-ui/blob/main/skills/pulse/references/state.md
Shows how to define a `ps.State` class that accepts constructor arguments. This allows for initial setup and configuration of the state object upon creation.
```python
class FormState(ps.State):
value: str = ""
submitted: bool = False
def __init__(self, initial: str, readonly: bool = False):
self.value = initial
self._readonly = readonly # Private, non-reactive
```
--------------------------------
### Simple DatePickerInput Example (Python)
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/packages/pulse-mantine/dates.mdx
A straightforward example of using DatePickerInput with custom value formatting and a clear button. It requires MantineProvider and DatePickerInput from pulse_mantine.
```python
from pulse_mantine import MantineProvider, DatePickerInput
@ps.component
def SimpleDatePicker():
return MantineProvider()[
DatePickerInput(
label="Birth date",
placeholder="Select your birth date",
valueFormat="MMMM D, YYYY",
clearable=True,
)
]
```
--------------------------------
### Install pulse-lucide and lucide-react
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/packages/pulse-lucide.mdx
Installs the pulse-lucide Python package and the lucide-react JavaScript dependency required for Pulse UI applications. Ensure you are in the correct project directories.
```bash
uv add pulse-lucide
cd web && bun add lucide-react
```
--------------------------------
### Pulse UI App Configuration in Python
Source: https://github.com/erwinkn/pulse-ui/blob/main/skills/pulse/SKILL.md
Provides an example of configuring a Pulse UI application. This includes setting up routes, middleware, session stores (e.g., CookieSessionStore for production), server address, and the application mode (single-server or subdomains).
```python
app = ps.App(
routes=[...],
middleware=[LoggingMiddleware()],
session_store=ps.CookieSessionStore(secret_key="..."), # Production
server_address="https://app.example.com", # Required in prod
mode="single-server", # or "subdomains"
)
```
--------------------------------
### Install Pulse MSAL Plugin
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/packages/pulse-msal.mdx
Installs the pulse-msal package using the uv package manager. This is the first step to integrate MSAL authentication into your Pulse application.
```bash
uv add pulse-msal
```
--------------------------------
### Define a Basic Pulse App Component (Python)
Source: https://github.com/erwinkn/pulse-ui/blob/main/tutorial/README.md
Demonstrates how to define a reusable UI component using the `@ps.component` decorator and render it within a Pulse application. This example sets up a simple welcome message with basic styling using Tailwind CSS classes.
```python
from pathlib import Path
import pulse as ps
@ps.component
def welcome():
return ps.div(
className="min-h-screen flex items-center justify-center flex-col bg-gray-100"
)[
ps.h1("Welcome to Pulse!", className="text-4xl font-bold text-blue-600 mb-4"),
ps.p(
"You've created your first Pulse application!",
className="text-lg text-gray-700",
),
]
app = ps.App(
routes=[ps.Route("/", welcome)],
codegen=ps.CodegenConfig(web_dir=Path(__file__).parent.parent / "web"),
)
```
--------------------------------
### Render HTML Elements with Pulse Syntax (Python)
Source: https://github.com/erwinkn/pulse-ui/blob/main/tutorial/README.md
Illustrates how to create HTML elements using Pulse's Python syntax, including passing attributes (props) and child elements. It shows two methods for passing children: as positional arguments and using indexing after defining props.
```python
ps.div(
className="min-h-screen flex items-center justify-center flex-col bg-gray-100"
)[
ps.h1("Welcome to Pulse!", className="text-4xl font-bold text-blue-600 mb-4"),
ps.p(
"You've created your first Pulse application!",
className="text-lg text-gray-700",
),
]
```
--------------------------------
### Define App with Routes and Layouts in Pulse Python
Source: https://github.com/erwinkn/pulse-ui/blob/main/packages/pulse/python/README.md
This snippet demonstrates the basic setup of a Pulse Python application. It shows how to instantiate the `ps.App` class, defining top-level routes and nested layouts with their respective child routes. This is the entry point for configuring the application's structure and navigation.
```python
import pulse as ps
app = ps.App(routes=[
ps.Route("/", home),
ps.Layout("/dashboard", layout, children=[
ps.Route("/", dashboard),
]),
])
```
--------------------------------
### usePulseChannel - User Search Example
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/reference/pulse-client/hooks.mdx
An example demonstrating the use of the `usePulseChannel` hook for performing a user search. It shows how to send a 'search' request to a channel and handle the results.
```APIDOC
## usePulseChannel - User Search Example
### Description
This example demonstrates how to use the `usePulseChannel` hook to interact with a 'user-search' channel. It includes functionality to send a search query and display the results, along with loading and error handling.
### Method
POST (Implicit via channel.request)
### Endpoint
'user-search' channel
### Parameters
#### Query Parameters
- **query** (string) - Required - The search term for users.
### Request Example
```json
{
"query": "john doe"
}
```
### Response
#### Success Response (200)
- **users** (array) - An array of user objects, each containing at least an `id` and `name`.
#### Response Example
```json
[
{
"id": "123",
"name": "John Doe"
},
{
"id": "456",
"name": "Jane Doe"
}
]
```
```
--------------------------------
### Pulse Recharts PieChart Example
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/packages/pulse-recharts.mdx
An example of how to generate a PieChart using Pulse Recharts to display proportions of a whole. It uses the Pie component with dataKey and nameKey for data binding.
```python
from pulse_recharts import PieChart, Pie
PieChart()[
Pie(data=data, dataKey="value", nameKey="name", fill="#8884d8"),
]
```
--------------------------------
### Pulse Recharts LineChart Example
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/packages/pulse-recharts.mdx
A basic example of creating a LineChart component with Pulse Recharts. It includes data, a Line component for visualization, and XAxis and YAxis for data representation.
```python
LineChart(data=data)[
Line(dataKey="value", stroke="#8884d8"),
XAxis(dataKey="name"),
YAxis(),
]
```
--------------------------------
### Pulse Recharts BarChart Example
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/packages/pulse-recharts.mdx
An example demonstrating the creation of a BarChart using Pulse Recharts. It utilizes Bar, XAxis, and YAxis components to compare quantities across different categories.
```python
from pulse_recharts import BarChart, Bar
BarChart(data=data)[
Bar(dataKey="value", fill="#8884d8"),
XAxis(dataKey="name"),
YAxis(),
]
```
--------------------------------
### Grouped BarChart Example in Python
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/packages/pulse-mantine/charts.mdx
Shows how to create a grouped BarChart for comparing categories across different series. This example uses quarterly revenue and profit data, with options for legends.
```python
from pulse_mantine import BarChart
BarChart(
h=300,
data=[
{"quarter": "Q1", "revenue": 12000, "profit": 3000},
{"quarter": "Q2", "revenue": 15000, "profit": 4500},
{"quarter": "Q3", "revenue": 18000, "profit": 5200},
{"quarter": "Q4", "revenue": 22000, "profit": 7000},
],
dataKey="quarter",
series=[
{"name": "revenue", "color": "violet.6"},
{"name": "profit", "color": "teal.6"},
],
withLegend=True,
)
```
--------------------------------
### Define and Render a Pulse Component
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/(core)/tutorial/01-basics.mdx
This snippet demonstrates how to create a basic Pulse component using the `@ps.component` decorator and render HTML elements like `div`, `h1`, and `p` within it. It also shows how to initialize a Pulse application with defined routes.
```python
import pulse as ps
@ps.component
def home():
return ps.div(
ps.h1("Welcome to Pulse!", className="text-xl font-bold"),
ps.p("You've created your first Pulse application."),
className="p-4",
)
app = ps.App([ps.Route("/", home)])
```
--------------------------------
### CodegenConfig Initialization (Python)
Source: https://github.com/erwinkn/pulse-ui/blob/main/docs/content/docs/reference/pulse/codegen.mdx
Demonstrates how to initialize the CodegenConfig class with default and custom parameters for web directory, Pulse directory name, and base directory.
```python
from pulse import App, CodegenConfig
# Default configuration
app = App()
# Custom web directory
app = App(
codegen=CodegenConfig(web_dir="frontend")
)
# Absolute path
app = App(
codegen=CodegenConfig(web_dir="/var/www/app/web")
)
# Custom pulse directory name
app = App(
codegen=CodegenConfig(pulse_dir="generated")
)
```