ripplex
TypeScript icon, indicating that this package has built-in type declarations

1.0.9 • Public • Published

Ripplex

A lightweight, reactive state management library for React applications with built-in event bus and automatic async state handling.

Installation

npm install ripplex

Quick Start

import { ripple, useRipple, emit, useRippleEffect } from "ripplex";

// Create reactive state
const counterStore = {
  count: ripple(0),
  loading: ripple(false),
  error: ripple(null),
};

function Counter() {
  const count = useRipple(counterStore.count);
  const loading = useRipple(counterStore.loading);

  // Handle async operations with auto loading/error states
  useRippleEffect(
    "increment:async",
    async () => {
      await new Promise((resolve) => setTimeout(resolve, 1000));
      counterStore.count.value += 1;
    },
    counterStore // Auto-handles loading and error
  );

  return (
    <div>
      <h2>{count}</h2>
      <button onClick={() => emit("increment:async")}>
        {loading ? "Loading..." : "+1 Async"}
      </button>
      <button onClick={() => (counterStore.count.value -= 1)}>-1</button>
    </div>
  );
}

Core Concepts

Reactive State with ripple()

Create reactive state that automatically triggers React re-renders:

const userStore = {
  name: ripple(""),
  isLoggedIn: ripple(false),
};

React Integration with useRipple()

Subscribe to state changes in React components:

function UserProfile() {
  const name = useRipple(userStore.name);
  const isLoggedIn = useRipple(userStore.isLoggedIn);

  return <div>{isLoggedIn ? `Hello ${name}` : "Please login"}</div>;
}

Event-Driven Architecture

Decouple your application logic using events:

import { emit, on } from "ripple";

// Listen for events
on("user:login", (userData) => {
  userStore.name.value = userData.name;
  userStore.isLoggedIn.value = true;
});

// Emit events from anywhere
emit("user:login", { name: "John" });

Automatic Async State Management

Handle loading and error states automatically:

const todoStore = {
  todos: ripple([]),
  loading: ripple(false),
  error: ripple(null),
};

// Async operations with auto-managed loading/error states
useRippleEffect(
  "fetch:todos",
  async () => {
    const response = await fetch("/api/todos");
    const data = await response.json();
    todoStore.todos.value = data;
  },
  todoStore // Automatically manages loading and error signals
);

// Trigger from UI
emit("fetch:todos");

API Reference

Core Functions

  • ripple(initialValue) - Create a reactive signal
  • useRipple(signal) - React hook to subscribe to a signal
  • emit(event, payload?) - Emit an event
  • on(event, handler) - Listen for events
  • useRippleEffect(event, asyncHandler, store?) - Handle async events with auto state management

Signal Properties

const signal = ripple(0);

signal.value = 10; // Set value
const current = signal.value; // Get value
const peek = signal.peek(); // Get without subscribing

Store Pattern

Organize related state in store objects:

const appStore = {
  // Data
  user: ripple(null),
  todos: ripple([]),

  // UI State
  loading: ripple(false),
  error: ripple(null),

  // Computed values can be derived in components
  // or using external computed libraries
};

// Use throughout your app
function App() {
  const user = useRipple(appStore.user);
  const loading = useRipple(appStore.loading);

  useRippleEffect(
    "load:user",
    async (userId) => {
      const response = await fetch(`/api/users/${userId}`);
      const userData = await response.json();
      appStore.user.value = userData;
    },
    appStore
  );

  return (
    <div>
      {loading ? "Loading..." : user?.name}
      <button onClick={() => emit("load:user", 123)}>Load User</button>
    </div>
  );
}

TypeScript Support

Ripple provides full TypeScript support:

interface User {
  id: number;
  name: string;
}

const userStore = {
  currentUser: ripple<User | null>(null),
  users: ripple<User[]>([]),
};

Why Ripplex?

  • Simple: Minimal API with maximum power
  • Reactive: Automatic React integration with useRipple
  • Event-driven: Decouple logic with built-in event system
  • Async-friendly: Automatic loading and error state management
  • TypeScript: Full type safety out of the box
  • Lightweight: Small bundle size, zero dependencies

Package Sidebar

Install

npm i ripplex

Weekly Downloads

368

Version

1.0.9

License

MIT

Unpacked Size

24.6 kB

Total Files

6

Last publish

Collaborators

  • rk_92