prague-fluent
Advanced tools
Comparing version 0.17.12 to 0.17.13
@@ -5,5 +5,5 @@ import { Observable } from 'rxjs'; | ||
export declare abstract class Route<VALUE = any> { | ||
private _route; | ||
do$(): Observable<boolean>; | ||
do(): Promise<boolean>; | ||
type$(): Observable<string>; | ||
} | ||
@@ -37,3 +37,3 @@ export declare abstract class ScoredRoute<VALUE = any> extends Route<VALUE> { | ||
router<ACTION extends keyof TEMPLATES, ARGS extends TEMPLATES[ACTION]>(action: ACTION, args?: ARGS, score?: number): Router; | ||
mapToDo(route: TemplateRoute<keyof TEMPLATES, TEMPLATES[keyof TEMPLATES]>, context?: CONTEXT): TemplateRoute<keyof TEMPLATES, TEMPLATES[keyof TEMPLATES]> | DoRoute; | ||
mapToDo(route: TemplateRoute<keyof TEMPLATES, TEMPLATES[keyof TEMPLATES]>, context?: CONTEXT): DoRoute; | ||
} | ||
@@ -45,8 +45,6 @@ export declare class MultipleRoute extends Route { | ||
export declare type Action<ARG = undefined> = (arg?: ARG) => Observableable<any>; | ||
export declare class DoRoute extends ScoredRoute<undefined> { | ||
private action; | ||
constructor(action: Action, score?: number); | ||
do$(): Observable<boolean>; | ||
export declare class DoRoute extends Route<undefined> { | ||
constructor(action: Action); | ||
} | ||
export declare function _do<ARG = undefined>(action: Action<ARG>, score?: number): Router<ARG, DoRoute>; | ||
export declare function _do<ARG = undefined>(action: Action<ARG>): Router<ARG, DoRoute>; | ||
export { _do as do }; | ||
@@ -57,3 +55,2 @@ export declare class MatchRoute<VALUE = any> extends ScoredRoute<VALUE> { | ||
} | ||
export declare function match<VALUE = any>(value: VALUE, score?: number): Router<{}, MatchRoute<VALUE>>; | ||
export declare class NoRoute<VALUE = any> extends Route<VALUE> { | ||
@@ -64,6 +61,5 @@ reason: string; | ||
constructor(reason?: string, value?: VALUE); | ||
static do$: () => Observable<boolean>; | ||
static default: NoRoute<any>; | ||
static default$: Observable<NoRoute<any>>; | ||
static router: () => Observable<NoRoute<any>>; | ||
do$(): Observable<boolean>; | ||
static defaultGetRoute$(): Observable<NoRoute<any>>; | ||
} | ||
@@ -106,8 +102,6 @@ declare function _no<VALUE>(reason?: string, value?: VALUE): Router<{}, NoRoute<VALUE>>; | ||
export declare type RouteTypes<VALUE> = keyof MapTypeToRouteClass<VALUE>; | ||
export declare function getTypesFromRoute(route: Route): IterableIterator<"default" | "no" | "do" | "match" | "template" | "multiple" | "scored" | "route">; | ||
export declare type MapTypeToRouter<VALUE> = { | ||
[P in RouteTypes<VALUE>]: AnyRouter<MapTypeToRouteClass<VALUE>[P]>; | ||
}; | ||
export declare function typeRouter<VALUE>(mapTypeToRouter: Partial<MapTypeToRouter<VALUE>>): Router<Route<VALUE>, any>; | ||
export declare function ifGet<VALUE>(getMatch: AnyRouter<undefined, VALUE>, mapMatchRoute: AnyRouter<MatchRoute<VALUE>>, mapNoRoute?: AnyRouter<NoRoute<VALUE>>): Router<undefined, any>; | ||
export declare function match<VALUE>(getMatch: AnyRouter<undefined, VALUE>, mapMatchRoute: AnyRouter<MatchRoute<VALUE>>, mapNoRoute?: AnyRouter<NoRoute<VALUE>>): Router<undefined, any>; | ||
export declare function _if(predicate: AnyRouter<undefined, boolean>, mapMatchRoute: AnyRouter<MatchRoute<boolean>>, mapNoRoute?: AnyRouter<NoRoute<boolean>>): Router<undefined, any>; | ||
@@ -114,0 +108,0 @@ export { _if as if }; |
@@ -12,59 +12,2 @@ "use strict"; | ||
})(); | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [0, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spread = (this && this.__spread) || function () { | ||
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); | ||
return ar; | ||
}; | ||
var __values = (this && this.__values) || function (o) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; | ||
if (m) return m.call(o); | ||
return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -90,2 +33,22 @@ var rxjs_1 = require("rxjs"); | ||
}; | ||
Route.prototype.type$ = function () { | ||
var _this = this; | ||
return new rxjs_1.Observable(function (observer) { | ||
if (_this instanceof NoRoute) | ||
observer.next('no'); | ||
if (_this instanceof DoRoute) | ||
observer.next('do'); | ||
if (_this instanceof MatchRoute) | ||
observer.next('match'); | ||
if (_this instanceof TemplateRoute) | ||
observer.next('template'); | ||
if (_this instanceof MultipleRoute) | ||
observer.next('multiple'); | ||
if (_this instanceof ScoredRoute) | ||
observer.next('scored'); | ||
observer.next('route'); | ||
observer.next('default'); | ||
observer.complete(); | ||
}); | ||
}; | ||
return Route; | ||
@@ -152,3 +115,3 @@ }()); | ||
} | ||
return new (TemplateRoute.bind.apply(TemplateRoute, __spread([void 0, action, args], rest)))(); | ||
return new (TemplateRoute.bind.apply(TemplateRoute, [void 0, action, args].concat(rest)))(); | ||
}; | ||
@@ -161,3 +124,3 @@ Templates.prototype.router = function (action, args) { | ||
} | ||
return Router.from(function () { return _this.route.apply(_this, __spread([action, args], rest)); }); | ||
return Router.from(function () { return _this.route.apply(_this, [action, args].concat(rest)); }); | ||
}; | ||
@@ -185,15 +148,15 @@ Templates.prototype.mapToDo = function (route, context) { | ||
__extends(DoRoute, _super); | ||
function DoRoute(action, score) { | ||
var _this = _super.call(this, score) || this; | ||
_this.action = action; | ||
function DoRoute(action) { | ||
var _this = _super.call(this) || this; | ||
_this.do$ = function () { return rxjs_1.Observable | ||
.of(action) | ||
.flatMap(function (action) { return toObservable(action()); }) | ||
.mapTo(true); }; | ||
return _this; | ||
} | ||
DoRoute.prototype.do$ = function () { | ||
return toObservable(this.action()).mapTo(true); | ||
}; | ||
return DoRoute; | ||
}(ScoredRoute)); | ||
}(Route)); | ||
exports.DoRoute = DoRoute; | ||
function _do(action, score) { | ||
return Router.from(function (arg) { return new DoRoute(function () { return action(arg); }, score); }); | ||
function _do(action) { | ||
return Router.from(function (arg) { return new DoRoute(function () { return action(arg); }); }); | ||
} | ||
@@ -212,6 +175,2 @@ exports._do = _do; | ||
exports.MatchRoute = MatchRoute; | ||
function match(value, score) { | ||
return Router.from(function () { return new MatchRoute(value, score); }); | ||
} | ||
exports.match = match; | ||
var NoRoute = /** @class */ (function (_super) { | ||
@@ -224,11 +183,11 @@ __extends(NoRoute, _super); | ||
_this.value = value; | ||
_this.do$ = NoRoute.do$; | ||
return _this; | ||
} | ||
NoRoute.prototype.do$ = function () { | ||
return rxjs_1.Observable.of(false); | ||
NoRoute.defaultGetRoute$ = function () { | ||
return rxjs_1.Observable.of(NoRoute.default); | ||
}; | ||
NoRoute.defaultReason = "none"; | ||
NoRoute.do$ = function () { return rxjs_1.Observable.of(false); }; | ||
NoRoute.default = new NoRoute(); | ||
NoRoute.default$ = rxjs_1.Observable.of(NoRoute.default); | ||
NoRoute.router = function () { return NoRoute.default$; }; | ||
return NoRoute; | ||
@@ -245,3 +204,3 @@ }(Route)); | ||
if (router == null) | ||
this.route$ = NoRoute.router; | ||
this.route$ = NoRoute.defaultGetRoute$; | ||
else if (router instanceof Router) | ||
@@ -272,5 +231,7 @@ this.route$ = router.route$; | ||
Router.from = function (router) { | ||
return router instanceof Router | ||
? router | ||
: new Router(router); | ||
if (router == null) | ||
return noRouter; | ||
if (router instanceof Router) | ||
return router; | ||
return new Router(router); | ||
}; | ||
@@ -294,3 +255,9 @@ Router.prototype.do$ = function (arg) { | ||
Router.prototype.mapByType = function (mapTypeToRouter) { | ||
return this.map(typeRouter(mapTypeToRouter)); | ||
return this.map(function (route) { return route | ||
.type$() | ||
.map(function (type) { return mapTypeToRouter[type]; }) | ||
.filter(function (router) { return !!router; }) | ||
.take(1) | ||
.flatMap(function (router) { return Router.from(router).route$(route); }) | ||
.defaultIfEmpty(route); }); | ||
}; | ||
@@ -319,4 +286,4 @@ Router.prototype.mapTemplate = function (templates, context) { | ||
.mapByType({ | ||
do: function (route) { return new DoRoute(function () { return toObservable(action()) | ||
.flatMap(function (_) { return route.do$(); }); }, route.score); } | ||
do: _do(function (route) { return toObservable(action()) | ||
.flatMap(function (_) { return route.do$(); }); }) | ||
}); | ||
@@ -328,5 +295,5 @@ }; | ||
.mapByType({ | ||
do: function (route) { return new DoRoute(function () { return route | ||
do: _do(function (route) { return route | ||
.do$() | ||
.flatMap(function (_) { return toObservable(action()); }); }, route.score); } | ||
.flatMap(function (_) { return toObservable(action()); }); }) | ||
}); | ||
@@ -337,3 +304,4 @@ }; | ||
exports.Router = Router; | ||
var firstError = new Error("first routers can only return ScoredRoute and NoRoute"); | ||
var noRouter = new Router(NoRoute.defaultGetRoute$); | ||
var firstError = new Error("first routers can only return TemplateRoute, DoRoute, and NoRoute"); | ||
function first() { | ||
@@ -350,3 +318,3 @@ var routers = []; | ||
.filter(function (route) { | ||
if (route instanceof ScoredRoute) | ||
if (route instanceof TemplateRoute || route instanceof DoRoute) | ||
return true; | ||
@@ -370,3 +338,3 @@ if (route instanceof NoRoute) | ||
if (typeof args[0] === 'number') { | ||
_a = __read(args), tolerance = _a[0], routers = _a.slice(1); | ||
tolerance = args[0], routers = args.slice(1); | ||
} | ||
@@ -403,3 +371,2 @@ else { | ||
}); }); }); | ||
var _a; | ||
} | ||
@@ -413,77 +380,5 @@ exports.best = best; | ||
exports.noop = noop; | ||
function getTypesFromRoute(route) { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (!(route instanceof NoRoute)) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, 'no']; | ||
case 1: | ||
_a.sent(); | ||
_a.label = 2; | ||
case 2: | ||
if (!(route instanceof DoRoute)) return [3 /*break*/, 4]; | ||
return [4 /*yield*/, 'do']; | ||
case 3: | ||
_a.sent(); | ||
_a.label = 4; | ||
case 4: | ||
if (!(route instanceof MatchRoute)) return [3 /*break*/, 6]; | ||
return [4 /*yield*/, 'match']; | ||
case 5: | ||
_a.sent(); | ||
_a.label = 6; | ||
case 6: | ||
if (!(route instanceof TemplateRoute)) return [3 /*break*/, 8]; | ||
return [4 /*yield*/, 'template']; | ||
case 7: | ||
_a.sent(); | ||
_a.label = 8; | ||
case 8: | ||
if (!(route instanceof MultipleRoute)) return [3 /*break*/, 10]; | ||
return [4 /*yield*/, 'multiple']; | ||
case 9: | ||
_a.sent(); | ||
_a.label = 10; | ||
case 10: | ||
if (!(route instanceof ScoredRoute)) return [3 /*break*/, 12]; | ||
return [4 /*yield*/, 'scored']; | ||
case 11: | ||
_a.sent(); | ||
_a.label = 12; | ||
case 12: return [4 /*yield*/, 'route']; | ||
case 13: | ||
_a.sent(); | ||
return [4 /*yield*/, 'default']; | ||
case 14: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
} | ||
exports.getTypesFromRoute = getTypesFromRoute; | ||
function typeRouter(mapTypeToRouter) { | ||
return Router.from(function (route) { | ||
try { | ||
for (var _a = __values(getTypesFromRoute(route)), _b = _a.next(); !_b.done; _b = _a.next()) { | ||
var type = _b.value; | ||
var router = mapTypeToRouter[type]; | ||
if (router) | ||
return Router.from(router).route$(route); | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (_b && !_b.done && (_c = _a.return)) _c.call(_a); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
return route; | ||
var e_1, _c; | ||
}); | ||
} | ||
exports.typeRouter = typeRouter; | ||
var mapRouteIdentity = function (route) { return route; }; | ||
var getMatchError = new Error("ifGet's matchRouter should only return MatchRoute or NoRoute"); | ||
function ifGet(getMatch, mapMatchRoute, mapNoRoute) { | ||
var getMatchError = new Error("match's matchRouter should only return MatchRoute or NoRoute"); | ||
function match(getMatch, mapMatchRoute, mapNoRoute) { | ||
return Router | ||
@@ -499,3 +394,3 @@ .from(getMatch) | ||
} | ||
exports.ifGet = ifGet; | ||
exports.match = match; | ||
// _if is a special case of ifGet | ||
@@ -506,3 +401,3 @@ // value of MatchRoute must be true or false | ||
function _if(predicate, mapMatchRoute, mapNoRoute) { | ||
return ifGet(Router | ||
return match(Router | ||
.from(predicate) | ||
@@ -527,3 +422,3 @@ .mapByType({ | ||
function _switch(getKey, mapKeyToRouter) { | ||
return ifGet(getKey, function (match) { return mapKeyToRouter[match.value]; }); | ||
return match(getKey, function (match) { return mapKeyToRouter[match.value]; }); | ||
} | ||
@@ -530,0 +425,0 @@ exports._switch = _switch; |
{ | ||
"name": "prague-fluent", | ||
"version": "0.17.12", | ||
"version": "0.17.13", | ||
"description": "fluent API for Prague", | ||
@@ -5,0 +5,0 @@ "main": "dist/fluent.js", |
@@ -17,11 +17,38 @@ import { Observable } from 'rxjs'; | ||
export abstract class Route <VALUE = any> { | ||
private _route: undefined; // hack so that TypeScript will do better type checking on Routes | ||
do$(): Observable<boolean> { | ||
do$ (): Observable<boolean> { | ||
throw routeDoError; | ||
} | ||
do() { | ||
do () { | ||
return this.do$().toPromise(); | ||
} | ||
type$ () { | ||
return new Observable<string>(observer => { | ||
if (this instanceof NoRoute) | ||
observer.next('no'); | ||
if (this instanceof DoRoute) | ||
observer.next('do'); | ||
if (this instanceof MatchRoute) | ||
observer.next('match'); | ||
if (this instanceof TemplateRoute) | ||
observer.next('template'); | ||
if (this instanceof MultipleRoute) | ||
observer.next('multiple'); | ||
if (this instanceof ScoredRoute) | ||
observer.next('scored'); | ||
observer.next('route'); | ||
observer.next('default'); | ||
observer.complete(); | ||
}); | ||
} | ||
} | ||
@@ -40,3 +67,3 @@ | ||
static normalizedScore(score?: number) { | ||
static normalizedScore (score?: number) { | ||
return score != null && score >= 0 && score < 1 | ||
@@ -47,7 +74,7 @@ ? score | ||
static combinedScore(score, otherScore) { | ||
static combinedScore (score, otherScore) { | ||
return score * otherScore | ||
} | ||
cloneWithScore(score?: number): this { | ||
cloneWithScore (score?: number): this { | ||
score = ScoredRoute.normalizedScore(score); | ||
@@ -60,3 +87,3 @@ | ||
cloneWithCombinedScore(score?: number) { | ||
cloneWithCombinedScore (score?: number) { | ||
return this.cloneWithScore(ScoredRoute.combinedScore(this.score, ScoredRoute.normalizedScore(score))); | ||
@@ -108,3 +135,3 @@ } | ||
export class Templates <TEMPLATES, CONTEXT = any, SOURCE extends TemplateSource = string> { | ||
constructor( | ||
constructor ( | ||
public mapTemplateToAction: (context: CONTEXT) => Partial<MapTemplateToAction<TEMPLATES>> | ||
@@ -178,20 +205,18 @@ ) { | ||
export class DoRoute extends ScoredRoute<undefined> { | ||
export class DoRoute extends Route<undefined> { | ||
constructor ( | ||
private action: Action, | ||
score?: number | ||
action: Action | ||
) { | ||
super(score); | ||
super(); | ||
this.do$ = () => Observable | ||
.of(action) | ||
.flatMap(action => toObservable(action())) | ||
.mapTo(true); | ||
} | ||
do$() { | ||
return toObservable(this.action()).mapTo(true); | ||
} | ||
} | ||
export function _do <ARG = undefined> ( | ||
action: Action<ARG>, | ||
score?: number | ||
) { | ||
return Router.from((arg: ARG) => new DoRoute(() => action(arg), score)); | ||
action: Action<ARG> | ||
) { | ||
return Router.from((arg: ARG) => new DoRoute(() => action(arg))); | ||
} | ||
@@ -210,9 +235,2 @@ | ||
export function match <VALUE = any> ( | ||
value: VALUE, | ||
score?: number | ||
) { | ||
return Router.from(() => new MatchRoute(value, score)); | ||
} | ||
export class NoRoute <VALUE = any> extends Route<VALUE> { | ||
@@ -226,12 +244,11 @@ static defaultReason = "none"; | ||
super(); | ||
this.do$ = NoRoute.do$; | ||
} | ||
static do$ = () => Observable.of(false); | ||
static default = new NoRoute(); | ||
static default$ = Observable.of(NoRoute.default); | ||
static router = () => NoRoute.default$; | ||
do$() { | ||
return Observable.of(false); | ||
static defaultGetRoute$ () { | ||
return Observable.of(NoRoute.default); | ||
} | ||
@@ -262,5 +279,5 @@ } | ||
constructor(router?: AnyRouter<ARG, VALUE>) { | ||
constructor (router?: AnyRouter<ARG, VALUE>) { | ||
if (router == null) | ||
this.route$ = NoRoute.router; | ||
this.route$ = NoRoute.defaultGetRoute$; | ||
else if (router instanceof Router) | ||
@@ -293,6 +310,10 @@ this.route$ = router.route$; | ||
static from <ARG, VALUE> (router?: AnyRouter<ARG, VALUE>) { | ||
return router instanceof Router | ||
? router | ||
: new Router(router); | ||
static from <ARG, VALUE> (router?: AnyRouter<ARG, VALUE>): Router<ARG, VALUE> { | ||
if (router == null) | ||
return noRouter as Router; | ||
if (router instanceof Router) | ||
return router; | ||
return new Router(router); | ||
} | ||
@@ -312,3 +333,5 @@ | ||
map (mapRoute: AnyRouter<Route<VALUE>>) { | ||
map ( | ||
mapRoute: AnyRouter<Route<VALUE>> | ||
) { | ||
return new Router((arg?: ARG) => this | ||
@@ -323,3 +346,10 @@ .route$(arg) | ||
) { | ||
return this.map(typeRouter(mapTypeToRouter)); | ||
return this.map(route => route | ||
.type$() | ||
.map(type => mapTypeToRouter[type] as AnyRouter<Route<VALUE>>) | ||
.filter(router => !!router) | ||
.take(1) | ||
.flatMap(router => Router.from(router).route$(route)) | ||
.defaultIfEmpty(route) | ||
); | ||
} | ||
@@ -344,3 +374,5 @@ | ||
tap <VALUE> (fn: (route: Route<VALUE>) => Observableable<any>) { | ||
tap <VALUE> ( | ||
fn: (route: Route<VALUE>) => Observableable<any> | ||
) { | ||
return this.map(route => toObservable(fn(route)).mapTo(route)); | ||
@@ -357,3 +389,3 @@ } | ||
beforeDo( | ||
beforeDo ( | ||
action: Action | ||
@@ -364,11 +396,9 @@ ) { | ||
.mapByType({ | ||
do: route => new DoRoute( | ||
() => toObservable(action()) | ||
.flatMap(_ => route.do$()), | ||
route.score | ||
do: _do(route => toObservable(action()) | ||
.flatMap(_ => route.do$()) | ||
) | ||
}); | ||
}); | ||
} | ||
afterDo( | ||
afterDo ( | ||
action: Action | ||
@@ -379,14 +409,14 @@ ) { | ||
.mapByType({ | ||
do: route => new DoRoute( | ||
() => route | ||
.do$() | ||
.flatMap(_ => toObservable(action())), | ||
route.score | ||
do: _do(route => route | ||
.do$() | ||
.flatMap(_ => toObservable(action())) | ||
) | ||
}); | ||
}); | ||
} | ||
} | ||
const firstError = new Error("first routers can only return ScoredRoute and NoRoute"); | ||
const noRouter = new Router(NoRoute.defaultGetRoute$); | ||
const firstError = new Error("first routers can only return TemplateRoute, DoRoute, and NoRoute"); | ||
export function first ( | ||
@@ -403,3 +433,3 @@ ... routers: AnyRouter[] | ||
.filter(route => { | ||
if (route instanceof ScoredRoute) | ||
if (route instanceof TemplateRoute || route instanceof DoRoute) | ||
return true; | ||
@@ -498,49 +528,9 @@ | ||
export function* getTypesFromRoute( | ||
route: Route | ||
) { | ||
if (route instanceof NoRoute) | ||
yield 'no'; | ||
if (route instanceof DoRoute) | ||
yield 'do'; | ||
if (route instanceof MatchRoute) | ||
yield 'match'; | ||
if (route instanceof TemplateRoute) | ||
yield 'template'; | ||
if (route instanceof MultipleRoute) | ||
yield 'multiple'; | ||
if (route instanceof ScoredRoute) | ||
yield 'scored'; | ||
yield 'route'; | ||
yield 'default'; | ||
} | ||
export type MapTypeToRouter <VALUE> = { [P in RouteTypes<VALUE>]: AnyRouter<MapTypeToRouteClass<VALUE>[P]> } | ||
export function typeRouter <VALUE> ( | ||
mapTypeToRouter: Partial<MapTypeToRouter<VALUE>> | ||
) { | ||
return Router.from((route: Route<VALUE>) => { | ||
for (let type of getTypesFromRoute(route)) { | ||
const router = mapTypeToRouter[type]; | ||
if (router) | ||
return Router.from(router).route$(route); | ||
} | ||
return route; | ||
}) | ||
} | ||
const mapRouteIdentity = <VALUE> (route: Route<VALUE>) => route; | ||
const getMatchError = new Error("ifGet's matchRouter should only return MatchRoute or NoRoute"); | ||
const getMatchError = new Error("match's matchRouter should only return MatchRoute or NoRoute"); | ||
export function ifGet <VALUE> ( | ||
export function match <VALUE> ( | ||
getMatch: AnyRouter<undefined, VALUE>, | ||
@@ -572,3 +562,3 @@ mapMatchRoute: AnyRouter<MatchRoute<VALUE>>, | ||
) { | ||
return ifGet<boolean>( | ||
return match<boolean>( | ||
Router | ||
@@ -605,5 +595,5 @@ .from(predicate) | ||
) { | ||
return ifGet(getKey, match => mapKeyToRouter[match.value]); | ||
return match(getKey, match => mapKeyToRouter[match.value]); | ||
} | ||
export { _switch as switch } |
237
tutorial.md
@@ -72,2 +72,3 @@ Some simple bot logic. | ||
replace ad-hoc | ||
@@ -78,2 +79,3 @@ ```ts | ||
let matches = /I am (.*)/i.exec(text); | ||
if (matches) | ||
@@ -85,2 +87,3 @@ return new p.DoRoute(() => bot.send(`Nice to meet you, ${matches[1]}`)); | ||
let matches = /What's the weather like today?/i.exec(text); | ||
if (matches) | ||
@@ -117,3 +120,3 @@ return new p.DoRoute(() => bot.send(`It's Seattle, so let's say "rainy"`)); | ||
) | ||
.getRoute() | ||
.route() | ||
.then(route => route.do()); | ||
@@ -211,1 +214,233 @@ ``` | ||
``` | ||
# Today's approach | ||
Start with: | ||
```ts | ||
const botLogic = (c: BotContext) => { | ||
const matches = /I am (.*)/i.exec(c.request.text); | ||
if (matches) | ||
c.reply(`Nice to meet you, ${matches[1]}`); | ||
} | ||
``` | ||
```ts | ||
const botLogic = (c: BotContext) => { | ||
const router = () => { | ||
const matches = /I am (.*)/i.exec(c.request.text); | ||
if (matches) | ||
return { | ||
do: () => c.reply(`Nice to meet you, ${matches[1]}`); | ||
} | ||
} | ||
const route = router(); | ||
if (route) { | ||
route.do(); | ||
} | ||
} | ||
``` | ||
```ts | ||
const botLogic = (c: BotContext) => { | ||
const router = () => { | ||
const matches = /I am (.*)/i.exec(c.request.text); | ||
if (matches) | ||
return new DoRoute(() => c.reply(`Nice to meet you, ${matches[1]}`)); | ||
else | ||
return new NoRoute(); | ||
} | ||
const route = router(); | ||
route.do(); | ||
} | ||
``` | ||
```ts | ||
const botLogic = (c: BotContext) => { | ||
p.Router | ||
.from(() => { | ||
const matches = /I am (.*)/i.exec(c.request.text); | ||
if (matches) | ||
return new DoRoute(() => c.reply(`Nice to meet you, ${matches[1]}`)); | ||
else | ||
return new NoRoute(); | ||
}) | ||
.route() | ||
.then(route => route.do()); | ||
} | ||
``` | ||
```ts | ||
const botLogic = (c: BotContext) => { | ||
p.Router | ||
.from(() => { | ||
const matches = /I am (.*)/i.exec(c.request.text); | ||
if (matches) | ||
return new DoRoute(() => c.reply(`Nice to meet you, ${matches[1]}`)); | ||
else | ||
return new NoRoute(); | ||
}) | ||
.do(); | ||
} | ||
``` | ||
```ts | ||
const botLogic = (c: BotContext) => { | ||
p.Router | ||
.from(() => { | ||
const matches = /I am (.*)/i.exec(c.request.text)); | ||
if (matches) | ||
return MatchRoute(matches); | ||
else | ||
return new NoRoute(); | ||
}) | ||
.map(route => { | ||
if (route instanceof MatchRoute) | ||
return new DoRoute(() => c.reply(`Nice to meet you, ${route.value[1]}`)); | ||
else | ||
return route; | ||
}) | ||
.do(); | ||
} | ||
``` | ||
```ts | ||
const botLogic = (c: BotContext) => { | ||
p.Router | ||
.from(() => { | ||
const matches = /I am (.*)/i.exec(c.request.text)); | ||
if (matches) | ||
return MatchRoute(matches); | ||
}) | ||
.map(route => { | ||
if (route instanceof MatchRoute) | ||
return new DoRoute(() => c.reply(`Nice to meet you, ${route.value[1]}`)); | ||
else | ||
return route; | ||
}) | ||
.do(); | ||
} | ||
``` | ||
```ts | ||
const botLogic = (c: BotContext) => { | ||
p.Router | ||
.from(() => /I am (.*)/i.exec(c.request.text)) | ||
.map(route => { | ||
if (route instanceof MatchRoute) | ||
return new DoRoute(() => c.reply(`Nice to meet you, ${route.value[1]}`)); | ||
else | ||
return route; | ||
}) | ||
.do(); | ||
} | ||
``` | ||
```ts | ||
const botLogic = (c: BotContext) => { | ||
p.Router | ||
.from(() => /I am (.*)/i.exec(c.request.text)) | ||
.mapByType({ | ||
match: matchRoute => new DoRoute(() => c.reply(`Nice to meet you, ${matchRoute.value[1]}`)); | ||
}) | ||
.do(); | ||
} | ||
``` | ||
```ts | ||
const botLogic = (c: BotContext) => { | ||
p.ifGet(() => /I am (.*)/i.exec(c.request.text), | ||
matchRoute => new DoRoute(() => c.reply(`Nice to meet you, ${matchRoute.value[1]}`)); | ||
}) | ||
.do(); | ||
} | ||
``` | ||
```ts | ||
const botLogic = (c: BotContext) => { | ||
p.ifGet(() => /I am (.*)/i.exec(c.request.text), | ||
matchRoute => p.do(() => c.reply(`Nice to meet you, ${matchRoute.value[1]}`)); | ||
}) | ||
.do(); | ||
} | ||
``` | ||
```tsx | ||
const botLogic = (c: BotContext) => { | ||
p.ifGet(() => /I am (.*)/i.exec(c.request.text), | ||
p.do(matchRoute => c.reply(`Nice to meet you, ${matchRoute.value[1]}`)); | ||
}) | ||
.do(); | ||
} | ||
``` | ||
Now add stuff | ||
```tsx | ||
const botLogic = (c: BotContext) => { | ||
p | ||
.first( | ||
p.ifGet(() => /I am (.*)/i.exec(c.request.text), | ||
p.do(matchRoute => c.reply(`Nice to meet you, ${matchRoute.value[1]}`)); | ||
}), | ||
p.ifGet(() => /time/.exec(c.request.text), | ||
p.do(() => c.reply(`It is ${new Date().toString()}`)) | ||
) | ||
) | ||
.mapByType({ | ||
no: p.do(() => c.reply("I don't understand you")) | ||
}) | ||
.do(); | ||
} | ||
``` | ||
```ts | ||
const botLogic = (c: BotContext) => { | ||
p | ||
.first( | ||
p.ifGet(() => /I am (.*)/i.exec(c.request.text), | ||
p.do(matchRoute => c.reply(`Nice to meet you, ${matchRoute.value[1]}`)); | ||
}), | ||
p.ifGet(() => /time/.exec(c.request.text), | ||
p.do(() => c.reply(`It is ${new Date().toString()}`)) | ||
) | ||
) | ||
.default( | ||
p.do(() => c.reply("I don't understand you")) | ||
) | ||
.do(); | ||
} | ||
``` | ||
```ts | ||
const botLogic = (c: BotContext) => { | ||
p | ||
.first( | ||
() => { | ||
switch (c.state.conversation.prompt) { | ||
case 'name': | ||
} | ||
} | ||
p.ifGet(() => /I am (.*)/i.exec(c.request.text), | ||
p.do(matchRoute => c.reply(`Nice to meet you, ${matchRoute.value[1]}`)); | ||
}), | ||
p.ifGet(() => /time/.exec(c.request.text), | ||
p.do(() => c.reply(`It is ${new Date().toString()}`)) | ||
) | ||
) | ||
.default( | ||
p.do(() => c.reply("I don't understand you")) | ||
) | ||
.do(); | ||
} | ||
``` |
Sorry, the diff of this file is not supported yet
63651
1035