Defer wordlist loading

This commit is contained in:
Jack Kingsman
2026-01-13 14:20:35 -08:00
parent 55d68beeb7
commit 2981b022bb
8 changed files with 563 additions and 546 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

537
frontend/dist/assets/index-DKdsyLDV.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -13,8 +13,8 @@
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="manifest" href="/site.webmanifest" />
<script type="module" crossorigin src="/assets/index-CUZgfnRO.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-49wEGwkK.css">
<script type="module" crossorigin src="/assets/index-DKdsyLDV.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Bk7xCS0b.css">
</head>
<body>
<div id="root"></div>

View File

@@ -633,6 +633,7 @@ export function App() {
<CrackerPanel
packets={rawPackets}
channels={channels}
visible={showCracker}
onChannelCreate={async (name, key) => {
const created = await api.createChannel(name, key);
const data = await api.getChannels();

View File

@@ -1,6 +1,5 @@
import { useState, useEffect, useRef, useCallback } from 'react';
import { GroupTextCracker, type ProgressReport } from 'meshcore-hashtag-cracker';
import { ENGLISH_WORDLIST } from 'meshcore-hashtag-cracker/wordlist';
import NoSleep from 'nosleep.js';
import type { RawPacket, Channel } from '../types';
import { api } from '../api';
@@ -62,9 +61,10 @@ interface CrackerPanelProps {
channels: Channel[];
onChannelCreate: (name: string, key: string) => Promise<void>;
onRunningChange?: (running: boolean) => void;
visible?: boolean;
}
export function CrackerPanel({ packets, channels, onChannelCreate, onRunningChange }: CrackerPanelProps) {
export function CrackerPanel({ packets, channels, onChannelCreate, onRunningChange, visible = false }: CrackerPanelProps) {
const [isRunning, setIsRunning] = useState(false);
const [maxLength, setMaxLength] = useState(6);
const [retryFailedAtNextLength, setRetryFailedAtNextLength] = useState(false);
@@ -100,10 +100,6 @@ export function CrackerPanel({ packets, channels, onChannelCreate, onRunningChan
const noSleep = new NoSleep();
noSleepRef.current = noSleep;
// Use built-in wordlist
cracker.setWordlist(ENGLISH_WORDLIST);
setWordlistLoaded(true);
return () => {
cracker.destroy();
crackerRef.current = null;
@@ -112,6 +108,25 @@ export function CrackerPanel({ packets, channels, onChannelCreate, onRunningChan
};
}, []);
// Load wordlist dynamically when panel becomes visible for the first time
useEffect(() => {
if (!visible || wordlistLoaded) return;
import('meshcore-hashtag-cracker/wordlist')
.then(({ ENGLISH_WORDLIST }) => {
if (crackerRef.current) {
crackerRef.current.setWordlist(ENGLISH_WORDLIST);
setWordlistLoaded(true);
}
})
.catch((err) => {
console.error('Failed to load wordlist:', err);
toast.error('Failed to load wordlist', {
description: 'Cracking will not be available',
});
});
}, [visible, wordlistLoaded]);
// Fetch undecrypted packet count
useEffect(() => {
const fetchCount = () => {