diff --git a/jest.config.ts b/jest.config.ts index e91da3d..8d8424a 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -174,7 +174,7 @@ export default { }, // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation - transformIgnorePatterns: ['/node_modules/(?!(alova|@alova\\/mock)/)'] + transformIgnorePatterns: ['/node_modules/(?!(alova|@alova/mock))'] // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them // unmockedModulePathPatterns: undefined, diff --git a/package-lock.json b/package-lock.json index abe35f1..6b507e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "@typescript-eslint/eslint-plugin": "^5.43.0", "@typescript-eslint/parser": "^5.43.0", "@vue/vue3-jest": "^29.2.4", - "alova": "^2.10.1", + "alova": "^2.11.0", "babel-jest": "^29.2.2", "commitizen": "^4.3.0", "commitlint": "^17.5.1", @@ -5756,9 +5756,9 @@ } }, "node_modules/alova": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/alova/-/alova-2.10.1.tgz", - "integrity": "sha512-eNQ3o+Svie7w0mfEeSmgoRrJcmxEIed5b2j4hfIvpOSQNaOO5qNaf0yc0GtUNBpM/cGoKjaJWaSn/bP+fSilrA==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/alova/-/alova-2.11.0.tgz", + "integrity": "sha512-RAKGPddlQJP0TRaSVTOzM3MrgVQ5AJDeX/sNo8zdqB/uEaRG8q2sp3maXae0cR+FTER1cRA+P+drARDwKhhj5g==", "dev": true, "engines": { "node": ">= 0.12.0" @@ -21629,17 +21629,17 @@ }, "packages/scene-react": { "name": "@alova/scene-react", - "version": "1.1.7", + "version": "1.1.8", "license": "MIT" }, "packages/scene-svelte": { "name": "@alova/scene-svelte", - "version": "1.1.7", + "version": "1.1.8", "license": "MIT" }, "packages/scene-vue": { "name": "@alova/scene-vue", - "version": "1.1.7", + "version": "1.1.8", "license": "MIT" } }, @@ -25829,9 +25829,9 @@ } }, "alova": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/alova/-/alova-2.10.1.tgz", - "integrity": "sha512-eNQ3o+Svie7w0mfEeSmgoRrJcmxEIed5b2j4hfIvpOSQNaOO5qNaf0yc0GtUNBpM/cGoKjaJWaSn/bP+fSilrA==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/alova/-/alova-2.11.0.tgz", + "integrity": "sha512-RAKGPddlQJP0TRaSVTOzM3MrgVQ5AJDeX/sNo8zdqB/uEaRG8q2sp3maXae0cR+FTER1cRA+P+drARDwKhhj5g==", "dev": true }, "ansi-escapes": { diff --git a/package.json b/package.json index b0f4bfd..1ed330c 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "@typescript-eslint/eslint-plugin": "^5.43.0", "@typescript-eslint/parser": "^5.43.0", "@vue/vue3-jest": "^29.2.4", - "alova": "^2.10.1", + "alova": "^2.11.0", "babel-jest": "^29.2.2", "commitizen": "^4.3.0", "commitlint": "^17.5.1", diff --git a/src/framework/react.js b/src/framework/react.js index fa0a3f4..0b0ecd4 100644 --- a/src/framework/react.js +++ b/src/framework/react.js @@ -1,5 +1,5 @@ import { isArray, isFn, isObject, map, noop, pushItem } from '@/helper'; -import { falseValue, undefinedValue } from '@/helper/variables'; +import { falseValue } from '@/helper/variables'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; /** @@ -13,7 +13,7 @@ export const $ = (initialState, isRef) => { const state = useState(initialState); if (isRef) { const ref = useFlag$(); - ref.v = state[0]; + ref.current = state[0]; state[2] = ref; // 将引用值保存到数组中 } return state; @@ -32,7 +32,7 @@ export const $$ = (factory, deps, isRef) => { const memoAry = [memo, noop]; if (isRef) { const ref = useFlag$(); - ref.v = memo; + ref.current = memo; pushItem(memoAry, ref); } return memoAry; @@ -46,7 +46,7 @@ export const $$ = (factory, deps, isRef) => { */ export const _$ = state => { if (isArray(state) && isFn(state[1])) { - return state[2] ? state[2].v : state[0]; + return state[2] ? state[2].current : state[0]; } return state; }; @@ -73,14 +73,14 @@ export const _expBatch$ = (...states) => map(states, s => _exp$(s)); */ export const upd$ = (state, newData) => { if (isFn(newData)) { - const oldState = state[2] ? state[2].v : state[0]; + const oldState = state[2] ? state[2].current : state[0]; newData = newData(isArray(oldState) ? [...oldState] : isObject(oldState) ? { ...oldState } : oldState); } state[1](newData); // 如果有引用类型值,也要更新它 if (state[2]) { - state[2].v = newData; + state[2].current = newData; } }; @@ -109,11 +109,7 @@ export const onMounted$ = cb => useEffect(cb, []); * 为解决这个问题,在react中需使用useRef作为标识 * @param initialValue 初始值 */ -export const useFlag$ = initialValue => { - const ref = useRef(initialValue); - ref.v === undefinedValue && (ref.v = initialValue); - return ref; -}; +export const useFlag$ = initialValue => useRef(initialValue); /** * 将alova的hook返回状态如loading、data等转换为不受闭包陷阱影响的值 @@ -124,7 +120,7 @@ export const useFlag$ = initialValue => { export const useRequestRefState$ = requestState => { const requestStateWrapper = [requestState, noop]; const ref = useFlag$(); - ref.v = requestState; + ref.current = requestState; pushItem(requestStateWrapper, ref); return requestStateWrapper; }; @@ -136,7 +132,7 @@ export const useRequestRefState$ = requestState => { */ export const useMemorizedCallback$ = callback => { const ref = useFlag$(); - ref.v = callback; + ref.current = callback; return useCallback((...args) => { callback.apply(null, args); }, []); diff --git a/src/framework/svelte.js b/src/framework/svelte.js index f916143..21bb61f 100644 --- a/src/framework/svelte.js +++ b/src/framework/svelte.js @@ -1,4 +1,4 @@ -import { __self, createSyncOnceRunner, isFn, map } from '@/helper'; +import { createSyncOnceRunner, isFn, map, __self } from '@/helper'; import { falseValue, trueValue, undefinedValue } from '@/helper/variables'; import { onMount } from 'svelte'; import { derived, writable } from 'svelte/store'; @@ -87,7 +87,7 @@ export const onMounted$ = cb => { * 兼容react * @param initialValue 初始值 */ -export const useFlag$ = initialValue => ({ v: initialValue }); +export const useFlag$ = initialValue => ({ current: initialValue }); /** * 由于在react下,use hook返回的loading、data等状态为普遍值,将会受闭包影响 diff --git a/src/framework/type.ts b/src/framework/type.ts index 68601c2..a3c2de0 100644 --- a/src/framework/type.ts +++ b/src/framework/type.ts @@ -73,7 +73,7 @@ export type TonMounted$ = (cb: () => void) => void; * 兼容react * @param initialValue 初始值 */ -export type TuseFlag$ = (initialValue: T) => { v: T }; +export type TuseFlag$ = (initialValue: T) => { current: T }; /** * 将alova的hook返回状态如loading、data等转换为不受闭包陷阱影响的值 diff --git a/src/framework/vue.js b/src/framework/vue.js index d3fcfe4..28aa269 100644 --- a/src/framework/vue.js +++ b/src/framework/vue.js @@ -1,6 +1,6 @@ -import { __self, isFn, map } from '@/helper'; +import { isFn, map, __self } from '@/helper'; import { trueValue } from '@/helper/variables'; -import { computed, ref, onMounted as vueOnMounted, watch as vueWatch } from 'vue'; +import { computed, onMounted as vueOnMounted, ref, watch as vueWatch } from 'vue'; /** * 创建状态 @@ -69,7 +69,7 @@ export const onMounted$ = cb => { * 兼容react * @param initialValue 初始值 */ -export const useFlag$ = initialValue => ({ v: initialValue }); +export const useFlag$ = initialValue => ({ current: initialValue }); /** * 由于在react下,use hook返回的loading、data等状态为普遍值,将会受闭包影响 diff --git a/src/hooks/pagination/usePagination.js b/src/hooks/pagination/usePagination.js index 6dc22bb..55b984d 100644 --- a/src/hooks/pagination/usePagination.js +++ b/src/hooks/pagination/usePagination.js @@ -63,7 +63,7 @@ export default function ( const pageSize = $(initialPageSize, trueValue); const data = $([], trueValue); const handerRef = useFlag$(); - handerRef.v = handler; + handerRef.current = handler; // 保存当前hook所使用到的所有method实例快照 const { @@ -71,7 +71,7 @@ export default function ( get: getSnapshotMethods, save: saveSnapshot, remove: removeSnapshot - } = useFlag$(createSnapshotMethodsManager(page => handerRef.v(page, _$(pageSize)))).v; + } = useFlag$(createSnapshotMethodsManager(page => handerRef.current(page, _$(pageSize)))).current; const listDataGetter = rawData => dataGetter(rawData) || rawData; const getHandlerMethod = (refreshPage = _$(page)) => { @@ -86,7 +86,7 @@ export default function ( // 监听状态变化时,重置page为1 watch$(watchingStates, () => { upd$(page, 1); - isReset.v = trueValue; + isReset.current = trueValue; }); // 兼容react,将需要代理的函数存放在此 @@ -95,11 +95,12 @@ export default function ( const createDelegationAction = actionName => (...args) => - delegationActions.v[actionName](...args); + delegationActions.current[actionName](...args); const states = useWatcher(getHandlerMethod, [...watchingStates, _exp$(page), _exp$(pageSize)], { immediate, initialData, debounce, + abortLast: falseValue, middleware(ctx, next) { middleware( { @@ -128,10 +129,10 @@ export default function ( // 监听值改变时将会重置为第一页,此时会触发两次请求,在这边过滤掉一次请求 let requestPromise = promiseResolve(); - if (!isReset.v) { + if (!isReset.current) { requestPromise = next(); - } else if (requestCountInReseting.v === 0) { - requestCountInReseting.v++; + } else if (requestCountInReseting.current === 0) { + requestCountInReseting.current++; requestPromise = next(); } return requestPromise; @@ -260,7 +261,7 @@ export default function ( // 如果追加数据,才更新data if (append) { // 如果是reset则先清空数据 - isReset.v && upd$(data, []); + isReset.current && upd$(data, []); if (refreshPage === undefinedValue) { upd$(data, [..._$(data), ...listData]); } else if (refreshPage) { @@ -273,8 +274,8 @@ export default function ( } else { upd$(data, listData); } - isReset.v = falseValue; - requestCountInReseting.v = 0; + isReset.current = falseValue; + requestCountInReseting.current = 0; }); // 获取列表项所在位置 @@ -307,7 +308,7 @@ export default function ( } }); - const removeSyncRunner = useFlag$(createSyncOnceRunner()).v; + const removeSyncRunner = useFlag$(createSyncOnceRunner()).current; // 删除除此usehook当前页和下一页的所有相关缓存 const invalidatePaginationCache = (all = falseValue) => { const pageVal = _$(page); @@ -338,7 +339,7 @@ export default function ( // 单独拿出来的原因是 // 无论同步调用几次insert、remove,或它们组合调用,reset操作只需要异步执行一次 - const resetSyncRunner = useFlag$(createSyncOnceRunner()).v; + const resetSyncRunner = useFlag$(createSyncOnceRunner()).current; const resetCache = () => resetSyncRunner(() => { _$(fetchingRef) && abortFetch(); @@ -493,12 +494,12 @@ export default function ( */ const reload = useMemorizedCallback$(() => { invalidatePaginationCache(trueValue); - isReset.v = trueValue; + isReset.current = trueValue; _$(page) === 1 ? send() : upd$(page, 1); }); // 兼容react,每次缓存最新的操作函数,避免闭包陷阱 - delegationActions.v = { + delegationActions.current = { refresh, insert, remove, diff --git a/src/hooks/useCaptcha.ts b/src/hooks/useCaptcha.ts index 49af5f0..2399a0b 100644 --- a/src/hooks/useCaptcha.ts +++ b/src/hooks/useCaptcha.ts @@ -1,6 +1,6 @@ -import { T$, T_$, T_exp$, Tupd$, TuseFlag$, TuseMemorizedCallback$ } from '@/framework/type'; +import { T$, Tupd$, TuseFlag$, TuseMemorizedCallback$, T_$, T_exp$ } from '@/framework/type'; import { buildErrorMsg, createAssert, newInstance } from '@/helper'; -import { PromiseCls, falseValue, trueValue, undefinedValue } from '@/helper/variables'; +import { falseValue, PromiseCls, trueValue, undefinedValue } from '@/helper/variables'; import { AlovaMethodHandler, Method, useRequest } from 'alova'; import { CaptchaHookConfig } from '~/typings/general'; @@ -34,10 +34,10 @@ export default ( .send(...args) .then(result => { upd$(countdown, config.initialCountdown || 60); - timer.v = setInterval(() => { + timer.current = setInterval(() => { upd$(countdown, val => val - 1); if (_$(countdown) <= 0) { - clearInterval(timer.v); + clearInterval(timer.current); } }, 1000); resolve(result); diff --git a/src/hooks/useForm.ts b/src/hooks/useForm.ts index 7b058e6..b5f188b 100644 --- a/src/hooks/useForm.ts +++ b/src/hooks/useForm.ts @@ -86,9 +86,9 @@ export default ( * 重置form数据 */ const reset = useMemorizedCallback$(() => { - reseting.v = trueValue; + reseting.current = trueValue; upd$(form, cloneFormData(initialForm)); - enableStore && storageContext.remove(storagedKey.v); + enableStore && storageContext.remove(storagedKey.current); }); /** @@ -138,11 +138,11 @@ export default ( if (id) { // 还没有共享状态则表示当前hook是创建的hook if (!sharedState) { - isCreateShardState.v = trueValue; + isCreateShardState.current = trueValue; } // 只保存创建hook的共享状态 - if (isCreateShardState.v) { + if (isCreateShardState.current) { sharedStates[id] = { hookReturns, config @@ -156,7 +156,7 @@ export default ( if (enableStore && !sharedState) { // 获取存储并更新data // 需要在onMounted中调用,否则会导致在react中重复被调用 - const storagedForm = serializerPerformer.v.deserialize(storageContext.get(storagedKey.v)); + const storagedForm = serializerPerformer.current.deserialize(storageContext.get(storagedKey.current)); // 有草稿数据时,异步恢复数据,否则无法正常绑定onRetore事件 if (storagedForm) { @@ -170,11 +170,11 @@ export default ( // 监听变化同步存储,如果是reset触发的则不需要再序列化 watch$([form], () => { - if (reseting.v || !enableStore) { - reseting.v = falseValue; + if (reseting.current || !enableStore) { + reseting.current = falseValue; return; } - storageContext.set(storagedKey.v, serializerPerformer.v.serialize(_$(form))); + storageContext.set(storagedKey.current, serializerPerformer.current.serialize(_$(form))); }); // 如果在提交后需要清除数据,则调用reset onSuccess(() => { @@ -183,5 +183,5 @@ export default ( // 有已保存的sharedState,则返回它 // 如果是当前hook创建的共享状态,则返回最新的而非缓存的 - return sharedState && !isCreateShardState.v ? sharedState.hookReturns : hookReturns; + return sharedState && !isCreateShardState.current ? sharedState.hookReturns : hookReturns; }; diff --git a/src/hooks/useRetriableRequest.ts b/src/hooks/useRetriableRequest.ts index 472ccd5..bacafa3 100644 --- a/src/hooks/useRetriableRequest.ts +++ b/src/hooks/useRetriableRequest.ts @@ -51,7 +51,7 @@ export default ( undefinedValue, undefinedValue, undefinedValue, - retryTimes.v, + retryTimes.current, undefinedValue, sendArgs, undefinedValue, @@ -59,8 +59,8 @@ export default ( error ) ); - stopManuallyError.v = undefinedValue; - retryTimes.v = 0; // 重置已重试次数 + stopManuallyError.current = undefinedValue; + retryTimes.current = 0; // 重置已重试次数 }); }; @@ -70,15 +70,15 @@ export default ( * 停止后将立即触发onFail事件 */ const stop = useMemorizedCallback$(() => { - assert(currentLoadingState.v, 'there are no requests being retried'); - stopManuallyError.v = new Error(buildErrorMsg(hookPrefix, 'stop retry manually')); - if (requesting.v) { + assert(currentLoadingState.current, 'there are no requests being retried'); + stopManuallyError.current = new Error(buildErrorMsg(hookPrefix, 'stop retry manually')); + if (requesting.current) { requestReturns.abort(); } else { - emitOnFail(methodInstanceLastest.v as any, sendArgsLatest.v as any, stopManuallyError.v); - requestReturns.update({ error: stopManuallyError.v, loading: falseValue }); - currentLoadingState.v = falseValue; - clearTimeoutFn(retryTimer.v); // 清除重试定时器 + emitOnFail(methodInstanceLastest.current as any, sendArgsLatest.current as any, stopManuallyError.current); + requestReturns.update({ error: stopManuallyError.current, loading: falseValue }); + currentLoadingState.current = falseValue; + clearTimeoutFn(retryTimer.current); // 清除重试定时器 } }); const requestReturns = useRequest(handler, { @@ -95,23 +95,23 @@ export default ( ); const { update, sendArgs, send, method, controlLoading } = ctx; const setLoading = (loading = falseValue) => { - if (loading !== currentLoadingState.v) { + if (loading !== currentLoadingState.current) { update({ loading }); - currentLoadingState.v = loading; + currentLoadingState.current = loading; } }; controlLoading(); setLoading(trueValue); - methodInstanceLastest.v = method; - sendArgsLatest.v = sendArgs; - requesting.v = trueValue; + methodInstanceLastest.current = method; + sendArgsLatest.current = sendArgs; + requesting.current = trueValue; return promiseThen( next(), // 请求成功时设置loading为false val => { - retryTimes.v = 0; // 重置已重试次数 - requesting.v = falseValue; + retryTimes.current = 0; // 重置已重试次数 + requesting.current = falseValue; setLoading(); return val; }, @@ -119,11 +119,14 @@ export default ( // 请求失败时触发重试机制 error => { // 没有手动触发停止,以及重试次数未到达最大时触发重试 - if (!stopManuallyError.v && (isNumber(retry) ? retryTimes.v < retry : retry(error, ...sendArgs))) { + if ( + !stopManuallyError.current && + (isNumber(retry) ? retryTimes.current < retry : retry(error, ...sendArgs)) + ) { // 计算重试延迟时间 - const retryDelay = delayWithBackoff(backoff, ++retryTimes.v); + const retryDelay = delayWithBackoff(backoff, ++retryTimes.current); // 延迟对应时间重试 - retryTimer.v = setTimeoutFn(() => { + retryTimer.current = setTimeoutFn(() => { // 如果手动停止了则不再触发重试 promiseCatch(send(...sendArgs), noop); // 捕获错误不再往外抛,否则重试时也会抛出错误 // 触发重试事件 @@ -135,7 +138,7 @@ export default ( undefinedValue, undefinedValue, undefinedValue, - retryTimes.v, + retryTimes.current, retryDelay, sendArgs ) @@ -143,11 +146,11 @@ export default ( }, retryDelay); } else { setLoading(); - error = stopManuallyError.v || error; // 如果stopManuallyError有值表示是通过stop函数触发停止的 + error = stopManuallyError.current || error; // 如果stopManuallyError有值表示是通过stop函数触发停止的 emitOnFail(method, sendArgs, error); } - requesting.v = falseValue; + requesting.current = falseValue; // 返回reject执行后续的错误流程 return promiseReject(error); } diff --git a/src/middlewares/actionDelegation.ts b/src/middlewares/actionDelegation.ts index 6b644c5..984d17d 100644 --- a/src/middlewares/actionDelegation.ts +++ b/src/middlewares/actionDelegation.ts @@ -29,7 +29,7 @@ export const actionDelegationMiddleware = (id: string | number | symbol, useFlag next: AlovaGuardNext ) => { // 中间件会重复调用,已经订阅过了就无需再订阅了 - if (!delegated.v) { + if (!delegated.current) { const { abort, update, delegatingActions = {} } = context; // 相同id的将以数组形式保存在一起 const handlersItems = (actionsMap[id] = actionsMap[id] || []); @@ -49,7 +49,7 @@ export const actionDelegationMiddleware = (id: string | number | symbol, useFlag } ); - delegated.v = trueValue; + delegated.current = trueValue; } return next(); };