Comparing version 0.13.5 to 0.14.0
@@ -30,59 +30,64 @@ import { konsole } from './Konsole'; | ||
export interface Match { | ||
export interface Routable { | ||
score?: number; | ||
} | ||
export class Router <M extends Match> { | ||
constructor(public getRoute: (m: M) => Observable<Route>) {} | ||
export interface Handler <Z extends Routable = {}> { | ||
(m: Z): Observableable<any>; | ||
} | ||
export const nullRouter = new Router<any>(m => Observable.empty()); | ||
export type RouterOrHandler <M extends Routable = {}> = Router<M> | Handler<M>; | ||
export function routeMessage <M extends Match> (router: Router<M>, m: M) { | ||
return router.getRoute(m) | ||
.do(route => konsole.log("handle: matched a route", route)) | ||
.flatMap(route => toObservable(route.action())) | ||
.do(_ => konsole.log("handle: called action")); | ||
} | ||
export class Router <M extends Routable> { | ||
constructor(public getRoute: (m: M) => Observable<Route>) {} | ||
export interface Handler <Z extends Match = {}> { | ||
(m: Z): Observableable<any>; | ||
} | ||
static fromHandler <M extends Routable> (handler: Handler<M>) { | ||
return new Router<M>(m => Observable.of({ | ||
action: () => handler(m) | ||
} as Route)); | ||
} | ||
static null = new Router<any>(m => Observable.empty()); | ||
export type RouterOrHandler <M extends Match = {}> = Router<M> | Handler<M>; | ||
static from <M extends Routable> (routerOrHandler: RouterOrHandler<M>): Router<M> { | ||
return routerOrHandler | ||
? routerOrHandler instanceof Router | ||
? routerOrHandler | ||
: Router.fromHandler(routerOrHandler) | ||
: Router.null; | ||
} | ||
export function isRouter <M extends Match> (routerOrHandler: RouterOrHandler<M>): routerOrHandler is Router<M> { | ||
return ((routerOrHandler as any).getRoute !== undefined); | ||
static routersFrom <M extends Routable> (routersOrHandlers: RouterOrHandler<M>[]) { | ||
return routersOrHandlers | ||
.map(routerOrHandler => Router.from(routerOrHandler)); | ||
} | ||
route (m: M) { | ||
return this.getRoute(m) | ||
.do(route => konsole.log("route: returned a route", route)) | ||
.flatMap(route => toObservable(route.action())) | ||
.do(_ => konsole.log("route: called action")); | ||
} | ||
} | ||
export function simpleRouter <M extends Match> (handler: Handler<M>) { | ||
return new Router<M>(m => Observable.of({ | ||
action: () => handler(m) | ||
} as Route)); | ||
export class FirstRouter <M extends Routable> extends Router<M> { | ||
constructor (... routersOrHandlers: RouterOrHandler<M>[]) { | ||
const router$ = Observable.from(Router.routersFrom(routersOrHandlers)); | ||
super(m => router$ | ||
.concatMap( | ||
(router, i) => { | ||
konsole.log(`first: trying router #${i}`); | ||
return router.getRoute(m) | ||
.do(n => konsole.log(`first: router #${i} succeeded`, n)); | ||
} | ||
) | ||
.take(1) // so that we don't keep going through routers after we find one that matches | ||
); | ||
} | ||
} | ||
export function toRouter <M extends Match> (routerOrHandler: RouterOrHandler<M>) { | ||
return isRouter(routerOrHandler) ? routerOrHandler : simpleRouter(routerOrHandler); | ||
export function first <M extends Routable> (... routersOrHandlers: RouterOrHandler<M>[]) { | ||
return new FirstRouter(... routersOrHandlers); | ||
} | ||
function filteredRouter$ <M extends Match> (... routersOrHandlers: RouterOrHandler<M>[]) { | ||
return Observable.from(routersOrHandlers) | ||
.filter(routerOrHandler => !!routerOrHandler) | ||
.map(routerOrHandler => toRouter(routerOrHandler)); | ||
} | ||
export function first <M extends Match> (... routersOrHandlers: RouterOrHandler<M>[]) { | ||
const router$ = filteredRouter$(... routersOrHandlers); | ||
return new Router<M>(m => router$ | ||
.concatMap( | ||
(router, i) => { | ||
konsole.log(`first: trying router #${i}`); | ||
return router.getRoute(m) | ||
.do(n => konsole.log(`first: router #${i} succeeded`, n)); | ||
} | ||
) | ||
.take(1) // so that we don't keep going through routers after we find one that matches | ||
); | ||
} | ||
const minRoute: Route = { | ||
@@ -97,109 +102,123 @@ score: 0, | ||
export function addScore<T extends { score?: number }>(t: T, score: number): T { | ||
return toScore(t.score) === score | ||
? t | ||
: { | ||
... t as any, | ||
score | ||
} as T; | ||
} | ||
export class BestRouter <M extends Routable> extends Router<M> { | ||
constructor(... routersOrHandlers: RouterOrHandler<M>[]) { | ||
const router$ = Observable.from(Router.routersFrom(routersOrHandlers)); | ||
super(m => new Observable<Route>(observer => { | ||
let bestRoute: Route = minRoute; | ||
export function best <M extends Match> (... routersOrHandlers: RouterOrHandler<M>[]) { | ||
const router$ = filteredRouter$(... routersOrHandlers); | ||
return new Router<M>(m => new Observable<Route>(observer => { | ||
let bestRoute: Route = minRoute; | ||
const subscription = router$ | ||
.takeWhile(_ => toScore(bestRoute.score) < 1) | ||
.concatMap(router => router.getRoute(m)) | ||
.subscribe( | ||
route => { | ||
if (toScore(route.score) > toScore(bestRoute.score)) { | ||
bestRoute = route; | ||
if (toScore(bestRoute.score) === 1) { | ||
const subscription = router$ | ||
.takeWhile(_ => toScore(bestRoute.score) < 1) | ||
.concatMap(router => router.getRoute(m)) | ||
.subscribe( | ||
route => { | ||
if (toScore(route.score) > toScore(bestRoute.score)) { | ||
bestRoute = route; | ||
if (toScore(bestRoute.score) === 1) { | ||
observer.next(bestRoute); | ||
observer.complete(); | ||
} | ||
} | ||
}, | ||
error => | ||
observer.error(error), | ||
() => { | ||
if (toScore(bestRoute.score) > 0) | ||
observer.next(bestRoute); | ||
observer.complete(); | ||
} | ||
observer.complete(); | ||
} | ||
}, | ||
error => | ||
observer.error(error), | ||
() => { | ||
if (toScore(bestRoute.score) > 0) | ||
observer.next(bestRoute); | ||
observer.complete(); | ||
} | ||
); | ||
); | ||
return () => subscription.unsubscribe(); | ||
})); | ||
return () => subscription.unsubscribe(); | ||
})); | ||
} | ||
} | ||
export function run <M extends Match> (handler: Handler<M>) { | ||
return new Router<M>(m => toObservable(handler(m)) | ||
.filter(_ => false) | ||
); | ||
export function best <M extends Routable> (... routersOrHandlers: RouterOrHandler<M>[]) { | ||
return new BestRouter(... routersOrHandlers); | ||
} | ||
export interface Matcher <M extends Match = {}, Z extends Match = {}> { | ||
(m: M): Observableable<Z>; | ||
export class RunRouter <M extends Routable> extends Router<M> { | ||
constructor(handler: Handler<M>) { | ||
super(m => toObservable(handler(m)) | ||
.filter(_ => false) | ||
); | ||
} | ||
} | ||
export interface Predicate <M extends Match = {}> { | ||
(m: M): Observableable<boolean>; | ||
export function run <M extends Routable> (handler: Handler<M>) { | ||
return new RunRouter(handler); | ||
} | ||
export function tryMatch <M extends Match, N extends Match> (matcher: Matcher<M, N>, m: M): Observable<N>; | ||
export function tryMatch <M extends Match> (predicate: Predicate<M>, m: M): Observable<M>; | ||
export function tryMatch <M extends Match> (predicateOrMatcher: Predicate | Matcher, m: M): Observable<any>; | ||
export function tryMatch(predicateOrMatcher: Matcher | Predicate, m): Observable<any> { | ||
// we want to allow any matcher to be a predicate (return a boolean) | ||
// if so, the 'falsey' case will be filtered out by toFilteredObservable, | ||
// so we just need to catch the case where it is precisely true | ||
konsole.log("tryMatch", predicateOrMatcher, m); | ||
return toFilteredObservable(predicateOrMatcher(m)) | ||
.map(n => typeof n === 'boolean' | ||
? addScore(m, 1) | ||
: n | ||
); | ||
export interface Predicate <M extends Routable = {}> { | ||
(m: M): Observableable<boolean>; | ||
} | ||
export function combineScores(previousScore, nextScore) { | ||
return toScore(previousScore) * toScore(nextScore); | ||
export function routeWithCombinedScore(route: Route, newScore: number) { | ||
const score = toScore(newScore) * toScore(route.score); | ||
return toScore(route.score) === score | ||
? route | ||
: { | ||
... route, | ||
score | ||
} as Route; | ||
} | ||
export function routeWithCombinedScore(route: Route, score?: number) { | ||
return addScore(route, combineScores(score, route.score)); | ||
export class IfDoRouter <M extends Routable> extends Router<M> { | ||
constructor ( | ||
predicate: Predicate<M>, | ||
ifRouterOrHandler: RouterOrHandler<M>, | ||
elseRouterOrHandler?: RouterOrHandler<M>, | ||
) { | ||
const ifRouter = Router.from(ifRouterOrHandler); | ||
const elseRouter = Router.from(elseRouterOrHandler); | ||
super(m => toObservable(predicate(m)) | ||
.flatMap(n => n | ||
? ifRouter.getRoute(m) | ||
: elseRouter.getRoute(m) | ||
.map(route => routeWithCombinedScore(route, m.score)) | ||
) | ||
); | ||
} | ||
} | ||
export function ifMatch <M extends Match> ( | ||
export function ifDo <M extends Routable> ( | ||
predicate: Predicate<M>, | ||
ifRouterOrHandler: RouterOrHandler<M>, | ||
elseRouterOrHandler?: RouterOrHandler<M>, | ||
): Router<M>; | ||
elseRouterOrHandler?: RouterOrHandler<M> | ||
): IfDoRouter<M> { | ||
return new IfDoRouter(predicate, ifRouterOrHandler, elseRouterOrHandler); | ||
} | ||
export function ifMatch <M extends Match, N extends Match> ( | ||
export interface Matcher <M extends Routable = {}, Z extends Routable = {}> { | ||
(m: M): Observableable<Z>; | ||
} | ||
export class IfMatchRouter <M extends Routable, N extends Routable> extends Router<M> { | ||
constructor ( | ||
matcher: Matcher<M, N>, | ||
ifRouterOrHandler: RouterOrHandler<N>, | ||
elseRouterOrHandler?: RouterOrHandler<M> | ||
) { | ||
const ifRouter = Router.from(ifRouterOrHandler); | ||
const elseRouter = Router.from(elseRouterOrHandler); | ||
super(m => toObservable(matcher(m)) | ||
.flatMap(n => n | ||
? ifRouter.getRoute(n) | ||
.map(route => routeWithCombinedScore(route, n.score)) | ||
: elseRouter.getRoute(m) | ||
.map(route => routeWithCombinedScore(route, m.score)) | ||
) | ||
); | ||
} | ||
} | ||
export function ifMatch <M extends Routable, N extends Routable> ( | ||
matcher: Matcher<M, N>, | ||
ifRouterOrHandler: RouterOrHandler<N>, | ||
elseRouterOrHandler?: RouterOrHandler<M>, | ||
): Router<M>; | ||
export function ifMatch <M extends Match> ( | ||
predicateOrMatcher: Predicate<M> | Matcher<M>, | ||
ifRouterOrHandler: RouterOrHandler, | ||
elseRouterOrHandler?: RouterOrHandler, | ||
) { | ||
const ifRouter = toRouter(ifRouterOrHandler); | ||
const elseRouter = elseRouterOrHandler | ||
? toRouter(elseRouterOrHandler) | ||
: nullRouter; | ||
return new Router<M>(m => tryMatch(predicateOrMatcher, m) | ||
.defaultIfEmpty(null) | ||
.flatMap((n: Match) => n | ||
? ifRouter.getRoute(n) | ||
.map(route => routeWithCombinedScore(route, n.score)) | ||
: elseRouter.getRoute(m) | ||
.map(route => routeWithCombinedScore(route, m.score)) | ||
) | ||
); | ||
elseRouterOrHandler?: RouterOrHandler<M> | ||
): IfMatchRouter<M, N> { | ||
return new IfMatchRouter(matcher, ifRouterOrHandler, elseRouterOrHandler); | ||
} | ||
@@ -212,8 +231,8 @@ | ||
export function throwRoute <M extends Match> () { | ||
export function throwRoute <M extends Routable> () { | ||
return new Router<M>(m => Observable.of(thrownRoute)); | ||
} | ||
export function catchRoute <M extends Match> (routerOrHandler: RouterOrHandler<M>): Router<M> { | ||
return new Router<M>(m => toRouter(routerOrHandler) | ||
export function catchRoute <M extends Routable> (routerOrHandler: RouterOrHandler<M>): Router<M> { | ||
return new Router<M>(m => Router.from(routerOrHandler) | ||
.getRoute(m) | ||
@@ -224,22 +243,35 @@ .filter(route => !route.thrown) | ||
export function before <M extends Match> (beforeHandler: Handler<M>, routerOrHandler: RouterOrHandler<M>) { | ||
const router = toRouter(routerOrHandler); | ||
return new Router<M>(m => router.getRoute(m) | ||
.map(route => ({ | ||
... route, | ||
action: () => toObservable(beforeHandler(m)) | ||
.flatMap(_ => toObservable(route.action())) | ||
})) | ||
); | ||
export class BeforeRouter <M extends Routable> extends Router<M> { | ||
constructor (beforeHandler: Handler<M>, routerOrHandler: RouterOrHandler<M>) { | ||
const router = Router.from(routerOrHandler); | ||
super(m => router.getRoute(m) | ||
.map(route => ({ | ||
... route, | ||
action: () => toObservable(beforeHandler(m)) | ||
.flatMap(_ => toObservable(route.action())) | ||
})) | ||
); | ||
} | ||
} | ||
export function after <M extends Match> (routerOrHandler: RouterOrHandler<M>, afterHandler: Handler<M>) { | ||
const router = toRouter(routerOrHandler); | ||
return new Router<M>(m => router.getRoute(m) | ||
.map(route => ({ | ||
... route, | ||
action: () => toObservable(route.action()) | ||
.flatMap(_ => toObservable(afterHandler(m))) | ||
})) | ||
); | ||
export function before <M extends Routable> (beforeHandler: Handler<M>, routerOrHandler: RouterOrHandler<M>) { | ||
return new BeforeRouter(beforeHandler, routerOrHandler); | ||
} | ||
export class AfterRouter <M extends Routable> extends Router<M> { | ||
constructor (routerOrHandler: RouterOrHandler<M>, afterHandler: Handler<M>) { | ||
const router = Router.from(routerOrHandler); | ||
super(m => router.getRoute(m) | ||
.map(route => ({ | ||
... route, | ||
action: () => toObservable(route.action()) | ||
.flatMap(_ => toObservable(afterHandler(m))) | ||
})) | ||
); | ||
} | ||
} | ||
export function after <M extends Routable> (routerOrHandler: RouterOrHandler<M>, afterHandler: Handler<M>) { | ||
return new AfterRouter(routerOrHandler, afterHandler); | ||
} | ||
@@ -10,41 +10,55 @@ import { Observable } from 'rxjs'; | ||
} | ||
export interface Match { | ||
export interface Routable { | ||
score?: number; | ||
} | ||
export declare class Router<M extends Match> { | ||
export interface Handler<Z extends Routable = {}> { | ||
(m: Z): Observableable<any>; | ||
} | ||
export declare type RouterOrHandler<M extends Routable = {}> = Router<M> | Handler<M>; | ||
export declare class Router<M extends Routable> { | ||
getRoute: (m: M) => Observable<Route>; | ||
constructor(getRoute: (m: M) => Observable<Route>); | ||
static fromHandler<M extends Routable>(handler: Handler<M>): Router<M>; | ||
static null: Router<any>; | ||
static from<M extends Routable>(routerOrHandler: RouterOrHandler<M>): Router<M>; | ||
static routersFrom<M extends Routable>(routersOrHandlers: RouterOrHandler<M>[]): Router<M>[]; | ||
route(m: M): Observable<any>; | ||
} | ||
export declare const nullRouter: Router<any>; | ||
export declare function routeMessage<M extends Match>(router: Router<M>, m: M): Observable<any>; | ||
export interface Handler<Z extends Match = {}> { | ||
(m: Z): Observableable<any>; | ||
export declare class FirstRouter<M extends Routable> extends Router<M> { | ||
constructor(...routersOrHandlers: RouterOrHandler<M>[]); | ||
} | ||
export declare type RouterOrHandler<M extends Match = {}> = Router<M> | Handler<M>; | ||
export declare function isRouter<M extends Match>(routerOrHandler: RouterOrHandler<M>): routerOrHandler is Router<M>; | ||
export declare function simpleRouter<M extends Match>(handler: Handler<M>): Router<M>; | ||
export declare function toRouter<M extends Match>(routerOrHandler: RouterOrHandler<M>): Router<M>; | ||
export declare function first<M extends Match>(...routersOrHandlers: RouterOrHandler<M>[]): Router<M>; | ||
export declare function first<M extends Routable>(...routersOrHandlers: RouterOrHandler<M>[]): FirstRouter<M>; | ||
export declare function toScore(score: number): number; | ||
export declare function addScore<T extends { | ||
score?: number; | ||
}>(t: T, score: number): T; | ||
export declare function best<M extends Match>(...routersOrHandlers: RouterOrHandler<M>[]): Router<M>; | ||
export declare function run<M extends Match>(handler: Handler<M>): Router<M>; | ||
export interface Matcher<M extends Match = {}, Z extends Match = {}> { | ||
(m: M): Observableable<Z>; | ||
export declare class BestRouter<M extends Routable> extends Router<M> { | ||
constructor(...routersOrHandlers: RouterOrHandler<M>[]); | ||
} | ||
export interface Predicate<M extends Match = {}> { | ||
export declare function best<M extends Routable>(...routersOrHandlers: RouterOrHandler<M>[]): BestRouter<M>; | ||
export declare class RunRouter<M extends Routable> extends Router<M> { | ||
constructor(handler: Handler<M>); | ||
} | ||
export declare function run<M extends Routable>(handler: Handler<M>): RunRouter<M>; | ||
export interface Predicate<M extends Routable = {}> { | ||
(m: M): Observableable<boolean>; | ||
} | ||
export declare function tryMatch<M extends Match, N extends Match>(matcher: Matcher<M, N>, m: M): Observable<N>; | ||
export declare function tryMatch<M extends Match>(predicate: Predicate<M>, m: M): Observable<M>; | ||
export declare function tryMatch<M extends Match>(predicateOrMatcher: Predicate | Matcher, m: M): Observable<any>; | ||
export declare function combineScores(previousScore: any, nextScore: any): number; | ||
export declare function routeWithCombinedScore(route: Route, score?: number): Route; | ||
export declare function ifMatch<M extends Match>(predicate: Predicate<M>, ifRouterOrHandler: RouterOrHandler<M>, elseRouterOrHandler?: RouterOrHandler<M>): Router<M>; | ||
export declare function ifMatch<M extends Match, N extends Match>(matcher: Matcher<M, N>, ifRouterOrHandler: RouterOrHandler<N>, elseRouterOrHandler?: RouterOrHandler<M>): Router<M>; | ||
export declare function throwRoute<M extends Match>(): Router<M>; | ||
export declare function catchRoute<M extends Match>(routerOrHandler: RouterOrHandler<M>): Router<M>; | ||
export declare function before<M extends Match>(beforeHandler: Handler<M>, routerOrHandler: RouterOrHandler<M>): Router<M>; | ||
export declare function after<M extends Match>(routerOrHandler: RouterOrHandler<M>, afterHandler: Handler<M>): Router<M>; | ||
export declare function routeWithCombinedScore(route: Route, newScore: number): Route; | ||
export declare class IfDoRouter<M extends Routable> extends Router<M> { | ||
constructor(predicate: Predicate<M>, ifRouterOrHandler: RouterOrHandler<M>, elseRouterOrHandler?: RouterOrHandler<M>); | ||
} | ||
export declare function ifDo<M extends Routable>(predicate: Predicate<M>, ifRouterOrHandler: RouterOrHandler<M>, elseRouterOrHandler?: RouterOrHandler<M>): IfDoRouter<M>; | ||
export interface Matcher<M extends Routable = {}, Z extends Routable = {}> { | ||
(m: M): Observableable<Z>; | ||
} | ||
export declare class IfMatchRouter<M extends Routable, N extends Routable> extends Router<M> { | ||
constructor(matcher: Matcher<M, N>, ifRouterOrHandler: RouterOrHandler<N>, elseRouterOrHandler?: RouterOrHandler<M>); | ||
} | ||
export declare function ifMatch<M extends Routable, N extends Routable>(matcher: Matcher<M, N>, ifRouterOrHandler: RouterOrHandler<N>, elseRouterOrHandler?: RouterOrHandler<M>): IfMatchRouter<M, N>; | ||
export declare function throwRoute<M extends Routable>(): Router<M>; | ||
export declare function catchRoute<M extends Routable>(routerOrHandler: RouterOrHandler<M>): Router<M>; | ||
export declare class BeforeRouter<M extends Routable> extends Router<M> { | ||
constructor(beforeHandler: Handler<M>, routerOrHandler: RouterOrHandler<M>); | ||
} | ||
export declare function before<M extends Routable>(beforeHandler: Handler<M>, routerOrHandler: RouterOrHandler<M>): BeforeRouter<M>; | ||
export declare class AfterRouter<M extends Routable> extends Router<M> { | ||
constructor(routerOrHandler: RouterOrHandler<M>, afterHandler: Handler<M>); | ||
} | ||
export declare function after<M extends Routable>(routerOrHandler: RouterOrHandler<M>, afterHandler: Handler<M>): AfterRouter<M>; |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
return function (d, b) { | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __assign = (this && this.__assign) || Object.assign || function(t) { | ||
@@ -35,36 +45,50 @@ for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
} | ||
Router.fromHandler = function (handler) { | ||
return new Router(function (m) { return rxjs_1.Observable.of({ | ||
action: function () { return handler(m); } | ||
}); }); | ||
}; | ||
Router.from = function (routerOrHandler) { | ||
return routerOrHandler | ||
? routerOrHandler instanceof Router | ||
? routerOrHandler | ||
: Router.fromHandler(routerOrHandler) | ||
: Router.null; | ||
}; | ||
Router.routersFrom = function (routersOrHandlers) { | ||
return routersOrHandlers | ||
.map(function (routerOrHandler) { return Router.from(routerOrHandler); }); | ||
}; | ||
Router.prototype.route = function (m) { | ||
return this.getRoute(m) | ||
.do(function (route) { return Konsole_1.konsole.log("route: returned a route", route); }) | ||
.flatMap(function (route) { return toObservable(route.action()); }) | ||
.do(function (_) { return Konsole_1.konsole.log("route: called action"); }); | ||
}; | ||
Router.null = new Router(function (m) { return rxjs_1.Observable.empty(); }); | ||
return Router; | ||
}()); | ||
exports.Router = Router; | ||
exports.nullRouter = new Router(function (m) { return rxjs_1.Observable.empty(); }); | ||
function routeMessage(router, m) { | ||
return router.getRoute(m) | ||
.do(function (route) { return Konsole_1.konsole.log("handle: matched a route", route); }) | ||
.flatMap(function (route) { return toObservable(route.action()); }) | ||
.do(function (_) { return Konsole_1.konsole.log("handle: called action"); }); | ||
} | ||
exports.routeMessage = routeMessage; | ||
function isRouter(routerOrHandler) { | ||
return (routerOrHandler.getRoute !== undefined); | ||
} | ||
exports.isRouter = isRouter; | ||
function simpleRouter(handler) { | ||
return new Router(function (m) { return rxjs_1.Observable.of({ | ||
action: function () { return handler(m); } | ||
}); }); | ||
} | ||
exports.simpleRouter = simpleRouter; | ||
function toRouter(routerOrHandler) { | ||
return isRouter(routerOrHandler) ? routerOrHandler : simpleRouter(routerOrHandler); | ||
} | ||
exports.toRouter = toRouter; | ||
function filteredRouter$() { | ||
var routersOrHandlers = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
routersOrHandlers[_i] = arguments[_i]; | ||
var FirstRouter = (function (_super) { | ||
__extends(FirstRouter, _super); | ||
function FirstRouter() { | ||
var routersOrHandlers = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
routersOrHandlers[_i] = arguments[_i]; | ||
} | ||
var _this = this; | ||
var router$ = rxjs_1.Observable.from(Router.routersFrom(routersOrHandlers)); | ||
_this = _super.call(this, function (m) { return router$ | ||
.concatMap(function (router, i) { | ||
Konsole_1.konsole.log("first: trying router #" + i); | ||
return router.getRoute(m) | ||
.do(function (n) { return Konsole_1.konsole.log("first: router #" + i + " succeeded", n); }); | ||
}) | ||
.take(1); } // so that we don't keep going through routers after we find one that matches | ||
) || this; | ||
return _this; | ||
} | ||
return rxjs_1.Observable.from(routersOrHandlers) | ||
.filter(function (routerOrHandler) { return !!routerOrHandler; }) | ||
.map(function (routerOrHandler) { return toRouter(routerOrHandler); }); | ||
} | ||
return FirstRouter; | ||
}(Router)); | ||
exports.FirstRouter = FirstRouter; | ||
function first() { | ||
@@ -75,11 +99,3 @@ var routersOrHandlers = []; | ||
} | ||
var router$ = filteredRouter$.apply(void 0, routersOrHandlers); | ||
return new Router(function (m) { return router$ | ||
.concatMap(function (router, i) { | ||
Konsole_1.konsole.log("first: trying router #" + i); | ||
return router.getRoute(m) | ||
.do(function (n) { return Konsole_1.konsole.log("first: router #" + i + " succeeded", n); }); | ||
}) | ||
.take(1); } // so that we don't keep going through routers after we find one that matches | ||
); | ||
return new (FirstRouter.bind.apply(FirstRouter, [void 0].concat(routersOrHandlers)))(); | ||
} | ||
@@ -95,8 +111,38 @@ exports.first = first; | ||
exports.toScore = toScore; | ||
function addScore(t, score) { | ||
return toScore(t.score) === score | ||
? t | ||
: __assign({}, t, { score: score }); | ||
} | ||
exports.addScore = addScore; | ||
var BestRouter = (function (_super) { | ||
__extends(BestRouter, _super); | ||
function BestRouter() { | ||
var routersOrHandlers = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
routersOrHandlers[_i] = arguments[_i]; | ||
} | ||
var _this = this; | ||
var router$ = rxjs_1.Observable.from(Router.routersFrom(routersOrHandlers)); | ||
_this = _super.call(this, function (m) { return new rxjs_1.Observable(function (observer) { | ||
var bestRoute = minRoute; | ||
var subscription = router$ | ||
.takeWhile(function (_) { return toScore(bestRoute.score) < 1; }) | ||
.concatMap(function (router) { return router.getRoute(m); }) | ||
.subscribe(function (route) { | ||
if (toScore(route.score) > toScore(bestRoute.score)) { | ||
bestRoute = route; | ||
if (toScore(bestRoute.score) === 1) { | ||
observer.next(bestRoute); | ||
observer.complete(); | ||
} | ||
} | ||
}, function (error) { | ||
return observer.error(error); | ||
}, function () { | ||
if (toScore(bestRoute.score) > 0) | ||
observer.next(bestRoute); | ||
observer.complete(); | ||
}); | ||
return function () { return subscription.unsubscribe(); }; | ||
}); }) || this; | ||
return _this; | ||
} | ||
return BestRouter; | ||
}(Router)); | ||
exports.BestRouter = BestRouter; | ||
function best() { | ||
@@ -107,64 +153,65 @@ var routersOrHandlers = []; | ||
} | ||
var router$ = filteredRouter$.apply(void 0, routersOrHandlers); | ||
return new Router(function (m) { return new rxjs_1.Observable(function (observer) { | ||
var bestRoute = minRoute; | ||
var subscription = router$ | ||
.takeWhile(function (_) { return toScore(bestRoute.score) < 1; }) | ||
.concatMap(function (router) { return router.getRoute(m); }) | ||
.subscribe(function (route) { | ||
if (toScore(route.score) > toScore(bestRoute.score)) { | ||
bestRoute = route; | ||
if (toScore(bestRoute.score) === 1) { | ||
observer.next(bestRoute); | ||
observer.complete(); | ||
} | ||
} | ||
}, function (error) { | ||
return observer.error(error); | ||
}, function () { | ||
if (toScore(bestRoute.score) > 0) | ||
observer.next(bestRoute); | ||
observer.complete(); | ||
}); | ||
return function () { return subscription.unsubscribe(); }; | ||
}); }); | ||
return new (BestRouter.bind.apply(BestRouter, [void 0].concat(routersOrHandlers)))(); | ||
} | ||
exports.best = best; | ||
var RunRouter = (function (_super) { | ||
__extends(RunRouter, _super); | ||
function RunRouter(handler) { | ||
return _super.call(this, function (m) { return toObservable(handler(m)) | ||
.filter(function (_) { return false; }); }) || this; | ||
} | ||
return RunRouter; | ||
}(Router)); | ||
exports.RunRouter = RunRouter; | ||
function run(handler) { | ||
return new Router(function (m) { return toObservable(handler(m)) | ||
.filter(function (_) { return false; }); }); | ||
return new RunRouter(handler); | ||
} | ||
exports.run = run; | ||
function tryMatch(predicateOrMatcher, m) { | ||
// we want to allow any matcher to be a predicate (return a boolean) | ||
// if so, the 'falsey' case will be filtered out by toFilteredObservable, | ||
// so we just need to catch the case where it is precisely true | ||
Konsole_1.konsole.log("tryMatch", predicateOrMatcher, m); | ||
return toFilteredObservable(predicateOrMatcher(m)) | ||
.map(function (n) { return typeof n === 'boolean' | ||
? addScore(m, 1) | ||
: n; }); | ||
function routeWithCombinedScore(route, newScore) { | ||
var score = toScore(newScore) * toScore(route.score); | ||
return toScore(route.score) === score | ||
? route | ||
: __assign({}, route, { score: score }); | ||
} | ||
exports.tryMatch = tryMatch; | ||
function combineScores(previousScore, nextScore) { | ||
return toScore(previousScore) * toScore(nextScore); | ||
exports.routeWithCombinedScore = routeWithCombinedScore; | ||
var IfDoRouter = (function (_super) { | ||
__extends(IfDoRouter, _super); | ||
function IfDoRouter(predicate, ifRouterOrHandler, elseRouterOrHandler) { | ||
var _this = this; | ||
var ifRouter = Router.from(ifRouterOrHandler); | ||
var elseRouter = Router.from(elseRouterOrHandler); | ||
_this = _super.call(this, function (m) { return toObservable(predicate(m)) | ||
.flatMap(function (n) { return n | ||
? ifRouter.getRoute(m) | ||
: elseRouter.getRoute(m) | ||
.map(function (route) { return routeWithCombinedScore(route, m.score); }); }); }) || this; | ||
return _this; | ||
} | ||
return IfDoRouter; | ||
}(Router)); | ||
exports.IfDoRouter = IfDoRouter; | ||
function ifDo(predicate, ifRouterOrHandler, elseRouterOrHandler) { | ||
return new IfDoRouter(predicate, ifRouterOrHandler, elseRouterOrHandler); | ||
} | ||
exports.combineScores = combineScores; | ||
function routeWithCombinedScore(route, score) { | ||
return addScore(route, combineScores(score, route.score)); | ||
exports.ifDo = ifDo; | ||
var IfMatchRouter = (function (_super) { | ||
__extends(IfMatchRouter, _super); | ||
function IfMatchRouter(matcher, ifRouterOrHandler, elseRouterOrHandler) { | ||
var _this = this; | ||
var ifRouter = Router.from(ifRouterOrHandler); | ||
var elseRouter = Router.from(elseRouterOrHandler); | ||
_this = _super.call(this, function (m) { return toObservable(matcher(m)) | ||
.flatMap(function (n) { return n | ||
? ifRouter.getRoute(n) | ||
.map(function (route) { return routeWithCombinedScore(route, n.score); }) | ||
: elseRouter.getRoute(m) | ||
.map(function (route) { return routeWithCombinedScore(route, m.score); }); }); }) || this; | ||
return _this; | ||
} | ||
return IfMatchRouter; | ||
}(Router)); | ||
exports.IfMatchRouter = IfMatchRouter; | ||
function ifMatch(matcher, ifRouterOrHandler, elseRouterOrHandler) { | ||
return new IfMatchRouter(matcher, ifRouterOrHandler, elseRouterOrHandler); | ||
} | ||
exports.routeWithCombinedScore = routeWithCombinedScore; | ||
function ifMatch(predicateOrMatcher, ifRouterOrHandler, elseRouterOrHandler) { | ||
var ifRouter = toRouter(ifRouterOrHandler); | ||
var elseRouter = elseRouterOrHandler | ||
? toRouter(elseRouterOrHandler) | ||
: exports.nullRouter; | ||
return new Router(function (m) { return tryMatch(predicateOrMatcher, m) | ||
.defaultIfEmpty(null) | ||
.flatMap(function (n) { return n | ||
? ifRouter.getRoute(n) | ||
.map(function (route) { return routeWithCombinedScore(route, n.score); }) | ||
: elseRouter.getRoute(m) | ||
.map(function (route) { return routeWithCombinedScore(route, m.score); }); }); }); | ||
} | ||
exports.ifMatch = ifMatch; | ||
@@ -180,3 +227,3 @@ var thrownRoute = { | ||
function catchRoute(routerOrHandler) { | ||
return new Router(function (m) { return toRouter(routerOrHandler) | ||
return new Router(function (m) { return Router.from(routerOrHandler) | ||
.getRoute(m) | ||
@@ -186,16 +233,36 @@ .filter(function (route) { return !route.thrown; }); }); | ||
exports.catchRoute = catchRoute; | ||
var BeforeRouter = (function (_super) { | ||
__extends(BeforeRouter, _super); | ||
function BeforeRouter(beforeHandler, routerOrHandler) { | ||
var _this = this; | ||
var router = Router.from(routerOrHandler); | ||
_this = _super.call(this, function (m) { return router.getRoute(m) | ||
.map(function (route) { return (__assign({}, route, { action: function () { return toObservable(beforeHandler(m)) | ||
.flatMap(function (_) { return toObservable(route.action()); }); } })); }); }) || this; | ||
return _this; | ||
} | ||
return BeforeRouter; | ||
}(Router)); | ||
exports.BeforeRouter = BeforeRouter; | ||
function before(beforeHandler, routerOrHandler) { | ||
var router = toRouter(routerOrHandler); | ||
return new Router(function (m) { return router.getRoute(m) | ||
.map(function (route) { return (__assign({}, route, { action: function () { return toObservable(beforeHandler(m)) | ||
.flatMap(function (_) { return toObservable(route.action()); }); } })); }); }); | ||
return new BeforeRouter(beforeHandler, routerOrHandler); | ||
} | ||
exports.before = before; | ||
var AfterRouter = (function (_super) { | ||
__extends(AfterRouter, _super); | ||
function AfterRouter(routerOrHandler, afterHandler) { | ||
var _this = this; | ||
var router = Router.from(routerOrHandler); | ||
_this = _super.call(this, function (m) { return router.getRoute(m) | ||
.map(function (route) { return (__assign({}, route, { action: function () { return toObservable(route.action()) | ||
.flatMap(function (_) { return toObservable(afterHandler(m)); }); } })); }); }) || this; | ||
return _this; | ||
} | ||
return AfterRouter; | ||
}(Router)); | ||
exports.AfterRouter = AfterRouter; | ||
function after(routerOrHandler, afterHandler) { | ||
var router = toRouter(routerOrHandler); | ||
return new Router(function (m) { return router.getRoute(m) | ||
.map(function (route) { return (__assign({}, route, { action: function () { return toObservable(route.action()) | ||
.flatMap(function (_) { return toObservable(afterHandler(m)); }); } })); }); }); | ||
return new AfterRouter(routerOrHandler, afterHandler); | ||
} | ||
exports.after = after; | ||
//# sourceMappingURL=Router.js.map |
@@ -7,3 +7,3 @@ { | ||
}, | ||
"version": "0.13.5", | ||
"version": "0.14.0", | ||
"description": "rules-based app engine", | ||
@@ -10,0 +10,0 @@ "main": "dist/prague.js", |
@@ -6,3 +6,3 @@ "use strict"; | ||
const expect = chai.expect; | ||
const { toObservable, toFilteredObservable, isRouter, simpleRouter, toRouter, routeMessage, first, best, run, tryMatch, toScore, routeWithCombinedScore, ifMatch, nullRouter, throwRoute, catchRoute, matchAll, firstMatch, bestMatch, before, after } = require('../dist/prague.js'); | ||
const { toObservable, toFilteredObservable, Router, first, best, run, toScore, routeWithCombinedScore, ifDo, ifMatch, throwRoute, catchRoute, before, after } = require('../dist/prague.js'); | ||
const { Observable } = require('rxjs'); | ||
@@ -278,5 +278,5 @@ | ||
describe('nullRouter', () => { | ||
describe('Router.null', () => { | ||
it('should not route', (done) => { | ||
nullRouter | ||
Router.null | ||
.getRoute(foo) | ||
@@ -291,7 +291,5 @@ .subscribe(throwErr, passErr, done); | ||
const testRouter = { | ||
getRoute: (m) => Observable.of({ | ||
action: () => { routed = true; } | ||
}) | ||
} | ||
const testRouter = new Router(m => Observable.of({ | ||
action: () => { routed = true; } | ||
})); | ||
@@ -308,8 +306,6 @@ testRouter | ||
describe('routeMessage', () => { | ||
it("should complete and never commit on nullRouter", (done) => { | ||
routeMessage( | ||
nullRouter, | ||
foo | ||
) | ||
describe('Router.route', () => { | ||
it("should complete and never commit on Router.null", (done) => { | ||
Router.null | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done); | ||
@@ -321,12 +317,8 @@ }); | ||
const testRouter = { | ||
getRoute: (m) => Observable.of({ | ||
action: () => { routed = true; } | ||
}) | ||
} | ||
const testRouter = new Router(m => Observable.of({ | ||
action: () => { routed = true; } | ||
})); | ||
routeMessage( | ||
testRouter, | ||
foo | ||
) | ||
testRouter | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -339,23 +331,10 @@ expect(routed).to.be.true; | ||
describe('isRouter', () => { | ||
it('should return true for a router', () => { | ||
expect(isRouter(nullRouter)).to.be.true; | ||
}); | ||
it('should return false for a handler', () => { | ||
expect(isRouter(m => true)).to.be.false; | ||
}); | ||
}) | ||
describe('simpleRouter', () => { | ||
describe('Router.fromHandler', () => { | ||
it("should convert a handler to a router", (done) => { | ||
let routed; | ||
routeMessage( | ||
simpleRouter(m => { | ||
routed = true; | ||
}), | ||
foo | ||
) | ||
Router.fromHandler(m => { | ||
routed = true; | ||
}) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -368,12 +347,10 @@ expect(routed).to.be.true; | ||
describe('toRouter', () => { | ||
describe('Router.from', () => { | ||
it('should convert a router to a router', (done) => { | ||
let routed; | ||
routeMessage( | ||
toRouter(simpleRouter(m => { | ||
routed = true; | ||
})), | ||
foo | ||
) | ||
Router.from(Router.fromHandler(m => { | ||
routed = true; | ||
})) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -388,8 +365,6 @@ expect(routed).to.be.true; | ||
routeMessage( | ||
toRouter(m => { | ||
routed = true; | ||
}), | ||
foo | ||
) | ||
Router.from(m => { | ||
routed = true; | ||
}) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -404,6 +379,4 @@ expect(routed).to.be.true; | ||
it('should complete and never emit on no routers', (done) => | ||
routeMessage( | ||
first(), | ||
foo | ||
) | ||
first() | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
@@ -413,9 +386,7 @@ ); | ||
it('should complete and never emit on only null/undefined routers', (done) => | ||
routeMessage( | ||
first( | ||
null, | ||
undefined | ||
), | ||
foo | ||
first( | ||
null, | ||
undefined | ||
) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
@@ -425,10 +396,8 @@ ); | ||
it('should complete and never emit on only unsuccessful and null/undefined routers', (done) => | ||
routeMessage( | ||
first( | ||
nullRouter, | ||
null, | ||
undefined | ||
), | ||
foo | ||
first( | ||
Router.null, | ||
null, | ||
undefined | ||
) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
@@ -438,8 +407,6 @@ ); | ||
it('should complete and never emit on no successful routers', (done) => { | ||
routeMessage( | ||
first( | ||
nullRouter | ||
), | ||
foo | ||
first( | ||
Router.null | ||
) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
@@ -451,10 +418,8 @@ }); | ||
routeMessage( | ||
first( | ||
m => { | ||
routed = true; | ||
} | ||
), | ||
foo | ||
first( | ||
m => { | ||
routed = true; | ||
} | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -469,10 +434,8 @@ expect(routed).to.be.true; | ||
routeMessage( | ||
first( | ||
simpleRouter(m => { | ||
routed = true; | ||
}) | ||
), | ||
foo | ||
first( | ||
Router.fromHandler(m => { | ||
routed = true; | ||
}) | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -487,12 +450,10 @@ expect(routed).to.be.true; | ||
routeMessage( | ||
first( | ||
null, | ||
undefined, | ||
simpleRouter(m => { | ||
routed = true; | ||
}) | ||
), | ||
false | ||
first( | ||
null, | ||
undefined, | ||
Router.fromHandler(m => { | ||
routed = true; | ||
}) | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -507,11 +468,9 @@ expect(routed).to.be.true; | ||
routeMessage( | ||
first( | ||
nullRouter, | ||
simpleRouter(m => { | ||
routed = true; | ||
}) | ||
), | ||
foo | ||
first( | ||
Router.null, | ||
Router.fromHandler(m => { | ||
routed = true; | ||
}) | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -525,15 +484,11 @@ expect(routed).to.be.true; | ||
const makeRouter = (score, action) => ({ | ||
getRoute: (m) => Observable.of({ | ||
score, | ||
action | ||
}) | ||
}); | ||
const makeRouter = (score, action) => new Router(m => Observable.of({ | ||
score, | ||
action | ||
})); | ||
describe('best', () => { | ||
it('should complete and never emit on no routers', (done) => | ||
routeMessage( | ||
best(), | ||
foo | ||
) | ||
best() | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
@@ -543,9 +498,7 @@ ); | ||
it('should complete and never emit on only null/undefined routers', (done) => | ||
routeMessage( | ||
best( | ||
null, | ||
undefined | ||
), | ||
foo | ||
best( | ||
null, | ||
undefined | ||
) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
@@ -555,10 +508,8 @@ ); | ||
it('should complete and never emit on only unsuccessful and null/undefined routers', (done) => | ||
routeMessage( | ||
best( | ||
nullRouter, | ||
null, | ||
undefined | ||
), | ||
foo | ||
best( | ||
Router.null, | ||
null, | ||
undefined | ||
) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
@@ -568,8 +519,6 @@ ); | ||
it('should complete and never emit on no successful routers', (done) => { | ||
routeMessage( | ||
best( | ||
nullRouter | ||
), | ||
foo | ||
best( | ||
Router.null | ||
) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
@@ -581,10 +530,8 @@ }); | ||
routeMessage( | ||
best( | ||
m => { | ||
routed = true; | ||
} | ||
), | ||
foo | ||
best( | ||
m => { | ||
routed = true; | ||
} | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -599,10 +546,8 @@ expect(routed).to.be.true; | ||
routeMessage( | ||
best( | ||
simpleRouter(m => { | ||
routed = true; | ||
}) | ||
), | ||
foo | ||
best( | ||
Router.fromHandler(m => { | ||
routed = true; | ||
}) | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -617,12 +562,10 @@ expect(routed).to.be.true; | ||
routeMessage( | ||
best( | ||
null, | ||
undefined, | ||
simpleRouter(m => { | ||
routed = true; | ||
}) | ||
), | ||
foo | ||
best( | ||
null, | ||
undefined, | ||
Router.fromHandler(m => { | ||
routed = true; | ||
}) | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -637,11 +580,9 @@ expect(routed).to.be.true; | ||
routeMessage( | ||
best( | ||
nullRouter, | ||
simpleRouter(m => { | ||
routed = true; | ||
}) | ||
), | ||
foo | ||
best( | ||
Router.null, | ||
Router.fromHandler(m => { | ||
routed = true; | ||
}) | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -656,11 +597,9 @@ expect(routed).to.be.true; | ||
routeMessage( | ||
best( | ||
m => { | ||
routed = true; | ||
}, | ||
throwErr | ||
), | ||
foo | ||
best( | ||
m => { | ||
routed = true; | ||
}, | ||
throwErr | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -675,9 +614,7 @@ expect(routed).to.be.true; | ||
routeMessage( | ||
best( | ||
makeRouter(0.75, _ => { routed = 'first'; }), | ||
makeRouter(0.50, _ => { routed = 'second'; }) | ||
), | ||
foo | ||
best( | ||
makeRouter(0.75, _ => { routed = 'first'; }), | ||
makeRouter(0.50, _ => { routed = 'second'; }) | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -692,9 +629,7 @@ expect(routed).to.eql('first'); | ||
routeMessage( | ||
best( | ||
makeRouter(0.50, _ => { routed = 'first'; }), | ||
makeRouter(0.75, _ => { routed = 'second'; }) | ||
), | ||
foo | ||
best( | ||
makeRouter(0.50, _ => { routed = 'first'; }), | ||
makeRouter(0.75, _ => { routed = 'second'; }) | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -709,9 +644,7 @@ expect(routed).to.eql('second'); | ||
routeMessage( | ||
best( | ||
makeRouter(undefined, _ => { routed = 'first'; }), | ||
makeRouter(0.75, _ => { routed = 'second'; }) | ||
), | ||
foo | ||
best( | ||
makeRouter(undefined, _ => { routed = 'first'; }), | ||
makeRouter(0.75, _ => { routed = 'second'; }) | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -726,9 +659,7 @@ expect(routed).to.eql('first'); | ||
routeMessage( | ||
best( | ||
makeRouter(0.75, _ => { routed = 'first'; }), | ||
makeRouter(0.75, _ => { routed = 'second'; }) | ||
), | ||
foo | ||
best( | ||
makeRouter(0.75, _ => { routed = 'first'; }), | ||
makeRouter(0.75, _ => { routed = 'second'; }) | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -746,10 +677,8 @@ expect(routed).to.eql('first'); | ||
routeMessage( | ||
run( | ||
m => { | ||
routed = true; | ||
} | ||
), | ||
foo | ||
run( | ||
m => { | ||
routed = true; | ||
} | ||
) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, _ => { | ||
@@ -762,39 +691,2 @@ expect(routed).to.be.true; | ||
describe('tryMatch', () => { | ||
it('should complete and never emit on false predicate', (done) => | ||
tryMatch(m => false, foo) | ||
.subscribe(throwErr, passErr, done) | ||
); | ||
it('should complete on true predicate', (done) => { | ||
tryMatch(m => true, foo) | ||
.subscribe(noop, noop, done); | ||
}); | ||
it('should pass message through on true predicate', (done) => { | ||
tryMatch(m => true, foo).subscribe(n => { | ||
expect(n).to.containSubset(foo); | ||
done(); | ||
}); | ||
}); | ||
it('should complete on match', (done) => { | ||
tryMatch(addBar, foo) | ||
.subscribe(noop, noop, done); | ||
}); | ||
it('should pass result through on match', (done) => { | ||
tryMatch(addBar, foo).subscribe(n => { | ||
expect(n).to.eql(fooPlusBar); | ||
done(); | ||
}); | ||
}); | ||
it('should complete and never emit on no match', (done) => | ||
tryMatch(addBar, notFoo) | ||
.subscribe(throwErr, passErr, done) | ||
); | ||
}); | ||
describe('routeWithCombinedScore', () => { | ||
@@ -838,108 +730,51 @@ it("should return score=1 with both scores undefined", () => { | ||
describe('ifMatch', () => { | ||
it("should complete and never emit on false predicate when 'else' router doesn't exist", (done) => | ||
routeMessage( | ||
ifMatch( | ||
m => false, | ||
throwErr | ||
), | ||
foo | ||
describe('ifDo', () => { | ||
it("should complete and never emit on false when 'else' router doesn't exist", (done) => | ||
ifMatch( | ||
m => false, | ||
throwErr | ||
) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
); | ||
it("should complete and never emit on false predicate when 'else' router doesn't route", (done) => | ||
routeMessage( | ||
ifMatch( | ||
m => false, | ||
throwErr, | ||
nullRouter | ||
), | ||
foo | ||
it("should complete and never emit on true when 'else' router doesn't route", (done) => | ||
ifDo( | ||
m => false, | ||
throwErr, | ||
Router.null | ||
) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
); | ||
it("should complete and never emit on no match when 'else' router doesn't exist", (done) => | ||
routeMessage( | ||
ifMatch( | ||
addBar, | ||
throwErr | ||
), | ||
notFoo | ||
it("should complete and never emit on true when 'if' router doesn't route and 'else' router doesn't exist", (done) => | ||
ifDo( | ||
m => true, | ||
Router.null | ||
) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
); | ||
it("should complete and never emit on no match when 'else' router doesn't route", (done) => | ||
routeMessage( | ||
ifMatch( | ||
addBar, | ||
throwErr, | ||
nullRouter | ||
), | ||
notFoo | ||
it("should complete and never emit on true when 'if' router doesn't route and 'else' router exists", (done) => | ||
ifDo( | ||
m => true, | ||
Router.null, | ||
throwErr | ||
) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
); | ||
it("should complete and never emit on true predicate when 'if' router doesn't route and 'else' router doesn't exist", (done) => | ||
routeMessage( | ||
ifMatch( | ||
m => true, | ||
nullRouter | ||
), | ||
foo | ||
) | ||
.subscribe(throwErr, passErr, done) | ||
); | ||
it("should complete and never emit on true predicate when 'if' router doesn't route and 'else' router exists", (done) => | ||
routeMessage( | ||
ifMatch( | ||
m => true, | ||
nullRouter, | ||
throwErr | ||
), | ||
foo | ||
) | ||
.subscribe(throwErr, passErr, done) | ||
); | ||
it("should complete and never emit on match when 'if' router doesn't route and 'else' router doesn't exist", (done) => | ||
routeMessage( | ||
ifMatch( | ||
addBar, | ||
nullRouter | ||
), | ||
foo | ||
) | ||
.subscribe(throwErr, passErr, done) | ||
); | ||
it("should complete and never emit on match when 'if' router doesn't route and 'else' router exists", (done) => | ||
routeMessage( | ||
ifMatch( | ||
addBar, | ||
nullRouter, | ||
throwErr | ||
), | ||
foo | ||
) | ||
.subscribe(throwErr, passErr, done) | ||
); | ||
it("should route message to 'if' handler on true predicate when 'else' router doesn't exist", (done) => { | ||
let routed; | ||
routeMessage( | ||
ifMatch( | ||
m => true, | ||
m => { | ||
routed = true; | ||
} | ||
), | ||
foo | ||
ifDo( | ||
m => true, | ||
m => { | ||
routed = true; | ||
} | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -954,12 +789,10 @@ expect(routed).to.be.true; | ||
routeMessage( | ||
ifMatch( | ||
m => true, | ||
m => { | ||
routed = true; | ||
}, | ||
throwErr | ||
), | ||
foo | ||
ifDo( | ||
m => true, | ||
m => { | ||
routed = true; | ||
}, | ||
throwErr | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -974,11 +807,9 @@ expect(routed).to.be.true; | ||
routeMessage( | ||
ifMatch( | ||
m => true, | ||
simpleRouter(m => { | ||
routed = true; | ||
}) | ||
), | ||
foo | ||
ifDo( | ||
m => true, | ||
Router.fromHandler(m => { | ||
routed = true; | ||
}) | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -993,12 +824,10 @@ expect(routed).to.be.true; | ||
routeMessage( | ||
ifMatch( | ||
m => true, | ||
simpleRouter(m => { | ||
routed = true; | ||
}), | ||
throwErr | ||
), | ||
foo | ||
ifDo( | ||
m => true, | ||
Router.fromHandler(m => { | ||
routed = true; | ||
}), | ||
throwErr | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -1010,14 +839,13 @@ expect(routed).to.be.true; | ||
it("should route message to 'if' handler on match when 'else' router doesn't exist", (done) => { | ||
it("should route message to 'else' handler on false predicate", (done) => { | ||
let routed; | ||
routeMessage( | ||
ifMatch( | ||
addBar, | ||
m => { | ||
routed = true; | ||
} | ||
), | ||
foo | ||
ifDo( | ||
m => false, | ||
throwErr, | ||
m => { | ||
routed = true; | ||
} | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -1029,15 +857,13 @@ expect(routed).to.be.true; | ||
it("should route message to 'if' handler on match when 'else' router exists", (done) => { | ||
it("should route message to 'else' router on false predicate", (done) => { | ||
let routed; | ||
routeMessage( | ||
ifMatch( | ||
addBar, | ||
m => { | ||
routed = true; | ||
}, | ||
throwErr | ||
), | ||
foo | ||
ifDo( | ||
m => false, | ||
throwErr, | ||
Router.fromHandler(m => { | ||
routed = true; | ||
}) | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -1049,16 +875,22 @@ expect(routed).to.be.true; | ||
it("should route message to 'if' router on match when 'else' router doesn't exist", (done) => { | ||
let routed; | ||
it("should return score=1 on true predicate when 'if' score undefined", (done) => { | ||
ifDo( | ||
m => true, | ||
m => {} | ||
) | ||
.getRoute(foo) | ||
.subscribe(route => { | ||
expect(toScore(route.score)).to.eql(1); | ||
done(); | ||
}) | ||
}); | ||
routeMessage( | ||
ifMatch( | ||
addBar, | ||
simpleRouter(m => { | ||
routed = true; | ||
}) | ||
), | ||
foo | ||
it("should return route score on true predicate", (done) => { | ||
ifDo( | ||
m => true, | ||
makeRouter(0.25, () => {}) | ||
) | ||
.subscribe(n => { | ||
expect(routed).to.be.true; | ||
.getRoute(foo) | ||
.subscribe(route => { | ||
expect(toScore(route.score)).to.eql(.25); | ||
done(); | ||
@@ -1068,15 +900,80 @@ }) | ||
it("should route message to 'if' router on match when 'else' router exists", (done) => { | ||
it("should return score=1 on false predicate when 'else' score undefined", (done) => { | ||
ifDo( | ||
m => false, | ||
m => {}, | ||
m => {} | ||
) | ||
.getRoute(foo) | ||
.subscribe(route => { | ||
expect(toScore(route.score)).to.eql(1); | ||
done(); | ||
}) | ||
}); | ||
it("should return 'else' route score on false predicate", (done) => { | ||
ifDo( | ||
m => false, | ||
throwErr, | ||
makeRouter(0.5, () => {}) | ||
) | ||
.getRoute(foo) | ||
.subscribe(route => { | ||
expect(toScore(route.score)).to.eql(.5); | ||
done(); | ||
}) | ||
}); | ||
}); | ||
describe('ifMatch', () => { | ||
it("should complete and never emit on no match when 'else' router doesn't exist", (done) => | ||
ifMatch( | ||
addBar, | ||
throwErr | ||
) | ||
.route(notFoo) | ||
.subscribe(throwErr, passErr, done) | ||
); | ||
it("should complete and never emit on no match when 'else' router doesn't route", (done) => | ||
ifMatch( | ||
addBar, | ||
throwErr, | ||
Router.null | ||
) | ||
.route(notFoo) | ||
.subscribe(throwErr, passErr, done) | ||
); | ||
it("should complete and never emit on match when 'if' router doesn't route and 'else' router doesn't exist", (done) => | ||
ifMatch( | ||
addBar, | ||
Router.null | ||
) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
); | ||
it("should complete and never emit on match when 'if' router doesn't route and 'else' router exists", (done) => | ||
ifMatch( | ||
addBar, | ||
Router.null, | ||
throwErr | ||
) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
); | ||
it("should route message to 'if' handler on match when 'else' router doesn't exist", (done) => { | ||
let routed; | ||
routeMessage( | ||
ifMatch( | ||
addBar, | ||
simpleRouter(m => { | ||
routed = true; | ||
}), | ||
throwErr | ||
), | ||
foo | ||
ifMatch( | ||
addBar, | ||
m => { | ||
routed = true; | ||
} | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -1088,16 +985,13 @@ expect(routed).to.be.true; | ||
it("should route message to 'else' handler on false predicate", (done) => { | ||
it("should route message to 'if' handler on match when 'else' router exists", (done) => { | ||
let routed; | ||
routeMessage( | ||
ifMatch( | ||
m => false, | ||
throwErr, | ||
m => { | ||
routed = true; | ||
} | ||
), | ||
foo | ||
ifMatch( | ||
addBar, | ||
m => { | ||
routed = true; | ||
}, | ||
throwErr | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -1109,15 +1003,12 @@ expect(routed).to.be.true; | ||
it("should route message to 'else' router on false predicate", (done) => { | ||
it("should route message to 'if' router on match when 'else' router doesn't exist", (done) => { | ||
let routed; | ||
routeMessage( | ||
ifMatch( | ||
m => false, | ||
throwErr, | ||
simpleRouter(m => { | ||
routed = true; | ||
}) | ||
), | ||
foo | ||
ifMatch( | ||
addBar, | ||
Router.fromHandler(m => { | ||
routed = true; | ||
}) | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -1129,15 +1020,13 @@ expect(routed).to.be.true; | ||
it("should route message to 'else' handler on no match", (done) => { | ||
it("should route message to 'if' router on match when 'else' router exists", (done) => { | ||
let routed; | ||
routeMessage( | ||
ifMatch( | ||
addBar, | ||
throwErr, | ||
m => { | ||
routed = true; | ||
} | ||
), | ||
notFoo | ||
ifMatch( | ||
addBar, | ||
Router.fromHandler(m => { | ||
routed = true; | ||
}), | ||
throwErr | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -1149,15 +1038,13 @@ expect(routed).to.be.true; | ||
it("should route message to 'else' router on no match", (done) => { | ||
it("should route message to 'else' handler on no match", (done) => { | ||
let routed; | ||
routeMessage( | ||
ifMatch( | ||
addBar, | ||
throwErr, | ||
simpleRouter(m => { | ||
routed = true; | ||
}) | ||
), | ||
notFoo | ||
ifMatch( | ||
addBar, | ||
throwErr, | ||
m => { | ||
routed = true; | ||
} | ||
) | ||
.route(notFoo) | ||
.subscribe(n => { | ||
@@ -1169,10 +1056,15 @@ expect(routed).to.be.true; | ||
it("should return score=1 on true predicate when 'if' score undefined", (done) => { | ||
it("should route message to 'else' router on no match", (done) => { | ||
let routed; | ||
ifMatch( | ||
m => true, | ||
m => {} | ||
addBar, | ||
throwErr, | ||
Router.fromHandler(m => { | ||
routed = true; | ||
}) | ||
) | ||
.getRoute(foo) | ||
.subscribe(route => { | ||
expect(toScore(route.score)).to.eql(1); | ||
.route(notFoo) | ||
.subscribe(n => { | ||
expect(routed).to.be.true; | ||
done(); | ||
@@ -1208,14 +1100,2 @@ }) | ||
it("should return route score on true predicate", (done) => { | ||
ifMatch( | ||
m => true, | ||
makeRouter(0.25, () => {}) | ||
) | ||
.getRoute(foo) | ||
.subscribe(route => { | ||
expect(toScore(route.score)).to.eql(.25); | ||
done(); | ||
}) | ||
}); | ||
it("should return route score on scoreless match", (done) => { | ||
@@ -1247,15 +1127,2 @@ ifMatch( | ||
it("should return score=1 on false predicate when 'else' score undefined", (done) => { | ||
ifMatch( | ||
m => false, | ||
m => {}, | ||
m => {} | ||
) | ||
.getRoute(foo) | ||
.subscribe(route => { | ||
expect(toScore(route.score)).to.eql(1); | ||
done(); | ||
}) | ||
}); | ||
it("should return score=1 on scoreless match when 'else' score undefined", (done) => { | ||
@@ -1274,15 +1141,2 @@ ifMatch( | ||
it("should return 'else' route score on false predicate", (done) => { | ||
ifMatch( | ||
m => false, | ||
throwErr, | ||
makeRouter(0.5, () => {}) | ||
) | ||
.getRoute(foo) | ||
.subscribe(route => { | ||
expect(toScore(route.score)).to.eql(.5); | ||
done(); | ||
}) | ||
}); | ||
it("should return 'else' route score on no match", (done) => { | ||
@@ -1317,8 +1171,6 @@ ifMatch( | ||
routeMessage( | ||
catchRoute(m => { | ||
routed = true; | ||
}), | ||
foo | ||
) | ||
catchRoute(m => { | ||
routed = true; | ||
}) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -1333,8 +1185,6 @@ expect(routed).to.be.true; | ||
routeMessage( | ||
catchRoute(simpleRouter(m => { | ||
routed = true; | ||
})), | ||
foo | ||
) | ||
catchRoute(Router.fromHandler(m => { | ||
routed = true; | ||
})) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -1349,6 +1199,4 @@ expect(routed).to.be.true; | ||
routeMessage( | ||
catchRoute(throwRoute()), | ||
foo | ||
) | ||
catchRoute(throwRoute()) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done); | ||
@@ -1360,9 +1208,7 @@ }); | ||
it("should complete and never emit with null router", (done) => { | ||
routeMessage( | ||
before( | ||
throwErr, | ||
nullRouter | ||
), | ||
foo | ||
before( | ||
throwErr, | ||
Router.null | ||
) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
@@ -1375,12 +1221,12 @@ }); | ||
routeMessage( | ||
before( | ||
m => { | ||
handled = true; | ||
}, | ||
m => { | ||
expect(handled).to.be.true; | ||
routed = true; | ||
} | ||
)) | ||
before( | ||
m => { | ||
handled = true; | ||
}, | ||
m => { | ||
expect(handled).to.be.true; | ||
routed = true; | ||
} | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -1396,12 +1242,12 @@ expect(routed).to.be.true; | ||
routeMessage( | ||
before( | ||
m => { | ||
handled = true; | ||
}, | ||
simpleRouter(m => { | ||
expect(handled).to.be.true; | ||
routed = true; | ||
}) | ||
)) | ||
before( | ||
m => { | ||
handled = true; | ||
}, | ||
Router.fromHandler(m => { | ||
expect(handled).to.be.true; | ||
routed = true; | ||
}) | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -1418,9 +1264,7 @@ expect(routed).to.be.true; | ||
it("should complete and never emit with null router", (done) => { | ||
routeMessage( | ||
after( | ||
nullRouter, | ||
throwErr | ||
), | ||
foo | ||
after( | ||
Router.null, | ||
throwErr | ||
) | ||
.route(foo) | ||
.subscribe(throwErr, passErr, done) | ||
@@ -1433,12 +1277,12 @@ }); | ||
routeMessage( | ||
after( | ||
m => { | ||
routed = true; | ||
}, | ||
m => { | ||
expect(routed).to.be.true; | ||
handled = true; | ||
} | ||
)) | ||
after( | ||
m => { | ||
routed = true; | ||
}, | ||
m => { | ||
expect(routed).to.be.true; | ||
handled = true; | ||
} | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -1454,12 +1298,12 @@ expect(handled).to.be.true; | ||
routeMessage( | ||
after( | ||
simpleRouter(m => { | ||
routed = true; | ||
}), | ||
m => { | ||
expect(routed).to.be.true; | ||
handled = true; | ||
} | ||
)) | ||
after( | ||
Router.fromHandler(m => { | ||
routed = true; | ||
}), | ||
m => { | ||
expect(routed).to.be.true; | ||
handled = true; | ||
} | ||
) | ||
.route(foo) | ||
.subscribe(n => { | ||
@@ -1466,0 +1310,0 @@ expect(handled).to.be.true; |
Sorry, the diff of this file is not supported yet
116038
24
1934