Files
SnowLuma/.pnpm-store/v11/files/15/de0e4031c8e2be14f803201bba9ce73a05a050723641ed408d06b4f3ea7679d81309b6275c3421004cd34c83e2107b3774ad6f26ad1a05736038e353e0010f
TanTan 2a69b23b47
Dev Build / cleanup (push) Canceled after 0s
Dev Build / typecheck (push) Canceled after 0s
Dev Build / build (linux-arm64, ubuntu-24.04-arm, linux-arm64) (push) Canceled after 0s
Dev Build / build (linux-x64, ubuntu-latest, linux-x64) (push) Canceled after 0s
Dev Build / build (win-x64, windows-latest, win32-x64) (push) Canceled after 0s
Dev Build / dispatch-dev-docker (push) Skipped
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

102 lines
3.1 KiB
Plaintext

import Options from './Options'
import { DefaultFeedbackFunction, FeedbackType, MatchEstimated } from './types'
import bruteforceMatcher from './matcher/bruteforce/feedback'
import dateMatcher from './matcher/date/feedback'
import dictionaryMatcher from './matcher/dictionary/feedback'
import regexMatcher from './matcher/regex/feedback'
import repeatMatcher from './matcher/repeat/feedback'
import sequenceMatcher from './matcher/sequence/feedback'
import spatialMatcher from './matcher/spatial/feedback'
import separatorMatcher from './matcher/separator/feedback'
import wordSequenceMatcher from './matcher/wordSequence/feedback'
const defaultFeedback = {
warning: null,
suggestions: [],
}
type Matchers = Record<string, DefaultFeedbackFunction>
/*
* -------------------------------------------------------------------------------
* Generate feedback ---------------------------------------------------------------
* -------------------------------------------------------------------------------
*/
class Feedback {
private matchers: Matchers = {}
private defaultFeedback: FeedbackType = {
warning: null,
suggestions: [],
}
constructor(private options: Options) {
this.setDefaultSuggestions()
this.matchers = {
bruteforce: bruteforceMatcher,
date: dateMatcher,
dictionary: dictionaryMatcher,
regex: regexMatcher,
repeat: repeatMatcher,
sequence: sequenceMatcher,
spatial: spatialMatcher,
separator: separatorMatcher,
wordSequence: wordSequenceMatcher,
}
Object.entries(this.options.matchers).forEach(([key, matcher]) => {
if (matcher.feedback) {
this.matchers[key] = matcher.feedback
}
})
}
private setDefaultSuggestions() {
this.defaultFeedback.suggestions.push(
this.options.translations.suggestions.useWords,
this.options.translations.suggestions.noNeed,
)
}
public getFeedback(score: number, sequence: MatchEstimated[]) {
if (sequence.length === 0) {
return this.defaultFeedback
}
if (score > 2) {
return defaultFeedback
}
const extraFeedback = this.options.translations.suggestions.anotherWord
const longestMatch = this.getLongestMatch(sequence)
let feedback = this.getMatchFeedback(longestMatch, sequence.length === 1)
if (feedback !== null && feedback !== undefined) {
feedback.suggestions.unshift(extraFeedback)
} else {
feedback = {
warning: null,
suggestions: [extraFeedback],
}
}
return feedback
}
private getLongestMatch(sequence: MatchEstimated[]) {
let longestMatch = sequence[0]
// ignore first entry
for (let i = 1; i < sequence.length; i += 1) {
const match = sequence[i]
if (match.token.length > longestMatch.token.length) {
longestMatch = match
}
}
return longestMatch
}
private getMatchFeedback(match: MatchEstimated, isSoleMatch: boolean) {
if (this.matchers[match.pattern]) {
return this.matchers[match.pattern](this.options, match, isSoleMatch)
}
return defaultFeedback
}
}
export default Feedback