Skip to content

v0.2.1

Release Date: January 19, 2026

This release introduces powerful new guard composition utilities and enhanced debugging for complex dependency trees.


A new way to transform sources directly into guards with full semantic tracking. This replaces the legacy compute for most use cases.

const todos = source([{ done: false }, { done: true }]);
// Reactive guard derived from source
const doneCount = guard.map(todos, (list) => list.filter((t) => t.done).length);
// doneCount works as a full Guard<number>
console.log(doneCount.state()); // { status: "ok", value: 1 }

Extracting types from guards is now seamless with the new InferGuardType utility. Perfect for creating robust TypeScript interfaces.

import { guard, type InferGuardType } from "@pulse-js/core";
const authGuard = guard("auth", async () => fetchUser());
type AuthUser = InferGuardType<typeof authGuard>; // User | undefined

The .explain() tree now includes the specific failure reasons for every sub-dependency, eliminating the guesswork in complex guard chains.

/* New explain() output for a failed guard: */
{
"name": "can-place-order",
"status": "fail",
"reason": "Insufficient balance",
"dependencies": [
{ "name": "has-items", "status": "ok" },
{
"name": "sufficient-balance",
"status": "fail",
"reason": "Balance is too low"
}
]
}

  • guard.map: Native implementation for source transformations
  • Improved explain(): Deep dependency trees now propagate reasons

  • @pulse-js/core: 0.2.1
  • @pulse-js/tools: 0.1.9
  • @pulse-js/react: 0.1.9
  • @pulse-js/vue: 0.1.3
  • @pulse-js/svelte: 0.1.5