Skip to content

Commit

Permalink
fix: export typing incomplete
Browse files Browse the repository at this point in the history
  • Loading branch information
LiJun committed Oct 7, 2019
1 parent eeb466d commit f881293
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 130 deletions.
83 changes: 0 additions & 83 deletions src/index.d.ts

This file was deleted.

48 changes: 16 additions & 32 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,22 @@
import equal from "fast-deep-equal";
import produce from "immer";
import { useState } from "react";
import {
calledFn,
Effects,
EnhanceEffects,
EnhanceReducerFn,
EnhanceReducers,
HookMap,
InitOpt,
Opt,
Plugin,
Reducers,
StateSelector,
StoreMap,
Updater
} from "./index.d";
import { isPromise, useMount } from "./util";
import { CubeState } from "./typings";

const storeMap: StoreMap = {};
const storeMap: CubeState.StoreMap = {};

const hookMap: HookMap = {
const hookMap: CubeState.HookMap = {
onError: [],
beforeReducer: [],
afterReducer: [],
beforeEffect: [],
afterEffect: []
};

function use(plugin: Plugin) {
function use(plugin: CubeState.Plugin) {
Object.keys(hookMap).forEach(hookKey => {
const key = hookKey as keyof Plugin;
const key = hookKey as keyof CubeState.Plugin;
if (typeof plugin[key] === "function") {
// @ts-ignore
hookMap[key].push(plugin[key]);
Expand All @@ -40,7 +26,7 @@ function use(plugin: Plugin) {

let initFlag = false;
let customEffectMeta = {};
function init(initOpt: InitOpt = {}) {
function init(initOpt: CubeState.InitOpt = {}) {
if (initFlag) {
return;
}
Expand All @@ -56,16 +42,16 @@ function init(initOpt: InitOpt = {}) {
// }
function createStore<
S,
R extends EnhanceReducers<S>,
E extends EnhanceEffects<S>
>(opt: Opt<S, R, E>) {
R extends CubeState.EnhanceReducers<S>,
E extends CubeState.EnhanceEffects<S>
>(opt: CubeState.Opt<S, R, E>) {
const storeName = opt.name;
let storeState: S = opt.state;
const storeReducers = opt.reducers;
const storeEffects = opt.effects;
const updaters: Array<Updater<S>> = [];
const updaters: Array<CubeState.Updater<S>> = [];

function useStore<P>(selector: StateSelector<S, P>) {
function useStore<P>(selector: CubeState.StateSelector<S, P>) {
const [state, setState] = useState(() => selector(storeState));

const updater: any = (oldState: S, nextState: S) => {
Expand All @@ -85,10 +71,10 @@ function createStore<
return Object.freeze(state);
}

const effects = {} as Effects<E>;
const effects = {} as CubeState.Effects<E>;
if (typeof storeEffects === "object") {
const effectMeta = {
async call<A, R>(fn: calledFn<A, R>, payload: A) {
async call<A, R>(fn: CubeState.CalledFn<A, R>, payload: A) {
const res = await fn(payload);
return res;
},
Expand All @@ -98,7 +84,6 @@ function createStore<
storeMap
};
Object.keys(storeEffects).forEach(fnName => {
// @ts-ignore
const originalEffect = storeEffects[fnName];
// @ts-ignore
effects[fnName] = async function<A, B>(payload: A, extra?: B) {
Expand Down Expand Up @@ -136,13 +121,12 @@ function createStore<
});
}

const reducers = {} as Reducers<R>;
const reducers = {} as CubeState.Reducers<R>;
if (typeof storeReducers === "object") {
Object.keys(storeReducers).forEach(fnName => {
// @ts-ignore
reducers[fnName] = function(...payload: any) {
let result: any;
// @ts-ignore
const originalReducer = storeReducers[fnName];
const nextState: S = produce<S, S>(storeState, (draft: S) => {
(hookMap.beforeReducer || []).forEach(beforeReducer =>
Expand All @@ -160,13 +144,13 @@ function createStore<
updater(oldState, nextState);
});
return result;
} as EnhanceReducerFn<
} as CubeState.EnhanceReducerFn<
R[Extract<keyof (R extends undefined ? undefined : R), string>]
>;
});
}

function getState<P>(selector: StateSelector<S, P>) {
function getState<P>(selector: CubeState.StateSelector<S, P>) {
return selector(storeState);
}

Expand Down
82 changes: 82 additions & 0 deletions src/typings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
export declare namespace CubeState {
export interface StoreItem {
name: string;
useStore: Function;
effects: Record<string, Function>;
reducers: Record<string, Function>;
getState: Function;
}

export type StoreMap = Record<string, StoreItem>;

export interface InitOpt {
effectMeta?(config: { storeMap: StoreMap }): object;
}

export interface Opt<S, R, E> {
name: string;
state: S;
reducers?: R extends undefined ? undefined : R;
effects?: E extends undefined ? undefined : E;
[k: string]: any;
}

export type StateSelector<S, P> = (state: S) => P;

export interface EnhanceReducers<S> {
[key: string]: EnhanceReducerFn<S>;
}
export type EnhanceReducerFn<S> = (state: S, ...payload: any) => any;

export type Reducers<R> = {
[K in keyof R]: ReducerFn<R[K]>;
};
export type ReducerFn<F> = F extends (state: infer S, ...args: infer A) => any
? (...args: A) => any
: unknown;

export interface EnhanceEffects<S> {
[key: string]: EnhanceEffectFn<S>;
}
export type EnhanceEffectFn<S> = (
meta: EffectMeta<S>,
...args: any
) => Promise<any>;

export interface EffectMeta<S> {
call<A, R>(fn: () => R, ...extra: any): Promise<R>;
call<A, R>(fn: CalledFn<A, R>, payload: A, ...extra: any): Promise<R>;
update(newState: Partial<S>): any;
select<P>(selector: StateSelector<S, P>): P;
}

export type CalledFn<A, R> = (payload: A) => R;

export type Effects<E> = {
[K in keyof E]: EffectFn<E[K]>;
};
export type EffectFn<F> = F extends (
meta: infer U,
...args: infer A
) => Promise<any>
? (...args: A) => ReturnType<F>
: unknown;

export type Updater<S> = (oldState: S, nextState: S) => any;

export type ErrorFn = (e: Error, meta: object) => any;
export type ReducerHook = (result: any, reducerName: string) => any;
export type BeforeEffectHook = (payload: any, meta: object) => any;
export type AfterEffectHook = (result: any, meta: object) => any;
export interface Plugin {
onError?: ErrorFn;
beforeReducer?: ReducerHook;
afterReducer?: ReducerHook;
beforeEffect?: BeforeEffectHook;
afterEffect?: AfterEffectHook;
extraReducers?: Function;
}
export type HookMap = {
[K in keyof Plugin]: Function[];
};
}
15 changes: 0 additions & 15 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,3 @@ export const isPromise = (obj: PromiseLike<any>) => {
typeof obj.then === "function"
);
};

/**
* @param obj The object to inspect.
* @returns True if the argument appears to be a plain object.
*/
// export default function isPlainObject(obj: any): boolean {
// if (typeof obj !== 'object' || obj === null) return false;

// let proto = obj;
// while (Object.getPrototypeOf(proto) !== null) {
// proto = Object.getPrototypeOf(proto);
// }

// return Object.getPrototypeOf(obj) === proto;
// }

0 comments on commit f881293

Please sign in to comment.