what-server 0.8.4 → 0.10.0
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.
- package/dist/actions.js +32 -1
- package/dist/actions.js.map +3 -3
- package/dist/actions.min.js +1 -1
- package/dist/actions.min.js.map +4 -4
- package/dist/index.js +531 -23
- package/dist/index.js.map +4 -4
- package/dist/index.min.js +10 -10
- package/dist/index.min.js.map +4 -4
- package/dist/islands.js +23 -1
- package/dist/islands.js.map +3 -3
- package/dist/islands.min.js +1 -1
- package/dist/islands.min.js.map +4 -4
- package/package.json +8 -2
- package/src/action-handler.js +149 -0
- package/src/actions.js +13 -1
- package/src/adapter/cloudflare.js +18 -0
- package/src/adapter/core.js +112 -0
- package/src/adapter/node.js +77 -0
- package/src/adapter/static.js +62 -0
- package/src/adapter/vercel.js +29 -0
- package/src/index.js +184 -9
- package/src/islands.js +12 -2
- package/src/revalidation-registry.js +37 -0
- package/src/serialize.js +34 -0
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.js", "../src/actions.js"],
|
|
4
|
-
"sourcesContent": ["// What Framework - Server\n// SSR, static site generation, server components.\n// Zero-JS pages by default. Islands opt-in to client JS.\n\nimport { h } from 'what-core';\n\n// --- Hydration ID Generator ---\nlet _hydrationIdCounter = 0;\n\nfunction resetHydrationId() {\n _hydrationIdCounter = 0;\n}\n\nfunction nextHydrationId() {\n return 'h' + (_hydrationIdCounter++);\n}\n\n// --- Render to Hydratable String ---\n// Renders with hydration markers (data-hk attributes, comment boundaries)\n// so the client can reuse the server-rendered DOM.\n\nexport function renderToHydratableString(vnode) {\n resetHydrationId();\n return _renderHydratable(vnode);\n}\n\nfunction _renderHydratable(vnode) {\n if (vnode == null || vnode === false || vnode === true) return '';\n\n // Text\n if (typeof vnode === 'string' || typeof vnode === 'number') {\n return escapeHtml(String(vnode));\n }\n\n // Signal \u2014 unwrap\n if (typeof vnode === 'function' && vnode._signal) {\n return `<!--$-->${_renderHydratable(vnode())}<!--/$-->`;\n }\n\n // Reactive function child \u2014 wrap in dynamic content markers\n if (typeof vnode === 'function') {\n try {\n return `<!--$-->${_renderHydratable(vnode())}<!--/$-->`;\n } catch (e) {\n if (typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {\n console.warn('[what-server] Error rendering reactive function in SSR:', e.message);\n }\n return '<!--$--><!--/$-->';\n }\n }\n\n // Array \u2014 wrap in list markers\n if (Array.isArray(vnode)) {\n return `<!--[]-->${vnode.map(_renderHydratable).join('')}<!--/[]-->`;\n }\n\n // Component \u2014 add hydration key to root element\n if (typeof vnode.tag === 'function') {\n const hkId = nextHydrationId();\n const result = vnode.tag({ ...vnode.props, children: vnode.children });\n const html = _renderHydratable(result);\n // Inject data-hk into the first element tag if present\n return injectHydrationKey(html, hkId);\n }\n\n // Element\n const { tag, props, children } = vnode;\n const attrs = renderAttrs(props || {});\n const open = `<${tag}${attrs}>`;\n\n // Void elements\n if (VOID_ELEMENTS.has(tag)) return open;\n\n const rawInner = _resolveInnerHTML(props);\n const inner = rawInner != null ? String(rawInner) : children.map(_renderHydratable).join('');\n return `${open}${inner}</${tag}>`;\n}\n\n// Inject data-hk=\"id\" into the first HTML opening tag\nfunction injectHydrationKey(html, hkId) {\n // Skip comment markers to find the first real element\n const match = html.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);\n if (match) {\n const prefix = match[1];\n const tagName = match[2];\n const insertAt = prefix.length + 1 + tagName.length; // after '<tagName'\n return html.slice(0, insertAt) + ` data-hk=\"${hkId}\"` + html.slice(insertAt);\n }\n return html;\n}\n\n// --- Render to String ---\n// Renders a VNode tree to an HTML string. Used for SSR and static gen.\n\nexport function renderToString(vnode) {\n if (vnode == null || vnode === false || vnode === true) return '';\n\n // Text\n if (typeof vnode === 'string' || typeof vnode === 'number') {\n return escapeHtml(String(vnode));\n }\n\n // Signal \u2014 unwrap by calling it\n if (typeof vnode === 'function' && vnode._signal) {\n return renderToString(vnode());\n }\n\n // Reactive function child \u2014 call to get value\n if (typeof vnode === 'function') {\n try {\n return renderToString(vnode());\n } catch (e) {\n if (typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {\n console.warn('[what-server] Error rendering reactive function in SSR:', e.message);\n }\n return '';\n }\n }\n\n // Array\n if (Array.isArray(vnode)) {\n return vnode.map(renderToString).join('');\n }\n\n // Component\n if (typeof vnode.tag === 'function') {\n const result = vnode.tag({ ...vnode.props, children: vnode.children });\n return renderToString(result);\n }\n\n // Element\n const { tag, props, children } = vnode;\n const attrs = renderAttrs(props || {});\n const open = `<${tag}${attrs}>`;\n\n // Void elements\n if (VOID_ELEMENTS.has(tag)) return open;\n\n const rawInner = _resolveInnerHTML(props);\n const inner = rawInner != null ? String(rawInner) : children.map(renderToString).join('');\n return `${open}${inner}</${tag}>`;\n}\n\n// --- Stream Render ---\n// Returns an async iterator for streaming SSR.\n\nexport async function* renderToStream(vnode) {\n if (vnode == null || vnode === false || vnode === true) return;\n\n if (typeof vnode === 'string' || typeof vnode === 'number') {\n yield escapeHtml(String(vnode));\n return;\n }\n\n // Signal \u2014 unwrap by calling it\n if (typeof vnode === 'function' && vnode._signal) {\n yield* renderToStream(vnode());\n return;\n }\n\n // Reactive function child \u2014 call to get value\n if (typeof vnode === 'function') {\n try {\n yield* renderToStream(vnode());\n } catch (e) {\n if (typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {\n console.warn('[what-server] Error rendering reactive function in stream SSR:', e.message);\n }\n }\n return;\n }\n\n if (Array.isArray(vnode)) {\n for (const child of vnode) {\n yield* renderToStream(child);\n }\n return;\n }\n\n if (typeof vnode.tag === 'function') {\n try {\n const result = vnode.tag({ ...vnode.props, children: vnode.children });\n // Support async components\n const resolved = result instanceof Promise ? await result : result;\n yield* renderToStream(resolved);\n } catch (e) {\n if (typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {\n console.warn('[what-server] Error rendering component in stream SSR:', e.message);\n }\n yield _isDevMode\n ? `<!-- SSR Error: ${escapeHtml(e.message || 'Component error')} -->`\n : `<!-- SSR Error -->`;\n }\n return;\n }\n\n const { tag, props, children } = vnode;\n const attrs = renderAttrs(props || {});\n yield `<${tag}${attrs}>`;\n\n if (!VOID_ELEMENTS.has(tag)) {\n const rawInner = _resolveInnerHTML(props);\n if (rawInner != null) {\n yield String(rawInner);\n } else {\n for (const child of children) {\n yield* renderToStream(child);\n }\n }\n yield `</${tag}>`;\n }\n}\n\n// --- Static Site Generation ---\n\nexport function definePage(config) {\n return {\n // 'static' = pre-render at build time (default)\n // 'server' = render on each request\n // 'client' = render in browser (SPA)\n // 'hybrid' = static shell + islands\n mode: 'static',\n ...config,\n };\n}\n\n// Generate static HTML for a page\nexport function generateStaticPage(page, data = {}) {\n const vnode = page.component(data);\n const html = renderToString(vnode);\n const islands = page.islands || [];\n\n return wrapDocument({\n title: page.title || '',\n meta: page.meta || {},\n body: html,\n islands,\n scripts: page.mode === 'static' ? [] : page.scripts || [],\n styles: page.styles || [],\n mode: page.mode,\n });\n}\n\nfunction wrapDocument({ title, meta, body, islands, scripts, styles, mode }) {\n const metaTags = Object.entries(meta)\n .map(([name, content]) => `<meta name=\"${escapeHtml(name)}\" content=\"${escapeHtml(content)}\">`)\n .join('\\n ');\n\n const styleTags = styles\n .map(href => `<link rel=\"stylesheet\" href=\"${escapeHtml(href)}\">`)\n .join('\\n ');\n\n const islandScript = islands.length > 0 ? `\n <script type=\"module\">\n import { hydrateIslands } from '/@what/islands.js';\n hydrateIslands();\n </script>` : '';\n\n const scriptTags = scripts\n .map(src => `<script type=\"module\" src=\"${escapeHtml(src)}\"></script>`)\n .join('\\n ');\n\n const clientScript = mode === 'client' ? `\n <script type=\"module\" src=\"/@what/client.js\"></script>` : '';\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n ${metaTags}\n <title>${escapeHtml(title)}</title>\n ${styleTags}\n </head>\n <body>\n <div id=\"app\">${body}</div>\n ${islandScript}\n ${scriptTags}\n ${clientScript}\n </body>\n</html>`;\n}\n\n// --- Server Component ---\n// Renders on the server, sends HTML to client. No JS shipped.\n\nexport function server(Component) {\n Component._server = true;\n return Component;\n}\n\n// --- Helpers ---\n\n// Dev-mode flag for server\nconst _isDevMode = typeof process !== 'undefined'\n ? process.env?.NODE_ENV !== 'production'\n : true;\n\n/**\n * Resolve innerHTML / dangerouslySetInnerHTML from props.\n * Requires { __html: ... } wrapper. Plain string innerHTML is rejected (XSS prevention).\n */\nfunction _resolveInnerHTML(props) {\n if (!props) return null;\n\n // dangerouslySetInnerHTML always requires { __html }\n if (props.dangerouslySetInnerHTML) {\n return props.dangerouslySetInnerHTML.__html ?? null;\n }\n\n // innerHTML with { __html } wrapper \u2014 allowed\n if (props.innerHTML && typeof props.innerHTML === 'object' && '__html' in props.innerHTML) {\n return props.innerHTML.__html ?? null;\n }\n\n // innerHTML as plain string \u2014 reject with warning\n if (props.innerHTML != null && typeof props.innerHTML === 'string') {\n if (_isDevMode) {\n console.warn(\n '[what-server] innerHTML received a raw string. This is a security risk (XSS). ' +\n 'Use innerHTML={{ __html: trustedString }} or dangerouslySetInnerHTML={{ __html: trustedString }} instead.'\n );\n }\n return null;\n }\n\n return null;\n}\n\nfunction renderAttrs(props) {\n let out = '';\n for (const [key, val] of Object.entries(props)) {\n if (key === 'key' || key === 'ref' || key === 'children' || key === 'dangerouslySetInnerHTML' || key === 'innerHTML') continue;\n if (key.startsWith('on') && key.length > 2) continue; // Skip event handlers in SSR\n if (val === false || val == null) continue;\n\n if (key === 'className' || key === 'class') {\n out += ` class=\"${escapeHtml(String(val))}\"`;\n } else if (key === 'style' && typeof val === 'object') {\n const css = Object.entries(val)\n .map(([p, v]) => `${camelToKebab(p)}:${v}`)\n .join(';');\n out += ` style=\"${escapeHtml(css)}\"`;\n } else if (val === true) {\n // ARIA attributes require explicit =\"true\", HTML boolean attrs can be bare\n if (key.startsWith('aria-') || key === 'role') {\n out += ` ${key}=\"true\"`;\n } else {\n out += ` ${key}`;\n }\n } else {\n if (isUnsafeUrlAttribute(key, val)) continue;\n out += ` ${key}=\"${escapeHtml(String(val))}\"`;\n }\n }\n\n return out;\n}\n\n\nfunction isUnsafeUrlAttribute(key, val) {\n const normalizedKey = key.toLowerCase();\n if (!URL_ATTRS.has(normalizedKey)) return false;\n const normalizedValue = String(val).trim().replace(/[\\u0000-\\u001f\\u007f\\s]+/g, '').toLowerCase();\n return normalizedValue.startsWith('javascript:') || normalizedValue.startsWith('vbscript:');\n}\n\nconst URL_ATTRS = new Set([\n 'href', 'src', 'action', 'formaction', 'xlink:href',\n]);\n\nfunction escapeHtml(str) {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction camelToKebab(str) {\n if (str.startsWith('--')) return str; // CSS custom properties (variables) \u2014 leave unchanged\n return str.replace(/([A-Z])/g, '-$1').toLowerCase();\n}\n\nconst VOID_ELEMENTS = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr',\n]);\n\n// Re-export server actions\nexport {\n action,\n formAction,\n useAction,\n useFormAction,\n useOptimistic,\n useMutation,\n onRevalidate,\n invalidatePath,\n handleActionRequest,\n getRegisteredActions,\n generateCsrfToken,\n validateCsrfToken,\n csrfMetaTag,\n} from './actions.js';\n", "// What Framework - Server Actions\n// Call server-side functions from client code seamlessly.\n// Similar to Next.js Server Actions / SolidStart server functions.\n//\n// Usage:\n// // Define on server\n// const saveUser = action(async (formData) => {\n// 'use server';\n// const user = await db.users.create(formData);\n// return { success: true, id: user.id };\n// });\n//\n// // Call from client\n// const result = await saveUser({ name: 'John' });\n\nimport { signal, batch } from 'what-core';\n\n// Registry of server actions\nconst actionRegistry = new Map();\n\n// --- CSRF Protection ---\n// Server generates a token per session; client sends it with every action request.\n// The token is injected into the page via a meta tag or embedded in the server response.\n\n// Client: read the CSRF token from the page meta tag or cookie\n// Re-reads on every call to handle token rotation\nfunction getCsrfToken() {\n if (typeof document !== 'undefined') {\n // Try meta tag first\n const meta = document.querySelector('meta[name=\"what-csrf-token\"]');\n if (meta) {\n return meta.getAttribute('content');\n }\n // Try cookie\n const match = document.cookie.match(/(?:^|;\\s*)what-csrf=([^;]+)/);\n if (match) {\n return decodeURIComponent(match[1]);\n }\n }\n return null;\n}\n\n// Server: generate a CSRF token (call this per session/request)\nexport function generateCsrfToken() {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Fallback for environments without crypto.randomUUID \u2014 use crypto.getRandomValues\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n const arr = new Uint8Array(16);\n crypto.getRandomValues(arr);\n return Array.from(arr, b => b.toString(16).padStart(2, '0')).join('');\n }\n // Last resort \u2014 should not be reached in modern environments\n throw new Error('[what] No secure random source available for CSRF token generation');\n}\n\n// Server: validate CSRF token from request header against session token\nexport function validateCsrfToken(requestToken, sessionToken) {\n if (!requestToken || !sessionToken) return false;\n // Constant-time comparison to prevent timing attacks\n if (requestToken.length !== sessionToken.length) return false;\n let result = 0;\n for (let i = 0; i < requestToken.length; i++) {\n result |= requestToken.charCodeAt(i) ^ sessionToken.charCodeAt(i);\n }\n return result === 0;\n}\n\n// Server: middleware helper to inject CSRF meta tag into HTML\nexport function csrfMetaTag(token) {\n // HTML-escape the token to prevent XSS if a non-standard value is used\n const escaped = String(token).replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<').replace(/>/g, '>');\n return `<meta name=\"what-csrf-token\" content=\"${escaped}\">`;\n}\n\n// --- Define a server action ---\n\nlet _actionCounter = 0;\n\nfunction generateActionId() {\n // Generate a deterministic ID \u2014 prefer crypto.getRandomValues, fall back to a\n // monotonic counter (never Math.random, which is not cryptographically safe and\n // produces predictable IDs in some runtimes).\n const rand = typeof crypto !== 'undefined' && crypto.getRandomValues\n ? Array.from(crypto.getRandomValues(new Uint8Array(6)), b => b.toString(16).padStart(2, '0')).join('')\n : `c${(++_actionCounter).toString(36)}_${Date.now().toString(36)}`;\n return `a_${rand}`;\n}\n\nexport function action(fn, options = {}) {\n const id = options.id || generateActionId();\n const { onError, onSuccess, revalidate } = options;\n\n // Server-side: register the action\n if (typeof window === 'undefined') {\n actionRegistry.set(id, { fn, options });\n }\n\n // Create the callable wrapper\n async function callAction(...args) {\n // Server-side: call directly\n if (typeof window === 'undefined') {\n return fn(...args);\n }\n\n // Client-side: call via fetch with timeout support\n const timeout = options.timeout || 30000; // Default 30s timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const csrfToken = getCsrfToken();\n const headers = {\n 'Content-Type': 'application/json',\n 'X-What-Action': id,\n };\n if (csrfToken) headers['X-CSRF-Token'] = csrfToken;\n\n const response = await fetch('/__what_action', {\n method: 'POST',\n headers,\n credentials: 'same-origin',\n signal: controller.signal,\n body: JSON.stringify({ args }),\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: 'Action failed' }));\n throw new Error(error.message || 'Action failed');\n }\n\n const result = await response.json();\n\n if (onSuccess) onSuccess(result);\n if (revalidate) {\n // Trigger revalidation of specified paths\n for (const path of revalidate) {\n invalidatePath(path);\n }\n }\n\n return result;\n } catch (error) {\n if (error.name === 'AbortError') {\n const timeoutError = new Error(`Action \"${id}\" timed out after ${timeout}ms`);\n timeoutError.code = 'TIMEOUT';\n if (onError) onError(timeoutError);\n throw timeoutError;\n }\n if (onError) onError(error);\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n callAction._actionId = id;\n callAction._isAction = true;\n\n return callAction;\n}\n\n// --- Form action helper ---\n// For forms that submit to server actions.\n\nexport function formAction(actionFn, options = {}) {\n const { onSuccess, onError, resetOnSuccess = true } = options;\n\n return async (formDataOrEvent) => {\n let formData;\n let form;\n\n if (formDataOrEvent instanceof Event) {\n formDataOrEvent.preventDefault();\n form = formDataOrEvent.target;\n formData = new FormData(form);\n } else {\n formData = formDataOrEvent;\n }\n\n // Convert FormData to plain object, preserving File instances\n const data = {};\n let hasFiles = false;\n for (const [key, value] of formData.entries()) {\n if (typeof File !== 'undefined' && value instanceof File) {\n hasFiles = true;\n }\n if (data[key]) {\n // Handle multiple values (e.g., checkboxes, multi-file inputs)\n if (Array.isArray(data[key])) {\n data[key].push(value);\n } else {\n data[key] = [data[key], value];\n }\n } else {\n data[key] = value;\n }\n }\n\n try {\n // If form contains files, pass the raw FormData as second arg\n // so the action handler can access files directly\n const result = hasFiles\n ? await actionFn(data, formData)\n : await actionFn(data);\n if (onSuccess) onSuccess(result, form);\n if (resetOnSuccess && form) form.reset();\n return result;\n } catch (error) {\n if (onError) onError(error, form);\n throw error;\n }\n };\n}\n\n// --- useAction hook ---\n// Returns action state and trigger function.\n\nexport function useAction(actionFn) {\n const isPending = signal(false);\n const error = signal(null);\n const data = signal(null);\n\n async function trigger(...args) {\n isPending.set(true);\n error.set(null);\n\n try {\n const result = await actionFn(...args);\n data.set(result);\n return result;\n } catch (e) {\n error.set(e);\n throw e;\n } finally {\n isPending.set(false);\n }\n }\n\n return {\n trigger,\n isPending: () => isPending(),\n error: () => error(),\n data: () => data(),\n reset: () => {\n error.set(null);\n data.set(null);\n },\n };\n}\n\n// --- useFormAction hook ---\n// Combines useAction with form handling.\n\nexport function useFormAction(actionFn, options = {}) {\n const { resetOnSuccess = true } = options;\n const formRef = { current: null };\n const actionState = useAction(formAction(actionFn, { resetOnSuccess }));\n\n function handleSubmit(e) {\n e.preventDefault();\n const formData = new FormData(e.target);\n formRef.current = e.target;\n return actionState.trigger(formData);\n }\n\n return {\n ...actionState,\n handleSubmit,\n formRef,\n };\n}\n\n// --- Optimistic updates ---\n\nexport function useOptimistic(initialValue, reducer) {\n const value = signal(initialValue);\n const pending = signal([]);\n const baseValue = signal(initialValue); // Track the confirmed server value\n\n function addOptimistic(action) {\n const optimisticValue = reducer(value.peek(), action);\n batch(() => {\n pending.set([...pending.peek(), action]);\n value.set(optimisticValue);\n });\n }\n\n function resolve(action, serverValue) {\n batch(() => {\n pending.set(pending.peek().filter(a => a !== action));\n if (serverValue !== undefined) {\n baseValue.set(serverValue);\n // Recompute optimistic state from new base + remaining pending actions\n let current = serverValue;\n for (const a of pending.peek()) {\n current = reducer(current, a);\n }\n value.set(current);\n }\n });\n }\n\n function rollback(action, realValue) {\n batch(() => {\n const newPending = pending.peek().filter(a => a !== action);\n pending.set(newPending);\n const base = realValue !== undefined ? realValue : baseValue.peek();\n baseValue.set(base);\n // Recompute from base + remaining pending actions\n let current = base;\n for (const a of newPending) {\n current = reducer(current, a);\n }\n value.set(current);\n });\n }\n\n // Auto-rollback helper: wraps an async action with automatic rollback on error\n async function withOptimistic(action, asyncFn) {\n addOptimistic(action);\n try {\n const result = await asyncFn();\n resolve(action, result);\n return result;\n } catch (e) {\n rollback(action);\n throw e;\n }\n }\n\n return {\n value: () => value(),\n isPending: () => pending().length > 0,\n addOptimistic,\n resolve,\n rollback,\n withOptimistic,\n set: (v) => { value.set(v); baseValue.set(v); },\n };\n}\n\n// --- Path revalidation ---\n\nconst revalidationCallbacks = new Map();\n\nexport function onRevalidate(path, callback) {\n if (!revalidationCallbacks.has(path)) {\n revalidationCallbacks.set(path, new Set());\n }\n revalidationCallbacks.get(path).add(callback);\n\n return () => {\n revalidationCallbacks.get(path)?.delete(callback);\n };\n}\n\nexport function invalidatePath(path) {\n const callbacks = revalidationCallbacks.get(path);\n if (callbacks) {\n for (const cb of callbacks) {\n try { cb(); } catch (e) { console.error('[what] Revalidation error:', e); }\n }\n }\n}\n\n// --- Server-side action handler ---\n// Add this to your server middleware.\n\nexport function handleActionRequest(req, actionId, args, options = {}) {\n const { csrfToken: sessionCsrfToken, skipCsrf = false } = options;\n\n // Validate CSRF token unless explicitly skipped\n if (!skipCsrf) {\n if (!sessionCsrfToken) {\n // Fail closed: no CSRF token configured means the developer forgot to set it up.\n // This prevents silent security vulnerabilities in production.\n return Promise.resolve({\n status: 500,\n body: {\n message: '[what] CSRF token not configured. ' +\n 'Pass { csrfToken: sessionToken } to handleActionRequest, ' +\n 'or { skipCsrf: true } to explicitly opt out.'\n }\n });\n }\n const requestCsrfToken = req?.headers?.['x-csrf-token'] || req?.headers?.['X-CSRF-Token'];\n if (!validateCsrfToken(requestCsrfToken, sessionCsrfToken)) {\n return Promise.resolve({ status: 403, body: { message: 'Invalid CSRF token' } });\n }\n }\n\n const action = actionRegistry.get(actionId);\n if (!action) {\n return Promise.resolve({ status: 404, body: { message: 'Action not found' } });\n }\n\n // Validate args is an array to prevent prototype pollution\n if (!Array.isArray(args)) {\n return Promise.resolve({ status: 400, body: { message: 'Invalid action arguments' } });\n }\n\n return action.fn(...args)\n .then(result => ({ status: 200, body: result }))\n .catch(error => {\n // Log the full error server-side, return generic message to client\n console.error(`[what] Action \"${actionId}\" error:`, error);\n return {\n status: 500,\n body: { message: 'Action failed' },\n };\n });\n}\n\n// --- Get all registered actions (for SSR/build) ---\n\nexport function getRegisteredActions() {\n return [...actionRegistry.keys()];\n}\n\n// --- Mutation helper ---\n// Like useSWR mutation but simpler.\n\nexport function useMutation(mutationFn, options = {}) {\n const { onSuccess, onError, onSettled } = options;\n\n const state = {\n isPending: signal(false),\n error: signal(null),\n data: signal(null),\n };\n\n async function mutate(...args) {\n state.isPending.set(true);\n state.error.set(null);\n\n try {\n const result = await mutationFn(...args);\n state.data.set(result);\n if (onSuccess) onSuccess(result, ...args);\n return result;\n } catch (error) {\n state.error.set(error);\n if (onError) onError(error, ...args);\n throw error;\n } finally {\n state.isPending.set(false);\n if (onSettled) onSettled(state.data.peek(), state.error.peek(), ...args);\n }\n }\n\n return {\n mutate,\n isPending: () => state.isPending(),\n error: () => state.error(),\n data: () => state.data(),\n reset: () => {\n state.error.set(null);\n state.data.set(null);\n },\n };\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["action"]
|
|
3
|
+
"sources": ["../src/index.js", "../src/serialize.js", "../src/islands.js", "../src/actions.js", "../src/revalidation-registry.js", "../src/action-handler.js", "../src/adapter/core.js", "../src/adapter/node.js", "../src/adapter/static.js", "../src/adapter/cloudflare.js", "../src/adapter/vercel.js"],
|
|
4
|
+
"sourcesContent": ["// What Framework - Server\n// SSR, static site generation, server components.\n// Zero-JS pages by default. Islands opt-in to client JS.\n\nimport { h, runWithServerContext, beginHeadCollection, endHeadCollection } from 'what-core';\nimport { serializeState } from './serialize.js';\nimport { getIslandStoresSnapshot } from './islands.js';\n\n// Build a fresh render-scoped server context (head sink, loader data, resources).\nfunction createRenderContext(loaderData) {\n return {\n head: beginHeadCollection(),\n loaderData,\n resources: new Map(),\n resourceCounter: 0,\n boundaryCounter: 0,\n suspended: [],\n };\n}\n\n// --- Hydration ID Generator ---\nlet _hydrationIdCounter = 0;\n\nfunction resetHydrationId() {\n _hydrationIdCounter = 0;\n}\n\nfunction nextHydrationId() {\n return 'h' + (_hydrationIdCounter++);\n}\n\n// --- Render to Hydratable String ---\n// Renders with hydration markers (data-hk attributes, comment boundaries)\n// so the client can reuse the server-rendered DOM.\n\nexport function renderToHydratableString(vnode) {\n resetHydrationId();\n return _renderHydratable(vnode);\n}\n\nfunction _renderHydratable(vnode) {\n if (vnode == null || vnode === false || vnode === true) return '';\n\n // Text\n if (typeof vnode === 'string' || typeof vnode === 'number') {\n return escapeHtml(String(vnode));\n }\n\n // Signal \u2014 unwrap\n if (typeof vnode === 'function' && vnode._signal) {\n return `<!--$-->${_renderHydratable(vnode())}<!--/$-->`;\n }\n\n // Reactive function child \u2014 wrap in dynamic content markers\n if (typeof vnode === 'function') {\n try {\n return `<!--$-->${_renderHydratable(vnode())}<!--/$-->`;\n } catch (e) {\n if (typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {\n console.warn('[what-server] Error rendering reactive function in SSR:', e.message);\n }\n return '<!--$--><!--/$-->';\n }\n }\n\n // Array \u2014 wrap in list markers\n if (Array.isArray(vnode)) {\n return `<!--[]-->${vnode.map(_renderHydratable).join('')}<!--/[]-->`;\n }\n\n // Component \u2014 add hydration key to root element\n if (typeof vnode.tag === 'function') {\n const hkId = nextHydrationId();\n const result = vnode.tag({ ...vnode.props, children: vnode.children });\n const html = _renderHydratable(result);\n // Inject data-hk into the first element tag if present\n return injectHydrationKey(html, hkId);\n }\n\n // Element\n const { tag, props, children } = vnode;\n const attrs = renderAttrs(props || {});\n const open = `<${tag}${attrs}>`;\n\n // Void elements\n if (VOID_ELEMENTS.has(tag)) return open;\n\n const rawInner = _resolveInnerHTML(props);\n const inner = rawInner != null ? String(rawInner) : children.map(_renderHydratable).join('');\n return `${open}${inner}</${tag}>`;\n}\n\n// Inject data-hk=\"id\" into the first HTML opening tag\nfunction injectHydrationKey(html, hkId) {\n // Skip comment markers to find the first real element\n const match = html.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);\n if (match) {\n const prefix = match[1];\n const tagName = match[2];\n const insertAt = prefix.length + 1 + tagName.length; // after '<tagName'\n return html.slice(0, insertAt) + ` data-hk=\"${hkId}\"` + html.slice(insertAt);\n }\n return html;\n}\n\n// --- Render to String ---\n// Renders a VNode tree to an HTML string. Used for SSR and static gen.\n\nexport function renderToString(vnode) {\n if (vnode == null || vnode === false || vnode === true) return '';\n\n // Text\n if (typeof vnode === 'string' || typeof vnode === 'number') {\n return escapeHtml(String(vnode));\n }\n\n // Signal \u2014 unwrap by calling it\n if (typeof vnode === 'function' && vnode._signal) {\n return renderToString(vnode());\n }\n\n // Reactive function child \u2014 call to get value\n if (typeof vnode === 'function') {\n try {\n return renderToString(vnode());\n } catch (e) {\n if (typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {\n console.warn('[what-server] Error rendering reactive function in SSR:', e.message);\n }\n return '';\n }\n }\n\n // Array\n if (Array.isArray(vnode)) {\n return vnode.map(renderToString).join('');\n }\n\n // Suspense boundary \u2014 render children; if a child suspends (throws a thenable),\n // show the fallback (a synchronous render cannot await). renderToStringAsync /\n // renderToStream await the pending resources and re-render with real content.\n if (vnode.tag === '__suspense') {\n try {\n return (vnode.children || []).map(renderToString).join('');\n } catch (e) {\n if (e && typeof e.then === 'function') {\n return renderToString(vnode.props && vnode.props.fallback);\n }\n throw e;\n }\n }\n\n // Component\n if (typeof vnode.tag === 'function') {\n const result = vnode.tag({ ...vnode.props, children: vnode.children });\n return renderToString(result);\n }\n\n // Element\n const { tag, props, children } = vnode;\n const attrs = renderAttrs(props || {});\n const open = `<${tag}${attrs}>`;\n\n // Void elements\n if (VOID_ELEMENTS.has(tag)) return open;\n\n const rawInner = _resolveInnerHTML(props);\n const inner = rawInner != null ? String(rawInner) : children.map(renderToString).join('');\n return `${open}${inner}</${tag}>`;\n}\n\n// --- Render to String + collected <head> ---\n// Like renderToString, but captures any <Head> tags declared anywhere in the\n// tree into a render-scoped sink and returns them as escaped <head> HTML.\n//\n// Concurrency: renderToString is synchronous, so the render context set by\n// runWithServerContext lives within one uninterrupted tick \u2014 safe under\n// concurrent requests (no two renders interleave in the sync path).\nexport function renderToStringWithHead(vnode) {\n const ctx = createRenderContext(undefined);\n const body = runWithServerContext(ctx, () => renderToString(vnode));\n return { body, head: endHeadCollection(ctx.head) };\n}\n\n// --- Render a page module (loader + component) ---\n// Runs the page's `export const loader` (if any) BEFORE the synchronous render,\n// so the resolved value is plain data by the time the render reads it. The\n// loader receives { params, query, request }. Its result is passed to the page\n// component as a `loaderData` prop and is readable anywhere via useLoaderData().\n//\n// `pageModule` is `{ default: Component, loader? }` (the shape file-router emits).\nexport async function renderPage(pageModule, reqCtx = {}) {\n const Component = pageModule.default || pageModule;\n const loaderData = typeof pageModule.loader === 'function'\n ? await pageModule.loader(reqCtx)\n : undefined;\n const ctx = createRenderContext(loaderData);\n const params = reqCtx.params || {};\n const body = runWithServerContext(ctx, () =>\n renderToString(h(Component, { ...params, loaderData }))\n );\n return { body, head: endHeadCollection(ctx.head), loaderData };\n}\n\n// --- Async render (resolves Suspense / createResource data) ---\n// Renders, then awaits any resources that suspended, then re-renders with the\n// resolved data \u2014 repeating until the tree is stable. Returns the body, the\n// collected head, and the resolved resources for the hydration payload.\nconst MAX_RESOLVE_PASSES = 12;\n\nexport async function renderToStringAsync(vnode, ctx) {\n if (!ctx) ctx = createRenderContext(undefined);\n let body = '';\n for (let pass = 0; pass < MAX_RESOLVE_PASSES; pass++) {\n body = runWithServerContext(ctx, () => renderToString(vnode));\n const pending = [...ctx.resources.values()]\n .filter((r) => r.status === 'pending')\n .map((r) => r.promise);\n if (pending.length === 0) break;\n await Promise.all(pending);\n }\n const resources = {};\n for (const [k, v] of ctx.resources) if (v.status === 'ready') resources[k] = v.value;\n return { body, head: endHeadCollection(ctx.head), loaderData: ctx.loaderData, resources, ctx };\n}\n\n// --- Render a complete HTML document (loader + data + head + hydration payload) ---\n// The full-stack entry: runs the loader, renders (resolving async resources),\n// and emits one consolidated <script id=\"__what_data\"> with { loaderData,\n// resources, islandStores } for the client to hydrate from without refetching.\nexport async function renderDocument(pageModule, reqCtx = {}, options = {}) {\n const Component = pageModule.default || pageModule;\n const loaderData = typeof pageModule.loader === 'function'\n ? await pageModule.loader(reqCtx)\n : undefined;\n const ctx = createRenderContext(loaderData);\n const params = reqCtx.params || {};\n const { body, head, resources } = await renderToStringAsync(\n h(Component, { ...params, loaderData }),\n ctx\n );\n const payload = {\n loaderData: loaderData ?? null,\n resources,\n islandStores: getIslandStoresSnapshot(),\n };\n return wrapHtmlDocument({ body, head, payload, options });\n}\n\nfunction wrapHtmlDocument({ body, head, payload, options = {} }) {\n const lang = options.lang || 'en';\n const dataScript = `<script id=\"__what_data\" type=\"application/json\">${serializeState(payload)}</script>`;\n const clientScript = options.clientEntry\n ? `<script type=\"module\" src=\"${escapeHtml(options.clientEntry)}\"></script>`\n : '';\n const extraHead = options.head || '';\n const bodyClass = options.bodyClass ? ` class=\"${escapeHtml(options.bodyClass)}\"` : '';\n return (\n `<!DOCTYPE html><html lang=\"${escapeHtml(lang)}\"><head>` +\n `<meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">` +\n `${head || ''}${extraHead}</head><body${bodyClass}>` +\n `${body}${dataScript}${clientScript}</body></html>`\n );\n}\n\n// --- Stream Render ---\n// Returns an async iterator for streaming SSR. `ctx` is threaded explicitly so\n// concurrent streams never share state across `await` points.\n\nexport async function* renderToStream(vnode, ctx) {\n if (ctx === undefined) ctx = createRenderContext(undefined);\n if (vnode == null || vnode === false || vnode === true) return;\n\n if (typeof vnode === 'string' || typeof vnode === 'number') {\n yield escapeHtml(String(vnode));\n return;\n }\n\n // Signal \u2014 unwrap by calling it\n if (typeof vnode === 'function' && vnode._signal) {\n yield* renderToStream(vnode(), ctx);\n return;\n }\n\n // Reactive function child \u2014 call to get value\n if (typeof vnode === 'function') {\n try {\n yield* renderToStream(vnode(), ctx);\n } catch (e) {\n if (typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {\n console.warn('[what-server] Error rendering reactive function in stream SSR:', e.message);\n }\n }\n return;\n }\n\n if (Array.isArray(vnode)) {\n for (const child of vnode) {\n yield* renderToStream(child, ctx);\n }\n return;\n }\n\n // Suspense boundary \u2014 render the subtree, awaiting any suspended resources,\n // then emit the resolved content. (In-order; out-of-order swap is a future\n // enhancement.) The synchronous render runs inside the threaded ctx.\n if (vnode.tag === '__suspense') {\n let html = null;\n for (let attempt = 0; attempt < MAX_RESOLVE_PASSES && html === null; attempt++) {\n let suspended = null;\n try {\n html = runWithServerContext(ctx, () => (vnode.children || []).map(renderToString).join(''));\n } catch (e) {\n if (e && typeof e.then === 'function') suspended = e;\n else throw e;\n }\n if (html === null) {\n const pending = [...ctx.resources.values()].filter((r) => r.status === 'pending').map((r) => r.promise);\n await Promise.all([suspended, ...pending].filter(Boolean));\n }\n }\n if (html === null) {\n html = runWithServerContext(ctx, () => renderToString(vnode.props && vnode.props.fallback));\n }\n yield html;\n return;\n }\n\n if (typeof vnode.tag === 'function') {\n try {\n const result = vnode.tag({ ...vnode.props, children: vnode.children });\n // Support async components\n const resolved = result instanceof Promise ? await result : result;\n yield* renderToStream(resolved, ctx);\n } catch (e) {\n if (typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {\n console.warn('[what-server] Error rendering component in stream SSR:', e.message);\n }\n yield _isDevMode\n ? `<!-- SSR Error: ${escapeHtml(e.message || 'Component error')} -->`\n : `<!-- SSR Error -->`;\n }\n return;\n }\n\n const { tag, props, children } = vnode;\n const attrs = renderAttrs(props || {});\n yield `<${tag}${attrs}>`;\n\n if (!VOID_ELEMENTS.has(tag)) {\n const rawInner = _resolveInnerHTML(props);\n if (rawInner != null) {\n yield String(rawInner);\n } else {\n for (const child of children) {\n yield* renderToStream(child, ctx);\n }\n }\n yield `</${tag}>`;\n }\n}\n\n// --- Static Site Generation ---\n\nexport function definePage(config) {\n return {\n // 'static' = pre-render at build time (default)\n // 'server' = render on each request\n // 'client' = render in browser (SPA)\n // 'hybrid' = static shell + islands\n mode: 'static',\n ...config,\n };\n}\n\n// Generate static HTML for a page\nexport function generateStaticPage(page, data = {}) {\n const vnode = page.component(data);\n const html = renderToString(vnode);\n const islands = page.islands || [];\n\n return wrapDocument({\n title: page.title || '',\n meta: page.meta || {},\n body: html,\n islands,\n scripts: page.mode === 'static' ? [] : page.scripts || [],\n styles: page.styles || [],\n mode: page.mode,\n });\n}\n\nfunction wrapDocument({ title, meta, body, islands, scripts, styles, mode }) {\n const metaTags = Object.entries(meta)\n .map(([name, content]) => `<meta name=\"${escapeHtml(name)}\" content=\"${escapeHtml(content)}\">`)\n .join('\\n ');\n\n const styleTags = styles\n .map(href => `<link rel=\"stylesheet\" href=\"${escapeHtml(href)}\">`)\n .join('\\n ');\n\n const islandScript = islands.length > 0 ? `\n <script type=\"module\">\n import { hydrateIslands } from '/@what/islands.js';\n hydrateIslands();\n </script>` : '';\n\n const scriptTags = scripts\n .map(src => `<script type=\"module\" src=\"${escapeHtml(src)}\"></script>`)\n .join('\\n ');\n\n const clientScript = mode === 'client' ? `\n <script type=\"module\" src=\"/@what/client.js\"></script>` : '';\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n ${metaTags}\n <title>${escapeHtml(title)}</title>\n ${styleTags}\n </head>\n <body>\n <div id=\"app\">${body}</div>\n ${islandScript}\n ${scriptTags}\n ${clientScript}\n </body>\n</html>`;\n}\n\n// --- Server Component ---\n// Renders on the server, sends HTML to client. No JS shipped.\n\nexport function server(Component) {\n Component._server = true;\n return Component;\n}\n\n// --- Helpers ---\n\n// Dev-mode flag for server\nconst _isDevMode = typeof process !== 'undefined'\n ? process.env?.NODE_ENV !== 'production'\n : true;\n\n/**\n * Resolve innerHTML / dangerouslySetInnerHTML from props.\n * Requires { __html: ... } wrapper. Plain string innerHTML is rejected (XSS prevention).\n */\nfunction _resolveInnerHTML(props) {\n if (!props) return null;\n\n // dangerouslySetInnerHTML always requires { __html }\n if (props.dangerouslySetInnerHTML) {\n return props.dangerouslySetInnerHTML.__html ?? null;\n }\n\n // innerHTML with { __html } wrapper \u2014 allowed\n if (props.innerHTML && typeof props.innerHTML === 'object' && '__html' in props.innerHTML) {\n return props.innerHTML.__html ?? null;\n }\n\n // innerHTML as plain string \u2014 reject with warning\n if (props.innerHTML != null && typeof props.innerHTML === 'string') {\n if (_isDevMode) {\n console.warn(\n '[what-server] innerHTML received a raw string. This is a security risk (XSS). ' +\n 'Use innerHTML={{ __html: trustedString }} or dangerouslySetInnerHTML={{ __html: trustedString }} instead.'\n );\n }\n return null;\n }\n\n return null;\n}\n\nfunction renderAttrs(props) {\n let out = '';\n for (const [key, val] of Object.entries(props)) {\n if (key === 'key' || key === 'ref' || key === 'children' || key === 'dangerouslySetInnerHTML' || key === 'innerHTML') continue;\n if (key.startsWith('on') && key.length > 2) continue; // Skip event handlers in SSR\n if (val === false || val == null) continue;\n\n if (key === 'className' || key === 'class') {\n out += ` class=\"${escapeHtml(String(val))}\"`;\n } else if (key === 'style' && typeof val === 'object') {\n const css = Object.entries(val)\n .map(([p, v]) => `${camelToKebab(p)}:${v}`)\n .join(';');\n out += ` style=\"${escapeHtml(css)}\"`;\n } else if (val === true) {\n // ARIA attributes require explicit =\"true\", HTML boolean attrs can be bare\n if (key.startsWith('aria-') || key === 'role') {\n out += ` ${key}=\"true\"`;\n } else {\n out += ` ${key}`;\n }\n } else {\n if (isUnsafeUrlAttribute(key, val)) continue;\n out += ` ${key}=\"${escapeHtml(String(val))}\"`;\n }\n }\n\n return out;\n}\n\n\nfunction isUnsafeUrlAttribute(key, val) {\n const normalizedKey = key.toLowerCase();\n if (!URL_ATTRS.has(normalizedKey)) return false;\n const normalizedValue = String(val).trim().replace(/[\\u0000-\\u001f\\u007f\\s]+/g, '').toLowerCase();\n return normalizedValue.startsWith('javascript:') || normalizedValue.startsWith('vbscript:') || normalizedValue.startsWith('data:');\n}\n\nconst URL_ATTRS = new Set([\n 'href', 'src', 'action', 'formaction', 'xlink:href',\n]);\n\nfunction escapeHtml(str) {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\nfunction camelToKebab(str) {\n if (str.startsWith('--')) return str; // CSS custom properties (variables) \u2014 leave unchanged\n return str.replace(/([A-Z])/g, '-$1').toLowerCase();\n}\n\nconst VOID_ELEMENTS = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr',\n]);\n\n// Re-export server actions\nexport {\n action,\n formAction,\n useAction,\n useFormAction,\n useOptimistic,\n useMutation,\n onRevalidate,\n invalidatePath,\n handleActionRequest,\n getRegisteredActions,\n generateCsrfToken,\n validateCsrfToken,\n csrfMetaTag,\n} from './actions.js';\n\n// Served server actions: wire the /__what_action route (Node + fetch adapters)\nexport {\n createActionHandler,\n nodeActionMiddleware,\n fetchActionHandler,\n} from './action-handler.js';\n\n// Revalidation registry \u2014 app code calls revalidatePath/revalidateTag; the\n// deploy adapter binds a what-cache engine via setRevalidationHandler.\nexport {\n revalidatePath,\n revalidateTag,\n setRevalidationHandler,\n getRevalidationHandler,\n} from './revalidation-registry.js';\n\n// Deploy adapters \u2014 framework-agnostic core + Node / static / edge wrappers\nexport { createRequestHandler } from './adapter/core.js';\nexport { createServer, toNodeListener, whatMiddleware } from './adapter/node.js';\nexport { exportStatic } from './adapter/static.js';\nexport { createCloudflareHandler } from './adapter/cloudflare.js';\nexport { createVercelHandler, buildVercelOutput } from './adapter/vercel.js';\n\n// Safe state serialization for inlining into <script> tags (AUDIT-2026-06-06 M13)\nexport { serializeState } from './serialize.js';\n", "// Safe serialization of state for inlining into an HTML <script> tag.\n//\n// Stateless on purpose: this module holds no shared state, so it is safe for\n// the bundler to inline into multiple server entry points without creating\n// divergent instances (unlike islands.js's sharedStores).\n//\n// JSON.stringify alone is NOT safe to drop inside <script>...</script>: a value\n// containing \"</script>\" (or \"<!--\", \"<script\") breaks out of the element and\n// injects markup -- stored XSS when any value is user-controlled\n// (AUDIT-2026-06-06 H3). Escaping \"<\", \">\", \"&\" as \\uXXXX keeps the output\n// valid JSON (so JSON.parse on hydrate still works) while making it inert in\n// HTML. U+2028/U+2029 are also escaped: they are valid in JSON strings but are\n// illegal in JS string literals and can break inline script parsing.\n\n// Built via new RegExp from escape sequences so this source file contains no\n// invisible separator characters. Matches: < > & U+2028 U+2029.\nconst SCRIPT_UNSAFE = new RegExp('[<>&\\\\u2028\\\\u2029]', 'g');\n\nconst ESCAPES = {\n 0x3c: '\\\\u003c', // <\n 0x3e: '\\\\u003e', // >\n 0x26: '\\\\u0026', // &\n 0x2028: '\\\\u2028',\n 0x2029: '\\\\u2029',\n};\n\n/**\n * Serialize a value to a JSON string that is safe to embed verbatim inside an\n * HTML <script> element. Always use this instead of bare JSON.stringify when\n * inlining hydration/state payloads into server-rendered HTML.\n */\nexport function serializeState(value) {\n return JSON.stringify(value).replace(SCRIPT_UNSAFE, (c) => ESCAPES[c.charCodeAt(0)]);\n}\n", "// What Framework - Islands Architecture\n// Each interactive piece of the page is an \"island\" \u2014 a self-contained\n// component that hydrates independently. The rest is static HTML.\n//\n// Features:\n// - Multiple hydration modes (load, idle, visible, action, media, static)\n// - Shared state across islands\n// - Priority-based hydration queue\n// - Progressive enhancement\n//\n// Modes:\n// 'static' - No JS shipped. Pure HTML. (nav, footer, etc.)\n// 'idle' - Hydrate when browser is idle (requestIdleCallback)\n// 'visible' - Hydrate when scrolled into view (IntersectionObserver)\n// 'load' - Hydrate immediately on page load\n// 'media' - Hydrate when media query matches (e.g., mobile-only)\n// 'action' - Hydrate on first user interaction (click, focus, hover)\n\nimport { mount, hydrate, signal, batch } from 'what-core';\nimport { serializeState } from './serialize.js';\n\nconst islandRegistry = new Map();\nconst hydratedIslands = new Set();\nconst hydrationQueue = [];\nlet isProcessingQueue = false;\n\n// --- Shared Island State ---\n// Global reactive store that persists across islands and page navigations\n\nconst sharedStores = new Map();\n\nexport function createIslandStore(name, initialState) {\n if (sharedStores.has(name)) {\n return sharedStores.get(name);\n }\n\n const store = {};\n const signals = {};\n\n // Create signals for each key in initial state\n for (const [key, value] of Object.entries(initialState)) {\n signals[key] = signal(value);\n Object.defineProperty(store, key, {\n get: () => signals[key](),\n set: (val) => signals[key].set(val),\n enumerable: true,\n });\n }\n\n // Methods to interact with store\n store._signals = signals;\n store._subscribe = (key, fn) => {\n if (signals[key]) {\n return signals[key].subscribe(fn);\n }\n };\n store._batch = (fn) => batch(fn);\n store._getSnapshot = () => {\n const snapshot = {};\n for (const [key, sig] of Object.entries(signals)) {\n snapshot[key] = sig.peek();\n }\n return snapshot;\n };\n store._hydrate = (data) => {\n batch(() => {\n for (const [key, value] of Object.entries(data)) {\n if (signals[key]) {\n signals[key].set(value);\n }\n }\n });\n };\n\n sharedStores.set(name, store);\n return store;\n}\n\n// Get or create a shared store\nexport function useIslandStore(name, fallbackInitial = {}) {\n if (sharedStores.has(name)) {\n return sharedStores.get(name);\n }\n return createIslandStore(name, fallbackInitial);\n}\n\n// Serialize all shared stores for SSR.\n// Uses serializeState (not bare JSON.stringify) so user-controlled store values\n// containing \"</script>\" cannot break out of the <script> tag this is embedded\n// in. (AUDIT-2026-06-06 H3)\nexport function serializeIslandStores() {\n return serializeState(getIslandStoresSnapshot());\n}\n\n// Raw (unserialized) snapshot of all shared island stores, so renderDocument can\n// merge it into the single consolidated #__what_data payload (one serialize pass).\nexport function getIslandStoresSnapshot() {\n const data = {};\n for (const [name, store] of sharedStores) {\n data[name] = store._getSnapshot();\n }\n return data;\n}\n\n// Hydrate shared stores from SSR data\nexport function hydrateIslandStores(serialized) {\n try {\n const data = typeof serialized === 'string' ? JSON.parse(serialized) : serialized;\n for (const [name, storeData] of Object.entries(data)) {\n const store = useIslandStore(name, storeData);\n store._hydrate(storeData);\n }\n } catch (e) {\n console.warn('[what] Failed to hydrate island stores:', e);\n }\n}\n\n// --- Register an island component ---\n\nexport function island(name, loader, opts = {}) {\n islandRegistry.set(name, {\n loader, // () => import('./MyComponent.js')\n mode: opts.mode || 'idle',\n media: opts.media || null,\n priority: opts.priority || 0, // Higher = hydrate first\n stores: opts.stores || [], // Shared stores this island uses\n });\n}\n\n// --- Island wrapper for SSR ---\n// Renders the static HTML with a marker the client can find.\n\nexport function Island({ name, props = {}, children, mode, priority, stores }) {\n const entry = islandRegistry.get(name);\n const resolvedMode = mode || entry?.mode || 'idle';\n const resolvedPriority = priority ?? entry?.priority ?? 0;\n const resolvedStores = stores || entry?.stores || [];\n\n // Server: render as a div with data attributes for hydration\n return {\n tag: 'div',\n props: {\n 'data-island': name,\n 'data-island-mode': resolvedMode,\n 'data-island-props': JSON.stringify(props),\n 'data-island-priority': resolvedPriority,\n 'data-island-stores': JSON.stringify(resolvedStores),\n },\n children: children || [],\n key: null,\n _vnode: true,\n };\n}\n\n// --- Priority Hydration Queue ---\n\nfunction enqueueHydration(task) {\n // Insert in priority order (higher priority first)\n let inserted = false;\n for (let i = 0; i < hydrationQueue.length; i++) {\n if (task.priority > hydrationQueue[i].priority) {\n hydrationQueue.splice(i, 0, task);\n inserted = true;\n break;\n }\n }\n if (!inserted) {\n hydrationQueue.push(task);\n }\n\n processQueue();\n}\n\nfunction processQueue() {\n if (isProcessingQueue || hydrationQueue.length === 0) return;\n isProcessingQueue = true;\n\n // Process one task at a time to avoid blocking\n const task = hydrationQueue.shift();\n\n Promise.resolve(task.hydrate())\n .catch(e => console.error('[what] Island hydration failed:', task.name, e))\n .finally(() => {\n isProcessingQueue = false;\n // Continue processing after a microtask\n queueMicrotask(processQueue);\n });\n}\n\n// Boost priority for an island (e.g., on user interaction)\nexport function boostIslandPriority(name, newPriority = 100) {\n for (const task of hydrationQueue) {\n if (task.name === name) {\n task.priority = newPriority;\n // Re-sort queue\n hydrationQueue.sort((a, b) => b.priority - a.priority);\n break;\n }\n }\n}\n\n// --- Client-side hydration ---\n\nexport function hydrateIslands() {\n // First, hydrate any shared stores from the page\n const storeScript = document.querySelector('script[data-island-stores]');\n if (storeScript) {\n hydrateIslandStores(storeScript.textContent);\n }\n\n const islands = document.querySelectorAll('[data-island]');\n\n for (const el of islands) {\n const name = el.dataset.island;\n const mode = el.dataset.islandMode || 'idle';\n const props = JSON.parse(el.dataset.islandProps || '{}');\n const priority = parseInt(el.dataset.islandPriority || '0', 10);\n const stores = JSON.parse(el.dataset.islandStores || '[]');\n const entry = islandRegistry.get(name);\n\n if (!entry) {\n console.warn(`[what] Island \"${name}\" not registered`);\n continue;\n }\n\n // Skip if already hydrated\n if (hydratedIslands.has(el)) continue;\n\n scheduleHydration(el, entry, props, mode, priority, name, stores);\n }\n}\n\nfunction scheduleHydration(el, entry, props, mode, priority, name, stores) {\n const hydrate = async () => {\n if (hydratedIslands.has(el)) return;\n hydratedIslands.add(el);\n\n const mod = await entry.loader();\n const Component = mod.default || mod;\n\n // Inject shared stores into props\n const storeProps = {};\n for (const storeName of stores) {\n storeProps[storeName] = useIslandStore(storeName);\n }\n\n // Use hydrate() to reuse server-rendered DOM instead of destroying/recreating\n const vnode = Component({ ...props, ...storeProps });\n if (el.childNodes.length > 0) {\n hydrate(vnode, el);\n } else {\n mount(vnode, el);\n }\n\n // Clean up data attributes\n el.removeAttribute('data-island');\n el.removeAttribute('data-island-mode');\n el.removeAttribute('data-island-props');\n el.removeAttribute('data-island-priority');\n el.removeAttribute('data-island-stores');\n\n // Dispatch event for analytics/debugging\n el.dispatchEvent(new CustomEvent('island:hydrated', {\n bubbles: true,\n detail: { name, mode },\n }));\n };\n\n switch (mode) {\n case 'load':\n // Immediate hydration via queue (respects priority)\n enqueueHydration({ name, priority: priority + 1000, hydrate });\n break;\n\n case 'idle':\n if ('requestIdleCallback' in window) {\n requestIdleCallback(() => {\n enqueueHydration({ name, priority, hydrate });\n });\n } else {\n setTimeout(() => {\n enqueueHydration({ name, priority, hydrate });\n }, 200);\n }\n break;\n\n case 'visible': {\n const observer = new IntersectionObserver((entries, obs) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n obs.disconnect();\n enqueueHydration({ name, priority, hydrate });\n break;\n }\n }\n }, { rootMargin: '200px' });\n observer.observe(el);\n break;\n }\n\n case 'media': {\n const mq = window.matchMedia(entry.media || '(max-width: 768px)');\n if (mq.matches) {\n enqueueHydration({ name, priority, hydrate });\n } else {\n mq.addEventListener('change', (e) => {\n if (e.matches) {\n enqueueHydration({ name, priority, hydrate });\n }\n }, { once: true });\n }\n break;\n }\n\n case 'action': {\n const events = ['click', 'focus', 'mouseover', 'touchstart'];\n const handler = () => {\n events.forEach(e => el.removeEventListener(e, handler));\n // Boost priority since user interacted\n enqueueHydration({ name, priority: priority + 500, hydrate });\n };\n events.forEach(e => el.addEventListener(e, handler, { once: true, passive: true }));\n break;\n }\n\n case 'static':\n // Never hydrate\n break;\n\n default:\n enqueueHydration({ name, priority, hydrate });\n }\n}\n\n// --- Auto-discover islands from data attributes ---\n// Call this once on the client to set up all islands.\n\nexport function autoIslands(registry) {\n for (const [name, config] of Object.entries(registry)) {\n island(name, config.loader || config, {\n mode: config.mode || 'idle',\n media: config.media,\n priority: config.priority || 0,\n stores: config.stores || [],\n });\n }\n\n if (typeof document !== 'undefined') {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', hydrateIslands);\n } else {\n hydrateIslands();\n }\n }\n}\n\n// --- Progressive Enhancement Helpers ---\n\n// Mark an element as progressively enhanced\nexport function enhance(selector, handler) {\n if (typeof document === 'undefined') return;\n\n const elements = document.querySelectorAll(selector);\n for (const el of elements) {\n if (el.dataset.enhanced) continue;\n el.dataset.enhanced = 'true';\n handler(el);\n }\n}\n\n// Form enhancement: submit via fetch instead of page reload\nexport function enhanceForms(selector = 'form[data-enhance]') {\n enhance(selector, (form) => {\n form.addEventListener('submit', async (e) => {\n e.preventDefault();\n\n const formData = new FormData(form);\n const method = form.method.toUpperCase() || 'POST';\n const action = form.action || location.href;\n\n try {\n // Read CSRF token from meta tag\n const csrfMeta = document.querySelector('meta[name=\"csrf-token\"]') ||\n document.querySelector('meta[name=\"what-csrf-token\"]');\n const csrfToken = csrfMeta ? csrfMeta.getAttribute('content') : null;\n\n // If no CSRF token and form hasn't opted out, block submission\n const noCsrf = form.getAttribute('data-no-csrf') === 'true';\n if (!csrfToken && !noCsrf) {\n console.warn(\n '[what] Form submission blocked: no CSRF token found. ' +\n 'Add a <meta name=\"csrf-token\"> tag or set data-no-csrf=\"true\" on the form to opt out.'\n );\n form.dispatchEvent(new CustomEvent('form:error', {\n bubbles: true,\n detail: { error: new Error('Missing CSRF token') },\n }));\n return;\n }\n\n const headers = {\n 'X-Requested-With': 'XMLHttpRequest',\n };\n if (csrfToken) {\n headers['X-CSRF-Token'] = csrfToken;\n }\n\n const response = await fetch(action, {\n method,\n body: method === 'GET' ? undefined : formData,\n headers,\n });\n\n form.dispatchEvent(new CustomEvent('form:response', {\n bubbles: true,\n detail: { response, ok: response.ok },\n }));\n } catch (error) {\n form.dispatchEvent(new CustomEvent('form:error', {\n bubbles: true,\n detail: { error },\n }));\n }\n });\n });\n}\n\n// --- Debugging ---\n\nexport function getIslandStatus() {\n const status = {\n registered: [...islandRegistry.keys()],\n hydrated: hydratedIslands.size,\n pending: hydrationQueue.length,\n queue: hydrationQueue.map(t => ({ name: t.name, priority: t.priority })),\n stores: [...sharedStores.keys()],\n };\n return status;\n}\n", "// What Framework - Server Actions\n// Call server-side functions from client code seamlessly.\n// Similar to Next.js Server Actions / SolidStart server functions.\n//\n// Usage:\n// // Define on server\n// const saveUser = action(async (formData) => {\n// 'use server';\n// const user = await db.users.create(formData);\n// return { success: true, id: user.id };\n// });\n//\n// // Call from client\n// const result = await saveUser({ name: 'John' });\n\nimport { signal, batch } from 'what-core';\nimport { revalidatePath as serverRevalidatePath, revalidateTag as serverRevalidateTag } from './revalidation-registry.js';\n\n// Registry of server actions\nconst actionRegistry = new Map();\n\n// --- CSRF Protection ---\n// Server generates a token per session; client sends it with every action request.\n// The token is injected into the page via a meta tag or embedded in the server response.\n\n// Client: read the CSRF token from the page meta tag or cookie\n// Re-reads on every call to handle token rotation\nfunction getCsrfToken() {\n if (typeof document !== 'undefined') {\n // Try meta tag first\n const meta = document.querySelector('meta[name=\"what-csrf-token\"]');\n if (meta) {\n return meta.getAttribute('content');\n }\n // Try cookie\n const match = document.cookie.match(/(?:^|;\\s*)what-csrf=([^;]+)/);\n if (match) {\n return decodeURIComponent(match[1]);\n }\n }\n return null;\n}\n\n// Server: generate a CSRF token (call this per session/request)\nexport function generateCsrfToken() {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Fallback for environments without crypto.randomUUID \u2014 use crypto.getRandomValues\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n const arr = new Uint8Array(16);\n crypto.getRandomValues(arr);\n return Array.from(arr, b => b.toString(16).padStart(2, '0')).join('');\n }\n // Last resort \u2014 should not be reached in modern environments\n throw new Error('[what] No secure random source available for CSRF token generation');\n}\n\n// Server: validate CSRF token from request header against session token\nexport function validateCsrfToken(requestToken, sessionToken) {\n if (!requestToken || !sessionToken) return false;\n // Constant-time comparison to prevent timing attacks\n if (requestToken.length !== sessionToken.length) return false;\n let result = 0;\n for (let i = 0; i < requestToken.length; i++) {\n result |= requestToken.charCodeAt(i) ^ sessionToken.charCodeAt(i);\n }\n return result === 0;\n}\n\n// Server: middleware helper to inject CSRF meta tag into HTML\nexport function csrfMetaTag(token) {\n // HTML-escape the token to prevent XSS if a non-standard value is used\n const escaped = String(token).replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<').replace(/>/g, '>');\n return `<meta name=\"what-csrf-token\" content=\"${escaped}\">`;\n}\n\n// --- Define a server action ---\n\nlet _actionCounter = 0;\n\nfunction generateActionId() {\n // Generate a deterministic ID \u2014 prefer crypto.getRandomValues, fall back to a\n // monotonic counter (never Math.random, which is not cryptographically safe and\n // produces predictable IDs in some runtimes).\n const rand = typeof crypto !== 'undefined' && crypto.getRandomValues\n ? Array.from(crypto.getRandomValues(new Uint8Array(6)), b => b.toString(16).padStart(2, '0')).join('')\n : `c${(++_actionCounter).toString(36)}_${Date.now().toString(36)}`;\n return `a_${rand}`;\n}\n\nexport function action(fn, options = {}) {\n const id = options.id || generateActionId();\n const { onError, onSuccess, revalidate } = options;\n\n // Server-side: register the action\n if (typeof window === 'undefined') {\n actionRegistry.set(id, { fn, options });\n }\n\n // Create the callable wrapper\n async function callAction(...args) {\n // Server-side: call directly\n if (typeof window === 'undefined') {\n return fn(...args);\n }\n\n // Client-side: call via fetch with timeout support\n const timeout = options.timeout || 30000; // Default 30s timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const csrfToken = getCsrfToken();\n const headers = {\n 'Content-Type': 'application/json',\n 'X-What-Action': id,\n };\n if (csrfToken) headers['X-CSRF-Token'] = csrfToken;\n\n const response = await fetch('/__what_action', {\n method: 'POST',\n headers,\n credentials: 'same-origin',\n signal: controller.signal,\n body: JSON.stringify({ args }),\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: 'Action failed' }));\n throw new Error(error.message || 'Action failed');\n }\n\n const result = await response.json();\n\n if (onSuccess) onSuccess(result);\n if (revalidate) {\n // Trigger revalidation of specified paths\n for (const path of revalidate) {\n invalidatePath(path);\n }\n }\n\n return result;\n } catch (error) {\n if (error.name === 'AbortError') {\n const timeoutError = new Error(`Action \"${id}\" timed out after ${timeout}ms`);\n timeoutError.code = 'TIMEOUT';\n if (onError) onError(timeoutError);\n throw timeoutError;\n }\n if (onError) onError(error);\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n callAction._actionId = id;\n callAction._isAction = true;\n\n return callAction;\n}\n\n// --- Form action helper ---\n// For forms that submit to server actions.\n\nexport function formAction(actionFn, options = {}) {\n const { onSuccess, onError, resetOnSuccess = true } = options;\n\n return async (formDataOrEvent) => {\n let formData;\n let form;\n\n if (formDataOrEvent instanceof Event) {\n formDataOrEvent.preventDefault();\n form = formDataOrEvent.target;\n formData = new FormData(form);\n } else {\n formData = formDataOrEvent;\n }\n\n // Convert FormData to plain object, preserving File instances\n const data = {};\n let hasFiles = false;\n for (const [key, value] of formData.entries()) {\n if (typeof File !== 'undefined' && value instanceof File) {\n hasFiles = true;\n }\n if (data[key]) {\n // Handle multiple values (e.g., checkboxes, multi-file inputs)\n if (Array.isArray(data[key])) {\n data[key].push(value);\n } else {\n data[key] = [data[key], value];\n }\n } else {\n data[key] = value;\n }\n }\n\n try {\n // If form contains files, pass the raw FormData as second arg\n // so the action handler can access files directly\n const result = hasFiles\n ? await actionFn(data, formData)\n : await actionFn(data);\n if (onSuccess) onSuccess(result, form);\n if (resetOnSuccess && form) form.reset();\n return result;\n } catch (error) {\n if (onError) onError(error, form);\n throw error;\n }\n };\n}\n\n// --- useAction hook ---\n// Returns action state and trigger function.\n\nexport function useAction(actionFn) {\n const isPending = signal(false);\n const error = signal(null);\n const data = signal(null);\n\n async function trigger(...args) {\n isPending.set(true);\n error.set(null);\n\n try {\n const result = await actionFn(...args);\n data.set(result);\n return result;\n } catch (e) {\n error.set(e);\n throw e;\n } finally {\n isPending.set(false);\n }\n }\n\n return {\n trigger,\n isPending: () => isPending(),\n error: () => error(),\n data: () => data(),\n reset: () => {\n error.set(null);\n data.set(null);\n },\n };\n}\n\n// --- useFormAction hook ---\n// Combines useAction with form handling.\n\nexport function useFormAction(actionFn, options = {}) {\n const { resetOnSuccess = true } = options;\n const formRef = { current: null };\n const actionState = useAction(formAction(actionFn, { resetOnSuccess }));\n\n function handleSubmit(e) {\n e.preventDefault();\n const formData = new FormData(e.target);\n formRef.current = e.target;\n return actionState.trigger(formData);\n }\n\n return {\n ...actionState,\n handleSubmit,\n formRef,\n };\n}\n\n// --- Optimistic updates ---\n\nexport function useOptimistic(initialValue, reducer) {\n const value = signal(initialValue);\n const pending = signal([]);\n const baseValue = signal(initialValue); // Track the confirmed server value\n\n function addOptimistic(action) {\n const optimisticValue = reducer(value.peek(), action);\n batch(() => {\n pending.set([...pending.peek(), action]);\n value.set(optimisticValue);\n });\n }\n\n function resolve(action, serverValue) {\n batch(() => {\n pending.set(pending.peek().filter(a => a !== action));\n if (serverValue !== undefined) {\n baseValue.set(serverValue);\n // Recompute optimistic state from new base + remaining pending actions\n let current = serverValue;\n for (const a of pending.peek()) {\n current = reducer(current, a);\n }\n value.set(current);\n }\n });\n }\n\n function rollback(action, realValue) {\n batch(() => {\n const newPending = pending.peek().filter(a => a !== action);\n pending.set(newPending);\n const base = realValue !== undefined ? realValue : baseValue.peek();\n baseValue.set(base);\n // Recompute from base + remaining pending actions\n let current = base;\n for (const a of newPending) {\n current = reducer(current, a);\n }\n value.set(current);\n });\n }\n\n // Auto-rollback helper: wraps an async action with automatic rollback on error\n async function withOptimistic(action, asyncFn) {\n addOptimistic(action);\n try {\n const result = await asyncFn();\n resolve(action, result);\n return result;\n } catch (e) {\n rollback(action);\n throw e;\n }\n }\n\n return {\n value: () => value(),\n isPending: () => pending().length > 0,\n addOptimistic,\n resolve,\n rollback,\n withOptimistic,\n set: (v) => { value.set(v); baseValue.set(v); },\n };\n}\n\n// --- Path revalidation ---\n\nconst revalidationCallbacks = new Map();\n\nexport function onRevalidate(path, callback) {\n if (!revalidationCallbacks.has(path)) {\n revalidationCallbacks.set(path, new Set());\n }\n revalidationCallbacks.get(path).add(callback);\n\n return () => {\n revalidationCallbacks.get(path)?.delete(callback);\n };\n}\n\nexport function invalidatePath(path) {\n const callbacks = revalidationCallbacks.get(path);\n if (callbacks) {\n for (const cb of callbacks) {\n try { cb(); } catch (e) { console.error('[what] Revalidation error:', e); }\n }\n }\n}\n\n// --- Server-side action handler ---\n// Add this to your server middleware.\n\nexport function handleActionRequest(req, actionId, args, options = {}) {\n const { csrfToken: sessionCsrfToken, skipCsrf = false } = options;\n\n // Validate CSRF token unless explicitly skipped\n if (!skipCsrf) {\n if (!sessionCsrfToken) {\n // Fail closed: no CSRF token configured means the developer forgot to set it up.\n // This prevents silent security vulnerabilities in production.\n return Promise.resolve({\n status: 500,\n body: {\n message: '[what] CSRF token not configured. ' +\n 'Pass { csrfToken: sessionToken } to handleActionRequest, ' +\n 'or { skipCsrf: true } to explicitly opt out.'\n }\n });\n }\n const requestCsrfToken = req?.headers?.['x-csrf-token'] || req?.headers?.['X-CSRF-Token'];\n if (!validateCsrfToken(requestCsrfToken, sessionCsrfToken)) {\n return Promise.resolve({ status: 403, body: { message: 'Invalid CSRF token' } });\n }\n }\n\n const action = actionRegistry.get(actionId);\n if (!action) {\n return Promise.resolve({ status: 404, body: { message: 'Action not found' } });\n }\n\n // Validate args is an array to prevent prototype pollution\n if (!Array.isArray(args)) {\n return Promise.resolve({ status: 400, body: { message: 'Invalid action arguments' } });\n }\n\n return action.fn(...args)\n .then(async result => {\n // Server-side cache revalidation: if the action declared revalidate paths\n // or tags, purge them through the bound cache engine (no-op if unbound).\n const opts = action.options || {};\n if (Array.isArray(opts.revalidate)) {\n for (const p of opts.revalidate) await serverRevalidatePath(p);\n }\n if (Array.isArray(opts.revalidateTags)) {\n for (const t of opts.revalidateTags) await serverRevalidateTag(t);\n }\n return { status: 200, body: result };\n })\n .catch(error => {\n // Log the full error server-side, return generic message to client\n console.error(`[what] Action \"${actionId}\" error:`, error);\n return {\n status: 500,\n body: { message: 'Action failed' },\n };\n });\n}\n\n// --- Get all registered actions (for SSR/build) ---\n\nexport function getRegisteredActions() {\n return [...actionRegistry.keys()];\n}\n\n// --- Mutation helper ---\n// Like useSWR mutation but simpler.\n\nexport function useMutation(mutationFn, options = {}) {\n const { onSuccess, onError, onSettled } = options;\n\n const state = {\n isPending: signal(false),\n error: signal(null),\n data: signal(null),\n };\n\n async function mutate(...args) {\n state.isPending.set(true);\n state.error.set(null);\n\n try {\n const result = await mutationFn(...args);\n state.data.set(result);\n if (onSuccess) onSuccess(result, ...args);\n return result;\n } catch (error) {\n state.error.set(error);\n if (onError) onError(error, ...args);\n throw error;\n } finally {\n state.isPending.set(false);\n if (onSettled) onSettled(state.data.peek(), state.error.peek(), ...args);\n }\n }\n\n return {\n mutate,\n isPending: () => state.isPending(),\n error: () => state.error(),\n data: () => state.data(),\n reset: () => {\n state.error.set(null);\n state.data.set(null);\n },\n };\n}\n", "// Revalidation registry \u2014 the indirection that lets app code call\n// revalidatePath()/revalidateTag() from `what-framework/server` while the actual\n// cache engine lives in the optional `what-cache` package. The deploy adapter\n// binds the engine at startup via setRevalidationHandler(); until then these are\n// safe no-ops (with a dev hint).\n\nlet _handler = null;\n\nconst isDev = typeof process !== 'undefined' ? process.env?.NODE_ENV !== 'production' : true;\n\n/** Bind a cache engine: setRevalidationHandler({ revalidatePath, revalidateTag }). */\nexport function setRevalidationHandler(handler) {\n _handler = handler;\n}\n\nexport function getRevalidationHandler() {\n return _handler;\n}\n\nexport async function revalidatePath(path, options) {\n if (_handler && _handler.revalidatePath) return _handler.revalidatePath(path, options);\n if (isDev) {\n console.warn(\n `[what] revalidatePath('${path}') had no effect: no cache engine is bound. ` +\n 'Create a what-cache engine and bind it in your adapter (setRevalidationHandler).'\n );\n }\n}\n\nexport async function revalidateTag(tag, options) {\n if (_handler && _handler.revalidateTag) return _handler.revalidateTag(tag, options);\n if (isDev) {\n console.warn(\n `[what] revalidateTag('${tag}') had no effect: no cache engine is bound.`\n );\n }\n}\n", "// What Framework - Served Server Actions\n//\n// actions.js defines actions and `handleActionRequest`, but nothing wires the\n// `/__what_action` HTTP route the client posts to. This module provides that\n// missing piece: a framework-agnostic core handler plus thin Node-middleware\n// and Web-Fetch adapters. CSRF + dispatch + error masking are reused from\n// actions.js (handleActionRequest) \u2014 no security logic is duplicated here.\n\nimport { handleActionRequest } from './actions.js';\n\nconst DEFAULT_BASE_PATH = '/__what_action';\nconst MAX_BODY_BYTES = 1024 * 1024; // 1 MB\n\nfunction lowerHeaders(headers) {\n if (!headers) return {};\n // Headers (fetch) -> object\n if (typeof headers.forEach === 'function' && typeof headers.get === 'function') {\n const out = {};\n headers.forEach((v, k) => { out[k.toLowerCase()] = v; });\n return out;\n }\n const out = {};\n for (const k in headers) out[k.toLowerCase()] = headers[k];\n return out;\n}\n\nfunction jsonResponse(status, bodyObj) {\n return {\n status,\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(bodyObj),\n };\n}\n\n/**\n * Framework-agnostic action dispatcher.\n *\n * options:\n * - getCsrfToken(reqLike) -> sessionToken (sync or async). Omit + skipCsrf for none.\n * - skipCsrf: bool \u2014 opt out of CSRF (e.g. token-authed APIs).\n * - basePath: string \u2014 defaults to '/__what_action' (used by the adapters).\n *\n * Returns: async (reqLike) -> { status, headers, body:string }\n * reqLike: { method, headers, body } where body is the parsed JSON ({ args }).\n */\nexport function createActionHandler(options = {}) {\n const { getCsrfToken, skipCsrf = false } = options;\n\n return async function handle(reqLike) {\n const method = (reqLike.method || 'POST').toUpperCase();\n if (method !== 'POST') {\n return jsonResponse(405, { message: 'Method Not Allowed' });\n }\n\n const headers = lowerHeaders(reqLike.headers);\n const actionId = headers['x-what-action'];\n if (!actionId) {\n return jsonResponse(400, { message: 'Missing X-What-Action header' });\n }\n\n const body = reqLike.body || {};\n const args = body.args;\n\n const sessionCsrfToken = skipCsrf\n ? undefined\n : (getCsrfToken ? await getCsrfToken(reqLike) : undefined);\n\n const result = await handleActionRequest(\n { headers },\n actionId,\n args,\n { csrfToken: sessionCsrfToken, skipCsrf }\n );\n\n return jsonResponse(result.status, result.body);\n };\n}\n\n// --- Node connect/express middleware ---\n// Mount before your routes: app.use(nodeActionMiddleware({ getCsrfToken }))\n\nexport function nodeActionMiddleware(options = {}) {\n const basePath = options.basePath || DEFAULT_BASE_PATH;\n const handle = createActionHandler(options);\n\n return async function middleware(req, res, next) {\n const url = (req.url || '').split('?')[0];\n if (url !== basePath || (req.method || '').toUpperCase() !== 'POST') {\n return next ? next() : undefined;\n }\n\n let body;\n try {\n body = await readJsonBody(req);\n } catch (err) {\n res.writeHead(err.code === 'BODY_TOO_LARGE' ? 413 : 400, { 'content-type': 'application/json' });\n res.end(JSON.stringify({ message: err.code === 'BODY_TOO_LARGE' ? 'Payload too large' : 'Invalid JSON body' }));\n return;\n }\n\n const out = await handle({ method: req.method, headers: req.headers, body });\n res.writeHead(out.status, out.headers);\n res.end(out.body);\n };\n}\n\nfunction readJsonBody(req) {\n return new Promise((resolve, reject) => {\n let size = 0;\n const chunks = [];\n req.on('data', (chunk) => {\n size += chunk.length;\n if (size > MAX_BODY_BYTES) {\n const e = new Error('Body too large');\n e.code = 'BODY_TOO_LARGE';\n reject(e);\n req.destroy?.();\n return;\n }\n chunks.push(chunk);\n });\n req.on('end', () => {\n if (chunks.length === 0) return resolve({});\n try {\n resolve(JSON.parse(Buffer.concat(chunks).toString('utf8')));\n } catch (e) {\n reject(e);\n }\n });\n req.on('error', reject);\n });\n}\n\n// --- Web Fetch handler (edge / Deno / Bun / Cloudflare) ---\n// const handler = fetchActionHandler({ getCsrfToken }); addEventListener('fetch', e => e.respondWith(handler(e.request)))\n\nexport function fetchActionHandler(options = {}) {\n const handle = createActionHandler(options);\n return async function (request) {\n let body = {};\n try {\n body = await request.json();\n } catch {\n body = {};\n }\n const out = await handle({ method: request.method, headers: request.headers, body });\n return new Response(out.body, { status: out.status, headers: out.headers });\n };\n}\n", "// Framework-agnostic deploy adapter core. A Web-Fetch handler\n// (request) -> Response that powers Node, Vercel and Cloudflare alike:\n// match route -> intercept actions + revalidate webhook -> ISR cache\n// (HIT/STALE/MISS) -> render -> respond with Cache-Control headers.\n//\n// The cache engine is OPTIONAL and injected (from what-cache) so what-server\n// stays standalone. Render is owned here (renderDocument) but overridable.\n\nimport { matchRoute, parseQuery } from 'what-router/match';\nimport { renderDocument } from '../index.js';\nimport { createActionHandler } from '../action-handler.js';\nimport { setRevalidationHandler } from '../revalidation-registry.js';\n\nconst ACTION_PATH = '/__what_action';\nconst REVALIDATE_PATH = '/__what_revalidate';\n\nfunction headersToObject(headers) {\n const out = {};\n if (headers && typeof headers.forEach === 'function') headers.forEach((v, k) => { out[k.toLowerCase()] = v; });\n return out;\n}\n\nasync function readJsonBody(request) {\n try { return await request.json(); } catch { return {}; }\n}\n\nfunction defaultRenderRoute(documentOptions) {\n return async function renderRoute(routeMatch) {\n const { route, params, query, request } = routeMatch;\n const pageModule = { default: route.component, loader: route.loader };\n const html = await renderDocument(pageModule, { params, query, request }, documentOptions);\n return {\n html,\n status: 200,\n tags: (routeMatch.config && routeMatch.config.tags) || [],\n path: routeMatch.path,\n };\n };\n}\n\nexport function createRequestHandler(options = {}) {\n const {\n routes = [],\n cache,\n render,\n actionHandler = createActionHandler({ skipCsrf: true }),\n revalidateWebhook,\n document: documentOptions = {},\n notFound,\n basePath = '',\n } = options;\n\n const renderRoute = render || defaultRenderRoute(documentOptions);\n\n // Bind the cache engine so server actions' revalidatePath/revalidateTag (and\n // any app code calling them from what-framework/server) purge this engine.\n if (cache && (cache.revalidatePath || cache.revalidateTag)) {\n setRevalidationHandler({\n revalidatePath: cache.revalidatePath,\n revalidateTag: cache.revalidateTag,\n });\n }\n\n return async function handle(request) {\n const url = new URL(request.url, 'http://localhost');\n let pathname = url.pathname;\n if (basePath && pathname.startsWith(basePath)) pathname = pathname.slice(basePath.length) || '/';\n\n // Server actions\n if (request.method === 'POST' && pathname === ACTION_PATH) {\n const body = await readJsonBody(request);\n const out = await actionHandler({ method: 'POST', headers: headersToObject(request.headers), body });\n return new Response(out.body, { status: out.status, headers: out.headers });\n }\n\n // On-demand revalidation webhook\n if (request.method === 'POST' && pathname === REVALIDATE_PATH && revalidateWebhook) {\n const body = await readJsonBody(request);\n const out = await revalidateWebhook({ headers: headersToObject(request.headers), body });\n return new Response(JSON.stringify(out.body), {\n status: out.status,\n headers: { 'content-type': 'application/json' },\n });\n }\n\n // Route match\n const matched = matchRoute(pathname, routes);\n if (!matched) {\n const html = notFound ? notFound() : '<!DOCTYPE html><html><body><h1>404 \u2014 Not Found</h1></body></html>';\n return new Response(html, { status: 404, headers: { 'content-type': 'text/html; charset=utf-8' } });\n }\n\n const { route, params } = matched;\n const config = route.page || { mode: route.mode || 'client' };\n const routeMatch = { path: pathname, query: parseQuery(url.search), config, route, params, request };\n\n // ISR cache path (static/hybrid with a cache engine). Server-mode bypasses.\n if (cache && config.mode !== 'server') {\n const result = await cache.handle(routeMatch, () => renderRoute(routeMatch));\n return new Response(result.html, {\n status: result.status || 200,\n headers: { 'content-type': 'text/html; charset=utf-8', ...(result.headers || {}) },\n });\n }\n\n // Direct render (server mode, or no cache configured)\n const out = await renderRoute(routeMatch);\n const headers = { 'content-type': 'text/html; charset=utf-8' };\n if (config.mode === 'server') headers['Cache-Control'] = 'private, no-store';\n return new Response(out.html, { status: out.status || 200, headers });\n };\n}\n", "// Node deploy adapter \u2014 wraps the framework-agnostic Web-Fetch handler from\n// core.js in a Node http.Server / connect-style middleware. Dependency-free\n// (Node 18+ ships global Request/Response/Headers).\n\nimport http from 'node:http';\nimport { createRequestHandler } from './core.js';\n\nasync function nodeToWebRequest(req) {\n const host = req.headers.host || 'localhost';\n const url = `http://${host}${req.url}`;\n const headers = new Headers();\n for (const [k, v] of Object.entries(req.headers)) {\n if (v != null) headers.set(k, Array.isArray(v) ? v.join(', ') : String(v));\n }\n let body;\n if (req.method !== 'GET' && req.method !== 'HEAD') {\n const chunks = [];\n for await (const chunk of req) chunks.push(chunk);\n if (chunks.length) body = Buffer.concat(chunks);\n }\n return new Request(url, { method: req.method, headers, body });\n}\n\nasync function sendWebResponse(res, webRes) {\n res.statusCode = webRes.status;\n webRes.headers.forEach((value, key) => res.setHeader(key, value));\n const text = await webRes.text();\n res.end(text);\n}\n\n/** Convert a Web-Fetch handler into a Node (req, res) listener. */\nexport function toNodeListener(handler) {\n return async function listener(req, res) {\n try {\n const webReq = await nodeToWebRequest(req);\n const webRes = await handler(webReq);\n await sendWebResponse(res, webRes);\n } catch (err) {\n if (!res.headersSent) res.writeHead(500, { 'content-type': 'text/html; charset=utf-8' });\n res.end('<!DOCTYPE html><html><body><h1>500 \u2014 Server Error</h1></body></html>');\n // eslint-disable-next-line no-console\n console.error('[what-server] request error:', err);\n }\n };\n}\n\n/** connect/express middleware: handles app routes, calls next() on a 404. */\nexport function whatMiddleware(options = {}) {\n const handler = createRequestHandler(options);\n return async function middleware(req, res, next) {\n const webReq = await nodeToWebRequest(req);\n const webRes = await handler(webReq);\n if (webRes.status === 404 && typeof next === 'function') return next();\n await sendWebResponse(res, webRes);\n };\n}\n\n/**\n * Create a ready-to-listen Node server. Starts the poll scheduler (if provided)\n * and stops it on SIGTERM/SIGINT.\n * const server = createServer({ routes, cache, scheduler });\n * server.listen(3000);\n */\nexport function createServer(options = {}) {\n const handler = createRequestHandler(options);\n const server = http.createServer(toNodeListener(handler));\n\n const { scheduler } = options;\n if (scheduler) {\n scheduler.start();\n const stop = () => { try { scheduler.stop(); } catch {} server.close(); };\n process.once('SIGTERM', stop);\n process.once('SIGINT', stop);\n }\n\n return server;\n}\n", "// Static export adapter \u2014 build-time render of static/hybrid routes to a\n// deployable directory of .html files (+ a data.json per page for client-side\n// navigation, mirroring Next's _next/data).\n\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { matchRoute } from 'what-router/match';\nimport { renderDocument, serializeState } from '../index.js';\n\nfunction isDynamic(path) {\n return path.includes(':') || path.includes('*') || path.includes('[');\n}\n\n// Build a concrete URL from a route pattern + params (:p, [p], [...p], *p).\nfunction buildConcretePath(pattern, params) {\n return pattern\n .replace(/\\[\\.\\.\\.(\\w+)\\]/g, (_, n) => params[n] ?? '')\n .replace(/\\[(\\w+)\\]/g, (_, n) => params[n] ?? '')\n .replace(/[:*](\\w+)/g, (_, n) => params[n] ?? '');\n}\n\nexport async function exportStatic({ routes = [], outDir, render, documentOptions = {} } = {}) {\n const written = [];\n\n for (const route of routes) {\n const mode = (route.page && route.page.mode) || route.mode;\n if (mode !== 'static' && mode !== 'hybrid') continue;\n\n const pageModule = { default: route.component, loader: route.loader };\n\n let concrete = [route.path];\n if (isDynamic(route.path)) {\n if (typeof route.getStaticPaths !== 'function') continue; // can't enumerate\n const result = await route.getStaticPaths();\n concrete = (result.paths || []).map((p) => buildConcretePath(route.path, p.params || {}));\n }\n\n for (const urlPath of concrete) {\n const matched = matchRoute(urlPath, [route]);\n const params = matched ? matched.params : {};\n const reqCtx = { params, query: {} };\n\n const html = render\n ? await render(pageModule, reqCtx)\n : await renderDocument(pageModule, reqCtx, documentOptions);\n\n const dirPath = join(outDir, urlPath === '/' ? '' : urlPath);\n await mkdir(dirPath, { recursive: true });\n await writeFile(join(dirPath, 'index.html'), html);\n\n // data.json for client-side navigation (loader data without a round-trip)\n if (typeof route.loader === 'function') {\n const data = await route.loader(reqCtx);\n await writeFile(join(dirPath, '__what_data.json'), serializeState({ loaderData: data }));\n }\n\n written.push(urlPath);\n }\n }\n\n return { pages: written };\n}\n", "// Cloudflare Workers adapter \u2014 exposes a `fetch(request, env, ctx)` worker\n// entry over the same Web-Fetch core handler. ISR runs via the origin cache\n// engine; pass a what-cache redis/KV-backed store for cross-isolate caching and\n// use ctx.waitUntil for background regeneration.\n\nimport { createRequestHandler } from './core.js';\n\nexport function createCloudflareHandler(options = {}) {\n const handle = createRequestHandler(options);\n return {\n async fetch(request, env, ctx) {\n // Expose env/ctx to render via the request for adapters that need them.\n if (env) request.__env = env;\n if (ctx) request.__ctx = ctx;\n return handle(request);\n },\n };\n}\n", "// Vercel adapter. The runtime render function is the same Web-Fetch core\n// handler (deployable as a Vercel Function). ISR maps to Vercel's native\n// s-maxage/stale-while-revalidate headers emitted by the cache engine, so it\n// works on Vercel with no extra config. buildVercelOutput writes a minimal\n// Build Output API config pointing at the function.\n\nimport { createRequestHandler } from './core.js';\n\nexport function createVercelHandler(options = {}) {\n // Vercel Functions accept a Web-Fetch (Request) -> Response handler.\n return createRequestHandler(options);\n}\n\n/**\n * Write a minimal .vercel/output/config.json that routes all requests to a\n * single render function. The function file itself is emitted by the build step\n * (it imports createVercelHandler with the app's routes).\n */\nexport async function buildVercelOutput({ outDir = '.vercel/output', functionName = 'render' } = {}) {\n const { mkdir, writeFile } = await import('node:fs/promises');\n const { join } = await import('node:path');\n await mkdir(outDir, { recursive: true });\n const config = {\n version: 3,\n routes: [{ src: '/.*', dest: `/${functionName}` }],\n };\n await writeFile(join(outDir, 'config.json'), JSON.stringify(config, null, 2));\n return { config, outDir };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["signal", "batch", "signal", "action", "batch", "out", "getCsrfToken", "readJsonBody", "out", "server", "matchRoute", "matchRoute", "mkdir", "writeFile", "join"]
|
|
7
7
|
}
|
package/dist/index.min.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import"what-core";import{signal as y,batch as T}from"what-core";var b=new Map;function P(){if(typeof document<"u"){let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let r=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);if(r)return decodeURIComponent(r[1])}return null}function H(){if(typeof crypto<"u"&&crypto.randomUUID)return crypto.randomUUID();if(typeof crypto<"u"&&crypto.getRandomValues){let t=new Uint8Array(16);return crypto.getRandomValues(t),Array.from(t,r=>r.toString(16).padStart(2,"0")).join("")}throw new Error("[what] No secure random source available for CSRF token generation")}function E(t,r){if(!t||!r||t.length!==r.length)return!1;let e=0;for(let n=0;n<t.length;n++)e|=t.charCodeAt(n)^r.charCodeAt(n);return e===0}function L(t){return`<meta name="what-csrf-token" content="${String(t).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}">`}var O=0;function D(){return`a_${typeof crypto<"u"&&crypto.getRandomValues?Array.from(crypto.getRandomValues(new Uint8Array(6)),r=>r.toString(16).padStart(2,"0")).join(""):`c${(++O).toString(36)}_${Date.now().toString(36)}`}`}function N(t,r={}){let e=r.id||D(),{onError:n,onSuccess:s,revalidate:o}=r;typeof window>"u"&&b.set(e,{fn:t,options:r});async function i(...a){if(typeof window>"u")return t(...a);let c=r.timeout||3e4,f=new AbortController,u=setTimeout(()=>f.abort(),c);try{let l=P(),d={"Content-Type":"application/json","X-What-Action":e};l&&(d["X-CSRF-Token"]=l);let m=await fetch("/__what_action",{method:"POST",headers:d,credentials:"same-origin",signal:f.signal,body:JSON.stringify({args:a})});if(!m.ok){let A=await m.json().catch(()=>({message:"Action failed"}));throw new Error(A.message||"Action failed")}let g=await m.json();if(s&&s(g),o)for(let A of o)I(A);return g}catch(l){if(l.name==="AbortError"){let d=new Error(`Action "${e}" timed out after ${c}ms`);throw d.code="TIMEOUT",n&&n(d),d}throw n&&n(l),l}finally{clearTimeout(u)}}return i._actionId=e,i._isAction=!0,i}function C(t,r={}){let{onSuccess:e,onError:n,resetOnSuccess:s=!0}=r;return async o=>{let i,a;o instanceof Event?(o.preventDefault(),a=o.target,i=new FormData(a)):i=o;let c={},f=!1;for(let[u,l]of i.entries())typeof File<"u"&&l instanceof File&&(f=!0),c[u]?Array.isArray(c[u])?c[u].push(l):c[u]=[c[u],l]:c[u]=l;try{let u=f?await t(c,i):await t(c);return e&&e(u,a),s&&a&&a.reset(),u}catch(u){throw n&&n(u,a),u}}}function x(t){let r=y(!1),e=y(null),n=y(null);async function s(...o){r.set(!0),e.set(null);try{let i=await t(...o);return n.set(i),i}catch(i){throw e.set(i),i}finally{r.set(!1)}}return{trigger:s,isPending:()=>r(),error:()=>e(),data:()=>n(),reset:()=>{e.set(null),n.set(null)}}}function U(t,r={}){let{resetOnSuccess:e=!0}=r,n={current:null},s=x(C(t,{resetOnSuccess:e}));function o(i){i.preventDefault();let a=new FormData(i.target);return n.current=i.target,s.trigger(a)}return{...s,handleSubmit:o,formRef:n}}function F(t,r){let e=y(t),n=y([]),s=y(t);function o(f){let u=r(e.peek(),f);T(()=>{n.set([...n.peek(),f]),e.set(u)})}function i(f,u){T(()=>{if(n.set(n.peek().filter(l=>l!==f)),u!==void 0){s.set(u);let l=u;for(let d of n.peek())l=r(l,d);e.set(l)}})}function a(f,u){T(()=>{let l=n.peek().filter(g=>g!==f);n.set(l);let d=u!==void 0?u:s.peek();s.set(d);let m=d;for(let g of l)m=r(m,g);e.set(m)})}async function c(f,u){o(f);try{let l=await u();return i(f,l),l}catch(l){throw a(f),l}}return{value:()=>e(),isPending:()=>n().length>0,addOptimistic:o,resolve:i,rollback:a,withOptimistic:c,set:f=>{e.set(f),s.set(f)}}}var S=new Map;function V(t,r){return S.has(t)||S.set(t,new Set),S.get(t).add(r),()=>{S.get(t)?.delete(r)}}function I(t){let r=S.get(t);if(r)for(let e of r)try{e()}catch(n){console.error("[what] Revalidation error:",n)}}function W(t,r,e,n={}){let{csrfToken:s,skipCsrf:o=!1}=n;if(!o){if(!s)return Promise.resolve({status:500,body:{message:"[what] CSRF token not configured. Pass { csrfToken: sessionToken } to handleActionRequest, or { skipCsrf: true } to explicitly opt out."}});let a=t?.headers?.["x-csrf-token"]||t?.headers?.["X-CSRF-Token"];if(!E(a,s))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let i=b.get(r);return i?Array.isArray(e)?i.fn(...e).then(a=>({status:200,body:a})).catch(a=>(console.error(`[what] Action "${r}" error:`,a),{status:500,body:{message:"Action failed"}})):Promise.resolve({status:400,body:{message:"Invalid action arguments"}}):Promise.resolve({status:404,body:{message:"Action not found"}})}function z(){return[...b.keys()]}function X(t,r={}){let{onSuccess:e,onError:n,onSettled:s}=r,o={isPending:y(!1),error:y(null),data:y(null)};async function i(...a){o.isPending.set(!0),o.error.set(null);try{let c=await t(...a);return o.data.set(c),e&&e(c,...a),c}catch(c){throw o.error.set(c),n&&n(c,...a),c}finally{o.isPending.set(!1),s&&s(o.data.peek(),o.error.peek(),...a)}}return{mutate:i,isPending:()=>o.isPending(),error:()=>o.error(),data:()=>o.data(),reset:()=>{o.error.set(null),o.data.set(null)}}}var M=0;function q(){M=0}function K(){return"h"+M++}function rt(t){return q(),h(t)}function h(t){if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return p(String(t));if(typeof t=="function"&&t._signal)return`<!--$-->${h(t())}<!--/$-->`;if(typeof t=="function")try{return`<!--$-->${h(t())}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(Array.isArray(t))return`<!--[]-->${t.map(h).join("")}<!--/[]-->`;if(typeof t.tag=="function"){let c=K(),f=t.tag({...t.props,children:t.children}),u=h(f);return Z(u,c)}let{tag:r,props:e,children:n}=t,s=_(e||{}),o=`<${r}${s}>`;if(R.has(r))return o;let i=k(e),a=i!=null?String(i):n.map(h).join("");return`${o}${a}</${r}>`}function Z(t,r){let e=t.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);if(e){let n=e[1],s=e[2],o=n.length+1+s.length;return t.slice(0,o)+` data-hk="${r}"`+t.slice(o)}return t}function w(t){if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return p(String(t));if(typeof t=="function"&&t._signal)return w(t());if(typeof t=="function")try{return w(t())}catch{return typeof process<"u",""}if(Array.isArray(t))return t.map(w).join("");if(typeof t.tag=="function"){let c=t.tag({...t.props,children:t.children});return w(c)}let{tag:r,props:e,children:n}=t,s=_(e||{}),o=`<${r}${s}>`;if(R.has(r))return o;let i=k(e),a=i!=null?String(i):n.map(w).join("");return`${o}${a}</${r}>`}async function*$(t){if(t==null||t===!1||t===!0)return;if(typeof t=="string"||typeof t=="number"){yield p(String(t));return}if(typeof t=="function"&&t._signal){yield*$(t());return}if(typeof t=="function"){try{yield*$(t())}catch{typeof process<"u"}return}if(Array.isArray(t)){for(let o of t)yield*$(o);return}if(typeof t.tag=="function"){try{let o=t.tag({...t.props,children:t.children}),i=o instanceof Promise?await o:o;yield*$(i)}catch(o){typeof process<"u",yield j?`<!-- SSR Error: ${p(o.message||"Component error")} -->`:"<!-- SSR Error -->"}return}let{tag:r,props:e,children:n}=t,s=_(e||{});if(yield`<${r}${s}>`,!R.has(r)){let o=k(e);if(o!=null)yield String(o);else for(let i of n)yield*$(i);yield`</${r}>`}}function nt(t){return{mode:"static",...t}}function ot(t,r={}){let e=t.component(r),n=w(e),s=t.islands||[];return J({title:t.title||"",meta:t.meta||{},body:n,islands:s,scripts:t.mode==="static"?[]:t.scripts||[],styles:t.styles||[],mode:t.mode})}function J({title:t,meta:r,body:e,islands:n,scripts:s,styles:o,mode:i}){let a=Object.entries(r).map(([d,m])=>`<meta name="${p(d)}" content="${p(m)}">`).join(`
|
|
2
|
-
`),c=o.map(
|
|
3
|
-
`),
|
|
1
|
+
import{h as at,runWithServerContext as x,beginHeadCollection as Xt,endHeadCollection as U}from"what-core";var dt=new RegExp("[<>&\\u2028\\u2029]","g"),lt={60:"\\u003c",62:"\\u003e",38:"\\u0026",8232:"\\u2028",8233:"\\u2029"};function k(t){return JSON.stringify(t).replace(dt,e=>lt[e.charCodeAt(0)])}import{mount as ae,signal as ie,batch as ce}from"what-core";var ft=new Map;function X(){let t={};for(let[e,n]of ft)t[e]=n._getSnapshot();return t}import{signal as b,batch as D}from"what-core";var S=null,Y=!(typeof process<"u");function H(t){S=t}function pt(){return S}async function I(t,e){if(S&&S.revalidatePath)return S.revalidatePath(t,e);Y&&console.warn(`[what] revalidatePath('${t}') had no effect: no cache engine is bound. Create a what-cache engine and bind it in your adapter (setRevalidationHandler).`)}async function j(t,e){if(S&&S.revalidateTag)return S.revalidateTag(t,e);Y&&console.warn(`[what] revalidateTag('${t}') had no effect: no cache engine is bound.`)}var M=new Map;function ht(){if(typeof document<"u"){let t=document.querySelector('meta[name="what-csrf-token"]');if(t)return t.getAttribute("content");let e=document.cookie.match(/(?:^|;\s*)what-csrf=([^;]+)/);if(e)return decodeURIComponent(e[1])}return null}function mt(){if(typeof crypto<"u"&&crypto.randomUUID)return crypto.randomUUID();if(typeof crypto<"u"&&crypto.getRandomValues){let t=new Uint8Array(16);return crypto.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}throw new Error("[what] No secure random source available for CSRF token generation")}function G(t,e){if(!t||!e||t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t.charCodeAt(r)^e.charCodeAt(r);return n===0}function yt(t){return`<meta name="what-csrf-token" content="${String(t).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}">`}var gt=0;function wt(){return`a_${typeof crypto<"u"&&crypto.getRandomValues?Array.from(crypto.getRandomValues(new Uint8Array(6)),e=>e.toString(16).padStart(2,"0")).join(""):`c${(++gt).toString(36)}_${Date.now().toString(36)}`}`}function bt(t,e={}){let n=e.id||wt(),{onError:r,onSuccess:a,revalidate:o}=e;typeof window>"u"&&M.set(n,{fn:t,options:e});async function s(...i){if(typeof window>"u")return t(...i);let c=e.timeout||3e4,u=new AbortController,d=setTimeout(()=>u.abort(),c);try{let l=ht(),f={"Content-Type":"application/json","X-What-Action":n};l&&(f["X-CSRF-Token"]=l);let p=await fetch("/__what_action",{method:"POST",headers:f,credentials:"same-origin",signal:u.signal,body:JSON.stringify({args:i})});if(!p.ok){let g=await p.json().catch(()=>({message:"Action failed"}));throw new Error(g.message||"Action failed")}let m=await p.json();if(a&&a(m),o)for(let g of o)K(g);return m}catch(l){if(l.name==="AbortError"){let f=new Error(`Action "${n}" timed out after ${c}ms`);throw f.code="TIMEOUT",r&&r(f),f}throw r&&r(l),l}finally{clearTimeout(d)}}return s._actionId=n,s._isAction=!0,s}function Q(t,e={}){let{onSuccess:n,onError:r,resetOnSuccess:a=!0}=e;return async o=>{let s,i;o instanceof Event?(o.preventDefault(),i=o.target,s=new FormData(i)):s=o;let c={},u=!1;for(let[d,l]of s.entries())typeof File<"u"&&l instanceof File&&(u=!0),c[d]?Array.isArray(c[d])?c[d].push(l):c[d]=[c[d],l]:c[d]=l;try{let d=u?await t(c,s):await t(c);return n&&n(d,i),a&&i&&i.reset(),d}catch(d){throw r&&r(d,i),d}}}function q(t){let e=b(!1),n=b(null),r=b(null);async function a(...o){e.set(!0),n.set(null);try{let s=await t(...o);return r.set(s),s}catch(s){throw n.set(s),s}finally{e.set(!1)}}return{trigger:a,isPending:()=>e(),error:()=>n(),data:()=>r(),reset:()=>{n.set(null),r.set(null)}}}function St(t,e={}){let{resetOnSuccess:n=!0}=e,r={current:null},a=q(Q(t,{resetOnSuccess:n}));function o(s){s.preventDefault();let i=new FormData(s.target);return r.current=s.target,a.trigger(i)}return{...a,handleSubmit:o,formRef:r}}function At(t,e){let n=b(t),r=b([]),a=b(t);function o(u){let d=e(n.peek(),u);D(()=>{r.set([...r.peek(),u]),n.set(d)})}function s(u,d){D(()=>{if(r.set(r.peek().filter(l=>l!==u)),d!==void 0){a.set(d);let l=d;for(let f of r.peek())l=e(l,f);n.set(l)}})}function i(u,d){D(()=>{let l=r.peek().filter(m=>m!==u);r.set(l);let f=d!==void 0?d:a.peek();a.set(f);let p=f;for(let m of l)p=e(p,m);n.set(p)})}async function c(u,d){o(u);try{let l=await d();return s(u,l),l}catch(l){throw i(u),l}}return{value:()=>n(),isPending:()=>r().length>0,addOptimistic:o,resolve:s,rollback:i,withOptimistic:c,set:u=>{n.set(u),a.set(u)}}}var v=new Map;function Tt(t,e){return v.has(t)||v.set(t,new Set),v.get(t).add(e),()=>{v.get(t)?.delete(e)}}function K(t){let e=v.get(t);if(e)for(let n of e)try{n()}catch(r){console.error("[what] Revalidation error:",r)}}function N(t,e,n,r={}){let{csrfToken:a,skipCsrf:o=!1}=r;if(!o){if(!a)return Promise.resolve({status:500,body:{message:"[what] CSRF token not configured. Pass { csrfToken: sessionToken } to handleActionRequest, or { skipCsrf: true } to explicitly opt out."}});let i=t?.headers?.["x-csrf-token"]||t?.headers?.["X-CSRF-Token"];if(!G(i,a))return Promise.resolve({status:403,body:{message:"Invalid CSRF token"}})}let s=M.get(e);return s?Array.isArray(n)?s.fn(...n).then(async i=>{let c=s.options||{};if(Array.isArray(c.revalidate))for(let u of c.revalidate)await I(u);if(Array.isArray(c.revalidateTags))for(let u of c.revalidateTags)await j(u);return{status:200,body:i}}).catch(i=>(console.error(`[what] Action "${e}" error:`,i),{status:500,body:{message:"Action failed"}})):Promise.resolve({status:400,body:{message:"Invalid action arguments"}}):Promise.resolve({status:404,body:{message:"Action not found"}})}function _t(){return[...M.keys()]}function kt(t,e={}){let{onSuccess:n,onError:r,onSettled:a}=e,o={isPending:b(!1),error:b(null),data:b(null)};async function s(...i){o.isPending.set(!0),o.error.set(null);try{let c=await t(...i);return o.data.set(c),n&&n(c,...i),c}catch(c){throw o.error.set(c),r&&r(c,...i),c}finally{o.isPending.set(!1),a&&a(o.data.peek(),o.error.peek(),...i)}}return{mutate:s,isPending:()=>o.isPending(),error:()=>o.error(),data:()=>o.data(),reset:()=>{o.error.set(null),o.data.set(null)}}}var vt="/__what_action",Et=1024*1024;function Rt(t){if(!t)return{};if(typeof t.forEach=="function"&&typeof t.get=="function"){let n={};return t.forEach((r,a)=>{n[a.toLowerCase()]=r}),n}let e={};for(let n in t)e[n.toLowerCase()]=t[n];return e}function L(t,e){return{status:t,headers:{"content-type":"application/json"},body:JSON.stringify(e)}}function E(t={}){let{getCsrfToken:e,skipCsrf:n=!1}=t;return async function(a){if((a.method||"POST").toUpperCase()!=="POST")return L(405,{message:"Method Not Allowed"});let s=Rt(a.headers),i=s["x-what-action"];if(!i)return L(400,{message:"Missing X-What-Action header"});let u=(a.body||{}).args,d=n?void 0:e?await e(a):void 0,l=await N({headers:s},i,u,{csrfToken:d,skipCsrf:n});return L(l.status,l.body)}}function xt(t={}){let e=t.basePath||vt,n=E(t);return async function(a,o,s){if((a.url||"").split("?")[0]!==e||(a.method||"").toUpperCase()!=="POST")return s?s():void 0;let c;try{c=await Ct(a)}catch(d){o.writeHead(d.code==="BODY_TOO_LARGE"?413:400,{"content-type":"application/json"}),o.end(JSON.stringify({message:d.code==="BODY_TOO_LARGE"?"Payload too large":"Invalid JSON body"}));return}let u=await n({method:a.method,headers:a.headers,body:c});o.writeHead(u.status,u.headers),o.end(u.body)}}function Ct(t){return new Promise((e,n)=>{let r=0,a=[];t.on("data",o=>{if(r+=o.length,r>Et){let s=new Error("Body too large");s.code="BODY_TOO_LARGE",n(s),t.destroy?.();return}a.push(o)}),t.on("end",()=>{if(a.length===0)return e({});try{e(JSON.parse(Buffer.concat(a).toString("utf8")))}catch(o){n(o)}}),t.on("error",n)})}function Pt(t={}){let e=E(t);return async function(n){let r={};try{r=await n.json()}catch{r={}}let a=await e({method:n.method,headers:n.headers,body:r});return new Response(a.body,{status:a.status,headers:a.headers})}}import{matchRoute as $t,parseQuery as Ot}from"what-router/match";var Ht="/__what_action",It="/__what_revalidate";function Z(t){let e={};return t&&typeof t.forEach=="function"&&t.forEach((n,r)=>{e[r.toLowerCase()]=n}),e}async function tt(t){try{return await t.json()}catch{return{}}}function jt(t){return async function(n){let{route:r,params:a,query:o,request:s}=n,i={default:r.component,loader:r.loader};return{html:await P(i,{params:a,query:o,request:s},t),status:200,tags:n.config&&n.config.tags||[],path:n.path}}}function A(t={}){let{routes:e=[],cache:n,render:r,actionHandler:a=E({skipCsrf:!0}),revalidateWebhook:o,document:s={},notFound:i,basePath:c=""}=t,u=r||jt(s);return n&&(n.revalidatePath||n.revalidateTag)&&H({revalidatePath:n.revalidatePath,revalidateTag:n.revalidateTag}),async function(l){let f=new URL(l.url,"http://localhost"),p=f.pathname;if(c&&p.startsWith(c)&&(p=p.slice(c.length)||"/"),l.method==="POST"&&p===Ht){let w=await tt(l),T=await a({method:"POST",headers:Z(l.headers),body:w});return new Response(T.body,{status:T.status,headers:T.headers})}if(l.method==="POST"&&p===It&&o){let w=await tt(l),T=await o({headers:Z(l.headers),body:w});return new Response(JSON.stringify(T.body),{status:T.status,headers:{"content-type":"application/json"}})}let m=$t(p,e);if(!m){let w=i?i():"<!DOCTYPE html><html><body><h1>404 \u2014 Not Found</h1></body></html>";return new Response(w,{status:404,headers:{"content-type":"text/html; charset=utf-8"}})}let{route:g,params:ut}=m,$=g.page||{mode:g.mode||"client"},O={path:p,query:Ot(f.search),config:$,route:g,params:ut,request:l};if(n&&$.mode!=="server"){let w=await n.handle(O,()=>u(O));return new Response(w.html,{status:w.status||200,headers:{"content-type":"text/html; charset=utf-8",...w.headers||{}}})}let B=await u(O),z={"content-type":"text/html; charset=utf-8"};return $.mode==="server"&&(z["Cache-Control"]="private, no-store"),new Response(B.html,{status:B.status||200,headers:z})}}import Dt from"node:http";async function et(t){let n=`http://${t.headers.host||"localhost"}${t.url}`,r=new Headers;for(let[o,s]of Object.entries(t.headers))s!=null&&r.set(o,Array.isArray(s)?s.join(", "):String(s));let a;if(t.method!=="GET"&&t.method!=="HEAD"){let o=[];for await(let s of t)o.push(s);o.length&&(a=Buffer.concat(o))}return new Request(n,{method:t.method,headers:r,body:a})}async function nt(t,e){t.statusCode=e.status,e.headers.forEach((r,a)=>t.setHeader(a,r));let n=await e.text();t.end(n)}function rt(t){return async function(n,r){try{let a=await et(n),o=await t(a);await nt(r,o)}catch(a){r.headersSent||r.writeHead(500,{"content-type":"text/html; charset=utf-8"}),r.end("<!DOCTYPE html><html><body><h1>500 \u2014 Server Error</h1></body></html>"),console.error("[what-server] request error:",a)}}}function Mt(t={}){let e=A(t);return async function(r,a,o){let s=await et(r),i=await e(s);if(i.status===404&&typeof o=="function")return o();await nt(a,i)}}function Nt(t={}){let e=A(t),n=Dt.createServer(rt(e)),{scheduler:r}=t;if(r){r.start();let a=()=>{try{r.stop()}catch{}n.close()};process.once("SIGTERM",a),process.once("SIGINT",a)}return n}import{mkdir as Lt,writeFile as ot}from"node:fs/promises";import{join as F}from"node:path";import{matchRoute as Ft}from"what-router/match";function Ut(t){return t.includes(":")||t.includes("*")||t.includes("[")}function Vt(t,e){return t.replace(/\[\.\.\.(\w+)\]/g,(n,r)=>e[r]??"").replace(/\[(\w+)\]/g,(n,r)=>e[r]??"").replace(/[:*](\w+)/g,(n,r)=>e[r]??"")}async function Jt({routes:t=[],outDir:e,render:n,documentOptions:r={}}={}){let a=[];for(let o of t){let s=o.page&&o.page.mode||o.mode;if(s!=="static"&&s!=="hybrid")continue;let i={default:o.component,loader:o.loader},c=[o.path];if(Ut(o.path)){if(typeof o.getStaticPaths!="function")continue;c=((await o.getStaticPaths()).paths||[]).map(d=>Vt(o.path,d.params||{}))}for(let u of c){let d=Ft(u,[o]),f={params:d?d.params:{},query:{}},p=n?await n(i,f):await P(i,f,r),m=F(e,u==="/"?"":u);if(await Lt(m,{recursive:!0}),await ot(F(m,"index.html"),p),typeof o.loader=="function"){let g=await o.loader(f);await ot(F(m,"__what_data.json"),k({loaderData:g}))}a.push(u)}}return{pages:a}}function Wt(t={}){let e=A(t);return{async fetch(n,r,a){return r&&(n.__env=r),a&&(n.__ctx=a),e(n)}}}function Bt(t={}){return A(t)}async function zt({outDir:t=".vercel/output",functionName:e="render"}={}){let{mkdir:n,writeFile:r}=await import("node:fs/promises"),{join:a}=await import("node:path");await n(t,{recursive:!0});let o={version:3,routes:[{src:"/.*",dest:`/${e}`}]};return await r(a(t,"config.json"),JSON.stringify(o,null,2)),{config:o,outDir:t}}function C(t){return{head:Xt(),loaderData:t,resources:new Map,resourceCounter:0,boundaryCounter:0,suspended:[]}}var st=0;function Yt(){st=0}function Gt(){return"h"+st++}function De(t){return Yt(),_(t)}function _(t){if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return h(String(t));if(typeof t=="function"&&t._signal)return`<!--$-->${_(t())}<!--/$-->`;if(typeof t=="function")try{return`<!--$-->${_(t())}<!--/$-->`}catch{return typeof process<"u","<!--$--><!--/$-->"}if(Array.isArray(t))return`<!--[]-->${t.map(_).join("")}<!--/[]-->`;if(typeof t.tag=="function"){let c=Gt(),u=t.tag({...t.props,children:t.children}),d=_(u);return Qt(d,c)}let{tag:e,props:n,children:r}=t,a=J(n||{}),o=`<${e}${a}>`;if(W.has(e))return o;let s=V(n),i=s!=null?String(s):r.map(_).join("");return`${o}${i}</${e}>`}function Qt(t,e){let n=t.match(/^((?:<!--.*?-->)*)<([a-zA-Z][a-zA-Z0-9-]*)/);if(n){let r=n[1],a=n[2],o=r.length+1+a.length;return t.slice(0,o)+` data-hk="${e}"`+t.slice(o)}return t}function y(t){if(t==null||t===!1||t===!0)return"";if(typeof t=="string"||typeof t=="number")return h(String(t));if(typeof t=="function"&&t._signal)return y(t());if(typeof t=="function")try{return y(t())}catch{return typeof process<"u",""}if(Array.isArray(t))return t.map(y).join("");if(t.tag==="__suspense")try{return(t.children||[]).map(y).join("")}catch(c){if(c&&typeof c.then=="function")return y(t.props&&t.props.fallback);throw c}if(typeof t.tag=="function"){let c=t.tag({...t.props,children:t.children});return y(c)}let{tag:e,props:n,children:r}=t,a=J(n||{}),o=`<${e}${a}>`;if(W.has(e))return o;let s=V(n),i=s!=null?String(s):r.map(y).join("");return`${o}${i}</${e}>`}function Me(t){let e=C(void 0);return{body:x(e,()=>y(t)),head:U(e.head)}}async function Ne(t,e={}){let n=t.default||t,r=typeof t.loader=="function"?await t.loader(e):void 0,a=C(r),o=e.params||{};return{body:x(a,()=>y(at(n,{...o,loaderData:r}))),head:U(a.head),loaderData:r}}var it=12;async function qt(t,e){e||(e=C(void 0));let n="";for(let a=0;a<it;a++){n=x(e,()=>y(t));let o=[...e.resources.values()].filter(s=>s.status==="pending").map(s=>s.promise);if(o.length===0)break;await Promise.all(o)}let r={};for(let[a,o]of e.resources)o.status==="ready"&&(r[a]=o.value);return{body:n,head:U(e.head),loaderData:e.loaderData,resources:r,ctx:e}}async function P(t,e={},n={}){let r=t.default||t,a=typeof t.loader=="function"?await t.loader(e):void 0,o=C(a),s=e.params||{},{body:i,head:c,resources:u}=await qt(at(r,{...s,loaderData:a}),o),d={loaderData:a??null,resources:u,islandStores:X()};return Kt({body:i,head:c,payload:d,options:n})}function Kt({body:t,head:e,payload:n,options:r={}}){let a=r.lang||"en",o=`<script id="__what_data" type="application/json">${k(n)}<\/script>`,s=r.clientEntry?`<script type="module" src="${h(r.clientEntry)}"><\/script>`:"",i=r.head||"",c=r.bodyClass?` class="${h(r.bodyClass)}"`:"";return`<!DOCTYPE html><html lang="${h(a)}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">${e||""}${i}</head><body${c}>${t}${o}${s}</body></html>`}async function*R(t,e){if(e===void 0&&(e=C(void 0)),t==null||t===!1||t===!0)return;if(typeof t=="string"||typeof t=="number"){yield h(String(t));return}if(typeof t=="function"&&t._signal){yield*R(t(),e);return}if(typeof t=="function"){try{yield*R(t(),e)}catch{typeof process<"u"}return}if(Array.isArray(t)){for(let s of t)yield*R(s,e);return}if(t.tag==="__suspense"){let s=null;for(let i=0;i<it&&s===null;i++){let c=null;try{s=x(e,()=>(t.children||[]).map(y).join(""))}catch(u){if(u&&typeof u.then=="function")c=u;else throw u}if(s===null){let u=[...e.resources.values()].filter(d=>d.status==="pending").map(d=>d.promise);await Promise.all([c,...u].filter(Boolean))}}s===null&&(s=x(e,()=>y(t.props&&t.props.fallback))),yield s;return}if(typeof t.tag=="function"){try{let s=t.tag({...t.props,children:t.children}),i=s instanceof Promise?await s:s;yield*R(i,e)}catch(s){typeof process<"u",yield ct?`<!-- SSR Error: ${h(s.message||"Component error")} -->`:"<!-- SSR Error -->"}return}let{tag:n,props:r,children:a}=t,o=J(r||{});if(yield`<${n}${o}>`,!W.has(n)){let s=V(r);if(s!=null)yield String(s);else for(let i of a)yield*R(i,e);yield`</${n}>`}}function Le(t){return{mode:"static",...t}}function Fe(t,e={}){let n=t.component(e),r=y(n),a=t.islands||[];return Zt({title:t.title||"",meta:t.meta||{},body:r,islands:a,scripts:t.mode==="static"?[]:t.scripts||[],styles:t.styles||[],mode:t.mode})}function Zt({title:t,meta:e,body:n,islands:r,scripts:a,styles:o,mode:s}){let i=Object.entries(e).map(([f,p])=>`<meta name="${h(f)}" content="${h(p)}">`).join(`
|
|
2
|
+
`),c=o.map(f=>`<link rel="stylesheet" href="${h(f)}">`).join(`
|
|
3
|
+
`),u=r.length>0?`
|
|
4
4
|
<script type="module">
|
|
5
5
|
import { hydrateIslands } from '/@what/islands.js';
|
|
6
6
|
hydrateIslands();
|
|
7
|
-
<\/script>`:"",
|
|
8
|
-
`),l=
|
|
7
|
+
<\/script>`:"",d=a.map(f=>`<script type="module" src="${h(f)}"><\/script>`).join(`
|
|
8
|
+
`),l=s==="client"?`
|
|
9
9
|
<script type="module" src="/@what/client.js"><\/script>`:"";return`<!DOCTYPE html>
|
|
10
10
|
<html lang="en">
|
|
11
11
|
<head>
|
|
12
12
|
<meta charset="UTF-8">
|
|
13
13
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
14
|
-
${
|
|
15
|
-
<title>${
|
|
14
|
+
${i}
|
|
15
|
+
<title>${h(t)}</title>
|
|
16
16
|
${c}
|
|
17
17
|
</head>
|
|
18
18
|
<body>
|
|
19
|
-
<div id="app">${
|
|
20
|
-
${f}
|
|
19
|
+
<div id="app">${n}</div>
|
|
21
20
|
${u}
|
|
21
|
+
${d}
|
|
22
22
|
${l}
|
|
23
23
|
</body>
|
|
24
|
-
</html>`}function
|
|
24
|
+
</html>`}function Ue(t){return t._server=!0,t}var ct=!(typeof process<"u");function V(t){return t?t.dangerouslySetInnerHTML?t.dangerouslySetInnerHTML.__html??null:t.innerHTML&&typeof t.innerHTML=="object"&&"__html"in t.innerHTML?t.innerHTML.__html??null:(t.innerHTML!=null&&typeof t.innerHTML=="string"&&ct&&console.warn("[what-server] innerHTML received a raw string. This is a security risk (XSS). Use innerHTML={{ __html: trustedString }} or dangerouslySetInnerHTML={{ __html: trustedString }} instead."),null):null}function J(t){let e="";for(let[n,r]of Object.entries(t))if(!(n==="key"||n==="ref"||n==="children"||n==="dangerouslySetInnerHTML"||n==="innerHTML")&&!(n.startsWith("on")&&n.length>2)&&!(r===!1||r==null))if(n==="className"||n==="class")e+=` class="${h(String(r))}"`;else if(n==="style"&&typeof r=="object"){let a=Object.entries(r).map(([o,s])=>`${ne(o)}:${s}`).join(";");e+=` style="${h(a)}"`}else if(r===!0)n.startsWith("aria-")||n==="role"?e+=` ${n}="true"`:e+=` ${n}`;else{if(te(n,r))continue;e+=` ${n}="${h(String(r))}"`}return e}function te(t,e){let n=t.toLowerCase();if(!ee.has(n))return!1;let r=String(e).trim().replace(/[\u0000-\u001f\u007f\s]+/g,"").toLowerCase();return r.startsWith("javascript:")||r.startsWith("vbscript:")||r.startsWith("data:")}var ee=new Set(["href","src","action","formaction","xlink:href"]);function h(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function ne(t){return t.startsWith("--")?t:t.replace(/([A-Z])/g,"-$1").toLowerCase()}var W=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);export{bt as action,zt as buildVercelOutput,E as createActionHandler,Wt as createCloudflareHandler,A as createRequestHandler,Nt as createServer,Bt as createVercelHandler,yt as csrfMetaTag,Le as definePage,Jt as exportStatic,Pt as fetchActionHandler,Q as formAction,mt as generateCsrfToken,Fe as generateStaticPage,_t as getRegisteredActions,pt as getRevalidationHandler,N as handleActionRequest,K as invalidatePath,xt as nodeActionMiddleware,Tt as onRevalidate,P as renderDocument,Ne as renderPage,De as renderToHydratableString,R as renderToStream,y as renderToString,qt as renderToStringAsync,Me as renderToStringWithHead,I as revalidatePath,j as revalidateTag,k as serializeState,Ue as server,H as setRevalidationHandler,rt as toNodeListener,q as useAction,St as useFormAction,kt as useMutation,At as useOptimistic,G as validateCsrfToken,Mt as whatMiddleware};
|
|
25
25
|
//# sourceMappingURL=index.min.js.map
|