CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-legendapp--state

A super fast and powerful state management library for JavaScript and React applications with proxy-based observables and fine-grained reactivity

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

core-observables.mddocs/

Core Observables

Core observable creation and manipulation functions for reactive state management. These functions form the foundation of Legend State's reactive system.

Capabilities

Observable Creation

Creates observables from values with proxy-based reactivity.

/**
 * Creates an observable from any value with automatic proxy wrapping
 * @param value - Initial value for the observable
 * @returns Observable wrapper around the value
 */
function observable<T>(value?: T): Observable<T>;
/**
 * Creates an observable from a Promise value
 * @param value - Promise to wrap in observable
 * @returns Observable that includes loading state
 */
function observable<T>(value: Promise<T>): Observable<T & WithState>;

/**
 * Creates a primitive observable that wraps a single value
 * @param value - Initial primitive value
 * @returns ObservablePrimitive for the value
 */
function observablePrimitive<T>(value?: T): ObservablePrimitive<T>;
/**
 * Creates a primitive observable from a Promise value
 * @param value - Promise to wrap in observable
 * @returns ObservablePrimitive that includes loading state
 */
function observablePrimitive<T>(value: Promise<T>): ObservablePrimitive<T & WithState>;

Computed Observables

Creates computed values that automatically update when dependencies change.

/**
 * Creates a computed observable that automatically tracks dependencies
 * @param compute - Function to compute the value
 * @returns Computed observable that updates when dependencies change
 */
function computed<T>(compute: () => T): ObservableComputed<T>;

/**
 * Creates a two-way computed observable with custom setter
 * @param compute - Function to compute the value
 * @param set - Function to handle value updates
 * @returns Two-way computed observable
 */
function computed<T, T2 = T>(
  compute: () => T,
  set: (value: T2) => void
): ObservableComputedTwoWay<T, T2>;

Observable Tracking

Track selector execution and manage observable change listening.

/**
 * Tracks a selector function and sets up automatic updates
 * @param selector - Function to track for changes
 * @param update - Update function called when dependencies change
 * @param observeEvent - Optional observe event for cancellation
 * @param observeOptions - Options for observation behavior
 * @returns Object with value, dispose function, and resubscribe function
 */
function trackSelector<T>(
  selector: Selector<T>,
  update: (params: ListenerParams) => void,
  observeEvent?: ObserveEvent<T>,
  observeOptions?: ObserveOptions
): { value: T; dispose?: () => void; resubscribe?: () => () => void };

/**
 * Sets up a change listener on a node value
 * @param node - The node to listen to
 * @param callback - Callback function for changes
 * @param options - Listener options
 * @returns Function to dispose the listener
 */
function onChange(
  node: NodeValue,
  callback: ListenerFn,
  options?: {
    trackingType?: TrackingType;
    initial?: boolean;
    immediate?: boolean;
    noArgs?: boolean;
  }
): () => void;

Batching Operations

Groups multiple observable updates into a single batch to optimize performance.

/**
 * Executes function with all observable updates batched
 * @param fn - Function to execute with batched updates
 */
function batch(fn: () => void): void;

/**
 * Starts batching mode for manual control
 */
function beginBatch(): void;

/**
 * Ends batching mode and flushes pending updates
 */
function endBatch(): void;

Events

Creates event emitters for decoupled communication.

/**
 * Creates an event emitter
 * @returns Event emitter instance
 */
function event(): EventEmitter;

interface EventEmitter {
  fire(data?: any): void;
  on(callback: (data?: any) => void): () => void;
}

Observer Function

Sets up observers that react to observable changes.

/**
 * Observes changes to observables and executes reaction function
 * @param selector - Function that accesses observables to track
 * @param reaction - Function called when dependencies change
 * @returns Dispose function to stop observing
 */
function observe<T>(
  selector: () => T, 
  reaction: (value: T) => void
): () => void;

When Functions

Provides Promise-based waiting for specific conditions.

/**
 * Returns a Promise that resolves when the predicate returns truthy
 * @param predicate - Function to evaluate for truthiness
 * @returns Promise that resolves with the truthy value
 */
function when<T>(predicate: () => T): Promise<T>;

/**
 * Like when() but waits for observable values to be ready (not loading)
 * @param predicate - Function to evaluate for ready state
 * @returns Promise that resolves when value is ready
 */
function whenReady<T>(predicate: () => T): Promise<T>;

Proxy Creation

Creates observable proxies for existing objects.

/**
 * Creates an observable proxy around an existing object
 * @param target - Object to make observable
 * @returns Observable proxy of the target object
 */
function proxy<T>(target: T): ObservableProxy<T>;

Selector Tracking

Provides dependency tracking utilities for advanced use cases.

/**
 * Tracks dependencies of a selector function
 * @param selector - Function to track dependencies for
 * @returns Object with selector and tracking information
 */
function trackSelector<T>(selector: () => T): TrackedSelector<T>;

interface TrackedSelector<T> {
  selector: () => T;
  dependencies: Observable[];
  dispose: () => void;
}

Observable Interface

interface Observable<T> {
  /** Get the current value, tracking for changes */
  get(): T;
  /** Get the current value without tracking for changes */
  peek(): T;
  /** Set a new value */
  set(value: T | ((prev: T) => T) | Promise<T>): void;
  /** Listen for changes to this observable */
  onChange(
    callback: ListenerFn<T>,
    options?: ChangeListenerOptions
  ): () => void;
  /** Assign properties to object observables */
  assign(value: Partial<T>): void;
  /** Delete this observable */
  delete(): void;
}

interface ObservablePrimitive<T> extends Observable<T> {
  /** Toggle boolean values */
  toggle(): T; // Only available for boolean types
}

interface ChangeListenerOptions {
  trackingType?: boolean | symbol;
  initial?: boolean;
  immediate?: boolean;
  noArgs?: boolean;
}

Usage Examples:

import { observable, computed, batch, when } from "@legendapp/state";

// Create observables
const counter$ = observable(0);
const user$ = observable({
  name: "Alice",
  age: 30,
  preferences: {
    theme: "dark"
  }
});

// Create computed values
const doubled$ = computed(() => counter$.get() * 2);
const greeting$ = computed(() => `Hello, ${user$.name.get()}!`);

// Batch updates
batch(() => {
  counter$.set(5);
  user$.name.set("Bob");
  user$.age.set(25);
}); // Only fires listeners once at the end

// Wait for conditions
await when(() => counter$.get() > 10);
console.log("Counter exceeded 10!");

// Listen for changes
const dispose = user$.onChange(({ value }) => {
  console.log("User changed:", value);
});

// Access nested properties
user$.preferences.theme.set("light");
console.log(user$.preferences.theme.get()); // "light"

// Clean up
dispose();

docs

configuration.md

core-observables.md

helper-functions.md

index.md

persistence.md

react-integration.md

tile.json