Sign In

@tanstack/devtools-utils

Package Overview
Dependencies
Maintainers
6
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tanstack/devtools-utils - npm Package Compare versions

Comparing version
0.3.1
to
0.3.2
+4
dist/solid-class/esm/class-mount-impl.d.ts
import { JSX } from 'solid-js';
export declare function __mountComponent(el: HTMLElement, theme: 'light' | 'dark', importFn: () => Promise<{
default: () => JSX.Element;
}>): () => void;
import { render, createComponent, Portal, insert, template } from "solid-js/web";
import { lazy } from "solid-js";
var _tmpl$ = /* @__PURE__ */ template(`<div style=height:100%>`);
function __mountComponent(el, theme, importFn) {
const Component = lazy(importFn);
const ThemeProvider = lazy(() => import("@tanstack/devtools-ui").then((m) => ({
default: m.ThemeContextProvider
})));
return render(() => createComponent(Portal, {
mount: el,
get children() {
var _el$ = _tmpl$();
insert(_el$, createComponent(ThemeProvider, {
theme,
get children() {
return createComponent(Component, {});
}
}));
return _el$;
}
}), el);
}
export {
__mountComponent
};
//# sourceMappingURL=class-mount-impl.js.map
{"version":3,"file":"class-mount-impl.js","sources":["../../../src/solid/class-mount-impl.tsx"],"sourcesContent":["/** @jsxImportSource solid-js - we use Solid.js as JSX here */\n\nimport { lazy } from 'solid-js'\nimport { Portal, render } from 'solid-js/web'\nimport type { JSX } from 'solid-js'\n\nexport function __mountComponent(\n el: HTMLElement,\n theme: 'light' | 'dark',\n importFn: () => Promise<{ default: () => JSX.Element }>,\n): () => void {\n const Component = lazy(importFn)\n const ThemeProvider = lazy(() =>\n import('@tanstack/devtools-ui').then((m) => ({\n default: m.ThemeContextProvider,\n })),\n )\n\n return render(\n () => (\n <Portal mount={el}>\n <div style={{ height: '100%' }}>\n <ThemeProvider theme={theme}>\n <Component />\n </ThemeProvider>\n </div>\n </Portal>\n ),\n el,\n )\n}\n"],"names":["__mountComponent","el","theme","importFn","Component","lazy","ThemeProvider","then","m","default","ThemeContextProvider","render","_$createComponent","Portal","mount","children","_el$","_tmpl$","_$insert"],"mappings":";;;AAMO,SAASA,iBACdC,IACAC,OACAC,UACY;AACZ,QAAMC,YAAYC,KAAKF,QAAQ;AAC/B,QAAMG,gBAAgBD,KAAK,MACzB,OAAO,uBAAuB,EAAEE,KAAMC,CAAAA,OAAO;AAAA,IAC3CC,SAASD,EAAEE;AAAAA,EAAAA,EACX,CACJ;AAEA,SAAOC,OACL,MAAAC,gBACGC,QAAM;AAAA,IAACC,OAAOb;AAAAA,IAAE,IAAAc,WAAA;AAAA,UAAAC,OAAAC,OAAAA;AAAAC,aAAAF,MAAAJ,gBAEZN,eAAa;AAAA,QAACJ;AAAAA,QAAY,IAAAa,WAAA;AAAA,iBAAAH,gBACxBR,WAAS,EAAA;AAAA,QAAA;AAAA,MAAA,CAAA,CAAA;AAAA,aAAAY;AAAAA,IAAA;AAAA,EAAA,CAAA,GAKlBf,EACF;AACF;"}
import { JSX } from 'solid-js';
/**
* Constructs the core class for the Devtools.
* This utility is used to construct a lazy loaded Solid component for the Devtools.
* It returns a tuple containing the main DevtoolsCore class and a NoOpDevtoolsCore class.
* The NoOpDevtoolsCore class is a no-op implementation that can be used for production if you want to explicitly exclude
* the Devtools from your application.
* @param importFn A function that returns a dynamic import of the Solid component
* @returns Tuple containing the DevtoolsCore class and a NoOpDevtoolsCore class
*/
export declare function constructCoreClass(importFn: () => Promise<{
default: () => JSX.Element;
}>): readonly [{
new (): {
"__#private@#isMounted": boolean;
"__#private@#isMounting": boolean;
"__#private@#abortMount": boolean;
"__#private@#dispose"?: () => void;
mount<T extends HTMLElement>(el: T, theme: "light" | "dark"): Promise<void>;
unmount(): void;
};
}, {
new (): {
mount<T extends HTMLElement>(_el: T, _theme: "light" | "dark"): Promise<void>;
unmount(): void;
"__#private@#isMounted": boolean;
"__#private@#isMounting": boolean;
"__#private@#abortMount": boolean;
"__#private@#dispose"?: () => void;
};
}];
export type ClassType = ReturnType<typeof constructCoreClass>[0];
function constructCoreClass(importFn) {
class DevtoolsCore {
#isMounted = false;
#isMounting = false;
#abortMount = false;
#dispose;
constructor() {
}
async mount(el, theme) {
if (this.#isMounted || this.#isMounting) {
throw new Error("Devtools is already mounted");
}
this.#isMounting = true;
this.#abortMount = false;
try {
const { __mountComponent } = await import("./class-mount-impl.js");
if (this.#abortMount) {
this.#isMounting = false;
return;
}
this.#dispose = __mountComponent(el, theme, importFn);
this.#isMounted = true;
this.#isMounting = false;
} catch (err) {
this.#isMounting = false;
console.error("[TanStack Devtools] Failed to load:", err);
}
}
unmount() {
if (!this.#isMounted && !this.#isMounting) {
throw new Error("Devtools is not mounted");
}
if (this.#isMounting) {
this.#abortMount = true;
this.#isMounting = false;
return;
}
this.#dispose?.();
this.#isMounted = false;
}
}
class NoOpDevtoolsCore extends DevtoolsCore {
constructor() {
super();
}
async mount(_el, _theme) {
}
unmount() {
}
}
return [DevtoolsCore, NoOpDevtoolsCore];
}
export {
constructCoreClass
};
//# sourceMappingURL=class.js.map
{"version":3,"file":"class.js","sources":["../../../src/solid/class.ts"],"sourcesContent":["import type { JSX } from 'solid-js'\n\n/**\n * Constructs the core class for the Devtools.\n * This utility is used to construct a lazy loaded Solid component for the Devtools.\n * It returns a tuple containing the main DevtoolsCore class and a NoOpDevtoolsCore class.\n * The NoOpDevtoolsCore class is a no-op implementation that can be used for production if you want to explicitly exclude\n * the Devtools from your application.\n * @param importFn A function that returns a dynamic import of the Solid component\n * @returns Tuple containing the DevtoolsCore class and a NoOpDevtoolsCore class\n */\nexport function constructCoreClass(\n importFn: () => Promise<{ default: () => JSX.Element }>,\n) {\n class DevtoolsCore {\n #isMounted = false\n #isMounting = false\n #abortMount = false\n #dispose?: () => void\n\n constructor() {}\n\n async mount<T extends HTMLElement>(el: T, theme: 'light' | 'dark') {\n if (this.#isMounted || this.#isMounting) {\n throw new Error('Devtools is already mounted')\n }\n this.#isMounting = true\n this.#abortMount = false\n\n try {\n const { __mountComponent } = await import('./class-mount-impl')\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- can be set by unmount() during await\n if (this.#abortMount) {\n this.#isMounting = false\n return\n }\n\n this.#dispose = __mountComponent(el, theme, importFn)\n this.#isMounted = true\n this.#isMounting = false\n } catch (err) {\n this.#isMounting = false\n console.error('[TanStack Devtools] Failed to load:', err)\n }\n }\n\n unmount() {\n if (!this.#isMounted && !this.#isMounting) {\n throw new Error('Devtools is not mounted')\n }\n if (this.#isMounting) {\n this.#abortMount = true\n this.#isMounting = false\n return\n }\n this.#dispose?.()\n this.#isMounted = false\n }\n }\n\n class NoOpDevtoolsCore extends DevtoolsCore {\n constructor() {\n super()\n }\n async mount<T extends HTMLElement>(_el: T, _theme: 'light' | 'dark') {}\n unmount() {}\n }\n\n return [DevtoolsCore, NoOpDevtoolsCore] as const\n}\n\nexport type ClassType = ReturnType<typeof constructCoreClass>[0]\n"],"names":[],"mappings":"AAWO,SAAS,mBACd,UACA;AAAA,EACA,MAAM,aAAa;AAAA,IACjB,aAAa;AAAA,IACb,cAAc;AAAA,IACd,cAAc;AAAA,IACd;AAAA,IAEA,cAAc;AAAA,IAAC;AAAA,IAEf,MAAM,MAA6B,IAAO,OAAyB;AACjE,UAAI,KAAK,cAAc,KAAK,aAAa;AACvC,cAAM,IAAI,MAAM,6BAA6B;AAAA,MAC/C;AACA,WAAK,cAAc;AACnB,WAAK,cAAc;AAEnB,UAAI;AACF,cAAM,EAAE,iBAAA,IAAqB,MAAM,OAAO,uBAAoB;AAE9D,YAAI,KAAK,aAAa;AACpB,eAAK,cAAc;AACnB;AAAA,QACF;AAEA,aAAK,WAAW,iBAAiB,IAAI,OAAO,QAAQ;AACpD,aAAK,aAAa;AAClB,aAAK,cAAc;AAAA,MACrB,SAAS,KAAK;AACZ,aAAK,cAAc;AACnB,gBAAQ,MAAM,uCAAuC,GAAG;AAAA,MAC1D;AAAA,IACF;AAAA,IAEA,UAAU;AACR,UAAI,CAAC,KAAK,cAAc,CAAC,KAAK,aAAa;AACzC,cAAM,IAAI,MAAM,yBAAyB;AAAA,MAC3C;AACA,UAAI,KAAK,aAAa;AACpB,aAAK,cAAc;AACnB,aAAK,cAAc;AACnB;AAAA,MACF;AACA,WAAK,WAAA;AACL,WAAK,aAAa;AAAA,IACpB;AAAA,EAAA;AAAA,EAGF,MAAM,yBAAyB,aAAa;AAAA,IAC1C,cAAc;AACZ,YAAA;AAAA,IACF;AAAA,IACA,MAAM,MAA6B,KAAQ,QAA0B;AAAA,IAAC;AAAA,IACtE,UAAU;AAAA,IAAC;AAAA,EAAA;AAGb,SAAO,CAAC,cAAc,gBAAgB;AACxC;"}
export * from './class.js';
export * from './panel.js';
export * from './plugin.js';
export { __mountComponent } from './class-mount-impl.js';
import { ClassType } from './class.js';
export interface DevtoolsPanelProps {
theme?: 'light' | 'dark';
}
export declare function createSolidPanel<TComponentProps extends DevtoolsPanelProps | undefined>(CoreClass: ClassType): readonly [(props: TComponentProps) => import("solid-js").JSX.Element, (_props: TComponentProps) => import("solid-js").JSX.Element];
import { JSX } from 'solid-js';
import { DevtoolsPanelProps } from './panel.js';
export declare function createSolidPlugin({ Component, ...config }: {
name: string;
id?: string;
defaultOpen?: boolean;
Component: (props: DevtoolsPanelProps) => JSX.Element;
}): readonly [() => {
render: (_el: HTMLElement, theme: "light" | "dark") => JSX.Element;
name: string;
id?: string;
defaultOpen?: boolean;
}, () => {
render: (_el: HTMLElement, _theme: "light" | "dark") => JSX.Element;
name: string;
id?: string;
defaultOpen?: boolean;
}];
import { render, createComponent, Portal, ssr, ssrStyleProperty, escape } from 'solid-js/web';
import { lazy } from 'solid-js';
// src/solid/class-mount-impl.tsx
var _tmpl$ = ['<div style="', '">', "</div>"];
function __mountComponent(el, theme, importFn) {
const Component = lazy(importFn);
const ThemeProvider = lazy(() => import('@tanstack/devtools-ui').then((m) => ({
default: m.ThemeContextProvider
})));
return render(() => createComponent(Portal, {
mount: el,
get children() {
return ssr(_tmpl$, ssrStyleProperty("height:", "100%"), escape(createComponent(ThemeProvider, {
theme,
get children() {
return createComponent(Component, {});
}
})));
}
}), el);
}
export { __mountComponent };
import { render, createComponent, Portal, insert, template } from 'solid-js/web';
import { lazy } from 'solid-js';
// src/solid/class-mount-impl.tsx
var _tmpl$ = /* @__PURE__ */ template(`<div style=height:100%>`);
function __mountComponent(el, theme, importFn) {
const Component = lazy(importFn);
const ThemeProvider = lazy(() => import('@tanstack/devtools-ui').then((m) => ({
default: m.ThemeContextProvider
})));
return render(() => createComponent(Portal, {
mount: el,
get children() {
var _el$ = _tmpl$();
insert(_el$, createComponent(ThemeProvider, {
theme,
get children() {
return createComponent(Component, {});
}
}));
return _el$;
}
}), el);
}
export { __mountComponent };
export { __mountComponent } from '../chunk/UX5ZZ4MG.js';
export { __mountComponent } from '../chunk/ZXPCWXRH.js';
/** @jsxImportSource solid-js - we use Solid.js as JSX here */
import { lazy } from 'solid-js'
import { Portal, render } from 'solid-js/web'
import type { JSX } from 'solid-js'
export function __mountComponent(
el: HTMLElement,
theme: 'light' | 'dark',
importFn: () => Promise<{ default: () => JSX.Element }>,
): () => void {
const Component = lazy(importFn)
const ThemeProvider = lazy(() =>
import('@tanstack/devtools-ui').then((m) => ({
default: m.ThemeContextProvider,
})),
)
return render(
() => (
<Portal mount={el}>
<div style={{ height: '100%' }}>
<ThemeProvider theme={theme}>
<Component />
</ThemeProvider>
</div>
</Portal>
),
el,
)
}
import type { JSX } from 'solid-js'
/**
* Constructs the core class for the Devtools.
* This utility is used to construct a lazy loaded Solid component for the Devtools.
* It returns a tuple containing the main DevtoolsCore class and a NoOpDevtoolsCore class.
* The NoOpDevtoolsCore class is a no-op implementation that can be used for production if you want to explicitly exclude
* the Devtools from your application.
* @param importFn A function that returns a dynamic import of the Solid component
* @returns Tuple containing the DevtoolsCore class and a NoOpDevtoolsCore class
*/
export function constructCoreClass(
importFn: () => Promise<{ default: () => JSX.Element }>,
) {
class DevtoolsCore {
#isMounted = false
#isMounting = false
#abortMount = false
#dispose?: () => void
constructor() {}
async mount<T extends HTMLElement>(el: T, theme: 'light' | 'dark') {
if (this.#isMounted || this.#isMounting) {
throw new Error('Devtools is already mounted')
}
this.#isMounting = true
this.#abortMount = false
try {
const { __mountComponent } = await import('./class-mount-impl')
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- can be set by unmount() during await
if (this.#abortMount) {
this.#isMounting = false
return
}
this.#dispose = __mountComponent(el, theme, importFn)
this.#isMounted = true
this.#isMounting = false
} catch (err) {
this.#isMounting = false
console.error('[TanStack Devtools] Failed to load:', err)
}
}
unmount() {
if (!this.#isMounted && !this.#isMounting) {
throw new Error('Devtools is not mounted')
}
if (this.#isMounting) {
this.#abortMount = true
this.#isMounting = false
return
}
this.#dispose?.()
this.#isMounted = false
}
}
class NoOpDevtoolsCore extends DevtoolsCore {
constructor() {
super()
}
async mount<T extends HTMLElement>(_el: T, _theme: 'light' | 'dark') {}
unmount() {}
}
return [DevtoolsCore, NoOpDevtoolsCore] as const
}
export type ClassType = ReturnType<typeof constructCoreClass>[0]
+24
-50

@@ -1,56 +0,32 @@

import { createComponent, insert, use, template } from 'solid-js/web';
export { __mountComponent } from './chunk/ZXPCWXRH.js';
import { use, createComponent, template } from 'solid-js/web';
import { createSignal, onMount, onCleanup } from 'solid-js';
// src/solid/class.tsx
var _tmpl$ = /* @__PURE__ */ template(`<div style=height:100%>`);
function constructCoreClass(Component) {
// src/solid/class.ts
function constructCoreClass(importFn) {
class DevtoolsCore {
#isMounted = false;
#isMounting = false;
#mountCb = null;
#abortMount = false;
#dispose;
#Component;
#ThemeProvider;
constructor() {
}
async mount(el, theme) {
this.#isMounting = true;
const {
lazy
} = await import('solid-js');
const {
render,
Portal
} = await import('solid-js/web');
if (this.#isMounted) {
if (this.#isMounted || this.#isMounting) {
throw new Error("Devtools is already mounted");
}
const mountTo = el;
const dispose = render(() => {
this.#Component = Component;
this.#ThemeProvider = lazy(() => import('@tanstack/devtools-ui').then((mod) => ({
default: mod.ThemeContextProvider
})));
const Devtools = this.#Component;
const ThemeProvider = this.#ThemeProvider;
return createComponent(Portal, {
mount: mountTo,
get children() {
var _el$ = _tmpl$();
insert(_el$, createComponent(ThemeProvider, {
theme,
get children() {
return createComponent(Devtools, {});
}
}));
return _el$;
}
});
}, mountTo);
this.#isMounted = true;
this.#isMounting = false;
this.#dispose = dispose;
if (this.#mountCb) {
this.#mountCb();
this.#mountCb = null;
this.#isMounting = true;
this.#abortMount = false;
try {
const { __mountComponent: __mountComponent2 } = await import('./class-mount-impl/ZAIAXV4M.js');
if (this.#abortMount) {
this.#isMounting = false;
return;
}
this.#dispose = __mountComponent2(el, theme, importFn);
this.#isMounted = true;
this.#isMounting = false;
} catch (err) {
this.#isMounting = false;
console.error("[TanStack Devtools] Failed to load:", err);
}

@@ -63,6 +39,4 @@ }

if (this.#isMounting) {
this.#mountCb = () => {
this.#dispose?.();
this.#isMounted = false;
};
this.#abortMount = true;
this.#isMounting = false;
return;

@@ -85,3 +59,3 @@ }

}
var _tmpl$2 = /* @__PURE__ */ template(`<div style=height:100%>`);
var _tmpl$ = /* @__PURE__ */ template(`<div style=height:100%>`);
function createSolidPanel(CoreClass) {

@@ -100,3 +74,3 @@ function Panel(props) {

return (() => {
var _el$ = _tmpl$2();
var _el$ = _tmpl$();
var _ref$ = devToolRef;

@@ -103,0 +77,0 @@ typeof _ref$ === "function" ? use(_ref$, _el$) : devToolRef = _el$;

import * as solid_js from 'solid-js';
import { JSX } from 'solid-js';
/** @jsxImportSource solid-js - we use Solid.js as JSX here */
/**

@@ -12,13 +10,13 @@ * Constructs the core class for the Devtools.

* the Devtools from your application.
* @param importPath The path to the Solid component to be lazily imported
* @param importFn A function that returns a dynamic import of the Solid component
* @returns Tuple containing the DevtoolsCore class and a NoOpDevtoolsCore class
*/
declare function constructCoreClass(Component: () => JSX.Element): readonly [{
declare function constructCoreClass(importFn: () => Promise<{
default: () => JSX.Element;
}>): readonly [{
new (): {
"__#private@#isMounted": boolean;
"__#private@#isMounting": boolean;
"__#private@#mountCb": (() => void) | null;
"__#private@#abortMount": boolean;
"__#private@#dispose"?: () => void;
"__#private@#Component": any;
"__#private@#ThemeProvider": any;
mount<T extends HTMLElement>(el: T, theme: "light" | "dark"): Promise<void>;

@@ -33,6 +31,4 @@ unmount(): void;

"__#private@#isMounting": boolean;
"__#private@#mountCb": (() => void) | null;
"__#private@#abortMount": boolean;
"__#private@#dispose"?: () => void;
"__#private@#Component": any;
"__#private@#ThemeProvider": any;
};

@@ -66,2 +62,8 @@ }];

export { type ClassType, type DevtoolsPanelProps, constructCoreClass, createSolidPanel, createSolidPlugin };
/** @jsxImportSource solid-js - we use Solid.js as JSX here */
declare function __mountComponent(el: HTMLElement, theme: 'light' | 'dark', importFn: () => Promise<{
default: () => JSX.Element;
}>): () => void;
export { type ClassType, type DevtoolsPanelProps, __mountComponent, constructCoreClass, createSolidPanel, createSolidPlugin };

@@ -1,56 +0,32 @@

import { createComponent, insert, use, template } from 'solid-js/web';
export { __mountComponent } from './chunk/ZXPCWXRH.js';
import { use, createComponent, template } from 'solid-js/web';
import { createSignal, onMount, onCleanup } from 'solid-js';
// src/solid/class.tsx
var _tmpl$ = /* @__PURE__ */ template(`<div style=height:100%>`);
function constructCoreClass(Component) {
// src/solid/class.ts
function constructCoreClass(importFn) {
class DevtoolsCore {
#isMounted = false;
#isMounting = false;
#mountCb = null;
#abortMount = false;
#dispose;
#Component;
#ThemeProvider;
constructor() {
}
async mount(el, theme) {
this.#isMounting = true;
const {
lazy
} = await import('solid-js');
const {
render,
Portal
} = await import('solid-js/web');
if (this.#isMounted) {
if (this.#isMounted || this.#isMounting) {
throw new Error("Devtools is already mounted");
}
const mountTo = el;
const dispose = render(() => {
this.#Component = Component;
this.#ThemeProvider = lazy(() => import('@tanstack/devtools-ui').then((mod) => ({
default: mod.ThemeContextProvider
})));
const Devtools = this.#Component;
const ThemeProvider = this.#ThemeProvider;
return createComponent(Portal, {
mount: mountTo,
get children() {
var _el$ = _tmpl$();
insert(_el$, createComponent(ThemeProvider, {
theme,
get children() {
return createComponent(Devtools, {});
}
}));
return _el$;
}
});
}, mountTo);
this.#isMounted = true;
this.#isMounting = false;
this.#dispose = dispose;
if (this.#mountCb) {
this.#mountCb();
this.#mountCb = null;
this.#isMounting = true;
this.#abortMount = false;
try {
const { __mountComponent: __mountComponent2 } = await import('./class-mount-impl/ZAIAXV4M.js');
if (this.#abortMount) {
this.#isMounting = false;
return;
}
this.#dispose = __mountComponent2(el, theme, importFn);
this.#isMounted = true;
this.#isMounting = false;
} catch (err) {
this.#isMounting = false;
console.error("[TanStack Devtools] Failed to load:", err);
}

@@ -63,6 +39,4 @@ }

if (this.#isMounting) {
this.#mountCb = () => {
this.#dispose?.();
this.#isMounted = false;
};
this.#abortMount = true;
this.#isMounting = false;
return;

@@ -85,3 +59,3 @@ }

}
var _tmpl$2 = /* @__PURE__ */ template(`<div style=height:100%>`);
var _tmpl$ = /* @__PURE__ */ template(`<div style=height:100%>`);
function createSolidPanel(CoreClass) {

@@ -100,3 +74,3 @@ function Panel(props) {

return (() => {
var _el$ = _tmpl$2();
var _el$ = _tmpl$();
var _ref$ = devToolRef;

@@ -103,0 +77,0 @@ typeof _ref$ === "function" ? use(_ref$, _el$) : devToolRef = _el$;

@@ -1,54 +0,32 @@

import { createComponent, ssr, ssrStyleProperty, escape } from 'solid-js/web';
export { __mountComponent } from './chunk/UX5ZZ4MG.js';
import { ssr, ssrStyleProperty, createComponent } from 'solid-js/web';
import { createSignal, onMount, onCleanup } from 'solid-js';
// src/solid/class.tsx
var _tmpl$ = ['<div style="', '">', "</div>"];
function constructCoreClass(Component) {
// src/solid/class.ts
function constructCoreClass(importFn) {
class DevtoolsCore {
#isMounted = false;
#isMounting = false;
#mountCb = null;
#abortMount = false;
#dispose;
#Component;
#ThemeProvider;
constructor() {
}
async mount(el, theme) {
this.#isMounting = true;
const {
lazy
} = await import('solid-js');
const {
render,
Portal
} = await import('solid-js/web');
if (this.#isMounted) {
if (this.#isMounted || this.#isMounting) {
throw new Error("Devtools is already mounted");
}
const mountTo = el;
const dispose = render(() => {
this.#Component = Component;
this.#ThemeProvider = lazy(() => import('@tanstack/devtools-ui').then((mod) => ({
default: mod.ThemeContextProvider
})));
const Devtools = this.#Component;
const ThemeProvider = this.#ThemeProvider;
return createComponent(Portal, {
mount: mountTo,
get children() {
return ssr(_tmpl$, ssrStyleProperty("height:", "100%"), escape(createComponent(ThemeProvider, {
theme,
get children() {
return createComponent(Devtools, {});
}
})));
}
});
}, mountTo);
this.#isMounted = true;
this.#isMounting = false;
this.#dispose = dispose;
if (this.#mountCb) {
this.#mountCb();
this.#mountCb = null;
this.#isMounting = true;
this.#abortMount = false;
try {
const { __mountComponent: __mountComponent2 } = await import('./class-mount-impl/LK7V47IP.js');
if (this.#abortMount) {
this.#isMounting = false;
return;
}
this.#dispose = __mountComponent2(el, theme, importFn);
this.#isMounted = true;
this.#isMounting = false;
} catch (err) {
this.#isMounting = false;
console.error("[TanStack Devtools] Failed to load:", err);
}

@@ -61,6 +39,4 @@ }

if (this.#isMounting) {
this.#mountCb = () => {
this.#dispose?.();
this.#isMounted = false;
};
this.#abortMount = true;
this.#isMounting = false;
return;

@@ -83,3 +59,3 @@ }

}
var _tmpl$2 = ['<div style="', '"></div>'];
var _tmpl$ = ['<div style="', '"></div>'];
function createSolidPanel(CoreClass) {

@@ -93,3 +69,3 @@ function Panel(props) {

});
return ssr(_tmpl$2, ssrStyleProperty("height:", "100%"));
return ssr(_tmpl$, ssrStyleProperty("height:", "100%"));
}

@@ -96,0 +72,0 @@ function NoOpPanel(_props) {

{
"name": "@tanstack/devtools-utils",
"version": "0.3.1",
"version": "0.3.2",
"description": "TanStack Devtools utilities for creating your own devtools.",

@@ -35,2 +35,6 @@ "author": "Tanner Linsley",

"./solid": {
"workerd": {
"types": "./dist/solid/esm/index.d.ts",
"import": "./dist/solid/esm/server.js"
},
"browser": {

@@ -51,2 +55,8 @@ "development": {

},
"./solid/class": {
"import": {
"types": "./dist/solid-class/esm/class.d.ts",
"default": "./dist/solid-class/esm/class.js"
}
},
"./vue": {

@@ -108,4 +118,4 @@ "import": {

"test:build": "publint --strict",
"build": "vite build && vite build --config vite.config.preact.ts && vite build --config vite.config.vue.ts && tsup "
"build": "vite build && vite build --config vite.config.preact.ts && vite build --config vite.config.vue.ts && vite build --config vite.config.solid-class.ts && tsup"
}
}

@@ -5,22 +5,11 @@ /** @jsxImportSource solid-js - we use Solid.js as JSX here */

const lazyImportMock = vi.fn((fn) => fn())
const renderMock = vi.fn()
const portalMock = vi.fn((props: any) => <div>{props.children}</div>)
const disposeMock = vi.fn()
const mountComponentMock = vi.fn(() => disposeMock)
vi.mock('solid-js', async () => {
const actual = await vi.importActual<any>('solid-js')
return {
...actual,
lazy: lazyImportMock,
}
})
vi.mock('./class-mount-impl', () => ({
__mountComponent: mountComponentMock,
}))
vi.mock('solid-js/web', async () => {
const actual = await vi.importActual<any>('solid-js/web')
return {
...actual,
render: renderMock,
Portal: portalMock,
}
})
const importFn = () =>
Promise.resolve({ default: () => <div>Test Component</div> })

@@ -31,24 +20,20 @@ describe('constructCoreClass', () => {

})
it('should export DevtoolsCore and NoOpDevtoolsCore classes and make no calls to Solid.js primitives', () => {
const [DevtoolsCore, NoOpDevtoolsCore] = constructCoreClass(() => (
<div>Test Component</div>
))
const [DevtoolsCore, NoOpDevtoolsCore] = constructCoreClass(importFn)
expect(DevtoolsCore).toBeDefined()
expect(NoOpDevtoolsCore).toBeDefined()
expect(lazyImportMock).not.toHaveBeenCalled()
expect(mountComponentMock).not.toHaveBeenCalled()
})
it('DevtoolsCore should call solid primitives when mount is called', async () => {
const [DevtoolsCore, _] = constructCoreClass(() => (
<div>Test Component</div>
))
it('DevtoolsCore should call __mountComponent when mount is called', async () => {
const [DevtoolsCore] = constructCoreClass(importFn)
const instance = new DevtoolsCore()
await instance.mount(document.createElement('div'), 'dark')
expect(renderMock).toHaveBeenCalled()
const el = document.createElement('div')
await instance.mount(el, 'dark')
expect(mountComponentMock).toHaveBeenCalledWith(el, 'dark', importFn)
})
it('DevtoolsCore should throw if mount is called twice without unmounting', async () => {
const [DevtoolsCore, _] = constructCoreClass(() => (
<div>Test Component</div>
))
const [DevtoolsCore] = constructCoreClass(importFn)
const instance = new DevtoolsCore()

@@ -62,5 +47,3 @@ await instance.mount(document.createElement('div'), 'dark')

it('DevtoolsCore should throw if unmount is called before mount', () => {
const [DevtoolsCore, _] = constructCoreClass(() => (
<div>Test Component</div>
))
const [DevtoolsCore] = constructCoreClass(importFn)
const instance = new DevtoolsCore()

@@ -71,5 +54,3 @@ expect(() => instance.unmount()).toThrow('Devtools is not mounted')

it('DevtoolsCore should allow mount after unmount', async () => {
const [DevtoolsCore, _] = constructCoreClass(() => (
<div>Test Component</div>
))
const [DevtoolsCore] = constructCoreClass(importFn)
const instance = new DevtoolsCore()

@@ -83,18 +64,31 @@ await instance.mount(document.createElement('div'), 'dark')

it('NoOpDevtoolsCore should not call any solid primitives when mount is called', async () => {
const [_, NoOpDevtoolsCore] = constructCoreClass(() => (
<div>Test Component</div>
))
it('DevtoolsCore should call dispose on unmount', async () => {
const [DevtoolsCore] = constructCoreClass(importFn)
const instance = new DevtoolsCore()
await instance.mount(document.createElement('div'), 'dark')
instance.unmount()
expect(disposeMock).toHaveBeenCalled()
})
it('DevtoolsCore should abort mount if unmount is called during mounting', async () => {
const [DevtoolsCore] = constructCoreClass(importFn)
const instance = new DevtoolsCore()
const mountPromise = instance.mount(document.createElement('div'), 'dark')
// Unmount while mount is in progress — triggers abort path
// Note: since the mock resolves immediately, this tests the #abortMount flag
await mountPromise
// Mount completed, so unmount should work normally
instance.unmount()
expect(disposeMock).toHaveBeenCalled()
})
it('NoOpDevtoolsCore should not call __mountComponent when mount is called', async () => {
const [, NoOpDevtoolsCore] = constructCoreClass(importFn)
const noOpInstance = new NoOpDevtoolsCore()
await noOpInstance.mount(document.createElement('div'), 'dark')
expect(lazyImportMock).not.toHaveBeenCalled()
expect(renderMock).not.toHaveBeenCalled()
expect(portalMock).not.toHaveBeenCalled()
expect(mountComponentMock).not.toHaveBeenCalled()
})
it('NoOpDevtoolsCore should not throw if mount is called multiple times', async () => {
const [_, NoOpDevtoolsCore] = constructCoreClass(() => (
<div>Test Component</div>
))
const [, NoOpDevtoolsCore] = constructCoreClass(importFn)
const noOpInstance = new NoOpDevtoolsCore()

@@ -108,5 +102,3 @@ await noOpInstance.mount(document.createElement('div'), 'dark')

it('NoOpDevtoolsCore should not throw if unmount is called before mount', () => {
const [_, NoOpDevtoolsCore] = constructCoreClass(() => (
<div>Test Component</div>
))
const [, NoOpDevtoolsCore] = constructCoreClass(importFn)
const noOpInstance = new NoOpDevtoolsCore()

@@ -117,5 +109,3 @@ expect(() => noOpInstance.unmount()).not.toThrow()

it('NoOpDevtoolsCore should not throw if unmount is called after mount', async () => {
const [_, NoOpDevtoolsCore] = constructCoreClass(() => (
<div>Test Component</div>
))
const [, NoOpDevtoolsCore] = constructCoreClass(importFn)
const noOpInstance = new NoOpDevtoolsCore()

@@ -122,0 +112,0 @@ await noOpInstance.mount(document.createElement('div'), 'dark')

export * from './class'
export * from './panel'
export * from './plugin'
export { __mountComponent } from './class-mount-impl'
/** @jsxImportSource solid-js - we use Solid.js as JSX here */
import type { JSX } from 'solid-js'
/**
* Constructs the core class for the Devtools.
* This utility is used to construct a lazy loaded Solid component for the Devtools.
* It returns a tuple containing the main DevtoolsCore class and a NoOpDevtoolsCore class.
* The NoOpDevtoolsCore class is a no-op implementation that can be used for production if you want to explicitly exclude
* the Devtools from your application.
* @param importPath The path to the Solid component to be lazily imported
* @returns Tuple containing the DevtoolsCore class and a NoOpDevtoolsCore class
*/
export function constructCoreClass(Component: () => JSX.Element) {
class DevtoolsCore {
#isMounted = false
#isMounting = false
#mountCb: (() => void) | null = null
#dispose?: () => void
#Component: any
#ThemeProvider: any
constructor() {}
async mount<T extends HTMLElement>(el: T, theme: 'light' | 'dark') {
this.#isMounting = true
const { lazy } = await import('solid-js')
const { render, Portal } = await import('solid-js/web')
if (this.#isMounted) {
throw new Error('Devtools is already mounted')
}
const mountTo = el
const dispose = render(() => {
this.#Component = Component
this.#ThemeProvider = lazy(() =>
import('@tanstack/devtools-ui').then((mod) => ({
default: mod.ThemeContextProvider,
})),
)
const Devtools = this.#Component
const ThemeProvider = this.#ThemeProvider
return (
<Portal mount={mountTo}>
<div style={{ height: '100%' }}>
<ThemeProvider theme={theme}>
<Devtools />
</ThemeProvider>
</div>
</Portal>
)
}, mountTo)
this.#isMounted = true
this.#isMounting = false
this.#dispose = dispose
if (this.#mountCb) {
this.#mountCb()
this.#mountCb = null
}
}
unmount() {
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?.()
this.#isMounted = false
}
}
class NoOpDevtoolsCore extends DevtoolsCore {
constructor() {
super()
}
async mount<T extends HTMLElement>(_el: T, _theme: 'light' | 'dark') {}
unmount() {}
}
return [DevtoolsCore, NoOpDevtoolsCore] as const
}
export type ClassType = ReturnType<typeof constructCoreClass>[0]