miniread 1.115.0 → 1.115.1
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/transforms/preset-stats.json +2 -2
- package/dist/transforms-by-id/rename-array-accumulator-variables/manifest.json +4 -4
- package/dist/transforms-by-id/rename-array-accumulator-variables/rename-array-accumulator-variables-transform.js +12 -41
- package/dist/transforms-by-id/rename-invalid-parameter-arguments/manifest.json +8 -8
- package/dist/transforms-by-id/rename-invalid-parameter-arguments/rename-invalid-parameter-arguments-transform.js +6 -8
- package/dist/transforms-by-id/stabilize-deferred-stable-rhs/manifest.json +8 -8
- package/dist/transforms-by-id/stabilize-deferred-stable-rhs/stabilize-deferred-stable-rhs-transform.js +11 -8
- package/dist/transforms-by-id/stabilize-nested-bindings/manifest.json +8 -8
- package/dist/transforms-by-id/stabilize-nested-bindings/stabilize-nested-bindings-transform.js +28 -33
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"recommended": {
|
|
3
|
-
"diffSizePercent": 25.
|
|
4
|
-
"notes": "
|
|
3
|
+
"diffSizePercent": 25.296707865593227,
|
|
4
|
+
"notes": "Measured with baseline none: 25.30% of original diff."
|
|
5
5
|
}
|
|
6
6
|
}
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"notes": "Renames variables initialized as empty arrays with .push()/.unshift() usage to stable/readable names.",
|
|
3
3
|
"evaluations": {
|
|
4
4
|
"claude-code-2.1.10:claude-code-2.1.11": {
|
|
5
|
-
"diffSizePercent":
|
|
6
|
-
"evaluatedAt": "2026-02-
|
|
7
|
-
"changedLines":
|
|
8
|
-
"durationSeconds":
|
|
5
|
+
"diffSizePercent": 98.38606039989418,
|
|
6
|
+
"evaluatedAt": "2026-02-18T06:56:35.742Z",
|
|
7
|
+
"changedLines": 18428,
|
|
8
|
+
"durationSeconds": 52.968690957999996,
|
|
9
9
|
"stableNames": 1360
|
|
10
10
|
}
|
|
11
11
|
},
|
|
@@ -5,42 +5,24 @@ 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;
|
|
7
7
|
const BASE_NAME = "results";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
*/
|
|
12
|
-
const isAccumulatorMutationReference = (referencePath) => {
|
|
13
|
-
const memberPath = referencePath.parentPath;
|
|
14
|
-
if (!memberPath?.isMemberExpression())
|
|
8
|
+
const isArrayInitialization = (path) => {
|
|
9
|
+
const init = path.node.init;
|
|
10
|
+
if (!init)
|
|
15
11
|
return false;
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
if (init.type === "ArrayExpression")
|
|
13
|
+
return true;
|
|
14
|
+
if (init.type !== "NewExpression")
|
|
18
15
|
return false;
|
|
19
|
-
if (
|
|
16
|
+
if (init.callee.type !== "Identifier")
|
|
20
17
|
return false;
|
|
21
|
-
|
|
22
|
-
if (property.type !== "Identifier")
|
|
18
|
+
if (init.callee.name !== "Array")
|
|
23
19
|
return false;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// The member expression must be called: X.push(...) / X.unshift(...)
|
|
27
|
-
const callPath = memberPath.parentPath;
|
|
28
|
-
if (!callPath.isCallExpression())
|
|
29
|
-
return false;
|
|
30
|
-
if (callPath.node.callee !== memberPath.node)
|
|
31
|
-
return false;
|
|
32
|
-
return true;
|
|
33
|
-
};
|
|
34
|
-
/**
|
|
35
|
-
* Checks whether a binding has at least one array mutation call reference,
|
|
36
|
-
* confirming the accumulator pattern.
|
|
37
|
-
*/
|
|
38
|
-
const hasAtLeastOneAccumulatorMutation = (referencePaths) => {
|
|
39
|
-
return referencePaths.some((path) => isAccumulatorMutationReference(path));
|
|
20
|
+
// Only treat the global Array constructor as an array initializer.
|
|
21
|
+
return !path.scope.hasBinding("Array", true);
|
|
40
22
|
};
|
|
41
23
|
export const renameArrayAccumulatorVariablesTransform = {
|
|
42
24
|
id: "rename-array-accumulator-variables",
|
|
43
|
-
description: "Renames variables initialized as
|
|
25
|
+
description: "Renames local variables initialized as arrays to $results/$results2/... or results/results2/...",
|
|
44
26
|
scope: "file",
|
|
45
27
|
parallelizable: true,
|
|
46
28
|
transform(context) {
|
|
@@ -59,24 +41,13 @@ export const renameArrayAccumulatorVariablesTransform = {
|
|
|
59
41
|
return;
|
|
60
42
|
if (currentName === BASE_NAME)
|
|
61
43
|
return;
|
|
62
|
-
|
|
63
|
-
const init = path.node.init;
|
|
64
|
-
if (init?.type !== "ArrayExpression")
|
|
65
|
-
return;
|
|
66
|
-
if (init.elements.length > 0)
|
|
44
|
+
if (!isArrayInitialization(path))
|
|
67
45
|
return;
|
|
68
46
|
const binding = path.scope.getBinding(currentName);
|
|
69
47
|
if (!binding)
|
|
70
48
|
return;
|
|
71
|
-
// Must not be reassigned (Babel treats `const x = []; x.push(1)` as constant)
|
|
72
|
-
if (!binding.constant)
|
|
73
|
-
return;
|
|
74
|
-
// Must have at least one reference
|
|
75
49
|
if (binding.referencePaths.length === 0)
|
|
76
50
|
return;
|
|
77
|
-
// Must have at least one array mutation call to confirm accumulator pattern
|
|
78
|
-
if (!hasAtLeastOneAccumulatorMutation(binding.referencePaths))
|
|
79
|
-
return;
|
|
80
51
|
group.add({
|
|
81
52
|
scope: path.scope,
|
|
82
53
|
currentName,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
|
-
"recommended": true,
|
|
3
|
-
"recommendedOrder": 100,
|
|
4
2
|
"notes": "Added to recommended for readability of invalidParameterError call sites.",
|
|
5
3
|
"evaluations": {
|
|
6
4
|
"claude-code-2.1.10:claude-code-2.1.11": {
|
|
7
|
-
"diffSizePercent":
|
|
8
|
-
"evaluatedAt": "2026-02-
|
|
9
|
-
"changedLines":
|
|
10
|
-
"durationSeconds":
|
|
11
|
-
"stableNames":
|
|
5
|
+
"diffSizePercent": 99.99811516350957,
|
|
6
|
+
"evaluatedAt": "2026-02-17T13:28:14.742Z",
|
|
7
|
+
"changedLines": 420,
|
|
8
|
+
"durationSeconds": 204.312632724,
|
|
9
|
+
"stableNames": 1379
|
|
12
10
|
}
|
|
13
|
-
}
|
|
11
|
+
},
|
|
12
|
+
"recommended": true,
|
|
13
|
+
"recommendedOrder": 100
|
|
14
14
|
}
|
|
@@ -33,15 +33,13 @@ const isInvalidParameterErrorCallee = (callee) => {
|
|
|
33
33
|
}
|
|
34
34
|
if (callee.type !== "MemberExpression")
|
|
35
35
|
return false;
|
|
36
|
-
if (callee.
|
|
37
|
-
return
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (callee.computed)
|
|
41
|
-
return false;
|
|
42
|
-
if (callee.property.type !== "Identifier")
|
|
36
|
+
if (!callee.computed && callee.property.type === "Identifier") {
|
|
37
|
+
return callee.property.name === "invalidParameterError";
|
|
38
|
+
}
|
|
39
|
+
if (!callee.computed || callee.property.type !== "StringLiteral") {
|
|
43
40
|
return false;
|
|
44
|
-
|
|
41
|
+
}
|
|
42
|
+
return callee.property.value === "invalidParameterError";
|
|
45
43
|
};
|
|
46
44
|
const getInvalidParameterRename = (path) => {
|
|
47
45
|
if (!isInvalidParameterErrorCallee(path.node.callee))
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
|
-
"recommended": true,
|
|
3
|
-
"recommendedOrder": 4,
|
|
4
2
|
"notes": "Stabilizes deferred top-level vars whose RHS contains only stable identifiers (globals or $h_/$f_/$v_ prefixed names). Derives names by hashing the RHS code. Complements stabilize-deferred-top-level-bindings by handling multi-var functions.",
|
|
5
3
|
"evaluations": {
|
|
6
4
|
"claude-code-2.1.10:claude-code-2.1.11": {
|
|
7
|
-
"diffSizePercent":
|
|
8
|
-
"evaluatedAt": "2026-02-
|
|
9
|
-
"changedLines":
|
|
10
|
-
"durationSeconds":
|
|
11
|
-
"stableNames":
|
|
5
|
+
"diffSizePercent": 98.27455871791965,
|
|
6
|
+
"evaluatedAt": "2026-02-18T06:53:13.858Z",
|
|
7
|
+
"changedLines": 6008,
|
|
8
|
+
"durationSeconds": 43.110313000000005,
|
|
9
|
+
"stableNames": 1996
|
|
12
10
|
}
|
|
13
|
-
}
|
|
11
|
+
},
|
|
12
|
+
"recommended": true,
|
|
13
|
+
"recommendedOrder": 4
|
|
14
14
|
}
|
|
@@ -5,7 +5,7 @@ import * as t from "@babel/types";
|
|
|
5
5
|
import { getFilesToProcess, } from "../../core/types.js";
|
|
6
6
|
import { generateCode } from "../../core/generate-code.js";
|
|
7
7
|
import { isHashBasedStableName } from "../../core/stable-naming.js";
|
|
8
|
-
import {
|
|
8
|
+
import { renameBindingInPlace } from "../stabilize-deferred-top-level-bindings/rename-helpers.js";
|
|
9
9
|
import { canRenameBindingSafely } from "../../transforms/shared/can-rename-binding-safely.js";
|
|
10
10
|
import { hasAllStableReferences } from "./check-rhs-stability.js";
|
|
11
11
|
const require = createRequire(import.meta.url);
|
|
@@ -35,7 +35,8 @@ export const stabilizeDeferredStableRhsTransform = {
|
|
|
35
35
|
});
|
|
36
36
|
if (!programScope)
|
|
37
37
|
continue;
|
|
38
|
-
const
|
|
38
|
+
const fileProgramScope = programScope;
|
|
39
|
+
const programScopeBindings = new Set(Object.keys(fileProgramScope.bindings));
|
|
39
40
|
// Step 1: Find all uninitialized top-level vars that aren't already stable
|
|
40
41
|
const uninitializedVariables = new Set();
|
|
41
42
|
traverse(fileInfo.ast, {
|
|
@@ -54,7 +55,9 @@ export const stabilizeDeferredStableRhsTransform = {
|
|
|
54
55
|
}
|
|
55
56
|
},
|
|
56
57
|
});
|
|
57
|
-
// Step 2: Find assignments inside
|
|
58
|
+
// Step 2: Find assignments to those vars inside functions.
|
|
59
|
+
// Exclude shadowed locals by requiring the assignment target to resolve
|
|
60
|
+
// to the program-scope binding for that name.
|
|
58
61
|
const assignments = [];
|
|
59
62
|
traverse(fileInfo.ast, {
|
|
60
63
|
AssignmentExpression(path) {
|
|
@@ -64,13 +67,14 @@ export const stabilizeDeferredStableRhsTransform = {
|
|
|
64
67
|
const variableName = path.node.left.name;
|
|
65
68
|
if (!uninitializedVariables.has(variableName))
|
|
66
69
|
return;
|
|
70
|
+
const programBinding = fileProgramScope.getBinding(variableName);
|
|
71
|
+
if (!programBinding)
|
|
72
|
+
return;
|
|
73
|
+
if (path.scope.getBinding(variableName) !== programBinding)
|
|
74
|
+
return;
|
|
67
75
|
const functionPath = path.findParent((p) => p.isFunction());
|
|
68
76
|
if (!functionPath)
|
|
69
77
|
return;
|
|
70
|
-
const enclosingFunctionName = findEnclosingBindingName(functionPath);
|
|
71
|
-
if (!enclosingFunctionName ||
|
|
72
|
-
!isHashBasedStableName(enclosingFunctionName))
|
|
73
|
-
return;
|
|
74
78
|
// Check stability and capture RHS code NOW, before any renames happen.
|
|
75
79
|
// This prevents order-dependent cascading where renaming one var
|
|
76
80
|
// makes another var's RHS appear stable.
|
|
@@ -79,7 +83,6 @@ export const stabilizeDeferredStableRhsTransform = {
|
|
|
79
83
|
assignments.push({
|
|
80
84
|
variableName,
|
|
81
85
|
rhsNode,
|
|
82
|
-
enclosingFunctionName,
|
|
83
86
|
rhsCode: isStable
|
|
84
87
|
? generate(rhsNode, { concise: true }).code
|
|
85
88
|
: undefined,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
|
-
"recommended": true,
|
|
3
|
-
"recommendedOrder": 2,
|
|
4
2
|
"notes": "Stabilizes local bindings inside CommonJS factory callbacks using content-hash naming ($f_<hash>). Must run AFTER stabilize-top-level-bindings. Combined with top-level stabilization, achieves 33.49% diff size (67% reduction from baseline).",
|
|
5
3
|
"evaluations": {
|
|
6
4
|
"claude-code-2.1.10:claude-code-2.1.11": {
|
|
7
|
-
"diffSizePercent":
|
|
8
|
-
"evaluatedAt": "2026-02-
|
|
9
|
-
"changedLines":
|
|
10
|
-
"durationSeconds":
|
|
11
|
-
"stableNames":
|
|
5
|
+
"diffSizePercent": 56.44536417583248,
|
|
6
|
+
"evaluatedAt": "2026-02-18T06:56:26.504Z",
|
|
7
|
+
"changedLines": 115147,
|
|
8
|
+
"durationSeconds": 85.89585675000001,
|
|
9
|
+
"stableNames": 13284
|
|
12
10
|
}
|
|
13
|
-
}
|
|
11
|
+
},
|
|
12
|
+
"recommended": true,
|
|
13
|
+
"recommendedOrder": 2
|
|
14
14
|
}
|
package/dist/transforms-by-id/stabilize-nested-bindings/stabilize-nested-bindings-transform.js
CHANGED
|
@@ -10,11 +10,29 @@ import { isFactoryCallback } from "./is-factory-callback.js";
|
|
|
10
10
|
const require = createRequire(import.meta.url);
|
|
11
11
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
12
12
|
const traverse = require("@babel/traverse").default;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
const renameCallbackLocalBindings = (path) => {
|
|
14
|
+
// Check if first argument is a function (the callback)
|
|
15
|
+
const callArguments = path.node.arguments;
|
|
16
|
+
if (callArguments.length === 0)
|
|
17
|
+
return 0;
|
|
18
|
+
const firstArgument = callArguments[0];
|
|
19
|
+
if (!t.isFunctionExpression(firstArgument) &&
|
|
20
|
+
!t.isArrowFunctionExpression(firstArgument))
|
|
21
|
+
return 0;
|
|
22
|
+
// Verify it looks like a callback shape this transform should process
|
|
23
|
+
if (!isFactoryCallback(firstArgument))
|
|
24
|
+
return 0;
|
|
25
|
+
// Get the path to the function argument
|
|
26
|
+
const functionArgumentPath = path.get("arguments.0");
|
|
27
|
+
if (!functionArgumentPath.isFunctionExpression() &&
|
|
28
|
+
!functionArgumentPath.isArrowFunctionExpression())
|
|
29
|
+
return 0;
|
|
30
|
+
// Skip renaming if callback contains dynamic name lookup (eval, with, etc.)
|
|
31
|
+
if (hasDynamicNameLookup(functionArgumentPath))
|
|
32
|
+
return 0;
|
|
33
|
+
// Collect and rename local bindings
|
|
34
|
+
const candidates = collectFactoryBindings(functionArgumentPath);
|
|
35
|
+
return applyRenames(candidates);
|
|
18
36
|
};
|
|
19
37
|
export const stabilizeNestedBindingsTransform = {
|
|
20
38
|
id: "stabilize-nested-bindings",
|
|
@@ -29,34 +47,11 @@ export const stabilizeNestedBindingsTransform = {
|
|
|
29
47
|
traverse(fileInfo.ast, {
|
|
30
48
|
CallExpression(path) {
|
|
31
49
|
nodesVisited++;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return;
|
|
38
|
-
// Check if first argument is a function (the factory callback)
|
|
39
|
-
const callArguments = path.node.arguments;
|
|
40
|
-
if (callArguments.length === 0)
|
|
41
|
-
return;
|
|
42
|
-
const firstArgument = callArguments[0];
|
|
43
|
-
if (!t.isFunctionExpression(firstArgument) &&
|
|
44
|
-
!t.isArrowFunctionExpression(firstArgument))
|
|
45
|
-
return;
|
|
46
|
-
// Verify it looks like a factory callback
|
|
47
|
-
if (!isFactoryCallback(firstArgument))
|
|
48
|
-
return;
|
|
49
|
-
// Get the path to the function argument
|
|
50
|
-
const functionArgumentPath = path.get("arguments.0");
|
|
51
|
-
if (!functionArgumentPath.isFunctionExpression() &&
|
|
52
|
-
!functionArgumentPath.isArrowFunctionExpression())
|
|
53
|
-
return;
|
|
54
|
-
// Skip renaming if factory contains dynamic name lookup (eval, with, etc.)
|
|
55
|
-
if (hasDynamicNameLookup(functionArgumentPath))
|
|
56
|
-
return;
|
|
57
|
-
// Collect and rename local bindings
|
|
58
|
-
const candidates = collectFactoryBindings(functionArgumentPath);
|
|
59
|
-
fileTransformations += applyRenames(candidates);
|
|
50
|
+
fileTransformations += renameCallbackLocalBindings(path);
|
|
51
|
+
},
|
|
52
|
+
OptionalCallExpression(path) {
|
|
53
|
+
nodesVisited++;
|
|
54
|
+
fileTransformations += renameCallbackLocalBindings(path);
|
|
60
55
|
},
|
|
61
56
|
});
|
|
62
57
|
transformationsApplied += fileTransformations;
|
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.115.
|
|
5
|
+
"version": "1.115.1",
|
|
6
6
|
"description": "Transform minified JavaScript/TypeScript into a more readable form using deterministic AST-based transforms.",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|