miniread 1.121.1 → 1.121.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.
Files changed (70) hide show
  1. package/dist/presets/recommended/manifest.json +2 -2
  2. package/dist/transforms/shared/default-options-parameter-names/collect-default-options-parameter-names.js +68 -12
  3. package/dist/transforms/shared/default-options-parameter-names/get-defaulted-parameter-name.js +27 -0
  4. package/dist/transforms-by-id/rename-arguments-length-flags/has-shadowed-arguments-binding.js +5 -2
  5. package/dist/transforms-by-id/rename-arguments-length-flags/manifest.json +4 -4
  6. package/dist/transforms-by-id/rename-arguments-length-flags/rename-arguments-length-flags-transform.js +97 -4
  7. package/dist/transforms-by-id/rename-asap-wrappers/get-asap-wrapper-details.d.ts +2 -2
  8. package/dist/transforms-by-id/rename-asap-wrappers/get-asap-wrapper-details.js +32 -27
  9. package/dist/transforms-by-id/rename-asap-wrappers/get-direct-scheduled-callback-name.d.ts +2 -0
  10. package/dist/transforms-by-id/rename-asap-wrappers/get-direct-scheduled-callback-name.js +62 -0
  11. package/dist/transforms-by-id/rename-asap-wrappers/get-forwarded-arguments-identifier.js +19 -19
  12. package/dist/transforms-by-id/rename-asap-wrappers/is-asap-callee.d.ts +2 -0
  13. package/dist/transforms-by-id/rename-asap-wrappers/is-asap-callee.js +26 -0
  14. package/dist/transforms-by-id/rename-asap-wrappers/manifest.json +4 -4
  15. package/dist/transforms-by-id/rename-asap-wrappers/rename-asap-wrappers-transform.js +45 -26
  16. package/dist/transforms-by-id/rename-awaiter-parameters/awaiter-pattern.d.ts +3 -2
  17. package/dist/transforms-by-id/rename-awaiter-parameters/awaiter-pattern.js +1 -1
  18. package/dist/transforms-by-id/rename-awaiter-parameters/manifest.json +3 -3
  19. package/dist/transforms-by-id/rename-awaiter-parameters/rename-awaiter-bindings.d.ts +1 -1
  20. package/dist/transforms-by-id/rename-awaiter-parameters/rename-awaiter-bindings.js +47 -40
  21. package/dist/transforms-by-id/rename-default-options-parameters-v3/manifest.json +4 -4
  22. package/dist/transforms-by-id/rename-default-options-parameters-v3/rename-default-options-parameters-v3-transform.js +1 -4
  23. package/dist/transforms-by-id/rename-http-server-parameters/analyze-parameters.d.ts +4 -1
  24. package/dist/transforms-by-id/rename-http-server-parameters/analyze-parameters.js +6 -5
  25. package/dist/transforms-by-id/rename-http-server-parameters/detector.js +33 -6
  26. package/dist/transforms-by-id/rename-http-server-parameters/get-listener-from-argument-path.js +31 -4
  27. package/dist/transforms-by-id/rename-http-server-parameters/get-listener-from-request-event-registration.js +14 -3
  28. package/dist/transforms-by-id/rename-http-server-parameters/handlers.d.ts +1 -1
  29. package/dist/transforms-by-id/rename-http-server-parameters/handlers.js +26 -12
  30. package/dist/transforms-by-id/rename-http-server-parameters/manifest.json +3 -3
  31. package/dist/transforms-by-id/rename-http-server-parameters/rename-http-server-parameters-transform.js +4 -4
  32. package/dist/transforms-by-id/rename-http-server-parameters/validate-listener.js +16 -6
  33. package/dist/transforms-by-id/rename-indexeddb-request-variables/analyze-indexeddb-request-binding.d.ts +2 -1
  34. package/dist/transforms-by-id/rename-indexeddb-request-variables/analyze-indexeddb-request-binding.js +57 -0
  35. package/dist/transforms-by-id/rename-indexeddb-request-variables/collect-local-dynamic-lookup-scopes.d.ts +3 -0
  36. package/dist/transforms-by-id/rename-indexeddb-request-variables/collect-local-dynamic-lookup-scopes.js +29 -0
  37. package/dist/transforms-by-id/rename-indexeddb-request-variables/manifest.json +3 -3
  38. package/dist/transforms-by-id/rename-indexeddb-request-variables/rename-indexeddb-request-variables-transform.js +32 -16
  39. package/dist/transforms-by-id/rename-invalid-parameter-arguments/get-member-expression-object-parameter-binding.d.ts +3 -0
  40. package/dist/transforms-by-id/rename-invalid-parameter-arguments/get-member-expression-object-parameter-binding.js +16 -0
  41. package/dist/transforms-by-id/rename-invalid-parameter-arguments/get-name-argument-value.d.ts +3 -0
  42. package/dist/transforms-by-id/rename-invalid-parameter-arguments/get-name-argument-value.js +16 -0
  43. package/dist/transforms-by-id/rename-invalid-parameter-arguments/is-invalid-parameter-error-call.d.ts +3 -0
  44. package/dist/transforms-by-id/rename-invalid-parameter-arguments/is-invalid-parameter-error-call.js +37 -0
  45. package/dist/transforms-by-id/rename-invalid-parameter-arguments/manifest.json +4 -4
  46. package/dist/transforms-by-id/rename-invalid-parameter-arguments/rename-invalid-parameter-arguments-transform.js +36 -19
  47. package/dist/transforms-by-id/rename-object-entries-parameters/is-object-entries-consumer-call.js +44 -17
  48. package/dist/transforms-by-id/rename-object-entries-parameters/manifest.json +3 -3
  49. package/dist/transforms-by-id/rename-object-entries-parameters/rename-object-entries-parameters-transform.js +13 -14
  50. package/dist/transforms-by-id/replace-dynamic-require-eval/is-eval-require-callee.d.ts +3 -0
  51. package/dist/transforms-by-id/replace-dynamic-require-eval/is-eval-require-callee.js +42 -0
  52. package/dist/transforms-by-id/replace-dynamic-require-eval/is-obfuscated-require-eval-call-argument.d.ts +6 -0
  53. package/dist/transforms-by-id/replace-dynamic-require-eval/is-obfuscated-require-eval-call-argument.js +49 -0
  54. package/dist/transforms-by-id/replace-dynamic-require-eval/manifest.json +2 -2
  55. package/dist/transforms-by-id/replace-dynamic-require-eval/replace-dynamic-require-eval-transform.js +6 -26
  56. package/dist/transforms-by-id/stabilize-deferred-stable-rhs/check-rhs-stability.d.ts +1 -1
  57. package/dist/transforms-by-id/stabilize-deferred-stable-rhs/check-rhs-stability.js +6 -2
  58. package/dist/transforms-by-id/stabilize-deferred-stable-rhs/get-rhs-code-for-stable-hash.d.ts +2 -0
  59. package/dist/transforms-by-id/stabilize-deferred-stable-rhs/get-rhs-code-for-stable-hash.js +33 -0
  60. package/dist/transforms-by-id/stabilize-deferred-stable-rhs/get-single-assigned-identifier-name.d.ts +3 -0
  61. package/dist/transforms-by-id/stabilize-deferred-stable-rhs/get-single-assigned-identifier-name.js +63 -0
  62. package/dist/transforms-by-id/stabilize-deferred-stable-rhs/has-name-independent-shadowing-risk.d.ts +2 -0
  63. package/dist/transforms-by-id/stabilize-deferred-stable-rhs/has-name-independent-shadowing-risk.js +17 -0
  64. package/dist/transforms-by-id/stabilize-deferred-stable-rhs/manifest.json +5 -5
  65. package/dist/transforms-by-id/stabilize-deferred-stable-rhs/stabilize-deferred-stable-rhs-transform.js +16 -25
  66. package/dist/transforms-by-id/stabilize-top-level-bindings/collect-first-program-scope-assignments.js +20 -1
  67. package/dist/transforms-by-id/stabilize-top-level-bindings/has-disallowed-function-class-assignment-reference.d.ts +2 -3
  68. package/dist/transforms-by-id/stabilize-top-level-bindings/has-disallowed-function-class-assignment-reference.js +43 -54
  69. package/dist/transforms-by-id/stabilize-top-level-bindings/manifest.json +6 -6
  70. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "recommended": {
3
- "diffSizePercent": 22.779415655592093,
4
- "notes": "Measured with baseline none: 22.78% of original diff."
3
+ "diffSizePercent": 23.382280681861133,
4
+ "notes": "Measured with baseline none: 23.38% of original diff."
5
5
  }
6
6
  }
@@ -25,6 +25,56 @@ const getDefaultOptionsParameterNamesFromChain = (statement, parameterNames, all
25
25
  }
26
26
  return matchedParameterName;
27
27
  };
28
+ const isEmptyObjectLiteral = (expression) => {
29
+ if (!t.isObjectExpression(expression))
30
+ return false;
31
+ return expression.properties.length === 0;
32
+ };
33
+ const getExpressionStatementDefaultedParameterName = (statement, parameterNames) => {
34
+ if (!t.isExpressionStatement(statement))
35
+ return undefined;
36
+ const { expression } = statement;
37
+ if (t.isAssignmentExpression(expression) &&
38
+ (expression.operator === "||=" || expression.operator === "??=")) {
39
+ if (!t.isIdentifier(expression.left))
40
+ return undefined;
41
+ if (!parameterNames.has(expression.left.name))
42
+ return undefined;
43
+ if (!isEmptyObjectLiteral(expression.right))
44
+ return undefined;
45
+ return expression.left.name;
46
+ }
47
+ if (t.isAssignmentExpression(expression) &&
48
+ expression.operator === "=" &&
49
+ t.isIdentifier(expression.left) &&
50
+ t.isLogicalExpression(expression.right) &&
51
+ (expression.right.operator === "||" || expression.right.operator === "??")) {
52
+ const { left, right } = expression.right;
53
+ if (!t.isIdentifier(left, { name: expression.left.name }))
54
+ return undefined;
55
+ if (!parameterNames.has(expression.left.name))
56
+ return undefined;
57
+ if (!isEmptyObjectLiteral(right))
58
+ return undefined;
59
+ return expression.left.name;
60
+ }
61
+ if (t.isLogicalExpression(expression) &&
62
+ (expression.operator === "||" || expression.operator === "??")) {
63
+ if (!t.isIdentifier(expression.left))
64
+ return undefined;
65
+ if (!parameterNames.has(expression.left.name))
66
+ return undefined;
67
+ const right = expression.right;
68
+ if (!t.isAssignmentExpression(right, { operator: "=" }))
69
+ return undefined;
70
+ if (!t.isIdentifier(right.left, { name: expression.left.name }))
71
+ return undefined;
72
+ if (!isEmptyObjectLiteral(right.right))
73
+ return undefined;
74
+ return expression.left.name;
75
+ }
76
+ return undefined;
77
+ };
28
78
  export const collectDefaultOptionsParameterNames = (path) => {
29
79
  // Intentionally includes parent scopes, so an outer `function(undefined){...}`
30
80
  // disables identifier-based undefined checks for nested functions too.
@@ -42,13 +92,24 @@ export const collectDefaultOptionsParameterNames = (path) => {
42
92
  parameterNames.add(parameter.left.name);
43
93
  }
44
94
  }
45
- let sawIfStatement = false;
46
- let matchedParameterName;
95
+ let sawDefaultingStatement = false;
96
+ const matchedParameterNames = new Set();
47
97
  for (const statement of body.body) {
48
98
  if (t.isExpressionStatement(statement) &&
49
99
  t.isStringLiteral(statement.expression)) {
50
100
  continue;
51
101
  }
102
+ if (!sawDefaultingStatement &&
103
+ t.isVariableDeclaration(statement) &&
104
+ statement.declarations.every((declarator) => t.isIdentifier(declarator.id) && declarator.init === null)) {
105
+ continue;
106
+ }
107
+ const expressionStatementMatch = getExpressionStatementDefaultedParameterName(statement, parameterNames);
108
+ if (expressionStatementMatch) {
109
+ sawDefaultingStatement = true;
110
+ matchedParameterNames.add(expressionStatementMatch);
111
+ continue;
112
+ }
52
113
  // Intentionally only match chains at the top of the function body.
53
114
  // This keeps matches deterministic and avoids deeper control-flow guesses.
54
115
  if (!t.isIfStatement(statement))
@@ -56,17 +117,12 @@ export const collectDefaultOptionsParameterNames = (path) => {
56
117
  const chainMatch = getDefaultOptionsParameterNamesFromChain(statement, parameterNames, allowUndefinedCheck);
57
118
  if (!chainMatch)
58
119
  break;
59
- sawIfStatement = true;
60
- if (!matchedParameterName) {
61
- matchedParameterName = chainMatch;
62
- continue;
63
- }
64
- if (matchedParameterName !== chainMatch)
65
- return [];
120
+ sawDefaultingStatement = true;
121
+ matchedParameterNames.add(chainMatch);
66
122
  }
67
- if (!sawIfStatement)
123
+ if (!sawDefaultingStatement)
68
124
  return [];
69
- if (!matchedParameterName)
125
+ if (matchedParameterNames.size === 0)
70
126
  return [];
71
- return [matchedParameterName];
127
+ return [...matchedParameterNames];
72
128
  };
@@ -30,6 +30,24 @@ const getVoidZeroCheckedParameterName = (test) => {
30
30
  }
31
31
  return undefined;
32
32
  };
33
+ const getNullishCheckedParameterName = (test) => {
34
+ if (!t.isBinaryExpression(test, { operator: "==" }))
35
+ return undefined;
36
+ const { left, right } = test;
37
+ if (t.isIdentifier(left) && t.isNullLiteral(right)) {
38
+ return left.name;
39
+ }
40
+ if (t.isNullLiteral(left) && t.isIdentifier(right)) {
41
+ return right.name;
42
+ }
43
+ if (t.isIdentifier(left) && isCanonicalUndefinedLiteral(right)) {
44
+ return left.name;
45
+ }
46
+ if (isCanonicalUndefinedLiteral(left) && t.isIdentifier(right)) {
47
+ return right.name;
48
+ }
49
+ return undefined;
50
+ };
33
51
  const getFalsyCheckedParameterName = (test) => {
34
52
  if (!t.isUnaryExpression(test, { operator: "!" }))
35
53
  return undefined;
@@ -95,6 +113,15 @@ export const getDefaultedParameterName = (statement, parameterNames, options) =>
95
113
  }
96
114
  return voidZeroCheckedName;
97
115
  }
116
+ const nullishCheckedName = getNullishCheckedParameterName(statement.test);
117
+ if (nullishCheckedName) {
118
+ if (!parameterNames.has(nullishCheckedName))
119
+ return undefined;
120
+ if (!hasEmptyObjectAssignment(statement.consequent, nullishCheckedName)) {
121
+ return undefined;
122
+ }
123
+ return nullishCheckedName;
124
+ }
98
125
  const falsyCheckedName = getFalsyCheckedParameterName(statement.test);
99
126
  if (falsyCheckedName) {
100
127
  if (!parameterNames.has(falsyCheckedName))
@@ -1,8 +1,11 @@
1
1
  export const hasShadowedArgumentsBinding = (path) => {
2
2
  const functionScope = path.scope.getFunctionParent();
3
- if (!functionScope)
4
- return false;
5
3
  const argumentsBinding = path.scope.getBinding("arguments");
4
+ if (!functionScope) {
5
+ if (!argumentsBinding)
6
+ return false;
7
+ return argumentsBinding.scope.path.isProgram();
8
+ }
6
9
  if (!argumentsBinding)
7
10
  return false;
8
11
  if (functionScope.path.isArrowFunctionExpression()) {
@@ -3,10 +3,10 @@
3
3
  "evaluations": {
4
4
  "claude-code-2.1.10:claude-code-2.1.11": {
5
5
  "diffSizePercent": 100,
6
- "evaluatedAt": "2026-02-22T05:46:09.337Z",
7
- "changedLines": 42,
8
- "durationSeconds": 37.382712167,
9
- "stableNames": 1360
6
+ "evaluatedAt": "2026-02-28T11:36:51.668Z",
7
+ "changedLines": 258,
8
+ "durationSeconds": 102.80917774999999,
9
+ "stableNames": 1363
10
10
  }
11
11
  },
12
12
  "recommended": true,
@@ -1,12 +1,76 @@
1
1
  import { createRequire } from "node:module";
2
+ import { VISITOR_KEYS, isNode, isPrivateName, isFunction, } from "@babel/types";
2
3
  import { RenameGroup, isStableRenamed } from "../../core/stable-naming.js";
3
4
  import { getFilesToProcess, } from "../../core/types.js";
4
5
  import { getArgumentsLengthBaseName } from "./get-arguments-length-base-name.js";
5
6
  import { getArgumentsLengthMatch } from "./get-arguments-length-match.js";
6
7
  import { hasShadowedArgumentsBinding } from "./has-shadowed-arguments-binding.js";
8
+ import { getExpression, isArgumentsLengthExpression, } from "./arguments-length-expression.js";
7
9
  const require = createRequire(import.meta.url);
8
10
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
9
11
  const traverse = require("@babel/traverse").default;
12
+ const getArgumentsLengthOffsetBaseName = (init) => {
13
+ const left = getExpression(init.left);
14
+ const right = getExpression(init.right);
15
+ if (!left || !right)
16
+ return undefined;
17
+ if (!isArgumentsLengthExpression(left))
18
+ return undefined;
19
+ if (right.type !== "NumericLiteral")
20
+ return undefined;
21
+ if (!Number.isInteger(right.value))
22
+ return undefined;
23
+ if (init.operator === "-") {
24
+ if (right.value < 1)
25
+ return undefined;
26
+ return `argCountMinus${right.value}`;
27
+ }
28
+ if (init.operator === "+") {
29
+ if (right.value < 1)
30
+ return undefined;
31
+ return `argCountPlus${right.value}`;
32
+ }
33
+ return undefined;
34
+ };
35
+ const hasArgumentsLengthReference = (expression) => {
36
+ const stack = [expression];
37
+ while (stack.length > 0) {
38
+ const current = stack.pop();
39
+ if (!current)
40
+ continue;
41
+ if (isArgumentsLengthExpression(current))
42
+ return true;
43
+ if (isFunction(current))
44
+ continue;
45
+ const visitorKeys = VISITOR_KEYS[current.type];
46
+ if (!visitorKeys)
47
+ continue;
48
+ for (const key of visitorKeys) {
49
+ const value = current[key];
50
+ if (Array.isArray(value)) {
51
+ for (const child of value) {
52
+ if (!isNode(child))
53
+ continue;
54
+ if (!isExpression(child))
55
+ continue;
56
+ stack.push(child);
57
+ }
58
+ continue;
59
+ }
60
+ if (!isNode(value) || isPrivateName(value))
61
+ continue;
62
+ if (!isExpression(value))
63
+ continue;
64
+ stack.push(value);
65
+ }
66
+ }
67
+ return false;
68
+ };
69
+ const isExpression = (value) => {
70
+ if (!isNode(value))
71
+ return false;
72
+ return !isPrivateName(value);
73
+ };
10
74
  export const renameArgumentsLengthFlagsTransform = {
11
75
  id: "rename-arguments-length-flags",
12
76
  description: "Rename arguments.length guards (>= N, < N) to $hasAtLeastNArgs/$hasFewerThanNArgs when stable",
@@ -28,18 +92,47 @@ export const renameArgumentsLengthFlagsTransform = {
28
92
  const init = path.node.init;
29
93
  if (!init)
30
94
  return;
31
- if (hasShadowedArgumentsBinding(path))
95
+ if (!isExpression(init))
32
96
  return;
33
- const match = getArgumentsLengthMatch(init);
34
- if (!match || match.condition.count < 1)
97
+ if (hasShadowedArgumentsBinding(path))
35
98
  return;
36
99
  const binding = path.scope.getBinding(id.name);
37
100
  if (!binding?.constant)
38
101
  return;
102
+ if (isArgumentsLengthExpression(init)) {
103
+ renameGroup.add({
104
+ scope: binding.scope,
105
+ currentName: id.name,
106
+ baseName: "argCount",
107
+ });
108
+ return;
109
+ }
110
+ if (init.type === "BinaryExpression") {
111
+ const offsetBaseName = getArgumentsLengthOffsetBaseName(init);
112
+ if (offsetBaseName) {
113
+ renameGroup.add({
114
+ scope: binding.scope,
115
+ currentName: id.name,
116
+ baseName: offsetBaseName,
117
+ });
118
+ return;
119
+ }
120
+ }
121
+ const match = getArgumentsLengthMatch(init);
122
+ if (match && match.condition.count >= 1) {
123
+ renameGroup.add({
124
+ scope: binding.scope,
125
+ currentName: id.name,
126
+ baseName: getArgumentsLengthBaseName(match),
127
+ });
128
+ return;
129
+ }
130
+ if (!hasArgumentsLengthReference(init))
131
+ return;
39
132
  renameGroup.add({
40
133
  scope: binding.scope,
41
134
  currentName: id.name,
42
- baseName: getArgumentsLengthBaseName(match),
135
+ baseName: "argLengthValue",
43
136
  });
44
137
  },
45
138
  });
@@ -1,5 +1,5 @@
1
- import type { ArrowFunctionExpression, FunctionExpression } from "@babel/types";
2
- export declare const getAsapWrapperDetails: (init: ArrowFunctionExpression | FunctionExpression) => {
1
+ import type { ArrowFunctionExpression, FunctionDeclaration, FunctionExpression } from "@babel/types";
2
+ export declare const getAsapWrapperDetails: (init: ArrowFunctionExpression | FunctionExpression | FunctionDeclaration) => {
3
3
  outerParameterName: string;
4
4
  innerParameterName: string | undefined;
5
5
  } | undefined;
@@ -1,19 +1,7 @@
1
+ import { getDirectScheduledCallbackName } from "./get-direct-scheduled-callback-name.js";
1
2
  import { getForwardedArgumentsIdentifier } from "./get-forwarded-arguments-identifier.js";
2
3
  import { hasExactlyOneLexicalReturnStatement } from "./has-exactly-one-lexical-return-statement.js";
3
- const SCHEDULER_METHOD_NAMES = new Set(["asap", "nextTick", "queueMicrotask"]);
4
- const isAsapCallee = (call) => {
5
- const callee = call.callee;
6
- if (callee.type === "Identifier") {
7
- return SCHEDULER_METHOD_NAMES.has(callee.name);
8
- }
9
- if (callee.type === "MemberExpression") {
10
- if (callee.computed)
11
- return false;
12
- return (callee.property.type === "Identifier" &&
13
- SCHEDULER_METHOD_NAMES.has(callee.property.name));
14
- }
15
- return false;
16
- };
4
+ import { isAsapCallee } from "./is-asap-callee.js";
17
5
  const getIdentifierName = (node) => {
18
6
  if (node.type === "Identifier")
19
7
  return node.name;
@@ -81,11 +69,22 @@ const getInnerParameterName = (inner) => {
81
69
  return getIdentifierName(innerParameter);
82
70
  };
83
71
  export const getAsapWrapperDetails = (init) => {
84
- if (init.params.length !== 1)
72
+ if (init.params.length === 0)
85
73
  return undefined;
86
74
  const outerParameter = init.params[0];
87
75
  if (outerParameter?.type !== "Identifier")
88
76
  return undefined;
77
+ if (init.body.type === "BlockStatement") {
78
+ const directScheduledCallbackName = getDirectScheduledCallbackName(init.body);
79
+ if (directScheduledCallbackName) {
80
+ if (directScheduledCallbackName !== outerParameter.name)
81
+ return undefined;
82
+ return {
83
+ outerParameterName: outerParameter.name,
84
+ innerParameterName: undefined,
85
+ };
86
+ }
87
+ }
89
88
  const inner = getInnerWrapperFunction(init);
90
89
  if (!inner)
91
90
  return undefined;
@@ -100,8 +99,20 @@ export const getAsapWrapperDetails = (init) => {
100
99
  if (innerCallExpression.arguments.length === 0)
101
100
  return undefined;
102
101
  const callback = innerCallExpression.arguments[0];
103
- if (callback?.type !== "ArrowFunctionExpression" &&
104
- callback?.type !== "FunctionExpression") {
102
+ if (!callback)
103
+ return undefined;
104
+ if (callback.type === "Identifier") {
105
+ if (callback.name !== outerParameter.name)
106
+ return undefined;
107
+ if (inner.params.length > 0)
108
+ return undefined;
109
+ return {
110
+ outerParameterName: outerParameter.name,
111
+ innerParameterName,
112
+ };
113
+ }
114
+ if (callback.type !== "ArrowFunctionExpression" &&
115
+ callback.type !== "FunctionExpression") {
105
116
  return undefined;
106
117
  }
107
118
  if (callback.params.length > 0)
@@ -109,21 +120,15 @@ export const getAsapWrapperDetails = (init) => {
109
120
  const callbackCallExpression = getFunctionCallExpression(callback);
110
121
  if (!callbackCallExpression)
111
122
  return undefined;
112
- const forwardedArgumentsName = getForwardedArgumentsIdentifier(callbackCallExpression, outerParameter.name);
113
- if (!forwardedArgumentsName)
114
- return undefined;
115
- if (innerParameterName) {
116
- if (forwardedArgumentsName !== innerParameterName)
117
- return undefined;
118
- }
119
- else {
120
- if (forwardedArgumentsName !== "arguments")
121
- return undefined;
123
+ if (innerParameterName === undefined) {
122
124
  if (callback.type !== "ArrowFunctionExpression")
123
125
  return undefined;
124
126
  if (inner.type !== "FunctionExpression")
125
127
  return undefined;
126
128
  }
129
+ const forwardedArgumentsName = getForwardedArgumentsIdentifier(callbackCallExpression, outerParameter.name);
130
+ if (!forwardedArgumentsName)
131
+ return undefined;
127
132
  return {
128
133
  outerParameterName: outerParameter.name,
129
134
  innerParameterName,
@@ -0,0 +1,2 @@
1
+ import type { BlockStatement } from "@babel/types";
2
+ export declare const getDirectScheduledCallbackName: (body: BlockStatement) => string | undefined;
@@ -0,0 +1,62 @@
1
+ const getStatementCallExpression = (statement) => {
2
+ if (statement.type === "ExpressionStatement" &&
3
+ statement.expression.type === "CallExpression") {
4
+ return statement.expression;
5
+ }
6
+ if (statement.type === "ReturnStatement") {
7
+ if (statement.argument?.type !== "CallExpression")
8
+ return undefined;
9
+ return statement.argument;
10
+ }
11
+ if (statement.type === "BlockStatement") {
12
+ const firstStatement = statement.body[0];
13
+ if (!firstStatement || statement.body.length !== 1)
14
+ return undefined;
15
+ return getStatementCallExpression(firstStatement);
16
+ }
17
+ return undefined;
18
+ };
19
+ export const getDirectScheduledCallbackName = (body) => {
20
+ const maybeIf = body.body.at(-1);
21
+ if (!maybeIf)
22
+ return undefined;
23
+ if (maybeIf.type !== "IfStatement")
24
+ return undefined;
25
+ if (!maybeIf.alternate)
26
+ return undefined;
27
+ if (maybeIf.test.type !== "Identifier")
28
+ return undefined;
29
+ const schedulerName = maybeIf.test.name;
30
+ const schedulerCall = getStatementCallExpression(maybeIf.consequent);
31
+ if (!schedulerCall)
32
+ return undefined;
33
+ if (schedulerCall.callee.type !== "Identifier")
34
+ return undefined;
35
+ if (schedulerCall.callee.name !== schedulerName)
36
+ return undefined;
37
+ const schedulerCallback = schedulerCall.arguments[0];
38
+ if (schedulerCall.arguments.length !== 1)
39
+ return undefined;
40
+ if (schedulerCallback?.type !== "Identifier")
41
+ return undefined;
42
+ const fallbackCall = getStatementCallExpression(maybeIf.alternate);
43
+ if (!fallbackCall)
44
+ return undefined;
45
+ if (fallbackCall.callee.type !== "Identifier")
46
+ return undefined;
47
+ if (fallbackCall.callee.name !== "setTimeout")
48
+ return undefined;
49
+ if (fallbackCall.arguments.length !== 2)
50
+ return undefined;
51
+ const fallbackCallback = fallbackCall.arguments[0];
52
+ const fallbackDelay = fallbackCall.arguments[1];
53
+ if (fallbackCallback?.type !== "Identifier")
54
+ return undefined;
55
+ if (fallbackCallback.name !== schedulerCallback.name)
56
+ return undefined;
57
+ if (fallbackDelay?.type !== "NumericLiteral")
58
+ return undefined;
59
+ if (fallbackDelay.value !== 0)
60
+ return undefined;
61
+ return schedulerCallback.name;
62
+ };
@@ -3,14 +3,13 @@ export const getForwardedArgumentsIdentifier = (callbackCallExpression, outerPar
3
3
  if (callee.type === "Identifier") {
4
4
  if (callee.name !== outerParameterName)
5
5
  return undefined;
6
- if (callbackCallExpression.arguments.length !== 1)
7
- return undefined;
8
- const spreadArgument = callbackCallExpression.arguments[0];
9
- if (spreadArgument?.type !== "SpreadElement")
10
- return undefined;
11
- if (spreadArgument.argument.type !== "Identifier")
12
- return undefined;
13
- return spreadArgument.argument.name;
6
+ const firstArgument = callbackCallExpression.arguments[0];
7
+ if (callbackCallExpression.arguments.length === 1 &&
8
+ firstArgument?.type === "SpreadElement" &&
9
+ firstArgument.argument.type === "Identifier") {
10
+ return firstArgument.argument.name;
11
+ }
12
+ return "$invoked";
14
13
  }
15
14
  if (callee.type !== "MemberExpression" ||
16
15
  callee.computed ||
@@ -21,21 +20,22 @@ export const getForwardedArgumentsIdentifier = (callbackCallExpression, outerPar
21
20
  }
22
21
  if (callee.property.name === "apply") {
23
22
  if (callbackCallExpression.arguments.length !== 2)
24
- return undefined;
25
- const spreadArgument = callbackCallExpression.arguments[1];
26
- if (spreadArgument?.type !== "Identifier")
27
- return undefined;
28
- return spreadArgument.name;
23
+ return "$invoked";
24
+ const argumentsValue = callbackCallExpression.arguments[1];
25
+ if (argumentsValue?.type === "Identifier") {
26
+ return argumentsValue.name;
27
+ }
28
+ return "$invoked";
29
29
  }
30
30
  if (callee.property.name === "call") {
31
31
  if (callbackCallExpression.arguments.length !== 2)
32
- return undefined;
32
+ return "$invoked";
33
33
  const spreadArgument = callbackCallExpression.arguments[1];
34
- if (spreadArgument?.type !== "SpreadElement")
35
- return undefined;
36
- if (spreadArgument.argument.type !== "Identifier")
37
- return undefined;
38
- return spreadArgument.argument.name;
34
+ if (spreadArgument?.type === "SpreadElement" &&
35
+ spreadArgument.argument.type === "Identifier") {
36
+ return spreadArgument.argument.name;
37
+ }
38
+ return "$invoked";
39
39
  }
40
40
  return undefined;
41
41
  };
@@ -0,0 +1,2 @@
1
+ import type { CallExpression } from "@babel/types";
2
+ export declare const isAsapCallee: (call: CallExpression) => boolean;
@@ -0,0 +1,26 @@
1
+ const SCHEDULER_METHOD_NAMES = new Set([
2
+ "asap",
3
+ "nextTick",
4
+ "queueMicrotask",
5
+ "setImmediate",
6
+ ]);
7
+ export const isAsapCallee = (call) => {
8
+ const callee = call.callee;
9
+ if (callee.type === "Identifier") {
10
+ return SCHEDULER_METHOD_NAMES.has(callee.name);
11
+ }
12
+ if (callee.type === "MemberExpression") {
13
+ if (!callee.computed &&
14
+ callee.property.type === "Identifier" &&
15
+ SCHEDULER_METHOD_NAMES.has(callee.property.name)) {
16
+ return true;
17
+ }
18
+ if (callee.computed &&
19
+ callee.property.type === "StringLiteral" &&
20
+ SCHEDULER_METHOD_NAMES.has(callee.property.value)) {
21
+ return true;
22
+ }
23
+ return false;
24
+ }
25
+ return false;
26
+ };
@@ -2,10 +2,10 @@
2
2
  "notes": "Measured with baseline none: 0.00%. Added to recommended for readability.",
3
3
  "evaluations": {
4
4
  "claude-code-2.1.10:claude-code-2.1.11": {
5
- "diffSizePercent": 99.99811014098348,
6
- "evaluatedAt": "2026-02-22T15:48:34.214Z",
7
- "changedLines": 10,
8
- "durationSeconds": 31.124323875,
5
+ "diffSizePercent": 99.99433042295045,
6
+ "evaluatedAt": "2026-02-28T11:41:18.249Z",
7
+ "changedLines": 14,
8
+ "durationSeconds": 39.792677125000004,
9
9
  "stableNames": 1358
10
10
  }
11
11
  },