mcpField
S
signals-dart

signals-dart

github.com/rodydavisDevelopment824103 installsUpdated 12w ago
Repository

About signals-dart

A reference skill for advanced `signals_core` state management in Dart, aimed at developers building reactive applications. It covers asynchronous state, reactive collections, utility primitives, and option value semantics alongside the core APIs.

Key features

  1. 01Mutable and derived signals
  2. 02Synchronous effects and batching
  3. 03Async state and future primitives
  4. 04Reactive collection wrappers
  5. 05Undo, timers, and event connectors
  6. 06Option copying and equality semantics

Use cases

  1. 01Modeling derived reactive application state
  2. 02Handling asynchronous loading and error states
  3. 03Tracking changes in reactive collections
  4. 04Adding undo and redo to state flows

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/rodydavis/signals.dart --skill signals-dart

After installing, type/signals-dartin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

CONTEXT.md
async/
async_signal.md
computed_async.md
computed_from.md
CONTEXT.md
future_signal.md
stream_signal.md
collections/
CONTEXT.md
iterable_signal.md
list_signal.md
map_signal.md
queue_signal.md
set_signal.md
core/
batch.md
computed.md
CONTEXT.md
effect.md
readonly.md
signal.md
utils/
connect.md
CONTEXT.md
linked_signal.md
timer_signal.md
tracked_signal.md

Details

From the project README

Signals Core Advanced Primitives

This skill details advanced state management primitives, reactive collections, async features, and value options semantics in signals_core.

Related Documentation & Items

Core Primitives
Related FileDescription
signal.mdStandard writeable reactive state primitive containing value accessors, mutation mechanics, and basic custom options.
computed.mdLazy, memoized read-only derived state signal tracking reactive dependencies dynamically.
effect.mdSynchronous observer managing active subscription loops, dynamic dependency updates, and lifecycle teardown.
readonly.mdRead-only signal views ensuring unidirectional data access flows.
batch.mdTransactional state mutation blocks optimizing reactive computations and preventing rendering/recompute churn.
Asynchronous Operations
Related FileDescription
future_signal.mdSingle-evaluation asynchronous future state representation resolving the double-evaluation issue.
stream_signal.mdDynamic, lifecycle-safe, self-disposing stream listener mapping to async loading/data/error states.
async_signal.mdUnifying async state container mapping loading, success data, and failure error states cleanly.
computed_async.mdComposable asynchronous operations built over reactive signals with active race condition protection.
computed_from.mdState aggregator signal merging multiple async signals into a single unified result.
Reactive Collections
Related FileDescription
list_signal.mdOptimized list wrapper proxying standard operations to support element-level reactivity.
set_signal.mdCustom set wrapper ignoring duplicates and notifying on unique mutations.
map_signal.mdGranular map wrapper supporting isolated dictionary element lookup triggers.
iterable_signal.mdIterable wrapper mapping custom lazy traversals to dynamic subscription layers.
queue_signal.mdDouble-ended queue wrapper supporting optimized reactive pipeline structures.
Utility Primitives
Related FileDescription
linked_signal.mdWritable computed signals supporting manual override resets and custom equivalence checks.
tracked_signal.mdState history wrapper enabling clean out-of-the-box undo/redo mechanisms.
timer_signal.mdPeriodically emitting stopwatch signal with built-in pause, resume, and reset.
connect.mdDynamic event connector feeding multiple external data pipelines into single targets.

Core Primitives Quick Start Guide

The signals library exposes five core functions which are the building blocks to model any reactive business logic.

1. signal(initialValue)

Creates a new mutable signal container. You read a signal's value or subscribe to updates by accessing .value.

final counter = signal(0);
print(counter.value); // 0
counter.value = 1; // Mutates value and schedules dependent updates
.peek()

Reads a signal's current value without subscribing to its mutations.

final counter = signal(0);
final logCount = signal(0);

effect(() {
  print(counter.value);
  // Read using peek to avoid subscribing/triggering loop
  logCount.value = logCount.peek() + 1;
});
2. untracked(fn)

Executes a callback that reads signals without subscribing to any of them.

final counter = signal(0);
final count = signal(0);

effect(() {
  print(counter.value);
  count.value = untracked(() => count.value + 1);
});
3. computed(fn)

Combines the values of multiple signals into a lazy, memoized derived signal.

final first = signal('John');
final last = signal('Doe');
final fullName = computed(() => '${first.value} ${last.value}');
print(fullName.value); // John Doe
4. effect(fn)

Orchestrates immediate synchronous side effects by running a callback and subscribing to any signals read within it.

final name = signal('Jane');
final dispose = effect(() => print('Hello $name'));
dispose(); // Clean up subscription
5. batch(fn)

Groups multiple signal writes into a single transaction, executing all dependent computed evaluations and effects exactly once at the end.

final a = signal(0);
final b = signal(0);

batch(() {
  a.value = 1;
  b.value = 2;
});

1. Writable Computed Signal (linkedSignal)

A writable computed signal (LinkedSignal) provides a derived default value that can be overridden manually, resetting back to the derived default whenever its upstream dependencies mutate.

Usage
// Basic reset shorthand:
final size = signal('M');
final selection = linkedSignal(() => size.value);

// Advanced structural comparison:
final user = signal((id: 1, name: 'Alice'));
final name = linkedSignal<String, ({int id, String name})>(
  () => user.value,
  options: LinkedSignalOptions(
    computation: (u, prev) {
      if (prev != null && prev.source.id == u.id) {
        return prev.value; // Retain manual override
      }
      return u.name; // Reset on ID changes
    },
  ),
);

2. Collections and Async Primitives

A. Collections

Always use specialized collections (listSignal, setSignal, mapSignal, etc.) to wrap collections to ensure optimized mutations (only triggering updates when elements actually change).

final list = listSignal([1, 2], options: ListSignalOptions(autoDispose: true));
list.add(3); // Reacts to changes
B. Optimized FutureSignal

FutureSignal inherits directly from AsyncSignal to bypass Stream subscription overhead and tracks its dependencies manually via computed execution, executing future computations exactly once (avoiding double-evaluation loops).

final search = signal('');
final results = futureSignal(() => fetchResults(search.value));

3. Options Classes Value Semantics

All signal option objects support full value semantics (copyWith, custom equality, and hashCode overrides) for flexible copying and accurate comparisons:

  • SignalOptions
  • ComputedOptions
  • AsyncSignalOptions
  • LinkedSignalOptions
  • ListSignalOptions / SetSignalOptions / MapSignalOptions

Comments

Markdown supported