Skip to content

refactor(webpack-cli): replace fastest-levenshtein with in-tree implementation#4762

Merged
alexander-akait merged 2 commits into
mainfrom
claude/replace-fastest-levenshtein-Tkvl9
May 27, 2026
Merged

refactor(webpack-cli): replace fastest-levenshtein with in-tree implementation#4762
alexander-akait merged 2 commits into
mainfrom
claude/replace-fastest-levenshtein-Tkvl9

Conversation

@alexander-akait
Copy link
Copy Markdown
Member

Drop the fastest-levenshtein dependency in favor of a small in-tree
Levenshtein distance (Myers' bit-parallel algorithm, inspired by
fastest-levenshtein) used for command/option "did you mean" suggestions,
and add unit tests for it.

https://claude.ai/code/session_013zogbY9uURTCwhdRrifVBt

…mentation

Drop the fastest-levenshtein dependency in favor of a small in-tree
Levenshtein distance (Myers' bit-parallel algorithm, inspired by
fastest-levenshtein) used for command/option "did you mean" suggestions,
and add unit tests for it.

https://claude.ai/code/session_013zogbY9uURTCwhdRrifVBt
Copilot AI review requested due to automatic review settings May 27, 2026 13:39
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 27, 2026

🦋 Changeset detected

Latest commit: c4200f2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
webpack-cli Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented May 27, 2026

CLA Not Signed

@codecov
Copy link
Copy Markdown

codecov Bot commented May 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.82%. Comparing base (183d0e6) to head (c4200f2).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #4762      +/-   ##
==========================================
+ Coverage   92.58%   92.82%   +0.24%     
==========================================
  Files          14       15       +1     
  Lines        4911     5076     +165     
  Branches      731      752      +21     
==========================================
+ Hits         4547     4712     +165     
  Misses        362      362              
  Partials        2        2              
Files with missing lines Coverage Δ
packages/webpack-cli/src/levenshtein.ts 100.00% <100.00%> (ø)
packages/webpack-cli/src/webpack-cli.ts 96.18% <100.00%> (ø)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 183d0e6...c4200f2. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the fastest-levenshtein dependency from webpack-cli and replaces it with an in-tree Levenshtein distance implementation (Myers’ bit-parallel algorithm) to power “did you mean” suggestions, along with unit tests.

Changes:

  • Added an in-tree distance() implementation in packages/webpack-cli/src/levenshtein.ts and switched webpack-cli to use it.
  • Removed fastest-levenshtein from packages/webpack-cli/package.json and package-lock.json.
  • Added Jest tests for the new distance implementation and a changeset entry documenting the patch change.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
test/api/levenshtein.test.js Adds unit tests for the new in-tree Levenshtein distance() helper.
packages/webpack-cli/src/webpack-cli.ts Replaces the external fastest-levenshtein import with the new in-tree implementation.
packages/webpack-cli/src/levenshtein.ts Introduces the Myers bit-parallel Levenshtein implementation used for suggestions.
packages/webpack-cli/package.json Drops fastest-levenshtein from dependencies.
package-lock.json Removes the fastest-levenshtein lockfile entries.
.changeset/replace-fastest-levenshtein.md Records the dependency replacement as a patch-level change.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/webpack-cli/src/levenshtein.ts Outdated
Comment on lines +71 to +88
peq[b.charCodeAt(k)] |= 1 << k;
}

for (let i = 0; i < n; i++) {
const eq = peq[a.charCodeAt(i)];
const pb = (phc[(i / 32) | 0] >>> i) & 1;
const mb = (mhc[(i / 32) | 0] >>> i) & 1;
const xv = eq | mv;
const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb;
let ph = mv | ~(xh | pv);
let mh = pv & xh;

if ((ph >>> 31) ^ pb) {
phc[(i / 32) | 0] ^= 1 << i;
}

if ((mh >>> 31) ^ mb) {
mhc[(i / 32) | 0] ^= 1 << i;
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving this as-is: the word is already selected explicitly via (i / 32) | 0, and the within-word shift intentionally relies on JS's standard mask-to-31 semantics. This is a faithful port of the upstream fastest-levenshtein algorithm, verified bit-for-bit against it (including a 2000-case fuzz across the myersX paths), so I'd prefer not to rewrite the hot loop and risk diverging from the reference. The parameter-naming and long-vs-short-test suggestions are addressed in c4200f2.


Generated by Claude Code

Comment thread packages/webpack-cli/src/levenshtein.ts Outdated
Comment on lines +49 to +55
function myersX(b: string, a: string): number {
const n = a.length;
const m = b.length;
const mhc: number[] = [];
const phc: number[] = [];
const horizontalSize = Math.ceil(n / 32);
const verticalSize = Math.ceil(m / 32);
Comment on lines +31 to +34
const b = `${"a".repeat(39)}b`;

expect(distance(a, b)).toBe(1);
expect(distance("a".repeat(40), "b".repeat(40))).toBe(40);
…case

Address review feedback: rename the swapped myersX parameters to
longer/shorter so they match their internal usage, and add a regression
test for a long string against a much shorter one (40 vs 5).

https://claude.ai/code/session_013zogbY9uURTCwhdRrifVBt
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated no new comments.

@alexander-akait alexander-akait merged commit 2bbb639 into main May 27, 2026
19 of 20 checks passed
@alexander-akait alexander-akait deleted the claude/replace-fastest-levenshtein-Tkvl9 branch May 27, 2026 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants