Create a new SignalArray with an optional initial value.
Configure a custom equality function for a Signal. The equality function determines when updates are skipped (if values are "equal").
Use an existing Signal if provided, otherwise create a new one with the default value. This enables the controlled/uncontrolled component pattern.
// In a component that supports both controlled and uncontrolled modes:
const value = yield* Signal.fromNullable(props.value, props.defaultValue ?? "");
// If props.value is a Signal, it will be used directly
// If props.value is undefined, a new Signal is created with defaultValue
// With custom equality:
const value = yield* Signal.fromNullable(props.value, defaultUser).pipe(
Signal.equals((a, b) => a.id === b.id)
);
Create a Signal from a reactive value (Signal, Readable, or plain value).
This is useful for controlled/uncontrolled component patterns where a prop can be either a Signal (controlled), a Readable, or a plain value (uncontrolled).
// In a component that accepts flexible input:
interface CheckboxProps {
checked?: Signal<boolean> | Readable<boolean> | boolean;
defaultChecked?: boolean;
}
const Checkbox = (props: CheckboxProps) =>
Effect.gen(function* () {
// Works with Signal (controlled), Readable, or boolean (uncontrolled)
const checked = yield* Signal.fromReactive(
props.checked,
props.defaultChecked ?? false
);
// With custom equality:
const user = yield* Signal.fromReactive(props.user, defaultUser).pipe(
Signal.equals((a, b) => a.id === b.id)
);
});
Check if a value is a Signal.
Create a new Signal with an initial value.
Create a reactive Map with in-place mutation methods.
Check if a value is a SignalMap.
Create a new SignalMap with optional initial entries.
Create a reactive Set with in-place mutation methods.
Create a reactive struct with fixed keys, where each key is accessible as a Signal.
Check if a value is a SignalStruct.
Create a new SignalStruct with an initial value.
Create a reactive array with in-place mutation methods.