UNPKG

@tanstack/table-devtools

Version:

Devtools for TanStack Table.

471 lines (469 loc) • 19.1 kB
import { useTableDevtoolsContext } from "../TableContextProvider.js"; import { useStyles } from "../styles/use-styles.js"; import { useTableStore } from "../useTableStore.js"; import { NoTableConnected } from "./NoTableConnected.js"; import { bundleSizes } from "../bundleSizes.js"; import { estimateBundleSize } from "../estimateBundleSize.js"; import { ResizableSplit } from "./ResizableSplit.js"; import { For, Show, createMemo } from "solid-js"; import { className, createComponent, effect, insert, memo, template } from "solid-js/web"; import { aggregationFns, coreFeatures, filterFns, sortFns, stockFeatures } from "@tanstack/table-core"; //#region src/components/FeaturesPanel.tsx var _tmpl$ = /*#__PURE__*/ template(`<div><span></span><span></span><span>`); var _tmpl$2 = /*#__PURE__*/ template(`<div>`); var _tmpl$3 = /*#__PURE__*/ template(`<div>Features`); var _tmpl$4 = /*#__PURE__*/ template(`<div><div>Estimated @tanstack/table-core bundle</div><div><span>Core</span><span></span></div><div><span>Registered features</span><span>+</span></div><div><span>Client row models</span><span>+</span></div><div><span>Built-in fns</span><span>+</span></div><div><span>Total</span><span></span></div><div>Minified + brotli, the metric \`pnpm size\` reports, measured for v<!>. Each item shows what it adds on its own; the total counts code that items share once. Excludes the framework adapter and custom features.`); var _tmpl$5 = /*#__PURE__*/ template(`<div><div>Core Features`); var _tmpl$6 = /*#__PURE__*/ template(`<div><div>Stock Features`); var _tmpl$7 = /*#__PURE__*/ template(`<div><div>Additional Plugins`); var _tmpl$8 = /*#__PURE__*/ template(`<div>Client Side Row Models and Fns`); var _tmpl$9 = /*#__PURE__*/ template(`<div>Full package: `); var _tmpl$0 = /*#__PURE__*/ template(`<div><div>Execution Order`); var _tmpl$1 = /*#__PURE__*/ template(`<div><div><span></span><span> rows, `); var _tmpl$10 = /*#__PURE__*/ template(`<div><span></span><span>`); var _tmpl$11 = /*#__PURE__*/ template(`<div><div><span>aggregationFns</span><span> registered`); var _tmpl$12 = /*#__PURE__*/ template(`<div>No row models configured`); var _tmpl$13 = /*#__PURE__*/ template(`<span>`); function toFnBuckets(value) { return typeof value === "object" && value != null ? value : {}; } /** Maps each built-in fn back to its registry name to size registered fns */ const BUILT_IN_FN_NAMES = { filterFns: new Map(Object.entries(filterFns).map(([name, fn]) => [fn, name])), sortFns: new Map(Object.entries(sortFns).map(([name, fn]) => [fn, name])), aggregationFns: new Map(Object.entries(aggregationFns).map(([name, fn]) => [fn, name])) }; const CORE_REACTIVITY_FEATURE_NAME = "coreReactivityFeature"; const CORE_FEATURE_NAMES = [CORE_REACTIVITY_FEATURE_NAME, ...Object.keys(coreFeatures).filter((featureName) => featureName !== CORE_REACTIVITY_FEATURE_NAME)]; const STOCK_FEATURE_NAMES = Object.keys(stockFeatures); const CORE_FEATURE_SIZES = bundleSizes.coreFeatures; const FEATURE_SIZES = bundleSizes.features; const ROW_MODEL_SIZES = bundleSizes.rowModels; const FN_SIZES = { filterFns: bundleSizes.filterFns, sortFns: bundleSizes.sortFns, aggregationFns: bundleSizes.aggregationFns }; const ROW_MODEL_FEATURE_SLOTS = [ "coreRowModel", "filteredRowModel", "groupedRowModel", "sortedRowModel", "expandedRowModel", "paginatedRowModel", "facetedRowModel", "facetedMinMaxValues", "facetedUniqueValues" ]; const ROW_MODEL_SHARED_SIZE_LABELS = { preFilteredRowModel: "shared", preGroupedRowModel: "shared", preSortedRowModel: "shared" }; const ROW_MODEL_TO_FN_KIND = { filteredRowModel: "filterFns", preFilteredRowModel: "filterFns", sortedRowModel: "sortFns", preSortedRowModel: "sortFns", groupedRowModel: null, preGroupedRowModel: null }; const EXECUTION_ORDER_GETTERS = [ "getCoreRowModel", "getFilteredRowModel", "getGroupedRowModel", "getSortedRowModel", "getExpandedRowModel", "getPaginatedRowModel", "getRowModel" ]; function getterToRowModelKey(getter) { if (getter === "getRowModel") return "paginatedRowModel"; const withoutGet = getter.slice(3); return withoutGet.charAt(0).toLowerCase() + withoutGet.slice(1); } const ROW_MODEL_TO_GETTER = { coreRowModel: "getCoreRowModel", filteredRowModel: "getFilteredRowModel", preFilteredRowModel: "getFilteredRowModel", groupedRowModel: "getGroupedRowModel", preGroupedRowModel: "getGroupedRowModel", sortedRowModel: "getSortedRowModel", preSortedRowModel: "getSortedRowModel", expandedRowModel: "getExpandedRowModel", paginatedRowModel: "getRowModel" }; function getRowCountForModel(tableInstance, rowModelName) { const getter = ROW_MODEL_TO_GETTER[rowModelName]; if (!getter || !tableInstance) return 0; const tableRecord = tableInstance; if (typeof tableRecord[getter] !== "function") return 0; return tableRecord[getter]().rows?.length ?? 0; } function formatSize(sizeInBytes) { if (typeof sizeInBytes !== "number") return "n/a"; return `${(sizeInBytes / 1e3).toFixed(2)} kB`; } function formatRegisteredFnSize(kind, fn) { return fn.builtInName ? formatSize(FN_SIZES[kind][fn.builtInName]) : "custom"; } function normalizeRowModelSizeKey(rowModelName) { if (rowModelName === "preFilteredRowModel") return "filteredRowModel"; if (rowModelName === "preGroupedRowModel") return "groupedRowModel"; if (rowModelName === "preSortedRowModel") return "sortedRowModel"; return rowModelName; } function FeaturesPanel() { const styles = useStyles(); const { table } = useTableDevtoolsContext(); const tableState = useTableStore(() => table()?.store, (state) => state); const optionsStoreValue = useTableStore(() => table()?.optionsStore, (options) => options); const tableFeatures = createMemo(() => { const tableInstance = table(); if (!tableInstance) return /* @__PURE__ */ new Set(); return new Set(Object.keys(tableInstance._features)); }); const rowModelNames = createMemo(() => { const tableInstance = table(); if (!tableInstance) return []; optionsStoreValue(); return Object.keys(tableInstance.options.features ?? {}).filter((key) => ROW_MODEL_FEATURE_SLOTS.includes(key)); }); const getRegisteredFns = (kind) => { const tableInstance = table(); if (!tableInstance) return []; optionsStoreValue(); const rowModelFns = toFnBuckets(tableInstance._rowModelFns); const optionFns = toFnBuckets(tableInstance.options); const registry = rowModelFns[kind] ?? optionFns[kind] ?? {}; return Object.entries(registry).map(([name, fn]) => ({ name, builtInName: BUILT_IN_FN_NAMES[kind].get(fn) })); }; const additionalPlugins = createMemo(() => { const currentFeatures = tableFeatures(); const knownFeatures = /* @__PURE__ */ new Set([...CORE_FEATURE_NAMES, ...STOCK_FEATURE_NAMES]); return [...currentFeatures].filter((f) => !knownFeatures.has(f)).sort(); }); const registeredFns = createMemo(() => ({ filterFns: getRegisteredFns("filterFns"), sortFns: getRegisteredFns("sortFns"), aggregationFns: getRegisteredFns("aggregationFns") })); const getRowModelFunctions = (rowModelName) => { const fnKind = ROW_MODEL_TO_FN_KIND[rowModelName]; if (!fnKind) return []; return registeredFns()[fnKind]; }; const sizeEstimate = createMemo(() => { const builtInNames = (kind) => registeredFns()[kind].flatMap((fn) => fn.builtInName ? [fn.builtInName] : []); const withFeatures = { features: [...tableFeatures()] }; const withRowModels = { ...withFeatures, rowModels: rowModelNames() }; const withFns = { ...withRowModels, filterFns: builtInNames("filterFns"), sortFns: builtInNames("sortFns"), aggregationFns: builtInNames("aggregationFns") }; const core = bundleSizes.core; const features = estimateBundleSize(withFeatures); const rowModels = estimateBundleSize(withRowModels); const total = estimateBundleSize(withFns); return { core, features: features - core, rowModels: rowModels - features, fns: total - rowModels, total }; }); const rowModels = createMemo(() => { const tableInstance = table(); if (!tableInstance) return []; tableState(); return rowModelNames().map((rowModelName) => { const sharedLabel = ROW_MODEL_SHARED_SIZE_LABELS[rowModelName]; return { rowModelName, fnKind: ROW_MODEL_TO_FN_KIND[rowModelName] ?? null, fns: getRowModelFunctions(rowModelName), rowCount: getRowCountForModel(tableInstance, rowModelName), sizeLabel: sharedLabel ?? formatSize(ROW_MODEL_SIZES[normalizeRowModelSizeKey(rowModelName)]) }; }); }); const renderFeatureItem = (name, isEnabled, sizeLabel) => (() => { var _el$ = _tmpl$(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.nextSibling; insert(_el$2, isEnabled ? "✓" : "○"); insert(_el$3, name); insert(_el$4, sizeLabel); effect((_p$) => { var _v$ = styles().featureListItem, _v$2 = isEnabled ? styles().featureCheck : styles().featureUncheck, _v$3 = styles().featureLabel, _v$4 = styles().featureMeta; _v$ !== _p$.e && className(_el$, _p$.e = _v$); _v$2 !== _p$.t && className(_el$2, _p$.t = _v$2); _v$3 !== _p$.a && className(_el$3, _p$.a = _v$3); _v$4 !== _p$.o && className(_el$4, _p$.o = _v$4); return _p$; }, { e: void 0, t: void 0, a: void 0, o: void 0 }); return _el$; })(); return createComponent(Show, { get fallback() { return createComponent(NoTableConnected, { title: "Features" }); }, get when() { return table(); }, get children() { var _el$5 = _tmpl$2(); insert(_el$5, createComponent(ResizableSplit, { get left() { return [ (() => { var _el$6 = _tmpl$3(); effect(() => className(_el$6, styles().sectionTitle)); return _el$6; })(), (() => { var _el$7 = _tmpl$4(), _el$8 = _el$7.firstChild, _el$9 = _el$8.nextSibling, _el$1 = _el$9.firstChild.nextSibling, _el$10 = _el$9.nextSibling, _el$12 = _el$10.firstChild.nextSibling; _el$12.firstChild; var _el$14 = _el$10.nextSibling, _el$16 = _el$14.firstChild.nextSibling; _el$16.firstChild; var _el$18 = _el$14.nextSibling, _el$20 = _el$18.firstChild.nextSibling; _el$20.firstChild; var _el$22 = _el$18.nextSibling, _el$24 = _el$22.firstChild.nextSibling, _el$25 = _el$22.nextSibling, _el$28 = _el$25.firstChild.nextSibling; _el$28.nextSibling; insert(_el$1, () => formatSize(sizeEstimate().core)); insert(_el$12, () => formatSize(sizeEstimate().features), null); insert(_el$16, () => formatSize(sizeEstimate().rowModels), null); insert(_el$20, () => formatSize(sizeEstimate().fns), null); insert(_el$24, () => formatSize(sizeEstimate().total)); insert(_el$25, () => bundleSizes.tableCoreVersion, _el$28); effect((_p$) => { var _v$5 = styles().featureEstimateSummary, _v$6 = styles().featureEstimateSummaryTitle, _v$7 = styles().featureEstimateSummaryRow, _v$8 = styles().featureEstimateSummaryRow, _v$9 = styles().featureEstimateSummaryRow, _v$0 = styles().featureEstimateSummaryRow, _v$1 = styles().featureEstimateSummaryTotal, _v$10 = styles().featureEstimateSummaryNote; _v$5 !== _p$.e && className(_el$7, _p$.e = _v$5); _v$6 !== _p$.t && className(_el$8, _p$.t = _v$6); _v$7 !== _p$.a && className(_el$9, _p$.a = _v$7); _v$8 !== _p$.o && className(_el$10, _p$.o = _v$8); _v$9 !== _p$.i && className(_el$14, _p$.i = _v$9); _v$0 !== _p$.n && className(_el$18, _p$.n = _v$0); _v$1 !== _p$.s && className(_el$22, _p$.s = _v$1); _v$10 !== _p$.h && className(_el$25, _p$.h = _v$10); return _p$; }, { e: void 0, t: void 0, a: void 0, o: void 0, i: void 0, n: void 0, s: void 0, h: void 0 }); return _el$7; })(), (() => { var _el$29 = _tmpl$5(), _el$30 = _el$29.firstChild; insert(_el$29, createComponent(For, { each: CORE_FEATURE_NAMES, children: (name) => renderFeatureItem(name, tableFeatures().has(name), name === CORE_REACTIVITY_FEATURE_NAME ? "adapter" : formatSize(CORE_FEATURE_SIZES[name])) }), null); effect((_p$) => { var _v$11 = styles().featureSubsection, _v$12 = styles().featureSubsectionTitle; _v$11 !== _p$.e && className(_el$29, _p$.e = _v$11); _v$12 !== _p$.t && className(_el$30, _p$.t = _v$12); return _p$; }, { e: void 0, t: void 0 }); return _el$29; })(), (() => { var _el$31 = _tmpl$6(), _el$32 = _el$31.firstChild; insert(_el$31, createComponent(For, { each: STOCK_FEATURE_NAMES, children: (name) => renderFeatureItem(name, tableFeatures().has(name), `+${formatSize(FEATURE_SIZES[name])}`) }), null); effect((_p$) => { var _v$13 = styles().featureSubsection, _v$14 = styles().featureSubsectionTitle; _v$13 !== _p$.e && className(_el$31, _p$.e = _v$13); _v$14 !== _p$.t && className(_el$32, _p$.t = _v$14); return _p$; }, { e: void 0, t: void 0 }); return _el$31; })(), memo(() => memo(() => additionalPlugins().length > 0)() && (() => { var _el$33 = _tmpl$7(), _el$34 = _el$33.firstChild; insert(_el$33, createComponent(For, { get each() { return additionalPlugins(); }, children: (name) => renderFeatureItem(name, true, "custom") }), null); effect((_p$) => { var _v$15 = styles().featureSubsection, _v$16 = styles().featureSubsectionTitle; _v$15 !== _p$.e && className(_el$33, _p$.e = _v$15); _v$16 !== _p$.t && className(_el$34, _p$.t = _v$16); return _p$; }, { e: void 0, t: void 0 }); return _el$33; })()) ]; }, get right() { return [ (() => { var _el$35 = _tmpl$8(); effect(() => className(_el$35, styles().sectionTitle)); return _el$35; })(), createComponent(For, { get each() { return rowModels(); }, children: (rowModel) => (() => { var _el$40 = _tmpl$1(), _el$41 = _el$40.firstChild, _el$42 = _el$41.firstChild, _el$43 = _el$42.nextSibling, _el$44 = _el$43.firstChild; insert(_el$42, () => rowModel.rowModelName); insert(_el$43, () => rowModel.rowCount, _el$44); insert(_el$43, () => rowModel.sizeLabel, null); insert(_el$40, createComponent(For, { get each() { return rowModel.fns; }, children: (fn) => (() => { var _el$45 = _tmpl$10(), _el$46 = _el$45.firstChild, _el$47 = _el$46.nextSibling; insert(_el$46, () => fn.name); insert(_el$47, (() => { var _c$ = memo(() => !!rowModel.fnKind); return () => _c$() ? formatRegisteredFnSize(rowModel.fnKind, fn) : ""; })()); effect((_p$) => { var _v$22 = styles().rowModelFnItem, _v$23 = styles().featureLabel, _v$24 = styles().featureMeta; _v$22 !== _p$.e && className(_el$45, _p$.e = _v$22); _v$23 !== _p$.t && className(_el$46, _p$.t = _v$23); _v$24 !== _p$.a && className(_el$47, _p$.a = _v$24); return _p$; }, { e: void 0, t: void 0, a: void 0 }); return _el$45; })() }), null); effect((_p$) => { var _v$19 = styles().rowModelItem, _v$20 = styles().featureLabel, _v$21 = styles().featureMeta; _v$19 !== _p$.e && className(_el$41, _p$.e = _v$19); _v$20 !== _p$.t && className(_el$42, _p$.t = _v$20); _v$21 !== _p$.a && className(_el$43, _p$.a = _v$21); return _p$; }, { e: void 0, t: void 0, a: void 0 }); return _el$40; })() }), memo(() => memo(() => !!tableFeatures().has("rowAggregationFeature"))() && (() => { var _el$48 = _tmpl$11(), _el$49 = _el$48.firstChild, _el$50 = _el$49.firstChild, _el$51 = _el$50.nextSibling, _el$52 = _el$51.firstChild; insert(_el$51, () => registeredFns().aggregationFns.length, _el$52); insert(_el$48, createComponent(For, { get each() { return registeredFns().aggregationFns; }, children: (fn) => (() => { var _el$53 = _tmpl$10(), _el$54 = _el$53.firstChild, _el$55 = _el$54.nextSibling; insert(_el$54, () => fn.name); insert(_el$55, () => formatRegisteredFnSize("aggregationFns", fn)); effect((_p$) => { var _v$28 = styles().rowModelFnItem, _v$29 = styles().featureLabel, _v$30 = styles().featureMeta; _v$28 !== _p$.e && className(_el$53, _p$.e = _v$28); _v$29 !== _p$.t && className(_el$54, _p$.t = _v$29); _v$30 !== _p$.a && className(_el$55, _p$.a = _v$30); return _p$; }, { e: void 0, t: void 0, a: void 0 }); return _el$53; })() }), null); effect((_p$) => { var _v$25 = styles().rowModelItem, _v$26 = styles().featureLabel, _v$27 = styles().featureMeta; _v$25 !== _p$.e && className(_el$49, _p$.e = _v$25); _v$26 !== _p$.t && className(_el$50, _p$.t = _v$26); _v$27 !== _p$.a && className(_el$51, _p$.a = _v$27); return _p$; }, { e: void 0, t: void 0, a: void 0 }); return _el$48; })()), memo(() => memo(() => rowModelNames().length === 0)() && (() => { var _el$56 = _tmpl$12(); effect(() => className(_el$56, styles().rowModelItem)); return _el$56; })()), (() => { var _el$36 = _tmpl$9(); _el$36.firstChild; insert(_el$36, () => formatSize(bundleSizes.package), null); effect(() => className(_el$36, styles().featureEstimateSummaryNote)); return _el$36; })(), (() => { var _el$38 = _tmpl$0(), _el$39 = _el$38.firstChild; insert(_el$38, createComponent(For, { each: EXECUTION_ORDER_GETTERS, children: (getter, index) => { const rowModelKey = getterToRowModelKey(getter); const isPresent = rowModelKey !== null && rowModelNames().includes(rowModelKey); return [memo(() => index() > 0 && " → "), (() => { var _el$57 = _tmpl$13(); insert(_el$57, getter); effect(() => className(_el$57, isPresent ? styles().rowModelExecutionOrderBold : void 0)); return _el$57; })()]; } }), null); effect((_p$) => { var _v$17 = styles().rowModelExecutionOrder, _v$18 = styles().featureSubsectionTitle; _v$17 !== _p$.e && className(_el$38, _p$.e = _v$17); _v$18 !== _p$.t && className(_el$39, _p$.t = _v$18); return _p$; }, { e: void 0, t: void 0 }); return _el$38; })() ]; } })); effect(() => className(_el$5, styles().panelScroll)); return _el$5; } }); } //#endregion export { FeaturesPanel };