@vielzeug/scroll 1.1.4 → 1.1.6
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.
- package/dist/_dev.cjs +1 -1
- package/dist/_dev.cjs.map +1 -1
- package/dist/_dev.js +1 -1
- package/dist/_dev.js.map +1 -1
- package/dist/_utils.cjs +1 -1
- package/dist/_utils.cjs.map +1 -1
- package/dist/_utils.js +1 -1
- package/dist/_utils.js.map +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/grid-virtualizer.cjs +1 -1
- package/dist/grid-virtualizer.cjs.map +1 -1
- package/dist/grid-virtualizer.js +1 -1
- package/dist/grid-virtualizer.js.map +1 -1
- package/dist/reactive.cjs.map +1 -1
- package/dist/scroll.cjs +1 -1
- package/dist/scroll.cjs.map +1 -1
- package/dist/scroll.iife.js +1 -1
- package/dist/scroll.iife.js.map +1 -1
- package/dist/scroll.js +1 -1
- package/dist/scroll.js.map +1 -1
- package/dist/virtualizer.cjs +1 -1
- package/dist/virtualizer.cjs.map +1 -1
- package/dist/virtualizer.js +1 -1
- package/dist/virtualizer.js.map +1 -1
- package/package.json +4 -5
package/dist/_dev.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
function e(e){}exports.warn=e;
|
|
2
2
|
//# sourceMappingURL=_dev.cjs.map
|
package/dist/_dev.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_dev.cjs","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __SCROLL_PROD__?: boolean }).__SCROLL_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/scroll] ${msg}`);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"_dev.cjs","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __SCROLL_PROD__?: boolean }).__SCROLL_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/scroll] ${msg}`);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":"AAGA,SAAgB,EAAK,EAAmB,CAExC"}
|
package/dist/_dev.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
function e(e){}export{e as warn};
|
|
2
2
|
//# sourceMappingURL=_dev.js.map
|
package/dist/_dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_dev.js","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __SCROLL_PROD__?: boolean }).__SCROLL_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/scroll] ${msg}`);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"_dev.js","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __SCROLL_PROD__?: boolean }).__SCROLL_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/scroll] ${msg}`);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":"AAGA,SAAgB,EAAK,EAAmB,CAExC"}
|
package/dist/_utils.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
require("./_dev.cjs");function e(){return new Map}var t=36,n=3;function r(e,t=0){return Number.isFinite(e)?Math.max(0,Math.floor(e)):t}function i(e,t){return!Number.isFinite(e)||e<=0||e>1e7?t:e}function a(e){return typeof Window<`u`&&e instanceof Window||typeof e.innerHeight==`number`&&typeof e.document==`object`}function o(e,t){if(typeof e==`number`){let n=r(e,t);return{end:n,start:n}}return{end:r(e?.end??t),start:r(e?.start??t)}}function s(e,t,n){let r=new ResizeObserver(e=>{for(let t of e)n(t)});return r.observe(t),e.addEventListener(`abort`,()=>r.disconnect(),{once:!0}),()=>r.disconnect()}function c(e,t){if(typeof e==`function`)return n=>{try{return i(e(n),t)}catch(e){return`${n}${e}`,t}};let n=typeof e==`number`?i(e,t):t;return()=>n}exports.DEFAULT_ESTIMATE_SIZE=t,exports.DEFAULT_OVERSCAN=n,exports.createMeasurementCache=e,exports.isWindowTarget=a,exports.normalizeOverscan=o,exports.observeResize=s,exports.resolveEstimateFn=c,exports.toNonNegativeInt=r,exports.toPositiveNumber=i;
|
|
2
2
|
//# sourceMappingURL=_utils.cjs.map
|
package/dist/_utils.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_utils.cjs","names":[],"sources":["../src/_utils.ts"],"sourcesContent":["import { warn } from './_dev';\n\nexport type ScrollTarget = HTMLElement | Window;\n\nexport type VirtualKey = number | string;\n\n/** Shared measurement cache. Pass the same instance to multiple virtualizers\n * for scroll restoration or SSR pre-measurement. */\nexport type MeasurementCache = Map<VirtualKey, number>;\n\n/** Create a new, empty measurement cache. */\nexport function createMeasurementCache(): MeasurementCache {\n return new Map();\n}\n\nexport type Overscan = number | { end?: number; start?: number };\n\nexport const DEFAULT_ESTIMATE_SIZE = 36;\nexport const DEFAULT_OVERSCAN = 3;\n\n// ─── Numeric helpers ───────────────────────────────────────────────────────────\n\nexport function toNonNegativeInt(value: number, fallback = 0): number {\n if (!Number.isFinite(value)) return fallback;\n\n return Math.max(0, Math.floor(value));\n}\n\nexport function toPositiveNumber(value: number, fallback: number): number {\n if (!Number.isFinite(value) || value <= 0 || value > 1e7) return fallback;\n\n return value;\n}\n\nexport function isWindowTarget(target: ScrollTarget): target is Window {\n return (\n (typeof Window !== 'undefined' && target instanceof Window) ||\n (typeof (target as Window).innerHeight === 'number' && typeof (target as Window).document === 'object')\n );\n}\n\nexport function normalizeOverscan(overscan: Overscan | undefined, defaultVal: number): { end: number; start: number } {\n if (typeof overscan === 'number') {\n const n = toNonNegativeInt(overscan, defaultVal);\n\n return { end: n, start: n };\n }\n\n return {\n end: toNonNegativeInt(overscan?.end ?? defaultVal),\n start: toNonNegativeInt(overscan?.start ?? defaultVal),\n };\n}\n\n/**\n * Create a `ResizeObserver` that reports size changes on `el` via `onSize`, tied to\n * `signal` so it is disconnected automatically when the owning factory disposes —\n * even if the caller never calls the returned disconnect function.\n */\nexport function observeResize(\n signal: AbortSignal,\n el: HTMLElement,\n onSize: (entry: ResizeObserverEntry) => void,\n): () => void {\n const ro = new ResizeObserver((entries) => {\n for (const entry of entries) onSize(entry);\n });\n\n ro.observe(el);\n signal.addEventListener('abort', () => ro.disconnect(), { once: true });\n\n return () => ro.disconnect();\n}\n\nexport function resolveEstimateFn(\n estimate: number | ((index: number) => number) | undefined,\n defaultSize: number,\n): (index: number) => number {\n if (typeof estimate === 'function') {\n return (index: number) => {\n try {\n return toPositiveNumber(estimate(index), defaultSize);\n } catch (err) {\n warn(`estimateSize threw for index ${index}: ${err}`);\n\n return defaultSize;\n }\n };\n }\n\n const size = typeof estimate === 'number' ? toPositiveNumber(estimate, defaultSize) : defaultSize;\n\n return () => size;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"_utils.cjs","names":[],"sources":["../src/_utils.ts"],"sourcesContent":["import { warn } from './_dev';\n\nexport type ScrollTarget = HTMLElement | Window;\n\nexport type VirtualKey = number | string;\n\n/** Shared measurement cache. Pass the same instance to multiple virtualizers\n * for scroll restoration or SSR pre-measurement. */\nexport type MeasurementCache = Map<VirtualKey, number>;\n\n/** Create a new, empty measurement cache. */\nexport function createMeasurementCache(): MeasurementCache {\n return new Map();\n}\n\nexport type Overscan = number | { end?: number; start?: number };\n\nexport const DEFAULT_ESTIMATE_SIZE = 36;\nexport const DEFAULT_OVERSCAN = 3;\n\n// ─── Numeric helpers ───────────────────────────────────────────────────────────\n\nexport function toNonNegativeInt(value: number, fallback = 0): number {\n if (!Number.isFinite(value)) return fallback;\n\n return Math.max(0, Math.floor(value));\n}\n\nexport function toPositiveNumber(value: number, fallback: number): number {\n if (!Number.isFinite(value) || value <= 0 || value > 1e7) return fallback;\n\n return value;\n}\n\nexport function isWindowTarget(target: ScrollTarget): target is Window {\n return (\n (typeof Window !== 'undefined' && target instanceof Window) ||\n (typeof (target as Window).innerHeight === 'number' && typeof (target as Window).document === 'object')\n );\n}\n\nexport function normalizeOverscan(overscan: Overscan | undefined, defaultVal: number): { end: number; start: number } {\n if (typeof overscan === 'number') {\n const n = toNonNegativeInt(overscan, defaultVal);\n\n return { end: n, start: n };\n }\n\n return {\n end: toNonNegativeInt(overscan?.end ?? defaultVal),\n start: toNonNegativeInt(overscan?.start ?? defaultVal),\n };\n}\n\n/**\n * Create a `ResizeObserver` that reports size changes on `el` via `onSize`, tied to\n * `signal` so it is disconnected automatically when the owning factory disposes —\n * even if the caller never calls the returned disconnect function.\n */\nexport function observeResize(\n signal: AbortSignal,\n el: HTMLElement,\n onSize: (entry: ResizeObserverEntry) => void,\n): () => void {\n const ro = new ResizeObserver((entries) => {\n for (const entry of entries) onSize(entry);\n });\n\n ro.observe(el);\n signal.addEventListener('abort', () => ro.disconnect(), { once: true });\n\n return () => ro.disconnect();\n}\n\nexport function resolveEstimateFn(\n estimate: number | ((index: number) => number) | undefined,\n defaultSize: number,\n): (index: number) => number {\n if (typeof estimate === 'function') {\n return (index: number) => {\n try {\n return toPositiveNumber(estimate(index), defaultSize);\n } catch (err) {\n warn(`estimateSize threw for index ${index}: ${err}`);\n\n return defaultSize;\n }\n };\n }\n\n const size = typeof estimate === 'number' ? toPositiveNumber(estimate, defaultSize) : defaultSize;\n\n return () => size;\n}\n"],"mappings":"sBAWA,SAAgB,GAA2C,CACzD,OAAO,IAAI,GACb,CAIA,IAAa,EAAwB,GACxB,EAAmB,EAIhC,SAAgB,EAAiB,EAAe,EAAW,EAAW,CAGpE,OAFK,OAAO,SAAS,CAAK,EAEnB,KAAK,IAAI,EAAG,KAAK,MAAM,CAAK,CAAC,EAFA,CAGtC,CAEA,SAAgB,EAAiB,EAAe,EAA0B,CAGxE,MAFI,CAAC,OAAO,SAAS,CAAK,GAAK,GAAS,GAAK,EAAQ,IAAY,EAE1D,CACT,CAEA,SAAgB,EAAe,EAAwC,CACrE,OACG,OAAO,OAAW,KAAe,aAAkB,QACnD,OAAQ,EAAkB,aAAgB,UAAY,OAAQ,EAAkB,UAAa,QAElG,CAEA,SAAgB,EAAkB,EAAgC,EAAoD,CACpH,GAAI,OAAO,GAAa,SAAU,CAChC,IAAM,EAAI,EAAiB,EAAU,CAAU,EAE/C,MAAO,CAAE,IAAK,EAAG,MAAO,CAAE,CAC5B,CAEA,MAAO,CACL,IAAK,EAAiB,GAAU,KAAO,CAAU,EACjD,MAAO,EAAiB,GAAU,OAAS,CAAU,CACvD,CACF,CAOA,SAAgB,EACd,EACA,EACA,EACY,CACZ,IAAM,EAAK,IAAI,eAAgB,GAAY,CACzC,IAAK,IAAM,KAAS,EAAS,EAAO,CAAK,CAC3C,CAAC,EAKD,OAHA,EAAG,QAAQ,CAAE,EACb,EAAO,iBAAiB,YAAe,EAAG,WAAW,EAAG,CAAE,KAAM,EAAK,CAAC,MAEzD,EAAG,WAAW,CAC7B,CAEA,SAAgB,EACd,EACA,EAC2B,CAC3B,GAAI,OAAO,GAAa,WACtB,MAAQ,IAAkB,CACxB,GAAI,CACF,OAAO,EAAiB,EAAS,CAAK,EAAG,CAAW,CACtD,OAAS,EAAK,CAGZ,MAFK,GAAgC,EAAhC,EAA0C,EAA1C,EAEE,CACT,CACF,EAGF,IAAM,EAAO,OAAO,GAAa,SAAW,EAAiB,EAAU,CAAW,EAAI,EAEtF,UAAa,CACf"}
|
package/dist/_utils.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
1
|
+
import"./_dev.js";function e(){return new Map}var t=36,n=3;function r(e,t=0){return Number.isFinite(e)?Math.max(0,Math.floor(e)):t}function i(e,t){return!Number.isFinite(e)||e<=0||e>1e7?t:e}function a(e){return typeof Window<`u`&&e instanceof Window||typeof e.innerHeight==`number`&&typeof e.document==`object`}function o(e,t){if(typeof e==`number`){let n=r(e,t);return{end:n,start:n}}return{end:r(e?.end??t),start:r(e?.start??t)}}function s(e,t,n){let r=new ResizeObserver(e=>{for(let t of e)n(t)});return r.observe(t),e.addEventListener(`abort`,()=>r.disconnect(),{once:!0}),()=>r.disconnect()}function c(e,t){if(typeof e==`function`)return n=>{try{return i(e(n),t)}catch(e){return`${n}${e}`,t}};let n=typeof e==`number`?i(e,t):t;return()=>n}export{t as DEFAULT_ESTIMATE_SIZE,n as DEFAULT_OVERSCAN,e as createMeasurementCache,a as isWindowTarget,o as normalizeOverscan,s as observeResize,c as resolveEstimateFn,r as toNonNegativeInt,i as toPositiveNumber};
|
|
2
2
|
//# sourceMappingURL=_utils.js.map
|
package/dist/_utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_utils.js","names":[],"sources":["../src/_utils.ts"],"sourcesContent":["import { warn } from './_dev';\n\nexport type ScrollTarget = HTMLElement | Window;\n\nexport type VirtualKey = number | string;\n\n/** Shared measurement cache. Pass the same instance to multiple virtualizers\n * for scroll restoration or SSR pre-measurement. */\nexport type MeasurementCache = Map<VirtualKey, number>;\n\n/** Create a new, empty measurement cache. */\nexport function createMeasurementCache(): MeasurementCache {\n return new Map();\n}\n\nexport type Overscan = number | { end?: number; start?: number };\n\nexport const DEFAULT_ESTIMATE_SIZE = 36;\nexport const DEFAULT_OVERSCAN = 3;\n\n// ─── Numeric helpers ───────────────────────────────────────────────────────────\n\nexport function toNonNegativeInt(value: number, fallback = 0): number {\n if (!Number.isFinite(value)) return fallback;\n\n return Math.max(0, Math.floor(value));\n}\n\nexport function toPositiveNumber(value: number, fallback: number): number {\n if (!Number.isFinite(value) || value <= 0 || value > 1e7) return fallback;\n\n return value;\n}\n\nexport function isWindowTarget(target: ScrollTarget): target is Window {\n return (\n (typeof Window !== 'undefined' && target instanceof Window) ||\n (typeof (target as Window).innerHeight === 'number' && typeof (target as Window).document === 'object')\n );\n}\n\nexport function normalizeOverscan(overscan: Overscan | undefined, defaultVal: number): { end: number; start: number } {\n if (typeof overscan === 'number') {\n const n = toNonNegativeInt(overscan, defaultVal);\n\n return { end: n, start: n };\n }\n\n return {\n end: toNonNegativeInt(overscan?.end ?? defaultVal),\n start: toNonNegativeInt(overscan?.start ?? defaultVal),\n };\n}\n\n/**\n * Create a `ResizeObserver` that reports size changes on `el` via `onSize`, tied to\n * `signal` so it is disconnected automatically when the owning factory disposes —\n * even if the caller never calls the returned disconnect function.\n */\nexport function observeResize(\n signal: AbortSignal,\n el: HTMLElement,\n onSize: (entry: ResizeObserverEntry) => void,\n): () => void {\n const ro = new ResizeObserver((entries) => {\n for (const entry of entries) onSize(entry);\n });\n\n ro.observe(el);\n signal.addEventListener('abort', () => ro.disconnect(), { once: true });\n\n return () => ro.disconnect();\n}\n\nexport function resolveEstimateFn(\n estimate: number | ((index: number) => number) | undefined,\n defaultSize: number,\n): (index: number) => number {\n if (typeof estimate === 'function') {\n return (index: number) => {\n try {\n return toPositiveNumber(estimate(index), defaultSize);\n } catch (err) {\n warn(`estimateSize threw for index ${index}: ${err}`);\n\n return defaultSize;\n }\n };\n }\n\n const size = typeof estimate === 'number' ? toPositiveNumber(estimate, defaultSize) : defaultSize;\n\n return () => size;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"_utils.js","names":[],"sources":["../src/_utils.ts"],"sourcesContent":["import { warn } from './_dev';\n\nexport type ScrollTarget = HTMLElement | Window;\n\nexport type VirtualKey = number | string;\n\n/** Shared measurement cache. Pass the same instance to multiple virtualizers\n * for scroll restoration or SSR pre-measurement. */\nexport type MeasurementCache = Map<VirtualKey, number>;\n\n/** Create a new, empty measurement cache. */\nexport function createMeasurementCache(): MeasurementCache {\n return new Map();\n}\n\nexport type Overscan = number | { end?: number; start?: number };\n\nexport const DEFAULT_ESTIMATE_SIZE = 36;\nexport const DEFAULT_OVERSCAN = 3;\n\n// ─── Numeric helpers ───────────────────────────────────────────────────────────\n\nexport function toNonNegativeInt(value: number, fallback = 0): number {\n if (!Number.isFinite(value)) return fallback;\n\n return Math.max(0, Math.floor(value));\n}\n\nexport function toPositiveNumber(value: number, fallback: number): number {\n if (!Number.isFinite(value) || value <= 0 || value > 1e7) return fallback;\n\n return value;\n}\n\nexport function isWindowTarget(target: ScrollTarget): target is Window {\n return (\n (typeof Window !== 'undefined' && target instanceof Window) ||\n (typeof (target as Window).innerHeight === 'number' && typeof (target as Window).document === 'object')\n );\n}\n\nexport function normalizeOverscan(overscan: Overscan | undefined, defaultVal: number): { end: number; start: number } {\n if (typeof overscan === 'number') {\n const n = toNonNegativeInt(overscan, defaultVal);\n\n return { end: n, start: n };\n }\n\n return {\n end: toNonNegativeInt(overscan?.end ?? defaultVal),\n start: toNonNegativeInt(overscan?.start ?? defaultVal),\n };\n}\n\n/**\n * Create a `ResizeObserver` that reports size changes on `el` via `onSize`, tied to\n * `signal` so it is disconnected automatically when the owning factory disposes —\n * even if the caller never calls the returned disconnect function.\n */\nexport function observeResize(\n signal: AbortSignal,\n el: HTMLElement,\n onSize: (entry: ResizeObserverEntry) => void,\n): () => void {\n const ro = new ResizeObserver((entries) => {\n for (const entry of entries) onSize(entry);\n });\n\n ro.observe(el);\n signal.addEventListener('abort', () => ro.disconnect(), { once: true });\n\n return () => ro.disconnect();\n}\n\nexport function resolveEstimateFn(\n estimate: number | ((index: number) => number) | undefined,\n defaultSize: number,\n): (index: number) => number {\n if (typeof estimate === 'function') {\n return (index: number) => {\n try {\n return toPositiveNumber(estimate(index), defaultSize);\n } catch (err) {\n warn(`estimateSize threw for index ${index}: ${err}`);\n\n return defaultSize;\n }\n };\n }\n\n const size = typeof estimate === 'number' ? toPositiveNumber(estimate, defaultSize) : defaultSize;\n\n return () => size;\n}\n"],"mappings":"kBAWA,SAAgB,GAA2C,CACzD,OAAO,IAAI,GACb,CAIA,IAAa,EAAwB,GACxB,EAAmB,EAIhC,SAAgB,EAAiB,EAAe,EAAW,EAAW,CAGpE,OAFK,OAAO,SAAS,CAAK,EAEnB,KAAK,IAAI,EAAG,KAAK,MAAM,CAAK,CAAC,EAFA,CAGtC,CAEA,SAAgB,EAAiB,EAAe,EAA0B,CAGxE,MAFI,CAAC,OAAO,SAAS,CAAK,GAAK,GAAS,GAAK,EAAQ,IAAY,EAE1D,CACT,CAEA,SAAgB,EAAe,EAAwC,CACrE,OACG,OAAO,OAAW,KAAe,aAAkB,QACnD,OAAQ,EAAkB,aAAgB,UAAY,OAAQ,EAAkB,UAAa,QAElG,CAEA,SAAgB,EAAkB,EAAgC,EAAoD,CACpH,GAAI,OAAO,GAAa,SAAU,CAChC,IAAM,EAAI,EAAiB,EAAU,CAAU,EAE/C,MAAO,CAAE,IAAK,EAAG,MAAO,CAAE,CAC5B,CAEA,MAAO,CACL,IAAK,EAAiB,GAAU,KAAO,CAAU,EACjD,MAAO,EAAiB,GAAU,OAAS,CAAU,CACvD,CACF,CAOA,SAAgB,EACd,EACA,EACA,EACY,CACZ,IAAM,EAAK,IAAI,eAAgB,GAAY,CACzC,IAAK,IAAM,KAAS,EAAS,EAAO,CAAK,CAC3C,CAAC,EAKD,OAHA,EAAG,QAAQ,CAAE,EACb,EAAO,iBAAiB,YAAe,EAAG,WAAW,EAAG,CAAE,KAAM,EAAK,CAAC,MAEzD,EAAG,WAAW,CAC7B,CAEA,SAAgB,EACd,EACA,EAC2B,CAC3B,GAAI,OAAO,GAAa,WACtB,MAAQ,IAAkB,CACxB,GAAI,CACF,OAAO,EAAiB,EAAS,CAAK,EAAG,CAAW,CACtD,OAAS,EAAK,CAGZ,MAFK,GAAgC,EAAhC,EAA0C,EAA1C,EAEE,CACT,CACF,EAGF,IAAM,EAAO,OAAO,GAAa,SAAW,EAAiB,EAAU,CAAW,EAAI,EAEtF,UAAa,CACf"}
|
package/dist/errors.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all scroll errors. */\nexport class ScrollError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is ScrollError {\n return err instanceof ScrollError;\n }\n}\n\n/** Thrown when a virtual-list index is out of bounds. */\nexport class ScrollRangeError extends ScrollError {}\n"],"mappings":"AACA,IAAa,EAAb,MAAa,UAAoB,KAAM,CACrC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,
|
|
1
|
+
{"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all scroll errors. */\nexport class ScrollError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is ScrollError {\n return err instanceof ScrollError;\n }\n}\n\n/** Thrown when a virtual-list index is out of bounds. */\nexport class ScrollRangeError extends ScrollError {}\n"],"mappings":"AACA,IAAa,EAAb,MAAa,UAAoB,KAAM,CACrC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CAEA,OAAO,GAAG,EAAkC,CAC1C,OAAO,aAAe,CACxB,CACF,EAGa,EAAb,cAAsC,CAAY,CAAC"}
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all scroll errors. */\nexport class ScrollError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is ScrollError {\n return err instanceof ScrollError;\n }\n}\n\n/** Thrown when a virtual-list index is out of bounds. */\nexport class ScrollRangeError extends ScrollError {}\n"],"mappings":"AACA,IAAa,EAAb,MAAa,UAAoB,KAAM,CACrC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,
|
|
1
|
+
{"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all scroll errors. */\nexport class ScrollError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is ScrollError {\n return err instanceof ScrollError;\n }\n}\n\n/** Thrown when a virtual-list index is out of bounds. */\nexport class ScrollRangeError extends ScrollError {}\n"],"mappings":"AACA,IAAa,EAAb,MAAa,UAAoB,KAAM,CACrC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CAEA,OAAO,GAAG,EAAkC,CAC1C,OAAO,aAAe,CACxB,CACF,EAGa,EAAb,cAAsC,CAAY,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./_utils.cjs"),t=require("./_adapter.cjs"),n=require("./_axis1d.cjs");function r(e,t,n,r,i,a){return a===`start`?e:a===`end`?t-i:a===`center`?e-(i-n)/2:e>=r&&t<=r+i?null:e<r?e:t-i}function i(i,a){let o=e.toNonNegativeInt(a.rowCount),s=e.toNonNegativeInt(a.colCount),c=e.resolveEstimateFn(a.estimateRowSize,36),l=e.resolveEstimateFn(a.estimateColSize,36),u=e.normalizeOverscan(a.overscanY,3),d=e.normalizeOverscan(a.overscanX,3),f=a.onChange,p=a.onRangeChange,m=a.rowMeasurementCache??new Map,h=a.colMeasurementCache??new Map,g=0,_=0,v=0,y=0,b=[],x=[],S=!1,C=n.createAxis1D(o,e=>m.get(e)??c(e),e.toNonNegativeInt(a.rowGap??0)),w=n.createAxis1D(s,e=>h.get(e)??l(e),e.toNonNegativeInt(a.colGap??0)),T=!1;function E(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,C.totalSize-v),Math.max(0,t))}function D(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,w.totalSize-y),Math.max(0,t))}function O(){if(S)return;let e=C.totalSize,t=w.totalSize;if(o===0||s===0||v<=0||y<=0){C.prevStart
|
|
1
|
+
const e=require("./_utils.cjs"),t=require("./_adapter.cjs"),n=require("./_axis1d.cjs");function r(e,t,n,r,i,a){return a===`start`?e:a===`end`?t-i:a===`center`?e-(i-n)/2:e>=r&&t<=r+i?null:e<r?e:t-i}function i(i,a){let o=e.toNonNegativeInt(a.rowCount),s=e.toNonNegativeInt(a.colCount),c=e.resolveEstimateFn(a.estimateRowSize,36),l=e.resolveEstimateFn(a.estimateColSize,36),u=e.normalizeOverscan(a.overscanY,3),d=e.normalizeOverscan(a.overscanX,3),f=a.onChange,p=a.onRangeChange,m=a.rowMeasurementCache??new Map,h=a.colMeasurementCache??new Map,g=0,_=0,v=0,y=0,b=[],x=[],S=!1,C=n.createAxis1D(o,e=>m.get(e)??c(e),e.toNonNegativeInt(a.rowGap??0)),w=n.createAxis1D(s,e=>h.get(e)??l(e),e.toNonNegativeInt(a.colGap??0)),T=!1;function E(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,C.totalSize-v),Math.max(0,t))}function D(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,w.totalSize-y),Math.max(0,t))}function O(){if(S)return;let e=C.totalSize,t=w.totalSize;if(o===0||s===0||v<=0||y<=0){(C.prevStart!==-1||C.prevTotalSize!==e||w.prevTotalSize!==t)&&(C.commitDedup(-1,-1),w.commitDedup(-1,-1),b=[],x=[],f?.({cols:[],rows:[],totalHeight:e,totalWidth:t}));return}let{renderEnd:n,renderStart:r}=C.computeRange(g,g+v,u.start,u.end),{renderEnd:i,renderStart:a}=w.computeRange(_,_+y,d.start,d.end),c=C.isDedupSame(r,n),l=w.isDedupSame(a,i);if(c&&l)return;C.commitDedup(r,n),w.commitDedup(a,i),(!c||!l)&&p&&p({firstCol:a,firstRow:r,lastCol:i,lastRow:n});let m=[];for(let e=r;e<=n;e++)m.push(C.itemAt(e));let h=[];for(let e=a;e<=i;e++)h.push(w.itemAt(e));b=m,x=h,f?.({cols:x,rows:b,totalHeight:e,totalWidth:t})}function k(t,n){if(!Number.isFinite(t))return!1;let r=Math.floor(t);if(r<0||r>=o)return!1;let i=e.toPositiveNumber(n,-1);return i<=0||m.get(r)===i?!1:(m.set(r,i),C.markChanged(r),!0)}function A(t,n){if(!Number.isFinite(t))return!1;let r=Math.floor(t);if(r<0||r>=s)return!1;let i=e.toPositiveNumber(n,-1);return i<=0||h.get(r)===i?!1:(h.set(r,i),w.markChanged(r),!0)}function j(){T||(T=!0,queueMicrotask(()=>{T=!1;let e=C.consumeMinChangedIndex();e!==1/0&&C.rebuildFrom(e);let t=w.consumeMinChangedIndex();t!==1/0&&w.rebuildFrom(t),O()}))}function M(e,t){S||k(e,t)&&j()}function N(e,t){S||A(e,t)&&j()}function P(e,t){if(S)return;let n=!1;for(let{index:t,size:r}of e)k(t,r)&&(n=!0);for(let{index:e,size:r}of t)A(e,r)&&(n=!0);n&&j()}function F(t,n){return S?()=>{}:e.observeResize(W.signal,n,e=>M(t,e.contentRect.height))}function I(t,n){return S?()=>{}:e.observeResize(W.signal,n,e=>N(t,e.contentRect.width))}function L(){S||(m.clear(),h.clear(),C.rebuild(!0),w.rebuild(!0),O())}function R(){S||(C.rebuild(!0),w.rebuild(!0),O())}function z(t){if(S)return;let n=e.toNonNegativeInt(t);if(n===0)return;o+=n,C.setCount(o),C.rebuild(!0);let r=C.startAt(n),i=E(g+r);J.scrollTo(_,i,`auto`),g=i,O()}function B(e,t={}){if(S||o===0)return;let n=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),o-1)),i=t.behavior??`auto`,a=C.startAt(n),s=C.sizeAt(n),c=r(a,a+s,s,g,v,t.rowAlign??`auto`);c!==null&&J.scrollTo(_,E(c),i)}function V(e,t={}){if(S||s===0)return;let n=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),s-1)),i=t.behavior??`auto`,a=w.startAt(n),o=w.sizeAt(n),c=r(a,a+o,o,_,y,t.colAlign??`auto`);c!==null&&J.scrollTo(D(c),g,i)}function H(e,t,n={}){if(S||o===0||s===0)return;let i=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),o-1)),a=Math.max(0,Math.min(Math.floor(Number.isFinite(t)?t:0),s-1)),c=n.behavior??`auto`,l=C.startAt(i),u=C.sizeAt(i),d=w.startAt(a),f=w.sizeAt(a),p=r(l,l+u,u,g,v,n.rowAlign??`auto`),m=r(d,d+f,f,_,y,n.colAlign??`auto`);(p!==null||m!==null)&&J.scrollTo(m===null?_:D(m),p===null?g:E(p),c)}function U(t){if(S)return;let n=!1,r=!1,i=!1;if(t.rowCount!==void 0){let r=e.toNonNegativeInt(t.rowCount);r!==o&&(o=r,C.setCount(o),n=!0)}if(t.colCount!==void 0){let n=e.toNonNegativeInt(t.colCount);n!==s&&(s=n,w.setCount(s),r=!0)}if(t.rowGap!==void 0){let r=e.toNonNegativeInt(t.rowGap);r!==C.gap&&(C.setGap(r),n=!0)}if(t.colGap!==void 0){let n=e.toNonNegativeInt(t.colGap);n!==w.gap&&(w.setGap(n),r=!0)}if(`estimateRowSize`in t&&(c=e.resolveEstimateFn(t.estimateRowSize,36),m.clear(),n=!0),`estimateColSize`in t&&(l=e.resolveEstimateFn(t.estimateColSize,36),h.clear(),r=!0),t.overscanY!==void 0){let n=e.normalizeOverscan(t.overscanY,3);(n.start!==u.start||n.end!==u.end)&&(u=n,i=!0)}if(t.overscanX!==void 0){let n=e.normalizeOverscan(t.overscanX,3);(n.start!==d.start||n.end!==d.end)&&(d=n,i=!0)}n&&C.rebuild(!0),r&&w.rebuild(!0),(n||r||i)&&O()}let W=new AbortController;function G(){S||(S=!0,W.abort(),J.detach())}function K(){g=E(J.y.readOffset()),_=D(J.x.readOffset()),O()}function q(){v=J.y.readViewportSize(),y=J.x.readViewportSize(),O()}let J=t.createScrollAdapter(i,K,q);return C.rebuild(!0),w.rebuild(!0),v=J.y.readViewportSize(),y=J.x.readViewportSize(),a.initialScrollTop===void 0?a.initialScrollLeft!==void 0&&J.scrollTo(D(a.initialScrollLeft),0,`auto`):J.scrollTo(a.initialScrollLeft??0,E(a.initialScrollTop),`auto`),g=E(J.y.readOffset()),_=D(J.x.readOffset()),O(),{get cols(){return x},get disposalSignal(){return W.signal},dispose:G,get disposed(){return S},invalidate:L,measureBatch:P,measureColEl:I,measureColumn:N,measureRow:M,measureRowEl:F,prependRows:z,refresh:R,get rows(){return b},get scrollLeft(){return _},scrollToCell:H,scrollToColumn:V,get scrollTop(){return g},scrollToRow:B,[Symbol.dispose]:G,get totalHeight(){return C.totalSize},get totalWidth(){return w.totalSize},update:U}}exports.createGridVirtualizer=i;
|
|
2
2
|
//# sourceMappingURL=grid-virtualizer.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid-virtualizer.cjs","names":[],"sources":["../src/grid-virtualizer.ts"],"sourcesContent":["import { createScrollAdapter } from './_adapter';\nimport { createAxis1D, type VirtualItem } from './_axis1d';\nimport {\n DEFAULT_ESTIMATE_SIZE,\n DEFAULT_OVERSCAN,\n normalizeOverscan,\n observeResize,\n type Overscan,\n resolveEstimateFn,\n type ScrollTarget,\n toNonNegativeInt,\n toPositiveNumber,\n} from './_utils';\n\nexport { type VirtualItem };\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface GridVirtualizerState {\n /**\n * Visible column descriptors.\n * Callers form the cross-product `rows × cols` as needed — no O(r×c) Cell\n * allocation per scroll tick (R8).\n */\n readonly cols: VirtualItem[];\n /** Visible row descriptors. */\n readonly rows: VirtualItem[];\n readonly totalHeight: number;\n readonly totalWidth: number;\n}\n\nexport interface GridRangeChangeEvent {\n firstCol: number;\n firstRow: number;\n lastCol: number;\n lastRow: number;\n}\n\nexport interface ScrollToCellOptions {\n behavior?: ScrollBehavior;\n colAlign?: 'auto' | 'center' | 'end' | 'start';\n rowAlign?: 'auto' | 'center' | 'end' | 'start';\n}\n\nexport interface GridVirtualizerOptions {\n colCount: number;\n /** External measurement cache for columns. Share across instances for scroll restoration. */\n colMeasurementCache?: Map<number, number>;\n colGap?: number;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n initialScrollLeft?: number;\n initialScrollTop?: number;\n /**\n * Called after every render cycle with the new state.\n * **Fixed at construction** \\u2014 cannot be changed after creation.\n */\n onChange?: (state: GridVirtualizerState) => void;\n /** Zero-allocation alternative to onChange for range-based consumers. */\n onRangeChange?: (range: GridRangeChangeEvent) => void;\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount: number;\n /** External measurement cache for rows. Share across instances for scroll restoration. */\n rowMeasurementCache?: Map<number, number>;\n rowGap?: number;\n}\n\n/**\n * Options accepted by `update()`. Explicit interface instead of\n * `Partial<Omit<...>>` for better IDE hover (R7).\n */\nexport interface GridVirtualizerUpdateOptions {\n colCount?: number;\n colGap?: number;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount?: number;\n rowGap?: number;\n}\n\nexport interface GridVirtualizer {\n readonly cols: VirtualItem[];\n readonly disposalSignal: AbortSignal;\n readonly disposed: boolean;\n readonly rows: VirtualItem[];\n readonly scrollLeft: number;\n readonly scrollTop: number;\n readonly totalHeight: number;\n readonly totalWidth: number;\n dispose: () => void;\n invalidate: () => void;\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n measureBatch: (rows: Array<{ index: number; size: number }>, cols: Array<{ index: number; size: number }>) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the column width on resize. Returns disconnect fn. */\n measureColEl: (col: number, el: HTMLElement) => () => void;\n measureColumn: (col: number, size: number) => void;\n measureRow: (row: number, size: number) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the row height on resize. Returns disconnect fn. */\n measureRowEl: (row: number, el: HTMLElement) => () => void;\n /** Prepend `additionalRowCount` rows at the top while keeping the viewport visually stable. */\n prependRows: (additionalRowCount: number) => void;\n refresh: () => void;\n scrollToCell: (row: number, col: number, options?: ScrollToCellOptions) => void;\n /** Scroll to bring a row into view without changing the horizontal position. */\n scrollToColumn: (col: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'>) => void;\n /** Scroll to bring a column into view without changing the vertical position. */\n scrollToRow: (row: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'>) => void;\n update: (next: GridVirtualizerUpdateOptions) => void;\n [Symbol.dispose]: () => void;\n}\n\n// ─── Align helper ─────────────────────────────────────────────────────────────\n\nfunction alignOffset(\n itemStart: number,\n itemEnd: number,\n itemSize: number,\n currentOffset: number,\n viewportSize: number,\n align: 'auto' | 'center' | 'end' | 'start',\n): number | null {\n if (align === 'start') return itemStart;\n\n if (align === 'end') return itemEnd - viewportSize;\n\n if (align === 'center') return itemStart - (viewportSize - itemSize) / 2;\n\n // auto: no-op when already fully visible\n if (itemStart >= currentOffset && itemEnd <= currentOffset + viewportSize) return null;\n\n return itemStart < currentOffset ? itemStart : itemEnd - viewportSize;\n}\n\n// ─── Implementation ────────────────────────────────────────────────────────────\n\nexport function createGridVirtualizer(target: ScrollTarget, options: GridVirtualizerOptions): GridVirtualizer {\n let rowCount = toNonNegativeInt(options.rowCount);\n let colCount = toNonNegativeInt(options.colCount);\n let estimateRowFn = resolveEstimateFn(options.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n let estimateColFn = resolveEstimateFn(options.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n let overscanY = normalizeOverscan(options.overscanY, DEFAULT_OVERSCAN);\n let overscanX = normalizeOverscan(options.overscanX, DEFAULT_OVERSCAN);\n\n // Callbacks fixed at construction.\n const onChange = options.onChange;\n const onRangeChange = options.onRangeChange;\n\n // External or internal measurement caches (numeric row/col index keys).\n const measuredRows: Map<number, number> = options.rowMeasurementCache ?? new Map();\n const measuredCols: Map<number, number> = options.colMeasurementCache ?? new Map();\n\n let scrollTop = 0;\n let scrollLeft = 0;\n let viewportHeight = 0;\n let viewportWidth = 0;\n let rows: VirtualItem[] = [];\n let cols: VirtualItem[] = [];\n let disposed = false;\n\n // ─── Axis1D instances (R1) ─────────────────────────────────────────────────\n // sizeAt closures capture live `measuredRows/Cols` and `estimateFn` vars.\n\n const rowAx = createAxis1D(\n rowCount,\n (r) => measuredRows.get(r) ?? estimateRowFn(r),\n toNonNegativeInt(options.rowGap ?? 0),\n );\n\n const colAx = createAxis1D(\n colCount,\n (c) => measuredCols.get(c) ?? estimateColFn(c),\n toNonNegativeInt(options.colGap ?? 0),\n );\n\n // R4: Single coordinated flush flag — prevents two separate microtasks.\n let pendingBatchBuild = false;\n\n // ─── Clamping ──────────────────────────────────────────────────────────────\n\n function clampTop(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, rowAx.totalSize - viewportHeight), Math.max(0, safe));\n }\n\n function clampLeft(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, colAx.totalSize - viewportWidth), Math.max(0, safe));\n }\n\n // ─── Compute and emit ──────────────────────────────────────────────────────\n\n function computeVisible(): void {\n if (disposed) return;\n\n const totalHeight = rowAx.totalSize;\n const totalWidth = colAx.totalSize;\n\n if (rowCount === 0 || colCount === 0 || viewportHeight <= 0 || viewportWidth <= 0) {\n const wasEmpty =\n rowAx.prevStart === -1 && rowAx.prevTotalSize === totalHeight && colAx.prevTotalSize === totalWidth;\n\n if (!wasEmpty) {\n // commitDedup(-1, -1) captures the current totalSize so the guard doesn't\n // fire on every subsequent event while the empty state persists (Bug 2).\n rowAx.commitDedup(-1, -1);\n colAx.commitDedup(-1, -1);\n rows = [];\n cols = [];\n onChange?.({ cols: [], rows: [], totalHeight, totalWidth });\n }\n\n return;\n }\n\n const { renderEnd: renderLastRow, renderStart: renderFirstRow } = rowAx.computeRange(\n scrollTop,\n scrollTop + viewportHeight,\n overscanY.start,\n overscanY.end,\n );\n\n const { renderEnd: renderLastCol, renderStart: renderFirstCol } = colAx.computeRange(\n scrollLeft,\n scrollLeft + viewportWidth,\n overscanX.start,\n overscanX.end,\n );\n\n const rowSame = rowAx.isDedupSame(renderFirstRow, renderLastRow);\n const colSame = colAx.isDedupSame(renderFirstCol, renderLastCol);\n\n if (rowSame && colSame) return;\n\n rowAx.commitDedup(renderFirstRow, renderLastRow);\n colAx.commitDedup(renderFirstCol, renderLastCol);\n\n const rangeChanged = !rowSame || !colSame;\n\n if (rangeChanged && onRangeChange) {\n onRangeChange({\n firstCol: renderFirstCol,\n firstRow: renderFirstRow,\n lastCol: renderLastCol,\n lastRow: renderLastRow,\n });\n }\n\n // R8: Build rows[] and cols[] separately — no cross-product VirtualCell[].\n const nextRows: VirtualItem[] = [];\n\n for (let r = renderFirstRow; r <= renderLastRow; r++) {\n nextRows.push(rowAx.itemAt(r));\n }\n\n const nextCols: VirtualItem[] = [];\n\n for (let c = renderFirstCol; c <= renderLastCol; c++) {\n nextCols.push(colAx.itemAt(c));\n }\n\n rows = nextRows;\n cols = nextCols;\n\n onChange?.({ cols, rows, totalHeight, totalWidth });\n }\n\n // ─── Measurement helpers ───────────────────────────────────────────────────\n\n function recordRowMeasurement(row: number, size: number): boolean {\n if (!Number.isFinite(row)) return false;\n\n const r = Math.floor(row);\n\n if (r < 0 || r >= rowCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredRows.get(r) === s) return false;\n\n measuredRows.set(r, s);\n rowAx.markChanged(r);\n\n return true;\n }\n\n function recordColMeasurement(col: number, size: number): boolean {\n if (!Number.isFinite(col)) return false;\n\n const c = Math.floor(col);\n\n if (c < 0 || c >= colCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredCols.get(c) === s) return false;\n\n measuredCols.set(c, s);\n colAx.markChanged(c);\n\n return true;\n }\n\n /**\n * R4: Single coordinated flush for both axes.\n * Replaces the previous two independent microtask schedules.\n */\n function scheduleFlush(): void {\n if (pendingBatchBuild) return;\n\n pendingBatchBuild = true;\n queueMicrotask(() => {\n pendingBatchBuild = false;\n\n // consumeMinChangedIndex() atomically reads and resets minChangedIndex.\n // Without the reset, every subsequent flush would rebuild from index 0\n // instead of the actual earliest changed index (Bug 3).\n const fromRow = rowAx.consumeMinChangedIndex();\n\n if (fromRow !== Infinity) rowAx.rebuildFrom(fromRow);\n\n const fromCol = colAx.consumeMinChangedIndex();\n\n if (fromCol !== Infinity) colAx.rebuildFrom(fromCol);\n\n computeVisible();\n });\n }\n\n // ─── Public measurement API ────────────────────────────────────────────────\n\n function measureRow(row: number, size: number): void {\n if (disposed) return;\n\n if (recordRowMeasurement(row, size)) scheduleFlush();\n }\n\n function measureColumn(col: number, size: number): void {\n if (disposed) return;\n\n if (recordColMeasurement(col, size)) scheduleFlush();\n }\n\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n function measureBatch(\n rowEntries: Array<{ index: number; size: number }>,\n colEntries: Array<{ index: number; size: number }>,\n ): void {\n if (disposed) return;\n\n let changed = false;\n\n for (const { index, size } of rowEntries) {\n if (recordRowMeasurement(index, size)) changed = true;\n }\n\n for (const { index, size } of colEntries) {\n if (recordColMeasurement(index, size)) changed = true;\n }\n\n if (changed) scheduleFlush();\n }\n\n function measureRowEl(row: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureRow(row, entry.contentRect.height));\n }\n\n function measureColEl(col: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureColumn(col, entry.contentRect.width));\n }\n\n function invalidate(): void {\n if (disposed) return;\n\n measuredRows.clear();\n measuredCols.clear();\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function refresh(): void {\n if (disposed) return;\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function prependRows(additionalRowCount: number): void {\n if (disposed) return;\n\n const n = toNonNegativeInt(additionalRowCount);\n\n if (n === 0) return;\n\n rowCount += n;\n rowAx.setCount(rowCount);\n rowAx.rebuild(true);\n\n const prependedHeight = rowAx.startAt(n);\n const newScrollTop = clampTop(scrollTop + prependedHeight);\n\n adapter.scrollTo(scrollLeft, newScrollTop, 'auto');\n scrollTop = newScrollTop;\n\n computeVisible();\n }\n\n function scrollToRow(row: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'> = {}): void {\n if (disposed || rowCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n\n if (targetTop === null) return;\n\n adapter.scrollTo(scrollLeft, clampTop(targetTop), behavior);\n }\n\n function scrollToColumn(col: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'> = {}): void {\n if (disposed || colCount === 0) return;\n\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetLeft === null) return;\n\n adapter.scrollTo(clampLeft(targetLeft), scrollTop, behavior);\n }\n\n function scrollToCell(row: number, col: number, opts: ScrollToCellOptions = {}): void {\n if (disposed || rowCount === 0 || colCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetTop === null && targetLeft === null) return;\n\n adapter.scrollTo(\n targetLeft !== null ? clampLeft(targetLeft) : scrollLeft,\n targetTop !== null ? clampTop(targetTop) : scrollTop,\n behavior,\n );\n }\n\n function update(next: GridVirtualizerUpdateOptions): void {\n if (disposed) return;\n\n let rebuildRows = false;\n let rebuildCols = false;\n let needsCompute = false;\n\n if (next.rowCount !== undefined) {\n const n = toNonNegativeInt(next.rowCount);\n\n if (n !== rowCount) {\n rowCount = n;\n rowAx.setCount(rowCount);\n rebuildRows = true;\n }\n }\n\n if (next.colCount !== undefined) {\n const n = toNonNegativeInt(next.colCount);\n\n if (n !== colCount) {\n colCount = n;\n colAx.setCount(colCount);\n rebuildCols = true;\n }\n }\n\n if (next.rowGap !== undefined) {\n const n = toNonNegativeInt(next.rowGap);\n\n if (n !== rowAx.gap) {\n rowAx.setGap(n);\n rebuildRows = true;\n }\n }\n\n if (next.colGap !== undefined) {\n const n = toNonNegativeInt(next.colGap);\n\n if (n !== colAx.gap) {\n colAx.setGap(n);\n rebuildCols = true;\n }\n }\n\n if ('estimateRowSize' in next) {\n estimateRowFn = resolveEstimateFn(next.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n measuredRows.clear();\n rebuildRows = true;\n }\n\n if ('estimateColSize' in next) {\n estimateColFn = resolveEstimateFn(next.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n measuredCols.clear();\n rebuildCols = true;\n }\n\n if (next.overscanY !== undefined) {\n const n = normalizeOverscan(next.overscanY, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanY.start || n.end !== overscanY.end) {\n overscanY = n;\n needsCompute = true;\n }\n }\n\n if (next.overscanX !== undefined) {\n const n = normalizeOverscan(next.overscanX, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanX.start || n.end !== overscanX.end) {\n overscanX = n;\n needsCompute = true;\n }\n }\n\n if (rebuildRows) rowAx.rebuild(true);\n\n if (rebuildCols) colAx.rebuild(true);\n\n if (rebuildRows || rebuildCols || needsCompute) computeVisible();\n }\n\n const ac = new AbortController();\n\n function disposeImpl(): void {\n if (disposed) return;\n\n disposed = true;\n ac.abort();\n adapter.detach();\n }\n\n // ─── Bootstrap (R9: read viewport BEFORE writing initial scroll) ───────────\n\n function handleScroll(): void {\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n computeVisible();\n }\n\n function handleResize(): void {\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n computeVisible();\n }\n\n const adapter = createScrollAdapter(target, handleScroll, handleResize);\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n\n // R9: Read viewport dimensions BEFORE writing initial scroll positions so that\n // computeVisible() sees a valid viewport on the very first call.\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n\n if (options.initialScrollTop !== undefined) {\n adapter.scrollTo(options.initialScrollLeft ?? 0, clampTop(options.initialScrollTop), 'auto');\n } else if (options.initialScrollLeft !== undefined) {\n adapter.scrollTo(clampLeft(options.initialScrollLeft), 0, 'auto');\n }\n\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n\n computeVisible();\n\n return {\n get cols() {\n return cols;\n },\n get disposalSignal() {\n return ac.signal;\n },\n dispose: disposeImpl,\n get disposed() {\n return disposed;\n },\n invalidate,\n measureBatch,\n measureColEl,\n measureColumn,\n measureRow,\n measureRowEl,\n prependRows,\n refresh,\n get rows() {\n return rows;\n },\n get scrollLeft() {\n return scrollLeft;\n },\n scrollToCell,\n scrollToColumn,\n get scrollTop() {\n return scrollTop;\n },\n scrollToRow,\n [Symbol.dispose]: disposeImpl,\n get totalHeight() {\n return rowAx.totalSize;\n },\n get totalWidth() {\n return colAx.totalSize;\n },\n update,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"grid-virtualizer.cjs","names":[],"sources":["../src/grid-virtualizer.ts"],"sourcesContent":["import { createScrollAdapter } from './_adapter';\nimport { createAxis1D, type VirtualItem } from './_axis1d';\nimport {\n DEFAULT_ESTIMATE_SIZE,\n DEFAULT_OVERSCAN,\n normalizeOverscan,\n observeResize,\n type Overscan,\n resolveEstimateFn,\n type ScrollTarget,\n toNonNegativeInt,\n toPositiveNumber,\n} from './_utils';\n\nexport { type VirtualItem };\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface GridVirtualizerState {\n /**\n * Visible column descriptors.\n * Callers form the cross-product `rows × cols` as needed — no O(r×c) Cell\n * allocation per scroll tick (R8).\n */\n readonly cols: VirtualItem[];\n /** Visible row descriptors. */\n readonly rows: VirtualItem[];\n readonly totalHeight: number;\n readonly totalWidth: number;\n}\n\nexport interface GridRangeChangeEvent {\n firstCol: number;\n firstRow: number;\n lastCol: number;\n lastRow: number;\n}\n\nexport interface ScrollToCellOptions {\n behavior?: ScrollBehavior;\n colAlign?: 'auto' | 'center' | 'end' | 'start';\n rowAlign?: 'auto' | 'center' | 'end' | 'start';\n}\n\nexport interface GridVirtualizerOptions {\n colCount: number;\n /** External measurement cache for columns. Share across instances for scroll restoration. */\n colMeasurementCache?: Map<number, number>;\n colGap?: number;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n initialScrollLeft?: number;\n initialScrollTop?: number;\n /**\n * Called after every render cycle with the new state.\n * **Fixed at construction** \\u2014 cannot be changed after creation.\n */\n onChange?: (state: GridVirtualizerState) => void;\n /** Zero-allocation alternative to onChange for range-based consumers. */\n onRangeChange?: (range: GridRangeChangeEvent) => void;\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount: number;\n /** External measurement cache for rows. Share across instances for scroll restoration. */\n rowMeasurementCache?: Map<number, number>;\n rowGap?: number;\n}\n\n/**\n * Options accepted by `update()`. Explicit interface instead of\n * `Partial<Omit<...>>` for better IDE hover (R7).\n */\nexport interface GridVirtualizerUpdateOptions {\n colCount?: number;\n colGap?: number;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount?: number;\n rowGap?: number;\n}\n\nexport interface GridVirtualizer {\n readonly cols: VirtualItem[];\n readonly disposalSignal: AbortSignal;\n readonly disposed: boolean;\n readonly rows: VirtualItem[];\n readonly scrollLeft: number;\n readonly scrollTop: number;\n readonly totalHeight: number;\n readonly totalWidth: number;\n dispose: () => void;\n invalidate: () => void;\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n measureBatch: (rows: Array<{ index: number; size: number }>, cols: Array<{ index: number; size: number }>) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the column width on resize. Returns disconnect fn. */\n measureColEl: (col: number, el: HTMLElement) => () => void;\n measureColumn: (col: number, size: number) => void;\n measureRow: (row: number, size: number) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the row height on resize. Returns disconnect fn. */\n measureRowEl: (row: number, el: HTMLElement) => () => void;\n /** Prepend `additionalRowCount` rows at the top while keeping the viewport visually stable. */\n prependRows: (additionalRowCount: number) => void;\n refresh: () => void;\n scrollToCell: (row: number, col: number, options?: ScrollToCellOptions) => void;\n /** Scroll to bring a row into view without changing the horizontal position. */\n scrollToColumn: (col: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'>) => void;\n /** Scroll to bring a column into view without changing the vertical position. */\n scrollToRow: (row: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'>) => void;\n update: (next: GridVirtualizerUpdateOptions) => void;\n [Symbol.dispose]: () => void;\n}\n\n// ─── Align helper ─────────────────────────────────────────────────────────────\n\nfunction alignOffset(\n itemStart: number,\n itemEnd: number,\n itemSize: number,\n currentOffset: number,\n viewportSize: number,\n align: 'auto' | 'center' | 'end' | 'start',\n): number | null {\n if (align === 'start') return itemStart;\n\n if (align === 'end') return itemEnd - viewportSize;\n\n if (align === 'center') return itemStart - (viewportSize - itemSize) / 2;\n\n // auto: no-op when already fully visible\n if (itemStart >= currentOffset && itemEnd <= currentOffset + viewportSize) return null;\n\n return itemStart < currentOffset ? itemStart : itemEnd - viewportSize;\n}\n\n// ─── Implementation ────────────────────────────────────────────────────────────\n\nexport function createGridVirtualizer(target: ScrollTarget, options: GridVirtualizerOptions): GridVirtualizer {\n let rowCount = toNonNegativeInt(options.rowCount);\n let colCount = toNonNegativeInt(options.colCount);\n let estimateRowFn = resolveEstimateFn(options.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n let estimateColFn = resolveEstimateFn(options.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n let overscanY = normalizeOverscan(options.overscanY, DEFAULT_OVERSCAN);\n let overscanX = normalizeOverscan(options.overscanX, DEFAULT_OVERSCAN);\n\n // Callbacks fixed at construction.\n const onChange = options.onChange;\n const onRangeChange = options.onRangeChange;\n\n // External or internal measurement caches (numeric row/col index keys).\n const measuredRows: Map<number, number> = options.rowMeasurementCache ?? new Map();\n const measuredCols: Map<number, number> = options.colMeasurementCache ?? new Map();\n\n let scrollTop = 0;\n let scrollLeft = 0;\n let viewportHeight = 0;\n let viewportWidth = 0;\n let rows: VirtualItem[] = [];\n let cols: VirtualItem[] = [];\n let disposed = false;\n\n // ─── Axis1D instances (R1) ─────────────────────────────────────────────────\n // sizeAt closures capture live `measuredRows/Cols` and `estimateFn` vars.\n\n const rowAx = createAxis1D(\n rowCount,\n (r) => measuredRows.get(r) ?? estimateRowFn(r),\n toNonNegativeInt(options.rowGap ?? 0),\n );\n\n const colAx = createAxis1D(\n colCount,\n (c) => measuredCols.get(c) ?? estimateColFn(c),\n toNonNegativeInt(options.colGap ?? 0),\n );\n\n // R4: Single coordinated flush flag — prevents two separate microtasks.\n let pendingBatchBuild = false;\n\n // ─── Clamping ──────────────────────────────────────────────────────────────\n\n function clampTop(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, rowAx.totalSize - viewportHeight), Math.max(0, safe));\n }\n\n function clampLeft(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, colAx.totalSize - viewportWidth), Math.max(0, safe));\n }\n\n // ─── Compute and emit ──────────────────────────────────────────────────────\n\n function computeVisible(): void {\n if (disposed) return;\n\n const totalHeight = rowAx.totalSize;\n const totalWidth = colAx.totalSize;\n\n if (rowCount === 0 || colCount === 0 || viewportHeight <= 0 || viewportWidth <= 0) {\n const wasEmpty =\n rowAx.prevStart === -1 && rowAx.prevTotalSize === totalHeight && colAx.prevTotalSize === totalWidth;\n\n if (!wasEmpty) {\n // commitDedup(-1, -1) captures the current totalSize so the guard doesn't\n // fire on every subsequent event while the empty state persists (Bug 2).\n rowAx.commitDedup(-1, -1);\n colAx.commitDedup(-1, -1);\n rows = [];\n cols = [];\n onChange?.({ cols: [], rows: [], totalHeight, totalWidth });\n }\n\n return;\n }\n\n const { renderEnd: renderLastRow, renderStart: renderFirstRow } = rowAx.computeRange(\n scrollTop,\n scrollTop + viewportHeight,\n overscanY.start,\n overscanY.end,\n );\n\n const { renderEnd: renderLastCol, renderStart: renderFirstCol } = colAx.computeRange(\n scrollLeft,\n scrollLeft + viewportWidth,\n overscanX.start,\n overscanX.end,\n );\n\n const rowSame = rowAx.isDedupSame(renderFirstRow, renderLastRow);\n const colSame = colAx.isDedupSame(renderFirstCol, renderLastCol);\n\n if (rowSame && colSame) return;\n\n rowAx.commitDedup(renderFirstRow, renderLastRow);\n colAx.commitDedup(renderFirstCol, renderLastCol);\n\n const rangeChanged = !rowSame || !colSame;\n\n if (rangeChanged && onRangeChange) {\n onRangeChange({\n firstCol: renderFirstCol,\n firstRow: renderFirstRow,\n lastCol: renderLastCol,\n lastRow: renderLastRow,\n });\n }\n\n // R8: Build rows[] and cols[] separately — no cross-product VirtualCell[].\n const nextRows: VirtualItem[] = [];\n\n for (let r = renderFirstRow; r <= renderLastRow; r++) {\n nextRows.push(rowAx.itemAt(r));\n }\n\n const nextCols: VirtualItem[] = [];\n\n for (let c = renderFirstCol; c <= renderLastCol; c++) {\n nextCols.push(colAx.itemAt(c));\n }\n\n rows = nextRows;\n cols = nextCols;\n\n onChange?.({ cols, rows, totalHeight, totalWidth });\n }\n\n // ─── Measurement helpers ───────────────────────────────────────────────────\n\n function recordRowMeasurement(row: number, size: number): boolean {\n if (!Number.isFinite(row)) return false;\n\n const r = Math.floor(row);\n\n if (r < 0 || r >= rowCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredRows.get(r) === s) return false;\n\n measuredRows.set(r, s);\n rowAx.markChanged(r);\n\n return true;\n }\n\n function recordColMeasurement(col: number, size: number): boolean {\n if (!Number.isFinite(col)) return false;\n\n const c = Math.floor(col);\n\n if (c < 0 || c >= colCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredCols.get(c) === s) return false;\n\n measuredCols.set(c, s);\n colAx.markChanged(c);\n\n return true;\n }\n\n /**\n * R4: Single coordinated flush for both axes.\n * Replaces the previous two independent microtask schedules.\n */\n function scheduleFlush(): void {\n if (pendingBatchBuild) return;\n\n pendingBatchBuild = true;\n queueMicrotask(() => {\n pendingBatchBuild = false;\n\n // consumeMinChangedIndex() atomically reads and resets minChangedIndex.\n // Without the reset, every subsequent flush would rebuild from index 0\n // instead of the actual earliest changed index (Bug 3).\n const fromRow = rowAx.consumeMinChangedIndex();\n\n if (fromRow !== Infinity) rowAx.rebuildFrom(fromRow);\n\n const fromCol = colAx.consumeMinChangedIndex();\n\n if (fromCol !== Infinity) colAx.rebuildFrom(fromCol);\n\n computeVisible();\n });\n }\n\n // ─── Public measurement API ────────────────────────────────────────────────\n\n function measureRow(row: number, size: number): void {\n if (disposed) return;\n\n if (recordRowMeasurement(row, size)) scheduleFlush();\n }\n\n function measureColumn(col: number, size: number): void {\n if (disposed) return;\n\n if (recordColMeasurement(col, size)) scheduleFlush();\n }\n\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n function measureBatch(\n rowEntries: Array<{ index: number; size: number }>,\n colEntries: Array<{ index: number; size: number }>,\n ): void {\n if (disposed) return;\n\n let changed = false;\n\n for (const { index, size } of rowEntries) {\n if (recordRowMeasurement(index, size)) changed = true;\n }\n\n for (const { index, size } of colEntries) {\n if (recordColMeasurement(index, size)) changed = true;\n }\n\n if (changed) scheduleFlush();\n }\n\n function measureRowEl(row: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureRow(row, entry.contentRect.height));\n }\n\n function measureColEl(col: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureColumn(col, entry.contentRect.width));\n }\n\n function invalidate(): void {\n if (disposed) return;\n\n measuredRows.clear();\n measuredCols.clear();\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function refresh(): void {\n if (disposed) return;\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function prependRows(additionalRowCount: number): void {\n if (disposed) return;\n\n const n = toNonNegativeInt(additionalRowCount);\n\n if (n === 0) return;\n\n rowCount += n;\n rowAx.setCount(rowCount);\n rowAx.rebuild(true);\n\n const prependedHeight = rowAx.startAt(n);\n const newScrollTop = clampTop(scrollTop + prependedHeight);\n\n adapter.scrollTo(scrollLeft, newScrollTop, 'auto');\n scrollTop = newScrollTop;\n\n computeVisible();\n }\n\n function scrollToRow(row: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'> = {}): void {\n if (disposed || rowCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n\n if (targetTop === null) return;\n\n adapter.scrollTo(scrollLeft, clampTop(targetTop), behavior);\n }\n\n function scrollToColumn(col: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'> = {}): void {\n if (disposed || colCount === 0) return;\n\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetLeft === null) return;\n\n adapter.scrollTo(clampLeft(targetLeft), scrollTop, behavior);\n }\n\n function scrollToCell(row: number, col: number, opts: ScrollToCellOptions = {}): void {\n if (disposed || rowCount === 0 || colCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetTop === null && targetLeft === null) return;\n\n adapter.scrollTo(\n targetLeft !== null ? clampLeft(targetLeft) : scrollLeft,\n targetTop !== null ? clampTop(targetTop) : scrollTop,\n behavior,\n );\n }\n\n function update(next: GridVirtualizerUpdateOptions): void {\n if (disposed) return;\n\n let rebuildRows = false;\n let rebuildCols = false;\n let needsCompute = false;\n\n if (next.rowCount !== undefined) {\n const n = toNonNegativeInt(next.rowCount);\n\n if (n !== rowCount) {\n rowCount = n;\n rowAx.setCount(rowCount);\n rebuildRows = true;\n }\n }\n\n if (next.colCount !== undefined) {\n const n = toNonNegativeInt(next.colCount);\n\n if (n !== colCount) {\n colCount = n;\n colAx.setCount(colCount);\n rebuildCols = true;\n }\n }\n\n if (next.rowGap !== undefined) {\n const n = toNonNegativeInt(next.rowGap);\n\n if (n !== rowAx.gap) {\n rowAx.setGap(n);\n rebuildRows = true;\n }\n }\n\n if (next.colGap !== undefined) {\n const n = toNonNegativeInt(next.colGap);\n\n if (n !== colAx.gap) {\n colAx.setGap(n);\n rebuildCols = true;\n }\n }\n\n if ('estimateRowSize' in next) {\n estimateRowFn = resolveEstimateFn(next.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n measuredRows.clear();\n rebuildRows = true;\n }\n\n if ('estimateColSize' in next) {\n estimateColFn = resolveEstimateFn(next.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n measuredCols.clear();\n rebuildCols = true;\n }\n\n if (next.overscanY !== undefined) {\n const n = normalizeOverscan(next.overscanY, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanY.start || n.end !== overscanY.end) {\n overscanY = n;\n needsCompute = true;\n }\n }\n\n if (next.overscanX !== undefined) {\n const n = normalizeOverscan(next.overscanX, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanX.start || n.end !== overscanX.end) {\n overscanX = n;\n needsCompute = true;\n }\n }\n\n if (rebuildRows) rowAx.rebuild(true);\n\n if (rebuildCols) colAx.rebuild(true);\n\n if (rebuildRows || rebuildCols || needsCompute) computeVisible();\n }\n\n const ac = new AbortController();\n\n function disposeImpl(): void {\n if (disposed) return;\n\n disposed = true;\n ac.abort();\n adapter.detach();\n }\n\n // ─── Bootstrap (R9: read viewport BEFORE writing initial scroll) ───────────\n\n function handleScroll(): void {\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n computeVisible();\n }\n\n function handleResize(): void {\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n computeVisible();\n }\n\n const adapter = createScrollAdapter(target, handleScroll, handleResize);\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n\n // R9: Read viewport dimensions BEFORE writing initial scroll positions so that\n // computeVisible() sees a valid viewport on the very first call.\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n\n if (options.initialScrollTop !== undefined) {\n adapter.scrollTo(options.initialScrollLeft ?? 0, clampTop(options.initialScrollTop), 'auto');\n } else if (options.initialScrollLeft !== undefined) {\n adapter.scrollTo(clampLeft(options.initialScrollLeft), 0, 'auto');\n }\n\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n\n computeVisible();\n\n return {\n get cols() {\n return cols;\n },\n get disposalSignal() {\n return ac.signal;\n },\n dispose: disposeImpl,\n get disposed() {\n return disposed;\n },\n invalidate,\n measureBatch,\n measureColEl,\n measureColumn,\n measureRow,\n measureRowEl,\n prependRows,\n refresh,\n get rows() {\n return rows;\n },\n get scrollLeft() {\n return scrollLeft;\n },\n scrollToCell,\n scrollToColumn,\n get scrollTop() {\n return scrollTop;\n },\n scrollToRow,\n [Symbol.dispose]: disposeImpl,\n get totalHeight() {\n return rowAx.totalSize;\n },\n get totalWidth() {\n return colAx.totalSize;\n },\n update,\n };\n}\n"],"mappings":"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"}
|
package/dist/grid-virtualizer.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{normalizeOverscan as e,observeResize as t,resolveEstimateFn as n,toNonNegativeInt as r,toPositiveNumber as i}from"./_utils.js";import{createScrollAdapter as a}from"./_adapter.js";import{createAxis1D as o}from"./_axis1d.js";function s(e,t,n,r,i,a){return a===`start`?e:a===`end`?t-i:a===`center`?e-(i-n)/2:e>=r&&t<=r+i?null:e<r?e:t-i}function c(c,l){let u=r(l.rowCount),d=r(l.colCount),f=n(l.estimateRowSize,36),p=n(l.estimateColSize,36),m=e(l.overscanY,3),h=e(l.overscanX,3),g=l.onChange,_=l.onRangeChange,v=l.rowMeasurementCache??new Map,y=l.colMeasurementCache??new Map,b=0,x=0,S=0,C=0,w=[],T=[],E=!1,D=o(u,e=>v.get(e)??f(e),r(l.rowGap??0)),O=o(d,e=>y.get(e)??p(e),r(l.colGap??0)),k=!1;function A(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,D.totalSize-S),Math.max(0,t))}function j(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,O.totalSize-C),Math.max(0,t))}function M(){if(E)return;let e=D.totalSize,t=O.totalSize;if(u===0||d===0||S<=0||C<=0){D.prevStart
|
|
1
|
+
import{normalizeOverscan as e,observeResize as t,resolveEstimateFn as n,toNonNegativeInt as r,toPositiveNumber as i}from"./_utils.js";import{createScrollAdapter as a}from"./_adapter.js";import{createAxis1D as o}from"./_axis1d.js";function s(e,t,n,r,i,a){return a===`start`?e:a===`end`?t-i:a===`center`?e-(i-n)/2:e>=r&&t<=r+i?null:e<r?e:t-i}function c(c,l){let u=r(l.rowCount),d=r(l.colCount),f=n(l.estimateRowSize,36),p=n(l.estimateColSize,36),m=e(l.overscanY,3),h=e(l.overscanX,3),g=l.onChange,_=l.onRangeChange,v=l.rowMeasurementCache??new Map,y=l.colMeasurementCache??new Map,b=0,x=0,S=0,C=0,w=[],T=[],E=!1,D=o(u,e=>v.get(e)??f(e),r(l.rowGap??0)),O=o(d,e=>y.get(e)??p(e),r(l.colGap??0)),k=!1;function A(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,D.totalSize-S),Math.max(0,t))}function j(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,O.totalSize-C),Math.max(0,t))}function M(){if(E)return;let e=D.totalSize,t=O.totalSize;if(u===0||d===0||S<=0||C<=0){(D.prevStart!==-1||D.prevTotalSize!==e||O.prevTotalSize!==t)&&(D.commitDedup(-1,-1),O.commitDedup(-1,-1),w=[],T=[],g?.({cols:[],rows:[],totalHeight:e,totalWidth:t}));return}let{renderEnd:n,renderStart:r}=D.computeRange(b,b+S,m.start,m.end),{renderEnd:i,renderStart:a}=O.computeRange(x,x+C,h.start,h.end),o=D.isDedupSame(r,n),s=O.isDedupSame(a,i);if(o&&s)return;D.commitDedup(r,n),O.commitDedup(a,i),(!o||!s)&&_&&_({firstCol:a,firstRow:r,lastCol:i,lastRow:n});let c=[];for(let e=r;e<=n;e++)c.push(D.itemAt(e));let l=[];for(let e=a;e<=i;e++)l.push(O.itemAt(e));w=c,T=l,g?.({cols:T,rows:w,totalHeight:e,totalWidth:t})}function N(e,t){if(!Number.isFinite(e))return!1;let n=Math.floor(e);if(n<0||n>=u)return!1;let r=i(t,-1);return r<=0||v.get(n)===r?!1:(v.set(n,r),D.markChanged(n),!0)}function P(e,t){if(!Number.isFinite(e))return!1;let n=Math.floor(e);if(n<0||n>=d)return!1;let r=i(t,-1);return r<=0||y.get(n)===r?!1:(y.set(n,r),O.markChanged(n),!0)}function F(){k||(k=!0,queueMicrotask(()=>{k=!1;let e=D.consumeMinChangedIndex();e!==1/0&&D.rebuildFrom(e);let t=O.consumeMinChangedIndex();t!==1/0&&O.rebuildFrom(t),M()}))}function I(e,t){E||N(e,t)&&F()}function L(e,t){E||P(e,t)&&F()}function R(e,t){if(E)return;let n=!1;for(let{index:t,size:r}of e)N(t,r)&&(n=!0);for(let{index:e,size:r}of t)P(e,r)&&(n=!0);n&&F()}function z(e,n){return E?()=>{}:t(J.signal,n,t=>I(e,t.contentRect.height))}function B(e,n){return E?()=>{}:t(J.signal,n,t=>L(e,t.contentRect.width))}function V(){E||(v.clear(),y.clear(),D.rebuild(!0),O.rebuild(!0),M())}function H(){E||(D.rebuild(!0),O.rebuild(!0),M())}function U(e){if(E)return;let t=r(e);if(t===0)return;u+=t,D.setCount(u),D.rebuild(!0);let n=D.startAt(t),i=A(b+n);Q.scrollTo(x,i,`auto`),b=i,M()}function W(e,t={}){if(E||u===0)return;let n=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),u-1)),r=t.behavior??`auto`,i=D.startAt(n),a=D.sizeAt(n),o=s(i,i+a,a,b,S,t.rowAlign??`auto`);o!==null&&Q.scrollTo(x,A(o),r)}function G(e,t={}){if(E||d===0)return;let n=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),d-1)),r=t.behavior??`auto`,i=O.startAt(n),a=O.sizeAt(n),o=s(i,i+a,a,x,C,t.colAlign??`auto`);o!==null&&Q.scrollTo(j(o),b,r)}function K(e,t,n={}){if(E||u===0||d===0)return;let r=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),u-1)),i=Math.max(0,Math.min(Math.floor(Number.isFinite(t)?t:0),d-1)),a=n.behavior??`auto`,o=D.startAt(r),c=D.sizeAt(r),l=O.startAt(i),f=O.sizeAt(i),p=s(o,o+c,c,b,S,n.rowAlign??`auto`),m=s(l,l+f,f,x,C,n.colAlign??`auto`);(p!==null||m!==null)&&Q.scrollTo(m===null?x:j(m),p===null?b:A(p),a)}function q(t){if(E)return;let i=!1,a=!1,o=!1;if(t.rowCount!==void 0){let e=r(t.rowCount);e!==u&&(u=e,D.setCount(u),i=!0)}if(t.colCount!==void 0){let e=r(t.colCount);e!==d&&(d=e,O.setCount(d),a=!0)}if(t.rowGap!==void 0){let e=r(t.rowGap);e!==D.gap&&(D.setGap(e),i=!0)}if(t.colGap!==void 0){let e=r(t.colGap);e!==O.gap&&(O.setGap(e),a=!0)}if(`estimateRowSize`in t&&(f=n(t.estimateRowSize,36),v.clear(),i=!0),`estimateColSize`in t&&(p=n(t.estimateColSize,36),y.clear(),a=!0),t.overscanY!==void 0){let n=e(t.overscanY,3);(n.start!==m.start||n.end!==m.end)&&(m=n,o=!0)}if(t.overscanX!==void 0){let n=e(t.overscanX,3);(n.start!==h.start||n.end!==h.end)&&(h=n,o=!0)}i&&D.rebuild(!0),a&&O.rebuild(!0),(i||a||o)&&M()}let J=new AbortController;function Y(){E||(E=!0,J.abort(),Q.detach())}function X(){b=A(Q.y.readOffset()),x=j(Q.x.readOffset()),M()}function Z(){S=Q.y.readViewportSize(),C=Q.x.readViewportSize(),M()}let Q=a(c,X,Z);return D.rebuild(!0),O.rebuild(!0),S=Q.y.readViewportSize(),C=Q.x.readViewportSize(),l.initialScrollTop===void 0?l.initialScrollLeft!==void 0&&Q.scrollTo(j(l.initialScrollLeft),0,`auto`):Q.scrollTo(l.initialScrollLeft??0,A(l.initialScrollTop),`auto`),b=A(Q.y.readOffset()),x=j(Q.x.readOffset()),M(),{get cols(){return T},get disposalSignal(){return J.signal},dispose:Y,get disposed(){return E},invalidate:V,measureBatch:R,measureColEl:B,measureColumn:L,measureRow:I,measureRowEl:z,prependRows:U,refresh:H,get rows(){return w},get scrollLeft(){return x},scrollToCell:K,scrollToColumn:G,get scrollTop(){return b},scrollToRow:W,[Symbol.dispose]:Y,get totalHeight(){return D.totalSize},get totalWidth(){return O.totalSize},update:q}}export{c as createGridVirtualizer};
|
|
2
2
|
//# sourceMappingURL=grid-virtualizer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid-virtualizer.js","names":[],"sources":["../src/grid-virtualizer.ts"],"sourcesContent":["import { createScrollAdapter } from './_adapter';\nimport { createAxis1D, type VirtualItem } from './_axis1d';\nimport {\n DEFAULT_ESTIMATE_SIZE,\n DEFAULT_OVERSCAN,\n normalizeOverscan,\n observeResize,\n type Overscan,\n resolveEstimateFn,\n type ScrollTarget,\n toNonNegativeInt,\n toPositiveNumber,\n} from './_utils';\n\nexport { type VirtualItem };\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface GridVirtualizerState {\n /**\n * Visible column descriptors.\n * Callers form the cross-product `rows × cols` as needed — no O(r×c) Cell\n * allocation per scroll tick (R8).\n */\n readonly cols: VirtualItem[];\n /** Visible row descriptors. */\n readonly rows: VirtualItem[];\n readonly totalHeight: number;\n readonly totalWidth: number;\n}\n\nexport interface GridRangeChangeEvent {\n firstCol: number;\n firstRow: number;\n lastCol: number;\n lastRow: number;\n}\n\nexport interface ScrollToCellOptions {\n behavior?: ScrollBehavior;\n colAlign?: 'auto' | 'center' | 'end' | 'start';\n rowAlign?: 'auto' | 'center' | 'end' | 'start';\n}\n\nexport interface GridVirtualizerOptions {\n colCount: number;\n /** External measurement cache for columns. Share across instances for scroll restoration. */\n colMeasurementCache?: Map<number, number>;\n colGap?: number;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n initialScrollLeft?: number;\n initialScrollTop?: number;\n /**\n * Called after every render cycle with the new state.\n * **Fixed at construction** \\u2014 cannot be changed after creation.\n */\n onChange?: (state: GridVirtualizerState) => void;\n /** Zero-allocation alternative to onChange for range-based consumers. */\n onRangeChange?: (range: GridRangeChangeEvent) => void;\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount: number;\n /** External measurement cache for rows. Share across instances for scroll restoration. */\n rowMeasurementCache?: Map<number, number>;\n rowGap?: number;\n}\n\n/**\n * Options accepted by `update()`. Explicit interface instead of\n * `Partial<Omit<...>>` for better IDE hover (R7).\n */\nexport interface GridVirtualizerUpdateOptions {\n colCount?: number;\n colGap?: number;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount?: number;\n rowGap?: number;\n}\n\nexport interface GridVirtualizer {\n readonly cols: VirtualItem[];\n readonly disposalSignal: AbortSignal;\n readonly disposed: boolean;\n readonly rows: VirtualItem[];\n readonly scrollLeft: number;\n readonly scrollTop: number;\n readonly totalHeight: number;\n readonly totalWidth: number;\n dispose: () => void;\n invalidate: () => void;\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n measureBatch: (rows: Array<{ index: number; size: number }>, cols: Array<{ index: number; size: number }>) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the column width on resize. Returns disconnect fn. */\n measureColEl: (col: number, el: HTMLElement) => () => void;\n measureColumn: (col: number, size: number) => void;\n measureRow: (row: number, size: number) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the row height on resize. Returns disconnect fn. */\n measureRowEl: (row: number, el: HTMLElement) => () => void;\n /** Prepend `additionalRowCount` rows at the top while keeping the viewport visually stable. */\n prependRows: (additionalRowCount: number) => void;\n refresh: () => void;\n scrollToCell: (row: number, col: number, options?: ScrollToCellOptions) => void;\n /** Scroll to bring a row into view without changing the horizontal position. */\n scrollToColumn: (col: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'>) => void;\n /** Scroll to bring a column into view without changing the vertical position. */\n scrollToRow: (row: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'>) => void;\n update: (next: GridVirtualizerUpdateOptions) => void;\n [Symbol.dispose]: () => void;\n}\n\n// ─── Align helper ─────────────────────────────────────────────────────────────\n\nfunction alignOffset(\n itemStart: number,\n itemEnd: number,\n itemSize: number,\n currentOffset: number,\n viewportSize: number,\n align: 'auto' | 'center' | 'end' | 'start',\n): number | null {\n if (align === 'start') return itemStart;\n\n if (align === 'end') return itemEnd - viewportSize;\n\n if (align === 'center') return itemStart - (viewportSize - itemSize) / 2;\n\n // auto: no-op when already fully visible\n if (itemStart >= currentOffset && itemEnd <= currentOffset + viewportSize) return null;\n\n return itemStart < currentOffset ? itemStart : itemEnd - viewportSize;\n}\n\n// ─── Implementation ────────────────────────────────────────────────────────────\n\nexport function createGridVirtualizer(target: ScrollTarget, options: GridVirtualizerOptions): GridVirtualizer {\n let rowCount = toNonNegativeInt(options.rowCount);\n let colCount = toNonNegativeInt(options.colCount);\n let estimateRowFn = resolveEstimateFn(options.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n let estimateColFn = resolveEstimateFn(options.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n let overscanY = normalizeOverscan(options.overscanY, DEFAULT_OVERSCAN);\n let overscanX = normalizeOverscan(options.overscanX, DEFAULT_OVERSCAN);\n\n // Callbacks fixed at construction.\n const onChange = options.onChange;\n const onRangeChange = options.onRangeChange;\n\n // External or internal measurement caches (numeric row/col index keys).\n const measuredRows: Map<number, number> = options.rowMeasurementCache ?? new Map();\n const measuredCols: Map<number, number> = options.colMeasurementCache ?? new Map();\n\n let scrollTop = 0;\n let scrollLeft = 0;\n let viewportHeight = 0;\n let viewportWidth = 0;\n let rows: VirtualItem[] = [];\n let cols: VirtualItem[] = [];\n let disposed = false;\n\n // ─── Axis1D instances (R1) ─────────────────────────────────────────────────\n // sizeAt closures capture live `measuredRows/Cols` and `estimateFn` vars.\n\n const rowAx = createAxis1D(\n rowCount,\n (r) => measuredRows.get(r) ?? estimateRowFn(r),\n toNonNegativeInt(options.rowGap ?? 0),\n );\n\n const colAx = createAxis1D(\n colCount,\n (c) => measuredCols.get(c) ?? estimateColFn(c),\n toNonNegativeInt(options.colGap ?? 0),\n );\n\n // R4: Single coordinated flush flag — prevents two separate microtasks.\n let pendingBatchBuild = false;\n\n // ─── Clamping ──────────────────────────────────────────────────────────────\n\n function clampTop(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, rowAx.totalSize - viewportHeight), Math.max(0, safe));\n }\n\n function clampLeft(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, colAx.totalSize - viewportWidth), Math.max(0, safe));\n }\n\n // ─── Compute and emit ──────────────────────────────────────────────────────\n\n function computeVisible(): void {\n if (disposed) return;\n\n const totalHeight = rowAx.totalSize;\n const totalWidth = colAx.totalSize;\n\n if (rowCount === 0 || colCount === 0 || viewportHeight <= 0 || viewportWidth <= 0) {\n const wasEmpty =\n rowAx.prevStart === -1 && rowAx.prevTotalSize === totalHeight && colAx.prevTotalSize === totalWidth;\n\n if (!wasEmpty) {\n // commitDedup(-1, -1) captures the current totalSize so the guard doesn't\n // fire on every subsequent event while the empty state persists (Bug 2).\n rowAx.commitDedup(-1, -1);\n colAx.commitDedup(-1, -1);\n rows = [];\n cols = [];\n onChange?.({ cols: [], rows: [], totalHeight, totalWidth });\n }\n\n return;\n }\n\n const { renderEnd: renderLastRow, renderStart: renderFirstRow } = rowAx.computeRange(\n scrollTop,\n scrollTop + viewportHeight,\n overscanY.start,\n overscanY.end,\n );\n\n const { renderEnd: renderLastCol, renderStart: renderFirstCol } = colAx.computeRange(\n scrollLeft,\n scrollLeft + viewportWidth,\n overscanX.start,\n overscanX.end,\n );\n\n const rowSame = rowAx.isDedupSame(renderFirstRow, renderLastRow);\n const colSame = colAx.isDedupSame(renderFirstCol, renderLastCol);\n\n if (rowSame && colSame) return;\n\n rowAx.commitDedup(renderFirstRow, renderLastRow);\n colAx.commitDedup(renderFirstCol, renderLastCol);\n\n const rangeChanged = !rowSame || !colSame;\n\n if (rangeChanged && onRangeChange) {\n onRangeChange({\n firstCol: renderFirstCol,\n firstRow: renderFirstRow,\n lastCol: renderLastCol,\n lastRow: renderLastRow,\n });\n }\n\n // R8: Build rows[] and cols[] separately — no cross-product VirtualCell[].\n const nextRows: VirtualItem[] = [];\n\n for (let r = renderFirstRow; r <= renderLastRow; r++) {\n nextRows.push(rowAx.itemAt(r));\n }\n\n const nextCols: VirtualItem[] = [];\n\n for (let c = renderFirstCol; c <= renderLastCol; c++) {\n nextCols.push(colAx.itemAt(c));\n }\n\n rows = nextRows;\n cols = nextCols;\n\n onChange?.({ cols, rows, totalHeight, totalWidth });\n }\n\n // ─── Measurement helpers ───────────────────────────────────────────────────\n\n function recordRowMeasurement(row: number, size: number): boolean {\n if (!Number.isFinite(row)) return false;\n\n const r = Math.floor(row);\n\n if (r < 0 || r >= rowCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredRows.get(r) === s) return false;\n\n measuredRows.set(r, s);\n rowAx.markChanged(r);\n\n return true;\n }\n\n function recordColMeasurement(col: number, size: number): boolean {\n if (!Number.isFinite(col)) return false;\n\n const c = Math.floor(col);\n\n if (c < 0 || c >= colCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredCols.get(c) === s) return false;\n\n measuredCols.set(c, s);\n colAx.markChanged(c);\n\n return true;\n }\n\n /**\n * R4: Single coordinated flush for both axes.\n * Replaces the previous two independent microtask schedules.\n */\n function scheduleFlush(): void {\n if (pendingBatchBuild) return;\n\n pendingBatchBuild = true;\n queueMicrotask(() => {\n pendingBatchBuild = false;\n\n // consumeMinChangedIndex() atomically reads and resets minChangedIndex.\n // Without the reset, every subsequent flush would rebuild from index 0\n // instead of the actual earliest changed index (Bug 3).\n const fromRow = rowAx.consumeMinChangedIndex();\n\n if (fromRow !== Infinity) rowAx.rebuildFrom(fromRow);\n\n const fromCol = colAx.consumeMinChangedIndex();\n\n if (fromCol !== Infinity) colAx.rebuildFrom(fromCol);\n\n computeVisible();\n });\n }\n\n // ─── Public measurement API ────────────────────────────────────────────────\n\n function measureRow(row: number, size: number): void {\n if (disposed) return;\n\n if (recordRowMeasurement(row, size)) scheduleFlush();\n }\n\n function measureColumn(col: number, size: number): void {\n if (disposed) return;\n\n if (recordColMeasurement(col, size)) scheduleFlush();\n }\n\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n function measureBatch(\n rowEntries: Array<{ index: number; size: number }>,\n colEntries: Array<{ index: number; size: number }>,\n ): void {\n if (disposed) return;\n\n let changed = false;\n\n for (const { index, size } of rowEntries) {\n if (recordRowMeasurement(index, size)) changed = true;\n }\n\n for (const { index, size } of colEntries) {\n if (recordColMeasurement(index, size)) changed = true;\n }\n\n if (changed) scheduleFlush();\n }\n\n function measureRowEl(row: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureRow(row, entry.contentRect.height));\n }\n\n function measureColEl(col: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureColumn(col, entry.contentRect.width));\n }\n\n function invalidate(): void {\n if (disposed) return;\n\n measuredRows.clear();\n measuredCols.clear();\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function refresh(): void {\n if (disposed) return;\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function prependRows(additionalRowCount: number): void {\n if (disposed) return;\n\n const n = toNonNegativeInt(additionalRowCount);\n\n if (n === 0) return;\n\n rowCount += n;\n rowAx.setCount(rowCount);\n rowAx.rebuild(true);\n\n const prependedHeight = rowAx.startAt(n);\n const newScrollTop = clampTop(scrollTop + prependedHeight);\n\n adapter.scrollTo(scrollLeft, newScrollTop, 'auto');\n scrollTop = newScrollTop;\n\n computeVisible();\n }\n\n function scrollToRow(row: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'> = {}): void {\n if (disposed || rowCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n\n if (targetTop === null) return;\n\n adapter.scrollTo(scrollLeft, clampTop(targetTop), behavior);\n }\n\n function scrollToColumn(col: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'> = {}): void {\n if (disposed || colCount === 0) return;\n\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetLeft === null) return;\n\n adapter.scrollTo(clampLeft(targetLeft), scrollTop, behavior);\n }\n\n function scrollToCell(row: number, col: number, opts: ScrollToCellOptions = {}): void {\n if (disposed || rowCount === 0 || colCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetTop === null && targetLeft === null) return;\n\n adapter.scrollTo(\n targetLeft !== null ? clampLeft(targetLeft) : scrollLeft,\n targetTop !== null ? clampTop(targetTop) : scrollTop,\n behavior,\n );\n }\n\n function update(next: GridVirtualizerUpdateOptions): void {\n if (disposed) return;\n\n let rebuildRows = false;\n let rebuildCols = false;\n let needsCompute = false;\n\n if (next.rowCount !== undefined) {\n const n = toNonNegativeInt(next.rowCount);\n\n if (n !== rowCount) {\n rowCount = n;\n rowAx.setCount(rowCount);\n rebuildRows = true;\n }\n }\n\n if (next.colCount !== undefined) {\n const n = toNonNegativeInt(next.colCount);\n\n if (n !== colCount) {\n colCount = n;\n colAx.setCount(colCount);\n rebuildCols = true;\n }\n }\n\n if (next.rowGap !== undefined) {\n const n = toNonNegativeInt(next.rowGap);\n\n if (n !== rowAx.gap) {\n rowAx.setGap(n);\n rebuildRows = true;\n }\n }\n\n if (next.colGap !== undefined) {\n const n = toNonNegativeInt(next.colGap);\n\n if (n !== colAx.gap) {\n colAx.setGap(n);\n rebuildCols = true;\n }\n }\n\n if ('estimateRowSize' in next) {\n estimateRowFn = resolveEstimateFn(next.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n measuredRows.clear();\n rebuildRows = true;\n }\n\n if ('estimateColSize' in next) {\n estimateColFn = resolveEstimateFn(next.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n measuredCols.clear();\n rebuildCols = true;\n }\n\n if (next.overscanY !== undefined) {\n const n = normalizeOverscan(next.overscanY, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanY.start || n.end !== overscanY.end) {\n overscanY = n;\n needsCompute = true;\n }\n }\n\n if (next.overscanX !== undefined) {\n const n = normalizeOverscan(next.overscanX, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanX.start || n.end !== overscanX.end) {\n overscanX = n;\n needsCompute = true;\n }\n }\n\n if (rebuildRows) rowAx.rebuild(true);\n\n if (rebuildCols) colAx.rebuild(true);\n\n if (rebuildRows || rebuildCols || needsCompute) computeVisible();\n }\n\n const ac = new AbortController();\n\n function disposeImpl(): void {\n if (disposed) return;\n\n disposed = true;\n ac.abort();\n adapter.detach();\n }\n\n // ─── Bootstrap (R9: read viewport BEFORE writing initial scroll) ───────────\n\n function handleScroll(): void {\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n computeVisible();\n }\n\n function handleResize(): void {\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n computeVisible();\n }\n\n const adapter = createScrollAdapter(target, handleScroll, handleResize);\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n\n // R9: Read viewport dimensions BEFORE writing initial scroll positions so that\n // computeVisible() sees a valid viewport on the very first call.\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n\n if (options.initialScrollTop !== undefined) {\n adapter.scrollTo(options.initialScrollLeft ?? 0, clampTop(options.initialScrollTop), 'auto');\n } else if (options.initialScrollLeft !== undefined) {\n adapter.scrollTo(clampLeft(options.initialScrollLeft), 0, 'auto');\n }\n\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n\n computeVisible();\n\n return {\n get cols() {\n return cols;\n },\n get disposalSignal() {\n return ac.signal;\n },\n dispose: disposeImpl,\n get disposed() {\n return disposed;\n },\n invalidate,\n measureBatch,\n measureColEl,\n measureColumn,\n measureRow,\n measureRowEl,\n prependRows,\n refresh,\n get rows() {\n return rows;\n },\n get scrollLeft() {\n return scrollLeft;\n },\n scrollToCell,\n scrollToColumn,\n get scrollTop() {\n return scrollTop;\n },\n scrollToRow,\n [Symbol.dispose]: disposeImpl,\n get totalHeight() {\n return rowAx.totalSize;\n },\n get totalWidth() {\n return colAx.totalSize;\n },\n update,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"grid-virtualizer.js","names":[],"sources":["../src/grid-virtualizer.ts"],"sourcesContent":["import { createScrollAdapter } from './_adapter';\nimport { createAxis1D, type VirtualItem } from './_axis1d';\nimport {\n DEFAULT_ESTIMATE_SIZE,\n DEFAULT_OVERSCAN,\n normalizeOverscan,\n observeResize,\n type Overscan,\n resolveEstimateFn,\n type ScrollTarget,\n toNonNegativeInt,\n toPositiveNumber,\n} from './_utils';\n\nexport { type VirtualItem };\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface GridVirtualizerState {\n /**\n * Visible column descriptors.\n * Callers form the cross-product `rows × cols` as needed — no O(r×c) Cell\n * allocation per scroll tick (R8).\n */\n readonly cols: VirtualItem[];\n /** Visible row descriptors. */\n readonly rows: VirtualItem[];\n readonly totalHeight: number;\n readonly totalWidth: number;\n}\n\nexport interface GridRangeChangeEvent {\n firstCol: number;\n firstRow: number;\n lastCol: number;\n lastRow: number;\n}\n\nexport interface ScrollToCellOptions {\n behavior?: ScrollBehavior;\n colAlign?: 'auto' | 'center' | 'end' | 'start';\n rowAlign?: 'auto' | 'center' | 'end' | 'start';\n}\n\nexport interface GridVirtualizerOptions {\n colCount: number;\n /** External measurement cache for columns. Share across instances for scroll restoration. */\n colMeasurementCache?: Map<number, number>;\n colGap?: number;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n initialScrollLeft?: number;\n initialScrollTop?: number;\n /**\n * Called after every render cycle with the new state.\n * **Fixed at construction** \\u2014 cannot be changed after creation.\n */\n onChange?: (state: GridVirtualizerState) => void;\n /** Zero-allocation alternative to onChange for range-based consumers. */\n onRangeChange?: (range: GridRangeChangeEvent) => void;\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount: number;\n /** External measurement cache for rows. Share across instances for scroll restoration. */\n rowMeasurementCache?: Map<number, number>;\n rowGap?: number;\n}\n\n/**\n * Options accepted by `update()`. Explicit interface instead of\n * `Partial<Omit<...>>` for better IDE hover (R7).\n */\nexport interface GridVirtualizerUpdateOptions {\n colCount?: number;\n colGap?: number;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount?: number;\n rowGap?: number;\n}\n\nexport interface GridVirtualizer {\n readonly cols: VirtualItem[];\n readonly disposalSignal: AbortSignal;\n readonly disposed: boolean;\n readonly rows: VirtualItem[];\n readonly scrollLeft: number;\n readonly scrollTop: number;\n readonly totalHeight: number;\n readonly totalWidth: number;\n dispose: () => void;\n invalidate: () => void;\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n measureBatch: (rows: Array<{ index: number; size: number }>, cols: Array<{ index: number; size: number }>) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the column width on resize. Returns disconnect fn. */\n measureColEl: (col: number, el: HTMLElement) => () => void;\n measureColumn: (col: number, size: number) => void;\n measureRow: (row: number, size: number) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the row height on resize. Returns disconnect fn. */\n measureRowEl: (row: number, el: HTMLElement) => () => void;\n /** Prepend `additionalRowCount` rows at the top while keeping the viewport visually stable. */\n prependRows: (additionalRowCount: number) => void;\n refresh: () => void;\n scrollToCell: (row: number, col: number, options?: ScrollToCellOptions) => void;\n /** Scroll to bring a row into view without changing the horizontal position. */\n scrollToColumn: (col: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'>) => void;\n /** Scroll to bring a column into view without changing the vertical position. */\n scrollToRow: (row: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'>) => void;\n update: (next: GridVirtualizerUpdateOptions) => void;\n [Symbol.dispose]: () => void;\n}\n\n// ─── Align helper ─────────────────────────────────────────────────────────────\n\nfunction alignOffset(\n itemStart: number,\n itemEnd: number,\n itemSize: number,\n currentOffset: number,\n viewportSize: number,\n align: 'auto' | 'center' | 'end' | 'start',\n): number | null {\n if (align === 'start') return itemStart;\n\n if (align === 'end') return itemEnd - viewportSize;\n\n if (align === 'center') return itemStart - (viewportSize - itemSize) / 2;\n\n // auto: no-op when already fully visible\n if (itemStart >= currentOffset && itemEnd <= currentOffset + viewportSize) return null;\n\n return itemStart < currentOffset ? itemStart : itemEnd - viewportSize;\n}\n\n// ─── Implementation ────────────────────────────────────────────────────────────\n\nexport function createGridVirtualizer(target: ScrollTarget, options: GridVirtualizerOptions): GridVirtualizer {\n let rowCount = toNonNegativeInt(options.rowCount);\n let colCount = toNonNegativeInt(options.colCount);\n let estimateRowFn = resolveEstimateFn(options.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n let estimateColFn = resolveEstimateFn(options.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n let overscanY = normalizeOverscan(options.overscanY, DEFAULT_OVERSCAN);\n let overscanX = normalizeOverscan(options.overscanX, DEFAULT_OVERSCAN);\n\n // Callbacks fixed at construction.\n const onChange = options.onChange;\n const onRangeChange = options.onRangeChange;\n\n // External or internal measurement caches (numeric row/col index keys).\n const measuredRows: Map<number, number> = options.rowMeasurementCache ?? new Map();\n const measuredCols: Map<number, number> = options.colMeasurementCache ?? new Map();\n\n let scrollTop = 0;\n let scrollLeft = 0;\n let viewportHeight = 0;\n let viewportWidth = 0;\n let rows: VirtualItem[] = [];\n let cols: VirtualItem[] = [];\n let disposed = false;\n\n // ─── Axis1D instances (R1) ─────────────────────────────────────────────────\n // sizeAt closures capture live `measuredRows/Cols` and `estimateFn` vars.\n\n const rowAx = createAxis1D(\n rowCount,\n (r) => measuredRows.get(r) ?? estimateRowFn(r),\n toNonNegativeInt(options.rowGap ?? 0),\n );\n\n const colAx = createAxis1D(\n colCount,\n (c) => measuredCols.get(c) ?? estimateColFn(c),\n toNonNegativeInt(options.colGap ?? 0),\n );\n\n // R4: Single coordinated flush flag — prevents two separate microtasks.\n let pendingBatchBuild = false;\n\n // ─── Clamping ──────────────────────────────────────────────────────────────\n\n function clampTop(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, rowAx.totalSize - viewportHeight), Math.max(0, safe));\n }\n\n function clampLeft(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, colAx.totalSize - viewportWidth), Math.max(0, safe));\n }\n\n // ─── Compute and emit ──────────────────────────────────────────────────────\n\n function computeVisible(): void {\n if (disposed) return;\n\n const totalHeight = rowAx.totalSize;\n const totalWidth = colAx.totalSize;\n\n if (rowCount === 0 || colCount === 0 || viewportHeight <= 0 || viewportWidth <= 0) {\n const wasEmpty =\n rowAx.prevStart === -1 && rowAx.prevTotalSize === totalHeight && colAx.prevTotalSize === totalWidth;\n\n if (!wasEmpty) {\n // commitDedup(-1, -1) captures the current totalSize so the guard doesn't\n // fire on every subsequent event while the empty state persists (Bug 2).\n rowAx.commitDedup(-1, -1);\n colAx.commitDedup(-1, -1);\n rows = [];\n cols = [];\n onChange?.({ cols: [], rows: [], totalHeight, totalWidth });\n }\n\n return;\n }\n\n const { renderEnd: renderLastRow, renderStart: renderFirstRow } = rowAx.computeRange(\n scrollTop,\n scrollTop + viewportHeight,\n overscanY.start,\n overscanY.end,\n );\n\n const { renderEnd: renderLastCol, renderStart: renderFirstCol } = colAx.computeRange(\n scrollLeft,\n scrollLeft + viewportWidth,\n overscanX.start,\n overscanX.end,\n );\n\n const rowSame = rowAx.isDedupSame(renderFirstRow, renderLastRow);\n const colSame = colAx.isDedupSame(renderFirstCol, renderLastCol);\n\n if (rowSame && colSame) return;\n\n rowAx.commitDedup(renderFirstRow, renderLastRow);\n colAx.commitDedup(renderFirstCol, renderLastCol);\n\n const rangeChanged = !rowSame || !colSame;\n\n if (rangeChanged && onRangeChange) {\n onRangeChange({\n firstCol: renderFirstCol,\n firstRow: renderFirstRow,\n lastCol: renderLastCol,\n lastRow: renderLastRow,\n });\n }\n\n // R8: Build rows[] and cols[] separately — no cross-product VirtualCell[].\n const nextRows: VirtualItem[] = [];\n\n for (let r = renderFirstRow; r <= renderLastRow; r++) {\n nextRows.push(rowAx.itemAt(r));\n }\n\n const nextCols: VirtualItem[] = [];\n\n for (let c = renderFirstCol; c <= renderLastCol; c++) {\n nextCols.push(colAx.itemAt(c));\n }\n\n rows = nextRows;\n cols = nextCols;\n\n onChange?.({ cols, rows, totalHeight, totalWidth });\n }\n\n // ─── Measurement helpers ───────────────────────────────────────────────────\n\n function recordRowMeasurement(row: number, size: number): boolean {\n if (!Number.isFinite(row)) return false;\n\n const r = Math.floor(row);\n\n if (r < 0 || r >= rowCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredRows.get(r) === s) return false;\n\n measuredRows.set(r, s);\n rowAx.markChanged(r);\n\n return true;\n }\n\n function recordColMeasurement(col: number, size: number): boolean {\n if (!Number.isFinite(col)) return false;\n\n const c = Math.floor(col);\n\n if (c < 0 || c >= colCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredCols.get(c) === s) return false;\n\n measuredCols.set(c, s);\n colAx.markChanged(c);\n\n return true;\n }\n\n /**\n * R4: Single coordinated flush for both axes.\n * Replaces the previous two independent microtask schedules.\n */\n function scheduleFlush(): void {\n if (pendingBatchBuild) return;\n\n pendingBatchBuild = true;\n queueMicrotask(() => {\n pendingBatchBuild = false;\n\n // consumeMinChangedIndex() atomically reads and resets minChangedIndex.\n // Without the reset, every subsequent flush would rebuild from index 0\n // instead of the actual earliest changed index (Bug 3).\n const fromRow = rowAx.consumeMinChangedIndex();\n\n if (fromRow !== Infinity) rowAx.rebuildFrom(fromRow);\n\n const fromCol = colAx.consumeMinChangedIndex();\n\n if (fromCol !== Infinity) colAx.rebuildFrom(fromCol);\n\n computeVisible();\n });\n }\n\n // ─── Public measurement API ────────────────────────────────────────────────\n\n function measureRow(row: number, size: number): void {\n if (disposed) return;\n\n if (recordRowMeasurement(row, size)) scheduleFlush();\n }\n\n function measureColumn(col: number, size: number): void {\n if (disposed) return;\n\n if (recordColMeasurement(col, size)) scheduleFlush();\n }\n\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n function measureBatch(\n rowEntries: Array<{ index: number; size: number }>,\n colEntries: Array<{ index: number; size: number }>,\n ): void {\n if (disposed) return;\n\n let changed = false;\n\n for (const { index, size } of rowEntries) {\n if (recordRowMeasurement(index, size)) changed = true;\n }\n\n for (const { index, size } of colEntries) {\n if (recordColMeasurement(index, size)) changed = true;\n }\n\n if (changed) scheduleFlush();\n }\n\n function measureRowEl(row: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureRow(row, entry.contentRect.height));\n }\n\n function measureColEl(col: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureColumn(col, entry.contentRect.width));\n }\n\n function invalidate(): void {\n if (disposed) return;\n\n measuredRows.clear();\n measuredCols.clear();\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function refresh(): void {\n if (disposed) return;\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function prependRows(additionalRowCount: number): void {\n if (disposed) return;\n\n const n = toNonNegativeInt(additionalRowCount);\n\n if (n === 0) return;\n\n rowCount += n;\n rowAx.setCount(rowCount);\n rowAx.rebuild(true);\n\n const prependedHeight = rowAx.startAt(n);\n const newScrollTop = clampTop(scrollTop + prependedHeight);\n\n adapter.scrollTo(scrollLeft, newScrollTop, 'auto');\n scrollTop = newScrollTop;\n\n computeVisible();\n }\n\n function scrollToRow(row: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'> = {}): void {\n if (disposed || rowCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n\n if (targetTop === null) return;\n\n adapter.scrollTo(scrollLeft, clampTop(targetTop), behavior);\n }\n\n function scrollToColumn(col: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'> = {}): void {\n if (disposed || colCount === 0) return;\n\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetLeft === null) return;\n\n adapter.scrollTo(clampLeft(targetLeft), scrollTop, behavior);\n }\n\n function scrollToCell(row: number, col: number, opts: ScrollToCellOptions = {}): void {\n if (disposed || rowCount === 0 || colCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetTop === null && targetLeft === null) return;\n\n adapter.scrollTo(\n targetLeft !== null ? clampLeft(targetLeft) : scrollLeft,\n targetTop !== null ? clampTop(targetTop) : scrollTop,\n behavior,\n );\n }\n\n function update(next: GridVirtualizerUpdateOptions): void {\n if (disposed) return;\n\n let rebuildRows = false;\n let rebuildCols = false;\n let needsCompute = false;\n\n if (next.rowCount !== undefined) {\n const n = toNonNegativeInt(next.rowCount);\n\n if (n !== rowCount) {\n rowCount = n;\n rowAx.setCount(rowCount);\n rebuildRows = true;\n }\n }\n\n if (next.colCount !== undefined) {\n const n = toNonNegativeInt(next.colCount);\n\n if (n !== colCount) {\n colCount = n;\n colAx.setCount(colCount);\n rebuildCols = true;\n }\n }\n\n if (next.rowGap !== undefined) {\n const n = toNonNegativeInt(next.rowGap);\n\n if (n !== rowAx.gap) {\n rowAx.setGap(n);\n rebuildRows = true;\n }\n }\n\n if (next.colGap !== undefined) {\n const n = toNonNegativeInt(next.colGap);\n\n if (n !== colAx.gap) {\n colAx.setGap(n);\n rebuildCols = true;\n }\n }\n\n if ('estimateRowSize' in next) {\n estimateRowFn = resolveEstimateFn(next.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n measuredRows.clear();\n rebuildRows = true;\n }\n\n if ('estimateColSize' in next) {\n estimateColFn = resolveEstimateFn(next.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n measuredCols.clear();\n rebuildCols = true;\n }\n\n if (next.overscanY !== undefined) {\n const n = normalizeOverscan(next.overscanY, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanY.start || n.end !== overscanY.end) {\n overscanY = n;\n needsCompute = true;\n }\n }\n\n if (next.overscanX !== undefined) {\n const n = normalizeOverscan(next.overscanX, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanX.start || n.end !== overscanX.end) {\n overscanX = n;\n needsCompute = true;\n }\n }\n\n if (rebuildRows) rowAx.rebuild(true);\n\n if (rebuildCols) colAx.rebuild(true);\n\n if (rebuildRows || rebuildCols || needsCompute) computeVisible();\n }\n\n const ac = new AbortController();\n\n function disposeImpl(): void {\n if (disposed) return;\n\n disposed = true;\n ac.abort();\n adapter.detach();\n }\n\n // ─── Bootstrap (R9: read viewport BEFORE writing initial scroll) ───────────\n\n function handleScroll(): void {\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n computeVisible();\n }\n\n function handleResize(): void {\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n computeVisible();\n }\n\n const adapter = createScrollAdapter(target, handleScroll, handleResize);\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n\n // R9: Read viewport dimensions BEFORE writing initial scroll positions so that\n // computeVisible() sees a valid viewport on the very first call.\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n\n if (options.initialScrollTop !== undefined) {\n adapter.scrollTo(options.initialScrollLeft ?? 0, clampTop(options.initialScrollTop), 'auto');\n } else if (options.initialScrollLeft !== undefined) {\n adapter.scrollTo(clampLeft(options.initialScrollLeft), 0, 'auto');\n }\n\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n\n computeVisible();\n\n return {\n get cols() {\n return cols;\n },\n get disposalSignal() {\n return ac.signal;\n },\n dispose: disposeImpl,\n get disposed() {\n return disposed;\n },\n invalidate,\n measureBatch,\n measureColEl,\n measureColumn,\n measureRow,\n measureRowEl,\n prependRows,\n refresh,\n get rows() {\n return rows;\n },\n get scrollLeft() {\n return scrollLeft;\n },\n scrollToCell,\n scrollToColumn,\n get scrollTop() {\n return scrollTop;\n },\n scrollToRow,\n [Symbol.dispose]: disposeImpl,\n get totalHeight() {\n return rowAx.totalSize;\n },\n get totalWidth() {\n return colAx.totalSize;\n },\n update,\n };\n}\n"],"mappings":"sOAoHA,SAAS,EACP,EACA,EACA,EACA,EACA,EACA,EACe,CAUf,OATI,IAAU,QAAgB,EAE1B,IAAU,MAAc,EAAU,EAElC,IAAU,SAAiB,GAAa,EAAe,GAAY,EAGnE,GAAa,GAAiB,GAAW,EAAgB,EAAqB,KAE3E,EAAY,EAAgB,EAAY,EAAU,CAC3D,CAIA,SAAgB,EAAsB,EAAsB,EAAkD,CAC5G,IAAI,EAAW,EAAiB,EAAQ,QAAQ,EAC5C,EAAW,EAAiB,EAAQ,QAAQ,EAC5C,EAAgB,EAAkB,EAAQ,gBAAA,EAAsC,EAChF,EAAgB,EAAkB,EAAQ,gBAAA,EAAsC,EAChF,EAAY,EAAkB,EAAQ,UAAA,CAA2B,EACjE,EAAY,EAAkB,EAAQ,UAAA,CAA2B,EAG/D,EAAW,EAAQ,SACnB,EAAgB,EAAQ,cAGxB,EAAoC,EAAQ,qBAAuB,IAAI,IACvE,EAAoC,EAAQ,qBAAuB,IAAI,IAEzE,EAAY,EACZ,EAAa,EACb,EAAiB,EACjB,EAAgB,EAChB,EAAsB,CAAC,EACvB,EAAsB,CAAC,EACvB,EAAW,GAKT,EAAQ,EACZ,EACC,GAAM,EAAa,IAAI,CAAC,GAAK,EAAc,CAAC,EAC7C,EAAiB,EAAQ,QAAU,CAAC,CACtC,EAEM,EAAQ,EACZ,EACC,GAAM,EAAa,IAAI,CAAC,GAAK,EAAc,CAAC,EAC7C,EAAiB,EAAQ,QAAU,CAAC,CACtC,EAGI,EAAoB,GAIxB,SAAS,EAAS,EAAwB,CACxC,IAAM,EAAO,OAAO,SAAS,CAAM,EAAI,EAAS,EAEhD,OAAO,KAAK,IAAI,KAAK,IAAI,EAAG,EAAM,UAAY,CAAc,EAAG,KAAK,IAAI,EAAG,CAAI,CAAC,CAClF,CAEA,SAAS,EAAU,EAAwB,CACzC,IAAM,EAAO,OAAO,SAAS,CAAM,EAAI,EAAS,EAEhD,OAAO,KAAK,IAAI,KAAK,IAAI,EAAG,EAAM,UAAY,CAAa,EAAG,KAAK,IAAI,EAAG,CAAI,CAAC,CACjF,CAIA,SAAS,GAAuB,CAC9B,GAAI,EAAU,OAEd,IAAM,EAAc,EAAM,UACpB,EAAa,EAAM,UAEzB,GAAI,IAAa,GAAK,IAAa,GAAK,GAAkB,GAAK,GAAiB,EAAG,EAE/E,EAAM,YAAc,IAAM,EAAM,gBAAkB,GAAe,EAAM,gBAAkB,KAKzF,EAAM,YAAY,GAAI,EAAE,EACxB,EAAM,YAAY,GAAI,EAAE,EACxB,EAAO,CAAC,EACR,EAAO,CAAC,EACR,IAAW,CAAE,KAAM,CAAC,EAAG,KAAM,CAAC,EAAG,cAAa,YAAW,CAAC,GAG5D,MACF,CAEA,GAAM,CAAE,UAAW,EAAe,YAAa,GAAmB,EAAM,aACtE,EACA,EAAY,EACZ,EAAU,MACV,EAAU,GACZ,EAEM,CAAE,UAAW,EAAe,YAAa,GAAmB,EAAM,aACtE,EACA,EAAa,EACb,EAAU,MACV,EAAU,GACZ,EAEM,EAAU,EAAM,YAAY,EAAgB,CAAa,EACzD,EAAU,EAAM,YAAY,EAAgB,CAAa,EAE/D,GAAI,GAAW,EAAS,OAExB,EAAM,YAAY,EAAgB,CAAa,EAC/C,EAAM,YAAY,EAAgB,CAAa,GAE1B,CAAC,GAAW,CAAC,IAEd,GAClB,EAAc,CACZ,SAAU,EACV,SAAU,EACV,QAAS,EACT,QAAS,CACX,CAAC,EAIH,IAAM,EAA0B,CAAC,EAEjC,IAAK,IAAI,EAAI,EAAgB,GAAK,EAAe,IAC/C,EAAS,KAAK,EAAM,OAAO,CAAC,CAAC,EAG/B,IAAM,EAA0B,CAAC,EAEjC,IAAK,IAAI,EAAI,EAAgB,GAAK,EAAe,IAC/C,EAAS,KAAK,EAAM,OAAO,CAAC,CAAC,EAG/B,EAAO,EACP,EAAO,EAEP,IAAW,CAAE,OAAM,OAAM,cAAa,YAAW,CAAC,CACpD,CAIA,SAAS,EAAqB,EAAa,EAAuB,CAChE,GAAI,CAAC,OAAO,SAAS,CAAG,EAAG,MAAO,GAElC,IAAM,EAAI,KAAK,MAAM,CAAG,EAExB,GAAI,EAAI,GAAK,GAAK,EAAU,MAAO,GAEnC,IAAM,EAAI,EAAiB,EAAM,EAAE,EASnC,OAPI,GAAK,GAEL,EAAa,IAAI,CAAC,IAAM,EAAU,IAEtC,EAAa,IAAI,EAAG,CAAC,EACrB,EAAM,YAAY,CAAC,EAEZ,GACT,CAEA,SAAS,EAAqB,EAAa,EAAuB,CAChE,GAAI,CAAC,OAAO,SAAS,CAAG,EAAG,MAAO,GAElC,IAAM,EAAI,KAAK,MAAM,CAAG,EAExB,GAAI,EAAI,GAAK,GAAK,EAAU,MAAO,GAEnC,IAAM,EAAI,EAAiB,EAAM,EAAE,EASnC,OAPI,GAAK,GAEL,EAAa,IAAI,CAAC,IAAM,EAAU,IAEtC,EAAa,IAAI,EAAG,CAAC,EACrB,EAAM,YAAY,CAAC,EAEZ,GACT,CAMA,SAAS,GAAsB,CACzB,IAEJ,EAAoB,GACpB,mBAAqB,CACnB,EAAoB,GAKpB,IAAM,EAAU,EAAM,uBAAuB,EAEzC,IAAY,KAAU,EAAM,YAAY,CAAO,EAEnD,IAAM,EAAU,EAAM,uBAAuB,EAEzC,IAAY,KAAU,EAAM,YAAY,CAAO,EAEnD,EAAe,CACjB,CAAC,EACH,CAIA,SAAS,EAAW,EAAa,EAAoB,CAC/C,GAEA,EAAqB,EAAK,CAAI,GAAG,EAAc,CACrD,CAEA,SAAS,EAAc,EAAa,EAAoB,CAClD,GAEA,EAAqB,EAAK,CAAI,GAAG,EAAc,CACrD,CAGA,SAAS,EACP,EACA,EACM,CACN,GAAI,EAAU,OAEd,IAAI,EAAU,GAEd,IAAK,GAAM,CAAE,QAAO,UAAU,EACxB,EAAqB,EAAO,CAAI,IAAG,EAAU,IAGnD,IAAK,GAAM,CAAE,QAAO,UAAU,EACxB,EAAqB,EAAO,CAAI,IAAG,EAAU,IAG/C,GAAS,EAAc,CAC7B,CAEA,SAAS,EAAa,EAAa,EAA6B,CAG9D,OAFI,MAAuB,CAAC,EAErB,EAAc,EAAG,OAAQ,EAAK,GAAU,EAAW,EAAK,EAAM,YAAY,MAAM,CAAC,CAC1F,CAEA,SAAS,EAAa,EAAa,EAA6B,CAG9D,OAFI,MAAuB,CAAC,EAErB,EAAc,EAAG,OAAQ,EAAK,GAAU,EAAc,EAAK,EAAM,YAAY,KAAK,CAAC,CAC5F,CAEA,SAAS,GAAmB,CACtB,IAEJ,EAAa,MAAM,EACnB,EAAa,MAAM,EACnB,EAAM,QAAQ,EAAI,EAClB,EAAM,QAAQ,EAAI,EAClB,EAAe,EACjB,CAEA,SAAS,GAAgB,CACnB,IAEJ,EAAM,QAAQ,EAAI,EAClB,EAAM,QAAQ,EAAI,EAClB,EAAe,EACjB,CAEA,SAAS,EAAY,EAAkC,CACrD,GAAI,EAAU,OAEd,IAAM,EAAI,EAAiB,CAAkB,EAE7C,GAAI,IAAM,EAAG,OAEb,GAAY,EACZ,EAAM,SAAS,CAAQ,EACvB,EAAM,QAAQ,EAAI,EAElB,IAAM,EAAkB,EAAM,QAAQ,CAAC,EACjC,EAAe,EAAS,EAAY,CAAe,EAEzD,EAAQ,SAAS,EAAY,EAAc,MAAM,EACjD,EAAY,EAEZ,EAAe,CACjB,CAEA,SAAS,EAAY,EAAa,EAA2D,CAAC,EAAS,CACrG,GAAI,GAAY,IAAa,EAAG,OAEhC,IAAM,EAAU,KAAK,IAAI,EAAG,KAAK,IAAI,KAAK,MAAM,OAAO,SAAS,CAAG,EAAI,EAAM,CAAC,EAAG,EAAW,CAAC,CAAC,EACxF,EAAW,EAAK,UAAY,OAC5B,EAAW,EAAM,QAAQ,CAAO,EAChC,EAAU,EAAM,OAAO,CAAO,EAC9B,EAAY,EAChB,EACA,EAAW,EACX,EACA,EACA,EACA,EAAK,UAAY,MACnB,EAEI,IAAc,MAElB,EAAQ,SAAS,EAAY,EAAS,CAAS,EAAG,CAAQ,CAC5D,CAEA,SAAS,EAAe,EAAa,EAA2D,CAAC,EAAS,CACxG,GAAI,GAAY,IAAa,EAAG,OAEhC,IAAM,EAAU,KAAK,IAAI,EAAG,KAAK,IAAI,KAAK,MAAM,OAAO,SAAS,CAAG,EAAI,EAAM,CAAC,EAAG,EAAW,CAAC,CAAC,EACxF,EAAW,EAAK,UAAY,OAC5B,EAAW,EAAM,QAAQ,CAAO,EAChC,EAAU,EAAM,OAAO,CAAO,EAC9B,EAAa,EACjB,EACA,EAAW,EACX,EACA,EACA,EACA,EAAK,UAAY,MACnB,EAEI,IAAe,MAEnB,EAAQ,SAAS,EAAU,CAAU,EAAG,EAAW,CAAQ,CAC7D,CAEA,SAAS,EAAa,EAAa,EAAa,EAA4B,CAAC,EAAS,CACpF,GAAI,GAAY,IAAa,GAAK,IAAa,EAAG,OAElD,IAAM,EAAU,KAAK,IAAI,EAAG,KAAK,IAAI,KAAK,MAAM,OAAO,SAAS,CAAG,EAAI,EAAM,CAAC,EAAG,EAAW,CAAC,CAAC,EACxF,EAAU,KAAK,IAAI,EAAG,KAAK,IAAI,KAAK,MAAM,OAAO,SAAS,CAAG,EAAI,EAAM,CAAC,EAAG,EAAW,CAAC,CAAC,EACxF,EAAW,EAAK,UAAY,OAE5B,EAAW,EAAM,QAAQ,CAAO,EAChC,EAAU,EAAM,OAAO,CAAO,EAC9B,EAAW,EAAM,QAAQ,CAAO,EAChC,EAAU,EAAM,OAAO,CAAO,EAE9B,EAAY,EAChB,EACA,EAAW,EACX,EACA,EACA,EACA,EAAK,UAAY,MACnB,EACM,EAAa,EACjB,EACA,EAAW,EACX,EACA,EACA,EACA,EAAK,UAAY,MACnB,GAEI,IAAc,MAAQ,IAAe,OAEzC,EAAQ,SACN,IAAe,KAA+B,EAAxB,EAAU,CAAU,EAC1C,IAAc,KAA6B,EAAtB,EAAS,CAAS,EACvC,CACF,CACF,CAEA,SAAS,EAAO,EAA0C,CACxD,GAAI,EAAU,OAEd,IAAI,EAAc,GACd,EAAc,GACd,EAAe,GAEnB,GAAI,EAAK,WAAa,IAAA,GAAW,CAC/B,IAAM,EAAI,EAAiB,EAAK,QAAQ,EAEpC,IAAM,IACR,EAAW,EACX,EAAM,SAAS,CAAQ,EACvB,EAAc,GAElB,CAEA,GAAI,EAAK,WAAa,IAAA,GAAW,CAC/B,IAAM,EAAI,EAAiB,EAAK,QAAQ,EAEpC,IAAM,IACR,EAAW,EACX,EAAM,SAAS,CAAQ,EACvB,EAAc,GAElB,CAEA,GAAI,EAAK,SAAW,IAAA,GAAW,CAC7B,IAAM,EAAI,EAAiB,EAAK,MAAM,EAElC,IAAM,EAAM,MACd,EAAM,OAAO,CAAC,EACd,EAAc,GAElB,CAEA,GAAI,EAAK,SAAW,IAAA,GAAW,CAC7B,IAAM,EAAI,EAAiB,EAAK,MAAM,EAElC,IAAM,EAAM,MACd,EAAM,OAAO,CAAC,EACd,EAAc,GAElB,CAcA,GAZI,oBAAqB,IACvB,EAAgB,EAAkB,EAAK,gBAAA,EAAsC,EAC7E,EAAa,MAAM,EACnB,EAAc,IAGZ,oBAAqB,IACvB,EAAgB,EAAkB,EAAK,gBAAA,EAAsC,EAC7E,EAAa,MAAM,EACnB,EAAc,IAGZ,EAAK,YAAc,IAAA,GAAW,CAChC,IAAM,EAAI,EAAkB,EAAK,UAAA,CAA2B,GAExD,EAAE,QAAU,EAAU,OAAS,EAAE,MAAQ,EAAU,OACrD,EAAY,EACZ,EAAe,GAEnB,CAEA,GAAI,EAAK,YAAc,IAAA,GAAW,CAChC,IAAM,EAAI,EAAkB,EAAK,UAAA,CAA2B,GAExD,EAAE,QAAU,EAAU,OAAS,EAAE,MAAQ,EAAU,OACrD,EAAY,EACZ,EAAe,GAEnB,CAEI,GAAa,EAAM,QAAQ,EAAI,EAE/B,GAAa,EAAM,QAAQ,EAAI,GAE/B,GAAe,GAAe,IAAc,EAAe,CACjE,CAEA,IAAM,EAAK,IAAI,gBAEf,SAAS,GAAoB,CACvB,IAEJ,EAAW,GACX,EAAG,MAAM,EACT,EAAQ,OAAO,EACjB,CAIA,SAAS,GAAqB,CAC5B,EAAY,EAAS,EAAQ,EAAE,WAAW,CAAC,EAC3C,EAAa,EAAU,EAAQ,EAAE,WAAW,CAAC,EAC7C,EAAe,CACjB,CAEA,SAAS,GAAqB,CAC5B,EAAiB,EAAQ,EAAE,iBAAiB,EAC5C,EAAgB,EAAQ,EAAE,iBAAiB,EAC3C,EAAe,CACjB,CAEA,IAAM,EAAU,EAAoB,EAAQ,EAAc,CAAY,EAqBtE,OAnBA,EAAM,QAAQ,EAAI,EAClB,EAAM,QAAQ,EAAI,EAIlB,EAAiB,EAAQ,EAAE,iBAAiB,EAC5C,EAAgB,EAAQ,EAAE,iBAAiB,EAEvC,EAAQ,mBAAqB,IAAA,GAEtB,EAAQ,oBAAsB,IAAA,IACvC,EAAQ,SAAS,EAAU,EAAQ,iBAAiB,EAAG,EAAG,MAAM,EAFhE,EAAQ,SAAS,EAAQ,mBAAqB,EAAG,EAAS,EAAQ,gBAAgB,EAAG,MAAM,EAK7F,EAAY,EAAS,EAAQ,EAAE,WAAW,CAAC,EAC3C,EAAa,EAAU,EAAQ,EAAE,WAAW,CAAC,EAE7C,EAAe,EAER,CACL,IAAI,MAAO,CACT,OAAO,CACT,EACA,IAAI,gBAAiB,CACnB,OAAO,EAAG,MACZ,EACA,QAAS,EACT,IAAI,UAAW,CACb,OAAO,CACT,EACA,aACA,eACA,eACA,gBACA,aACA,eACA,cACA,UACA,IAAI,MAAO,CACT,OAAO,CACT,EACA,IAAI,YAAa,CACf,OAAO,CACT,EACA,eACA,iBACA,IAAI,WAAY,CACd,OAAO,CACT,EACA,eACC,OAAO,SAAU,EAClB,IAAI,aAAc,CAChB,OAAO,EAAM,SACf,EACA,IAAI,YAAa,CACf,OAAO,EAAM,SACf,EACA,QACF,CACF"}
|
package/dist/reactive.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactive.cjs","names":[],"sources":["../src/reactive.ts"],"sourcesContent":["/**\n * F1: Ripple integration layer.\n * Wraps `createVirtualizer` so the current state is exposed as a reactive\n * `Signal<VirtualizerState>` from `@vielzeug/ripple`.\n */\nimport { signal, type Signal } from '@vielzeug/ripple';\n\nimport {\n createGroupedVirtualizer,\n type GroupVirtualizer,\n type GroupVirtualizerOptions,\n type GroupVirtualizerState,\n} from './grouped-virtualizer';\nimport {\n createVirtualizer,\n type ScrollTarget,\n type Virtualizer,\n type VirtualizerOptions,\n type VirtualizerState,\n} from './virtualizer';\n\nexport type { Signal };\n\nexport interface ReactiveGroupVirtualizer<T> extends GroupVirtualizer<T> {\n /** Reactive signal carrying the current grouped virtualizer state. */\n readonly state: Signal<GroupVirtualizerState<T>>;\n}\n\nexport interface ReactiveVirtualizer extends Virtualizer {\n /** Reactive signal carrying the current virtualizer state. */\n readonly state: Signal<VirtualizerState>;\n}\n\n/**\n * Create a grouped virtualizer whose current state is exposed as a reactive signal.\n *\n * All `GroupVirtualizer` accessors remain live — they are proxied through to the\n * underlying virtualizer on every access.\n *\n * @example\n * ```ts\n * const v = createReactiveGroupedVirtualizer(el, { sections, estimateItemSize: 48 });\n * effect(() => {\n * const { headers, items, stickyHeader, totalSize } = v.state.value;\n * render(headers, items, totalSize);\n * });\n * ```\n */\nexport function createReactiveGroupedVirtualizer<T>(\n target: ScrollTarget,\n options: Omit<GroupVirtualizerOptions<T>, 'onChange'>,\n): ReactiveGroupVirtualizer<T> {\n const state = signal<GroupVirtualizerState<T>>({ headers: [], items: [], stickyHeader: null, totalSize: 0 });\n\n const v = createGroupedVirtualizer<T>(target, {\n ...options,\n onChange: (s) => {\n state.value = s;\n },\n });\n\n return new Proxy(v, {\n get(t, p, r) {\n if (p === 'state') return state;\n\n return Reflect.get(t, p, r);\n },\n getOwnPropertyDescriptor(t, p) {\n if (p === 'state') return { configurable: true, enumerable: true, value: state };\n\n return Reflect.getOwnPropertyDescriptor(t, p);\n },\n has(t, p) {\n return p === 'state' || Reflect.has(t, p);\n },\n ownKeys(t) {\n return [...Reflect.ownKeys(t), 'state'];\n },\n }) as unknown as ReactiveGroupVirtualizer<T>;\n}\n\n/**\n * Create a virtualizer whose current state is exposed as a reactive signal.\n *\n * All `Virtualizer` accessors (count, items, totalSize, scrollOffset, stickyItems)\n * remain live — they are proxied through to the underlying virtualizer on every\n * access. A Proxy is used instead of object spread, which would snapshot getter\n * values at construction time and cause stale reads after state changes.\n *\n * @example\n * ```ts\n * const v = createReactiveVirtualizer(el, { count: 1000, estimateSize: 40 });\n * effect(() => {\n * const { items, totalSize } = v.state.value;\n * render(items, totalSize);\n * });\n * ```\n */\nexport function createReactiveVirtualizer(\n target: ScrollTarget,\n options: Omit<VirtualizerOptions, 'onChange'>,\n): ReactiveVirtualizer {\n const state = signal<VirtualizerState>({ items: [], stickyItems: [], totalSize: 0 });\n\n const v = createVirtualizer(target, {\n ...options,\n onChange: (s) => {\n state.value = s;\n },\n });\n\n return new Proxy(v, {\n get(t, p, r) {\n if (p === 'state') return state;\n\n return Reflect.get(t, p, r);\n },\n getOwnPropertyDescriptor(t, p) {\n if (p === 'state') return { configurable: true, enumerable: true, value: state };\n\n return Reflect.getOwnPropertyDescriptor(t, p);\n },\n has(t, p) {\n return p === 'state' || Reflect.has(t, p);\n },\n ownKeys(t) {\n return [...Reflect.ownKeys(t), 'state'];\n },\n }) as unknown as ReactiveVirtualizer;\n}\n"],"mappings":"8GAgDA,SAAgB,EACd,EACA,EAC6B,CAC7B,IAAM,GAAA,
|
|
1
|
+
{"version":3,"file":"reactive.cjs","names":[],"sources":["../src/reactive.ts"],"sourcesContent":["/**\n * F1: Ripple integration layer.\n * Wraps `createVirtualizer` so the current state is exposed as a reactive\n * `Signal<VirtualizerState>` from `@vielzeug/ripple`.\n */\nimport { signal, type Signal } from '@vielzeug/ripple';\n\nimport {\n createGroupedVirtualizer,\n type GroupVirtualizer,\n type GroupVirtualizerOptions,\n type GroupVirtualizerState,\n} from './grouped-virtualizer';\nimport {\n createVirtualizer,\n type ScrollTarget,\n type Virtualizer,\n type VirtualizerOptions,\n type VirtualizerState,\n} from './virtualizer';\n\nexport type { Signal };\n\nexport interface ReactiveGroupVirtualizer<T> extends GroupVirtualizer<T> {\n /** Reactive signal carrying the current grouped virtualizer state. */\n readonly state: Signal<GroupVirtualizerState<T>>;\n}\n\nexport interface ReactiveVirtualizer extends Virtualizer {\n /** Reactive signal carrying the current virtualizer state. */\n readonly state: Signal<VirtualizerState>;\n}\n\n/**\n * Create a grouped virtualizer whose current state is exposed as a reactive signal.\n *\n * All `GroupVirtualizer` accessors remain live — they are proxied through to the\n * underlying virtualizer on every access.\n *\n * @example\n * ```ts\n * const v = createReactiveGroupedVirtualizer(el, { sections, estimateItemSize: 48 });\n * effect(() => {\n * const { headers, items, stickyHeader, totalSize } = v.state.value;\n * render(headers, items, totalSize);\n * });\n * ```\n */\nexport function createReactiveGroupedVirtualizer<T>(\n target: ScrollTarget,\n options: Omit<GroupVirtualizerOptions<T>, 'onChange'>,\n): ReactiveGroupVirtualizer<T> {\n const state = signal<GroupVirtualizerState<T>>({ headers: [], items: [], stickyHeader: null, totalSize: 0 });\n\n const v = createGroupedVirtualizer<T>(target, {\n ...options,\n onChange: (s) => {\n state.value = s;\n },\n });\n\n return new Proxy(v, {\n get(t, p, r) {\n if (p === 'state') return state;\n\n return Reflect.get(t, p, r);\n },\n getOwnPropertyDescriptor(t, p) {\n if (p === 'state') return { configurable: true, enumerable: true, value: state };\n\n return Reflect.getOwnPropertyDescriptor(t, p);\n },\n has(t, p) {\n return p === 'state' || Reflect.has(t, p);\n },\n ownKeys(t) {\n return [...Reflect.ownKeys(t), 'state'];\n },\n }) as unknown as ReactiveGroupVirtualizer<T>;\n}\n\n/**\n * Create a virtualizer whose current state is exposed as a reactive signal.\n *\n * All `Virtualizer` accessors (count, items, totalSize, scrollOffset, stickyItems)\n * remain live — they are proxied through to the underlying virtualizer on every\n * access. A Proxy is used instead of object spread, which would snapshot getter\n * values at construction time and cause stale reads after state changes.\n *\n * @example\n * ```ts\n * const v = createReactiveVirtualizer(el, { count: 1000, estimateSize: 40 });\n * effect(() => {\n * const { items, totalSize } = v.state.value;\n * render(items, totalSize);\n * });\n * ```\n */\nexport function createReactiveVirtualizer(\n target: ScrollTarget,\n options: Omit<VirtualizerOptions, 'onChange'>,\n): ReactiveVirtualizer {\n const state = signal<VirtualizerState>({ items: [], stickyItems: [], totalSize: 0 });\n\n const v = createVirtualizer(target, {\n ...options,\n onChange: (s) => {\n state.value = s;\n },\n });\n\n return new Proxy(v, {\n get(t, p, r) {\n if (p === 'state') return state;\n\n return Reflect.get(t, p, r);\n },\n getOwnPropertyDescriptor(t, p) {\n if (p === 'state') return { configurable: true, enumerable: true, value: state };\n\n return Reflect.getOwnPropertyDescriptor(t, p);\n },\n has(t, p) {\n return p === 'state' || Reflect.has(t, p);\n },\n ownKeys(t) {\n return [...Reflect.ownKeys(t), 'state'];\n },\n }) as unknown as ReactiveVirtualizer;\n}\n"],"mappings":"8GAgDA,SAAgB,EACd,EACA,EAC6B,CAC7B,IAAM,GAAA,EAAQ,EAAA,OAAA,CAAiC,CAAE,QAAS,CAAC,EAAG,MAAO,CAAC,EAAG,aAAc,KAAM,UAAW,CAAE,CAAC,EAErG,EAAI,EAAA,yBAA4B,EAAQ,CAC5C,GAAG,EACH,SAAW,GAAM,CACf,EAAM,MAAQ,CAChB,CACF,CAAC,EAED,OAAO,IAAI,MAAM,EAAG,CAClB,IAAI,EAAG,EAAG,EAAG,CAGX,OAFI,IAAM,QAAgB,EAEnB,QAAQ,IAAI,EAAG,EAAG,CAAC,CAC5B,EACA,yBAAyB,EAAG,EAAG,CAG7B,OAFI,IAAM,QAAgB,CAAE,aAAc,GAAM,WAAY,GAAM,MAAO,CAAM,EAExE,QAAQ,yBAAyB,EAAG,CAAC,CAC9C,EACA,IAAI,EAAG,EAAG,CACR,OAAO,IAAM,SAAW,QAAQ,IAAI,EAAG,CAAC,CAC1C,EACA,QAAQ,EAAG,CACT,MAAO,CAAC,GAAG,QAAQ,QAAQ,CAAC,EAAG,OAAO,CACxC,CACF,CAAC,CACH,CAmBA,SAAgB,EACd,EACA,EACqB,CACrB,IAAM,GAAA,EAAQ,EAAA,OAAA,CAAyB,CAAE,MAAO,CAAC,EAAG,YAAa,CAAC,EAAG,UAAW,CAAE,CAAC,EAE7E,EAAI,EAAA,kBAAkB,EAAQ,CAClC,GAAG,EACH,SAAW,GAAM,CACf,EAAM,MAAQ,CAChB,CACF,CAAC,EAED,OAAO,IAAI,MAAM,EAAG,CAClB,IAAI,EAAG,EAAG,EAAG,CAGX,OAFI,IAAM,QAAgB,EAEnB,QAAQ,IAAI,EAAG,EAAG,CAAC,CAC5B,EACA,yBAAyB,EAAG,EAAG,CAG7B,OAFI,IAAM,QAAgB,CAAE,aAAc,GAAM,WAAY,GAAM,MAAO,CAAM,EAExE,QAAQ,yBAAyB,EAAG,CAAC,CAC9C,EACA,IAAI,EAAG,EAAG,CACR,OAAO,IAAM,SAAW,QAAQ,IAAI,EAAG,CAAC,CAC1C,EACA,QAAQ,EAAG,CACT,MAAO,CAAC,GAAG,QAAQ,QAAQ,CAAC,EAAG,OAAO,CACxC,CACF,CAAC,CACH"}
|
package/dist/scroll.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@vielzeug/ripple");var t=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},n=class extends t{},r=!globalThis.__SCROLL_PROD__;function i(e){r&&console.warn(`[@vielzeug/scroll] ${e}`)}function a(){return new Map}var o=36,s=3;function c(e,t=0){return Number.isFinite(e)?Math.max(0,Math.floor(e)):t}function l(e,t){return!Number.isFinite(e)||e<=0||e>1e7?t:e}function u(e){return typeof Window<`u`&&e instanceof Window||typeof e.innerHeight==`number`&&typeof e.document==`object`}function d(e,t){if(typeof e==`number`){let n=c(e,t);return{end:n,start:n}}return{end:c(e?.end??t),start:c(e?.start??t)}}function f(e,t,n){let r=new ResizeObserver(e=>{for(let t of e)n(t)});return r.observe(t),e.addEventListener(`abort`,()=>r.disconnect(),{once:!0}),()=>r.disconnect()}function p(e,t){if(typeof e==`function`)return n=>{try{return l(e(n),t)}catch(e){return i(`estimateSize threw for index ${n}: ${e}`),t}};let n=typeof e==`number`?l(e,t):t;return()=>n}function m(e,t,n){if(u(e))return e.addEventListener(`scroll`,t,{passive:!0}),e.addEventListener(`resize`,n,{passive:!0}),{detach(){e.removeEventListener(`scroll`,t),e.removeEventListener(`resize`,n)},scrollTo:(t,n,r)=>e.scrollTo({behavior:r,left:t,top:n}),x:{readOffset:()=>e.scrollX,readViewportSize:()=>e.innerWidth,writeOffset:(t,n)=>e.scrollTo({behavior:n,left:t})},y:{readOffset:()=>e.scrollY,readViewportSize:()=>e.innerHeight,writeOffset:(t,n)=>e.scrollTo({behavior:n,top:t})}};let r=new ResizeObserver(n);return e.addEventListener(`scroll`,t,{passive:!0}),r.observe(e),{detach(){e.removeEventListener(`scroll`,t),r.disconnect()},scrollTo:(t,n,r)=>e.scrollTo({behavior:r,left:t,top:n}),x:{readOffset:()=>e.scrollLeft,readViewportSize:()=>e.clientWidth,writeOffset:(t,n)=>e.scrollTo({behavior:n,left:t})},y:{readOffset:()=>e.scrollTop,readViewportSize:()=>e.clientHeight,writeOffset:(t,n)=>e.scrollTo({behavior:n,top:t})}}}function h(e,t,n){let r=e,i=n,a=t,o=[],s=0,c=-1,l=-1,u=-1,d=!1,f=1/0;function p(e){return o[e]??0}function m(e){return p(e)+a(e)}function h(e=!1){e&&(c=-1,l=-1,u=-1);let t=[0],n=0;for(let e=0;e<r;e++)n+=a(e)+(e<r-1?i:0),t.push(n);o=t,s=n}function g(e){if(!Number.isFinite(e)||e>=r)return;c=-1,l=-1,u=-1;let t=o[e]??0;for(let n=e;n<r;n++)o[n]=t,t+=a(n)+(n<r-1?i:0);o[r]=t,s=t}function _(e){let t=0,n=r-1;for(;t<n;){let r=t+n>>1;m(r)<=e?t=r+1:n=r}return t}function v(e,t){let n=t,i=r-1;for(;n<i;){let t=n+i+1>>1;p(t)<e?n=t:i=t-1}return n}function y(e,t,n,i){let a=_(e),o=v(t,a);return{renderEnd:Math.min(r-1,o+i),renderStart:Math.max(0,a-n)}}function b(e,t){return e===c&&t===l&&s===u}function x(e,t){c=e,l=t,u=s}function S(){c=-1,l=-1,u=-1}function C(e){d||(d=!0,queueMicrotask(()=>{d=!1;let t=f;f=1/0,g(t),e()}))}function w(e){e<f&&(f=e)}function T(e){let t=p(e),n=a(e);return{end:t+n,index:e,size:n,start:t}}return{commitDedup:x,computeRange:y,consumeMinChangedIndex(){let e=f;return f=1/0,e},get count(){return r},endAt:m,findFirst:_,findLast:v,get gap(){return i},isDedupSame:b,itemAt:T,markChanged:w,get minChangedIndex(){return f},get pendingBuild(){return d},get prevEnd(){return l},get prevStart(){return c},get prevTotalSize(){return u},rebuild:h,rebuildFrom:g,resetDedup:S,scheduleBuild:C,setCount(e){r=e},setGap(e){i=e},sizeAt(e){return a(e)},startAt:p,get totalSize(){return s}}}function g(e,t){let n=!!t.horizontal,r=e=>e,i=c(t.count),a=p(t.estimateSize,36),o=c(t.gap??0),s=t.getItemKey??r,u=d(t.overscan,3),g=t.sticky??null,_=t.onChange,v=t.onScrollEnd,y=t.onScrollingChange,b=typeof t.scrollEndDelay==`number`&&t.scrollEndDelay>=0?t.scrollEndDelay:150,x=!1,S=null,C=`onscrollend`in e;function w(){x&&(x=!1,y?.(!1),v?.(M))}function T(){x||(x=!0,y?.(!0)),C||(S!==null&&clearTimeout(S),S=setTimeout(w,b))}let E=t.measurementCache??new Map,D=[],O=[],k=h(i,e=>E.get(s(e))??a(e),o),A=-1,j=0,M=0,N=0,P=-1,F=!1;function I(e){let t=Number.isFinite(e)?e:0,n=Math.max(0,k.totalSize-N);return Math.min(n,Math.max(0,t))}function L(){if(!g||i===0||M<=0)return[];let e=-1,t=0,n=i-1;for(;t<=n;){let r=t+n>>1;k.startAt(r)<M?(e=r,t=r+1):n=r-1}if(e<0)return[];let r=-1;for(let t=e;t>=0;t--)if(g(t)){r=t;break}if(r===-1)return[];let a=k.sizeAt(r),o=1/0;for(let e=r+1;e<i;e++)if(g(e)){o=k.startAt(e);break}let s=Math.min(M,o-a);return[{end:s+a,index:r,size:a,start:s}]}function R(){if(F)return;if(i===0||N<=0){(k.prevStart!==-1||k.prevTotalSize!==k.totalSize)&&(k.commitDedup(-1,-1),D=[],O=[],_&&_({items:D,stickyItems:O,totalSize:k.totalSize}));return}let{renderEnd:e,renderStart:t}=k.computeRange(M,M+N,u.start,u.end),n=g!==null&&M!==P;if(k.isDedupSame(t,e)&&!n)return;k.commitDedup(t,e),P=M;let r=[];for(let n=t;n<=e;n++)r.push(k.itemAt(n));D=r,O=g?L():[],_&&_({items:D,stickyItems:O,totalSize:k.totalSize})}function ee(e,t){if(!Number.isFinite(e))return!1;let n=Math.floor(e);if(n<0||n>=i)return!1;let r=l(t,-1);if(r<=0)return!1;let a=s(n);return E.get(a)===r?!1:(E.set(a,r),k.markChanged(n),!0)}function z(){if(M<=0||i===0){A=-1;return}A=k.findFirst(M),j=M-k.startAt(A)}function B(){if(A<0)return;let e=k.startAt(A)+j-M;if(A=-1,Math.abs(e)>=1){let t=I(M+e);$.writeOffset(t,`auto`),M=t}}function V(e){if(F)return;let t=!1;for(let{index:n,size:r}of e)ee(n,r)&&(t=!0);t&&(k.pendingBuild||z(),k.scheduleBuild(()=>{B(),R()}))}function H(e,t){V([{index:e,size:t}])}function U(e,t){return F?()=>{}:f(Z.signal,t,t=>{H(e,n?t.contentRect.width:t.contentRect.height)})}function W(e){let t=!1,n=!1;if(e.count!==void 0){let n=c(e.count);n!==i&&(i=n,k.setCount(i),t=!0)}if(Object.hasOwn(e,`estimateSize`)&&(a=p(e.estimateSize,36),E.clear(),t=!0),e.gap!==void 0){let n=c(e.gap);n!==o&&(o=n,k.setGap(o),t=!0)}if(Object.hasOwn(e,`getItemKey`)){let n=e.getItemKey??r;n!==s&&(s=n,E.clear(),t=!0)}if(Object.hasOwn(e,`measurementCache`)&&e.measurementCache!==void 0&&(E=e.measurementCache,t=!0),e.overscan!==void 0){let t=d(e.overscan,3);(t.start!==u.start||t.end!==u.end)&&(u=t,n=!0)}if(Object.hasOwn(e,`sticky`)){let t=e.sticky??null;t!==g&&(g=t,k.resetDedup()),n=!0}t&&(z(),k.rebuild(!0),B()),(n||t)&&R()}function G(){F||(E.clear(),k.rebuild(!0),R())}function K(){F||(k.rebuild(!0),R())}function q(e){if(F)return;let t=c(e);if(t===0)return;i+=t,k.setCount(i),k.rebuild(!0);let n=k.startAt(t),r=I(M+n);$.writeOffset(r,`auto`),M=r,R()}function J(e){F||W(e)}function te(t,n={}){if(F||i<=0)return;let r=Math.max(0,Math.min(Number.isFinite(t)?Math.floor(t):0,i-1)),a=n.align??`auto`,o=n.behavior??`auto`,s=k.startAt(r),c=k.sizeAt(r),l=s+c,u;if(a===`start`)u=s;else if(a===`end`)u=l-N;else if(a===`center`)u=s-(N-c)/2;else{let e=M,t=e+N;if(s>=e&&l<=t){n.onComplete&&queueMicrotask(n.onComplete);return}u=s<e?s:l-N}$.writeOffset(I(u),o),n.onComplete&&(o===`smooth`&&`onscrollend`in e?e.addEventListener(`scrollend`,n.onComplete,{once:!0}):queueMicrotask(n.onComplete))}function Y(e,t={}){F||$.writeOffset(I(e),t.behavior??`auto`)}function X(e={}){Y(0,e)}function ne(e={}){Y(Math.max(0,k.totalSize-N),e)}function re(e=0){return k.totalSize-(M+N)<=e}let Z=new AbortController;function ie(){F||(F=!0,Z.abort(),S!==null&&(clearTimeout(S),S=null),C&&e.removeEventListener(`scrollend`,w),Q.detach())}function ae(){M=I($.readOffset()),T(),R()}function oe(){N=$.readViewportSize(),R()}let Q=m(e,ae,oe),$=n?Q.x:Q.y;return C&&e.addEventListener(`scrollend`,w,{passive:!0}),k.rebuild(!0),t.initialOffset!==void 0&&$.writeOffset(I(t.initialOffset),`auto`),M=I($.readOffset()),N=$.readViewportSize(),R(),{get count(){return i},get disposalSignal(){return Z.signal},dispose:ie,get disposed(){return F},invalidate:G,isAtEnd:re,get isScrolling(){return x},get items(){return D},measure:H,measureBatch:V,measureEl:U,prepend:q,refresh:K,get scrollOffset(){return M},scrollToBottom:ne,scrollToIndex:te,scrollToOffset:Y,scrollToTop:X,get stickyItems(){return O},[Symbol.dispose]:ie,get totalSize(){return k.totalSize},update:J}}function _(){let e=new Map,t=new Map,n=[],r=!1;return{acquire(i,a){if(!r)return a();let o=e.get(i);if(o)return t.set(i,o),o;let s=n.pop()??a();return t.set(i,s),s},beginCycle(){t=new Map,r=!0},clear(){for(let t of e.values())t.remove();e.clear(),t.clear(),n.length=0,r=!1},endCycle(){if(r){r=!1;for(let[r,i]of e)t.has(r)||(i.remove(),n.push(i));e=t}}}}function v(e){let t=[],r=!1,i=new AbortController,a=e.listElement,o=_(),s=null;function c(n){let r=t[n];return r!==void 0&&e.getItemKey?e.getItemKey(n,r):n}function l(n){if(e.estimateSize===void 0)return 36;if(typeof e.estimateSize==`number`)return e.estimateSize;let r=t[n];return r===void 0?36:e.estimateSize(n,r)}function u(t){e.horizontal?(a.style.height=``,a.style.width=`${t}px`):(a.style.height=`${t}px`,a.style.width=``)}function d(e){let r=t[e.index];if(r===void 0)throw new n(`toRenderItem: index ${e.index} is out of range (currentItems.length=${t.length})`);return{...e,data:r}}function f(t){u(t.totalSize),o.beginCycle();try{e.render({items:t.items.map(d),listEl:a,recycle:(e,t)=>o.acquire(e,t),stickyItems:t.stickyItems.map(d),totalSize:t.totalSize})}finally{o.endCycle()}}function p(){o.clear(),e.clear?e.clear(a):a.textContent=``,a.style.height=``,a.style.width=``,a.style.position=``,a.style.contain=``}function m(){let t=e.stickToBottom;return t?t===!0?{enabled:!0,threshold:48}:{enabled:t.enabled??!0,threshold:t.threshold??48}:{enabled:!1,threshold:48}}function h(){let n=g(e.scrollElement,{count:t.length,estimateSize:l,gap:e.gap,getItemKey:c,horizontal:e.horizontal,measurementCache:e.measurementCache,onChange:f,overscan:e.overscan??3,sticky:e.sticky?n=>{let r=t[n];return r!==void 0&&e.sticky(n,r)}:void 0});return s=n,a.style.position=`relative`,a.style.contain=`layout`,n}function v(){r||(r=!0,i.abort(),s?.dispose(),s=null,p())}return{get count(){return s?.count??0},get disposalSignal(){return i.signal},dispose:v,get disposed(){return r},invalidate(){r||s?.invalidate()},isAtEnd(e){return s?.isAtEnd(e)??!0},get isScrolling(){return s?.isScrolling??!1},get items(){return s?.items??[]},measure(e,t){r||s?.measure(e,t)},measureBatch(e){r||s?.measureBatch(e)},measureEl(e,t){return r?()=>{}:s?.measureEl(e,t)??(()=>{})},refresh(){r||s?.refresh()},get scrollOffset(){return s?.scrollOffset??0},scrollToBottom(e){r||s?.scrollToBottom(e)},scrollToIndex(e,t){r||s?.scrollToIndex(e,t)},scrollToOffset(e,t){r||s?.scrollToOffset(e,t)},scrollToTop(e){r||s?.scrollToTop(e)},setItems(n){if(r)return;let i=m(),a=i.enabled&&(s?.isAtEnd(i.threshold)??!0);if(t=n,n.length===0){s?.dispose(),s=null,p();return}if(!s){let e=h();a&&e.scrollToBottom();return}let o=n.length!==s.count;s.update({count:n.length}),o?e.getItemKey||s.invalidate():e.getItemKey?s.refresh():s.invalidate(),a&&s.scrollToBottom()},get stickyItems(){return s?.stickyItems??[]},[Symbol.dispose]:v,get totalSize(){return s?.totalSize??0}}}function y(e,t){let n=document.createElement(`div`);n.style.cssText=t.horizontal?`overflow: auto hidden; width: 100%; height: 100%;`:`overflow: hidden auto; width: 100%; height: 100%;`,t.containerClass&&(n.className=t.containerClass);let r=document.createElement(`div`);n.appendChild(r),e.appendChild(n);let i;try{i=v({...t,listElement:r,scrollElement:n})}catch(e){throw n.remove(),e}let a=i.dispose.bind(i);return Object.assign(i,{dispose(){a(),n.remove()},[Symbol.dispose](){a(),n.remove()}})}function b(e,t,n,r,i,a){return a===`start`?e:a===`end`?t-i:a===`center`?e-(i-n)/2:e>=r&&t<=r+i?null:e<r?e:t-i}function x(e,t){let n=c(t.rowCount),r=c(t.colCount),i=p(t.estimateRowSize,36),a=p(t.estimateColSize,36),o=d(t.overscanY,3),s=d(t.overscanX,3),u=t.onChange,g=t.onRangeChange,_=t.rowMeasurementCache??new Map,v=t.colMeasurementCache??new Map,y=0,x=0,S=0,C=0,w=[],T=[],E=!1,D=h(n,e=>_.get(e)??i(e),c(t.rowGap??0)),O=h(r,e=>v.get(e)??a(e),c(t.colGap??0)),k=!1;function A(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,D.totalSize-S),Math.max(0,t))}function j(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,O.totalSize-C),Math.max(0,t))}function M(){if(E)return;let e=D.totalSize,t=O.totalSize;if(n===0||r===0||S<=0||C<=0){D.prevStart===-1&&D.prevTotalSize===e&&O.prevTotalSize===t||(D.commitDedup(-1,-1),O.commitDedup(-1,-1),w=[],T=[],u?.({cols:[],rows:[],totalHeight:e,totalWidth:t}));return}let{renderEnd:i,renderStart:a}=D.computeRange(y,y+S,o.start,o.end),{renderEnd:c,renderStart:l}=O.computeRange(x,x+C,s.start,s.end),d=D.isDedupSame(a,i),f=O.isDedupSame(l,c);if(d&&f)return;D.commitDedup(a,i),O.commitDedup(l,c),(!d||!f)&&g&&g({firstCol:l,firstRow:a,lastCol:c,lastRow:i});let p=[];for(let e=a;e<=i;e++)p.push(D.itemAt(e));let m=[];for(let e=l;e<=c;e++)m.push(O.itemAt(e));w=p,T=m,u?.({cols:T,rows:w,totalHeight:e,totalWidth:t})}function N(e,t){if(!Number.isFinite(e))return!1;let r=Math.floor(e);if(r<0||r>=n)return!1;let i=l(t,-1);return i<=0||_.get(r)===i?!1:(_.set(r,i),D.markChanged(r),!0)}function P(e,t){if(!Number.isFinite(e))return!1;let n=Math.floor(e);if(n<0||n>=r)return!1;let i=l(t,-1);return i<=0||v.get(n)===i?!1:(v.set(n,i),O.markChanged(n),!0)}function F(){k||(k=!0,queueMicrotask(()=>{k=!1;let e=D.consumeMinChangedIndex();e!==1/0&&D.rebuildFrom(e);let t=O.consumeMinChangedIndex();t!==1/0&&O.rebuildFrom(t),M()}))}function I(e,t){E||N(e,t)&&F()}function L(e,t){E||P(e,t)&&F()}function R(e,t){if(E)return;let n=!1;for(let{index:t,size:r}of e)N(t,r)&&(n=!0);for(let{index:e,size:r}of t)P(e,r)&&(n=!0);n&&F()}function ee(e,t){return E?()=>{}:f(q.signal,t,t=>I(e,t.contentRect.height))}function z(e,t){return E?()=>{}:f(q.signal,t,t=>L(e,t.contentRect.width))}function B(){E||(_.clear(),v.clear(),D.rebuild(!0),O.rebuild(!0),M())}function V(){E||(D.rebuild(!0),O.rebuild(!0),M())}function H(e){if(E)return;let t=c(e);if(t===0)return;n+=t,D.setCount(n),D.rebuild(!0);let r=D.startAt(t),i=A(y+r);X.scrollTo(x,i,`auto`),y=i,M()}function U(e,t={}){if(E||n===0)return;let r=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),n-1)),i=t.behavior??`auto`,a=D.startAt(r),o=D.sizeAt(r),s=b(a,a+o,o,y,S,t.rowAlign??`auto`);s!==null&&X.scrollTo(x,A(s),i)}function W(e,t={}){if(E||r===0)return;let n=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),r-1)),i=t.behavior??`auto`,a=O.startAt(n),o=O.sizeAt(n),s=b(a,a+o,o,x,C,t.colAlign??`auto`);s!==null&&X.scrollTo(j(s),y,i)}function G(e,t,i={}){if(E||n===0||r===0)return;let a=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),n-1)),o=Math.max(0,Math.min(Math.floor(Number.isFinite(t)?t:0),r-1)),s=i.behavior??`auto`,c=D.startAt(a),l=D.sizeAt(a),u=O.startAt(o),d=O.sizeAt(o),f=b(c,c+l,l,y,S,i.rowAlign??`auto`),p=b(u,u+d,d,x,C,i.colAlign??`auto`);f===null&&p===null||X.scrollTo(p===null?x:j(p),f===null?y:A(f),s)}function K(e){if(E)return;let t=!1,l=!1,u=!1;if(e.rowCount!==void 0){let r=c(e.rowCount);r!==n&&(n=r,D.setCount(n),t=!0)}if(e.colCount!==void 0){let t=c(e.colCount);t!==r&&(r=t,O.setCount(r),l=!0)}if(e.rowGap!==void 0){let n=c(e.rowGap);n!==D.gap&&(D.setGap(n),t=!0)}if(e.colGap!==void 0){let t=c(e.colGap);t!==O.gap&&(O.setGap(t),l=!0)}if(`estimateRowSize`in e&&(i=p(e.estimateRowSize,36),_.clear(),t=!0),`estimateColSize`in e&&(a=p(e.estimateColSize,36),v.clear(),l=!0),e.overscanY!==void 0){let t=d(e.overscanY,3);(t.start!==o.start||t.end!==o.end)&&(o=t,u=!0)}if(e.overscanX!==void 0){let t=d(e.overscanX,3);(t.start!==s.start||t.end!==s.end)&&(s=t,u=!0)}t&&D.rebuild(!0),l&&O.rebuild(!0),(t||l||u)&&M()}let q=new AbortController;function J(){E||(E=!0,q.abort(),X.detach())}function te(){y=A(X.y.readOffset()),x=j(X.x.readOffset()),M()}function Y(){S=X.y.readViewportSize(),C=X.x.readViewportSize(),M()}let X=m(e,te,Y);return D.rebuild(!0),O.rebuild(!0),S=X.y.readViewportSize(),C=X.x.readViewportSize(),t.initialScrollTop===void 0?t.initialScrollLeft!==void 0&&X.scrollTo(j(t.initialScrollLeft),0,`auto`):X.scrollTo(t.initialScrollLeft??0,A(t.initialScrollTop),`auto`),y=A(X.y.readOffset()),x=j(X.x.readOffset()),M(),{get cols(){return T},get disposalSignal(){return q.signal},dispose:J,get disposed(){return E},invalidate:B,measureBatch:R,measureColEl:z,measureColumn:L,measureRow:I,measureRowEl:ee,prependRows:H,refresh:V,get rows(){return w},get scrollLeft(){return x},scrollToCell:G,scrollToColumn:W,get scrollTop(){return y},scrollToRow:U,[Symbol.dispose]:J,get totalHeight(){return D.totalSize},get totalWidth(){return O.totalSize},update:K}}function S(e){let t=[];for(let n=0;n<e.length;n++){let r=e[n];t.push({isHeader:!0,itemIndex:-1,label:r.label,sectionIndex:n});for(let e=0;e<r.items.length;e++)t.push({isHeader:!1,item:r.items[e],itemIndex:e,sectionIndex:n})}return t}function C(e,t){let n=t.sections,r=S(n);function i(e){return typeof e==`function`?t=>{let i=r[t];return e(n[i.sectionIndex],i.sectionIndex)}:p(typeof e==`number`?e:void 0,36)}let a=i(t.estimateHeaderSize),o=typeof t.estimateItemSize==`function`?t.estimateItemSize:null,s=o?null:p(typeof t.estimateItemSize==`number`?t.estimateItemSize:void 0,36),c=t.getItemKey;function l(e){let t=r[e];return t?t.isHeader?a(e):o?o(t.item,t.itemIndex,t.sectionIndex):s(e):36}function u(e){let t=r[e];return t?t.isHeader?`__header_${t.sectionIndex}`:c?c(t.item,t.itemIndex,t.sectionIndex):e:e}let d=!1,f=[];function m(e){let t=[],n=[],i=null;for(let i of e.items){let e=r[i.index];e&&(e.isHeader?n.push({...i,label:e.label??``,sectionIndex:e.sectionIndex}):t.push({...i,data:e.item,itemIndex:e.itemIndex,sectionIndex:e.sectionIndex}))}if(e.stickyItems.length>0){let t=e.stickyItems[0],n=r[t.index];n?.isHeader&&(i={...t,label:n.label??``,sectionIndex:n.sectionIndex})}return f=t,{headers:n,items:t,stickyHeader:i,totalSize:e.totalSize}}let h=g(e,{count:r.length,estimateSize:l,getItemKey:u,horizontal:t.horizontal,measurementCache:t.measurementCache,onChange:e=>{let n=m(e);t.onChange?.(n)},onScrollEnd:t.onScrollEnd,onScrollingChange:t.onScrollingChange,overscan:t.overscan??3,scrollEndDelay:t.scrollEndDelay,sticky:e=>r[e]?.isHeader??!1}),_=new AbortController;function v(){d||(d=!0,_.abort(),h.dispose())}function y(e,t){if(e<0||e>=n.length)return-1;let r=0;for(let i=0;i<n.length;i++){if(i===e)return t===void 0?r:r+1+t;r+=1+n[i].items.length}return-1}return{get count(){return h.count},get disposalSignal(){return _.signal},dispose:v,get disposed(){return d},invalidate(){d||h.invalidate()},get isScrolling(){return h.isScrolling},get items(){return f},measure(e,t){d||h.measure(e,t)},measureBatch(e){d||h.measureBatch(e)},measureEl(e,t){return d?()=>{}:h.measureEl(e,t)},refresh(){d||h.refresh()},get scrollOffset(){return h.scrollOffset},scrollToBottom(e){d||h.scrollToBottom(e)},scrollToIndex(e,t){d||h.scrollToIndex(e,t)},scrollToItem(e,t,n={}){if(d)return;let r=y(e,t);r<0||h.scrollToIndex(r,n)},scrollToOffset(e,t){d||h.scrollToOffset(e,t)},scrollToSection(e,t={}){if(d)return;let n=y(e);n<0||h.scrollToIndex(n,t)},scrollToTop(e){d||h.scrollToTop(e)},get stickyItems(){return h.stickyItems},[Symbol.dispose]:v,get totalSize(){return h.totalSize},update(e,t){if(d)return;t&&(t.estimateHeaderSize!==void 0&&(a=i(t.estimateHeaderSize)),t.estimateItemSize!==void 0&&(o=typeof t.estimateItemSize==`function`?t.estimateItemSize:null,s=o?null:p(typeof t.estimateItemSize==`number`?t.estimateItemSize:void 0,36)),t.getItemKey!==void 0&&(c=t.getItemKey)),n=e;let l=r.length;r=S(n);let u={count:r.length};t?.measurementCache!==void 0&&(u.measurementCache=t.measurementCache),t?.overscan!==void 0&&(u.overscan=t.overscan),r.length!==l||t?.measurementCache!==void 0||t?.overscan!==void 0?h.update(u):h.refresh()}}}function w(t,n){let r=(0,e.signal)({headers:[],items:[],stickyHeader:null,totalSize:0}),i=C(t,{...n,onChange:e=>{r.value=e}});return new Proxy(i,{get(e,t,n){return t===`state`?r:Reflect.get(e,t,n)},getOwnPropertyDescriptor(e,t){return t===`state`?{configurable:!0,enumerable:!0,value:r}:Reflect.getOwnPropertyDescriptor(e,t)},has(e,t){return t===`state`||Reflect.has(e,t)},ownKeys(e){return[...Reflect.ownKeys(e),`state`]}})}function T(t,n){let r=(0,e.signal)({items:[],stickyItems:[],totalSize:0}),i=g(t,{...n,onChange:e=>{r.value=e}});return new Proxy(i,{get(e,t,n){return t===`state`?r:Reflect.get(e,t,n)},getOwnPropertyDescriptor(e,t){return t===`state`?{configurable:!0,enumerable:!0,value:r}:Reflect.getOwnPropertyDescriptor(e,t)},has(e,t){return t===`state`||Reflect.has(e,t)},ownKeys(e){return[...Reflect.ownKeys(e),`state`]}})}exports.DEFAULT_ESTIMATE_SIZE=o,exports.DEFAULT_OVERSCAN=s,exports.ScrollError=t,exports.ScrollRangeError=n,exports.createDomVirtualList=v,exports.createGridVirtualizer=x,exports.createGroupedVirtualizer=C,exports.createMeasurementCache=a,exports.createReactiveGroupedVirtualizer=w,exports.createReactiveVirtualizer=T,exports.createVirtualScroller=y,exports.createVirtualizer=g;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@vielzeug/ripple");var t=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},n=class extends t{};function r(){return new Map}var i=36,a=3;function o(e,t=0){return Number.isFinite(e)?Math.max(0,Math.floor(e)):t}function s(e,t){return!Number.isFinite(e)||e<=0||e>1e7?t:e}function c(e){return typeof Window<`u`&&e instanceof Window||typeof e.innerHeight==`number`&&typeof e.document==`object`}function l(e,t){if(typeof e==`number`){let n=o(e,t);return{end:n,start:n}}return{end:o(e?.end??t),start:o(e?.start??t)}}function u(e,t,n){let r=new ResizeObserver(e=>{for(let t of e)n(t)});return r.observe(t),e.addEventListener(`abort`,()=>r.disconnect(),{once:!0}),()=>r.disconnect()}function d(e,t){if(typeof e==`function`)return n=>{try{return s(e(n),t)}catch(e){return`${n}${e}`,t}};let n=typeof e==`number`?s(e,t):t;return()=>n}function f(e,t,n){if(c(e))return e.addEventListener(`scroll`,t,{passive:!0}),e.addEventListener(`resize`,n,{passive:!0}),{detach(){e.removeEventListener(`scroll`,t),e.removeEventListener(`resize`,n)},scrollTo:(t,n,r)=>e.scrollTo({behavior:r,left:t,top:n}),x:{readOffset:()=>e.scrollX,readViewportSize:()=>e.innerWidth,writeOffset:(t,n)=>e.scrollTo({behavior:n,left:t})},y:{readOffset:()=>e.scrollY,readViewportSize:()=>e.innerHeight,writeOffset:(t,n)=>e.scrollTo({behavior:n,top:t})}};let r=new ResizeObserver(n);return e.addEventListener(`scroll`,t,{passive:!0}),r.observe(e),{detach(){e.removeEventListener(`scroll`,t),r.disconnect()},scrollTo:(t,n,r)=>e.scrollTo({behavior:r,left:t,top:n}),x:{readOffset:()=>e.scrollLeft,readViewportSize:()=>e.clientWidth,writeOffset:(t,n)=>e.scrollTo({behavior:n,left:t})},y:{readOffset:()=>e.scrollTop,readViewportSize:()=>e.clientHeight,writeOffset:(t,n)=>e.scrollTo({behavior:n,top:t})}}}function p(e,t,n){let r=e,i=n,a=t,o=[],s=0,c=-1,l=-1,u=-1,d=!1,f=1/0;function p(e){return o[e]??0}function m(e){return p(e)+a(e)}function h(e=!1){e&&(c=-1,l=-1,u=-1);let t=[0],n=0;for(let e=0;e<r;e++)n+=a(e)+(e<r-1?i:0),t.push(n);o=t,s=n}function g(e){if(!Number.isFinite(e)||e>=r)return;c=-1,l=-1,u=-1;let t=o[e]??0;for(let n=e;n<r;n++)o[n]=t,t+=a(n)+(n<r-1?i:0);o[r]=t,s=t}function _(e){let t=0,n=r-1;for(;t<n;){let r=t+n>>1;m(r)<=e?t=r+1:n=r}return t}function v(e,t){let n=t,i=r-1;for(;n<i;){let t=n+i+1>>1;p(t)<e?n=t:i=t-1}return n}function y(e,t,n,i){let a=_(e),o=v(t,a);return{renderEnd:Math.min(r-1,o+i),renderStart:Math.max(0,a-n)}}function b(e,t){return e===c&&t===l&&s===u}function x(e,t){c=e,l=t,u=s}function S(){c=-1,l=-1,u=-1}function C(e){d||(d=!0,queueMicrotask(()=>{d=!1;let t=f;f=1/0,g(t),e()}))}function w(e){e<f&&(f=e)}function T(e){let t=p(e),n=a(e);return{end:t+n,index:e,size:n,start:t}}return{commitDedup:x,computeRange:y,consumeMinChangedIndex(){let e=f;return f=1/0,e},get count(){return r},endAt:m,findFirst:_,findLast:v,get gap(){return i},isDedupSame:b,itemAt:T,markChanged:w,get minChangedIndex(){return f},get pendingBuild(){return d},get prevEnd(){return l},get prevStart(){return c},get prevTotalSize(){return u},rebuild:h,rebuildFrom:g,resetDedup:S,scheduleBuild:C,setCount(e){r=e},setGap(e){i=e},sizeAt(e){return a(e)},startAt:p,get totalSize(){return s}}}function m(e,t){let n=!!t.horizontal,r=e=>e,i=o(t.count),a=d(t.estimateSize,36),c=o(t.gap??0),m=t.getItemKey??r,h=l(t.overscan,3),g=t.sticky??null,_=t.onChange,v=t.onScrollEnd,y=t.onScrollingChange,b=typeof t.scrollEndDelay==`number`&&t.scrollEndDelay>=0?t.scrollEndDelay:150,x=!1,S=null,C=`onscrollend`in e;function w(){x&&(x=!1,y?.(!1),v?.(M))}function T(){x||(x=!0,y?.(!0)),C||(S!==null&&clearTimeout(S),S=setTimeout(w,b))}let E=t.measurementCache??new Map,D=[],O=[],k=p(i,e=>E.get(m(e))??a(e),c),A=-1,j=0,M=0,N=0,P=-1,F=!1;function I(e){let t=Number.isFinite(e)?e:0,n=Math.max(0,k.totalSize-N);return Math.min(n,Math.max(0,t))}function L(){if(!g||i===0||M<=0)return[];let e=-1,t=0,n=i-1;for(;t<=n;){let r=t+n>>1;k.startAt(r)<M?(e=r,t=r+1):n=r-1}if(e<0)return[];let r=-1;for(let t=e;t>=0;t--)if(g(t)){r=t;break}if(r===-1)return[];let a=k.sizeAt(r),o=1/0;for(let e=r+1;e<i;e++)if(g(e)){o=k.startAt(e);break}let s=Math.min(M,o-a);return[{end:s+a,index:r,size:a,start:s}]}function R(){if(F)return;if(i===0||N<=0){(k.prevStart!==-1||k.prevTotalSize!==k.totalSize)&&(k.commitDedup(-1,-1),D=[],O=[],_&&_({items:D,stickyItems:O,totalSize:k.totalSize}));return}let{renderEnd:e,renderStart:t}=k.computeRange(M,M+N,h.start,h.end),n=g!==null&&M!==P;if(k.isDedupSame(t,e)&&!n)return;k.commitDedup(t,e),P=M;let r=[];for(let n=t;n<=e;n++)r.push(k.itemAt(n));D=r,O=g?L():[],_&&_({items:D,stickyItems:O,totalSize:k.totalSize})}function ee(e,t){if(!Number.isFinite(e))return!1;let n=Math.floor(e);if(n<0||n>=i)return!1;let r=s(t,-1);if(r<=0)return!1;let a=m(n);return E.get(a)!==r&&(E.set(a,r),k.markChanged(n),!0)}function z(){if(M<=0||i===0){A=-1;return}A=k.findFirst(M),j=M-k.startAt(A)}function B(){if(A<0)return;let e=k.startAt(A)+j-M;if(A=-1,Math.abs(e)>=1){let t=I(M+e);$.writeOffset(t,`auto`),M=t}}function V(e){if(F)return;let t=!1;for(let{index:n,size:r}of e)ee(n,r)&&(t=!0);t&&(k.pendingBuild||z(),k.scheduleBuild(()=>{B(),R()}))}function H(e,t){V([{index:e,size:t}])}function U(e,t){return F?()=>{}:u(Z.signal,t,t=>{H(e,n?t.contentRect.width:t.contentRect.height)})}function W(e){let t=!1,n=!1;if(e.count!==void 0){let n=o(e.count);n!==i&&(i=n,k.setCount(i),t=!0)}if(Object.hasOwn(e,`estimateSize`)&&(a=d(e.estimateSize,36),E.clear(),t=!0),e.gap!==void 0){let n=o(e.gap);n!==c&&(c=n,k.setGap(c),t=!0)}if(Object.hasOwn(e,`getItemKey`)){let n=e.getItemKey??r;n!==m&&(m=n,E.clear(),t=!0)}if(Object.hasOwn(e,`measurementCache`)&&e.measurementCache!==void 0&&(E=e.measurementCache,t=!0),e.overscan!==void 0){let t=l(e.overscan,3);(t.start!==h.start||t.end!==h.end)&&(h=t,n=!0)}if(Object.hasOwn(e,`sticky`)){let t=e.sticky??null;t!==g&&(g=t,k.resetDedup()),n=!0}t&&(z(),k.rebuild(!0),B()),(n||t)&&R()}function G(){F||(E.clear(),k.rebuild(!0),R())}function K(){F||(k.rebuild(!0),R())}function q(e){if(F)return;let t=o(e);if(t===0)return;i+=t,k.setCount(i),k.rebuild(!0);let n=k.startAt(t),r=I(M+n);$.writeOffset(r,`auto`),M=r,R()}function J(e){F||W(e)}function te(t,n={}){if(F||i<=0)return;let r=Math.max(0,Math.min(Number.isFinite(t)?Math.floor(t):0,i-1)),a=n.align??`auto`,o=n.behavior??`auto`,s=k.startAt(r),c=k.sizeAt(r),l=s+c,u;if(a===`start`)u=s;else if(a===`end`)u=l-N;else if(a===`center`)u=s-(N-c)/2;else{let e=M,t=e+N;if(s>=e&&l<=t){n.onComplete&&queueMicrotask(n.onComplete);return}u=s<e?s:l-N}$.writeOffset(I(u),o),n.onComplete&&(o===`smooth`&&`onscrollend`in e?e.addEventListener(`scrollend`,n.onComplete,{once:!0}):queueMicrotask(n.onComplete))}function Y(e,t={}){F||$.writeOffset(I(e),t.behavior??`auto`)}function X(e={}){Y(0,e)}function ne(e={}){Y(Math.max(0,k.totalSize-N),e)}function re(e=0){return k.totalSize-(M+N)<=e}let Z=new AbortController;function ie(){F||(F=!0,Z.abort(),S!==null&&(clearTimeout(S),S=null),C&&e.removeEventListener(`scrollend`,w),Q.detach())}function ae(){M=I($.readOffset()),T(),R()}function oe(){N=$.readViewportSize(),R()}let Q=f(e,ae,oe),$=n?Q.x:Q.y;return C&&e.addEventListener(`scrollend`,w,{passive:!0}),k.rebuild(!0),t.initialOffset!==void 0&&$.writeOffset(I(t.initialOffset),`auto`),M=I($.readOffset()),N=$.readViewportSize(),R(),{get count(){return i},get disposalSignal(){return Z.signal},dispose:ie,get disposed(){return F},invalidate:G,isAtEnd:re,get isScrolling(){return x},get items(){return D},measure:H,measureBatch:V,measureEl:U,prepend:q,refresh:K,get scrollOffset(){return M},scrollToBottom:ne,scrollToIndex:te,scrollToOffset:Y,scrollToTop:X,get stickyItems(){return O},[Symbol.dispose]:ie,get totalSize(){return k.totalSize},update:J}}function h(){let e=new Map,t=new Map,n=[],r=!1;return{acquire(i,a){if(!r)return a();let o=e.get(i);if(o)return t.set(i,o),o;let s=n.pop()??a();return t.set(i,s),s},beginCycle(){t=new Map,r=!0},clear(){for(let t of e.values())t.remove();e.clear(),t.clear(),n.length=0,r=!1},endCycle(){if(r){r=!1;for(let[r,i]of e)t.has(r)||(i.remove(),n.push(i));e=t}}}}function g(e){let t=[],r=!1,i=new AbortController,a=e.listElement,o=h(),s=null;function c(n){let r=t[n];return r!==void 0&&e.getItemKey?e.getItemKey(n,r):n}function l(n){if(e.estimateSize===void 0)return 36;if(typeof e.estimateSize==`number`)return e.estimateSize;let r=t[n];return r===void 0?36:e.estimateSize(n,r)}function u(t){e.horizontal?(a.style.height=``,a.style.width=`${t}px`):(a.style.height=`${t}px`,a.style.width=``)}function d(e){let r=t[e.index];if(r===void 0)throw new n(`toRenderItem: index ${e.index} is out of range (currentItems.length=${t.length})`);return{...e,data:r}}function f(t){u(t.totalSize),o.beginCycle();try{e.render({items:t.items.map(d),listEl:a,recycle:(e,t)=>o.acquire(e,t),stickyItems:t.stickyItems.map(d),totalSize:t.totalSize})}finally{o.endCycle()}}function p(){o.clear(),e.clear?e.clear(a):a.textContent=``,a.style.height=``,a.style.width=``,a.style.position=``,a.style.contain=``}function g(){let t=e.stickToBottom;return t?t===!0?{enabled:!0,threshold:48}:{enabled:t.enabled??!0,threshold:t.threshold??48}:{enabled:!1,threshold:48}}function _(){let n=m(e.scrollElement,{count:t.length,estimateSize:l,gap:e.gap,getItemKey:c,horizontal:e.horizontal,measurementCache:e.measurementCache,onChange:f,overscan:e.overscan??3,sticky:e.sticky?n=>{let r=t[n];return r!==void 0&&e.sticky(n,r)}:void 0});return s=n,a.style.position=`relative`,a.style.contain=`layout`,n}function v(){r||(r=!0,i.abort(),s?.dispose(),s=null,p())}return{get count(){return s?.count??0},get disposalSignal(){return i.signal},dispose:v,get disposed(){return r},invalidate(){r||s?.invalidate()},isAtEnd(e){return s?.isAtEnd(e)??!0},get isScrolling(){return s?.isScrolling??!1},get items(){return s?.items??[]},measure(e,t){r||s?.measure(e,t)},measureBatch(e){r||s?.measureBatch(e)},measureEl(e,t){return r?()=>{}:s?.measureEl(e,t)??(()=>{})},refresh(){r||s?.refresh()},get scrollOffset(){return s?.scrollOffset??0},scrollToBottom(e){r||s?.scrollToBottom(e)},scrollToIndex(e,t){r||s?.scrollToIndex(e,t)},scrollToOffset(e,t){r||s?.scrollToOffset(e,t)},scrollToTop(e){r||s?.scrollToTop(e)},setItems(n){if(r)return;let i=g(),a=i.enabled&&(s?.isAtEnd(i.threshold)??!0);if(t=n,n.length===0){s?.dispose(),s=null,p();return}if(!s){let e=_();a&&e.scrollToBottom();return}let o=n.length!==s.count;s.update({count:n.length}),o?e.getItemKey||s.invalidate():e.getItemKey?s.refresh():s.invalidate(),a&&s.scrollToBottom()},get stickyItems(){return s?.stickyItems??[]},[Symbol.dispose]:v,get totalSize(){return s?.totalSize??0}}}function _(e,t){let n=document.createElement(`div`);n.style.cssText=t.horizontal?`overflow: auto hidden; width: 100%; height: 100%;`:`overflow: hidden auto; width: 100%; height: 100%;`,t.containerClass&&(n.className=t.containerClass);let r=document.createElement(`div`);n.appendChild(r),e.appendChild(n);let i;try{i=g({...t,listElement:r,scrollElement:n})}catch(e){throw n.remove(),e}let a=i.dispose.bind(i);return Object.assign(i,{dispose(){a(),n.remove()},[Symbol.dispose](){a(),n.remove()}})}function v(e,t,n,r,i,a){return a===`start`?e:a===`end`?t-i:a===`center`?e-(i-n)/2:e>=r&&t<=r+i?null:e<r?e:t-i}function y(e,t){let n=o(t.rowCount),r=o(t.colCount),i=d(t.estimateRowSize,36),a=d(t.estimateColSize,36),c=l(t.overscanY,3),m=l(t.overscanX,3),h=t.onChange,g=t.onRangeChange,_=t.rowMeasurementCache??new Map,y=t.colMeasurementCache??new Map,b=0,x=0,S=0,C=0,w=[],T=[],E=!1,D=p(n,e=>_.get(e)??i(e),o(t.rowGap??0)),O=p(r,e=>y.get(e)??a(e),o(t.colGap??0)),k=!1;function A(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,D.totalSize-S),Math.max(0,t))}function j(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,O.totalSize-C),Math.max(0,t))}function M(){if(E)return;let e=D.totalSize,t=O.totalSize;if(n===0||r===0||S<=0||C<=0){(D.prevStart!==-1||D.prevTotalSize!==e||O.prevTotalSize!==t)&&(D.commitDedup(-1,-1),O.commitDedup(-1,-1),w=[],T=[],h?.({cols:[],rows:[],totalHeight:e,totalWidth:t}));return}let{renderEnd:i,renderStart:a}=D.computeRange(b,b+S,c.start,c.end),{renderEnd:o,renderStart:s}=O.computeRange(x,x+C,m.start,m.end),l=D.isDedupSame(a,i),u=O.isDedupSame(s,o);if(l&&u)return;D.commitDedup(a,i),O.commitDedup(s,o),(!l||!u)&&g&&g({firstCol:s,firstRow:a,lastCol:o,lastRow:i});let d=[];for(let e=a;e<=i;e++)d.push(D.itemAt(e));let f=[];for(let e=s;e<=o;e++)f.push(O.itemAt(e));w=d,T=f,h?.({cols:T,rows:w,totalHeight:e,totalWidth:t})}function N(e,t){if(!Number.isFinite(e))return!1;let r=Math.floor(e);if(r<0||r>=n)return!1;let i=s(t,-1);return i<=0||_.get(r)===i?!1:(_.set(r,i),D.markChanged(r),!0)}function P(e,t){if(!Number.isFinite(e))return!1;let n=Math.floor(e);if(n<0||n>=r)return!1;let i=s(t,-1);return i<=0||y.get(n)===i?!1:(y.set(n,i),O.markChanged(n),!0)}function F(){k||(k=!0,queueMicrotask(()=>{k=!1;let e=D.consumeMinChangedIndex();e!==1/0&&D.rebuildFrom(e);let t=O.consumeMinChangedIndex();t!==1/0&&O.rebuildFrom(t),M()}))}function I(e,t){E||N(e,t)&&F()}function L(e,t){E||P(e,t)&&F()}function R(e,t){if(E)return;let n=!1;for(let{index:t,size:r}of e)N(t,r)&&(n=!0);for(let{index:e,size:r}of t)P(e,r)&&(n=!0);n&&F()}function ee(e,t){return E?()=>{}:u(q.signal,t,t=>I(e,t.contentRect.height))}function z(e,t){return E?()=>{}:u(q.signal,t,t=>L(e,t.contentRect.width))}function B(){E||(_.clear(),y.clear(),D.rebuild(!0),O.rebuild(!0),M())}function V(){E||(D.rebuild(!0),O.rebuild(!0),M())}function H(e){if(E)return;let t=o(e);if(t===0)return;n+=t,D.setCount(n),D.rebuild(!0);let r=D.startAt(t),i=A(b+r);X.scrollTo(x,i,`auto`),b=i,M()}function U(e,t={}){if(E||n===0)return;let r=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),n-1)),i=t.behavior??`auto`,a=D.startAt(r),o=D.sizeAt(r),s=v(a,a+o,o,b,S,t.rowAlign??`auto`);s!==null&&X.scrollTo(x,A(s),i)}function W(e,t={}){if(E||r===0)return;let n=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),r-1)),i=t.behavior??`auto`,a=O.startAt(n),o=O.sizeAt(n),s=v(a,a+o,o,x,C,t.colAlign??`auto`);s!==null&&X.scrollTo(j(s),b,i)}function G(e,t,i={}){if(E||n===0||r===0)return;let a=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),n-1)),o=Math.max(0,Math.min(Math.floor(Number.isFinite(t)?t:0),r-1)),s=i.behavior??`auto`,c=D.startAt(a),l=D.sizeAt(a),u=O.startAt(o),d=O.sizeAt(o),f=v(c,c+l,l,b,S,i.rowAlign??`auto`),p=v(u,u+d,d,x,C,i.colAlign??`auto`);(f!==null||p!==null)&&X.scrollTo(p===null?x:j(p),f===null?b:A(f),s)}function K(e){if(E)return;let t=!1,s=!1,u=!1;if(e.rowCount!==void 0){let r=o(e.rowCount);r!==n&&(n=r,D.setCount(n),t=!0)}if(e.colCount!==void 0){let t=o(e.colCount);t!==r&&(r=t,O.setCount(r),s=!0)}if(e.rowGap!==void 0){let n=o(e.rowGap);n!==D.gap&&(D.setGap(n),t=!0)}if(e.colGap!==void 0){let t=o(e.colGap);t!==O.gap&&(O.setGap(t),s=!0)}if(`estimateRowSize`in e&&(i=d(e.estimateRowSize,36),_.clear(),t=!0),`estimateColSize`in e&&(a=d(e.estimateColSize,36),y.clear(),s=!0),e.overscanY!==void 0){let t=l(e.overscanY,3);(t.start!==c.start||t.end!==c.end)&&(c=t,u=!0)}if(e.overscanX!==void 0){let t=l(e.overscanX,3);(t.start!==m.start||t.end!==m.end)&&(m=t,u=!0)}t&&D.rebuild(!0),s&&O.rebuild(!0),(t||s||u)&&M()}let q=new AbortController;function J(){E||(E=!0,q.abort(),X.detach())}function te(){b=A(X.y.readOffset()),x=j(X.x.readOffset()),M()}function Y(){S=X.y.readViewportSize(),C=X.x.readViewportSize(),M()}let X=f(e,te,Y);return D.rebuild(!0),O.rebuild(!0),S=X.y.readViewportSize(),C=X.x.readViewportSize(),t.initialScrollTop===void 0?t.initialScrollLeft!==void 0&&X.scrollTo(j(t.initialScrollLeft),0,`auto`):X.scrollTo(t.initialScrollLeft??0,A(t.initialScrollTop),`auto`),b=A(X.y.readOffset()),x=j(X.x.readOffset()),M(),{get cols(){return T},get disposalSignal(){return q.signal},dispose:J,get disposed(){return E},invalidate:B,measureBatch:R,measureColEl:z,measureColumn:L,measureRow:I,measureRowEl:ee,prependRows:H,refresh:V,get rows(){return w},get scrollLeft(){return x},scrollToCell:G,scrollToColumn:W,get scrollTop(){return b},scrollToRow:U,[Symbol.dispose]:J,get totalHeight(){return D.totalSize},get totalWidth(){return O.totalSize},update:K}}function b(e){let t=[];for(let n=0;n<e.length;n++){let r=e[n];t.push({isHeader:!0,itemIndex:-1,label:r.label,sectionIndex:n});for(let e=0;e<r.items.length;e++)t.push({isHeader:!1,item:r.items[e],itemIndex:e,sectionIndex:n})}return t}function x(e,t){let n=t.sections,r=b(n);function i(e){return typeof e==`function`?t=>{let i=r[t];return e(n[i.sectionIndex],i.sectionIndex)}:d(typeof e==`number`?e:void 0,36)}let a=i(t.estimateHeaderSize),o=typeof t.estimateItemSize==`function`?t.estimateItemSize:null,s=o?null:d(typeof t.estimateItemSize==`number`?t.estimateItemSize:void 0,36),c=t.getItemKey;function l(e){let t=r[e];return t?t.isHeader?a(e):o?o(t.item,t.itemIndex,t.sectionIndex):s(e):36}function u(e){let t=r[e];return t?t.isHeader?`__header_${t.sectionIndex}`:c?c(t.item,t.itemIndex,t.sectionIndex):e:e}let f=!1,p=[];function h(e){let t=[],n=[],i=null;for(let i of e.items){let e=r[i.index];e&&(e.isHeader?n.push({...i,label:e.label??``,sectionIndex:e.sectionIndex}):t.push({...i,data:e.item,itemIndex:e.itemIndex,sectionIndex:e.sectionIndex}))}if(e.stickyItems.length>0){let t=e.stickyItems[0],n=r[t.index];n?.isHeader&&(i={...t,label:n.label??``,sectionIndex:n.sectionIndex})}return p=t,{headers:n,items:t,stickyHeader:i,totalSize:e.totalSize}}let g=m(e,{count:r.length,estimateSize:l,getItemKey:u,horizontal:t.horizontal,measurementCache:t.measurementCache,onChange:e=>{let n=h(e);t.onChange?.(n)},onScrollEnd:t.onScrollEnd,onScrollingChange:t.onScrollingChange,overscan:t.overscan??3,scrollEndDelay:t.scrollEndDelay,sticky:e=>r[e]?.isHeader??!1}),_=new AbortController;function v(){f||(f=!0,_.abort(),g.dispose())}function y(e,t){if(e<0||e>=n.length)return-1;let r=0;for(let i=0;i<n.length;i++){if(i===e)return t===void 0?r:r+1+t;r+=1+n[i].items.length}return-1}return{get count(){return g.count},get disposalSignal(){return _.signal},dispose:v,get disposed(){return f},invalidate(){f||g.invalidate()},get isScrolling(){return g.isScrolling},get items(){return p},measure(e,t){f||g.measure(e,t)},measureBatch(e){f||g.measureBatch(e)},measureEl(e,t){return f?()=>{}:g.measureEl(e,t)},refresh(){f||g.refresh()},get scrollOffset(){return g.scrollOffset},scrollToBottom(e){f||g.scrollToBottom(e)},scrollToIndex(e,t){f||g.scrollToIndex(e,t)},scrollToItem(e,t,n={}){if(f)return;let r=y(e,t);r<0||g.scrollToIndex(r,n)},scrollToOffset(e,t){f||g.scrollToOffset(e,t)},scrollToSection(e,t={}){if(f)return;let n=y(e);n<0||g.scrollToIndex(n,t)},scrollToTop(e){f||g.scrollToTop(e)},get stickyItems(){return g.stickyItems},[Symbol.dispose]:v,get totalSize(){return g.totalSize},update(e,t){if(f)return;t&&(t.estimateHeaderSize!==void 0&&(a=i(t.estimateHeaderSize)),t.estimateItemSize!==void 0&&(o=typeof t.estimateItemSize==`function`?t.estimateItemSize:null,s=o?null:d(typeof t.estimateItemSize==`number`?t.estimateItemSize:void 0,36)),t.getItemKey!==void 0&&(c=t.getItemKey)),n=e;let l=r.length;r=b(n);let u={count:r.length};t?.measurementCache!==void 0&&(u.measurementCache=t.measurementCache),t?.overscan!==void 0&&(u.overscan=t.overscan),r.length!==l||t?.measurementCache!==void 0||t?.overscan!==void 0?g.update(u):g.refresh()}}}function S(t,n){let r=(0,e.signal)({headers:[],items:[],stickyHeader:null,totalSize:0}),i=x(t,{...n,onChange:e=>{r.value=e}});return new Proxy(i,{get(e,t,n){return t===`state`?r:Reflect.get(e,t,n)},getOwnPropertyDescriptor(e,t){return t===`state`?{configurable:!0,enumerable:!0,value:r}:Reflect.getOwnPropertyDescriptor(e,t)},has(e,t){return t===`state`||Reflect.has(e,t)},ownKeys(e){return[...Reflect.ownKeys(e),`state`]}})}function C(t,n){let r=(0,e.signal)({items:[],stickyItems:[],totalSize:0}),i=m(t,{...n,onChange:e=>{r.value=e}});return new Proxy(i,{get(e,t,n){return t===`state`?r:Reflect.get(e,t,n)},getOwnPropertyDescriptor(e,t){return t===`state`?{configurable:!0,enumerable:!0,value:r}:Reflect.getOwnPropertyDescriptor(e,t)},has(e,t){return t===`state`||Reflect.has(e,t)},ownKeys(e){return[...Reflect.ownKeys(e),`state`]}})}exports.DEFAULT_ESTIMATE_SIZE=i,exports.DEFAULT_OVERSCAN=a,exports.ScrollError=t,exports.ScrollRangeError=n,exports.createDomVirtualList=g,exports.createGridVirtualizer=y,exports.createGroupedVirtualizer=x,exports.createMeasurementCache=r,exports.createReactiveGroupedVirtualizer=S,exports.createReactiveVirtualizer=C,exports.createVirtualScroller=_,exports.createVirtualizer=m;
|
|
2
2
|
//# sourceMappingURL=scroll.cjs.map
|