Server Functions, Exposed Securely
Call PHP functions from your frontend as if they were local JavaScript functions.
Protected by the
#[Exposed]
attribute.
Attribute Security
Functions are private by default. You must explicitly opt-in using PHP 8 Attributes to expose them to the client.
Built-in Auth Checks
Stop writing if (!$user) return;.
Just add requiresAuth: true and the framework handles the guard.
Role Based Access
Granular control. Restrict execution to specific roles like
['admin', 'editor']
directly in the function signature.
Security & Authentication
Control who can access your backend logic using PHP Attributes.
use PP\Attributes\Exposed; // Only logged in users can call this #[Exposed(requiresAuth: true)] function getUserProfile() { return Auth::user(); }
use PP\Attributes\Exposed; // Implies requiresAuth: true #[Exposed(allowedRoles: ['admin', 'editor'])] function deletePost($args) { // Safe to perform admin action Post::delete($args->id); }
requiresAuth fails.
Data Flow Example
<?php use PP\Attributes\Exposed; #[Exposed] function updateUser($data) { // $data is an object automatically $email = $data->email; return [ 'success' => true, 'msg' => "Updated $email" ]; } ?>
<script> async function save() { const res = await pp.fetchFunction( 'updateUser', { email: 'john@doe.com' } ); if (res.success) { console.log(res.msg); } } </script>
Real-time Streaming
Stream data from PHP to the client in real-time using Generators and Server-Sent Events (SSE).
<?php use PP\Attributes\Exposed; #[Exposed] function streamAIResponse($args) { yield "Connecting..."; // Simulate long running task sleep(1); yield ['status' => 'thinking', 'progress' => 50]; sleep(1); yield "Done!"; } ?>
<script> await pp.fetchFunction( 'streamAIResponse', { prompt: 'Hello' }, { onStream: (chunk) => { // Auto-parsed as JSON or String console.log(chunk); }, onStreamComplete: () => { console.log('Stream finished'); } } ); </script>
Auto-JSON Parsing
If the chunk is a valid JSON string (array or object), PulsePoint automatically parses it before firing onStream.
Native PHP Generators
No complex event loop libraries required. Just use the native yield keyword in your PHP function.
File Uploads with Real Progress
When your payload includes a File,
PulsePoint automatically switches the request to multipart/form-data.
To track real upload progress, pass options.onUploadProgress.
Under the hood, PulsePoint uses XMLHttpRequest only for that case
(because fetch() cannot report upload progress).
<?php use PP\Attributes\Exposed; // Receives multipart/form-data automatically when File is detected in the payload #[Exposed(requiresAuth: true)] function processUpload($data) { // $data->title, $data->description, $data->folderId ... // Your UploadFile / move_uploaded_file logic here return [ 'success' => true, 'message' => 'Files uploaded successfully' ]; } ?>
<script> const [progress, setProgress] = pp.state(0); async function uploadFile(file) { const res = await pp.fetchFunction( 'processUpload', { file, title: 'Document Title', description: 'Short description', folderId: 'root' }, { onUploadProgress: ({ percent }) => { // percent can be null if total is unknown if (percent != null) setProgress(Math.floor(percent)); }, onUploadComplete: () => { setProgress(100); } } ); if (res.success) { console.log(res.message); } } </script>
Zero-Config Multipart
If PulsePoint detects File / FileList in your payload, it auto-builds FormData.
No manual encoding required.
Progress Without UI Hacks
No fake setProgress(15) or setProgress(100). The UI reflects real upload bytes via onUploadProgress.
Client API Reference
fetchFunction<T = any>( functionName: string, data: Record<string, any> = {}, options: boolean | RpcOptions = false ): Promise<T | void> // RpcOptions (Streaming + Upload Progress) type RpcOptions = { abortPrevious?: boolean; // Streaming (SSE) onStream?: (chunk: any) => void; onStreamError?: (error: any) => void; onStreamComplete?: () => void; // Upload Progress (only when payload contains File/FileList) onUploadProgress?: (info: { loaded: number; total: number | null; percent: number | null; }) => void; onUploadComplete?: () => void; };
-
functionNameThe exact name of the PHP function. Supports namespaces for static methods (e.g.,User::update). -
dataObject containing arguments. Supports nested objects, arrays, andFile/FileList(auto switches to multipart/form-data). -
options.onStreamCallback fired for every SSE chunk received. JSON-like chunks are automatically parsed. -
options.onUploadProgressFired during file upload. Receivesloaded,total(or null), andpercent(0–100 or null). When this handler is present, PulsePoint uses XHR for that request (enabling upload progress). -
options.abortPreviousIftrue, cancels any pending requests from this caller before starting the new one.
Zero-Config File Uploads
PulsePoint detects File objects in your payload and automatically switches the content-type.
No need for manual FormData construction.
Auto-Response Parsing
PHP arrays are automatically converted to JSON objects on the frontend. Strings and booleans are preserved.