8bf8725baf33

finish LV-8 zxcvbn-ts migration: fix the Add/Export/Health.tsx imports missed by the original migration (still importing the unmaintained zxcvbn package) — unblocks npm run build:mobile and 4 previously-failing test files

time
2026-07-01 23:52 UTC · 3 months ago
machine
koh2
agent
claude-sonnet-5
session
ring 1 chrome shim
parent
bdd7540953f8
4 files src/mobile/chrome-shim.test.ts+1 −1src/popup/views/Add.tsx+12 −2src/popup/views/Export.tsx+15 −5src/popup/views/Health.tsx+14 −1
src/mobile/chrome-shim.test.ts+1 −1
@@ -62,7 +62,7 @@6262     const chromeShim = await freshShim();6363     const seenByBroadcast: unknown[] = [];6464 65-    chromeShim.runtime.onMessage.addListener((msg, _sender, sendResponse) => {65+    chromeShim.runtime.onMessage.addListener((_msg, _sender, sendResponse) => {6666       Promise.resolve({ ok: true, from: "primary" }).then(sendResponse);6767       return true;6868     });

view file

src/popup/views/Add.tsx+12 −2
@@ -166,8 +166,18 @@166166     if (pwd.length < 4) { setPasswordStrength(null); return; }167167     try {168168       if (!zxcvbnFn()) {169-        const mod = await import("zxcvbn");170-        setZxcvbnFn(() => mod.default);169+        // Replaces the unmaintained `zxcvbn` package (LV-8; see Lock.tsx).170+        const [{ zxcvbn, zxcvbnOptions }, common, en] = await Promise.all([171+          import("@zxcvbn-ts/core"),172+          import("@zxcvbn-ts/language-common"),173+          import("@zxcvbn-ts/language-en"),174+        ]);175+        zxcvbnOptions.setOptions({176+          translations: en.translations,177+          graphs: common.adjacencyGraphs,178+          dictionary: { ...common.dictionary, ...en.dictionary },179+        });180+        setZxcvbnFn(() => (pwd: string) => zxcvbn(pwd));171181       }172182       const fn = zxcvbnFn();173183       if (fn) setPasswordStrength(fn(pwd).score);

view file

src/popup/views/Export.tsx+15 −5
@@ -16,15 +16,25 @@1616   onBack: () => void;1717 }1818 19-// Lazy-load zxcvbn — it's heavy (~800 kB) and only needed when the user19+// Lazy-load @zxcvbn-ts — it's heavy (~700 kB) and only needed when the user2020 // starts typing a backup password. Shared module-level cache so it is only21-// fetched once across multiple PeachScriptExport mounts.22-type ZxcvbnFn = (pw: string) => { score: number; feedback: { warning: string; suggestions: string[] } };21+// fetched once across multiple PeachScriptExport mounts. Replaces the22+// unmaintained `zxcvbn` package (LV-8; see Lock.tsx).23+type ZxcvbnFn = (pw: string) => { score: number; feedback: { warning: string | null; suggestions: string[] } };2324 let _zxcvbn: ZxcvbnFn | null = null;2425 async function getZxcvbn(): Promise<ZxcvbnFn> {2526   if (_zxcvbn) return _zxcvbn;26-  const mod = await import("zxcvbn");27-  _zxcvbn = mod.default as ZxcvbnFn;27+  const [{ zxcvbn, zxcvbnOptions }, common, en] = await Promise.all([28+    import("@zxcvbn-ts/core"),29+    import("@zxcvbn-ts/language-common"),30+    import("@zxcvbn-ts/language-en"),31+  ]);32+  zxcvbnOptions.setOptions({33+    translations: en.translations,34+    graphs: common.adjacencyGraphs,35+    dictionary: { ...common.dictionary, ...en.dictionary },36+  });37+  _zxcvbn = (pw: string) => zxcvbn(pw);2838   return _zxcvbn;2939 }3040 

view file

src/popup/views/Health.tsx+14 −1
@@ -1,9 +1,22 @@11 import { createMemo, createSignal, For, onMount, Show } from "solid-js";2-import { default as zxcvbn } from "zxcvbn";2+import { zxcvbn, zxcvbnOptions } from "@zxcvbn-ts/core";3+import * as zxcvbnCommon from "@zxcvbn-ts/language-common";4+import * as zxcvbnEn from "@zxcvbn-ts/language-en";35 import type { AdvancedHealthReport, VaultEntry } from "../../shared/types";46 import { getDisplayDomain } from "../../shared/domain";57 import { sendMessage } from "../App";68 import { VaultView } from "./Vault";9+10+// Replaces the unmaintained `zxcvbn` package (LV-8; see Lock.tsx) — this file11+// was missed by that migration. Health.tsx is already its own route-level12+// lazy chunk, so a static import here carries the same load-timing as the13+// dynamic imports used elsewhere; it just needs the dictionaries configured14+// once before first use.15+zxcvbnOptions.setOptions({16+  translations: zxcvbnEn.translations,17+  graphs: zxcvbnCommon.adjacencyGraphs,18+  dictionary: { ...zxcvbnCommon.dictionary, ...zxcvbnEn.dictionary },19+});720 821 function sha256(plain: string): Promise<string> {922   const encoder = new TextEncoder();

view file