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

changeset-bot Bot commented May 27, 2026

Copy link
Copy Markdown

🦋 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

linux-foundation-easycla Bot commented May 27, 2026

Copy link
Copy Markdown

CLA Not Signed

@codecov

codecov Bot commented May 27, 2026

Copy link
Copy Markdown

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.

Copilot AI left a comment

Copy link
Copy Markdown

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

Copilot AI left a comment

Copy link
Copy Markdown

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

3 participants