UNPKG

lexio

Version:

Quickest way to production grade RAG UI.

615 lines (614 loc) 21.2 kB
import * as S from "react"; import { flushSync as T } from "react-dom"; function p(o, r, e) { let s = e.initialDeps ?? [], t; function n() { var i, l, h, c; let a; e.key && ((i = e.debug) != null && i.call(e)) && (a = Date.now()); const u = o(); if (!(u.length !== s.length || u.some((m, f) => s[f] !== m))) return t; s = u; let v; if (e.key && ((l = e.debug) != null && l.call(e)) && (v = Date.now()), t = r(...u), e.key && ((h = e.debug) != null && h.call(e))) { const m = Math.round((Date.now() - a) * 100) / 100, f = Math.round((Date.now() - v) * 100) / 100, x = f / 16, E = (g, C) => { for (g = String(g); g.length < C; ) g = " " + g; return g; }; console.info( `%c⏱ ${E(f, 5)} /${E(m, 5)} ms`, ` font-size: .6rem; font-weight: bold; color: hsl(${Math.max( 0, Math.min(120 - 120 * x, 120) )}deg 100% 31%);`, e == null ? void 0 : e.key ); } return (c = e == null ? void 0 : e.onChange) == null || c.call(e, t), t; } return n.updateDeps = (i) => { s = i; }, n; } function z(o, r) { if (o === void 0) throw new Error(`Unexpected undefined${r ? `: ${r}` : ""}`); return o; } const R = (o, r) => Math.abs(o - r) < 1, M = (o, r, e) => { let s; return function(...t) { o.clearTimeout(s), s = o.setTimeout(() => r.apply(this, t), e); }; }, _ = (o) => o, W = (o) => { const r = Math.max(o.startIndex - o.overscan, 0), e = Math.min(o.endIndex + o.overscan, o.count - 1), s = []; for (let t = r; t <= e; t++) s.push(t); return s; }, k = (o, r) => { const e = o.scrollElement; if (!e) return; const s = o.targetWindow; if (!s) return; const t = (i) => { const { width: l, height: h } = i; r({ width: Math.round(l), height: Math.round(h) }); }; if (t(e.getBoundingClientRect()), !s.ResizeObserver) return () => { }; const n = new s.ResizeObserver((i) => { const l = () => { const h = i[0]; if (h != null && h.borderBoxSize) { const c = h.borderBoxSize[0]; if (c) { t({ width: c.inlineSize, height: c.blockSize }); return; } } t(e.getBoundingClientRect()); }; o.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(l) : l(); }); return n.observe(e, { box: "border-box" }), () => { n.unobserve(e); }; }, b = { passive: !0 }, A = (o, r) => { const e = o.scrollElement; if (!e) return; const s = () => { r({ width: e.innerWidth, height: e.innerHeight }); }; return s(), e.addEventListener("resize", s, b), () => { e.removeEventListener("resize", s); }; }, w = typeof window > "u" ? !0 : "onscrollend" in window, D = (o, r) => { const e = o.scrollElement; if (!e) return; const s = o.targetWindow; if (!s) return; let t = 0; const n = o.options.useScrollendEvent && w ? () => { } : M( s, () => { r(t, !1); }, o.options.isScrollingResetDelay ), i = (a) => () => { const { horizontal: u, isRtl: d } = o.options; t = u ? e.scrollLeft * (d && -1 || 1) : e.scrollTop, n(), r(t, a); }, l = i(!0), h = i(!1); h(), e.addEventListener("scroll", l, b); const c = o.options.useScrollendEvent && w; return c && e.addEventListener("scrollend", h, b), () => { e.removeEventListener("scroll", l), c && e.removeEventListener("scrollend", h); }; }, F = (o, r) => { const e = o.scrollElement; if (!e) return; const s = o.targetWindow; if (!s) return; let t = 0; const n = o.options.useScrollendEvent && w ? () => { } : M( s, () => { r(t, !1); }, o.options.isScrollingResetDelay ), i = (a) => () => { t = e[o.options.horizontal ? "scrollX" : "scrollY"], n(), r(t, a); }, l = i(!0), h = i(!1); h(), e.addEventListener("scroll", l, b); const c = o.options.useScrollendEvent && w; return c && e.addEventListener("scrollend", h, b), () => { e.removeEventListener("scroll", l), c && e.removeEventListener("scrollend", h); }; }, L = (o, r, e) => { if (r != null && r.borderBoxSize) { const s = r.borderBoxSize[0]; if (s) return Math.round( s[e.options.horizontal ? "inlineSize" : "blockSize"] ); } return Math.round( o.getBoundingClientRect()[e.options.horizontal ? "width" : "height"] ); }, j = (o, { adjustments: r = 0, behavior: e }, s) => { var t, n; const i = o + r; (n = (t = s.scrollElement) == null ? void 0 : t.scrollTo) == null || n.call(t, { [s.options.horizontal ? "left" : "top"]: i, behavior: e }); }, B = (o, { adjustments: r = 0, behavior: e }, s) => { var t, n; const i = o + r; (n = (t = s.scrollElement) == null ? void 0 : t.scrollTo) == null || n.call(t, { [s.options.horizontal ? "left" : "top"]: i, behavior: e }); }; class P { constructor(r) { this.unsubs = [], this.scrollElement = null, this.targetWindow = null, this.isScrolling = !1, this.scrollToIndexTimeoutId = null, this.measurementsCache = [], this.itemSizeCache = /* @__PURE__ */ new Map(), this.pendingMeasuredCacheIndexes = [], this.scrollRect = null, this.scrollOffset = null, this.scrollDirection = null, this.scrollAdjustments = 0, this.elementsCache = /* @__PURE__ */ new Map(), this.observer = /* @__PURE__ */ (() => { let e = null; const s = () => e || (!this.targetWindow || !this.targetWindow.ResizeObserver ? null : e = new this.targetWindow.ResizeObserver((t) => { t.forEach((n) => { const i = () => { this._measureElement(n.target, n); }; this.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(i) : i(); }); })); return { disconnect: () => { var t; (t = s()) == null || t.disconnect(), e = null; }, observe: (t) => { var n; return (n = s()) == null ? void 0 : n.observe(t, { box: "border-box" }); }, unobserve: (t) => { var n; return (n = s()) == null ? void 0 : n.unobserve(t); } }; })(), this.range = null, this.setOptions = (e) => { Object.entries(e).forEach(([s, t]) => { typeof t > "u" && delete e[s]; }), this.options = { debug: !1, initialOffset: 0, overscan: 1, paddingStart: 0, paddingEnd: 0, scrollPaddingStart: 0, scrollPaddingEnd: 0, horizontal: !1, getItemKey: _, rangeExtractor: W, onChange: () => { }, measureElement: L, initialRect: { width: 0, height: 0 }, scrollMargin: 0, gap: 0, indexAttribute: "data-index", initialMeasurementsCache: [], lanes: 1, isScrollingResetDelay: 150, enabled: !0, isRtl: !1, useScrollendEvent: !1, useAnimationFrameWithResizeObserver: !1, ...e }; }, this.notify = (e) => { var s, t; (t = (s = this.options).onChange) == null || t.call(s, this, e); }, this.maybeNotify = p( () => (this.calculateRange(), [ this.isScrolling, this.range ? this.range.startIndex : null, this.range ? this.range.endIndex : null ]), (e) => { this.notify(e); }, { key: !1, debug: () => this.options.debug, initialDeps: [ this.isScrolling, this.range ? this.range.startIndex : null, this.range ? this.range.endIndex : null ] } ), this.cleanup = () => { this.unsubs.filter(Boolean).forEach((e) => e()), this.unsubs = [], this.observer.disconnect(), this.scrollElement = null, this.targetWindow = null; }, this._didMount = () => () => { this.cleanup(); }, this._willUpdate = () => { var e; const s = this.options.enabled ? this.options.getScrollElement() : null; if (this.scrollElement !== s) { if (this.cleanup(), !s) { this.maybeNotify(); return; } this.scrollElement = s, this.scrollElement && "ownerDocument" in this.scrollElement ? this.targetWindow = this.scrollElement.ownerDocument.defaultView : this.targetWindow = ((e = this.scrollElement) == null ? void 0 : e.window) ?? null, this.elementsCache.forEach((t) => { this.observer.observe(t); }), this._scrollToOffset(this.getScrollOffset(), { adjustments: void 0, behavior: void 0 }), this.unsubs.push( this.options.observeElementRect(this, (t) => { this.scrollRect = t, this.maybeNotify(); }) ), this.unsubs.push( this.options.observeElementOffset(this, (t, n) => { this.scrollAdjustments = 0, this.scrollDirection = n ? this.getScrollOffset() < t ? "forward" : "backward" : null, this.scrollOffset = t, this.isScrolling = n, this.maybeNotify(); }) ); } }, this.getSize = () => this.options.enabled ? (this.scrollRect = this.scrollRect ?? this.options.initialRect, this.scrollRect[this.options.horizontal ? "width" : "height"]) : (this.scrollRect = null, 0), this.getScrollOffset = () => this.options.enabled ? (this.scrollOffset = this.scrollOffset ?? (typeof this.options.initialOffset == "function" ? this.options.initialOffset() : this.options.initialOffset), this.scrollOffset) : (this.scrollOffset = null, 0), this.getFurthestMeasurement = (e, s) => { const t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(); for (let i = s - 1; i >= 0; i--) { const l = e[i]; if (t.has(l.lane)) continue; const h = n.get( l.lane ); if (h == null || l.end > h.end ? n.set(l.lane, l) : l.end < h.end && t.set(l.lane, !0), t.size === this.options.lanes) break; } return n.size === this.options.lanes ? Array.from(n.values()).sort((i, l) => i.end === l.end ? i.index - l.index : i.end - l.end)[0] : void 0; }, this.getMeasurementOptions = p( () => [ this.options.count, this.options.paddingStart, this.options.scrollMargin, this.options.getItemKey, this.options.enabled ], (e, s, t, n, i) => (this.pendingMeasuredCacheIndexes = [], { count: e, paddingStart: s, scrollMargin: t, getItemKey: n, enabled: i }), { key: !1 } ), this.getMeasurements = p( () => [this.getMeasurementOptions(), this.itemSizeCache], ({ count: e, paddingStart: s, scrollMargin: t, getItemKey: n, enabled: i }, l) => { if (!i) return this.measurementsCache = [], this.itemSizeCache.clear(), []; this.measurementsCache.length === 0 && (this.measurementsCache = this.options.initialMeasurementsCache, this.measurementsCache.forEach((a) => { this.itemSizeCache.set(a.key, a.size); })); const h = this.pendingMeasuredCacheIndexes.length > 0 ? Math.min(...this.pendingMeasuredCacheIndexes) : 0; this.pendingMeasuredCacheIndexes = []; const c = this.measurementsCache.slice(0, h); for (let a = h; a < e; a++) { const u = n(a), d = this.options.lanes === 1 ? c[a - 1] : this.getFurthestMeasurement(c, a), v = d ? d.end + this.options.gap : s + t, m = l.get(u), f = typeof m == "number" ? m : this.options.estimateSize(a), x = v + f, E = d ? d.lane : a % this.options.lanes; c[a] = { index: a, start: v, size: f, end: x, key: u, lane: E }; } return this.measurementsCache = c, c; }, { key: !1, debug: () => this.options.debug } ), this.calculateRange = p( () => [ this.getMeasurements(), this.getSize(), this.getScrollOffset(), this.options.lanes ], (e, s, t, n) => this.range = e.length > 0 && s > 0 ? V({ measurements: e, outerSize: s, scrollOffset: t, lanes: n }) : null, { key: !1, debug: () => this.options.debug } ), this.getVirtualIndexes = p( () => { let e = null, s = null; const t = this.calculateRange(); return t && (e = t.startIndex, s = t.endIndex), this.maybeNotify.updateDeps([this.isScrolling, e, s]), [ this.options.rangeExtractor, this.options.overscan, this.options.count, e, s ]; }, (e, s, t, n, i) => n === null || i === null ? [] : e({ startIndex: n, endIndex: i, overscan: s, count: t }), { key: !1, debug: () => this.options.debug } ), this.indexFromElement = (e) => { const s = this.options.indexAttribute, t = e.getAttribute(s); return t ? parseInt(t, 10) : (console.warn( `Missing attribute name '${s}={index}' on measured element.` ), -1); }, this._measureElement = (e, s) => { const t = this.indexFromElement(e), n = this.measurementsCache[t]; if (!n) return; const i = n.key, l = this.elementsCache.get(i); l !== e && (l && this.observer.unobserve(l), this.observer.observe(e), this.elementsCache.set(i, e)), e.isConnected && this.resizeItem(t, this.options.measureElement(e, s, this)); }, this.resizeItem = (e, s) => { const t = this.measurementsCache[e]; if (!t) return; const n = this.itemSizeCache.get(t.key) ?? t.size, i = s - n; i !== 0 && ((this.shouldAdjustScrollPositionOnItemSizeChange !== void 0 ? this.shouldAdjustScrollPositionOnItemSizeChange(t, i, this) : t.start < this.getScrollOffset() + this.scrollAdjustments) && this._scrollToOffset(this.getScrollOffset(), { adjustments: this.scrollAdjustments += i, behavior: void 0 }), this.pendingMeasuredCacheIndexes.push(t.index), this.itemSizeCache = new Map(this.itemSizeCache.set(t.key, s)), this.notify(!1)); }, this.measureElement = (e) => { if (!e) { this.elementsCache.forEach((s, t) => { s.isConnected || (this.observer.unobserve(s), this.elementsCache.delete(t)); }); return; } this._measureElement(e, void 0); }, this.getVirtualItems = p( () => [this.getVirtualIndexes(), this.getMeasurements()], (e, s) => { const t = []; for (let n = 0, i = e.length; n < i; n++) { const l = e[n], h = s[l]; t.push(h); } return t; }, { key: !1, debug: () => this.options.debug } ), this.getVirtualItemForOffset = (e) => { const s = this.getMeasurements(); if (s.length !== 0) return z( s[I( 0, s.length - 1, (t) => z(s[t]).start, e )] ); }, this.getOffsetForAlignment = (e, s, t = 0) => { const n = this.getSize(), i = this.getScrollOffset(); s === "auto" && (s = e >= i + n ? "end" : "start"), s === "center" ? e += (t - n) / 2 : s === "end" && (e -= n); const l = this.options.horizontal ? "scrollWidth" : "scrollHeight", c = (this.scrollElement ? "document" in this.scrollElement ? this.scrollElement.document.documentElement[l] : this.scrollElement[l] : 0) - n; return Math.max(Math.min(c, e), 0); }, this.getOffsetForIndex = (e, s = "auto") => { e = Math.max(0, Math.min(e, this.options.count - 1)); const t = this.measurementsCache[e]; if (!t) return; const n = this.getSize(), i = this.getScrollOffset(); if (s === "auto") if (t.end >= i + n - this.options.scrollPaddingEnd) s = "end"; else if (t.start <= i + this.options.scrollPaddingStart) s = "start"; else return [i, s]; const l = s === "end" ? t.end + this.options.scrollPaddingEnd : t.start - this.options.scrollPaddingStart; return [ this.getOffsetForAlignment(l, s, t.size), s ]; }, this.isDynamicMode = () => this.elementsCache.size > 0, this.cancelScrollToIndex = () => { this.scrollToIndexTimeoutId !== null && this.targetWindow && (this.targetWindow.clearTimeout(this.scrollToIndexTimeoutId), this.scrollToIndexTimeoutId = null); }, this.scrollToOffset = (e, { align: s = "start", behavior: t } = {}) => { this.cancelScrollToIndex(), t === "smooth" && this.isDynamicMode() && console.warn( "The `smooth` scroll behavior is not fully supported with dynamic size." ), this._scrollToOffset(this.getOffsetForAlignment(e, s), { adjustments: void 0, behavior: t }); }, this.scrollToIndex = (e, { align: s = "auto", behavior: t } = {}) => { e = Math.max(0, Math.min(e, this.options.count - 1)), this.cancelScrollToIndex(), t === "smooth" && this.isDynamicMode() && console.warn( "The `smooth` scroll behavior is not fully supported with dynamic size." ); const n = this.getOffsetForIndex(e, s); if (!n) return; const [i, l] = n; this._scrollToOffset(i, { adjustments: void 0, behavior: t }), t !== "smooth" && this.isDynamicMode() && this.targetWindow && (this.scrollToIndexTimeoutId = this.targetWindow.setTimeout(() => { if (this.scrollToIndexTimeoutId = null, this.elementsCache.has( this.options.getItemKey(e) )) { const [c] = z( this.getOffsetForIndex(e, l) ); R(c, this.getScrollOffset()) || this.scrollToIndex(e, { align: l, behavior: t }); } else this.scrollToIndex(e, { align: l, behavior: t }); })); }, this.scrollBy = (e, { behavior: s } = {}) => { this.cancelScrollToIndex(), s === "smooth" && this.isDynamicMode() && console.warn( "The `smooth` scroll behavior is not fully supported with dynamic size." ), this._scrollToOffset(this.getScrollOffset() + e, { adjustments: void 0, behavior: s }); }, this.getTotalSize = () => { var e; const s = this.getMeasurements(); let t; if (s.length === 0) t = this.options.paddingStart; else if (this.options.lanes === 1) t = ((e = s[s.length - 1]) == null ? void 0 : e.end) ?? 0; else { const n = Array(this.options.lanes).fill(null); let i = s.length - 1; for (; i >= 0 && n.some((l) => l === null); ) { const l = s[i]; n[l.lane] === null && (n[l.lane] = l.end), i--; } t = Math.max(...n.filter((l) => l !== null)); } return Math.max( t - this.options.scrollMargin + this.options.paddingEnd, 0 ); }, this._scrollToOffset = (e, { adjustments: s, behavior: t }) => { this.options.scrollToFn(e, { behavior: t, adjustments: s }, this); }, this.measure = () => { this.itemSizeCache = /* @__PURE__ */ new Map(), this.notify(!1); }, this.setOptions(r); } } const I = (o, r, e, s) => { for (; o <= r; ) { const t = (o + r) / 2 | 0, n = e(t); if (n < s) o = t + 1; else if (n > s) r = t - 1; else return t; } return o > 0 ? o - 1 : 0; }; function V({ measurements: o, outerSize: r, scrollOffset: e, lanes: s }) { const t = o.length - 1, n = (h) => o[h].start; if (o.length <= s) return { startIndex: 0, endIndex: t }; let i = I( 0, t, n, e ), l = i; if (s === 1) for (; l < t && o[l].end < e + r; ) l++; else if (s > 1) { const h = Array(s).fill(0); for (; l < t && h.some((a) => a < e + r); ) { const a = o[l]; h[a.lane] = a.end, l++; } const c = Array(s).fill(e + r); for (; i >= 0 && c.some((a) => a >= e); ) { const a = o[i]; c[a.lane] = a.start, i--; } i = Math.max(0, i - i % s), l = Math.min(t, l + (s - 1 - l % s)); } return { startIndex: i, endIndex: l }; } const y = typeof document < "u" ? S.useLayoutEffect : S.useEffect; function O(o) { const r = S.useReducer(() => ({}), {})[1], e = { ...o, onChange: (t, n) => { var i; n ? T(r) : r(), (i = o.onChange) == null || i.call(o, t, n); } }, [s] = S.useState( () => new P(e) ); return s.setOptions(e), y(() => s._didMount(), []), y(() => s._willUpdate()), s; } function H(o) { return O({ observeElementRect: k, observeElementOffset: D, scrollToFn: B, ...o }); } function $(o) { return O({ getScrollElement: () => typeof document < "u" ? window : null, observeElementRect: A, observeElementOffset: F, scrollToFn: j, initialOffset: () => typeof document < "u" ? window.scrollY : 0, ...o }); } export { P as Virtualizer, R as approxEqual, M as debounce, _ as defaultKeyExtractor, W as defaultRangeExtractor, B as elementScroll, L as measureElement, p as memo, z as notUndefined, D as observeElementOffset, k as observeElementRect, F as observeWindowOffset, A as observeWindowRect, H as useVirtualizer, $ as useWindowVirtualizer, j as windowScroll };