hightable
Version:
A dynamic windowed scrolling table component for react
292 lines (291 loc) • 11 kB
JavaScript
function x(e) {
return JSON.stringify(e);
}
function N(e) {
return JSON.parse(e);
}
function D({ sortableColumns: e, orderBy: n, exclusiveSort: t }) {
if (!n) return;
const o = n.map(({ column: r }) => r).filter((r) => !e?.has(r));
if (o.length > 0)
throw new Error(`Unsortable columns in orderBy field: ${o.join(", ")}`);
if (t && n.length > 1)
throw new Error("DataFrame is exclusiveSort, but orderBy contains multiple columns");
}
function W(e, n) {
return !e && !n ? !0 : !e || !n || e.length !== n.length ? !1 : e.every((t, o) => {
const r = n[o];
return r ? t.column === r.column && t.direction === r.direction : !1;
});
}
function S(e, n) {
const t = [];
let o;
const r = [];
for (const u of e)
o ? r.push(u) : u.column === n ? o = u : t.push(u);
return { prefix: t, item: o, suffix: r };
}
function z(e, n) {
const { prefix: t, item: o, suffix: r } = S(n, e);
return o && t.length === 0 ? o.direction === "ascending" ? [{ column: e, direction: "descending" }, ...r] : [...r] : [{ column: e, direction: "ascending" }, ...t, ...r];
}
function G(e, n) {
const { item: t } = S(n, e);
return t ? t.direction === "ascending" ? [{ column: e, direction: "descending" }] : [] : [{ column: e, direction: "ascending" }];
}
function j(e) {
const n = e.map((i, c) => ({ value: i, index: c })), t = Array.from(n).sort(({ value: i }, { value: c }) => i < c ? -1 : i > c ? 1 : 0), o = Array(t.length).fill(-1);
let r = 0, u;
for (const [i, { value: c, index: f }] of t.entries())
c === u ? o[f] = r : (o[f] = i, r = i, u = c);
return o;
}
function M(e) {
return ({ row: n, orderBy: t }) => {
if (w({ row: n, data: { numRows: e.numRows } }), t && t.length > 0)
throw new Error("orderBy is not supported in this getRowNumber implementation.");
return { value: n };
};
}
function A({ row: e, orderBy: n, data: t }) {
w({ row: e, data: { numRows: t.numRows } }), E({ orderBy: n, data: { columnDescriptors: t.columnDescriptors } });
}
function P({ row: e, column: n, orderBy: t, data: o }) {
w({ row: e, data: { numRows: o.numRows } }), y({ column: n, data: { columnDescriptors: o.columnDescriptors } }), E({ orderBy: t, data: { columnDescriptors: o.columnDescriptors } });
}
function T({ rowStart: e, rowEnd: n, columns: t, orderBy: o, data: r }) {
if (e < 0 || n > r.numRows || !Number.isInteger(e) || !Number.isInteger(n) || e > n)
throw new Error(`Invalid row range: ${e} - ${n}, numRows: ${r.numRows}`);
const u = r.columnDescriptors.map((i) => i.name);
if (t?.some((i) => !u.includes(i)))
throw new Error(`Invalid columns: ${t.join(", ")}. Available columns: ${u.join(", ")}`);
E({ orderBy: o, data: r });
}
function w({ row: e, data: n }) {
if (e < 0 || e >= n.numRows || !Number.isInteger(e))
throw new Error(`Invalid row index: ${e}, numRows: ${n.numRows}`);
}
function y({ column: e, data: n }) {
const t = n.columnDescriptors.map((o) => o.name);
if (!t.includes(e))
throw new Error(`Invalid column: ${e}. Available columns: ${t.join(", ")}`);
}
function E({ orderBy: e, data: n }) {
const t = new Set(n.columnDescriptors.filter((o) => o.sortable).map((o) => o.name));
D({ orderBy: e, sortableColumns: t, exclusiveSort: n.exclusiveSort });
}
function B(e) {
if (e?.aborted)
throw new DOMException("The operation was aborted.", "AbortError");
}
const U = CustomEvent;
function k() {
return new EventTarget();
}
function V(e, n, t = {}) {
const o = t.columnDescriptors ?? Object.keys(e[0] ?? {}).map((a) => ({ name: a })), r = k(), i = {
_array: new Proxy(e, {
set(a, m, h) {
const g = Reflect.set(a, m, h);
return m === "length" ? r.dispatchEvent(new CustomEvent("numrowschange")) : r.dispatchEvent(new CustomEvent("update")), g;
}
}),
_rowNumbers: n,
metadata: t.metadata,
columnDescriptors: o,
getRowNumber: c,
getCell: f,
get numRows() {
return this._array.length;
},
eventTarget: r
};
function c({ row: a, orderBy: m }) {
if (A({ row: a, orderBy: m, data: { numRows: 1 / 0, columnDescriptors: o } }), !n)
return a < e.length ? { value: a } : void 0;
if (n[a] !== void 0) {
if (n[a] < 0 || !Number.isInteger(n[a]))
throw new Error(`Invalid row number: ${n[a]} for row ${a}`);
return { value: n[a] };
}
}
function f({ row: a, column: m, orderBy: h }) {
P({ column: m, row: a, orderBy: h, data: { numRows: 1 / 0, columnDescriptors: o } });
const g = e[a];
if (g)
return { value: g[m] };
}
return i;
}
function q(e, n) {
const t = n?.sortableColumns ?? new Set(e.columnDescriptors.map((s) => s.name)), o = n?.exclusiveSort ?? e.exclusiveSort;
for (const s of t)
y({ column: s, data: { columnDescriptors: e.columnDescriptors } });
if (e.columnDescriptors.every(({ name: s, sortable: l }) => t.has(s) ? l === !0 : l === !1 || l === void 0))
return n && "exclusiveSort" in n && e.exclusiveSort !== n.exclusiveSort ? { ...e, exclusiveSort: n.exclusiveSort } : e;
const r = e.columnDescriptors.map(({ name: s, metadata: l }) => ({
name: s,
sortable: t.has(s),
metadata: structuredClone(l)
// Create a deep copy of the column metadata to avoid mutating the original
})), u = structuredClone(e.metadata), i = k(), c = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map();
function a({ orderBy: s, signal: l, refresh: d }) {
return L({
orderBy: s,
signal: l,
ranksByColumn: c,
indexes: d ? void 0 : f.get(x(s)),
setIndexes: ({ orderBy: v, indexes: p }) => {
f.set(x(v), p), d || i.dispatchEvent(new CustomEvent("resolve"));
},
data: e
});
}
function m() {
return Promise.all([...f.keys()].map(
(s) => a({ orderBy: N(s), refresh: !0 })
));
}
e.eventTarget?.addEventListener("update", async () => {
await m(), i.dispatchEvent(new CustomEvent("update"));
}), e.eventTarget?.addEventListener("numrowschange", async () => {
await m(), i.dispatchEvent(new CustomEvent("numrowschange"));
});
const h = function({ row: s, orderBy: l }) {
if (w({ row: s, data: { numRows: 1 / 0 } }), D({ orderBy: l, sortableColumns: t, exclusiveSort: o }), !l || l.length === 0)
return { value: s };
const d = x(l), p = f.get(d)?.[s];
if (p !== void 0)
return { value: p };
};
return {
metadata: u,
columnDescriptors: r,
getRowNumber: function({ row: s, orderBy: l }) {
w({ row: s, data: { numRows: 1 / 0 } });
const d = h({ row: s, orderBy: l });
if (d)
return e.getRowNumber({ row: d.value });
},
getCell: function({ row: s, column: l, orderBy: d }) {
y({ column: l, data: { columnDescriptors: r } }), w({ row: s, data: { numRows: 1 / 0 } });
const v = h({ row: s, orderBy: d });
if (v)
return e.getCell({ row: v.value, column: l });
},
fetch: async function({ rowStart: s, rowEnd: l, columns: d, orderBy: v, signal: p }) {
T({ rowStart: s, rowEnd: l, columns: d, orderBy: v, data: { numRows: 1 / 0, columnDescriptors: r } });
function C() {
i.dispatchEvent(new CustomEvent("resolve"));
}
e.eventTarget?.addEventListener("resolve", C);
try {
if (!v || v.length === 0) {
await e.fetch?.({ rowStart: s, rowEnd: l, columns: d, signal: p });
return;
}
if (s === l)
return;
const O = await a({ orderBy: v, signal: p });
d && d.length > 0 && e.fetch && await F({ columns: d, signal: p, indexes: O.slice(s, l), fetch: e.fetch });
} finally {
e.eventTarget?.removeEventListener("resolve", C);
}
},
eventTarget: i,
exclusiveSort: o,
get numRows() {
return e.numRows;
}
};
}
async function F({ columns: e, indexes: n, signal: t, fetch: o }) {
const r = n.sort(), u = [];
let i;
for (const c of r)
i === void 0 ? i = [c, c + 1] : i[1] === c ? i[1] = c + 1 : (u.push(o({ rowStart: i[0], rowEnd: i[1], columns: e, signal: t })), i = [c, c + 1]);
i && u.push(o({ rowStart: i[0], rowEnd: i[1], columns: e, signal: t })), await Promise.all(u);
}
async function L({ orderBy: e, signal: n, ranksByColumn: t, setRanks: o, indexes: r, setIndexes: u, data: i }) {
if (!r) {
const c = await _({ orderBy: e, signal: n, ranksByColumn: t, setRanks: o, data: i });
r = J(c), u?.({ orderBy: e, indexes: r });
}
return r;
}
async function _({ orderBy: e, signal: n, ranksByColumn: t, setRanks: o, data: r }) {
const u = [], i = [];
for (const [c, { column: f, direction: a }] of e.entries()) {
y({ column: f, data: { columnDescriptors: r.columnDescriptors } });
const m = t?.get(f);
m ? u[c] = { direction: a, ranks: m } : i.push(
(r.fetch ? r.fetch({ rowStart: 0, rowEnd: r.numRows, columns: [f], signal: n }) : Promise.resolve()).then(() => {
B(n);
const h = Array.from({ length: r.numRows }, ($, R) => {
const s = r.getCell({ row: R, column: f });
if (!s)
throw new Error(`Cell not found for row ${R} and column ${f}`);
return s.value;
}), g = j(h);
o?.({ column: f, ranks: g }), u[c] = { direction: a, ranks: g };
})
);
}
return await Promise.all(i), u;
}
function J(e) {
if (!(0 in e))
throw new Error("orderByWithRanks should have at least one element");
const n = e[0].ranks.length;
return Array.from({ length: n }, (r, u) => u).sort((r, u) => {
for (const { direction: i, ranks: c } of e) {
const f = c[r], a = c[u];
if (f === void 0 || a === void 0)
throw new Error("Invalid ranks");
const m = i === "ascending" ? 1 : -1;
if (f < a) return -m;
if (f > a) return m;
}
return r - u;
});
}
function I(e) {
return typeof e == "string" ? e : typeof e == "number" || typeof e == "bigint" ? e.toLocaleString("en-US") : typeof e == "boolean" ? e.toString() : Array.isArray(e) ? `[
${e.map((n) => b(I(n), 2)).join(`,
`)}
]` : e == null ? JSON.stringify(e) : e instanceof Date ? e.toISOString() : typeof e == "object" ? `{
${Object.entries(e).filter((n) => n[1] !== void 0).map(([n, t]) => b(`${n}: ${I(t)}`, 2)).join(`,
`)}
}` : JSON.stringify(e);
}
function b(e, n) {
return e?.split(`
`).map((t) => " ".repeat(n) + t).join(`
`);
}
export {
U as TypedCustomEvent,
W as areEqualOrderBy,
V as arrayDataFrame,
B as checkSignal,
j as computeRanks,
k as createEventTarget,
M as createGetRowNumber,
N as deserializeOrderBy,
L as fetchIndexes,
S as partitionOrderBy,
x as serializeOrderBy,
q as sortableDataFrame,
I as stringify,
z as toggleColumn,
G as toggleColumnExclusive,
y as validateColumn,
T as validateFetchParams,
P as validateGetCellParams,
A as validateGetRowNumberParams,
E as validateOrderBy,
D as validateOrderByAgainstSortableColumns,
w as validateRow
};
//# sourceMappingURL=dataframe.js.map