miniread 1.79.0 → 1.81.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.
@@ -207,6 +207,10 @@ const manifestData = {
207
207
  recommended: true,
208
208
  evaluations: { "claude-code-2.1.10:claude-code-2.1.11": { "diffSizePercent": 100, "evaluatedAt": "2026-02-04T12:47:49.357Z", "changedLines": 606, "durationSeconds": 152.335242224, "stableNames": 1359 } },
209
209
  },
210
+ "rename-object-keys-reducer-parameters": {
211
+ recommended: true,
212
+ evaluations: { "claude-code-2.1.10:claude-code-2.1.11": { "diffSizePercent": 100, "evaluatedAt": "2026-02-06T14:50:58.548Z", "changedLines": 208, "durationSeconds": 170.10544662, "stableNames": 1358 } },
213
+ },
210
214
  "rename-object-keys-variables": {
211
215
  recommended: true,
212
216
  notes: "Measured with baseline none: 0.01%. Added to recommended for readability.",
@@ -271,6 +275,10 @@ const manifestData = {
271
275
  recommended: true,
272
276
  evaluations: { "legacy:evaluation": { "evaluatedAt": "2026-01-25T20:11:03.532Z", "changedLines": 1300, "durationSeconds": 0, "stableNames": 0, "diffSizePercent": 100 }, "claude-code-2.1.10:claude-code-2.1.11": { "diffSizePercent": 100, "evaluatedAt": "2026-01-25T23:29:09.589Z", "changedLines": 1300, "durationSeconds": 56.599702834000006, "stableNames": 1359 } },
273
277
  },
278
+ "rename-rest-pop-callbacks": {
279
+ recommended: true,
280
+ evaluations: { "claude-code-2.1.10:claude-code-2.1.11": { "diffSizePercent": 100, "evaluatedAt": "2026-02-06T17:36:36.948Z", "changedLines": 14, "durationSeconds": 177.13338240899998, "stableNames": 1358 } },
281
+ },
274
282
  "rename-safe-property-accessor-parameters": {
275
283
  recommended: false,
276
284
  notes: "Negative diff reduction in evaluation; keep optional.",
@@ -454,6 +462,7 @@ export const recommendedTransformIds = [
454
462
  "rename-deferred-resolve-parameters",
455
463
  "rename-destructured-aliases",
456
464
  "rename-rest-parameters",
465
+ "rename-rest-pop-callbacks",
457
466
  "rename-execfile-arguments",
458
467
  "rename-file-reader-variables",
459
468
  "rename-error-first-callback-parameters",
@@ -470,6 +479,7 @@ export const recommendedTransformIds = [
470
479
  "rename-document-fragment-variables",
471
480
  "rename-object-keys-variables",
472
481
  "rename-object-keys-iterator-variables",
482
+ "rename-object-keys-reducer-parameters",
473
483
  "rename-parameters-to-match-properties-v2",
474
484
  "rename-invalid-parameter-arguments",
475
485
  "rename-promise-executor-parameters-v2",
@@ -42,6 +42,7 @@ import { renameLoopIndexVariablesV2Transform } from "../rename-loop-index-variab
42
42
  import { renameLoopIndexVariablesV3Transform } from "../rename-loop-index-variables-v3/rename-loop-index-variables-v3-transform.js";
43
43
  import { renameLoopLengthVariablesTransform } from "../rename-loop-length-variables/rename-loop-length-variables-transform.js";
44
44
  import { renameObjectKeysIteratorVariablesTransform } from "../rename-object-keys-iterator-variables/rename-object-keys-iterator-variables-transform.js";
45
+ import { renameObjectKeysReducerParametersTransform } from "../rename-object-keys-reducer-parameters/rename-object-keys-reducer-parameters-transform.js";
45
46
  import { renameObjectKeysVariablesTransform } from "../rename-object-keys-variables/rename-object-keys-variables-transform.js";
46
47
  import { renameParametersToMatchPropertiesTransform } from "../rename-parameters-to-match-properties/rename-parameters-to-match-properties-transform.js";
47
48
  import { renameParametersToMatchPropertiesV2Transform } from "../rename-parameters-to-match-properties-v2/rename-parameters-to-match-properties-v2-transform.js";
@@ -55,6 +56,7 @@ import { renameRegexBuildersTransform } from "../rename-regex-builders/rename-re
55
56
  import { renameRegexSourceParametersTransform } from "../rename-regex-source-parameters/rename-regex-source-parameters-transform.js";
56
57
  import { renameReplaceChildParametersTransform } from "../rename-replace-child-parameters/rename-replace-child-parameters-transform.js";
57
58
  import { renameRestParametersTransform } from "../rename-rest-parameters/rename-rest-parameters-transform.js";
59
+ import { renameRestPopCallbacksTransform } from "../rename-rest-pop-callbacks/rename-rest-pop-callbacks-transform.js";
58
60
  import { renameSafePropertyAccessorParametersTransform } from "../rename-safe-property-accessor-parameters/rename-safe-property-accessor-parameters-transform.js";
59
61
  import { renameSearchParametersVariablesTransform } from "../rename-search-parameters-variables/rename-search-parameters-variables-transform.js";
60
62
  import { renameStringSplitVariablesTransform } from "../rename-string-split-variables/rename-string-split-variables-transform.js";
@@ -127,6 +129,7 @@ export const transformRegistry = {
127
129
  [renameLoopIndexVariablesV3Transform.id]: renameLoopIndexVariablesV3Transform,
128
130
  [renameLoopLengthVariablesTransform.id]: renameLoopLengthVariablesTransform,
129
131
  [renameObjectKeysIteratorVariablesTransform.id]: renameObjectKeysIteratorVariablesTransform,
132
+ [renameObjectKeysReducerParametersTransform.id]: renameObjectKeysReducerParametersTransform,
130
133
  [renameObjectKeysVariablesTransform.id]: renameObjectKeysVariablesTransform,
131
134
  [renameParametersToMatchPropertiesTransform.id]: renameParametersToMatchPropertiesTransform,
132
135
  [renameParametersToMatchPropertiesV2Transform.id]: renameParametersToMatchPropertiesV2Transform,
@@ -140,6 +143,7 @@ export const transformRegistry = {
140
143
  [renameRegexSourceParametersTransform.id]: renameRegexSourceParametersTransform,
141
144
  [renameReplaceChildParametersTransform.id]: renameReplaceChildParametersTransform,
142
145
  [renameRestParametersTransform.id]: renameRestParametersTransform,
146
+ [renameRestPopCallbacksTransform.id]: renameRestPopCallbacksTransform,
143
147
  [renameSafePropertyAccessorParametersTransform.id]: renameSafePropertyAccessorParametersTransform,
144
148
  [renameSearchParametersVariablesTransform.id]: renameSearchParametersVariablesTransform,
145
149
  [renameStringSplitVariablesTransform.id]: renameStringSplitVariablesTransform,
@@ -4,4 +4,4 @@
4
4
  * This lets us tune transform interactions intentionally instead of relying on
5
5
  * alphabetical ID sorting.
6
6
  */
7
- export declare const recommendedTransformOrder: readonly ["stabilize-top-level-bindings", "stabilize-nested-bindings", "stabilize-deferred-top-level-bindings", "stabilize-deferred-stable-rhs", "expand-boolean-literals", "expand-sequence-expressions-v5", "expand-special-number-literals", "expand-typeof-undefined-comparisons", "expand-undefined-literals", "remove-redundant-else", "rename-arguments-length-flags", "rename-asap-wrappers", "rename-awaiter-parameters", "rename-awaiter-helper-functions", "rename-buffer-variables", "rename-to-buffer-results", "rename-catch-parameters", "rename-promise-catch-parameters", "rename-char-code-at", "rename-charcode-variables-v2", "rename-client-aliases", "rename-comparison-flags", "rename-date-now-start-times", "rename-default-options-parameters-v2", "rename-deferred-resolve-parameters", "rename-destructured-aliases", "rename-rest-parameters", "rename-execfile-arguments", "rename-file-reader-variables", "rename-error-first-callback-parameters", "rename-error-first-callback-parameters-v2", "rename-error-variables", "rename-event-parameters", "rename-http-server-parameters", "rename-fs-sync-variables", "rename-http-method-parameters", "rename-interval-ids", "rename-indexeddb-request-variables", "rename-loop-index-variables-v3", "rename-loop-length-variables", "rename-document-fragment-variables", "rename-object-keys-variables", "rename-object-keys-iterator-variables", "rename-parameters-to-match-properties-v2", "rename-invalid-parameter-arguments", "rename-promise-executor-parameters-v2", "rename-range-parameters", "rename-read-file-lines", "rename-regex-builders", "rename-regex-source-parameters", "rename-search-parameters-variables", "rename-file-extension-variables", "rename-string-split-variables", "rename-this-aliases", "rename-timeout-promises", "rename-timeout-ids", "rename-typeof-variables", "rename-typescript-helper-aliases", "rename-uint8array-concat-variables", "rename-url-parameters", "rename-url-variables", "rename-use-reference-guards-v2", "rename-use-reference-sets", "rename-worker-handles", "rename-zod-check-parameters", "simplify-boolean-negations", "simplify-string-trim", "split-variable-declarations", "use-optional-chaining", "use-object-property-shorthand", "use-object-shorthand", "replace-dynamic-require-eval"];
7
+ export declare const recommendedTransformOrder: readonly ["stabilize-top-level-bindings", "stabilize-nested-bindings", "stabilize-deferred-top-level-bindings", "stabilize-deferred-stable-rhs", "expand-boolean-literals", "expand-sequence-expressions-v5", "expand-special-number-literals", "expand-typeof-undefined-comparisons", "expand-undefined-literals", "remove-redundant-else", "rename-arguments-length-flags", "rename-asap-wrappers", "rename-awaiter-parameters", "rename-awaiter-helper-functions", "rename-buffer-variables", "rename-to-buffer-results", "rename-catch-parameters", "rename-promise-catch-parameters", "rename-char-code-at", "rename-charcode-variables-v2", "rename-client-aliases", "rename-comparison-flags", "rename-date-now-start-times", "rename-default-options-parameters-v2", "rename-deferred-resolve-parameters", "rename-destructured-aliases", "rename-rest-parameters", "rename-rest-pop-callbacks", "rename-execfile-arguments", "rename-file-reader-variables", "rename-error-first-callback-parameters", "rename-error-first-callback-parameters-v2", "rename-error-variables", "rename-event-parameters", "rename-http-server-parameters", "rename-fs-sync-variables", "rename-http-method-parameters", "rename-interval-ids", "rename-indexeddb-request-variables", "rename-loop-index-variables-v3", "rename-loop-length-variables", "rename-document-fragment-variables", "rename-object-keys-variables", "rename-object-keys-iterator-variables", "rename-object-keys-reducer-parameters", "rename-parameters-to-match-properties-v2", "rename-invalid-parameter-arguments", "rename-promise-executor-parameters-v2", "rename-range-parameters", "rename-read-file-lines", "rename-regex-builders", "rename-regex-source-parameters", "rename-search-parameters-variables", "rename-file-extension-variables", "rename-string-split-variables", "rename-this-aliases", "rename-timeout-promises", "rename-timeout-ids", "rename-typeof-variables", "rename-typescript-helper-aliases", "rename-uint8array-concat-variables", "rename-url-parameters", "rename-url-variables", "rename-use-reference-guards-v2", "rename-use-reference-sets", "rename-worker-handles", "rename-zod-check-parameters", "simplify-boolean-negations", "simplify-string-trim", "split-variable-declarations", "use-optional-chaining", "use-object-property-shorthand", "use-object-shorthand", "replace-dynamic-require-eval"];
@@ -41,6 +41,7 @@ export const recommendedTransformOrder = [
41
41
  "rename-deferred-resolve-parameters",
42
42
  "rename-destructured-aliases",
43
43
  "rename-rest-parameters",
44
+ "rename-rest-pop-callbacks",
44
45
  "rename-execfile-arguments",
45
46
  "rename-file-reader-variables",
46
47
  "rename-error-first-callback-parameters",
@@ -60,6 +61,7 @@ export const recommendedTransformOrder = [
60
61
  "rename-document-fragment-variables",
61
62
  "rename-object-keys-variables",
62
63
  "rename-object-keys-iterator-variables",
64
+ "rename-object-keys-reducer-parameters",
63
65
  "rename-parameters-to-match-properties-v2",
64
66
  "rename-invalid-parameter-arguments",
65
67
  "rename-promise-executor-parameters-v2",
@@ -0,0 +1,12 @@
1
+ {
2
+ "recommended": true,
3
+ "evaluations": {
4
+ "claude-code-2.1.10:claude-code-2.1.11": {
5
+ "diffSizePercent": 100,
6
+ "evaluatedAt": "2026-02-06T14:50:58.548Z",
7
+ "changedLines": 208,
8
+ "durationSeconds": 170.10544662,
9
+ "stableNames": 1358
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,2 @@
1
+ import { type Transform } from "../../core/types.js";
2
+ export declare const renameObjectKeysReducerParametersTransform: Transform;
@@ -0,0 +1,136 @@
1
+ import { createRequire } from "node:module";
2
+ import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
3
+ import { getFilesToProcess, } from "../../core/types.js";
4
+ import * as t from "@babel/types";
5
+ const require = createRequire(import.meta.url);
6
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
7
+ const traverse = require("@babel/traverse").default;
8
+ const KEY_BASE_NAME = "key";
9
+ const RESULT_BASE_NAME = "result";
10
+ const isObjectKeysCall = (node) => {
11
+ if (node.arguments.length === 0)
12
+ return false;
13
+ if (!t.isMemberExpression(node.callee))
14
+ return false;
15
+ if (!t.isIdentifier(node.callee.object))
16
+ return false;
17
+ if (node.callee.object.name !== "Object")
18
+ return false;
19
+ if (node.callee.computed) {
20
+ if (t.isStringLiteral(node.callee.property)) {
21
+ return node.callee.property.value === "keys";
22
+ }
23
+ if (t.isTemplateLiteral(node.callee.property) &&
24
+ node.callee.property.expressions.length === 0) {
25
+ const quasi = node.callee.property.quasis[0];
26
+ return quasi?.value.cooked === "keys";
27
+ }
28
+ return false;
29
+ }
30
+ return (t.isIdentifier(node.callee.property) && node.callee.property.name === "keys");
31
+ };
32
+ const isReduceCallOnObjectKeys = (node) => {
33
+ if (!t.isMemberExpression(node.callee))
34
+ return false;
35
+ if (node.callee.computed) {
36
+ if (!t.isCallExpression(node.callee.object))
37
+ return false;
38
+ if (!isObjectKeysCall(node.callee.object))
39
+ return false;
40
+ if (t.isStringLiteral(node.callee.property)) {
41
+ return node.callee.property.value === "reduce";
42
+ }
43
+ if (t.isTemplateLiteral(node.callee.property) &&
44
+ node.callee.property.expressions.length === 0) {
45
+ const quasi = node.callee.property.quasis[0];
46
+ return quasi?.value.cooked === "reduce";
47
+ }
48
+ return false;
49
+ }
50
+ if (!t.isIdentifier(node.callee.property))
51
+ return false;
52
+ if (node.callee.property.name !== "reduce")
53
+ return false;
54
+ return (t.isCallExpression(node.callee.object) &&
55
+ isObjectKeysCall(node.callee.object));
56
+ };
57
+ const shouldSkipForInitialValue = (node, scope) => {
58
+ if (t.isSpreadElement(node) || t.isArgumentPlaceholder(node))
59
+ return true;
60
+ if (t.isIdentifier(node)) {
61
+ return node.name === "undefined" && !scope.hasBinding("undefined", true);
62
+ }
63
+ return t.isUnaryExpression(node) && node.operator === "void";
64
+ };
65
+ const getIdentifierParameter = (parameters, index) => {
66
+ const parameter = parameters[index];
67
+ if (!parameter)
68
+ return undefined;
69
+ if (!t.isIdentifier(parameter))
70
+ return undefined;
71
+ return parameter;
72
+ };
73
+ export const renameObjectKeysReducerParametersTransform = {
74
+ id: "rename-object-keys-reducer-parameters",
75
+ description: "Renames Object.keys(...).reduce accumulator/key parameters to stable $result/$key (or readable result/key/key2) when safe and reduce has an explicit non-undefined initial value",
76
+ scope: "file",
77
+ parallelizable: true,
78
+ transform(context) {
79
+ let nodesVisited = 0;
80
+ let transformationsApplied = 0;
81
+ for (const fileInfo of getFilesToProcess(context)) {
82
+ const group = new RenameGroup();
83
+ traverse(fileInfo.ast, {
84
+ CallExpression(path) {
85
+ nodesVisited++;
86
+ if (!isReduceCallOnObjectKeys(path.node))
87
+ return;
88
+ if (path.scope.getBinding("Object"))
89
+ return;
90
+ if (path.node.arguments.length < 2)
91
+ return;
92
+ const initialValue = path.node.arguments[1];
93
+ if (!initialValue)
94
+ return;
95
+ if (shouldSkipForInitialValue(initialValue, path.scope))
96
+ return;
97
+ const callbackPath = path.get("arguments.0");
98
+ if (!callbackPath.isFunctionExpression() &&
99
+ !callbackPath.isArrowFunctionExpression()) {
100
+ return;
101
+ }
102
+ const accumulatorParameter = getIdentifierParameter(callbackPath.node.params, 0);
103
+ const keyParameter = getIdentifierParameter(callbackPath.node.params, 1);
104
+ if (!accumulatorParameter || !keyParameter)
105
+ return;
106
+ if (accumulatorParameter.name === keyParameter.name)
107
+ return;
108
+ if (!isStableRenamed(accumulatorParameter.name)) {
109
+ const currentName = accumulatorParameter.name;
110
+ const binding = callbackPath.scope.getBinding(currentName);
111
+ if (binding?.constant) {
112
+ group.add({
113
+ scope: binding.scope,
114
+ currentName,
115
+ baseName: RESULT_BASE_NAME,
116
+ });
117
+ }
118
+ }
119
+ if (!isStableRenamed(keyParameter.name)) {
120
+ const currentName = keyParameter.name;
121
+ const binding = callbackPath.scope.getBinding(currentName);
122
+ if (binding?.constant) {
123
+ group.add({
124
+ scope: binding.scope,
125
+ currentName,
126
+ baseName: KEY_BASE_NAME,
127
+ });
128
+ }
129
+ }
130
+ },
131
+ });
132
+ transformationsApplied += group.apply();
133
+ }
134
+ return Promise.resolve({ nodesVisited, transformationsApplied });
135
+ },
136
+ };
@@ -0,0 +1,12 @@
1
+ {
2
+ "recommended": true,
3
+ "evaluations": {
4
+ "claude-code-2.1.10:claude-code-2.1.11": {
5
+ "diffSizePercent": 100,
6
+ "evaluatedAt": "2026-02-06T17:36:36.948Z",
7
+ "changedLines": 14,
8
+ "durationSeconds": 177.13338240899998,
9
+ "stableNames": 1358
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,2 @@
1
+ import { type Transform } from "../../core/types.js";
2
+ export declare const renameRestPopCallbacksTransform: Transform;
@@ -0,0 +1,125 @@
1
+ import { createRequire } from "node:module";
2
+ import { isIdentifier } from "@babel/types";
3
+ import { RenameGroup, isStableRenamed } from "../../core/stable-naming.js";
4
+ import { getFilesToProcess, } from "../../core/types.js";
5
+ const require = createRequire(import.meta.url);
6
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
7
+ const traverse = require("@babel/traverse").default;
8
+ const BASE_NAME = "callback";
9
+ const getRestParameterName = (parameters) => {
10
+ const lastParameter = parameters.at(-1);
11
+ if (!lastParameter)
12
+ return undefined;
13
+ if (lastParameter.type !== "RestElement")
14
+ return undefined;
15
+ if (!isIdentifier(lastParameter.argument))
16
+ return undefined;
17
+ return lastParameter.argument.name;
18
+ };
19
+ const getRestPopReceiverName = (init) => {
20
+ if (init.arguments.length > 0)
21
+ return undefined;
22
+ const callee = init.callee;
23
+ if (callee.type !== "MemberExpression")
24
+ return undefined;
25
+ if (callee.computed)
26
+ return undefined;
27
+ if (!isIdentifier(callee.object))
28
+ return undefined;
29
+ if (!isIdentifier(callee.property))
30
+ return undefined;
31
+ if (callee.property.name !== "pop")
32
+ return undefined;
33
+ return callee.object.name;
34
+ };
35
+ const getCallbackReferenceUsage = (referencePath) => {
36
+ const parentPath = referencePath.parentPath;
37
+ if (!parentPath ||
38
+ (!parentPath.isCallExpression() && !parentPath.isOptionalCallExpression())) {
39
+ return undefined;
40
+ }
41
+ if (referencePath.key === "callee")
42
+ return "direct-call";
43
+ if (referencePath.listKey === "arguments")
44
+ return "call-argument";
45
+ return undefined;
46
+ };
47
+ export const renameRestPopCallbacksTransform = {
48
+ id: "rename-rest-pop-callbacks",
49
+ description: "Renames callback locals assigned from this function's rest.pop() when references include a direct call site",
50
+ scope: "file",
51
+ parallelizable: true,
52
+ transform(context) {
53
+ let nodesVisited = 0;
54
+ let transformationsApplied = 0;
55
+ for (const fileInfo of getFilesToProcess(context)) {
56
+ const group = new RenameGroup();
57
+ traverse(fileInfo.ast, {
58
+ Function(path) {
59
+ nodesVisited++;
60
+ const restName = getRestParameterName(path.node.params);
61
+ if (!restName)
62
+ return;
63
+ const restParameterBinding = path.scope.getBinding(restName);
64
+ if (!restParameterBinding)
65
+ return;
66
+ path.traverse({
67
+ VariableDeclarator(declaratorPath) {
68
+ const id = declaratorPath.node.id;
69
+ if (!isIdentifier(id))
70
+ return;
71
+ const currentName = id.name;
72
+ if (isStableRenamed(currentName))
73
+ return;
74
+ const init = declaratorPath.node.init;
75
+ if (init?.type !== "CallExpression")
76
+ return;
77
+ const restPopReceiverName = getRestPopReceiverName(init);
78
+ if (restPopReceiverName !== restName)
79
+ return;
80
+ const restPopReceiverBinding = declaratorPath.scope.getBinding(restPopReceiverName);
81
+ if (restPopReceiverBinding !== restParameterBinding)
82
+ return;
83
+ const binding = declaratorPath.scope.getBinding(currentName);
84
+ if (!binding)
85
+ return;
86
+ if (!binding.constant)
87
+ return;
88
+ if (binding.referencePaths.length === 0)
89
+ return;
90
+ let hasInvalidUsage = false;
91
+ let hasDirectCallUsage = false;
92
+ for (const referencePath of binding.referencePaths) {
93
+ const usage = getCallbackReferenceUsage(referencePath);
94
+ if (!usage) {
95
+ hasInvalidUsage = true;
96
+ break;
97
+ }
98
+ if (usage === "direct-call")
99
+ hasDirectCallUsage = true;
100
+ }
101
+ if (hasInvalidUsage)
102
+ return;
103
+ if (!hasDirectCallUsage)
104
+ return;
105
+ group.add({
106
+ scope: declaratorPath.scope,
107
+ currentName,
108
+ baseName: BASE_NAME,
109
+ });
110
+ },
111
+ Function(innerPath) {
112
+ // Keep analysis local to the current function body.
113
+ innerPath.skip();
114
+ },
115
+ });
116
+ },
117
+ });
118
+ transformationsApplied += group.apply();
119
+ }
120
+ return Promise.resolve({
121
+ nodesVisited,
122
+ transformationsApplied,
123
+ });
124
+ },
125
+ };
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.79.0",
5
+ "version": "1.81.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",