UNPKG

@sanity/ui-workshop

Version:

An environment for designing, reviewing, and quality-testing React components.

315 lines (314 loc) 11.1 kB
import { jsx, Fragment, jsxs } from "react/jsx-runtime"; import { c } from "react/compiler-runtime"; import { TrashIcon, PlayIcon } from "@sanity/icons"; import { Box, Text, Stack, Card, Flex, Button } from "@sanity/ui"; import { createContext, useContext, useRef, memo, Profiler, useEffect, useState } from "react"; import { useWorkshop } from "@sanity/ui-workshop"; const PerfContext = createContext(null); function usePerf() { const perf = useContext(PerfContext); if (!perf) throw new Error("Perf: missing context value"); return perf; } function usePerfTest(props) { const $ = c(18), { name, title, description, run } = props, { activeTest, addRenderResult, registerTest } = usePerf(), active = activeTest === name, ref = useRef(null); let t0, t1; $[0] !== description || $[1] !== name || $[2] !== run || $[3] !== title ? (t1 = { description, name, ref, run, title }, $[0] = description, $[1] = name, $[2] = run, $[3] = title, $[4] = t1) : t1 = $[4], t0 = t1; const test = t0; let t2; $[5] !== addRenderResult || $[6] !== name ? (t2 = (id, phase, actualDuration, baseDuration, startTime, commitTime) => { const result = { id, phase, actualDuration, baseDuration, startTime, commitTime, interactions: /* @__PURE__ */ new Set() }; setTimeout(() => { console.log("@todo: render", { addRenderResult, name, result }); }, 0); }, $[5] = addRenderResult, $[6] = name, $[7] = t2) : t2 = $[7]; const handleRender = t2; let t3, t4; $[8] !== active || $[9] !== handleRender || $[10] !== name ? (t4 = memo(function(t52) { const { children } = t52; return active ? /* @__PURE__ */ jsx(Profiler, { id: name, onRender: handleRender, children }) : /* @__PURE__ */ jsx(Fragment, { children }); }), $[8] = active, $[9] = handleRender, $[10] = name, $[11] = t4) : t4 = $[11], t3 = t4; const Wrapper = t3; let t5, t6; $[12] !== registerTest || $[13] !== test ? (t5 = () => registerTest(test), t6 = [registerTest, test], $[12] = registerTest, $[13] = test, $[14] = t5, $[15] = t6) : (t5 = $[14], t6 = $[15]), useEffect(t5, t6); let t7, t8; return $[16] !== Wrapper ? (t8 = { ref, Wrapper }, $[16] = Wrapper, $[17] = t8) : t8 = $[17], t7 = t8, t7; } const PerfInspector = memo(function() { const $ = c(12), { clearResults, results, runTest, testDetails } = usePerf(); if (testDetails.length === 0) { let t02; return $[0] === Symbol.for("react.memo_cache_sentinel") ? (t02 = /* @__PURE__ */ jsx(Box, { padding: 2, children: /* @__PURE__ */ jsx(Box, { padding: 2, children: /* @__PURE__ */ jsx(Text, { muted: !0, size: [2, 2, 1], children: "No tests" }) }) }), $[0] = t02) : t02 = $[0], t02; } let t0; if ($[1] !== clearResults || $[2] !== results || $[3] !== runTest || $[4] !== testDetails) { let t12; $[6] !== clearResults || $[7] !== results || $[8] !== runTest ? (t12 = (detail) => { const testResults = results.filter((r) => r.name === detail.name); return /* @__PURE__ */ jsxs(Card, { border: !0, overflow: "hidden", radius: 2, style: { lineHeight: 0 }, children: [ /* @__PURE__ */ jsxs(Flex, { children: [ /* @__PURE__ */ jsxs(Stack, { flex: 1, padding: 2, space: 2, children: [ /* @__PURE__ */ jsx(Text, { size: 1, weight: "semibold", children: detail.title || detail.name }), detail.description && /* @__PURE__ */ jsx(Text, { muted: !0, size: 1, children: detail.description }) ] }), /* @__PURE__ */ jsx(Flex, { align: "flex-start", gap: 1, padding: 1, children: /* @__PURE__ */ jsx(Button, { "aria-label": "Clear results", fontSize: 1, icon: TrashIcon, mode: "bleed", onClick: () => clearResults(detail.name), padding: 1 }) }) ] }), /* @__PURE__ */ jsxs(Stack, { children: [ testResults.map(_temp2), /* @__PURE__ */ jsx(Card, { borderTop: !0, children: /* @__PURE__ */ jsx(Stack, { children: /* @__PURE__ */ jsx(Button, { "aria-label": "Run", fontSize: 1, icon: PlayIcon, mode: "bleed", onClick: () => runTest(detail.name), padding: 2, radius: 0 }) }) }) ] }) ] }, detail.name); }, $[6] = clearResults, $[7] = results, $[8] = runTest, $[9] = t12) : t12 = $[9], t0 = testDetails.map(t12), $[1] = clearResults, $[2] = results, $[3] = runTest, $[4] = testDetails, $[5] = t0; } else t0 = $[5]; let t1; return $[10] !== t0 ? (t1 = /* @__PURE__ */ jsx(Stack, { padding: 2, space: 2, children: t0 }), $[10] = t0, $[11] = t1) : t1 = $[11], t1; }); function _temp$1(r_0, rIdx) { return /* @__PURE__ */ jsx(Card, { children: r_0.phase }, rIdx); } function _temp2(result, resultIndex) { return /* @__PURE__ */ jsxs(Card, { borderTop: !0, children: [ /* @__PURE__ */ jsx(Stack, { children: result.renders.map(_temp$1) }), /* @__PURE__ */ jsxs(Flex, { padding: 2, children: [ /* @__PURE__ */ jsx(Box, { flex: 1, children: /* @__PURE__ */ jsxs(Text, { muted: !0, size: 1, children: [ result.timing?.runs, " runs" ] }) }), /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { size: 1, children: [ "Avg. ", result.timing?.avgDuration.toFixed(3), "ms" ] }) }) ] }) ] }, resultIndex); } function delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } async function _runTest(test, target) { performance.clearMarks(), performance.clearMeasures(); for (let i = 0; i < 1; i += 1) performance.mark(`start:${test.name}`), await test.run({ target }), performance.mark(`end:${test.name}`), performance.measure(test.name, `start:${test.name}`, `end:${test.name}`), await delay(100); const sumDuration = performance.getEntriesByName(test.name).reduce((t, e) => t + e.duration, 0); return { avgDuration: sumDuration / 1, sumDuration, runs: 1 }; } function perfReducer(state, msg) { if (msg.type === "workshop/perf/clearResults") return { ...state, results: state.results.filter((d) => d.name !== msg.name) }; if (msg.type === "workshop/perf/registerTest") return { ...state, testDetails: state.testDetails.concat([{ description: msg.description, name: msg.name, title: msg.title }]) }; if (msg.type === "workshop/perf/unregisterTest") return { ...state, testDetails: state.testDetails.filter((d) => d.name !== msg.name) }; if (msg.type === "workshop/perf/runTest") return { ...state, activeTest: msg.name, results: state.results.concat([{ name: msg.name, renders: [] }]) }; if (msg.type === "workshop/perf/addResult") { if (state.activeTest === msg.name) { const result = state.results.filter((r) => r.name === msg.name), lastResult = result[result.length - 1]; if (lastResult) return { ...state, results: state.results.map((r) => r === lastResult ? { ...r, timing: msg.result } : r) }; } return state; } if (msg.type === "workshop/perf/addRenderResult") { if (state.activeTest === msg.name) { const result = state.results.filter((r) => r.name === msg.name), lastResult = result[result.length - 1]; if (lastResult) return { ...state, results: state.results.map((r) => r === lastResult ? { ...r, renders: r.renders.concat([msg.result]) } : r) }; } return state; } return state; } const PerfProvider = memo(function(props) { const $ = c(26), { children } = props, { broadcast, channel } = useWorkshop(); let t0; $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = { results: [], testDetails: [], tests: [] }, $[0] = t0) : t0 = $[0]; const [t1, setState] = useState(t0), { activeTest, results, testDetails, tests } = t1; let t2; $[1] !== broadcast ? (t2 = (name, result) => { broadcast({ type: "workshop/perf/addRenderResult", name, result }); }, $[1] = broadcast, $[2] = t2) : t2 = $[2]; const addRenderResult = t2; let t3; $[3] !== broadcast ? (t3 = (name_0) => { broadcast({ type: "workshop/perf/clearResults", name: name_0 }); }, $[3] = broadcast, $[4] = t3) : t3 = $[4]; const clearResults = t3; let t4; $[5] !== broadcast ? (t4 = (test) => (broadcast({ type: "workshop/perf/registerTest", description: test.description, title: test.title, name: test.name }), setState((s) => ({ ...s, tests: s.tests.concat([test]) })), () => { broadcast({ type: "workshop/perf/unregisterTest", name: test.name }), setState((s_0) => ({ ...s_0, tests: s_0.tests.filter((t) => t !== test) })); }), $[5] = broadcast, $[6] = t4) : t4 = $[6]; const registerTest = t4; let t5; $[7] !== broadcast ? (t5 = (testName) => { broadcast({ type: "workshop/perf/runTest", name: testName }); }, $[7] = broadcast, $[8] = t5) : t5 = $[8]; const runTest = t5; let t6, t7; $[9] !== activeTest || $[10] !== addRenderResult || $[11] !== clearResults || $[12] !== registerTest || $[13] !== results || $[14] !== runTest || $[15] !== testDetails || $[16] !== tests ? (t7 = { activeTest, addRenderResult, clearResults, registerTest, results, runTest, testDetails, tests }, $[9] = activeTest, $[10] = addRenderResult, $[11] = clearResults, $[12] = registerTest, $[13] = results, $[14] = runTest, $[15] = testDetails, $[16] = tests, $[17] = t7) : t7 = $[17], t6 = t7; const perf = t6; let t8, t9; $[18] !== broadcast || $[19] !== channel || $[20] !== tests ? (t8 = () => channel.subscribe((msg) => { if (setState((s_1) => perfReducer(s_1, msg)), msg.type === "workshop/perf/runTest") { setTimeout(() => { const test_0 = tests.find((t_0) => t_0.name === msg.name); if (test_0) { const container = test_0.ref.current; container !== null && _runTest(test_0, container).then((result_0) => { broadcast({ type: "workshop/perf/addResult", name: test_0.name, result: result_0 }); }).catch(_temp); } }, 0); return; } }), t9 = [broadcast, channel, tests], $[18] = broadcast, $[19] = channel, $[20] = tests, $[21] = t8, $[22] = t9) : (t8 = $[21], t9 = $[22]), useEffect(t8, t9); let t10; return $[23] !== children || $[24] !== perf ? (t10 = /* @__PURE__ */ jsx(PerfContext.Provider, { value: perf, children }), $[23] = children, $[24] = perf, $[25] = t10) : t10 = $[25], t10; }); function _temp(err) { console.error(err); } function perfPlugin() { return { name: "perf", title: "Performance", inspector: PerfInspector, provider: PerfProvider }; } export { perfPlugin, usePerf, usePerfTest }; //# sourceMappingURL=plugin-perf.js.map