diff --git a/app/(docs)/@chat/chat/[chatId]/page.tsx b/app/(docs)/@chat/chat/[chatId]/page.tsx index 35462ced..8f5d1fd9 100644 --- a/app/(docs)/@chat/chat/[chatId]/page.tsx +++ b/app/(docs)/@chat/chat/[chatId]/page.tsx @@ -6,7 +6,7 @@ import { } from "@/lib/chatHistory"; import { getMarkdownSections, getPagesList } from "@/lib/docs"; import { ChatAreaContainer, ChatAreaContent } from "./chatArea"; -import { unstable_cacheLife, unstable_cacheTag } from "next/cache"; +import { cacheLife, cacheTag } from "next/cache"; import { isCloudflare } from "@/lib/detectCloudflare"; export default async function ChatPage({ @@ -56,8 +56,8 @@ export default async function ChatPage({ async function getChatOneFromCache(chatId: string, userId?: string) { "use cache"; - unstable_cacheLife("days"); - unstable_cacheTag(cacheKeyForChat(chatId)); + cacheLife("days"); + cacheTag(cacheKeyForChat(chatId)); if (!userId) { return null; diff --git a/app/(docs)/@docs/[lang]/[pageId]/page.tsx b/app/(docs)/@docs/[lang]/[pageId]/page.tsx index cd825e8c..b1be47b8 100644 --- a/app/(docs)/@docs/[lang]/[pageId]/page.tsx +++ b/app/(docs)/@docs/[lang]/[pageId]/page.tsx @@ -14,7 +14,7 @@ import { PagePath, PageSlug, } from "@/lib/docs"; -import { unstable_cacheLife, unstable_cacheTag } from "next/cache"; +import { cacheLife, cacheTag } from "next/cache"; import { isCloudflare } from "@/lib/detectCloudflare"; import { DocsAutoRedirect } from "./autoRedirect"; @@ -83,12 +83,12 @@ async function getChatFromCache(path: PagePath, userId?: string) { // 一方、use cacheの関数内でheaders()にはアクセスできない。 // したがって、外でheaders()を使ってuserIdを取得した後、関数の中で再度drizzleを初期化しないといけない。 "use cache"; - unstable_cacheLife("days"); + cacheLife("days"); if (!userId) { return []; } - unstable_cacheTag(cacheKeyForPage(path, userId)); + cacheTag(cacheKeyForPage(path, userId)); if (isCloudflare()) { const cache = await caches.open("chatHistory"); diff --git a/app/(docs)/@docs/[lang]/[pageId]/pageContent.tsx b/app/(docs)/@docs/[lang]/[pageId]/pageContent.tsx index fe075476..007c75a9 100644 --- a/app/(docs)/@docs/[lang]/[pageId]/pageContent.tsx +++ b/app/(docs)/@docs/[lang]/[pageId]/pageContent.tsx @@ -1,6 +1,6 @@ "use client"; -import { Fragment, useCallback, useEffect, useRef, useState } from "react"; +import { Fragment, useEffect, useMemo, useRef, useState } from "react"; import { ChatForm } from "./chatForm"; import { StyledMarkdown } from "@/markdown/markdown"; import { useSidebarMdContext } from "@/sidebar"; @@ -32,11 +32,41 @@ export function PageContent(props: PageContentProps) { const { setSidebarMdContent } = useSidebarMdContext(); const { splitMdContent, pageEntry, path, chatHistories } = props; - const initDynamicMdContent = useCallback(() => { + const [sectionInView, setSectionInView] = useState([]); + const sectionRefs = useRef>([]); + useEffect(() => { + const handleScroll = () => { + setSectionInView((sectionInView) => { + sectionInView = sectionInView.slice(); // Reactの変更検知のために新しい配列を作成 + for ( + let i = 0; + i < sectionRefs.current.length || i < sectionInView.length; + i++ + ) { + if (sectionRefs.current.at(i)) { + const rect = sectionRefs.current.at(i)!.getBoundingClientRect(); + sectionInView[i] = + rect.top < window.innerHeight * 0.9 && + rect.bottom >= window.innerHeight * 0.1; + } else { + sectionInView[i] = false; + } + } + return sectionInView; + }); + }; + window.addEventListener("scroll", handleScroll); + handleScroll(); + return () => { + window.removeEventListener("scroll", handleScroll); + }; + }, []); + + const dynamicMdContent = useMemo(() => { const newContent: DynamicMarkdownSection[] = splitMdContent.map( - (section) => ({ + (section, i) => ({ ...section, - inView: false, + inView: sectionInView[i], replacedContent: section.rawContent, replacedRange: [], }) @@ -94,54 +124,13 @@ export function PageContent(props: PageContentProps) { } return newContent; - }, [splitMdContent, chatHistories]); - - // SSR用のローカルstate - const [dynamicMdContent, setDynamicMdContent] = useState< - DynamicMarkdownSection[] - >(() => initDynamicMdContent()); + }, [splitMdContent, chatHistories, sectionInView]); useEffect(() => { // props.splitMdContentが変わったとき, チャットのdiffが変わった時に - // ローカルstateとcontextの両方を更新 - const newContent = initDynamicMdContent(); - setDynamicMdContent(newContent); - setSidebarMdContent(path, newContent); - }, [initDynamicMdContent, path, setSidebarMdContent]); - - const sectionRefs = useRef>([]); - // sectionRefsの長さをsplitMdContentに合わせる - while (sectionRefs.current.length < props.splitMdContent.length) { - sectionRefs.current.push(null); - } - - useEffect(() => { - const handleScroll = () => { - const updateContent = ( - prevDynamicMdContent: DynamicMarkdownSection[] - ) => { - const dynMdContent = prevDynamicMdContent.slice(); // Reactの変更検知のために新しい配列を作成 - for (let i = 0; i < sectionRefs.current.length; i++) { - if (sectionRefs.current.at(i) && dynMdContent.at(i)) { - const rect = sectionRefs.current.at(i)!.getBoundingClientRect(); - dynMdContent.at(i)!.inView = - rect.top < window.innerHeight * 0.9 && - rect.bottom >= window.innerHeight * 0.1; - } - } - return dynMdContent; - }; - - // ローカルstateとcontextの両方を更新 - setDynamicMdContent(updateContent); - setSidebarMdContent(path, updateContent); - }; - window.addEventListener("scroll", handleScroll); - handleScroll(); - return () => { - window.removeEventListener("scroll", handleScroll); - }; - }, [setSidebarMdContent, path]); + // sidebarのcontextを更新 + setSidebarMdContent(path, dynamicMdContent); + }, [dynamicMdContent, path, setSidebarMdContent]); const [isFormVisible, setIsFormVisible] = useState(false); diff --git a/app/lib/chatHistory.ts b/app/lib/chatHistory.ts index e1392102..2158941f 100644 --- a/app/lib/chatHistory.ts +++ b/app/lib/chatHistory.ts @@ -4,7 +4,7 @@ import { getDrizzle } from "./drizzle"; import { chat, diff, message, section } from "@/schema/chat"; import { and, asc, eq, exists } from "drizzle-orm"; import { Auth } from "better-auth"; -import { revalidateTag } from "next/cache"; +import { updateTag } from "next/cache"; import { isCloudflare } from "./detectCloudflare"; import { getPagesList, LangId, PagePath, PageSlug, SectionId } from "./docs"; @@ -31,7 +31,6 @@ export function cacheKeyForChat(chatId: string) { // nextjsのキャッシュのrevalidateはRouteHandlerではなくServerActionから呼ばないと正しく動作しないらしい。 // https://github.com/vercel/next.js/issues/69064 // そのためlib/以下の関数では直接revalidateChatを呼ばず、ServerActionの関数から呼ぶようにする。 -// Nextjs 16 に更新したらこれをupdateTag()で置き換える。 export async function revalidateChat( chatId: string, userId: string, @@ -41,8 +40,8 @@ export async function revalidateChat( const [lang, page] = pagePath.split("/") as [LangId, PageSlug]; pagePath = { lang, page }; } - revalidateTag(cacheKeyForChat(chatId)); - revalidateTag(cacheKeyForPage(pagePath, userId)); + updateTag(cacheKeyForChat(chatId)); + updateTag(cacheKeyForPage(pagePath, userId)); if (isCloudflare()) { const cache = await caches.open("chatHistory"); await cache.delete(cacheKeyForChat(chatId)); @@ -283,7 +282,7 @@ export async function migrateChatUser(oldUserId: string, newUserId: string) { const pagesList = await getPagesList(); for (const lang of pagesList) { for (const page of lang.pages) { - revalidateTag( + updateTag( cacheKeyForPage({ lang: lang.id, page: page.slug }, newUserId) ); } diff --git a/app/lib/clientOnly.ts b/app/lib/clientOnly.ts new file mode 100644 index 00000000..3e9515e9 --- /dev/null +++ b/app/lib/clientOnly.ts @@ -0,0 +1,12 @@ +"use client"; + +import { useSyncExternalStore } from "react"; + +// --- SSR無効化のためのカスタムフック準備 --- +const subscribe = () => () => {}; +const getSnapshot = () => true; // クライアントでは true +const getServerSnapshot = () => false; // サーバーでは false + +export function useIsClient() { + return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); +} diff --git a/app/markdown/styledSyntaxHighlighter.tsx b/app/markdown/styledSyntaxHighlighter.tsx index 6203c561..6bfd7f46 100644 --- a/app/markdown/styledSyntaxHighlighter.tsx +++ b/app/markdown/styledSyntaxHighlighter.tsx @@ -5,9 +5,10 @@ import { tomorrow, tomorrowNight, } from "react-syntax-highlighter/dist/esm/styles/hljs"; -import { lazy, Suspense, useEffect, useState } from "react"; +import { lazy, Suspense } from "react"; import { LangConstants } from "@my-code/runtime/languages"; import clsx from "clsx"; +import { useIsClient } from "@/lib/clientOnly"; // SyntaxHighlighterはファイルサイズがでかいので & HydrationErrorを起こすので、SSRを無効化する const SyntaxHighlighter = lazy(() => { @@ -24,11 +25,8 @@ export function StyledSyntaxHighlighter(props: { }) { const theme = useChangeTheme(); const codetheme = theme === "tomorrow" ? tomorrow : tomorrowNight; - const [initHighlighter, setInitHighlighter] = useState(false); - useEffect(() => { - setInitHighlighter(true); - }, []); - return initHighlighter ? ( + const isClient = useIsClient(); + return isClient ? ( {props.children}}> ([]); - const currentLangIndex = pagesList.findIndex( - (group) => currentLang === group.id - ); - useEffect(() => { - // 表示しているグループが変わったときに現在のグループのdetailsを開く - if (currentLangIndex !== -1) { - setDetailsOpen((detailsOpen) => { - const newDetailsOpen = [...detailsOpen]; - while (newDetailsOpen.length <= currentLangIndex) { - newDetailsOpen.push(false); - } - newDetailsOpen[currentLangIndex] = true; - return newDetailsOpen; - }); - } - }, [currentLangIndex]); + const [prevLangIndex, setPrevLangIndex] = useState(-1); + const langIndex = pagesList.findIndex((group) => currentLang === group.id); + // 表示しているグループが変わったときに現在のグループのdetailsを開く + if (prevLangIndex !== langIndex) { + setPrevLangIndex(langIndex); + setDetailsOpen((detailsOpen) => { + const newDetailsOpen = [...detailsOpen]; + newDetailsOpen[langIndex] = true; + return newDetailsOpen; + }); + } return (
diff --git a/app/terminal/embedContext.tsx b/app/terminal/embedContext.tsx index 4f4fc8d3..1c3eaadb 100644 --- a/app/terminal/embedContext.tsx +++ b/app/terminal/embedContext.tsx @@ -7,7 +7,6 @@ import { ReactNode, useCallback, useContext, - useEffect, useState, } from "react"; @@ -58,7 +57,7 @@ export function useEmbedContext() { export function EmbedContextProvider({ children }: { children: ReactNode }) { const pathname = usePathname(); - const [currentPathname, setCurrentPathname] = useState(""); + const [prevPathname, setPrevPathname] = useState(""); const [files, setFiles] = useState< Record> >({}); @@ -72,15 +71,12 @@ export function EmbedContextProvider({ children }: { children: ReactNode }) { const [execResults, setExecResults] = useState< Record >({}); - // pathnameが変わったらデータを初期化 - useEffect(() => { - if (pathname && pathname !== currentPathname) { - setCurrentPathname(pathname); - setReplOutputs({}); - setCommandIdCounters({}); - setExecResults({}); - } - }, [pathname, currentPathname]); + if (pathname && pathname !== prevPathname) { + setPrevPathname(pathname); + setReplOutputs({}); + setCommandIdCounters({}); + setExecResults({}); + } const writeFile = useCallback( (updatedFiles: Record) => { diff --git a/app/terminal/exec.tsx b/app/terminal/exec.tsx index a2bc1cc6..89b63870 100644 --- a/app/terminal/exec.tsx +++ b/app/terminal/exec.tsx @@ -77,8 +77,8 @@ export function ExecFile(props: ExecProps) { >("idle"); useEffect(() => { if (executionState === "triggered" && ready) { - setExecutionState("executing"); (async () => { + setExecutionState("executing"); clearTerminal(terminalInstanceRef.current!); terminalInstanceRef.current!.write(systemMessageColor("実行中です...")); // TODO: 1つのファイル名しか受け付けないところに無理やりコンマ区切りで全部のファイル名を突っ込んでいる diff --git a/app/terminal/page.tsx b/app/terminal/page.tsx index fc9f4741..17c65a0e 100644 --- a/app/terminal/page.tsx +++ b/app/terminal/page.tsx @@ -2,7 +2,7 @@ import { Heading } from "@/markdown/heading"; import "mocha/mocha.css"; -import { Fragment, useEffect, useState } from "react"; +import { Fragment, useEffect, useRef, useState } from "react"; import { langConstants, RuntimeLang } from "@my-code/runtime/languages"; import { ReplTerminal } from "./repl"; import { EditorComponent } from "./editor"; @@ -202,7 +202,11 @@ function AnsiColorSample() { } function MochaTest() { - const runtimeRef = useRuntimeAll(); + const runtimeAll = useRuntimeAll(); + const runtimeRef = useRef(runtimeAll); + for (const lang of Object.keys(runtimeAll) as RuntimeLang[]) { + runtimeRef.current[lang] = runtimeAll[lang]; + } const [searchParams, setSearchParams] = useState(""); useEffect(() => { diff --git a/eslint.config.mjs b/eslint.config.mjs index ead83e30..74b56a0a 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,17 +1,22 @@ -import { dirname } from "path"; -import { fileURLToPath } from "url"; -import { FlatCompat } from "@eslint/eslintrc"; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); - -const compat = new FlatCompat({ - baseDirectory: __dirname, -}); +import nextCoreWebVitals from "eslint-config-next/core-web-vitals"; +import nextTypescript from "eslint-config-next/typescript"; +import reactHooks from "eslint-plugin-react-hooks"; const eslintConfig = [ - ...compat.config({ - extends: ["next/core-web-vitals", "next/typescript"], + { + ignores: [ + ".next/**", + ".open-next/**", + ".wrangler/**", + "node_modules/**", + "public/**", + "cloudflare-env.d.ts", + ], + }, + ...nextCoreWebVitals, + ...nextTypescript, + { + plugins: { "react-hooks": reactHooks }, rules: { // Next.jsのデフォルト設定を上書き "@typescript-eslint/no-unused-vars": [ @@ -23,7 +28,7 @@ const eslintConfig = [ }, ], }, - }), + }, ]; export default eslintConfig; diff --git a/next.config.ts b/next.config.ts index 724528dc..5c237c16 100644 --- a/next.config.ts +++ b/next.config.ts @@ -11,9 +11,6 @@ const nextConfig: NextConfig = { experimental: { useCache: true, }, - eslint: { - ignoreDuringBuilds: true, - }, typescript: { ignoreBuildErrors: true, }, @@ -45,7 +42,7 @@ const nextConfig: NextConfig = { }, ]; }, - webpack: (config, { isServer }) => { + webpack: (config) => { config.plugins.push( new PyodidePlugin({ // public/ 以下に書き出すと404 diff --git a/package-lock.json b/package-lock.json index 7e70b1c7..3436ca10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@fontsource-variable/inconsolata": "^5.2.7", "@fontsource/m-plus-rounded-1c": "^5.2.9", "@google/genai": "^1.21.0", - "@opennextjs/cloudflare": "^1.16.1", + "@opennextjs/cloudflare": "^1.18.0", "@xterm/addon-fit": "^0.11.0", "@xterm/xterm": "^6.1.0-beta.168", "ace-builds": "^1.43.2", @@ -25,7 +25,7 @@ "drizzle-orm": "^0.44.7", "js-yaml": "^4.1.1", "mocha": "^11.7.4", - "next": "^15.5.14", + "next": "^16.2.1", "pg": "^8.16.3", "prismjs": "^1.30.0", "react": "^19", @@ -41,7 +41,6 @@ "zod": "^4.0.17" }, "devDependencies": { - "@eslint/eslintrc": "^3", "@pyodide/webpack-plugin": "^1.4.0", "@tailwindcss/postcss": "^4", "@types/js-yaml": "^4.0.9", @@ -57,7 +56,7 @@ "daisyui": "^5.5.5", "drizzle-kit": "^0.31.5", "eslint": "^9", - "eslint-config-next": "^15.5.14", + "eslint-config-next": "^16.2.1", "fonteditor-core": "^2.6.3", "pako": "^2.1.0", "prettier": "^3.6.2", @@ -3585,15 +3584,15 @@ } }, "node_modules/@next/env": { - "version": "15.5.14", - "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.14.tgz", - "integrity": "sha512-aXeirLYuASxEgi4X4WhfXsShCFxWDfNn/8ZeC5YXAS2BB4A8FJi1kwwGL6nvMVboE7fZCzmJPNdMvVHc8JpaiA==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.1.tgz", + "integrity": "sha512-n8P/HCkIWW+gVal2Z8XqXJ6aB3J0tuM29OcHpCsobWlChH/SITBs1DFBk/HajgrwDkqqBXPbuUuzgDvUekREPg==", "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { - "version": "15.5.14", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.5.14.tgz", - "integrity": "sha512-ogBjgsFrPPz19abP3VwcYSahbkUOMMvJjxCOYWYndw+PydeMuLuB4XrvNkNutFrTjC9St2KFULRdKID8Sd/CMQ==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.2.1.tgz", + "integrity": "sha512-r0epZGo24eT4g08jJlg2OEryBphXqO8aL18oajoTKLzHJ6jVr6P6FI58DLMug04MwD3j8Fj0YK0slyzneKVyzA==", "dev": true, "license": "MIT", "dependencies": { @@ -3601,9 +3600,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "15.5.14", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.14.tgz", - "integrity": "sha512-Y9K6SPzobnZvrRDPO2s0grgzC+Egf0CqfbdvYmQVaztV890zicw8Z8+4Vqw8oPck8r1TjUHxVh8299Cg4TrxXg==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.1.tgz", + "integrity": "sha512-BwZ8w8YTaSEr2HIuXLMLxIdElNMPvY9fLqb20LX9A9OMGtJilhHLbCL3ggyd0TwjmMcTxi0XXt+ur1vWUoxj2Q==", "cpu": [ "arm64" ], @@ -3617,9 +3616,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "15.5.14", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.14.tgz", - "integrity": "sha512-aNnkSMjSFRTOmkd7qoNI2/rETQm/vKD6c/Ac9BZGa9CtoOzy3c2njgz7LvebQJ8iPxdeTuGnAjagyis8a9ifBw==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.1.tgz", + "integrity": "sha512-/vrcE6iQSJq3uL3VGVHiXeaKbn8Es10DGTGRJnRZlkNQQk3kaNtAJg8Y6xuAlrx/6INKVjkfi5rY0iEXorZ6uA==", "cpu": [ "x64" ], @@ -3633,9 +3632,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "15.5.14", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.14.tgz", - "integrity": "sha512-tjlpia+yStPRS//6sdmlVwuO1Rioern4u2onafa5n+h2hCS9MAvMXqpVbSrjgiEOoCs0nJy7oPOmWgtRRNSM5Q==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.1.tgz", + "integrity": "sha512-uLn+0BK+C31LTVbQ/QU+UaVrV0rRSJQ8RfniQAHPghDdgE+SlroYqcmFnO5iNjNfVWCyKZHYrs3Nl0mUzWxbBw==", "cpu": [ "arm64" ], @@ -3649,9 +3648,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "15.5.14", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.14.tgz", - "integrity": "sha512-8B8cngBaLadl5lbDRdxGCP1Lef8ipD6KlxS3v0ElDAGil6lafrAM3B258p1KJOglInCVFUjk751IXMr2ixeQOQ==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.1.tgz", + "integrity": "sha512-ssKq6iMRnHdnycGp9hCuGnXJZ0YPr4/wNwrfE5DbmvEcgl9+yv97/Kq3TPVDfYome1SW5geciLB9aiEqKXQjlQ==", "cpu": [ "arm64" ], @@ -3665,9 +3664,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.5.14", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.14.tgz", - "integrity": "sha512-bAS6tIAg8u4Gn3Nz7fCPpSoKAexEt2d5vn1mzokcqdqyov6ZJ6gu6GdF9l8ORFrBuRHgv3go/RfzYz5BkZ6YSQ==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.1.tgz", + "integrity": "sha512-HQm7SrHRELJ30T1TSmT706IWovFFSRGxfgUkyWJZF/RKBMdbdRWJuFrcpDdE5vy9UXjFOx6L3mRdqH04Mmx0hg==", "cpu": [ "x64" ], @@ -3681,9 +3680,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "15.5.14", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.14.tgz", - "integrity": "sha512-mMxv/FcrT7Gfaq4tsR22l17oKWXZmH/lVqcvjX0kfp5I0lKodHYLICKPoX1KRnnE+ci6oIUdriUhuA3rBCDiSw==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.1.tgz", + "integrity": "sha512-aV2iUaC/5HGEpbBkE+4B8aHIudoOy5DYekAKOMSHoIYQ66y/wIVeaRx8MS2ZMdxe/HIXlMho4ubdZs/J8441Tg==", "cpu": [ "x64" ], @@ -3697,9 +3696,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "15.5.14", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.14.tgz", - "integrity": "sha512-OTmiBlYThppnvnsqx0rBqjDRemlmIeZ8/o4zI7veaXoeO1PVHoyj2lfTfXTiiGjCyRDhA10y4h6ZvZvBiynr2g==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.1.tgz", + "integrity": "sha512-IXdNgiDHaSk0ZUJ+xp0OQTdTgnpx1RCfRTalhn3cjOP+IddTMINwA7DXZrwTmGDO8SUr5q2hdP/du4DcrB1GxA==", "cpu": [ "arm64" ], @@ -3713,9 +3712,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "15.5.14", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.14.tgz", - "integrity": "sha512-+W7eFf3RS7m4G6tppVTOSyP9Y6FsJXfOuKzav1qKniiFm3KFByQfPEcouHdjlZmysl4zJGuGLQ/M9XyVeyeNEg==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.1.tgz", + "integrity": "sha512-qvU+3a39Hay+ieIztkGSbF7+mccbbg1Tk25hc4JDylf8IHjYmY/Zm64Qq1602yPyQqvie+vf5T/uPwNxDNIoeg==", "cpu": [ "x64" ], @@ -3981,9 +3980,9 @@ } }, "node_modules/@opennextjs/cloudflare": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@opennextjs/cloudflare/-/cloudflare-1.17.1.tgz", - "integrity": "sha512-TtmjhXUEpSbnb9kgr7IQtmlQugOeX0cHiLc/e6NYAnmqQVro3yN49WvzaclSGFZod/lJFW7pOJ0NGT6JpqypAw==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@opennextjs/cloudflare/-/cloudflare-1.18.0.tgz", + "integrity": "sha512-JM236YHnKzroFAZqst1t28ZGOShvnkVUDtjrp7TJ/W2P3RLo4b6npJ8VEXOn6frs6lsUfR5rvsKYLYb7h1GIJQ==", "license": "MIT", "dependencies": { "@ast-grep/napi": "^0.40.5", @@ -5215,13 +5214,6 @@ "tslib": "^2.8.1" } }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.16.1.tgz", - "integrity": "sha512-TvZbIpeKqGQQ7X0zSCvPH9riMSFQFSggnfBjFZ1mEoILW+UuXCKwOoPcgjMwiUtRqFZ8jWhPJc4um14vC6I4ag==", - "dev": true, - "license": "MIT" - }, "node_modules/@sindresorhus/is": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz", @@ -6641,17 +6633,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.1.tgz", - "integrity": "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.2.tgz", + "integrity": "sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.56.1", - "@typescript-eslint/type-utils": "8.56.1", - "@typescript-eslint/utils": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/type-utils": "8.57.2", + "@typescript-eslint/utils": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -6664,7 +6656,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.56.1", + "@typescript-eslint/parser": "^8.57.2", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } @@ -6680,16 +6672,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.1.tgz", - "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.2.tgz", + "integrity": "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.56.1", - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/typescript-estree": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3" }, "engines": { @@ -6705,14 +6697,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", - "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.2.tgz", + "integrity": "sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.56.1", - "@typescript-eslint/types": "^8.56.1", + "@typescript-eslint/tsconfig-utils": "^8.57.2", + "@typescript-eslint/types": "^8.57.2", "debug": "^4.4.3" }, "engines": { @@ -6727,14 +6719,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", - "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.2.tgz", + "integrity": "sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1" + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6745,9 +6737,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", - "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.2.tgz", + "integrity": "sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==", "dev": true, "license": "MIT", "engines": { @@ -6762,15 +6754,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.1.tgz", - "integrity": "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.2.tgz", + "integrity": "sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/typescript-estree": "8.56.1", - "@typescript-eslint/utils": "8.56.1", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/utils": "8.57.2", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -6787,9 +6779,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", - "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.2.tgz", + "integrity": "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==", "dev": true, "license": "MIT", "engines": { @@ -6801,16 +6793,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", - "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.2.tgz", + "integrity": "sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.56.1", - "@typescript-eslint/tsconfig-utils": "8.56.1", - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1", + "@typescript-eslint/project-service": "8.57.2", + "@typescript-eslint/tsconfig-utils": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -6839,9 +6831,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6881,16 +6873,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", - "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.2.tgz", + "integrity": "sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.56.1", - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/typescript-estree": "8.56.1" + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6905,13 +6897,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", - "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.2.tgz", + "integrity": "sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/types": "8.57.2", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -8840,7 +8832,6 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", - "dev": true, "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.cjs" @@ -11025,25 +11016,24 @@ } }, "node_modules/eslint-config-next": { - "version": "15.5.14", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.5.14.tgz", - "integrity": "sha512-lmJ5F8ZgOYogq0qtH4L5SpxuASY2SPdOzqUprN2/56+P3GPsIpXaUWIJC66kYIH+yZdsM4nkHE5MIBP6s1NiBw==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.2.1.tgz", + "integrity": "sha512-qhabwjQZ1Mk53XzXvmogf8KQ0tG0CQXF0CZ56+2/lVhmObgmaqj7x5A1DSrWdZd3kwI7GTPGUjFne+krRxYmFg==", "dev": true, "license": "MIT", "dependencies": { - "@next/eslint-plugin-next": "15.5.14", - "@rushstack/eslint-patch": "^1.10.3", - "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", - "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "@next/eslint-plugin-next": "16.2.1", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", - "eslint-plugin-import": "^2.31.0", + "eslint-plugin-import": "^2.32.0", "eslint-plugin-jsx-a11y": "^6.10.0", "eslint-plugin-react": "^7.37.0", - "eslint-plugin-react-hooks": "^5.0.0" + "eslint-plugin-react-hooks": "^7.0.0", + "globals": "16.4.0", + "typescript-eslint": "^8.46.0" }, "peerDependencies": { - "eslint": "^7.23.0 || ^8.0.0 || ^9.0.0", + "eslint": ">=9.0.0", "typescript": ">=3.3.1" }, "peerDependenciesMeta": { @@ -11052,6 +11042,19 @@ } } }, + "node_modules/eslint-config-next/node_modules/globals": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", + "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", @@ -11255,13 +11258,20 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", - "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz", + "integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, "engines": { - "node": ">=10" + "node": ">=18" }, "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" @@ -12753,6 +12763,23 @@ "he": "bin/he" } }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, "node_modules/highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", @@ -15427,9 +15454,9 @@ } }, "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -16041,13 +16068,14 @@ } }, "node_modules/next": { - "version": "15.5.14", - "resolved": "https://registry.npmjs.org/next/-/next-15.5.14.tgz", - "integrity": "sha512-M6S+4JyRjmKic2Ssm7jHUPkE6YUJ6lv4507jprsSZLulubz0ihO2E+S4zmQK3JZ2ov81JrugukKU4Tz0ivgqqQ==", + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/next/-/next-16.2.1.tgz", + "integrity": "sha512-VaChzNL7o9rbfdt60HUj8tev4m6d7iC1igAy157526+cJlXOQu5LzsBXNT+xaJnTP/k+utSX5vMv7m0G+zKH+Q==", "license": "MIT", "dependencies": { - "@next/env": "15.5.14", + "@next/env": "16.2.1", "@swc/helpers": "0.5.15", + "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" @@ -16056,18 +16084,18 @@ "next": "dist/bin/next" }, "engines": { - "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" + "node": ">=20.9.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "15.5.14", - "@next/swc-darwin-x64": "15.5.14", - "@next/swc-linux-arm64-gnu": "15.5.14", - "@next/swc-linux-arm64-musl": "15.5.14", - "@next/swc-linux-x64-gnu": "15.5.14", - "@next/swc-linux-x64-musl": "15.5.14", - "@next/swc-win32-arm64-msvc": "15.5.14", - "@next/swc-win32-x64-msvc": "15.5.14", - "sharp": "^0.34.3" + "@next/swc-darwin-arm64": "16.2.1", + "@next/swc-darwin-x64": "16.2.1", + "@next/swc-linux-arm64-gnu": "16.2.1", + "@next/swc-linux-arm64-musl": "16.2.1", + "@next/swc-linux-x64-gnu": "16.2.1", + "@next/swc-linux-x64-musl": "16.2.1", + "@next/swc-win32-arm64-msvc": "16.2.1", + "@next/swc-win32-x64-msvc": "16.2.1", + "sharp": "^0.34.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -19379,9 +19407,9 @@ } }, "node_modules/ts-api-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", - "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "dev": true, "license": "MIT", "engines": { @@ -20065,6 +20093,30 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.57.2.tgz", + "integrity": "sha512-VEPQ0iPgWO/sBaZOU1xo4nuNdODVOajPnTIbog2GKYr31nIlZ0fWPoCQgGfF3ETyBl1vn63F/p50Um9Z4J8O8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.57.2", + "@typescript-eslint/parser": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/utils": "8.57.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", @@ -22283,6 +22335,19 @@ "url": "https://github.com/sponsors/colinhacks" } }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index 0ad1f539..e26cec42 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,10 @@ ], "scripts": { "prebuild": "npm run cf-typegen && tsx ./scripts/checkDocs.ts && tsx ./scripts/generateDocsMeta.ts && tsx ./scripts/copyAllDTSFiles.ts && tsx ./scripts/removeHinting.ts", - "dev": "npm run prebuild && next dev", - "build": "next build", + "dev": "npm run prebuild && next dev --webpack", + "build": "next build --webpack", "start": "next start", - "lint": "npm run cf-typegen && next lint", + "lint": "npm run cf-typegen && eslint .", "tsc": "npm run cf-typegen && tsc", "format": "prettier --write app/ packages/", "db-migrate": "drizzle-kit migrate", @@ -25,7 +25,7 @@ "@fontsource-variable/inconsolata": "^5.2.7", "@fontsource/m-plus-rounded-1c": "^5.2.9", "@google/genai": "^1.21.0", - "@opennextjs/cloudflare": "^1.16.1", + "@opennextjs/cloudflare": "^1.18.0", "@xterm/addon-fit": "^0.11.0", "@xterm/xterm": "^6.1.0-beta.168", "ace-builds": "^1.43.2", @@ -36,7 +36,7 @@ "drizzle-orm": "^0.44.7", "js-yaml": "^4.1.1", "mocha": "^11.7.4", - "next": "^15.5.14", + "next": "^16.2.1", "pg": "^8.16.3", "prismjs": "^1.30.0", "react": "^19", @@ -52,7 +52,6 @@ "zod": "^4.0.17" }, "devDependencies": { - "@eslint/eslintrc": "^3", "@pyodide/webpack-plugin": "^1.4.0", "@tailwindcss/postcss": "^4", "@types/js-yaml": "^4.0.9", @@ -68,7 +67,7 @@ "daisyui": "^5.5.5", "drizzle-kit": "^0.31.5", "eslint": "^9", - "eslint-config-next": "^15.5.14", + "eslint-config-next": "^16.2.1", "fonteditor-core": "^2.6.3", "pako": "^2.1.0", "prettier": "^3.6.2", diff --git a/packages/runtime/src/context.tsx b/packages/runtime/src/context.tsx index 6351e341..a83f96bb 100644 --- a/packages/runtime/src/context.tsx +++ b/packages/runtime/src/context.tsx @@ -1,6 +1,6 @@ "use client"; -import { ReactNode, RefObject, useEffect, useRef } from "react"; +import { ReactNode, useEffect } from "react"; import { RuntimeContext } from "./interface"; import { RuntimeLang } from "./languages"; import { TypeScriptProvider, useTypeScript } from "./typescript/runtime"; @@ -12,14 +12,14 @@ import { WorkerProvider } from "./worker/runtime"; export function useRuntime(language: RuntimeLang): RuntimeContext { const runtimes = useRuntimeAll(); - const runtime = runtimes.current[language]; + const runtime = runtimes[language]; const { init } = runtime; useEffect(() => { init?.(); }, [init]); return runtime; } -export function useRuntimeAll(): RefObject> { +export function useRuntimeAll(): Record { // すべての言語のcontextをインスタンス化 const pyodide = usePyodide(); const ruby = useRuby(); @@ -28,16 +28,15 @@ export function useRuntimeAll(): RefObject> const wandboxCpp = useWandbox("cpp"); const wandboxRust = useWandbox("rust"); - const runtimes = useRef>({} as never); - runtimes.current.python = pyodide; - runtimes.current.ruby = ruby; - runtimes.current.javascript = jsEval; - runtimes.current.typescript = typescript; - runtimes.current.cpp = wandboxCpp; - runtimes.current.rust = wandboxRust; - // initはしない。呼び出し側でする必要がある - return runtimes; + return { + python: pyodide, + ruby: ruby, + javascript: jsEval, + typescript: typescript, + cpp: wandboxCpp, + rust: wandboxRust, + }; } export function RuntimeProvider({ children }: { children: ReactNode }) { return ( diff --git a/packages/runtime/tests/vitest-all.tsx b/packages/runtime/tests/vitest-all.tsx index 15fd2c49..abfcea2f 100644 --- a/packages/runtime/tests/vitest-all.tsx +++ b/packages/runtime/tests/vitest-all.tsx @@ -14,8 +14,9 @@ const RuntimeLoader = ({ }: { runtimeRef: RefObject | null>; }) => { - const runtimes = useRuntimeAll(); - runtimeRef.current = runtimes.current; + const runtimeAll = useRuntimeAll(); + // eslint-disable-next-line react-hooks/refs + runtimeRef.current = runtimeAll; return null; }; diff --git a/tsconfig.json b/tsconfig.json index 63c1d1e9..60d973ab 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,11 @@ { "compilerOptions": { "target": "ES2017", - "lib": ["dom", "dom.iterable", "es2023"], + "lib": [ + "dom", + "dom.iterable", + "es2023" + ], "allowJs": true, "skipLibCheck": true, "strict": true, @@ -11,7 +15,7 @@ "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve", + "jsx": "react-jsx", "incremental": true, "plugins": [ { @@ -19,11 +23,25 @@ } ], "paths": { - "@/*": ["./app/*"], - "@my-code/runtime/tests/*": ["./packages/runtime/tests/*"], - "@my-code/runtime/*": ["./packages/runtime/src/*"] + "@/*": [ + "./app/*" + ], + "@my-code/runtime/tests/*": [ + "./packages/runtime/tests/*" + ], + "@my-code/runtime/*": [ + "./packages/runtime/src/*" + ] } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] }