Skip to content

@stephansama packages / @stephansama/typed-events

@stephansama/typed-events

Source codeDocumentationNPM Versionnpm downloads

Typed events store using standard schema

Table of contents
Open Table of contents

Installation

sh
pnpm install @stephansama/typed-events

Usage

createEvent

create a typed CustomEvent using a standard-schema compatible validator

open example
javascript
import { createEvent } from "@stephansama/typed-events";

export const customAnimationEvent = createEvent(
  "custom-animation-event",
  z.object({
    x: z.number(),
    y: z.number(),
  }),
);

somewhere in your codebase

javascript
export function listenForAnimationEvent() {
  const item = document.getElementById("item");

  const cleanup = customAnimationEvent.listen((event) => {
    item.style.x = event.data.x;
    item.style.y = event.data.y;
  });

  return () => cleanup();
}

somewhere else in your codebase

javascript
export function dispatchEvent() {
  const x = document.getElementById("x");
  const y = document.getElementById("y");

  const button = document.getElementById("button");

  button.addEventListener("click", () => {
    customAnimationEvent.dispatch({
      x: +x.innerText,
      y: +y.innerText,
    });
  });
}

createEventMap

open example
javascript
import { createEventMap } from "@stephansama/typed-events";

export const eventMap = createEventMap("event-map", {
  reset: z.object({}),
  update: z.object({ value: z.number() }),
});

somewhere in your codebase

javascript
export function listenForEventMap() {
  const value = document.getElementById("value");

  const cleanup = eventMap.listen("update", (message) => {
    value.textContent = message.data.value;
  });

  return () => cleanup();
}

somewhere else in your codebase

javascript
export function dispatchEventMap() {
  const button = document.getElementById("button");

  button.addEventListener("click", () => {
    eventMap.dispatch("update", {
      value: Math.floor(Math.random() * 100),
    });
  });
}

createBroadcastChannel

create a typed BroadcastChannel using a standard-schema compatible validator

open example
javascript
import { createBroadcastChannel } from "@stephansama/typed-events";

export const channel = createBroadcastChannel("broadcaster", {
  reset: z.object({}),
  update: z.object({ value: z.number() }),
});

somewhere in your codebase

javascript
export function listenForChannelMessage() {
  const value = document.getElementById("value");

  const cleanup = channel.listen("update", (message) => {
    value.textContent = message.data.value;
  });

  return () => cleanup();
}

somewhere else in your codebase

javascript
export function dispatchChannelMessage() {
  const button = document.getElementById("button");

  button.addEventListener("click", () => {
    channel.dispatch("update", {
      value: Math.floor(Math.random() * 100),
    });
  });
}

createBroadcastEvent

create a typed BroadcastChannel and CustomEvent using a standard-schema compatible validator

open example
javascript
import { createBroadcastEvent } from "@stephansama/typed-events";

export const broadcastEvent = createBroadcastEvent("broadcaster", {
  reset: z.object({}),
  update: z.object({ value: z.number() }),
});

somewhere in your codebase

javascript
export function listenForBroadcastEvent() {
  const value = document.getElementById("value");

  const cleanup = broadcastEvent.listen("update", (message) => {
    value.textContent = message.data.value;
  });

  return () => cleanup();
}

somewhere else in your codebase

javascript
export function dispatchBroadcastEvent() {
  const button = document.getElementById("button");

  button.addEventListener("click", () => {
    broadcastEvent.dispatch("update", {
      value: Math.floor(Math.random() * 100),
    });
  });
}

createMessage

create a typed MessageEvent using a standard-schema compatible validator

open example
javascript
import { createMessage } from "@stephansama/typed-events";

export const message = createMessage("event-map", {
  reset: z.object({}),
  update: z.object({ value: z.number() }),
});

somewhere in your codebase

javascript
export function listenForMessage() {
  const value = document.getElementById("value");

  const cleanup = message.listen("update", (message) => {
    value.textContent = message.data.value;
  });

  return () => cleanup();
}

somewhere else in your codebase

javascript
export function dispatchMessage() {
  const button = document.getElementById("button");

  button.addEventListener("click", () => {
    message.dispatch("update", {
      value: Math.floor(Math.random() * 100),
    });
  });
}

React

you can use useListener or useListeners to automatically register and cleanup typed event listeners

open example
javascript
import { useListeners } from "../dist/react.cjs";

const map = createBroadcastEvent("react-example", {
  first: z.object({}),
  second: z.object({ payload: z.number() }),
});

export function ExampleComponent() {
  useListeners(map, {
    first: () => console.info("first event happened"),
    second: ({ data }) => console.info(data.payload),
  });

  return; // more jsx...
}

References

Modules

ModuleDescription

broadcast

broadcast-event

errors

event

event-map

index

message

react

utils

Released under MIT license