mirror of
https://github.com/Automattic/harper.git
synced 2025-12-23 08:48:15 +00:00
feat(harper.js): now logs lint application statistics
This commit is contained in:
parent
88b0aea00a
commit
4832a328ee
11 changed files with 44 additions and 40 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
|
@ -662,8 +662,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -849,6 +851,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"harper-core",
|
||||
"harper-stats",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"serde-wasm-bindgen",
|
||||
|
|
@ -2405,6 +2408,7 @@ checksum = "744018581f9a3454a9e15beb8a33b017183f1e7c0cd170232a2d1453b23a51c4"
|
|||
dependencies = [
|
||||
"getrandom",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -12,3 +12,7 @@ serde_json = "1.0.140"
|
|||
[dev-dependencies]
|
||||
quickcheck = "1.0.3"
|
||||
quickcheck_macros = "1.0.0"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
js = ["uuid/js"]
|
||||
|
|
|
|||
|
|
@ -61,8 +61,6 @@ impl Stats {
|
|||
for line_res in br.lines() {
|
||||
let line = line_res?;
|
||||
|
||||
dbg!(&line);
|
||||
|
||||
let record: Record = serde_json::from_str(&line)?;
|
||||
records.push(record);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,3 +19,4 @@ once_cell = "1.20.3"
|
|||
serde-wasm-bindgen = "0.6.5"
|
||||
serde_json = "1.0.140"
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
harper-stats = { path = "../harper-stats", version = "0.25.0", features = ["js"] }
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use harper_core::{
|
|||
CharString, Dictionary, Document, FstDictionary, IgnoredLints, Lrc, MergedDictionary,
|
||||
MutableDictionary, WordMetadata, remove_overlaps,
|
||||
};
|
||||
use harper_stats::{Record, RecordKind, Stats};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use wasm_bindgen::JsValue;
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
|
@ -92,6 +93,7 @@ pub struct Linter {
|
|||
dictionary: Arc<MergedDictionary>,
|
||||
ignored_lints: IgnoredLints,
|
||||
dialect: Dialect,
|
||||
stats: Stats,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
|
|
@ -109,6 +111,7 @@ impl Linter {
|
|||
dictionary,
|
||||
ignored_lints: IgnoredLints::default(),
|
||||
dialect,
|
||||
stats: Stats::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -274,6 +277,24 @@ impl Linter {
|
|||
pub fn get_dialect(&self) -> Dialect {
|
||||
self.dialect
|
||||
}
|
||||
|
||||
/// Apply a suggestion from a given lint.
|
||||
/// This action will be logged to the Linter's statistics.
|
||||
pub fn apply_suggestion(
|
||||
&mut self,
|
||||
lint: &Lint,
|
||||
suggestion: &Suggestion,
|
||||
) -> Result<String, String> {
|
||||
let mut source = lint.source.clone();
|
||||
|
||||
self.stats.records.push(
|
||||
Record::now(RecordKind::Lint(lint.inner.lint_kind)).map_err(|err| err.to_string())?,
|
||||
);
|
||||
|
||||
suggestion.inner.apply(lint.inner.span, &mut source);
|
||||
|
||||
Ok(source.iter().collect())
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
|
|
@ -281,20 +302,6 @@ pub fn to_title_case(text: String) -> String {
|
|||
harper_core::make_title_case_str(&text, &PlainEnglish, &FstDictionary::curated())
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn apply_suggestion(
|
||||
text: String,
|
||||
span: Span,
|
||||
suggestion: &Suggestion,
|
||||
) -> Result<String, String> {
|
||||
let mut source: Vec<_> = text.chars().collect();
|
||||
let span: harper_core::Span = span.into();
|
||||
|
||||
suggestion.inner.apply(span, &mut source);
|
||||
|
||||
Ok(source.iter().collect())
|
||||
}
|
||||
|
||||
/// A suggestion to fix a Lint.
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[wasm_bindgen]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { Dialect, Lint, Span, Suggestion } from 'harper-wasm';
|
||||
import type { Dialect, Lint, Suggestion } from 'harper-wasm';
|
||||
import type { BinaryModule } from './binary';
|
||||
import type { LintConfig, LintOptions } from './main';
|
||||
|
||||
|
|
@ -12,8 +12,8 @@ export default interface Linter {
|
|||
/** Lint the provided text. */
|
||||
lint(text: string, options?: LintOptions): Promise<Lint[]>;
|
||||
|
||||
/** Apply a suggestion to the given text, returning the transformed result. */
|
||||
applySuggestion(text: string, suggestion: Suggestion, span: Span): Promise<string>;
|
||||
/** Apply a suggestion from a lint, returning the changed text. */
|
||||
applySuggestion(lint: Lint, suggestion: Suggestion): Promise<string>;
|
||||
|
||||
/** Determine if the provided text is likely to be intended to be English.
|
||||
* The algorithm can be described as "proof of concept" and as such does not work terribly well.*/
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { Dialect, Lint, Span, Suggestion, Linter as WasmLinter } from 'harper-wasm';
|
||||
import type { Dialect, Lint, Suggestion, Linter as WasmLinter } from 'harper-wasm';
|
||||
import { Language } from 'harper-wasm';
|
||||
import LazyPromise from 'p-lazy';
|
||||
import type Linter from './Linter';
|
||||
|
|
@ -38,8 +38,9 @@ export default class LocalLinter implements Linter {
|
|||
return lints;
|
||||
}
|
||||
|
||||
async applySuggestion(text: string, suggestion: Suggestion, span: Span): Promise<string> {
|
||||
return await this.binary.applySuggestion(text, suggestion, span);
|
||||
async applySuggestion(lint: Lint, suggestion: Suggestion): Promise<string> {
|
||||
const inner = await this.inner;
|
||||
return inner.apply_suggestion(lint, suggestion);
|
||||
}
|
||||
|
||||
async isLikelyEnglish(text: string): Promise<boolean> {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { Dialect, Lint, Span, Suggestion } from 'harper-wasm';
|
||||
import type { Dialect, Lint, Suggestion } from 'harper-wasm';
|
||||
import type Linter from '../Linter';
|
||||
import type { LinterInit } from '../Linter';
|
||||
import type { BinaryModule, DeserializedRequest } from '../binary';
|
||||
|
|
@ -69,8 +69,8 @@ export default class WorkerLinter implements Linter {
|
|||
return this.rpc('lint', [text, options]);
|
||||
}
|
||||
|
||||
applySuggestion(text: string, suggestion: Suggestion, span: Span): Promise<string> {
|
||||
return this.rpc('applySuggestion', [text, suggestion, span]);
|
||||
applySuggestion(lint: Lint, suggestion: Suggestion): Promise<string> {
|
||||
return this.rpc('applySuggestion', [lint, suggestion]);
|
||||
}
|
||||
|
||||
isLikelyEnglish(text: string): Promise<boolean> {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,4 @@
|
|||
import {
|
||||
Dialect,
|
||||
type InitInput,
|
||||
type Span,
|
||||
type Suggestion,
|
||||
type Linter as WasmLinter,
|
||||
} from 'harper-wasm';
|
||||
import { Dialect, type InitInput, type Linter as WasmLinter } from 'harper-wasm';
|
||||
import { default as binaryInlinedUrl } from 'harper-wasm/harper_wasm_bg.wasm?inline';
|
||||
import { default as binaryUrl } from 'harper-wasm/harper_wasm_bg.wasm?no-inline';
|
||||
import LazyPromise from 'p-lazy';
|
||||
|
|
@ -82,11 +76,6 @@ export class BinaryModule {
|
|||
);
|
||||
}
|
||||
|
||||
async applySuggestion(text: string, suggestion: Suggestion, span: Span): Promise<string> {
|
||||
const exported = await this.inner;
|
||||
return exported.apply_suggestion(text, span, suggestion);
|
||||
}
|
||||
|
||||
async getDefaultLintConfigAsJSON(): Promise<string> {
|
||||
const exported = await this.inner;
|
||||
return exported.get_default_lint_config_as_json();
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ $: superSmall = (w ?? 1024) < 550;
|
|||
style="height: 40px; margin: 5px 0px;"
|
||||
on:click={() =>
|
||||
linter
|
||||
.applySuggestion(content, suggestion, lint.span())
|
||||
.applySuggestion(lint, suggestion)
|
||||
.then((edited) => (content = edited))}
|
||||
>
|
||||
{#if suggestion.kind() == SuggestionKind.Remove}
|
||||
|
|
@ -142,7 +142,7 @@ $: superSmall = (w ?? 1024) < 550;
|
|||
on:click={() =>
|
||||
focused != null &&
|
||||
linter
|
||||
.applySuggestion(content, suggestion, lints[focused].span())
|
||||
.applySuggestion(lints[focused], suggestion)
|
||||
.then((edited) => (content = edited))}
|
||||
>
|
||||
{#if suggestion.kind() == SuggestionKind.Remove}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ export default class RichText {
|
|||
height: targetRect.height,
|
||||
lint,
|
||||
applySuggestion: async (sug: Suggestion) => {
|
||||
const fixed = await linter.applySuggestion(text, sug, span);
|
||||
const fixed = await linter.applySuggestion(lint, sug);
|
||||
|
||||
this.editContent(fixed);
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue