lingengyuan’s Jev Ad Block combines conventional ad-request filtering with TypeSafe judgments about suspicious page elements. Its interesting contribution is the machinery around the decision: protecting necessary UI, recovering from mistakes, and avoiding cache collisions.
I inspected commit ca03bdc91d9203576aaa02ca03bd886d2c6f399e, ran 79 passing offline unit tests, and completed npm run check successfully. I did not install it in Chrome or make live Jev calls. These checks are not a security audit or proof of ad-detection accuracy.
Rules first; semantics where useful
- Chrome’s declarative network rules block requests separately from page-element hiding.
- Strong CSS markers and explicit user rules can hide elements without consulting Jev.
- Other candidates go to the actual
/v1/systemoneendpoint usingjev-latest. - Inline candidates get advertising and primary-content judgments; overlays additionally ask whether they obstruct content and are necessary.
- Inline hiding uses the configured ad threshold and main-content guard; overlay logic separately protects login, consent and other necessary UI.
Typed output is not a correct decision. Those threshold policies are implementation choices, not demonstrated calibration.
Recovery is part of the design
Some candidates are hidden before the answer arrives and restored if Jev says to keep them. On transient failure, ambiguous optimistic hides are released, while detector- or label-backed candidates can fall back to local hiding.
Not every hide has the same recovery path: the README warns that early CSS hiding requires a refresh to reverse. Users should not assume a restore button undoes everything.
The cache is useful—and approximate
The implementation caches slot judgments for seven days, a code-defined lifetime rather than a measured optimum. It normalizes recognizable generated class names, but refuses caching when stripping them would erase all distinguishing classes. Tests exercise that collision-avoidance behavior.
Text and geometry are absent from the cache signature. That makes repeated slots cheaper to revisit, but a reused slot with changed content can receive an old judgment. jev-latest also makes the underlying model a moving target.
Privacy and performance remain separate questions
Candidate text is capped at 240 characters in the implementation; outbound state also contains element features and link hostnames. URL paths and queries are stripped, but text can still contain personal information. Hosted semantic filtering is not wholly local browsing.
The README reports 364 ms for one candidate and 406 ms for 64, calling batch judgment nearly free. I did not reproduce those figures, and they do not establish total browsing cost, typical latency or accuracy. A meaningful next test would measure both missed ads and accidentally hidden content on labeled pages, including cache reuse and failure recovery.