feat: add Cloudflare Workers deployment alongside Vercel

InfiPlot now deploys to either Vercel or Cloudflare Workers — both
targets are first-class. The project is fully stateless (sessions live
on the client), so the Cloudflare side needs only Workers + Workers
Assets and zero D1/KV/R2.

- apps/web/wrangler.jsonc — nodejs_compat, Assets binding, 60s CPU
  limit (Workers Paid required; matches vercel.json maxDuration). I/O
  wait does not count against this budget — fits the LLM-bound
  workload that's most of the runtime.
- apps/web/open-next.config.ts — minimal defineCloudflareConfig (no
  cache needed since the engine is stateless).
- apps/web/package.json — added build:cf / preview:cf / deploy:cf via
  @opennextjs/cloudflare + wrangler (both devDeps); sharp moved from
  dependencies to devDependencies (only used by the manual
  optimize-home-images.mjs / localize-firstact-images.mjs scripts now).
- .gitignore — .open-next, .wrangler, .dev.vars.
- READMEs (3 langs) — Deploy to Cloudflare button next to Vercel,
  plus a Cloudflare section in the env-var setup (wrangler secret put
  + Cloudflare Access for staging access control).

Verified: pnpm typecheck + pnpm build (Vercel path) + pnpm build:cf
(OpenNext bundle: worker 4 KB, server 24 MB, assets 32 MB / 186
files — all within Workers limits) + pnpm preview:cf with the full
play loop (start → scene → background click → CORS-clean Canvas
annotation via Runware CDN → vision LLM → insert-beat) all green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
yuanzonghao
2026-06-02 21:47:03 +08:00
parent 346d5359d4
commit 72331bb865
8 changed files with 3519 additions and 28 deletions
+5
View File
@@ -0,0 +1,5 @@
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
// Minimal config — the project is fully stateless (sessions live on the
// client), so no R2/KV/D1 incremental cache is needed.
export default defineCloudflareConfig();
+9 -4
View File
@@ -8,7 +8,10 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit",
"build:cf": "opennextjs-cloudflare build",
"preview:cf": "opennextjs-cloudflare preview",
"deploy:cf": "opennextjs-cloudflare deploy"
},
"dependencies": {
"@infiplot/ai-client": "workspace:*",
@@ -16,16 +19,18 @@
"@infiplot/types": "workspace:*",
"next": "^16.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"sharp": "^0.33.5"
"react-dom": "^19.0.0"
},
"devDependencies": {
"@opennextjs/cloudflare": "^1.19.11",
"sharp": "^0.33.5",
"@types/node": "^22.9.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"autoprefixer": "^10.4.20",
"postcss": "^8.4.49",
"tailwindcss": "^3.4.15",
"typescript": "^5.6.3"
"typescript": "^5.6.3",
"wrangler": "^4.96.0"
}
}
+20
View File
@@ -0,0 +1,20 @@
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "infiplot",
"main": ".open-next/worker.js",
"compatibility_date": "2025-03-25",
"compatibility_flags": ["nodejs_compat"],
"assets": {
"binding": "ASSETS",
"directory": ".open-next/assets"
},
"observability": {
"enabled": true
},
// 60s mirrors apps/web/vercel.json maxDuration for the scene pipeline tail
// (multi-agent LLM, ~30-45s p95). Requires Workers Paid — Free is capped
// at 10ms CPU. I/O wait does not count against this budget.
"limits": {
"cpu_ms": 60000
}
}