miniread 1.114.0 → 1.115.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.
- package/dist/transforms/preset-stats.json +2 -2
- package/dist/transforms-by-id/rename-loop-index-variables-v3/get-loop-counter-name.js +0 -4
- package/dist/transforms-by-id/rename-loop-index-variables-v3/manifest.json +3 -3
- package/dist/transforms-by-id/rename-return-object-bindings/collect-return-object-binding-candidates.d.ts +0 -2
- package/dist/transforms-by-id/rename-return-object-bindings/collect-return-object-binding-candidates.js +3 -10
- package/dist/transforms-by-id/rename-return-object-bindings/manifest.json +5 -5
- package/dist/transforms-by-id/rename-return-object-bindings/rename-return-object-bindings-transform.js +0 -3
- package/dist/transforms-by-id/stabilize-deferred-top-level-bindings/collect-deferred-variables.d.ts +4 -3
- package/dist/transforms-by-id/stabilize-deferred-top-level-bindings/collect-deferred-variables.js +28 -6
- package/dist/transforms-by-id/stabilize-deferred-top-level-bindings/manifest.json +6 -6
- package/dist/transforms-by-id/stabilize-deferred-top-level-bindings/stabilize-deferred-top-level-bindings-transform.js +5 -5
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"recommended": {
|
|
3
|
-
"diffSizePercent":
|
|
4
|
-
"notes": "
|
|
3
|
+
"diffSizePercent": 25.50270249839362,
|
|
4
|
+
"notes": "Average test/baseline diff size ratio for the recommended preset with baseline set to none."
|
|
5
5
|
}
|
|
6
6
|
}
|
|
@@ -105,8 +105,6 @@ export const getStableRenamedIndexLoopCounterName = (path) => {
|
|
|
105
105
|
continue;
|
|
106
106
|
if (declarator.init.type !== "NumericLiteral")
|
|
107
107
|
continue;
|
|
108
|
-
if (declarator.init.value !== 0)
|
|
109
|
-
continue;
|
|
110
108
|
if (!isLoopCounterDeclarator(loopCounterName, path))
|
|
111
109
|
continue;
|
|
112
110
|
if (stableName !== undefined)
|
|
@@ -133,8 +131,6 @@ export const getLoopCounterNameIfEligible = (path) => {
|
|
|
133
131
|
continue;
|
|
134
132
|
if (declarator.init.type !== "NumericLiteral")
|
|
135
133
|
continue;
|
|
136
|
-
if (declarator.init.value !== 0)
|
|
137
|
-
continue;
|
|
138
134
|
const loopCounterName = declarator.id.name;
|
|
139
135
|
if (!isLoopCounterDeclarator(loopCounterName, path))
|
|
140
136
|
continue;
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
"evaluations": {
|
|
4
4
|
"claude-code-2.1.10:claude-code-2.1.11": {
|
|
5
5
|
"diffSizePercent": 100,
|
|
6
|
-
"evaluatedAt": "2026-02-
|
|
7
|
-
"changedLines":
|
|
8
|
-
"durationSeconds":
|
|
6
|
+
"evaluatedAt": "2026-02-14T13:04:12.173Z",
|
|
7
|
+
"changedLines": 3626,
|
|
8
|
+
"durationSeconds": 180.525304795,
|
|
9
9
|
"stableNames": 1361
|
|
10
10
|
}
|
|
11
11
|
},
|
|
@@ -4,7 +4,6 @@ type BindingCandidate = {
|
|
|
4
4
|
binding: Binding;
|
|
5
5
|
currentName: string;
|
|
6
6
|
baseName: string;
|
|
7
|
-
conflicted: boolean;
|
|
8
7
|
};
|
|
9
8
|
type CollectReturnObjectBindingCandidatesResult = {
|
|
10
9
|
candidates: Map<Binding, BindingCandidate>;
|
|
@@ -12,7 +11,6 @@ type CollectReturnObjectBindingCandidatesResult = {
|
|
|
12
11
|
};
|
|
13
12
|
type CollectReturnObjectBindingCandidatesOptions = {
|
|
14
13
|
ast: File;
|
|
15
|
-
isScript: boolean;
|
|
16
14
|
exportedNames: ReadonlySet<string>;
|
|
17
15
|
};
|
|
18
16
|
export declare const collectReturnObjectBindingCandidates: (options: CollectReturnObjectBindingCandidatesOptions) => CollectReturnObjectBindingCandidatesResult;
|
|
@@ -25,8 +25,6 @@ const collectCandidatesForObjectExpression = (options) => {
|
|
|
25
25
|
const propertyName = getPropertyName(property.key);
|
|
26
26
|
if (!propertyName)
|
|
27
27
|
continue;
|
|
28
|
-
if (propertyName.length <= 1)
|
|
29
|
-
continue;
|
|
30
28
|
if (!isValidBindingIdentifier(propertyName))
|
|
31
29
|
continue;
|
|
32
30
|
if (isHashBasedStableName(`$${propertyName}`))
|
|
@@ -53,23 +51,18 @@ const collectCandidatesForObjectExpression = (options) => {
|
|
|
53
51
|
exportedNames.has(currentName)) {
|
|
54
52
|
continue;
|
|
55
53
|
}
|
|
56
|
-
|
|
57
|
-
if (existing) {
|
|
58
|
-
if (existing.baseName !== propertyName) {
|
|
59
|
-
existing.conflicted = true;
|
|
60
|
-
}
|
|
54
|
+
if (candidates.has(binding))
|
|
61
55
|
continue;
|
|
62
|
-
}
|
|
63
56
|
candidates.set(binding, {
|
|
64
57
|
binding,
|
|
65
58
|
currentName,
|
|
66
59
|
baseName: propertyName,
|
|
67
|
-
conflicted: false,
|
|
68
60
|
});
|
|
69
61
|
}
|
|
70
62
|
};
|
|
71
63
|
export const collectReturnObjectBindingCandidates = (options) => {
|
|
72
|
-
const { ast,
|
|
64
|
+
const { ast, exportedNames } = options;
|
|
65
|
+
const isScript = ast.program.sourceType === "script";
|
|
73
66
|
let nodesVisited = 0;
|
|
74
67
|
const candidates = new Map();
|
|
75
68
|
traverse(ast, {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"evaluations": {
|
|
3
3
|
"claude-code-2.1.10:claude-code-2.1.11": {
|
|
4
|
-
"diffSizePercent": 99.
|
|
5
|
-
"evaluatedAt": "2026-02-
|
|
6
|
-
"changedLines":
|
|
7
|
-
"durationSeconds":
|
|
8
|
-
"stableNames":
|
|
4
|
+
"diffSizePercent": 99.88282874097592,
|
|
5
|
+
"evaluatedAt": "2026-02-17T12:48:21.759Z",
|
|
6
|
+
"changedLines": 13827,
|
|
7
|
+
"durationSeconds": 47.550179875,
|
|
8
|
+
"stableNames": 2458
|
|
9
9
|
}
|
|
10
10
|
},
|
|
11
11
|
"recommended": true,
|
|
@@ -30,15 +30,12 @@ export const renameReturnObjectBindingsTransform = {
|
|
|
30
30
|
const exportedNames = collectExportedNames(fileInfo.ast.program);
|
|
31
31
|
const { candidates, nodesVisited: fileNodesVisited } = collectReturnObjectBindingCandidates({
|
|
32
32
|
ast: fileInfo.ast,
|
|
33
|
-
isScript,
|
|
34
33
|
exportedNames,
|
|
35
34
|
});
|
|
36
35
|
nodesVisited += fileNodesVisited;
|
|
37
36
|
const dynamicLookupScopes = collectLocalDynamicLookupScopes(fileInfo.ast);
|
|
38
37
|
const group = new RenameGroup();
|
|
39
38
|
for (const candidate of candidates.values()) {
|
|
40
|
-
if (candidate.conflicted)
|
|
41
|
-
continue;
|
|
42
39
|
if (candidate.binding.scope.block.type === "Program"
|
|
43
40
|
? hasProgramScopeDynamicNameLookup
|
|
44
41
|
: hasBindingLocalDynamicNameLookup(candidate.binding, candidate.currentName, dynamicLookupScopes)) {
|
package/dist/transforms-by-id/stabilize-deferred-top-level-bindings/collect-deferred-variables.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ type DeferredVariableInfo = {
|
|
|
5
5
|
enclosingFunctionName: string;
|
|
6
6
|
enclosingFunctionScopeUid: number;
|
|
7
7
|
scope: Scope;
|
|
8
|
+
declarationStart: number | undefined;
|
|
8
9
|
};
|
|
9
10
|
/**
|
|
10
11
|
* Collect information about deferred top-level var declarations.
|
|
@@ -16,8 +17,8 @@ export declare const collectDeferredVariables: (ast: t.File, programScope: Scope
|
|
|
16
17
|
nodesVisited: number;
|
|
17
18
|
};
|
|
18
19
|
/**
|
|
19
|
-
* Group deferred vars by
|
|
20
|
-
*
|
|
20
|
+
* Group deferred vars by enclosing function and select one deterministic
|
|
21
|
+
* candidate for each function.
|
|
21
22
|
*/
|
|
22
|
-
export declare const
|
|
23
|
+
export declare const selectDeferredVariablesForRename: (deferredVariables: DeferredVariableInfo[]) => DeferredVariableInfo[];
|
|
23
24
|
export {};
|
package/dist/transforms-by-id/stabilize-deferred-top-level-bindings/collect-deferred-variables.js
CHANGED
|
@@ -87,6 +87,7 @@ export const collectDeferredVariables = (ast, programScope) => {
|
|
|
87
87
|
enclosingFunctionName: info.enclosingFunctionName,
|
|
88
88
|
enclosingFunctionScopeUid: info.enclosingFunctionScopeUid,
|
|
89
89
|
scope: binding.scope,
|
|
90
|
+
declarationStart: binding.identifier.start ?? undefined,
|
|
90
91
|
});
|
|
91
92
|
}
|
|
92
93
|
}
|
|
@@ -94,10 +95,10 @@ export const collectDeferredVariables = (ast, programScope) => {
|
|
|
94
95
|
return { deferredVariables, nodesVisited };
|
|
95
96
|
};
|
|
96
97
|
/**
|
|
97
|
-
* Group deferred vars by
|
|
98
|
-
*
|
|
98
|
+
* Group deferred vars by enclosing function and select one deterministic
|
|
99
|
+
* candidate for each function.
|
|
99
100
|
*/
|
|
100
|
-
export const
|
|
101
|
+
export const selectDeferredVariablesForRename = (deferredVariables) => {
|
|
101
102
|
// Group by enclosing function identity (name + scope UID).
|
|
102
103
|
const byFunction = new Map();
|
|
103
104
|
for (const info of deferredVariables) {
|
|
@@ -110,12 +111,33 @@ export const filterToSingleVariableFunctions = (deferredVariables) => {
|
|
|
110
111
|
byFunction.set(functionIdentity, [info]);
|
|
111
112
|
}
|
|
112
113
|
}
|
|
113
|
-
//
|
|
114
|
+
// Keep one candidate per function:
|
|
115
|
+
// - Skip already-stable bindings (`$...`) to avoid churn.
|
|
116
|
+
// - For multi-candidate functions, pick the earliest declaration position.
|
|
117
|
+
// This tie-break is independent of minified identifier text.
|
|
114
118
|
const result = [];
|
|
115
119
|
for (const variables of byFunction.values()) {
|
|
116
|
-
|
|
117
|
-
|
|
120
|
+
const unstabilizedVariables = variables.filter((variableInfo) => !isStableRenamed(variableInfo.variableName));
|
|
121
|
+
if (unstabilizedVariables.length === 0)
|
|
122
|
+
continue;
|
|
123
|
+
if (unstabilizedVariables.length === 1 && unstabilizedVariables[0]) {
|
|
124
|
+
result.push(unstabilizedVariables[0]);
|
|
125
|
+
continue;
|
|
118
126
|
}
|
|
127
|
+
const sortedByDeclarationStart = unstabilizedVariables.toSorted((left, right) => {
|
|
128
|
+
const leftStart = left.declarationStart ?? Number.POSITIVE_INFINITY;
|
|
129
|
+
const rightStart = right.declarationStart ?? Number.POSITIVE_INFINITY;
|
|
130
|
+
return leftStart - rightStart;
|
|
131
|
+
});
|
|
132
|
+
const first = sortedByDeclarationStart[0];
|
|
133
|
+
const second = sortedByDeclarationStart[1];
|
|
134
|
+
if (!first)
|
|
135
|
+
continue;
|
|
136
|
+
const firstStart = first.declarationStart ?? Number.POSITIVE_INFINITY;
|
|
137
|
+
const secondStart = second?.declarationStart ?? Number.POSITIVE_INFINITY;
|
|
138
|
+
if (firstStart === secondStart)
|
|
139
|
+
continue;
|
|
140
|
+
result.push(first);
|
|
119
141
|
}
|
|
120
142
|
return result;
|
|
121
143
|
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"notes": "Stabilizes top-level var declarations
|
|
2
|
+
"notes": "Stabilizes top-level var declarations initialized inside stable-named functions (lazy init pattern). For multi-deferred functions, picks a deterministic candidate by declaration order and skips already-stable `$...` bindings to avoid churn from minifier-dependent variable names.",
|
|
3
3
|
"evaluations": {
|
|
4
4
|
"claude-code-2.1.10:claude-code-2.1.11": {
|
|
5
|
-
"diffSizePercent": 100.
|
|
6
|
-
"evaluatedAt": "2026-02-
|
|
7
|
-
"changedLines":
|
|
8
|
-
"durationSeconds":
|
|
9
|
-
"stableNames":
|
|
5
|
+
"diffSizePercent": 100.24568167214727,
|
|
6
|
+
"evaluatedAt": "2026-02-17T12:58:15.137Z",
|
|
7
|
+
"changedLines": 448,
|
|
8
|
+
"durationSeconds": 44.418337541,
|
|
9
|
+
"stableNames": 1380
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
12
|
"recommended": true,
|
|
@@ -2,7 +2,7 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
import { parse } from "@babel/parser";
|
|
3
3
|
import { getFilesToProcess, } from "../../core/types.js";
|
|
4
4
|
import { generateCode } from "../../core/generate-code.js";
|
|
5
|
-
import { collectDeferredVariables,
|
|
5
|
+
import { collectDeferredVariables, selectDeferredVariablesForRename, } from "./collect-deferred-variables.js";
|
|
6
6
|
import { extractHashFromStableName, renameBindingInPlace, } from "./rename-helpers.js";
|
|
7
7
|
import { canRenameBindingSafely } from "../../transforms/shared/can-rename-binding-safely.js";
|
|
8
8
|
const require = createRequire(import.meta.url);
|
|
@@ -11,8 +11,8 @@ const traverse = require("@babel/traverse").default;
|
|
|
11
11
|
export const stabilizeDeferredTopLevelBindingsTransform = {
|
|
12
12
|
id: "stabilize-deferred-top-level-bindings",
|
|
13
13
|
description: "Renames top-level var declarations without initializers (deferred bindings) to stable names " +
|
|
14
|
-
"derived from their enclosing stable function.
|
|
15
|
-
"
|
|
14
|
+
"derived from their enclosing stable function. For functions with multiple deferred vars, " +
|
|
15
|
+
"chooses a deterministic candidate by declaration order and skips already-stable bindings.",
|
|
16
16
|
scope: "file",
|
|
17
17
|
parallelizable: true,
|
|
18
18
|
transform(context) {
|
|
@@ -33,8 +33,8 @@ export const stabilizeDeferredTopLevelBindingsTransform = {
|
|
|
33
33
|
// Collect deferred vars
|
|
34
34
|
const { deferredVariables, nodesVisited: fileNodesVisited } = collectDeferredVariables(fileInfo.ast, programScope);
|
|
35
35
|
nodesVisited += fileNodesVisited;
|
|
36
|
-
//
|
|
37
|
-
const eligibleVariables =
|
|
36
|
+
// Select one deterministic deferred var candidate per function.
|
|
37
|
+
const eligibleVariables = selectDeferredVariablesForRename(deferredVariables);
|
|
38
38
|
// Apply renames. Track used names for consistency with stabilize-deferred-stable-rhs
|
|
39
39
|
// and to avoid duplicate `$v_...` targets when different functions produce
|
|
40
40
|
// the same derived hash.
|
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.
|
|
5
|
+
"version": "1.115.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",
|