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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@cobeo2004/proof-sub

v0.0.5

Published

A production-ready, real-time, type-safe publish-subscribe system with dynamic schema loading, automatic client code generation, and **full Node.js compatibility**.

Readme

🚀 ProofSub - A real-time, type-safe, dynamic pubsub system with auto-generated client code

A production-ready, real-time, type-safe publish-subscribe system with dynamic schema loading, automatic client code generation, and full Node.js compatibility.

✨ Features

  • 🔄 Dynamic Schema Loading: Automatically watches for changes in your schema definitions
  • 📋 Auto Code Generation: Generates complete TypeScript client code with types and interfaces
  • 🔗 Real-time Updates: Broadcasts schema changes to all connected clients instantly
  • 🛡️ Type Safety: Full TypeScript support with Zod validation
  • Hot Reload: No server restart needed when schemas change
  • 🏗️ Auto-Setup: Creates schema files and directories automatically
  • 🎯 Auto-Emit: Server automatically emits events based on defined schemas
  • 📦 Easy SDK: Simple SDK that generates client code for you
  • 🔧 Robust Error Handling: Comprehensive error messages and validation
  • 📊 Health Monitoring: Built-in health checks and statistics
  • 🖥️ CLI Tool: Command-line interface for easy client generation
  • 🟢 Node.js Compatible: Works seamlessly in Node.js, Bun, and Browser environments

🚀 Quick Start (2 steps!)

1. Start the Server (Bun)

bun run start:example-server

The server will automatically:

  • ✅ Create ./proofsub/schema.ts (or path that you specify) if it doesn't exist
  • ✅ Start watching for schema changes
  • ✅ Set up type-safe event emitters

2. Generate & Use Client (Node.js or Bun)

For Node.js:

# Install Node.js dependencies
npm run install:node

# Generate client for Node.js
npm run generate:example-client

# Use in your Node.js project
// Node.js JavaScript
const { PubSubClient } = require("./generated.js");

const client = new PubSubClient("ws://localhost:3000");
await client.connect();

await client.subscribe("example.event", (data) => {
  console.log("Event:", data.name);
});

await client.publish("example.event", {
  id: "test-123",
  name: "Hello from Node.js!",
  createdAt: new Date(),
});

For TypeScript (Node.js):

// Node.js TypeScript
import { PubSubClient } from "./generated";

const client = new PubSubClient("ws://localhost:3000", {
  debug: true,
  maxReconnectAttempts: 5,
});

await client.connect();

// Full type safety!
await client.subscribe("example.event", (data) => {
  console.log("Event:", data.name); // TypeScript knows data.name exists!
});

🟢 Node.js Setup

Install Dependencies

# For Node.js users
npm run install:node

# Or manually
npm install ws @types/ws tsx esbuild-register

Generate Client for Node.js

# Generate JavaScript client
npm run generate -- -o ./generated.js

# Generate TypeScript client
npm run generate -- -o ./generated.ts

# Watch for changes (Node.js)
npm run generate:node -- --watch

🎯 SDK Usage

The SDK works identically in both Node.js and Bun environments:

Generate Once

# Bun
bun run generate

# Node.js
npm run generate:node

# Custom output for Node.js
npm run generate:node -- -o ./src/pubsub-client.js

Watch for Changes

# Bun
bun run generate:watch

# Node.js
npm run generate:node -- --watch --debug

Programmatic Usage (Node.js)

import { generatePubSubClientOnce } from "./sdk/pubsub-sdk";

// Works in Node.js with 'ws' package
await generatePubSubClientOnce("ws://localhost:3000", "./my-client.ts");

🎮 Examples

Node.js Examples

# Terminal 1: Start server (Bun)
bun run start

# Terminal 2: Run Node.js JavaScript example
npm run example:node

# Terminal 3: Run Node.js TypeScript example
npm run example:node-ts

Cross-Platform Workflow

# Server (Bun)
bun run start

# Client Generation (Node.js)
npm run generate:node -- --watch

# Your Node.js Application
node your-app.js  # Uses ./generated.js

🔧 Environment Compatibility

| Environment | Server | SDK | Generated Client | | ----------- | ---------- | ------------------- | ---------------- | | Bun | ✅ Primary | ✅ Native | ✅ Full Support | | Node.js | ✅ | ✅ With ws | ✅ Full Support | | Deno | ✅ | ✅ With ws | ✅ Full Support | | Browser | ❌ | ✅ Native WebSocket | ✅ Full Support |

WebSocket Dependencies

The system automatically detects your environment:

  • Browser: Uses native WebSocket
  • Bun: Uses native WebSocket support
  • Node.js: Uses ws package (install with npm install ws)

🛠️ Generated Client Features

The generated client works identically across all environments:

// Generated client features (same API everywhere)
export class PubSubClient {
  constructor(serverUrl: string, config?: PubSubClientConfig);

  // Connection management
  async connect(): Promise<void>;
  disconnect(): void;
  isConnected(): boolean;

  // Type-safe pub/sub
  async subscribe<T>(
    event: T,
    callback: (data: EventTypes[T]) => void
  ): Promise<PubSubSubscription>;
  async publish<T>(event: T, data: EventTypes[T]): Promise<void>;
  async unsubscribe(subscriptionId: string): Promise<void>;

  // Utilities
  getStatus(): ClientStatus;
  getActiveSubscriptions(): string[];

  // Auto-generated typed methods (based on your schemas)
  async subscribeExampleEvent(
    callback: (data: ExampleEventEvent) => void
  ): Promise<PubSubSubscription>;
  async publishExampleEvent(data: ExampleEventEvent): Promise<void>;
}

🖥️ CLI Commands

Works with both Bun and Node.js:

# Bun
bun run generate                    # Basic generation
bun run generate:watch             # Watch for schema changes
bun run generate:debug             # Watch with debug logging

# Node.js
npm run generate:node              # Basic generation
npm run generate:node -- --watch   # Watch for schema changes
npm run generate:node -- --debug   # Debug logging

# CLI options (same for both)
--server <url>     # WebSocket server URL
--output <path>    # Output path for generated client
--watch           # Watch for schema changes
--debug           # Enable debug logging

🏗️ How It Works

1. Server (Bun Only)

📁 Created directory: ./proofsub
📄 Created default schema file: ./proofsub/schema.ts
✅ Schemas loaded successfully: example.event
👀 Watching schema file: ./proofsub/schema.ts
🚀 PubSub server running on http://localhost:3000

2. Client Generation (Node.js or Bun)

🚀 PubSub Client Generator
📡 Server: ws://localhost:3000
📁 Output: ./generated.js
🔧 Generating client code...
✅ Client code generated successfully!

3. Universal Client Usage

The generated client works the same everywhere:

// Works in Node.js, Bun, and Browser
const client = new PubSubClient("ws://localhost:3000");
await client.connect();
// ... same API everywhere

📊 Monitoring & Health Checks

Health Endpoint

curl http://localhost:3000/health

Response:

{
  "connectedClients": 3,
  "availableEvents": ["example.event"],
  "totalEvents": 1,
  "uptime": 1234.56
}

🔧 Message Types

| Type | Direction | Description | | --------------- | --------------- | -------------------------- | | get_schema | SDK → Server | Request latest schema | | schema_update | Server → SDK | Schema/code update | | subscribe | Client → Server | Subscribe to an event | | unsubscribe | Client → Server | Unsubscribe from an event | | publish | Client → Server | Publish an event with data | | event | Server → Client | Subscribed event data | | error | Server → Client | Error with details |

📁 File Structure

├── server/                    # Bun server
│   ├── index.ts              # Main server entry point
│   ├── pubsub-server.ts      # Robust PubSub server class
│   ├── schema-loader.ts      # Dynamic schema loading & watching
│   ├── code-generator.ts     # Client code generation
│   └── event-emitter-2.ts    # Type-safe event emitter
├── sdk/                      # Universal SDK (Node.js + Bun)
│   └── pubsub-sdk.ts         # Code generator SDK
├── cli/                      # Universal CLI
│   └── generate-client.ts    # CLI tool for client generation
├── examples/                 # Platform-specific examples
│   ├── node-simple-client.js      # Node.js JavaScript example
│   └── node-typescript-client.ts  # Node.js TypeScript example
├── proofsub/
│   └── schema.ts            # Your event schemas (auto-created)
├── generated.ts             # Auto-generated TypeScript client
├── generated.js             # Auto-generated JavaScript client
└── README.md               # This file

🎮 Complete Examples

Node.js JavaScript Example

// examples/node-simple-client.js
const { generatePubSubClientOnce } = require("../sdk/pubsub-sdk.ts");

async function main() {
  // Generate client
  await generatePubSubClientOnce("ws://localhost:3000", "./generated.js");

  // Use generated client
  const { PubSubClient } = require("../generated.js");
  const client = new PubSubClient("ws://localhost:3000");

  await client.connect();

  await client.subscribe("example.event", (data) => {
    console.log("Received:", data);
  });

  await client.publish("example.event", {
    id: "test",
    name: "Hello Node.js!",
    createdAt: new Date(),
  });
}

Node.js TypeScript Example

// examples/node-typescript-client.ts
import { generatePubSubClientOnce } from "../sdk/pubsub-sdk";

async function main() {
  await generatePubSubClientOnce("ws://localhost:3000", "./generated.ts");

  const { PubSubClient } = await import("../generated.ts");
  const client = new PubSubClient("ws://localhost:3000", {
    debug: true,
    maxReconnectAttempts: 5,
  });

  await client.connect();
  // ... full type safety!
}

🚨 Error Handling

Node.js Specific Errors

❌ WebSocket not available. In Node.js, please install the "ws" package: npm install ws @types/ws

💡 Solution:
npm run install:node

Schema Validation Errors

// Same error format across all environments
{
  "type": "error",
  "message": "Validation error for event 'example.event'",
  "details": {
    "errors": [...],
    "receivedData": {...}
  }
}

🔒 Production Ready

Cross-Platform Deployment

# Server (Bun)
bun run build
bun run dist/index.js

# Client Generation (Node.js CI/CD)
npm run generate:node -- --output ./dist/pubsub-client.js

# Your Node.js Application
node dist/your-app.js

Resource Cleanup

  • Automatic client cleanup on disconnect
  • Memory leak prevention
  • File watcher cleanup
  • Event listener cleanup
  • Cross-platform compatibility

📈 Performance

  • Minimal Memory Footprint: Efficient event handling
  • Fast Schema Reloading: < 100ms schema updates
  • Concurrent Connections: Handles hundreds of clients
  • Type-Safe: Zero runtime type checking overhead
  • Fast Generation: Client code generated in milliseconds
  • Universal: Same performance across Node.js, Bun, and Browser

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Test on both Node.js and Bun
  5. Submit a pull request

📝 Roadmap

  • [ ] Add authentication string for both client and server
  • [ ] Add support for multi-server instances
  • [x] Add further support for different environments (e.g. Deno, Cloudflare Workers, etc.)
  • [x] Add more Zod types, especially for zod-form-data (deprecated, instead make compatible with zod-v4),
  • [ ] Ping every 10 seconds to keep the connection alive
  • [ ] Generate Python Client Code

📄 License

MIT License - see LICENSE file for details


Ready to build real-time, type-safe applications across all JavaScript environments? 🚀

# Server (Bun)
bun run start

# Client (Node.js)
npm run install:node
npm run generate:node
node your-app.js

# Client (Bun)
bun run generate
bun run your-app.ts