From 8fc0e379f0254450ebdc52537edfb6e8dac54f0f Mon Sep 17 00:00:00 2001 From: nextify Date: Mon, 13 May 2024 18:59:28 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(customer):=20improve=20custo?= =?UTF-8?q?mer=20query=20performance=20(#56)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🐛 fix(customer): improve customer query performance * 🐛 fix(app,components): improve formatting and styling * 🔧 chore: Upgrade dependencies in Next.js and Auth packages --- apps/nextjs/contentlayer.config.ts | 26 +++-- apps/nextjs/next.config.mjs | 2 +- apps/nextjs/package.json | 12 +- apps/nextjs/src/app/layout.tsx | 2 +- .../src/components/k8s/cluster-config.tsx | 8 +- apps/nextjs/src/components/main-nav.tsx | 10 +- apps/nextjs/src/components/mobile-nav.tsx | 2 +- apps/nextjs/src/trpc/client.ts | 44 +++++-- apps/nextjs/src/trpc/server.ts | 78 +++++++++---- apps/nextjs/src/trpc/shared.ts | 109 +++++++++--------- packages/api/package.json | 4 +- packages/api/src/router/customer.ts | 13 +++ packages/auth/package.json | 2 +- 13 files changed, 198 insertions(+), 114 deletions(-) diff --git a/apps/nextjs/contentlayer.config.ts b/apps/nextjs/contentlayer.config.ts index 6e215424..fc8a8cf6 100644 --- a/apps/nextjs/contentlayer.config.ts +++ b/apps/nextjs/contentlayer.config.ts @@ -1,4 +1,8 @@ -import { ComputedFields, defineDocumentType, makeSource } from "contentlayer2/source-files"; +import { + ComputedFields, + defineDocumentType, + makeSource, +} from "contentlayer2/source-files"; import rehypeAutolinkHeadings from "rehype-autolink-headings"; import rehypePrettyCode from "rehype-pretty-code"; import rehypeSlug from "rehype-slug"; @@ -33,7 +37,7 @@ export const Doc = defineDocumentType(() => ({ default: true, }, }, - computedFields:defaultComputedFields + computedFields: defaultComputedFields, })); export const Guide = defineDocumentType(() => ({ @@ -61,7 +65,7 @@ export const Guide = defineDocumentType(() => ({ default: false, }, }, - computedFields:defaultComputedFields + computedFields: defaultComputedFields, })); export const Post = defineDocumentType(() => ({ @@ -98,7 +102,7 @@ export const Post = defineDocumentType(() => ({ required: true, }, }, - computedFields:defaultComputedFields + computedFields: defaultComputedFields, })); export const Author = defineDocumentType(() => ({ @@ -122,7 +126,7 @@ export const Author = defineDocumentType(() => ({ required: true, }, }, - computedFields:defaultComputedFields + computedFields: defaultComputedFields, })); export const Page = defineDocumentType(() => ({ @@ -138,7 +142,7 @@ export const Page = defineDocumentType(() => ({ type: "string", }, }, - computedFields:defaultComputedFields, + computedFields: defaultComputedFields, })); export default makeSource({ @@ -152,14 +156,16 @@ export default makeSource({ rehypePrettyCode, { theme: "github-dark", - onVisitLine(node: { children: string | any[]; }) { + onVisitLine(node: { children: string | any[] }) { // Prevent lines from collapsing in `display: grid` mode, and allow empty // lines to be copy/pasted if (node.children.length === 0) { node.children = [{ type: "text", value: " " }]; } }, - onVisitHighlightedLine(node: { properties: { className: string[]; }; }) { + onVisitHighlightedLine(node: { + properties: { className: string[] }; + }) { // node.properties.className.push("line--highlighted") // FIX: I changed remark-gmf 4.0.0 to 3.0.1 (return a lot errors in mdx?) @@ -172,7 +178,9 @@ export default makeSource({ node.properties.className = ["line--highlighted"]; } }, - onVisitHighlightedWord(node: { properties: { className: string[]; }; }) { + onVisitHighlightedWord(node: { + properties: { className: string[] }; + }) { node.properties.className = ["word--highlighted"]; }, }, diff --git a/apps/nextjs/next.config.mjs b/apps/nextjs/next.config.mjs index 7ffcf34d..e0549cc6 100644 --- a/apps/nextjs/next.config.mjs +++ b/apps/nextjs/next.config.mjs @@ -2,9 +2,9 @@ import "./src/env.mjs"; import "@saasfly/auth/env.mjs"; +import { withNextDevtools } from "@next-devtools/core/plugin"; // import "@saasfly/api/env" import withMDX from "@next/mdx"; -import {withNextDevtools} from "@next-devtools/core/plugin"; !process.env.SKIP_ENV_VALIDATION && (await import("./src/env.mjs")); diff --git a/apps/nextjs/package.json b/apps/nextjs/package.json index 790e845f..c73e11aa 100644 --- a/apps/nextjs/package.json +++ b/apps/nextjs/package.json @@ -15,7 +15,7 @@ "@dinero.js/currencies": "2.0.0-alpha.14", "@formatjs/intl-localematcher": "0.5.4", "@hookform/resolvers": "3.3.4", - "@next/mdx": "14.0.4", + "@next/mdx": "14.2.3", "@saasfly/api": "workspace:*", "@saasfly/auth": "workspace:*", "@saasfly/db": "workspace:*", @@ -24,14 +24,14 @@ "@tanstack/react-query": "5.18.1", "@tanstack/react-query-devtools": "5.18.1", "@tanstack/react-table": "8.11.8", - "@trpc/client": "10.44.1", - "@trpc/next": "10.44.1", - "@trpc/react-query": "10.44.1", - "@trpc/server": "10.44.1", + "@trpc/client": "next", + "@trpc/next": "next", + "@trpc/react-query": "next", + "@trpc/server": "next", "date-fns": "3.3.1", "framer-motion": "11.0.3", "negotiator": "0.6.3", - "next": "14.0.4", + "next": "14.2.3", "next-themes": "0.2.1", "react": "18.3.1", "react-day-picker": "8.10.0", diff --git a/apps/nextjs/src/app/layout.tsx b/apps/nextjs/src/app/layout.tsx index a08fa5a3..b43f7391 100644 --- a/apps/nextjs/src/app/layout.tsx +++ b/apps/nextjs/src/app/layout.tsx @@ -3,6 +3,7 @@ import localFont from "next/font/local"; import "~/styles/globals.css"; +import { NextDevtoolsProvider } from "@next-devtools/core"; import { Analytics } from "@vercel/analytics/react"; import { SpeedInsights } from "@vercel/speed-insights/next"; @@ -13,7 +14,6 @@ import { TailwindIndicator } from "~/components/tailwind-indicator"; import { ThemeProvider } from "~/components/theme-provider"; import { i18n } from "~/config/i18n-config"; import { siteConfig } from "~/config/site"; -import {NextDevtoolsProvider} from "@next-devtools/core"; // import { Suspense } from "react"; // import { PostHogPageview } from "~/config/providers"; diff --git a/apps/nextjs/src/components/k8s/cluster-config.tsx b/apps/nextjs/src/components/k8s/cluster-config.tsx index 205e9bd5..9cbdf326 100644 --- a/apps/nextjs/src/components/k8s/cluster-config.tsx +++ b/apps/nextjs/src/components/k8s/cluster-config.tsx @@ -343,11 +343,11 @@ export function ClusterConfig({ cluster, params: { lang } }: ClusterProps) {
+
diff --git a/apps/nextjs/src/components/main-nav.tsx b/apps/nextjs/src/components/main-nav.tsx index b0da0b6c..09351ba6 100644 --- a/apps/nextjs/src/components/main-nav.tsx +++ b/apps/nextjs/src/components/main-nav.tsx @@ -22,11 +22,11 @@ export function MainNav({ items, children, params: { lang } }: MainNavProps) { const segment = useSelectedLayoutSegment(); const [showMobileMenu, setShowMobileMenu] = React.useState(false); const toggleMenu = () => { - setShowMobileMenu(!showMobileMenu) - } + setShowMobileMenu(!showMobileMenu); + }; const handleMenuItemClick = () => { toggleMenu(); - } + }; return (
@@ -61,7 +61,9 @@ export function MainNav({ items, children, params: { lang } }: MainNavProps) { Menu {showMobileMenu && items && ( - {children} + + {children} + )}
); diff --git a/apps/nextjs/src/components/mobile-nav.tsx b/apps/nextjs/src/components/mobile-nav.tsx index 59bdc705..f8abdfc4 100644 --- a/apps/nextjs/src/components/mobile-nav.tsx +++ b/apps/nextjs/src/components/mobile-nav.tsx @@ -14,7 +14,7 @@ interface MobileNavProps { menuItemClick?: () => void; } -export function MobileNav({ items, children, menuItemClick}: MobileNavProps) { +export function MobileNav({ items, children, menuItemClick }: MobileNavProps) { useLockBody(); return (
({ +// config() { +// return { +// transformer, +// links: [ +// // loggerLink({ +// // enabled: (opts) => +// // process.env.NODE_ENV === "development" || +// // (opts.direction === "down" && opts.result instanceof Error), +// // }), +// loggerLink({ +// enabled: () => true, +// }), +// endingLink({ +// headers: { +// "x-trpc-source": "client", +// }, +// }), +// ], +// }; +// }, +// }); export const trpc = experimental_createTRPCNextAppDirClient({ config() { return { - transformer, links: [ - // loggerLink({ - // enabled: (opts) => - // process.env.NODE_ENV === "development" || - // (opts.direction === "down" && opts.result instanceof Error), - // }), loggerLink({ enabled: () => true, }), - endingLink({ - headers: { - "x-trpc-source": "client", + experimental_nextHttpLink({ + transformer: superjson, + batch: true, + url: getUrl(), + headers() { + return { + "x-trpc-source": "client", + }; }, }), ], }; }, }); - export { type RouterInputs, type RouterOutputs } from "@saasfly/api"; diff --git a/apps/nextjs/src/trpc/server.ts b/apps/nextjs/src/trpc/server.ts index c5e25a1e..492c94ca 100644 --- a/apps/nextjs/src/trpc/server.ts +++ b/apps/nextjs/src/trpc/server.ts @@ -1,42 +1,76 @@ -"use server"; - -import "server-only"; - -import { cookies, headers } from "next/headers"; +// "use server"; +// +// import "server-only"; +// +// import { cookies, headers } from "next/headers"; +// import { loggerLink } from "@trpc/client"; +// import { experimental_createTRPCNextAppDirServer } from "@trpc/next/app-dir/server"; +// +import { cookies } from "next/headers"; +// +// import { endingLink, transformer } from "./shared"; +// +// export const trpc = experimental_createTRPCNextAppDirServer({ +// config() { +// return { +// ssr: true, +// transformer, +// links: [ +// // loggerLink({ +// // enabled: (opts) => +// // process.env.NODE_ENV === "development" || +// // (opts.direction === "down" && opts.result instanceof Error), +// // }), +// loggerLink({ +// enabled: () => true, +// }), +// endingLink({ +// headers: () => { +// const h = new Map(headers()); +// h.delete("connection"); +// h.delete("transfer-encoding"); +// h.set("x-trpc-source", "server"); +// h.set("cookie", cookies().toString()); +// return Object.fromEntries(h.entries()); +// }, +// }), +// ], +// }; +// }, +// }); +// import { loggerLink } from "@trpc/client"; +import { experimental_nextHttpLink } from "@trpc/next/app-dir/links/nextHttp"; import { experimental_createTRPCNextAppDirServer } from "@trpc/next/app-dir/server"; +import superjson from "superjson"; import type { AppRouter } from "@saasfly/api"; -import { endingLink, transformer } from "./shared"; +import { getUrl } from "~/trpc/shared"; +/** + * This client invokes procedures directly on the server without fetching over HTTP. + */ export const trpc = experimental_createTRPCNextAppDirServer({ config() { return { - ssr: true, - transformer, links: [ - // loggerLink({ - // enabled: (opts) => - // process.env.NODE_ENV === "development" || - // (opts.direction === "down" && opts.result instanceof Error), - // }), loggerLink({ enabled: () => true, }), - endingLink({ - headers: () => { - const h = new Map(headers()); - h.delete("connection"); - h.delete("transfer-encoding"); - h.set("x-trpc-source", "server"); - h.set("cookie", cookies().toString()); - return Object.fromEntries(h.entries()); + experimental_nextHttpLink({ + batch: true, + url: getUrl(), + transformer: superjson, + headers() { + return { + cookie: cookies().toString(), + "x-trpc-source": "rsc-http", + }; }, }), ], }; }, }); - export { type RouterInputs, type RouterOutputs } from "@saasfly/api"; diff --git a/apps/nextjs/src/trpc/shared.ts b/apps/nextjs/src/trpc/shared.ts index 592737a1..58d6c2d2 100644 --- a/apps/nextjs/src/trpc/shared.ts +++ b/apps/nextjs/src/trpc/shared.ts @@ -1,52 +1,57 @@ -import { - httpBatchLink, - type HTTPBatchLinkOptions, - type HTTPHeaders, - type TRPCLink, -} from "@trpc/client"; - -import type {AppRouter} from "@saasfly/api"; - -import {env} from "~/env.mjs"; -import fetchPonyfill from "fetch-ponyfill"; - -export {transformer} from "@saasfly/api/transformer"; -const getBaseUrl = () => { - if (typeof window !== "undefined") return ""; - const vc = env.NEXT_PUBLIC_APP_URL; - if (vc) return vc; - return `http://127.0.0.1:3000`; -}; - -const lambdas = [""]; - -export const endingLink = (opts?: { - headers?: HTTPHeaders | (() => HTTPHeaders); -}) => - ((runtime) => { - const sharedOpts = { - headers: opts?.headers, - } satisfies Partial; - - const edgeLink = httpBatchLink({ - ...sharedOpts, - url: `${getBaseUrl()}/api/trpc/edge`, - fetch: fetchPonyfill().fetch, - })(runtime); - const lambdaLink = httpBatchLink({ - ...sharedOpts, - url: `${getBaseUrl()}/api/trpc/lambda`, - fetch: fetchPonyfill().fetch, - })(runtime); - - return (ctx) => { - const path = ctx.op.path.split(".") as [string, ...string[]]; - const endpoint = lambdas.includes(path[0]) ? "lambda" : "edge"; - - const newCtx = { - ...ctx, - op: {...ctx.op, path: path.join(".")}, - }; - return endpoint === "edge" ? edgeLink(newCtx) : lambdaLink(newCtx); - }; - }) satisfies TRPCLink; +// import { +// httpBatchLink, +// type HTTPBatchLinkOptions, +// type HTTPHeaders, +// type TRPCLink, +// } from "@trpc/client"; +// +// import type {AppRouter} from "@saasfly/api"; + +import { env } from "~/env.mjs"; + +// import fetchPonyfill from "fetch-ponyfill"; + +export { transformer } from "@saasfly/api/transformer"; + +function getBaseUrl() { + if (typeof window !== "undefined") return ""; + const vc = env.NEXT_PUBLIC_APP_URL; + if (vc) return vc; + return `http://127.0.0.1:3000`; +} + +export function getUrl() { + return getBaseUrl() + "/api/trpc/edge"; +} +// const lambdas = [""]; +// +// export const endingLink = (opts?: { +// headers?: HTTPHeaders | (() => HTTPHeaders); +// }) => +// ((runtime) => { +// const sharedOpts = { +// headers: opts?.headers, +// } satisfies Partial; +// +// const edgeLink = httpBatchLink({ +// ...sharedOpts, +// url: `${getBaseUrl()}/api/trpc/edge`, +// fetch: fetchPonyfill().fetch, +// })(runtime); +// const lambdaLink = httpBatchLink({ +// ...sharedOpts, +// url: `${getBaseUrl()}/api/trpc/lambda`, +// fetch: fetchPonyfill().fetch, +// })(runtime); +// +// return (ctx) => { +// const path = ctx.op.path.split(".") as [string, ...string[]]; +// const endpoint = lambdas.includes(path[0]) ? "lambda" : "edge"; +// +// const newCtx = { +// ...ctx, +// op: {...ctx.op, path: path.join(".")}, +// }; +// return endpoint === "edge" ? edgeLink(newCtx) : lambdaLink(newCtx); +// }; +// }) satisfies TRPCLink; diff --git a/packages/api/package.json b/packages/api/package.json index bfef20cd..3b2f8df4 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -27,8 +27,8 @@ "dependencies": { "@saasfly/auth": "workspace:*", "@saasfly/db": "workspace:*", - "@trpc/client": "10.44.1", - "@trpc/server": "10.44.1", + "@trpc/client": "next", + "@trpc/server": "next", "@t3-oss/env-nextjs": "0.8.0", "superjson": "2.2.1", "dinero.js": "2.0.0-alpha.14", diff --git a/packages/api/src/router/customer.ts b/packages/api/src/router/customer.ts index 52c9993d..a5eb035a 100644 --- a/packages/api/src/router/customer.ts +++ b/packages/api/src/router/customer.ts @@ -52,6 +52,19 @@ export const customerRouter = createTRPCRouter({ .input(insertCustomerSchema) .query(async ({ input }) => { const { userId } = input; + console.log("userId:", userId); + try { + console.log( + "result:", + await db + .selectFrom("Customer") + .where("authUserId", "=", userId) + .executeTakeFirst(), + ); + } catch (e) { + console.error("e:", e); + } + return await db .selectFrom("Customer") .where("authUserId", "=", userId) diff --git a/packages/auth/package.json b/packages/auth/package.json index c7e8413c..edd39dda 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -14,7 +14,7 @@ "@auth/kysely-adapter": "0.4.2", "@saasfly/db": "workspace:*", "@t3-oss/env-nextjs": "0.8.0", - "next": "14.0.4", + "next": "14.2.3", "next-auth": "4.24.7", "react": "18.3.1", "react-dom": "18.3.1",