Skip to content

Instantly share code, notes, and snippets.

@tusharmath
Created November 29, 2016 18:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tusharmath/5203c22abcfc823409a0046924252679 to your computer and use it in GitHub Desktop.
Save tusharmath/5203c22abcfc823409a0046924252679 to your computer and use it in GitHub Desktop.
/**
* Created by tushar on 29/11/16.
*/
import * as O from 'observable-air'
type faco = <F> (t: F) => Action<F>
export class Action<T> {
constructor (public readonly type: string, public readonly value: T) {
}
static of<T> (type: string, value: T) {
return new Action(type, value)
}
}
export class Dispatcher<T> {
constructor (private fac: faco, private subject: O.ISubject<Action<T>>) {
this.listen = this.listen.bind(this)
}
of <F> (scope: string) {
return new Dispatcher((ev: F) => this.fac(new Action(scope, ev)), this.subject)
}
listen (ev: T) {
this.subject.next(this.fac(ev))
}
}
export interface IDispatcher {
listen<T>(val: T): void
get(scope: string): IDispatcher
set(scope: string, dispatcher: IDispatcher): IDispatcher
of?(scope: string, bind?: boolean): IDispatcher
}
export class RootDispatcher implements IDispatcher {
private subject = O.subject()
private cache: {[scope: string]: IDispatcher} = {}
listen<T> (val: T): void {
this.subject.next(val)
}
get (scope: string) {
return this.cache[scope]
}
set (scope: string, dispatcher: IDispatcher) {
this.cache[scope] = dispatcher
return dispatcher
}
}
export class Dispatcher2 implements IDispatcher {
get (scope: string): IDispatcher {
return this.parent.get(scope)
}
set (scope: string, dispatcher: IDispatcher): IDispatcher {
return this.parent.set(scope, dispatcher)
}
constructor (private scope: string, private parent: IDispatcher, bind: boolean) {
if (bind) {
this.listen = this.listen.bind(this)
}
}
of (scope: string, bind = false): IDispatcher {
const dispatcher = this.parent.get(scope)
if (dispatcher) {
return dispatcher
}
return this.parent.set(scope, new Dispatcher2(scope, this, bind))
}
listen <T> (val: T): void {
this.parent.listen(new Action(this.scope, val))
}
}
export const dispatcher1 = <T> (scope: string) =>
new Dispatcher((ev: T) => new Action(scope, ev), O.subject())
export const dispatcher2 = <T> (scope: string) => new Dispatcher2(scope, new RootDispatcher(), false)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment