Skip to content

Commit

Permalink
StatefulEvt.prototype.statefulPipe becomes pipe; no need to increace …
Browse files Browse the repository at this point in the history
…the api surface
  • Loading branch information
garronej committed Apr 19, 2020
1 parent f4a39f2 commit 1d7a925
Show file tree
Hide file tree
Showing 22 changed files with 259 additions and 134 deletions.
18 changes: 12 additions & 6 deletions deno_dist/lib/StatefulEvt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { importProxy } from "./importProxy.ts";
import { invokeOperator } from "./util/invokeOperator.ts";
import { Operator } from "./types/Operator.ts";
import { parsePropsFromArgs } from "./Evt.parsePropsFromArgs.ts";
import { CtxLike } from "./types/interfaces/CtxLike.ts";
type Diff<T> = import("./types/interfaces/index.ts").Diff<T>;
type NonPostableEvt<T> = import("./types/interfaces/index.ts").NonPostableEvt<T>;
type StatefulReadonlyEvt<T>= import("./types/interfaces/index.ts").StatefulReadonlyEvt<T>;
Expand Down Expand Up @@ -94,11 +95,10 @@ class StatefulEvtImpl<T> extends Evt<T> implements StatefulEvt<T> {

}

pipe(...args: any[]): StatefulEvt<any> {

statefulPipe(...args: any[]): StatefulEvt<any> {

const evt = this
.pipe(...(args as Parameters<typeof StatefulEvtImpl.prototype.pipe>))
const evt = super
.pipe(...(args as Parameters<typeof importProxy.Evt.prototype.pipe>))
;

const opResult = invokeOperator(
Expand All @@ -111,8 +111,9 @@ class StatefulEvtImpl<T> extends Evt<T> implements StatefulEvt<T> {
if (Operator..Result.NotMatched.match(opResult)) {

throw new Error([
"Operator do not match current state",
"use evt.pipe([ctx], op).toStatic(initialState)",
"Cannot pipe StatefulEvt because the operator does not match",
"it's current state.",
"Use evt.toStateless([ctx]).pipe(op).toStatic(initialState)",
"to be sure the StatefulEvt is correctly initialized"
].join(" "));

Expand All @@ -122,6 +123,11 @@ class StatefulEvtImpl<T> extends Evt<T> implements StatefulEvt<T> {

}

/** Return a stateless copy */
toStateless(ctx?: CtxLike): Evt<any> {
return !!ctx ? super.pipe(ctx) : super.pipe();
}

}

export const StatefulEvt: {
Expand Down
59 changes: 32 additions & 27 deletions deno_dist/lib/types/interfaces/StatefulReadonlyEvt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ import { Operator } from "../Operator.ts";
type NonPostableEvt<T> = import("./NonPostableEvt.ts").NonPostableEvt<T>;
type CtxLike<Result = any> = import("./CtxLike.ts").CtxLike<Result>;
type StatefulEvt<T> = import("./StatefulEvt.ts").StatefulEvt<T>;
type Evt<T> = import("./Evt.ts").Evt<T>;

export type StateDiff<T> = { prevState: T, newState: T };

export interface StatefulReadonlyEvt<T> extends NonPostableEvt<T> {

/** https://docs.evt.land/api/statefulevt#converting-an-evt-into-a-statefulevt */
toStateless(ctx?: CtxLike): Evt<T>;

readonly state: T;

/** https://docs.evt.land/api/statefulevt#evtdiff */
Expand All @@ -20,93 +24,94 @@ export interface StatefulReadonlyEvt<T> extends NonPostableEvt<T> {
/** https://docs.evt.land/api/statefulevt#evtchangediff */
readonly evtChangeDiff: NonPostableEvt<StateDiff<T>>;

//TODO: update docs.
/** https://docs.evt.land/api/statefulevt#statefulpipe */
statefulPipe(): StatefulEvt<T>;
pipe(): StatefulEvt<T>;

statefulPipe<U, CtxResult>(
pipe<U, CtxResult>(
op: Operator.<T, U, CtxResult>
): StatefulEvt<U>;
statefulPipe<U extends T>(
pipe<U extends T>(
op: (data: T) => data is U
): StatefulEvt<U>;
statefulPipe(
pipe(
op: (data: T) => boolean
): StatefulEvt<T>;

statefulPipe(ctx: CtxLike<any>): StatefulEvt<T>;
pipe(ctx: CtxLike<any>): StatefulEvt<T>;

statefulPipe<U, CtxResult>(
pipe<U, CtxResult>(
ctx: CtxLike<any>,
op: Operator.<T, U, CtxResult>
): StatefulEvt<U>;
statefulPipe<U extends T>(
pipe<U extends T>(
ctx: CtxLike<any>,
op: (data: T) => data is U
): StatefulEvt<U>;
statefulPipe(
pipe(
ctx: CtxLike<any>,
op: (data: T) => boolean
): StatefulEvt<T>;

statefulPipe<B, C, CtxResultOp1, CtxResultOp2>(
pipe<B, C, CtxResultOp1, CtxResultOp2>(
op1: Operator.<T, B, CtxResultOp1>,
op2: Operator.<B, C, CtxResultOp2>
): StatefulEvt<C>;
statefulPipe<B, C extends B, CtxResult>(
pipe<B, C extends B, CtxResult>(
op1: Operator.<T, B, CtxResult>,
op2: (data: B) => data is C
): StatefulEvt<C>;
statefulPipe<B, CtxResult>(
pipe<B, CtxResult>(
op1: Operator.<T, B, CtxResult>,
op2: (data: B) => boolean
): StatefulEvt<B>;
statefulPipe<B extends T, C, CtxResult>(
pipe<B extends T, C, CtxResult>(
op1: (data: T) => data is B,
op2: Operator.<B, C, CtxResult>
): StatefulEvt<B>;
statefulPipe<B, CtxResult>(
pipe<B, CtxResult>(
op1: (data: T) => boolean,
op2: Operator.<T, B, CtxResult>
): StatefulEvt<B>;
statefulPipe<B extends T, C extends B>(
pipe<B extends T, C extends B>(
op1: (data: T) => data is B,
op2: (data: B) => data is C
): StatefulEvt<C>;
statefulPipe<B extends T>(
pipe<B extends T>(
op1: (data: T) => data is B,
op2: (data: B) => boolean
): StatefulEvt<B>;
statefulPipe<B extends T>(
pipe<B extends T>(
op1: (data: T) => boolean,
op2: (data: T) => data is B
): StatefulEvt<B>;
statefulPipe<T>(
pipe<T>(
op1: (data: T) => boolean,
op2: (data: T) => boolean
): StatefulEvt<T>;


statefulPipe<B, C, D, CtxResultOp1, CtxResultOp2, CtxResultOp3>(
pipe<B, C, D, CtxResultOp1, CtxResultOp2, CtxResultOp3>(
op1: Operator.<T, B, CtxResultOp1>,
op2: Operator.<B, C, CtxResultOp2>,
op3: Operator.<C, D, CtxResultOp3>
): StatefulEvt<D>;

statefulPipe<B, C, D, E, CtxResultOp1 = any, CtxResultOp2 = any, CtxResultOp3 = any, CtxResultOp4 = any>(
pipe<B, C, D, E, CtxResultOp1 = any, CtxResultOp2 = any, CtxResultOp3 = any, CtxResultOp4 = any>(
op1: Operator.<T, B, CtxResultOp1>,
op2: Operator.<B, C, CtxResultOp2>,
op3: Operator.<C, D, CtxResultOp3>,
op4: Operator.<D, E, CtxResultOp4>
): StatefulEvt<E>;

statefulPipe<B, C, D, E, CtxResultOp1 = any, CtxResultOp2 = any, CtxResultOp3 = any, CtxResultOp4 = any>(
pipe<B, C, D, E, CtxResultOp1 = any, CtxResultOp2 = any, CtxResultOp3 = any, CtxResultOp4 = any>(
op1: Operator.<T, B, CtxResultOp1>,
op2: Operator.<B, C, CtxResultOp2>,
op3: Operator.<C, D, CtxResultOp3>,
op4: Operator.<D, E, CtxResultOp4>
): StatefulEvt<E>;

statefulPipe<B, C, D, E, F, CtxResultOp1 = any, CtxResultOp2 = any, CtxResultOp3 = any, CtxResultOp4 = any, CtxResultOp5 = any>(
pipe<B, C, D, E, F, CtxResultOp1 = any, CtxResultOp2 = any, CtxResultOp3 = any, CtxResultOp4 = any, CtxResultOp5 = any>(
op1: Operator.<T, B, CtxResultOp1>,
op2: Operator.<B, C, CtxResultOp2>,
op3: Operator.<C, D, CtxResultOp3>,
Expand All @@ -115,40 +120,40 @@ export interface StatefulReadonlyEvt<T> extends NonPostableEvt<T> {
): StatefulEvt<F>;


statefulPipe<B, C, CtxResultOp1 = any, CtxResultOp2 = any>(
pipe<B, C, CtxResultOp1 = any, CtxResultOp2 = any>(
op1: Operator<T, B, CtxResultOp2>,
op2: Operator<B, C, CtxResultOp2>
): StatefulEvt<C>;

statefulPipe<B, C, D, CtxResultOp1 = any, CtxResultOp2 = any, CtxResultOp3 = any>(
pipe<B, C, D, CtxResultOp1 = any, CtxResultOp2 = any, CtxResultOp3 = any>(
op1: Operator<T, B, CtxResultOp1>,
op2: Operator<B, C, CtxResultOp2>,
op3: Operator<C, D, CtxResultOp3>
): StatefulEvt<D>;

statefulPipe<B, C, D, E, CtxResultOp1 = any, CtxResultOp2 = any, CtxResultOp3 = any, CtxResultOp4 = any>(
pipe<B, C, D, E, CtxResultOp1 = any, CtxResultOp2 = any, CtxResultOp3 = any, CtxResultOp4 = any>(
op1: Operator<T, B, CtxResultOp1>,
op2: Operator<B, C, CtxResultOp2>,
op3: Operator<C, D, CtxResultOp3>,
op4: Operator<D, E, CtxResultOp4>
): StatefulEvt<E>;

statefulPipe<B, C, D, E, F, CtxResultOp1 = any, CtxResultOp2 = any, CtxResultOp3 = any, CtxResultOp4 = any, CtxResultOp5 = any>(
pipe<B, C, D, E, F, CtxResultOp1 = any, CtxResultOp2 = any, CtxResultOp3 = any, CtxResultOp4 = any, CtxResultOp5 = any>(
op1: Operator<T, B, CtxResultOp1>,
op2: Operator<B, C, CtxResultOp2>,
op3: Operator<C, D, CtxResultOp3>,
op4: Operator<D, E, CtxResultOp4>,
op5: Operator<E, F, CtxResultOp5>
): StatefulEvt<F>;

statefulPipe(
pipe(
...ops: [
Operator<T, any, any>,
...Operator<any, any, any>[]
]
): StatefulEvt<any>;

statefulPipe<T>(
pipe<T>(
...ops: [
Operator<T, any, any>,
...Operator<any, any, any>[]
Expand Down
3 changes: 2 additions & 1 deletion deno_dist/test/deno_index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,5 @@ import "./test85.ts";
import "./test86.ts";
import "./test87.ts";
import "./test88.ts";
import "./test89.ts";
import "./test89.ts";
import "./test90.ts";
2 changes: 1 addition & 1 deletion deno_dist/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ if (n) {

await new Promise(resolve => setTimeout(resolve, 2400));

const n = 89;
const n = 90;

console.log({ n });

Expand Down
8 changes: 4 additions & 4 deletions deno_dist/test/test73.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { assert } from "../tools/typeSafety/assert.ts";

const sevText = Evt.create("foo");

const sevCharCount = sevText.statefulPipe(text => [text.length]);
const sevCharCount = sevText.pipe(text => [text.length]);

assert(sevCharCount.state === sevText.state.length);

Expand All @@ -24,7 +24,7 @@ import { assert } from "../tools/typeSafety/assert.ts";

const sevText = Evt.create("foo");

const sevCharCount = sevText.statefulPipe(ctx, text => [text.length]);
const sevCharCount = sevText.pipe(ctx, text => [text.length]);

assert(sevCharCount.state === sevText.state.length);

Expand Down Expand Up @@ -97,7 +97,7 @@ import { assert } from "../tools/typeSafety/assert.ts";

const sevText = Evt.create("foo");

const sevCharCount = sevText.statefulPipe(text => [text.length]);
const sevCharCount = sevText.pipe(text => [text.length]);

assert(sevCharCount.state === sevText.state.length);

Expand All @@ -113,7 +113,7 @@ import { assert } from "../tools/typeSafety/assert.ts";

const sevText = Evt.create("foo");

const sevCharCount = sevText.statefulPipe(ctx, text => [text.length]);
const sevCharCount = sevText.pipe(ctx, text => [text.length]);

assert(sevCharCount.state === sevText.state.length);

Expand Down
4 changes: 2 additions & 2 deletions deno_dist/test/test87.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ const evtIsBigAndBlue = Evt.merge([
evtIsBlue.evtChange,
evtIsBig.evtChange
])
.toStateful() //It is safe to use as any here
.statefulPipe(()=> [ evtIsBlue.state && evtIsBig.state ])
.toStateful()
.pipe(()=> [ evtIsBlue.state && evtIsBig.state ])
;

assert(evtIsBigAndBlue.state === false as boolean);
Expand Down
2 changes: 1 addition & 1 deletion deno_dist/test/test89.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const ctx = Evt.newCtx();

Evt.useEffect(
text => std_out+= text.toString(),
evtText.evtChange.statefulPipe(ctx)
evtText.evtChange.pipe(ctx)
);

assert( std_out === "foo" as string);
Expand Down
40 changes: 40 additions & 0 deletions deno_dist/test/test90.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

import { Evt } from "../lib/index.ts";
import { assert } from "../tools/typeSafety/index.ts";

const evtText = Evt.create("foo");

try {

evtText.pipe(text => text.startsWith("f") ? null : [text.toUpperCase()]);

assert(false);

} catch{ }

const ctx = Evt.newCtx();

const evtTextSt = evtText.toStateless(ctx)
.pipe(text => text.startsWith("f") ? null : [text.toUpperCase()])
.toStateful()
;


assert(evtTextSt.state === undefined as any);

evtText.post("foobar");

assert(evtTextSt.state === undefined as any);

evtText.post("baz");

assert(evtTextSt.state === "BAZ" as any);

ctx.done();

evtText.post("hello");

assert(evtTextSt.state === "BAZ" as any);

console.log("PASS");

14 changes: 9 additions & 5 deletions dist/lib/StatefulEvt.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/lib/StatefulEvt.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 1d7a925

Please sign in to comment.