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 🙏

© 2026 – Pkg Stats / Ryan Hefner

guardz-event

v1.11.3

Published

Type-safe event handling with runtime validation using guardz for unsafe data from 3rd parties

Downloads

7

Readme

Guardz Event - Safe Event Handling Library

A modern, type-safe event handling library that provides multiple ergonomic APIs for handling browser events with validation, security checks, and error handling. Built on top of guardz 1.11.3 for robust runtime type validation.

🚀 Quick Start

import { onEvent, onMessage, safeHandler } from 'guardz-event';

// Type guard for your data
const isChatMessage = (data: unknown): data is { text: string; userId: string } => {
  return typeof data === 'object' && data !== null && 
         typeof (data as any).text === 'string' && 
         typeof (data as any).userId === 'string';
};

// Simple usage
window.addEventListener('message', onMessage(isChatMessage, {
  onSuccess: (data) => console.log('Received:', data.text),
  onError: (error) => console.error('Error:', error)
}));

// Or even simpler
window.addEventListener('message', safeHandler(isChatMessage, 
  (data) => console.log('Received:', data.text),
  (error) => console.error('Error:', error)
));

📚 API Overview

1. Primary API: onEvent

The main function for creating safe event handlers:

import { onEvent } from 'guardz-event';

// For any event type
const handler = onEvent('message', isChatMessage, {
  onSuccess: (data) => { /* handle success */ },
  onError: (error) => { /* handle error */ },
  tolerance: true,
  allowedOrigins: ['https://trusted.com']
});

window.addEventListener('message', handler);

2. Specialized Handlers

Pre-configured handlers for common event types:

import { onMessage, onClick, onCustom, onStorage } from 'guardz-event';

// Message events
window.addEventListener('message', onMessage(isChatMessage, {
  onSuccess: handleChatMessage
}));

// DOM events
element.addEventListener('click', onClick(isClickData, {
  onSuccess: handleClick
}));

// Custom events
element.addEventListener('user-action', onCustom('user-action', isUserAction, {
  onSuccess: handleUserAction
}));

// Storage events
window.addEventListener('storage', onStorage(isStorageData, {
  onSuccess: handleStorageChange
}));

3. Fluent Builder API

For complex configurations:

import { eventGuard } from 'guardz-event';

const handler = eventGuard()
  .type('message')
  .validate(isChatMessage)
  .onSuccess(handleChatMessage)
  .onError(handleError)
  .tolerance(true)
  .allowedOrigins(['https://trusted.com'])
  .allowedSources(['chat-widget'])
  .build();

window.addEventListener('message', handler);

4. Utility Functions

Quick handlers for common use cases:

import { safeHandler, safeTolerant } from 'guardz-event';

// Minimal configuration
window.addEventListener('message', safeHandler(isChatMessage, handleData, handleError));

// With tolerance mode
window.addEventListener('message', safeTolerant(isChatMessage, handleData, handleError));

5. React Hook (Coming Soon)

import { useEvent } from 'guardz-event';

function ChatComponent() {
  const { data, error } = useEvent('message', isChatMessage, {
    tolerance: true,
    allowedOrigins: ['https://trusted.com']
  });

  if (error) return <div>Error: {error}</div>;
  if (!data) return <div>Loading...</div>;
  
  return <div>Message: {data.text}</div>;
}

🔧 Configuration Options

All APIs support these options:

interface EventOptions<T> {
  onSuccess: (data: T) => void;           // Required: Success callback
  onError?: (message: string) => void;    // Optional: General error handler
  onTypeMismatch?: (message: string) => void; // Optional: Type validation errors
  onSecurityViolation?: (origin: string, message: string) => void; // Optional: Security errors
  tolerance?: boolean;                    // Optional: Enable tolerance mode
  allowedOrigins?: string[];              // Optional: Security: allowed origins
  allowedSources?: string[];              // Optional: Security: allowed sources
  identifier?: string;                    // Optional: Custom identifier for errors
}

🛡️ Security Features

Origin Validation

window.addEventListener('message', onMessage(isChatMessage, {
  onSuccess: handleData,
  allowedOrigins: ['https://trusted-domain.com'],
  onSecurityViolation: (origin, message) => {
    console.warn(`Blocked message from ${origin}: ${message}`);
  }
}));

Source Validation

window.addEventListener('message', onMessage(isChatMessage, {
  onSuccess: handleData,
  allowedSources: ['trusted-widget'],
  onSecurityViolation: (origin, message) => {
    console.warn(`Blocked message from untrusted source: ${message}`);
  }
}));

🔄 Tolerance Mode

Tolerance mode allows partial data to pass through with warnings:

window.addEventListener('message', onMessage(isChatMessage, {
  onSuccess: handleData,
  onTypeMismatch: (error) => console.warn('Partial data:', error),
  tolerance: true
}));

📝 Type Guards

Create type guards for your data structures using Guardz 1.11.3's enhanced type validation:

Basic Type Guards

import { isString, isNumber, isBoolean, isObject } from 'guardz';

// Simple object validation
const isUserData = (data: unknown): data is { id: number; name: string } => {
  return isObject(data) && 
         isNumber((data as any).id) && 
         isString((data as any).name);
};

// Complex validation with nested objects
const isOrderData = (data: unknown): data is {
  id: string;
  items: Array<{ productId: string; quantity: number }>;
  total: number;
} => {
  if (!isObject(data)) return false;
  const order = data as any;
  
  return isString(order.id) &&
         Array.isArray(order.items) &&
         order.items.every((item: any) => 
           isString(item.productId) && 
           isNumber(item.quantity)
         ) &&
         isNumber(order.total);
};

Advanced Type Guards (New in Guardz 1.11.3)

import { isSchema, isShape, isObjectWith, toNumber, toDate } from 'guardz';

// Schema-based validation
const userSchema = {
  id: isNumber,
  name: isString,
  email: isString,
  isActive: isBoolean
};

const isUser = isSchema(userSchema);

// Shape-based validation with transformations
const isOrderWithTransform = isShape({
  id: isString,
  amount: toNumber,  // Automatically converts string to number
  createdAt: toDate, // Automatically converts string to Date
  items: isArrayWithEachItem(isObjectWith({
    productId: isString,
    quantity: isNumber
  }))
});

// Object with specific properties
const isApiResponse = isObjectWith({
  success: isBoolean,
  data: isObject,
  message: isString
});

🔄 Migration from Legacy API

Before (Legacy API)

import { safePostMessageListener } from 'guardz-event';

window.addEventListener('message', safePostMessageListener(isChatMessage, {
  onSuccess: handleData,
  onTypeMismatch: handleTypeError,
  onSecurityViolation: handleSecurityError,
  onError: handleError
}));

After (New API)

import { onMessage } from 'guardz-event';

window.addEventListener('message', onMessage(isChatMessage, {
  onSuccess: handleData,
  onTypeMismatch: handleTypeError,
  onSecurityViolation: handleSecurityError,
  onError: handleError
}));

🆕 What's New in Guardz 1.11.3

This version includes several new features and improvements:

New Type Guards

  • isSchema - Schema-based validation for complex objects
  • isShape - Shape-based validation with automatic data transformation
  • isObjectWith - Validate objects with specific properties
  • isNestedType - Handle nested type validation
  • isIndexSignature - Validate objects with index signatures

New Utility Functions

  • toNumber - Convert and validate numbers from strings
  • toDate - Convert and validate Date objects from strings
  • toBoolean - Convert and validate booleans from various types

Enhanced Validation

  • Better error messages and debugging information
  • Improved performance for complex validations
  • More flexible type checking options

📦 Installation

npm install guardz-event guardz@^1.11.3
# or
yarn add guardz-event guardz@^1.11.3

Note: This library requires guardz version 1.11.3 or higher as a peer dependency for runtime type validation.

📦 Bundle Size

The library is designed to be tree-shakeable. Only the APIs you use will be included in your bundle:

  • Core API only: ~2KB gzipped
  • All APIs: ~5KB gzipped
  • With React hooks: ~6KB gzipped

🎯 Use Cases

1. PostMessage Communication with Data Transformation

import { onMessage } from 'guardz-event';
import { isShape, toNumber, toDate } from 'guardz';

// Handle messages with automatic data transformation
const isOrderMessage = isShape({
  orderId: isString,
  amount: toNumber,      // Converts string to number
  timestamp: toDate,     // Converts string to Date
  items: isArrayWithEachItem(isObjectWith({
    productId: isString,
    quantity: toNumber
  }))
});

window.addEventListener('message', onMessage(isOrderMessage, {
  onSuccess: (data) => {
    // data.amount is now a number, data.timestamp is a Date
    console.log(`Order ${data.orderId}: $${data.amount} at ${data.timestamp}`);
  }
}));

2. API Response Validation

import { onMessage } from 'guardz-event';
import { isSchema, isObjectWith } from 'guardz';

const apiResponseSchema = {
  success: isBoolean,
  data: isObject,
  message: isString
};

const isApiResponse = isSchema(apiResponseSchema);

window.addEventListener('message', onMessage(isApiResponse, {
  onSuccess: (response) => {
    if (response.success) {
      handleApiData(response.data);
    } else {
      showError(response.message);
    }
  }
}));
import { onClick } from 'guardz-event';
import { isShape, isEmail, toNumber } from 'guardz';

// Enhanced form validation with automatic type conversion
const isFormData = isShape({
  email: isEmail,           // Validates email format
  name: isString,
  age: toNumber,            // Converts string to number
  preferences: isObjectWith({
    newsletter: isBoolean,
    notifications: isBoolean
  })
});

form.addEventListener('submit', onClick(isFormData, {
  onSuccess: (data) => {
    // data.age is now a number, data.email is validated
    submitForm(data);
  },
  onTypeMismatch: (error) => showValidationError(error)
}));

4. Custom Events with Schema Validation

import { onCustom } from 'guardz-event';
import { isSchema } from 'guardz';

const userActionSchema = {
  action: isString,
  payload: isObject,
  timestamp: toDate
};

const isUserAction = isSchema(userActionSchema);

document.addEventListener('user-action', onCustom('user-action', isUserAction, {
  onSuccess: (data) => {
    // data.timestamp is now a Date object
    handleUserAction(data.action, data.payload, data.timestamp);
  }
}));

5. Storage Events with Enhanced Validation

import { onStorage } from 'guardz-event';
import { isShape, toNumber, toBoolean } from 'guardz';

const isStorageData = isShape({
  key: isString,
  value: isString,
  oldValue: isString,
  timestamp: toNumber
});

window.addEventListener('storage', onStorage(isStorageData, {
  onSuccess: (data) => {
    // data.timestamp is now a number
    handleStorageChange(data.key, data.value, data.oldValue, data.timestamp);
  }
}));

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

📄 License

MIT License - see LICENSE file for details.