hensei-web/package.json
Justin Edmund 426645813e
Fix intermittent crash: bounded caching + HTTP timeouts/keepAlive + preview route dedupe (#428)
## Summary
- Fixes periodic production crashes (undici ECONNREFUSED ::1) by
bounding server cache size/lifetime and hardening server HTTP client.

### Root cause
- React server cache (cache(...)) held axios responses indefinitely
across many parameter combinations, causing slow memory growth until the
Next.js app router worker was OOM-killed. The main server then failed
IPC to the worker (ECONNREFUSED ::1:<port>).

### Changes
- `app/lib/data.ts`: Replace unbounded cache(...) with unstable_cache
and explicit keys; TTLs: 60s for teams/detail/favorites/user, 300s for
meta (jobs/skills/accessories/raids/version).
- `app/lib/api-utils.ts`: Add shared Axios instance with 15s timeout and
keepAlive http/https agents; apply to GET/POST/PUT/DELETE helpers.
- `pages/api/preview/[shortcode].ts`: Remove duplicate handler to dedupe
route; retain the .tsx variant using `NEXT_PUBLIC_SIERO_API_URL`.

### Notes
- Build currently has pre-existing app/pages route duplication errors;
out of scope here but unrelated to this fix.
- Ensure `NEXT_PUBLIC_SIERO_API_URL` and `NEXT_PUBLIC_SIERO_OAUTH_URL`
are set on Railway.

### Risk/impact
- Low risk; behavior is unchanged aside from bounded caching and
resilient HTTP.
- Cache TTLs can be tuned later if needed.

### Test plan
- Verify saved/teams/user pages load and revalidate after TTL.
- Validate API routes still proxy correctly; timeouts occur after ~15s
for hung upstreams.
- Monitor memory over several days; expect stable usage without steady
growth.
2025-08-31 12:16:42 -07:00

119 lines
3.9 KiB
JSON

{
"name": "grid-web",
"private": true,
"cacheDirectories": [
".next/cache"
],
"scripts": {
"dev": "next dev -p 1234",
"build": "next build",
"start": "next start",
"lint": "next lint",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"dependencies": {
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-hover-card": "^1.0.7",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-radio-group": "^1.1.3",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-slider": "^1.1.2",
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-toast": "^1.1.5",
"@radix-ui/react-toggle-group": "^1.0.4",
"@radix-ui/react-tooltip": "^1.0.7",
"@svgr/webpack": "^8.1.0",
"@tanstack/react-query": "^5.17.19",
"@tiptap/extension-bubble-menu": "^2.1.16",
"@tiptap/extension-highlight": "^2.1.16",
"@tiptap/extension-link": "^2.1.16",
"@tiptap/extension-mention": "^2.1.16",
"@tiptap/extension-placeholder": "^2.1.16",
"@tiptap/extension-typography": "^2.1.16",
"@tiptap/extension-youtube": "^2.1.16",
"@tiptap/pm": "^2.1.16",
"@tiptap/react": "^2.1.16",
"@tiptap/starter-kit": "^2.1.16",
"@tiptap/suggestion": "^2.1.16",
"@types/react-bootstrap-typeahead": "^5.1.9",
"axios": "^1.6.7",
"classnames": "^2.5.1",
"cmdk": "^0.2.1",
"cookies-next": "^4.1.0",
"date-fns": "^3.3.1",
"dompurify": "^3.0.8",
"fast-deep-equal": "^3.1.3",
"fix-date": "^1.1.6",
"i18next": "^23.7.20",
"i18next-browser-languagedetector": "^7.2.0",
"i18next-http-backend": "^2.4.2",
"local-storage": "^2.0.0",
"lodash.clonedeep": "^4.5.0",
"lodash.debounce": "^4.0.8",
"lodash.isequal": "^4.5.0",
"meyer-reset-scss": "^2.0.4",
"next": "^14.1.0",
"next-i18next": "^15.1.1",
"next-themes": "^0.2.1",
"nuqs": "^1.15.4",
"pluralize": "^8.0.0",
"react": "^18.2.0",
"react-bootstrap-typeahead": "^6.3.2",
"react-dom": "^18.2.0",
"react-i18next": "^14.0.1",
"react-infinite-scroll-component": "^6.1.0",
"react-linkify": "^1.0.0-alpha",
"react-lite-youtube-embed": "^2.4.0",
"react-scroll": "^1.9.0",
"react-string-replace": "^1.1.1",
"react-use": "^17.4.2",
"remixicon-react": "^1.0.0",
"sanitize-html": "^2.11.0",
"sass": "^1.69.7",
"tippy.js": "^6.3.7",
"usehooks-ts": "^2.9.1",
"uuid": "^9.0.1",
"valtio": "^1.13.0",
"youtube-api-v3-wrapper": "^2.3.0",
"zod": "^3.22.4"
},
"devDependencies": {
"@storybook/addon-essentials": "latest",
"@storybook/addon-interactions": "latest",
"@storybook/addon-links": "latest",
"@storybook/addon-mdx-gfm": "latest",
"@storybook/addon-styling": "latest",
"@storybook/blocks": "latest",
"@storybook/nextjs": "latest",
"@storybook/react": "latest",
"@storybook/testing-library": "latest",
"@types/dompurify": "^3.0.5",
"@types/lodash.clonedeep": "^4.5.9",
"@types/lodash.debounce": "^4.0.9",
"@types/node": "20.11.5",
"@types/pluralize": "^0.0.33",
"@types/react": "18.2.48",
"@types/react-dom": "18.2.18",
"@types/react-infinite-scroller": "^1.2.5",
"@types/react-linkify": "^1.0.4",
"@types/react-scroll": "^1.8.10",
"@types/sanitize-html": "^2.9.5",
"@types/uuid": "^9.0.7",
"eslint": "8.56.0",
"eslint-config-next": "14.1.0",
"eslint-plugin-storybook": "^0.6.15",
"eslint-plugin-valtio": "^0.6.2",
"sass-loader": "^13.3.3",
"storybook": "latest",
"typescript": "5.3.3"
},
"overrides": {
"@tiptap/extension-mention": {
"@tiptap/suggestion": "^2.1.16"
}
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}