Skip to content
This repository has been archived by the owner on Dec 2, 2024. It is now read-only.

Commit

Permalink
fix 1.6.0 release issue
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathan-chancetop committed Oct 25, 2023
1 parent 95c3838 commit 2823302
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 3 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"build": "node script/build.js",
"test": "jest --config config/jest.config.js",
"format": "prettier --write \"{src,test,script,config}/**/*.{js,ts,tsx,json}\"",
"prepublishOnly": "node script/build.js --mode fast",
"prepublishOnly": "node ../../script/build.js --mode fast",
"deploy": "node script/publish.js"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion src/decorator/Interval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export interface OnTickMethodDecorator<Fn extends ActionHandler & TickIntervalDe
/**
* For *onTick() action only, to specify to tick interval in second.
*/
export function Interval<Fn extends ActionHandler>(second: number) {
export function Interval<Fn extends ActionHandler>(second: number = 5) {
return function (target: Fn, _: OnTickMethodDecorator<Fn>) {
Reflect.defineProperty(target, "tickInterval", {
value: second,
Expand Down
107 changes: 106 additions & 1 deletion src/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React, {useMemo} from "react";
import {type Action as InterfaceAction, type AnyAction} from "redux";
import {useDispatch, useSelector} from "react-redux";
import type {Action, State} from "./reducer";
Expand Down Expand Up @@ -67,3 +67,108 @@ export function usePromise() {
const dispatch: Dispatch<any> = useDispatch();
return dispatch;
}

type Keys<S extends State, T extends keyof S["app"]> = keyof S["app"][T] & string;

const getModuleState = <S extends State, T extends keyof S["app"] & string, P extends keyof S["app"][T]>(state: S, moduleStateName: T, keys: Array<P>): Pick<S["app"][T], P> => {
if (!state.app[moduleStateName]) {
return {} as S["app"][T];
}
return keys.reduce(
(moduleState, key) => {
moduleState[key] = state.app[moduleStateName][key];
return moduleState;
},
{} as S["app"][T]
);
};

const compareState = <T extends keyof State["app"], P extends keyof State["app"][T], S extends Pick<State["app"][T], P>>(left: S, right: S, keys: Array<P>): boolean => {
if (!left || !right) {
return true;
}
for (const key of keys) {
if (left[key] !== right[key]) {
return false;
}
}
return true;
};

export function useModuleState<
RS extends State,
M extends Partial<{
[key in keyof RS["app"]]: Array<Keys<RS, key>>;
}>,
T extends keyof M,
>(
moduleKeys: M
): {
[key in T]: key extends keyof RS["app"] ? Pick<RS["app"][key], M[key] extends Array<Keys<RS, key>> ? M[key][number] : never> : never;
};
export function useModuleState<RS extends State, M extends keyof RS["app"], T extends keyof RS["app"][M]>(moduleStateName: M, keys: Array<T>): Pick<RS["app"][M], T>;

export function useModuleState<
RS extends State,
M extends
| {
[key in keyof RS["app"] as string]: Array<Keys<RS, key>>;
}
| (keyof RS["app"] & string),
T extends M extends keyof RS["app"] ? keyof RS["app"][M] : keyof M,
ModuleKeys extends Array<keyof RS["app"] & string>,
S extends Pick<RS["app"], keyof RS["app"]>,
>(moduleNameOrKeys: M, keys?: Array<T>) {
const state = useSelector(
(state: RS) => {
if (typeof moduleNameOrKeys === "string") {
return getModuleState(state, moduleNameOrKeys, keys as any) as M extends keyof RS["app"] ? (T extends keyof RS["app"][M] ? Pick<RS["app"][M], T> : never) : never;
}
return (
Object.keys(
moduleNameOrKeys as {
[key in keyof RS["app"] as string]: Array<Keys<RS, key>>;
}
) as ModuleKeys
).reduce(
(result, moduleStateName) => {
result[moduleStateName] = getModuleState(
state,
moduleStateName,
(
moduleNameOrKeys as {
[key in keyof RS["app"] as string]: Array<Keys<RS, key>>;
}
)[moduleStateName]
) as any;
return result;
},
{} as {
[key in keyof RS["app"]]: Pick<RS["app"][key], keyof RS["app"][key]>;
}
);
},
(left, right) => {
if (typeof moduleNameOrKeys === "string") {
moduleNameOrKeys;
return compareState(left, right, keys as any);
}

// return compareRootState(left as S, right as S, moduleNameOrKeys[moduleStateName] as Array<Keys<typeof moduleStateName>>);
return !(Object.keys(moduleNameOrKeys) as ModuleKeys).some(
moduleStateName =>
!compareState(
(left as S)[moduleStateName],
(right as S)[moduleStateName],
(
moduleNameOrKeys as {
[key in keyof RS["app"] as string]: Array<Keys<RS, key>>;
}
)[moduleStateName]
)
);
}
);

return useMemo(() => state ?? {}, [state]);
}
9 changes: 9 additions & 0 deletions src/type/state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type {State} from "../reducer";

export interface RootState extends State {
app: {
[key: string]: {
[key: string]: any;
};
};
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"extends": "./config/tsconfig.base.json",
"compilerOptions": {
"baseUrl": "./src",
"rootDir": "src",
"outDir": "lib",
"composite": true,
Expand Down

0 comments on commit 2823302

Please sign in to comment.