Edge Functions
Run your own TypeScript/Deno code in your Wok, next to your data. Use functions for webhooks, third-party integrations, or any logic the database and REST API don't cover.
Deploy (shipped)
Write your function and ship it. The cp's deploy_function step uploads the bundle into your Wok's Edge Runtime container; it's live on your next invoke call.
Deploy notify-slack as a function on my Wok.Your function runs in your Wok, with secure access to its database and secrets — no servers to manage.
Invoke (shipped)
const { data } = await tw.functions.invoke("notify-slack", {
body: { message: "New signup 🎉" },
});Trigger on new rows (shipped)
Wire a function to run automatically when a row is written to a table. cp installs a Postgres trigger that fires pg_notify; a per-Wok listener inside cp picks the notify up and POSTs the row payload ({op, table, old, new}) to your function. The whole loop runs over the wok-local docker network — no public ingress, no extra latency.
// "run notify-slack on every INSERT into orders"
await tw.functions.triggers.create({
table: "public.orders",
event: "insert", // or "update" | "delete" | "*"
function_name: "notify-slack",
});Your function's request body looks like {trigger, fn, op, table, old?, new?}. new is the inserted/updated row; old is the deleted/pre-update row. Use the wok's in-network SUPABASE_URL (http://rest:3000) inside the function if you need to write back via PostgREST without hitting a public port.
Redis + BullMQ (shipped)
Every Wok ships a dedicated Redis 7 container, with process.env.REDIS_URL wired into every edge function — no setup. Reach for it for caching, rate limits, and sessions.
For work that has to run reliably — payroll runs, print batches, billing, invoice generation — BullMQ gives you durable job queues: a job that fails is retried with backoff instead of lost, jobs run in order, and a dropped worker picks up where it left off. That's the difference between "fire an HTTP call and hope" and a queue you can trust with money and paper.
import { Queue, Worker } from "bullmq";
import Redis from "ioredis";
const redis = new Redis(process.env.REDIS_URL!);
const emails = new Queue("emails", { connection: redis });
// in your function — enqueue from a webhook or API call
await emails.add("welcome", { userId: "u_123" });
// in another function — process
new Worker("emails", async (job) => {
await sendWelcomeEmail(job.data.userId);
}, { connection: redis });Redis runs inside the wok's docker network — only your functions and database can reach it. Persisted across restarts (AOF), 200 MiB memory cap with LRU eviction. For caching: any Redis client (ioredis, redis, etc) works against the same URL.
Roadmap
- Filtered + conditional triggers — WHEN clauses + column-list filters so "only when orders.total > 100" is one call.
- External Redis access — opt-in TLS proxy so apps outside the Wok can reach Redis with auth (today Redis is internal-only by design; proxy via an edge function if you need external ops).