eslint-plugin-react-hooks-extra 1.5.28-beta.7 → 1.5.28-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ var astUtils = require('@typescript-eslint/utils/ast-utils');
9
9
 
10
10
  // package.json
11
11
  var name = "eslint-plugin-react-hooks-extra";
12
- var version = "1.5.28-beta.7";
12
+ var version = "1.5.28-next.2";
13
13
  var createRule = shared.createRuleForPlugin("hooks-extra");
14
14
 
15
15
  // src/rules/ensure-custom-hooks-using-other-hooks.ts
@@ -467,26 +467,29 @@ var no_direct_set_state_in_use_effect_default = createRule({
467
467
  return $(node).when(isEffectFunction, () => "effect").when(isCleanUpFunction, () => "cleanup").when(ast.isIIFE, () => "immediate").otherwise(() => "other");
468
468
  }
469
469
  const useEffectCallRef = tools.MutRef.make(null);
470
+ const callStack = tools.MutList.make();
470
471
  const functionStack = tools.MutList.make();
471
472
  const effectFunctionRef = tools.MutRef.make(null);
472
473
  const cleanUpFunctionRef = tools.MutRef.make(null);
473
- const indirectFunctionCalls = tools.MutRef.make(tools.Chunk.empty());
474
+ const indirectFunctionCalls = [];
474
475
  const indirectSetStateCalls = /* @__PURE__ */ new Map();
476
+ const onUseEffectCallEnter = (node) => void tools.MutRef.set(useEffectCallRef, node);
477
+ const onUseEffectCallExit = () => void tools.MutRef.set(useEffectCallRef, null);
475
478
  return {
476
- ":function"(node) {
477
- const functionKind = getFunctionKind(node);
478
- tools.MutList.append(functionStack, [node, functionKind]);
479
- $(functionKind).with("effect", () => {
480
- tools.MutRef.set(effectFunctionRef, node);
481
- }).with("cleanup", () => {
482
- tools.MutRef.set(cleanUpFunctionRef, node);
483
- }).otherwise(tools.F.constVoid);
484
- },
485
- ":function:exit"(node) {
486
- tools.MutRef.update(effectFunctionRef, (current) => current === node ? null : current);
487
- tools.MutList.pop(functionStack);
479
+ Identifier(node) {
480
+ const isInUseEffectCall = tools.MutRef.get(useEffectCallRef) !== null;
481
+ const parentFn = tools.MutList.tail(functionStack)?.[0];
482
+ const useEffectCall = tools.MutRef.get(useEffectCallRef);
483
+ const isEffectFunction2 = useEffectCall && tools.O.isSome(ast.traverseUp(useEffectCall, (n2) => n2 === parentFn));
484
+ if (isFromUseStateCall(node) && isInUseEffectCall && isEffectFunction2) {
485
+ context.report({
486
+ node,
487
+ messageId: "NO_DIRECT_SET_STATE_IN_USE_EFFECT"
488
+ });
489
+ }
488
490
  },
489
491
  CallExpression(node) {
492
+ tools.MutList.append(callStack, node);
490
493
  const effectFn = tools.MutRef.get(effectFunctionRef);
491
494
  const [parentFn, parentFnKind] = tools.MutList.tail(functionStack) ?? [];
492
495
  if (parentFn?.async) return;
@@ -494,29 +497,47 @@ var no_direct_set_state_in_use_effect_default = createRule({
494
497
  $(callKind).with("setState", () => {
495
498
  if (!parentFn) return;
496
499
  if (parentFn !== effectFn && parentFnKind !== "immediate") {
497
- const calls = indirectSetStateCalls.get(parentFn) ?? tools.Chunk.empty();
498
- indirectSetStateCalls.set(parentFn, tools.Chunk.append(calls, node));
500
+ indirectSetStateCalls.set(parentFn, [...indirectSetStateCalls.get(parentFn) ?? [], node]);
499
501
  return;
500
502
  }
501
503
  context.report({
502
- messageId: "NO_DIRECT_SET_STATE_IN_USE_EFFECT",
503
- node
504
+ node,
505
+ messageId: "NO_DIRECT_SET_STATE_IN_USE_EFFECT"
504
506
  });
505
507
  }).with("useEffect", () => {
506
- tools.MutRef.set(useEffectCallRef, node);
508
+ onUseEffectCallEnter(node);
509
+ }).with("useState", () => {
510
+ }).with("then", () => {
507
511
  }).with("other", () => {
508
- const isInEffectFunction = effectFn === parentFn;
509
- if (!isInEffectFunction) return;
510
- tools.MutRef.update(indirectFunctionCalls, tools.Chunk.append(node));
511
- }).otherwise(tools.F.constVoid);
512
+ indirectFunctionCalls.push(node);
513
+ }).exhaustive();
514
+ },
515
+ ":function"(node) {
516
+ const functionKind = getFunctionKind(node);
517
+ tools.MutList.append(functionStack, [node, functionKind]);
518
+ $(functionKind).with("effect", () => {
519
+ tools.MutRef.set(effectFunctionRef, node);
520
+ }).with("cleanup", () => {
521
+ tools.MutRef.set(cleanUpFunctionRef, node);
522
+ }).otherwise(() => {
523
+ });
524
+ },
525
+ ":function:exit"(node) {
526
+ const effectFn = tools.MutRef.get(effectFunctionRef);
527
+ if (effectFn === node) {
528
+ tools.MutRef.set(effectFunctionRef, null);
529
+ }
530
+ tools.MutList.pop(functionStack);
512
531
  },
513
532
  "CallExpression:exit"(node) {
533
+ tools.MutList.pop(callStack);
514
534
  if (tools.MutRef.get(useEffectCallRef) === node) {
535
+ onUseEffectCallExit();
515
536
  tools.MutRef.set(useEffectCallRef, null);
516
537
  }
517
538
  },
518
539
  "Program:exit"() {
519
- for (const call of tools.Chunk.toReadonlyArray(tools.MutRef.get(indirectFunctionCalls))) {
540
+ for (const call of indirectFunctionCalls) {
520
541
  if (!("name" in call.callee)) continue;
521
542
  const { name: name2 } = call.callee;
522
543
  const setStateCalls = tools.F.pipe(
@@ -524,7 +545,6 @@ var no_direct_set_state_in_use_effect_default = createRule({
524
545
  tools.O.flatMap(_var.getVariableInit(0)),
525
546
  tools.O.filter(ast.isFunction),
526
547
  tools.O.flatMapNullable((init) => indirectSetStateCalls.get(init)),
527
- tools.O.map(tools.Chunk.toReadonlyArray),
528
548
  tools.O.getOrElse(() => [])
529
549
  );
530
550
  for (const setStateCall of setStateCalls) {
@@ -621,26 +641,29 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
621
641
  return $(node).when(isEffectFunction, () => "effect").when(isCleanUpFunction, () => "cleanup").when(ast.isIIFE, () => "immediate").otherwise(() => "other");
622
642
  }
623
643
  const useLayoutEffectCallRef = tools.MutRef.make(null);
644
+ const callStack = tools.MutList.make();
624
645
  const functionStack = tools.MutList.make();
625
646
  const effectFunctionRef = tools.MutRef.make(null);
626
647
  const cleanUpFunctionRef = tools.MutRef.make(null);
627
- const indirectFunctionCalls = tools.MutRef.make(tools.Chunk.empty());
648
+ const indirectFunctionCalls = [];
628
649
  const indirectSetStateCalls = /* @__PURE__ */ new Map();
650
+ const onUseLayoutEffectCallEnter = (node) => void tools.MutRef.set(useLayoutEffectCallRef, node);
651
+ const onUseLayoutEffectCallExit = () => void tools.MutRef.set(useLayoutEffectCallRef, null);
629
652
  return {
630
- ":function"(node) {
631
- const functionKind = getFunctionKind(node);
632
- tools.MutList.append(functionStack, [node, functionKind]);
633
- $(functionKind).with("effect", () => {
634
- tools.MutRef.set(effectFunctionRef, node);
635
- }).with("cleanup", () => {
636
- tools.MutRef.set(cleanUpFunctionRef, node);
637
- }).otherwise(tools.F.constVoid);
638
- },
639
- ":function:exit"(node) {
640
- tools.MutRef.update(effectFunctionRef, (current) => current === node ? null : current);
641
- tools.MutList.pop(functionStack);
653
+ Identifier(node) {
654
+ const isInUseLayoutEffectCall = tools.MutRef.get(useLayoutEffectCallRef) !== null;
655
+ const parentFn = tools.MutList.tail(functionStack)?.[0];
656
+ const useLayoutEffectCall = tools.MutRef.get(useLayoutEffectCallRef);
657
+ const isEffectFunction2 = useLayoutEffectCall && tools.O.isSome(ast.traverseUp(useLayoutEffectCall, (n2) => n2 === parentFn));
658
+ if (isFromUseStateCall(node) && isInUseLayoutEffectCall && isEffectFunction2) {
659
+ context.report({
660
+ node,
661
+ messageId: "NO_DIRECT_SET_STATE_IN_USE_LAYOUT_EFFECT"
662
+ });
663
+ }
642
664
  },
643
665
  CallExpression(node) {
666
+ tools.MutList.append(callStack, node);
644
667
  const effectFn = tools.MutRef.get(effectFunctionRef);
645
668
  const [parentFn, parentFnKind] = tools.MutList.tail(functionStack) ?? [];
646
669
  if (parentFn?.async) return;
@@ -648,29 +671,47 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
648
671
  $(callKind).with("setState", () => {
649
672
  if (!parentFn) return;
650
673
  if (parentFn !== effectFn && parentFnKind !== "immediate") {
651
- const calls = indirectSetStateCalls.get(parentFn) ?? tools.Chunk.empty();
652
- indirectSetStateCalls.set(parentFn, tools.Chunk.append(calls, node));
674
+ indirectSetStateCalls.set(parentFn, [...indirectSetStateCalls.get(parentFn) ?? [], node]);
653
675
  return;
654
676
  }
655
677
  context.report({
656
- messageId: "NO_DIRECT_SET_STATE_IN_USE_LAYOUT_EFFECT",
657
- node
678
+ node,
679
+ messageId: "NO_DIRECT_SET_STATE_IN_USE_LAYOUT_EFFECT"
658
680
  });
659
681
  }).with("useLayoutEffect", () => {
660
- tools.MutRef.set(useLayoutEffectCallRef, node);
682
+ onUseLayoutEffectCallEnter(node);
683
+ }).with("useState", () => {
684
+ }).with("then", () => {
661
685
  }).with("other", () => {
662
- const isInEffectFunction = effectFn === parentFn;
663
- if (!isInEffectFunction) return;
664
- tools.MutRef.update(indirectFunctionCalls, tools.Chunk.append(node));
665
- }).otherwise(tools.F.constVoid);
686
+ indirectFunctionCalls.push(node);
687
+ }).exhaustive();
688
+ },
689
+ ":function"(node) {
690
+ const functionKind = getFunctionKind(node);
691
+ tools.MutList.append(functionStack, [node, functionKind]);
692
+ $(functionKind).with("effect", () => {
693
+ tools.MutRef.set(effectFunctionRef, node);
694
+ }).with("cleanup", () => {
695
+ tools.MutRef.set(cleanUpFunctionRef, node);
696
+ }).otherwise(() => {
697
+ });
698
+ },
699
+ ":function:exit"(node) {
700
+ const effectFn = tools.MutRef.get(effectFunctionRef);
701
+ if (effectFn === node) {
702
+ tools.MutRef.set(effectFunctionRef, null);
703
+ }
704
+ tools.MutList.pop(functionStack);
666
705
  },
667
706
  "CallExpression:exit"(node) {
707
+ tools.MutList.pop(callStack);
668
708
  if (tools.MutRef.get(useLayoutEffectCallRef) === node) {
709
+ onUseLayoutEffectCallExit();
669
710
  tools.MutRef.set(useLayoutEffectCallRef, null);
670
711
  }
671
712
  },
672
713
  "Program:exit"() {
673
- for (const call of tools.Chunk.toReadonlyArray(tools.MutRef.get(indirectFunctionCalls))) {
714
+ for (const call of indirectFunctionCalls) {
674
715
  if (!("name" in call.callee)) continue;
675
716
  const { name: name2 } = call.callee;
676
717
  const setStateCalls = tools.F.pipe(
@@ -678,7 +719,6 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
678
719
  tools.O.flatMap(_var.getVariableInit(0)),
679
720
  tools.O.filter(ast.isFunction),
680
721
  tools.O.flatMapNullable((init) => indirectSetStateCalls.get(init)),
681
- tools.O.map(tools.Chunk.toReadonlyArray),
682
722
  tools.O.getOrElse(() => [])
683
723
  );
684
724
  for (const setStateCall of setStateCalls) {
package/dist/index.mjs CHANGED
@@ -1,13 +1,13 @@
1
1
  import { useHookCollector, isReactHookCall, isUseCallbackCall, isReactHookCallWithNameLoose, isUseMemoCall, isUseStateCall, isUseEffectCall, isUseLayoutEffectCall } from '@eslint-react/core';
2
2
  import { createRuleForPlugin, getESLintReactSettings } from '@eslint-react/shared';
3
- import { isFunction, NodeType, is, getNestedCallExpressions, isIIFE } from '@eslint-react/ast';
4
- import { F, O, MutRef, MutList, Chunk } from '@eslint-react/tools';
3
+ import { isFunction, NodeType, is, traverseUp, getNestedCallExpressions, isIIFE } from '@eslint-react/ast';
4
+ import { F, O, MutRef, MutList } from '@eslint-react/tools';
5
5
  import { findVariable, getVariableInit } from '@eslint-react/var';
6
6
  import { getStaticValue } from '@typescript-eslint/utils/ast-utils';
7
7
 
8
8
  // package.json
9
9
  var name = "eslint-plugin-react-hooks-extra";
10
- var version = "1.5.28-beta.7";
10
+ var version = "1.5.28-next.2";
11
11
  var createRule = createRuleForPlugin("hooks-extra");
12
12
 
13
13
  // src/rules/ensure-custom-hooks-using-other-hooks.ts
@@ -465,26 +465,29 @@ var no_direct_set_state_in_use_effect_default = createRule({
465
465
  return $(node).when(isEffectFunction, () => "effect").when(isCleanUpFunction, () => "cleanup").when(isIIFE, () => "immediate").otherwise(() => "other");
466
466
  }
467
467
  const useEffectCallRef = MutRef.make(null);
468
+ const callStack = MutList.make();
468
469
  const functionStack = MutList.make();
469
470
  const effectFunctionRef = MutRef.make(null);
470
471
  const cleanUpFunctionRef = MutRef.make(null);
471
- const indirectFunctionCalls = MutRef.make(Chunk.empty());
472
+ const indirectFunctionCalls = [];
472
473
  const indirectSetStateCalls = /* @__PURE__ */ new Map();
474
+ const onUseEffectCallEnter = (node) => void MutRef.set(useEffectCallRef, node);
475
+ const onUseEffectCallExit = () => void MutRef.set(useEffectCallRef, null);
473
476
  return {
474
- ":function"(node) {
475
- const functionKind = getFunctionKind(node);
476
- MutList.append(functionStack, [node, functionKind]);
477
- $(functionKind).with("effect", () => {
478
- MutRef.set(effectFunctionRef, node);
479
- }).with("cleanup", () => {
480
- MutRef.set(cleanUpFunctionRef, node);
481
- }).otherwise(F.constVoid);
482
- },
483
- ":function:exit"(node) {
484
- MutRef.update(effectFunctionRef, (current) => current === node ? null : current);
485
- MutList.pop(functionStack);
477
+ Identifier(node) {
478
+ const isInUseEffectCall = MutRef.get(useEffectCallRef) !== null;
479
+ const parentFn = MutList.tail(functionStack)?.[0];
480
+ const useEffectCall = MutRef.get(useEffectCallRef);
481
+ const isEffectFunction2 = useEffectCall && O.isSome(traverseUp(useEffectCall, (n2) => n2 === parentFn));
482
+ if (isFromUseStateCall(node) && isInUseEffectCall && isEffectFunction2) {
483
+ context.report({
484
+ node,
485
+ messageId: "NO_DIRECT_SET_STATE_IN_USE_EFFECT"
486
+ });
487
+ }
486
488
  },
487
489
  CallExpression(node) {
490
+ MutList.append(callStack, node);
488
491
  const effectFn = MutRef.get(effectFunctionRef);
489
492
  const [parentFn, parentFnKind] = MutList.tail(functionStack) ?? [];
490
493
  if (parentFn?.async) return;
@@ -492,29 +495,47 @@ var no_direct_set_state_in_use_effect_default = createRule({
492
495
  $(callKind).with("setState", () => {
493
496
  if (!parentFn) return;
494
497
  if (parentFn !== effectFn && parentFnKind !== "immediate") {
495
- const calls = indirectSetStateCalls.get(parentFn) ?? Chunk.empty();
496
- indirectSetStateCalls.set(parentFn, Chunk.append(calls, node));
498
+ indirectSetStateCalls.set(parentFn, [...indirectSetStateCalls.get(parentFn) ?? [], node]);
497
499
  return;
498
500
  }
499
501
  context.report({
500
- messageId: "NO_DIRECT_SET_STATE_IN_USE_EFFECT",
501
- node
502
+ node,
503
+ messageId: "NO_DIRECT_SET_STATE_IN_USE_EFFECT"
502
504
  });
503
505
  }).with("useEffect", () => {
504
- MutRef.set(useEffectCallRef, node);
506
+ onUseEffectCallEnter(node);
507
+ }).with("useState", () => {
508
+ }).with("then", () => {
505
509
  }).with("other", () => {
506
- const isInEffectFunction = effectFn === parentFn;
507
- if (!isInEffectFunction) return;
508
- MutRef.update(indirectFunctionCalls, Chunk.append(node));
509
- }).otherwise(F.constVoid);
510
+ indirectFunctionCalls.push(node);
511
+ }).exhaustive();
512
+ },
513
+ ":function"(node) {
514
+ const functionKind = getFunctionKind(node);
515
+ MutList.append(functionStack, [node, functionKind]);
516
+ $(functionKind).with("effect", () => {
517
+ MutRef.set(effectFunctionRef, node);
518
+ }).with("cleanup", () => {
519
+ MutRef.set(cleanUpFunctionRef, node);
520
+ }).otherwise(() => {
521
+ });
522
+ },
523
+ ":function:exit"(node) {
524
+ const effectFn = MutRef.get(effectFunctionRef);
525
+ if (effectFn === node) {
526
+ MutRef.set(effectFunctionRef, null);
527
+ }
528
+ MutList.pop(functionStack);
510
529
  },
511
530
  "CallExpression:exit"(node) {
531
+ MutList.pop(callStack);
512
532
  if (MutRef.get(useEffectCallRef) === node) {
533
+ onUseEffectCallExit();
513
534
  MutRef.set(useEffectCallRef, null);
514
535
  }
515
536
  },
516
537
  "Program:exit"() {
517
- for (const call of Chunk.toReadonlyArray(MutRef.get(indirectFunctionCalls))) {
538
+ for (const call of indirectFunctionCalls) {
518
539
  if (!("name" in call.callee)) continue;
519
540
  const { name: name2 } = call.callee;
520
541
  const setStateCalls = F.pipe(
@@ -522,7 +543,6 @@ var no_direct_set_state_in_use_effect_default = createRule({
522
543
  O.flatMap(getVariableInit(0)),
523
544
  O.filter(isFunction),
524
545
  O.flatMapNullable((init) => indirectSetStateCalls.get(init)),
525
- O.map(Chunk.toReadonlyArray),
526
546
  O.getOrElse(() => [])
527
547
  );
528
548
  for (const setStateCall of setStateCalls) {
@@ -619,26 +639,29 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
619
639
  return $(node).when(isEffectFunction, () => "effect").when(isCleanUpFunction, () => "cleanup").when(isIIFE, () => "immediate").otherwise(() => "other");
620
640
  }
621
641
  const useLayoutEffectCallRef = MutRef.make(null);
642
+ const callStack = MutList.make();
622
643
  const functionStack = MutList.make();
623
644
  const effectFunctionRef = MutRef.make(null);
624
645
  const cleanUpFunctionRef = MutRef.make(null);
625
- const indirectFunctionCalls = MutRef.make(Chunk.empty());
646
+ const indirectFunctionCalls = [];
626
647
  const indirectSetStateCalls = /* @__PURE__ */ new Map();
648
+ const onUseLayoutEffectCallEnter = (node) => void MutRef.set(useLayoutEffectCallRef, node);
649
+ const onUseLayoutEffectCallExit = () => void MutRef.set(useLayoutEffectCallRef, null);
627
650
  return {
628
- ":function"(node) {
629
- const functionKind = getFunctionKind(node);
630
- MutList.append(functionStack, [node, functionKind]);
631
- $(functionKind).with("effect", () => {
632
- MutRef.set(effectFunctionRef, node);
633
- }).with("cleanup", () => {
634
- MutRef.set(cleanUpFunctionRef, node);
635
- }).otherwise(F.constVoid);
636
- },
637
- ":function:exit"(node) {
638
- MutRef.update(effectFunctionRef, (current) => current === node ? null : current);
639
- MutList.pop(functionStack);
651
+ Identifier(node) {
652
+ const isInUseLayoutEffectCall = MutRef.get(useLayoutEffectCallRef) !== null;
653
+ const parentFn = MutList.tail(functionStack)?.[0];
654
+ const useLayoutEffectCall = MutRef.get(useLayoutEffectCallRef);
655
+ const isEffectFunction2 = useLayoutEffectCall && O.isSome(traverseUp(useLayoutEffectCall, (n2) => n2 === parentFn));
656
+ if (isFromUseStateCall(node) && isInUseLayoutEffectCall && isEffectFunction2) {
657
+ context.report({
658
+ node,
659
+ messageId: "NO_DIRECT_SET_STATE_IN_USE_LAYOUT_EFFECT"
660
+ });
661
+ }
640
662
  },
641
663
  CallExpression(node) {
664
+ MutList.append(callStack, node);
642
665
  const effectFn = MutRef.get(effectFunctionRef);
643
666
  const [parentFn, parentFnKind] = MutList.tail(functionStack) ?? [];
644
667
  if (parentFn?.async) return;
@@ -646,29 +669,47 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
646
669
  $(callKind).with("setState", () => {
647
670
  if (!parentFn) return;
648
671
  if (parentFn !== effectFn && parentFnKind !== "immediate") {
649
- const calls = indirectSetStateCalls.get(parentFn) ?? Chunk.empty();
650
- indirectSetStateCalls.set(parentFn, Chunk.append(calls, node));
672
+ indirectSetStateCalls.set(parentFn, [...indirectSetStateCalls.get(parentFn) ?? [], node]);
651
673
  return;
652
674
  }
653
675
  context.report({
654
- messageId: "NO_DIRECT_SET_STATE_IN_USE_LAYOUT_EFFECT",
655
- node
676
+ node,
677
+ messageId: "NO_DIRECT_SET_STATE_IN_USE_LAYOUT_EFFECT"
656
678
  });
657
679
  }).with("useLayoutEffect", () => {
658
- MutRef.set(useLayoutEffectCallRef, node);
680
+ onUseLayoutEffectCallEnter(node);
681
+ }).with("useState", () => {
682
+ }).with("then", () => {
659
683
  }).with("other", () => {
660
- const isInEffectFunction = effectFn === parentFn;
661
- if (!isInEffectFunction) return;
662
- MutRef.update(indirectFunctionCalls, Chunk.append(node));
663
- }).otherwise(F.constVoid);
684
+ indirectFunctionCalls.push(node);
685
+ }).exhaustive();
686
+ },
687
+ ":function"(node) {
688
+ const functionKind = getFunctionKind(node);
689
+ MutList.append(functionStack, [node, functionKind]);
690
+ $(functionKind).with("effect", () => {
691
+ MutRef.set(effectFunctionRef, node);
692
+ }).with("cleanup", () => {
693
+ MutRef.set(cleanUpFunctionRef, node);
694
+ }).otherwise(() => {
695
+ });
696
+ },
697
+ ":function:exit"(node) {
698
+ const effectFn = MutRef.get(effectFunctionRef);
699
+ if (effectFn === node) {
700
+ MutRef.set(effectFunctionRef, null);
701
+ }
702
+ MutList.pop(functionStack);
664
703
  },
665
704
  "CallExpression:exit"(node) {
705
+ MutList.pop(callStack);
666
706
  if (MutRef.get(useLayoutEffectCallRef) === node) {
707
+ onUseLayoutEffectCallExit();
667
708
  MutRef.set(useLayoutEffectCallRef, null);
668
709
  }
669
710
  },
670
711
  "Program:exit"() {
671
- for (const call of Chunk.toReadonlyArray(MutRef.get(indirectFunctionCalls))) {
712
+ for (const call of indirectFunctionCalls) {
672
713
  if (!("name" in call.callee)) continue;
673
714
  const { name: name2 } = call.callee;
674
715
  const setStateCalls = F.pipe(
@@ -676,7 +717,6 @@ var no_direct_set_state_in_use_layout_effect_default = createRule({
676
717
  O.flatMap(getVariableInit(0)),
677
718
  O.filter(isFunction),
678
719
  O.flatMapNullable((init) => indirectSetStateCalls.get(init)),
679
- O.map(Chunk.toReadonlyArray),
680
720
  O.getOrElse(() => [])
681
721
  );
682
722
  for (const setStateCall of setStateCalls) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-hooks-extra",
3
- "version": "1.5.28-beta.7",
3
+ "version": "1.5.28-next.2",
4
4
  "description": "ESLint React's ESLint plugin for React Hooks related rules.",
5
5
  "homepage": "https://github.com/rel1cx/eslint-react",
6
6
  "bugs": {
@@ -39,13 +39,13 @@
39
39
  "@typescript-eslint/type-utils": "^7.16.1",
40
40
  "@typescript-eslint/types": "^7.16.1",
41
41
  "@typescript-eslint/utils": "^7.16.1",
42
- "@eslint-react/ast": "1.5.28-beta.7",
43
- "@eslint-react/core": "1.5.28-beta.7",
44
- "@eslint-react/jsx": "1.5.28-beta.7",
45
- "@eslint-react/shared": "1.5.28-beta.7",
46
- "@eslint-react/tools": "1.5.28-beta.7",
47
- "@eslint-react/types": "1.5.28-beta.7",
48
- "@eslint-react/var": "1.5.28-beta.7"
42
+ "@eslint-react/ast": "1.5.28-next.2",
43
+ "@eslint-react/core": "1.5.28-next.2",
44
+ "@eslint-react/shared": "1.5.28-next.2",
45
+ "@eslint-react/types": "1.5.28-next.2",
46
+ "@eslint-react/var": "1.5.28-next.2",
47
+ "@eslint-react/jsx": "1.5.28-next.2",
48
+ "@eslint-react/tools": "1.5.28-next.2"
49
49
  },
50
50
  "devDependencies": {
51
51
  "string-ts": "2.2.0",