refactor: flatten monorepo to single web package (#12)

Flatten the pnpm monorepo (apps/web + packages/*) into a single web package at the repo root.

- Move app/lib/components/scripts/public to root; drop apps/web and packages/* wrappers
- Rewrite tsconfig paths (@infiplot/*) to ./lib/*; turbopack.root = __dirname
- Update Vercel (no root-directory) and Cloudflare (pnpm build:cf at root) deploy paths
- Regenerate pnpm-lock.yaml to drop stale workspace importers
- Bump engines.node to >=22 to match wrangler

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Zonghao Yuan
2026-06-03 00:55:45 +08:00
committed by GitHub
parent 9543c3dba1
commit dc5ecd60f6
221 changed files with 241 additions and 379 deletions
+39
View File
@@ -0,0 +1,39 @@
type RetryInit = RequestInit & { retries?: number; retryDelayMs?: number };
export async function fetchWithRetry(
url: string,
init: RetryInit,
): Promise<Response> {
const { retries = 2, retryDelayMs = 1500, ...fetchInit } = init;
let lastError: unknown;
for (let attempt = 0; attempt <= retries; attempt++) {
try {
const res = await fetch(url, fetchInit);
if (res.ok) return res;
// Don't retry 4xx (client errors won't fix themselves)
if (res.status >= 400 && res.status < 500) return res;
// 5xx: retry if we have budget left
if (attempt < retries) {
await sleep(retryDelayMs * (attempt + 1));
continue;
}
return res;
} catch (err) {
lastError = err;
const isAbort =
err instanceof DOMException && err.name === "AbortError";
if (isAbort) throw err;
if (attempt < retries) {
await sleep(retryDelayMs * (attempt + 1));
continue;
}
throw err;
}
}
throw lastError;
}
function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}