Comparing version 0.8.0 to 0.9.0
@@ -1,2 +0,2 @@ | ||
import { Match, IRule, Handler, ruleize, RuleResult, Observableable, toObservable, toFilteredObservable } from './Rules'; | ||
import { IRouter, Handler, routerize, Route, Observableable, toObservable, toFilteredObservable } from './Rules'; | ||
import { Observable } from 'rxjs'; | ||
@@ -10,7 +10,7 @@ import { konsole } from './Konsole'; | ||
export interface DialogRegistry<M extends Match = any> { | ||
export interface DialogRegistry<M extends object = any> { | ||
[name: string]: LocalOrRemoteDialog<M>; | ||
} | ||
export interface IDialogRootMatch<M extends Match = any> { | ||
export interface IDialogRootMatch<M extends object = any> { | ||
beginChildDialog<DIALOGARGS extends object = any>(dialogOrName: LocalOrRemoteDialog<M, DIALOGARGS> | string, dialogArgs?: DIALOGARGS): Promise<void>; | ||
@@ -24,3 +24,3 @@ clearChildDialog(): Promise<void>; | ||
export interface IDialogMatch<M extends Match = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any> extends IDialogRootMatch<M> { | ||
export interface IDialogMatch<M extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any> extends IDialogRootMatch<M> { | ||
dialogData: IDialogData<DIALOGDATA>; | ||
@@ -36,4 +36,4 @@ dialogStack: DialogInstance[]; | ||
export interface DialogResponder<M extends Match = any, DIALOGRESPONSE extends object = any> { | ||
(match: M & IDialogResponderMatch<DIALOGRESPONSE>): Observableable<void>; | ||
export interface DialogResponder<M extends object = any, DIALOGRESPONSE extends object = any> { | ||
(message: M & IDialogResponderMatch<DIALOGRESPONSE>): Observableable<void>; | ||
} | ||
@@ -46,3 +46,3 @@ | ||
export interface XDialog< | ||
M extends Match = any, | ||
M extends object = any, | ||
DIALOGARGS extends object = any, | ||
@@ -52,8 +52,8 @@ DIALOGRESPONSE extends object = any, | ||
> { | ||
init?: (match: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>, | ||
rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>, | ||
init?: (message: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>, | ||
router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>, | ||
} | ||
export interface LocalDialog< | ||
M extends Match = any, | ||
M extends object = any, | ||
DIALOGARGS extends object = any, | ||
@@ -65,8 +65,8 @@ DIALOGRESPONSE extends object = any, | ||
remoteName?: string; // If defined, how it is named to the outside world, otherwise not exposed | ||
init: (match: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>; | ||
rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>; | ||
init: (message: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>; | ||
router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>; | ||
} | ||
export interface RemoteDialog< | ||
M extends Match = any, | ||
M extends object = any, | ||
DIALOGARGS extends object = any, | ||
@@ -81,3 +81,3 @@ DIALOGRESPONSE extends object = any, | ||
export type LocalOrRemoteDialog< | ||
M extends Match = any, | ||
M extends object = any, | ||
DIALOGARGS extends object = any, | ||
@@ -89,3 +89,3 @@ DIALOGRESPONSE extends object = any, | ||
const isLocalDialog = < | ||
M extends Match = any, | ||
M extends object = any, | ||
DIALOGARGS extends object = any, | ||
@@ -96,10 +96,10 @@ DIALOGRESPONSE extends object = any, | ||
: localOrRemoteDialog is LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA> => | ||
(localOrRemoteDialog as any).rule !== undefined; | ||
(localOrRemoteDialog as any).router !== undefined; | ||
export interface RootDialogInstance { | ||
get: (match: any) => Observableable<DialogInstance>; | ||
set: (match: any, rootDialogInstance?: DialogInstance) => Observableable<void>; | ||
get: (message: any) => Observableable<DialogInstance>; | ||
set: (message: any, rootDialogInstance?: DialogInstance) => Observableable<void>; | ||
} | ||
export interface DialogResponders<M extends Match = any> { | ||
export interface DialogResponders<M extends object = any> { | ||
[name: string]: DialogResponder<M>; | ||
@@ -120,6 +120,6 @@ } | ||
export interface RemoteDialogProxy<M extends Match = any> { | ||
matchLocalToRemote?: (match: M) => Observableable<any>, | ||
matchRemoteToLocal?: (match: any, tasks: DialogTask[]) => Observableable<M>, | ||
executeTask?: (match: M, tasks: DialogTask) => Observableable<any>, | ||
export interface RemoteDialogProxy<M extends object = any> { | ||
matchLocalToRemote?: (message: M) => Observableable<any>, | ||
matchRemoteToLocal?: (message: any, tasks: DialogTask[]) => Observableable<M>, | ||
executeTask?: (message: M, tasks: DialogTask) => Observableable<any>, | ||
} | ||
@@ -130,3 +130,3 @@ | ||
name: string; | ||
match: any; | ||
message: any; | ||
args: any; | ||
@@ -148,3 +148,3 @@ } | ||
instance: string; | ||
match: any; | ||
message: any; | ||
} | ||
@@ -166,3 +166,3 @@ | ||
export class Dialogs<M extends Match = any> { | ||
export class Dialogs<M extends object = any> { | ||
private dialogs: DialogRegistry<M> = {} | ||
@@ -178,3 +178,3 @@ | ||
runChildIfActive< | ||
ANYMATCH extends Match = M, | ||
ANYMATCH extends object = M, | ||
DIALOGRESPONSE extends object = any | ||
@@ -184,23 +184,23 @@ >( | ||
dialogResponder: DialogResponder<ANYMATCH, DIALOGRESPONSE> = () => {} | ||
): IRule<ANYMATCH> { | ||
): IRouter<ANYMATCH> { | ||
return { | ||
tryMatch: (match: ANYMATCH & IDialogMatch<ANYMATCH>) => { | ||
getRoute: (message: ANYMATCH & IDialogMatch<ANYMATCH>) => { | ||
konsole.log("runChildIfActive", match); | ||
konsole.log("runChildIfActive", message); | ||
let odi: Observable<DialogInstance>; | ||
if (match.dialogStack) { | ||
if (!match.dialogData.childDialogInstance) | ||
if (message.dialogStack) { | ||
if (!message.dialogData.childDialogInstance) | ||
return; | ||
odi = Observable.of(match.dialogData.childDialogInstance); | ||
odi = Observable.of(message.dialogData.childDialogInstance); | ||
} else { | ||
// This is being run from the "root" (a non-dialog rule) | ||
match = { | ||
... match as any, | ||
// This is being run from the "root" (a non-dialog router) | ||
message = { | ||
... message as any, | ||
dialogStack: [], | ||
} | ||
odi = toFilteredObservable(this.rootDialogInstance.get(match)); | ||
odi = toFilteredObservable(this.rootDialogInstance.get(message)); | ||
} | ||
konsole.log("runChildIfActive (active)", match); | ||
konsole.log("runChildIfActive (active)", message); | ||
@@ -213,3 +213,3 @@ return odi | ||
konsole.warn(`The stack references a dialog named "${dialogInstance.name}", which doesn't exist.`); | ||
return Observable.empty<RuleResult>(); | ||
return Observable.empty<Route>(); | ||
} | ||
@@ -219,18 +219,18 @@ | ||
if (dialogOrName && this.dialogize(dialogOrName) !== dialog) | ||
return Observable.empty<RuleResult>(); | ||
return Observable.empty<Route>(); | ||
return this.tryMatch(dialog, match as any, dialogInstance, dialogResponder as any); | ||
return this.tryMatch(dialog, message as any, dialogInstance, dialogResponder as any); | ||
}); | ||
} | ||
} as IRule<ANYMATCH>; | ||
} as IRouter<ANYMATCH>; | ||
} | ||
matchRootDialog(match: M): M & IDialogRootMatch<M> { | ||
matchRootDialog(message: M): M & IDialogRootMatch<M> { | ||
return { | ||
... match as any, | ||
... message as any, | ||
beginChildDialog: <DIALOGARGS extends object = any>(dialog: LocalOrRemoteDialog<M, DIALOGARGS> | string, dialogArgs?: DIALOGARGS) => | ||
this.activate(dialog, match, dialogArgs) | ||
.flatMap(dialogInstance => toObservable(this.rootDialogInstance.set(match, dialogInstance))) | ||
this.activate(dialog, message, dialogArgs) | ||
.flatMap(dialogInstance => toObservable(this.rootDialogInstance.set(message, dialogInstance))) | ||
.toPromise(), | ||
clearChildDialog: () => toObservable(this.rootDialogInstance.set(match)).toPromise() | ||
clearChildDialog: () => toObservable(this.rootDialogInstance.set(message)).toPromise() | ||
} | ||
@@ -259,4 +259,4 @@ } | ||
remoteName: string, | ||
init: (match: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>, | ||
rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | ||
init: (message: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>, | ||
router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | ||
): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
@@ -267,4 +267,4 @@ | ||
remoteable: boolean, | ||
init: (match: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>, | ||
rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | ||
init: (message: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>, | ||
router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | ||
): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
@@ -274,4 +274,4 @@ | ||
localName: string, | ||
init: (match: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>, | ||
rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | ||
init: (message: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>, | ||
router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | ||
): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
@@ -282,3 +282,3 @@ | ||
remoteName: string, | ||
rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | ||
router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | ||
): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
@@ -289,3 +289,3 @@ | ||
remoteable: boolean, | ||
rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | ||
router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | ||
): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
@@ -295,3 +295,3 @@ | ||
localName: string, | ||
rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | ||
router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | ||
): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
@@ -326,3 +326,3 @@ | ||
let init = () => ({}); | ||
let rule; | ||
let router; | ||
let dialogIndex = 2; | ||
@@ -340,12 +340,12 @@ | ||
if (args.length === dialogIndex + 2) { | ||
// init + rule | ||
// init + router | ||
init = args[dialogIndex]; | ||
rule = args[dialogIndex + 1]; | ||
} else if (args[dialogIndex].rule) { | ||
router = args[dialogIndex + 1]; | ||
} else if (args[dialogIndex].router) { | ||
// XDialog | ||
init = args[dialogIndex].init; | ||
rule = args[dialogIndex].rule; | ||
router = args[dialogIndex].router; | ||
} else { | ||
// just rule (use default init) | ||
rule = args[dialogIndex]; | ||
// just router (use default init) | ||
router = args[dialogIndex]; | ||
} | ||
@@ -357,3 +357,3 @@ | ||
init, | ||
rule: ruleize(rule), | ||
router: routerize(router), | ||
} | ||
@@ -398,3 +398,3 @@ } | ||
dialogOrName: LocalOrRemoteDialog<M, DIALOGARGS> | string, | ||
match: M, | ||
message: M, | ||
dialogArgs?: DIALOGARGS | ||
@@ -407,3 +407,3 @@ ): Observable<DialogInstance> { | ||
return toObservable(dialog.init({ | ||
... match as any, | ||
... message as any, | ||
dialogArgs | ||
@@ -413,4 +413,4 @@ })) | ||
} else { | ||
return toObservable(this.matchLocalToRemote(match as any)) // TYPE CHECK | ||
.flatMap(match => | ||
return toObservable(this.matchLocalToRemote(message as any)) // TYPE CHECK | ||
.flatMap(message => | ||
fetch( | ||
@@ -425,3 +425,3 @@ dialog.remoteUrl, | ||
args: dialogArgs, | ||
match | ||
message | ||
} as RemoteActivateRequest) | ||
@@ -439,3 +439,3 @@ } | ||
return toObservable(this.executeTasks(match as any, response.tasks)) // TYPE CHECK | ||
return toObservable(this.executeTasks(message as any, response.tasks)) // TYPE CHECK | ||
.map(_ => ({ | ||
@@ -460,6 +460,6 @@ name: dialog.localName, | ||
dialogOrName: LocalOrRemoteDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA> | string, | ||
match: M & IDialogMatch<DIALOGRESPONSE>, | ||
message: M & IDialogMatch<DIALOGRESPONSE>, | ||
dialogInstance: DialogInstance, | ||
dialogResponder: DialogResponder<M, DIALOGRESPONSE> | ||
) : Observable<RuleResult> { | ||
) : Observable<Route> { | ||
@@ -469,14 +469,14 @@ const dialog: LocalOrRemoteDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA> = this.dialogize(dialogOrName); | ||
if (isLocalDialog(dialog)) { | ||
konsole.log("tryMatch local", match); | ||
konsole.log("tryMatch local", message); | ||
return toObservable(this.localDialogInstances.getDialogData<DIALOGDATA>(dialogInstance)) | ||
.flatMap(dialogData => | ||
dialog.rule.tryMatch({ | ||
... match as any, | ||
dialog.router.getRoute({ | ||
... message as any, | ||
dialogData, | ||
dialogStack: [... match.dialogStack, dialogInstance], | ||
dialogStack: [... message.dialogStack, dialogInstance], | ||
beginChildDialog: <DIALOGARGS extends object = any>(dialogOrName: LocalOrRemoteDialog<M, DIALOGARGS> | string, dialogArgs?: DIALOGARGS) => | ||
this.activate(dialogOrName, match, dialogArgs) | ||
.do(dialogInstance => match.dialogData.childDialogInstance = dialogInstance) | ||
this.activate(dialogOrName, message, dialogArgs) | ||
.do(dialogInstance => message.dialogData.childDialogInstance = dialogInstance) | ||
.toPromise(), | ||
@@ -489,14 +489,14 @@ clearChildDialog: () => new Promise<void>((resolve) => { | ||
toObservable(dialogResponder({ | ||
... match as any, | ||
... message as any, | ||
dialogResponse | ||
})) | ||
.toPromise() | ||
.then(() => match.beginChildDialog(dialogOrName as any, dialogArgs)), // TYPE CHECK | ||
.then(() => message.beginChildDialog(dialogOrName as any, dialogArgs)), // TYPE CHECK | ||
endThisDialog: (dialogResponse?: DIALOGRESPONSE) => | ||
toObservable(dialogResponder({ | ||
... match as any, | ||
... message as any, | ||
dialogResponse | ||
})) | ||
.toPromise() | ||
.then(() => match.clearChildDialog()), | ||
.then(() => message.clearChildDialog()), | ||
}) | ||
@@ -507,9 +507,9 @@ .map(ruleResult => ({ | ||
.flatMap(_ => toObservable(this.localDialogInstances.setDialogData(dialogInstance, dialogData))) | ||
} as RuleResult)) | ||
} as Route)) | ||
) | ||
} else { | ||
konsole.log("tryMatch remote", match); | ||
return toObservable(this.matchLocalToRemote(match)) | ||
.do(match => konsole.log("matchLocalToRemote", match)) | ||
.flatMap(match => | ||
konsole.log("tryMatch remote", message); | ||
return toObservable(this.matchLocalToRemote(message)) | ||
.do(message => konsole.log("matchLocalToRemote", message)) | ||
.flatMap(message => | ||
fetch( | ||
@@ -524,3 +524,3 @@ dialog.remoteUrl, | ||
instance: dialogInstance.instance, | ||
match | ||
message | ||
}) | ||
@@ -531,3 +531,3 @@ } | ||
) | ||
.flatMap<RemoteTryMatchResponse, RuleResult>(response => { | ||
.flatMap<RemoteTryMatchResponse, Route>(response => { | ||
if (response.status === 'error') | ||
@@ -537,3 +537,3 @@ return Observable.throw(`RemoteDialog.tryMatch returned error "${response.error}".`); | ||
if (response.status === 'matchless') | ||
return Observable.empty<RuleResult>(); | ||
return Observable.empty<Route>(); | ||
@@ -544,4 +544,4 @@ if (response.status !== 'match') | ||
return Observable.of({ | ||
action: () => this.executeTasks(match, response.tasks, dialogResponder) | ||
} as RuleResult); | ||
action: () => this.executeTasks(message, response.tasks, dialogResponder) | ||
} as Route); | ||
}) | ||
@@ -572,13 +572,13 @@ } | ||
private matchLocalToRemote(match: M & IDialogMatch): any { | ||
private matchLocalToRemote(message: M & IDialogMatch): any { | ||
return { | ||
... this.remoteDialogProxy.matchLocalToRemote(match), | ||
dialogStack: match.dialogStack, | ||
... this.remoteDialogProxy.matchLocalToRemote(message), | ||
dialogStack: message.dialogStack, | ||
} | ||
} | ||
private matchRemoteToLocal(match: any, tasks: DialogTask[]) { | ||
private matchRemoteToLocal(message: any, tasks: DialogTask[]) { | ||
return { | ||
... this.remoteDialogProxy.matchRemoteToLocal(match, tasks) as any, | ||
dialogStack: match.dialogStack as DialogInstance[], | ||
... this.remoteDialogProxy.matchRemoteToLocal(message, tasks) as any, | ||
dialogStack: message.dialogStack as DialogInstance[], | ||
} as M & IDialogMatch | ||
@@ -588,3 +588,3 @@ } | ||
private executeTasks( | ||
match: M & IDialogRootMatch, | ||
message: M & IDialogRootMatch, | ||
tasks: DialogTask[], | ||
@@ -597,5 +597,5 @@ dialogResponder?: DialogResponder<M> | ||
case 'beginChildDialog': | ||
return match.beginChildDialog(task.args.name, task.args.args); | ||
return message.beginChildDialog(task.args.name, task.args.args); | ||
case 'clearChildDialog': | ||
return match.clearChildDialog(); | ||
return message.clearChildDialog(); | ||
case 'responder': | ||
@@ -606,3 +606,3 @@ return dialogResponder | ||
default: | ||
return toObservable(this.remoteDialogProxy.executeTask(match, task)); | ||
return toObservable(this.remoteDialogProxy.executeTask(message, task)); | ||
} | ||
@@ -615,3 +615,3 @@ }); | ||
const match: M & IDialogMatch = { | ||
const message: M & IDialogMatch = { | ||
... this.matchRemoteToLocal(remoteMatch, tasks) as any, | ||
@@ -641,9 +641,9 @@ beginChildDialog: (dialogOrName: LocalOrRemoteDialog<M> | string, dialogArgs?: any) => | ||
konsole.log("remoteTryMatch", match); | ||
konsole.log("remoteTryMatch", message); | ||
const dialogResponder = (match: M & IDialogResponderMatch) => { | ||
const dialogResponder = (message: M & IDialogResponderMatch) => { | ||
tasks.push({ | ||
method: 'responder', | ||
args: { | ||
response: match.dialogResponse | ||
response: message.dialogResponse | ||
} | ||
@@ -653,3 +653,3 @@ }) | ||
return this.tryMatch(name, match, { name, instance }, dialogResponder) | ||
return this.tryMatch(name, message, { name, instance }, dialogResponder) | ||
.do(ruleResult => konsole.log("ruleResult", ruleResult)) | ||
@@ -656,0 +656,0 @@ // add a sentinal value so that we can detect an empty sequence |
import { Observable } from 'rxjs'; | ||
import { ITextMatch } from './Text'; | ||
import { konsole } from './Konsole'; | ||
import { IRule, RuleResult, simpleRule, Handler, Match, Observableable, toFilteredObservable, ruleize } from './Rules'; | ||
import { IRouter, Route, simpleRouter, Handler, Observableable, toFilteredObservable, routerize } from './Rules'; | ||
import 'isomorphic-fetch'; | ||
@@ -39,4 +39,4 @@ | ||
export interface LuisRules<M> { | ||
[intent: string] : Handler<M & ILuisMatch> | IRule<M & ILuisMatch> | ||
export interface LuisRouters<M> { | ||
[intent: string] : Handler<M & ILuisMatch> | IRouter<M & ILuisMatch> | ||
} | ||
@@ -160,7 +160,7 @@ | ||
public match<M extends ITextMatch = any>(match: M) { | ||
return this.call(match.text) | ||
public match<M extends ITextMatch = any>(message: M) { | ||
return this.call(message.text) | ||
.filter(luisResponse => luisResponse.topScoringIntent.score >= this.scoreThreshold) | ||
.map(luisResponse => ({ | ||
... match as any, // remove "as any" when TypeScript fixes this bug | ||
... message as any, // remove "as any" when TypeScript fixes this bug | ||
luisResponse: { | ||
@@ -174,24 +174,8 @@ ... luisResponse, | ||
// "classic" LUIS usage - for a given model, say what to do with each intent above a given threshold | ||
// IMPORTANT: the order of rules is not important - the rule matching the *highest-ranked intent* will be executed | ||
// Note that: | ||
// luis.best( | ||
// luis.rule('intent1', handler1), | ||
// luis.rule('intent2', handler2) | ||
// ) | ||
// is just a more efficient (and concise) version of: | ||
// Rule.first( | ||
// new Rule(luis.model(), luis.intent('intent1'), handler1)), | ||
// new Rule(luis.model(), luis.intent('intent2'), handler2)) | ||
// ) | ||
// or: | ||
// Rule.first( | ||
// luis.rule('intent1', handler1), | ||
// luis.rule('intent2', handler2) | ||
// ).prependMatcher(luis.model()) | ||
// IMPORTANT: the order of rules is not important - the router matching the *highest-ranked intent* will be executed | ||
best<M extends Match & ITextMatch = any>(luisRules: LuisRules<M>) { | ||
best<M extends ITextMatch = any>(luisRouters: LuisRouters<M>) { | ||
return { | ||
tryMatch: (match: M) => | ||
toFilteredObservable(this.match(match)) | ||
getRoute: (message: M) => | ||
toFilteredObservable(this.match(message)) | ||
.flatMap(m => | ||
@@ -201,7 +185,7 @@ Observable.from(m.luisResponse.intents) | ||
luisIntent => | ||
Observable.of(luisRules[luisIntent.intent]) | ||
.filter(rule => !!rule) | ||
.flatMap(rule => | ||
ruleize(rule).tryMatch({ | ||
... match as any, | ||
Observable.of(luisRouters[luisIntent.intent]) | ||
.filter(router => !!router) | ||
.flatMap(router => | ||
routerize(router).getRoute({ | ||
... message as any, | ||
score: luisIntent.score, | ||
@@ -215,3 +199,3 @@ ... entityFields(m.luisResponse.entities), | ||
) | ||
} as IRule<M>; | ||
} as IRouter<M>; | ||
} | ||
@@ -218,0 +202,0 @@ |
import { konsole } from './Konsole'; | ||
import { IRule, Handler, Match, rule } from './Rules'; | ||
import { IRouter, Handler, router } from './Rules'; | ||
import { Observable } from 'rxjs'; | ||
@@ -11,6 +11,6 @@ import { ITextMatch } from './Text'; | ||
export const matchChoice = (choices: string[]) => | ||
<M extends Match & ITextMatch = any>(match: M) => { | ||
const choice = choices.find(choice => choice.toLowerCase() === match.text.toLowerCase()); | ||
<M extends ITextMatch = any>(message: M) => { | ||
const choice = choices.find(choice => choice.toLowerCase() === message.text.toLowerCase()); | ||
return choice && { | ||
... match as any, // remove "as any" when TypeScript fixes this bug | ||
... message as any, // remove "as any" when TypeScript fixes this bug | ||
choice | ||
@@ -20,14 +20,14 @@ } as M & IChatPromptChoiceMatch | ||
export const promptChoice = <M extends Match & ITextMatch = any>(choices: string[], ruleOrHandler: Handler<M & IChatPromptChoiceMatch> | IRule<M & IChatPromptChoiceMatch>) => { | ||
return rule(matchChoice(choices), ruleOrHandler) as IRule<M>; | ||
export const promptChoice = <M extends ITextMatch = any>(choices: string[], ruleOrHandler: Handler<M & IChatPromptChoiceMatch> | IRouter<M & IChatPromptChoiceMatch>) => { | ||
return router(matchChoice(choices), ruleOrHandler) as IRouter<M>; | ||
} | ||
export const matchConfirm = () => | ||
<M extends Match & ITextMatch = any>(match: M) => { | ||
const m = matchChoice(['Yes', 'No'])(match); | ||
return m.choice === 'Yes' && match; | ||
<M extends ITextMatch = any>(message: M) => { | ||
const m = matchChoice(['Yes', 'No'])(message); | ||
return m.choice === 'Yes' && message; | ||
} | ||
export const promptConfirm = <M extends Match & ITextMatch = any>(ruleOrHandler: Handler<M> | IRule<M>) => { | ||
return rule(matchConfirm(), ruleOrHandler) as IRule<M>; | ||
export const promptConfirm = <M extends ITextMatch = any>(ruleOrHandler: Handler<M> | IRouter<M>) => { | ||
return router(matchConfirm(), ruleOrHandler) as IRouter<M>; | ||
} |
import { Observable } from 'rxjs'; | ||
import { konsole } from './Konsole'; | ||
import { ITextMatch } from './Text'; | ||
import { Match, IRule, rule, Handler, arrayize } from './Rules'; | ||
import { IRouter, router, Handler, arrayize } from './Rules'; | ||
@@ -11,12 +11,12 @@ export interface IRegExpMatch { | ||
export const matchRegExp = (intents: RegExp | RegExp[]) => | ||
<M extends Match & ITextMatch = any>(match) => | ||
<M extends ITextMatch = any>(message: M) => | ||
Observable.from(arrayize(intents)) | ||
.do(_ => konsole.log("RegExp.match matching", match)) | ||
.map(regexp => regexp.exec(match.text)) | ||
.do(groups => konsole.log("RegExp.match result", groups)) | ||
.filter(groups => groups && groups[0] === match.text) | ||
.do(_ => konsole.log("matchRegExp matching", message)) | ||
.map(regexp => regexp.exec(message.text)) | ||
.do(groups => konsole.log("matchRegExp result", groups)) | ||
.filter(groups => groups && groups[0] === message.text) | ||
.take(1) | ||
.do(groups => konsole.log("RegExp.match returning", groups)) | ||
.do(groups => konsole.log("matchRegExp returning", groups)) | ||
.map(groups => ({ | ||
... match as any, // remove "as any" when TypeScript fixes this bug, | ||
... message as any, // remove "as any" when TypeScript fixes this bug, | ||
groups | ||
@@ -26,4 +26,3 @@ } as M & IRegExpMatch)); | ||
// Either call as re(intent, action) or re([intent, intent, ...], action) | ||
export const re = <M extends Match & ITextMatch = any>(intents: RegExp | RegExp[], ruleOrHandler: Handler<M & IRegExpMatch> | IRule<M & IRegExpMatch>) => { | ||
return rule(matchRegExp(intents), ruleOrHandler) as IRule<M>; | ||
} | ||
export const re = <M extends ITextMatch = any>(intents: RegExp | RegExp[], ruleOrHandler: Handler<M & IRegExpMatch> | IRouter<M & IRegExpMatch>) => | ||
router(matchRegExp(intents), ruleOrHandler) as IRouter<M>; |
import { konsole } from './Konsole'; | ||
import { Observable } from 'rxjs'; | ||
export type Observableable<T> = T | Observable<T> | Promise<T> | ||
export type Observableable<T> = T | Observable<T> | Promise<T>; | ||
export interface RuleResult { | ||
score?: number, | ||
action: () => Observableable<any> | ||
export interface Route { | ||
score?: number; | ||
action: () => Observableable<any>; | ||
} | ||
export interface Match { | ||
score?: number | ||
export interface IRouter<M extends object = any> { | ||
getRoute(message: M): Observable<Route>; | ||
} | ||
export interface IRule<M extends Match = any> { | ||
tryMatch(match: M): Observable<RuleResult>; | ||
} | ||
export type Matcher<A extends object = any, Z extends object = any> = (message: A) => Observableable<Z>; | ||
export type Matcher<A extends Match = any, Z extends Match = any> = (match: A) => Observableable<Z>; | ||
export type Handler<Z extends object = any> = (message: Z) => Observableable<any>; | ||
export type Handler<Z extends Match = any> = (match: Z) => Observableable<any>; | ||
export const arrayize = <T>(stuff: T | T[]) => Array.isArray(stuff) ? stuff : [stuff]; | ||
@@ -43,34 +39,34 @@ | ||
export function isRule<M>(r: IRule<M> | Handler<M>): r is IRule<M> { | ||
return ((r as any).tryMatch !== undefined); | ||
export function isRouter<M extends object = any>(r: IRouter<M> | Handler<M>): r is IRouter<M> { | ||
return ((r as any).getRoute !== undefined); | ||
} | ||
export const ruleize = <M extends Match = any>(r: IRule<M> | Handler<M>) => { | ||
return isRule(r) ? r : simpleRule(r); | ||
export const routerize = <M extends object = any>(r: IRouter<M> | Handler<M>) => { | ||
return isRouter(r) ? r : simpleRouter(r); | ||
} | ||
export const matchize = <M extends Match = any>(matcher: Matcher<M>, match: M) => { | ||
export const matchize = <M extends object = any>(matcher: Matcher<M>, message: M) => { | ||
// we want to allow any matcher to be a predicate (return a boolean) | ||
// if so, the 'falsey' case will be filtered out by toFilteredObservable, | ||
// so we just need to catch the case where it is precisely true | ||
return toFilteredObservable(matcher(match)) | ||
.map(m => typeof m === 'boolean' ? match : m); | ||
return toFilteredObservable(matcher(message)) | ||
.map(m => typeof m === 'boolean' ? message : m); | ||
} | ||
export const callActionIfMatch = <M extends Match = any>(match: M, rule: IRule<M>) => | ||
rule.tryMatch(match) | ||
.do(result => konsole.log("handle: matched a rule", result)) | ||
.flatMap(result => toObservable(result.action())) | ||
export const callActionIfMatch = <M extends object = any>(router: IRouter<M>, message: M) => | ||
router.getRoute(message) | ||
.do(route => konsole.log("handle: matched a route", route)) | ||
.flatMap(route => toObservable(route.action())) | ||
.do(_ => konsole.log("handle: called action")); | ||
export function combineMatchers<M extends Match = any, N extends Match = any>(m1: Matcher<M, N>): Matcher<M, N> | ||
export function combineMatchers<M extends Match = any, N extends Match = any, O extends Match = any>(m1: Matcher<M, N>, m2: Matcher<N, O>): Matcher<M, O> | ||
export function combineMatchers<M extends Match = any, N extends Match = any, O extends Match = any, P extends Match = any>(m1: Matcher<M, N>, m2: Matcher<N, O>, m3: Matcher<O, P>): Matcher<M, P> | ||
export function combineMatchers<M extends Match = any, N extends Match = any, O extends Match = any, P extends Match = any, Q extends Match = any>(m1: Matcher<M, N>, m2: Matcher<N, O>, m3: Matcher<O, P>, m4: Matcher<P, Q>): Matcher<M, Q> | ||
export function combineMatchers<M extends Match = any>(... matchers: Matcher[]): Matcher<M, any> | ||
export function combineMatchers<M extends Match = any>(... args: Matcher[]): Matcher<M, any> { | ||
export function combineMatchers<M extends object = any, N extends object = any>(m1: Matcher<M, N>): Matcher<M, N> | ||
export function combineMatchers<M extends object = any, N extends object = any, O extends object = any>(m1: Matcher<M, N>, m2: Matcher<N, O>): Matcher<M, O> | ||
export function combineMatchers<M extends object = any, N extends object = any, O extends object = any, P extends object = any>(m1: Matcher<M, N>, m2: Matcher<N, O>, m3: Matcher<O, P>): Matcher<M, P> | ||
export function combineMatchers<M extends object = any, N extends object = any, O extends object = any, P extends object = any, Q extends object = any>(m1: Matcher<M, N>, m2: Matcher<N, O>, m3: Matcher<O, P>, m4: Matcher<P, Q>): Matcher<M, Q> | ||
export function combineMatchers<M extends object = any>(... matchers: Matcher[]): Matcher<M, any> | ||
export function combineMatchers<M extends object = any>(... args: Matcher[]): Matcher<M, any> { | ||
konsole.log("combineMatchers", args); | ||
return match => | ||
return message => | ||
Observable.from(args) | ||
.reduce<Matcher, Observable<Match>>( | ||
.reduce<Matcher, Observable<any>>( | ||
(prevObservable, currentMatcher, i) => | ||
@@ -83,37 +79,35 @@ prevObservable | ||
}), | ||
Observable.of(match) | ||
) | ||
.flatMap(omatch => omatch); | ||
Observable.of(message) | ||
); | ||
} | ||
export const simpleRule = <M extends Match = any>(handler: Handler<M>) => ({ | ||
tryMatch: (match: M) => Observable.of({ | ||
score: match.score, | ||
action: () => handler(match) | ||
} as RuleResult) | ||
}) as IRule<M>; | ||
export const simpleRouter = <M extends object = any>(handler: Handler<M>) => ({ | ||
getRoute: (message: M) => Observable.of({ | ||
action: () => handler(message) | ||
} as Route) | ||
}) as IRouter<M>; | ||
const filteredRule$ = <M extends Match = any>(... rules: (IRule<M> | Handler<M>)[]) => | ||
Observable.from(rules) | ||
.filter(rule => !!rule) | ||
.map(rule => ruleize(rule)); | ||
const filteredRouter$ = <M extends object = any>(... routers: (IRouter<M> | Handler<M>)[]) => | ||
Observable.from(routers) | ||
.filter(router => !!router) | ||
.map(router => routerize(router)); | ||
export const first = <M extends Match = any>(... rules: (IRule<M> | Handler<M>)[]) => { | ||
const rule$ = filteredRule$(... rules); | ||
export const first = <M extends object = any>(... routers: (IRouter<M> | Handler<M>)[]) => { | ||
const router = filteredRouter$(... routers); | ||
return { | ||
tryMatch: (match: M) => | ||
rule$.flatMap( | ||
(rule, i) => { | ||
konsole.log(`Rule.first: trying rule #${i}`); | ||
return rule.tryMatch(match) | ||
.do(m => konsole.log(`Rule.first: rule #${i} succeeded`, m)); | ||
getRoute: (message: M) => | ||
router.flatMap( | ||
(router, i) => { | ||
konsole.log(`first: trying router #${i}`); | ||
return router.getRoute(message) | ||
.do(m => konsole.log(`first: router #${i} succeeded`, m)); | ||
}, | ||
1 | ||
) | ||
.take(1) // so that we don't keep going through rules after we find one that matches | ||
} as IRule<M>; | ||
.take(1) // so that we don't keep going through routers after we find one that matches | ||
} as IRouter<M>; | ||
} | ||
const minRuleResult: RuleResult = { | ||
const minRoute: Route = { | ||
score: 0, | ||
@@ -123,12 +117,12 @@ action: () => console.log("This should never be called") | ||
export const best = <M extends Match = any>(... rules: (IRule<M> | Handler<M>)[]) => { | ||
const rule$ = filteredRule$(... rules); | ||
export const best = <M extends object = any>(... routers: (IRouter<M> | Handler<M>)[]) => { | ||
const router = filteredRouter$(... routers); | ||
return { | ||
tryMatch: (match: M) => | ||
rule$.flatMap( | ||
(rule, i) => { | ||
konsole.log(`Rule.best: trying rule #${i}`); | ||
return rule.tryMatch(match) | ||
.do(m => konsole.log(`Rule.best: rule #${i} succeeded`, m)); | ||
getRoute: (message: M) => | ||
router.flatMap( | ||
(router, i) => { | ||
konsole.log(`best: trying router #${i}`); | ||
return router.getRoute(message) | ||
.do(m => konsole.log(`best: router #${i} succeeded`, m)); | ||
} | ||
@@ -138,64 +132,50 @@ ) | ||
(prev, current) => Math.min(prev.score === undefined ? 1 : prev.score) > Math.min(current.score === undefined ? 1 : current.score) ? prev : current, | ||
minRuleResult | ||
minRoute | ||
) | ||
// .takeWhile(ruleResult => ruleResult.score && ruleResult.score < 1) | ||
} as IRule<M>; | ||
} as IRouter<M>; | ||
} | ||
export const prependMatcher = <L extends Match = any, M extends Match = any>(matcher: Matcher<L, M>, rule: IRule<M>) => ({ | ||
tryMatch: (match: L) => | ||
matchize(matcher, match) | ||
.flatMap((m: M) => rule.tryMatch(m)) | ||
} as IRule<L>); | ||
export const prependMatcher = <L extends object = any, M extends object = any>(matcher: Matcher<L, M>, router: IRouter<M>) => ({ | ||
getRoute: (message: L) => | ||
matchize(matcher, message) | ||
.flatMap((m: M) => router.getRoute(m)) | ||
} as IRouter<L>); | ||
export const run = <M extends Match = any>(handler: Handler<M>) => ({ | ||
tryMatch: (match: M) => | ||
toObservable(handler(match)) | ||
export const run = <M extends object = any>(handler: Handler<M>) => ({ | ||
getRoute: (message: M) => | ||
toObservable(handler(message)) | ||
.map(_ => null) | ||
} as IRule<M>); | ||
} as IRouter<M>); | ||
// These are left over from previous versions of the API and need to be updated to the latest hotness | ||
// export const everyMatch$ = <S>(rule$: Observable<Rule<S>>, scoreThreshold = 0) => (input) => | ||
// rule$ | ||
// .do(_ => konsole.log("everyMatch$: trying rule")) | ||
// .flatMap(rule => observize(rule(input))) | ||
// .reduce((prev, current) => (current.score || 1) < scoreThreshold ? prev : { | ||
// action: prev | ||
// ? () => observize(prev.action()).flatMap(_ => observize(current.action())) | ||
// : () => current.action() | ||
// } | ||
// ); | ||
export interface Predicate<M extends Match = any> { | ||
(match: M): Observableable<boolean>; | ||
export interface Predicate<M extends object = any> { | ||
(message: M): Observableable<boolean>; | ||
} | ||
export function rule<M extends Match = any>(handler: Handler<M> | IRule<M>): IRule<M> | ||
export function router<M extends object = any>(handler: Handler<M> | IRouter<M>): IRouter<M> | ||
export function rule<M extends Match = any>(p1: Predicate<M>, handler: Handler<M> | IRule<M>): IRule<M> | ||
export function rule<M extends Match = any, Z extends Match = any>(m1: Matcher<M, Z>, handler: Handler<Z> | IRule<Z>): IRule<M> | ||
export function router<M extends object = any>(p1: Predicate<M>, handler: Handler<M> | IRouter<M>): IRouter<M> | ||
export function router<M extends object = any, Z extends object = any>(m1: Matcher<M, Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M> | ||
export function rule<M extends Match = any, Z extends Match = any>(p1: Predicate<M>, m2: Matcher<M, Z>, handler: Handler<Z> | IRule<Z>): IRule<M> | ||
export function rule<M extends Match = any, Z extends Match = any>(m1: Matcher<M, Z>, p2: Predicate<Z>, handler: Handler<Z> | IRule<Z>): IRule<M> | ||
export function rule<M extends Match = any, N extends Match = any, Z extends Match = any>(m1: Matcher<M, N>, m2: Matcher<N, Z>, handler: Handler<Z> | IRule<Z>): IRule<M> | ||
export function router<M extends object = any, Z extends object = any>(p1: Predicate<M>, m2: Matcher<M, Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M> | ||
export function router<M extends object = any, Z extends object = any>(m1: Matcher<M, Z>, p2: Predicate<Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M> | ||
export function router<M extends object = any, N extends object = any, Z extends object = any>(m1: Matcher<M, N>, m2: Matcher<N, Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M> | ||
export function rule<M extends Match = any, Z extends Match = any>(m1: Matcher<M, Z>, p2: Predicate<Z>, p3: Predicate<Z>, handler: Handler<Z> | IRule<Z>): IRule<M> | ||
export function rule<M extends Match = any, Z extends Match = any>(p1: Matcher<M>, m2: Matcher<M, Z>, p3: Predicate<Z>, handler: Handler<Z> | IRule<Z>): IRule<M> | ||
export function rule<M extends Match = any, Z extends Match = any>(p1: Predicate<M>, p2: Predicate<M>, m3: Matcher<M, Z>, handler: Handler<Z> | IRule<Z>): IRule<M> | ||
export function rule<M extends Match = any, N extends Match = any, Z extends Match = any>(p1: Predicate<M>, m2: Matcher<M, N>, m3: Matcher<N, Z>, handler: Handler<Z> | IRule<Z>): IRule<M> | ||
export function rule<M extends Match = any, N extends Match = any, Z extends Match = any>(m1: Matcher<M, N>, p2: Predicate<N>, m3: Matcher<N, Z>, handler: Handler<Z> | IRule<Z>): IRule<M> | ||
export function rule<M extends Match = any, N extends Match = any, Z extends Match = any>(m1: Matcher<M, N>, m2: Matcher<N, Z>, p3: Predicate<Z>, handler: Handler<Z> | IRule<Z>): IRule<M> | ||
export function rule<M extends Match = any, N extends Match = any, O extends Match = any, Z extends Match = any>(m1: Matcher<M, N>, m2: Matcher<N, O>, m3: Matcher<O, Z>, handler: Handler<Z> | IRule<Z>): IRule<M> | ||
export function router<M extends object = any, Z extends object = any>(m1: Matcher<M, Z>, p2: Predicate<Z>, p3: Predicate<Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M> | ||
export function router<M extends object = any, Z extends object = any>(p1: Matcher<M>, m2: Matcher<M, Z>, p3: Predicate<Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M> | ||
export function router<M extends object = any, Z extends object = any>(p1: Predicate<M>, p2: Predicate<M>, m3: Matcher<M, Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M> | ||
export function router<M extends object = any, N extends object = any, Z extends object = any>(p1: Predicate<M>, m2: Matcher<M, N>, m3: Matcher<N, Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M> | ||
export function router<M extends object = any, N extends object = any, Z extends object = any>(m1: Matcher<M, N>, p2: Predicate<N>, m3: Matcher<N, Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M> | ||
export function router<M extends object = any, N extends object = any, Z extends object = any>(m1: Matcher<M, N>, m2: Matcher<N, Z>, p3: Predicate<Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M> | ||
export function router<M extends object = any, N extends object = any, O extends object = any, Z extends object = any>(m1: Matcher<M, N>, m2: Matcher<N, O>, m3: Matcher<O, Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M> | ||
export function rule<M extends Match = any>(... args: (Predicate | Matcher | Handler | IRule)[]): IRule<M> { | ||
const ruleOrHandler = ruleize(args[args.length - 1] as Handler | IRule); | ||
export function router<M extends object = any>(... args: (Predicate | Matcher | Handler | IRouter)[]): IRouter<M> { | ||
const routerOrHandler = routerize(args[args.length - 1] as Handler | IRouter); | ||
switch (args.length) { | ||
case 1: | ||
return ruleOrHandler; | ||
return routerOrHandler; | ||
case 2: | ||
return prependMatcher(args[0] as Matcher, ruleOrHandler); | ||
return prependMatcher(args[0] as Matcher, routerOrHandler); | ||
default: | ||
return prependMatcher(combineMatchers(... args.slice(0, args.length - 1) as Matcher[]), ruleOrHandler); | ||
return prependMatcher(combineMatchers(... args.slice(0, args.length - 1) as Matcher[]), routerOrHandler); | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import { Match, IRule, Handler, Observableable } from './Rules'; | ||
import { IRouter, Handler, Observableable } from './Rules'; | ||
import { Observable } from 'rxjs'; | ||
@@ -7,6 +7,6 @@ export interface DialogInstance { | ||
} | ||
export interface DialogRegistry<M extends Match = any> { | ||
export interface DialogRegistry<M extends object = any> { | ||
[name: string]: LocalOrRemoteDialog<M>; | ||
} | ||
export interface IDialogRootMatch<M extends Match = any> { | ||
export interface IDialogRootMatch<M extends object = any> { | ||
beginChildDialog<DIALOGARGS extends object = any>(dialogOrName: LocalOrRemoteDialog<M, DIALOGARGS> | string, dialogArgs?: DIALOGARGS): Promise<void>; | ||
@@ -18,3 +18,3 @@ clearChildDialog(): Promise<void>; | ||
}; | ||
export interface IDialogMatch<M extends Match = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any> extends IDialogRootMatch<M> { | ||
export interface IDialogMatch<M extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any> extends IDialogRootMatch<M> { | ||
dialogData: IDialogData<DIALOGDATA>; | ||
@@ -28,4 +28,4 @@ dialogStack: DialogInstance[]; | ||
} | ||
export interface DialogResponder<M extends Match = any, DIALOGRESPONSE extends object = any> { | ||
(match: M & IDialogResponderMatch<DIALOGRESPONSE>): Observableable<void>; | ||
export interface DialogResponder<M extends object = any, DIALOGRESPONSE extends object = any> { | ||
(message: M & IDialogResponderMatch<DIALOGRESPONSE>): Observableable<void>; | ||
} | ||
@@ -35,13 +35,13 @@ export interface IDialogResponderMatch<DIALOGRESPONSE extends object = object> { | ||
} | ||
export interface XDialog<M extends Match = any, DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any> { | ||
init?: (match: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>; | ||
rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>; | ||
export interface XDialog<M extends object = any, DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any> { | ||
init?: (message: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>; | ||
router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>; | ||
} | ||
export interface LocalDialog<M extends Match = any, DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any> { | ||
export interface LocalDialog<M extends object = any, DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any> { | ||
localName: string; | ||
remoteName?: string; | ||
init: (match: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>; | ||
rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>; | ||
init: (message: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>; | ||
router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>; | ||
} | ||
export interface RemoteDialog<M extends Match = any, DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any> { | ||
export interface RemoteDialog<M extends object = any, DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any> { | ||
remoteUrl: string; | ||
@@ -51,8 +51,8 @@ localName: string; | ||
} | ||
export declare type LocalOrRemoteDialog<M extends Match = any, DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any> = LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA> | RemoteDialog<M, DIALOGARGS, DIALOGRESPONSE>; | ||
export declare type LocalOrRemoteDialog<M extends object = any, DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any> = LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA> | RemoteDialog<M, DIALOGARGS, DIALOGRESPONSE>; | ||
export interface RootDialogInstance { | ||
get: (match: any) => Observableable<DialogInstance>; | ||
set: (match: any, rootDialogInstance?: DialogInstance) => Observableable<void>; | ||
get: (message: any) => Observableable<DialogInstance>; | ||
set: (message: any, rootDialogInstance?: DialogInstance) => Observableable<void>; | ||
} | ||
export interface DialogResponders<M extends Match = any> { | ||
export interface DialogResponders<M extends object = any> { | ||
[name: string]: DialogResponder<M>; | ||
@@ -70,6 +70,6 @@ } | ||
} | ||
export interface RemoteDialogProxy<M extends Match = any> { | ||
matchLocalToRemote?: (match: M) => Observableable<any>; | ||
matchRemoteToLocal?: (match: any, tasks: DialogTask[]) => Observableable<M>; | ||
executeTask?: (match: M, tasks: DialogTask) => Observableable<any>; | ||
export interface RemoteDialogProxy<M extends object = any> { | ||
matchLocalToRemote?: (message: M) => Observableable<any>; | ||
matchRemoteToLocal?: (message: any, tasks: DialogTask[]) => Observableable<M>; | ||
executeTask?: (message: M, tasks: DialogTask) => Observableable<any>; | ||
} | ||
@@ -79,3 +79,3 @@ export interface RemoteActivateRequest { | ||
name: string; | ||
match: any; | ||
message: any; | ||
args: any; | ||
@@ -95,3 +95,3 @@ } | ||
instance: string; | ||
match: any; | ||
message: any; | ||
} | ||
@@ -109,3 +109,3 @@ export declare type RemoteTryMatchResponse = { | ||
export declare type RemoteResponse = RemoteActivateResponse | RemoteTryMatchResponse; | ||
export declare class Dialogs<M extends Match = any> { | ||
export declare class Dialogs<M extends object = any> { | ||
private rootDialogInstance; | ||
@@ -116,13 +116,13 @@ private localDialogInstances; | ||
constructor(rootDialogInstance: RootDialogInstance, localDialogInstances: LocalDialogInstances, remoteDialogProxy: RemoteDialogProxy<M>); | ||
runChildIfActive<ANYMATCH extends Match = M, DIALOGRESPONSE extends object = any>(dialogOrName?: LocalOrRemoteDialog<M, any, DIALOGRESPONSE> | string, dialogResponder?: DialogResponder<ANYMATCH, DIALOGRESPONSE>): IRule<ANYMATCH>; | ||
matchRootDialog(match: M): M & IDialogRootMatch<M>; | ||
runChildIfActive<ANYMATCH extends object = M, DIALOGRESPONSE extends object = any>(dialogOrName?: LocalOrRemoteDialog<M, any, DIALOGRESPONSE> | string, dialogResponder?: DialogResponder<ANYMATCH, DIALOGRESPONSE>): IRouter<ANYMATCH>; | ||
matchRootDialog(message: M): M & IDialogRootMatch<M>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any>(localName: string, remoteName: string, dialog: XDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any>(localName: string, remoteable: boolean, dialog: XDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any>(localName: string, dialog: XDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any>(localName: string, remoteName: string, init: (match: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>, rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any>(localName: string, remoteable: boolean, init: (match: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>, rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any>(localName: string, init: (match: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>, rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any>(localName: string, remoteName: string, rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any>(localName: string, remoteable: boolean, rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any>(localName: string, rule: IRule<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any>(localName: string, remoteName: string, init: (message: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>, router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any>(localName: string, remoteable: boolean, init: (message: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>, router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any>(localName: string, init: (message: M & IDialogArgsMatch<DIALOGARGS>) => Observableable<DIALOGDATA>, router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any>(localName: string, remoteName: string, router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any>(localName: string, remoteable: boolean, router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any, DIALOGDATA extends object = any>(localName: string, router: IRouter<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>> | Handler<M & IDialogMatch<M, DIALOGRESPONSE, DIALOGDATA>>): LocalDialog<M, DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>; | ||
add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any>(localName: string, remoteUrl: string): RemoteDialog<M, DIALOGARGS, DIALOGRESPONSE>; | ||
@@ -132,9 +132,9 @@ add<DIALOGARGS extends object = any, DIALOGRESPONSE extends object = any>(localName: string, remoteUrl: string, remoteName: string): RemoteDialog<M, DIALOGARGS, DIALOGRESPONSE>; | ||
private nameize(dialogOrName); | ||
private activate<DIALOGARGS>(dialogOrName, match, dialogArgs?); | ||
private tryMatch<DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>(dialogOrName, match, dialogInstance, dialogResponder); | ||
private activate<DIALOGARGS>(dialogOrName, message, dialogArgs?); | ||
private tryMatch<DIALOGARGS, DIALOGRESPONSE, DIALOGDATA>(dialogOrName, message, dialogInstance, dialogResponder); | ||
remoteActivate(name: string, remoteMatch: any, dialogArgs: any): Observable<RemoteActivateResponse>; | ||
private matchLocalToRemote(match); | ||
private matchRemoteToLocal(match, tasks); | ||
private executeTasks(match, tasks, dialogResponder?); | ||
private matchLocalToRemote(message); | ||
private matchRemoteToLocal(message, tasks); | ||
private executeTasks(message, tasks, dialogResponder?); | ||
remoteTryMatch(name: string, instance: string, remoteMatch: any): Observable<RemoteTryMatchResponse>; | ||
} |
@@ -15,3 +15,3 @@ "use strict"; | ||
var isLocalDialog = function (localOrRemoteDialog) { | ||
return localOrRemoteDialog.rule !== undefined; | ||
return localOrRemoteDialog.router !== undefined; | ||
}; | ||
@@ -29,16 +29,16 @@ var Dialogs = (function () { | ||
return { | ||
tryMatch: function (match) { | ||
Konsole_1.konsole.log("runChildIfActive", match); | ||
getRoute: function (message) { | ||
Konsole_1.konsole.log("runChildIfActive", message); | ||
var odi; | ||
if (match.dialogStack) { | ||
if (!match.dialogData.childDialogInstance) | ||
if (message.dialogStack) { | ||
if (!message.dialogData.childDialogInstance) | ||
return; | ||
odi = rxjs_1.Observable.of(match.dialogData.childDialogInstance); | ||
odi = rxjs_1.Observable.of(message.dialogData.childDialogInstance); | ||
} | ||
else { | ||
// This is being run from the "root" (a non-dialog rule) | ||
match = __assign({}, match, { dialogStack: [] }); | ||
odi = Rules_1.toFilteredObservable(_this.rootDialogInstance.get(match)); | ||
// This is being run from the "root" (a non-dialog router) | ||
message = __assign({}, message, { dialogStack: [] }); | ||
odi = Rules_1.toFilteredObservable(_this.rootDialogInstance.get(message)); | ||
} | ||
Konsole_1.konsole.log("runChildIfActive (active)", match); | ||
Konsole_1.konsole.log("runChildIfActive (active)", message); | ||
return odi | ||
@@ -54,3 +54,3 @@ .flatMap(function (dialogInstance) { | ||
return rxjs_1.Observable.empty(); | ||
return _this.tryMatch(dialog, match, dialogInstance, dialogResponder); | ||
return _this.tryMatch(dialog, message, dialogInstance, dialogResponder); | ||
}); | ||
@@ -60,9 +60,9 @@ } | ||
}; | ||
Dialogs.prototype.matchRootDialog = function (match) { | ||
Dialogs.prototype.matchRootDialog = function (message) { | ||
var _this = this; | ||
return __assign({}, match, { beginChildDialog: function (dialog, dialogArgs) { | ||
return _this.activate(dialog, match, dialogArgs) | ||
.flatMap(function (dialogInstance) { return Rules_1.toObservable(_this.rootDialogInstance.set(match, dialogInstance)); }) | ||
return __assign({}, message, { beginChildDialog: function (dialog, dialogArgs) { | ||
return _this.activate(dialog, message, dialogArgs) | ||
.flatMap(function (dialogInstance) { return Rules_1.toObservable(_this.rootDialogInstance.set(message, dialogInstance)); }) | ||
.toPromise(); | ||
}, clearChildDialog: function () { return Rules_1.toObservable(_this.rootDialogInstance.set(match)).toPromise(); } }); | ||
}, clearChildDialog: function () { return Rules_1.toObservable(_this.rootDialogInstance.set(message)).toPromise(); } }); | ||
}; | ||
@@ -88,3 +88,3 @@ Dialogs.prototype.add = function () { | ||
var init = function () { return ({}); }; | ||
var rule = void 0; | ||
var router = void 0; | ||
var dialogIndex = 2; | ||
@@ -102,14 +102,14 @@ if (typeof args[1] === 'string') { | ||
if (args.length === dialogIndex + 2) { | ||
// init + rule | ||
// init + router | ||
init = args[dialogIndex]; | ||
rule = args[dialogIndex + 1]; | ||
router = args[dialogIndex + 1]; | ||
} | ||
else if (args[dialogIndex].rule) { | ||
else if (args[dialogIndex].router) { | ||
// XDialog | ||
init = args[dialogIndex].init; | ||
rule = args[dialogIndex].rule; | ||
router = args[dialogIndex].router; | ||
} | ||
else { | ||
// just rule (use default init) | ||
rule = args[dialogIndex]; | ||
// just router (use default init) | ||
router = args[dialogIndex]; | ||
} | ||
@@ -120,3 +120,3 @@ dialog = { | ||
init: init, | ||
rule: Rules_1.ruleize(rule), | ||
router: Rules_1.routerize(router), | ||
}; | ||
@@ -148,12 +148,12 @@ } | ||
// * by remote proxy, to activate local dialog | ||
Dialogs.prototype.activate = function (dialogOrName, match, dialogArgs) { | ||
Dialogs.prototype.activate = function (dialogOrName, message, dialogArgs) { | ||
var _this = this; | ||
var dialog = this.dialogize(dialogOrName); | ||
if (isLocalDialog(dialog)) { | ||
return Rules_1.toObservable(dialog.init(__assign({}, match, { dialogArgs: dialogArgs }))) | ||
return Rules_1.toObservable(dialog.init(__assign({}, message, { dialogArgs: dialogArgs }))) | ||
.flatMap(function (dialogData) { return Rules_1.toObservable(_this.localDialogInstances.newInstance(dialog.localName, dialogData)); }); | ||
} | ||
else { | ||
return Rules_1.toObservable(this.matchLocalToRemote(match)) // TYPE CHECK | ||
.flatMap(function (match) { | ||
return Rules_1.toObservable(this.matchLocalToRemote(message)) // TYPE CHECK | ||
.flatMap(function (message) { | ||
return fetch(dialog.remoteUrl, { | ||
@@ -166,3 +166,3 @@ method: 'POST', | ||
args: dialogArgs, | ||
match: match | ||
message: message | ||
}) | ||
@@ -177,3 +177,3 @@ }) | ||
return rxjs_1.Observable.throw("RemoteDialog.activate returned unexpected status \"" + response.status + "\"."); | ||
return Rules_1.toObservable(_this.executeTasks(match, response.tasks)) // TYPE CHECK | ||
return Rules_1.toObservable(_this.executeTasks(message, response.tasks)) // TYPE CHECK | ||
.map(function (_) { return ({ | ||
@@ -190,12 +190,12 @@ name: dialog.localName, | ||
// * by remote proxy, to run local dialog | ||
Dialogs.prototype.tryMatch = function (dialogOrName, match, dialogInstance, dialogResponder) { | ||
Dialogs.prototype.tryMatch = function (dialogOrName, message, dialogInstance, dialogResponder) { | ||
var _this = this; | ||
var dialog = this.dialogize(dialogOrName); | ||
if (isLocalDialog(dialog)) { | ||
Konsole_1.konsole.log("tryMatch local", match); | ||
Konsole_1.konsole.log("tryMatch local", message); | ||
return Rules_1.toObservable(this.localDialogInstances.getDialogData(dialogInstance)) | ||
.flatMap(function (dialogData) { | ||
return dialog.rule.tryMatch(__assign({}, match, { dialogData: dialogData, dialogStack: match.dialogStack.concat([dialogInstance]), beginChildDialog: function (dialogOrName, dialogArgs) { | ||
return _this.activate(dialogOrName, match, dialogArgs) | ||
.do(function (dialogInstance) { return match.dialogData.childDialogInstance = dialogInstance; }) | ||
return dialog.router.getRoute(__assign({}, message, { dialogData: dialogData, dialogStack: message.dialogStack.concat([dialogInstance]), beginChildDialog: function (dialogOrName, dialogArgs) { | ||
return _this.activate(dialogOrName, message, dialogArgs) | ||
.do(function (dialogInstance) { return message.dialogData.childDialogInstance = dialogInstance; }) | ||
.toPromise(); | ||
@@ -206,9 +206,9 @@ }, clearChildDialog: function () { return new Promise(function (resolve) { | ||
}); }, replaceThisDialog: function (dialogOrName, dialogArgs, dialogResponse) { | ||
return Rules_1.toObservable(dialogResponder(__assign({}, match, { dialogResponse: dialogResponse }))) | ||
return Rules_1.toObservable(dialogResponder(__assign({}, message, { dialogResponse: dialogResponse }))) | ||
.toPromise() | ||
.then(function () { return match.beginChildDialog(dialogOrName, dialogArgs); }); | ||
.then(function () { return message.beginChildDialog(dialogOrName, dialogArgs); }); | ||
}, endThisDialog: function (dialogResponse) { | ||
return Rules_1.toObservable(dialogResponder(__assign({}, match, { dialogResponse: dialogResponse }))) | ||
return Rules_1.toObservable(dialogResponder(__assign({}, message, { dialogResponse: dialogResponse }))) | ||
.toPromise() | ||
.then(function () { return match.clearChildDialog(); }); | ||
.then(function () { return message.clearChildDialog(); }); | ||
} })) | ||
@@ -220,6 +220,6 @@ .map(function (ruleResult) { return (__assign({}, ruleResult, { action: function () { return Rules_1.toObservable(ruleResult.action()) | ||
else { | ||
Konsole_1.konsole.log("tryMatch remote", match); | ||
return Rules_1.toObservable(this.matchLocalToRemote(match)) | ||
.do(function (match) { return Konsole_1.konsole.log("matchLocalToRemote", match); }) | ||
.flatMap(function (match) { | ||
Konsole_1.konsole.log("tryMatch remote", message); | ||
return Rules_1.toObservable(this.matchLocalToRemote(message)) | ||
.do(function (message) { return Konsole_1.konsole.log("matchLocalToRemote", message); }) | ||
.flatMap(function (message) { | ||
return fetch(dialog.remoteUrl, { | ||
@@ -232,3 +232,3 @@ method: 'POST', | ||
instance: dialogInstance.instance, | ||
match: match | ||
message: message | ||
}) | ||
@@ -246,3 +246,3 @@ }) | ||
return rxjs_1.Observable.of({ | ||
action: function () { return _this.executeTasks(match, response.tasks, dialogResponder); } | ||
action: function () { return _this.executeTasks(message, response.tasks, dialogResponder); } | ||
}); | ||
@@ -266,9 +266,9 @@ }); | ||
}; | ||
Dialogs.prototype.matchLocalToRemote = function (match) { | ||
return __assign({}, this.remoteDialogProxy.matchLocalToRemote(match), { dialogStack: match.dialogStack }); | ||
Dialogs.prototype.matchLocalToRemote = function (message) { | ||
return __assign({}, this.remoteDialogProxy.matchLocalToRemote(message), { dialogStack: message.dialogStack }); | ||
}; | ||
Dialogs.prototype.matchRemoteToLocal = function (match, tasks) { | ||
return __assign({}, this.remoteDialogProxy.matchRemoteToLocal(match, tasks), { dialogStack: match.dialogStack }); | ||
Dialogs.prototype.matchRemoteToLocal = function (message, tasks) { | ||
return __assign({}, this.remoteDialogProxy.matchRemoteToLocal(message, tasks), { dialogStack: message.dialogStack }); | ||
}; | ||
Dialogs.prototype.executeTasks = function (match, tasks, dialogResponder) { | ||
Dialogs.prototype.executeTasks = function (message, tasks, dialogResponder) { | ||
var _this = this; | ||
@@ -279,5 +279,5 @@ return rxjs_1.Observable.from(tasks) | ||
case 'beginChildDialog': | ||
return match.beginChildDialog(task.args.name, task.args.args); | ||
return message.beginChildDialog(task.args.name, task.args.args); | ||
case 'clearChildDialog': | ||
return match.clearChildDialog(); | ||
return message.clearChildDialog(); | ||
case 'responder': | ||
@@ -288,3 +288,3 @@ return dialogResponder | ||
default: | ||
return Rules_1.toObservable(_this.remoteDialogProxy.executeTask(match, task)); | ||
return Rules_1.toObservable(_this.remoteDialogProxy.executeTask(message, task)); | ||
} | ||
@@ -296,3 +296,3 @@ }); | ||
var tasks = []; | ||
var match = __assign({}, this.matchRemoteToLocal(remoteMatch, tasks), { beginChildDialog: function (dialogOrName, dialogArgs) { | ||
var message = __assign({}, this.matchRemoteToLocal(remoteMatch, tasks), { beginChildDialog: function (dialogOrName, dialogArgs) { | ||
// will only be called by replaceThisDialog | ||
@@ -318,12 +318,12 @@ return new Promise(function (resolve) { | ||
} }); | ||
Konsole_1.konsole.log("remoteTryMatch", match); | ||
var dialogResponder = function (match) { | ||
Konsole_1.konsole.log("remoteTryMatch", message); | ||
var dialogResponder = function (message) { | ||
tasks.push({ | ||
method: 'responder', | ||
args: { | ||
response: match.dialogResponse | ||
response: message.dialogResponse | ||
} | ||
}); | ||
}; | ||
return this.tryMatch(name, match, { name: name, instance: instance }, dialogResponder) | ||
return this.tryMatch(name, message, { name: name, instance: instance }, dialogResponder) | ||
.do(function (ruleResult) { return Konsole_1.konsole.log("ruleResult", ruleResult); }) | ||
@@ -330,0 +330,0 @@ .concat(rxjs_1.Observable.of(-1)) |
import { Observable } from 'rxjs'; | ||
import { ITextMatch } from './Text'; | ||
import { IRule, Handler, Match } from './Rules'; | ||
import { IRouter, Handler } from './Rules'; | ||
import 'isomorphic-fetch'; | ||
@@ -27,4 +27,4 @@ export interface LuisIntent { | ||
} | ||
export interface LuisRules<M> { | ||
[intent: string]: Handler<M & ILuisMatch> | IRule<M & ILuisMatch>; | ||
export interface LuisRouters<M> { | ||
[intent: string]: Handler<M & ILuisMatch> | IRouter<M & ILuisMatch>; | ||
} | ||
@@ -38,8 +38,8 @@ export declare class LuisModel { | ||
call(utterance: string): Observable<LuisResponse>; | ||
match<M extends ITextMatch = any>(match: M): Observable<M & { | ||
match<M extends ITextMatch = any>(message: M): Observable<M & { | ||
luisResponse: LuisResponse; | ||
}>; | ||
best<M extends Match & ITextMatch = any>(luisRules: LuisRules<M>): IRule<M>; | ||
best<M extends ITextMatch = any>(luisRouters: LuisRouters<M>): IRouter<M>; | ||
static findEntity(entities: LuisEntity[], type: string): LuisEntity[]; | ||
static entityValues(entities: LuisEntity[], type: string): string[]; | ||
} |
@@ -123,38 +123,22 @@ "use strict"; | ||
}; | ||
LuisModel.prototype.match = function (match) { | ||
LuisModel.prototype.match = function (message) { | ||
var _this = this; | ||
return this.call(match.text) | ||
return this.call(message.text) | ||
.filter(function (luisResponse) { return luisResponse.topScoringIntent.score >= _this.scoreThreshold; }) | ||
.map(function (luisResponse) { return (__assign({}, match, { luisResponse: __assign({}, luisResponse, { intents: (luisResponse.intents || luisResponse.topScoringIntent && [luisResponse.topScoringIntent]) | ||
.map(function (luisResponse) { return (__assign({}, message, { luisResponse: __assign({}, luisResponse, { intents: (luisResponse.intents || luisResponse.topScoringIntent && [luisResponse.topScoringIntent]) | ||
.filter(function (luisIntent) { return luisIntent.score >= _this.scoreThreshold; }) }) })); }); | ||
}; | ||
// "classic" LUIS usage - for a given model, say what to do with each intent above a given threshold | ||
// IMPORTANT: the order of rules is not important - the rule matching the *highest-ranked intent* will be executed | ||
// Note that: | ||
// luis.best( | ||
// luis.rule('intent1', handler1), | ||
// luis.rule('intent2', handler2) | ||
// ) | ||
// is just a more efficient (and concise) version of: | ||
// Rule.first( | ||
// new Rule(luis.model(), luis.intent('intent1'), handler1)), | ||
// new Rule(luis.model(), luis.intent('intent2'), handler2)) | ||
// ) | ||
// or: | ||
// Rule.first( | ||
// luis.rule('intent1', handler1), | ||
// luis.rule('intent2', handler2) | ||
// ).prependMatcher(luis.model()) | ||
LuisModel.prototype.best = function (luisRules) { | ||
// IMPORTANT: the order of rules is not important - the router matching the *highest-ranked intent* will be executed | ||
LuisModel.prototype.best = function (luisRouters) { | ||
var _this = this; | ||
return { | ||
tryMatch: function (match) { | ||
return Rules_1.toFilteredObservable(_this.match(match)) | ||
getRoute: function (message) { | ||
return Rules_1.toFilteredObservable(_this.match(message)) | ||
.flatMap(function (m) { | ||
return rxjs_1.Observable.from(m.luisResponse.intents) | ||
.flatMap(function (luisIntent) { | ||
return rxjs_1.Observable.of(luisRules[luisIntent.intent]) | ||
.filter(function (rule) { return !!rule; }) | ||
.flatMap(function (rule) { | ||
return Rules_1.ruleize(rule).tryMatch(__assign({}, match, { score: luisIntent.score }, entityFields(m.luisResponse.entities))); | ||
return rxjs_1.Observable.of(luisRouters[luisIntent.intent]) | ||
.filter(function (router) { return !!router; }) | ||
.flatMap(function (router) { | ||
return Rules_1.routerize(router).getRoute(__assign({}, message, { score: luisIntent.score }, entityFields(m.luisResponse.entities))); | ||
}); | ||
@@ -161,0 +145,0 @@ }, 1) |
@@ -1,2 +0,2 @@ | ||
import { IRule, Handler, Match } from './Rules'; | ||
import { IRouter, Handler } from './Rules'; | ||
import { ITextMatch } from './Text'; | ||
@@ -6,5 +6,5 @@ export interface IChatPromptChoiceMatch { | ||
} | ||
export declare const matchChoice: (choices: string[]) => <M extends Match & ITextMatch = any>(match: M) => M & IChatPromptChoiceMatch; | ||
export declare const promptChoice: <M extends Match & ITextMatch = any>(choices: string[], ruleOrHandler: Handler<M & IChatPromptChoiceMatch> | IRule<M & IChatPromptChoiceMatch>) => IRule<M>; | ||
export declare const matchConfirm: () => <M extends Match & ITextMatch = any>(match: M) => M; | ||
export declare const promptConfirm: <M extends Match & ITextMatch = any>(ruleOrHandler: Handler<M> | IRule<M>) => IRule<M>; | ||
export declare const matchChoice: (choices: string[]) => <M extends ITextMatch = any>(message: M) => M & IChatPromptChoiceMatch; | ||
export declare const promptChoice: <M extends ITextMatch = any>(choices: string[], ruleOrHandler: Handler<M & IChatPromptChoiceMatch> | IRouter<M & IChatPromptChoiceMatch>) => IRouter<M>; | ||
export declare const matchConfirm: () => <M extends ITextMatch = any>(message: M) => M; | ||
export declare const promptConfirm: <M extends ITextMatch = any>(ruleOrHandler: Handler<M> | IRouter<M>) => IRouter<M>; |
@@ -13,5 +13,5 @@ "use strict"; | ||
exports.matchChoice = function (choices) { | ||
return function (match) { | ||
var choice = choices.find(function (choice) { return choice.toLowerCase() === match.text.toLowerCase(); }); | ||
return choice && __assign({}, match, { // remove "as any" when TypeScript fixes this bug | ||
return function (message) { | ||
var choice = choices.find(function (choice) { return choice.toLowerCase() === message.text.toLowerCase(); }); | ||
return choice && __assign({}, message, { // remove "as any" when TypeScript fixes this bug | ||
choice: choice }); | ||
@@ -21,13 +21,13 @@ }; | ||
exports.promptChoice = function (choices, ruleOrHandler) { | ||
return Rules_1.rule(exports.matchChoice(choices), ruleOrHandler); | ||
return Rules_1.router(exports.matchChoice(choices), ruleOrHandler); | ||
}; | ||
exports.matchConfirm = function () { | ||
return function (match) { | ||
var m = exports.matchChoice(['Yes', 'No'])(match); | ||
return m.choice === 'Yes' && match; | ||
return function (message) { | ||
var m = exports.matchChoice(['Yes', 'No'])(message); | ||
return m.choice === 'Yes' && message; | ||
}; | ||
}; | ||
exports.promptConfirm = function (ruleOrHandler) { | ||
return Rules_1.rule(exports.matchConfirm(), ruleOrHandler); | ||
return Rules_1.router(exports.matchConfirm(), ruleOrHandler); | ||
}; | ||
//# sourceMappingURL=Prompt.js.map |
import { Observable } from 'rxjs'; | ||
import { ITextMatch } from './Text'; | ||
import { Match, IRule, Handler } from './Rules'; | ||
import { IRouter, Handler } from './Rules'; | ||
export interface IRegExpMatch { | ||
groups: RegExpExecArray; | ||
} | ||
export declare const matchRegExp: (intents: RegExp | RegExp[]) => <M extends Match & ITextMatch = any>(match: any) => Observable<M & IRegExpMatch>; | ||
export declare const re: <M extends Match & ITextMatch = any>(intents: RegExp | RegExp[], ruleOrHandler: Handler<M & IRegExpMatch> | IRule<M & IRegExpMatch>) => IRule<M>; | ||
export declare const matchRegExp: (intents: RegExp | RegExp[]) => <M extends ITextMatch = any>(message: M) => Observable<M & IRegExpMatch>; | ||
export declare const re: <M extends ITextMatch = any>(intents: RegExp | RegExp[], ruleOrHandler: Handler<M & IRegExpMatch> | IRouter<M & IRegExpMatch>) => IRouter<M>; |
@@ -15,11 +15,11 @@ "use strict"; | ||
exports.matchRegExp = function (intents) { | ||
return function (match) { | ||
return function (message) { | ||
return rxjs_1.Observable.from(Rules_1.arrayize(intents)) | ||
.do(function (_) { return Konsole_1.konsole.log("RegExp.match matching", match); }) | ||
.map(function (regexp) { return regexp.exec(match.text); }) | ||
.do(function (groups) { return Konsole_1.konsole.log("RegExp.match result", groups); }) | ||
.filter(function (groups) { return groups && groups[0] === match.text; }) | ||
.do(function (_) { return Konsole_1.konsole.log("matchRegExp matching", message); }) | ||
.map(function (regexp) { return regexp.exec(message.text); }) | ||
.do(function (groups) { return Konsole_1.konsole.log("matchRegExp result", groups); }) | ||
.filter(function (groups) { return groups && groups[0] === message.text; }) | ||
.take(1) | ||
.do(function (groups) { return Konsole_1.konsole.log("RegExp.match returning", groups); }) | ||
.map(function (groups) { return (__assign({}, match, { // remove "as any" when TypeScript fixes this bug, | ||
.do(function (groups) { return Konsole_1.konsole.log("matchRegExp returning", groups); }) | ||
.map(function (groups) { return (__assign({}, message, { // remove "as any" when TypeScript fixes this bug, | ||
groups: groups })); }); | ||
@@ -30,4 +30,4 @@ }; | ||
exports.re = function (intents, ruleOrHandler) { | ||
return Rules_1.rule(exports.matchRegExp(intents), ruleOrHandler); | ||
return Rules_1.router(exports.matchRegExp(intents), ruleOrHandler); | ||
}; | ||
//# sourceMappingURL=RegExp.js.map |
import { Observable } from 'rxjs'; | ||
export declare type Observableable<T> = T | Observable<T> | Promise<T>; | ||
export interface RuleResult { | ||
export interface Route { | ||
score?: number; | ||
action: () => Observableable<any>; | ||
} | ||
export interface Match { | ||
score?: number; | ||
export interface IRouter<M extends object = any> { | ||
getRoute(message: M): Observable<Route>; | ||
} | ||
export interface IRule<M extends Match = any> { | ||
tryMatch(match: M): Observable<RuleResult>; | ||
} | ||
export declare type Matcher<A extends Match = any, Z extends Match = any> = (match: A) => Observableable<Z>; | ||
export declare type Handler<Z extends Match = any> = (match: Z) => Observableable<any>; | ||
export declare type Matcher<A extends object = any, Z extends object = any> = (message: A) => Observableable<Z>; | ||
export declare type Handler<Z extends object = any> = (message: Z) => Observableable<any>; | ||
export declare const arrayize: <T>(stuff: T | T[]) => T[]; | ||
export declare const toFilteredObservable: <T>(t: Observableable<T>) => Observable<T>; | ||
export declare const toObservable: <T>(t: Observableable<T>) => Observable<T>; | ||
export declare function isRule<M>(r: IRule<M> | Handler<M>): r is IRule<M>; | ||
export declare const ruleize: <M extends Match = any>(r: IRule<M> | Handler<M>) => IRule<M>; | ||
export declare const matchize: <M extends Match = any>(matcher: Matcher<M, any>, match: M) => Observable<any>; | ||
export declare const callActionIfMatch: <M extends Match = any>(match: M, rule: IRule<M>) => Observable<any>; | ||
export declare function combineMatchers<M extends Match = any, N extends Match = any>(m1: Matcher<M, N>): Matcher<M, N>; | ||
export declare function combineMatchers<M extends Match = any, N extends Match = any, O extends Match = any>(m1: Matcher<M, N>, m2: Matcher<N, O>): Matcher<M, O>; | ||
export declare function combineMatchers<M extends Match = any, N extends Match = any, O extends Match = any, P extends Match = any>(m1: Matcher<M, N>, m2: Matcher<N, O>, m3: Matcher<O, P>): Matcher<M, P>; | ||
export declare function combineMatchers<M extends Match = any, N extends Match = any, O extends Match = any, P extends Match = any, Q extends Match = any>(m1: Matcher<M, N>, m2: Matcher<N, O>, m3: Matcher<O, P>, m4: Matcher<P, Q>): Matcher<M, Q>; | ||
export declare function combineMatchers<M extends Match = any>(...matchers: Matcher[]): Matcher<M, any>; | ||
export declare const simpleRule: <M extends Match = any>(handler: Handler<M>) => IRule<M>; | ||
export declare const first: <M extends Match = any>(...rules: (IRule<M> | Handler<M>)[]) => IRule<M>; | ||
export declare const best: <M extends Match = any>(...rules: (IRule<M> | Handler<M>)[]) => IRule<M>; | ||
export declare const prependMatcher: <L extends Match = any, M extends Match = any>(matcher: Matcher<L, M>, rule: IRule<M>) => IRule<L>; | ||
export declare const run: <M extends Match = any>(handler: Handler<M>) => IRule<M>; | ||
export interface Predicate<M extends Match = any> { | ||
(match: M): Observableable<boolean>; | ||
export declare function isRouter<M extends object = any>(r: IRouter<M> | Handler<M>): r is IRouter<M>; | ||
export declare const routerize: <M extends object = any>(r: IRouter<M> | Handler<M>) => IRouter<M>; | ||
export declare const matchize: <M extends object = any>(matcher: Matcher<M, any>, message: M) => Observable<any>; | ||
export declare const callActionIfMatch: <M extends object = any>(router: IRouter<M>, message: M) => Observable<any>; | ||
export declare function combineMatchers<M extends object = any, N extends object = any>(m1: Matcher<M, N>): Matcher<M, N>; | ||
export declare function combineMatchers<M extends object = any, N extends object = any, O extends object = any>(m1: Matcher<M, N>, m2: Matcher<N, O>): Matcher<M, O>; | ||
export declare function combineMatchers<M extends object = any, N extends object = any, O extends object = any, P extends object = any>(m1: Matcher<M, N>, m2: Matcher<N, O>, m3: Matcher<O, P>): Matcher<M, P>; | ||
export declare function combineMatchers<M extends object = any, N extends object = any, O extends object = any, P extends object = any, Q extends object = any>(m1: Matcher<M, N>, m2: Matcher<N, O>, m3: Matcher<O, P>, m4: Matcher<P, Q>): Matcher<M, Q>; | ||
export declare function combineMatchers<M extends object = any>(...matchers: Matcher[]): Matcher<M, any>; | ||
export declare const simpleRouter: <M extends object = any>(handler: Handler<M>) => IRouter<M>; | ||
export declare const first: <M extends object = any>(...routers: (IRouter<M> | Handler<M>)[]) => IRouter<M>; | ||
export declare const best: <M extends object = any>(...routers: (IRouter<M> | Handler<M>)[]) => IRouter<M>; | ||
export declare const prependMatcher: <L extends object = any, M extends object = any>(matcher: Matcher<L, M>, router: IRouter<M>) => IRouter<L>; | ||
export declare const run: <M extends object = any>(handler: Handler<M>) => IRouter<M>; | ||
export interface Predicate<M extends object = any> { | ||
(message: M): Observableable<boolean>; | ||
} | ||
export declare function rule<M extends Match = any>(handler: Handler<M> | IRule<M>): IRule<M>; | ||
export declare function rule<M extends Match = any>(p1: Predicate<M>, handler: Handler<M> | IRule<M>): IRule<M>; | ||
export declare function rule<M extends Match = any, Z extends Match = any>(m1: Matcher<M, Z>, handler: Handler<Z> | IRule<Z>): IRule<M>; | ||
export declare function rule<M extends Match = any, Z extends Match = any>(p1: Predicate<M>, m2: Matcher<M, Z>, handler: Handler<Z> | IRule<Z>): IRule<M>; | ||
export declare function rule<M extends Match = any, Z extends Match = any>(m1: Matcher<M, Z>, p2: Predicate<Z>, handler: Handler<Z> | IRule<Z>): IRule<M>; | ||
export declare function rule<M extends Match = any, N extends Match = any, Z extends Match = any>(m1: Matcher<M, N>, m2: Matcher<N, Z>, handler: Handler<Z> | IRule<Z>): IRule<M>; | ||
export declare function rule<M extends Match = any, Z extends Match = any>(m1: Matcher<M, Z>, p2: Predicate<Z>, p3: Predicate<Z>, handler: Handler<Z> | IRule<Z>): IRule<M>; | ||
export declare function rule<M extends Match = any, Z extends Match = any>(p1: Matcher<M>, m2: Matcher<M, Z>, p3: Predicate<Z>, handler: Handler<Z> | IRule<Z>): IRule<M>; | ||
export declare function rule<M extends Match = any, Z extends Match = any>(p1: Predicate<M>, p2: Predicate<M>, m3: Matcher<M, Z>, handler: Handler<Z> | IRule<Z>): IRule<M>; | ||
export declare function rule<M extends Match = any, N extends Match = any, Z extends Match = any>(p1: Predicate<M>, m2: Matcher<M, N>, m3: Matcher<N, Z>, handler: Handler<Z> | IRule<Z>): IRule<M>; | ||
export declare function rule<M extends Match = any, N extends Match = any, Z extends Match = any>(m1: Matcher<M, N>, p2: Predicate<N>, m3: Matcher<N, Z>, handler: Handler<Z> | IRule<Z>): IRule<M>; | ||
export declare function rule<M extends Match = any, N extends Match = any, Z extends Match = any>(m1: Matcher<M, N>, m2: Matcher<N, Z>, p3: Predicate<Z>, handler: Handler<Z> | IRule<Z>): IRule<M>; | ||
export declare function rule<M extends Match = any, N extends Match = any, O extends Match = any, Z extends Match = any>(m1: Matcher<M, N>, m2: Matcher<N, O>, m3: Matcher<O, Z>, handler: Handler<Z> | IRule<Z>): IRule<M>; | ||
export declare function router<M extends object = any>(handler: Handler<M> | IRouter<M>): IRouter<M>; | ||
export declare function router<M extends object = any>(p1: Predicate<M>, handler: Handler<M> | IRouter<M>): IRouter<M>; | ||
export declare function router<M extends object = any, Z extends object = any>(m1: Matcher<M, Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M>; | ||
export declare function router<M extends object = any, Z extends object = any>(p1: Predicate<M>, m2: Matcher<M, Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M>; | ||
export declare function router<M extends object = any, Z extends object = any>(m1: Matcher<M, Z>, p2: Predicate<Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M>; | ||
export declare function router<M extends object = any, N extends object = any, Z extends object = any>(m1: Matcher<M, N>, m2: Matcher<N, Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M>; | ||
export declare function router<M extends object = any, Z extends object = any>(m1: Matcher<M, Z>, p2: Predicate<Z>, p3: Predicate<Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M>; | ||
export declare function router<M extends object = any, Z extends object = any>(p1: Matcher<M>, m2: Matcher<M, Z>, p3: Predicate<Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M>; | ||
export declare function router<M extends object = any, Z extends object = any>(p1: Predicate<M>, p2: Predicate<M>, m3: Matcher<M, Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M>; | ||
export declare function router<M extends object = any, N extends object = any, Z extends object = any>(p1: Predicate<M>, m2: Matcher<M, N>, m3: Matcher<N, Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M>; | ||
export declare function router<M extends object = any, N extends object = any, Z extends object = any>(m1: Matcher<M, N>, p2: Predicate<N>, m3: Matcher<N, Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M>; | ||
export declare function router<M extends object = any, N extends object = any, Z extends object = any>(m1: Matcher<M, N>, m2: Matcher<N, Z>, p3: Predicate<Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M>; | ||
export declare function router<M extends object = any, N extends object = any, O extends object = any, Z extends object = any>(m1: Matcher<M, N>, m2: Matcher<N, O>, m3: Matcher<O, Z>, handler: Handler<Z> | IRouter<Z>): IRouter<M>; |
@@ -22,20 +22,20 @@ "use strict"; | ||
}; | ||
function isRule(r) { | ||
return (r.tryMatch !== undefined); | ||
function isRouter(r) { | ||
return (r.getRoute !== undefined); | ||
} | ||
exports.isRule = isRule; | ||
exports.ruleize = function (r) { | ||
return isRule(r) ? r : exports.simpleRule(r); | ||
exports.isRouter = isRouter; | ||
exports.routerize = function (r) { | ||
return isRouter(r) ? r : exports.simpleRouter(r); | ||
}; | ||
exports.matchize = function (matcher, match) { | ||
exports.matchize = function (matcher, message) { | ||
// we want to allow any matcher to be a predicate (return a boolean) | ||
// if so, the 'falsey' case will be filtered out by toFilteredObservable, | ||
// so we just need to catch the case where it is precisely true | ||
return exports.toFilteredObservable(matcher(match)) | ||
.map(function (m) { return typeof m === 'boolean' ? match : m; }); | ||
return exports.toFilteredObservable(matcher(message)) | ||
.map(function (m) { return typeof m === 'boolean' ? message : m; }); | ||
}; | ||
exports.callActionIfMatch = function (match, rule) { | ||
return rule.tryMatch(match) | ||
.do(function (result) { return Konsole_1.konsole.log("handle: matched a rule", result); }) | ||
.flatMap(function (result) { return exports.toObservable(result.action()); }) | ||
exports.callActionIfMatch = function (router, message) { | ||
return router.getRoute(message) | ||
.do(function (route) { return Konsole_1.konsole.log("handle: matched a route", route); }) | ||
.flatMap(function (route) { return exports.toObservable(route.action()); }) | ||
.do(function (_) { return Konsole_1.konsole.log("handle: called action"); }); | ||
@@ -49,3 +49,3 @@ }; | ||
Konsole_1.konsole.log("combineMatchers", args); | ||
return function (match) { | ||
return function (message) { | ||
return rxjs_1.Observable.from(args) | ||
@@ -59,40 +59,38 @@ .reduce(function (prevObservable, currentMatcher, i) { | ||
}); | ||
}, rxjs_1.Observable.of(match)) | ||
.flatMap(function (omatch) { return omatch; }); | ||
}, rxjs_1.Observable.of(message)); | ||
}; | ||
} | ||
exports.combineMatchers = combineMatchers; | ||
exports.simpleRule = function (handler) { return ({ | ||
tryMatch: function (match) { return rxjs_1.Observable.of({ | ||
score: match.score, | ||
action: function () { return handler(match); } | ||
exports.simpleRouter = function (handler) { return ({ | ||
getRoute: function (message) { return rxjs_1.Observable.of({ | ||
action: function () { return handler(message); } | ||
}); } | ||
}); }; | ||
var filteredRule$ = function () { | ||
var rules = []; | ||
var filteredRouter$ = function () { | ||
var routers = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
rules[_i] = arguments[_i]; | ||
routers[_i] = arguments[_i]; | ||
} | ||
return rxjs_1.Observable.from(rules) | ||
.filter(function (rule) { return !!rule; }) | ||
.map(function (rule) { return exports.ruleize(rule); }); | ||
return rxjs_1.Observable.from(routers) | ||
.filter(function (router) { return !!router; }) | ||
.map(function (router) { return exports.routerize(router); }); | ||
}; | ||
exports.first = function () { | ||
var rules = []; | ||
var routers = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
rules[_i] = arguments[_i]; | ||
routers[_i] = arguments[_i]; | ||
} | ||
var rule$ = filteredRule$.apply(void 0, rules); | ||
var router = filteredRouter$.apply(void 0, routers); | ||
return { | ||
tryMatch: function (match) { | ||
return rule$.flatMap(function (rule, i) { | ||
Konsole_1.konsole.log("Rule.first: trying rule #" + i); | ||
return rule.tryMatch(match) | ||
.do(function (m) { return Konsole_1.konsole.log("Rule.first: rule #" + i + " succeeded", m); }); | ||
getRoute: function (message) { | ||
return router.flatMap(function (router, i) { | ||
Konsole_1.konsole.log("first: trying router #" + i); | ||
return router.getRoute(message) | ||
.do(function (m) { return Konsole_1.konsole.log("first: router #" + i + " succeeded", m); }); | ||
}, 1) | ||
.take(1); | ||
} // so that we don't keep going through rules after we find one that matches | ||
} // so that we don't keep going through routers after we find one that matches | ||
}; | ||
}; | ||
var minRuleResult = { | ||
var minRoute = { | ||
score: 0, | ||
@@ -102,32 +100,31 @@ action: function () { return console.log("This should never be called"); } | ||
exports.best = function () { | ||
var rules = []; | ||
var routers = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
rules[_i] = arguments[_i]; | ||
routers[_i] = arguments[_i]; | ||
} | ||
var rule$ = filteredRule$.apply(void 0, rules); | ||
var router = filteredRouter$.apply(void 0, routers); | ||
return { | ||
tryMatch: function (match) { | ||
return rule$.flatMap(function (rule, i) { | ||
Konsole_1.konsole.log("Rule.best: trying rule #" + i); | ||
return rule.tryMatch(match) | ||
.do(function (m) { return Konsole_1.konsole.log("Rule.best: rule #" + i + " succeeded", m); }); | ||
getRoute: function (message) { | ||
return router.flatMap(function (router, i) { | ||
Konsole_1.konsole.log("best: trying router #" + i); | ||
return router.getRoute(message) | ||
.do(function (m) { return Konsole_1.konsole.log("best: router #" + i + " succeeded", m); }); | ||
}) | ||
.reduce(function (prev, current) { return Math.min(prev.score === undefined ? 1 : prev.score) > Math.min(current.score === undefined ? 1 : current.score) ? prev : current; }, minRuleResult); | ||
.reduce(function (prev, current) { return Math.min(prev.score === undefined ? 1 : prev.score) > Math.min(current.score === undefined ? 1 : current.score) ? prev : current; }, minRoute); | ||
} | ||
// .takeWhile(ruleResult => ruleResult.score && ruleResult.score < 1) | ||
}; | ||
}; | ||
exports.prependMatcher = function (matcher, rule) { return ({ | ||
tryMatch: function (match) { | ||
return exports.matchize(matcher, match) | ||
.flatMap(function (m) { return rule.tryMatch(m); }); | ||
exports.prependMatcher = function (matcher, router) { return ({ | ||
getRoute: function (message) { | ||
return exports.matchize(matcher, message) | ||
.flatMap(function (m) { return router.getRoute(m); }); | ||
} | ||
}); }; | ||
exports.run = function (handler) { return ({ | ||
tryMatch: function (match) { | ||
return exports.toObservable(handler(match)) | ||
getRoute: function (message) { | ||
return exports.toObservable(handler(message)) | ||
.map(function (_) { return null; }); | ||
} | ||
}); }; | ||
function rule() { | ||
function router() { | ||
var args = []; | ||
@@ -137,13 +134,13 @@ for (var _i = 0; _i < arguments.length; _i++) { | ||
} | ||
var ruleOrHandler = exports.ruleize(args[args.length - 1]); | ||
var routerOrHandler = exports.routerize(args[args.length - 1]); | ||
switch (args.length) { | ||
case 1: | ||
return ruleOrHandler; | ||
return routerOrHandler; | ||
case 2: | ||
return exports.prependMatcher(args[0], ruleOrHandler); | ||
return exports.prependMatcher(args[0], routerOrHandler); | ||
default: | ||
return exports.prependMatcher(combineMatchers.apply(void 0, args.slice(0, args.length - 1)), ruleOrHandler); | ||
return exports.prependMatcher(combineMatchers.apply(void 0, args.slice(0, args.length - 1)), routerOrHandler); | ||
} | ||
} | ||
exports.rule = rule; | ||
exports.router = router; | ||
//# sourceMappingURL=Rules.js.map |
@@ -7,3 +7,3 @@ { | ||
}, | ||
"version": "0.8.0", | ||
"version": "0.9.0", | ||
"description": "rules-based app engine", | ||
@@ -21,3 +21,3 @@ "main": "dist/prague.js", | ||
"@types/node": "^7.0.31", | ||
"typescript": "^2.4.0-dev.20170610" | ||
"typescript": "2.4.0" | ||
}, | ||
@@ -24,0 +24,0 @@ "dependencies": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
136365
1973