"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.DataTableProfiler = DataTableProfiler;
const react_1 = __importStar(require("react"));
const button_1 = require("../../button");
const box_1 = require("../../primitives/box");
const stack_1 = require("../../primitives/stack");
const typography_1 = require("../../typography");
function DataTableProfiler({ children }) {
    const lastProfilerStateRef = (0, react_1.useRef)({});
    return (react_1.default.createElement("div", null,
        react_1.default.createElement(ProfilerDisplay, { getLatestData: () => lastProfilerStateRef.current }),
        react_1.default.createElement(react_1.default.Profiler, { id: "DataTable", onRender: (_, phase, actualDuration) => {
                var _a;
                lastProfilerStateRef.current = Object.assign(Object.assign({}, lastProfilerStateRef.current), { [phase]: {
                        actualDuration: rollingLatestValues(((_a = lastProfilerStateRef.current[phase]) === null || _a === void 0 ? void 0 : _a.actualDuration) || [], { duration: actualDuration.toFixed(2), timestamp: Date.now() }, 10),
                    } });
            } },
            react_1.default.createElement("div", { id: "dataTable-profiler-content" }, children))));
}
function rollingLatestValues(arr, newValue, maxLength) {
    let newArr = [newValue, ...arr];
    if (newArr.length > maxLength) {
        newArr = newArr.slice(0, -1);
    }
    return newArr;
}
const getOpacity = (timestamp) => {
    const age = Date.now() - timestamp;
    const maxAge = 10000;
    return Math.max(0.4, 1 - age / maxAge);
};
function ProfilerDisplay({ getLatestData, }) {
    const [open, setOpen] = (0, react_1.useState)(false);
    const [domStats, setDomStats] = (0, react_1.useState)(null);
    const [, setTick] = (0, react_1.useState)(0);
    const lastProfilerState = getLatestData();
    (0, react_1.useEffect)(() => {
        if (!open)
            return;
        const interval = setInterval(() => {
            const dataTableElement = document.getElementById("dataTable-profiler-content");
            if (dataTableElement) {
                const walker = document.createTreeWalker(dataTableElement, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, null);
                let elements = 0;
                let nodes = 0;
                while (walker.nextNode()) {
                    nodes++;
                    if (walker.currentNode.nodeType === Node.ELEMENT_NODE) {
                        elements++;
                    }
                }
                setDomStats({ elements, nodes });
            }
            setTick((t) => t + 1);
        }, 500);
        return () => clearInterval(interval);
    }, [open]);
    return (react_1.default.createElement(stack_1.VStack, { asChild: true },
        react_1.default.createElement(box_1.Box, { position: "fixed", top: "space-4", right: "space-4", padding: "space-6", background: "raised", borderRadius: "8", borderWidth: "1", borderColor: "neutral-subtleA", style: { zIndex: 1000 } },
            react_1.default.createElement(button_1.Button, { "data-color": "neutral", variant: "tertiary", size: "small", onClick: () => setOpen(!open) }, open ? "Hide Profiler" : "Show Profiler"),
            open && (react_1.default.createElement(react_1.default.Fragment, null,
                !domStats && react_1.default.createElement("div", null, "Loading stats..."),
                domStats && (react_1.default.createElement("div", null,
                    react_1.default.createElement(typography_1.Heading, { level: "2", size: "xsmall" }, "DOM Stats:"),
                    react_1.default.createElement("ul", { style: { margin: 0, paddingLeft: "1rem" } },
                        react_1.default.createElement("li", { style: { listStyle: "none" } }, `${domStats.elements} elements`),
                        react_1.default.createElement("li", { style: { listStyle: "none" } }, `${domStats.nodes} nodes`)))),
                lastProfilerState.mount && (react_1.default.createElement("div", null,
                    react_1.default.createElement(typography_1.Heading, { level: "2", size: "xsmall" }, "Mount:"),
                    react_1.default.createElement("ul", { style: { margin: 0, paddingLeft: "1rem" } }, lastProfilerState.mount.actualDuration.map((entry, index) => (react_1.default.createElement("li", { style: {
                            listStyle: "none",
                            opacity: getOpacity(entry.timestamp),
                            transition: "opacity 0.5s",
                        }, key: index }, `${entry.duration} ms`)))))),
                lastProfilerState.update && (react_1.default.createElement("div", null,
                    react_1.default.createElement(typography_1.Heading, { level: "2", size: "xsmall" }, "Update:"),
                    react_1.default.createElement("ul", { style: { margin: 0, paddingLeft: "1rem" } }, lastProfilerState.update.actualDuration.map((entry, index) => (react_1.default.createElement("li", { style: {
                            listStyle: "none",
                            opacity: getOpacity(entry.timestamp),
                            transition: "opacity 0.5s",
                        }, key: index }, `${entry.duration} ms`)))))),
                lastProfilerState["nested-update"] && (react_1.default.createElement("div", null,
                    react_1.default.createElement(typography_1.Heading, { level: "2", size: "xsmall" }, "Nested-update"),
                    react_1.default.createElement("ul", { style: { margin: 0, paddingLeft: "1rem" } }, lastProfilerState["nested-update"].actualDuration.map((entry, index) => (react_1.default.createElement("li", { style: {
                            listStyle: "none",
                            opacity: getOpacity(entry.timestamp),
                            transition: "opacity 0.5s",
                        }, key: index }, `${entry.duration} ms`)))))))))));
}
//# sourceMappingURL=DataTableProfiler.js.map