pusher-zod
v0.0.7
Published
pusher with typesafety using zod to parse the data
Downloads
16
Maintainers
Readme
Pusher-Zod
Pusher-Zod is a TypeScript package designed to enhance type safety for both server and client implementations when using Pusher (or Soketi). By integrating the powerful Zod library for runtime type validation, Pusher-Zod ensures that your Pusher event data adheres to the expected types, reducing the risk of runtime errors and providing a more robust development experience.
Installation
To install Pusher-Zod, use your package manager of choice:
npm install pusher-zod zod
# or
yarn add pusher-zod zod
# or
pnpm instal pusher-zod zod
Ressources
New methods added to the Pusher server and client instances
Client
instead of using subscribe you should use joinChannel. The channelID can be any string you want. The channelName must be one of the channels defined in the setup object :
client.joinChannel(channelName: string, channelID: string): Channel;
// with subscribe :
client.subscribe("channelName_channelID");
same logic for unsubscribe you should use leaveChannel:
client.leaveChannel(channelName: string, channelID: string): void;
// with unsubscribe :
client.unsubscribe("channelName_channelID");
When joining a channel with joinChannel you can now listen to events using the listen method. The event name must be one of the events defined in the setup object :
channel.listen("eventName", (data) => {});
// with bind but no typesafety :
channel.bind("eventName", (data) => {});
Server
instead of using trigger you should use invoke. The channelID can be any string you want. The channelName must be one of the channels defined in the setup object :
pusherServer.invoke(
channelName: string,
channelID: string | string[],
eventName: string,
data: any
);
// with trigger :
pusherServer.trigger("channelName_channelID", "eventName", data);
Even through bind/subcribe/unsubscribe or trigger are still available they are not type-safe and should not be used. Instead you should use listen/joinChannel/leaveChannel
Usage
First create a setup object that defines your Pusher channels and events with Zod schemas:
import pusherZod from "pusher-zod";
import { z } from "zod";
const setup = {
chat: {
message: z.object({
user: z.string(),
text: z.string(),
}),
messageDeleted: z.object({
user: z.string(),
messageId: z.string(),
}),
},
// Add more channels and events as needed
};
// Optional : Define user events
const userEvents = {
typing: z.object({
user: z.string(),
}),
notification: z.object({
user: z.string(),
text: z.string(),
}),
booleanEvents: z.boolean(),
numberEvents: z.number(),
// Add more events as needed
};
// Export the client and server and import them where you need them
export const { TypeSafePusherClient, TypeSafePusherServer } = pusherZod({
setup,
userEvents, // optional
channel_id_separator: "_", // Optional: Choose your own separator. For example, a channel could be called 'chat_conversationID'
});
Then create a Pusher client instance using the TypeSafePusherClient class. See the PusherJS docs for more information
import { TypeSafePusherClient } from "./pusher-zod-setup";
// For the options check the pusher-js docs
const Client = new TypeSafePusherClient({
"app_key", // your app key
// ...your options
})
// Subscribe to a channel. You will get a type error if you try to join a channel that is not defined. The ID can be any value you want.
const channel = Client.joinChannel("chat", "conversationID");
// listen to an event
channel.listen("message", (data) => {
// data is parsed and validated using Parse from Zod
console.log(data.user, data.text);
});
// user events are also type-safe
channel.user.bind("typing", (data) => {
// data is parsed and validated using Parse from Zod
console.log(data.user);
});
Then create a Pusher server instance using the TypeSafePusherServer class:
import { TypeSafePusherServer } from "./pusher-zod-setup";
// For the options check the pusher-js docs
const pusherServer = new TypeSafePusherServer({
appId: "YOUR_PUSHER_APP_ID",
key: "YOUR_PUSHER_KEY",
secret: "YOUR_PUSHER_SECRET",
cluster: "YOUR_PUSHER_CLUSTER",
});
// Use the invoke method for a type-safe way to trigger events
await pusherServer.invoke("channelName", "channelID", "event", {
user: "user",
text: "text",
});
// example:
await pusherServer.invoke("chat", "conversation1", "message", {
user: "user",
text: "text",
});
// Invoke like trigger also support multiple channels but instead you need to pass multiple channel ids
await pusherServer.invoke(
"chat",
["conversation1", "conversation2", "conversation3"],
"message",
{
user: "user",
text: "text",
}
);
// sendToUser method is also now typesafe
await pusherServer.sendToUser(
"userID",
"event",
"data matching the event schema"
);
// example:
await pusherServer.sendToUser("1", "typing", {
user: "random username",
});
Features
- Type-Safe Event Data: Ensure that event data sent and received through Pusher adheres to predefined TypeScript types.
- Server and Client Integration: Apply type safety both on the server and client sides for a seamless end-to-end development experience.
- Zod Integration: Leverage the Zod library for runtime type validation, making it easy to define and enforce data schemas.
Roadmap
- [x] Type-safe event data
- [x] Server and client integration
- [x] Zod integration
- [ ] Support for presence channels
- [ ] Support for private channels
- [ ] Add choice between safeParse and parse
- [ ] Type-safe user data
- [ ] Retrieve existing private channels and presence channels names on the server side
- [ ] Add tests
Contributing
Feel free to contribute to Pusher-Zod by opening issues or pull requests on the GitHub repository.
License
Pusher-Zod is licensed under the MIT License.