miniread 1.6.0 → 1.8.0

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 (74) hide show
  1. package/bin/miniread-snapshot +17 -0
  2. package/dist/core/normalize-code.d.ts +17 -0
  3. package/dist/core/normalize-code.js +35 -0
  4. package/dist/core/stable-naming.d.ts +61 -0
  5. package/dist/core/stable-naming.js +121 -0
  6. package/dist/scripts/evaluate/check-expected-evaluations.js +2 -0
  7. package/dist/scripts/evaluate/check-recommended-snapshot.d.ts +11 -0
  8. package/dist/scripts/evaluate/check-recommended-snapshot.js +53 -0
  9. package/dist/scripts/evaluate/check-snapshots.d.ts +1 -0
  10. package/dist/scripts/evaluate/check-snapshots.js +21 -2
  11. package/dist/scripts/evaluate/transform-content.d.ts +5 -0
  12. package/dist/scripts/evaluate/transform-content.js +23 -13
  13. package/dist/scripts/snapshot/create-snapshot-command.d.ts +9 -0
  14. package/dist/scripts/snapshot/create-snapshot-command.js +32 -0
  15. package/dist/scripts/snapshot/run-snapshot-cli.d.ts +1 -0
  16. package/dist/scripts/snapshot/run-snapshot-cli.js +162 -0
  17. package/dist/scripts/snapshot.d.ts +2 -0
  18. package/dist/scripts/snapshot.js +13 -0
  19. package/dist/transforms/rename-catch-parameters/rename-catch-parameters-transform.js +15 -38
  20. package/dist/transforms/rename-destructured-aliases/rename-destructured-aliases-transform.js +13 -12
  21. package/dist/transforms/rename-event-parameters/process-event-handler-function.d.ts +2 -3
  22. package/dist/transforms/rename-event-parameters/process-event-handler-function.js +13 -9
  23. package/dist/transforms/rename-event-parameters/rename-event-parameters-transform.d.ts +1 -1
  24. package/dist/transforms/rename-event-parameters/rename-event-parameters-transform.js +10 -7
  25. package/dist/transforms/rename-loop-index-variables/rename-loop-index-variables-transform.js +19 -13
  26. package/dist/transforms/rename-promise-executor-parameters/rename-promise-executor-parameters-transform.js +12 -5
  27. package/dist/transforms/rename-timeout-ids/rename-timeout-ids-transform.d.ts +1 -1
  28. package/dist/transforms/rename-timeout-ids/rename-timeout-ids-transform.js +10 -11
  29. package/dist/transforms/rename-use-reference-guards/rename-use-reference-guards-transform.js +10 -11
  30. package/dist/transforms/rename-use-reference-guards-v2/rename-use-reference-guards-v2-transform.d.ts +1 -1
  31. package/dist/transforms/rename-use-reference-guards-v2/rename-use-reference-guards-v2-transform.js +14 -12
  32. package/dist/transforms/transform-registry.js +0 -10
  33. package/package.json +4 -2
  34. package/transform-manifest.json +3 -53
  35. package/dist/transforms/expand-return-sequence/expand-return-sequence-transform.d.ts +0 -2
  36. package/dist/transforms/expand-return-sequence/expand-return-sequence-transform.js +0 -91
  37. package/dist/transforms/expand-sequence-expressions/expand-expression-statement-sequence.d.ts +0 -3
  38. package/dist/transforms/expand-sequence-expressions/expand-expression-statement-sequence.js +0 -57
  39. package/dist/transforms/expand-sequence-expressions/expand-sequence-expressions-transform.d.ts +0 -2
  40. package/dist/transforms/expand-sequence-expressions/expand-sequence-expressions-transform.js +0 -34
  41. package/dist/transforms/expand-sequence-expressions/expand-variable-declaration-sequence.d.ts +0 -3
  42. package/dist/transforms/expand-sequence-expressions/expand-variable-declaration-sequence.js +0 -93
  43. package/dist/transforms/expand-sequence-expressions-v2/expand-expression-statement-sequence.d.ts +0 -3
  44. package/dist/transforms/expand-sequence-expressions-v2/expand-expression-statement-sequence.js +0 -55
  45. package/dist/transforms/expand-sequence-expressions-v2/expand-return-sequence.d.ts +0 -3
  46. package/dist/transforms/expand-sequence-expressions-v2/expand-return-sequence.js +0 -86
  47. package/dist/transforms/expand-sequence-expressions-v2/expand-sequence-expressions-v2-transform.d.ts +0 -2
  48. package/dist/transforms/expand-sequence-expressions-v2/expand-sequence-expressions-v2-transform.js +0 -41
  49. package/dist/transforms/expand-sequence-expressions-v2/expand-variable-declaration-sequence.d.ts +0 -3
  50. package/dist/transforms/expand-sequence-expressions-v2/expand-variable-declaration-sequence.js +0 -93
  51. package/dist/transforms/expand-sequence-expressions-v3/expand-expression-statement-sequence.d.ts +0 -3
  52. package/dist/transforms/expand-sequence-expressions-v3/expand-expression-statement-sequence.js +0 -64
  53. package/dist/transforms/expand-sequence-expressions-v3/expand-return-sequence.d.ts +0 -3
  54. package/dist/transforms/expand-sequence-expressions-v3/expand-return-sequence.js +0 -91
  55. package/dist/transforms/expand-sequence-expressions-v3/expand-sequence-expressions-v3-transform.d.ts +0 -2
  56. package/dist/transforms/expand-sequence-expressions-v3/expand-sequence-expressions-v3-transform.js +0 -48
  57. package/dist/transforms/expand-sequence-expressions-v3/expand-throw-sequence.d.ts +0 -3
  58. package/dist/transforms/expand-sequence-expressions-v3/expand-throw-sequence.js +0 -101
  59. package/dist/transforms/expand-sequence-expressions-v3/expand-variable-declaration-sequence.d.ts +0 -3
  60. package/dist/transforms/expand-sequence-expressions-v3/expand-variable-declaration-sequence.js +0 -99
  61. package/dist/transforms/expand-throw-sequence/expand-throw-sequence-transform.d.ts +0 -2
  62. package/dist/transforms/expand-throw-sequence/expand-throw-sequence-transform.js +0 -117
  63. package/dist/transforms/rename-binding/get-target-name.d.ts +0 -4
  64. package/dist/transforms/rename-binding/get-target-name.js +0 -25
  65. package/dist/transforms/rename-binding/is-valid-binding-identifier.d.ts +0 -1
  66. package/dist/transforms/rename-binding/is-valid-binding-identifier.js +0 -10
  67. package/dist/transforms/rename-use-reference-guards/get-target-name.d.ts +0 -2
  68. package/dist/transforms/rename-use-reference-guards/get-target-name.js +0 -23
  69. package/dist/transforms/rename-use-reference-guards/is-valid-binding-identifier.d.ts +0 -1
  70. package/dist/transforms/rename-use-reference-guards/is-valid-binding-identifier.js +0 -10
  71. package/dist/transforms/rename-use-reference-guards-v2/get-target-name.d.ts +0 -2
  72. package/dist/transforms/rename-use-reference-guards-v2/get-target-name.js +0 -23
  73. package/dist/transforms/rename-use-reference-guards-v2/is-valid-binding-identifier.d.ts +0 -1
  74. package/dist/transforms/rename-use-reference-guards-v2/is-valid-binding-identifier.js +0 -10
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import { runSnapshotCli } from "./snapshot/run-snapshot-cli.js";
3
+ try {
4
+ const exitCode = await runSnapshotCli(process.argv);
5
+ if (exitCode !== 0) {
6
+ process.exitCode = exitCode;
7
+ }
8
+ }
9
+ catch (error) {
10
+ const message = error instanceof Error ? error.message : String(error);
11
+ console.error(`Error: ${message}`);
12
+ process.exitCode = 1;
13
+ }
@@ -1,63 +1,40 @@
1
1
  import { createRequire } from "node:module";
2
+ import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
2
3
  import { getFilesToProcess, } from "../../core/types.js";
3
4
  const require = createRequire(import.meta.url);
4
5
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
5
6
  const traverse = require("@babel/traverse").default;
6
7
  const BASE_NAME = "caughtError";
7
- const getRenamedAncestorCatchCount = (path, renamedCatches) => {
8
- let count = 0;
9
- for (const ancestor of path.getAncestry()) {
10
- if (ancestor === path)
11
- continue;
12
- if (!ancestor.isCatchClause())
13
- continue;
14
- if (renamedCatches.has(ancestor.node))
15
- count++;
16
- }
17
- return count;
18
- };
19
- const getTargetCaughtErrorName = (renamedAncestorCatchCount) => {
20
- if (renamedAncestorCatchCount === 0)
21
- return BASE_NAME;
22
- return `${BASE_NAME}${renamedAncestorCatchCount + 1}`;
23
- };
24
- const getCatchParameterNameIfEligible = (path) => {
25
- const parameter = path.node.param;
26
- if (!parameter)
27
- return;
28
- if (parameter.type !== "Identifier")
29
- return;
30
- if (parameter.name.length > 2)
31
- return;
32
- return parameter.name;
33
- };
34
8
  export const renameCatchParametersTransform = {
35
9
  id: "rename-catch-parameters",
36
- description: "Renames minified catch clause parameters to caughtError/caughtError2/...",
10
+ description: "Renames catch clause parameters to $caughtError/$caughtError2/...",
37
11
  scope: "file",
38
12
  parallelizable: true,
39
13
  transform(context) {
40
14
  let nodesVisited = 0;
41
15
  let transformationsApplied = 0;
42
16
  for (const fileInfo of getFilesToProcess(context)) {
43
- const renamedCatches = new WeakMap();
17
+ const group = new RenameGroup();
44
18
  traverse(fileInfo.ast, {
45
19
  CatchClause(path) {
46
20
  nodesVisited++;
47
- const currentName = getCatchParameterNameIfEligible(path);
48
- if (!currentName)
21
+ const parameter = path.node.param;
22
+ if (!parameter)
49
23
  return;
50
- const renamedAncestorCatchCount = getRenamedAncestorCatchCount(path, renamedCatches);
51
- const targetName = getTargetCaughtErrorName(renamedAncestorCatchCount);
52
- if (currentName === targetName)
24
+ if (parameter.type !== "Identifier")
53
25
  return;
54
- if (path.scope.hasBinding(targetName))
26
+ const currentName = parameter.name;
27
+ // Skip already-stable names
28
+ if (isStableRenamed(currentName))
55
29
  return;
56
- path.scope.rename(currentName, targetName);
57
- renamedCatches.set(path.node, targetName);
58
- transformationsApplied++;
30
+ group.add({
31
+ scope: path.scope,
32
+ currentName,
33
+ baseName: BASE_NAME,
34
+ });
59
35
  },
60
36
  });
37
+ transformationsApplied += group.apply();
61
38
  }
62
39
  return Promise.resolve({
63
40
  nodesVisited,
@@ -1,6 +1,7 @@
1
1
  import { createRequire } from "node:module";
2
2
  import { isIdentifierName, isKeyword, isStrictBindReservedWord, } from "@babel/helper-validator-identifier";
3
3
  import { getFilesToProcess, } from "../../core/types.js";
4
+ import { RenameGroup } from "../../core/stable-naming.js";
4
5
  import { isBindingContext } from "./binding-context.js";
5
6
  const require = createRequire(import.meta.url);
6
7
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
@@ -22,7 +23,7 @@ const isValidBindingIdentifier = (name) => {
22
23
  return false;
23
24
  return true;
24
25
  };
25
- const processObjectPattern = (path, stats) => {
26
+ const processObjectPattern = (path, group) => {
26
27
  // Only process in binding contexts, not assignment expressions
27
28
  if (!isBindingContext(path))
28
29
  return;
@@ -84,14 +85,12 @@ const processObjectPattern = (path, stats) => {
84
85
  referencePath.scope.hasBinding(keyName));
85
86
  if (wouldBeShadowed)
86
87
  continue;
87
- // Rename the variable in the scope
88
- bindingScope.rename(aliasName, keyName);
89
- // Update the destructuring to use shorthand
90
- // For { a: b } -> { a }
91
- // For { a: b = 1 } -> { a = 1 }
92
- property.shorthand = true;
93
- aliasIdentifier.name = keyName;
94
- stats.transformationsApplied++;
88
+ // Add to rename group for batch processing with stability logic
89
+ group.add({
90
+ scope: bindingScope,
91
+ currentName: aliasName,
92
+ baseName: keyName,
93
+ });
95
94
  }
96
95
  };
97
96
  export const renameDestructuredAliasesTransform = {
@@ -101,18 +100,20 @@ export const renameDestructuredAliasesTransform = {
101
100
  parallelizable: true,
102
101
  transform(context) {
103
102
  let nodesVisited = 0;
104
- const stats = { transformationsApplied: 0 };
103
+ let transformationsApplied = 0;
105
104
  for (const fileInfo of getFilesToProcess(context)) {
105
+ const group = new RenameGroup();
106
106
  traverse(fileInfo.ast, {
107
107
  ObjectPattern(path) {
108
108
  nodesVisited++;
109
- processObjectPattern(path, stats);
109
+ processObjectPattern(path, group);
110
110
  },
111
111
  });
112
+ transformationsApplied += group.apply();
112
113
  }
113
114
  return Promise.resolve({
114
115
  nodesVisited,
115
- transformationsApplied: stats.transformationsApplied,
116
+ transformationsApplied,
116
117
  });
117
118
  },
118
119
  };
@@ -1,5 +1,4 @@
1
1
  import type { NodePath } from "@babel/traverse";
2
2
  import type { ArrowFunctionExpression, FunctionDeclaration, FunctionExpression } from "@babel/types";
3
- export declare const processEventHandlerFunction: (path: NodePath<FunctionDeclaration | FunctionExpression | ArrowFunctionExpression>, stats: {
4
- transformationsApplied: number;
5
- }) => void;
3
+ import { type RenameGroup } from "../../core/stable-naming.js";
4
+ export declare const processEventHandlerFunction: (path: NodePath<FunctionDeclaration | FunctionExpression | ArrowFunctionExpression>, group: RenameGroup) => void;
@@ -1,3 +1,4 @@
1
+ import { isStableRenamed } from "../../core/stable-naming.js";
1
2
  import { getEventParameterUsage, isHighConfidenceEventParameter, } from "./event-parameter-usage.js";
2
3
  import { getTargetEventName } from "./get-target-event-name.js";
3
4
  import { canRenameBindingSafely } from "./can-rename-binding-safely.js";
@@ -23,7 +24,7 @@ const wouldShadowReferencedImplicitGlobal = (functionPath, targetName) => {
23
24
  });
24
25
  return foundReference;
25
26
  };
26
- export const processEventHandlerFunction = (path, stats) => {
27
+ export const processEventHandlerFunction = (path, group) => {
27
28
  const parameters = path.node.params;
28
29
  if (parameters.length !== 1)
29
30
  return;
@@ -32,12 +33,12 @@ export const processEventHandlerFunction = (path, stats) => {
32
33
  return;
33
34
  if (parameter.type !== "Identifier")
34
35
  return;
35
- // 1-2 character parameter names are a strong minification signal (e.g. `e`, `t`, `WA`).
36
- // Keeping this conservative avoids renaming common intentional abbreviations (e.g. `evt`).
37
- if (parameter.name.length > 2)
36
+ const currentName = parameter.name;
37
+ // Skip already-stable names
38
+ if (isStableRenamed(currentName))
38
39
  return;
39
40
  const bindingScope = path.scope;
40
- const binding = bindingScope.getBinding(parameter.name);
41
+ const binding = bindingScope.getBinding(currentName);
41
42
  if (!binding)
42
43
  return;
43
44
  if (!binding.constant)
@@ -46,14 +47,17 @@ export const processEventHandlerFunction = (path, stats) => {
46
47
  if (!isHighConfidenceEventParameter(usage))
47
48
  return;
48
49
  const targetName = getTargetEventName(usage);
49
- if (parameter.name === targetName)
50
+ if (currentName === targetName)
50
51
  return;
51
52
  if (wouldShadowReferencedImplicitGlobal(path, targetName))
52
53
  return;
53
54
  if (wouldShadowReferencedOuterBinding(path, targetName))
54
55
  return;
55
- if (!canRenameBindingSafely(bindingScope, parameter.name, targetName))
56
+ if (!canRenameBindingSafely(bindingScope, currentName, targetName))
56
57
  return;
57
- bindingScope.rename(parameter.name, targetName);
58
- stats.transformationsApplied++;
58
+ group.add({
59
+ scope: bindingScope,
60
+ currentName,
61
+ baseName: targetName,
62
+ });
59
63
  };
@@ -1,2 +1,2 @@
1
- import type { Transform } from "../../core/types.js";
1
+ import { type Transform } from "../../core/types.js";
2
2
  export declare const renameEventParametersTransform: Transform;
@@ -1,4 +1,6 @@
1
1
  import { createRequire } from "node:module";
2
+ import { RenameGroup } from "../../core/stable-naming.js";
3
+ import { getFilesToProcess, } from "../../core/types.js";
2
4
  import { processEventHandlerFunction } from "./process-event-handler-function.js";
3
5
  const require = createRequire(import.meta.url);
4
6
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
@@ -9,28 +11,29 @@ export const renameEventParametersTransform = {
9
11
  scope: "file",
10
12
  parallelizable: true,
11
13
  transform(context) {
12
- const { projectGraph } = context;
13
14
  let nodesVisited = 0;
14
- const stats = { transformationsApplied: 0 };
15
- for (const [, fileInfo] of projectGraph.files) {
15
+ let transformationsApplied = 0;
16
+ for (const fileInfo of getFilesToProcess(context)) {
17
+ const group = new RenameGroup();
16
18
  traverse(fileInfo.ast, {
17
19
  FunctionDeclaration(path) {
18
20
  nodesVisited++;
19
- processEventHandlerFunction(path, stats);
21
+ processEventHandlerFunction(path, group);
20
22
  },
21
23
  FunctionExpression(path) {
22
24
  nodesVisited++;
23
- processEventHandlerFunction(path, stats);
25
+ processEventHandlerFunction(path, group);
24
26
  },
25
27
  ArrowFunctionExpression(path) {
26
28
  nodesVisited++;
27
- processEventHandlerFunction(path, stats);
29
+ processEventHandlerFunction(path, group);
28
30
  },
29
31
  });
32
+ transformationsApplied += group.apply();
30
33
  }
31
34
  return Promise.resolve({
32
35
  nodesVisited,
33
- transformationsApplied: stats.transformationsApplied,
36
+ transformationsApplied,
34
37
  });
35
38
  },
36
39
  };
@@ -1,4 +1,5 @@
1
1
  import { createRequire } from "node:module";
2
+ import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
2
3
  import { getFilesToProcess, } from "../../core/types.js";
3
4
  const require = createRequire(import.meta.url);
4
5
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
@@ -15,10 +16,11 @@ const getRenamedAncestorLoopCount = (path, renamedLoops) => {
15
16
  }
16
17
  return count;
17
18
  };
18
- const getTargetIndexName = (renamedAncestorLoopCount) => {
19
+ const BASE_NAME = "index";
20
+ const getTargetIndexBaseName = (renamedAncestorLoopCount) => {
19
21
  if (renamedAncestorLoopCount === 0)
20
- return "index";
21
- return `index${renamedAncestorLoopCount + 1}`;
22
+ return BASE_NAME;
23
+ return `${BASE_NAME}${renamedAncestorLoopCount + 1}`;
22
24
  };
23
25
  const getLoopCounterNameIfEligible = (path) => {
24
26
  const init = path.node.init;
@@ -91,31 +93,35 @@ const getLoopCounterNameIfEligible = (path) => {
91
93
  };
92
94
  export const renameLoopIndexVariablesTransform = {
93
95
  id: "rename-loop-index-variables",
94
- description: "Renames numeric for-loop counters to index/index2/... based on nesting depth",
96
+ description: "Renames numeric for-loop counters to $index/$index2/... based on nesting depth",
95
97
  scope: "file",
96
98
  parallelizable: true,
97
99
  transform(context) {
98
100
  let nodesVisited = 0;
99
101
  let transformationsApplied = 0;
100
102
  for (const fileInfo of getFilesToProcess(context)) {
101
- const renamedLoops = new WeakMap();
103
+ const group = new RenameGroup();
104
+ const eligibleLoops = new WeakMap();
102
105
  traverse(fileInfo.ast, {
103
106
  ForStatement(path) {
104
107
  nodesVisited++;
105
108
  const loopCounterName = getLoopCounterNameIfEligible(path);
106
109
  if (!loopCounterName)
107
110
  return;
108
- const renamedAncestorLoopCount = getRenamedAncestorLoopCount(path, renamedLoops);
109
- const targetName = getTargetIndexName(renamedAncestorLoopCount);
110
- if (loopCounterName === targetName)
111
+ // Skip already-stable names
112
+ if (isStableRenamed(loopCounterName))
111
113
  return;
112
- if (path.scope.hasBinding(targetName))
113
- return;
114
- path.scope.rename(loopCounterName, targetName);
115
- renamedLoops.set(path.node, targetName);
116
- transformationsApplied++;
114
+ const renamedAncestorLoopCount = getRenamedAncestorLoopCount(path, eligibleLoops);
115
+ const baseName = getTargetIndexBaseName(renamedAncestorLoopCount);
116
+ eligibleLoops.set(path.node, baseName);
117
+ group.add({
118
+ scope: path.scope,
119
+ currentName: loopCounterName,
120
+ baseName,
121
+ });
117
122
  },
118
123
  });
124
+ transformationsApplied += group.apply();
119
125
  }
120
126
  return Promise.resolve({
121
127
  nodesVisited,
@@ -1,13 +1,15 @@
1
1
  import { createRequire } from "node:module";
2
+ import { isStableRenamed } from "../../core/stable-naming.js";
2
3
  import { getFilesToProcess, } from "../../core/types.js";
3
4
  import { getExecutorFunctionIfEligible, isAssignedToOnHandlerProperty, isDirectCallOfBinding, wouldShadowReferencedOuterBinding, } from "./promise-executor-heuristics.js";
4
5
  import { canRenameBindingSafely, renameBindingIfSafe, } from "./rename-binding-if-safe.js";
6
+ const STABLE_PREFIX = "$";
5
7
  const require = createRequire(import.meta.url);
6
8
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
7
9
  const traverse = require("@babel/traverse").default;
8
10
  export const renamePromiseExecutorParametersTransform = {
9
11
  id: "rename-promise-executor-parameters",
10
- description: "Renames promise-like executor parameters in `new X(executor)` to resolve/reject when usage is high-confidence",
12
+ description: "Renames promise-like executor parameters in `new X(executor)` to $resolve/$reject when usage is high-confidence",
11
13
  scope: "file",
12
14
  parallelizable: true,
13
15
  transform(context) {
@@ -22,6 +24,11 @@ export const renamePromiseExecutorParametersTransform = {
22
24
  return;
23
25
  const [resolveParameter, rejectParameter] = executorPath.node
24
26
  .params;
27
+ // Skip already-stable names
28
+ if (isStableRenamed(resolveParameter.name))
29
+ return;
30
+ if (isStableRenamed(rejectParameter.name))
31
+ return;
25
32
  const bindingScope = executorPath.scope;
26
33
  const resolveBinding = bindingScope.getBinding(resolveParameter.name);
27
34
  const rejectBinding = bindingScope.getBinding(rejectParameter.name);
@@ -41,10 +48,10 @@ export const renamePromiseExecutorParametersTransform = {
41
48
  isAssignedToOnHandlerProperty(referencePath));
42
49
  if (!rejectIsOnlyCalledOrHandlerAssigned)
43
50
  return;
44
- const resolveWouldShadow = wouldShadowReferencedOuterBinding(executorPath, "resolve");
45
- const rejectWouldShadow = wouldShadowReferencedOuterBinding(executorPath, "reject");
46
- const targetResolveName = "resolve";
47
- const targetRejectName = "reject";
51
+ const targetResolveName = `${STABLE_PREFIX}resolve`;
52
+ const targetRejectName = `${STABLE_PREFIX}reject`;
53
+ const resolveWouldShadow = wouldShadowReferencedOuterBinding(executorPath, targetResolveName);
54
+ const rejectWouldShadow = wouldShadowReferencedOuterBinding(executorPath, targetRejectName);
48
55
  const wantsResolveRename = resolveParameter.name !== targetResolveName;
49
56
  const wantsRejectRename = rejectParameter.name !== targetRejectName;
50
57
  const canRenameResolve = !wantsResolveRename ||
@@ -1,2 +1,2 @@
1
- import type { Transform } from "../../core/types.js";
1
+ import { type Transform } from "../../core/types.js";
2
2
  export declare const renameTimeoutIdsTransform: Transform;
@@ -1,6 +1,6 @@
1
1
  import { createRequire } from "node:module";
2
- import { getFilesToProcess } from "../../core/types.js";
3
- import { getTargetName } from "../rename-binding/get-target-name.js";
2
+ import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
3
+ import { getFilesToProcess, } from "../../core/types.js";
4
4
  const require = createRequire(import.meta.url);
5
5
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
6
6
  const traverse = require("@babel/traverse").default;
@@ -40,20 +40,22 @@ const isClearTimeoutCallArgument = (referencePath, bindingName) => {
40
40
  };
41
41
  export const renameTimeoutIdsTransform = {
42
42
  id: "rename-timeout-ids",
43
- description: "Renames setTimeout handle variables to timeoutId/timeoutId2/... when usage is only clearTimeout(...)",
43
+ description: "Renames setTimeout handle variables to $timeoutId/$timeoutId2/... or timeoutId/timeoutId2/... when usage is only clearTimeout(...)",
44
44
  scope: "file",
45
45
  parallelizable: true,
46
46
  transform(context) {
47
47
  let nodesVisited = 0;
48
48
  let transformationsApplied = 0;
49
49
  for (const fileInfo of getFilesToProcess(context)) {
50
+ const group = new RenameGroup();
50
51
  traverse(fileInfo.ast, {
51
52
  VariableDeclarator(path) {
52
53
  nodesVisited++;
53
54
  const id = path.node.id;
54
55
  if (id.type !== "Identifier")
55
56
  return;
56
- if (id.name.length > 2)
57
+ // Skip already-stable names
58
+ if (isStableRenamed(id.name))
57
59
  return;
58
60
  const init = path.node.init;
59
61
  if (init?.type !== "CallExpression")
@@ -69,17 +71,14 @@ export const renameTimeoutIdsTransform = {
69
71
  return;
70
72
  if (!binding.referencePaths.every((referencePath) => isClearTimeoutCallArgument(referencePath, id.name)))
71
73
  return;
72
- const targetName = getTargetName(path.scope, binding, {
74
+ group.add({
75
+ scope: path.scope,
76
+ currentName: id.name,
73
77
  baseName: BASE_NAME,
74
78
  });
75
- if (!targetName)
76
- return;
77
- if (id.name === targetName)
78
- return;
79
- path.scope.rename(id.name, targetName);
80
- transformationsApplied++;
81
79
  },
82
80
  });
81
+ transformationsApplied += group.apply();
83
82
  }
84
83
  return Promise.resolve({ nodesVisited, transformationsApplied });
85
84
  },
@@ -1,28 +1,28 @@
1
1
  import { createRequire } from "node:module";
2
+ import { RenameGroup } from "../../core/stable-naming.js";
2
3
  import { getFilesToProcess, } from "../../core/types.js";
3
4
  import { getReferenceUsage } from "./get-reference-usage.js";
4
- import { getTargetName } from "./get-target-name.js";
5
5
  import { isUseReferenceFalseInitializer } from "./is-use-reference-false-initializer.js";
6
6
  const require = createRequire(import.meta.url);
7
7
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
8
8
  const traverse = require("@babel/traverse").default;
9
+ const BASE_NAME = "hasRunRef";
9
10
  const renameUseReferenceGuardsTransform = {
10
11
  id: "rename-use-reference-guards",
11
- description: "Renames boolean useRef(false) guard variables to hasRunRef/hasRunRef2/...",
12
+ description: "Renames boolean useRef(false) guard variables to $hasRunRef/$hasRunRef2/... or hasRunRef/hasRunRef2/...",
12
13
  scope: "file",
13
14
  parallelizable: true,
14
15
  transform(context) {
15
16
  let nodesVisited = 0;
16
17
  let transformationsApplied = 0;
17
18
  for (const fileInfo of getFilesToProcess(context)) {
19
+ const group = new RenameGroup();
18
20
  traverse(fileInfo.ast, {
19
21
  VariableDeclarator(path) {
20
22
  nodesVisited++;
21
23
  const id = path.node.id;
22
24
  if (id.type !== "Identifier")
23
25
  return;
24
- if (id.name.length > 2)
25
- return;
26
26
  if (!isUseReferenceFalseInitializer(path.node))
27
27
  return;
28
28
  const binding = path.scope.getBinding(id.name);
@@ -36,15 +36,14 @@ const renameUseReferenceGuardsTransform = {
36
36
  !usage.hasTrueWrite ||
37
37
  usage.hasFalseWrite)
38
38
  return;
39
- const targetName = getTargetName(path.scope, binding);
40
- if (!targetName)
41
- return;
42
- if (id.name === targetName)
43
- return;
44
- path.scope.rename(id.name, targetName);
45
- transformationsApplied++;
39
+ group.add({
40
+ scope: path.scope,
41
+ currentName: id.name,
42
+ baseName: BASE_NAME,
43
+ });
46
44
  },
47
45
  });
46
+ transformationsApplied += group.apply();
48
47
  }
49
48
  return Promise.resolve({
50
49
  nodesVisited,
@@ -1,3 +1,3 @@
1
- import type { Transform } from "../../core/types.js";
1
+ import { type Transform } from "../../core/types.js";
2
2
  declare const renameUseReferenceGuardsV2Transform: Transform;
3
3
  export { renameUseReferenceGuardsV2Transform };
@@ -1,27 +1,29 @@
1
1
  import { createRequire } from "node:module";
2
+ import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
3
+ import { getFilesToProcess, } from "../../core/types.js";
2
4
  import { getReferenceUsage } from "./get-reference-usage.js";
3
- import { getTargetName } from "./get-target-name.js";
4
5
  import { isUseReferenceFalseInitializer } from "./is-use-reference-false-initializer.js";
5
6
  const require = createRequire(import.meta.url);
6
7
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
7
8
  const traverse = require("@babel/traverse").default;
9
+ const BASE_NAME = "hasRunRef";
8
10
  const renameUseReferenceGuardsV2Transform = {
9
11
  id: "rename-use-reference-guards-v2",
10
- description: "Renames boolean useRef(false) guard variables (including reset-to-false guards) to hasRunRef/hasRunRef2/...",
12
+ description: "Renames boolean useRef(false) guard variables (including reset-to-false guards) to $hasRunRef/$hasRunRef2/... or hasRunRef/hasRunRef2/...",
11
13
  scope: "file",
12
14
  parallelizable: true,
13
15
  transform(context) {
14
- const { projectGraph } = context;
15
16
  let nodesVisited = 0;
16
17
  let transformationsApplied = 0;
17
- for (const [, fileInfo] of projectGraph.files) {
18
+ for (const fileInfo of getFilesToProcess(context)) {
19
+ const group = new RenameGroup();
18
20
  traverse(fileInfo.ast, {
19
21
  VariableDeclarator(path) {
20
22
  nodesVisited++;
21
23
  const id = path.node.id;
22
24
  if (id.type !== "Identifier")
23
25
  return;
24
- if (id.name.length > 2)
26
+ if (isStableRenamed(id.name))
25
27
  return;
26
28
  if (!isUseReferenceFalseInitializer(path.node))
27
29
  return;
@@ -31,17 +33,17 @@ const renameUseReferenceGuardsV2Transform = {
31
33
  if (!binding.constant)
32
34
  return;
33
35
  const usage = getReferenceUsage(binding);
36
+ // Unlike v1, this version also accepts guards that reset to false
34
37
  if (!usage.isSafe || !usage.hasRead || !usage.hasTrueWrite)
35
38
  return;
36
- const targetName = getTargetName(path.scope, binding);
37
- if (!targetName)
38
- return;
39
- if (id.name === targetName)
40
- return;
41
- path.scope.rename(id.name, targetName);
42
- transformationsApplied++;
39
+ group.add({
40
+ scope: path.scope,
41
+ currentName: id.name,
42
+ baseName: BASE_NAME,
43
+ });
43
44
  },
44
45
  });
46
+ transformationsApplied += group.apply();
45
47
  }
46
48
  return Promise.resolve({
47
49
  nodesVisited,
@@ -1,11 +1,6 @@
1
1
  import { expandBooleanLiteralsTransform } from "./expand-boolean-literals/expand-boolean-literals-transform.js";
2
- import { expandReturnSequenceTransform } from "./expand-return-sequence/expand-return-sequence-transform.js";
3
- import { expandSequenceExpressionsTransform } from "./expand-sequence-expressions/expand-sequence-expressions-transform.js";
4
- import { expandSequenceExpressionsV2Transform } from "./expand-sequence-expressions-v2/expand-sequence-expressions-v2-transform.js";
5
2
  import { expandSpecialNumberLiteralsTransform } from "./expand-special-number-literals/expand-special-number-literals-transform.js";
6
- import { expandSequenceExpressionsV3Transform } from "./expand-sequence-expressions-v3/expand-sequence-expressions-v3-transform.js";
7
3
  import { expandSequenceExpressionsV4Transform } from "./expand-sequence-expressions-v4/expand-sequence-expressions-v4-transform.js";
8
- import { expandThrowSequenceTransform } from "./expand-throw-sequence/expand-throw-sequence-transform.js";
9
4
  import { expandUndefinedLiteralsTransform } from "./expand-undefined-literals/expand-undefined-literals-transform.js";
10
5
  import { renameCatchParametersTransform } from "./rename-catch-parameters/rename-catch-parameters-transform.js";
11
6
  import { renameDestructuredAliasesTransform } from "./rename-destructured-aliases/rename-destructured-aliases-transform.js";
@@ -18,13 +13,8 @@ import { renameUseReferenceGuardsV2Transform } from "./rename-use-reference-guar
18
13
  import { splitVariableDeclarationsTransform } from "./split-variable-declarations/split-variable-declarations-transform.js";
19
14
  export const transformRegistry = {
20
15
  [expandBooleanLiteralsTransform.id]: expandBooleanLiteralsTransform,
21
- [expandReturnSequenceTransform.id]: expandReturnSequenceTransform,
22
- [expandSequenceExpressionsTransform.id]: expandSequenceExpressionsTransform,
23
- [expandSequenceExpressionsV2Transform.id]: expandSequenceExpressionsV2Transform,
24
- [expandSequenceExpressionsV3Transform.id]: expandSequenceExpressionsV3Transform,
25
16
  [expandSpecialNumberLiteralsTransform.id]: expandSpecialNumberLiteralsTransform,
26
17
  [expandSequenceExpressionsV4Transform.id]: expandSequenceExpressionsV4Transform,
27
- [expandThrowSequenceTransform.id]: expandThrowSequenceTransform,
28
18
  [expandUndefinedLiteralsTransform.id]: expandUndefinedLiteralsTransform,
29
19
  [renameCatchParametersTransform.id]: renameCatchParametersTransform,
30
20
  [renameDestructuredAliasesTransform.id]: renameDestructuredAliasesTransform,
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "miniread",
3
3
  "author": "Łukasz Jerciński",
4
4
  "license": "MIT",
5
- "version": "1.6.0",
5
+ "version": "1.8.0",
6
6
  "description": "Transform minified JavaScript/TypeScript into a more readable form using deterministic AST-based transforms.",
7
7
  "repository": {
8
8
  "type": "git",
@@ -24,7 +24,8 @@
24
24
  "bin": {
25
25
  "miniread": "bin/miniread",
26
26
  "miniread-evaluate": "bin/miniread-evaluate",
27
- "miniread-sample": "bin/miniread-sample"
27
+ "miniread-sample": "bin/miniread-sample",
28
+ "miniread-snapshot": "bin/miniread-snapshot"
28
29
  },
29
30
  "files": [
30
31
  "bin/",
@@ -47,6 +48,7 @@
47
48
  "miniread": "pnpm -s run rebuild && node bin/miniread",
48
49
  "miniread-evaluate": "pnpm -s run rebuild && node bin/miniread-evaluate",
49
50
  "miniread-sample": "pnpm -s run rebuild && node bin/miniread-sample",
51
+ "snapshot": "pnpm -s run rebuild && node bin/miniread-snapshot",
50
52
  "rebuild": "pnpm run clean && pnpm run build",
51
53
  "test": "vitest run",
52
54
  "test:coverage": "vitest run --coverage",