phase 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -93,7 +93,7 @@ function missingContextError(child, parent) {
93
93
  }
94
94
  //#endregion
95
95
  //#region src/core/tick/index.ts
96
- /** Prevents teleportation on resume. Matches motion's maxElapsed. */
96
+ /** Maximum amount delta may exceed the active FPS interval. */
97
97
  const MAX_DELTA_MS = 40;
98
98
  /** Default first-frame delta when no previous tick exists. */
99
99
  const DEFAULT_FIRST_DELTA_MS = 16.67;
@@ -153,7 +153,7 @@ function advanceDeadline(deadline, now, interval) {
153
153
  return next + Math.floor(behind / interval) * interval;
154
154
  }
155
155
  /**
156
- * Core rAF loop primitive with FPS cap, delta clamping, and strong pause.
156
+ * Low-level requestAnimationFrame loop with an optional FPS limit and pause controls.
157
157
  *
158
158
  * @remarks
159
159
  * `FrameState` is reused across frames. Do not store a reference to it.
@@ -164,12 +164,12 @@ function createTicker(options) {
164
164
  sharedClock ??= getSharedClock();
165
165
  const { onTick, signal } = options;
166
166
  let minFrameTime = resolveMinFrameTime("createTicker", options.fps);
167
+ let maxDeltaTime = minFrameTime + MAX_DELTA_MS;
167
168
  let _phase = "idle";
168
169
  let _reason = "initial";
169
- let lastTickTime = 0;
170
- let pauseStartTime = 0;
171
- let totalPausedTime = 0;
172
- let startTime = 0;
170
+ let lastTickTime = -1;
171
+ let elapsedTime = 0;
172
+ let frameCount = 0;
173
173
  let nextDueTime = 0;
174
174
  const frame = {
175
175
  time: 0,
@@ -179,14 +179,16 @@ function createTicker(options) {
179
179
  };
180
180
  function tick(now) {
181
181
  if (now < nextDueTime) return;
182
- const isFirstDelivery = lastTickTime === 0;
183
- const rawDelta = isFirstDelivery ? DEFAULT_FIRST_DELTA_MS : now - lastTickTime;
182
+ const isFirstDelivery = lastTickTime < 0;
183
+ const rawDelta = isFirstDelivery ? minFrameTime || DEFAULT_FIRST_DELTA_MS : now - lastTickTime;
184
184
  lastTickTime = now;
185
185
  if (minFrameTime > 0) nextDueTime = isFirstDelivery ? now + minFrameTime : advanceDeadline(nextDueTime, now, minFrameTime);
186
186
  frame.time = now;
187
- frame.delta = rawDelta > MAX_DELTA_MS ? MAX_DELTA_MS : rawDelta;
188
- frame.elapsed = now - startTime - totalPausedTime;
189
- frame.frame++;
187
+ frame.delta = rawDelta > maxDeltaTime ? maxDeltaTime : rawDelta;
188
+ elapsedTime += frame.delta;
189
+ frame.elapsed = elapsedTime;
190
+ frameCount++;
191
+ frame.frame = frameCount;
190
192
  onTick(frame);
191
193
  }
192
194
  const subscription = {
@@ -202,10 +204,10 @@ function createTicker(options) {
202
204
  }
203
205
  _phase = "running";
204
206
  _reason = "started";
205
- startTime = performance.now();
206
- lastTickTime = 0;
207
+ lastTickTime = -1;
207
208
  nextDueTime = 0;
208
- totalPausedTime = 0;
209
+ elapsedTime = 0;
210
+ frameCount = 0;
209
211
  resetFrameState(frame);
210
212
  joinSharedClock(subscription);
211
213
  }
@@ -213,14 +215,12 @@ function createTicker(options) {
213
215
  if (_phase !== "running") return;
214
216
  _phase = "paused";
215
217
  _reason = "manual";
216
- pauseStartTime = performance.now();
217
218
  leaveSharedClock(subscription);
218
219
  }
219
220
  function resume() {
220
221
  if (_phase === "stopped") tickerStoppedError();
221
222
  if (_phase !== "paused") return;
222
- totalPausedTime += performance.now() - pauseStartTime;
223
- lastTickTime = 0;
223
+ lastTickTime = -1;
224
224
  nextDueTime = 0;
225
225
  _phase = "running";
226
226
  _reason = "resumed";
@@ -228,8 +228,10 @@ function createTicker(options) {
228
228
  }
229
229
  function setFps(fps) {
230
230
  if (_phase === "stopped") tickerStoppedError();
231
- minFrameTime = resolveMinFrameTime("setFps", fps);
232
- nextDueTime = lastTickTime === 0 ? 0 : lastTickTime + minFrameTime;
231
+ const nextMinFrameTime = resolveMinFrameTime("setFps", fps);
232
+ minFrameTime = nextMinFrameTime;
233
+ maxDeltaTime = nextMinFrameTime + MAX_DELTA_MS;
234
+ nextDueTime = lastTickTime < 0 ? 0 : lastTickTime + minFrameTime;
233
235
  }
234
236
  function stop() {
235
237
  if (_phase === "stopped") return;
@@ -1768,4 +1770,4 @@ function createDebounce(options) {
1768
1770
  //#endregion
1769
1771
  export { isPhaseError as C, linkAbortSignal as E, invalidDurationError as S, serverContextError as T, subscribeMediaQuery as _, createPointer as a, PhaseError as b, prefersReducedMotion as c, subscribeDpr as d, createRenderState as f, readMediaQuery as g, createLifecycle as h, observeResize as i, whenIdle as l, createLoop as m, createThrottle as n, createMutation as o, createScrollProgress as p, createScroll as r, REDUCED_MOTION_QUERY as s, createDebounce as t, readDpr as u, createSight as v, missingContextError as w, conflictingTargetError as x, createTicker as y };
1770
1772
 
1771
- //# sourceMappingURL=debounce-BkVwTxwI.js.map
1773
+ //# sourceMappingURL=debounce-Bh0QOKIX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debounce-Bh0QOKIX.js","names":["pool","createPoolEntry","REDUCED_MOTION_QUERY"],"sources":["../src/core/_internal/abort/index.ts","../src/core/_internal/errors/index.ts","../src/core/tick/index.ts","../src/core/_internal/dom/index.ts","../src/core/_internal/pool/io-pool.ts","../src/core/sight/index.ts","../src/core/_internal/pool/mql-pool.ts","../src/core/lifecycle/index.ts","../src/core/loop/index.ts","../src/core/scroll-progress/index.ts","../src/core/render-state/index.ts","../src/core/_internal/pool/dpr.ts","../src/core/idle/index.ts","../src/core/reduced-motion/index.ts","../src/core/mutation/index.ts","../src/core/pointer/index.ts","../src/core/_internal/pool/ro-pool.ts","../src/core/scroll/index.ts","../src/core/throttle/index.ts","../src/core/debounce/index.ts"],"sourcesContent":["/**\n * Link an optional `AbortSignal` to a primitive's `stop`/cancel function.\n *\n * When the signal aborts, `stop` runs once. If the signal is already aborted,\n * `stop` runs synchronously. Returns an unlink function that removes the abort\n * listener. Call it from inside `stop` so a manual stop does not leave a\n * dangling listener on a long-lived controller.\n *\n * The listener is registered with `{ once: true }`, so abort and manual stop\n * are safe to interleave: whichever fires first wins, the other is a no-op.\n */\nexport function linkAbortSignal(\n signal: AbortSignal | undefined,\n stop: () => void,\n): () => void {\n if (!signal) return unlinkNoop;\n if (signal.aborted) {\n stop();\n return unlinkNoop;\n }\n signal.addEventListener('abort', stop, { once: true });\n return () => signal.removeEventListener('abort', stop);\n}\n\n/** Shared empty unlink for the no-signal and already-aborted paths. */\nfunction unlinkNoop(): void {\n // No listener was registered, so there is nothing to remove.\n}\n","export type PhaseErrorCode =\n | 'server_context'\n | 'no_target'\n | 'conflicting_target'\n | 'invalid_duration'\n | 'invalid_fps'\n | 'ticker_stopped'\n | 'missing_context';\n\ninterface PhaseErrorOptions {\n code: PhaseErrorCode;\n reason?: string;\n fix?: string;\n link?: string;\n}\n\n/** Lightweight structured error for phase. */\nexport class PhaseError extends Error {\n readonly code: PhaseErrorCode;\n readonly reason: string | undefined;\n readonly fix: string | undefined;\n readonly link: string | undefined;\n\n constructor(message: string, options: PhaseErrorOptions) {\n super(message);\n this.name = 'PhaseError';\n this.code = options.code;\n this.reason = options.reason;\n this.fix = options.fix;\n this.link = options.link;\n }\n}\n\n/** Check if a value is a PhaseError instance. */\nexport function isPhaseError(error: unknown): error is PhaseError {\n return error instanceof PhaseError;\n}\n\nexport function serverContextError(fn: string): never {\n throw new PhaseError(`${fn}() cannot be called on the server.`, {\n code: 'server_context',\n reason: 'Browser APIs are unavailable during SSR.',\n fix: 'Move into a useEffect or client-only module.',\n });\n}\n\nexport function noTargetError(fn: string): never {\n throw new PhaseError(`${fn}() requires a target.`, {\n code: 'no_target',\n reason: 'The target was null or undefined.',\n fix: 'Pass a mounted Element, or use the React hook which manages the ref.',\n });\n}\n\nexport function conflictingTargetError(fn: string): never {\n throw new PhaseError(`${fn}() received both ref and target.`, {\n code: 'conflicting_target',\n reason: 'A tracker has one anchor.',\n fix: \"Pass one: ref for an element, target: 'page' for the page.\",\n });\n}\n\nexport function invalidDurationError(fn: string, value: number): never {\n throw new PhaseError(`${fn}() received an invalid duration: ${value}`, {\n code: 'invalid_duration',\n reason: 'Duration must be a finite positive number.',\n fix: 'Pass a positive number (e.g., 300 for 300ms).',\n });\n}\n\nexport function invalidFpsError(fn: string, value: number): never {\n throw new PhaseError(`${fn}() received an invalid fps: ${value}`, {\n code: 'invalid_fps',\n reason: 'fps must be a finite number greater than 0.',\n fix: 'Pass a positive number (e.g. 30), or undefined to uncap.',\n });\n}\n\nexport function tickerStoppedError(): never {\n throw new PhaseError('Cannot resume a stopped ticker.', {\n code: 'ticker_stopped',\n reason: 'stop() is terminal, so a stopped ticker cannot be resumed.',\n fix: 'Create a new ticker instance instead of resuming a stopped one.',\n });\n}\n\nexport function missingContextError(child: string, parent: string): never {\n throw new PhaseError(`<${child}> must be used inside <${parent}>.`, {\n code: 'missing_context',\n reason: `<${child}> reads from a context that <${parent}> provides.`,\n fix: `Wrap <${child}> with <${parent}>.`,\n });\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport {\n invalidFpsError,\n serverContextError,\n tickerStoppedError,\n} from '../_internal/errors';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface FrameState {\n /** Current browser requestAnimationFrame timestamp. */\n time: number;\n /** Milliseconds to advance this frame. At most 40ms, or one FPS interval plus 40ms. */\n delta: number;\n /** Sum of delivered deltas since start. */\n elapsed: number;\n /** Frame count since start. */\n frame: number;\n}\n\nexport type TickerPhase = 'idle' | 'running' | 'paused' | 'stopped';\nexport type TickerReason =\n | 'initial'\n | 'started'\n | 'resumed'\n | 'manual'\n | 'disposed';\n\nexport interface TickerOptions {\n /** Cap frame rate. Default: uncapped (display refresh rate). */\n fps?: number;\n /**\n * Called every frame with the current frame state. Write to refs or DOM\n * directly. Never call React `setState` here (60 state updates/sec = 60 re-renders/sec).\n */\n onTick: (frame: FrameState) => void;\n /** Abort signal that stops the ticker when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Ticker {\n start(): void;\n stop(): void;\n pause(): void;\n resume(): void;\n /**\n * Change the FPS cap. `undefined` removes it. The running timeline is\n * untouched: frame count, elapsed, and pause accounting all continue.\n * Throws on a stopped ticker or an fps that is not a finite number\n * greater than 0, leaving the previous cap in place.\n */\n setFps(fps?: number): void;\n readonly phase: TickerPhase;\n readonly phaseReason: TickerReason;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Maximum amount delta may exceed the active FPS interval. */\nconst MAX_DELTA_MS = 40;\n\n/** Default first-frame delta when no previous tick exists. */\nconst DEFAULT_FIRST_DELTA_MS = 16.67;\n\n// ---------------------------------------------------------------------------\n// Shared frame-locked clock\n//\n// All ticker instances subscribe to a single rAF loop so they read the same\n// timestamp each frame. Separately bundled copies in the same JavaScript\n// global share this clock. It starts when the first subscriber joins and stops\n// when the last one leaves.\n// ---------------------------------------------------------------------------\n\ninterface SharedSubscription {\n callback: (time: number) => void;\n joinedFrame: number;\n}\n\ninterface SharedClock {\n rafId: number | null;\n frame: number;\n time: number;\n subscribers: Set<SharedSubscription>;\n}\n\nlet sharedClock: SharedClock;\n\nfunction getSharedClock(): SharedClock {\n const registry = globalThis as unknown as Record<\n symbol,\n SharedClock | undefined\n >;\n return (registry[Symbol.for('phase.clock@1')] ??= {\n rafId: null,\n frame: 0,\n time: 0,\n subscribers: new Set<SharedSubscription>(),\n });\n}\n\nfunction dispatchSharedSubscription(subscription: SharedSubscription): void {\n if (subscription.joinedFrame < sharedClock.frame) {\n subscription.callback(sharedClock.time);\n }\n}\n\nfunction sharedTick(time: number): void {\n sharedClock.time = time;\n sharedClock.frame++;\n sharedClock.rafId = requestAnimationFrame(sharedTick);\n // eslint-disable-next-line unicorn/no-array-for-each -- Set#forEach avoids a per-frame iterator.\n sharedClock.subscribers.forEach(dispatchSharedSubscription);\n}\n\nfunction joinSharedClock(subscription: SharedSubscription): void {\n const wasEmpty: boolean = sharedClock.subscribers.size === 0;\n subscription.joinedFrame = sharedClock.frame;\n sharedClock.subscribers.add(subscription);\n\n if (wasEmpty) {\n sharedClock.rafId = requestAnimationFrame(sharedTick);\n }\n}\n\nfunction leaveSharedClock(subscription: SharedSubscription): void {\n sharedClock.subscribers.delete(subscription);\n if (sharedClock.subscribers.size === 0 && sharedClock.rafId !== null) {\n cancelAnimationFrame(sharedClock.rafId);\n sharedClock.rafId = null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction resetFrameState(state: FrameState): void {\n state.time = 0;\n state.delta = 0;\n state.elapsed = 0;\n state.frame = 0;\n}\n\n/** Validate an FPS cap and convert it to a minimum frame interval (0 = uncapped). */\nfunction resolveMinFrameTime(fn: string, fps: number | undefined): number {\n if (fps === undefined) return 0;\n if (!Number.isFinite(fps) || fps <= 0) invalidFpsError(fn, fps);\n return 1000 / fps;\n}\n\n/**\n * Advance a capped delivery deadline by one interval. Deadlines move in whole\n * intervals from a fixed anchor, so a slightly-late browser frame never pushes\n * later deadlines back (that drift is how a 60fps cap decays to ~30fps).\n */\nfunction advanceDeadline(\n deadline: number,\n now: number,\n interval: number,\n): number {\n const next: number = deadline + interval;\n const behind: number = now - next;\n if (behind < interval) return next;\n // A stall left whole intervals unfilled. Skip them, so delivery resumes at\n // the cap's pace instead of bursting to catch up.\n return next + Math.floor(behind / interval) * interval;\n}\n\n// ---------------------------------------------------------------------------\n// createTicker\n// ---------------------------------------------------------------------------\n\n/**\n * Low-level requestAnimationFrame loop with an optional FPS limit and pause controls.\n *\n * @remarks\n * `FrameState` is reused across frames. Do not store a reference to it.\n * Read values immediately in your `onTick` callback.\n */\nexport function createTicker(options: TickerOptions): Ticker {\n if (typeof requestAnimationFrame === 'undefined') {\n serverContextError('createTicker');\n }\n sharedClock ??= getSharedClock();\n\n const { onTick, signal } = options;\n let minFrameTime: number = resolveMinFrameTime('createTicker', options.fps);\n let maxDeltaTime: number = minFrameTime + MAX_DELTA_MS;\n\n let _phase: TickerPhase = 'idle';\n let _reason: TickerReason = 'initial';\n\n let lastTickTime = -1;\n let elapsedTime = 0;\n let frameCount = 0;\n\n // When the next capped delivery becomes eligible (see advanceDeadline).\n // 0 while uncapped.\n let nextDueTime = 0;\n\n // Pre-allocated, mutated in place each frame — zero allocations per tick.\n const frame: FrameState = { time: 0, delta: 0, elapsed: 0, frame: 0 };\n\n function tick(now: number): void {\n // FPS throttle: skip this frame if the cap's deadline hasn't arrived.\n if (now < nextDueTime) return;\n\n const isFirstDelivery: boolean = lastTickTime < 0;\n const rawDelta: number = isFirstDelivery\n ? minFrameTime || DEFAULT_FIRST_DELTA_MS\n : now - lastTickTime;\n lastTickTime = now;\n\n if (minFrameTime > 0) {\n nextDueTime = isFirstDelivery\n ? now + minFrameTime // the first delivery after (re)start anchors the deadlines\n : advanceDeadline(nextDueTime, now, minFrameTime);\n }\n\n frame.time = now;\n frame.delta = rawDelta > maxDeltaTime ? maxDeltaTime : rawDelta;\n elapsedTime += frame.delta;\n frame.elapsed = elapsedTime;\n frameCount++;\n frame.frame = frameCount;\n\n onTick(frame);\n }\n\n const subscription: SharedSubscription = { callback: tick, joinedFrame: 0 };\n\n function start(): void {\n if (_phase === 'running') return;\n if (_phase === 'stopped') tickerStoppedError();\n if (_phase === 'paused') {\n resume();\n return;\n }\n\n _phase = 'running';\n _reason = 'started';\n lastTickTime = -1;\n nextDueTime = 0;\n elapsedTime = 0;\n frameCount = 0;\n resetFrameState(frame);\n\n joinSharedClock(subscription);\n }\n\n function pause(): void {\n if (_phase !== 'running') return;\n\n _phase = 'paused';\n _reason = 'manual';\n\n // Strong pause: cancel rAF subscription entirely — zero CPU while paused.\n leaveSharedClock(subscription);\n }\n\n function resume(): void {\n if (_phase === 'stopped') tickerStoppedError();\n if (_phase !== 'paused') return;\n\n // Reset so the first resumed tick gets a clean delta (not the pause gap)\n // and delivers immediately, re-anchoring the cadence grid.\n lastTickTime = -1;\n nextDueTime = 0;\n\n _phase = 'running';\n _reason = 'resumed';\n joinSharedClock(subscription);\n }\n\n function setFps(fps?: number): void {\n if (_phase === 'stopped') tickerStoppedError();\n const nextMinFrameTime: number = resolveMinFrameTime('setFps', fps);\n minFrameTime = nextMinFrameTime;\n maxDeltaTime = nextMinFrameTime + MAX_DELTA_MS;\n // Base the next deadline on the last delivery: the new cap applies from\n // the next frame, and never sooner than the new interval allows.\n nextDueTime = lastTickTime < 0 ? 0 : lastTickTime + minFrameTime;\n }\n\n function stop(): void {\n if (_phase === 'stopped') return;\n\n _phase = 'stopped';\n _reason = _reason === 'initial' ? 'disposed' : 'manual';\n unlinkAbort?.();\n leaveSharedClock(subscription);\n }\n\n // Declared before assignment because an already-aborted signal makes\n // linkAbortSignal call stop() synchronously, which reads unlinkAbort.\n let unlinkAbort: (() => void) | undefined;\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n start,\n stop,\n pause,\n resume,\n setFps,\n get phase() {\n return _phase;\n },\n get phaseReason() {\n return _reason;\n },\n };\n}\n","const DOCUMENT_NODE = 9;\n\n/**\n * Discriminates a page target from an element target.\n *\n * Uses `nodeType` rather than a property check: `document.scrollingElement` is\n * absent in some test DOMs, so feature detection would silently classify a\n * Document as an Element.\n */\nexport function isDocument(target: Element | Document): target is Document {\n return target.nodeType === DOCUMENT_NODE;\n}\n","type IOCallback = (entry: IntersectionObserverEntry) => void;\n\nexport interface ObserveIntersectionOptions {\n element: Element;\n onIntersect: IOCallback;\n root?: Element | Document | null;\n rootMargin?: string;\n threshold?: number | number[];\n}\n\ninterface IOPoolEntry {\n observer: IntersectionObserver;\n callbacks: Map<Element, Set<IOCallback>>;\n}\n\nconst pool = new Map<string, IOPoolEntry>();\n\n/**\n * Observe an element via a shared IntersectionObserver pool.\n * Elements with identical options share one IO instance. An element may have\n * any number of subscribers; each receives every entry delivered after it\n * subscribes, and the element stays observed until the last one cleans up.\n *\n * A subscriber joining an already-observed element does not get the initial\n * entry: `observe()` is a no-op for a target the observer already holds, so\n * nothing arrives until the next intersection change. Callers that need\n * current state on subscribe have to read it themselves.\n *\n * @returns Cleanup function that removes this subscriber, unobserving the\n * element once none remain and dropping the IO once it observes nothing.\n */\nexport function observeIntersection(\n options: ObserveIntersectionOptions,\n): () => void {\n const { element, onIntersect, root, rootMargin, threshold } = options;\n const ioInit: IntersectionObserverInit = { root, rootMargin, threshold };\n\n const key: string = getPoolKey(ioInit);\n const entry: IOPoolEntry = getOrCreatePoolEntry(key, ioInit);\n\n let subscribers: Set<IOCallback> | undefined = entry.callbacks.get(element);\n if (!subscribers) {\n subscribers = new Set();\n entry.callbacks.set(element, subscribers);\n }\n subscribers.add(onIntersect);\n entry.observer.observe(element);\n\n let disposed = false;\n\n return () => {\n if (disposed) return;\n disposed = true;\n\n const poolEntry: IOPoolEntry | undefined = pool.get(key);\n if (!poolEntry) return;\n\n // Unobserve once this element has no subscribers left; other subscribers\n // on the same element must keep receiving entries.\n const current: Set<IOCallback> | undefined =\n poolEntry.callbacks.get(element);\n if (current) {\n current.delete(onIntersect);\n if (current.size === 0) {\n poolEntry.observer.unobserve(element);\n poolEntry.callbacks.delete(element);\n }\n }\n\n if (poolEntry.callbacks.size === 0) {\n poolEntry.observer.disconnect();\n pool.delete(key);\n }\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Produces a stable string key from IO options to group observers in the pool.\n * IO options are immutable after construction, so identical options can share.\n */\nfunction getPoolKey(opts: IntersectionObserverInit): string {\n const root = opts.root ? 'custom' : 'null';\n const margin = opts.rootMargin ?? '0px';\n const threshold = Array.isArray(opts.threshold)\n ? opts.threshold.join(',')\n : String(opts.threshold ?? 0);\n\n return `${root}|${margin}|${threshold}`;\n}\n\n/** Return an existing pool entry for this key, or create and register a new one. */\nfunction getOrCreatePoolEntry(\n key: string,\n options: IntersectionObserverInit,\n): IOPoolEntry {\n const existing: IOPoolEntry | undefined = pool.get(key);\n if (existing) return existing;\n\n const entry = createPoolEntry(options);\n\n pool.set(key, entry);\n return entry;\n}\n\n/** Create a new pool entry for the given options. */\nconst createPoolEntry = (options: IntersectionObserverInit): IOPoolEntry => {\n const callbacks = new Map<Element, Set<IOCallback>>();\n const observer = new IntersectionObserver((entries) => {\n for (const ioEntry of entries) {\n const subscribers: Set<IOCallback> | undefined = callbacks.get(\n ioEntry.target,\n );\n if (!subscribers) continue;\n // Iterated directly rather than copied: Set iteration already tolerates\n // a subscriber removing itself, which is the reentrant case that happens.\n for (const cb of subscribers) cb(ioEntry);\n }\n }, options);\n\n return { observer, callbacks };\n};\n","import { linkAbortSignal } from '../_internal/abort';\nimport { isDocument } from '../_internal/dom';\nimport { noTargetError, serverContextError } from '../_internal/errors';\nimport { observeIntersection } from '../_internal/pool/io-pool';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type SightPhase = 'unknown' | 'visible' | 'hidden';\nexport type SightReason =\n | 'initial'\n | 'viewport'\n | 'document'\n | 'bfcache'\n | 'all-hidden';\n\nexport interface SightOptions {\n /**\n * Element to observe, or `document` to track the page. A page is never\n * off-screen, so a Document target reports document visibility alone.\n */\n target: Element | Document;\n /** Forwarded to the pooled observer. Ignored for `document`. */\n intersectionOptions?: IntersectionObserverInit;\n onPhaseChange?: (phase: SightPhase, reason: SightReason) => void;\n /** Abort signal that stops the observer when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Sight {\n readonly phase: SightPhase;\n readonly phaseReason: SightReason;\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// createSight\n// ---------------------------------------------------------------------------\n\n/**\n * Visibility observer combining document focus and viewport intersection.\n *\n * `phase` is `'visible'` only when both the document is visible (not backgrounded)\n * and the element is within the viewport. Uses a shared IntersectionObserver\n * pool. Multiple `createSight` calls with the same options share one observer.\n *\n * Pass `document` to anchor to the page instead. There is no viewport test to\n * make, so no observer is created and `phase` follows document visibility.\n *\n * @example\n * const sight = createSight({\n * target: el,\n * onPhaseChange: (phase) => phase === 'visible' ? loop.start() : loop.pause(),\n * });\n * // cleanup:\n * sight.stop();\n *\n * @remarks\n * `onPhaseChange` fires only on phase transitions, not on every IntersectionObserver callback.\n */\nexport function createSight(options: SightOptions): Sight {\n if (typeof document === 'undefined') {\n serverContextError('createSight');\n }\n\n const { target, intersectionOptions, onPhaseChange, signal } = options;\n\n if (!target) noTargetError('createSight');\n\n let _phase: SightPhase = 'unknown';\n let _reason: SightReason = 'initial';\n let stopped = false;\n\n const isPage = isDocument(target);\n\n let documentVisible: boolean = !document.hidden;\n let elementInView = isPage;\n\n function recompute(trigger: SightReason): void {\n if (stopped) return;\n\n const prev = _phase;\n const next: SightPhase =\n documentVisible && elementInView ? 'visible' : 'hidden';\n\n _reason =\n next === 'hidden' && !documentVisible && !elementInView\n ? 'all-hidden'\n : trigger;\n\n if (next === prev) return;\n _phase = next;\n onPhaseChange?.(_phase, _reason);\n }\n\n // --- Signal handlers ---\n\n function onVisibilityChange(): void {\n documentVisible = !document.hidden;\n recompute('document');\n }\n\n function onPageShow(event: PageTransitionEvent): void {\n if (!event.persisted) return;\n documentVisible = true;\n recompute('bfcache');\n }\n\n function onIntersection(entry: IntersectionObserverEntry): void {\n elementInView = entry.isIntersecting;\n recompute('viewport');\n }\n\n // --- Subscribe ---\n\n document.addEventListener('visibilitychange', onVisibilityChange);\n window.addEventListener('pageshow', onPageShow);\n\n let unobserveIO: (() => void) | undefined;\n if (isPage) {\n // An element target gets its first phase from the observer's initial\n // callback. A page has no observer, so report the starting phase here or\n // consumers would wait on a transition that never comes.\n //\n // This is the only path where a consumer callback runs before the caller\n // holds an instance to stop, so a throw here has to release the listeners\n // itself or they outlive the failed construction.\n try {\n recompute('initial');\n } catch (error) {\n document.removeEventListener('visibilitychange', onVisibilityChange);\n window.removeEventListener('pageshow', onPageShow);\n throw error;\n }\n } else {\n unobserveIO = observeIntersection({\n element: target,\n onIntersect: onIntersection,\n ...intersectionOptions,\n });\n }\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n document.removeEventListener('visibilitychange', onVisibilityChange);\n window.removeEventListener('pageshow', onPageShow);\n unobserveIO?.();\n _phase = 'hidden';\n _reason = 'initial';\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n get phase() {\n return stopped ? 'hidden' : _phase;\n },\n get phaseReason() {\n return _reason;\n },\n stop,\n };\n}\n","type MQLCallback = (matches: boolean) => void;\n\ninterface MQLPoolEntry {\n mql: MediaQueryList;\n listeners: Set<MQLCallback>;\n handler: (e: MediaQueryListEvent) => void;\n}\n\nconst pool = new Map<string, MQLPoolEntry>();\n\n/**\n * Subscribe to a media query via a shared MediaQueryList pool.\n * Multiple subscribers to the same query share one MQL and one change listener.\n *\n * @returns Cleanup function that removes the subscriber.\n */\nexport function subscribeMediaQuery(\n query: string,\n callback: MQLCallback,\n): () => void {\n const entry: MQLPoolEntry = getOrCreateEntry(query);\n\n entry.listeners.add(callback);\n\n let disposed = false;\n\n return () => {\n if (disposed) return;\n disposed = true;\n\n const poolEntry: MQLPoolEntry | undefined = pool.get(query);\n if (!poolEntry) return;\n poolEntry.listeners.delete(callback);\n\n if (poolEntry.listeners.size === 0) {\n poolEntry.mql.removeEventListener('change', poolEntry.handler);\n pool.delete(query);\n }\n };\n}\n\n/**\n * Synchronous read of a media query via the shared pool.\n * Uses the existing pool entry if available, otherwise reads directly.\n */\nexport function readMediaQuery(query: string): boolean {\n const entry: MQLPoolEntry | undefined = pool.get(query);\n if (entry) return entry.mql.matches;\n return matchMedia(query).matches;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Return an existing pool entry for this query, or create and register a new one. */\nfunction getOrCreateEntry(query: string): MQLPoolEntry {\n const existing: MQLPoolEntry | undefined = pool.get(query);\n if (existing) return existing;\n\n const entry = createPoolEntry(query);\n\n entry.mql.addEventListener('change', entry.handler);\n pool.set(query, entry);\n\n return entry;\n}\n\nconst createPoolEntry = (query: string): MQLPoolEntry => {\n const mql: MediaQueryList = matchMedia(query);\n const listeners = new Set<MQLCallback>();\n\n const handler = (event: MediaQueryListEvent): void => {\n for (const cb of listeners) cb(event.matches);\n };\n return { mql, listeners, handler };\n};\n","import { linkAbortSignal } from '../_internal/abort';\nimport { noTargetError, serverContextError } from '../_internal/errors';\nimport {\n readMediaQuery,\n subscribeMediaQuery,\n} from '../_internal/pool/mql-pool';\nimport { createSight } from '../sight';\nimport type { SightPhase } from '../sight';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type LifecyclePhase = 'idle' | 'active' | 'paused' | 'stopped';\nexport type LifecycleReason =\n | 'initial'\n | 'started'\n | 'resumed'\n | 'sight'\n | 'reduced-motion'\n | 'manual'\n | 'disposed';\n\n/** Whether reduced motion pauses the lifecycle. Default `'pause'`. */\nexport type LifecycleReducedMotion = 'pause' | 'ignore';\n\nexport interface LifecycleOptions {\n /** Element to observe, or `document` to anchor to the page. */\n target: Element | Document;\n reducedMotion?: LifecycleReducedMotion;\n intersectionOptions?: IntersectionObserverInit;\n start?: 'auto' | 'manual';\n onPhaseChange?: (phase: LifecyclePhase, reason: LifecycleReason) => void;\n /** Abort signal that stops the lifecycle when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Lifecycle {\n /** Begin honoring signals. Called automatically unless `start: 'manual'`. */\n start(): void;\n /** Terminal. Disposes observers and listeners. Cannot be restarted. */\n stop(): void;\n /** Manually pause (e.g. a panel opened over the animation). Lowest priority. */\n pause(): void;\n /** Clear a manual pause. */\n resume(): void;\n readonly phase: LifecyclePhase;\n readonly phaseReason: LifecycleReason;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst REDUCED_MOTION_QUERY = '(prefers-reduced-motion: reduce)';\n\n// ---------------------------------------------------------------------------\n// createLifecycle\n// ---------------------------------------------------------------------------\n\n/**\n * The activation decision for an animation, decoupled from who drives the frames.\n *\n * Composes visibility (`createSight`), reduced motion, and a manual pause into a\n * single `active` / `paused` phase. Use when you own your render loop (WebGL,\n * three.js, a Web Worker, or non-rAF work that should still pause off-screen or\n * under reduced motion). For loops `phase` should drive, use `createLoop` instead.\n *\n * @example\n * const lifecycle = createLifecycle({\n * target: canvas,\n * onPhaseChange: (phase) => {\n * if (phase === 'active') renderer.start();\n * else renderer.stop();\n * },\n * });\n * // cleanup:\n * lifecycle.stop();\n */\nexport function createLifecycle(options: LifecycleOptions): Lifecycle {\n if (typeof document === 'undefined') {\n serverContextError('createLifecycle');\n }\n\n const {\n target,\n reducedMotion = 'pause',\n intersectionOptions,\n start: startMode = 'auto',\n onPhaseChange,\n signal,\n } = options;\n\n if (!target) noTargetError('createLifecycle');\n\n let _phase: LifecyclePhase = 'idle';\n let _reason: LifecycleReason = 'initial';\n\n let sightVisible = false;\n let reducedMotionActive = false;\n let manualPaused = false;\n let intentStarted = false;\n let hasBeenActive = false;\n\n function setPhase(phase: LifecyclePhase, reason: LifecycleReason): void {\n if (_phase === phase && _reason === reason) return;\n _phase = phase;\n _reason = reason;\n onPhaseChange?.(phase, reason);\n }\n\n /** Highest-priority active pause signal, or null when nothing should pause. */\n function pauseReason(): LifecycleReason | null {\n if (reducedMotionActive && reducedMotion === 'pause')\n return 'reduced-motion';\n if (!sightVisible) return 'sight';\n if (manualPaused) return 'manual';\n return null;\n }\n\n function reconcile(): void {\n if (_phase === 'stopped' || !intentStarted) return;\n\n const reason = pauseReason();\n if (reason) {\n setPhase('paused', reason);\n return;\n }\n\n setPhase('active', hasBeenActive ? 'resumed' : 'started');\n hasBeenActive = true;\n }\n\n // --- Signal handlers ---\n\n function onSightChange(phase: SightPhase): void {\n sightVisible = phase === 'visible';\n reconcile();\n }\n\n function onReducedMotionChange(matches: boolean): void {\n reducedMotionActive = matches;\n reconcile();\n }\n\n // --- Init subsystems ---\n\n const sight = createSight({\n target,\n intersectionOptions,\n onPhaseChange: onSightChange,\n });\n\n let unsubReducedMotion: (() => void) | null = null;\n if (reducedMotion !== 'ignore') {\n reducedMotionActive = readMediaQuery(REDUCED_MOTION_QUERY);\n unsubReducedMotion = subscribeMediaQuery(\n REDUCED_MOTION_QUERY,\n onReducedMotionChange,\n );\n }\n\n // --- Public API ---\n\n function start(): void {\n if (_phase === 'stopped') return;\n intentStarted = true;\n reconcile();\n }\n\n function stop(): void {\n if (_phase === 'stopped') return;\n unlinkAbort?.();\n sight.stop();\n unsubReducedMotion?.();\n unsubReducedMotion = null;\n setPhase('stopped', 'disposed');\n }\n\n function pause(): void {\n if (manualPaused) return;\n manualPaused = true;\n reconcile();\n }\n\n function resume(): void {\n if (!manualPaused) return;\n manualPaused = false;\n reconcile();\n }\n\n let unlinkAbort: (() => void) | undefined;\n unlinkAbort = linkAbortSignal(signal, stop);\n\n if (startMode === 'auto') {\n start();\n }\n\n return {\n start,\n stop,\n pause,\n resume,\n get phase() {\n return _phase;\n },\n get phaseReason() {\n return _reason;\n },\n };\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport {\n invalidFpsError,\n noTargetError,\n serverContextError,\n} from '../_internal/errors';\nimport { createLifecycle } from '../lifecycle';\nimport { createTicker } from '../tick';\nimport type { FrameState, Ticker } from '../tick';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ReducedMotionBehavior = 'pause' | 'complete' | 'ignore';\nexport type DegradedBehavior = 'throttle' | 'pause' | 'ignore';\n\nexport type LoopPhase = 'idle' | 'running' | 'paused' | 'stopped';\nexport type LoopReason =\n | 'initial'\n | 'started'\n | 'resumed'\n | 'sight'\n | 'reduced-motion'\n | 'degraded'\n | 'manual'\n | 'disposed';\n\nexport type Quality = 'full' | 'degraded';\nexport type DegradedReason = 'unfocused' | 'frame-budget';\n\ninterface LoopOptionsBase {\n /** Element to observe, or `document` to anchor the loop to the page. */\n target: Element | Document;\n /**\n * Called every frame. Write to refs or DOM directly. Never call React\n * `setState` here (60 calls/sec = 60 re-renders/sec).\n */\n onTick: (frame: FrameState) => void;\n fps?: number;\n reducedMotion?: ReducedMotionBehavior;\n intersectionOptions?: IntersectionObserverInit;\n start?: 'auto' | 'manual';\n onPhaseChange?: (phase: LoopPhase, reason: LoopReason) => void;\n /** Abort signal that stops the loop when aborted. */\n signal?: AbortSignal;\n}\n\ntype DegradedOptions =\n | { degraded?: 'throttle'; degradedFps?: number }\n | { degraded: 'pause' }\n | { degraded: 'ignore' };\n\nexport type LoopOptions = LoopOptionsBase & DegradedOptions;\n\nexport interface Loop {\n start(): void;\n stop(): void;\n readonly phase: LoopPhase;\n readonly phaseReason: LoopReason;\n readonly quality: Quality;\n readonly qualityReason: DegradedReason | undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** How many consecutive over-budget frames before degrading quality. */\nconst OVER_BUDGET_THRESHOLD = 3;\n\n/** FPS cap applied when quality is degraded (throttle mode). */\nconst DEGRADED_FPS_CAP = 30;\n\n/**\n * In `degraded: 'pause'` mode a frame-budget degrade pauses the loop, so no\n * further frames tick to clear it. Without a timer the loop would stay paused\n * forever after a transient spike. After this delay the loop optimistically\n * un-pauses and re-measures, rescheduling on each subsequent degrade. (Throttle\n * mode keeps ticking, so it does not use this.)\n */\nconst RECOVERY_RETRY_MS = 2000;\n\n// ---------------------------------------------------------------------------\n// createLoop\n// ---------------------------------------------------------------------------\n\n/**\n * Lifecycle-aware animation loop composing ticker, visibility, and reduced motion.\n *\n * Pass an element and get a loop that pauses when the element leaves the viewport\n * or the tab is backgrounded, resumes when it returns, and cleans up with `stop()`.\n *\n * @remarks\n * The loop is signal-driven and exposes only `start()` and `stop()`. There is no\n * imperative `pause()`/`resume()`. Pausing is decided by visibility, reduced\n * motion, and quality, so an imperative pause would compete with those signals.\n * For manual control, use `useLoop`'s `enabled` option (React) or `createLifecycle`,\n * which exposes `pause()`/`resume()` for loops you drive yourself.\n *\n * @example\n * const loop = createLoop({\n * target: el,\n * onTick: (frame) => draw(ctx, frame),\n * });\n * // cleanup:\n * loop.stop();\n */\nexport function createLoop(options: LoopOptions): Loop {\n if (typeof requestAnimationFrame === 'undefined') {\n serverContextError('createLoop');\n }\n\n const {\n target,\n onTick,\n fps: baseFps,\n reducedMotion = 'pause',\n degraded = 'throttle' as DegradedBehavior,\n degradedFps: configuredDegradedFps,\n intersectionOptions,\n start: startMode = 'auto',\n onPhaseChange,\n signal,\n } = options as LoopOptionsBase & {\n degraded?: DegradedBehavior;\n degradedFps?: number;\n signal?: AbortSignal;\n };\n\n if (!target) noTargetError('createLoop');\n validateFps(baseFps);\n validateFps(configuredDegradedFps);\n\n const degradedFps: number | undefined =\n degraded === 'throttle' ? configuredDegradedFps : undefined;\n\n // --- State ---\n\n let _phase: LoopPhase = 'idle';\n let _reason: LoopReason = 'initial';\n let _quality: Quality = 'full';\n let _qualityReason: DegradedReason | undefined;\n\n let intentStarted = false;\n let overBudgetCount = 0;\n let ticker: Ticker | null = null;\n\n // Frame-budget threshold for the current effective FPS. Mutable so the\n // once-created ticker callback always compares frame time against the\n // current cap.\n let frameBudget = 1000 / 60;\n\n // Quality signal flags\n let focusDegraded = false;\n\n // Pending pause-mode frame-budget recovery timer (see RECOVERY_RETRY_MS).\n let recoveryTimer: ReturnType<typeof setTimeout> | null = null;\n\n // --- State transitions ---\n\n function setPhase(phase: LoopPhase, reason: LoopReason): void {\n if (_phase === phase && _reason === reason) return;\n _phase = phase;\n _reason = reason;\n onPhaseChange?.(phase, reason);\n }\n\n function setQuality(quality: Quality, reason?: DegradedReason): void {\n const changed = _quality !== quality;\n _quality = quality;\n _qualityReason = reason;\n\n if (!changed) return;\n\n if (degraded === 'throttle') {\n if (_phase !== 'stopped') applyFpsPolicy();\n } else if (degraded === 'pause') {\n reconcile();\n }\n }\n\n /** Evaluate all quality signals and pick the highest-priority active one. */\n function reconcileQuality(): void {\n if (focusDegraded) {\n setQuality('degraded', 'unfocused');\n return;\n }\n if (overBudgetCount >= OVER_BUDGET_THRESHOLD) {\n setQuality('degraded', 'frame-budget');\n return;\n }\n setQuality('full');\n }\n\n /**\n * Un-pause and re-measure after a pause-mode frame-budget degrade. If frames\n * are still over budget, the next degrade reschedules this.\n */\n function scheduleBudgetRecovery(): void {\n // A consumer callback may stop the loop between the degrade and this\n // call; never arm a timer on a stopped loop.\n if (_phase === 'stopped' || recoveryTimer !== null) return;\n recoveryTimer = setTimeout(() => {\n recoveryTimer = null;\n overBudgetCount = 0;\n reconcileQuality();\n }, RECOVERY_RETRY_MS);\n }\n\n function clearBudgetRecovery(): void {\n if (recoveryTimer === null) return;\n clearTimeout(recoveryTimer);\n recoveryTimer = null;\n }\n\n // --- Ticker lifecycle ---\n\n function getEffectiveFps(): number | undefined {\n if (_quality !== 'degraded') return baseFps;\n const cap: number = degradedFps ?? DEGRADED_FPS_CAP;\n if (baseFps === undefined) return cap;\n return Math.min(baseFps, cap);\n }\n\n /**\n * Derive effective FPS and its frame budget together, then apply the cap to\n * the live ticker. The frame count, elapsed time, and frame object are\n * untouched; only the delivery rate changes.\n */\n function applyFpsPolicy(): number | undefined {\n const targetFps: number | undefined = getEffectiveFps();\n frameBudget = 1000 / (targetFps ?? 60);\n ticker?.setFps(targetFps);\n return targetFps;\n }\n\n // Created once and reused for the loop's lifetime (stable reference).\n function loopTick(frame: FrameState): void {\n checkFrameBudget(frame.delta);\n onTick(frame);\n }\n\n /** Lazily create the loop's single ticker. Never replaced before stop(). */\n function ensureTicker(): void {\n if (ticker) return;\n ticker = createTicker({ fps: applyFpsPolicy(), onTick: loopTick });\n ticker.start();\n }\n\n function checkFrameBudget(delta: number): void {\n if (delta <= frameBudget * 1.5) {\n overBudgetCount = 0;\n return;\n }\n\n overBudgetCount++;\n if (overBudgetCount < OVER_BUDGET_THRESHOLD) return;\n\n reconcileQuality();\n // Pause mode stops ticking once degraded, so no future frame can clear the\n // degraded state — schedule a timed retry. Throttle keeps running.\n if (degraded === 'pause') scheduleBudgetRecovery();\n }\n\n // --- Reconcile ---\n\n /** Check if any signal requires the loop to be paused. */\n function shouldPause(): LoopReason | null {\n // Visibility + reduced motion are owned by the lifecycle; its paused reasons\n // ('sight' | 'reduced-motion') are a subset of LoopReason.\n if (lifecycle.phase === 'paused')\n return lifecycle.phaseReason as LoopReason;\n // Quality-driven pause stays here — it needs the ticker's frame timing.\n if (degraded === 'pause' && _quality === 'degraded') return 'degraded';\n return null;\n }\n\n /** Evaluate all signals and transition to the correct phase. */\n function reconcile(): void {\n if (_phase === 'stopped' || !intentStarted) return;\n\n const pauseReason = shouldPause();\n\n if (pauseReason) {\n if (ticker && _phase === 'running') ticker.pause();\n setPhase('paused', pauseReason);\n return;\n }\n\n if (!ticker) {\n ensureTicker();\n setPhase('running', _reason === 'initial' ? 'started' : 'resumed');\n } else if (_phase === 'paused') {\n ticker.resume();\n setPhase('running', 'resumed');\n }\n }\n\n // --- Signal handlers ---\n\n function onFocusChange(): void {\n focusDegraded = !document.hasFocus();\n reconcileQuality();\n }\n\n // --- Init subsystems ---\n\n // Lifecycle owns the visibility + reduced-motion decision. The loop layers the\n // ticker and quality (frame-budget / focus) on top. Driven manually so it only\n // activates once the loop itself starts.\n const lifecycle = createLifecycle({\n target,\n reducedMotion: reducedMotion === 'pause' ? 'pause' : 'ignore',\n intersectionOptions,\n start: 'manual',\n onPhaseChange: reconcile,\n });\n\n const unsubFocus: () => void = subscribeFocusTracking(onFocusChange);\n\n // --- Public API ---\n\n function start(): void {\n if (_phase === 'stopped') return;\n intentStarted = true;\n lifecycle.start();\n reconcile();\n }\n\n function stop(): void {\n if (_phase === 'stopped') return;\n unlinkAbort?.();\n clearBudgetRecovery();\n // Enter the terminal phase before teardown: lifecycle.stop() fires\n // onPhaseChange -> reconcile() synchronously, and reconcile must see\n // 'stopped' so it cannot resume or recreate the ticker mid-stop. The\n // consumer is notified last, after teardown has finished, so a throwing\n // callback cannot leave the loop half-disposed.\n _phase = 'stopped';\n _reason = 'disposed';\n ticker?.stop();\n lifecycle.stop();\n unsubFocus();\n onPhaseChange?.('stopped', 'disposed');\n }\n\n // Declared before assignment because an already-aborted signal makes\n // linkAbortSignal call stop() synchronously, which reads unlinkAbort.\n let unlinkAbort: (() => void) | undefined;\n unlinkAbort = linkAbortSignal(signal, stop);\n\n if (startMode === 'auto') {\n start();\n }\n\n return {\n start,\n stop,\n get phase() {\n return _phase;\n },\n get phaseReason() {\n return _reason;\n },\n get quality() {\n return _quality;\n },\n get qualityReason() {\n return _qualityReason;\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Throws `invalid_fps` for a defined fps that is not a positive finite number. */\nfunction validateFps(fps: number | undefined): void {\n if (fps !== undefined && (!Number.isFinite(fps) || fps <= 0)) {\n invalidFpsError('createLoop', fps);\n }\n}\n\nfunction subscribeFocusTracking(onChange: () => void): () => void {\n window.addEventListener('focus', onChange);\n window.addEventListener('blur', onChange);\n return () => {\n window.removeEventListener('focus', onChange);\n window.removeEventListener('blur', onChange);\n };\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { noTargetError, serverContextError } from '../_internal/errors';\nimport { observeIntersection } from '../_internal/pool/io-pool';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ScrollProgressOptions {\n target: Element;\n /** Called when the intersection ratio changes at a threshold crossing. */\n onProgress: (ratio: number) => void;\n /** Number of evenly-spaced thresholds. Default 20 (~5% granularity). */\n steps?: number;\n root?: Element | Document | null;\n rootMargin?: string;\n /** Abort signal that stops the observer when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface ScrollProgress {\n /** Current intersection ratio (0–1). Synchronous read of the last-reported value. */\n readonly ratio: number;\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_STEPS = 20;\n\n// ---------------------------------------------------------------------------\n// Threshold cache\n//\n// Most consumers use the same step count. Cache the array so the IO pool\n// receives stable references and identical pool keys without re-allocating.\n// ---------------------------------------------------------------------------\n\nconst thresholdCache = new Map<number, number[]>();\n\nfunction buildThresholds(steps: number): number[] {\n const cached: number[] | undefined = thresholdCache.get(steps);\n if (cached) return cached;\n\n const thresholds: number[] = [];\n for (let i = 0; i <= steps; i++) {\n thresholds.push(i / steps);\n }\n thresholdCache.set(steps, thresholds);\n return thresholds;\n}\n\n// ---------------------------------------------------------------------------\n// createScrollProgress\n// ---------------------------------------------------------------------------\n\n/**\n * Observe what fraction of an element is visible in the viewport (0–1).\n *\n * Uses the shared IntersectionObserver pool with multi-threshold options.\n * Multiple instances with the same `steps` share a single IO.\n *\n * @example\n * const progress = createScrollProgress({\n * target: el,\n * onProgress: (ratio) => {\n * el.style.opacity = String(ratio);\n * },\n * });\n * // cleanup:\n * progress.stop();\n */\nexport function createScrollProgress(\n options: ScrollProgressOptions,\n): ScrollProgress {\n if (typeof IntersectionObserver === 'undefined') {\n serverContextError('createScrollProgress');\n }\n\n const {\n target: element,\n onProgress,\n steps = DEFAULT_STEPS,\n root,\n rootMargin,\n signal,\n } = options;\n\n if (!element) noTargetError('createScrollProgress');\n\n let _ratio = 0;\n let stopped = false;\n\n const threshold: number[] = buildThresholds(steps);\n\n const unobserve: () => void = observeIntersection({\n element,\n onIntersect: (entry: IntersectionObserverEntry) => {\n const newRatio: number = entry.intersectionRatio;\n if (newRatio === _ratio) return;\n _ratio = newRatio;\n onProgress(newRatio);\n },\n root,\n rootMargin,\n threshold,\n });\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n unobserve();\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n get ratio(): number {\n return _ratio;\n },\n stop,\n };\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { noTargetError, serverContextError } from '../_internal/errors';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type RenderPhase = 'rendered' | 'skipped';\n\nexport interface RenderStateOptions {\n target: Element;\n onPhaseChange?: (phase: RenderPhase) => void;\n /** Abort signal that stops the observer when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface RenderState {\n /** Whether the browser is currently rendering the element or skipping it. */\n readonly phase: RenderPhase;\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// createRenderState\n// ---------------------------------------------------------------------------\n\n/**\n * Report whether the browser is rendering an element or skipping it under\n * `content-visibility`. Listens to the `contentvisibilityautostatechange`\n * event, the browser's ground-truth paint decision.\n *\n * Use it to pause raw, non-phase work (a hand-written rAF loop, `setInterval`,\n * expensive effects) when a `Defer` subtree stops painting. phase's own loops\n * already self-pause off-screen, so they do not need this.\n *\n * Listening and reacting has zero layout effect. It never breaks the\n * no-layout-shift guarantee of `content-visibility`.\n *\n * @example\n * const render = createRenderState({\n * target: el,\n * onPhaseChange: (phase) => phase === 'skipped' ? clock.pause() : clock.resume(),\n * });\n * // cleanup:\n * render.stop();\n *\n * @remarks\n * Where `content-visibility` is unsupported, `phase` stays `'rendered'`.\n *\n * Per the CSS Containment spec, `ResizeObserver` callbacks pause for elements\n * inside a skipped `content-visibility: auto` subtree. Use this primitive to\n * detect that transition when your code depends on size observations resuming.\n */\nexport function createRenderState(options: RenderStateOptions): RenderState {\n if (typeof document === 'undefined') {\n serverContextError('createRenderState');\n }\n\n const { target: element, onPhaseChange, signal } = options;\n\n if (!element) noTargetError('createRenderState');\n\n let _phase: RenderPhase = 'rendered';\n let stopped = false;\n\n function onStateChange(event: Event): void {\n if (stopped) return;\n const next: RenderPhase = (event as ContentVisibilityAutoStateChangeEvent)\n .skipped\n ? 'skipped'\n : 'rendered';\n if (next === _phase) return;\n _phase = next;\n onPhaseChange?.(_phase);\n }\n\n element.addEventListener('contentvisibilityautostatechange', onStateChange);\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n element.removeEventListener(\n 'contentvisibilityautostatechange',\n onStateChange,\n );\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n get phase() {\n return _phase;\n },\n stop,\n };\n}\n","type DprCallback = (dpr: number) => void;\n\nconst listeners = new Set<DprCallback>();\n\n// Last-bound DPR. Set by bind() before the MQL is created; only meaningful\n// while a subscription is active.\nlet currentDpr = 1;\n\nlet mql: MediaQueryList | null = null;\nlet handler: (() => void) | null = null;\n\n/**\n * Subscribe to devicePixelRatio changes (e.g. user drags window between monitors).\n *\n * Uses a single shared `matchMedia` query that re-subscribes on every DPR change,\n * so chained monitor switches (A -> B -> C) are all caught.\n *\n * @returns Cleanup function that removes the subscriber.\n */\nexport function subscribeDpr(callback: DprCallback): () => void {\n listeners.add(callback);\n\n if (listeners.size === 1) {\n bind();\n }\n\n let disposed = false;\n return () => {\n if (disposed) return;\n disposed = true;\n listeners.delete(callback);\n if (listeners.size === 0) {\n unbind();\n }\n };\n}\n\n/** Read the current devicePixelRatio. */\nexport function readDpr(): number {\n if (typeof window === 'undefined') return 1;\n return window.devicePixelRatio || 1;\n}\n\n// ---------------------------------------------------------------------------\n// Internal: bind/unbind the resolution MQL\n// ---------------------------------------------------------------------------\n\nfunction bind(): void {\n if (typeof matchMedia === 'undefined') return;\n currentDpr = window.devicePixelRatio || 1;\n mql = matchMedia(`(resolution: ${currentDpr}dppx)`);\n handler = onDprChange;\n mql.addEventListener('change', handler);\n}\n\nfunction unbind(): void {\n if (mql && handler) {\n mql.removeEventListener('change', handler);\n }\n mql = null;\n handler = null;\n}\n\nfunction onDprChange(): void {\n const newDpr: number = window.devicePixelRatio || 1;\n if (newDpr === currentDpr) return;\n currentDpr = newDpr;\n\n // Re-subscribe with the new DPR value so the next change is caught.\n unbind();\n bind();\n\n for (const cb of listeners) cb(newDpr);\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { serverContextError } from '../_internal/errors';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface IdleOptions {\n /** Max ms to wait before running the callback even if no idle period occurs. */\n timeout?: number;\n /** Abort signal that cancels the scheduled callback when aborted. */\n signal?: AbortSignal;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Fallback delay when `requestIdleCallback` is unavailable (e.g. Safari). */\nconst FALLBACK_DELAY = 1;\n\n// ---------------------------------------------------------------------------\n// whenIdle\n// ---------------------------------------------------------------------------\n\n/**\n * Run a callback once the browser is idle. Wraps `requestIdleCallback`, falling\n * back to a near-immediate `setTimeout` where it is unavailable (Safari).\n *\n * Returns a cancel function. Calling it before the callback runs prevents it.\n *\n * @example\n * const cancel = whenIdle(() => warmCache(), { timeout: 2000 });\n * // later, if no longer needed:\n * cancel();\n */\nexport function whenIdle(\n callback: () => void,\n options?: IdleOptions,\n): () => void {\n if (typeof window === 'undefined') {\n serverContextError('whenIdle');\n }\n\n const { timeout, signal } = options ?? {};\n\n // Already aborted: never schedule, and hand back a no-op cancel.\n if (signal?.aborted) {\n return () => {\n // Nothing was scheduled, so there is nothing to cancel.\n };\n }\n\n let cancel: () => void;\n\n if (typeof window.requestIdleCallback === 'function') {\n // Capture cancelIdleCallback now (bound to window), rather than reading\n // window.cancelIdleCallback inside the returned closure. The cancel may run\n // after the global is swapped out (e.g. test teardown unstubbing globals),\n // and a late lookup would throw \"not a function\". Binding also avoids an\n // illegal-invocation error from calling it detached from window.\n const cancelIdle = window.cancelIdleCallback.bind(window);\n const handle: number = window.requestIdleCallback(\n () => callback(),\n timeout === undefined ? undefined : { timeout },\n );\n cancel = () => cancelIdle(handle);\n } else {\n const handle: ReturnType<typeof setTimeout> = setTimeout(\n callback,\n FALLBACK_DELAY,\n );\n cancel = () => clearTimeout(handle);\n }\n\n const unlinkAbort: () => void = linkAbortSignal(signal, cancel);\n\n return () => {\n unlinkAbort();\n cancel();\n };\n}\n","import { readMediaQuery } from '../_internal/pool/mql-pool';\n\nexport const REDUCED_MOTION_QUERY = '(prefers-reduced-motion: reduce)';\n\n/**\n * Synchronous check for `prefers-reduced-motion: reduce`.\n *\n * Returns `false` on the server (no `matchMedia`). On the client, reads from\n * the shared MQL pool so the underlying `MediaQueryList` is reused across\n * all callers.\n */\nexport function prefersReducedMotion(): boolean {\n if (typeof matchMedia === 'undefined') return false;\n return readMediaQuery(REDUCED_MOTION_QUERY);\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { noTargetError, serverContextError } from '../_internal/errors';\nimport { observeIntersection } from '../_internal/pool/io-pool';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type MutationPhase = 'observing' | 'paused' | 'stopped';\nexport type MutationReason = 'initial' | 'started' | 'sight' | 'disposed';\n\nexport interface MutationOptions {\n target: Element;\n /** Standard MutationObserver configuration. */\n mutation: MutationObserverInit;\n /** Called once per rAF frame with coalesced records. Never per-record. */\n onMutations: (records: MutationRecord[]) => void;\n /** Called on phase transitions (observing, paused, stopped). */\n onPhaseChange?: (phase: MutationPhase, reason: MutationReason) => void;\n /** Pause when off-screen or ignore visibility. Default `'pause'`. */\n visibility?: 'pause' | 'ignore';\n /** IO options forwarded to the visibility observer. */\n intersectionOptions?: IntersectionObserverInit;\n /** Stops the observer when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Mutation {\n readonly phase: MutationPhase;\n readonly phaseReason: MutationReason;\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// createMutation\n// ---------------------------------------------------------------------------\n\n/** Lifecycle-aware MutationObserver with rAF-coalesced callbacks. */\nexport function createMutation(options: MutationOptions): Mutation {\n if (typeof document === 'undefined') {\n serverContextError('createMutation');\n }\n\n const {\n target: element,\n mutation: mutationInit,\n onMutations,\n onPhaseChange,\n visibility = 'pause',\n intersectionOptions,\n signal,\n } = options;\n\n if (!element) noTargetError('createMutation');\n\n warnReflowStorm(mutationInit);\n\n let _phase: MutationPhase = 'paused';\n let _reason: MutationReason = 'initial';\n let stopped = false;\n let pendingRecords: MutationRecord[] = [];\n let rafId = 0;\n\n function setPhase(phase: MutationPhase, reason: MutationReason): void {\n const prev = _phase;\n _phase = phase;\n _reason = reason;\n if (prev !== phase) onPhaseChange?.(phase, reason);\n }\n\n function flushRecords(): void {\n rafId = 0;\n if (stopped || pendingRecords.length === 0) return;\n const batch = pendingRecords;\n pendingRecords = [];\n onMutations(batch);\n }\n\n function scheduleFlush(): void {\n if (rafId !== 0) return;\n rafId = requestAnimationFrame(flushRecords);\n }\n\n const mo = new MutationObserver((records) => {\n if (stopped || _phase !== 'observing') return;\n for (let i = 0, len = records.length; i < len; i++) {\n pendingRecords[pendingRecords.length] = records[i] as MutationRecord;\n }\n scheduleFlush();\n });\n\n function startObserving(): void {\n if (stopped || _phase === 'observing') return;\n setPhase('observing', 'started');\n mo.observe(element, mutationInit);\n }\n\n function pauseObserving(reason: MutationReason): void {\n if (stopped || _phase === 'paused') return;\n setPhase('paused', reason);\n mo.disconnect();\n if (rafId !== 0) {\n cancelAnimationFrame(rafId);\n rafId = 0;\n }\n pendingRecords = [];\n }\n\n let cleanupVisibility: (() => void) | undefined;\n\n if (visibility === 'pause') {\n let elementInView = false;\n let documentVisible = !document.hidden;\n\n function recompute(): void {\n if (stopped) return;\n if (documentVisible && elementInView) startObserving();\n else pauseObserving('sight');\n }\n\n function onVisibilityChange(): void {\n documentVisible = !document.hidden;\n recompute();\n }\n\n function onPageShow(event: PageTransitionEvent): void {\n if (!event.persisted) return;\n documentVisible = true;\n recompute();\n }\n\n document.addEventListener('visibilitychange', onVisibilityChange);\n window.addEventListener('pageshow', onPageShow);\n\n const unobserveIO = observeIntersection({\n element,\n onIntersect: (entry) => {\n elementInView = entry.isIntersecting;\n recompute();\n },\n ...intersectionOptions,\n });\n\n cleanupVisibility = () => {\n document.removeEventListener('visibilitychange', onVisibilityChange);\n window.removeEventListener('pageshow', onPageShow);\n unobserveIO();\n };\n } else {\n startObserving();\n }\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n cleanupVisibility?.();\n mo.disconnect();\n if (rafId !== 0) {\n cancelAnimationFrame(rafId);\n rafId = 0;\n }\n pendingRecords = [];\n setPhase('stopped', 'disposed');\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n get phase() {\n return _phase;\n },\n get phaseReason() {\n return _reason;\n },\n stop,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nconst REFLOW_STORM_ATTRIBUTES = new Set(['style', 'class']);\n\nfunction warnReflowStorm(opts: MutationObserverInit): void {\n if (process.env.NODE_ENV === 'production') return;\n if (!opts.subtree) return;\n const filter = opts.attributeFilter;\n if (!filter) return;\n if (!filter.some((attr) => REFLOW_STORM_ATTRIBUTES.has(attr))) return;\n\n console.warn(\n '[phase] createMutation: observing subtree + attributeFilter including ' +\n '\"style\" or \"class\" fires on every descendant style/class change ' +\n '(animations, hovers, framework churn). Narrow the scope or use a ' +\n 'visibility signal instead.',\n );\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { noTargetError, serverContextError } from '../_internal/errors';\nimport { observeIntersection } from '../_internal/pool/io-pool';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type PointerPhase = 'idle' | 'tracking' | 'stopped';\nexport type PointerReason =\n | 'initial'\n | 'enter'\n | 'leave'\n | 'sight'\n | 'disposed';\n\nexport interface PointerState {\n /** X position relative to the element's top-left, in CSS pixels. */\n x: number;\n /** Y position relative to the element's top-left, in CSS pixels. */\n y: number;\n /** Whether a pointer is currently over the element. */\n active: boolean;\n}\n\nexport interface PointerOptions {\n target: Element;\n /** Called once per rAF frame with the latest pointer position. */\n onPointer: (state: PointerState) => void;\n /** Called on phase transitions (idle, tracking, stopped). */\n onPhaseChange?: (phase: PointerPhase, reason: PointerReason) => void;\n /** Pause when off-screen or ignore visibility. Default `'pause'`. */\n visibility?: 'pause' | 'ignore';\n /** IO options forwarded to the visibility observer. */\n intersectionOptions?: IntersectionObserverInit;\n /** Stops the tracker when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Pointer {\n readonly phase: PointerPhase;\n readonly phaseReason: PointerReason;\n readonly state: Readonly<PointerState>;\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// createPointer\n// ---------------------------------------------------------------------------\n\n/** Lifecycle-aware pointer tracker with rAF-batched `getBoundingClientRect`. */\nexport function createPointer(options: PointerOptions): Pointer {\n if (typeof document === 'undefined') {\n serverContextError('createPointer');\n }\n\n const {\n target: element,\n onPointer,\n onPhaseChange,\n visibility = 'pause',\n intersectionOptions,\n signal,\n } = options;\n\n if (!element) noTargetError('createPointer');\n\n let _phase: PointerPhase = 'idle';\n let _reason: PointerReason = 'initial';\n let stopped = false;\n const _state: PointerState = { x: 0, y: 0, active: false };\n\n let rafId = 0;\n let lastClientX = 0;\n let lastClientY = 0;\n let dirty = false;\n\n function setPhase(phase: PointerPhase, reason: PointerReason): void {\n const prev = _phase;\n _phase = phase;\n _reason = reason;\n if (prev !== phase) onPhaseChange?.(phase, reason);\n }\n\n function flush(): void {\n rafId = 0;\n if (!dirty || stopped) return;\n dirty = false;\n const rect = element.getBoundingClientRect();\n _state.x = lastClientX - rect.left;\n _state.y = lastClientY - rect.top;\n onPointer(_state);\n }\n\n function scheduleFlush(): void {\n if (rafId !== 0) return;\n rafId = requestAnimationFrame(flush);\n }\n\n function cancelFlush(): void {\n if (rafId !== 0) {\n cancelAnimationFrame(rafId);\n rafId = 0;\n }\n dirty = false;\n }\n\n function onPointerMove(e: Event): void {\n if (stopped || _phase !== 'tracking') return;\n const pe = e as PointerEvent;\n lastClientX = pe.clientX;\n lastClientY = pe.clientY;\n dirty = true;\n scheduleFlush();\n }\n\n function onPointerEnter(): void {\n if (stopped) return;\n _state.active = true;\n setPhase('tracking', 'enter');\n }\n\n function onPointerLeave(): void {\n if (stopped) return;\n cancelFlush();\n _state.active = false;\n setPhase('idle', 'leave');\n onPointer(_state);\n }\n\n let cleanupVisibility: (() => void) | undefined;\n let listenersAttached = false;\n\n function attachListeners(): void {\n if (listenersAttached) return;\n listenersAttached = true;\n element.addEventListener('pointermove', onPointerMove);\n element.addEventListener('pointerenter', onPointerEnter);\n element.addEventListener('pointerleave', onPointerLeave);\n }\n\n function detachListeners(): void {\n if (!listenersAttached) return;\n listenersAttached = false;\n element.removeEventListener('pointermove', onPointerMove);\n element.removeEventListener('pointerenter', onPointerEnter);\n element.removeEventListener('pointerleave', onPointerLeave);\n }\n\n if (visibility === 'pause') {\n let elementInView = false;\n let documentVisible = !document.hidden;\n\n function recompute(): void {\n if (stopped) return;\n if (documentVisible && elementInView) {\n attachListeners();\n } else {\n detachListeners();\n if (_state.active) {\n cancelFlush();\n _state.active = false;\n setPhase('idle', 'sight');\n }\n }\n }\n\n function onVisChange(): void {\n documentVisible = !document.hidden;\n recompute();\n }\n\n function onPageShow(event: PageTransitionEvent): void {\n if (!event.persisted) return;\n documentVisible = true;\n recompute();\n }\n\n document.addEventListener('visibilitychange', onVisChange);\n window.addEventListener('pageshow', onPageShow);\n\n const unobserveIO = observeIntersection({\n element,\n onIntersect: (entry) => {\n elementInView = entry.isIntersecting;\n recompute();\n },\n ...intersectionOptions,\n });\n\n cleanupVisibility = () => {\n document.removeEventListener('visibilitychange', onVisChange);\n window.removeEventListener('pageshow', onPageShow);\n unobserveIO();\n };\n } else {\n attachListeners();\n }\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n cleanupVisibility?.();\n detachListeners();\n cancelFlush();\n _state.active = false;\n setPhase('stopped', 'disposed');\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n get phase() {\n return _phase;\n },\n get phaseReason() {\n return _reason;\n },\n get state() {\n return _state;\n },\n stop,\n };\n}\n","type ROCallback = (entry: ResizeObserverEntry) => void;\n\nlet observer: ResizeObserver | null = null;\nconst callbacks = new Map<Element, Set<ROCallback>>();\n\n/**\n * Observe an element via a singleton ResizeObserver.\n * One RO instance for the entire page. An element may have any number of\n * subscribers; each receives every entry delivered after it subscribes, and\n * the element stays observed until the last one cleans up.\n *\n * Per-element `box` options are forwarded to `ResizeObserver.observe()`. A\n * single RO holds one observation per target, so when subscribers disagree on\n * `box` the most recent call wins. Every entry carries all box sizes, so a\n * subscriber can still read the box it cares about; only which box change\n * triggers a notification is affected.\n *\n * @returns Cleanup function that removes this subscriber, unobserving the\n * element once none remain.\n */\nexport function observeResize(\n element: Element,\n callback: ROCallback,\n box?: ResizeObserverBoxOptions,\n): () => void {\n let subscribers: Set<ROCallback> | undefined = callbacks.get(element);\n if (!subscribers) {\n subscribers = new Set();\n callbacks.set(element, subscribers);\n }\n subscribers.add(callback);\n getObserver().observe(element, box ? { box } : undefined);\n\n let disposed = false;\n\n return () => {\n if (disposed) return;\n disposed = true;\n\n const current: Set<ROCallback> | undefined = callbacks.get(element);\n if (!current) return;\n\n current.delete(callback);\n if (current.size > 0) return;\n\n callbacks.delete(element);\n observer?.unobserve(element);\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Lazy-created singleton. RO takes zero constructor options, so one instance can observe everything. */\nfunction getObserver(): ResizeObserver {\n if (!observer) {\n observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const subscribers: Set<ROCallback> | undefined = callbacks.get(\n entry.target,\n );\n if (!subscribers) continue;\n // Iterated directly rather than copied: this runs on every resize\n // notification, and Set iteration already tolerates a subscriber\n // removing itself, which is the reentrant case that actually happens.\n for (const cb of subscribers) cb(entry);\n }\n });\n }\n return observer;\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { isDocument } from '../_internal/dom';\nimport { noTargetError, serverContextError } from '../_internal/errors';\nimport { observeIntersection } from '../_internal/pool/io-pool';\nimport { observeResize } from '../_internal/pool/ro-pool';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type ScrollPhase = 'tracking' | 'paused' | 'stopped';\nexport type ScrollReason = 'initial' | 'started' | 'sight' | 'disposed';\n\nexport interface ScrollState {\n /** `scrollLeft`, clamped to `[0, maxX]`. */\n x: number;\n /** `scrollTop`, clamped to `[0, maxY]`. */\n y: number;\n /** Max horizontal scroll distance (`scrollWidth - clientWidth`, never negative). */\n maxX: number;\n /** Max vertical scroll distance (`scrollHeight - clientHeight`, never negative). */\n maxY: number;\n /** Horizontal scroll progress `x / maxX` (0–1). `0` when not scrollable. */\n progressX: number;\n /** Vertical scroll progress `y / maxY` (0–1). `0` when not scrollable. */\n progressY: number;\n /** Visible horizontal fraction `clientWidth / scrollWidth` (0–1). Thumb `scaleX`. */\n visibleX: number;\n /** Visible vertical fraction `clientHeight / scrollHeight` (0–1). Thumb `scaleY`. */\n visibleY: number;\n}\n\n// `ScrollOptions` is a lib.dom global; do not shadow it (see code-style rules).\nexport interface CreateScrollOptions {\n /**\n * Scroll container to track. Pass an `Element` for a scrollable element, or\n * `document` to track the page scroller.\n */\n target: Element | Document;\n /** Called once per rAF frame with the latest scroll position + progress. */\n onScroll: (state: ScrollState) => void;\n /** Called on phase transitions (tracking, paused, stopped). */\n onPhaseChange?: (phase: ScrollPhase, reason: ScrollReason) => void;\n /** Pause when off-screen or ignore visibility. Default `'pause'`. */\n visibility?: 'pause' | 'ignore';\n /** IO options forwarded to the visibility observer. Ignored for `document`. */\n intersectionOptions?: IntersectionObserverInit;\n /** Stops the tracker when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Scroll {\n readonly phase: ScrollPhase;\n readonly phaseReason: ScrollReason;\n readonly state: Readonly<ScrollState>;\n /** Re-read geometry (`scrollWidth`/`clientWidth`) after a content change. */\n measure(): void;\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// createScroll\n// ---------------------------------------------------------------------------\n\n/**\n * Lifecycle-aware scroll tracker. Reads `scrollLeft`/`scrollTop` once per rAF\n * frame and reads the reflow-heavy geometry (`scrollWidth`/`clientWidth`) only\n * on resize or explicit `measure()`, never on the scroll path. Auto-pauses when\n * the element is off-screen.\n *\n * This is to `scroll` + `scrollWidth` what `createPointer` is to `pointermove`\n * + `getBoundingClientRect`: the layout read is batched off the hot path so the\n * per-scroll work is a single cheap position read plus math on cached geometry.\n *\n * Pass `document` to track the page. Offsets and geometry then come from\n * `document.scrollingElement`, and because the page is always in view,\n * `visibility: 'pause'` reacts to tab visibility alone rather than an\n * `IntersectionObserver`.\n */\nexport function createScroll(options: CreateScrollOptions): Scroll {\n if (typeof document === 'undefined') {\n serverContextError('createScroll');\n }\n\n const {\n target,\n onScroll,\n onPhaseChange,\n visibility = 'pause',\n intersectionOptions,\n signal,\n } = options;\n\n if (!target) noTargetError('createScroll');\n\n // Page mode reads offsets and geometry from the scrolling element, while the\n // `scroll` event stays on the Document (where the page fires it). Element mode\n // uses the same node for both.\n let pageDoc: Document | undefined;\n let scroller: Element;\n if (isDocument(target)) {\n pageDoc = target;\n // `scrollingElement` is `body` in quirks mode and absent in some test DOMs.\n scroller = target.scrollingElement ?? target.documentElement;\n } else {\n scroller = target;\n }\n\n let _phase: ScrollPhase = 'paused';\n let _reason: ScrollReason = 'initial';\n let stopped = false;\n const _state: ScrollState = {\n x: 0,\n y: 0,\n maxX: 0,\n maxY: 0,\n progressX: 0,\n progressY: 0,\n visibleX: 1,\n visibleY: 1,\n };\n\n let rafId = 0;\n let dirty = false;\n let geometryDirty = false;\n let listenersAttached = false;\n let unobserveRO: (() => void) | undefined;\n\n function setPhase(phase: ScrollPhase, reason: ScrollReason): void {\n const prev = _phase;\n _phase = phase;\n _reason = reason;\n if (prev !== phase) onPhaseChange?.(phase, reason);\n }\n\n // Reads only scroll offsets (cheap, post-layout) and derives progress from\n // the cached geometry. No `scrollWidth`/`clientWidth` here; that stays on\n // the resize path.\n function computePosition(): void {\n const { maxX, maxY } = _state;\n const x = scroller.scrollLeft;\n const y = scroller.scrollTop;\n _state.x = x < 0 ? 0 : x > maxX ? maxX : x;\n _state.y = y < 0 ? 0 : y > maxY ? maxY : y;\n _state.progressX = maxX > 0 ? _state.x / maxX : 0;\n _state.progressY = maxY > 0 ? _state.y / maxY : 0;\n }\n\n // The one reflow-heavy read. Runs on attach, on a coalesced resize, and on an\n // explicit `measure()`, never per scroll event.\n function readGeometry(): void {\n const scrollWidth = scroller.scrollWidth;\n const clientWidth = scroller.clientWidth;\n const scrollHeight = scroller.scrollHeight;\n const clientHeight = scroller.clientHeight;\n\n const maxX = scrollWidth - clientWidth;\n const maxY = scrollHeight - clientHeight;\n _state.maxX = maxX > 0 ? maxX : 0;\n _state.maxY = maxY > 0 ? maxY : 0;\n _state.visibleX = maxX > 0 ? clientWidth / scrollWidth : 1;\n _state.visibleY = maxY > 0 ? clientHeight / scrollHeight : 1;\n }\n\n // Skipped while paused/off-screen (re-entry re-measures), so this never forces\n // an off-screen reflow.\n function measure(): void {\n if (stopped || !listenersAttached) return;\n geometryDirty = false;\n readGeometry();\n computePosition();\n onScroll(_state);\n }\n\n function flush(): void {\n rafId = 0;\n if (stopped || (!dirty && !geometryDirty)) return;\n if (geometryDirty) {\n geometryDirty = false;\n readGeometry();\n }\n dirty = false;\n computePosition();\n onScroll(_state);\n }\n\n function scheduleFlush(): void {\n if (rafId !== 0) return;\n rafId = requestAnimationFrame(flush);\n }\n\n function cancelFlush(): void {\n if (rafId !== 0) {\n cancelAnimationFrame(rafId);\n rafId = 0;\n }\n dirty = false;\n geometryDirty = false;\n }\n\n function onScrollEvent(): void {\n if (stopped) return;\n dirty = true;\n scheduleFlush();\n }\n\n // Page mode hears one layout change from two sources (the observer and the\n // resize event), and an element can see a burst from the observer alone. Mark\n // the geometry stale and let the frame flush read it once.\n function onROResize(): void {\n if (stopped || !listenersAttached) return;\n geometryDirty = true;\n scheduleFlush();\n }\n\n function attachListeners(): void {\n if (listenersAttached) return;\n listenersAttached = true;\n target.addEventListener('scroll', onScrollEvent, { passive: true });\n unobserveRO = observeResize(scroller, onROResize);\n // A viewport height change (mobile URL bar, window resize) moves `maxY`\n // without resizing the scrolling element's content box, so the observer\n // alone would leave page geometry stale.\n if (pageDoc) window.addEventListener('resize', onROResize);\n measure();\n }\n\n function detachListeners(): void {\n if (!listenersAttached) return;\n listenersAttached = false;\n target.removeEventListener('scroll', onScrollEvent);\n unobserveRO?.();\n unobserveRO = undefined;\n if (pageDoc) window.removeEventListener('resize', onROResize);\n cancelFlush();\n }\n\n let cleanupVisibility: (() => void) | undefined;\n\n if (visibility === 'pause') {\n // The page is always in view, so only tab visibility gates page mode.\n let elementInView = pageDoc !== undefined;\n let documentVisible = !document.hidden;\n\n function recompute(): void {\n if (stopped) return;\n const shouldTrack = documentVisible && elementInView;\n if (shouldTrack && !listenersAttached) {\n setPhase('tracking', 'started');\n attachListeners();\n } else if (!shouldTrack && listenersAttached) {\n detachListeners();\n setPhase('paused', 'sight');\n }\n }\n\n function onVisChange(): void {\n documentVisible = !document.hidden;\n recompute();\n }\n\n function onPageShow(event: PageTransitionEvent): void {\n if (!event.persisted) return;\n documentVisible = true;\n recompute();\n }\n\n document.addEventListener('visibilitychange', onVisChange);\n window.addEventListener('pageshow', onPageShow);\n\n const unobserveIO = pageDoc\n ? undefined\n : observeIntersection({\n element: scroller,\n onIntersect: (entry) => {\n elementInView = entry.isIntersecting;\n recompute();\n },\n ...intersectionOptions,\n });\n\n cleanupVisibility = () => {\n document.removeEventListener('visibilitychange', onVisChange);\n window.removeEventListener('pageshow', onPageShow);\n unobserveIO?.();\n };\n\n // A page attaches immediately, so `onScroll` runs before the caller holds\n // an instance to stop. Release what was attached if it throws.\n try {\n recompute();\n } catch (error) {\n cleanupVisibility();\n detachListeners();\n throw error;\n }\n } else {\n setPhase('tracking', 'started');\n attachListeners();\n }\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n cleanupVisibility?.();\n detachListeners();\n cancelFlush();\n setPhase('stopped', 'disposed');\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n get phase() {\n return _phase;\n },\n get phaseReason() {\n return _reason;\n },\n get state() {\n return _state;\n },\n measure,\n stop,\n };\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { serverContextError } from '../_internal/errors';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type ThrottleEdge = 'leading' | 'trailing' | 'both';\n\nexport interface ThrottleOptions<T = void> {\n /** Called with the latest value passed to `call`. */\n callback: (value: T) => void;\n /**\n * Minimum milliseconds between invocations. Trailing calls fire on the\n * first animation frame at or past the interval, so the effective interval\n * quantizes up to frame boundaries.\n */\n interval: number;\n /** Which edges fire. Default `'both'`. */\n edge?: ThrottleEdge;\n /** Pending-call policy when the document hides. Default `'flush'`. */\n hidden?: 'flush' | 'drop';\n /** Stops the throttle when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Throttle<T = void> {\n /** Record `value` and fire per the edge rules. */\n call(value: T): void;\n /** Invoke a pending trailing call now. No-op when nothing is pending. */\n flush(): void;\n /** Discard a pending trailing call and reset the interval window. */\n cancel(): void;\n /** Whether a trailing call is waiting to fire. */\n readonly pending: boolean;\n /** Terminal. Discards pending work and removes listeners. */\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// createThrottle\n// ---------------------------------------------------------------------------\n\n/**\n * Frame-aligned, visibility-aware throttle. Leading calls fire synchronously;\n * a pending trailing call rides a one-shot rAF chain and fires with the latest\n * value on the first frame at or past `interval`. While the document is hidden\n * nothing is scheduled: a pending call is flushed or dropped per `hidden`, and\n * new calls are recorded but deferred until the document is visible again.\n *\n * @remarks\n * `call` takes exactly one value and stores it by reference, so the hot path\n * never allocates. Trailing calls read the value at fire time.\n */\nexport function createThrottle<T = void>(\n options: ThrottleOptions<T>,\n): Throttle<T> {\n if (typeof document === 'undefined') {\n serverContextError('createThrottle');\n }\n\n const {\n callback,\n interval,\n edge = 'both',\n hidden = 'flush',\n signal,\n } = options;\n const leading: boolean = edge !== 'trailing';\n const trailing: boolean = edge !== 'leading';\n\n let stopped = false;\n let pending = false;\n let lastFire = 0;\n let rafId = 0;\n let documentVisible: boolean = !document.hidden;\n let latest: T = undefined as T;\n\n function fire(now: number): void {\n lastFire = now;\n pending = false;\n callback(latest);\n }\n\n function cancelRaf(): void {\n if (rafId !== 0) {\n cancelAnimationFrame(rafId);\n rafId = 0;\n }\n }\n\n function tick(): void {\n rafId = 0;\n if (stopped || !pending) return;\n const now: number = performance.now();\n if (now - lastFire >= interval) {\n fire(now);\n } else {\n rafId = requestAnimationFrame(tick);\n }\n }\n\n function scheduleRaf(): void {\n if (rafId === 0) rafId = requestAnimationFrame(tick);\n }\n\n function call(value: T): void {\n if (stopped) return;\n latest = value;\n\n // Hidden: record only. Everything defers until the document is visible.\n if (!documentVisible) {\n pending = true;\n return;\n }\n\n const now: number = performance.now();\n if (now - lastFire >= interval) {\n if (leading) {\n fire(now);\n return;\n }\n // Trailing-only: open the window without firing; the trailing call\n // lands at lastFire + interval.\n lastFire = now;\n }\n\n if (trailing) {\n pending = true;\n scheduleRaf();\n }\n }\n\n function flush(): void {\n if (stopped || !pending) return;\n cancelRaf();\n fire(performance.now());\n }\n\n function cancel(): void {\n if (stopped) return;\n cancelRaf();\n pending = false;\n lastFire = 0;\n }\n\n function onVisibilityChange(): void {\n documentVisible = !document.hidden;\n if (stopped) return;\n if (!documentVisible) {\n cancelRaf();\n if (pending) {\n if (hidden === 'flush') fire(performance.now());\n else pending = false;\n }\n } else if (pending) {\n scheduleRaf();\n }\n }\n\n function onPageShow(event: PageTransitionEvent): void {\n if (!event.persisted) return;\n documentVisible = true;\n if (!stopped && pending) scheduleRaf();\n }\n\n document.addEventListener('visibilitychange', onVisibilityChange);\n window.addEventListener('pageshow', onPageShow);\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n document.removeEventListener('visibilitychange', onVisibilityChange);\n window.removeEventListener('pageshow', onPageShow);\n cancelRaf();\n pending = false;\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n call,\n flush,\n cancel,\n get pending() {\n return pending;\n },\n stop,\n };\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { serverContextError } from '../_internal/errors';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface DebounceOptions<T = void> {\n /** Called with the latest value passed to `call`. */\n callback: (value: T) => void;\n /** Quiet period in milliseconds. Each call restarts it. */\n wait: number;\n /** Pending-call policy when the document hides. Default `'flush'`. */\n hidden?: 'flush' | 'drop';\n /** Stops the debounce when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Debounce<T = void> {\n /** Record `value` and restart the quiet timer. */\n call(value: T): void;\n /** Invoke a pending call now. No-op when nothing is pending. */\n flush(): void;\n /** Discard a pending call. */\n cancel(): void;\n /** Whether a call is waiting for the quiet period to elapse. */\n readonly pending: boolean;\n /** Terminal. Discards pending work and removes listeners. */\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// createDebounce\n// ---------------------------------------------------------------------------\n\n/**\n * Visibility-aware trailing debounce. Fires the callback with the latest\n * value once `wait` milliseconds pass without a new call. While the document\n * is hidden no timer runs: a pending call is flushed or dropped per `hidden`,\n * and new calls are recorded but wait until the document is visible again,\n * when the quiet timer restarts.\n */\nexport function createDebounce<T = void>(\n options: DebounceOptions<T>,\n): Debounce<T> {\n if (typeof document === 'undefined') {\n serverContextError('createDebounce');\n }\n\n const { callback, wait, hidden = 'flush', signal } = options;\n\n let stopped = false;\n let pending = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let documentVisible: boolean = !document.hidden;\n let latest: T = undefined as T;\n\n function fire(): void {\n pending = false;\n callback(latest);\n }\n\n function clearTimer(): void {\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n }\n }\n\n function onTimer(): void {\n timer = undefined;\n if (stopped || !pending) return;\n fire();\n }\n\n function startTimer(): void {\n clearTimer();\n timer = setTimeout(onTimer, wait);\n }\n\n function call(value: T): void {\n if (stopped) return;\n latest = value;\n pending = true;\n // Hidden: record only. The quiet timer restarts on visibility.\n if (documentVisible) startTimer();\n }\n\n function flush(): void {\n if (stopped || !pending) return;\n clearTimer();\n fire();\n }\n\n function cancel(): void {\n if (stopped) return;\n clearTimer();\n pending = false;\n }\n\n function onVisibilityChange(): void {\n documentVisible = !document.hidden;\n if (stopped) return;\n if (!documentVisible) {\n clearTimer();\n if (pending) {\n if (hidden === 'flush') fire();\n else pending = false;\n }\n } else if (pending) {\n startTimer();\n }\n }\n\n function onPageShow(event: PageTransitionEvent): void {\n if (!event.persisted) return;\n documentVisible = true;\n if (!stopped && pending) startTimer();\n }\n\n document.addEventListener('visibilitychange', onVisibilityChange);\n window.addEventListener('pageshow', onPageShow);\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n document.removeEventListener('visibilitychange', onVisibilityChange);\n window.removeEventListener('pageshow', onPageShow);\n clearTimer();\n pending = false;\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n call,\n flush,\n cancel,\n get pending() {\n return pending;\n },\n stop,\n };\n}\n"],"mappings":"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"}
@@ -2,9 +2,9 @@
2
2
  interface FrameState {
3
3
  /** Current browser requestAnimationFrame timestamp. */
4
4
  time: number;
5
- /** Milliseconds since last tick, clamped to 40ms. */
5
+ /** Milliseconds to advance this frame. At most 40ms, or one FPS interval plus 40ms. */
6
6
  delta: number;
7
- /** Milliseconds since start, excluding paused time. */
7
+ /** Sum of delivered deltas since start. */
8
8
  elapsed: number;
9
9
  /** Frame count since start. */
10
10
  frame: number;
@@ -38,7 +38,7 @@ interface Ticker {
38
38
  readonly phaseReason: TickerReason;
39
39
  }
40
40
  /**
41
- * Core rAF loop primitive with FPS cap, delta clamping, and strong pause.
41
+ * Low-level requestAnimationFrame loop with an optional FPS limit and pause controls.
42
42
  *
43
43
  * @remarks
44
44
  * `FrameState` is reused across frames. Do not store a reference to it.
@@ -428,4 +428,4 @@ interface Throttle<T = void> {
428
428
  declare function createThrottle<T = void>(options: ThrottleOptions<T>): Throttle<T>;
429
429
  //#endregion
430
430
  export { createTicker as $, Loop as A, LifecycleReason as B, whenIdle as C, createRenderState as D, RenderStateOptions as E, ReducedMotionBehavior as F, SightPhase as G, createLifecycle as H, createLoop as I, FrameState as J, SightReason as K, Lifecycle as L, LoopPhase as M, LoopReason as N, DegradedBehavior as O, Quality as P, TickerReason as Q, LifecycleOptions as R, IdleOptions as S, RenderState as T, Sight as U, LifecycleReducedMotion as V, SightOptions as W, TickerOptions as X, Ticker as Y, TickerPhase as Z, Mutation as _, CreateScrollOptions as a, MutationReason as b, ScrollReason as c, Pointer as d, PointerOptions as f, createPointer as g, PointerState as h, createThrottle as i, LoopOptions as j, DegradedReason as k, ScrollState as l, PointerReason as m, ThrottleEdge as n, Scroll as o, PointerPhase as p, createSight as q, ThrottleOptions as r, ScrollPhase as s, Throttle as t, createScroll as u, MutationOptions as v, RenderPhase as w, createMutation as x, MutationPhase as y, LifecyclePhase as z };
431
- //# sourceMappingURL=index-DE0O-FZ4.d.ts.map
431
+ //# sourceMappingURL=index-_cMMr55u.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-DE0O-FZ4.d.ts","names":[],"sources":["../src/core/tick/index.ts","../src/core/sight/index.ts","../src/core/lifecycle/index.ts","../src/core/loop/index.ts","../src/core/render-state/index.ts","../src/core/idle/index.ts","../src/core/mutation/index.ts","../src/core/pointer/index.ts","../src/core/scroll/index.ts","../src/core/throttle/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index-_cMMr55u.d.ts","names":[],"sources":["../src/core/tick/index.ts","../src/core/sight/index.ts","../src/core/lifecycle/index.ts","../src/core/loop/index.ts","../src/core/render-state/index.ts","../src/core/idle/index.ts","../src/core/mutation/index.ts","../src/core/pointer/index.ts","../src/core/scroll/index.ts","../src/core/throttle/index.ts"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { RemapOptions, clamp, clamp01, easeInOutCubic, easeOutBack, easeOutCubic, easeOutQuart, inverseLerp, lerp, linear, remap } from "./ease.js";
2
- import { $ as createTicker, A as Loop, B as LifecycleReason, C as whenIdle, D as createRenderState, E as RenderStateOptions, F as ReducedMotionBehavior, G as SightPhase, H as createLifecycle, I as createLoop, J as FrameState, K as SightReason, L as Lifecycle, M as LoopPhase, N as LoopReason, O as DegradedBehavior, P as Quality, Q as TickerReason, R as LifecycleOptions, S as IdleOptions, T as RenderState, U as Sight, V as LifecycleReducedMotion, W as SightOptions, X as TickerOptions, Y as Ticker, Z as TickerPhase, _ as Mutation, a as CreateScrollOptions, b as MutationReason, c as ScrollReason, d as Pointer, f as PointerOptions, g as createPointer, h as PointerState, i as createThrottle, j as LoopOptions, k as DegradedReason, l as ScrollState, m as PointerReason, n as ThrottleEdge, o as Scroll, p as PointerPhase, q as createSight, r as ThrottleOptions, s as ScrollPhase, t as Throttle, u as createScroll, v as MutationOptions, w as RenderPhase, x as createMutation, y as MutationPhase, z as LifecyclePhase } from "./index-DE0O-FZ4.js";
2
+ import { $ as createTicker, A as Loop, B as LifecycleReason, C as whenIdle, D as createRenderState, E as RenderStateOptions, F as ReducedMotionBehavior, G as SightPhase, H as createLifecycle, I as createLoop, J as FrameState, K as SightReason, L as Lifecycle, M as LoopPhase, N as LoopReason, O as DegradedBehavior, P as Quality, Q as TickerReason, R as LifecycleOptions, S as IdleOptions, T as RenderState, U as Sight, V as LifecycleReducedMotion, W as SightOptions, X as TickerOptions, Y as Ticker, Z as TickerPhase, _ as Mutation, a as CreateScrollOptions, b as MutationReason, c as ScrollReason, d as Pointer, f as PointerOptions, g as createPointer, h as PointerState, i as createThrottle, j as LoopOptions, k as DegradedReason, l as ScrollState, m as PointerReason, n as ThrottleEdge, o as Scroll, p as PointerPhase, q as createSight, r as ThrottleOptions, s as ScrollPhase, t as Throttle, u as createScroll, v as MutationOptions, w as RenderPhase, x as createMutation, y as MutationPhase, z as LifecyclePhase } from "./index-_cMMr55u.js";
3
3
 
4
4
  //#region src/core/scroll-progress/index.d.ts
5
5
  interface ScrollProgressOptions {
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { clamp, clamp01, easeInOutCubic, easeOutBack, easeOutCubic, easeOutQuart, inverseLerp, lerp, linear, remap } from "./ease.js";
2
- import { C as isPhaseError, E as linkAbortSignal, T as serverContextError, a as createPointer, b as PhaseError, c as prefersReducedMotion, d as subscribeDpr, f as createRenderState, h as createLifecycle, l as whenIdle, m as createLoop, n as createThrottle, o as createMutation, p as createScrollProgress, r as createScroll, t as createDebounce, u as readDpr, v as createSight, y as createTicker } from "./debounce-BkVwTxwI.js";
2
+ import { C as isPhaseError, E as linkAbortSignal, T as serverContextError, a as createPointer, b as PhaseError, c as prefersReducedMotion, d as subscribeDpr, f as createRenderState, h as createLifecycle, l as whenIdle, m as createLoop, n as createThrottle, o as createMutation, p as createScrollProgress, r as createScroll, t as createDebounce, u as readDpr, v as createSight, y as createTicker } from "./debounce-Bh0QOKIX.js";
3
3
  //#region src/core/device-pixel-ratio/index.ts
4
4
  /**
5
5
  * Track devicePixelRatio changes (e.g. user drags the window between monitors
package/dist/react.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { B as LifecycleReason, F as ReducedMotionBehavior, G as SightPhase, J as FrameState, K as SightReason, M as LoopPhase, N as LoopReason, O as DegradedBehavior, P as Quality, S as IdleOptions, V as LifecycleReducedMotion, b as MutationReason, c as ScrollReason, h as PointerState, k as DegradedReason, l as ScrollState, m as PointerReason, n as ThrottleEdge, p as PointerPhase, s as ScrollPhase, w as RenderPhase, y as MutationPhase, z as LifecyclePhase } from "./index-DE0O-FZ4.js";
1
+ import { B as LifecycleReason, F as ReducedMotionBehavior, G as SightPhase, J as FrameState, K as SightReason, M as LoopPhase, N as LoopReason, O as DegradedBehavior, P as Quality, S as IdleOptions, V as LifecycleReducedMotion, b as MutationReason, c as ScrollReason, h as PointerState, k as DegradedReason, l as ScrollState, m as PointerReason, n as ThrottleEdge, p as PointerPhase, s as ScrollPhase, w as RenderPhase, y as MutationPhase, z as LifecyclePhase } from "./index-_cMMr55u.js";
2
2
  import { ComponentProps, ElementType, HTMLAttributes, JSX, ReactNode, Ref, RefObject } from "react";
3
3
 
4
4
  //#region src/react/use-synced-ref/index.d.ts
package/dist/react.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { clamp01, easeOutCubic } from "./ease.js";
3
- import { S as invalidDurationError, _ as subscribeMediaQuery, a as createPointer, c as prefersReducedMotion, d as subscribeDpr, f as createRenderState, g as readMediaQuery, h as createLifecycle, i as observeResize, l as whenIdle, m as createLoop, n as createThrottle, o as createMutation, p as createScrollProgress, r as createScroll, s as REDUCED_MOTION_QUERY, t as createDebounce, u as readDpr, v as createSight, w as missingContextError, x as conflictingTargetError } from "./debounce-BkVwTxwI.js";
3
+ import { S as invalidDurationError, _ as subscribeMediaQuery, a as createPointer, c as prefersReducedMotion, d as subscribeDpr, f as createRenderState, g as readMediaQuery, h as createLifecycle, i as observeResize, l as whenIdle, m as createLoop, n as createThrottle, o as createMutation, p as createScrollProgress, r as createScroll, s as REDUCED_MOTION_QUERY, t as createDebounce, u as readDpr, v as createSight, w as missingContextError, x as conflictingTargetError } from "./debounce-Bh0QOKIX.js";
4
4
  import { createContext, createElement, use, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  //#region src/react/use-synced-ref/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phase",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "description": "A lightweight, lifecycle-aware UI performance layer for the web. Includes tools to optimize render performance, build performant animations, and manage layout and off-screen resources",
5
5
  "author": "Vercel",
6
6
  "license": "MIT",
@@ -1 +0,0 @@
1
- {"version":3,"file":"debounce-BkVwTxwI.js","names":["pool","createPoolEntry","REDUCED_MOTION_QUERY"],"sources":["../src/core/_internal/abort/index.ts","../src/core/_internal/errors/index.ts","../src/core/tick/index.ts","../src/core/_internal/dom/index.ts","../src/core/_internal/pool/io-pool.ts","../src/core/sight/index.ts","../src/core/_internal/pool/mql-pool.ts","../src/core/lifecycle/index.ts","../src/core/loop/index.ts","../src/core/scroll-progress/index.ts","../src/core/render-state/index.ts","../src/core/_internal/pool/dpr.ts","../src/core/idle/index.ts","../src/core/reduced-motion/index.ts","../src/core/mutation/index.ts","../src/core/pointer/index.ts","../src/core/_internal/pool/ro-pool.ts","../src/core/scroll/index.ts","../src/core/throttle/index.ts","../src/core/debounce/index.ts"],"sourcesContent":["/**\n * Link an optional `AbortSignal` to a primitive's `stop`/cancel function.\n *\n * When the signal aborts, `stop` runs once. If the signal is already aborted,\n * `stop` runs synchronously. Returns an unlink function that removes the abort\n * listener. Call it from inside `stop` so a manual stop does not leave a\n * dangling listener on a long-lived controller.\n *\n * The listener is registered with `{ once: true }`, so abort and manual stop\n * are safe to interleave: whichever fires first wins, the other is a no-op.\n */\nexport function linkAbortSignal(\n signal: AbortSignal | undefined,\n stop: () => void,\n): () => void {\n if (!signal) return unlinkNoop;\n if (signal.aborted) {\n stop();\n return unlinkNoop;\n }\n signal.addEventListener('abort', stop, { once: true });\n return () => signal.removeEventListener('abort', stop);\n}\n\n/** Shared empty unlink for the no-signal and already-aborted paths. */\nfunction unlinkNoop(): void {\n // No listener was registered, so there is nothing to remove.\n}\n","export type PhaseErrorCode =\n | 'server_context'\n | 'no_target'\n | 'conflicting_target'\n | 'invalid_duration'\n | 'invalid_fps'\n | 'ticker_stopped'\n | 'missing_context';\n\ninterface PhaseErrorOptions {\n code: PhaseErrorCode;\n reason?: string;\n fix?: string;\n link?: string;\n}\n\n/** Lightweight structured error for phase. */\nexport class PhaseError extends Error {\n readonly code: PhaseErrorCode;\n readonly reason: string | undefined;\n readonly fix: string | undefined;\n readonly link: string | undefined;\n\n constructor(message: string, options: PhaseErrorOptions) {\n super(message);\n this.name = 'PhaseError';\n this.code = options.code;\n this.reason = options.reason;\n this.fix = options.fix;\n this.link = options.link;\n }\n}\n\n/** Check if a value is a PhaseError instance. */\nexport function isPhaseError(error: unknown): error is PhaseError {\n return error instanceof PhaseError;\n}\n\nexport function serverContextError(fn: string): never {\n throw new PhaseError(`${fn}() cannot be called on the server.`, {\n code: 'server_context',\n reason: 'Browser APIs are unavailable during SSR.',\n fix: 'Move into a useEffect or client-only module.',\n });\n}\n\nexport function noTargetError(fn: string): never {\n throw new PhaseError(`${fn}() requires a target.`, {\n code: 'no_target',\n reason: 'The target was null or undefined.',\n fix: 'Pass a mounted Element, or use the React hook which manages the ref.',\n });\n}\n\nexport function conflictingTargetError(fn: string): never {\n throw new PhaseError(`${fn}() received both ref and target.`, {\n code: 'conflicting_target',\n reason: 'A tracker has one anchor.',\n fix: \"Pass one: ref for an element, target: 'page' for the page.\",\n });\n}\n\nexport function invalidDurationError(fn: string, value: number): never {\n throw new PhaseError(`${fn}() received an invalid duration: ${value}`, {\n code: 'invalid_duration',\n reason: 'Duration must be a finite positive number.',\n fix: 'Pass a positive number (e.g., 300 for 300ms).',\n });\n}\n\nexport function invalidFpsError(fn: string, value: number): never {\n throw new PhaseError(`${fn}() received an invalid fps: ${value}`, {\n code: 'invalid_fps',\n reason: 'fps must be a finite number greater than 0.',\n fix: 'Pass a positive number (e.g. 30), or undefined to uncap.',\n });\n}\n\nexport function tickerStoppedError(): never {\n throw new PhaseError('Cannot resume a stopped ticker.', {\n code: 'ticker_stopped',\n reason: 'stop() is terminal, so a stopped ticker cannot be resumed.',\n fix: 'Create a new ticker instance instead of resuming a stopped one.',\n });\n}\n\nexport function missingContextError(child: string, parent: string): never {\n throw new PhaseError(`<${child}> must be used inside <${parent}>.`, {\n code: 'missing_context',\n reason: `<${child}> reads from a context that <${parent}> provides.`,\n fix: `Wrap <${child}> with <${parent}>.`,\n });\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport {\n invalidFpsError,\n serverContextError,\n tickerStoppedError,\n} from '../_internal/errors';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface FrameState {\n /** Current browser requestAnimationFrame timestamp. */\n time: number;\n /** Milliseconds since last tick, clamped to 40ms. */\n delta: number;\n /** Milliseconds since start, excluding paused time. */\n elapsed: number;\n /** Frame count since start. */\n frame: number;\n}\n\nexport type TickerPhase = 'idle' | 'running' | 'paused' | 'stopped';\nexport type TickerReason =\n | 'initial'\n | 'started'\n | 'resumed'\n | 'manual'\n | 'disposed';\n\nexport interface TickerOptions {\n /** Cap frame rate. Default: uncapped (display refresh rate). */\n fps?: number;\n /**\n * Called every frame with the current frame state. Write to refs or DOM\n * directly. Never call React `setState` here (60 state updates/sec = 60 re-renders/sec).\n */\n onTick: (frame: FrameState) => void;\n /** Abort signal that stops the ticker when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Ticker {\n start(): void;\n stop(): void;\n pause(): void;\n resume(): void;\n /**\n * Change the FPS cap. `undefined` removes it. The running timeline is\n * untouched: frame count, elapsed, and pause accounting all continue.\n * Throws on a stopped ticker or an fps that is not a finite number\n * greater than 0, leaving the previous cap in place.\n */\n setFps(fps?: number): void;\n readonly phase: TickerPhase;\n readonly phaseReason: TickerReason;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Prevents teleportation on resume. Matches motion's maxElapsed. */\nconst MAX_DELTA_MS = 40;\n\n/** Default first-frame delta when no previous tick exists. */\nconst DEFAULT_FIRST_DELTA_MS = 16.67;\n\n// ---------------------------------------------------------------------------\n// Shared frame-locked clock\n//\n// All ticker instances subscribe to a single rAF loop so they read the same\n// timestamp each frame. Separately bundled copies in the same JavaScript\n// global share this clock. It starts when the first subscriber joins and stops\n// when the last one leaves.\n// ---------------------------------------------------------------------------\n\ninterface SharedSubscription {\n callback: (time: number) => void;\n joinedFrame: number;\n}\n\ninterface SharedClock {\n rafId: number | null;\n frame: number;\n time: number;\n subscribers: Set<SharedSubscription>;\n}\n\nlet sharedClock: SharedClock;\n\nfunction getSharedClock(): SharedClock {\n const registry = globalThis as unknown as Record<\n symbol,\n SharedClock | undefined\n >;\n return (registry[Symbol.for('phase.clock@1')] ??= {\n rafId: null,\n frame: 0,\n time: 0,\n subscribers: new Set<SharedSubscription>(),\n });\n}\n\nfunction dispatchSharedSubscription(subscription: SharedSubscription): void {\n if (subscription.joinedFrame < sharedClock.frame) {\n subscription.callback(sharedClock.time);\n }\n}\n\nfunction sharedTick(time: number): void {\n sharedClock.time = time;\n sharedClock.frame++;\n sharedClock.rafId = requestAnimationFrame(sharedTick);\n // eslint-disable-next-line unicorn/no-array-for-each -- Set#forEach avoids a per-frame iterator.\n sharedClock.subscribers.forEach(dispatchSharedSubscription);\n}\n\nfunction joinSharedClock(subscription: SharedSubscription): void {\n const wasEmpty: boolean = sharedClock.subscribers.size === 0;\n subscription.joinedFrame = sharedClock.frame;\n sharedClock.subscribers.add(subscription);\n\n if (wasEmpty) {\n sharedClock.rafId = requestAnimationFrame(sharedTick);\n }\n}\n\nfunction leaveSharedClock(subscription: SharedSubscription): void {\n sharedClock.subscribers.delete(subscription);\n if (sharedClock.subscribers.size === 0 && sharedClock.rafId !== null) {\n cancelAnimationFrame(sharedClock.rafId);\n sharedClock.rafId = null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction resetFrameState(state: FrameState): void {\n state.time = 0;\n state.delta = 0;\n state.elapsed = 0;\n state.frame = 0;\n}\n\n/** Validate an FPS cap and convert it to a minimum frame interval (0 = uncapped). */\nfunction resolveMinFrameTime(fn: string, fps: number | undefined): number {\n if (fps === undefined) return 0;\n if (!Number.isFinite(fps) || fps <= 0) invalidFpsError(fn, fps);\n return 1000 / fps;\n}\n\n/**\n * Advance a capped delivery deadline by one interval. Deadlines move in whole\n * intervals from a fixed anchor, so a slightly-late browser frame never pushes\n * later deadlines back (that drift is how a 60fps cap decays to ~30fps).\n */\nfunction advanceDeadline(\n deadline: number,\n now: number,\n interval: number,\n): number {\n const next: number = deadline + interval;\n const behind: number = now - next;\n if (behind < interval) return next;\n // A stall left whole intervals unfilled. Skip them, so delivery resumes at\n // the cap's pace instead of bursting to catch up.\n return next + Math.floor(behind / interval) * interval;\n}\n\n// ---------------------------------------------------------------------------\n// createTicker\n// ---------------------------------------------------------------------------\n\n/**\n * Core rAF loop primitive with FPS cap, delta clamping, and strong pause.\n *\n * @remarks\n * `FrameState` is reused across frames. Do not store a reference to it.\n * Read values immediately in your `onTick` callback.\n */\nexport function createTicker(options: TickerOptions): Ticker {\n if (typeof requestAnimationFrame === 'undefined') {\n serverContextError('createTicker');\n }\n sharedClock ??= getSharedClock();\n\n const { onTick, signal } = options;\n let minFrameTime: number = resolveMinFrameTime('createTicker', options.fps);\n\n let _phase: TickerPhase = 'idle';\n let _reason: TickerReason = 'initial';\n\n let lastTickTime = 0;\n let pauseStartTime = 0;\n let totalPausedTime = 0;\n let startTime = 0;\n\n // When the next capped delivery becomes eligible (see advanceDeadline).\n // 0 while uncapped.\n let nextDueTime = 0;\n\n // Pre-allocated, mutated in place each frame — zero allocations per tick.\n const frame: FrameState = { time: 0, delta: 0, elapsed: 0, frame: 0 };\n\n function tick(now: number): void {\n // FPS throttle: skip this frame if the cap's deadline hasn't arrived.\n if (now < nextDueTime) return;\n\n const isFirstDelivery: boolean = lastTickTime === 0;\n const rawDelta: number = isFirstDelivery\n ? DEFAULT_FIRST_DELTA_MS\n : now - lastTickTime;\n lastTickTime = now;\n\n if (minFrameTime > 0) {\n nextDueTime = isFirstDelivery\n ? now + minFrameTime // the first delivery after (re)start anchors the deadlines\n : advanceDeadline(nextDueTime, now, minFrameTime);\n }\n\n frame.time = now;\n frame.delta = rawDelta > MAX_DELTA_MS ? MAX_DELTA_MS : rawDelta;\n frame.elapsed = now - startTime - totalPausedTime;\n frame.frame++;\n\n onTick(frame);\n }\n\n const subscription: SharedSubscription = { callback: tick, joinedFrame: 0 };\n\n function start(): void {\n if (_phase === 'running') return;\n if (_phase === 'stopped') tickerStoppedError();\n if (_phase === 'paused') {\n resume();\n return;\n }\n\n _phase = 'running';\n _reason = 'started';\n startTime = performance.now();\n lastTickTime = 0;\n nextDueTime = 0;\n totalPausedTime = 0;\n resetFrameState(frame);\n\n joinSharedClock(subscription);\n }\n\n function pause(): void {\n if (_phase !== 'running') return;\n\n _phase = 'paused';\n _reason = 'manual';\n pauseStartTime = performance.now();\n\n // Strong pause: cancel rAF subscription entirely — zero CPU while paused.\n leaveSharedClock(subscription);\n }\n\n function resume(): void {\n if (_phase === 'stopped') tickerStoppedError();\n if (_phase !== 'paused') return;\n\n totalPausedTime += performance.now() - pauseStartTime;\n // Reset so the first resumed tick gets a clean delta (not the pause gap)\n // and delivers immediately, re-anchoring the cadence grid.\n lastTickTime = 0;\n nextDueTime = 0;\n\n _phase = 'running';\n _reason = 'resumed';\n joinSharedClock(subscription);\n }\n\n function setFps(fps?: number): void {\n if (_phase === 'stopped') tickerStoppedError();\n minFrameTime = resolveMinFrameTime('setFps', fps);\n // Base the next deadline on the last delivery: the new cap applies from\n // the next frame, and never sooner than the new interval allows.\n nextDueTime = lastTickTime === 0 ? 0 : lastTickTime + minFrameTime;\n }\n\n function stop(): void {\n if (_phase === 'stopped') return;\n\n _phase = 'stopped';\n _reason = _reason === 'initial' ? 'disposed' : 'manual';\n unlinkAbort?.();\n leaveSharedClock(subscription);\n }\n\n // Declared before assignment because an already-aborted signal makes\n // linkAbortSignal call stop() synchronously, which reads unlinkAbort.\n let unlinkAbort: (() => void) | undefined;\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n start,\n stop,\n pause,\n resume,\n setFps,\n get phase() {\n return _phase;\n },\n get phaseReason() {\n return _reason;\n },\n };\n}\n","const DOCUMENT_NODE = 9;\n\n/**\n * Discriminates a page target from an element target.\n *\n * Uses `nodeType` rather than a property check: `document.scrollingElement` is\n * absent in some test DOMs, so feature detection would silently classify a\n * Document as an Element.\n */\nexport function isDocument(target: Element | Document): target is Document {\n return target.nodeType === DOCUMENT_NODE;\n}\n","type IOCallback = (entry: IntersectionObserverEntry) => void;\n\nexport interface ObserveIntersectionOptions {\n element: Element;\n onIntersect: IOCallback;\n root?: Element | Document | null;\n rootMargin?: string;\n threshold?: number | number[];\n}\n\ninterface IOPoolEntry {\n observer: IntersectionObserver;\n callbacks: Map<Element, Set<IOCallback>>;\n}\n\nconst pool = new Map<string, IOPoolEntry>();\n\n/**\n * Observe an element via a shared IntersectionObserver pool.\n * Elements with identical options share one IO instance. An element may have\n * any number of subscribers; each receives every entry delivered after it\n * subscribes, and the element stays observed until the last one cleans up.\n *\n * A subscriber joining an already-observed element does not get the initial\n * entry: `observe()` is a no-op for a target the observer already holds, so\n * nothing arrives until the next intersection change. Callers that need\n * current state on subscribe have to read it themselves.\n *\n * @returns Cleanup function that removes this subscriber, unobserving the\n * element once none remain and dropping the IO once it observes nothing.\n */\nexport function observeIntersection(\n options: ObserveIntersectionOptions,\n): () => void {\n const { element, onIntersect, root, rootMargin, threshold } = options;\n const ioInit: IntersectionObserverInit = { root, rootMargin, threshold };\n\n const key: string = getPoolKey(ioInit);\n const entry: IOPoolEntry = getOrCreatePoolEntry(key, ioInit);\n\n let subscribers: Set<IOCallback> | undefined = entry.callbacks.get(element);\n if (!subscribers) {\n subscribers = new Set();\n entry.callbacks.set(element, subscribers);\n }\n subscribers.add(onIntersect);\n entry.observer.observe(element);\n\n let disposed = false;\n\n return () => {\n if (disposed) return;\n disposed = true;\n\n const poolEntry: IOPoolEntry | undefined = pool.get(key);\n if (!poolEntry) return;\n\n // Unobserve once this element has no subscribers left; other subscribers\n // on the same element must keep receiving entries.\n const current: Set<IOCallback> | undefined =\n poolEntry.callbacks.get(element);\n if (current) {\n current.delete(onIntersect);\n if (current.size === 0) {\n poolEntry.observer.unobserve(element);\n poolEntry.callbacks.delete(element);\n }\n }\n\n if (poolEntry.callbacks.size === 0) {\n poolEntry.observer.disconnect();\n pool.delete(key);\n }\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Produces a stable string key from IO options to group observers in the pool.\n * IO options are immutable after construction, so identical options can share.\n */\nfunction getPoolKey(opts: IntersectionObserverInit): string {\n const root = opts.root ? 'custom' : 'null';\n const margin = opts.rootMargin ?? '0px';\n const threshold = Array.isArray(opts.threshold)\n ? opts.threshold.join(',')\n : String(opts.threshold ?? 0);\n\n return `${root}|${margin}|${threshold}`;\n}\n\n/** Return an existing pool entry for this key, or create and register a new one. */\nfunction getOrCreatePoolEntry(\n key: string,\n options: IntersectionObserverInit,\n): IOPoolEntry {\n const existing: IOPoolEntry | undefined = pool.get(key);\n if (existing) return existing;\n\n const entry = createPoolEntry(options);\n\n pool.set(key, entry);\n return entry;\n}\n\n/** Create a new pool entry for the given options. */\nconst createPoolEntry = (options: IntersectionObserverInit): IOPoolEntry => {\n const callbacks = new Map<Element, Set<IOCallback>>();\n const observer = new IntersectionObserver((entries) => {\n for (const ioEntry of entries) {\n const subscribers: Set<IOCallback> | undefined = callbacks.get(\n ioEntry.target,\n );\n if (!subscribers) continue;\n // Iterated directly rather than copied: Set iteration already tolerates\n // a subscriber removing itself, which is the reentrant case that happens.\n for (const cb of subscribers) cb(ioEntry);\n }\n }, options);\n\n return { observer, callbacks };\n};\n","import { linkAbortSignal } from '../_internal/abort';\nimport { isDocument } from '../_internal/dom';\nimport { noTargetError, serverContextError } from '../_internal/errors';\nimport { observeIntersection } from '../_internal/pool/io-pool';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type SightPhase = 'unknown' | 'visible' | 'hidden';\nexport type SightReason =\n | 'initial'\n | 'viewport'\n | 'document'\n | 'bfcache'\n | 'all-hidden';\n\nexport interface SightOptions {\n /**\n * Element to observe, or `document` to track the page. A page is never\n * off-screen, so a Document target reports document visibility alone.\n */\n target: Element | Document;\n /** Forwarded to the pooled observer. Ignored for `document`. */\n intersectionOptions?: IntersectionObserverInit;\n onPhaseChange?: (phase: SightPhase, reason: SightReason) => void;\n /** Abort signal that stops the observer when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Sight {\n readonly phase: SightPhase;\n readonly phaseReason: SightReason;\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// createSight\n// ---------------------------------------------------------------------------\n\n/**\n * Visibility observer combining document focus and viewport intersection.\n *\n * `phase` is `'visible'` only when both the document is visible (not backgrounded)\n * and the element is within the viewport. Uses a shared IntersectionObserver\n * pool. Multiple `createSight` calls with the same options share one observer.\n *\n * Pass `document` to anchor to the page instead. There is no viewport test to\n * make, so no observer is created and `phase` follows document visibility.\n *\n * @example\n * const sight = createSight({\n * target: el,\n * onPhaseChange: (phase) => phase === 'visible' ? loop.start() : loop.pause(),\n * });\n * // cleanup:\n * sight.stop();\n *\n * @remarks\n * `onPhaseChange` fires only on phase transitions, not on every IntersectionObserver callback.\n */\nexport function createSight(options: SightOptions): Sight {\n if (typeof document === 'undefined') {\n serverContextError('createSight');\n }\n\n const { target, intersectionOptions, onPhaseChange, signal } = options;\n\n if (!target) noTargetError('createSight');\n\n let _phase: SightPhase = 'unknown';\n let _reason: SightReason = 'initial';\n let stopped = false;\n\n const isPage = isDocument(target);\n\n let documentVisible: boolean = !document.hidden;\n let elementInView = isPage;\n\n function recompute(trigger: SightReason): void {\n if (stopped) return;\n\n const prev = _phase;\n const next: SightPhase =\n documentVisible && elementInView ? 'visible' : 'hidden';\n\n _reason =\n next === 'hidden' && !documentVisible && !elementInView\n ? 'all-hidden'\n : trigger;\n\n if (next === prev) return;\n _phase = next;\n onPhaseChange?.(_phase, _reason);\n }\n\n // --- Signal handlers ---\n\n function onVisibilityChange(): void {\n documentVisible = !document.hidden;\n recompute('document');\n }\n\n function onPageShow(event: PageTransitionEvent): void {\n if (!event.persisted) return;\n documentVisible = true;\n recompute('bfcache');\n }\n\n function onIntersection(entry: IntersectionObserverEntry): void {\n elementInView = entry.isIntersecting;\n recompute('viewport');\n }\n\n // --- Subscribe ---\n\n document.addEventListener('visibilitychange', onVisibilityChange);\n window.addEventListener('pageshow', onPageShow);\n\n let unobserveIO: (() => void) | undefined;\n if (isPage) {\n // An element target gets its first phase from the observer's initial\n // callback. A page has no observer, so report the starting phase here or\n // consumers would wait on a transition that never comes.\n //\n // This is the only path where a consumer callback runs before the caller\n // holds an instance to stop, so a throw here has to release the listeners\n // itself or they outlive the failed construction.\n try {\n recompute('initial');\n } catch (error) {\n document.removeEventListener('visibilitychange', onVisibilityChange);\n window.removeEventListener('pageshow', onPageShow);\n throw error;\n }\n } else {\n unobserveIO = observeIntersection({\n element: target,\n onIntersect: onIntersection,\n ...intersectionOptions,\n });\n }\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n document.removeEventListener('visibilitychange', onVisibilityChange);\n window.removeEventListener('pageshow', onPageShow);\n unobserveIO?.();\n _phase = 'hidden';\n _reason = 'initial';\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n get phase() {\n return stopped ? 'hidden' : _phase;\n },\n get phaseReason() {\n return _reason;\n },\n stop,\n };\n}\n","type MQLCallback = (matches: boolean) => void;\n\ninterface MQLPoolEntry {\n mql: MediaQueryList;\n listeners: Set<MQLCallback>;\n handler: (e: MediaQueryListEvent) => void;\n}\n\nconst pool = new Map<string, MQLPoolEntry>();\n\n/**\n * Subscribe to a media query via a shared MediaQueryList pool.\n * Multiple subscribers to the same query share one MQL and one change listener.\n *\n * @returns Cleanup function that removes the subscriber.\n */\nexport function subscribeMediaQuery(\n query: string,\n callback: MQLCallback,\n): () => void {\n const entry: MQLPoolEntry = getOrCreateEntry(query);\n\n entry.listeners.add(callback);\n\n let disposed = false;\n\n return () => {\n if (disposed) return;\n disposed = true;\n\n const poolEntry: MQLPoolEntry | undefined = pool.get(query);\n if (!poolEntry) return;\n poolEntry.listeners.delete(callback);\n\n if (poolEntry.listeners.size === 0) {\n poolEntry.mql.removeEventListener('change', poolEntry.handler);\n pool.delete(query);\n }\n };\n}\n\n/**\n * Synchronous read of a media query via the shared pool.\n * Uses the existing pool entry if available, otherwise reads directly.\n */\nexport function readMediaQuery(query: string): boolean {\n const entry: MQLPoolEntry | undefined = pool.get(query);\n if (entry) return entry.mql.matches;\n return matchMedia(query).matches;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Return an existing pool entry for this query, or create and register a new one. */\nfunction getOrCreateEntry(query: string): MQLPoolEntry {\n const existing: MQLPoolEntry | undefined = pool.get(query);\n if (existing) return existing;\n\n const entry = createPoolEntry(query);\n\n entry.mql.addEventListener('change', entry.handler);\n pool.set(query, entry);\n\n return entry;\n}\n\nconst createPoolEntry = (query: string): MQLPoolEntry => {\n const mql: MediaQueryList = matchMedia(query);\n const listeners = new Set<MQLCallback>();\n\n const handler = (event: MediaQueryListEvent): void => {\n for (const cb of listeners) cb(event.matches);\n };\n return { mql, listeners, handler };\n};\n","import { linkAbortSignal } from '../_internal/abort';\nimport { noTargetError, serverContextError } from '../_internal/errors';\nimport {\n readMediaQuery,\n subscribeMediaQuery,\n} from '../_internal/pool/mql-pool';\nimport { createSight } from '../sight';\nimport type { SightPhase } from '../sight';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type LifecyclePhase = 'idle' | 'active' | 'paused' | 'stopped';\nexport type LifecycleReason =\n | 'initial'\n | 'started'\n | 'resumed'\n | 'sight'\n | 'reduced-motion'\n | 'manual'\n | 'disposed';\n\n/** Whether reduced motion pauses the lifecycle. Default `'pause'`. */\nexport type LifecycleReducedMotion = 'pause' | 'ignore';\n\nexport interface LifecycleOptions {\n /** Element to observe, or `document` to anchor to the page. */\n target: Element | Document;\n reducedMotion?: LifecycleReducedMotion;\n intersectionOptions?: IntersectionObserverInit;\n start?: 'auto' | 'manual';\n onPhaseChange?: (phase: LifecyclePhase, reason: LifecycleReason) => void;\n /** Abort signal that stops the lifecycle when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Lifecycle {\n /** Begin honoring signals. Called automatically unless `start: 'manual'`. */\n start(): void;\n /** Terminal. Disposes observers and listeners. Cannot be restarted. */\n stop(): void;\n /** Manually pause (e.g. a panel opened over the animation). Lowest priority. */\n pause(): void;\n /** Clear a manual pause. */\n resume(): void;\n readonly phase: LifecyclePhase;\n readonly phaseReason: LifecycleReason;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst REDUCED_MOTION_QUERY = '(prefers-reduced-motion: reduce)';\n\n// ---------------------------------------------------------------------------\n// createLifecycle\n// ---------------------------------------------------------------------------\n\n/**\n * The activation decision for an animation, decoupled from who drives the frames.\n *\n * Composes visibility (`createSight`), reduced motion, and a manual pause into a\n * single `active` / `paused` phase. Use when you own your render loop (WebGL,\n * three.js, a Web Worker, or non-rAF work that should still pause off-screen or\n * under reduced motion). For loops `phase` should drive, use `createLoop` instead.\n *\n * @example\n * const lifecycle = createLifecycle({\n * target: canvas,\n * onPhaseChange: (phase) => {\n * if (phase === 'active') renderer.start();\n * else renderer.stop();\n * },\n * });\n * // cleanup:\n * lifecycle.stop();\n */\nexport function createLifecycle(options: LifecycleOptions): Lifecycle {\n if (typeof document === 'undefined') {\n serverContextError('createLifecycle');\n }\n\n const {\n target,\n reducedMotion = 'pause',\n intersectionOptions,\n start: startMode = 'auto',\n onPhaseChange,\n signal,\n } = options;\n\n if (!target) noTargetError('createLifecycle');\n\n let _phase: LifecyclePhase = 'idle';\n let _reason: LifecycleReason = 'initial';\n\n let sightVisible = false;\n let reducedMotionActive = false;\n let manualPaused = false;\n let intentStarted = false;\n let hasBeenActive = false;\n\n function setPhase(phase: LifecyclePhase, reason: LifecycleReason): void {\n if (_phase === phase && _reason === reason) return;\n _phase = phase;\n _reason = reason;\n onPhaseChange?.(phase, reason);\n }\n\n /** Highest-priority active pause signal, or null when nothing should pause. */\n function pauseReason(): LifecycleReason | null {\n if (reducedMotionActive && reducedMotion === 'pause')\n return 'reduced-motion';\n if (!sightVisible) return 'sight';\n if (manualPaused) return 'manual';\n return null;\n }\n\n function reconcile(): void {\n if (_phase === 'stopped' || !intentStarted) return;\n\n const reason = pauseReason();\n if (reason) {\n setPhase('paused', reason);\n return;\n }\n\n setPhase('active', hasBeenActive ? 'resumed' : 'started');\n hasBeenActive = true;\n }\n\n // --- Signal handlers ---\n\n function onSightChange(phase: SightPhase): void {\n sightVisible = phase === 'visible';\n reconcile();\n }\n\n function onReducedMotionChange(matches: boolean): void {\n reducedMotionActive = matches;\n reconcile();\n }\n\n // --- Init subsystems ---\n\n const sight = createSight({\n target,\n intersectionOptions,\n onPhaseChange: onSightChange,\n });\n\n let unsubReducedMotion: (() => void) | null = null;\n if (reducedMotion !== 'ignore') {\n reducedMotionActive = readMediaQuery(REDUCED_MOTION_QUERY);\n unsubReducedMotion = subscribeMediaQuery(\n REDUCED_MOTION_QUERY,\n onReducedMotionChange,\n );\n }\n\n // --- Public API ---\n\n function start(): void {\n if (_phase === 'stopped') return;\n intentStarted = true;\n reconcile();\n }\n\n function stop(): void {\n if (_phase === 'stopped') return;\n unlinkAbort?.();\n sight.stop();\n unsubReducedMotion?.();\n unsubReducedMotion = null;\n setPhase('stopped', 'disposed');\n }\n\n function pause(): void {\n if (manualPaused) return;\n manualPaused = true;\n reconcile();\n }\n\n function resume(): void {\n if (!manualPaused) return;\n manualPaused = false;\n reconcile();\n }\n\n let unlinkAbort: (() => void) | undefined;\n unlinkAbort = linkAbortSignal(signal, stop);\n\n if (startMode === 'auto') {\n start();\n }\n\n return {\n start,\n stop,\n pause,\n resume,\n get phase() {\n return _phase;\n },\n get phaseReason() {\n return _reason;\n },\n };\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport {\n invalidFpsError,\n noTargetError,\n serverContextError,\n} from '../_internal/errors';\nimport { createLifecycle } from '../lifecycle';\nimport { createTicker } from '../tick';\nimport type { FrameState, Ticker } from '../tick';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ReducedMotionBehavior = 'pause' | 'complete' | 'ignore';\nexport type DegradedBehavior = 'throttle' | 'pause' | 'ignore';\n\nexport type LoopPhase = 'idle' | 'running' | 'paused' | 'stopped';\nexport type LoopReason =\n | 'initial'\n | 'started'\n | 'resumed'\n | 'sight'\n | 'reduced-motion'\n | 'degraded'\n | 'manual'\n | 'disposed';\n\nexport type Quality = 'full' | 'degraded';\nexport type DegradedReason = 'unfocused' | 'frame-budget';\n\ninterface LoopOptionsBase {\n /** Element to observe, or `document` to anchor the loop to the page. */\n target: Element | Document;\n /**\n * Called every frame. Write to refs or DOM directly. Never call React\n * `setState` here (60 calls/sec = 60 re-renders/sec).\n */\n onTick: (frame: FrameState) => void;\n fps?: number;\n reducedMotion?: ReducedMotionBehavior;\n intersectionOptions?: IntersectionObserverInit;\n start?: 'auto' | 'manual';\n onPhaseChange?: (phase: LoopPhase, reason: LoopReason) => void;\n /** Abort signal that stops the loop when aborted. */\n signal?: AbortSignal;\n}\n\ntype DegradedOptions =\n | { degraded?: 'throttle'; degradedFps?: number }\n | { degraded: 'pause' }\n | { degraded: 'ignore' };\n\nexport type LoopOptions = LoopOptionsBase & DegradedOptions;\n\nexport interface Loop {\n start(): void;\n stop(): void;\n readonly phase: LoopPhase;\n readonly phaseReason: LoopReason;\n readonly quality: Quality;\n readonly qualityReason: DegradedReason | undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** How many consecutive over-budget frames before degrading quality. */\nconst OVER_BUDGET_THRESHOLD = 3;\n\n/** FPS cap applied when quality is degraded (throttle mode). */\nconst DEGRADED_FPS_CAP = 30;\n\n/**\n * In `degraded: 'pause'` mode a frame-budget degrade pauses the loop, so no\n * further frames tick to clear it. Without a timer the loop would stay paused\n * forever after a transient spike. After this delay the loop optimistically\n * un-pauses and re-measures, rescheduling on each subsequent degrade. (Throttle\n * mode keeps ticking, so it does not use this.)\n */\nconst RECOVERY_RETRY_MS = 2000;\n\n// ---------------------------------------------------------------------------\n// createLoop\n// ---------------------------------------------------------------------------\n\n/**\n * Lifecycle-aware animation loop composing ticker, visibility, and reduced motion.\n *\n * Pass an element and get a loop that pauses when the element leaves the viewport\n * or the tab is backgrounded, resumes when it returns, and cleans up with `stop()`.\n *\n * @remarks\n * The loop is signal-driven and exposes only `start()` and `stop()`. There is no\n * imperative `pause()`/`resume()`. Pausing is decided by visibility, reduced\n * motion, and quality, so an imperative pause would compete with those signals.\n * For manual control, use `useLoop`'s `enabled` option (React) or `createLifecycle`,\n * which exposes `pause()`/`resume()` for loops you drive yourself.\n *\n * @example\n * const loop = createLoop({\n * target: el,\n * onTick: (frame) => draw(ctx, frame),\n * });\n * // cleanup:\n * loop.stop();\n */\nexport function createLoop(options: LoopOptions): Loop {\n if (typeof requestAnimationFrame === 'undefined') {\n serverContextError('createLoop');\n }\n\n const {\n target,\n onTick,\n fps: baseFps,\n reducedMotion = 'pause',\n degraded = 'throttle' as DegradedBehavior,\n degradedFps: configuredDegradedFps,\n intersectionOptions,\n start: startMode = 'auto',\n onPhaseChange,\n signal,\n } = options as LoopOptionsBase & {\n degraded?: DegradedBehavior;\n degradedFps?: number;\n signal?: AbortSignal;\n };\n\n if (!target) noTargetError('createLoop');\n validateFps(baseFps);\n validateFps(configuredDegradedFps);\n\n const degradedFps: number | undefined =\n degraded === 'throttle' ? configuredDegradedFps : undefined;\n\n // --- State ---\n\n let _phase: LoopPhase = 'idle';\n let _reason: LoopReason = 'initial';\n let _quality: Quality = 'full';\n let _qualityReason: DegradedReason | undefined;\n\n let intentStarted = false;\n let overBudgetCount = 0;\n let ticker: Ticker | null = null;\n\n // Frame-budget threshold for the current effective FPS. Mutable so the\n // once-created ticker callback always compares frame time against the\n // current cap.\n let frameBudget = 1000 / 60;\n\n // Quality signal flags\n let focusDegraded = false;\n\n // Pending pause-mode frame-budget recovery timer (see RECOVERY_RETRY_MS).\n let recoveryTimer: ReturnType<typeof setTimeout> | null = null;\n\n // --- State transitions ---\n\n function setPhase(phase: LoopPhase, reason: LoopReason): void {\n if (_phase === phase && _reason === reason) return;\n _phase = phase;\n _reason = reason;\n onPhaseChange?.(phase, reason);\n }\n\n function setQuality(quality: Quality, reason?: DegradedReason): void {\n const changed = _quality !== quality;\n _quality = quality;\n _qualityReason = reason;\n\n if (!changed) return;\n\n if (degraded === 'throttle') {\n if (_phase !== 'stopped') applyFpsPolicy();\n } else if (degraded === 'pause') {\n reconcile();\n }\n }\n\n /** Evaluate all quality signals and pick the highest-priority active one. */\n function reconcileQuality(): void {\n if (focusDegraded) {\n setQuality('degraded', 'unfocused');\n return;\n }\n if (overBudgetCount >= OVER_BUDGET_THRESHOLD) {\n setQuality('degraded', 'frame-budget');\n return;\n }\n setQuality('full');\n }\n\n /**\n * Un-pause and re-measure after a pause-mode frame-budget degrade. If frames\n * are still over budget, the next degrade reschedules this.\n */\n function scheduleBudgetRecovery(): void {\n // A consumer callback may stop the loop between the degrade and this\n // call; never arm a timer on a stopped loop.\n if (_phase === 'stopped' || recoveryTimer !== null) return;\n recoveryTimer = setTimeout(() => {\n recoveryTimer = null;\n overBudgetCount = 0;\n reconcileQuality();\n }, RECOVERY_RETRY_MS);\n }\n\n function clearBudgetRecovery(): void {\n if (recoveryTimer === null) return;\n clearTimeout(recoveryTimer);\n recoveryTimer = null;\n }\n\n // --- Ticker lifecycle ---\n\n function getEffectiveFps(): number | undefined {\n if (_quality !== 'degraded') return baseFps;\n const cap: number = degradedFps ?? DEGRADED_FPS_CAP;\n if (baseFps === undefined) return cap;\n return Math.min(baseFps, cap);\n }\n\n /**\n * Derive effective FPS and its frame budget together, then apply the cap to\n * the live ticker. The frame count, elapsed time, and frame object are\n * untouched; only the delivery rate changes.\n */\n function applyFpsPolicy(): number | undefined {\n const targetFps: number | undefined = getEffectiveFps();\n frameBudget = 1000 / (targetFps ?? 60);\n ticker?.setFps(targetFps);\n return targetFps;\n }\n\n // Created once and reused for the loop's lifetime (stable reference).\n function loopTick(frame: FrameState): void {\n checkFrameBudget(frame.delta);\n onTick(frame);\n }\n\n /** Lazily create the loop's single ticker. Never replaced before stop(). */\n function ensureTicker(): void {\n if (ticker) return;\n ticker = createTicker({ fps: applyFpsPolicy(), onTick: loopTick });\n ticker.start();\n }\n\n function checkFrameBudget(delta: number): void {\n if (delta <= frameBudget * 1.5) {\n overBudgetCount = 0;\n return;\n }\n\n overBudgetCount++;\n if (overBudgetCount < OVER_BUDGET_THRESHOLD) return;\n\n reconcileQuality();\n // Pause mode stops ticking once degraded, so no future frame can clear the\n // degraded state — schedule a timed retry. Throttle keeps running.\n if (degraded === 'pause') scheduleBudgetRecovery();\n }\n\n // --- Reconcile ---\n\n /** Check if any signal requires the loop to be paused. */\n function shouldPause(): LoopReason | null {\n // Visibility + reduced motion are owned by the lifecycle; its paused reasons\n // ('sight' | 'reduced-motion') are a subset of LoopReason.\n if (lifecycle.phase === 'paused')\n return lifecycle.phaseReason as LoopReason;\n // Quality-driven pause stays here — it needs the ticker's frame timing.\n if (degraded === 'pause' && _quality === 'degraded') return 'degraded';\n return null;\n }\n\n /** Evaluate all signals and transition to the correct phase. */\n function reconcile(): void {\n if (_phase === 'stopped' || !intentStarted) return;\n\n const pauseReason = shouldPause();\n\n if (pauseReason) {\n if (ticker && _phase === 'running') ticker.pause();\n setPhase('paused', pauseReason);\n return;\n }\n\n if (!ticker) {\n ensureTicker();\n setPhase('running', _reason === 'initial' ? 'started' : 'resumed');\n } else if (_phase === 'paused') {\n ticker.resume();\n setPhase('running', 'resumed');\n }\n }\n\n // --- Signal handlers ---\n\n function onFocusChange(): void {\n focusDegraded = !document.hasFocus();\n reconcileQuality();\n }\n\n // --- Init subsystems ---\n\n // Lifecycle owns the visibility + reduced-motion decision. The loop layers the\n // ticker and quality (frame-budget / focus) on top. Driven manually so it only\n // activates once the loop itself starts.\n const lifecycle = createLifecycle({\n target,\n reducedMotion: reducedMotion === 'pause' ? 'pause' : 'ignore',\n intersectionOptions,\n start: 'manual',\n onPhaseChange: reconcile,\n });\n\n const unsubFocus: () => void = subscribeFocusTracking(onFocusChange);\n\n // --- Public API ---\n\n function start(): void {\n if (_phase === 'stopped') return;\n intentStarted = true;\n lifecycle.start();\n reconcile();\n }\n\n function stop(): void {\n if (_phase === 'stopped') return;\n unlinkAbort?.();\n clearBudgetRecovery();\n // Enter the terminal phase before teardown: lifecycle.stop() fires\n // onPhaseChange -> reconcile() synchronously, and reconcile must see\n // 'stopped' so it cannot resume or recreate the ticker mid-stop. The\n // consumer is notified last, after teardown has finished, so a throwing\n // callback cannot leave the loop half-disposed.\n _phase = 'stopped';\n _reason = 'disposed';\n ticker?.stop();\n lifecycle.stop();\n unsubFocus();\n onPhaseChange?.('stopped', 'disposed');\n }\n\n // Declared before assignment because an already-aborted signal makes\n // linkAbortSignal call stop() synchronously, which reads unlinkAbort.\n let unlinkAbort: (() => void) | undefined;\n unlinkAbort = linkAbortSignal(signal, stop);\n\n if (startMode === 'auto') {\n start();\n }\n\n return {\n start,\n stop,\n get phase() {\n return _phase;\n },\n get phaseReason() {\n return _reason;\n },\n get quality() {\n return _quality;\n },\n get qualityReason() {\n return _qualityReason;\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Throws `invalid_fps` for a defined fps that is not a positive finite number. */\nfunction validateFps(fps: number | undefined): void {\n if (fps !== undefined && (!Number.isFinite(fps) || fps <= 0)) {\n invalidFpsError('createLoop', fps);\n }\n}\n\nfunction subscribeFocusTracking(onChange: () => void): () => void {\n window.addEventListener('focus', onChange);\n window.addEventListener('blur', onChange);\n return () => {\n window.removeEventListener('focus', onChange);\n window.removeEventListener('blur', onChange);\n };\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { noTargetError, serverContextError } from '../_internal/errors';\nimport { observeIntersection } from '../_internal/pool/io-pool';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ScrollProgressOptions {\n target: Element;\n /** Called when the intersection ratio changes at a threshold crossing. */\n onProgress: (ratio: number) => void;\n /** Number of evenly-spaced thresholds. Default 20 (~5% granularity). */\n steps?: number;\n root?: Element | Document | null;\n rootMargin?: string;\n /** Abort signal that stops the observer when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface ScrollProgress {\n /** Current intersection ratio (0–1). Synchronous read of the last-reported value. */\n readonly ratio: number;\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_STEPS = 20;\n\n// ---------------------------------------------------------------------------\n// Threshold cache\n//\n// Most consumers use the same step count. Cache the array so the IO pool\n// receives stable references and identical pool keys without re-allocating.\n// ---------------------------------------------------------------------------\n\nconst thresholdCache = new Map<number, number[]>();\n\nfunction buildThresholds(steps: number): number[] {\n const cached: number[] | undefined = thresholdCache.get(steps);\n if (cached) return cached;\n\n const thresholds: number[] = [];\n for (let i = 0; i <= steps; i++) {\n thresholds.push(i / steps);\n }\n thresholdCache.set(steps, thresholds);\n return thresholds;\n}\n\n// ---------------------------------------------------------------------------\n// createScrollProgress\n// ---------------------------------------------------------------------------\n\n/**\n * Observe what fraction of an element is visible in the viewport (0–1).\n *\n * Uses the shared IntersectionObserver pool with multi-threshold options.\n * Multiple instances with the same `steps` share a single IO.\n *\n * @example\n * const progress = createScrollProgress({\n * target: el,\n * onProgress: (ratio) => {\n * el.style.opacity = String(ratio);\n * },\n * });\n * // cleanup:\n * progress.stop();\n */\nexport function createScrollProgress(\n options: ScrollProgressOptions,\n): ScrollProgress {\n if (typeof IntersectionObserver === 'undefined') {\n serverContextError('createScrollProgress');\n }\n\n const {\n target: element,\n onProgress,\n steps = DEFAULT_STEPS,\n root,\n rootMargin,\n signal,\n } = options;\n\n if (!element) noTargetError('createScrollProgress');\n\n let _ratio = 0;\n let stopped = false;\n\n const threshold: number[] = buildThresholds(steps);\n\n const unobserve: () => void = observeIntersection({\n element,\n onIntersect: (entry: IntersectionObserverEntry) => {\n const newRatio: number = entry.intersectionRatio;\n if (newRatio === _ratio) return;\n _ratio = newRatio;\n onProgress(newRatio);\n },\n root,\n rootMargin,\n threshold,\n });\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n unobserve();\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n get ratio(): number {\n return _ratio;\n },\n stop,\n };\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { noTargetError, serverContextError } from '../_internal/errors';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type RenderPhase = 'rendered' | 'skipped';\n\nexport interface RenderStateOptions {\n target: Element;\n onPhaseChange?: (phase: RenderPhase) => void;\n /** Abort signal that stops the observer when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface RenderState {\n /** Whether the browser is currently rendering the element or skipping it. */\n readonly phase: RenderPhase;\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// createRenderState\n// ---------------------------------------------------------------------------\n\n/**\n * Report whether the browser is rendering an element or skipping it under\n * `content-visibility`. Listens to the `contentvisibilityautostatechange`\n * event, the browser's ground-truth paint decision.\n *\n * Use it to pause raw, non-phase work (a hand-written rAF loop, `setInterval`,\n * expensive effects) when a `Defer` subtree stops painting. phase's own loops\n * already self-pause off-screen, so they do not need this.\n *\n * Listening and reacting has zero layout effect. It never breaks the\n * no-layout-shift guarantee of `content-visibility`.\n *\n * @example\n * const render = createRenderState({\n * target: el,\n * onPhaseChange: (phase) => phase === 'skipped' ? clock.pause() : clock.resume(),\n * });\n * // cleanup:\n * render.stop();\n *\n * @remarks\n * Where `content-visibility` is unsupported, `phase` stays `'rendered'`.\n *\n * Per the CSS Containment spec, `ResizeObserver` callbacks pause for elements\n * inside a skipped `content-visibility: auto` subtree. Use this primitive to\n * detect that transition when your code depends on size observations resuming.\n */\nexport function createRenderState(options: RenderStateOptions): RenderState {\n if (typeof document === 'undefined') {\n serverContextError('createRenderState');\n }\n\n const { target: element, onPhaseChange, signal } = options;\n\n if (!element) noTargetError('createRenderState');\n\n let _phase: RenderPhase = 'rendered';\n let stopped = false;\n\n function onStateChange(event: Event): void {\n if (stopped) return;\n const next: RenderPhase = (event as ContentVisibilityAutoStateChangeEvent)\n .skipped\n ? 'skipped'\n : 'rendered';\n if (next === _phase) return;\n _phase = next;\n onPhaseChange?.(_phase);\n }\n\n element.addEventListener('contentvisibilityautostatechange', onStateChange);\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n element.removeEventListener(\n 'contentvisibilityautostatechange',\n onStateChange,\n );\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n get phase() {\n return _phase;\n },\n stop,\n };\n}\n","type DprCallback = (dpr: number) => void;\n\nconst listeners = new Set<DprCallback>();\n\n// Last-bound DPR. Set by bind() before the MQL is created; only meaningful\n// while a subscription is active.\nlet currentDpr = 1;\n\nlet mql: MediaQueryList | null = null;\nlet handler: (() => void) | null = null;\n\n/**\n * Subscribe to devicePixelRatio changes (e.g. user drags window between monitors).\n *\n * Uses a single shared `matchMedia` query that re-subscribes on every DPR change,\n * so chained monitor switches (A -> B -> C) are all caught.\n *\n * @returns Cleanup function that removes the subscriber.\n */\nexport function subscribeDpr(callback: DprCallback): () => void {\n listeners.add(callback);\n\n if (listeners.size === 1) {\n bind();\n }\n\n let disposed = false;\n return () => {\n if (disposed) return;\n disposed = true;\n listeners.delete(callback);\n if (listeners.size === 0) {\n unbind();\n }\n };\n}\n\n/** Read the current devicePixelRatio. */\nexport function readDpr(): number {\n if (typeof window === 'undefined') return 1;\n return window.devicePixelRatio || 1;\n}\n\n// ---------------------------------------------------------------------------\n// Internal: bind/unbind the resolution MQL\n// ---------------------------------------------------------------------------\n\nfunction bind(): void {\n if (typeof matchMedia === 'undefined') return;\n currentDpr = window.devicePixelRatio || 1;\n mql = matchMedia(`(resolution: ${currentDpr}dppx)`);\n handler = onDprChange;\n mql.addEventListener('change', handler);\n}\n\nfunction unbind(): void {\n if (mql && handler) {\n mql.removeEventListener('change', handler);\n }\n mql = null;\n handler = null;\n}\n\nfunction onDprChange(): void {\n const newDpr: number = window.devicePixelRatio || 1;\n if (newDpr === currentDpr) return;\n currentDpr = newDpr;\n\n // Re-subscribe with the new DPR value so the next change is caught.\n unbind();\n bind();\n\n for (const cb of listeners) cb(newDpr);\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { serverContextError } from '../_internal/errors';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface IdleOptions {\n /** Max ms to wait before running the callback even if no idle period occurs. */\n timeout?: number;\n /** Abort signal that cancels the scheduled callback when aborted. */\n signal?: AbortSignal;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Fallback delay when `requestIdleCallback` is unavailable (e.g. Safari). */\nconst FALLBACK_DELAY = 1;\n\n// ---------------------------------------------------------------------------\n// whenIdle\n// ---------------------------------------------------------------------------\n\n/**\n * Run a callback once the browser is idle. Wraps `requestIdleCallback`, falling\n * back to a near-immediate `setTimeout` where it is unavailable (Safari).\n *\n * Returns a cancel function. Calling it before the callback runs prevents it.\n *\n * @example\n * const cancel = whenIdle(() => warmCache(), { timeout: 2000 });\n * // later, if no longer needed:\n * cancel();\n */\nexport function whenIdle(\n callback: () => void,\n options?: IdleOptions,\n): () => void {\n if (typeof window === 'undefined') {\n serverContextError('whenIdle');\n }\n\n const { timeout, signal } = options ?? {};\n\n // Already aborted: never schedule, and hand back a no-op cancel.\n if (signal?.aborted) {\n return () => {\n // Nothing was scheduled, so there is nothing to cancel.\n };\n }\n\n let cancel: () => void;\n\n if (typeof window.requestIdleCallback === 'function') {\n // Capture cancelIdleCallback now (bound to window), rather than reading\n // window.cancelIdleCallback inside the returned closure. The cancel may run\n // after the global is swapped out (e.g. test teardown unstubbing globals),\n // and a late lookup would throw \"not a function\". Binding also avoids an\n // illegal-invocation error from calling it detached from window.\n const cancelIdle = window.cancelIdleCallback.bind(window);\n const handle: number = window.requestIdleCallback(\n () => callback(),\n timeout === undefined ? undefined : { timeout },\n );\n cancel = () => cancelIdle(handle);\n } else {\n const handle: ReturnType<typeof setTimeout> = setTimeout(\n callback,\n FALLBACK_DELAY,\n );\n cancel = () => clearTimeout(handle);\n }\n\n const unlinkAbort: () => void = linkAbortSignal(signal, cancel);\n\n return () => {\n unlinkAbort();\n cancel();\n };\n}\n","import { readMediaQuery } from '../_internal/pool/mql-pool';\n\nexport const REDUCED_MOTION_QUERY = '(prefers-reduced-motion: reduce)';\n\n/**\n * Synchronous check for `prefers-reduced-motion: reduce`.\n *\n * Returns `false` on the server (no `matchMedia`). On the client, reads from\n * the shared MQL pool so the underlying `MediaQueryList` is reused across\n * all callers.\n */\nexport function prefersReducedMotion(): boolean {\n if (typeof matchMedia === 'undefined') return false;\n return readMediaQuery(REDUCED_MOTION_QUERY);\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { noTargetError, serverContextError } from '../_internal/errors';\nimport { observeIntersection } from '../_internal/pool/io-pool';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type MutationPhase = 'observing' | 'paused' | 'stopped';\nexport type MutationReason = 'initial' | 'started' | 'sight' | 'disposed';\n\nexport interface MutationOptions {\n target: Element;\n /** Standard MutationObserver configuration. */\n mutation: MutationObserverInit;\n /** Called once per rAF frame with coalesced records. Never per-record. */\n onMutations: (records: MutationRecord[]) => void;\n /** Called on phase transitions (observing, paused, stopped). */\n onPhaseChange?: (phase: MutationPhase, reason: MutationReason) => void;\n /** Pause when off-screen or ignore visibility. Default `'pause'`. */\n visibility?: 'pause' | 'ignore';\n /** IO options forwarded to the visibility observer. */\n intersectionOptions?: IntersectionObserverInit;\n /** Stops the observer when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Mutation {\n readonly phase: MutationPhase;\n readonly phaseReason: MutationReason;\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// createMutation\n// ---------------------------------------------------------------------------\n\n/** Lifecycle-aware MutationObserver with rAF-coalesced callbacks. */\nexport function createMutation(options: MutationOptions): Mutation {\n if (typeof document === 'undefined') {\n serverContextError('createMutation');\n }\n\n const {\n target: element,\n mutation: mutationInit,\n onMutations,\n onPhaseChange,\n visibility = 'pause',\n intersectionOptions,\n signal,\n } = options;\n\n if (!element) noTargetError('createMutation');\n\n warnReflowStorm(mutationInit);\n\n let _phase: MutationPhase = 'paused';\n let _reason: MutationReason = 'initial';\n let stopped = false;\n let pendingRecords: MutationRecord[] = [];\n let rafId = 0;\n\n function setPhase(phase: MutationPhase, reason: MutationReason): void {\n const prev = _phase;\n _phase = phase;\n _reason = reason;\n if (prev !== phase) onPhaseChange?.(phase, reason);\n }\n\n function flushRecords(): void {\n rafId = 0;\n if (stopped || pendingRecords.length === 0) return;\n const batch = pendingRecords;\n pendingRecords = [];\n onMutations(batch);\n }\n\n function scheduleFlush(): void {\n if (rafId !== 0) return;\n rafId = requestAnimationFrame(flushRecords);\n }\n\n const mo = new MutationObserver((records) => {\n if (stopped || _phase !== 'observing') return;\n for (let i = 0, len = records.length; i < len; i++) {\n pendingRecords[pendingRecords.length] = records[i] as MutationRecord;\n }\n scheduleFlush();\n });\n\n function startObserving(): void {\n if (stopped || _phase === 'observing') return;\n setPhase('observing', 'started');\n mo.observe(element, mutationInit);\n }\n\n function pauseObserving(reason: MutationReason): void {\n if (stopped || _phase === 'paused') return;\n setPhase('paused', reason);\n mo.disconnect();\n if (rafId !== 0) {\n cancelAnimationFrame(rafId);\n rafId = 0;\n }\n pendingRecords = [];\n }\n\n let cleanupVisibility: (() => void) | undefined;\n\n if (visibility === 'pause') {\n let elementInView = false;\n let documentVisible = !document.hidden;\n\n function recompute(): void {\n if (stopped) return;\n if (documentVisible && elementInView) startObserving();\n else pauseObserving('sight');\n }\n\n function onVisibilityChange(): void {\n documentVisible = !document.hidden;\n recompute();\n }\n\n function onPageShow(event: PageTransitionEvent): void {\n if (!event.persisted) return;\n documentVisible = true;\n recompute();\n }\n\n document.addEventListener('visibilitychange', onVisibilityChange);\n window.addEventListener('pageshow', onPageShow);\n\n const unobserveIO = observeIntersection({\n element,\n onIntersect: (entry) => {\n elementInView = entry.isIntersecting;\n recompute();\n },\n ...intersectionOptions,\n });\n\n cleanupVisibility = () => {\n document.removeEventListener('visibilitychange', onVisibilityChange);\n window.removeEventListener('pageshow', onPageShow);\n unobserveIO();\n };\n } else {\n startObserving();\n }\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n cleanupVisibility?.();\n mo.disconnect();\n if (rafId !== 0) {\n cancelAnimationFrame(rafId);\n rafId = 0;\n }\n pendingRecords = [];\n setPhase('stopped', 'disposed');\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n get phase() {\n return _phase;\n },\n get phaseReason() {\n return _reason;\n },\n stop,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nconst REFLOW_STORM_ATTRIBUTES = new Set(['style', 'class']);\n\nfunction warnReflowStorm(opts: MutationObserverInit): void {\n if (process.env.NODE_ENV === 'production') return;\n if (!opts.subtree) return;\n const filter = opts.attributeFilter;\n if (!filter) return;\n if (!filter.some((attr) => REFLOW_STORM_ATTRIBUTES.has(attr))) return;\n\n console.warn(\n '[phase] createMutation: observing subtree + attributeFilter including ' +\n '\"style\" or \"class\" fires on every descendant style/class change ' +\n '(animations, hovers, framework churn). Narrow the scope or use a ' +\n 'visibility signal instead.',\n );\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { noTargetError, serverContextError } from '../_internal/errors';\nimport { observeIntersection } from '../_internal/pool/io-pool';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type PointerPhase = 'idle' | 'tracking' | 'stopped';\nexport type PointerReason =\n | 'initial'\n | 'enter'\n | 'leave'\n | 'sight'\n | 'disposed';\n\nexport interface PointerState {\n /** X position relative to the element's top-left, in CSS pixels. */\n x: number;\n /** Y position relative to the element's top-left, in CSS pixels. */\n y: number;\n /** Whether a pointer is currently over the element. */\n active: boolean;\n}\n\nexport interface PointerOptions {\n target: Element;\n /** Called once per rAF frame with the latest pointer position. */\n onPointer: (state: PointerState) => void;\n /** Called on phase transitions (idle, tracking, stopped). */\n onPhaseChange?: (phase: PointerPhase, reason: PointerReason) => void;\n /** Pause when off-screen or ignore visibility. Default `'pause'`. */\n visibility?: 'pause' | 'ignore';\n /** IO options forwarded to the visibility observer. */\n intersectionOptions?: IntersectionObserverInit;\n /** Stops the tracker when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Pointer {\n readonly phase: PointerPhase;\n readonly phaseReason: PointerReason;\n readonly state: Readonly<PointerState>;\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// createPointer\n// ---------------------------------------------------------------------------\n\n/** Lifecycle-aware pointer tracker with rAF-batched `getBoundingClientRect`. */\nexport function createPointer(options: PointerOptions): Pointer {\n if (typeof document === 'undefined') {\n serverContextError('createPointer');\n }\n\n const {\n target: element,\n onPointer,\n onPhaseChange,\n visibility = 'pause',\n intersectionOptions,\n signal,\n } = options;\n\n if (!element) noTargetError('createPointer');\n\n let _phase: PointerPhase = 'idle';\n let _reason: PointerReason = 'initial';\n let stopped = false;\n const _state: PointerState = { x: 0, y: 0, active: false };\n\n let rafId = 0;\n let lastClientX = 0;\n let lastClientY = 0;\n let dirty = false;\n\n function setPhase(phase: PointerPhase, reason: PointerReason): void {\n const prev = _phase;\n _phase = phase;\n _reason = reason;\n if (prev !== phase) onPhaseChange?.(phase, reason);\n }\n\n function flush(): void {\n rafId = 0;\n if (!dirty || stopped) return;\n dirty = false;\n const rect = element.getBoundingClientRect();\n _state.x = lastClientX - rect.left;\n _state.y = lastClientY - rect.top;\n onPointer(_state);\n }\n\n function scheduleFlush(): void {\n if (rafId !== 0) return;\n rafId = requestAnimationFrame(flush);\n }\n\n function cancelFlush(): void {\n if (rafId !== 0) {\n cancelAnimationFrame(rafId);\n rafId = 0;\n }\n dirty = false;\n }\n\n function onPointerMove(e: Event): void {\n if (stopped || _phase !== 'tracking') return;\n const pe = e as PointerEvent;\n lastClientX = pe.clientX;\n lastClientY = pe.clientY;\n dirty = true;\n scheduleFlush();\n }\n\n function onPointerEnter(): void {\n if (stopped) return;\n _state.active = true;\n setPhase('tracking', 'enter');\n }\n\n function onPointerLeave(): void {\n if (stopped) return;\n cancelFlush();\n _state.active = false;\n setPhase('idle', 'leave');\n onPointer(_state);\n }\n\n let cleanupVisibility: (() => void) | undefined;\n let listenersAttached = false;\n\n function attachListeners(): void {\n if (listenersAttached) return;\n listenersAttached = true;\n element.addEventListener('pointermove', onPointerMove);\n element.addEventListener('pointerenter', onPointerEnter);\n element.addEventListener('pointerleave', onPointerLeave);\n }\n\n function detachListeners(): void {\n if (!listenersAttached) return;\n listenersAttached = false;\n element.removeEventListener('pointermove', onPointerMove);\n element.removeEventListener('pointerenter', onPointerEnter);\n element.removeEventListener('pointerleave', onPointerLeave);\n }\n\n if (visibility === 'pause') {\n let elementInView = false;\n let documentVisible = !document.hidden;\n\n function recompute(): void {\n if (stopped) return;\n if (documentVisible && elementInView) {\n attachListeners();\n } else {\n detachListeners();\n if (_state.active) {\n cancelFlush();\n _state.active = false;\n setPhase('idle', 'sight');\n }\n }\n }\n\n function onVisChange(): void {\n documentVisible = !document.hidden;\n recompute();\n }\n\n function onPageShow(event: PageTransitionEvent): void {\n if (!event.persisted) return;\n documentVisible = true;\n recompute();\n }\n\n document.addEventListener('visibilitychange', onVisChange);\n window.addEventListener('pageshow', onPageShow);\n\n const unobserveIO = observeIntersection({\n element,\n onIntersect: (entry) => {\n elementInView = entry.isIntersecting;\n recompute();\n },\n ...intersectionOptions,\n });\n\n cleanupVisibility = () => {\n document.removeEventListener('visibilitychange', onVisChange);\n window.removeEventListener('pageshow', onPageShow);\n unobserveIO();\n };\n } else {\n attachListeners();\n }\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n cleanupVisibility?.();\n detachListeners();\n cancelFlush();\n _state.active = false;\n setPhase('stopped', 'disposed');\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n get phase() {\n return _phase;\n },\n get phaseReason() {\n return _reason;\n },\n get state() {\n return _state;\n },\n stop,\n };\n}\n","type ROCallback = (entry: ResizeObserverEntry) => void;\n\nlet observer: ResizeObserver | null = null;\nconst callbacks = new Map<Element, Set<ROCallback>>();\n\n/**\n * Observe an element via a singleton ResizeObserver.\n * One RO instance for the entire page. An element may have any number of\n * subscribers; each receives every entry delivered after it subscribes, and\n * the element stays observed until the last one cleans up.\n *\n * Per-element `box` options are forwarded to `ResizeObserver.observe()`. A\n * single RO holds one observation per target, so when subscribers disagree on\n * `box` the most recent call wins. Every entry carries all box sizes, so a\n * subscriber can still read the box it cares about; only which box change\n * triggers a notification is affected.\n *\n * @returns Cleanup function that removes this subscriber, unobserving the\n * element once none remain.\n */\nexport function observeResize(\n element: Element,\n callback: ROCallback,\n box?: ResizeObserverBoxOptions,\n): () => void {\n let subscribers: Set<ROCallback> | undefined = callbacks.get(element);\n if (!subscribers) {\n subscribers = new Set();\n callbacks.set(element, subscribers);\n }\n subscribers.add(callback);\n getObserver().observe(element, box ? { box } : undefined);\n\n let disposed = false;\n\n return () => {\n if (disposed) return;\n disposed = true;\n\n const current: Set<ROCallback> | undefined = callbacks.get(element);\n if (!current) return;\n\n current.delete(callback);\n if (current.size > 0) return;\n\n callbacks.delete(element);\n observer?.unobserve(element);\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Lazy-created singleton. RO takes zero constructor options, so one instance can observe everything. */\nfunction getObserver(): ResizeObserver {\n if (!observer) {\n observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const subscribers: Set<ROCallback> | undefined = callbacks.get(\n entry.target,\n );\n if (!subscribers) continue;\n // Iterated directly rather than copied: this runs on every resize\n // notification, and Set iteration already tolerates a subscriber\n // removing itself, which is the reentrant case that actually happens.\n for (const cb of subscribers) cb(entry);\n }\n });\n }\n return observer;\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { isDocument } from '../_internal/dom';\nimport { noTargetError, serverContextError } from '../_internal/errors';\nimport { observeIntersection } from '../_internal/pool/io-pool';\nimport { observeResize } from '../_internal/pool/ro-pool';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type ScrollPhase = 'tracking' | 'paused' | 'stopped';\nexport type ScrollReason = 'initial' | 'started' | 'sight' | 'disposed';\n\nexport interface ScrollState {\n /** `scrollLeft`, clamped to `[0, maxX]`. */\n x: number;\n /** `scrollTop`, clamped to `[0, maxY]`. */\n y: number;\n /** Max horizontal scroll distance (`scrollWidth - clientWidth`, never negative). */\n maxX: number;\n /** Max vertical scroll distance (`scrollHeight - clientHeight`, never negative). */\n maxY: number;\n /** Horizontal scroll progress `x / maxX` (0–1). `0` when not scrollable. */\n progressX: number;\n /** Vertical scroll progress `y / maxY` (0–1). `0` when not scrollable. */\n progressY: number;\n /** Visible horizontal fraction `clientWidth / scrollWidth` (0–1). Thumb `scaleX`. */\n visibleX: number;\n /** Visible vertical fraction `clientHeight / scrollHeight` (0–1). Thumb `scaleY`. */\n visibleY: number;\n}\n\n// `ScrollOptions` is a lib.dom global; do not shadow it (see code-style rules).\nexport interface CreateScrollOptions {\n /**\n * Scroll container to track. Pass an `Element` for a scrollable element, or\n * `document` to track the page scroller.\n */\n target: Element | Document;\n /** Called once per rAF frame with the latest scroll position + progress. */\n onScroll: (state: ScrollState) => void;\n /** Called on phase transitions (tracking, paused, stopped). */\n onPhaseChange?: (phase: ScrollPhase, reason: ScrollReason) => void;\n /** Pause when off-screen or ignore visibility. Default `'pause'`. */\n visibility?: 'pause' | 'ignore';\n /** IO options forwarded to the visibility observer. Ignored for `document`. */\n intersectionOptions?: IntersectionObserverInit;\n /** Stops the tracker when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Scroll {\n readonly phase: ScrollPhase;\n readonly phaseReason: ScrollReason;\n readonly state: Readonly<ScrollState>;\n /** Re-read geometry (`scrollWidth`/`clientWidth`) after a content change. */\n measure(): void;\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// createScroll\n// ---------------------------------------------------------------------------\n\n/**\n * Lifecycle-aware scroll tracker. Reads `scrollLeft`/`scrollTop` once per rAF\n * frame and reads the reflow-heavy geometry (`scrollWidth`/`clientWidth`) only\n * on resize or explicit `measure()`, never on the scroll path. Auto-pauses when\n * the element is off-screen.\n *\n * This is to `scroll` + `scrollWidth` what `createPointer` is to `pointermove`\n * + `getBoundingClientRect`: the layout read is batched off the hot path so the\n * per-scroll work is a single cheap position read plus math on cached geometry.\n *\n * Pass `document` to track the page. Offsets and geometry then come from\n * `document.scrollingElement`, and because the page is always in view,\n * `visibility: 'pause'` reacts to tab visibility alone rather than an\n * `IntersectionObserver`.\n */\nexport function createScroll(options: CreateScrollOptions): Scroll {\n if (typeof document === 'undefined') {\n serverContextError('createScroll');\n }\n\n const {\n target,\n onScroll,\n onPhaseChange,\n visibility = 'pause',\n intersectionOptions,\n signal,\n } = options;\n\n if (!target) noTargetError('createScroll');\n\n // Page mode reads offsets and geometry from the scrolling element, while the\n // `scroll` event stays on the Document (where the page fires it). Element mode\n // uses the same node for both.\n let pageDoc: Document | undefined;\n let scroller: Element;\n if (isDocument(target)) {\n pageDoc = target;\n // `scrollingElement` is `body` in quirks mode and absent in some test DOMs.\n scroller = target.scrollingElement ?? target.documentElement;\n } else {\n scroller = target;\n }\n\n let _phase: ScrollPhase = 'paused';\n let _reason: ScrollReason = 'initial';\n let stopped = false;\n const _state: ScrollState = {\n x: 0,\n y: 0,\n maxX: 0,\n maxY: 0,\n progressX: 0,\n progressY: 0,\n visibleX: 1,\n visibleY: 1,\n };\n\n let rafId = 0;\n let dirty = false;\n let geometryDirty = false;\n let listenersAttached = false;\n let unobserveRO: (() => void) | undefined;\n\n function setPhase(phase: ScrollPhase, reason: ScrollReason): void {\n const prev = _phase;\n _phase = phase;\n _reason = reason;\n if (prev !== phase) onPhaseChange?.(phase, reason);\n }\n\n // Reads only scroll offsets (cheap, post-layout) and derives progress from\n // the cached geometry. No `scrollWidth`/`clientWidth` here; that stays on\n // the resize path.\n function computePosition(): void {\n const { maxX, maxY } = _state;\n const x = scroller.scrollLeft;\n const y = scroller.scrollTop;\n _state.x = x < 0 ? 0 : x > maxX ? maxX : x;\n _state.y = y < 0 ? 0 : y > maxY ? maxY : y;\n _state.progressX = maxX > 0 ? _state.x / maxX : 0;\n _state.progressY = maxY > 0 ? _state.y / maxY : 0;\n }\n\n // The one reflow-heavy read. Runs on attach, on a coalesced resize, and on an\n // explicit `measure()`, never per scroll event.\n function readGeometry(): void {\n const scrollWidth = scroller.scrollWidth;\n const clientWidth = scroller.clientWidth;\n const scrollHeight = scroller.scrollHeight;\n const clientHeight = scroller.clientHeight;\n\n const maxX = scrollWidth - clientWidth;\n const maxY = scrollHeight - clientHeight;\n _state.maxX = maxX > 0 ? maxX : 0;\n _state.maxY = maxY > 0 ? maxY : 0;\n _state.visibleX = maxX > 0 ? clientWidth / scrollWidth : 1;\n _state.visibleY = maxY > 0 ? clientHeight / scrollHeight : 1;\n }\n\n // Skipped while paused/off-screen (re-entry re-measures), so this never forces\n // an off-screen reflow.\n function measure(): void {\n if (stopped || !listenersAttached) return;\n geometryDirty = false;\n readGeometry();\n computePosition();\n onScroll(_state);\n }\n\n function flush(): void {\n rafId = 0;\n if (stopped || (!dirty && !geometryDirty)) return;\n if (geometryDirty) {\n geometryDirty = false;\n readGeometry();\n }\n dirty = false;\n computePosition();\n onScroll(_state);\n }\n\n function scheduleFlush(): void {\n if (rafId !== 0) return;\n rafId = requestAnimationFrame(flush);\n }\n\n function cancelFlush(): void {\n if (rafId !== 0) {\n cancelAnimationFrame(rafId);\n rafId = 0;\n }\n dirty = false;\n geometryDirty = false;\n }\n\n function onScrollEvent(): void {\n if (stopped) return;\n dirty = true;\n scheduleFlush();\n }\n\n // Page mode hears one layout change from two sources (the observer and the\n // resize event), and an element can see a burst from the observer alone. Mark\n // the geometry stale and let the frame flush read it once.\n function onROResize(): void {\n if (stopped || !listenersAttached) return;\n geometryDirty = true;\n scheduleFlush();\n }\n\n function attachListeners(): void {\n if (listenersAttached) return;\n listenersAttached = true;\n target.addEventListener('scroll', onScrollEvent, { passive: true });\n unobserveRO = observeResize(scroller, onROResize);\n // A viewport height change (mobile URL bar, window resize) moves `maxY`\n // without resizing the scrolling element's content box, so the observer\n // alone would leave page geometry stale.\n if (pageDoc) window.addEventListener('resize', onROResize);\n measure();\n }\n\n function detachListeners(): void {\n if (!listenersAttached) return;\n listenersAttached = false;\n target.removeEventListener('scroll', onScrollEvent);\n unobserveRO?.();\n unobserveRO = undefined;\n if (pageDoc) window.removeEventListener('resize', onROResize);\n cancelFlush();\n }\n\n let cleanupVisibility: (() => void) | undefined;\n\n if (visibility === 'pause') {\n // The page is always in view, so only tab visibility gates page mode.\n let elementInView = pageDoc !== undefined;\n let documentVisible = !document.hidden;\n\n function recompute(): void {\n if (stopped) return;\n const shouldTrack = documentVisible && elementInView;\n if (shouldTrack && !listenersAttached) {\n setPhase('tracking', 'started');\n attachListeners();\n } else if (!shouldTrack && listenersAttached) {\n detachListeners();\n setPhase('paused', 'sight');\n }\n }\n\n function onVisChange(): void {\n documentVisible = !document.hidden;\n recompute();\n }\n\n function onPageShow(event: PageTransitionEvent): void {\n if (!event.persisted) return;\n documentVisible = true;\n recompute();\n }\n\n document.addEventListener('visibilitychange', onVisChange);\n window.addEventListener('pageshow', onPageShow);\n\n const unobserveIO = pageDoc\n ? undefined\n : observeIntersection({\n element: scroller,\n onIntersect: (entry) => {\n elementInView = entry.isIntersecting;\n recompute();\n },\n ...intersectionOptions,\n });\n\n cleanupVisibility = () => {\n document.removeEventListener('visibilitychange', onVisChange);\n window.removeEventListener('pageshow', onPageShow);\n unobserveIO?.();\n };\n\n // A page attaches immediately, so `onScroll` runs before the caller holds\n // an instance to stop. Release what was attached if it throws.\n try {\n recompute();\n } catch (error) {\n cleanupVisibility();\n detachListeners();\n throw error;\n }\n } else {\n setPhase('tracking', 'started');\n attachListeners();\n }\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n cleanupVisibility?.();\n detachListeners();\n cancelFlush();\n setPhase('stopped', 'disposed');\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n get phase() {\n return _phase;\n },\n get phaseReason() {\n return _reason;\n },\n get state() {\n return _state;\n },\n measure,\n stop,\n };\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { serverContextError } from '../_internal/errors';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type ThrottleEdge = 'leading' | 'trailing' | 'both';\n\nexport interface ThrottleOptions<T = void> {\n /** Called with the latest value passed to `call`. */\n callback: (value: T) => void;\n /**\n * Minimum milliseconds between invocations. Trailing calls fire on the\n * first animation frame at or past the interval, so the effective interval\n * quantizes up to frame boundaries.\n */\n interval: number;\n /** Which edges fire. Default `'both'`. */\n edge?: ThrottleEdge;\n /** Pending-call policy when the document hides. Default `'flush'`. */\n hidden?: 'flush' | 'drop';\n /** Stops the throttle when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Throttle<T = void> {\n /** Record `value` and fire per the edge rules. */\n call(value: T): void;\n /** Invoke a pending trailing call now. No-op when nothing is pending. */\n flush(): void;\n /** Discard a pending trailing call and reset the interval window. */\n cancel(): void;\n /** Whether a trailing call is waiting to fire. */\n readonly pending: boolean;\n /** Terminal. Discards pending work and removes listeners. */\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// createThrottle\n// ---------------------------------------------------------------------------\n\n/**\n * Frame-aligned, visibility-aware throttle. Leading calls fire synchronously;\n * a pending trailing call rides a one-shot rAF chain and fires with the latest\n * value on the first frame at or past `interval`. While the document is hidden\n * nothing is scheduled: a pending call is flushed or dropped per `hidden`, and\n * new calls are recorded but deferred until the document is visible again.\n *\n * @remarks\n * `call` takes exactly one value and stores it by reference, so the hot path\n * never allocates. Trailing calls read the value at fire time.\n */\nexport function createThrottle<T = void>(\n options: ThrottleOptions<T>,\n): Throttle<T> {\n if (typeof document === 'undefined') {\n serverContextError('createThrottle');\n }\n\n const {\n callback,\n interval,\n edge = 'both',\n hidden = 'flush',\n signal,\n } = options;\n const leading: boolean = edge !== 'trailing';\n const trailing: boolean = edge !== 'leading';\n\n let stopped = false;\n let pending = false;\n let lastFire = 0;\n let rafId = 0;\n let documentVisible: boolean = !document.hidden;\n let latest: T = undefined as T;\n\n function fire(now: number): void {\n lastFire = now;\n pending = false;\n callback(latest);\n }\n\n function cancelRaf(): void {\n if (rafId !== 0) {\n cancelAnimationFrame(rafId);\n rafId = 0;\n }\n }\n\n function tick(): void {\n rafId = 0;\n if (stopped || !pending) return;\n const now: number = performance.now();\n if (now - lastFire >= interval) {\n fire(now);\n } else {\n rafId = requestAnimationFrame(tick);\n }\n }\n\n function scheduleRaf(): void {\n if (rafId === 0) rafId = requestAnimationFrame(tick);\n }\n\n function call(value: T): void {\n if (stopped) return;\n latest = value;\n\n // Hidden: record only. Everything defers until the document is visible.\n if (!documentVisible) {\n pending = true;\n return;\n }\n\n const now: number = performance.now();\n if (now - lastFire >= interval) {\n if (leading) {\n fire(now);\n return;\n }\n // Trailing-only: open the window without firing; the trailing call\n // lands at lastFire + interval.\n lastFire = now;\n }\n\n if (trailing) {\n pending = true;\n scheduleRaf();\n }\n }\n\n function flush(): void {\n if (stopped || !pending) return;\n cancelRaf();\n fire(performance.now());\n }\n\n function cancel(): void {\n if (stopped) return;\n cancelRaf();\n pending = false;\n lastFire = 0;\n }\n\n function onVisibilityChange(): void {\n documentVisible = !document.hidden;\n if (stopped) return;\n if (!documentVisible) {\n cancelRaf();\n if (pending) {\n if (hidden === 'flush') fire(performance.now());\n else pending = false;\n }\n } else if (pending) {\n scheduleRaf();\n }\n }\n\n function onPageShow(event: PageTransitionEvent): void {\n if (!event.persisted) return;\n documentVisible = true;\n if (!stopped && pending) scheduleRaf();\n }\n\n document.addEventListener('visibilitychange', onVisibilityChange);\n window.addEventListener('pageshow', onPageShow);\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n document.removeEventListener('visibilitychange', onVisibilityChange);\n window.removeEventListener('pageshow', onPageShow);\n cancelRaf();\n pending = false;\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n call,\n flush,\n cancel,\n get pending() {\n return pending;\n },\n stop,\n };\n}\n","import { linkAbortSignal } from '../_internal/abort';\nimport { serverContextError } from '../_internal/errors';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface DebounceOptions<T = void> {\n /** Called with the latest value passed to `call`. */\n callback: (value: T) => void;\n /** Quiet period in milliseconds. Each call restarts it. */\n wait: number;\n /** Pending-call policy when the document hides. Default `'flush'`. */\n hidden?: 'flush' | 'drop';\n /** Stops the debounce when aborted. */\n signal?: AbortSignal;\n}\n\nexport interface Debounce<T = void> {\n /** Record `value` and restart the quiet timer. */\n call(value: T): void;\n /** Invoke a pending call now. No-op when nothing is pending. */\n flush(): void;\n /** Discard a pending call. */\n cancel(): void;\n /** Whether a call is waiting for the quiet period to elapse. */\n readonly pending: boolean;\n /** Terminal. Discards pending work and removes listeners. */\n stop(): void;\n}\n\n// ---------------------------------------------------------------------------\n// createDebounce\n// ---------------------------------------------------------------------------\n\n/**\n * Visibility-aware trailing debounce. Fires the callback with the latest\n * value once `wait` milliseconds pass without a new call. While the document\n * is hidden no timer runs: a pending call is flushed or dropped per `hidden`,\n * and new calls are recorded but wait until the document is visible again,\n * when the quiet timer restarts.\n */\nexport function createDebounce<T = void>(\n options: DebounceOptions<T>,\n): Debounce<T> {\n if (typeof document === 'undefined') {\n serverContextError('createDebounce');\n }\n\n const { callback, wait, hidden = 'flush', signal } = options;\n\n let stopped = false;\n let pending = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let documentVisible: boolean = !document.hidden;\n let latest: T = undefined as T;\n\n function fire(): void {\n pending = false;\n callback(latest);\n }\n\n function clearTimer(): void {\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n }\n }\n\n function onTimer(): void {\n timer = undefined;\n if (stopped || !pending) return;\n fire();\n }\n\n function startTimer(): void {\n clearTimer();\n timer = setTimeout(onTimer, wait);\n }\n\n function call(value: T): void {\n if (stopped) return;\n latest = value;\n pending = true;\n // Hidden: record only. The quiet timer restarts on visibility.\n if (documentVisible) startTimer();\n }\n\n function flush(): void {\n if (stopped || !pending) return;\n clearTimer();\n fire();\n }\n\n function cancel(): void {\n if (stopped) return;\n clearTimer();\n pending = false;\n }\n\n function onVisibilityChange(): void {\n documentVisible = !document.hidden;\n if (stopped) return;\n if (!documentVisible) {\n clearTimer();\n if (pending) {\n if (hidden === 'flush') fire();\n else pending = false;\n }\n } else if (pending) {\n startTimer();\n }\n }\n\n function onPageShow(event: PageTransitionEvent): void {\n if (!event.persisted) return;\n documentVisible = true;\n if (!stopped && pending) startTimer();\n }\n\n document.addEventListener('visibilitychange', onVisibilityChange);\n window.addEventListener('pageshow', onPageShow);\n\n let unlinkAbort: (() => void) | undefined;\n\n function stop(): void {\n if (stopped) return;\n stopped = true;\n unlinkAbort?.();\n document.removeEventListener('visibilitychange', onVisibilityChange);\n window.removeEventListener('pageshow', onPageShow);\n clearTimer();\n pending = false;\n }\n\n unlinkAbort = linkAbortSignal(signal, stop);\n\n return {\n call,\n flush,\n cancel,\n get pending() {\n return pending;\n },\n stop,\n };\n}\n"],"mappings":"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"}