|
| 1 | +# Changelog |
| 2 | + |
| 3 | +## 3.0.0-beta.1 |
| 4 | + |
| 5 | +### New Features |
| 6 | + |
| 7 | +- **`scrollVelocity` getter** — per-container scroll velocity in px/s, shared across all instances on the same scroll parent via ContainerProxy. Returns 0 when disabled, destroyed, or idle (100ms staleness decay). |
| 8 | +- **`enable()` / `disable()`** — temporarily disconnect all observers without destroying the instance. Progress freezes at its current value; `modify()`, `on()`/`off()`, plugins, and most getters remain functional. Re-enabling reconnects everything and schedules a full recalculation. |
| 9 | +- **`{ once: true }` event listener option** — follows the DOM `addEventListener` options bag pattern. Works with both `.on()` and `.subscribe()`. |
| 10 | +- **`refresh()` / `refreshAll()` / `destroyAll()`** — force bounds recalculation after layout changes invisible to ResizeObserver (position shifts, class toggles, sibling DOM mutations, font loading, etc.). |
| 11 | +- **Post-destroy and non-browser guards** — all public methods now warn in dev mode and bail cleanly instead of producing undefined behavior when called after `destroy()` or outside a browser environment. |
| 12 | +- **Element–scrollParent ancestry validation** (dev mode) — `console.error` when the tracked element isn't a descendant of its scroll parent, catching silent IntersectionObserver misconfiguration. |
| 13 | + |
| 14 | +### Bug Fixes |
| 15 | + |
| 16 | +- **Container position not initialized synchronously** — non-window containers defaulted to `{top:0,left:0}` until the first scroll/resize event, producing wrong initial progress for containers offset from the viewport top. |
| 17 | +- **Zero-size container guard** — when a scroll container collapses to 0px, `updateProgress()` no longer produces incorrect values (division by near-zero) and `updateViewportObserver()` no longer passes broken margins to the IntersectionObserver. |
| 18 | +- **Direction change not invalidating elementBoundsCache** — changing `vertical` via `modify()` left stale axis-dependent bounds in the cache. |
| 19 | +- **containerBounds not rescheduled on option changes** — `triggerStart`, `triggerEnd`, and `vertical` changes via `modify()` didn't trigger a container bounds recalculation, causing wrong progress and viewport margins. |
| 20 | +- **Stale closure in `onElementResize`** — `updateElementBoundsCache()` replaced the entire bounds object, but the resize handler's destructured reference pointed to the old one, so size comparisons always returned false and progress never recalculated after element resize. |
| 21 | +- **`destroy()` skipping plugin `onRemove` callbacks** — plugin cleanup was routed through `removePlugin()`, which hit the `guardInert()` check (destroyed was already true) and silently skipped all `onRemove` callbacks. |
| 22 | + |
| 23 | +### Performance |
| 24 | + |
| 25 | +- **Replace debounce with `throttleRaf` for container resize** — removes the arbitrary 100ms debounce delay. Both window and element resize paths now use rAF-batched throttling for consistent, responsive behavior. |
| 26 | +- **Cache PixelConverter results** — `elementStart`/`elementEnd` converters are skipped when element size is unchanged (common during scroll). Bounds caches mutated in-place via `Object.assign` instead of allocating new objects each frame. |
| 27 | + |
| 28 | +### Internal |
| 29 | + |
| 30 | +- Explicit `type` keyword on type-only imports for better tree-shaking. |
| 31 | +- New `Vector` type for `{x, y}` pairs, replacing the old `ScrollDelta` shape. |
| 32 | +- E2e tests reorganized from origin-based to feature-based structure. 13 regression tests covering v2-reported edge cases added. |
| 33 | +- Added MAINTAINING.md and ROADMAP.md. |
0 commit comments