{"id":19872561,"url":"https://github.com/georgecht/zod-custom-events","last_synced_at":"2026-01-25T07:32:42.407Z","repository":{"id":257827315,"uuid":"872920356","full_name":"GeorgeCht/zod-custom-events","owner":"GeorgeCht","description":"Type safe, framework agnostic, Zod based, custom events extension library.","archived":false,"fork":false,"pushed_at":"2024-11-18T09:20:14.000Z","size":2152,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-02T09:48:56.712Z","etag":null,"topics":["custom-events","dispatcher","emmiter","eventlistener","events","lit-element","middleware","react","typescript","zod","zod-validation","zod-validators"],"latest_commit_sha":null,"homepage":"https://jsr.io/@georgecht/zod-custom-events","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GeorgeCht.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-15T09:53:41.000Z","updated_at":"2024-11-18T09:20:16.000Z","dependencies_parsed_at":"2024-10-15T15:45:45.979Z","dependency_job_id":"cadd15e1-3aba-436a-bea6-2e0e33846e54","html_url":"https://github.com/GeorgeCht/zod-custom-events","commit_stats":null,"previous_names":["georgecht/zod-custom-events"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/GeorgeCht/zod-custom-events","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GeorgeCht%2Fzod-custom-events","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GeorgeCht%2Fzod-custom-events/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GeorgeCht%2Fzod-custom-events/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GeorgeCht%2Fzod-custom-events/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GeorgeCht","download_url":"https://codeload.github.com/GeorgeCht/zod-custom-events/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GeorgeCht%2Fzod-custom-events/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28747543,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T05:12:38.112Z","status":"ssl_error","status_checked_at":"2026-01-25T05:04:50.338Z","response_time":113,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["custom-events","dispatcher","emmiter","eventlistener","events","lit-element","middleware","react","typescript","zod","zod-validation","zod-validators"],"created_at":"2024-11-12T16:15:57.428Z","updated_at":"2026-01-25T07:32:42.393Z","avatar_url":"https://github.com/GeorgeCht.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\r\n\r\n# Zod Custom Events\r\n\r\nType safe, framework agnostic, Zod based, custom events extension library.\r\n\r\n[![NPM Version](https://img.shields.io/npm/v/zod-custom-events.svg?style=flat-square)](https://www.npmjs.com/package/zod-custom-events)\r\n[![JSR Version](https://jsr.io/badges/@georgecht/zod-custom-events)](https://jsr.io/@georgecht/zod-custom-events)\r\n[![JSR Score](https://jsr.io/badges/@georgecht/zod-custom-events/score)](https://jsr.io/@georgecht/zod-custom-events)\r\n[![CI](https://img.shields.io/github/actions/workflow/status/georgecht/zod-custom-events/release.yml?style=flat-square)](https://github.com/georgecht/zod-custom-events/actions/workflows/release.yml)\r\n[![Codecov](https://codecov.io/github/GeorgeCht/zod-custom-events/graph/badge.svg?token=X8MC11L7NV)](https://codecov.io/github/GeorgeCht/zod-custom-events)\r\n[![Checked with Biome](https://img.shields.io/badge/checked_with-biome-60a5fa?style=flat\u0026logo=biome)](https://biomejs.dev)\r\n\r\n[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=flat-square)](http://commitizen.github.io/cz-cli/)\r\n[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/georgecht/zod-custom-events/blob/master/LICENSE)\r\n[![NPM Bundle Size](https://img.shields.io/bundlephobia/min/zod-custom-events)](https://bundlephobia.com/package/zod-custom-events@latest)\r\n[![npm](https://img.shields.io/npm/dm/zod-custom-events.svg)](https://www.npmjs.org/package/zod-custom-events)\r\n\r\n\u003c/div\u003e\r\n\r\n\r\n\r\n- ✅ Utilize the full controll of [`CustomEvents`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) with a custom API\r\n- ✅ End-to-end type safety; validate event payload at runtime via your provided [`Zod`](https://github.com/colinhacks/zod) schema\r\n- ✅ Framework agnostic; runs on any `JavaScript` environment\r\n- ✅ Supports all [`CustomEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) native properties and methods inherited by the [`Event`](https://developer.mozilla.org/en-US/docs/Web/API/Event) interface\r\n- ✅ Middleware support for event processing\r\n- ✅ Less than __1kb__ minified and gzipped\r\n\r\n## Table of Contents\r\n\r\n* [Installation](#installation)\r\n  * [Prerequisites](#prerequisites)\r\n  * [Using NPM](#using-npm)\r\n  * [Using JSR](#using-jsr)\r\n  * [Using a CDN](#using-a-cdn)\r\n* [Usage](#usage)\r\n* [API Reference](#api-reference)\r\n  * [EventController](#eventcontroller)\r\n* [Contributing](#contributing)\r\n* [License](#license)\r\n\r\n## Preview\r\n\r\n\u003cimg src=\"./.github/assets/example.png\" width=\"1024px\" alt=\"example\" /\u003e\r\n\r\n## Installation\r\n\r\n### Prerequisites\r\n\r\n- [Zod](https://github.com/colinhacks/zod)\r\n\r\nInstall zod-custom-events using your favorite package manager or CDN, then include it in your project:\r\n\r\n### Using NPM\r\n\r\n```bash\r\n# Install with npm\r\nnpm install zod-custom-events\r\n\r\n# Install with pnpm\r\npnpm add zod-custom-events\r\n\r\n# Install with yarn\r\nyarn add zod-custom-events\r\n\r\n# Install with bun\r\nbun add zod-custom-events\r\n```\r\n\r\n### Using JSR\r\n\r\n```bash\r\n# Install in a node project\r\nnpx jsr add @georgecht/zod-custom-events\r\n\r\n# Install in a deno project\r\ndeno add jsr:@georgecht/zod-custom-events\r\n\r\n# Install in a bun project\r\nbunx jsr add @georgecht/zod-custom-events\r\n```\r\n\r\n### Using a CDN\r\n\r\n```html\r\n\u003c!-- Via jsdelivr --\u003e\r\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/zod-custom-events@latest/dist/index.min.js\"\u003e\u003c/script\u003e\r\n\r\n\u003c!-- Via unpkg --\u003e\r\n\u003cscript src=\"https://www.unpkg.com/zod-custom-events/dist/index.min.js\"\u003e\u003c/script\u003e\r\n```\r\n\r\n## Usage\r\n\r\nHere's a basic example of how to use zod-custom-events:\r\n\r\n```typescript\r\nimport { z } from 'zod';\r\nimport { EventController } from 'zod-custom-events';\r\n\r\n// Define your event schema\r\nconst userSchema = z.object({\r\n  id: z.number(),\r\n  email: z.email(),\r\n});\r\n\r\n// Create an event controller\r\nconst userEventController = new EventController(userSchema, 'user-event');\r\n\r\n// Subscribe to the event\r\nuserEventController.subscribe((event) =\u003e {\r\n  console.log('Received user event:', event.detail);\r\n});\r\n\r\n// Dispatch an event\r\nuserEventController.dispatch({\r\n  id: 123,\r\n  email: 'my@email.com',\r\n});\r\n\r\n// Cleanup\r\nuserEventController.unsubscribe();\r\n```\r\n\r\n## API Reference\r\n\r\nThe API reference is available on [GitHub](https://github.com/GeorgeCht/zod-custom-events/blob/main/README.md#api-reference).\r\n\r\n### EventController\r\n\r\nThe main class for managing custom events. The `EventController\u003cT extends ZodSchema\u003e` extends the `CustomEvent` interface with a `detail` property of type `T`. Meaning it will match the [`CustomEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) interface and infer all the functionality.\r\n\r\n---\r\n\r\n#### 👉 Constructor\r\n\r\n```typescript\r\nconstructor(schema: T, eventName: string, options?: EventControllerOptions\u003cT\u003e)\r\n```\r\n\r\nCreates a new `EventController` instance.\r\n\r\n##### Parameters\r\n\r\n- `schema` - The Zod schema for validating the event payload.\r\n- `eventName` - The name of the custom event.\r\n- `options` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - Configuration options for the `EventController`.\r\n\r\n##### Example\r\n\r\n```typescript\r\nimport { z } from 'zod';\r\nimport { EventController } from 'zod-custom-events';\r\n\r\nconst schema = z.object({\r\n  name: z.string(),\r\n});\r\n\r\nconst controller = new EventController(schema, 'myEvent', {\r\n  onError: ({ error }) =\u003e console.error('Validation error:', error),\r\n  onDispatch: ({ payload }) =\u003e console.log('Dispatching event with payload:', payload),\r\n});\r\n```\r\n\r\n##### Available options\r\n\r\n- `element` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - The element to bind the event to. Defaults to `window`.\r\n- `onError` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - Error handler for validation errors.\r\n- `onDispatch` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - Callback function called before dispatching the event.\r\n- `onSubscribe` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - Callback function called when the event listener is added.\r\n- `onUnsubscribe` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - Callback function called when the event listener is removed.\r\n\r\n---\r\n\r\n#### 👉 Subscribe\r\n\r\nSubscribe to the event.\r\n\r\n```typescript\r\nsubscribe(listener: (event: TypedCustomEvent\u003cEventPayload\u003cT\u003e\u003e) =\u003e void, options?: AddEventListenerOptions): void\r\n```\r\n\r\n##### Parameters\r\n\r\n- `listener` - The function to be called when the event is triggered.\r\n- `options` - Optional parameters for the event listener.\r\n\r\n##### Available options\r\n\r\n- `once` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - A boolean value indicating that the `listener` should be invoked at most [`once`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#once) after being added. If `true`, the `listener` would be automatically removed when invoked.\r\n- `passive` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - A boolean indicating whether the event listener is a [`passive`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#passive) listener. If set to `true`, indicates that the function specified by listener will never call [`preventDefault()`](https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault). If a passive listener calls `preventDefault()`, nothing will happen and a console warning may be generated.\r\n- `signal` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - An [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) to signal when the listener should be removed.\r\n\r\n##### Simple example\r\n\r\n```typescript\r\ncontroller.subscribe((event) =\u003e {\r\n  console.log('Received user event:', event.detail);\r\n});\r\n```\r\n\r\n##### Example with abort signal and once option\r\n\r\n```typescript\r\n// With abort signal and once option\r\nconst abortController = new AbortController();\r\nconst { signal } = abortController;\r\n\r\ncontroller.subscribe((event) =\u003e {\r\n  console.log('Received user event:', event.detail);\r\n}, { signal, once: true });\r\n\r\n// Later in the code\r\nabortController.abort();\r\n```\r\n\r\n---\r\n\r\n#### 👉 Unsubscribe\r\n\r\nRemoves the previously registered event listener for the event.\r\n\r\n```typescript\r\nunsubscribe(options?: EventListenerOptions): void\r\n```\r\n\r\n##### Parameters\r\n\r\n- `options` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - Optional parameters to match the event listener.\r\n\r\n##### Available options\r\n- `capture` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - 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.\r\n\r\n##### Example\r\n\r\n```typescript\r\ncontroller.unsubscribe();\r\n```\r\n\r\n---\r\n\r\n#### 👉 Dispatch\r\n\r\nDispatches the event, validating its payload using the Zod schema and applying middleware.\r\n\r\n```typescript\r\ndispatch(payload: EventPayload\u003cT\u003e, eventInitDict?: CustomEventInit\u003cEventPayload\u003cT\u003e\u003e): Promise\u003cvoid\u003e\r\n```\r\n\r\n##### Parameters\r\n\r\n- `payload` - The data associated with the event. Validated against the `Zod` schema initially provided.\r\n- `eventInitDict` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - Optional parameters for initializing the event.\r\n\r\n##### Available `eventInitDict` options\r\n\r\n- `bubbles` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - A boolean value indicating whether or not the event can bubble through the DOM.\r\n- `cancelable` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - A boolean value indicating whether the event can be cancelled.\r\n- `composed` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - A boolean value indicating whether the event will trigger listeners outside of a shadow root (see [`Event.composed`](https://developer.mozilla.org/en-US/docs/Web/API/Event/composed) for more details).\r\n\r\n##### Example\r\n\r\n```typescript\r\ncontroller.dispatch({\r\n  id: 1,\r\n  name: 'John Doe',\r\n}, {\r\n  bubbles: true\r\n});\r\n```\r\n\r\n---\r\n\r\n#### 👉 Refine\r\n\r\nSets a condition for the event, allowing control over whether the event is dispatched.\r\n\r\n```typescript\r\nrefine(condition: (payload: EventPayload\u003cT\u003e) =\u003e boolean, callback?: (ctx: EventPayloadContext\u003cT\u003e) =\u003e void): void\r\n```\r\n\r\n##### Parameters\r\n\r\n- `condition` - A function that takes the event payload as input and returns a boolean.\r\n- `callback` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - An optional callback function to be called when the condition is not met.\r\n\r\n##### Example\r\n\r\n```typescript\r\ncontroller.refine(\r\n  (payload) =\u003e payload.id \u003e 0,\r\n  (ctx) =\u003e {\r\n    const { payload } = ctx;\r\n    console.log(\"Invalid user ID:\", payload.id)\r\n  }\r\n);\r\n```\r\n\r\n---\r\n\r\n#### 👉 Update\r\n\r\nUpdates the `EventController` options.\r\n\r\n```typescript\r\nupdate(options: Partial\u003cEventControllerOptions\u003cT\u003e\u003e): void\r\n```\r\n\r\n##### Parameters\r\n\r\n- `options` \u003cspan style=\"font-size: 0.833rem; border: 1px solid; border-radius: 4rem; padding: .125rem .375rem;\"\u003eoptional\u003c/span\u003e - New configuration options for the `EventController`.\r\n\r\n##### Example\r\n\r\n```typescript\r\nconst controller = new EventController(schema, 'myEvent');\r\n\r\n// Later in the code\r\ncontroller.update({\r\n  onError: ({ error }) =\u003e console.warn('New error handler:', error),\r\n  onDispatch: ({ payload }) =\u003e console.log('New dispatch handler:', payload),\r\n});\r\n```\r\n\r\n---\r\n\r\n#### 👉 Use\r\n\r\nAdds a middleware function to the event processing pipeline.\r\n\r\n```typescript\r\nuse(middleware: Middleware\u003cEventPayload\u003cT\u003e\u003e): void\r\n```\r\n\r\n##### Parameters\r\n\r\n- `middleware` - A function that processes the event context and calls the next middleware.\r\n\r\n##### Example\r\n\r\n```typescript\r\ncontroller.use(async (ctx, next) =\u003e {\r\n  console.log(\"Processing user event:\", ctx.payload);\r\n  await next();\r\n});\r\n```\r\n\r\n## Contributing\r\n\r\nContributions are welcome! Please open an issue or submit a pull request.\r\n\r\n## License\r\n\r\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeorgecht%2Fzod-custom-events","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeorgecht%2Fzod-custom-events","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeorgecht%2Fzod-custom-events/lists"}