Mocha
Mocha
TTCTheo's Typesafe Cult
Created by Mocha on 8/26/2024 in #questions
Migrating from T3 to T3 Turborepo
I have an existing T3 web app (Next, Clerk, tRPC) and I'm developing a mobile version. How can I utilize the existing tRPC endpoints and Clerk auth? I know there's a monorepo sample that Theo went over in some videos, but I'm not starting from scratch.
13 replies
TTCTheo's Typesafe Cult
Created by Mocha on 7/19/2024 in #questions
Creating video from images
I have a lot of images in a page, and I want to allow my users to download the images as a video. It'd be great if that can be done on the client side so I don't have to think about or pay for servers. I tried @ffmpeg/ffmpeg but it gives the following error message, even when exactly following the example provided
ModuleBuildError: ./node_modules/@ffmpeg/ffmpeg/dist/esm/classes.js:104:28
Module not found
102 | if (!this.#worker) {
103 | this.#worker = classWorkerURL ?
> 104 | new Worker(new URL(classWorkerURL, import.meta.url), {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
105 | type: "module",
106 | }) :
107 | // We need to duplicated the code here to enable webpack
ModuleBuildError: ./node_modules/@ffmpeg/ffmpeg/dist/esm/classes.js:104:28
Module not found
102 | if (!this.#worker) {
103 | this.#worker = classWorkerURL ?
> 104 | new Worker(new URL(classWorkerURL, import.meta.url), {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
105 | type: "module",
106 | }) :
107 | // We need to duplicated the code here to enable webpack
My goal is to basically implement this function:
async function downloadVideo(images: string[]) {
const downloadUrl = 'TODO'
const a = document.createElement('a')
a.href = videoUrl
a.download = 'output.mp4'
a.click()
a.remove()
}
async function downloadVideo(images: string[]) {
const downloadUrl = 'TODO'
const a = document.createElement('a')
a.href = videoUrl
a.download = 'output.mp4'
a.click()
a.remove()
}
2 replies
TTCTheo's Typesafe Cult
Created by Mocha on 5/13/2024 in #questions
Next.js API Type Safety without tRPC?
I'm having issues with tRPC and am thinking of removing it from my project. Since I'm using App Router, it's less of a problem when calls are made on the server. However, I still need to make calls from client side. What are some good solutions for that?
10 replies
TTCTheo's Typesafe Cult
Created by Mocha on 5/12/2024 in #questions
[TRPCClientError]: Converting circular structure to JSON
I'm getting this error only in production (Vercel). I'm using tRPC, Supabase, Clerk. The website crashes right after login. Browser error:
Application error: a server-side exception has occurred (see the server logs for more information).
Vercel logs:
l [TRPCClientError]: Converting circular structure to JSON
--> starting at object with constructor 'Timeout'
| property '_idlePrev' -> object with constructor 'TimersList'
--- property '_idleNext' closes the circle
at l.from (/var/task/.next/server/chunks/696.js:7:53047)
at /var/task/.next/server/app/activity/page.js:1:48095
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
meta: undefined,
shape: undefined,
data: undefined,
digest: '2788403914',
[cause]: TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Timeout'
| property '_idlePrev' -> object with constructor 'TimersList'
--- property '_idleNext' closes the circle
at JSON.stringify (<anonymous>)
... 5 lines matching cause stack trace ...
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
code: 'INTERNAL_SERVER_ERROR',
name: 'TRPCError',
[cause]: TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Timeout'
| property '_idlePrev' -> object with constructor 'TimersList'
--- property '_idleNext' closes the circle
at JSON.stringify (<anonymous>)
at /var/task/.next/server/chunks/101.js:1:12977
at t (/var/task/.next/server/chunks/338.js:13:359299)
at a (/var/task/.next/server/chunks/338.js:13:359613)
at c (/var/task/.next/server/chunks/338.js:13:353322)
at /var/task/.next/server/app/activity/page.js:1:47939
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
}
}
l [TRPCClientError]: Converting circular structure to JSON
--> starting at object with constructor 'Timeout'
| property '_idlePrev' -> object with constructor 'TimersList'
--- property '_idleNext' closes the circle
at l.from (/var/task/.next/server/chunks/696.js:7:53047)
at /var/task/.next/server/app/activity/page.js:1:48095
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
meta: undefined,
shape: undefined,
data: undefined,
digest: '2788403914',
[cause]: TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Timeout'
| property '_idlePrev' -> object with constructor 'TimersList'
--- property '_idleNext' closes the circle
at JSON.stringify (<anonymous>)
... 5 lines matching cause stack trace ...
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
code: 'INTERNAL_SERVER_ERROR',
name: 'TRPCError',
[cause]: TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Timeout'
| property '_idlePrev' -> object with constructor 'TimersList'
--- property '_idleNext' closes the circle
at JSON.stringify (<anonymous>)
at /var/task/.next/server/chunks/101.js:1:12977
at t (/var/task/.next/server/chunks/338.js:13:359299)
at a (/var/task/.next/server/chunks/338.js:13:359613)
at c (/var/task/.next/server/chunks/338.js:13:353322)
at /var/task/.next/server/app/activity/page.js:1:47939
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
}
}
9 replies
TTCTheo's Typesafe Cult
Created by Mocha on 4/3/2024 in #questions
Failed to compile. Entry point for implicit type library 'mime'
I suddenly started getting this error message when trying to compile. The dev server works fine. I tried installing @types/mime and including "types": ["node"] in my tsconfig.json/compileOptions. The same error message appears on Vercel as well, so it's nothing about my setup. I suspected it could be caused by some JSON imports, so I appended with { type: 'json' } to my imports.
$ next build
▲ Next.js 14.1.4
- Environments: .env

Linting and checking validity of types .Failed to compile.

Type error: Cannot find type definition file for 'mime'.
The file is in the program because:
Entry point for implicit type library 'mime'

error: script "build" exited with code 1
$ next build
▲ Next.js 14.1.4
- Environments: .env

Linting and checking validity of types .Failed to compile.

Type error: Cannot find type definition file for 'mime'.
The file is in the program because:
Entry point for implicit type library 'mime'

error: script "build" exited with code 1
2 replies
TTCTheo's Typesafe Cult
Created by Mocha on 3/30/2024 in #questions
TRPCClientError: Unable to transform response from server
I just migrated from Next Auth to Clerk. Clerk is working fine. tRPC works fine too, but I keep getting this error message from all requests. src/pages/_app.tsx
// ...
return
<ClerkProvider {...pageProps}>
{/* Everything else goes in here */}
</ClerkProvider>
// ...
export default api.withTRPC(MyApp)
// ...
return
<ClerkProvider {...pageProps}>
{/* Everything else goes in here */}
</ClerkProvider>
// ...
export default api.withTRPC(MyApp)
src/api/trpc.ts
import { clerkClient, getAuth } from '@clerk/nextjs/server'

export const createTRPCContext = async ({ req }: CreateNextContextOptions) => {
const session = getAuth(req)
const user = session.userId
? await clerkClient.users.getUser(session.userId)
: null

return {
userId: session?.userId ?? undefined,
orgId: session.orgId ?? undefined,
firstName: user?.firstName,
prisma,
}
}

const t = initTRPC.context<typeof createTRPCContext>().create({
transformer: superjson,
errorFormatter({ shape, error }) {
return {
...shape,
data: {
...shape.data,
zodError:
error.cause instanceof ZodError ? error.cause.flatten() : null,
},
}
},
})
import { clerkClient, getAuth } from '@clerk/nextjs/server'

export const createTRPCContext = async ({ req }: CreateNextContextOptions) => {
const session = getAuth(req)
const user = session.userId
? await clerkClient.users.getUser(session.userId)
: null

return {
userId: session?.userId ?? undefined,
orgId: session.orgId ?? undefined,
firstName: user?.firstName,
prisma,
}
}

const t = initTRPC.context<typeof createTRPCContext>().create({
transformer: superjson,
errorFormatter({ shape, error }) {
return {
...shape,
data: {
...shape.data,
zodError:
error.cause instanceof ZodError ? error.cause.flatten() : null,
},
}
},
})
3 replies
TTCTheo's Typesafe Cult
Created by Mocha on 3/5/2024 in #questions
TRPCClientError: Unexpected token 'A', "An error o"... is not valid JSON
I'm making a fetch API call to an external server inside a tRPC route. It works perfectly on localhost, but never works when deployed on Vercel. The request normally takes ~30s, and it has a large body (~12KB).
10 replies
TTCTheo's Typesafe Cult
Created by Mocha on 2/7/2024 in #questions
How to Refetch in App Router?
How do I refetch/revalidate data loaded from Server Components? I have a Server Component page with a Client Component inside it
export default async function Parent() {
return <Child data={await api.route.data.query()} />
}
export default async function Parent() {
return <Child data={await api.route.data.query()} />
}
Normally, when I useMutation I call query.refetch(). How do I do that here without causing a full page refresh?
5 replies
TTCTheo's Typesafe Cult
Created by Mocha on 8/23/2023 in #questions
~/components vs ~/components/Button
Any opinions on this? Does A affect performance? (importing from a file that exports many other components) A
// ~/components/index.ts
export { default as Button } from './Button'
export { default as Label } from './Label'
export { default as Toggle } from './Toggle'

// ~/components/Button/Button.tsx
export default function Button() { return <button /> }

// ~/components/Button/index.ts
export { default } from './Button'

// ~/pages/index.tsx
import { Button, Label } from '~/components'
// ~/components/index.ts
export { default as Button } from './Button'
export { default as Label } from './Label'
export { default as Toggle } from './Toggle'

// ~/components/Button/Button.tsx
export default function Button() { return <button /> }

// ~/components/Button/index.ts
export { default } from './Button'

// ~/pages/index.tsx
import { Button, Label } from '~/components'
B
// ~/components/Button/Button.tsx
export default function Button() { return <button /> }

// ~/components/Button/index.ts
export { default } from './Button'

// ~/pages/index.tsx
import Button from '~/components/Button'
import Label from '~/components/Label'
// ~/components/Button/Button.tsx
export default function Button() { return <button /> }

// ~/components/Button/index.ts
export { default } from './Button'

// ~/pages/index.tsx
import Button from '~/components/Button'
import Label from '~/components/Label'
18 replies
TTCTheo's Typesafe Cult
Created by Mocha on 8/7/2023 in #questions
How to deploy API to Vercel
What's the easiest way to deploy a basic API endpoint to Vercel? I made an Express app structured like:
api
|--- index.js
package.json
pnpm-lock.yaml
vercel.json
api
|--- index.js
package.json
pnpm-lock.yaml
vercel.json
api/index.js:
import express from 'express'
import cors from 'cors'

const app = express()

// Disable CORS rules
app.use(cors())

app.get('/', (req, res) => {
res.send('It works!')
})

const PORT = process.env.PORT || 3000
app.listen(PORT, () => {
console.log(`API listening on PORT ${PORT} `)
})

export default app
import express from 'express'
import cors from 'cors'

const app = express()

// Disable CORS rules
app.use(cors())

app.get('/', (req, res) => {
res.send('It works!')
})

const PORT = process.env.PORT || 3000
app.listen(PORT, () => {
console.log(`API listening on PORT ${PORT} `)
})

export default app
vercel.json:
{
"version": 2,
"builds": [
{
"src": "index.js",
"use": "@now/node"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "index.js"
}
]
}
{
"version": 2,
"builds": [
{
"src": "index.js",
"use": "@now/node"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "index.js"
}
]
}
The API just uploads files to S3 or GCS, so I'm open to using any other language or framework. It will mainly be used in my T3 app, but I found Next.js really confusing with handling files (tried to use HTML form, formidable, multer, ...) Docs I followed: * https://vercel.com/docs/concepts/functions/serverless-functions/runtimes/node-js * https://vercel.com/guides/using-express-with-vercel#standalone-express
6 replies
TTCTheo's Typesafe Cult
Created by Mocha on 6/24/2023 in #questions
Simplest useInfiniteQuery implementation?
I'm trying to enable useInfiniteQuery on a tRPC query. I saw several tutorials, but it looked very different every time. My current setup looks something like:
vendors: protectedProcedure
.input(z.object({
take: z.number().default(10),
cursor: z.number().nullish(),
}))
.query(async ({ ctx: { prisma }, input: { take, cursor } }) => {
type Vendor = { vendor_id: string }

return prisma.$queryRaw<Vendor[]>`
select vendor_id
from vendor
limit ${take}
offset 0`
// how to use cursor here? ^
// not using .findMany()
}),
vendors: protectedProcedure
.input(z.object({
take: z.number().default(10),
cursor: z.number().nullish(),
}))
.query(async ({ ctx: { prisma }, input: { take, cursor } }) => {
type Vendor = { vendor_id: string }

return prisma.$queryRaw<Vendor[]>`
select vendor_id
from vendor
limit ${take}
offset 0`
// how to use cursor here? ^
// not using .findMany()
}),
Then:
const { data: vendors = [] } = api.accounts.vendors.useQuery({})
const { data: vendors = [] } = api.accounts.vendors.useQuery({})
4 replies
TTCTheo's Typesafe Cult
Created by Mocha on 6/15/2023 in #questions
tRPC + Clerk: user & org info
I'm switching from NextAuth to Clerk. With NextAuth, I got the user info like:
import type { Session } from 'next-auth'

type CreateContextOptions = {
session: Session | null
}
import type { Session } from 'next-auth'

type CreateContextOptions = {
session: Session | null
}
With Clerk's getAuth, I only get userId and nothing else about the user. It exists in the SignedInAuthObject type but it's always undefined, so I can't read the user's email or orgSlug in my tRPC context. I can retrieve it like this, but it'd be called too many times and retrieve too much data
export const createTRPCContext = async (opts: CreateNextContextOptions) => {
// Get the session from the server using the getServerSession wrapper function
const session = getAuth(opts.req)
const { userId } = session
if (!userId) return createInnerTRPCContext({ session })

const user = await clerkClient.users.getUser(userId)
const orgs = await clerkClient.users.getOrganizationMembershipList({ userId })

return createInnerTRPCContext({
session,
user,
orgSlug: orgs[0]?.organization?.slug,
})
}
export const createTRPCContext = async (opts: CreateNextContextOptions) => {
// Get the session from the server using the getServerSession wrapper function
const session = getAuth(opts.req)
const { userId } = session
if (!userId) return createInnerTRPCContext({ session })

const user = await clerkClient.users.getUser(userId)
const orgs = await clerkClient.users.getOrganizationMembershipList({ userId })

return createInnerTRPCContext({
session,
user,
orgSlug: orgs[0]?.organization?.slug,
})
}
tRPC setup: t3 then https://clerk.com/docs/nextjs/trpc
43 replies
TTCTheo's Typesafe Cult
Created by Mocha on 12/29/2022 in #questions
tRPC + WebSocket Client
14 replies
TTCTheo's Typesafe Cult
Created by Mocha on 12/13/2022 in #questions
Read input from many child components
I have a page with hundreds of text fields. From the page, I'm trying to read the user's input from each field when they click on a button. useState can work but would be too slow What would be a better solution? Should/how do I use useRef in this case?
20 replies
TTCTheo's Typesafe Cult
Created by Mocha on 12/9/2022 in #questions
Netlify – tRPC crashes after every deployment
8 replies