diff --git a/docs/docs/api/base/demos/run-watch.tsx b/docs/docs/api/base/demos/run-watch.tsx new file mode 100644 index 00000000..429033a3 --- /dev/null +++ b/docs/docs/api/base/demos/run-watch.tsx @@ -0,0 +1,35 @@ +/** + * defaultShowCode: true + */ +import { share, watch } from 'helux'; + +const [priceState, setState] = share({ a: 1, c: 0 }); + +// 观察整个 priceState 的变化 +const ret = watch( + () => { + console.log(`found price changed: [ priceState ]`); + }, + () => [priceState], +); + +ret.unwatch(); // 取消观察后,watch 不会再被自动触发 + +function changeState() { + setState(draft => void (draft.a += 100)); +} + +function run() { + ret.run(); // 人工触发始终有效,和 unwatch 是否执行没关系 +} + +// for react demo renderer +export default () => ( +
+

after calling unwatch

+ +
+
+ +
+); diff --git a/docs/docs/api/base/mutate.md b/docs/docs/api/base/mutate.md index 83e35465..3927c21d 100644 --- a/docs/docs/api/base/mutate.md +++ b/docs/docs/api/base/mutate.md @@ -117,7 +117,7 @@ task 和 fn 同时存在,设定`immediate`为`true`,首次执行 mutate 先 const witness = mutate(state)({ deps: () => [state.a, state.b], fn: (draft, { input }) => (draft.c = input[0] + input[1] + 1), - task: async ({ input }) => { + task: async ({ draft, input }) => { draft.c = input[0] + input[1] + 1; }, immediate: true, @@ -129,7 +129,7 @@ const witness = mutate(state)({ ```ts const witness = mutate(state)({ deps: () => [state.a, state.b], - task: async ({ input }) => { + task: async ({ draft, input }) => { draft.c = input[0] + input[1] + 1; }, }); @@ -140,7 +140,7 @@ const witness = mutate(state)({ ```ts const witness = mutate(state)({ deps: () => [state.a, state.b], - task: async ({ input }) => { + task: async ({ draft, input }) => { draft.c = input[0] + input[1] + 1; }, immediate: false, @@ -179,7 +179,7 @@ const [state] = share({ a: 1, b: 1, c: 0 }); const witness = mutate(state)({ deps: () => [state.a, state.b], // deps 返回结果会透传给 taskFnParams.input 数组 - task: async ({ input }) => { + task: async ({ draft, input }) => { draft.c = input[0] + input[1] + 1; }, }); @@ -200,7 +200,7 @@ const [state] = share({ a: 1, b: 1, c: 0 }); const witness = mutate(state)({ deps: () => [state.a], onlyDeps: true, - task: async ({ input }) => { + task: async ({ draft, input }) => { // 此时 b 的变化不会引起 task 执行 draft.c = input[0] + state.b + 1; }, diff --git a/docs/docs/api/base/watch.md b/docs/docs/api/base/watch.md index 38b5abb6..2d21d99e 100644 --- a/docs/docs/api/base/watch.md +++ b/docs/docs/api/base/watch.md @@ -25,6 +25,10 @@ watch 可观察共享状态跟对象的变化,第二位参数可写为`()=>[]` +### 人工执行/取消watch + + + ## 死循环 设置`immediate`为 true 时,watch 回调首次执行会自动收集依赖,此时如果存在读取自己修改自己的行为,会造成死循环。 diff --git a/package.json b/package.json index c6299a5f..cbb73078 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "helux", - "version": "4.2.6", + "version": "4.3.1", "description": "A reactive atomic state engine for React like.", "keywords": [], "author": { diff --git a/packages/helux-core/CHANGELOG.md b/packages/helux-core/CHANGELOG.md index 0dc80695..4f2870d1 100644 --- a/packages/helux-core/CHANGELOG.md +++ b/packages/helux-core/CHANGELOG.md @@ -1,5 +1,38 @@ # @helux/core +## 4.3.2 + +### Patch Changes + +- 94cd307: build(4.3.2): optimize delFnDepData + - @helux/hooks-impl@4.3.2 + - @helux/types@4.3.2 + - @helux/utils@4.3.2 + +## 4.3.1 + +### Patch Changes + +- 41b9f1d: build(4.3.1): support mutate cancel + - @helux/hooks-impl@4.3.1 + - @helux/types@4.3.1 + - @helux/utils@4.3.1 + +## 4.3.0 + +### Minor Changes + +- ac52a46: build(4.2.8): fix unwatch +- 5520458: build(4.2.7): fix unwatch + +### Patch Changes + +- Updated dependencies [ac52a46] +- Updated dependencies [5520458] + - @helux/hooks-impl@4.3.0 + - @helux/types@4.3.0 + - @helux/utils@4.3.0 + ## 4.2.7 ### Patch Changes diff --git a/packages/helux-core/package.json b/packages/helux-core/package.json index e8d1477e..fab99b0d 100644 --- a/packages/helux-core/package.json +++ b/packages/helux-core/package.json @@ -1,6 +1,6 @@ { "name": "@helux/core", - "version": "4.2.7", + "version": "4.3.2", "description": "A reactive atomic state engine for React like.", "bugs": { "url": "https://github.com/heluxjs/helux/issues" diff --git a/packages/helux-core/src/consts/user.ts b/packages/helux-core/src/consts/user.ts index 0110b75f..d2fd06d9 100644 --- a/packages/helux-core/src/consts/user.ts +++ b/packages/helux-core/src/consts/user.ts @@ -1,6 +1,6 @@ import { VER as limuVer } from 'limu'; -export const VER = '4.2.7'; +export const VER = '4.3.2'; export const LIMU_VER = limuVer; diff --git a/packages/helux-core/src/factory/common/fnScope.ts b/packages/helux-core/src/factory/common/fnScope.ts index daafc640..4558bbd8 100644 --- a/packages/helux-core/src/factory/common/fnScope.ts +++ b/packages/helux-core/src/factory/common/fnScope.ts @@ -30,11 +30,22 @@ export function delComputingFnKey(depKey: string, fnKey: string) { * 删除已记录的相关依赖数据 */ export function delFnDepData(fnCtx: IFnCtx) { - const { DEPKEY_FNKEYS_MAP } = getFnScope(); - const { depKeys, fnKey } = fnCtx; + const { DEPKEY_FNKEYS_MAP, SKEY_FNKEYS_MAP } = getFnScope(); + const { depKeys, fnKey, depSharedKeys } = fnCtx; + const toDel: string[] = []; + depKeys.forEach((key) => { const fnKeys = DEPKEY_FNKEYS_MAP.get(key) || []; delListItem(fnKeys, fnKey); + nodupPush(toDel, fnKey); + }); + + // 将 sharedKey 映射的 fnKey 也一并移除 + depSharedKeys.forEach((key) => { + const fnKeysOfSkey = SKEY_FNKEYS_MAP.get(String(key)) || []; + toDel.forEach((key) => { + delListItem(fnKeysOfSkey, key); + }); }); } diff --git a/packages/helux-core/src/factory/createMutate.ts b/packages/helux-core/src/factory/createMutate.ts index 191e6c72..5d1f4e19 100644 --- a/packages/helux-core/src/factory/createMutate.ts +++ b/packages/helux-core/src/factory/createMutate.ts @@ -1,4 +1,5 @@ import { FROM, SINGLE_MUTATE } from '../consts'; +import { delFnDep } from '../helpers/fnDep'; import { getBoundStateInfo, getInternal } from '../helpers/state'; import type { ActionReturn, @@ -48,7 +49,8 @@ function runMutateFnItem(options: { target: T; desc?: string; f return callMutateFnLogic(target, baseOpts); } -function makeWitness(target: SharedState, desc: string, oriDesc: string, internal: TInternal) { +function makeWitness(target: SharedState, options: { desc: string; oriDesc: string; internal: TInternal; watchFnCtx: any }) { + const { desc, oriDesc, internal, watchFnCtx } = options; return { run: (throwErr?: boolean) => { // 呼叫同步函数的句柄 @@ -57,6 +59,12 @@ function makeWitness(target: SharedState, desc: string, oriDesc: string, interna }, // 呼叫异步函数的句柄 runTask: (throwErr?: boolean) => Promise.resolve(runMutateFnItem({ target, desc, forTask: true, throwErr })).then(toMutateRet), + cancel: () => { + // unwatch + delFnDep(watchFnCtx); + // TODO optimize: shuold I use Relect.deleteProperty + delete internal.mutateFnDict[desc]; + }, desc, oriDesc, getSnap: () => internal.snap, @@ -94,14 +102,17 @@ function configureMutateFn(options: IConfigureMutateFnOpt) { if (extraTarget) { stdFnItem.extraBound = getBoundStateInfo(extraTarget); } + const { desc, oriDesc } = stdFnItem; - internal.mutateFnDict[stdFnItem.desc] = stdFnItem; + internal.mutateFnDict[desc] = stdFnItem; stdFnItem.enabled = internal.enableMutate; - const dict = { [stdFnItem.desc]: stdFnItem }; + const dict = { [desc]: stdFnItem }; + let watchFnCtx; if (internal.enableMutate) { - watchAndCallMutateDict({ target, dict }); + const retMap = watchAndCallMutateDict({ target, dict }); + watchFnCtx = retMap[desc]; } - return makeWitness(target, stdFnItem.desc, stdFnItem.oriDesc, internal); + return makeWitness(target, { desc, oriDesc, internal, watchFnCtx }); } /**IMutateWitness @@ -115,12 +126,14 @@ function configureMutateDict(options: IConfigureMutateDictOpt): any { const extraBound = getBoundStateInfo(options.extraTarget); Object.keys(dict).forEach((key) => (dict[key].extraBound = extraBound)); } + + let watchFnCtxMap: Dict = {}; if (internal.enableMutate) { - watchAndCallMutateDict({ target, dict }); + watchFnCtxMap = watchAndCallMutateDict({ target, dict }); } const witnessDict: Dict = {}; // 具体类型定义见 types-api multiDict Object.keys(dict).forEach((desc) => { - witnessDict[desc] = makeWitness(target, desc, desc, internal); + witnessDict[desc] = makeWitness(target, { desc, oriDesc: desc, internal, watchFnCtx: watchFnCtxMap[desc] }); }); return witnessDict; } diff --git a/packages/helux-core/src/factory/creator/mutateFn.ts b/packages/helux-core/src/factory/creator/mutateFn.ts index 55fa778f..59c7bb69 100644 --- a/packages/helux-core/src/factory/creator/mutateFn.ts +++ b/packages/helux-core/src/factory/creator/mutateFn.ts @@ -1,3 +1,4 @@ +import type { Dict } from '@helux/types'; import { enureReturnArr, isPromise, noop } from '@helux/utils'; import { FROM, SCOPE_TYPE } from '../../consts'; import { getRunningFn, getSafeFnCtx } from '../../factory/common/fnScope'; @@ -252,7 +253,8 @@ function initFnItem(internal: TInternal, fnItem: IMutateFnStdItem) { export function watchAndCallMutateDict(options: IWatchAndCallMutateDictOptions) { const { target, dict } = options; const keys = Object.keys(dict); - if (!keys.length) return; + const watchFnCtxMap: Dict = {}; + if (!keys.length) return watchFnCtxMap; const internal = getInternal(target); const { mutateFnDict, usefulName, forAtom, sharedRoot } = internal; const emitErrToPlugin = (err: Error) => emitErr(internal, err); @@ -260,7 +262,7 @@ export function watchAndCallMutateDict(options: IWatchAndCallMutateDictOptions) keys.forEach((descKey) => { const item = mutateFnDict[descKey]; // 开始映射 mutate 函数相关数据依赖关系 - createWatchLogic( + watchFnCtxMap[descKey] = createWatchLogic( ({ sn, isFirstCall }) => { if (isFirstCall) { initFnItem(internal, item); @@ -315,4 +317,6 @@ export function watchAndCallMutateDict(options: IWatchAndCallMutateDictOptions) }, ); }); + + return watchFnCtxMap; } diff --git a/packages/helux-core/src/helpers/fnRunner.ts b/packages/helux-core/src/helpers/fnRunner.ts index c8c8c4e7..89964974 100644 --- a/packages/helux-core/src/helpers/fnRunner.ts +++ b/packages/helux-core/src/helpers/fnRunner.ts @@ -53,7 +53,7 @@ function runWatch(fnCtx: IFnCtx, options: IRunFnOpt) { return; } - // simpleWatch 的依赖时转移进去的,不需要判死循环,否则会照成误判 + // simpleWatch 的依赖是转移进去的,不需要判死循环,否则会照成误判 // 设定了 checkDeadCycle 为 false,不检查死循环 if (fnCtx.isSimpleWatch || !fnCtx.checkDeadCycle) { return fnCtx.fn({ isFirstCall, triggerReasons, sn }); diff --git a/packages/helux-core/src/types/base.d.ts b/packages/helux-core/src/types/base.d.ts index 8aae1299..ad970319 100644 --- a/packages/helux-core/src/types/base.d.ts +++ b/packages/helux-core/src/types/base.d.ts @@ -353,6 +353,10 @@ export interface IMutateWitness { run: MutateCall; /** 人工调用 mutate 配置里的异步函数 */ runTask: MutateTaskCall; + /** + * 撤销 mutate 自动运行机制,这是一个不可逆的操作,执行后 mutate 将不再执行 + */ + cancel: () => void; /** 用户透传的原始描述值 */ oriDesc: string; /** diff --git a/packages/helux-demo-utils/package.json b/packages/helux-demo-utils/package.json index 5bbe5a8b..3feb09aa 100644 --- a/packages/helux-demo-utils/package.json +++ b/packages/helux-demo-utils/package.json @@ -33,7 +33,7 @@ "dependencies": { "@types/react": ">=16.0.0", "@types/react-dom": ">=16.0.0", - "helux": "^4.2.7", + "helux": "^4.3.2", "react": ">=16.10.2", "react-dom": ">=16.10.2" }, diff --git a/packages/helux-hooks-impl/CHANGELOG.md b/packages/helux-hooks-impl/CHANGELOG.md index 47f78110..87384b3c 100644 --- a/packages/helux-hooks-impl/CHANGELOG.md +++ b/packages/helux-hooks-impl/CHANGELOG.md @@ -1,5 +1,33 @@ # @helux/hooks-impl +## 4.3.2 + +### Patch Changes + +- @helux/types@4.3.2 +- @helux/utils@4.3.2 + +## 4.3.1 + +### Patch Changes + +- @helux/types@4.3.1 +- @helux/utils@4.3.1 + +## 4.3.0 + +### Minor Changes + +- ac52a46: build(4.2.8): fix unwatch +- 5520458: build(4.2.7): fix unwatch + +### Patch Changes + +- Updated dependencies [ac52a46] +- Updated dependencies [5520458] + - @helux/types@4.3.0 + - @helux/utils@4.3.0 + ## 4.2.7 ### Patch Changes diff --git a/packages/helux-hooks-impl/package.json b/packages/helux-hooks-impl/package.json index a5e3b209..3fba570f 100644 --- a/packages/helux-hooks-impl/package.json +++ b/packages/helux-hooks-impl/package.json @@ -1,6 +1,6 @@ { "name": "@helux/hooks-impl", - "version": "4.2.7", + "version": "4.3.2", "description": "helux hooks implement lib", "bugs": { "url": "https://github.com/heluxjs/helux/issues" diff --git a/packages/helux-hooks/CHANGELOG.md b/packages/helux-hooks/CHANGELOG.md index d8867433..f697b4bd 100644 --- a/packages/helux-hooks/CHANGELOG.md +++ b/packages/helux-hooks/CHANGELOG.md @@ -1,5 +1,36 @@ # @helux/hooks +## 4.3.2 + +### Patch Changes + +- @helux/hooks-impl@4.3.2 +- @helux/types@4.3.2 +- @helux/utils@4.3.2 + +## 4.3.1 + +### Patch Changes + +- @helux/hooks-impl@4.3.1 +- @helux/types@4.3.1 +- @helux/utils@4.3.1 + +## 4.3.0 + +### Minor Changes + +- ac52a46: build(4.2.8): fix unwatch +- 5520458: build(4.2.7): fix unwatch + +### Patch Changes + +- Updated dependencies [ac52a46] +- Updated dependencies [5520458] + - @helux/hooks-impl@4.3.0 + - @helux/types@4.3.0 + - @helux/utils@4.3.0 + ## 4.2.7 ### Patch Changes diff --git a/packages/helux-hooks/package.json b/packages/helux-hooks/package.json index 780fb6db..ddb1f87d 100644 --- a/packages/helux-hooks/package.json +++ b/packages/helux-hooks/package.json @@ -1,6 +1,6 @@ { "name": "@helux/hooks", - "version": "4.2.7", + "version": "4.3.2", "description": "helux hooks lib for react", "keywords": [ "helux", diff --git a/packages/helux-openinula/CHANGELOG.md b/packages/helux-openinula/CHANGELOG.md index 3a4b7c4b..9ee66ea0 100644 --- a/packages/helux-openinula/CHANGELOG.md +++ b/packages/helux-openinula/CHANGELOG.md @@ -1,5 +1,32 @@ # @helux/openinula +## 4.3.2 + +### Patch Changes + +- Updated dependencies [94cd307] + - @helux/core@4.3.2 + +## 4.3.1 + +### Patch Changes + +- Updated dependencies [41b9f1d] + - @helux/core@4.3.1 + +## 4.3.0 + +### Minor Changes + +- ac52a46: build(4.2.8): fix unwatch +- 5520458: build(4.2.7): fix unwatch + +### Patch Changes + +- Updated dependencies [ac52a46] +- Updated dependencies [5520458] + - @helux/core@4.3.0 + ## 4.2.7 ### Patch Changes diff --git a/packages/helux-openinula/package.json b/packages/helux-openinula/package.json index 41e89a21..b0309025 100644 --- a/packages/helux-openinula/package.json +++ b/packages/helux-openinula/package.json @@ -1,6 +1,6 @@ { "name": "@helux/openinula", - "version": "4.2.7", + "version": "4.3.2", "description": "State library for preact that integrates atom, signal, collection dep, derive and watch.", "bugs": { "url": "https://github.com/heluxjs/helux/issues" diff --git a/packages/helux-types/CHANGELOG.md b/packages/helux-types/CHANGELOG.md index 6088d5c4..ec682ca1 100644 --- a/packages/helux-types/CHANGELOG.md +++ b/packages/helux-types/CHANGELOG.md @@ -1,5 +1,16 @@ # @helux/types +## 4.3.2 + +## 4.3.1 + +## 4.3.0 + +### Minor Changes + +- ac52a46: build(4.2.8): fix unwatch +- 5520458: build(4.2.7): fix unwatch + ## 4.2.7 ### Patch Changes diff --git a/packages/helux-types/package.json b/packages/helux-types/package.json index 163c6b97..66c30d9a 100644 --- a/packages/helux-types/package.json +++ b/packages/helux-types/package.json @@ -1,6 +1,6 @@ { "name": "@helux/types", - "version": "4.2.7", + "version": "4.3.2", "description": "helux common types lib", "keywords": [ "helux", diff --git a/packages/helux-utils/CHANGELOG.md b/packages/helux-utils/CHANGELOG.md index 5318eee0..291585a2 100644 --- a/packages/helux-utils/CHANGELOG.md +++ b/packages/helux-utils/CHANGELOG.md @@ -1,5 +1,30 @@ # @helux/utils +## 4.3.2 + +### Patch Changes + +- @helux/types@4.3.2 + +## 4.3.1 + +### Patch Changes + +- @helux/types@4.3.1 + +## 4.3.0 + +### Minor Changes + +- ac52a46: build(4.2.8): fix unwatch +- 5520458: build(4.2.7): fix unwatch + +### Patch Changes + +- Updated dependencies [ac52a46] +- Updated dependencies [5520458] + - @helux/types@4.3.0 + ## 4.2.7 ### Patch Changes diff --git a/packages/helux-utils/package.json b/packages/helux-utils/package.json index 16b4e9c7..4070849a 100644 --- a/packages/helux-utils/package.json +++ b/packages/helux-utils/package.json @@ -1,6 +1,6 @@ { "name": "@helux/utils", - "version": "4.2.7", + "version": "4.3.2", "description": "helux utils lib", "keywords": [ "helux", diff --git a/packages/helux/CHANGELOG.md b/packages/helux/CHANGELOG.md index 83af8754..96425574 100644 --- a/packages/helux/CHANGELOG.md +++ b/packages/helux/CHANGELOG.md @@ -1,5 +1,32 @@ # helux +## 4.3.2 + +### Patch Changes + +- Updated dependencies [94cd307] + - @helux/core@4.3.2 + +## 4.3.1 + +### Patch Changes + +- Updated dependencies [41b9f1d] + - @helux/core@4.3.1 + +## 4.3.0 + +### Minor Changes + +- ac52a46: build(4.2.8): fix unwatch +- 5520458: build(4.2.7): fix unwatch + +### Patch Changes + +- Updated dependencies [ac52a46] +- Updated dependencies [5520458] + - @helux/core@4.3.0 + ## 4.2.7 ### Patch Changes diff --git a/packages/helux/package.json b/packages/helux/package.json index 5c4992d9..9a166ada 100644 --- a/packages/helux/package.json +++ b/packages/helux/package.json @@ -1,6 +1,6 @@ { "name": "helux", - "version": "4.2.7", + "version": "4.3.2", "description": "A reactive atomic state engine for React( including React 18).", "bugs": { "url": "https://github.com/heluxjs/helux/issues" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index add31b82..ad4c99b5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -97,8 +97,7 @@ importers: dumi: ^2.2.16 eslint: ^8.23.0 father: ^4.1.0 - helux: latest - helux-docs: 'link:' + helux: workspace:^4.3.0 husky: ^8.0.1 lint-staged: ^13.0.3 localforage: ^1.10.0 @@ -116,6 +115,7 @@ importers: react-copy-to-clipboard: ^5.1.0 react-dom: ^18.0.0 react-live: ^4.1.5 + styledfc: ^1.0.7 stylelint: ^14.9.1 dependencies: '@ant-design/icons-svg': 4.3.1 @@ -126,7 +126,6 @@ importers: classnames: 2.5.1 console-feed: 3.5.0_b2n7dceyjx62tehd6yl3udyazy helux: link:../packages/helux - helux-docs: 'link:' localforage: 1.10.0 lodash: 4.17.21 lodash.throttle: 4.1.1 @@ -137,6 +136,7 @@ importers: rc-tree: 5.8.2_biqbaboplfbrettd7655fr4n2y react-copy-to-clipboard: 5.1.0_react@18.2.0 react-live: 4.1.5_biqbaboplfbrettd7655fr4n2y + styledfc: 1.1.1_ew44pi3lpycpetk4ebiajdjvuy devDependencies: '@commitlint/cli': 17.8.1 '@commitlint/config-conventional': 17.8.1 @@ -223,7 +223,7 @@ importers: hel-micro: ^4.8.11 hel-micro-core: ^4.8.7 hel-types: ^4.3.3 - helux: ^4.2.1 + helux: ^4.2.7 react: '>=16.10.2' react-dom: '>=16.10.2' rollup: ^2.23.0 @@ -286,12 +286,9 @@ importers: specifiers: helux: workspace:^ redux: ^4.2.1 - terser: ^5.29.1 dependencies: helux: link:../helux redux: 4.2.1 - devDependencies: - terser: 5.29.1 packages/helux-types: specifiers: {} @@ -17373,6 +17370,19 @@ packages: inline-style-parser: 0.1.1 dev: true + /styledfc/1.1.1_ew44pi3lpycpetk4ebiajdjvuy: + resolution: {integrity: sha512-QbdGGZm46x+JiD7pZxyOLGlefLhr1wEGH3t+rOEMt9KHMwHPmIm0dPGIZ+3MlX5naQ7PBBXKgcIMuyPRgvgSMw==} + peerDependencies: + '@types/react': ^18.2.40 + react: ^18.2.0 + react-dom: ^18.2.0 + dependencies: + '@changesets/cli': 2.27.1 + '@types/react': 17.0.74 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + /stylelint-config-recommended/7.0.0_stylelint@14.16.1: resolution: {integrity: sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==} peerDependencies: @@ -17730,17 +17740,6 @@ packages: commander: 2.20.3 source-map-support: 0.5.21 - /terser/5.29.1: - resolution: {integrity: sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ==} - engines: {node: '>=10'} - hasBin: true - dependencies: - '@jridgewell/source-map': 0.3.5 - acorn: 8.11.3 - commander: 2.20.3 - source-map-support: 0.5.21 - dev: true - /test-exclude/6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'}