@tanstack/devtools-utils
Advanced tools
@@ -8,11 +8,10 @@ import { jsx, Fragment } from "react/jsx-runtime"; | ||
| useEffect(() => { | ||
| if (devtools.current) return; | ||
| devtools.current = new CoreClass(); | ||
| const instance = new CoreClass(); | ||
| devtools.current = instance; | ||
| if (devToolRef.current) { | ||
| devtools.current.mount(devToolRef.current, props?.theme ?? "dark"); | ||
| instance.mount(devToolRef.current, props?.theme ?? "dark"); | ||
| } | ||
| return () => { | ||
| if (devToolRef.current) { | ||
| devtools.current?.unmount(); | ||
| } | ||
| instance.unmount(); | ||
| devtools.current = null; | ||
| }; | ||
@@ -19,0 +18,0 @@ }, [props?.theme]); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"panel.js","sources":["../../../src/react/panel.tsx"],"sourcesContent":["import { useEffect, useRef } from 'react'\n\nexport interface DevtoolsPanelProps {\n theme?: 'light' | 'dark'\n}\n\n/**\n * Creates a React component that dynamically imports and mounts a devtools panel. SSR friendly.\n * @param devtoolsPackageName The name of the devtools package to be imported, e.g., '@tanstack/devtools-react'\n * @param importName The name of the export to be imported from the devtools package (e.g., 'default' or 'DevtoolsCore')\n * @returns A React component that mounts the devtools\n * @example\n * ```tsx\n * // if the export is default\n * const [ReactDevtoolsPanel, NoOpReactDevtoolsPanel] = createReactPanel('@tanstack/devtools-react')\n * ```\n *\n * @example\n * ```tsx\n * // if the export is named differently\n * const [ReactDevtoolsPanel, NoOpReactDevtoolsPanel] = createReactPanel('@tanstack/devtools-react', 'DevtoolsCore')\n * ```\n */\nexport function createReactPanel<\n TComponentProps extends DevtoolsPanelProps | undefined,\n TCoreDevtoolsClass extends {\n mount: (el: HTMLElement, theme: 'light' | 'dark') => void\n unmount: () => void\n },\n>(CoreClass: new () => TCoreDevtoolsClass) {\n function Panel(props: TComponentProps) {\n const devToolRef = useRef<HTMLDivElement>(null)\n const devtools = useRef<TCoreDevtoolsClass | null>(null)\n useEffect(() => {\n if (devtools.current) return\n\n devtools.current = new CoreClass()\n\n if (devToolRef.current) {\n devtools.current.mount(devToolRef.current, props?.theme ?? 'dark')\n }\n\n return () => {\n if (devToolRef.current) {\n devtools.current?.unmount()\n }\n }\n }, [props?.theme])\n\n return <div style={{ height: '100%' }} ref={devToolRef} />\n }\n\n function NoOpPanel(_props: TComponentProps) {\n return <></>\n }\n return [Panel, NoOpPanel] as const\n}\n"],"names":[],"mappings":";;AAuBO,SAAS,iBAMd,WAAyC;AACzC,WAAS,MAAM,OAAwB;AACrC,UAAM,aAAa,OAAuB,IAAI;AAC9C,UAAM,WAAW,OAAkC,IAAI;AACvD,cAAU,MAAM;AACd,UAAI,SAAS,QAAS;AAEtB,eAAS,UAAU,IAAI,UAAA;AAEvB,UAAI,WAAW,SAAS;AACtB,iBAAS,QAAQ,MAAM,WAAW,SAAS,OAAO,SAAS,MAAM;AAAA,MACnE;AAEA,aAAO,MAAM;AACX,YAAI,WAAW,SAAS;AACtB,mBAAS,SAAS,QAAA;AAAA,QACpB;AAAA,MACF;AAAA,IACF,GAAG,CAAC,OAAO,KAAK,CAAC;AAEjB,WAAO,oBAAC,SAAI,OAAO,EAAE,QAAQ,OAAA,GAAU,KAAK,YAAY;AAAA,EAC1D;AAEA,WAAS,UAAU,QAAyB;AAC1C,WAAO,oBAAA,UAAA,EAAE;AAAA,EACX;AACA,SAAO,CAAC,OAAO,SAAS;AAC1B;"} | ||
| {"version":3,"file":"panel.js","sources":["../../../src/react/panel.tsx"],"sourcesContent":["import { useEffect, useRef } from 'react'\n\nexport interface DevtoolsPanelProps {\n theme?: 'light' | 'dark'\n}\n\n/**\n * Creates a React component that dynamically imports and mounts a devtools panel. SSR friendly.\n * @param devtoolsPackageName The name of the devtools package to be imported, e.g., '@tanstack/devtools-react'\n * @param importName The name of the export to be imported from the devtools package (e.g., 'default' or 'DevtoolsCore')\n * @returns A React component that mounts the devtools\n * @example\n * ```tsx\n * // if the export is default\n * const [ReactDevtoolsPanel, NoOpReactDevtoolsPanel] = createReactPanel('@tanstack/devtools-react')\n * ```\n *\n * @example\n * ```tsx\n * // if the export is named differently\n * const [ReactDevtoolsPanel, NoOpReactDevtoolsPanel] = createReactPanel('@tanstack/devtools-react', 'DevtoolsCore')\n * ```\n */\nexport function createReactPanel<\n TComponentProps extends DevtoolsPanelProps | undefined,\n TCoreDevtoolsClass extends {\n mount: (el: HTMLElement, theme: 'light' | 'dark') => void\n unmount: () => void\n },\n>(CoreClass: new () => TCoreDevtoolsClass) {\n function Panel(props: TComponentProps) {\n const devToolRef = useRef<HTMLDivElement>(null)\n const devtools = useRef<TCoreDevtoolsClass | null>(null)\n useEffect(() => {\n const instance = new CoreClass()\n devtools.current = instance\n\n if (devToolRef.current) {\n instance.mount(devToolRef.current, props?.theme ?? 'dark')\n }\n\n return () => {\n instance.unmount()\n devtools.current = null\n }\n }, [props?.theme])\n\n return <div style={{ height: '100%' }} ref={devToolRef} />\n }\n\n function NoOpPanel(_props: TComponentProps) {\n return <></>\n }\n return [Panel, NoOpPanel] as const\n}\n"],"names":[],"mappings":";;AAuBO,SAAS,iBAMd,WAAyC;AACzC,WAAS,MAAM,OAAwB;AACrC,UAAM,aAAa,OAAuB,IAAI;AAC9C,UAAM,WAAW,OAAkC,IAAI;AACvD,cAAU,MAAM;AACd,YAAM,WAAW,IAAI,UAAA;AACrB,eAAS,UAAU;AAEnB,UAAI,WAAW,SAAS;AACtB,iBAAS,MAAM,WAAW,SAAS,OAAO,SAAS,MAAM;AAAA,MAC3D;AAEA,aAAO,MAAM;AACX,iBAAS,QAAA;AACT,iBAAS,UAAU;AAAA,MACrB;AAAA,IACF,GAAG,CAAC,OAAO,KAAK,CAAC;AAEjB,WAAO,oBAAC,SAAI,OAAO,EAAE,QAAQ,OAAA,GAAU,KAAK,YAAY;AAAA,EAC1D;AAEA,WAAS,UAAU,QAAyB;AAC1C,WAAO,oBAAA,UAAA,EAAE;AAAA,EACX;AACA,SAAO,CAAC,OAAO,SAAS;AAC1B;"} |
@@ -9,2 +9,4 @@ import { createComponent, template, insert, use } from 'solid-js/web'; | ||
| #isMounted = false; | ||
| #isMounting = false; | ||
| #mountCb = null; | ||
| #dispose; | ||
@@ -16,2 +18,3 @@ #Component; | ||
| async mount(el, theme) { | ||
| this.#isMounting = true; | ||
| const { | ||
@@ -51,8 +54,20 @@ lazy | ||
| this.#isMounted = true; | ||
| this.#isMounting = false; | ||
| this.#dispose = dispose; | ||
| if (this.#mountCb) { | ||
| this.#mountCb(); | ||
| this.#mountCb = null; | ||
| } | ||
| } | ||
| unmount() { | ||
| if (!this.#isMounted) { | ||
| if (!this.#isMounted && !this.#isMounting) { | ||
| throw new Error("Devtools is not mounted"); | ||
| } | ||
| if (this.#isMounting) { | ||
| this.#mountCb = () => { | ||
| this.#dispose?.(); | ||
| this.#isMounted = false; | ||
| }; | ||
| return; | ||
| } | ||
| this.#dispose?.(); | ||
@@ -59,0 +74,0 @@ this.#isMounted = false; |
@@ -18,2 +18,4 @@ import * as solid_js from 'solid-js'; | ||
| "__#private@#isMounted": boolean; | ||
| "__#private@#isMounting": boolean; | ||
| "__#private@#mountCb": (() => void) | null; | ||
| "__#private@#dispose"?: () => void; | ||
@@ -30,2 +32,4 @@ "__#private@#Component": any; | ||
| "__#private@#isMounted": boolean; | ||
| "__#private@#isMounting": boolean; | ||
| "__#private@#mountCb": (() => void) | null; | ||
| "__#private@#dispose"?: () => void; | ||
@@ -32,0 +36,0 @@ "__#private@#Component": any; |
@@ -9,2 +9,4 @@ import { createComponent, template, insert, use } from 'solid-js/web'; | ||
| #isMounted = false; | ||
| #isMounting = false; | ||
| #mountCb = null; | ||
| #dispose; | ||
@@ -16,2 +18,3 @@ #Component; | ||
| async mount(el, theme) { | ||
| this.#isMounting = true; | ||
| const { | ||
@@ -51,8 +54,20 @@ lazy | ||
| this.#isMounted = true; | ||
| this.#isMounting = false; | ||
| this.#dispose = dispose; | ||
| if (this.#mountCb) { | ||
| this.#mountCb(); | ||
| this.#mountCb = null; | ||
| } | ||
| } | ||
| unmount() { | ||
| if (!this.#isMounted) { | ||
| if (!this.#isMounted && !this.#isMounting) { | ||
| throw new Error("Devtools is not mounted"); | ||
| } | ||
| if (this.#isMounting) { | ||
| this.#mountCb = () => { | ||
| this.#dispose?.(); | ||
| this.#isMounted = false; | ||
| }; | ||
| return; | ||
| } | ||
| this.#dispose?.(); | ||
@@ -59,0 +74,0 @@ this.#isMounted = false; |
@@ -9,2 +9,4 @@ import { createComponent, ssr, escape } from 'solid-js/web'; | ||
| #isMounted = false; | ||
| #isMounting = false; | ||
| #mountCb = null; | ||
| #dispose; | ||
@@ -16,2 +18,3 @@ #Component; | ||
| async mount(el, theme) { | ||
| this.#isMounting = true; | ||
| const { | ||
@@ -48,8 +51,20 @@ lazy | ||
| this.#isMounted = true; | ||
| this.#isMounting = false; | ||
| this.#dispose = dispose; | ||
| if (this.#mountCb) { | ||
| this.#mountCb(); | ||
| this.#mountCb = null; | ||
| } | ||
| } | ||
| unmount() { | ||
| if (!this.#isMounted) { | ||
| if (!this.#isMounted && !this.#isMounting) { | ||
| throw new Error("Devtools is not mounted"); | ||
| } | ||
| if (this.#isMounting) { | ||
| this.#mountCb = () => { | ||
| this.#dispose?.(); | ||
| this.#isMounted = false; | ||
| }; | ||
| return; | ||
| } | ||
| this.#dispose?.(); | ||
@@ -56,0 +71,0 @@ this.#isMounted = false; |
+1
-1
| { | ||
| "name": "@tanstack/devtools-utils", | ||
| "version": "0.2.0", | ||
| "version": "0.2.1", | ||
| "description": "TanStack Devtools utilities for creating your own devtools.", | ||
@@ -5,0 +5,0 @@ "author": "Tanner Linsley", |
@@ -35,14 +35,12 @@ import { useEffect, useRef } from 'react' | ||
| useEffect(() => { | ||
| if (devtools.current) return | ||
| const instance = new CoreClass() | ||
| devtools.current = instance | ||
| devtools.current = new CoreClass() | ||
| if (devToolRef.current) { | ||
| devtools.current.mount(devToolRef.current, props?.theme ?? 'dark') | ||
| instance.mount(devToolRef.current, props?.theme ?? 'dark') | ||
| } | ||
| return () => { | ||
| if (devToolRef.current) { | ||
| devtools.current?.unmount() | ||
| } | ||
| instance.unmount() | ||
| devtools.current = null | ||
| } | ||
@@ -49,0 +47,0 @@ }, [props?.theme]) |
+16
-1
@@ -17,2 +17,4 @@ /** @jsxImportSource solid-js - we use Solid.js as JSX here */ | ||
| #isMounted = false | ||
| #isMounting = false | ||
| #mountCb: (() => void) | null = null | ||
| #dispose?: () => void | ||
@@ -25,2 +27,3 @@ #Component: any | ||
| async mount<T extends HTMLElement>(el: T, theme: 'light' | 'dark') { | ||
| this.#isMounting = true | ||
| const { lazy } = await import('solid-js') | ||
@@ -54,9 +57,21 @@ const { render, Portal } = await import('solid-js/web') | ||
| this.#isMounted = true | ||
| this.#isMounting = false | ||
| this.#dispose = dispose | ||
| if (this.#mountCb) { | ||
| this.#mountCb() | ||
| this.#mountCb = null | ||
| } | ||
| } | ||
| unmount() { | ||
| if (!this.#isMounted) { | ||
| if (!this.#isMounted && !this.#isMounting) { | ||
| throw new Error('Devtools is not mounted') | ||
| } | ||
| if (this.#isMounting) { | ||
| this.#mountCb = () => { | ||
| this.#dispose?.() | ||
| this.#isMounted = false | ||
| } | ||
| return | ||
| } | ||
| this.#dispose?.() | ||
@@ -63,0 +78,0 @@ this.#isMounted = false |
45680
3.61%1135
5.78%