kaiju
Version:
Virtual dom, observables and stateful components
188 lines (160 loc) • 8 kB
TypeScript
import { Result } from 'space-lift'
/**
* Either a Promise value or an Error thrown by the promise.
*/
export type PromiseResult<T> =
{ type: 'success', value: T } |
{ type: 'failure', error: {} }
export interface Observable<T> {
__T: T
/**
* Subscribes to this observable values and returns a function that may be used to unsubscribe.
*/
subscribe: (onValue: (val: T) => void) => () => void | void
/**
* Gives a debug name to the observable.
* names are inherited by observable transforms unless a new name is defined downstream.
*/
named: (name: string) => this
/**
* Reads the current value of the observable or returns undefined if no value was ever pushed in the observable.
*/
(): T | undefined
/**
* Delays values until a certain amount of silence has passed.
* Values in between silence periods are discarded.
*/
debounce(wait: number): Observable<T>
/**
* Delays all values by a fixed time offset
*/
delay(delay: number): Observable<T>
/**
* Creates a new Observable with adjacent repeated values removed.
* A compare function can optionally be passed to implement user-defined equality instead of strict reference equality.
* The functions should return true if the two values are equal.
*/
distinct(compareFunction?: (previousValue: T, currentValue: T) => boolean): Observable<T>
/**
* Drops 'count' initial values.
* Note: This can also be used to drop the initial value when subscribing to an Observable, if it had seen a value previously.
*/
drop(count: number): Observable<T>
/**
* Filters the values of this observable.
*/
filter(predicate: (t: T) => boolean): Observable<T>
/*
* Maps and flattens this observable then only publish values from the observable mapped last.
*/
flatMapLatest<B>(mapFn: (t: T) => Observable<B>): Observable<B>
/**
* Maps the values of this observable.
*/
map<B>(mapFn: (t: T) => B): Observable<B>
/**
* Partitions this observable into two observables based on a predicate
*/
partition<T>(predicate: (value: T) => boolean): [Observable<T>, Observable<T>]
/**
* Groups values in fixed size blocks (of size 2) by passing a "sliding window" over them.
* An array becomes the value of the new observable. It will have a size of 1 the first time a value is produced,
* then a size of 2 for subsequent values.
* The newest value is always found at the index 0 of the Array for convenience and type safety.
*/
sliding2(): Observable<[T, T | undefined]>
/**
* Groups values in fixed size blocks by passing a "sliding window" over them.
* An array becomes the value of the new observable. It will have a size of 1 the first time a value is produced,
* then an increasing size of max (maxWindowSize parameter) for subsequent values.
* The newest value is always found at the index 0 of the Array for convenience (...rest parameters).
*/
sliding(maxWindowSize: number): Observable<Array<T>>
/**
* Take the first 'count' values of this observable.
*/
take(count: number): Observable<T>
/**
* Delays values so that values are produced at most once per every 'time' milliseconds
*/
throttle(time: number): Observable<T>
}
interface SourceObservable<T> extends Observable<T> {
/**
* Sets the value of this observable.
* The observable is returned for convenient construction with an initial value.
*/
(value: T): SourceObservable<T>
}
/**
* A special observable that is garanteed to have an initial value.
*/
export interface ObservableWithInitialValue<T> extends Observable<T> {
/**
* Reads the current value of the observable.
*/
(): T
}
type UnsubFunction = void | (() => void)
export interface ObservableObject {
/** Creates a new Observable */
<T>(activate?: (add: (t: T) => void) => UnsubFunction): SourceObservable<T>
/**
* Listens for DOM events at the specified parent element.
* a childSelector can optionally be passed to listen to delegated events instead of direct events.
*/
fromEvent(name: 'blur', el: Element | EventTarget, childSelector?: string): Observable<FocusEvent>
fromEvent(name: 'click', el: Element | EventTarget, childSelector?: string): Observable<MouseEvent>
fromEvent(name: 'dblclick', el: Element | EventTarget, childSelector?: string): Observable<MouseEvent>
fromEvent(name: 'drag', el: Element | EventTarget, childSelector?: string): Observable<DragEvent>
fromEvent(name: 'dragend', el: Element | EventTarget, childSelector?: string): Observable<DragEvent>
fromEvent(name: 'dragenter', el: Element | EventTarget, childSelector?: string): Observable<DragEvent>
fromEvent(name: 'dragexit', el: Element | EventTarget, childSelector?: string): Observable<DragEvent>
fromEvent(name: 'dragleave', el: Element | EventTarget, childSelector?: string): Observable<DragEvent>
fromEvent(name: 'dragover', el: Element | EventTarget, childSelector?: string): Observable<DragEvent>
fromEvent(name: 'dragstart', el: Element | EventTarget, childSelector?: string): Observable<DragEvent>
fromEvent(name: 'drop', el: Element | EventTarget, childSelector?: string): Observable<DragEvent>
fromEvent(name: 'focus', el: Element | EventTarget, childSelector?: string): Observable<FocusEvent>
fromEvent(name: 'keydown', el: Element | EventTarget, childSelector?: string): Observable<KeyboardEvent>
fromEvent(name: 'keyup', el: Element | EventTarget, childSelector?: string): Observable<KeyboardEvent>
fromEvent(name: 'mousedown', el: Element | EventTarget, childSelector?: string): Observable<MouseEvent>
fromEvent(name: 'mouseenter', el: Element | EventTarget, childSelector?: string): Observable<MouseEvent>
fromEvent(name: 'mouseleave', el: Element | EventTarget, childSelector?: string): Observable<MouseEvent>
fromEvent(name: 'mousemove', el: Element | EventTarget, childSelector?: string): Observable<MouseEvent>
fromEvent(name: 'mouseout', el: Element | EventTarget, childSelector?: string): Observable<MouseEvent>
fromEvent(name: 'mouseup', el: Element | EventTarget, childSelector?: string): Observable<MouseEvent>
fromEvent(name: 'mousewheel', el: Element | EventTarget, childSelector?: string): Observable<MouseWheelEvent>
fromEvent(name: 'scroll', el: Element | EventTarget, childSelector?: string): Observable<UIEvent>
fromEvent(name: 'touchcancel', el: Element | EventTarget, childSelector?: string): Observable<TouchEvent>
fromEvent(name: 'touchend', el: Element | EventTarget, childSelector?: string): Observable<TouchEvent>
fromEvent(name: 'touchmove', el: Element | EventTarget, childSelector?: string): Observable<TouchEvent>
fromEvent(name: 'touchstart', el: Element | EventTarget, childSelector?: string): Observable<TouchEvent>
fromEvent(name: string, el: Element | EventTarget, childSelector?: string): Observable<Event>
/**
* Creates a new Observable from a Promise. The observable will produce only one value:
* Either an Ok, or an Err (see space-lift/result) object based on the result of the Promise.
*/
fromPromise<T, E = never>(promise: Promise<T>): Observable<Result<E, T>>
/**
* Creates a new observable that produces undefined values at the provided interval in milliseconds.
*/
interval(time: number): Observable<undefined>
/**
* Merges all the observables into one
*/
merge<T>(...obss: Array<Observable<T>>): Observable<T>
/**
* Creates a new observable that produces one value immediately.
*/
pure<A>(value: A): Observable<A>
}
/**
* Creates a new observable.
*
* The fist argument function is called every time the observable goes
* from inactive (no subscribers) to active (the first subscriber just registered)
*
* This function can optionally return a function that will be called when the last subscriber unregisters itself from the observable.
* Use this as an opportunity to clean up the observable.
*/
export const Observable: ObservableObject