PocketPages Datastar Backend SDK
Implements the Datastar SDK ADR for PocketPages, providing realtime DOM updates and signal management.
Installation
npm install pocketpages-plugin-datastar
Configuration
Add to your +config.js
:
module.exports = {
plugins: [
'pocketpages-plugin-ejs',
'pocketpages-plugin-datastar',
'pocketpages-plugin-realtime',
],
}
Add to your +layout.ejs
or similar:
<head>
<%- datastar.scripts() %>
</head>
API Reference
Core Methods
datastar.patchElements(elements, options?)
Updates DOM elements with new HTML content.
// Basic usage
datastar.patchElements('<div>New content</div>')
// With options
datastar.patchElements('<div>New content</div>', {
selector: '#target',
mode: 'inner',
useViewTransition: true,
eventId: 'unique-id',
retryDuration: 1000,
})
Options:
selector
- CSS selector for target elementmode
- Patch mode:outer
,inner
,remove
,replace
,prepend
,append
,before
,after
useViewTransition
- Enable ViewTransition APIeventId
- Unique event identifierretryDuration
- SSE retry duration in milliseconds
datastar.patchSignals(signals, options?)
Updates client-side signals with new data.
// Basic usage
datastar.patchSignals(stringify({ count: 42 }))
// With options
datastar.patchSignals(stringify({ count: 42 }), {
onlyIfMissing: true,
eventId: 'unique-id',
retryDuration: 1000,
})
Options:
onlyIfMissing
- Only patch if signals don't existeventId
- Unique event identifierretryDuration
- SSE retry duration in milliseconds
datastar.readSignals(request, target)
Reads signals from request and merges into target object.
// Read signals into a new object
const data = datastar.readSignals(request, {})
// Read into existing object
const form = datastar.readSignals(request, { name: '', email: '' })
Utility Methods
datastar.executeScript(script, options?)
Executes JavaScript on the client.
datastar.executeScript('console.log("Hello from server")')
// With options
datastar.executeScript('alert("Hello")', {
autoRemove: true,
attributes: ['type="module"'],
eventId: 'script-1',
retryDuration: 1000,
})
datastar.consoleLog(message, options?)
Logs a message to client console.
datastar.consoleLog('Server message')
datastar.consoleError(error, options?)
Logs an error to client console.
datastar.consoleError('Something went wrong')
datastar.consoleError(new Error('Server error'))
datastar.redirect(url, options?)
Redirects the client to a new URL.
datastar.redirect('/dashboard')
datastar.dispatchCustomEvent(eventName, detail, options?)
Dispatches a custom event on the client.
datastar.dispatchCustomEvent('user-updated', { id: 123 })
// With options
datastar.dispatchCustomEvent(
'custom-event',
{ data: 'value' },
{
selector: '.target',
bubbles: true,
cancelable: true,
composed: true,
}
)
datastar.replaceURL(url, options?)
Updates the browser URL without navigation.
datastar.replaceURL('/new-path')
datastar.prefetch(urls, options?)
Prefetches URLs using speculation rules.
datastar.prefetch(['/page1', '/page2'])
Realtime Methods
datastar.realtime.patchElements(elements, patchOptions?, realtimeOptions?)
Broadcasts element updates to all connected clients.
// Basic usage
datastar.realtime.patchElements('<div>Broadcast message</div>')
// With patch options
datastar.realtime.patchElements('<div>Broadcast message</div>', {
selector: '#target',
mode: 'inner',
useViewTransition: true,
})
// With realtime options for custom filtering
datastar.realtime.patchElements(
'<div>Broadcast message</div>',
{},
{
filter: (clientId, client, topic, message) => {
// Only send to authenticated clients
return client.get('auth')?.id
},
}
)
Parameters:
elements
(string) - HTML content to broadcastpatchOptions
(object, optional) - Element patch configurationrealtimeOptions
(object, optional) - Realtime delivery optionsfilter
(function, optional) - Custom filter function to target specific clients
datastar.realtime.patchSignals(signals, options?)
Broadcasts signal updates to all connected clients.
datastar.realtime.patchSignals(stringify({ globalCount: 100 }))
Examples
Chat Application
// Save message and broadcast to all clients
const messages = store('messages') || []
const { from, message } = request.url.query.datastar
messages.push({ from, message })
store('messages', messages)
// Broadcast updated chat box
datastar.realtime.patchElements(include('chat-box.ejs', { messages }))
// Clear input
datastar.patchSignals(stringify({ message: '' }))
Counter with Realtime Updates
// Increment counter
$app.runInTransaction(() => {
store('count', (store('count') || 1) + 1)
})
// Return updated counter
<%- include('count.ejs') %>
Form Handling
// Read form data
const formData = datastar.readSignals(request, { name: '', email: '' })
// Process and respond
if (formData.name && formData.email) {
datastar.patchElements('<div>Success!</div>')
} else {
datastar.consoleError('Please fill all fields')
}
Client-Side Integration
The plugin automatically injects the Datastar loader script. Use DataStar attributes in your HTML:
<button data-on-click="@get('/api/increment')">
Count: <span data-bind-count><%= store('count') %></span>
</button>
<form data-on-submit="@post('/api/submit')">
<input name="name" data-bind-name />
<button type="submit">Submit</button>
</form>
Client-Side Helper Functions
patchSignals(signals)
A client-side helper function that dispatches a datastar-fetch
event to patch signals. This function is automatically available in the global scope when the datastar plugin is loaded.
// Patch signals from client-side JavaScript
patchSignals({ count: 42, message: 'Hello' })
// Patch signals with complex data
patchSignals({
user: { id: 123, name: 'John' },
settings: { theme: 'dark' },
})
This function is particularly useful for:
- Updating signals from client-side event handlers
- Syncing state between different parts of your application
- Triggering signal updates from custom JavaScript code
$clientId
Signal
The $clientId
signal is automatically set when the realtime connection is established. This signal contains the unique client identifier assigned by PocketBase's realtime system.
<!-- Display the client ID -->
<div data-text="$clientId"></div>
<!-- Use in conditional rendering -->
<div data-if="$clientId">
Connected with ID: <span data-text="$clientId"></span>
</div>
<!-- Use in data attributes -->
<button data-on-click="@get('/api/action')" data-client-id="$clientId">
Perform Action
</button>
The $clientId
is useful for:
- Identifying the current client in realtime communications
- Debugging connection issues
- Creating client-specific functionality
- Tracking user sessions
Event Types
datastar-patch-elements
- DOM element updatesdatastar-patch-signals
- Signal updates
Default Values
DefaultSseRetryDuration
: 1000msDefaultElementsUseViewTransitions
: falseDefaultPatchSignalsOnlyIfMissing
: falseDefaultElementPatchMode
: 'outer'