-
Notifications
You must be signed in to change notification settings - Fork 0
Base Observable
A reactive primitive designed for managing and observing mutable state with built-in event dispatching and flexible binding modes.
baseObservable is a callable object that acts as both a getter and setter for a reactive value of type T. It implements the EventTarget interface for notifying subscribers about changes, supports binding mode configurations, and offers advanced features such as validation, coercion, and derived observables via a binding proxy.
| Parameter | Description |
|---|---|
T |
The type of the observable's managed value |
Internal instance responsible for event dispatch and listener management. Used to implement EventTarget methods.
Defines the data flow direction:
| Mode | Description |
|---|---|
"to" |
One-way: ViewModel → UI (output only) |
"from" |
One-way: UI → ViewModel (input only) |
"two-way" |
Two-way: bidirectional synchronization |
A proxy object that exposes:
- Properties of the underlying value as individual observables (
computed<T[K]>). - Methods of the underlying value as functions returning computed observables.
- A
select<U>(selector: (value: T) => U): computed<U>method for derived observables.
Example:
const person = baseObservable(() => ({ name: "Alice", age: 30 }));
const nameObs = person.bind.name; // observable for name property
const agePlusOne = person.bind.select(p => p.age + 1);(...args: any[]) => T- Getter: Called without arguments, returns current value.
- Setter: Called with arguments, updates or recomputes value.
- Dispatches a
"valuechanging"event before the value update. - Returns
falseif any event listener cancels the change viapreventDefault(). - Allows validation or veto logic.
- Dispatches a
"valuechanged"event after the value update. - Notifies subscribers of the completed change.
Performs an atomic update:
- Calls
notifyBeforeto allow cancellation. - Runs mutation function
fnif not canceled. - Calls
notifyafter mutation. - Returns result from
fnorundefinedif canceled.
- Adds reactive validation support.
-
isValidis a computed observable reflecting validity. - Default validator always returns
true.
- Adds coercion to input arguments before setting.
- Useful for input normalization or type enforcement.
Constructor and static helper methods for baseObservable.
<T = any>(baseFunction: (...args: any[]) => T): baseObservable<T>;Creates a baseObservable wrapping the supplied baseFunction.
autoBind<T>(observable: baseObservable<T> | T, set: (val: T) => void, observe?: (val: T) => void): void
Establishes a binding between a source (observable or plain value) and a setter:
- Immediately calls
setwith current value. - Subscribes to
"valuechanged"if observable supports output binding. - Calls
observefor input binding if supported.
const count = baseObservable(() => 0);
count.type = "two-way";
// Subscribe to changes
count._eventTarget.addEventListener("valuechanged", () => {
console.log("Count changed:", count());
});
// Update count
count(5);
// Extend with validation
const validatedCount = count.validatable(val => val >= 0);
console.log(validatedCount.isValid()); // true or false
// Coerce input (force integer)
count.coercible(val => Math.floor(val));
count(3.7);
console.log(count()); // Outputs: 3If you need any assistance or clarification on contributing, feel free to reach out by creating an issue.
Thank you for considering contributing to the Dom-Builder library!