Skip to content

Commit

Permalink
build: v4.3.6
Browse files Browse the repository at this point in the history
  • Loading branch information
fancyzhong committed Jun 20, 2024
1 parent ea2edd4 commit db995c6
Show file tree
Hide file tree
Showing 18 changed files with 70 additions and 21 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

click helux-core [change log](./packages/helux-core/CHANGELOG.md) to see more details

[released] - 2024-06-20

relese `4.3.6` to fix server mem leak( add `RUN_AT_SERVER` judgement)

[released] - 2024-01-16

- fix issue [136](https://github.com/heluxjs/helux/issues/136)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "helux",
"version": "4.3.5",
"version": "4.3.6",
"description": "A reactive atomic state engine for React like.",
"keywords": [],
"author": {
Expand Down
4 changes: 4 additions & 0 deletions packages/helux-core/src/consts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ export const PROTO_KEY = '__proto__';

export const HAS_PROXY = isProxyAvailable();

// export const RUN_AT_SERVER = isServer();
export const RUN_AT_SERVER = false;
// export const RUN_AT_SERVER = true;

/** 提供给 sync 返回 undefined 时之用 */
export const UNDEFINED = createSymbol('HeluxUndefined');

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 = '4.3.5';
export const VER = '4.3.6';

export const LIMU_VER = limuVer;

Expand Down
2 changes: 1 addition & 1 deletion packages/helux-core/src/factory/common/ctor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export function newMutateFnItem(partial?: Partial<IMutateFnStdItem>): IMutateFnS

export function newFnCtx() {
const base: IFnCtx = {
fnKey: '', // 在 feDep.mapFn 阶段会生成
fnKey: '', // 在 fnDep.mapFn 阶段会生成
fn: noop,
subFnInfo: fnItem,
checkDeadCycle: true,
Expand Down
2 changes: 1 addition & 1 deletion packages/helux-core/src/factory/common/derived.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export function initDeriveFn(options: IInitDeriveFnOptions) {
// 第一次调用时,如未显示定义 immediate 值,则触发规律是没有 fn 则执行,有 fn 则不执行
const canRunTask = runAsync && asyncType === TASK && (immediate ?? !options.fn);
if (task && canRunTask) {
runFn(curFnKey, { isFirstCall: true, sn: fnCtx.renderInfo.sn + 1 })
runFn(curFnKey, { isFirstCall: true, sn: fnCtx.renderInfo.sn + 1, throwErr: true })
.then((data: [any, Error | null]) => {
checkResult(fnCtx, data[0], forAtom);
})
Expand Down
5 changes: 3 additions & 2 deletions packages/helux-core/src/factory/creator/globalId.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { delListItem, nodupPush, safeMapGet } from '@helux/utils';
import { STATE_TYPE } from '../../consts';
import { RUN_AT_SERVER, STATE_TYPE } from '../../consts';
import { getInternal } from '../../helpers/state';
import type { CoreApiCtx } from '../../types/api-ctx';
import type { Fn, NumStrSymbol } from '../../types/base';
Expand Down Expand Up @@ -37,7 +37,8 @@ export function getGlobalEmptyInternal() {
}

export function mapGlobalId(id: NumStrSymbol, insKey: number) {
if (!id) return;
// 服务端运行时,不做 globalId 映射,避免内存浪费
if (!id || RUN_AT_SERVER) return;
const keys = getGlobalIdInsKeys(id);
nodupPush(keys, insKey);
}
Expand Down
3 changes: 2 additions & 1 deletion packages/helux-core/src/factory/creator/operateState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ export function handleOperate(opParams: IOperateParams, opts: { internal: TInter
if (currReactive.onRead) {
currReactive.onRead(opParams);
} else {
const runingFnCtx = getRunningFn().fnCtx;
// 支持对 draft 操作时可以收集到依赖: draft.a = draft.b + 1
if (getRunningFn().fnCtx) {
if (runingFnCtx) {
recordFnDepKeys([depKey], { sharedKey });
}
// 仅 top reactive 触发以下逻辑,为 block 收集依赖
Expand Down
8 changes: 7 additions & 1 deletion packages/helux-core/src/helpers/blockCtx.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { RUN_AT_SERVER } from '../consts';
import { getBlockCtxMap } from '../factory/common/blockScope';
import { genBlockKey } from '../factory/common/key';
import { getBlockScope } from '../factory/common/speedup';
Expand Down Expand Up @@ -30,7 +31,12 @@ export function initBlockCtx(isDynamic: boolean, enableStatus = false) {
}
const blockKey = genBlockKey();
const blockCtx = newBlockCtx(blockKey, enableStatus);
getBlockCtxMap(isDynamic).set(blockKey, blockCtx);

// 非服务器端执行才记录 blockCtx ,避免内存泄露
if (!RUN_AT_SERVER) {
getBlockCtxMap(isDynamic).set(blockKey, blockCtx);
}

return blockCtx;
}

Expand Down
10 changes: 9 additions & 1 deletion packages/helux-core/src/helpers/fnCtx.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { delListItem, includeOne, matchDictKey, nodupPush } from '@helux/utils';
import { RUN_AT_SERVER } from '../consts';
import { newFnCtx } from '../factory/common/ctor';
import { getCtxMap, getFnCtx, getFnKey, markFnKey } from '../factory/common/fnScope';
import { getFnScope } from '../factory/common/speedup';
Expand Down Expand Up @@ -78,7 +79,14 @@ export function registerFn(fn: Fn, options: { specificProps: Partial<IFnCtx> & {
const props = { fn, fnKey, ...specificProps };
// 如 fnCtxBase 存在则 fnCtx 指向用户透传的 fnCtxBase
const fnCtx = fnCtxBase ? Object.assign(fnCtxBase, props) : buildFnCtx(props);
getCtxMap(scopeType).set(fnKey, fnCtx);

// static 调用派生时始终记录 fnCtx
// hook 调用派生时仅在非服务器端执行才记录 fnCtx ,避免内存泄露
if (scopeType === 'static' || !RUN_AT_SERVER) {
// debugger;
getCtxMap(scopeType).set(fnKey, fnCtx);
}

return fnCtx;
}

Expand Down
11 changes: 9 additions & 2 deletions packages/helux-core/src/helpers/fnDep.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { nodupPush, safeMapGet } from '@helux/utils';
import { DERIVE, EXPIRE_MS, NOT_MOUNT, PROTO_KEY, SIZE_LIMIT, UNMOUNT } from '../consts';
import { DERIVE, EXPIRE_MS, NOT_MOUNT, PROTO_KEY, RUN_AT_SERVER, SIZE_LIMIT, UNMOUNT } from '../consts';
import { delFnDepData, getFnCtx, getRunningFn, opUpstreamFnKey } from '../factory/common/fnScope';
import { hasChangedNode } from '../factory/common/sharedScope';
import { getFnScope } from '../factory/common/speedup';
Expand All @@ -24,6 +24,12 @@ export function recordFnDepKeys(inputDepKeys: string[], options: { sharedKey?: n
DEPS_CB.current()(inputDepKeys);
return;
}
const { fnKey, scopeType } = fnCtx;
// 服务端运行的话,不记录任何 hook 实例对应的相关映射关系,避免不必要的服务端内存开销
if (RUN_AT_SERVER && scopeType === 'hook') {
return;
}

const { DEPKEY_FNKEYS_MAP, SKEY_FNKEYS_MAP } = getFnScope();
const { belongCtx, sharedKey } = options;

Expand All @@ -42,7 +48,6 @@ export function recordFnDepKeys(inputDepKeys: string[], options: { sharedKey?: n
nodupPush(belongCtx.nextLevelFnKeys, runningFnCtx.fnKey);
}

const { fnKey } = fnCtx;
inputDepKeys.forEach((depKey: string) => {
if (PROTO_KEY === depKey || isIgnore) {
return;
Expand Down Expand Up @@ -70,6 +75,8 @@ export function ensureFnDepData(fnCtx?: IFnCtx) {
/** TODO 后续接入内置 useEffect 后,这里可考虑移除 */
export function recoverDep(fnCtx: IFnCtx) {
const { FNKEY_HOOK_CTX_MAP, UNMOUNT_INFO_MAP } = getFnScope();
if (RUN_AT_SERVER) return;

const { fnKey } = fnCtx;
FNKEY_HOOK_CTX_MAP.set(fnKey, fnCtx);
opUpstreamFnKey(fnCtx, true);
Expand Down
18 changes: 15 additions & 3 deletions packages/helux-core/src/helpers/insCtx.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { delListItem, enureReturnArr, isFn, isSymbol, nodupPush, prefixValKey, warn } from '@helux/utils';
import { immut } from 'limu';
import { DICT, EXPIRE_MS, IS_DERIVED_ATOM, NOT_MOUNT, OTHER, RENDER_END, RENDER_START } from '../consts';
import { DICT, EXPIRE_MS, IS_DERIVED_ATOM, NOT_MOUNT, OTHER, RENDER_END, RENDER_START, RUN_AT_SERVER } from '../consts';
import { newOpParams } from '../factory/common/ctor';
import { hasRunningFn } from '../factory/common/fnScope';
import { genInsKey } from '../factory/common/key';
Expand Down Expand Up @@ -65,6 +65,8 @@ export function attachInsProxyState(insCtx: InsCtxDef) {
const { rawState, isDeep, sharedKey, onRead, forAtom } = internal;
if (isDeep) {
const onOperate: OnOperate = (opParams) => {
// 服务端执行,无需记录依赖关系
if (RUN_AT_SERVER) return;
const { isBuiltInFnKey, key } = opParams;
if (isBuiltInFnKey) return;
if (isSymbol(key)) {
Expand Down Expand Up @@ -99,6 +101,8 @@ export function attachInsProxyState(insCtx: InsCtxDef) {
return true;
},
get: (target: Dict, key: string) => {
// 服务端执行,无需记录依赖关系
if (RUN_AT_SERVER) return;
const value = target[key];
if (isSymbol(key)) {
return handleHeluxKey(true, forAtom, sharedKey, key, value);
Expand Down Expand Up @@ -252,8 +256,15 @@ export function buildInsCtx(options: Ext<IInnerUseSharedOptions>): InsCtxDef {
}
},
};

globalId && mapGlobalId(globalId, insKey);
attachInsProxyState(insCtx);

// 是服务器端执行的话,不需要真正的去映射实例和共享状态关系,避免内存泄露
if (RUN_AT_SERVER) {
return insCtx;
}

internal.mapInsCtx(insCtx, insKey);
internal.recordId(id, insKey);

Expand Down Expand Up @@ -281,7 +292,7 @@ export function buildInsCtx(options: Ext<IInnerUseSharedOptions>): InsCtxDef {
export function attachInsDerivedResult(fnCtx: IFnCtx) {
const { result, forAtom } = fnCtx;

// MARK: 此计算结果不具备依赖收集特性,如需要此特性可使用 share接口的 mutate 配置可变派生结果
// MARK: 此计算结果不具备依赖收集特性,如需要此特性可使用 share 接口的 mutate 配置可变派生结果
// LABEL: proxyResult
fnCtx.proxyResult = createOb(result, {
set: () => {
Expand All @@ -292,7 +303,8 @@ export function attachInsDerivedResult(fnCtx: IFnCtx) {
if (IS_DERIVED_ATOM === resultKey) {
return forAtom;
}
if (RENDER_START === fnCtx.renderStatus) {
// 服务端运行时,就不需要记录hook使用导出结果时的相关映射关系了,避免内存浪费
if (RENDER_START === fnCtx.renderStatus && !RUN_AT_SERVER) {
fnDep.ensureFnDepData(fnCtx);
}
return result[resultKey];
Expand Down
7 changes: 6 additions & 1 deletion packages/helux-core/src/helpers/state.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getSafeNext, warn } from '@helux/utils';
import { SHARED_KEY } from '../consts';
import { RUN_AT_SERVER, SHARED_KEY } from '../consts';
import { getInternalMap } from '../factory/common/internal';
import { getSharedScope } from '../factory/common/speedup';
import type { TInternal } from '../factory/creator/buildInternal';
Expand Down Expand Up @@ -76,6 +76,11 @@ export function getSharedState(sharedKey: number) {
}

export function recordMod(sharedState: Dict, options: ParsedOptions) {
// 服务端运行,没必要记录模块信息到 global 上,避免服务端内存浪费、冗余的模块重复信息提示(nextjs里同一个地方的share代码会被多次调用)
if (RUN_AT_SERVER) {
return;
}

const { rootState, ctx } = getRoot();
const { moduleName, usefulName } = options;
const existedShared = rootState[usefulName];
Expand Down
5 changes: 2 additions & 3 deletions packages/helux-core/src/hooks/common/derived.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,9 @@ export function genDerivedResult(deriveCtx: IDeriveCtx, options: IUseDerivedLogi
const isChanged = isInputChanged(fnCtx, input, result);
if (!isChanged) {
return;
} else {
isCtxChanged = true;
ensureHotReload(fnCtx);
}
isCtxChanged = true;
ensureHotReload(fnCtx);
}

deriveCtx.input = result;
Expand Down
2 changes: 1 addition & 1 deletion packages/helux-core/src/hooks/common/useAtomLogic.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Fn } from 'helux';
import type { Fn } from 'helux';
import { RENDER_END, RENDER_START } from '../../consts';
import type { InsCtxDef } from '../../factory/creator/buildInternal';
import { INS_CTX } from '../../factory/creator/current';
Expand Down
2 changes: 1 addition & 1 deletion packages/helux-core/src/types/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ import type {
} from './base';

export declare const cst: {
VER: '4.3.5';
VER: '4.3.6';
LIMU_VER: string;
EVENT_NAME: {
/** 共享状态创建时的事件 */
Expand Down
2 changes: 2 additions & 0 deletions packages/helux-utils/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export declare function noopVoid(...args: any[]): void;
export declare function noopArgs<T extends any[] = any[]>(...args: T): T;
export declare function noopArr(...args: any[]): any[];
export declare function noopAny(...args: any[]): any;
/** 是否是在 server 端运行 */
export declare function isServer(): boolean;
export declare function isMap(mayMap: any): boolean;
export declare function isMax(input: number): boolean;
export declare function isDebug(): boolean;
Expand Down
2 changes: 1 addition & 1 deletion packages/helux-utils/src/is.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const toString = Object.prototype.toString;
const MAP_DESC = '[object Map]';

export function isServer() {
return !(typeof window != 'undefined' && window.document);
return GLOBAL_REF.window === undefined && GLOBAL_REF.global !== undefined;
}

export function isMap(mayMap: any) {
Expand Down

0 comments on commit db995c6

Please sign in to comment.