Skip to content

Commit

Permalink
chore: bump to 3.5.4
Browse files Browse the repository at this point in the history
  • Loading branch information
fantasticsoul committed Dec 9, 2023
1 parent ee378a6 commit bc57c45
Show file tree
Hide file tree
Showing 40 changed files with 535 additions and 338 deletions.
11 changes: 5 additions & 6 deletions packages/helux-core/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import { addMiddleware } from './factory/common/middleware';
import { addPlugin } from './factory/common/plugin';
import { emit, on } from './factory/common/userBus';
import { action } from './factory/createAction';
import { derive, deriveAtom } from './factory/createDerived';
import { derive, deriveDict } from './factory/createDerived';
import { mutate, mutateDict, runMutate, runMutateTask } from './factory/createMutate';
import { atom, share, shareAtom, shareState } from './factory/createShared';
import { sync, syncer } from './factory/createSync';
import { watch } from './factory/createWatch';
import { flush, reactiveDesc } from './factory/creator/buildReactive';
import { currentDraftRoot, setAtomVal } from './factory/creator/current';
import { getDeriveLoading, runDerive, runDeriveAsync } from './helpers/fnRunner';
import { getDeriveLoading, runDerive, runDeriveTask } from './helpers/fnRunner';
import { getRawState, getSnap } from './helpers/state';
import { useAtom } from './hooks/useAtom';
import { useDerived, useDerivedAtom } from './hooks/useDerived';
import { useDerived } from './hooks/useDerived';
import { useGlobalId } from './hooks/useGlobalId';
import { getActionLoading, getMutateLoading, useActionLoading, useMutateLoading } from './hooks/useLoading';
import { useMutable } from './hooks/useMutable';
Expand All @@ -37,16 +37,15 @@ export {
createShared,
// derive api
derive,
deriveAtom,
deriveDict,
runDerive,
runDeriveAsync,
runDeriveTask,
// watch api
watch,
// hooks api
useAtom,
useReactive,
useDerived,
useDerivedAtom,
useWatch,
useGlobalId,
useService,
Expand Down
2 changes: 1 addition & 1 deletion packages/helux-core/src/consts/user.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { VER as limuVer } from 'limu';

export const VER = '3.5.3';
export const VER = '3.5.4';

export const LIMU_VER = limuVer;

Expand Down
16 changes: 11 additions & 5 deletions packages/helux-core/src/factory/common/check.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { tryAlert } from '@helux/utils';
import { getInternal } from '../../helpers/state';
import { getInternal, getInternalByKey } from '../../helpers/state';
import type { SharedState } from '../../types/base';
import type { TInternal } from '../creator/buildInternal';

Expand All @@ -23,9 +23,15 @@ interface ICheckSharedOptions extends ICheckSharedOptionsBase {
strict?: boolean;
}

export function checkShared<T = SharedState>(sharedState: T, options?: ICheckSharedOptions): TInternal | null {
export function checkShared<T = SharedState | number>(sharedStateOrKey: T, options?: ICheckSharedOptions): TInternal | null {
const { forAtom, label, strict = false } = options || {};
const internal = getInternal(sharedState);
let internal: TInternal;
if (typeof sharedStateOrKey === 'number') {
internal = getInternalByKey(sharedStateOrKey);
} else {
internal = getInternal(sharedStateOrKey);
}

let prefix = label ? `[[${label}]] err:` : 'err:';

if (!internal) {
Expand All @@ -51,6 +57,6 @@ export function checkShared<T = SharedState>(sharedState: T, options?: ICheckSha
/**
* 不抛错误的话,一定返回 internal
*/
export function checkSharedStrict<T = SharedState>(sharedState: T, options?: ICheckSharedOptionsBase): TInternal {
return checkShared(sharedState, { ...(options || {}), strict: true }) as TInternal;
export function checkSharedStrict<T = SharedState | number>(sharedStateOrKey: T, options?: ICheckSharedOptionsBase): TInternal {
return checkShared(sharedStateOrKey, { ...(options || {}), strict: true }) as TInternal;
}
4 changes: 2 additions & 2 deletions packages/helux-core/src/factory/common/derived.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ export function initDeriveFn(options: IInitDeriveFnOptions) {
const canRunTask = runAsync && asyncType === TASK && (immediate ?? !options.fn);
if (task && canRunTask) {
runFn(curFnKey, { isFirstCall: true, sn: fnCtx.renderInfo.sn + 1 })
.then((data: any) => {
checkResult(fnCtx, data, forAtom);
.then((data: [any, Error | null]) => {
checkResult(fnCtx, data[0], forAtom);
})
.catch((err: any) => tryAlert(err));
}
Expand Down
4 changes: 3 additions & 1 deletion packages/helux-core/src/factory/common/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getVal, isDebug, isFn, isMap, isObj, isProxyAvailable, noop, prefixValKey } from '@helux/utils';
import { immut, IOperateParams } from 'limu';
import { immut, IOperateParams, limuUtils } from 'limu';
import { ARR, KEY_SPLITER, MAP, STATE_TYPE } from '../../consts';
import { createOb } from '../../helpers/obj';
import type { Dict, IInnerSetStateOptions, NumStrSymbol, TriggerReason } from '../../types/base';
Expand Down Expand Up @@ -181,3 +181,5 @@ export function isArrLike(parentType?: string) {
export function isArrLikeVal(val: any) {
return Array.isArray(val) || isMap(val);
}

export const { isObject: isDict } = limuUtils;
31 changes: 20 additions & 11 deletions packages/helux-core/src/factory/createAction.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,39 @@
import { getStatusKey, setLoadStatus } from '../factory/creator/loading';
import type { Fn, SharedState } from '../types/base';
import { checkShared } from './common/check';
import { checkSharedStrict } from './common/check';
import { callAsyncMutateFnLogic } from './creator/mutateFn';

const Action = 'Action';

/**
* 内部统一封装,shared 和 atom 走统一的入口,上层接口自己标记对应类型
*/
function innerCreate<T = SharedState>(state: T, options: { fn: Fn; desc: string; label: string }) {
const { fn, desc = '', label } = options;
checkShared(state, { label, strict: true });
const commonParams = { desc, from: 'Action' } as const;
function innerCreate<T = SharedState>(state: T, options: { task: Fn; desc: string; label: string; throwErr?: boolean }) {
const { label, throwErr, desc = '', task } = options;
const internal = checkSharedStrict(state, { label });
// 把 action 函数统一当异步函数去处理,callAsyncMutateFnLogic 内部会自动判断是否需要走异步调用逻辑
const action = (payload: any) => {
// now fn can have a name 'action' at dev mode
const action = (payload: any, throwFnErr?: boolean) => {
// 用户调用 action 独立定义的 throwErr 优先级高于 创建 action 函数时预设的 throwErr
const throwErrVar = throwFnErr ?? throwErr;
return callAsyncMutateFnLogic(state, {
...commonParams,
task: fn,
desc,
task,
from: Action,
throwErr: throwErrVar,
getArgs: ({ draft, draftRoot, setState, desc }) => [{ draft, draftRoot, setState, desc, payload }],
});
};
// now fn can have a name 'action' at dev mode
// 提前记录一个值,方便用户使用 getLoading 时可收集到依赖
setLoadStatus(internal, getStatusKey(Action, desc), { loading: false, ok: true, err: null });
action.__sharedKey = internal.sharedKey;
action.__fnName = desc;
return action;
}

/**
* 创建一个 action 函数,建议设置 desc,这样可以结合 redux-devtool 准确定位到调用源
*/
export function action<T = SharedState>(sharedDict: T) {
return (fn: Fn, desc = '') => innerCreate(sharedDict, { fn, desc, label: 'action' });
export function action<T = SharedState>(sharedState: T) {
return (task: Fn, desc = '', throwErr?: boolean) => innerCreate(sharedState, { task, desc, label: 'action', throwErr });
}
21 changes: 9 additions & 12 deletions packages/helux-core/src/factory/createDerived.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { isFn } from '@helux/utils';
import type { Atom, DeriveAtomFn, DeriveAtomFnItem, DeriveFn, DeriveFnItem, ICreateDeriveLogicOptions, PlainObject } from '../types/base';
import type { Atom, DeriveFn, DeriveFnItem, ICreateDeriveLogicOptions, PlainObject } from '../types/base';
import { initDeriveFn } from './common/derived';

export function createDeriveLogic<T extends any = any>(
fn: DeriveFn<T> | DeriveFnItem | DeriveAtomFn<T> | DeriveAtomFnItem,
options?: ICreateDeriveLogicOptions,
) {
export function createDeriveLogic<T extends any = any>(fn: DeriveFn<T> | DeriveFnItem, options?: ICreateDeriveLogicOptions) {
const fnItem = isFn(fn) ? { fn } : fn || {};
const fnCtx = initDeriveFn({ ...(options || {}), ...fnItem });
return fnCtx;
Expand All @@ -14,15 +11,15 @@ export function createDeriveLogic<T extends any = any>(
/**
* 创建派生结果
*/
export function derive<T = PlainObject>(deriveFn: DeriveFn<T> | DeriveFnItem): T {
const fnCtx = createDeriveLogic<T>(deriveFn);
return fnCtx.proxyResult as T;
export function derive<T = any>(deriveFn: DeriveFn<T> | DeriveFnItem): Atom<T> {
const fnCtx = createDeriveLogic<T>(deriveFn, { forAtom: true });
return fnCtx.proxyResult as Atom<T>;
}

/**
* 为 atom 创建一个派生结果,支持返回 pritimive 类型
* 创建一个返回值为 dict 数据的派生结果,区别于 derive 接口,此接口无自动装箱行为
*/
export function deriveAtom<T = any>(deriveFn: DeriveAtomFn | DeriveAtomFnItem): Atom<T> {
const fnCtx = createDeriveLogic<T>(deriveFn, { forAtom: true });
return fnCtx.proxyResult as Atom<T>;
export function deriveDict<T = PlainObject>(deriveFn: DeriveFn<T> | DeriveFnItem): T {
const fnCtx = createDeriveLogic<T>(deriveFn);
return fnCtx.proxyResult as T;
}
51 changes: 29 additions & 22 deletions packages/helux-core/src/factory/createMutate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { SINGLE_MUTATE } from '../consts';
import { getInternal } from '../helpers/state';
import type { Dict, IRunMutateOptions, MutateFn, MutateFnDict, MutateFnLooseItem, MutateWitness, SharedState } from '../types/base';
import { checkShared, checkSharedStrict } from './common/check';
import type { TInternal } from './creator/buildInternal';
import { callMutateFn, watchAndCallMutateDict } from './creator/mutateFn';
import { parseCreateMutateOpt, parseMutate, parseMutateFn } from './creator/parse';

Expand All @@ -14,27 +15,30 @@ interface ILogicOptions {
/**
* 查找到配置到 mutate 函数并执行
*/
function runMutateFnItem(options: { target: SharedState; desc?: string; forTask?: boolean }) {
function runMutateFnItem<T = SharedState>(options: { target: T; desc?: string; forTask?: boolean }) {
const { target, desc: inputDesc = '', forTask = false } = options;
const { mutateFnDict, snap } = getInternal(target);
const desc = inputDesc || SINGLE_MUTATE; // 未传递任何描述,尝试调用可能存在的单函数

const item = mutateFnDict[desc];
if (!item) return snap;
if (!item) return [snap, new Error(`mutate fn ${desc} not defined`)] as [any, Error | null];
// 指定了 task 但未配置 task,返回最近一次修改结果的快照
if (forTask && !item.task) return snap;
if (forTask && !item.task) return [snap, new Error(`mutate task ${desc} not defined`)] as [any, Error | null];

// 调用 desc 对应的函数
return callMutateFn(target, { ...item, forTask });
}

function makeWitness(target: SharedState, desc: string, oriDesc: string, snap: any) {
function makeWitness(target: SharedState, desc: string, oriDesc: string, internal: TInternal) {
return {
call: () => runMutateFnItem({ target, desc }), // 呼叫同步函数的句柄
call: () => runMutateFnItem({ target, desc }) as [any, Error | null], // 呼叫同步函数的句柄
callTask: () => Promise.resolve(runMutateFnItem({ target, desc, forTask: true })), // 呼叫异步函数的句柄
desc,
oriDesc,
snap,
getSnap: () => internal.snap,
snap: internal.snap,
/** for initLoadingCtx */
__sharedKey: internal.sharedKey,
};
}

Expand Down Expand Up @@ -65,7 +69,7 @@ function configureMutateFn(options: IConfigureMutateFnOpt) {
internal.mutateFnDict[stdFnItem.desc] = stdFnItem;
const dict = { [stdFnItem.desc]: stdFnItem };
watchAndCallMutateDict({ target, dict });
return makeWitness(target, stdFnItem.desc, stdFnItem.oriDesc, internal.snap);
return makeWitness(target, stdFnItem.desc, stdFnItem.oriDesc, internal);
}

/**
Expand All @@ -78,7 +82,7 @@ function configureMutateDict(options: IConfigureMutateDictOpt): any {
watchAndCallMutateDict({ target, dict });
const witnessDict: Dict<MutateWitness> = {}; // 具体类型定义见 types-api multiDict
Object.keys(dict).forEach((desc) => {
witnessDict[desc] = makeWitness(target, desc, desc, internal.snap);
witnessDict[desc] = makeWitness(target, desc, desc, internal);
});
return witnessDict;
}
Expand All @@ -89,49 +93,52 @@ function configureMutateDict(options: IConfigureMutateDictOpt): any {
function prepareParms<T extends SharedState>(target: T, options: ILogicOptions) {
const { label, descOrOptions, forTask = false } = options;
const { desc, strict } = parseCreateMutateOpt(descOrOptions);
if (!desc) {
return { ok: false, desc, forTask, err: new Error('miss desc') };
}
const internal = checkShared(target, { label, strict });
if (!internal || !desc) {
return { ok: false, desc, forTask };
if (!internal) {
return { ok: false, desc, forTask, err: new Error('not a valid atom or shared result') };
}
return { ok: true, desc, forTask };
return { ok: true, desc, forTask, err: null };
}

/**
* 执行匹配 desc 的 mutate 函数
*/
export function runMutateLogic<T extends SharedState>(target: T, options: ILogicOptions): T | Promise<T> {
const { ok, desc, forTask } = prepareParms(target, options);
export function runMutateLogic<T extends SharedState>(target: T, options: ILogicOptions): [T, Error | null] | Promise<[T, Error | null]> {
const { ok, desc, forTask, err } = prepareParms(target, options);
if (!ok) {
return forTask ? Promise.resolve(target) : target;
return forTask ? Promise.resolve([target, err]) : [target, err];
}
const nextSnap = runMutateFnItem({ target, desc, forTask });
return forTask ? Promise.resolve(nextSnap) : nextSnap;
const result = runMutateFnItem({ target, desc, forTask });
return forTask ? Promise.resolve(result) : result;
}

/**
* 执行匹配 desc 的 mutate 函数
*/
export function runMutate<T extends SharedState>(target: T, descOrOptions?: string | IRunMutateOptions): T {
return runMutateLogic(target, { descOrOptions, label: 'runMutate' }) as T;
export function runMutate<T extends SharedState>(target: T, descOrOptions?: string | IRunMutateOptions) {
return runMutateLogic(target, { descOrOptions, label: 'runMutate' });
}

/**
* 执行匹配 desc 的 mutate task 函数(存在才执行)
*/
export function runMutateTask<T extends SharedState>(target: T, descOrOptions?: string | IRunMutateOptions): Promise<T> {
return runMutateLogic(target, { descOrOptions, label: 'runMutateTask', forTask: true }) as Promise<T>;
export function runMutateTask<T extends SharedState>(target: T, descOrOptions?: string | IRunMutateOptions) {
return runMutateLogic(target, { descOrOptions, label: 'runMutateTask', forTask: true }) as Promise<[T, Error | null]>;
}

/**
* 为 shared 创建一个 mutate 函数,如需创建异步计算结果,配置 task 即可
* 为 atom 或 share 创建一个 mutate 函数,如需创建异步计算结果,配置 task 即可
* 更详细的泛型定义见 types-api.d.ts
*/
export function mutate(target: SharedState) {
return (fnItem: MutateFnLooseItem<any, any> | MutateFn<any, any>) => configureMutateFn({ target, fnItem, label: 'mutate' });
}

/**
* 为 shared 创建多个 mutate 函数,接收一个字典配置来完成多函数配置,更详细的泛型定义见 types-api.d.ts
* 为 atom 或 share 创建多个 mutate 函数,接收一个字典配置来完成多函数配置,更详细的泛型定义见 types-api.d.ts
*/
export function mutateDict<T extends SharedState>(target: T) {
return <D = MutateFnDict<T>>(fnDict: D) => configureMutateDict({ target, fnDict, label: 'mutateDict' });
Expand Down
Loading

0 comments on commit bc57c45

Please sign in to comment.