New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

prague

Package Overview
Dependencies
Maintainers
1
Versions
91
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

prague - npm Package Compare versions

Comparing version 0.16.3 to 0.17.0

522

core/Router.ts

@@ -8,3 +8,3 @@ import { konsole } from './Konsole';

if (t instanceof Observable)
return t;
return t.take(1);
if (t instanceof Promise)

@@ -15,8 +15,18 @@ return Observable.fromPromise<T>(t);

export interface ActionRoute {
type: 'action';
action: () => Observableable<any>;
export type Action = () => Observableable<any>;
export interface DoRoute {
type: 'do';
action: Action;
score: number;
}
export function isDoRoute(route: Route): route is DoRoute {
return route.type === 'do';
}
export function isNoRoute(route: Route): route is NoRoute {
return route.type === 'no';
}
export interface NoRoute {

@@ -27,6 +37,20 @@ type: 'no';

export type Route = ActionRoute | NoRoute;
export type Route = DoRoute | NoRoute;
export type GetRoute$ <ROUTABLE> = (routable: ROUTABLE) => Observable<Route>
export type RawRoute = Route | {
type?: 'do';
action: Action;
score?: number;
} | {
type?: 'no';
reason: string;
}
export type GetRouteRaw <ROUTABLE> = (routable: ROUTABLE) => Observableable<Route | RawRoute | Action>;
export type GetRoute <ROUTABLE> = (routable: ROUTABLE) => Observableable<Route>;
export type GetRoute$ <ROUTABLE> = (routable: ROUTABLE) => Observable<Route>;
export type MapRoute <ROUTABLE> = (route: Route) => Observableable<GetRoute<ROUTABLE>>;
export type Handler <ROUTABLE> = (routable: ROUTABLE) => Observableable<any>;

@@ -50,284 +74,290 @@

export class Router <ROUTABLE> {
constructor(public _getRoute$: GetRoute$<ROUTABLE>) {}
export function doRoute (
action: () => Observableable<any>,
score: number = 1
): DoRoute {
return {
type: 'do',
action,
score
};
}
static actionRoute (
action: () => Observableable<any>,
score: number = 1
) {
return {
type: 'action',
action,
score
} as ActionRoute;
}
export const defaultReason = "none";
static noRoute (reason: string = Router.defaultReason) {
return {
type: 'no',
reason
} as NoRoute;
}
export function noRoute (
reason: string = defaultReason
): NoRoute {
return {
type: 'no',
reason
};
}
static combineScore(score, otherScore) {
return score * otherScore
}
export function normalizeRoute (rawRoute: RawRoute): Route {
if (!rawRoute || (rawRoute as NoRoute).reason)
return noRoute(rawRoute && (rawRoute as NoRoute).reason);
if (typeof(rawRoute) === 'function')
return doRoute(rawRoute);
if ((rawRoute as DoRoute).action)
return doRoute((rawRoute as DoRoute).action, (rawRoute as DoRoute).score);
throw new Error('invalid route');
}
static routeWithCombinedScore(route: ActionRoute, newScore: number) {
const score = Router.combineScore(newScore, route.score);
export const getNormalizedRoute = <ROUTABLE> (routable: ROUTABLE) => (getRoute: GetRouteRaw<ROUTABLE>) => getRoute
? toObservable(getRoute(routable))
.map(normalizeRoute)
: Observable.of(noRoute());
return route.score === score
? route
: {
... route,
score
} as Route;
}
export function route$ <ROUTABLE> (routable: ROUTABLE, getRoute: GetRouteRaw<ROUTABLE>) {
return Observable.of(getRoute)
.flatMap(getNormalizedRoute(routable))
.do(route => konsole.log("route: returned a route", route))
.flatMap(route => isDoRoute(route)
? toObservable(route.action())
.do(_ => konsole.log("route: called action"))
.map(_ => true)
: Observable.of(false)
);
}
static route$ <ROUTABLE> (routable: ROUTABLE, router: Router<ROUTABLE>) {
return router
._getRoute$(routable)
.do(route => konsole.log("route: returned a route", route))
.flatMap(route => route.type === 'action'
? toObservable(route.action())
.do(_ => konsole.log("route: called action"))
.map(_ => true)
: Observable.of(false)
);
}
export function no <ROUTABLE> (
reason?: string
): GetRoute$<ROUTABLE> {
return routable => Observable.of(noRoute(reason));
}
static minRoute = Router.actionRoute(
() => {
console.warn("BestRouter.minRoute.action should never be called");
},
0
);
export function getRouteDo <ROUTABLE> (
handler: Handler<ROUTABLE>,
score?: number
): GetRoute$<ROUTABLE> {
return routable => Observable.of(doRoute(() => handler(routable), score));
}
static defaultReason = "none";
export { getRouteDo as do }
static getRouteNo$ <ROUTABLE> (
reason?: string
): GetRoute$<ROUTABLE> {
return routable => Observable.of(Router.noRoute(reason));
}
export function first <ROUTABLE> (
... getRoutes: GetRouteRaw<ROUTABLE>[]
): GetRoute$<ROUTABLE> {
return routable => Observable.from(getRoutes)
.concatMap(getNormalizedRoute(routable))
.filter(isDoRoute)
.take(1) // so that we don't keep going through routers after we find one that matches;
.defaultIfEmpty(noRoute('first'));
}
static getRouteDo$ <ROUTABLE> (
handler: Handler<ROUTABLE>,
score?: number
): GetRoute$<ROUTABLE> {
return routable => Observable.of(Router.actionRoute(() => handler(routable), score));
}
export function combinedScore(score, otherScore) {
return score * otherScore
}
static getRouteFirst$ <ROUTABLE> (
... getRouters: ((routable: ROUTABLE) => Observableable<Router<ROUTABLE>>)[]
): GetRoute$<ROUTABLE> {
return routable => Observable.from(getRouters)
.filter(getRouter => !!getRouter)
.flatMap(getRouter => toObservable(getRouter(routable)))
.map(Router.toRouter)
.concatMap((router, i) => {
konsole.log(`first: trying router #${i}`);
return router
._getRoute$(routable)
.do(route => konsole.log(`first: router #${i} returned route`, route));
})
.filter(route => route.type === 'action')
.take(1) // so that we don't keep going through routers after we find one that matches;
.defaultIfEmpty(Router.noRoute('tryInOrder'));
}
export function routeWithCombinedScore(route: DoRoute, newScore: number) {
const score = combinedScore(newScore, route.score);
static getRouteBest$ <ROUTABLE> (
... getRouters: ((routable: ROUTABLE) => Observableable<Router<ROUTABLE>>)[]
): GetRoute$<ROUTABLE> {
return routable => new Observable<Route>(observer => {
let bestRoute = Router.minRoute;
return route.score === score
? route
: {
... route,
score
} as Route;
}
const subscription = Observable.from(getRouters)
.filter(getRouter => !!getRouter)
.flatMap(getRouter => toObservable(getRouter(routable)))
.map(Router.toRouter)
.takeWhile(_ => bestRoute.score < 1)
.concatMap(router => router._getRoute$(routable))
.filter(route => route.type === 'action')
.subscribe(
(route: ActionRoute) => {
if (route.score > bestRoute.score) {
bestRoute = route;
if (bestRoute.score === 1) {
observer.next(bestRoute);
observer.complete();
}
export const minRoute = doRoute(
() => {
console.warn("BestRouter.minRoute.action should never be called");
},
0
);
export function best <ROUTABLE> (
... getRoutes: GetRouteRaw<ROUTABLE>[]
): GetRoute<ROUTABLE> {
return routable => new Observable<Route>(observer => {
let bestRoute = minRoute;
const subscription = Observable.from(getRoutes)
.takeWhile(_ => bestRoute.score < 1)
.concatMap(getNormalizedRoute(routable))
.filter(isDoRoute)
.subscribe(
(route: DoRoute) => {
if (route.score > bestRoute.score) {
bestRoute = route;
if (bestRoute.score === 1) {
observer.next(bestRoute);
observer.complete();
}
},
error =>
observer.error(error),
() => {
observer.next(bestRoute.score > 0
? bestRoute
: Router.noRoute('tryInScoreOrder')
);
observer.complete();
}
);
},
error =>
observer.error(error),
() => {
observer.next(bestRoute.score > 0
? bestRoute
: noRoute('best')
);
observer.complete();
}
);
return () => subscription.unsubscribe();
});
}
return () => subscription.unsubscribe();
});
}
static getRouteNoop$ <ROUTABLE> (handler: Handler<ROUTABLE>): GetRoute$<ROUTABLE> {
return routable => toObservable(handler(routable))
.map(_ => Router.noRoute('noop'));
}
export function noop <ROUTABLE> (handler: Handler<ROUTABLE>): GetRouteRaw<ROUTABLE> {
return routable => toObservable(handler(routable))
.map(_ => noRoute('noop'));
}
static isMatch <VALUE> (match: MatchResult<any>): match is Match<VALUE> {
return ((match as any).reason === undefined);
}
export function isMatch <VALUE> (match: MatchResult<any>): match is Match<VALUE> {
return ((match as any).reason === undefined);
}
static normalizeMatchResult <VALUE> (response: any): MatchResult<VALUE> {
if (response == null || response === false)
return {
reason: Router.defaultReason
}
function normalizeMatchResult <VALUE> (response: any): MatchResult<VALUE> {
if (response == null || response === false)
return {
reason: defaultReason
}
if (typeof(response) === 'object') {
if (response.reason) {
if (typeof(response.reason) !== 'string')
throw new Error('The reason for NoMatch must be a string');
if (typeof(response) === 'object') {
if (response.reason) {
if (typeof(response.reason) !== 'string')
throw new Error('The reason for NoMatch must be a string');
return {
reason: response.reason
}
return {
reason: response.reason
}
}
if (response.value !== undefined) {
if (response.score !== undefined && typeof(response.score) !== 'number')
throw new Error('The score for Match must be a number');
if (response.value !== undefined) {
if (response.score !== undefined && typeof(response.score) !== 'number')
throw new Error('The score for Match must be a number');
return {
value: response.value,
score: response.score || 1
}
return {
value: response.value,
score: response.score || 1
}
}
return {
value: response,
score: 1
}
}
static toRouter <ROUTABLE> (router: Router<ROUTABLE>): Router<ROUTABLE> {
return router || new Router(Router.getRouteNo$());
return {
value: response,
score: 1
}
}
static getRouteIfMatches$ <ROUTABLE, VALUE> (
matcher: Matcher<ROUTABLE, VALUE>,
getThenRouter: (routable: ROUTABLE, value: VALUE) => Observableable<Router<ROUTABLE>>,
getElseRouter?: (routable: ROUTABLE, reason: string) => Observableable<Router<ROUTABLE>>
): GetRoute$<ROUTABLE> {
if (!getElseRouter)
getElseRouter = (routable: ROUTABLE, reason: string) => new Router<ROUTABLE>(Router.getRouteNo$(reason));
return routable => toObservable(matcher(routable))
.map(response => Router.normalizeMatchResult<VALUE>(response))
.flatMap(matchResult => Router.isMatch(matchResult)
? toObservable(getThenRouter(routable, matchResult.value))
.map(Router.toRouter)
.flatMap(router => router._getRoute$(routable))
.map(route => route.type === 'action'
? Router.routeWithCombinedScore(route, matchResult.score)
: route
)
: toObservable(getElseRouter(routable, matchResult.reason))
.map(Router.toRouter)
.flatMap(router => router._getRoute$(routable))
export function getNormalizedMatchResult$ <ROUTABLE, VALUE> (matcher: Matcher<ROUTABLE, VALUE>, routable: ROUTABLE) {
return toObservable(matcher(routable))
.map(response => normalizeMatchResult<VALUE>(response));
}
function getRouteIfMatches <ROUTABLE, VALUE> (
matcher: Matcher<ROUTABLE, VALUE>,
getThenGetRoute: (value: VALUE) => Observableable<GetRoute<ROUTABLE>>,
elseMapRoute: (route: NoRoute) => Observableable<GetRoute<ROUTABLE>> = route => routable => route
): GetRoute<ROUTABLE> {
return routable => getNormalizedMatchResult$(matcher, routable)
.flatMap(matchResult => isMatch(matchResult)
? toObservable(getThenGetRoute(matchResult.value))
.flatMap(getNormalizedRoute(routable))
.map(route => isDoRoute(route)
? routeWithCombinedScore(route, matchResult.score)
: route
)
: toObservable(elseMapRoute(noRoute(matchResult.reason)))
.flatMap(getNormalizedRoute(routable))
);
}
}
static predicateToMatcher <ROUTABLE> (predicate: Predicate<ROUTABLE>): Matcher<ROUTABLE, boolean> {
return routable => toObservable(predicate(routable))
.map((response: any) => {
if (response === true || response === false)
export { getRouteIfMatches as ifGet }
export function predicateToMatcher <ROUTABLE> (predicate: Predicate<ROUTABLE>): Matcher<ROUTABLE, boolean> {
return routable => toObservable(predicate(routable))
.map((response: any) => {
if (response === true || response === false)
return response;
if (typeof(response) === 'object') {
if (response.reason)
return response;
if (typeof(response) === 'object') {
if (response.reason)
if (response.value !== undefined) {
if (response.value === false)
return false;
if (response.value === true)
return response;
if (response.value !== undefined) {
if (response.value === false)
return false;
if (response.value === true)
return response;
throw new Error('When returning a Match from a predicate, the value must be true or false');
}
throw new Error('When returning a Match from a predicate, the value must be true or false');
}
}
throw new Error('A predicate may only return true, false, a Match of true or false, or a NoMatch');
});
}
throw new Error('A predicate may only return true, false, a Match of true or false, or a NoMatch');
});
}
static getRouteIfTrue$ <ROUTABLE> (
predicate: Predicate<ROUTABLE>,
getThenRouter: (routable: ROUTABLE, value: boolean) => Observableable<Router<ROUTABLE>>,
getElseRouter?: (routable: ROUTABLE, reason: string) => Observableable<Router<ROUTABLE>>
): GetRoute$<ROUTABLE> {
return Router.getRouteIfMatches$(Router.predicateToMatcher(predicate), getThenRouter, getElseRouter);
}
function getRouteIfTrue <ROUTABLE> (
predicate: Predicate<ROUTABLE>,
thenGetRoute: GetRoute<ROUTABLE>,
elseMapRoute: (route: NoRoute) => Observableable<GetRoute<ROUTABLE>>
): GetRoute<ROUTABLE> {
return getRouteIfMatches(predicateToMatcher(predicate), value => thenGetRoute, elseMapRoute);
}
static getRouteBefore$ <ROUTABLE> (
beforeHandler: Handler<ROUTABLE>,
router: Router<ROUTABLE>
): GetRoute$<ROUTABLE> {
return routable => router
._getRoute$(routable)
.map(route => route.type === 'action'
? {
... route,
action: () => toObservable(beforeHandler(routable))
.flatMap(_ => toObservable(route.action()))
}
: route
);
}
export { getRouteIfTrue as if }
static getRouteAfter$ <ROUTABLE> (
afterHandler: Handler<ROUTABLE>,
router: Router<ROUTABLE>
): GetRoute$<ROUTABLE> {
return routable => router
._getRoute$(routable)
.map(route => route.type === 'action'
? {
... route,
action: () => toObservable(route.action())
.flatMap(_ => toObservable(afterHandler(routable)))
}
: route
);
}
export function map <ROUTABLE> (
getRoute: GetRoute<ROUTABLE>,
mapper: MapRoute<ROUTABLE>
): GetRoute$<ROUTABLE> {
return routable => Observable.of(getRoute)
.flatMap(getNormalizedRoute(routable))
.flatMap(route => toObservable(mapper(route)))
.flatMap(getNormalizedRoute(routable))
}
static getRouteDefault$ <ROUTABLE> (
mainRouter: Router<ROUTABLE>,
getDefaultRouter: (routable: ROUTABLE, reason: string) => Observableable<Router<ROUTABLE>>
): GetRoute$<ROUTABLE> {
return routable => mainRouter._getRoute$(routable)
.flatMap(route => route.type === 'action'
? Observable.of(route)
: toObservable(getDefaultRouter(routable, route.reason))
.map(Router.toRouter)
.flatMap(router => router._getRoute$(routable))
);
}
export function before <ROUTABLE> (
beforeHandler: Handler<ROUTABLE>,
getRoute: GetRoute<ROUTABLE>
): GetRoute$<ROUTABLE> {
return map(getRoute, route => routable => isDoRoute(route)
? doRoute(
() => toObservable(beforeHandler(routable))
.flatMap(_ => toObservable(route.action())),
route.score
)
: route
);
}
static getRouteSwitch$ <ROUTABLE> (
getKey: (routable: ROUTABLE) => Observableable<string>,
getMapKeyToRouter: (routable: ROUTABLE) => Observableable<Record<string, Router<ROUTABLE>>>
): GetRoute$<ROUTABLE> {
return routable => toObservable(getKey(routable))
.flatMap(key => toObservable(getMapKeyToRouter(routable))
.map(mapKeyToRouter => mapKeyToRouter[key])
)
.map(Router.toRouter)
.flatMap(router => router._getRoute$(routable));
}
export function after <ROUTABLE> (
afterHandler: Handler<ROUTABLE>,
getRoute: GetRoute<ROUTABLE>
): GetRoute$<ROUTABLE> {
return map(getRoute, route => routable => isDoRoute(route)
? doRoute(
() => toObservable(route.action())
.flatMap(_ => toObservable(afterHandler(routable))),
route.score
)
: route
);
}
function getRouteDefault <ROUTABLE> (
getRoute: GetRoute<ROUTABLE>,
defaultMapRoute: (route: NoRoute) => Observableable<GetRoute<ROUTABLE>>
) {
return map(getRoute, route => isNoRoute(route)
? defaultMapRoute(route)
: routable => route
);
}
export { getRouteDefault as default }
function getRouteSwitch <ROUTABLE> (
getKey: (routable: ROUTABLE) => Observableable<string>,
mapKeyToGetRoute: Record<string, GetRoute<ROUTABLE>>
) {
return getRouteIfMatches(getKey, key => mapKeyToGetRoute[key]);
}
export { getRouteSwitch as switch }
import { Observable } from 'rxjs';
export declare type Observableable<T> = T | Observable<T> | Promise<T>;
export declare function toObservable<T>(t: Observableable<T>): Observable<T>;
export interface ActionRoute {
type: 'action';
action: () => Observableable<any>;
export declare type Action = () => Observableable<any>;
export interface DoRoute {
type: 'do';
action: Action;
score: number;
}
export declare function isDoRoute(route: Route): route is DoRoute;
export declare function isNoRoute(route: Route): route is NoRoute;
export interface NoRoute {

@@ -13,4 +16,15 @@ type: 'no';

}
export declare type Route = ActionRoute | NoRoute;
export declare type Route = DoRoute | NoRoute;
export declare type RawRoute = Route | {
type?: 'do';
action: Action;
score?: number;
} | {
type?: 'no';
reason: string;
};
export declare type GetRouteRaw<ROUTABLE> = (routable: ROUTABLE) => Observableable<Route | RawRoute | Action>;
export declare type GetRoute<ROUTABLE> = (routable: ROUTABLE) => Observableable<Route>;
export declare type GetRoute$<ROUTABLE> = (routable: ROUTABLE) => Observable<Route>;
export declare type MapRoute<ROUTABLE> = (route: Route) => Observableable<GetRoute<ROUTABLE>>;
export declare type Handler<ROUTABLE> = (routable: ROUTABLE) => Observableable<any>;

@@ -28,27 +42,30 @@ export interface Match<VALUE> {

export declare type Predicate<ROUTABLE> = Matcher<ROUTABLE, boolean>;
export declare class Router<ROUTABLE> {
_getRoute$: GetRoute$<ROUTABLE>;
constructor(_getRoute$: GetRoute$<ROUTABLE>);
static actionRoute(action: () => Observableable<any>, score?: number): ActionRoute;
static noRoute(reason?: string): NoRoute;
static combineScore(score: any, otherScore: any): number;
static routeWithCombinedScore(route: ActionRoute, newScore: number): Route;
static route$<ROUTABLE>(routable: ROUTABLE, router: Router<ROUTABLE>): Observable<boolean>;
static minRoute: ActionRoute;
static defaultReason: string;
static getRouteNo$<ROUTABLE>(reason?: string): GetRoute$<ROUTABLE>;
static getRouteDo$<ROUTABLE>(handler: Handler<ROUTABLE>, score?: number): GetRoute$<ROUTABLE>;
static getRouteFirst$<ROUTABLE>(...getRouters: ((routable: ROUTABLE) => Observableable<Router<ROUTABLE>>)[]): GetRoute$<ROUTABLE>;
static getRouteBest$<ROUTABLE>(...getRouters: ((routable: ROUTABLE) => Observableable<Router<ROUTABLE>>)[]): GetRoute$<ROUTABLE>;
static getRouteNoop$<ROUTABLE>(handler: Handler<ROUTABLE>): GetRoute$<ROUTABLE>;
static isMatch<VALUE>(match: MatchResult<any>): match is Match<VALUE>;
static normalizeMatchResult<VALUE>(response: any): MatchResult<VALUE>;
static toRouter<ROUTABLE>(router: Router<ROUTABLE>): Router<ROUTABLE>;
static getRouteIfMatches$<ROUTABLE, VALUE>(matcher: Matcher<ROUTABLE, VALUE>, getThenRouter: (routable: ROUTABLE, value: VALUE) => Observableable<Router<ROUTABLE>>, getElseRouter?: (routable: ROUTABLE, reason: string) => Observableable<Router<ROUTABLE>>): GetRoute$<ROUTABLE>;
static predicateToMatcher<ROUTABLE>(predicate: Predicate<ROUTABLE>): Matcher<ROUTABLE, boolean>;
static getRouteIfTrue$<ROUTABLE>(predicate: Predicate<ROUTABLE>, getThenRouter: (routable: ROUTABLE, value: boolean) => Observableable<Router<ROUTABLE>>, getElseRouter?: (routable: ROUTABLE, reason: string) => Observableable<Router<ROUTABLE>>): GetRoute$<ROUTABLE>;
static getRouteBefore$<ROUTABLE>(beforeHandler: Handler<ROUTABLE>, router: Router<ROUTABLE>): GetRoute$<ROUTABLE>;
static getRouteAfter$<ROUTABLE>(afterHandler: Handler<ROUTABLE>, router: Router<ROUTABLE>): GetRoute$<ROUTABLE>;
static getRouteDefault$<ROUTABLE>(mainRouter: Router<ROUTABLE>, getDefaultRouter: (routable: ROUTABLE, reason: string) => Observableable<Router<ROUTABLE>>): GetRoute$<ROUTABLE>;
static getRouteSwitch$<ROUTABLE>(getKey: (routable: ROUTABLE) => Observableable<string>, getMapKeyToRouter: (routable: ROUTABLE) => Observableable<Record<string, Router<ROUTABLE>>>): GetRoute$<ROUTABLE>;
}
export declare function doRoute(action: () => Observableable<any>, score?: number): DoRoute;
export declare const defaultReason = "none";
export declare function noRoute(reason?: string): NoRoute;
export declare function normalizeRoute(rawRoute: RawRoute): Route;
export declare const getNormalizedRoute: <ROUTABLE>(routable: ROUTABLE) => (getRoute: GetRouteRaw<ROUTABLE>) => Observable<Route>;
export declare function route$<ROUTABLE>(routable: ROUTABLE, getRoute: GetRouteRaw<ROUTABLE>): Observable<boolean>;
export declare function no<ROUTABLE>(reason?: string): GetRoute$<ROUTABLE>;
export declare function getRouteDo<ROUTABLE>(handler: Handler<ROUTABLE>, score?: number): GetRoute$<ROUTABLE>;
export { getRouteDo as do };
export declare function first<ROUTABLE>(...getRoutes: GetRouteRaw<ROUTABLE>[]): GetRoute$<ROUTABLE>;
export declare function combinedScore(score: any, otherScore: any): number;
export declare function routeWithCombinedScore(route: DoRoute, newScore: number): Route;
export declare const minRoute: DoRoute;
export declare function best<ROUTABLE>(...getRoutes: GetRouteRaw<ROUTABLE>[]): GetRoute<ROUTABLE>;
export declare function noop<ROUTABLE>(handler: Handler<ROUTABLE>): GetRouteRaw<ROUTABLE>;
export declare function isMatch<VALUE>(match: MatchResult<any>): match is Match<VALUE>;
export declare function getNormalizedMatchResult$<ROUTABLE, VALUE>(matcher: Matcher<ROUTABLE, VALUE>, routable: ROUTABLE): Observable<MatchResult<VALUE>>;
declare function getRouteIfMatches<ROUTABLE, VALUE>(matcher: Matcher<ROUTABLE, VALUE>, getThenGetRoute: (value: VALUE) => Observableable<GetRoute<ROUTABLE>>, elseMapRoute?: (route: NoRoute) => Observableable<GetRoute<ROUTABLE>>): GetRoute<ROUTABLE>;
export { getRouteIfMatches as ifGet };
export declare function predicateToMatcher<ROUTABLE>(predicate: Predicate<ROUTABLE>): Matcher<ROUTABLE, boolean>;
declare function getRouteIfTrue<ROUTABLE>(predicate: Predicate<ROUTABLE>, thenGetRoute: GetRoute<ROUTABLE>, elseMapRoute: (route: NoRoute) => Observableable<GetRoute<ROUTABLE>>): GetRoute<ROUTABLE>;
export { getRouteIfTrue as if };
export declare function map<ROUTABLE>(getRoute: GetRoute<ROUTABLE>, mapper: MapRoute<ROUTABLE>): GetRoute$<ROUTABLE>;
export declare function before<ROUTABLE>(beforeHandler: Handler<ROUTABLE>, getRoute: GetRoute<ROUTABLE>): GetRoute$<ROUTABLE>;
export declare function after<ROUTABLE>(afterHandler: Handler<ROUTABLE>, getRoute: GetRoute<ROUTABLE>): GetRoute$<ROUTABLE>;
declare function getRouteDefault<ROUTABLE>(getRoute: GetRoute<ROUTABLE>, defaultMapRoute: (route: NoRoute) => Observableable<GetRoute<ROUTABLE>>): GetRoute$<ROUTABLE>;
export { getRouteDefault as default };
declare function getRouteSwitch<ROUTABLE>(getKey: (routable: ROUTABLE) => Observableable<string>, mapKeyToGetRoute: Record<string, GetRoute<ROUTABLE>>): GetRoute<ROUTABLE>;
export { getRouteSwitch as switch };

@@ -15,3 +15,3 @@ "use strict";

if (t instanceof rxjs_1.Observable)
return t;
return t.take(1);
if (t instanceof Promise)

@@ -22,209 +22,228 @@ return rxjs_1.Observable.fromPromise(t);

exports.toObservable = toObservable;
var Router = /** @class */ (function () {
function Router(_getRoute$) {
this._getRoute$ = _getRoute$;
function isDoRoute(route) {
return route.type === 'do';
}
exports.isDoRoute = isDoRoute;
function isNoRoute(route) {
return route.type === 'no';
}
exports.isNoRoute = isNoRoute;
function doRoute(action, score) {
if (score === void 0) { score = 1; }
return {
type: 'do',
action: action,
score: score
};
}
exports.doRoute = doRoute;
exports.defaultReason = "none";
function noRoute(reason) {
if (reason === void 0) { reason = exports.defaultReason; }
return {
type: 'no',
reason: reason
};
}
exports.noRoute = noRoute;
function normalizeRoute(rawRoute) {
if (!rawRoute || rawRoute.reason)
return noRoute(rawRoute && rawRoute.reason);
if (typeof (rawRoute) === 'function')
return doRoute(rawRoute);
if (rawRoute.action)
return doRoute(rawRoute.action, rawRoute.score);
throw new Error('invalid route');
}
exports.normalizeRoute = normalizeRoute;
exports.getNormalizedRoute = function (routable) { return function (getRoute) { return getRoute
? toObservable(getRoute(routable))
.map(normalizeRoute)
: rxjs_1.Observable.of(noRoute()); }; };
function route$(routable, getRoute) {
return rxjs_1.Observable.of(getRoute)
.flatMap(exports.getNormalizedRoute(routable))
.do(function (route) { return Konsole_1.konsole.log("route: returned a route", route); })
.flatMap(function (route) { return isDoRoute(route)
? toObservable(route.action())
.do(function (_) { return Konsole_1.konsole.log("route: called action"); })
.map(function (_) { return true; })
: rxjs_1.Observable.of(false); });
}
exports.route$ = route$;
function no(reason) {
return function (routable) { return rxjs_1.Observable.of(noRoute(reason)); };
}
exports.no = no;
function getRouteDo(handler, score) {
return function (routable) { return rxjs_1.Observable.of(doRoute(function () { return handler(routable); }, score)); };
}
exports.getRouteDo = getRouteDo;
exports.do = getRouteDo;
function first() {
var getRoutes = [];
for (var _i = 0; _i < arguments.length; _i++) {
getRoutes[_i] = arguments[_i];
}
Router.actionRoute = function (action, score) {
if (score === void 0) { score = 1; }
return function (routable) { return rxjs_1.Observable.from(getRoutes)
.concatMap(exports.getNormalizedRoute(routable))
.filter(isDoRoute)
.take(1) // so that we don't keep going through routers after we find one that matches;
.defaultIfEmpty(noRoute('first')); };
}
exports.first = first;
function combinedScore(score, otherScore) {
return score * otherScore;
}
exports.combinedScore = combinedScore;
function routeWithCombinedScore(route, newScore) {
var score = combinedScore(newScore, route.score);
return route.score === score
? route
: __assign({}, route, { score: score });
}
exports.routeWithCombinedScore = routeWithCombinedScore;
exports.minRoute = doRoute(function () {
console.warn("BestRouter.minRoute.action should never be called");
}, 0);
function best() {
var getRoutes = [];
for (var _i = 0; _i < arguments.length; _i++) {
getRoutes[_i] = arguments[_i];
}
return function (routable) { return new rxjs_1.Observable(function (observer) {
var bestRoute = exports.minRoute;
var subscription = rxjs_1.Observable.from(getRoutes)
.takeWhile(function (_) { return bestRoute.score < 1; })
.concatMap(exports.getNormalizedRoute(routable))
.filter(isDoRoute)
.subscribe(function (route) {
if (route.score > bestRoute.score) {
bestRoute = route;
if (bestRoute.score === 1) {
observer.next(bestRoute);
observer.complete();
}
}
}, function (error) {
return observer.error(error);
}, function () {
observer.next(bestRoute.score > 0
? bestRoute
: noRoute('best'));
observer.complete();
});
return function () { return subscription.unsubscribe(); };
}); };
}
exports.best = best;
function noop(handler) {
return function (routable) { return toObservable(handler(routable))
.map(function (_) { return noRoute('noop'); }); };
}
exports.noop = noop;
function isMatch(match) {
return (match.reason === undefined);
}
exports.isMatch = isMatch;
function normalizeMatchResult(response) {
if (response == null || response === false)
return {
type: 'action',
action: action,
score: score
reason: exports.defaultReason
};
};
Router.noRoute = function (reason) {
if (reason === void 0) { reason = Router.defaultReason; }
return {
type: 'no',
reason: reason
};
};
Router.combineScore = function (score, otherScore) {
return score * otherScore;
};
Router.routeWithCombinedScore = function (route, newScore) {
var score = Router.combineScore(newScore, route.score);
return route.score === score
? route
: __assign({}, route, { score: score });
};
Router.route$ = function (routable, router) {
return router
._getRoute$(routable)
.do(function (route) { return Konsole_1.konsole.log("route: returned a route", route); })
.flatMap(function (route) { return route.type === 'action'
? toObservable(route.action())
.do(function (_) { return Konsole_1.konsole.log("route: called action"); })
.map(function (_) { return true; })
: rxjs_1.Observable.of(false); });
};
Router.getRouteNo$ = function (reason) {
return function (routable) { return rxjs_1.Observable.of(Router.noRoute(reason)); };
};
Router.getRouteDo$ = function (handler, score) {
return function (routable) { return rxjs_1.Observable.of(Router.actionRoute(function () { return handler(routable); }, score)); };
};
Router.getRouteFirst$ = function () {
var getRouters = [];
for (var _i = 0; _i < arguments.length; _i++) {
getRouters[_i] = arguments[_i];
if (typeof (response) === 'object') {
if (response.reason) {
if (typeof (response.reason) !== 'string')
throw new Error('The reason for NoMatch must be a string');
return {
reason: response.reason
};
}
return function (routable) { return rxjs_1.Observable.from(getRouters)
.filter(function (getRouter) { return !!getRouter; })
.flatMap(function (getRouter) { return toObservable(getRouter(routable)); })
.map(Router.toRouter)
.concatMap(function (router, i) {
Konsole_1.konsole.log("first: trying router #" + i);
return router
._getRoute$(routable)
.do(function (route) { return Konsole_1.konsole.log("first: router #" + i + " returned route", route); });
})
.filter(function (route) { return route.type === 'action'; })
.take(1) // so that we don't keep going through routers after we find one that matches;
.defaultIfEmpty(Router.noRoute('tryInOrder')); };
};
Router.getRouteBest$ = function () {
var getRouters = [];
for (var _i = 0; _i < arguments.length; _i++) {
getRouters[_i] = arguments[_i];
}
return function (routable) { return new rxjs_1.Observable(function (observer) {
var bestRoute = Router.minRoute;
var subscription = rxjs_1.Observable.from(getRouters)
.filter(function (getRouter) { return !!getRouter; })
.flatMap(function (getRouter) { return toObservable(getRouter(routable)); })
.map(Router.toRouter)
.takeWhile(function (_) { return bestRoute.score < 1; })
.concatMap(function (router) { return router._getRoute$(routable); })
.filter(function (route) { return route.type === 'action'; })
.subscribe(function (route) {
if (route.score > bestRoute.score) {
bestRoute = route;
if (bestRoute.score === 1) {
observer.next(bestRoute);
observer.complete();
}
}
}, function (error) {
return observer.error(error);
}, function () {
observer.next(bestRoute.score > 0
? bestRoute
: Router.noRoute('tryInScoreOrder'));
observer.complete();
});
return function () { return subscription.unsubscribe(); };
}); };
};
Router.getRouteNoop$ = function (handler) {
return function (routable) { return toObservable(handler(routable))
.map(function (_) { return Router.noRoute('noop'); }); };
};
Router.isMatch = function (match) {
return (match.reason === undefined);
};
Router.normalizeMatchResult = function (response) {
if (response == null || response === false)
if (response.value !== undefined) {
if (response.score !== undefined && typeof (response.score) !== 'number')
throw new Error('The score for Match must be a number');
return {
reason: Router.defaultReason
value: response.value,
score: response.score || 1
};
if (typeof (response) === 'object') {
if (response.reason) {
if (typeof (response.reason) !== 'string')
throw new Error('The reason for NoMatch must be a string');
return {
reason: response.reason
};
}
if (response.value !== undefined) {
if (response.score !== undefined && typeof (response.score) !== 'number')
throw new Error('The score for Match must be a number');
return {
value: response.value,
score: response.score || 1
};
}
}
return {
value: response,
score: 1
};
}
return {
value: response,
score: 1
};
Router.toRouter = function (router) {
return router || new Router(Router.getRouteNo$());
};
Router.getRouteIfMatches$ = function (matcher, getThenRouter, getElseRouter) {
if (!getElseRouter)
getElseRouter = function (routable, reason) { return new Router(Router.getRouteNo$(reason)); };
return function (routable) { return toObservable(matcher(routable))
.map(function (response) { return Router.normalizeMatchResult(response); })
.flatMap(function (matchResult) { return Router.isMatch(matchResult)
? toObservable(getThenRouter(routable, matchResult.value))
.map(Router.toRouter)
.flatMap(function (router) { return router._getRoute$(routable); })
.map(function (route) { return route.type === 'action'
? Router.routeWithCombinedScore(route, matchResult.score)
: route; })
: toObservable(getElseRouter(routable, matchResult.reason))
.map(Router.toRouter)
.flatMap(function (router) { return router._getRoute$(routable); }); }); };
};
Router.predicateToMatcher = function (predicate) {
return function (routable) { return toObservable(predicate(routable))
.map(function (response) {
if (response === true || response === false)
}
function getNormalizedMatchResult$(matcher, routable) {
return toObservable(matcher(routable))
.map(function (response) { return normalizeMatchResult(response); });
}
exports.getNormalizedMatchResult$ = getNormalizedMatchResult$;
function getRouteIfMatches(matcher, getThenGetRoute, elseMapRoute) {
if (elseMapRoute === void 0) { elseMapRoute = function (route) { return function (routable) { return route; }; }; }
return function (routable) { return getNormalizedMatchResult$(matcher, routable)
.flatMap(function (matchResult) { return isMatch(matchResult)
? toObservable(getThenGetRoute(matchResult.value))
.flatMap(exports.getNormalizedRoute(routable))
.map(function (route) { return isDoRoute(route)
? routeWithCombinedScore(route, matchResult.score)
: route; })
: toObservable(elseMapRoute(noRoute(matchResult.reason)))
.flatMap(exports.getNormalizedRoute(routable)); }); };
}
exports.ifGet = getRouteIfMatches;
function predicateToMatcher(predicate) {
return function (routable) { return toObservable(predicate(routable))
.map(function (response) {
if (response === true || response === false)
return response;
if (typeof (response) === 'object') {
if (response.reason)
return response;
if (typeof (response) === 'object') {
if (response.reason)
if (response.value !== undefined) {
if (response.value === false)
return false;
if (response.value === true)
return response;
if (response.value !== undefined) {
if (response.value === false)
return false;
if (response.value === true)
return response;
throw new Error('When returning a Match from a predicate, the value must be true or false');
}
throw new Error('When returning a Match from a predicate, the value must be true or false');
}
throw new Error('A predicate may only return true, false, a Match of true or false, or a NoMatch');
}); };
};
Router.getRouteIfTrue$ = function (predicate, getThenRouter, getElseRouter) {
return Router.getRouteIfMatches$(Router.predicateToMatcher(predicate), getThenRouter, getElseRouter);
};
Router.getRouteBefore$ = function (beforeHandler, router) {
return function (routable) { return router
._getRoute$(routable)
.map(function (route) { return route.type === 'action'
? __assign({}, route, { action: function () { return toObservable(beforeHandler(routable))
.flatMap(function (_) { return toObservable(route.action()); }); } }) : route; }); };
};
Router.getRouteAfter$ = function (afterHandler, router) {
return function (routable) { return router
._getRoute$(routable)
.map(function (route) { return route.type === 'action'
? __assign({}, route, { action: function () { return toObservable(route.action())
.flatMap(function (_) { return toObservable(afterHandler(routable)); }); } }) : route; }); };
};
Router.getRouteDefault$ = function (mainRouter, getDefaultRouter) {
return function (routable) { return mainRouter._getRoute$(routable)
.flatMap(function (route) { return route.type === 'action'
? rxjs_1.Observable.of(route)
: toObservable(getDefaultRouter(routable, route.reason))
.map(Router.toRouter)
.flatMap(function (router) { return router._getRoute$(routable); }); }); };
};
Router.getRouteSwitch$ = function (getKey, getMapKeyToRouter) {
return function (routable) { return toObservable(getKey(routable))
.flatMap(function (key) { return toObservable(getMapKeyToRouter(routable))
.map(function (mapKeyToRouter) { return mapKeyToRouter[key]; }); })
.map(Router.toRouter)
.flatMap(function (router) { return router._getRoute$(routable); }); };
};
Router.minRoute = Router.actionRoute(function () {
console.warn("BestRouter.minRoute.action should never be called");
}, 0);
Router.defaultReason = "none";
return Router;
}());
exports.Router = Router;
}
throw new Error('A predicate may only return true, false, a Match of true or false, or a NoMatch');
}); };
}
exports.predicateToMatcher = predicateToMatcher;
function getRouteIfTrue(predicate, thenGetRoute, elseMapRoute) {
return getRouteIfMatches(predicateToMatcher(predicate), function (value) { return thenGetRoute; }, elseMapRoute);
}
exports.if = getRouteIfTrue;
function map(getRoute, mapper) {
return function (routable) { return rxjs_1.Observable.of(getRoute)
.flatMap(exports.getNormalizedRoute(routable))
.flatMap(function (route) { return toObservable(mapper(route)); })
.flatMap(exports.getNormalizedRoute(routable)); };
}
exports.map = map;
function before(beforeHandler, getRoute) {
return map(getRoute, function (route) { return function (routable) { return isDoRoute(route)
? doRoute(function () { return toObservable(beforeHandler(routable))
.flatMap(function (_) { return toObservable(route.action()); }); }, route.score)
: route; }; });
}
exports.before = before;
function after(afterHandler, getRoute) {
return map(getRoute, function (route) { return function (routable) { return isDoRoute(route)
? doRoute(function () { return toObservable(route.action())
.flatMap(function (_) { return toObservable(afterHandler(routable)); }); }, route.score)
: route; }; });
}
exports.after = after;
function getRouteDefault(getRoute, defaultMapRoute) {
return map(getRoute, function (route) { return isNoRoute(route)
? defaultMapRoute(route)
: function (routable) { return route; }; });
}
exports.default = getRouteDefault;
function getRouteSwitch(getKey, mapKeyToGetRoute) {
return getRouteIfMatches(getKey, function (key) { return mapKeyToGetRoute[key]; });
}
exports.switch = getRouteSwitch;
//# sourceMappingURL=Router.js.map

@@ -7,3 +7,3 @@ {

},
"version": "0.16.3",
"version": "0.17.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, Router } = require('../dist/prague.js');
const p = require('../dist/prague.js');
const { Observable } = require('rxjs');

@@ -37,10 +37,7 @@

const routerNo = (reason) => new Router(Router.getRouteNo$(reason));
const routerDo = (handler, score) => new Router(Router.getRouteDo$(handler, score));
const noop = () => {}
describe('toObservable', () => {
describe('p.toObservable', () => {
it("should convert a number to an observable", (done) => {
toObservable(5)
p.toObservable(5)
.subscribe(n => {

@@ -52,3 +49,3 @@ expect(n).to.eql(5);

it("should convert a string to an observable", (done) => {
toObservable("Prague")
p.toObservable("Prague")
.subscribe(n => {

@@ -60,3 +57,3 @@ expect(n).to.eql("Prague");

it("should convert an array to an observable", (done) => {
toObservable([1, 2, 3])
p.toObservable([1, 2, 3])
.subscribe(n => {

@@ -68,3 +65,3 @@ expect(n).to.eql([1, 2, 3]);

it("should convert a Promise<number> to an observable", (done) => {
toObservable(Promise.resolve(5))
p.toObservable(Promise.resolve(5))
.subscribe(n => {

@@ -76,3 +73,3 @@ expect(n).to.eql(5);

it("should convert a Promise<string> to an observable", (done) => {
toObservable(Promise.resolve("Prague"))
p.toObservable(Promise.resolve("Prague"))
.subscribe(n => {

@@ -84,3 +81,3 @@ expect(n).to.eql("Prague");

it("should convert a Promise<array> to an observable", (done) => {
toObservable(Promise.resolve([1, 2, 3]))
p.toObservable(Promise.resolve([1, 2, 3]))
.subscribe(n => {

@@ -92,3 +89,3 @@ expect(n).to.eql([1, 2, 3]);

it("should convert an Observable<number> to an observable", (done) => {
toObservable(Observable.of(5))
p.toObservable(Observable.of(5))
.subscribe(n => {

@@ -100,3 +97,3 @@ expect(n).to.eql(5);

it("should convert an Observable<string> to an observable", (done) => {
toObservable(Observable.of("Prague"))
p.toObservable(Observable.of("Prague"))
.subscribe(n => {

@@ -108,3 +105,3 @@ expect(n).to.eql("Prague");

it("should convert an Observable<array> to an observable", (done) => {
toObservable(Observable.of([1, 2, 3]))
p.toObservable(Observable.of([1, 2, 3]))
.subscribe(n => {

@@ -116,3 +113,3 @@ expect(n).to.eql([1, 2, 3]);

it("should convert null to an observable", (done) => {
toObservable(null)
p.toObservable(null)
.subscribe(n => {

@@ -124,3 +121,3 @@ expect(n).to.eql(null);

it("should convert undefined to an observable", (done) => {
toObservable(undefined)
p.toObservable(undefined)
.subscribe(n => {

@@ -132,3 +129,3 @@ expect(n).to.eql(undefined);

it("should convert Promise<null> to an observable", (done) => {
toObservable(Promise.resolve(null))
p.toObservable(Promise.resolve(null))
.subscribe(n => {

@@ -140,3 +137,3 @@ expect(n).to.eql(null);

it("should convert Promise<undefined> to an observable", (done) => {
toObservable(Promise.resolve(undefined))
p.toObservable(Promise.resolve(undefined))
.subscribe(n => {

@@ -148,3 +145,3 @@ expect(n).to.eql(undefined);

it("should convert Observable<null> to an observable", (done) => {
toObservable(Observable.of(null))
p.toObservable(Observable.of(null))
.subscribe(n => {

@@ -156,3 +153,3 @@ expect(n).to.eql(null);

it("should convert Observable<undefined> to an observable", (done) => {
toObservable(Observable.of(undefined))
p.toObservable(Observable.of(undefined))
.subscribe(n => {

@@ -164,13 +161,12 @@ expect(n).to.eql(undefined);

it("should complete and never emit on Observable.empty()", (done) => {
toObservable(Observable.empty())
p.toObservable(Observable.empty())
.subscribe(throwErr, passErr, done);
});
});
describe('Router.actionRoute', () => {
it('should create an ActionRoute with supplied action and no score', () => {
describe('p.doRoute', () => {
it('should create an doRoute with supplied action and no score', () => {
let action = () => {};
let route = Router.actionRoute(action);
expect(route.type).to.eql('action');
let route = p.doRoute(action);
expect(route.type).to.eql('do');
expect(route.action).to.eql(action);

@@ -180,6 +176,6 @@ expect(route.score).to.eql(1);

it('should create an ActionRoute with supplied action and score', () => {
it('should create an doRoute with supplied action and score', () => {
let action = () => {};
let route = Router.actionRoute(action, 0.5);
expect(route.type).to.eql('action');
let route = p.doRoute(action, 0.5);
expect(route.type).to.eql('do');
expect(route.action).to.eql(action);

@@ -191,57 +187,44 @@ expect(route.score).to.eql(.5);

describe('router._getRoute$', () => {
it('should return action route', done => {
let theRoute = {
type: 'action',
action: noop
}
new Router(routable => Observable.of(theRoute))
._getRoute$(foo)
.subscribe(route => {
expect(route).to.eql(theRoute);
}, passErr, done);
describe('p.noRoute', () => {
it('should create a NoRoute with default reason', () => {
let route = p.noRoute();
expect(route.type).to.eql('no');
expect(route.reason).to.eql('none');
expect(route.action).to.be.undefined;
expect(route.score).to.be.undefined;
});
it('should return no route', done => {
let theRoute = {
type: 'no',
reason: 'reason'
}
new Router(routable => Observable.of(theRoute))
._getRoute$(foo)
.subscribe(route => {
expect(route).to.eql(theRoute);
}, passErr, done);
it('should create a NoRoute with supplied reason', () => {
let route = p.noRoute('reason');
expect(route.type).to.eql('no');
expect(route.reason).to.eql('reason');
expect(route.action).to.be.undefined;
expect(route.score).to.be.undefined;
});
})
});
describe('Router.getRouteDo$', () => {
it('should return an ActionRoute using supplied handler and no score', (done) => {
let handled;
routerDo(m => { handled = m; })
._getRoute$(foo)
.subscribe(route => {
expect(route.type).to.eql('action');
expect(route.score).to.eql(1);
route.action();
expect(handled).to.eql(foo);
}, passErr, done);
describe('p.normalizeRoute', () => {
it('should normalize undefined', () => {
let route = p.normalizeRoute(undefined);
expect(route.type).to.eql('no');
expect(route.reason).to.eql('none');
expect(route.action).to.be.undefined;
expect(route.score).to.be.undefined;
});
it('should return an ActionRoute using supplied handler and score', (done) => {
let handled;
routerDo(m => { handled = m; }, .5)
._getRoute$(foo)
.subscribe(route => {
expect(route.type).to.eql('action');
expect(route.score).to.eql(.5);
route.action();
expect(handled).to.eql(foo);
}, passErr, done);
it('should normalize { reason }', () => {
let route = p.normalizeRoute({ reason: 'reason' });
expect(route.type).to.eql('no');
expect(route.reason).to.eql('reason');
expect(route.action).to.be.undefined;
expect(route.score).to.be.undefined;
});
});
describe('Router.noRoute', () => {
it('should create a NoRoute with default reason', () => {
let route = Router.noRoute();
it('should normalize a noRoute without a reason', () => {
let route = p.normalizeRoute(p.noRoute());
expect(route.type).to.eql('no');

@@ -253,4 +236,5 @@ expect(route.reason).to.eql('none');

it('should create a NoRoute with supplied reason', () => {
let route = Router.noRoute('reason');
it('should normalize a noRoute with a reason', () => {
let route = p.normalizeRoute(p.noRoute('reason'));
expect(route.type).to.eql('no');

@@ -261,74 +245,121 @@ expect(route.reason).to.eql('reason');

});
it('should normalize an action', () => {
let action = () => {}
let route = p.normalizeRoute(action);
expect(route.type).to.eql('do');
expect(route.action).to.eql(action);
expect(route.score).to.eql(1);
expect(route.reason).to.be.undefined;
});
it('should normalize { action }', () => {
let action = () => {}
let route = p.normalizeRoute({ action });
expect(route.type).to.eql('do');
expect(route.action).to.eql(action);
expect(route.score).to.eql(1);
expect(route.reason).to.be.undefined;
});
it('should normalize { action, score }', () => {
let action = () => {}
let route = p.normalizeRoute({ action, score: .5 });
expect(route.type).to.eql('do');
expect(route.action).to.eql(action);
expect(route.score).to.eql(.5);
expect(route.reason).to.be.undefined;
});
it('should normalize a doRoute without a score', () => {
let action = () => {}
let route = p.normalizeRoute(p.doRoute(action));
expect(route.type).to.eql('do');
expect(route.action).to.eql(action);
expect(route.score).to.eql(1);
expect(route.reason).to.be.undefined;
});
it('should normalize a doRoute with a score', () => {
let action = () => {}
let route = p.normalizeRoute(p.doRoute(action, .5));
expect(route.type).to.eql('do');
expect(route.action).to.eql(action);
expect(route.score).to.eql(.5);
expect(route.reason).to.be.undefined;
});
});
describe('Router.getRouteNo$', () => {
it('should return a NoRoute with the default reason', done => {
routerNo()
._getRoute$(foo)
describe('p.getNormalizedRoute', () => {
it("should treat undefined as NoRoute", (done) => {
Observable
.of(undefined)
.flatMap(p.getNormalizedRoute(foo))
.subscribe(route => {
expect(route.type).to.eql('no');
expect(route.reason).to.eql('none');
}, passErr, done);
}, passErr, done)
});
it('should return a NoRoute with the default reason', done => {
routerNo('reason')
._getRoute$(foo)
it("should not route to NoRoute", (done) => {
Observable
.of(p.no('reason'))
.flatMap(p.getNormalizedRoute(foo))
.subscribe(route => {
expect(route.type).to.eql('no');
expect(route.reason).to.eql('reason');
}, passErr, done);
}, passErr, done)
});
});
describe('Router.route$', () => {
it("should return false on when router returns NoRoute", (done) => {
Router.route$(foo, routerNo())
.subscribe(t => {
expect(t).to.be.false;
}, passErr, done);
it("should route to supplied route", (done) => {
Observable
.of(p.do(c => {}, .5))
.flatMap(p.getNormalizedRoute(foo))
.subscribe(route => {
expect(route.type).to.eql('do');
expect(route.score).to.eql(.5);
}, passErr, done)
});
it("should return true when router returns ActionRoute", (done) => {
let routed;
it("should route to un-normalized route", (done) => {
let action = () => {};
Router.route$(foo, routerDo(() => {
routed = true;
}))
.subscribe(t => {
expect(t).to.be.true;
expect(routed).to.be.true;
}, passErr, done);
Observable
.of(c => action)
.flatMap(p.getNormalizedRoute(foo))
.subscribe(route => {
expect(route.type).to.eql('do');
expect(route.score).to.eql(1);
expect(route.action).to.eql(action);
}, passErr, done)
});
});
describe("Router.getRouteBefore$", () => {
it("should return false with routerNo()", (done) => {
Router.route$(foo, new Router(Router.getRouteBefore$(
throwErr,
routerNo()
))
)
.subscribe(t => expect(t).to.be.false, passErr, done);
describe('p.do', () => {
it('should return an doRoute using supplied handler and no score', (done) => {
let handled;
p.do(m => { handled = m; })
(foo)
.subscribe(route => {
expect(route.type).to.eql('do');
expect(route.score).to.eql(1);
route.action();
expect(handled).to.eql(foo);
}, passErr, done);
});
it("should run 'before' handler and then router's action", (done) => {
let handled = false;
let routed = false;
Router.route$(foo, new Router(Router.getRouteBefore$(
m => {
expect(routed).to.be.false;
handled = true;
},
routerDo(m => {
expect(handled).to.be.true;
routed = true;
})
))
)
.subscribe(t => {
expect(t).to.be.true;
expect(routed).to.be.true;
it('should return an doRoute using supplied handler and score', (done) => {
let handled;
p.do(m => { handled = m; }, .5)
(foo)
.subscribe(route => {
expect(route.type).to.eql('do');
expect(route.score).to.eql(.5);
route.action();
expect(handled).to.eql(foo);
}, passErr, done);

@@ -338,31 +369,18 @@ });

describe("Router.getRouteBefore$", () => {
it("should return false with routerNo()", (done) => {
Router.route$(foo, new Router(Router.getRouteAfter$(
throwErr,
routerNo()
))
)
.subscribe(t => expect(t).to.be.false, passErr, done);
describe('p.no', () => {
it('should return a NoRoute with the default reason', done => {
p.no()
(foo)
.subscribe(route => {
expect(route.type).to.eql('no');
expect(route.reason).to.eql('none');
}, passErr, done);
});
it("should run 'after' handler and then router's action", (done) => {
let handled = false;
let routed = false;
Router.route$(foo, new Router(Router.getRouteAfter$(
m => {
expect(routed).to.be.true;
handled = true;
},
routerDo(m => {
expect(handled).to.be.false;
routed = true;
})
))
)
.subscribe(t => {
expect(t).to.be.true;
expect(handled).to.be.true;
it('should return a NoRoute with the supplied reason', done => {
p.no('reason')
(foo)
.subscribe(route => {
expect(route.type).to.eql('no');
expect(route.reason).to.eql('reason');
}, passErr, done);

@@ -372,48 +390,26 @@ });

describe("Router.getRouteDefault$", () => {
it("should not be run when main router returns an action route", (done) => {
let routed;
Router.route$(foo, new Router(Router.getRouteDefault$(
routerDo(m => {
routed = true;
}),
reason => routerDo(throwErr)
))
)
.subscribe(n => {
expect(routed).to.be.true;
describe('p.route$', () => {
it("should return false on NoRoute", (done) => {
p.route$(foo, p.no())
.subscribe(t => {
expect(t).to.be.false;
}, passErr, done);
});
it("should be run when router returns no route", (done) => {
let handled;
it("should return true on DoRoute", (done) => {
let routed;
Router.route$(foo, new Router(Router.getRouteDefault$(
routerNo(),
reason => routerDo(m => {
handled = true;
})
))
)
.subscribe(n => {
expect(handled).to.be.true;
p.route$(foo, p.do(() => {
routed = true;
}))
.subscribe(t => {
expect(t).to.be.true;
expect(routed).to.be.true;
}, passErr, done);
});
it('should allow undefined result for getDefaultRouter', (done) =>{
new Router(Router.getRouteDefault$(
routerNo(),
() => undefined
))
._getRoute$(foo)
.subscribe(route => {
expect(route.type).to.eql('no')
}, passErr, done);
});
});
describe('Router.getRouteFirst$', () => {
describe('p.first', () => {
it('should return false on no routers', (done) =>
Router.route$(foo, new Router(Router.getRouteFirst$()))
p.route$(foo, p.first())
.subscribe(t => expect(t).to.be.false, passErr, done)

@@ -423,6 +419,6 @@ );

it('should return false on only null/undefined routers', (done) =>
Router.route$(foo, new Router(Router.getRouteFirst$(
p.route$(foo, p.first(
null,
undefined
)))
))
.subscribe(t => expect(t).to.be.false, passErr, done)

@@ -432,7 +428,7 @@ );

it('should return false on only unsuccessful and null/undefined routers', (done) =>
Router.route$(foo, new Router(Router.getRouteFirst$(
() => routerNo(),
p.route$(foo, p.first(
p.no(),
null,
undefined
)))
))
.subscribe(t => expect(t).to.be.false, passErr, done)

@@ -442,5 +438,5 @@ );

it('should return false on no successful routers', (done) => {
Router.route$(foo, new Router(Router.getRouteFirst$(
() => routerNo()
)))
p.route$(foo, p.first(
p.no()
))
.subscribe(t => expect(t).to.be.false, passErr, done)

@@ -452,7 +448,7 @@ });

Router.route$(foo, new Router(Router.getRouteFirst$(
() => routerDo(m => {
p.route$(foo, p.first(
p.do(m => {
routed = true;
})
)))
))
.subscribe(t => {

@@ -467,9 +463,9 @@ expect(t).to.be.true;

Router.route$(foo, new Router(Router.getRouteFirst$(
p.route$(foo, p.first(
null,
undefined,
() => routerDo(m => {
p.do(m => {
routed = true;
})
)))
))
.subscribe(n => {

@@ -483,8 +479,8 @@ expect(routed).to.be.true;

Router.route$(foo, new Router(Router.getRouteFirst$(
() => routerNo(),
() => routerDo(m => {
p.route$(foo, p.first(
p.no(),
p.do(m => {
routed = true;
})
)))
))
.subscribe(n => {

@@ -496,5 +492,27 @@ expect(routed).to.be.true;

describe('tryInScoreOrder', () => {
describe('p.combineScore', () => {
it("should return combined score", () => {
expect(p.combinedScore(.4, .25)).to.eql(.1);
});
})
describe('p.routeWithCombinedScore', () => {
it("should return route with combined score", () => {
expect(p.routeWithCombinedScore(
p.doRoute(() => {}, .4),
.25
).score).to.eql(.1);
});
})
describe('p.minRoute', () => {
it("should have a zero score", () => {
let route = p.minRoute;
expect(route.score).to.eql(0);
});
})
describe('p.best', () => {
it('should return false on no routers', (done) =>
Router.route$(foo, new Router(Router.getRouteBest$()))
p.route$(foo, p.best())
.subscribe(t => expect(t).to.be.false, passErr, done)

@@ -504,6 +522,6 @@ );

it('should return false on only null/undefined routers', (done) =>
Router.route$(foo, new Router(Router.getRouteBest$(
p.route$(foo, p.best(
null,
undefined
)))
))
.subscribe(t => expect(t).to.be.false, passErr, done)

@@ -513,7 +531,7 @@ );

it('should return false on only unsuccessful and null/undefined routers', (done) =>
Router.route$(foo, new Router(Router.getRouteBest$(
() => routerNo(),
p.route$(foo, p.best(
p.no(),
null,
undefined
)))
))
.subscribe(t => expect(t).to.be.false, passErr, done)

@@ -523,5 +541,5 @@ );

it('should return false on no successful routers', (done) => {
Router.route$(foo, new Router(Router.getRouteBest$(
() => routerNo()
)))
p.route$(foo, p.best(
p.no()
))
.subscribe(t => expect(t).to.be.false, passErr, done)

@@ -533,7 +551,7 @@ });

Router.route$(foo, new Router(Router.getRouteBest$(
() => routerDo(m => {
p.route$(foo, p.best(
p.do(m => {
routed = true;
})
)))
))
.subscribe(n => {

@@ -547,9 +565,9 @@ expect(routed).to.be.true;

Router.route$(foo, new Router(Router.getRouteBest$(
p.route$(foo, p.best(
null,
undefined,
() => routerDo(m => {
p.do(m => {
routed = true;
})
)))
))
.subscribe(n => {

@@ -563,8 +581,8 @@ expect(routed).to.be.true;

Router.route$(foo, new Router(Router.getRouteBest$(
() => routerNo(),
() => routerDo(m => {
p.route$(foo, p.best(
p.no(),
p.do(m => {
routed = true;
})
)))
))
.subscribe(n => {

@@ -578,8 +596,8 @@ expect(routed).to.be.true;

Router.route$(foo, new Router(Router.getRouteBest$(
() => routerDo(m => {
p.route$(foo, p.best(
p.do(m => {
routed = true;
}),
throwErr
)))
))
.subscribe(n => {

@@ -593,6 +611,6 @@ expect(routed).to.be.true;

Router.route$(foo, new Router(Router.getRouteBest$(
() => routerDo(_ => { routed = 'first'; }, 0.75),
() => routerDo(_ => { routed = 'second'; }, 0.50)
)))
p.route$(foo, p.best(
p.do(_ => { routed = 'first'; }, 0.75),
p.do(_ => { routed = 'second'; }, 0.50)
))
.subscribe(n => {

@@ -606,6 +624,6 @@ expect(routed).to.eql('first');

Router.route$(foo, new Router(Router.getRouteBest$(
() => routerDo(_ => { routed = 'first'; }, .5),
() => routerDo(_ => { routed = 'second'; }, .75)
)))
p.route$(foo, p.best(
p.do(_ => { routed = 'first'; }, .5),
p.do(_ => { routed = 'second'; }, .75)
))
.subscribe(n => {

@@ -619,6 +637,6 @@ expect(routed).to.eql('second');

Router.route$(foo, new Router(Router.getRouteBest$(
() => routerDo(_ => { routed = 'first'; }),
() => routerDo(_ => { routed = 'second'; }, .75)
)))
p.route$(foo, p.best(
p.do(_ => { routed = 'first'; }),
p.do(_ => { routed = 'second'; }, .75)
))
.subscribe(n => {

@@ -632,6 +650,6 @@ expect(routed).to.eql('first');

Router.route$(foo, new Router(Router.getRouteBest$(
() => routerDo(_ => { routed = 'first'; }, 0.75),
() => routerDo(_ => { routed = 'second'; }, 0.75)
)))
p.route$(foo, p.best(
p.do(_ => { routed = 'first'; }, 0.75),
p.do(_ => { routed = 'second'; }, 0.75)
))
.subscribe(n => {

@@ -643,11 +661,11 @@ expect(routed).to.eql('first');

describe('Router.noop', () => {
describe('p.noop', () => {
it("should execute the handler and return false", (done) => {
let routed;
Router.route$(foo, new Router(Router.getRouteNoop$(
p.route$(foo, p.noop(
m => {
routed = true;
}
)))
))
.subscribe(n => {

@@ -660,17 +678,344 @@ expect(n).to.be.false;

describe('Router.routeWithCombinedScore', () => {
it("should return combined score", () => {
expect(Router.routeWithCombinedScore(
Router.actionRoute(() => {}, .4),
.25
).score).to.eql(.1);
describe('p.isMatch', () => {
it("return true on a match", () => {
expect(p.isMatch({ value: 15 })).to.be.true;
});
})
describe('ifTrue', () => {
it("return false on no match", () => {
expect(p.isMatch({ reason: 'yo' })).to.be.false;
});
});
describe('p.getNormalizedMatchResult$', (done) => {
it("normalizes undefined", () => {
p
.getNormalizedMatchResult$(m => undefined)
.subscribe(match => {
expect(match.value).to.be.undefined;
expect(match.reason).to.eql('none');
}, passErr, done);
});
it("normalizes false", () => {
p
.getNormalizedMatchResult$(m => undefined)
.subscribe(match => {
expect(match.value).to.be.undefined;
expect(match.reason).to.eql('none');
}, passErr, done);
});
it("normalizes null", () => {
p
.getNormalizedMatchResult$(m => undefined)
.subscribe(match => {
expect(match.value).to.be.undefined;
expect(match.reason).to.eql('none');
}, passErr, done);
});
it("normalizes { reason }", () => {
p
.getNormalizedMatchResult$(m => ({ reason: 'reason' }))
.subscribe(match => {
expect(match.reason).to.eql('reason');
expect(match.value).to.be.undefined;
}, passErr, done);
});
it("normalizes number", () => {
p
.getNormalizedMatchResult$(m => 15)
.subscribe(match => {
expect(match.value).to.eql(15);
expect(match.score).to.eql(1);
expect(match.reason).to.be.undefined;
}, passErr, done);
});
it("normalizes object", () => {
p
.getNormalizedMatchResult$(m => ({ dog: 15 }))
.subscribe(match => {
expect(match.value.dog).to.eql(15);
expect(match.reason).to.be.undefined;
}, passErr, done);
});
it("normalizes { value }", () => {
p
.getNormalizedMatchResult$(m => ({
value: 15
}))
.subscribe(match => {
expect(match.value).to.eql(15);
expect(match.score).to.eql(1);
expect(match.reason).to.be.undefined;
}, passErr, done);
});
it("normalizes { value, score }", () => {
p
.getNormalizedMatchResult$(m => ({
value: 15,
score: .5
}))
.subscribe(match => {
expect(match.value).to.eql(15);
expect(match.score).to.eql(.5);
expect(match.reason).to.be.undefined;
}, passErr, done);
});
});
describe('p.ifGet', () => {
it("should return false on no match when 'else' router doesn't exist", (done) =>
p.route$(notFoo, p.ifGet(
barIfFoo,
value => p.do(throwErr)
))
.subscribe(t => expect(t).to.be.false, passErr, done)
);
it("should return false on no match when 'else' router doesn't exist", (done) =>
p.route$(notFoo, p.ifGet(
barIfFoo,
value => p.do(throwErr)
))
.subscribe(t => expect(t).to.be.false, passErr, done)
);
it("should return false on no match when 'else' router doesn't route", (done) =>
p.route$(notFoo, p.ifGet(
barIfFoo,
value => p.do(throwErr),
route => p.no()
))
.subscribe(t => expect(t).to.be.false, passErr, done)
);
it("should return false on match when 'if' router doesn't route and 'else' router exists", (done) =>
p.route$(foo, p.ifGet(
barIfFoo,
value => p.no(),
route => p.do(throwErr)
))
.subscribe(t => expect(t).to.be.false, passErr, done)
);
it("should route message to 'if' handler on match when 'else' router doesn't exist", (done) => {
let routed;
p.route$(foo, p.ifGet(
barIfFoo,
value => p.do(m => {
routed = true;
})
))
.subscribe(n => {
expect(routed).to.be.true;
}, passErr, done);
});
it("should route message to 'if' handler on match when 'else' router exists", (done) => {
let routed;
p.route$(foo, p.ifGet(
barIfFoo,
value => p.do(m => {
routed = true;
}),
route => p.do(throwErr)
))
.subscribe(n => {
expect(routed).to.be.true;
}, passErr, done);
});
it("should route message to 'else' handler on no match", (done) => {
let routed;
p.route$(notFoo, p.ifGet(
barIfFoo,
value => p.do(throwErr),
route => p.do(m => {
routed = true;
})
))
.subscribe(n => {
expect(routed).to.be.true;
}, passErr, done);
});
it("should route message to 'else' router on no match", (done) => {
let routed;
p.route$(notFoo, p.ifGet(
c => ({ reason: 'reason' }),
value => p.do(throwErr),
route => p.do(m => {
routed = route.reason;
})
))
.subscribe(n => {
expect(routed).to.eql('reason');
}, passErr, done);
});
it("should pass value to 'then' router on match", (done) => {
let routed;
p.route$(foo, p.ifGet(
c => ({ value: 'value' }),
value => p.do(c => {
routed = value;
}),
route => p.do(throwErr)
))
.subscribe(n => {
expect(routed).to.eql('value');
}, passErr, done);
});
it("should pass value to 'then' handler on match", (done) => {
let routed;
p.route$(foo, p.ifGet(
c => ({ value: 'value' }),
value => p.do(() => {
routed = value;
}),
route => p.do(throwErr)
))
.subscribe(n => {
expect(routed).to.eql('value');
}, passErr, done);
});
it("should return score=1 when score not supplied", (done) => {
p.ifGet(
barIfFoo,
value => p.do(m => {})
)
(foo)
.subscribe(route => {
expect(route.score).to.eql(1);
done();
})
});
it("should return supplied score", (done) => {
p.ifGet(
m => ({ value: 'dog', score: 0.4 }),
value => p.do(m => {})
)
(foo)
.subscribe(route => {
expect(route.score).to.eql(.4);
}, passErr, done);
});
it("should pass supplied value to handler", (done) => {
let handled;
p.route$(foo, p.ifGet(
m => ({ value: 'dog' }),
value => p.do(() => {
handled = value;
})
))
.subscribe(_ => {
expect(handled).to.eql('dog');
}, passErr, done);
});
it("should return combined score when route score supplied", (done) => {
p.ifGet(
barIfFoo,
value => p.do(() => {}, .25)
)
(foo)
.subscribe(route => {
expect(route.score).to.eql(.25);
}, passErr, done);
});
it("should return combined score when both scores supplied", (done) => {
p.ifGet(
m => ({ value: 'cat', score: 0.4 }),
value => p.do(() => {}, .25)
)
(foo)
.subscribe(route => {
expect(route.score).to.eql(.1);
}, passErr, done);
});
it("should return 'else' route score on no match", (done) => {
p.ifGet(
barIfFoo,
value => p.do(throwErr),
route => p.do(() => {}, .5)
)
(notFoo)
.subscribe(route => {
expect(route.score).to.eql(.5);
}, passErr, done);
});
});
describe("p.predicateToMatcher", () => {
it("should pass through true", (done) => {
p.predicateToMatcher(m => true)
(foo)
.subscribe(response => {
expect(response).to.be.true;
}, passErr, done);
});
it("should pass through true", (done) => {
p.predicateToMatcher(m => false)
(foo)
.subscribe(response => {
expect(response).to.be.false;
}, passErr, done);
});
it("should throw on object", (done) => {
p.predicateToMatcher(m => ({ dog: "reason"}))
(foo)
.subscribe(throwErr, error => done(), throwErr);
});
it("should throw on number", (done) => {
p.predicateToMatcher(m => 15)
(foo)
.subscribe(throwErr, error => done(), throwErr);
});
it("should pass through { value: true }", (done) => {
p.predicateToMatcher(m => ({ value: true }))
(foo)
.subscribe(response => {
expect(response.value).to.be.true;
}, passErr, done);
});
it("should treat { value: false } as false", (done) => {
p.predicateToMatcher(m => ({ value: false }))
(foo)
.subscribe(response => {
expect(response).to.be.false;
}, passErr, done);
});
});
describe('p.if', () => {
it("should return false on false when 'else' router doesn't exist", (done) =>
Router.route$(foo, new Router(Router.getRouteIfTrue$(
p.route$(foo, p.if(
m => false,
() => routerDo(throwErr)
)))
p.do(throwErr)
))
.subscribe(t => expect(t).to.be.false, passErr, done)

@@ -680,7 +1025,7 @@ );

it("should return false on false when 'else' router doesn't route", (done) =>
Router.route$(foo, new Router(Router.getRouteIfTrue$(
p.route$(foo, p.if(
m => false,
() => routerDo(throwErr),
() => routerNo()
)))
p.do(throwErr),
route => p.no()
))
.subscribe(t => expect(t).to.be.false, passErr, done)

@@ -690,6 +1035,6 @@ );

it("should return false on true when 'if' router doesn't route and 'else' router doesn't exist", (done) =>
Router.route$(foo, new Router(Router.getRouteIfTrue$(
p.route$(foo, p.if(
m => true,
() => routerNo()
)))
p.no()
))
.subscribe(t => expect(t).to.be.false, passErr, done)

@@ -699,7 +1044,7 @@ );

it("should return false on true when 'if' router doesn't route and 'else' router exists", (done) =>
Router.route$(foo, new Router(Router.getRouteIfTrue$(
p.route$(foo, p.if(
m => true,
() => routerNo(),
() => routerDo(throwErr)
)))
p.no(),
route => p.do(throwErr)
))
.subscribe(t => expect(t).to.be.false, passErr, done)

@@ -711,8 +1056,8 @@ );

Router.route$(foo, new Router(Router.getRouteIfTrue$(
p.route$(foo, p.if(
m => true,
() => routerDo(m => {
p.do(m => {
routed = true;
})
)))
))
.subscribe(n => {

@@ -726,9 +1071,9 @@ expect(routed).to.be.true;

Router.route$(foo, new Router(Router.getRouteIfTrue$(
p.route$(foo, p.if(
m => true,
() => routerDo(m => {
p.do(m => {
routed = true;
}),
() => routerDo(throwErr)
)))
route => p.do(throwErr)
))
.subscribe(n => {

@@ -742,9 +1087,9 @@ expect(routed).to.be.true;

Router.route$(foo, new Router(Router.getRouteIfTrue$(
p.route$(foo, p.if(
m => false,
() => routerDo(throwErr),
() => routerDo(m => {
p.do(throwErr),
route => p.do(m => {
routed = true;
})
)))
))
.subscribe(n => {

@@ -756,7 +1101,7 @@ expect(routed).to.be.true;

it("should return score=1 on true predicate when 'if' score undefined", (done) => {
new Router(Router.getRouteIfTrue$(
p.if(
m => true,
() => routerDo(m => {})
))
._getRoute$(foo)
p.do(m => {})
)
(foo)
.subscribe(route => {

@@ -768,7 +1113,7 @@ expect(route.score).to.eql(1);

it("should return route score on true predicate", (done) => {
new Router(Router.getRouteIfTrue$(
p.if(
m => true,
() => routerDo(() => {}, 0.25)
))
._getRoute$(foo)
p.do(() => {}, 0.25)
)
(foo)
.subscribe(route => {

@@ -780,8 +1125,8 @@ expect(route.score).to.eql(.25);

it("should return score=1 on false predicate when 'else' score undefined", (done) => {
new Router(Router.getRouteIfTrue$(
p.if(
m => false,
() => routernDo(throwErr),
() => routerDo(m => {})
))
._getRoute$(foo)
p.do(throwErr),
route => p.do(m => {})
)
(foo)
.subscribe(route => {

@@ -793,8 +1138,8 @@ expect(route.score).to.eql(1);

it("should return 'else' route score on false predicate", (done) => {
new Router(Router.getRouteIfTrue$(
p.if(
m => false,
() => routerDo(throwErr),
() => routerDo(_ => {}, .5)
))
._getRoute$(foo)
p.do(throwErr),
route => p.do(_ => {}, .5)
)
(foo)
.subscribe(route => {

@@ -806,7 +1151,7 @@ expect(route.score).to.eql(.5);

it("should throw on string", (done) => {
new Router(Router.getRouteIfTrue$(
p.if(
m => 'foo',
() => routerDo(throwErr)
))
._getRoute$(foo)
p.do(throwErr)
)
(foo)
.subscribe(throwErr, error => {

@@ -818,7 +1163,7 @@ done();

it("should throw on object", (done) => {
new Router(Router.getRouteIfTrue$(
p.if(
m => ({ foo: "foo" }),
() => routerDo(throwErr)
))
._getRoute$(foo)
p.do(throwErr)
)
(foo)
.subscribe(throwErr, error => {

@@ -830,7 +1175,7 @@ done();

it("should return a default reason on false", (done) => {
new Router(Router.getRouteIfTrue$(
p.if(
m => false,
() => routerDo(throwErr)
))
._getRoute$(foo)
p.do(throwErr)
)
(foo)
.subscribe(route => {

@@ -843,12 +1188,12 @@ expect(route.reason).to.eql("none");

let routed;
new Router(Router.getRouteIfTrue$(
p.if(
m => ({ reason: 'whatevs' }),
() => routerDo(throwErr),
(_, reason) => routerDo(m => {
routed = reason;
p.do(throwErr),
route => p.do(m => {
routed = route.reason;
})
))
._getRoute$(foo)
)
(foo)
.subscribe(route => {
expect(route.type === 'action');
expect(route.type === 'do');
route.action();

@@ -860,7 +1205,7 @@ expect(routed).to.eql("whatevs");

it("should return supplied reason when 'else' router not supplied", (done) => {
new Router(Router.getRouteIfTrue$(
p.if(
m => ({ reason: 'whatevs' }),
() => routerDo(throwErr)
))
._getRoute$(foo)
p.do(throwErr)
)
(foo)
.subscribe(route => {

@@ -875,7 +1220,7 @@ expect(route.type).to.eql('no');

new Router(Router.getRouteIfTrue$(
p.if(
m => ({ value: true, score: .5 }),
() => routerDo(m => { handled = true; })
))
._getRoute$(foo)
p.do(m => { handled = true; })
)
(foo)
.subscribe(route => {

@@ -891,7 +1236,7 @@ route.action();

new Router(Router.getRouteIfTrue$(
p.if(
m => ({ value: false }),
() => routerDo(throwErr)
))
._getRoute$(foo)
p.do(throwErr)
)
(foo)
.subscribe(route => {

@@ -903,7 +1248,7 @@ expect(route.type).to.eql('no')

it('should allow undefined result for getThenRouter', (done) =>{
new Router(Router.getRouteIfMatches$(
p.if(
c => true,
() => undefined
))
._getRoute$(foo)
undefined
)
(foo)
.subscribe(route => {

@@ -915,8 +1260,8 @@ expect(route.type).to.eql('no')

it('should allow undefined result for getElseRouter', (done) =>{
new Router(Router.getRouteIfMatches$(
p.if(
c => false,
throwErr,
() => undefined
))
._getRoute$(foo)
route => undefined
)
(foo)
.subscribe(route => {

@@ -929,195 +1274,104 @@ expect(route.type).to.eql('no')

describe('ifMatches', () => {
it("should return false on no match when 'else' router doesn't exist", (done) =>
Router.route$(notFoo, new Router(Router.getRouteIfMatches$(
barIfFoo,
() => routerDo(throwErr)
)))
.subscribe(t => expect(t).to.be.false, passErr, done)
);
describe("p.before", () => {
it("should return false with NoRoute", (done) => {
p.route$(foo, p.before(
throwErr,
p.no()
))
.subscribe(t => expect(t).to.be.false, passErr, done);
});
it("should return false on no match when 'else' router doesn't exist", (done) =>
Router.route$(notFoo, new Router(Router.getRouteIfMatches$(
barIfFoo,
() => routerDo(throwErr)
)))
.subscribe(t => expect(t).to.be.false, passErr, done)
);
it("should return false on no match when 'else' router doesn't route", (done) =>
Router.route$(notFoo, new Router(Router.getRouteIfMatches$(
barIfFoo,
() => routerDo(throwErr),
() => routerNo()
)))
.subscribe(t => expect(t).to.be.false, passErr, done)
);
it("should return false on match when 'if' router doesn't route and 'else' router exists", (done) =>
Router.route$(foo, new Router(Router.getRouteIfMatches$(
barIfFoo,
() => routerNo(),
() => routerDo(throwErr)
)))
.subscribe(t => expect(t).to.be.false, passErr, done)
);
it("should route message to 'if' handler on match when 'else' router doesn't exist", (done) => {
let routed;
Router.route$(foo, new Router(Router.getRouteIfMatches$(
barIfFoo,
() => routerDo(m => {
it("should run 'before' handler and then router's action", (done) => {
let handled = false;
let routed = false;
p.route$(foo, p.before(
m => {
expect(routed).to.be.false;
handled = true;
},
p.do(m => {
expect(handled).to.be.true;
routed = true;
})
)))
.subscribe(n => {
))
.subscribe(t => {
expect(t).to.be.true;
expect(routed).to.be.true;
}, passErr, done);
});
});
it("should route message to 'if' handler on match when 'else' router exists", (done) => {
let routed;
Router.route$(foo, new Router(Router.getRouteIfMatches$(
barIfFoo,
()=> routerDo(m => {
routed = true;
}),
() => routerDo(throwErr)
)))
.subscribe(n => {
expect(routed).to.be.true;
}, passErr, done);
describe("p.before", () => {
it("should return false with NoRoute", (done) => {
p.route$(foo, p.after(
throwErr,
p.no()
))
.subscribe(t => expect(t).to.be.false, passErr, done);
});
it("should route message to 'else' handler on no match", (done) => {
let routed;
Router.route$(notFoo, new Router(Router.getRouteIfMatches$(
barIfFoo,
() => routerDo(throwErr),
() => routerDo(m => {
it("should run 'after' handler and then router's action", (done) => {
let handled = false;
let routed = false;
p.route$(foo, p.after(
m => {
expect(routed).to.be.true;
handled = true;
},
p.do(m => {
expect(handled).to.be.false;
routed = true;
})
)))
.subscribe(n => {
expect(routed).to.be.true;
))
.subscribe(t => {
expect(t).to.be.true;
expect(handled).to.be.true;
}, passErr, done);
});
});
it("should route message to 'else' router on no match", (done) => {
describe("p.default", () => {
it("should not be run when main router returns an action route", (done) => {
let routed;
Router.route$(notFoo, new Router(Router.getRouteIfMatches$(
c => ({ reason: 'reason' }),
() => routerDo(throwErr),
(c, reason) => routerDo(m => {
routed = reason;
})
)))
.subscribe(n => {
expect(routed).to.eql('reason');
}, passErr, done);
});
it("should pass value to 'then' router on match", (done) => {
let routed;
Router.route$(foo, new Router(Router.getRouteIfMatches$(
c => ({ value: 'value' }),
(_, value) => routerDo(c => {
routed = value;
p.route$(foo, p.default(
p.do(m => {
routed = true;
}),
() => routerDo(throwErr)
)))
reason => p.do(throwErr)
))
.subscribe(n => {
expect(routed).to.eql('value');
expect(routed).to.be.true;
}, passErr, done);
});
it("should pass value to 'then' handler on match", (done) => {
let routed;
it("should be run when router returns no route", (done) => {
let handled;
Router.route$(foo, new Router(Router.getRouteIfMatches$(
c => ({ value: 'value' }),
(c, value) => routerDo(() => {
routed = value;
}),
() => routerDo(throwErr)
)))
.subscribe(n => {
expect(routed).to.eql('value');
}, passErr, done);
});
it("should return score=1 when score not supplied", (done) => {
new Router(Router.getRouteIfMatches$(
barIfFoo,
() => routerDo(m => {})
))
._getRoute$(foo)
.subscribe(route => {
expect(route.score).to.eql(1);
done();
p.route$(foo, p.default(
p.no('reason'),
route => p.do(m => {
handled = route.reason;
})
});
it("should return supplied score", (done) => {
new Router(Router.getRouteIfMatches$(
m => ({ value: 'dog', score: 0.4 }),
() => routerDo(m => {})
))
._getRoute$(foo)
.subscribe(route => {
expect(route.score).to.eql(.4);
.subscribe(n => {
expect(handled).to.eql('reason');
}, passErr, done);
});
it("should pass supplied value to handler", (done) => {
let handled;
Router.route$(foo, new Router(Router.getRouteIfMatches$(
m => ({ value: 'dog' }),
(m, value) => routerDo(() => {
handled = value;
})
)))
.subscribe(_ => {
expect(handled).to.eql('dog');
}, passErr, done);
});
it("should return combined score when route score supplied", (done) => {
new Router(Router.getRouteIfMatches$(
barIfFoo,
() => routerDo(() => {}, .25)
))
._getRoute$(foo)
it('should allow undefined result for getDefaultRouter', (done) =>{
p.default(
p.no('reason'),
route => undefined
)
(foo)
.subscribe(route => {
expect(route.score).to.eql(.25);
expect(route.type).to.eql('no');
expect(route.reason).to.eql('none');
}, passErr, done);
});
it("should return combined score when both scores supplied", (done) => {
new Router(Router.getRouteIfMatches$(
m => ({ value: 'cat', score: 0.4 }),
() => routerDo(() => {}, .25)
))
._getRoute$(foo)
.subscribe(route => {
expect(route.score).to.eql(.1);
}, passErr, done);
});
it("should return 'else' route score on no match", (done) => {
new Router(Router.getRouteIfMatches$(
barIfFoo,
() => routerDo(throwErr),
() => routerDo(() => {}, .5)
))
._getRoute$(notFoo)
.subscribe(route => {
expect(route.score).to.eql(.5);
}, passErr, done);
});
});

@@ -1127,4 +1381,4 @@

it("should pass through no route", (done) =>
Router.route$(foo, routerDo(c =>
Router.route$(c, routerNo())
p.route$(foo, p.do(c =>
p.route$(c, p.no())
))

@@ -1137,4 +1391,4 @@ .subscribe(t => expect(t).to.be.true, passErr, done)

Router.route$(foo, routerDo(c =>
Router.route$(c, routerDo(c => {
p.route$(foo, p.do(c =>
p.route$(c, p.do(c => {
handled = true;

@@ -1150,7 +1404,9 @@ }))

describe('trySwitch', () => {
describe('p.switch', () => {
it("doesn't route on undefined key", done => {
Router.route$(foo, new Router(Router.getRouteSwitch$(c => undefined, () => ({
foo: routerDo(throwErr)
}))))
p.route$(foo, p.switch(
c => undefined, {
foo: p.do(throwErr)
}
))
.subscribe(t => {

@@ -1162,5 +1418,7 @@ expect(t).to.be.false;

it("doesn't route on null key", done => {
Router.route$(foo, new Router(Router.getRouteSwitch$(c => undefined, () => ({
foo: routerDo(throwErr)
}))))
p.route$(foo, p.switch(
c => undefined, {
foo: p.do(throwErr)
}
))
.subscribe(t => {

@@ -1172,5 +1430,7 @@ expect(t).to.be.false;

it("doesn't route on non-matching key", done => {
Router.route$(foo, new Router(Router.getRouteSwitch$(c => 'bar', () => ({
foo: routerDo(throwErr)
}))))
p.route$(foo, p.switch(
c => 'bar', {
foo: p.do(throwErr)
}
))
.subscribe(t => {

@@ -1183,7 +1443,9 @@ expect(t).to.be.false;

let routed = false;
Router.route$(foo, new Router(Router.getRouteSwitch$(c => 'foo', () => ({
foo: routerDo(c => {
routed = true;
}),
}))))
p.route$(foo, p.switch(
c => 'foo', {
foo: p.do(c => {
routed = true;
}),
}
))
.subscribe(t => {

@@ -1197,8 +1459,10 @@ expect(t).to.be.true;

let routed = false;
Router.route$(foo, new Router(Router.getRouteSwitch$(c => 'foo', () => ({
foo: routerDo(c => {
routed = true;
}),
bar: routerDo(throwErr)
}))))
p.route$(foo, p.switch(
c => 'foo', {
foo: p.do(c => {
routed = true;
}),
bar: p.do(throwErr)
}
))
.subscribe(t => {

@@ -1212,8 +1476,10 @@ expect(t).to.be.true;

let routed = false;
Router.route$(foo, new Router(Router.getRouteSwitch$(c => 'foo', () => ({
bar: routerDo(throwErr),
foo: routerDo(c => {
routed = true;
})
}))))
p.route$(foo, p.switch(
c => 'foo', {
bar: p.do(throwErr),
foo: p.do(c => {
routed = true;
})
}
))
.subscribe(t => {

@@ -1226,5 +1492,7 @@ expect(t).to.be.true;

it("doesn't route when router for key doesn't route", done => {
Router.route$(foo, new Router(Router.getRouteSwitch$(c => 'foo', () => ({
foo: routerNo()
}))))
p.route$(foo, p.switch(
c => 'foo', {
foo: p.no()
}
))
.subscribe(t => {

@@ -1237,7 +1505,13 @@ expect(t).to.be.false;

let routed;
Router.route$(foo, new Router(Router.getRouteSwitch$(c => 'foo', (c) => ({
foo: c.foo === 'foo'
? routerDo(c => { routed = true; })
: routerDo(throwErr)
}))))
p.route$(foo, p.switch(
c => 'foo', {
foo: p.if(
c => c.foo === 'foo',
p.do(c => {
routed = true;
}),
reason => p.do(throwErr)
)
}
))
.subscribe(t => {

@@ -1244,0 +1518,0 @@ expect(t).to.be.true;

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc