You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
[3.1.0] - 2026-07-11
Added
Live crawl-time ETA (on by default): a periodic log line projecting remaining time from the crawl's own
throughput/discovery history, withheld until the frontier drains steadily. New SimpleCrawler.Core.Progress
namespace; CLI --progress, --progressInterval, --progressConfirm.
Changed
Replaced the shared FIFO crawl frontier with a host-partitioned one
(SimpleCrawler.Core.Scheduling.HostFrontier) to end cross-site head-of-line blocking: a single
dispatcher spaces each host and hands workers only ready URLs, so a slow host no longer stalls other
sites. Equally-ready hosts round-robin.
Updated Simple.Logging.Console to 2.0.0 and switched the CLI to the new truecolor AddRgbConsoleLogging()
(AddConsoleLogging() still exists for ANSI); a warm Write is now allocation-free.
Normalized per-page log lines across backends (Response '{code}' from '{url}' / Error …, numeric code
everywhere) and proxy references (via '{proxy}', 'direct connection' when none); ProxyInfo.ToString()
emits a clean scheme://host:port.
Checkpointing now logs its activity (start line with target+interval, debug line per write, failures name
the target); ICheckpointStore gained a Target property.
Fixed
JS DOM: closed three shim gaps that tripped SPA error boundaries mid-render. IntersectionObserverEntry is
now a global carrying the standard entry fields on its prototype (the 'isIntersecting' in IntersectionObserverEntry.prototype support probe threw a ReferenceError); <canvas> is a real HTMLCanvasElement with reflected width/height and a no-op 2D context from getContext('2d')
(animation libraries grabbing a context synchronously threw); and getComputedStyle returns a CSSStyleDeclaration whose properties read back "" by name or as direct properties (a direct .content
read was undefined, so Elementor's getCurrentDeviceMode did undefined.replace(...)).