npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@solid-mediakit/prpc

v1.3.3

Published

A typesafed Wrapper for Solid's RPC protocol

Downloads

422

Readme

@solid-mediakit/prpc

A typesafed Wrapper for Solid's RPC protocol

Docs

Please read the docs here, bellow info is less accurate.

Installation

pnpm install @solid-mediakit/prpc @tanstack/solid-query @solid-mediakit/prpc-plugin

Adding The Vite Plugin

Go ahead to app.config.ts and add the following:

import { defineConfig } from '@solidjs/start/config'
import { prpcVite } from '@solid-mediakit/prpc-plugin' // ->

export default defineConfig({
  ssr: true,
  vite: {
    plugins: [prpcVite({ log: false })], // ->
  },
})

Basically, what is going to happen is that the Vite plugin will make this piece of code run on the server, causing it so Zod doesn't leak to the client nor any other server-side code. What's so special about it is that it includes many useful features which aren't build in Vinxi, like Zod validation, event$ property, custom error handling and more. The transformation process is done via Babel at real time so you don't have to worry about having ugly code in your code base, you just write it and we are in charge of the 'behind the scenes' stuff.

Usage

Recommended (Builder)

Read more about the builder here

export const helloBuilder = builder$()
  .middleware$(() => {
    return {
      hello: 1,
    }
  })
  .middleware$((ctx) => {
    return {
      ...ctx,
      world: 2,
    }
  })

export const helloQuery = helloBuilder
  .input(
    z.object({
      hello: z.string(),
    })
  )
  .query$(({ payload, ctx$ }) => {
    if (payload.hello === 'hello') {
      return ctx$.hello
    }
    return ctx$.world
  }, 'myNewQuery')

Query

// server function declaration
import { query$ } from '@solid-mediakit/prpc'
import { z } from 'zod'

const testQuery = query$({
  queryFn: async ({ payload, event$ }) => {
    const ua = event$.request.headers.get('user-agent')
    console.log({ ua })
    return `hey ${payload.hello}`
  },
  key: 'hello',
  schema: z.object({
    hello: z.string(),
  }),
})

// client code:
// input should be an accessor
const hello = testQuery(() => ({
  hello: 'JDev',
}), () => ({
  deferStream: true,
}))

Transforms Into

const __$helloQuery = cache(async ({ payload: _$$payload }) => {
  'use server'
  const _$$validatedZod = await validateZod(
    _$$payload,
    z.object({
      hello: z.string(),
    })
  )
  if (_$$validatedZod instanceof Response) return _$$validatedZod
  const _$$event = getRequestEvent()
  const ua = _$$event.request.headers.get('user-agent')
  console.log({
    ua,
  })
  return `hey ${_$$validatedZod.hello}`
}, 'hello')
const testQuery = query$({
  queryFn: __$helloQuery,
  key: 'hello',
  deferStream: true,
})

Mutation

// server function declaration
import { z } from 'zod'
import { error$, mutation$ } from '@solid-mediakit/prpc'

const testMutation = mutation$({
  mutationFn: ({ payload, event$ }) => {
    const ua = event$.request.headers.get('user-agent')
    console.log({ ua })
    if (payload.hello === 'error') {
      return error$('This is an error')
    }
    return `hey ${payload.hello}`
  },
  key: 'hello',
  schema: z.object({
    hello: z.string(),
  }),
})

// client code
const Home: VoidComponent = () => {
  const [hello, setHello] = createSignal('')
  const helloMutation = testMutation(() => ({
    onError(error) {
      if (error.isZodError()) {
        console.log('zod error:', error.cause.fieldErrors)
      } else {
        console.log(error.message)
      }
    },
  }))
  return (
    <main class='flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-[#026d56] to-[#152a2c]'>
      <p class='text-2xl text-white'>
        {helloMutation.data ?? 'No Data yet...'}
      </p>
      <Show when={helloMutation.isError}>
        <p class='text-2xl text-red-500'>
          {helloMutation.error?.message ?? 'Unknown Error'}
        </p>
      </Show>
      <div class='container flex flex-col items-center justify-center gap-4 px-4 py-16'>
        <input
          type='text'
          class='p-4 text-2xl rounded-lg'
          value={hello()}
          onInput={(e) => setHello(e.currentTarget.value)}
        />
        <button
          class='p-4 text-2xl bg-white rounded-lg'
          onClick={() => helloMutation.mutate({ hello: hello() })}
        >
          Submit
        </button>
      </div>
    </main>
  )
}

Transforms Into

const __$helloMutation = cache(async ({ payload: _$$payload }) => {
  'use server'
  const _$$validatedZod = await validateZod(
    _$$payload,
    z.object({
      hello: z.string(),
    })
  )
  if (_$$validatedZod instanceof Response) return _$$validatedZod
  const _$$event = getRequestEvent()
  const ua = _$$event.request.headers.get('user-agent')
  console.log({
    ua,
  })
  if (_$$validatedZod.hello === 'error') {
    return error$('This is an error')
  }
  return `hey ${_$$validatedZod.hello}`
}, 'hello')
const testMutation = mutation$({
  mutationFn: __$helloMutation,
  key: 'hello',
})

Middleware

One of pRPC's features is the ability to add middleware to your queries and mutations. This is useful for adding additional logic to your queries and mutations, such as logging, authentication, and more.

const mw1 = middleware$(({ event$ }) => {
  const ua = event$.request.headers.get('user-agent')!
  const isBot = ua.includes('bot')
  return {
    isBot,
  }
})
const testQuery = query$({
  queryFn: async ({ payload, ctx$ }) => {
    return `hey ${payload.hello} ${ctx$.isBot ? 'bot' : 'human'}`
  },
  key: 'hello',
  schema: z.object({
    hello: z.string(),
  }),
  middleware: [mw1],
})

In this example, the middleware function mw1 adds a isBot property to the context object. This property is then used in the query function to determine if the user is a bot or a human.