mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-09-11 22:51:05 +00:00
Add docs-proxy worker app with fetch timeout and caching
Creates apps/docs-proxy/ - a new Cloudflare Worker that replaces the supermemory-docs-mintlify dashboard-deployed worker. Key improvements over the previous worker: - AbortController with 10-second timeout prevents indefinite hangs when Mintlify is slow (previous P99 reached 836 seconds) - Cache API (caches.default) caches successful GET responses for 5 minutes to reduce upstream load and improve response times - Returns 504 with a user-friendly message on timeout Worker proxies all requests to https://supermemory.mintlify.dev preserving original path, query string, method, headers, and body. Co-authored-by: Dhravya Shah <dhravya@supermemory.com>
This commit is contained in:
parent
e706a13877
commit
fad0553b67
5 changed files with 100 additions and 0 deletions
15
apps/docs-proxy/package.json
Normal file
15
apps/docs-proxy/package.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"name": "@repo/docs-proxy",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "wrangler dev",
|
||||
"deploy": "wrangler deploy --minify"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20250620.0",
|
||||
"typescript": "^5.8.3",
|
||||
"wrangler": "^4.4.0"
|
||||
}
|
||||
}
|
||||
46
apps/docs-proxy/src/index.ts
Normal file
46
apps/docs-proxy/src/index.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
const UPSTREAM_BASE = "https://supermemory.mintlify.dev";
|
||||
const CACHE_TTL = 300; // 5 minutes
|
||||
const FETCH_TIMEOUT_MS = 10000; // 10 seconds
|
||||
|
||||
export default {
|
||||
async fetch(request: Request): Promise<Response> {
|
||||
const url = new URL(request.url);
|
||||
const proxyUrl = UPSTREAM_BASE + url.pathname + url.search;
|
||||
|
||||
const cache = caches.default;
|
||||
|
||||
if (request.method === "GET") {
|
||||
const cached = await cache.match(request);
|
||||
if (cached) return cached;
|
||||
}
|
||||
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
||||
|
||||
try {
|
||||
const proxyRequest = new Request(proxyUrl, request);
|
||||
const response = await fetch(proxyRequest, { signal: controller.signal });
|
||||
|
||||
if (request.method === "GET" && response.ok) {
|
||||
const cachedResponse = new Response(response.clone().body, response);
|
||||
cachedResponse.headers.set("Cache-Control", `public, max-age=${CACHE_TTL}`);
|
||||
await cache.put(request, cachedResponse);
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (e) {
|
||||
if (e instanceof Error && e.name === "AbortError") {
|
||||
return new Response(
|
||||
"Documentation temporarily unavailable. Please try again in a moment.",
|
||||
{
|
||||
status: 504,
|
||||
headers: { "Content-Type": "text/plain; charset=utf-8" },
|
||||
},
|
||||
);
|
||||
}
|
||||
throw e;
|
||||
} finally {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
},
|
||||
};
|
||||
15
apps/docs-proxy/tsconfig.json
Normal file
15
apps/docs-proxy/tsconfig.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"lib": ["ESNext"],
|
||||
"types": ["@cloudflare/workers-types"],
|
||||
"outDir": "dist",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
11
apps/docs-proxy/wrangler.jsonc
Normal file
11
apps/docs-proxy/wrangler.jsonc
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"$schema": "node_modules/wrangler/config-schema.json",
|
||||
"name": "supermemory-docs-mintlify",
|
||||
"main": "src/index.ts",
|
||||
"compatibility_date": "2025-06-20",
|
||||
"compatibility_flags": [],
|
||||
|
||||
"observability": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
13
bun.lock
13
bun.lock
|
|
@ -83,6 +83,15 @@
|
|||
"typescript": "^5.9.2",
|
||||
},
|
||||
},
|
||||
"apps/docs-proxy": {
|
||||
"name": "@repo/docs-proxy",
|
||||
"version": "1.0.0",
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20250620.0",
|
||||
"typescript": "^5.8.3",
|
||||
"wrangler": "^4.4.0",
|
||||
},
|
||||
},
|
||||
"apps/mcp": {
|
||||
"name": "supermemory-mcp",
|
||||
"version": "4.0.0",
|
||||
|
|
@ -1448,6 +1457,8 @@
|
|||
|
||||
"@repo/docs": ["@repo/docs@workspace:apps/docs"],
|
||||
|
||||
"@repo/docs-proxy": ["@repo/docs-proxy@workspace:apps/docs-proxy"],
|
||||
|
||||
"@repo/hooks": ["@repo/hooks@workspace:packages/hooks"],
|
||||
|
||||
"@repo/lib": ["@repo/lib@workspace:packages/lib"],
|
||||
|
|
@ -5442,6 +5453,8 @@
|
|||
|
||||
"@repo/docs/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||
|
||||
"@repo/docs-proxy/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||
|
||||
"@repo/lib/better-auth": ["better-auth@1.3.3", "", { "dependencies": { "@better-auth/utils": "0.2.5", "@better-fetch/fetch": "^1.1.18", "@noble/ciphers": "^0.6.0", "@noble/hashes": "^1.8.0", "@simplewebauthn/browser": "^13.0.0", "@simplewebauthn/server": "^13.0.0", "better-call": "^1.0.12", "defu": "^6.1.4", "jose": "^5.9.6", "kysely": "^0.28.1", "nanostores": "^0.11.3", "zod": "^4.0.5" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["react", "react-dom"] }, "sha512-q1aD2nNpGfEI2ckYu+pBjN+23CIRctOpmREkWyJDJdoYW1q9EPs1Xdb+KhFztg2rMmsoUN8I9Xm5mUWMxiWuLw=="],
|
||||
|
||||
"@repo/web/@ai-sdk/google": ["@ai-sdk/google@3.0.64", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-CbR82EgGPNrj/6q0HtclwuCqe0/pDShyv3nWDP/A9DroujzWXnLMlUJVrgPOsg4b40zQCwwVs2XSKCxvt/4QaA=="],
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue