@leejpsd/nextjs-cache-handler 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/AGENTS.md +33 -0
  2. package/CHANGELOG.md +43 -0
  3. package/README.md +22 -3
  4. package/bin/cli.cjs +10 -0
  5. package/dist/cache-components/index.cjs +150 -4
  6. package/dist/cache-components/index.cjs.map +1 -1
  7. package/dist/cache-components/index.d.cts +1 -1
  8. package/dist/cache-components/index.d.ts +1 -1
  9. package/dist/cache-components/index.js +150 -4
  10. package/dist/cache-components/index.js.map +1 -1
  11. package/dist/cli/index.cjs +937 -0
  12. package/dist/cli/index.cjs.map +1 -0
  13. package/dist/cli/index.d.cts +28 -0
  14. package/dist/cli/index.d.ts +28 -0
  15. package/dist/cli/index.js +927 -0
  16. package/dist/cli/index.js.map +1 -0
  17. package/dist/incremental/index.cjs +77 -3
  18. package/dist/incremental/index.cjs.map +1 -1
  19. package/dist/incremental/index.d.cts +1 -1
  20. package/dist/incremental/index.d.ts +1 -1
  21. package/dist/incremental/index.js +77 -3
  22. package/dist/incremental/index.js.map +1 -1
  23. package/dist/index.cjs +153 -5
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +1 -1
  26. package/dist/index.d.ts +1 -1
  27. package/dist/index.js +153 -5
  28. package/dist/index.js.map +1 -1
  29. package/dist/ops/index.d.cts +1 -1
  30. package/dist/ops/index.d.ts +1 -1
  31. package/dist/otel/index.d.cts +1 -1
  32. package/dist/otel/index.d.ts +1 -1
  33. package/dist/seed/index.cjs +560 -0
  34. package/dist/seed/index.cjs.map +1 -0
  35. package/dist/seed/index.d.cts +53 -0
  36. package/dist/seed/index.d.ts +53 -0
  37. package/dist/seed/index.js +549 -0
  38. package/dist/seed/index.js.map +1 -0
  39. package/dist/shared/client/adapter-ioredis.cjs +40 -1
  40. package/dist/shared/client/adapter-ioredis.cjs.map +1 -1
  41. package/dist/shared/client/adapter-ioredis.d.cts +1 -1
  42. package/dist/shared/client/adapter-ioredis.d.ts +1 -1
  43. package/dist/shared/client/adapter-ioredis.js +40 -1
  44. package/dist/shared/client/adapter-ioredis.js.map +1 -1
  45. package/dist/shared/client/adapter-redis.cjs +34 -1
  46. package/dist/shared/client/adapter-redis.cjs.map +1 -1
  47. package/dist/shared/client/adapter-redis.d.cts +1 -1
  48. package/dist/shared/client/adapter-redis.d.ts +1 -1
  49. package/dist/shared/client/adapter-redis.js +34 -1
  50. package/dist/shared/client/adapter-redis.js.map +1 -1
  51. package/dist/{types-Bl-rkLKX.d.cts → types-C1vJ_sED.d.cts} +25 -1
  52. package/dist/{types-Bl-rkLKX.d.ts → types-C1vJ_sED.d.ts} +25 -1
  53. package/llms.txt +27 -0
  54. package/package.json +27 -2
  55. package/rules/nextjs-cache-rules.md +23 -0
  56. package/setup-instructions/setup.md +179 -0
  57. package/skills/nextjs-redis-cache/SKILL.md +182 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../node_modules/tsup/assets/cjs_shims.js","../../src/shared/node-require.ts","../../src/shared/client/adapter-redis.ts","../../src/shared/client/adapter-ioredis.ts","../../src/cli/index.ts","../../src/shared/client/index.ts","../../src/seed/index.ts","../../src/shared/compress.ts","../../src/shared/namespace.ts","../../src/incremental/serialize.ts"],"names":["createRequire","path","adaptRedisV5","createRedisV5Client","adaptIoredis","createIoredisClient","adaptCluster","createIoredisCluster","createIoredisSentinel","promisify","gzip","gunzip","brotliCompress","brotliDecompress","constants","fs","value","r"],"mappings":"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","file":"index.cjs","sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","/**\n * A require() that works from BOTH build outputs.\n *\n * The client/OTel factories load optional peers (`redis`, `ioredis`,\n * `@opentelemetry/api`) lazily at runtime. A bare `require()` compiles fine\n * for CJS but becomes esbuild's `__require` fallback in the ESM build, which\n * throws \"Dynamic require of X is not supported\" in pure-ESM consumers.\n * `createRequire(import.meta.url)` is real in ESM, and tsup's `shims: true`\n * provides an `import.meta.url` polyfill for the CJS build.\n */\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\n\nconst packageRequire = createRequire(import.meta.url);\nconst cwdRequire = createRequire(\n path.join(process.cwd(), \"__resolve-anchor__.js\")\n);\n\nexport function nodeRequire(id: string): unknown {\n try {\n return packageRequire(id);\n } catch {\n // Symlinked installs (npm i <local-path>, pnpm's virtual store) resolve\n // import.meta.url to the package's REAL location, outside the app tree —\n // so peers installed by the app aren't reachable from that anchor. Retry\n // from the process CWD, which under a Next.js server is the app root.\n return cwdRequire(id);\n }\n}\n","/**\n * Adapter for `redis@5` (the official `node-redis` client).\n *\n * v5 already uses camelCase methods that match `RedisClientLike` almost\n * exactly, so this adapter is mostly a type assertion plus the\n * `createRedisV5Client` factory that codifies the \"1.5s connectTimeout,\n * reconnectStrategy: false\" defaults validated in production by the reference\n * implementation.\n */\n\nimport type { RedisClientType } from \"redis\";\n\nimport type { RedisClientConfig, RedisClientLike } from \"../../types.js\";\nimport { nodeRequire } from \"../node-require.js\";\n\nexport function adaptRedisV5(client: RedisClientType): RedisClientLike {\n const like = client as unknown as RedisClientLike;\n like.dispose = () => {\n try {\n client.destroy();\n } catch {\n /* already closed */\n }\n };\n // redis@5 exposes publish natively; subscribe needs a duplicate connection.\n like.subscribe = async (channel, onMessage, onDown) => {\n const sub = client.duplicate();\n const teardown = () => {\n try {\n sub.destroy();\n } catch {\n /* already closed */\n }\n };\n let down = false;\n const markDown = () => {\n if (down) return;\n down = true;\n teardown();\n onDown?.();\n };\n sub.on(\"error\", markDown);\n // reconnectStrategy is false on duplicates — a dropped socket is final,\n // so surface it instead of latching a dead subscription as active.\n sub.on(\"end\", markDown);\n try {\n await sub.connect();\n await sub.subscribe(channel, (message: string) => onMessage(message));\n } catch (err) {\n // CRITICAL: without this, every failed SUBSCRIBE (e.g. ACL without\n // channel permissions) leaks one connected duplicate per retry.\n teardown();\n throw err;\n }\n return async () => teardown();\n };\n return like;\n}\n\nexport function createRedisV5Client(\n config: Extract<RedisClientConfig, { type: \"redis\" }>\n): RedisClientType {\n // Lazy require so consumers using ioredis only don't pay the cost.\n // We do `require` instead of `await import` here because the parent\n // `buildClient` is already in an async context that handles awaiting.\n \n const { createClient } = nodeRequire(\"redis\") as typeof import(\"redis\");\n const useTls = config.tls ?? config.url.startsWith(\"rediss://\");\n\n // redis@5 has a discriminated socket union (TCP / TLS / IPC) and disallows\n // explicit `undefined` under exactOptionalPropertyTypes. Build the options\n // object incrementally so optional fields stay absent when not set.\n \n const opts: any = {\n url: config.url,\n socket: {\n connectTimeout: config.connectTimeout ?? 1500,\n reconnectStrategy: false,\n ...(useTls ? { tls: true } : {}),\n },\n };\n if (config.password !== undefined) opts.password = config.password;\n\n return createClient(opts) as RedisClientType;\n}\n","/**\n * Adapter for `ioredis` (and `ioredis.Cluster`).\n *\n * ioredis uses snake_case method names (`sadd`, `smembers`, `mget`) and a\n * stream-based scan. We normalize both into the camelCase / async-iterable\n * `RedisClientLike` contract so the handlers don't need to know which client\n * is underneath.\n */\n\nimport type { Cluster, Redis } from \"ioredis\";\n\nimport type { RedisClientConfig, RedisClientLike } from \"../../types.js\";\nimport { nodeRequire } from \"../node-require.js\";\n\ntype AnyRedis = Redis | Cluster;\n\nfunction adapt(client: AnyRedis, isClusterClient = false): RedisClientLike {\n return {\n get isOpen() {\n // ioredis exposes a `status` string. Both single-node and cluster\n // report \"ready\" once connected.\n return client.status === \"ready\";\n },\n connect: async () => {\n if (client.status !== \"ready\" && client.status !== \"connecting\") {\n await client.connect();\n }\n },\n get: (k) => client.get(k),\n set: (k, v, opts) => {\n const args: (string | number)[] = [];\n if (opts?.EX !== undefined) args.push(\"EX\", opts.EX);\n if (opts?.NX) args.push(\"NX\");\n return (client.set as (...a: unknown[]) => Promise<unknown>)(k, v, ...args);\n },\n del: async (keys) => {\n const arr = Array.isArray(keys) ? keys : [keys];\n if (arr.length === 0) return 0;\n return client.del(...arr);\n },\n sAdd: async (k, m) => {\n const arr = Array.isArray(m) ? m : [m];\n if (arr.length === 0) return 0;\n return client.sadd(k, ...arr);\n },\n sMembers: (k) => client.smembers(k),\n expire: async (k, s) => {\n const r = await client.expire(k, s);\n return r;\n },\n mGet: async (keys) => {\n if (keys.length === 0) return [];\n return client.mget(...keys);\n },\n eval: (script, opts) =>\n client.eval(\n script,\n opts.keys.length,\n ...opts.keys,\n ...opts.arguments\n ) as Promise<unknown>,\n evalSha: (sha, opts) =>\n client.evalsha(\n sha,\n opts.keys.length,\n ...opts.keys,\n ...opts.arguments\n ) as Promise<unknown>,\n scriptLoad: async (script) =>\n (await client.script(\"LOAD\", script)) as string,\n scanIterator: async function* ({ MATCH, COUNT }) {\n // Cluster does not support a single SCAN cursor across slots; use\n // ioredis's per-node iterator there. Single-node: standard SCAN cursor.\n if (isClusterClient) {\n const cluster = client as Cluster;\n for (const node of cluster.nodes(\"master\")) {\n let cursor = \"0\";\n do {\n const [next, batch]: [string, string[]] = await node.scan(\n cursor,\n \"MATCH\",\n MATCH,\n \"COUNT\",\n COUNT ?? 100\n );\n cursor = next;\n if (batch.length > 0) yield batch;\n } while (cursor !== \"0\");\n }\n } else {\n const redis = client as Redis;\n let cursor = \"0\";\n do {\n const [next, batch]: [string, string[]] = await redis.scan(\n cursor,\n \"MATCH\",\n MATCH,\n \"COUNT\",\n COUNT ?? 100\n );\n cursor = next;\n if (batch.length > 0) yield batch;\n } while (cursor !== \"0\");\n }\n },\n ping: () => client.ping(),\n on: (event, listener) => {\n client.on(event, listener);\n return client;\n },\n publish: (channel, message) => client.publish(channel, message),\n ...(isClusterClient\n ? {}\n : {\n subscribe: async (\n channel: string,\n onMessage: (message: string) => void,\n onDown?: () => void\n ) => {\n const sub = (client as Redis).duplicate();\n let down = false;\n const markDown = () => {\n if (down) return;\n down = true;\n try {\n sub.disconnect();\n } catch {\n /* already closed */\n }\n onDown?.();\n };\n sub.on(\"error\", markDown);\n sub.on(\"end\", markDown);\n try {\n if (sub.status !== \"ready\" && sub.status !== \"connecting\") {\n await sub.connect();\n }\n await sub.subscribe(channel);\n } catch (err) {\n markDown();\n throw err;\n }\n sub.on(\"message\", (ch: string, message: string) => {\n if (ch === channel) onMessage(message);\n });\n return async () => {\n down = true;\n sub.disconnect();\n };\n },\n }),\n dispose: () => {\n client.disconnect();\n },\n };\n}\n\nexport function adaptIoredis(client: Redis): RedisClientLike {\n return adapt(client, false);\n}\n\nexport function adaptCluster(cluster: Cluster): RedisClientLike {\n return adapt(cluster, true);\n}\n\nexport function createIoredisClient(\n config: Extract<RedisClientConfig, { type: \"ioredis\" }>\n): Redis {\n \n const IORedis = nodeRequire(\"ioredis\") as typeof import(\"ioredis\");\n // ioredis exports the class as both `default` and a named property.\n // Hitting the default works for both ESM and CJS consumers.\n const Ctor = IORedis.default ?? (IORedis as unknown as typeof import(\"ioredis\").default);\n return new Ctor(config.url, {\n password: config.password,\n connectTimeout: config.connectTimeout ?? 1500,\n tls: config.tls ? {} : undefined,\n lazyConnect: true,\n maxRetriesPerRequest: 1,\n // Batch same-tick commands into one RTT (matches redis@5's default\n // behavior) — makes Promise.all fan-outs a single pipeline.\n enableAutoPipelining: true,\n });\n}\n\nexport function createIoredisSentinel(\n config: Extract<RedisClientConfig, { type: \"sentinel\" }>\n): Redis {\n const IORedis = nodeRequire(\"ioredis\") as typeof import(\"ioredis\");\n const Ctor = IORedis.default ?? (IORedis as unknown as typeof import(\"ioredis\").default);\n return new Ctor({\n sentinels: config.sentinels,\n name: config.name,\n password: config.password,\n sentinelPassword: config.sentinelPassword,\n connectTimeout: config.connectTimeout ?? 1500,\n tls: config.tls ? {} : undefined,\n lazyConnect: true,\n maxRetriesPerRequest: 1,\n enableAutoPipelining: true,\n });\n}\n\nexport function createIoredisCluster(\n config: Extract<RedisClientConfig, { type: \"cluster\" }>\n): Cluster {\n \n const IORedis = nodeRequire(\"ioredis\") as typeof import(\"ioredis\");\n const ClusterCtor =\n IORedis.Cluster ??\n (IORedis.default as unknown as { Cluster: typeof import(\"ioredis\").Cluster })\n .Cluster;\n return new ClusterCtor(config.nodes, {\n redisOptions: {\n password: config.password,\n tls: config.tls ? {} : undefined,\n },\n enableReadyCheck: true,\n lazyConnect: true,\n // Same-slot commands issued in the same tick share one pipeline.\n enableAutoPipelining: true,\n });\n}\n","/**\n * `nextjs-cache-handler` CLI — agent-friendly project setup & diagnostics.\n *\n * Commands:\n * init [--yes] [--dry-run] [--skills] wire the handlers into a Next.js app\n * doctor [--url <redis-url>] connectivity + cache-state diagnostics\n *\n * Design constraints:\n * - Zero dependencies: node builtins only. Redis access reuses the\n * package's own client adapters (which lazy-load the host app's\n * installed `redis`/`ioredis` peer).\n * - Never destructive by default: existing files are left alone unless\n * `--yes` is passed; next.config changes are shown as instructions.\n * - Output is written for BOTH humans and agents: stable `[ok]/[warn]/\n * [action]` prefixes that are trivial to parse.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { buildClient } from \"../shared/client/index.js\";\nimport { seedBuildOutput } from \"../seed/index.js\";\nimport type { RedisClientLike } from \"../types.js\";\n\nconst OK = \"[ok]\";\nconst WARN = \"[warn]\";\nconst ACTION = \"[action]\";\nconst ERR = \"[error]\";\n\ninterface Ctx {\n cwd: string;\n args: string[];\n flags: Set<string>;\n log: (line: string) => void;\n}\n\n// ─── helpers ─────────────────────────────────────────────────────────────────\n\nfunction readJson(file: string): Record<string, unknown> | null {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf8\")) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nfunction detectNextMajor(pkg: Record<string, unknown>): {\n raw: string | null;\n major: number | null;\n supportsCacheComponents: boolean;\n} {\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n const raw = deps[\"next\"] ?? null;\n if (!raw) return { raw: null, major: null, supportsCacheComponents: false };\n const m = raw.match(/(\\d+)\\.(\\d+)/);\n if (!m) return { raw, major: null, supportsCacheComponents: false };\n const major = Number(m[1]);\n const minor = Number(m[2]);\n // cacheHandlers exists from 16.1.5; treat 16.1+ ranges as capable and let\n // the peer range enforce the floor precisely.\n const supportsCacheComponents = major > 16 ? false : major === 16 && minor >= 1;\n return { raw, major, supportsCacheComponents };\n}\n\nfunction detectClient(pkg: Record<string, unknown>): \"redis\" | \"ioredis\" | null {\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n if (deps[\"redis\"]) return \"redis\";\n if (deps[\"ioredis\"]) return \"ioredis\";\n return null;\n}\n\nfunction findNextConfig(cwd: string): string | null {\n for (const name of [\"next.config.ts\", \"next.config.js\", \"next.config.mjs\", \"next.config.cjs\"]) {\n const p = path.join(cwd, name);\n if (fs.existsSync(p)) return p;\n }\n return null;\n}\n\nconst RULES_BEGIN = \"<!-- nextjs-cache-handler:rules:begin -->\";\nconst RULES_END = \"<!-- nextjs-cache-handler:rules:end -->\";\n\nfunction packagedFile(rel: string): string | null {\n // dist/cli/index.cjs|js → package root is two levels up.\n const root = path.resolve(__dirname, \"..\", \"..\");\n const p = path.join(root, rel);\n return fs.existsSync(p) ? p : null;\n}\n\nfunction shimSource(kind: \"incremental\" | \"cache-components\", clientType: string): string {\n const factory =\n kind === \"incremental\"\n ? \"createIncrementalCacheHandler\"\n : \"createCacheComponentsHandler\";\n const subpath = kind === \"incremental\" ? \"incremental\" : \"cache-components\";\n return `// Generated by \\`npx nextjs-cache-handler init\\`\nconst { ${factory} } = require(\"@leejpsd/nextjs-cache-handler/${subpath}\");\n\nmodule.exports = ${factory}({\n client: { type: \"${clientType}\", url: process.env.REDIS_URL },\n // Per-deploy namespace isolation — set DEPLOYMENT_VERSION in every runtime\n // environment (Docker: the runner stage), e.g. the git SHA.\n buildNamespace: () => process.env.DEPLOYMENT_VERSION,\n});\n`;\n}\n\n// ─── init ────────────────────────────────────────────────────────────────────\n\nexport async function init(ctx: Ctx): Promise<number> {\n const { cwd, flags, log } = ctx;\n const apply = flags.has(\"--yes\") && !flags.has(\"--dry-run\");\n\n const pkg = readJson(path.join(cwd, \"package.json\"));\n if (!pkg) {\n log(`${ERR} no package.json in ${cwd} — run inside your Next.js project`);\n return 1;\n }\n\n const next = detectNextMajor(pkg);\n if (!next.raw) {\n log(`${ERR} \"next\" is not a dependency here — not a Next.js project`);\n return 1;\n }\n if (next.major !== null && next.major < 15) {\n log(`${ERR} next@${next.raw} unsupported — this package needs next >=15.0.0 <17`);\n return 1;\n }\n log(`${OK} next: ${next.raw} → ${next.supportsCacheComponents ? \"BOTH handlers (ISR + 'use cache')\" : \"ISR handler only\"}`);\n\n const deps = pkg.dependencies as Record<string, string> | undefined;\n if (!deps?.[\"@leejpsd/nextjs-cache-handler\"]) {\n log(`${ACTION} install the package first: npm i @leejpsd/nextjs-cache-handler`);\n } else {\n log(`${OK} @leejpsd/nextjs-cache-handler ${deps[\"@leejpsd/nextjs-cache-handler\"]}`);\n }\n\n const client = detectClient(pkg);\n if (!client) {\n log(`${ACTION} no Redis client installed — run: npm i redis (or ioredis for Cluster/Sentinel)`);\n } else {\n log(`${OK} redis client: ${client}`);\n }\n const clientType = client ?? \"redis\";\n\n // 1) Wrapper shims.\n const wanted: Array<[\"incremental\" | \"cache-components\", string]> = [\n [\"incremental\", \"cache-incremental.cjs\"],\n ];\n if (next.supportsCacheComponents) wanted.push([\"cache-components\", \"cache-components.cjs\"]);\n\n for (const [kind, file] of wanted) {\n const target = path.join(cwd, file);\n if (fs.existsSync(target)) {\n log(`${OK} ${file} already exists — leaving it untouched`);\n continue;\n }\n if (apply) {\n fs.writeFileSync(target, shimSource(kind, clientType));\n log(`${OK} wrote ${file}`);\n } else {\n log(`${ACTION} would create ${file} (re-run with --yes to write)`);\n }\n }\n\n // 2) next.config guidance (never auto-edited — users customize this file).\n const cfg = findNextConfig(cwd);\n const cfgLines = [\n `cacheHandler: require.resolve(\"./cache-incremental.cjs\"),`,\n ...(next.supportsCacheComponents\n ? [\n `cacheHandlers: { default: require.resolve(\"./cache-components.cjs\") },`,\n `cacheComponents: true,`,\n ]\n : []),\n `cacheMaxMemorySize: 0, // required for multi-instance correctness`,\n ];\n if (!cfg) {\n log(`${WARN} no next.config found — create one with:`);\n } else {\n const body = fs.readFileSync(cfg, \"utf8\");\n if (body.includes(\"cacheHandler\")) {\n log(`${OK} ${path.basename(cfg)} already references a cacheHandler — verify it points at the shims above`);\n } else {\n log(`${ACTION} add to ${path.basename(cfg)}:`);\n }\n if (cfg.endsWith(\".mjs\")) {\n log(`${WARN} ESM config: add import { createRequire } from \"module\"; const require = createRequire(import.meta.url);`);\n }\n }\n for (const l of cfgLines) log(` ${l}`);\n\n // 3) Env template.\n const envExample = path.join(cwd, \".env.example\");\n const envBlock = `\\n# @leejpsd/nextjs-cache-handler\\nREDIS_URL=redis://127.0.0.1:6379\\nDEPLOYMENT_VERSION=dev\\n`;\n if (fs.existsSync(envExample)) {\n const body = fs.readFileSync(envExample, \"utf8\");\n if (body.includes(\"REDIS_URL\")) {\n log(`${OK} .env.example already mentions REDIS_URL`);\n } else if (apply) {\n fs.appendFileSync(envExample, envBlock);\n log(`${OK} appended REDIS_URL / DEPLOYMENT_VERSION to .env.example`);\n } else {\n log(`${ACTION} would append REDIS_URL / DEPLOYMENT_VERSION to .env.example`);\n }\n } else {\n log(`${ACTION} set REDIS_URL and DEPLOYMENT_VERSION in every runtime environment`);\n }\n\n // 4) Agent rules injection (idempotent via markers).\n const rulesSrc = packagedFile(\"rules/nextjs-cache-rules.md\");\n const ruleTargets = [\"CLAUDE.md\", \"AGENTS.md\"]\n .map((f) => path.join(cwd, f))\n .filter((p) => fs.existsSync(p));\n if (rulesSrc && ruleTargets.length > 0) {\n const rules = `\\n${RULES_BEGIN}\\n${fs.readFileSync(rulesSrc, \"utf8\")}\\n${RULES_END}\\n`;\n for (const target of ruleTargets) {\n const body = fs.readFileSync(target, \"utf8\");\n if (body.includes(RULES_BEGIN)) {\n log(`${OK} ${path.basename(target)} already has the cache rules block`);\n } else if (apply) {\n fs.appendFileSync(target, rules);\n log(`${OK} appended cache rules to ${path.basename(target)}`);\n } else {\n log(`${ACTION} would append cache rules to ${path.basename(target)}`);\n }\n }\n } else if (ruleTargets.length === 0) {\n log(`${WARN} no CLAUDE.md/AGENTS.md found — skip rules injection (create one to guide your agent)`);\n }\n\n // 5) MCP registration — one file turns any MCP-capable agent (Claude\n // Code, Cursor, ...) into a cache operator via npx (no install needed).\n const mcpPath = path.join(cwd, \".mcp.json\");\n if (fs.existsSync(mcpPath)) {\n const body = fs.readFileSync(mcpPath, \"utf8\");\n if (body.includes(\"nextjs-cache-handler-mcp\")) {\n log(`${OK} .mcp.json already registers the cache MCP server`);\n } else {\n log(`${ACTION} .mcp.json exists — add the \"nextjs-cache\" server manually (see @leejpsd/nextjs-cache-handler-mcp README)`);\n }\n } else if (apply) {\n fs.writeFileSync(\n mcpPath,\n JSON.stringify(\n {\n mcpServers: {\n \"nextjs-cache\": {\n command: \"npx\",\n args: [\"-y\", \"@leejpsd/nextjs-cache-handler-mcp\"],\n env: {\n REDIS_URL: \"redis://127.0.0.1:6379\",\n DEPLOYMENT_VERSION: \"dev\",\n },\n },\n },\n },\n null,\n 2\n ) + \"\\n\"\n );\n log(`${OK} wrote .mcp.json — your agent now has cache_health/tag_state/... tools (edit REDIS_URL for real environments)`);\n } else {\n log(`${ACTION} would create .mcp.json registering @leejpsd/nextjs-cache-handler-mcp`);\n }\n\n // 6) Optional skill install.\n if (flags.has(\"--skills\")) {\n const skillSrc = packagedFile(\"skills/nextjs-redis-cache/SKILL.md\");\n if (skillSrc) {\n const dest = path.join(cwd, \".claude\", \"skills\", \"nextjs-redis-cache\", \"SKILL.md\");\n if (apply) {\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n fs.copyFileSync(skillSrc, dest);\n log(`${OK} installed skill to .claude/skills/nextjs-redis-cache/`);\n } else {\n log(`${ACTION} would install skill to .claude/skills/nextjs-redis-cache/`);\n }\n }\n }\n\n log(`${OK} init ${apply ? \"complete\" : \"preview complete — re-run with --yes to apply\"}. Verify with: npx nextjs-cache-handler doctor`);\n return 0;\n}\n\n// ─── doctor ──────────────────────────────────────────────────────────────────\n\nexport async function doctor(ctx: Ctx): Promise<number> {\n const { args, log } = ctx;\n const urlIdx = args.indexOf(\"--url\");\n const url = urlIdx >= 0 ? args[urlIdx + 1] : process.env.REDIS_URL;\n if (!url) {\n log(`${ERR} no Redis URL — pass --url <redis-url> or set REDIS_URL`);\n return 1;\n }\n\n const deployment = process.env.DEPLOYMENT_VERSION;\n log(deployment ? `${OK} DEPLOYMENT_VERSION=${deployment}` : `${WARN} DEPLOYMENT_VERSION not set — keys will use the \"unversioned\" namespace`);\n\n let client: RedisClientLike;\n try {\n // Prefer node-redis; fall back to ioredis when only that peer is installed.\n try {\n client = await buildClient({ type: \"redis\", url });\n } catch (err) {\n if (/Cannot find module/.test((err as Error).message)) {\n client = await buildClient({ type: \"ioredis\", url });\n } else {\n throw err;\n }\n }\n if (!client.isOpen) await client.connect();\n } catch (err) {\n log(`${ERR} connect failed: ${(err as Error).message}`);\n log(`${ACTION} check the URL/network, or install a client: npm i redis (or ioredis)`);\n return 1;\n }\n\n try {\n const t0 = Date.now();\n await client.ping();\n log(`${OK} redis PING ${Date.now() - t0}ms (${url.replace(/\\/\\/[^@]*@/, \"//***@\")})`);\n\n const counts = new Map<string, number>();\n for await (const chunk of client.scanIterator({ MATCH: \"next-*\", COUNT: 500 })) {\n const keys = Array.isArray(chunk) ? chunk : [chunk];\n for (const k of keys) {\n const key = String(k);\n const m = key.match(/^(next-cache|next-incremental):([a-z-]+):/);\n const bucket = m ? `${m[1]}:${m[2]}` : \"other\";\n counts.set(bucket, (counts.get(bucket) ?? 0) + 1);\n }\n }\n if (counts.size === 0) {\n log(`${WARN} no next-* keys found — cache not yet exercised (or a custom keyPrefix is in use)`);\n } else {\n for (const [bucket, n] of [...counts.entries()].sort()) {\n log(`${OK} ${bucket}* — ${n} keys`);\n }\n }\n\n // Round-trip probe in an isolated namespace.\n const probeKey = `next-cache:doctor:${Date.now()}`;\n await client.set(probeKey, \"ok\", { EX: 30 });\n const back = await client.get(probeKey);\n await client.del(probeKey);\n log(back === \"ok\" ? `${OK} write/read round-trip` : `${ERR} round-trip failed`);\n return back === \"ok\" ? 0 : 1;\n } finally {\n client.dispose?.();\n }\n}\n\n\n// ─── seed ────────────────────────────────────────────────────────────────────\n\nexport async function seed(ctx: Ctx): Promise<number> {\n const { args, flags, log } = ctx;\n const urlIdx = args.indexOf(\"--url\");\n const url = urlIdx >= 0 ? args[urlIdx + 1] : process.env.REDIS_URL;\n if (!url) {\n log(`${ERR} no Redis URL — pass --url <redis-url> or set REDIS_URL`);\n return 1;\n }\n const flagVal = (name: string): string | undefined => {\n const i = args.indexOf(name);\n return i >= 0 ? args[i + 1] : undefined;\n };\n const dir = flagVal(\"--dir\") ?? \".next\";\n const keyPrefix = flagVal(\"--key-prefix\");\n const namespace = flagVal(\"--namespace\");\n const compression = flagVal(\"--compression\") as \"gzip\" | \"brotli\" | undefined;\n const hashTag = flags.has(\"--hash-tag\");\n\n const ns =\n namespace ??\n process.env.DEPLOYMENT_VERSION ??\n process.env.GIT_HASH ??\n \"unversioned\";\n if (ns === \"unversioned\") {\n log(`${WARN} no namespace — seeding into \"unversioned\" (set DEPLOYMENT_VERSION or pass --namespace)`);\n }\n // Print the exact key shape so a config mismatch with the runtime handler\n // (custom keyPrefix / hashTag) is visible instead of silently seeding\n // keys the app never reads.\n log(`${OK} target keys: ${keyPrefix ?? \"next-incremental:\"}entry:${hashTag ? `{${ns}}` : ns}:*`);\n\n const seedOpts = {\n dir,\n buildNamespace: ns,\n ...(keyPrefix ? { keyPrefix } : {}),\n ...(compression ? { compression } : {}),\n ...(hashTag ? { hashTag: true } : {}),\n };\n const report = (summary: Awaited<ReturnType<typeof seedBuildOutput>>): number => {\n log(`${OK} seeded: ${summary.routes} app routes, ${summary.pages} pages routes, ${summary.fetch} fetch entries`);\n if (summary.skippedExisting > 0)\n log(`${OK} left ${summary.skippedExisting} newer live entries untouched (NX)`);\n if (summary.skippedRouteHandlers > 0)\n log(`${OK} ${summary.skippedRouteHandlers} prerendered route handlers not seeded (by design)`);\n if (summary.skippedIncomplete > 0)\n log(`${WARN} skipped ${summary.skippedIncomplete} routes (incomplete files or PPR resume state)`);\n for (const e of summary.errors.slice(0, 5)) log(`${WARN} ${e}`);\n return summary.errors.length > 0 ? 1 : 0;\n };\n\n try {\n return report(\n await seedBuildOutput({ client: { type: \"redis\", url }, ...seedOpts })\n );\n } catch (err) {\n const msg = (err as Error).message;\n if (/Cannot find module 'redis'/.test(msg)) {\n // Retry with ioredis when only that peer is installed.\n try {\n return report(\n await seedBuildOutput({ client: { type: \"ioredis\", url }, ...seedOpts })\n );\n } catch (err2) {\n log(`${ERR} ${(err2 as Error).message}`);\n return 1;\n }\n }\n log(`${ERR} ${msg}`);\n return 1;\n }\n}\n\n// ─── entry ───────────────────────────────────────────────────────────────────\n\nexport async function main(argv: string[] = process.argv.slice(2)): Promise<number> {\n const [cmd, ...rest] = argv;\n const ctx: Ctx = {\n cwd: process.cwd(),\n args: rest,\n flags: new Set(rest.filter((a) => a.startsWith(\"--\"))),\n log: (l) => console.log(l),\n };\n switch (cmd) {\n case \"init\":\n return init(ctx);\n case \"doctor\":\n return doctor(ctx);\n case \"seed\":\n return seed(ctx);\n default:\n console.log(`nextjs-cache-handler <command>\n\nCommands:\n init [--yes] [--dry-run] [--skills] wire handlers into this Next.js app\n doctor [--url <redis-url>] connectivity + cache diagnostics\n seed [--dir .next] [--url <u>] [--namespace <ns>] [--key-prefix <p>] [--hash-tag] [--compression gzip|brotli]\n seed prerendered build output into Redis\n\nAgent setup instructions:\n https://raw.githubusercontent.com/leejpsd/nextjs-cache-handler/main/setup-instructions/setup.md`);\n return cmd ? 1 : 0;\n }\n}\n","/**\n * Client factory. Resolves a `RedisClientFactory | RedisClientConfig` to a\n * connected `RedisClientLike`, with idempotent connect.\n *\n * The factory caches the resolved client per-handler so repeated calls don't\n * spawn parallel connections. Adapter modules (`adapter-redis`,\n * `adapter-ioredis`) are lazy-imported so peer-deps you don't use stay out of\n * your bundle.\n */\n\nimport type {\n RedisClientFactory,\n RedisClientConfig,\n RedisClientLike,\n} from \"../../types.js\";\n\nexport async function buildClient(\n source: RedisClientFactory | RedisClientConfig\n): Promise<RedisClientLike> {\n if (typeof source === \"function\") {\n return await source();\n }\n switch (source.type) {\n case \"redis\": {\n const { adaptRedisV5, createRedisV5Client } = await import(\n \"./adapter-redis.js\"\n );\n return adaptRedisV5(createRedisV5Client(source));\n }\n case \"ioredis\": {\n const { adaptIoredis, createIoredisClient } = await import(\n \"./adapter-ioredis.js\"\n );\n return adaptIoredis(createIoredisClient(source));\n }\n case \"cluster\": {\n const { adaptCluster, createIoredisCluster } = await import(\n \"./adapter-ioredis.js\"\n );\n return adaptCluster(createIoredisCluster(source));\n }\n case \"sentinel\": {\n const { adaptIoredis, createIoredisSentinel } = await import(\n \"./adapter-ioredis.js\"\n );\n return adaptIoredis(createIoredisSentinel(source));\n }\n default: {\n const exhaustive: never = source;\n throw new Error(\n `[next-cache] unknown client config: ${JSON.stringify(exhaustive)}`\n );\n }\n }\n}\n\nexport interface ConnectionRetryOptions {\n /** Cooldown before the first retry after a failed connect (ms). Default 1000. */\n baseCooldownMs?: number;\n /** Upper bound for the exponential cooldown (ms). Default 30000. */\n maxCooldownMs?: number;\n}\n\n/**\n * Manage connect state without launching parallel connect calls. The reference\n * implementation's `connectPromise` pattern is preserved here.\n *\n * A failed connect does NOT latch the manager into a dead state: retries are\n * allowed after an exponential cooldown (base 1s, doubling per consecutive\n * failure, capped at 30s). During the cooldown `getOrConnect()` returns `null`\n * immediately so request paths fast-fail to the memory fallback instead of\n * queueing behind doomed connect attempts. A dropped connection (client\n * present but no longer open) is replaced with a fresh client on the next\n * call; the dead client is disposed best-effort.\n */\nexport class ConnectionManager {\n private client: RedisClientLike | null = null;\n private connecting: Promise<RedisClientLike | null> | null = null;\n private consecutiveFailures = 0;\n private lastFailureAt = 0;\n private readonly baseCooldownMs: number;\n private readonly maxCooldownMs: number;\n\n constructor(\n private readonly source: RedisClientFactory | RedisClientConfig,\n private readonly onError: (err: Error) => void,\n retry: ConnectionRetryOptions = {}\n ) {\n this.baseCooldownMs = retry.baseCooldownMs ?? 1000;\n this.maxCooldownMs = retry.maxCooldownMs ?? 30_000;\n }\n\n private cooldownMs(): number {\n if (this.consecutiveFailures === 0) return 0;\n return Math.min(\n this.maxCooldownMs,\n this.baseCooldownMs * 2 ** (this.consecutiveFailures - 1)\n );\n }\n\n async getOrConnect(): Promise<RedisClientLike | null> {\n if (this.client?.isOpen) return this.client;\n if (this.connecting) return this.connecting;\n if (Date.now() - this.lastFailureAt < this.cooldownMs()) return null;\n\n const stale = this.client;\n this.client = null;\n\n this.connecting = (async () => {\n disposeQuietly(stale);\n try {\n const c = await buildClient(this.source);\n c.on(\"error\", (err) => this.onError(err));\n if (!c.isOpen) await c.connect();\n this.client = c;\n this.consecutiveFailures = 0;\n return c;\n } catch (err) {\n this.consecutiveFailures += 1;\n this.lastFailureAt = Date.now();\n this.onError(err as Error);\n return null;\n } finally {\n this.connecting = null;\n }\n })();\n\n return this.connecting;\n }\n\n reset(): void {\n disposeQuietly(this.client);\n this.client = null;\n this.connecting = null;\n this.consecutiveFailures = 0;\n this.lastFailureAt = 0;\n }\n}\n\n/**\n * Close a replaced client so it stops reconnect loops and frees its socket.\n * The adapters expose `dispose`; raw clients passed via a factory may expose\n * `destroy` (redis@5) or `disconnect` (ioredis) instead.\n */\nfunction disposeQuietly(client: RedisClientLike | null): void {\n if (!client) return;\n const c = client as RedisClientLike & {\n destroy?: () => unknown;\n disconnect?: () => unknown;\n };\n try {\n (c.dispose ?? c.destroy ?? c.disconnect)?.call(c);\n } catch {\n // Best-effort: a client that fails to close is abandoned to GC.\n }\n}\n","/**\n * Build-output cache seeding.\n *\n * `next build` prerenders pages and fetch-cache entries into `.next/`, but a\n * fresh deployment's Redis is empty — every first request pays a full\n * regeneration (and N instances pay it N times). `seedBuildOutput()` walks\n * the build output and inserts it into Redis in the exact record format the\n * incremental handler reads, using **NX semantics**: an entry that a running\n * instance has already written (necessarily newer) is never overwritten.\n *\n * Run it once per deploy, after `next build` and before (or while) traffic\n * shifts — e.g. as a Docker entrypoint step or CI job:\n *\n * npx nextjs-cache-handler seed # uses REDIS_URL / DEPLOYMENT_VERSION\n * npx nextjs-cache-handler seed --dir .next\n *\n * Seeds:\n * - App Router routes (`.next/server/app/<route>.{html,rsc,meta}` +\n * PPR `.segments/`) → APP_PAGE records\n * - Pages Router routes (`.next/server/pages/<route>.{html,json}`) → PAGES\n * - fetch cache (`.next/cache/fetch-cache/<hash>`) → FETCH records\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { buildClient } from \"../shared/client/index.js\";\nimport { compressValue } from \"../shared/compress.js\";\nimport { buildKey, resolveBuildNamespace } from \"../shared/namespace.js\";\nimport { serializeCacheRecord } from \"../incremental/serialize.js\";\nimport type {\n Logger,\n RedisClientConfig,\n RedisClientFactory,\n RedisClientLike,\n} from \"../types.js\";\n\nconst ONE_YEAR_SEC = 60 * 60 * 24 * 365;\nconst MIN_TTL_SEC = 60;\nconst DEFAULT_KEY_PREFIX = \"next-incremental:\";\n\nexport interface SeedOptions {\n client: RedisClientFactory | RedisClientConfig;\n /** Path to the build output. Default: `./.next`. */\n dir?: string;\n keyPrefix?: string;\n buildNamespace?: string | (() => string);\n compression?: \"gzip\" | \"brotli\";\n hashTag?: boolean;\n logger?: Pick<Logger, \"warn\">;\n}\n\nexport interface SeedSummary {\n /** App Router routes written. */\n routes: number;\n /** Pages Router routes written. */\n pages: number;\n /** fetch-cache entries written. */\n fetch: number;\n /** Entries skipped because a (newer) live entry already existed (NX). */\n skippedExisting: number;\n /** Routes skipped because their files were incomplete or PPR-postponed. */\n skippedIncomplete: number;\n /** Prerendered route handlers (.body) — never seeded, by design. */\n skippedRouteHandlers: number;\n errors: string[];\n}\n\ninterface ManifestRoute {\n initialRevalidateSeconds?: number | false;\n dataRoute?: string | null;\n srcRoute?: string | null;\n}\n\nfunction clampTtl(revalidate: number | false | undefined): number {\n if (revalidate === false || revalidate === undefined) return ONE_YEAR_SEC;\n if (typeof revalidate === \"number\" && revalidate > 0) {\n return Math.min(Math.max(Math.ceil(revalidate), MIN_TTL_SEC), ONE_YEAR_SEC);\n }\n return MIN_TTL_SEC;\n}\n\nfunction routeToFileBase(route: string): string {\n return route === \"/\" ? \"/index\" : route;\n}\n\nfunction readMeta(file: string): {\n status?: number;\n headers?: Record<string, string>;\n segmentPaths?: string[];\n postponed?: string;\n} | null {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf8\")) as ReturnType<typeof readMeta>;\n } catch {\n return null;\n }\n}\n\nasync function writeRecord(\n client: RedisClientLike,\n key: string,\n value: unknown,\n revalidateSec: number | false | undefined,\n opts: Required<Pick<SeedOptions, \"keyPrefix\" | \"hashTag\">> & {\n ns: string;\n compression?: \"gzip\" | \"brotli\";\n }\n): Promise<\"written\" | \"skipped\"> {\n const record = {\n lastModified: Date.now(),\n value,\n revalidateSec: clampTtl(revalidateSec),\n };\n const redisKey = buildKey(`${opts.keyPrefix}entry:`, opts.ns, key, opts.hashTag);\n const payload = await compressValue(\n serializeCacheRecord(record),\n opts.compression\n );\n const result = await client.set(redisKey, payload, {\n EX: clampTtl(revalidateSec),\n NX: true,\n });\n // Redis returns null (nil) when NX blocks the write.\n return result === null ? \"skipped\" : \"written\";\n}\n\nexport async function seedBuildOutput(options: SeedOptions): Promise<SeedSummary> {\n const dir = path.resolve(options.dir ?? \".next\");\n const keyPrefix = options.keyPrefix ?? DEFAULT_KEY_PREFIX;\n const hashTag = options.hashTag ?? false;\n const ns = resolveBuildNamespace(options.buildNamespace);\n const warn = options.logger?.warn ?? (() => {});\n const summary: SeedSummary = {\n routes: 0,\n pages: 0,\n fetch: 0,\n skippedExisting: 0,\n skippedIncomplete: 0,\n skippedRouteHandlers: 0,\n errors: [],\n };\n\n const manifestPath = path.join(dir, \"prerender-manifest.json\");\n if (!fs.existsSync(manifestPath)) {\n throw new Error(\n `[next-cache] no prerender-manifest.json in ${dir} — run \\`next build\\` first`\n );\n }\n const manifest = JSON.parse(fs.readFileSync(manifestPath, \"utf8\")) as {\n routes?: Record<string, ManifestRoute>;\n };\n\n const client = await buildClient(options.client);\n if (!client.isOpen) await client.connect();\n\n const writeOpts = { keyPrefix, hashTag, ns, ...(options.compression ? { compression: options.compression } : {}) };\n\n try {\n // ── 1) Prerendered routes ────────────────────────────────────────────────\n for (const [route, info] of Object.entries(manifest.routes ?? {})) {\n try {\n const isPages = typeof info.dataRoute === \"string\" && info.dataRoute.endsWith(\".json\");\n const base = routeToFileBase(route);\n\n if (isPages) {\n const html = path.join(dir, \"server\", \"pages\", `${base.slice(1)}.html`);\n const data = path.join(dir, \"server\", \"pages\", `${base.slice(1)}.json`);\n if (!fs.existsSync(html)) {\n summary.skippedIncomplete += 1;\n continue;\n }\n const value = {\n kind: \"PAGES\",\n html: fs.readFileSync(html, \"utf8\"),\n pageData: fs.existsSync(data)\n ? (JSON.parse(fs.readFileSync(data, \"utf8\")) as unknown)\n : {},\n headers: undefined,\n status: undefined,\n };\n const r = await writeRecord(client, route, value, info.initialRevalidateSeconds, writeOpts);\n if (r === \"written\") summary.pages += 1;\n else summary.skippedExisting += 1;\n continue;\n }\n\n // App Router\n const htmlPath = path.join(dir, \"server\", \"app\", `${base.slice(1)}.html`);\n const rscPath = path.join(dir, \"server\", \"app\", `${base.slice(1)}.rsc`);\n const metaPath = path.join(dir, \"server\", \"app\", `${base.slice(1)}.meta`);\n if (!fs.existsSync(htmlPath) || !fs.existsSync(metaPath)) {\n // Prerendered route handlers emit .body/.meta instead of .html —\n // they are intentionally not seeded, and not \"incomplete\".\n if (fs.existsSync(path.join(dir, \"server\", \"app\", `${base.slice(1)}.body`))) {\n summary.skippedRouteHandlers += 1;\n } else {\n summary.skippedIncomplete += 1;\n }\n continue;\n }\n const meta = readMeta(metaPath) ?? {};\n if (meta.postponed) {\n // PPR routes with resume state cannot be faithfully seeded from\n // static files (the runtime needs `postponed` to resume dynamic\n // holes, and Next intentionally omits the .rsc for them). Serving\n // a seeded copy would freeze the unresolved shell as final HTML.\n summary.skippedIncomplete += 1;\n continue;\n }\n\n let segmentData: Map<string, Buffer> | undefined;\n if (Array.isArray(meta.segmentPaths) && meta.segmentPaths.length > 0) {\n const segDir = path.join(dir, \"server\", \"app\", `${base.slice(1)}.segments`);\n segmentData = new Map();\n for (const segPath of meta.segmentPaths) {\n const segFile = path.join(segDir, `${segPath.slice(1)}.segment.rsc`);\n if (fs.existsSync(segFile)) {\n segmentData.set(segPath, fs.readFileSync(segFile));\n }\n }\n if (segmentData.size !== meta.segmentPaths.length) {\n // Partial segment sets would break PPR resumes — safer to skip.\n summary.skippedIncomplete += 1;\n continue;\n }\n }\n\n const value: Record<string, unknown> = {\n kind: \"APP_PAGE\",\n html: fs.readFileSync(htmlPath, \"utf8\"),\n rscData: fs.existsSync(rscPath) ? fs.readFileSync(rscPath) : undefined,\n headers: meta.headers,\n status: meta.status,\n };\n if (segmentData) value.segmentData = segmentData;\n\n const r = await writeRecord(client, route, value, info.initialRevalidateSeconds, writeOpts);\n if (r === \"written\") summary.routes += 1;\n else summary.skippedExisting += 1;\n } catch (err) {\n summary.errors.push(`${route}: ${(err as Error).message}`);\n warn(\"seed: route failed\", { route, message: (err as Error).message });\n }\n }\n\n // ── 2) fetch cache ───────────────────────────────────────────────────────\n const fetchDir = path.join(dir, \"cache\", \"fetch-cache\");\n if (fs.existsSync(fetchDir)) {\n for (const file of fs.readdirSync(fetchDir)) {\n if (file.startsWith(\".\")) continue;\n try {\n const raw = fs.readFileSync(path.join(fetchDir, file), \"utf8\");\n const value = JSON.parse(raw) as { kind?: string; revalidate?: number };\n if (value.kind !== \"FETCH\") continue;\n const r = await writeRecord(client, file, value, value.revalidate, writeOpts);\n if (r === \"written\") summary.fetch += 1;\n else summary.skippedExisting += 1;\n } catch (err) {\n summary.errors.push(`fetch:${file}: ${(err as Error).message}`);\n }\n }\n }\n } finally {\n const c = client as RedisClientLike & {\n destroy?: () => unknown;\n disconnect?: () => unknown;\n };\n try {\n (c.dispose ?? c.destroy ?? c.disconnect)?.call(c);\n } catch {\n /* best-effort */\n }\n }\n\n return summary;\n}\n","/**\n * Transparent value compression for Redis-bound entries (node:zlib — zero\n * added dependencies).\n *\n * Storage format: `<marker><base64>` with marker `__ncgz__:` (gzip) or\n * `__ncbr__:` (brotli). Values without a marker pass through untouched, so\n * mixed caches stay readable: entries written before compression was enabled,\n * or by instances configured differently, decode fine — decompression is\n * always active regardless of the local `compression` option.\n *\n * Base64 re-inflates the compressed bytes by ~33% (our client contract is\n * string-typed), but RSC/HTML payloads are text-heavy enough that the net\n * reduction is typically 3–5×. Payloads under 1 KiB are stored uncompressed —\n * at that size marker+header overhead can exceed the savings.\n *\n * Only entry values are compressed. Tag markers and tag states are a few\n * bytes each and stay plain.\n */\n\nimport { promisify } from \"node:util\";\nimport {\n brotliCompress,\n brotliDecompress,\n constants,\n gunzip,\n gzip,\n} from \"node:zlib\";\n\nconst gzipAsync = promisify(gzip);\nconst gunzipAsync = promisify(gunzip);\nconst brotliCompressAsync = promisify(brotliCompress);\nconst brotliDecompressAsync = promisify(brotliDecompress);\n\nexport type CompressionAlgo = \"gzip\" | \"brotli\";\n\nconst GZIP_MARKER = \"__ncgz__:\";\nconst BROTLI_MARKER = \"__ncbr__:\";\nconst MIN_COMPRESS_BYTES = 1024;\n\n/**\n * Brotli's default quality (11) is tuned for static assets and is far too\n * slow for a request-path cache write. 5 compresses close to gzip speed\n * while still beating it on ratio for text.\n */\nconst BROTLI_OPTS = {\n params: { [constants.BROTLI_PARAM_QUALITY]: 5 },\n};\n\nexport async function compressValue(\n value: string,\n algo: CompressionAlgo | undefined\n): Promise<string> {\n if (!algo || Buffer.byteLength(value) < MIN_COMPRESS_BYTES) return value;\n const input = Buffer.from(value);\n if (algo === \"gzip\") {\n return GZIP_MARKER + (await gzipAsync(input)).toString(\"base64\");\n }\n return (\n BROTLI_MARKER +\n (await brotliCompressAsync(input, BROTLI_OPTS)).toString(\"base64\")\n );\n}\n\n/**\n * Marker-dispatched decompression. Unmarked values are returned as-is.\n * Throws on corrupt compressed data — callers treat that as a cache miss.\n */\nexport async function decompressValue(\n value: string | null\n): Promise<string | null> {\n if (value === null) return null;\n if (value.startsWith(GZIP_MARKER)) {\n const buf = Buffer.from(value.slice(GZIP_MARKER.length), \"base64\");\n return (await gunzipAsync(buf)).toString(\"utf8\");\n }\n if (value.startsWith(BROTLI_MARKER)) {\n const buf = Buffer.from(value.slice(BROTLI_MARKER.length), \"base64\");\n return (await brotliDecompressAsync(buf)).toString(\"utf8\");\n }\n return value;\n}\n","/**\n * Build namespace resolution.\n *\n * Why this matters: the reference implementation's \"static chunk 404\" incident\n * was caused by old prerender HTML from a previous deployment hitting in Redis.\n * Two deployments shared the same cache key prefix, so a new build's request\n * could deserialize an entry that referenced static chunks deleted by the\n * deployment swap.\n *\n * Embedding a per-deployment namespace into every entry key fixes this:\n * next-incremental:entry:<commit-sha>:<path>\n *\n * Rolling forward to a new SHA invalidates everything atomically without\n * needing a manual flush. Tags remain shared across deployments so\n * `revalidateTag()` keeps cross-deployment semantics.\n */\n\nconst FALLBACK = \"unversioned\";\n\n/**\n * Resolve the namespace value. Pure helper used at runtime when constructing\n * keys.\n */\nexport function resolveBuildNamespace(\n override?: string | (() => string)\n): string {\n if (override !== undefined) {\n return typeof override === \"function\" ? override() : override;\n }\n return (\n process.env.DEPLOYMENT_VERSION ??\n process.env.GIT_HASH ??\n process.env.NEXT_DEPLOYMENT_ID ??\n FALLBACK\n );\n}\n\n/**\n * Build a namespaced key. When `hashTag` is true, the namespace is wrapped in\n * `{}` so multi-key Lua scripts on Redis Cluster all hash to the same slot.\n *\n * Example:\n * buildKey(\"next-incremental:entry:\", \"ns42\", \"/blog/hello\", false)\n * → \"next-incremental:entry:ns42:/blog/hello\"\n * buildKey(\"next-cache:tag:\", \"ns42\", \"post-1\", true)\n * → \"next-cache:tag:{ns42}:post-1\"\n */\nexport function buildKey(\n prefix: string,\n namespace: string,\n rest: string,\n hashTag = false\n): string {\n const ns = hashTag ? `{${namespace}}` : namespace;\n return `${prefix}${ns}:${rest}`;\n}\n","/**\n * JSON serialization with Buffer / Map support for ISR cache records.\n *\n * Next.js's IncrementalCacheValue can contain Buffer (rendered HTML body) and\n * Map instances (RSC payload metadata). Plain JSON.stringify destroys both.\n *\n * The `__type` discriminator approach is borrowed from the reference handler\n * in next-redis-cache-demo. The reviver also accepts the legacy\n * `{ type: \"Buffer\", data: number[] }` shape that Node.js's default\n * Buffer.toJSON produces.\n */\n\ninterface BufferEnvelope {\n __type: \"Buffer\";\n data: string;\n}\ninterface MapEnvelope {\n __type: \"Map\";\n entries: Array<[unknown, unknown]>;\n}\ntype Envelope = BufferEnvelope | MapEnvelope;\n\nfunction isEnvelope(value: unknown): value is Envelope {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"__type\" in value &&\n typeof (value as { __type: unknown }).__type === \"string\"\n );\n}\n\ninterface LegacyBufferShape {\n type: \"Buffer\";\n data: number[];\n}\n\nfunction isLegacyBufferShape(value: unknown): value is LegacyBufferShape {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { type?: unknown }).type === \"Buffer\" &&\n Array.isArray((value as { data?: unknown }).data)\n );\n}\n\nfunction replacer(_key: string, value: unknown): unknown {\n if (Buffer.isBuffer(value)) {\n const env: BufferEnvelope = {\n __type: \"Buffer\",\n data: value.toString(\"base64\"),\n };\n return env;\n }\n if (value instanceof Map) {\n const env: MapEnvelope = {\n __type: \"Map\",\n entries: Array.from(value.entries()) as Array<[unknown, unknown]>,\n };\n return env;\n }\n return value;\n}\n\nfunction reviver(_key: string, value: unknown): unknown {\n if (isLegacyBufferShape(value)) {\n return Buffer.from(value.data);\n }\n if (!isEnvelope(value)) return value;\n if (value.__type === \"Buffer\") {\n return Buffer.from((value as BufferEnvelope).data, \"base64\");\n }\n if (value.__type === \"Map\") {\n return new Map((value as MapEnvelope).entries);\n }\n return value;\n}\n\nexport function serializeCacheRecord(record: unknown): string {\n return JSON.stringify(record, replacer);\n}\n\nexport function deserializeCacheRecord<T = unknown>(serialized: string): T | null {\n try {\n return JSON.parse(serialized, reviver) as T;\n } catch {\n return null;\n }\n}\n"]}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * `nextjs-cache-handler` CLI — agent-friendly project setup & diagnostics.
3
+ *
4
+ * Commands:
5
+ * init [--yes] [--dry-run] [--skills] wire the handlers into a Next.js app
6
+ * doctor [--url <redis-url>] connectivity + cache-state diagnostics
7
+ *
8
+ * Design constraints:
9
+ * - Zero dependencies: node builtins only. Redis access reuses the
10
+ * package's own client adapters (which lazy-load the host app's
11
+ * installed `redis`/`ioredis` peer).
12
+ * - Never destructive by default: existing files are left alone unless
13
+ * `--yes` is passed; next.config changes are shown as instructions.
14
+ * - Output is written for BOTH humans and agents: stable `[ok]/[warn]/
15
+ * [action]` prefixes that are trivial to parse.
16
+ */
17
+ interface Ctx {
18
+ cwd: string;
19
+ args: string[];
20
+ flags: Set<string>;
21
+ log: (line: string) => void;
22
+ }
23
+ declare function init(ctx: Ctx): Promise<number>;
24
+ declare function doctor(ctx: Ctx): Promise<number>;
25
+ declare function seed(ctx: Ctx): Promise<number>;
26
+ declare function main(argv?: string[]): Promise<number>;
27
+
28
+ export { doctor, init, main, seed };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * `nextjs-cache-handler` CLI — agent-friendly project setup & diagnostics.
3
+ *
4
+ * Commands:
5
+ * init [--yes] [--dry-run] [--skills] wire the handlers into a Next.js app
6
+ * doctor [--url <redis-url>] connectivity + cache-state diagnostics
7
+ *
8
+ * Design constraints:
9
+ * - Zero dependencies: node builtins only. Redis access reuses the
10
+ * package's own client adapters (which lazy-load the host app's
11
+ * installed `redis`/`ioredis` peer).
12
+ * - Never destructive by default: existing files are left alone unless
13
+ * `--yes` is passed; next.config changes are shown as instructions.
14
+ * - Output is written for BOTH humans and agents: stable `[ok]/[warn]/
15
+ * [action]` prefixes that are trivial to parse.
16
+ */
17
+ interface Ctx {
18
+ cwd: string;
19
+ args: string[];
20
+ flags: Set<string>;
21
+ log: (line: string) => void;
22
+ }
23
+ declare function init(ctx: Ctx): Promise<number>;
24
+ declare function doctor(ctx: Ctx): Promise<number>;
25
+ declare function seed(ctx: Ctx): Promise<number>;
26
+ declare function main(argv?: string[]): Promise<number>;
27
+
28
+ export { doctor, init, main, seed };