Skip to content
forked from OrJDev/prpc

Utility Library For Bling & SolidStart, Combining Tanstack Query With server$

Notifications You must be signed in to change notification settings

zakybilfagih/prpc

 
 

Repository files navigation

pRPC

Write server code, query / mutate it on the server and validate inputs using zod with only few lines of code. Supporting SolidStart and Bling.

Read more at our docs

pRPC currently has 2 adapters, one for Bling and one for SolidStart.

Bling

Read More Here Regarding Bling

SolidStart

Read More Here Regarding SolidStart

import { query$ } from '@prpc/solid'
import {
  createSignal,
  Match,
  Suspense,
  Switch,
  type VoidComponent,
} from 'solid-js'
import { z } from 'zod'

const queryOnServer = query$({
  queryFn: async ({ payload, request$ }) => {
    console.log('on server', request$.headers.get('user-agent'))
    return { result: payload.num / 2 }
  },
  key: 'queryOnServer',
  schema: z.object({
    num: z.number().max(5),
  }),
})

const Query: VoidComponent = () => {
  const [num, setNum1] = createSignal(1)

  const queryRes = queryOnServer(
    () => ({ num: num() }),
    () => ({
      placeholderData: (prev) => prev,
      onError: (error) => {
        if (error.isZodError()) {
          const fieldErrors = error.cause.fieldErrors
          console.log(fieldErrors.num)
        }
      },
      retry: false,
    })
  )

  return (
    <div class='flex flex-col gap-3 px-3'>
      <Suspense fallback='Loading...'>
        <Switch>
          <Match when={queryRes.error}>Error: {queryRes.error?.message}</Match>
          <Match when={queryRes.data}>Result: {queryRes.data?.result}</Match>
        </Switch>
      </Suspense>
      <button
        class='border border-gray-300 p-3'
        onClick={() => setNum1((num) => num + 1)}
      >
        {num()} - Increment
      </button>
      {queryRes.error?.message && <pre>{queryRes.error?.message}</pre>}
    </div>
  )
}

export default Query

Further Reading - SolidStart

Screenshot 2023-03-03 at 8 29 59

The code in this image is

import { query$ } from '@prpc/solid'
import { z } from 'zod'

export const helloQuery = query$(
  ({ payload, request$ }) => {
    console.log(request$.headers.get('user-agent'))
    return `server says hello: ${payload.name}`
  },
  'hello',
  z.object({ name: z.string() })
)

But how is this code working / running on the server? request$ is not an actual thing and you cannot use closures. We use a babel plugin built on top of vite that is meant to wrap functions that passed to query$ with server, so for instance:

query$(myFn)

becomes

query$(server$(myFn))

This piece of code make the function run on the server, but how do we access the request?

Well as you know request$ is not an actual thing in in SolidStart, this is again where our babel plugin helps, we pass an empty object to this function called request$ and then our babel plugin makes sure to replace all request$ acccess with server$.request (which is a way to get the request in SolidStart)

So for instance:

query$(({ request$ }) => {
  const headers = request$.headers
})

becomes

query$(
  server$(() => {
    const headers = server$.request.headers
  })
)

How do i call this function from the client?

query$ returns: (...) => createQuery(...) So what it does is, it is taking the function that is running on the server (wrapped with server$) and basically try to query it using createQuery from solid query.

So:

const myQuery = query$(myFn)

Can be used client side (still will run on the server):

const queryRes = myQuery(() => input)

// queryRes is basically tanstack query
queryRes.isLoading
queryRes.data

About

Utility Library For Bling & SolidStart, Combining Tanstack Query With server$

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 93.9%
  • JavaScript 5.6%
  • Other 0.5%