Skip to content

Instantly share code, notes, and snippets.

@simontreny
Created October 21, 2019 09:08
Show Gist options
  • Save simontreny/ffb0f8448abd16d35bbfe571005faaf5 to your computer and use it in GitHub Desktop.
Save simontreny/ffb0f8448abd16d35bbfe571005faaf5 to your computer and use it in GitHub Desktop.
import { ReadableSignal, Signal } from "micro-signals";
export interface ReadableObservable<T> {
onChange: ReadableSignal<T>;
get(): T;
map<U>(transform: (val: T) => U): ReadableObservable<U>;
filter(predicate: (val: T) => boolean): ReadableObservable<T | undefined>;
}
abstract class BaseObservable<T> implements ReadableObservable<T> {
protected _val: T;
constructor(val: T) {
this._val = val;
}
abstract onChange: ReadableSignal<T>;
get(): T {
return this._val;
}
map<U>(transform: (val: T) => U): ReadableObservable<U> {
return new MappedObservable(this, transform);
}
filter(predicate: (val: T) => boolean): ReadableObservable<T | undefined> {
return new FilteredObservable(this, predicate);
}
}
export class Observable<T> extends BaseObservable<T> {
private _onChange = new Signal<T>();
get onChange(): ReadableSignal<T> {
return this._onChange;
}
set(val: T) {
if (this._val !== val) {
this._val = val;
this._onChange.dispatch(val);
}
}
}
class MappedObservable<B, T> extends BaseObservable<T> {
readonly onChange: ReadableSignal<T>;
constructor(baseObservable: ReadableObservable<B>, transform: (val: B) => T) {
super(transform(baseObservable.get()));
this.onChange = baseObservable.onChange.map(transform);
this.onChange.add(val => {
this._val = val;
});
}
}
class FilteredObservable<T> extends BaseObservable<T | undefined> {
readonly onChange: ReadableSignal<T | undefined>;
constructor(baseObservable: ReadableObservable<T>, predicate: (val: T) => boolean) {
super(predicate(baseObservable.get()) ? baseObservable.get() : undefined);
this.onChange = baseObservable.onChange.filter(predicate);
this.onChange.add(val => {
this._val = val;
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment