TellWang
Dashboard

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.

Click Functions on any Wok card in the dashboard for an in-browser deploy panel: name + code textarea + Deploy button, with the invoke URL and a Delete button per function. No CLI install needed.

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.

you → Cursor
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)

app.ts
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.

trigger.ts
// "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.

queue.ts
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