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

zod-custom-events

v1.3.2

Published

Type safe, framework agnostic, Zod based, custom events extension library.

Downloads

319

Readme

Zod Custom Events

Type safe, framework agnostic, Zod based, custom events extension library.

NPM Version JSR Version JSR Score CI Codecov Checked with Biome

Commitizen friendly MIT License NPM Bundle Size npm

  • ✅ Utilize the full controll of CustomEvents with a custom API
  • ✅ End-to-end type safety; validate event payload at runtime via your provided Zod schema
  • ✅ Framework agnostic; runs on any JavaScript environment
  • ✅ Supports all CustomEvent native properties and methods inherited by the Event interface
  • ✅ Middleware support for event processing
  • ✅ Less than 1kb minified and gzipped

Table of Contents

Preview

Installation

Prerequisites

Install zod-custom-events using your favorite package manager or CDN, then include it in your project:

Using NPM

# Install with npm
npm install zod-custom-events

# Install with pnpm
pnpm add zod-custom-events

# Install with yarn
yarn add zod-custom-events

# Install with bun
bun add zod-custom-events

Using JSR

# Install in a node project
npx jsr add @georgecht/zod-custom-events

# Install in a deno project
deno add jsr:@georgecht/zod-custom-events

# Install in a bun project
bunx jsr add @georgecht/zod-custom-events

Using a CDN

<!-- Via jsdelivr -->
<script src="https://cdn.jsdelivr.net/npm/zod-custom-events@latest/dist/index.min.js"></script>

<!-- Via unpkg -->
<script src="https://www.unpkg.com/zod-custom-events/dist/index.min.js"></script>

Usage

Here's a basic example of how to use zod-custom-events:

import { z } from 'zod';
import { EventController } from 'zod-custom-events';

// Define your event schema
const userSchema = z.object({
  id: z.number(),
  email: z.email(),
});

// Create an event controller
const userEventController = new EventController(userSchema, 'user-event');

// Subscribe to the event
userEventController.subscribe((event) => {
  console.log('Received user event:', event.detail);
});

// Dispatch an event
userEventController.dispatch({
  id: 123,
  email: '[email protected]',
});

// Cleanup
userEventController.unsubscribe();

API Reference

The API reference is available on GitHub.

EventController

The main class for managing custom events. The EventController<T extends ZodSchema> extends the CustomEvent interface with a detail property of type T. Meaning it will match the CustomEvent interface and infer all the functionality.


👉 Constructor

constructor(schema: T, eventName: string, options?: EventControllerOptions<T>)

Creates a new EventController instance.

Parameters
  • schema - The Zod schema for validating the event payload.
  • eventName - The name of the custom event.
  • options optional - Configuration options for the EventController.
Example
import { z } from 'zod';
import { EventController } from 'zod-custom-events';

const schema = z.object({
  name: z.string(),
});

const controller = new EventController(schema, 'myEvent', {
  onError: ({ error }) => console.error('Validation error:', error),
  onDispatch: ({ payload }) => console.log('Dispatching event with payload:', payload),
});
Available options
  • element optional - The element to bind the event to. Defaults to window.
  • onError optional - Error handler for validation errors.
  • onDispatch optional - Callback function called before dispatching the event.
  • onSubscribe optional - Callback function called when the event listener is added.
  • onUnsubscribe optional - Callback function called when the event listener is removed.

👉 Subscribe

Subscribe to the event.

subscribe(listener: (event: TypedCustomEvent<EventPayload<T>>) => void, options?: AddEventListenerOptions): void
Parameters
  • listener - The function to be called when the event is triggered.
  • options - Optional parameters for the event listener.
Available options
  • once optional - A boolean value indicating that the listener should be invoked at most once after being added. If true, the listener would be automatically removed when invoked.
  • passive optional - A boolean indicating whether the event listener is a passive listener. If set to true, indicates that the function specified by listener will never call preventDefault(). If a passive listener calls preventDefault(), nothing will happen and a console warning may be generated.
  • signal optional - An AbortSignal to signal when the listener should be removed.
Simple example
controller.subscribe((event) => {
  console.log('Received user event:', event.detail);
});
Example with abort signal and once option
// With abort signal and once option
const abortController = new AbortController();
const { signal } = abortController;

controller.subscribe((event) => {
  console.log('Received user event:', event.detail);
}, { signal, once: true });

// Later in the code
abortController.abort();

👉 Unsubscribe

Removes the previously registered event listener for the event.

unsubscribe(options?: EventListenerOptions): void
Parameters
  • options optional - Optional parameters to match the event listener.
Available options
  • capture optional - A boolean value indicating that events of this type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree.
Example
controller.unsubscribe();

👉 Dispatch

Dispatches the event, validating its payload using the Zod schema and applying middleware.

dispatch(payload: EventPayload<T>, eventInitDict?: CustomEventInit<EventPayload<T>>): Promise<void>
Parameters
  • payload - The data associated with the event. Validated against the Zod schema initially provided.
  • eventInitDict optional - Optional parameters for initializing the event.
Available eventInitDict options
  • bubbles optional - A boolean value indicating whether or not the event can bubble through the DOM.
  • cancelable optional - A boolean value indicating whether the event can be cancelled.
  • composed optional - A boolean value indicating whether the event will trigger listeners outside of a shadow root (see Event.composed for more details).
Example
controller.dispatch({
  id: 1,
  name: 'John Doe',
}, {
  bubbles: true
});

👉 Refine

Sets a condition for the event, allowing control over whether the event is dispatched.

refine(condition: (payload: EventPayload<T>) => boolean, callback?: (ctx: EventPayloadContext<T>) => void): void
Parameters
  • condition - A function that takes the event payload as input and returns a boolean.
  • callback optional - An optional callback function to be called when the condition is not met.
Example
controller.refine(
  (payload) => payload.id > 0,
  (ctx) => {
    const { payload } = ctx;
    console.log("Invalid user ID:", payload.id)
  }
);

👉 Update

Updates the EventController options.

update(options: Partial<EventControllerOptions<T>>): void
Parameters
  • options optional - New configuration options for the EventController.
Example
const controller = new EventController(schema, 'myEvent');

// Later in the code
controller.update({
  onError: ({ error }) => console.warn('New error handler:', error),
  onDispatch: ({ payload }) => console.log('New dispatch handler:', payload),
});

👉 Use

Adds a middleware function to the event processing pipeline.

use(middleware: Middleware<EventPayload<T>>): void
Parameters
  • middleware - A function that processes the event context and calls the next middleware.
Example
controller.use(async (ctx, next) => {
  console.log("Processing user event:", ctx.payload);
  await next();
});

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

License

This project is licensed under the MIT License. See the LICENSE file for more details.