SDK Server Reference
Complete reference for @zaflun/lumio-sdk/server — the server-side library used in server/functions.ts.
Import
import { action, query, v } from "@zaflun/lumio-sdk/server";
Defining functions
action
Defines a server function that can be called by the client via useLumioAction() or useMutation(). Actions have full access to storage, secrets, egress, and real-time push.
function action<TArgs, TReturn>(definition: {
args: ArgSchema<TArgs>;
handler: (ctx: ActionContext, args: TArgs) => Promise<TReturn>;
}): Action<TArgs, TReturn>;
export const incrementScore = action({
args: { amount: v.number() },
handler: async (ctx, args) => {
const current = (await ctx.db.get<number>("install", "score")) ?? 0;
const next = current + args.amount;
await ctx.db.set("install", "score", next);
return { score: next };
},
});
query
Defines a read-only server function. Queries cannot write to storage, push real-time events, or call external APIs. They are intended for fetching state and may be cached by the platform.
function query<TArgs, TReturn>(definition: {
args: ArgSchema<TArgs>;
handler: (ctx: QueryContext, args: TArgs) => Promise<TReturn>;
}): Query<TArgs, TReturn>;
export const getScore = query({
args: { userId: v.string() },
handler: async (ctx, args) => {
return ctx.db.get<number>("user", args.userId, "score") ?? 0;
},
});
ActionContext
The ctx parameter in action() handlers.
ctx.db — Storage
Reads and writes extension storage, namespaced by scope.
// Read a value
const value = await ctx.db.get<T>(scope, ...keys);
// Write a value
await ctx.db.set(scope, ...keys, value);
// Delete a value
await ctx.db.delete(scope, ...keys);
// List all keys in a scope (with optional prefix)
const keys = await ctx.db.list(scope, prefix?);
Scopes:
| Scope | Isolation | Capacity |
|---|---|---|
"global" | Shared across all installs | 100 MB |
"install" | Per overlay install | 10 MB |
"user" | Per authenticated viewer (interactive page only) | 1 MB |
ctx.fetch — External HTTP
Calls an external HTTPS endpoint. Subject to the egress.allowHosts allowlist declared in lumio.config.json.
const res = await ctx.fetch("https://api.example.com/data");
const json = await res.json();
Has the same interface as the standard fetch() API. Restrictions:
- HTTPS only
- No private IP ranges or localhost
- Maximum 10 calls per action invocation
- 30-second timeout per request
ctx.secrets — Secret access
Reads secrets stored via lumio secrets set or the dashboard.
const apiKey = ctx.secrets.get("MY_API_KEY"); // throws if not set
const exists = ctx.secrets.has("MY_API_KEY"); // boolean check
Secret values are never logged or returned to the client.
ctx.realtime — Push real-time events
Pushes an event to all connected surfaces (layer, editor, interactive page) for this install.
await ctx.realtime.push("score:updated", { score: 42 });
Clients receive the event via a WebSocket subscription. Listen with:
window.addEventListener("lumio:realtime", (event) => {
if (event.type === "score:updated") {
console.log(event.data.score);
}
});
Maximum 64 KB payload. Maximum 100 pushes/second per extension.
ctx.identity — Caller identity
Present when the action is called from the interactive page by an authenticated viewer. null on the layer and editor surfaces.
if (ctx.identity) {
console.log(ctx.identity.userId);
console.log(ctx.identity.platform); // "twitch" | "youtube" | ...
console.log(ctx.identity.platformUserId);
}
QueryContext
The ctx parameter in query() handlers. A subset of ActionContext — read-only access only.
| Property | Available |
|---|---|
ctx.db.get | Yes |
ctx.db.list | Yes |
ctx.db.set | No — throws |
ctx.fetch | No — throws |
ctx.secrets | Yes (read-only) |
ctx.realtime | No — throws |
ctx.identity | Yes |
Validation — v
The v object provides runtime argument validators. All args must be declared with v — undeclared fields are stripped before the handler runs.
// Primitives
v.string()
v.number()
v.boolean()
v.null_()
// Modifiers
v.optional(v.string()) // string | undefined — field may be absent
v.nullable(v.string()) // string | null
// Collections
v.array(v.string())
v.object({ name: v.string(), count: v.number() })
// Union
v.union([v.string(), v.number()])
// Literal
v.literal("active")
Validation happens before the handler is called. Invalid args return a structured error to the caller without invoking the handler.
Exports from server/functions.ts
Every named export from server/functions.ts that is an action() or query() result is automatically registered with the platform at deploy time. No additional registration step is needed.
// server/functions.ts
export const getScore = query({ ... }); // registered as "getScore"
export const setScore = action({ ... }); // registered as "setScore"
// Not registered — not an action or query
export const MULTIPLIER = 2;
The exported name becomes the actionName / queryName used on the client.