Advanced Edge Computing patterns — streaming responses (TransformStream, Server-Sent Events), edge caching (Cache API, stale-while-revalidate), Miniflare testing, and common edge runtime mistakes (Node.js APIs, large npm packages, synchronous computation).
From clarcnpx claudepluginhub marvinrichter/clarc --plugin clarcThis skill uses the workspace's default tool permissions.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
This skill extends edge-patterns with streaming, caching, testing, and anti-patterns. Load edge-patterns first.
// Cloudflare Workers — streaming from a slow upstream
export default {
async fetch(request: Request): Promise<Response> {
const upstream = await fetch('https://slow-api.example.com/data');
// Transform stream (uppercase each chunk)
const { readable, writable } = new TransformStream({
transform(chunk, controller) {
const text = new TextDecoder().decode(chunk);
controller.enqueue(new TextEncoder().encode(text.toUpperCase()));
},
});
upstream.body!.pipeTo(writable);
return new Response(readable, {
headers: {
'Content-Type': 'text/plain',
'Transfer-Encoding': 'chunked',
},
});
},
};
// Server-Sent Events
function* generateEvents() {
for (let i = 0; i < 10; i++) {
yield `data: ${JSON.stringify({ count: i })}\n\n`;
}
}
export default {
fetch(): Response {
const encoder = new TextEncoder();
const stream = new ReadableStream({
async start(controller) {
for (const event of generateEvents()) {
controller.enqueue(encoder.encode(event));
await new Promise(r => setTimeout(r, 1000));
}
controller.close();
},
});
return new Response(stream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
},
});
},
};
// Cloudflare Cache API
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
const cache = caches.default;
// Cache key — can be different from request URL
const cacheKey = new Request(request.url, { method: 'GET' });
// Check cache
const cached = await cache.match(cacheKey);
if (cached) {
return new Response(cached.body, {
...cached,
headers: { ...cached.headers, 'X-Cache': 'HIT' },
});
}
// Fetch and cache
const response = await fetch(request);
const toCache = new Response(response.body, response);
toCache.headers.set('Cache-Control', 'public, max-age=3600');
toCache.headers.set('X-Cache', 'MISS');
// Store in background (don't block response)
ctx.waitUntil(cache.put(cacheKey, toCache.clone()));
return toCache;
},
};
// Stale-While-Revalidate pattern
async function swr(
cacheKey: Request,
fetchFn: () => Promise<Response>,
maxAge: number,
staleAge: number,
ctx: ExecutionContext
): Promise<Response> {
const cache = caches.default;
const cached = await cache.match(cacheKey);
if (cached) {
const age = parseInt(cached.headers.get('X-Cache-Age') ?? '0');
if (age < maxAge) return cached; // Fresh
// Stale — return cached but revalidate in background
if (age < staleAge) {
ctx.waitUntil(
fetchFn().then(fresh => {
fresh.headers.set('X-Cache-Age', '0');
return cache.put(cacheKey, fresh);
})
);
return cached;
}
}
// Miss or expired
const fresh = await fetchFn();
const toCache = new Response(fresh.body, fresh);
toCache.headers.set('X-Cache-Age', '0');
ctx.waitUntil(cache.put(cacheKey, toCache.clone()));
return toCache;
}
// test/worker.test.ts
import { Miniflare } from 'miniflare';
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
describe('Worker', () => {
let mf: Miniflare;
beforeAll(async () => {
mf = new Miniflare({
scriptPath: './src/index.ts',
kvNamespaces: ['MY_KV'],
d1Databases: ['MY_DB'],
bindings: { MY_SECRET: 'test-secret' },
});
});
afterAll(() => mf.dispose());
it('returns health check', async () => {
const res = await mf.dispatchFetch('http://localhost/api/health');
expect(res.status).toBe(200);
const body = await res.json();
expect(body).toEqual({ status: 'ok' });
});
it('reads from KV', async () => {
const kv = await mf.getKVNamespace('MY_KV');
await kv.put('user:1', JSON.stringify({ name: 'Alice' }));
const res = await mf.dispatchFetch('http://localhost/api/user/1');
expect(res.status).toBe(200);
});
});
# Install
npm install -D miniflare vitest
# Run tests
vitest run
// WRONG: Node.js API in Edge Runtime
import { readFileSync } from 'fs'; // Not available
// CORRECT: Use fetch to load static assets
const data = await fetch(new URL('./data.json', import.meta.url)).then(r => r.json());
// WRONG: Large npm package (pulls in Node.js dependencies)
import moment from 'moment'; // Too large, Node.js APIs
// CORRECT: Web-compatible alternative
import { format } from 'date-fns/format'; // Pure JS, tree-shakeable
// WRONG: Synchronous heavy computation blocking isolate
export default {
fetch(): Response {
const result = heavySync(largeData); // Hits CPU limit
return Response.json(result);
}
}
// CORRECT: Stream or offload to Durable Object / Queue
edge-patterns — runtime constraints, Cloudflare Workers (KV/D1/R2/Durable Objects), Vercel Edge Middleware, Deno Deployserverless-patterns — cold starts, Step Functions, Lambda Powertools, idempotencywasm-patterns — run Rust WASM in Cloudflare Workers