Skip to content

Latest commit

 

History

History
79 lines (53 loc) · 1.82 KB

File metadata and controls

79 lines (53 loc) · 1.82 KB

pulse logo pulse

Reacts where you watch.
Deep, exact-path reactivity for plain objects and arrays.

Concept

pulse is an exact-path reactive runtime for plain objects and arrays. It keeps reads, writes, and subscriptions scoped to the concrete node you access, while preserving normal property and index navigation for reachable child nodes.

Install

pnpm add @ochairo/pulse

Quick Start

import { pulse } from "@ochairo/pulse";
import type { User } from "./types";

const users = pulse<User[]>([
  { name: "Mary", age: 30 },
  { name: "Chloe", age: 25 },
]);

// Write through navigation.
users[0]?.name.set("Lois");

// Reads stay scoped to the exact path.
console.log(users[0]?.name.get());

// Exact listeners stay scoped to the exact path too.
users[0]?.prop("name").on((event) => {
  console.log(event.currentValue);
});

// Object branches also stay exact.
const state = pulse({ users: { basic: { name: "John" } } });

state.users.basic.prop("name").on((event) => {
  console.log(event.currentValue);
});

users[0]?.name.on((event) => {
  console.log(event.currentValue);
});

// Ancestor listeners do not fire for descendant-only changes.
state.users.on(() => {
  console.log("only fires when users itself changes");
});

pulse stays explicit by design:

  • get() reads exactly the node you access
  • set() writes exactly the node you access
  • on() subscribes only to that exact node
  • ancestor replacement can still notify a descendant if the descendant value actually changed

Documentation