Comparing version 0.21.1 to 0.21.2
@@ -15,10 +15,10 @@ import { Observable } from 'rxjs'; | ||
} | ||
export declare class Match<VALUE> extends Result { | ||
export declare class Value<VALUE> extends Result { | ||
value: VALUE; | ||
constructor(value: VALUE, score?: number); | ||
} | ||
declare type NormalizedResult<R> = R extends undefined | null ? never : R extends Result ? R : R extends () => any ? Action : Match<R>; | ||
declare type NormalizedResult<R> = R extends never | undefined | null ? never : R extends Result ? R : R extends () => any ? Action : Value<R>; | ||
export declare type Norm<R> = NormalizedResult<BaseType<R>>; | ||
export declare type Transform<ARGS extends any[], RESULT extends Result> = (...args: ARGS) => Observable<RESULT>; | ||
export declare function from<ARGS extends any[], R>(transform?: null | ((...args: ARGS) => R)): Transform<ARGS, Norm<R>>; | ||
export declare function from<ARGS extends any[] = [], R = never>(transform?: null | ((...args: ARGS) => R)): Transform<ARGS, Norm<R>>; | ||
export {}; |
@@ -34,3 +34,3 @@ "use strict"; | ||
exports.Action = Action; | ||
class Match extends Result { | ||
class Value extends Result { | ||
constructor(value, score) { | ||
@@ -41,7 +41,7 @@ super(score); | ||
} | ||
exports.Match = Match; | ||
const none = () => rxjs_1.empty(); | ||
exports.Value = Value; | ||
const returnsEmpty = () => rxjs_1.empty(); | ||
function from(transform) { | ||
if (!transform) | ||
return none; | ||
return returnsEmpty; | ||
if (typeof transform !== 'function') | ||
@@ -51,5 +51,5 @@ throw new Error("I can't transform that."); | ||
typeof result === 'function' ? new Action(result) : | ||
new Match(result)))); | ||
new Value(result)))); | ||
} | ||
exports.from = from; | ||
//# sourceMappingURL=core.js.map |
import { Result, Transform, Norm } from "./prague"; | ||
export declare function first<ARGS extends any[], R0>(...args: [(...args: ARGS) => R0]): Transform<ARGS, Norm<R0>>; | ||
export declare function first<ARGS extends any[], R0, R1>(...args: [(...args: ARGS) => R0, (...args: ARGS) => R1]): Transform<ARGS, Norm<R0 | R1>>; | ||
export declare function first<ARGS extends any[], R0, R1, R2>(...args: [(...args: ARGS) => R0, (...args: ARGS) => R1, (...args: ARGS) => R2]): Transform<ARGS, Norm<R0 | R1 | R2>>; | ||
export declare function first<ARGS extends any[], R0, R1, R2, R3>(...args: [(...args: ARGS) => R0, (...args: ARGS) => R1, (...args: ARGS) => R2, (...args: ARGS) => R3]): Transform<ARGS, Norm<R0 | R1 | R2 | R3>>; | ||
export declare function first<ARGS extends any[], R0, R1, R2, R3, R4>(...args: [(...args: ARGS) => R0, (...args: ARGS) => R1, (...args: ARGS) => R2, (...args: ARGS) => R3, (...args: ARGS) => R4]): Transform<ARGS, Norm<R0 | R1 | R2 | R3 | R4>>; | ||
export declare function first<ARGS extends any[]>(...args: ((...args: ARGS) => any)[]): Transform<ARGS, Result>; | ||
export declare function first(): Transform<[], never>; | ||
export declare function first<ARGS extends any[] = [], R0 = never>(...args: [null | undefined | ((...args: ARGS) => R0)]): Transform<ARGS, Norm<R0>>; | ||
export declare function first<ARGS extends any[] = [], R0 = never, R1 = never>(...args: [null | undefined | ((...args: ARGS) => R0), null | undefined | ((...args: ARGS) => R1)]): Transform<ARGS, Norm<R0 | R1>>; | ||
export declare function first<ARGS extends any[] = [], R0 = never, R1 = never, R2 = never>(...args: [null | undefined | ((...args: ARGS) => R0), null | undefined | ((...args: ARGS) => R1), null | undefined | ((...args: ARGS) => R2)]): Transform<ARGS, Norm<R0 | R1 | R2>>; | ||
export declare function first<ARGS extends any[] = [], R0 = never, R1 = never, R2 = never, R3 = never>(...args: [null | undefined | ((...args: ARGS) => R0), null | undefined | ((...args: ARGS) => R1), null | undefined | ((...args: ARGS) => R2), null | undefined | ((...args: ARGS) => R3)]): Transform<ARGS, Norm<R0 | R1 | R2 | R3>>; | ||
export declare function first<ARGS extends any[] = [], R0 = never, R1 = never, R2 = never, R3 = never, R4 = never>(...args: [null | undefined | ((...args: ARGS) => R0), null | undefined | ((...args: ARGS) => R1), null | undefined | ((...args: ARGS) => R2), null | undefined | ((...args: ARGS) => R3), null | undefined | ((...args: ARGS) => R4)]): Transform<ARGS, Norm<R0 | R1 | R2 | R3 | R4>>; | ||
export declare function first<ARGS extends any[] = []>(...args: (null | undefined | ((...args: ARGS) => any))[]): Transform<ARGS, Result>; |
@@ -1,4 +0,4 @@ | ||
import { Observableable, Match } from './prague'; | ||
export declare function match<ARGS extends any[], VALUE, ONMATCH, ONNOMATCH>(getMatch: (...args: ARGS) => Observableable<null | undefined | VALUE | Match<VALUE>>, onMatch: (match: Match<VALUE>) => ONMATCH, onNoMatch?: () => ONNOMATCH): import("./core").Transform<ARGS, import("./core").Result | ((import("./core").BaseType<ONNOMATCH> extends null | undefined ? never : import("./core").BaseType<ONNOMATCH> extends import("./core").Result ? import("./core").BaseType<ONNOMATCH> : import("./core").BaseType<ONNOMATCH> extends () => any ? import("./core").Action : Match<import("./core").BaseType<ONNOMATCH>>) extends null | undefined ? never : (import("./core").BaseType<ONNOMATCH> extends null | undefined ? never : import("./core").BaseType<ONNOMATCH> extends import("./core").Result ? import("./core").BaseType<ONNOMATCH> : import("./core").BaseType<ONNOMATCH> extends () => any ? import("./core").Action : Match<import("./core").BaseType<ONNOMATCH>>) extends import("./core").Result ? import("./core").BaseType<ONNOMATCH> extends null | undefined ? never : import("./core").BaseType<ONNOMATCH> extends import("./core").Result ? import("./core").BaseType<ONNOMATCH> : import("./core").BaseType<ONNOMATCH> extends () => any ? import("./core").Action : Match<import("./core").BaseType<ONNOMATCH>> : (import("./core").BaseType<ONNOMATCH> extends null | undefined ? never : import("./core").BaseType<ONNOMATCH> extends import("./core").Result ? import("./core").BaseType<ONNOMATCH> : import("./core").BaseType<ONNOMATCH> extends () => any ? import("./core").Action : Match<import("./core").BaseType<ONNOMATCH>>) extends () => any ? import("./core").Action : Match<import("./core").BaseType<ONNOMATCH> extends null | undefined ? never : import("./core").BaseType<ONNOMATCH> extends import("./core").Result ? import("./core").BaseType<ONNOMATCH> : import("./core").BaseType<ONNOMATCH> extends () => any ? import("./core").Action : Match<import("./core").BaseType<ONNOMATCH>>>)>; | ||
declare function _if<ARGS extends any[], ONTRUE, ONFALSE>(predicate: (...args: ARGS) => any, onTrue: () => ONTRUE, onFalse?: () => ONFALSE): import("./core").Transform<ARGS, import("./core").Result | ((import("./core").BaseType<ONFALSE> extends null | undefined ? never : import("./core").BaseType<ONFALSE> extends import("./core").Result ? import("./core").BaseType<ONFALSE> : import("./core").BaseType<ONFALSE> extends () => any ? import("./core").Action : Match<import("./core").BaseType<ONFALSE>>) extends null | undefined ? never : (import("./core").BaseType<ONFALSE> extends null | undefined ? never : import("./core").BaseType<ONFALSE> extends import("./core").Result ? import("./core").BaseType<ONFALSE> : import("./core").BaseType<ONFALSE> extends () => any ? import("./core").Action : Match<import("./core").BaseType<ONFALSE>>) extends import("./core").Result ? import("./core").BaseType<ONFALSE> extends null | undefined ? never : import("./core").BaseType<ONFALSE> extends import("./core").Result ? import("./core").BaseType<ONFALSE> : import("./core").BaseType<ONFALSE> extends () => any ? import("./core").Action : Match<import("./core").BaseType<ONFALSE>> : (import("./core").BaseType<ONFALSE> extends null | undefined ? never : import("./core").BaseType<ONFALSE> extends import("./core").Result ? import("./core").BaseType<ONFALSE> : import("./core").BaseType<ONFALSE> extends () => any ? import("./core").Action : Match<import("./core").BaseType<ONFALSE>>) extends () => any ? import("./core").Action : Match<import("./core").BaseType<ONFALSE> extends null | undefined ? never : import("./core").BaseType<ONFALSE> extends import("./core").Result ? import("./core").BaseType<ONFALSE> : import("./core").BaseType<ONFALSE> extends () => any ? import("./core").Action : Match<import("./core").BaseType<ONFALSE>>>)>; | ||
import { Observableable, Value } from './prague'; | ||
export declare function match<ARGS extends any[], VALUE, ONMATCH, ONNOMATCH>(getMatch: (...args: ARGS) => Observableable<null | undefined | VALUE | Value<VALUE>>, onMatch: (value: Value<VALUE>) => ONMATCH, onNoMatch?: () => ONNOMATCH): import("./core").Transform<ARGS, import("./core").Result | (import("./core").BaseType<ONNOMATCH> extends null | undefined ? never : import("./core").BaseType<ONNOMATCH> extends import("./core").Result ? import("./core").BaseType<ONNOMATCH> : import("./core").BaseType<ONNOMATCH> extends () => any ? import("./core").Action : Value<import("./core").BaseType<ONNOMATCH>>)>; | ||
declare function _if<ARGS extends any[], ONTRUE, ONFALSE>(predicate: (...args: ARGS) => any, onTrue: () => ONTRUE, onFalse?: () => ONFALSE): import("./core").Transform<ARGS, import("./core").Result | (import("./core").BaseType<ONFALSE> extends null | undefined ? never : import("./core").BaseType<ONFALSE> extends import("./core").Result ? import("./core").BaseType<ONFALSE> : import("./core").BaseType<ONFALSE> extends () => any ? import("./core").Action : Value<import("./core").BaseType<ONFALSE>>)>; | ||
export { _if as if }; |
@@ -6,8 +6,8 @@ "use strict"; | ||
const prague_1 = require("./prague"); | ||
const getMatchError = new Error("matching function should only return MatchRoute or NoRoute"); | ||
const getMatchError = new Error("matching function should only return Value"); | ||
function match(getMatch, onMatch, onNoMatch) { | ||
return prague_1.first(prague_1.pipe(getMatch, prague_1.tap(result => { | ||
if (!(result instanceof prague_1.Match)) | ||
if (!(result instanceof prague_1.Value)) | ||
throw getMatchError; | ||
}), onMatch), prague_1.from(onNoMatch)); | ||
}), onMatch), onNoMatch); | ||
} | ||
@@ -17,7 +17,7 @@ exports.match = match; | ||
function _if(predicate, onTrue, onFalse) { | ||
return match(prague_1.pipe((...args) => rxjs_1.of(args).pipe(operators_1.map(args => predicate(...args)), operators_1.flatMap(prague_1.toObservable), operators_1.map(result => result instanceof prague_1.Match ? !!result.value : !!result)), route => { | ||
if (route instanceof prague_1.Match) { | ||
if (route.value === true) | ||
return match(prague_1.pipe((...args) => rxjs_1.of(args).pipe(operators_1.map(args => predicate(...args)), operators_1.flatMap(prague_1.toObservable), operators_1.map(result => result instanceof prague_1.Value ? !!result.value : !!result)), result => { | ||
if (result instanceof prague_1.Value) { | ||
if (result.value === true) | ||
return true; | ||
if (route.value === false) | ||
if (result.value === false) | ||
return undefined; | ||
@@ -24,0 +24,0 @@ } |
import { Result } from './prague'; | ||
export declare class NoResult extends Result { | ||
} | ||
export declare function emitNoResult<ARGS extends any[], R>(transform: (...args: ARGS) => R, score?: number): import("./core").Transform<ARGS, NoResult | ((import("./core").BaseType<R> extends null | undefined ? never : import("./core").BaseType<R> extends Result ? import("./core").BaseType<R> : import("./core").BaseType<R> extends () => any ? import("./core").Action : import("./core").Match<import("./core").BaseType<R>>) extends null | undefined ? never : (import("./core").BaseType<R> extends null | undefined ? never : import("./core").BaseType<R> extends Result ? import("./core").BaseType<R> : import("./core").BaseType<R> extends () => any ? import("./core").Action : import("./core").Match<import("./core").BaseType<R>>) extends Result ? import("./core").BaseType<R> extends null | undefined ? never : import("./core").BaseType<R> extends Result ? import("./core").BaseType<R> : import("./core").BaseType<R> extends () => any ? import("./core").Action : import("./core").Match<import("./core").BaseType<R>> : (import("./core").BaseType<R> extends null | undefined ? never : import("./core").BaseType<R> extends Result ? import("./core").BaseType<R> : import("./core").BaseType<R> extends () => any ? import("./core").Action : import("./core").Match<import("./core").BaseType<R>>) extends () => any ? import("./core").Action : import("./core").Match<import("./core").BaseType<R> extends null | undefined ? never : import("./core").BaseType<R> extends Result ? import("./core").BaseType<R> : import("./core").BaseType<R> extends () => any ? import("./core").Action : import("./core").Match<import("./core").BaseType<R>>>)>; | ||
export declare function alwaysEmit<ARGS extends any[], R>(transform: (...args: ARGS) => R, score?: number): import("./core").Transform<ARGS, NoResult | (import("./core").BaseType<R> extends null | undefined ? never : import("./core").BaseType<R> extends Result ? import("./core").BaseType<R> : import("./core").BaseType<R> extends () => any ? import("./core").Action : import("./core").Value<import("./core").BaseType<R>>)>; |
@@ -7,6 +7,6 @@ "use strict"; | ||
exports.NoResult = NoResult; | ||
function emitNoResult(transform, score) { | ||
return prague_1.first(prague_1.from(transform), () => new NoResult(score)); | ||
function alwaysEmit(transform, score) { | ||
return prague_1.first(transform, () => new NoResult(score)); | ||
} | ||
exports.emitNoResult = emitNoResult; | ||
exports.alwaysEmit = alwaysEmit; | ||
//# sourceMappingURL=noResult.js.map |
@@ -7,3 +7,3 @@ import { Result, Transform, Norm } from "./prague"; | ||
export declare function pipe<ARGS extends any[], R0, R1, R2, R3, R4>(...args: [(...args: ARGS) => R0, (arg: Norm<R0>) => R1, (arg: Norm<R1>) => R2, (arg: Norm<R2>) => R3, (arg: Norm<R2>) => R4]): Transform<ARGS, Norm<R4>>; | ||
export declare function pipe<ARGS extends any[]>(transform: (...args: ARGS) => any, ...functions: ((...args: any[]) => any)[]): Transform<ARGS, Result>; | ||
export declare function pipe<ARGS extends any[]>(transform: (...args: ARGS) => any, ...transforms: ((result: any) => any)[]): Transform<ARGS, Result>; | ||
export declare const _tap: <RESULT extends Result>(fn: (result: RESULT) => any) => Transform<[RESULT], RESULT>; | ||
@@ -10,0 +10,0 @@ export declare const log: Transform<[any], any>; |
@@ -6,5 +6,5 @@ "use strict"; | ||
const operators_1 = require("rxjs/operators"); | ||
function pipe(...transforms) { | ||
const _transforms = rxjs_1.from(transforms.map(transform => prague_1.from(transform))); | ||
return (...args) => _transforms.pipe(operators_1.reduce((args$, transform) => args$.pipe(operators_1.flatMap(args => args instanceof prague_1.Result ? transform(args) : transform(...args))), rxjs_1.of(args)), operators_1.mergeAll()); | ||
function pipe(transform, ...transforms) { | ||
const _transforms = rxjs_1.from(transforms.map(_transform => prague_1.from(_transform))); | ||
return (...args) => _transforms.pipe(operators_1.reduce((result$, _transform) => result$.pipe(operators_1.flatMap(result => _transform(result))), prague_1.from(transform)(...args)), operators_1.mergeAll()); | ||
} | ||
@@ -11,0 +11,0 @@ exports.pipe = pipe; |
{ | ||
"name": "prague", | ||
"version": "0.21.1", | ||
"version": "0.21.2", | ||
"description": "EDSL for rules", | ||
@@ -5,0 +5,0 @@ "main": "lib/src/prague.js", |
@@ -40,13 +40,13 @@ # *Prague* | ||
`Result` is an abstract base class. The following two subclasses of `Result` are "core" to *Prague*: | ||
* `Match<VALUE>` - a value | ||
* `Action` - a function to execute at a future time | ||
* `Value<VALUE>` - contains a value of type VALUE | ||
* `Action` - contains an action (function) to potentially execute at a future time | ||
The following subclasses of `Result` are used for various helpers: | ||
* `ActionReference` - a serializable reference to a function to execute at a future time | ||
* `Multiple` - an array of `Result`s | ||
* `NoResult` - a way to get a positive "no result" signal from a `Transform` | ||
*Prague* also includes and makes use of these subclasses of `Result`: | ||
* `ActionReference` - contains the (serializable) name and arguments of a function to potentially execute at a future time | ||
* `Multiple` - contains an array of `Result`s | ||
* `NoResult` - a way to get a positive "no result" signal from a `Transform` using [emitNoResults](#noresult) | ||
### `from` | ||
The `from` function allows you to write `Tranform`s more simply, by returning a value instead a `Match`, a function instead of an `Action`, `undefined`/`null` when nothing is to be emitted, or a `Promise` or a synchronous result instead of an `Observable`: | ||
The `from` function allows you to write `Tranform`s more simply, by returning a value instead a `Value`, a function instead of an `Action`, `undefined`/`null` when nothing is to be emitted, or a `Promise` or a synchronous result instead of an `Observable`: | ||
@@ -63,7 +63,7 @@ ```ts | ||
```ts | ||
const repeat = (a: string) => Rx.of.(new Match(a.repeat(5))); | ||
const repeat = (a: string) => Rx.of.(new Value(a.repeat(5))); | ||
const confirm = (a: number) => Rx.of(new Action(() => console.log(`You picked ${a.toString()}`))); | ||
const getName = (a: string) => Rx.from(fetch(`url/${a}`).then(r => r.json()).then(r => new Match(r.someString))); | ||
const getName = (a: string) => Rx.from(fetch(`url/${a}`).then(r => r.json()).then(r => new Value(r.someString))); | ||
``` | ||
@@ -106,4 +106,4 @@ | ||
fullName("Bill").subscribe(console.log); // Match{ value: "Bill Barnes" } | ||
fullName("Hao").subscribe(console.log); // Match{ value: "Hao Luo" } | ||
fullName("Bill").subscribe(console.log); // Value{ value: "Bill Barnes" } | ||
fullName("Hao").subscribe(console.log); // Value{ value: "Hao Luo" } | ||
fullName("Yomi").subscribe(console.log); // | ||
@@ -126,3 +126,3 @@ ``` | ||
someAssemblyRequired("Kev", "in").subscribe(console.log); // Match{ value: "Kevin Leung." } | ||
someAssemblyRequired("Kev", "in").subscribe(console.log); // Value{ value: "Kevin Leung." } | ||
someAssemblyRequired("Yo", "mi").subscribe(console.log); // | ||
@@ -146,4 +146,4 @@ ``` | ||
greet("Kevin").subscribe(console.log); // Match{ value: "Nice to meet you, Kevin Leung." } | ||
greet("Yomi").subscribe(console.log); // Match{ value: "I don't know you." } | ||
greet("Kevin").subscribe(console.log); // Value{ value: "Nice to meet you, Kevin Leung." } | ||
greet("Yomi").subscribe(console.log); // Value{ value: "I don't know you." } | ||
``` | ||
@@ -179,3 +179,3 @@ | ||
greet("Bill") | ||
.subscribe(console.log); // Match{ value: "I greet you, my creator!" } | ||
.subscribe(console.log); // Value{ value: "I greet you, my creator!" } | ||
``` | ||
@@ -194,3 +194,3 @@ | ||
.subscribe(); | ||
// Match{ value: "Bill Barnes" } | ||
// Value{ value: "Bill Barnes" } | ||
``` | ||
@@ -258,3 +258,3 @@ | ||
```ts | ||
new Match("Bill", .5); // Match{ value: "Bill", score: .5 } | ||
new Value("Bill", .5); // Value{ value: "Bill", score: .5 } | ||
``` | ||
@@ -274,5 +274,5 @@ | ||
(t: string) => /My name is (.*)/i.exec(t), | ||
matches => matches.value[1], // gets converted to a Match of score 1 | ||
matches => matches.value[1], // gets converted to a Value of score 1 | ||
), | ||
t => new Match(t, .5), | ||
t => new Value(t, .5), | ||
), | ||
@@ -302,6 +302,6 @@ m => new Action(() => console.log(`Nice to meet you, ${m.value}`), m.score) | ||
const transforms = [ | ||
() => new Match("hi", .75), | ||
() => new Match("hello", .75), | ||
() => new Match("aloha", .70), | ||
() => new Match("wassup", .65), | ||
() => new Value("hi", .75), | ||
() => new Value("hello", .75), | ||
() => new Value("aloha", .70), | ||
() => new Value("wassup", .65), | ||
]; | ||
@@ -312,3 +312,3 @@ | ||
)() | ||
.subscribe(console.log) // Match{ value: "hi", score: .75 } | ||
.subscribe(console.log) // Value{ value: "hi", score: .75 } | ||
``` | ||
@@ -338,3 +338,3 @@ | ||
)() | ||
.subscribe(console.log); // Multiple{ results:[ Match{ value: "hi", score: .75 }, Match{ value: "hello", score: .75 }, ] } | ||
.subscribe(console.log); // Multiple{ results:[ Value{ value: "hi", score: .75 }, Value{ value: "hello", score: .75 }, ] } | ||
``` | ||
@@ -351,3 +351,3 @@ | ||
)() | ||
.subscribe(console.log); // Multiple{ results:[ Match{ value: "hi", score: .75 }, Match{ value: "hello", score: .75 }, Match{ value: "aloha", score: .70 }, ] } | ||
.subscribe(console.log); // Multiple{ results:[ Value{ value: "hi", score: .75 }, Value{ value: "hello", score: .75 }, Value{ value: "aloha", score: .70 }, ] } | ||
``` | ||
@@ -365,3 +365,3 @@ | ||
)() | ||
.subscribe(console.log); // Multiple{ results:[ Match{ value: "hi", score: .75 }, Match{ value: "hello", score: .75 }, Match{ value: "aloha", score: .70 }, ] } | ||
.subscribe(console.log); // Multiple{ results:[ Value{ value: "hi", score: .75 }, Value{ value: "hello", score: .75 }, Value{ value: "aloha", score: .70 }, ] } | ||
``` | ||
@@ -435,11 +435,18 @@ | ||
A quirk of `Observables` is that you don't automatically know if one emitted a value before completing. If you want a positive signal that no `Result` was emitted by your `Transform`, you can wrap it in `emitNoResult` as follows: | ||
A quirk of `Observables` is that you don't automatically know if one emitted a value before completing: | ||
```ts | ||
fullName("Bill").subscribe(console.log); // Value{ value: "Bill Barnes" } | ||
fullName("Yomi").subscribe(console.log); // <crickets> | ||
``` | ||
You can force a transform to always emit *something* by wrapping it in `emitNoResult` as follows: | ||
```ts | ||
import { NoResult, emitNoResult } from 'prague'; | ||
emitNoResult( | ||
fullName | ||
)("Yomi") | ||
.subscribe(console.log); // NoResult{} | ||
const fullNameAlwaysEmits = emitNoResult(fullName); | ||
fullNameAlwaysEmits("Bill").subscribe(console.log); // Value{ value: "Bill Barnes" } | ||
fullNameAlwaysEmits("Yomi").subscribe(console.log); // NoResult{} | ||
``` | ||
@@ -446,0 +453,0 @@ |
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
454
59387
333