mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-04-03 06:12:07 -07:00
feat: streamline Kiku duplicate grouping and popup flow (#38)
This commit is contained in:
@@ -5,6 +5,7 @@ import * as path from 'path';
|
||||
import test from 'node:test';
|
||||
import * as vm from 'node:vm';
|
||||
import {
|
||||
addYomitanNoteViaSearch,
|
||||
getYomitanDictionaryInfo,
|
||||
importYomitanDictionaryFromZip,
|
||||
deleteYomitanDictionaryByTitle,
|
||||
@@ -1373,3 +1374,48 @@ test('deleteYomitanDictionaryByTitle uses settings automation bridge instead of
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
test('addYomitanNoteViaSearch returns note and duplicate ids from the bridge payload', async () => {
|
||||
const deps = createDeps(async (_script) => ({
|
||||
noteId: 42,
|
||||
duplicateNoteIds: [18, 7, 18],
|
||||
}));
|
||||
|
||||
const result = await addYomitanNoteViaSearch('食べる', deps, {
|
||||
error: () => undefined,
|
||||
});
|
||||
|
||||
assert.deepEqual(result, {
|
||||
noteId: 42,
|
||||
duplicateNoteIds: [18, 7, 18],
|
||||
});
|
||||
});
|
||||
|
||||
test('addYomitanNoteViaSearch rejects invalid numeric note ids from the bridge shortcut', async () => {
|
||||
const deps = createDeps(async () => NaN);
|
||||
|
||||
const result = await addYomitanNoteViaSearch('食べる', deps, {
|
||||
error: () => undefined,
|
||||
});
|
||||
|
||||
assert.deepEqual(result, {
|
||||
noteId: null,
|
||||
duplicateNoteIds: [],
|
||||
});
|
||||
});
|
||||
|
||||
test('addYomitanNoteViaSearch sanitizes invalid payload note ids while keeping valid duplicate ids', async () => {
|
||||
const deps = createDeps(async (_script) => ({
|
||||
noteId: -1,
|
||||
duplicateNoteIds: [18, 0, 7.5, 7],
|
||||
}));
|
||||
|
||||
const result = await addYomitanNoteViaSearch('食べる', deps, {
|
||||
error: () => undefined,
|
||||
});
|
||||
|
||||
assert.deepEqual(result, {
|
||||
noteId: null,
|
||||
duplicateNoteIds: [18, 7],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -63,6 +63,11 @@ interface YomitanProfileMetadata {
|
||||
dictionaryFrequencyModeByName: Partial<Record<string, YomitanFrequencyMode>>;
|
||||
}
|
||||
|
||||
export interface YomitanAddNoteResult {
|
||||
noteId: number | null;
|
||||
duplicateNoteIds: number[];
|
||||
}
|
||||
|
||||
const DEFAULT_YOMITAN_SCAN_LENGTH = 40;
|
||||
const yomitanProfileMetadataByWindow = new WeakMap<BrowserWindow, YomitanProfileMetadata>();
|
||||
const yomitanFrequencyCacheByWindow = new WeakMap<
|
||||
@@ -1984,11 +1989,11 @@ export async function addYomitanNoteViaSearch(
|
||||
word: string,
|
||||
deps: YomitanParserRuntimeDeps,
|
||||
logger: LoggerLike,
|
||||
): Promise<number | null> {
|
||||
): Promise<YomitanAddNoteResult> {
|
||||
const isReady = await ensureYomitanParserWindow(deps, logger);
|
||||
const parserWindow = deps.getYomitanParserWindow();
|
||||
if (!isReady || !parserWindow || parserWindow.isDestroyed()) {
|
||||
return null;
|
||||
return { noteId: null, duplicateNoteIds: [] };
|
||||
}
|
||||
|
||||
const escapedWord = JSON.stringify(word);
|
||||
@@ -2003,10 +2008,35 @@ export async function addYomitanNoteViaSearch(
|
||||
`;
|
||||
|
||||
try {
|
||||
const noteId = await parserWindow.webContents.executeJavaScript(script, true);
|
||||
return typeof noteId === 'number' ? noteId : null;
|
||||
const result = await parserWindow.webContents.executeJavaScript(script, true);
|
||||
if (typeof result === 'number') {
|
||||
return {
|
||||
noteId: Number.isInteger(result) && result > 0 ? result : null,
|
||||
duplicateNoteIds: [],
|
||||
};
|
||||
}
|
||||
if (result && typeof result === 'object' && !Array.isArray(result)) {
|
||||
const envelope = result as {
|
||||
noteId?: unknown;
|
||||
duplicateNoteIds?: unknown;
|
||||
};
|
||||
return {
|
||||
noteId:
|
||||
typeof envelope.noteId === 'number' &&
|
||||
Number.isInteger(envelope.noteId) &&
|
||||
envelope.noteId > 0
|
||||
? envelope.noteId
|
||||
: null,
|
||||
duplicateNoteIds: Array.isArray(envelope.duplicateNoteIds)
|
||||
? envelope.duplicateNoteIds.filter(
|
||||
(entry): entry is number => typeof entry === 'number' && Number.isInteger(entry) && entry > 0,
|
||||
)
|
||||
: [],
|
||||
};
|
||||
}
|
||||
return { noteId: null, duplicateNoteIds: [] };
|
||||
} catch (err) {
|
||||
logger.error('Yomitan addNoteFromWord failed:', (err as Error).message);
|
||||
return null;
|
||||
return { noteId: null, duplicateNoteIds: [] };
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user