Skip to content

Commit

Permalink
feat(@dxjs/core): effect 超类 + ts声明
Browse files Browse the repository at this point in the history
  • Loading branch information
taixw2 committed Apr 28, 2020
1 parent e3c0997 commit 0841a71
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 0 deletions.
21 changes: 21 additions & 0 deletions packages/core/src/dx-model/guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { BaseGuardInterface } from '@dxjs/shared/interfaces/dx-guard.interface';
import { AnyAction } from 'redux';
import { BaseEffectContextInterface } from '@dxjs/shared/interfaces/dx-effect-context.interface';

export class Guard<T extends AnyAction> implements BaseGuardInterface<T> {
constructor(private option: BaseEffectContextInterface<T>) {}

getState(): any {
return this.option.getState();
}

dispatchCurrentAction(): T {
// TODO dispatch 无法获取
return this.option.action;
}

getPayload(): T['payload'] {
return this.option.action['payload'];
}
}
27 changes: 27 additions & 0 deletions packages/core/src/dx-model/sentinel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { BaseSentinelInterface } from '@dxjs/shared/interfaces/dx-sentinel.interface';
import { AnyAction } from 'redux';
import { BaseEffectContextInterface } from '@dxjs/shared/interfaces/dx-effect-context.interface';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export class Sentinel<T extends AnyAction = any> implements BaseSentinelInterface<T> {
constructor(private context: BaseEffectContextInterface<T>) {}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
getState(): any {
return this.context.getState();
}

getPayload(): T['payload'] {
return this.context.action.payload;
}

dispatchCurrentAction<P>(payload?: P): T {
const action = {
...this.context.action,
payload: typeof payload === 'undefined' ? this.context.action.payload : payload,
};
this.context.dispatch(action);

return action;
}
}
25 changes: 25 additions & 0 deletions packages/core/src/dx-model/spy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { DxBase } from './base';
import { SpyBaseInterface } from '@dxjs/shared/interfaces/dx-spy.interface';
import { AnyAction } from 'redux';

export class Spy<T extends AnyAction> extends DxBase implements SpyBaseInterface<T> {
private createEffect<T>(type: string): T {
return ({ '@dxjs/IO': true, type } as unknown) as T;
}

abort(): void {
return this.createEffect('abort');
}

next(): void {
return this.createEffect('next');
}

getPayload(): T['payload'] {
return this.createEffect('payload');
}

dispatchCurrentAction(): T {
return this.createEffect('dispatch');
}
}
26 changes: 26 additions & 0 deletions packages/shared/interfaces/dx-effect-context.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import { Dispatch } from 'react';
import { EffectTypeInterface } from './dx-effect-type.interface';
import { SpyStatic } from './dx-spy.interface';
import { EnhancerFunctionSupportInterface } from './dx-effect-support.interface';

export interface BaseEffectContextInterface<T> {
action: T;

dispatch: Dispatch<any>;

inst: symbol;

meta: EffectTypeInterface;

getState: () => any;
}

export interface EffectContextInterface<T> extends BaseEffectContextInterface<T> {
sentinels: EnhancerFunctionSupportInterface[];

guards: EnhancerFunctionSupportInterface[];

spies: SpyStatic[];
}
14 changes: 14 additions & 0 deletions packages/shared/interfaces/dx-effect-support.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { AnyAction } from 'redux';
import { BaseEffectContextInterface } from './dx-effect-context.interface';
import { SentinelInterface } from './dx-sentinel.interface';
import { GuardInterface } from './dx-guard.interface';

export interface EnhancerSupportStatic {
new <T extends AnyAction>(context: BaseEffectContextInterface<T>): SentinelInterface<T>;
new <T extends AnyAction>(context: BaseEffectContextInterface<T>, error?: Error, data?: unknown): GuardInterface<T>;
}

export interface EnhancerFunctionSupportInterface {
<T extends AnyAction>(context: BaseEffectContextInterface<T>): Promise<boolean | void>;
<T extends AnyAction>(context: BaseEffectContextInterface<T>, error?: Error, data?: unknown): Promise<boolean | void>;
}
30 changes: 30 additions & 0 deletions packages/shared/interfaces/dx-sentinel.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/**
*
* 能够获取到 effect 的 payload,
* 通过判断是否合法,决定是否要中断这次 action
*/

import { AnyAction } from 'redux';

export interface BaseSentinelInterface<T extends AnyAction> {
/**
* 获取整个状态树
*/
getState(): any;
/**
* 通过该方法可以拿到传入的 payload
*/
getPayload(): T;
/**
* 通过该方法可以拿到传入的 payload
*/
dispatchCurrentAction<P>(payload?: P): T;
}

export interface SentinelInterface<T extends AnyAction> extends BaseSentinelInterface<T> {
/**
* 实现该方法,返回 false 则 effect 执行
*/
sentinel(): Promise<boolean | void>;
}
42 changes: 42 additions & 0 deletions packages/shared/interfaces/dx-spy.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
*
* 可以穿插在 effect 中,并且可以中断 effect
*/
import { DxBaseInterface } from './dx-base.interface';
import { AnyAction } from 'redux';
import { BaseEffectContextInterface } from './dx-effect-context.interface';

export interface SpyBaseInterface<T extends AnyAction> extends DxBaseInterface {
/**
* 相当于 effect 的 generator 引用
* 通过 next 可以执行一次 effect 的一个 yield
* 于 generator 的引用不同,这个不能传值,也不能获取返回值
*/
next(): void;

/**
* 中断 effect
*/
abort(): void;

/**
* 获取 payload
*/
getPayload(): T['payload'];

/**
* 重新 dispatch 当前的 action
*/
dispatchCurrentAction(): T;
}

export interface SpyInterface<T extends AnyAction> extends SpyBaseInterface<T> {
/**
* 继承 Spy 必须实现 spy 方法
*/
spy(): Generator;
}

export interface SpyStatic {
new <T extends AnyAction>(context: BaseEffectContextInterface<T>): SpyInterface<T>;
}

0 comments on commit 0841a71

Please sign in to comment.