@tanstack/devtools-utils 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/solid/esm/chunk/UX5ZZ4MG.js +24 -0
- package/dist/solid/esm/chunk/ZXPCWXRH.js +26 -0
- package/dist/solid/esm/class-mount-impl/LK7V47IP.js +1 -0
- package/dist/solid/esm/class-mount-impl/ZAIAXV4M.js +1 -0
- package/dist/solid/esm/dev.js +24 -50
- package/dist/solid/esm/index.d.ts +13 -11
- package/dist/solid/esm/index.js +24 -50
- package/dist/solid/esm/server.js +24 -48
- package/dist/solid-class/esm/class-mount-impl.d.ts +4 -0
- package/dist/solid-class/esm/class-mount-impl.js +26 -0
- package/dist/solid-class/esm/class-mount-impl.js.map +1 -0
- package/dist/solid-class/esm/class.d.ts +32 -0
- package/dist/solid-class/esm/class.js +56 -0
- package/dist/solid-class/esm/class.js.map +1 -0
- package/dist/solid-class/esm/class.test.d.ts +1 -0
- package/dist/solid-class/esm/index.d.ts +4 -0
- package/dist/solid-class/esm/panel.d.ts +5 -0
- package/dist/solid-class/esm/plugin.d.ts +18 -0
- package/package.json +12 -2
- package/src/solid/class-mount-impl.tsx +31 -0
- package/src/solid/class.test.tsx +44 -54
- package/src/solid/{class.tsx → class.ts} +25 -41
- package/src/solid/index.ts +1 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { render, createComponent, Portal, ssr, ssrStyleProperty, escape } from 'solid-js/web';
|
|
2
|
+
import { lazy } from 'solid-js';
|
|
3
|
+
|
|
4
|
+
// src/solid/class-mount-impl.tsx
|
|
5
|
+
var _tmpl$ = ['<div style="', '">', "</div>"];
|
|
6
|
+
function __mountComponent(el, theme, importFn) {
|
|
7
|
+
const Component = lazy(importFn);
|
|
8
|
+
const ThemeProvider = lazy(() => import('@tanstack/devtools-ui').then((m) => ({
|
|
9
|
+
default: m.ThemeContextProvider
|
|
10
|
+
})));
|
|
11
|
+
return render(() => createComponent(Portal, {
|
|
12
|
+
mount: el,
|
|
13
|
+
get children() {
|
|
14
|
+
return ssr(_tmpl$, ssrStyleProperty("height:", "100%"), escape(createComponent(ThemeProvider, {
|
|
15
|
+
theme,
|
|
16
|
+
get children() {
|
|
17
|
+
return createComponent(Component, {});
|
|
18
|
+
}
|
|
19
|
+
})));
|
|
20
|
+
}
|
|
21
|
+
}), el);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { __mountComponent };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { render, createComponent, Portal, insert, template } from 'solid-js/web';
|
|
2
|
+
import { lazy } from 'solid-js';
|
|
3
|
+
|
|
4
|
+
// src/solid/class-mount-impl.tsx
|
|
5
|
+
var _tmpl$ = /* @__PURE__ */ template(`<div style=height:100%>`);
|
|
6
|
+
function __mountComponent(el, theme, importFn) {
|
|
7
|
+
const Component = lazy(importFn);
|
|
8
|
+
const ThemeProvider = lazy(() => import('@tanstack/devtools-ui').then((m) => ({
|
|
9
|
+
default: m.ThemeContextProvider
|
|
10
|
+
})));
|
|
11
|
+
return render(() => createComponent(Portal, {
|
|
12
|
+
mount: el,
|
|
13
|
+
get children() {
|
|
14
|
+
var _el$ = _tmpl$();
|
|
15
|
+
insert(_el$, createComponent(ThemeProvider, {
|
|
16
|
+
theme,
|
|
17
|
+
get children() {
|
|
18
|
+
return createComponent(Component, {});
|
|
19
|
+
}
|
|
20
|
+
}));
|
|
21
|
+
return _el$;
|
|
22
|
+
}
|
|
23
|
+
}), el);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { __mountComponent };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { __mountComponent } from '../chunk/UX5ZZ4MG.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { __mountComponent } from '../chunk/ZXPCWXRH.js';
|
package/dist/solid/esm/dev.js
CHANGED
|
@@ -1,58 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
export { __mountComponent } from './chunk/ZXPCWXRH.js';
|
|
2
|
+
import { use, createComponent, template } from 'solid-js/web';
|
|
2
3
|
import { createSignal, onMount, onCleanup } from 'solid-js';
|
|
3
4
|
|
|
4
|
-
// src/solid/class.
|
|
5
|
-
|
|
6
|
-
function constructCoreClass(Component) {
|
|
5
|
+
// src/solid/class.ts
|
|
6
|
+
function constructCoreClass(importFn) {
|
|
7
7
|
class DevtoolsCore {
|
|
8
8
|
#isMounted = false;
|
|
9
9
|
#isMounting = false;
|
|
10
|
-
#
|
|
10
|
+
#abortMount = false;
|
|
11
11
|
#dispose;
|
|
12
|
-
#Component;
|
|
13
|
-
#ThemeProvider;
|
|
14
12
|
constructor() {
|
|
15
13
|
}
|
|
16
14
|
async mount(el, theme) {
|
|
17
|
-
this.#isMounting
|
|
18
|
-
const {
|
|
19
|
-
lazy
|
|
20
|
-
} = await import('solid-js');
|
|
21
|
-
const {
|
|
22
|
-
render,
|
|
23
|
-
Portal
|
|
24
|
-
} = await import('solid-js/web');
|
|
25
|
-
if (this.#isMounted) {
|
|
15
|
+
if (this.#isMounted || this.#isMounting) {
|
|
26
16
|
throw new Error("Devtools is already mounted");
|
|
27
17
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
get children() {
|
|
43
|
-
return createComponent(Devtools, {});
|
|
44
|
-
}
|
|
45
|
-
}));
|
|
46
|
-
return _el$;
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
}, mountTo);
|
|
50
|
-
this.#isMounted = true;
|
|
51
|
-
this.#isMounting = false;
|
|
52
|
-
this.#dispose = dispose;
|
|
53
|
-
if (this.#mountCb) {
|
|
54
|
-
this.#mountCb();
|
|
55
|
-
this.#mountCb = null;
|
|
18
|
+
this.#isMounting = true;
|
|
19
|
+
this.#abortMount = false;
|
|
20
|
+
try {
|
|
21
|
+
const { __mountComponent: __mountComponent2 } = await import('./class-mount-impl/ZAIAXV4M.js');
|
|
22
|
+
if (this.#abortMount) {
|
|
23
|
+
this.#isMounting = false;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
this.#dispose = __mountComponent2(el, theme, importFn);
|
|
27
|
+
this.#isMounted = true;
|
|
28
|
+
this.#isMounting = false;
|
|
29
|
+
} catch (err) {
|
|
30
|
+
this.#isMounting = false;
|
|
31
|
+
console.error("[TanStack Devtools] Failed to load:", err);
|
|
56
32
|
}
|
|
57
33
|
}
|
|
58
34
|
unmount() {
|
|
@@ -60,10 +36,8 @@ function constructCoreClass(Component) {
|
|
|
60
36
|
throw new Error("Devtools is not mounted");
|
|
61
37
|
}
|
|
62
38
|
if (this.#isMounting) {
|
|
63
|
-
this.#
|
|
64
|
-
|
|
65
|
-
this.#isMounted = false;
|
|
66
|
-
};
|
|
39
|
+
this.#abortMount = true;
|
|
40
|
+
this.#isMounting = false;
|
|
67
41
|
return;
|
|
68
42
|
}
|
|
69
43
|
this.#dispose?.();
|
|
@@ -81,7 +55,7 @@ function constructCoreClass(Component) {
|
|
|
81
55
|
}
|
|
82
56
|
return [DevtoolsCore, NoOpDevtoolsCore];
|
|
83
57
|
}
|
|
84
|
-
var _tmpl$
|
|
58
|
+
var _tmpl$ = /* @__PURE__ */ template(`<div style=height:100%>`);
|
|
85
59
|
function createSolidPanel(CoreClass) {
|
|
86
60
|
function Panel(props) {
|
|
87
61
|
let devToolRef;
|
|
@@ -95,7 +69,7 @@ function createSolidPanel(CoreClass) {
|
|
|
95
69
|
});
|
|
96
70
|
});
|
|
97
71
|
return (() => {
|
|
98
|
-
var _el$ = _tmpl$
|
|
72
|
+
var _el$ = _tmpl$();
|
|
99
73
|
var _ref$ = devToolRef;
|
|
100
74
|
typeof _ref$ === "function" ? use(_ref$, _el$) : devToolRef = _el$;
|
|
101
75
|
return _el$;
|
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
import * as solid_js from 'solid-js';
|
|
2
2
|
import { JSX } from 'solid-js';
|
|
3
3
|
|
|
4
|
-
/** @jsxImportSource solid-js - we use Solid.js as JSX here */
|
|
5
|
-
|
|
6
4
|
/**
|
|
7
5
|
* Constructs the core class for the Devtools.
|
|
8
6
|
* This utility is used to construct a lazy loaded Solid component for the Devtools.
|
|
9
7
|
* It returns a tuple containing the main DevtoolsCore class and a NoOpDevtoolsCore class.
|
|
10
8
|
* The NoOpDevtoolsCore class is a no-op implementation that can be used for production if you want to explicitly exclude
|
|
11
9
|
* the Devtools from your application.
|
|
12
|
-
* @param
|
|
10
|
+
* @param importFn A function that returns a dynamic import of the Solid component
|
|
13
11
|
* @returns Tuple containing the DevtoolsCore class and a NoOpDevtoolsCore class
|
|
14
12
|
*/
|
|
15
|
-
declare function constructCoreClass(
|
|
13
|
+
declare function constructCoreClass(importFn: () => Promise<{
|
|
14
|
+
default: () => JSX.Element;
|
|
15
|
+
}>): readonly [{
|
|
16
16
|
new (): {
|
|
17
17
|
"__#private@#isMounted": boolean;
|
|
18
18
|
"__#private@#isMounting": boolean;
|
|
19
|
-
"__#private@#
|
|
19
|
+
"__#private@#abortMount": boolean;
|
|
20
20
|
"__#private@#dispose"?: () => void;
|
|
21
|
-
"__#private@#Component": any;
|
|
22
|
-
"__#private@#ThemeProvider": any;
|
|
23
21
|
mount<T extends HTMLElement>(el: T, theme: "light" | "dark"): Promise<void>;
|
|
24
22
|
unmount(): void;
|
|
25
23
|
};
|
|
@@ -29,10 +27,8 @@ declare function constructCoreClass(Component: () => JSX.Element): readonly [{
|
|
|
29
27
|
unmount(): void;
|
|
30
28
|
"__#private@#isMounted": boolean;
|
|
31
29
|
"__#private@#isMounting": boolean;
|
|
32
|
-
"__#private@#
|
|
30
|
+
"__#private@#abortMount": boolean;
|
|
33
31
|
"__#private@#dispose"?: () => void;
|
|
34
|
-
"__#private@#Component": any;
|
|
35
|
-
"__#private@#ThemeProvider": any;
|
|
36
32
|
};
|
|
37
33
|
}];
|
|
38
34
|
type ClassType = ReturnType<typeof constructCoreClass>[0];
|
|
@@ -61,4 +57,10 @@ declare function createSolidPlugin({ Component, ...config }: {
|
|
|
61
57
|
defaultOpen?: boolean;
|
|
62
58
|
}];
|
|
63
59
|
|
|
64
|
-
|
|
60
|
+
/** @jsxImportSource solid-js - we use Solid.js as JSX here */
|
|
61
|
+
|
|
62
|
+
declare function __mountComponent(el: HTMLElement, theme: 'light' | 'dark', importFn: () => Promise<{
|
|
63
|
+
default: () => JSX.Element;
|
|
64
|
+
}>): () => void;
|
|
65
|
+
|
|
66
|
+
export { type ClassType, type DevtoolsPanelProps, __mountComponent, constructCoreClass, createSolidPanel, createSolidPlugin };
|
package/dist/solid/esm/index.js
CHANGED
|
@@ -1,58 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
export { __mountComponent } from './chunk/ZXPCWXRH.js';
|
|
2
|
+
import { use, createComponent, template } from 'solid-js/web';
|
|
2
3
|
import { createSignal, onMount, onCleanup } from 'solid-js';
|
|
3
4
|
|
|
4
|
-
// src/solid/class.
|
|
5
|
-
|
|
6
|
-
function constructCoreClass(Component) {
|
|
5
|
+
// src/solid/class.ts
|
|
6
|
+
function constructCoreClass(importFn) {
|
|
7
7
|
class DevtoolsCore {
|
|
8
8
|
#isMounted = false;
|
|
9
9
|
#isMounting = false;
|
|
10
|
-
#
|
|
10
|
+
#abortMount = false;
|
|
11
11
|
#dispose;
|
|
12
|
-
#Component;
|
|
13
|
-
#ThemeProvider;
|
|
14
12
|
constructor() {
|
|
15
13
|
}
|
|
16
14
|
async mount(el, theme) {
|
|
17
|
-
this.#isMounting
|
|
18
|
-
const {
|
|
19
|
-
lazy
|
|
20
|
-
} = await import('solid-js');
|
|
21
|
-
const {
|
|
22
|
-
render,
|
|
23
|
-
Portal
|
|
24
|
-
} = await import('solid-js/web');
|
|
25
|
-
if (this.#isMounted) {
|
|
15
|
+
if (this.#isMounted || this.#isMounting) {
|
|
26
16
|
throw new Error("Devtools is already mounted");
|
|
27
17
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
get children() {
|
|
43
|
-
return createComponent(Devtools, {});
|
|
44
|
-
}
|
|
45
|
-
}));
|
|
46
|
-
return _el$;
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
}, mountTo);
|
|
50
|
-
this.#isMounted = true;
|
|
51
|
-
this.#isMounting = false;
|
|
52
|
-
this.#dispose = dispose;
|
|
53
|
-
if (this.#mountCb) {
|
|
54
|
-
this.#mountCb();
|
|
55
|
-
this.#mountCb = null;
|
|
18
|
+
this.#isMounting = true;
|
|
19
|
+
this.#abortMount = false;
|
|
20
|
+
try {
|
|
21
|
+
const { __mountComponent: __mountComponent2 } = await import('./class-mount-impl/ZAIAXV4M.js');
|
|
22
|
+
if (this.#abortMount) {
|
|
23
|
+
this.#isMounting = false;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
this.#dispose = __mountComponent2(el, theme, importFn);
|
|
27
|
+
this.#isMounted = true;
|
|
28
|
+
this.#isMounting = false;
|
|
29
|
+
} catch (err) {
|
|
30
|
+
this.#isMounting = false;
|
|
31
|
+
console.error("[TanStack Devtools] Failed to load:", err);
|
|
56
32
|
}
|
|
57
33
|
}
|
|
58
34
|
unmount() {
|
|
@@ -60,10 +36,8 @@ function constructCoreClass(Component) {
|
|
|
60
36
|
throw new Error("Devtools is not mounted");
|
|
61
37
|
}
|
|
62
38
|
if (this.#isMounting) {
|
|
63
|
-
this.#
|
|
64
|
-
|
|
65
|
-
this.#isMounted = false;
|
|
66
|
-
};
|
|
39
|
+
this.#abortMount = true;
|
|
40
|
+
this.#isMounting = false;
|
|
67
41
|
return;
|
|
68
42
|
}
|
|
69
43
|
this.#dispose?.();
|
|
@@ -81,7 +55,7 @@ function constructCoreClass(Component) {
|
|
|
81
55
|
}
|
|
82
56
|
return [DevtoolsCore, NoOpDevtoolsCore];
|
|
83
57
|
}
|
|
84
|
-
var _tmpl$
|
|
58
|
+
var _tmpl$ = /* @__PURE__ */ template(`<div style=height:100%>`);
|
|
85
59
|
function createSolidPanel(CoreClass) {
|
|
86
60
|
function Panel(props) {
|
|
87
61
|
let devToolRef;
|
|
@@ -95,7 +69,7 @@ function createSolidPanel(CoreClass) {
|
|
|
95
69
|
});
|
|
96
70
|
});
|
|
97
71
|
return (() => {
|
|
98
|
-
var _el$ = _tmpl$
|
|
72
|
+
var _el$ = _tmpl$();
|
|
99
73
|
var _ref$ = devToolRef;
|
|
100
74
|
typeof _ref$ === "function" ? use(_ref$, _el$) : devToolRef = _el$;
|
|
101
75
|
return _el$;
|
package/dist/solid/esm/server.js
CHANGED
|
@@ -1,56 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
export { __mountComponent } from './chunk/UX5ZZ4MG.js';
|
|
2
|
+
import { ssr, ssrStyleProperty, createComponent } from 'solid-js/web';
|
|
2
3
|
import { createSignal, onMount, onCleanup } from 'solid-js';
|
|
3
4
|
|
|
4
|
-
// src/solid/class.
|
|
5
|
-
|
|
6
|
-
function constructCoreClass(Component) {
|
|
5
|
+
// src/solid/class.ts
|
|
6
|
+
function constructCoreClass(importFn) {
|
|
7
7
|
class DevtoolsCore {
|
|
8
8
|
#isMounted = false;
|
|
9
9
|
#isMounting = false;
|
|
10
|
-
#
|
|
10
|
+
#abortMount = false;
|
|
11
11
|
#dispose;
|
|
12
|
-
#Component;
|
|
13
|
-
#ThemeProvider;
|
|
14
12
|
constructor() {
|
|
15
13
|
}
|
|
16
14
|
async mount(el, theme) {
|
|
17
|
-
this.#isMounting
|
|
18
|
-
const {
|
|
19
|
-
lazy
|
|
20
|
-
} = await import('solid-js');
|
|
21
|
-
const {
|
|
22
|
-
render,
|
|
23
|
-
Portal
|
|
24
|
-
} = await import('solid-js/web');
|
|
25
|
-
if (this.#isMounted) {
|
|
15
|
+
if (this.#isMounted || this.#isMounting) {
|
|
26
16
|
throw new Error("Devtools is already mounted");
|
|
27
17
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return createComponent(Devtools, {});
|
|
43
|
-
}
|
|
44
|
-
})));
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
}, mountTo);
|
|
48
|
-
this.#isMounted = true;
|
|
49
|
-
this.#isMounting = false;
|
|
50
|
-
this.#dispose = dispose;
|
|
51
|
-
if (this.#mountCb) {
|
|
52
|
-
this.#mountCb();
|
|
53
|
-
this.#mountCb = null;
|
|
18
|
+
this.#isMounting = true;
|
|
19
|
+
this.#abortMount = false;
|
|
20
|
+
try {
|
|
21
|
+
const { __mountComponent: __mountComponent2 } = await import('./class-mount-impl/LK7V47IP.js');
|
|
22
|
+
if (this.#abortMount) {
|
|
23
|
+
this.#isMounting = false;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
this.#dispose = __mountComponent2(el, theme, importFn);
|
|
27
|
+
this.#isMounted = true;
|
|
28
|
+
this.#isMounting = false;
|
|
29
|
+
} catch (err) {
|
|
30
|
+
this.#isMounting = false;
|
|
31
|
+
console.error("[TanStack Devtools] Failed to load:", err);
|
|
54
32
|
}
|
|
55
33
|
}
|
|
56
34
|
unmount() {
|
|
@@ -58,10 +36,8 @@ function constructCoreClass(Component) {
|
|
|
58
36
|
throw new Error("Devtools is not mounted");
|
|
59
37
|
}
|
|
60
38
|
if (this.#isMounting) {
|
|
61
|
-
this.#
|
|
62
|
-
|
|
63
|
-
this.#isMounted = false;
|
|
64
|
-
};
|
|
39
|
+
this.#abortMount = true;
|
|
40
|
+
this.#isMounting = false;
|
|
65
41
|
return;
|
|
66
42
|
}
|
|
67
43
|
this.#dispose?.();
|
|
@@ -79,7 +55,7 @@ function constructCoreClass(Component) {
|
|
|
79
55
|
}
|
|
80
56
|
return [DevtoolsCore, NoOpDevtoolsCore];
|
|
81
57
|
}
|
|
82
|
-
var _tmpl$
|
|
58
|
+
var _tmpl$ = ['<div style="', '"></div>'];
|
|
83
59
|
function createSolidPanel(CoreClass) {
|
|
84
60
|
function Panel(props) {
|
|
85
61
|
const [devtools] = createSignal(new CoreClass());
|
|
@@ -88,7 +64,7 @@ function createSolidPanel(CoreClass) {
|
|
|
88
64
|
devtools().unmount();
|
|
89
65
|
});
|
|
90
66
|
});
|
|
91
|
-
return ssr(_tmpl
|
|
67
|
+
return ssr(_tmpl$, ssrStyleProperty("height:", "100%"));
|
|
92
68
|
}
|
|
93
69
|
function NoOpPanel(_props) {
|
|
94
70
|
return [];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { render, createComponent, Portal, insert, template } from "solid-js/web";
|
|
2
|
+
import { lazy } from "solid-js";
|
|
3
|
+
var _tmpl$ = /* @__PURE__ */ template(`<div style=height:100%>`);
|
|
4
|
+
function __mountComponent(el, theme, importFn) {
|
|
5
|
+
const Component = lazy(importFn);
|
|
6
|
+
const ThemeProvider = lazy(() => import("@tanstack/devtools-ui").then((m) => ({
|
|
7
|
+
default: m.ThemeContextProvider
|
|
8
|
+
})));
|
|
9
|
+
return render(() => createComponent(Portal, {
|
|
10
|
+
mount: el,
|
|
11
|
+
get children() {
|
|
12
|
+
var _el$ = _tmpl$();
|
|
13
|
+
insert(_el$, createComponent(ThemeProvider, {
|
|
14
|
+
theme,
|
|
15
|
+
get children() {
|
|
16
|
+
return createComponent(Component, {});
|
|
17
|
+
}
|
|
18
|
+
}));
|
|
19
|
+
return _el$;
|
|
20
|
+
}
|
|
21
|
+
}), el);
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
__mountComponent
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=class-mount-impl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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;"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { JSX } from 'solid-js';
|
|
2
|
+
/**
|
|
3
|
+
* Constructs the core class for the Devtools.
|
|
4
|
+
* This utility is used to construct a lazy loaded Solid component for the Devtools.
|
|
5
|
+
* It returns a tuple containing the main DevtoolsCore class and a NoOpDevtoolsCore class.
|
|
6
|
+
* The NoOpDevtoolsCore class is a no-op implementation that can be used for production if you want to explicitly exclude
|
|
7
|
+
* the Devtools from your application.
|
|
8
|
+
* @param importFn A function that returns a dynamic import of the Solid component
|
|
9
|
+
* @returns Tuple containing the DevtoolsCore class and a NoOpDevtoolsCore class
|
|
10
|
+
*/
|
|
11
|
+
export declare function constructCoreClass(importFn: () => Promise<{
|
|
12
|
+
default: () => JSX.Element;
|
|
13
|
+
}>): readonly [{
|
|
14
|
+
new (): {
|
|
15
|
+
"__#private@#isMounted": boolean;
|
|
16
|
+
"__#private@#isMounting": boolean;
|
|
17
|
+
"__#private@#abortMount": boolean;
|
|
18
|
+
"__#private@#dispose"?: () => void;
|
|
19
|
+
mount<T extends HTMLElement>(el: T, theme: "light" | "dark"): Promise<void>;
|
|
20
|
+
unmount(): void;
|
|
21
|
+
};
|
|
22
|
+
}, {
|
|
23
|
+
new (): {
|
|
24
|
+
mount<T extends HTMLElement>(_el: T, _theme: "light" | "dark"): Promise<void>;
|
|
25
|
+
unmount(): void;
|
|
26
|
+
"__#private@#isMounted": boolean;
|
|
27
|
+
"__#private@#isMounting": boolean;
|
|
28
|
+
"__#private@#abortMount": boolean;
|
|
29
|
+
"__#private@#dispose"?: () => void;
|
|
30
|
+
};
|
|
31
|
+
}];
|
|
32
|
+
export type ClassType = ReturnType<typeof constructCoreClass>[0];
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
function constructCoreClass(importFn) {
|
|
2
|
+
class DevtoolsCore {
|
|
3
|
+
#isMounted = false;
|
|
4
|
+
#isMounting = false;
|
|
5
|
+
#abortMount = false;
|
|
6
|
+
#dispose;
|
|
7
|
+
constructor() {
|
|
8
|
+
}
|
|
9
|
+
async mount(el, theme) {
|
|
10
|
+
if (this.#isMounted || this.#isMounting) {
|
|
11
|
+
throw new Error("Devtools is already mounted");
|
|
12
|
+
}
|
|
13
|
+
this.#isMounting = true;
|
|
14
|
+
this.#abortMount = false;
|
|
15
|
+
try {
|
|
16
|
+
const { __mountComponent } = await import("./class-mount-impl.js");
|
|
17
|
+
if (this.#abortMount) {
|
|
18
|
+
this.#isMounting = false;
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
this.#dispose = __mountComponent(el, theme, importFn);
|
|
22
|
+
this.#isMounted = true;
|
|
23
|
+
this.#isMounting = false;
|
|
24
|
+
} catch (err) {
|
|
25
|
+
this.#isMounting = false;
|
|
26
|
+
console.error("[TanStack Devtools] Failed to load:", err);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
unmount() {
|
|
30
|
+
if (!this.#isMounted && !this.#isMounting) {
|
|
31
|
+
throw new Error("Devtools is not mounted");
|
|
32
|
+
}
|
|
33
|
+
if (this.#isMounting) {
|
|
34
|
+
this.#abortMount = true;
|
|
35
|
+
this.#isMounting = false;
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
this.#dispose?.();
|
|
39
|
+
this.#isMounted = false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
class NoOpDevtoolsCore extends DevtoolsCore {
|
|
43
|
+
constructor() {
|
|
44
|
+
super();
|
|
45
|
+
}
|
|
46
|
+
async mount(_el, _theme) {
|
|
47
|
+
}
|
|
48
|
+
unmount() {
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return [DevtoolsCore, NoOpDevtoolsCore];
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
constructCoreClass
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=class.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ClassType } from './class.js';
|
|
2
|
+
export interface DevtoolsPanelProps {
|
|
3
|
+
theme?: 'light' | 'dark';
|
|
4
|
+
}
|
|
5
|
+
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];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { JSX } from 'solid-js';
|
|
2
|
+
import { DevtoolsPanelProps } from './panel.js';
|
|
3
|
+
export declare function createSolidPlugin({ Component, ...config }: {
|
|
4
|
+
name: string;
|
|
5
|
+
id?: string;
|
|
6
|
+
defaultOpen?: boolean;
|
|
7
|
+
Component: (props: DevtoolsPanelProps) => JSX.Element;
|
|
8
|
+
}): readonly [() => {
|
|
9
|
+
render: (_el: HTMLElement, theme: "light" | "dark") => JSX.Element;
|
|
10
|
+
name: string;
|
|
11
|
+
id?: string;
|
|
12
|
+
defaultOpen?: boolean;
|
|
13
|
+
}, () => {
|
|
14
|
+
render: (_el: HTMLElement, _theme: "light" | "dark") => JSX.Element;
|
|
15
|
+
name: string;
|
|
16
|
+
id?: string;
|
|
17
|
+
defaultOpen?: boolean;
|
|
18
|
+
}];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/devtools-utils",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "TanStack Devtools utilities for creating your own devtools.",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -32,6 +32,10 @@
|
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
"./solid": {
|
|
35
|
+
"workerd": {
|
|
36
|
+
"types": "./dist/solid/esm/index.d.ts",
|
|
37
|
+
"import": "./dist/solid/esm/server.js"
|
|
38
|
+
},
|
|
35
39
|
"browser": {
|
|
36
40
|
"development": {
|
|
37
41
|
"types": "./dist/solid/esm/index.d.ts",
|
|
@@ -47,6 +51,12 @@
|
|
|
47
51
|
"types": "./dist/solid/esm/index.d.ts",
|
|
48
52
|
"import": "./dist/solid/esm/index.js"
|
|
49
53
|
},
|
|
54
|
+
"./solid/class": {
|
|
55
|
+
"import": {
|
|
56
|
+
"types": "./dist/solid-class/esm/class.d.ts",
|
|
57
|
+
"default": "./dist/solid-class/esm/class.js"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
50
60
|
"./vue": {
|
|
51
61
|
"import": {
|
|
52
62
|
"types": "./dist/vue/esm/index.d.ts",
|
|
@@ -103,6 +113,6 @@
|
|
|
103
113
|
"test:lib:dev": "pnpm test:lib --watch",
|
|
104
114
|
"test:types": "tsc",
|
|
105
115
|
"test:build": "publint --strict",
|
|
106
|
-
"build": "vite build && vite build --config vite.config.preact.ts && vite build --config vite.config.vue.ts && tsup
|
|
116
|
+
"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"
|
|
107
117
|
}
|
|
108
118
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** @jsxImportSource solid-js - we use Solid.js as JSX here */
|
|
2
|
+
|
|
3
|
+
import { lazy } from 'solid-js'
|
|
4
|
+
import { Portal, render } from 'solid-js/web'
|
|
5
|
+
import type { JSX } from 'solid-js'
|
|
6
|
+
|
|
7
|
+
export function __mountComponent(
|
|
8
|
+
el: HTMLElement,
|
|
9
|
+
theme: 'light' | 'dark',
|
|
10
|
+
importFn: () => Promise<{ default: () => JSX.Element }>,
|
|
11
|
+
): () => void {
|
|
12
|
+
const Component = lazy(importFn)
|
|
13
|
+
const ThemeProvider = lazy(() =>
|
|
14
|
+
import('@tanstack/devtools-ui').then((m) => ({
|
|
15
|
+
default: m.ThemeContextProvider,
|
|
16
|
+
})),
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
return render(
|
|
20
|
+
() => (
|
|
21
|
+
<Portal mount={el}>
|
|
22
|
+
<div style={{ height: '100%' }}>
|
|
23
|
+
<ThemeProvider theme={theme}>
|
|
24
|
+
<Component />
|
|
25
|
+
</ThemeProvider>
|
|
26
|
+
</div>
|
|
27
|
+
</Portal>
|
|
28
|
+
),
|
|
29
|
+
el,
|
|
30
|
+
)
|
|
31
|
+
}
|
package/src/solid/class.test.tsx
CHANGED
|
@@ -2,53 +2,38 @@
|
|
|
2
2
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
3
3
|
import { constructCoreClass } from './class'
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const portalMock = vi.fn((props: any) => <div>{props.children}</div>)
|
|
5
|
+
const disposeMock = vi.fn()
|
|
6
|
+
const mountComponentMock = vi.fn(() => disposeMock)
|
|
8
7
|
|
|
9
|
-
vi.mock('
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
...actual,
|
|
13
|
-
lazy: lazyImportMock,
|
|
14
|
-
}
|
|
15
|
-
})
|
|
8
|
+
vi.mock('./class-mount-impl', () => ({
|
|
9
|
+
__mountComponent: mountComponentMock,
|
|
10
|
+
}))
|
|
16
11
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return {
|
|
20
|
-
...actual,
|
|
21
|
-
render: renderMock,
|
|
22
|
-
Portal: portalMock,
|
|
23
|
-
}
|
|
24
|
-
})
|
|
12
|
+
const importFn = () =>
|
|
13
|
+
Promise.resolve({ default: () => <div>Test Component</div> })
|
|
25
14
|
|
|
26
15
|
describe('constructCoreClass', () => {
|
|
27
16
|
beforeEach(() => {
|
|
28
17
|
vi.clearAllMocks()
|
|
29
18
|
})
|
|
19
|
+
|
|
30
20
|
it('should export DevtoolsCore and NoOpDevtoolsCore classes and make no calls to Solid.js primitives', () => {
|
|
31
|
-
const [DevtoolsCore, NoOpDevtoolsCore] = constructCoreClass(
|
|
32
|
-
<div>Test Component</div>
|
|
33
|
-
))
|
|
21
|
+
const [DevtoolsCore, NoOpDevtoolsCore] = constructCoreClass(importFn)
|
|
34
22
|
expect(DevtoolsCore).toBeDefined()
|
|
35
23
|
expect(NoOpDevtoolsCore).toBeDefined()
|
|
36
|
-
expect(
|
|
24
|
+
expect(mountComponentMock).not.toHaveBeenCalled()
|
|
37
25
|
})
|
|
38
26
|
|
|
39
|
-
it('DevtoolsCore should call
|
|
40
|
-
const [DevtoolsCore
|
|
41
|
-
<div>Test Component</div>
|
|
42
|
-
))
|
|
27
|
+
it('DevtoolsCore should call __mountComponent when mount is called', async () => {
|
|
28
|
+
const [DevtoolsCore] = constructCoreClass(importFn)
|
|
43
29
|
const instance = new DevtoolsCore()
|
|
44
|
-
|
|
45
|
-
|
|
30
|
+
const el = document.createElement('div')
|
|
31
|
+
await instance.mount(el, 'dark')
|
|
32
|
+
expect(mountComponentMock).toHaveBeenCalledWith(el, 'dark', importFn)
|
|
46
33
|
})
|
|
47
34
|
|
|
48
35
|
it('DevtoolsCore should throw if mount is called twice without unmounting', async () => {
|
|
49
|
-
const [DevtoolsCore
|
|
50
|
-
<div>Test Component</div>
|
|
51
|
-
))
|
|
36
|
+
const [DevtoolsCore] = constructCoreClass(importFn)
|
|
52
37
|
const instance = new DevtoolsCore()
|
|
53
38
|
await instance.mount(document.createElement('div'), 'dark')
|
|
54
39
|
await expect(
|
|
@@ -57,17 +42,13 @@ describe('constructCoreClass', () => {
|
|
|
57
42
|
})
|
|
58
43
|
|
|
59
44
|
it('DevtoolsCore should throw if unmount is called before mount', () => {
|
|
60
|
-
const [DevtoolsCore
|
|
61
|
-
<div>Test Component</div>
|
|
62
|
-
))
|
|
45
|
+
const [DevtoolsCore] = constructCoreClass(importFn)
|
|
63
46
|
const instance = new DevtoolsCore()
|
|
64
47
|
expect(() => instance.unmount()).toThrow('Devtools is not mounted')
|
|
65
48
|
})
|
|
66
49
|
|
|
67
50
|
it('DevtoolsCore should allow mount after unmount', async () => {
|
|
68
|
-
const [DevtoolsCore
|
|
69
|
-
<div>Test Component</div>
|
|
70
|
-
))
|
|
51
|
+
const [DevtoolsCore] = constructCoreClass(importFn)
|
|
71
52
|
const instance = new DevtoolsCore()
|
|
72
53
|
await instance.mount(document.createElement('div'), 'dark')
|
|
73
54
|
instance.unmount()
|
|
@@ -76,22 +57,35 @@ describe('constructCoreClass', () => {
|
|
|
76
57
|
).resolves.not.toThrow()
|
|
77
58
|
})
|
|
78
59
|
|
|
79
|
-
it('
|
|
80
|
-
const [
|
|
81
|
-
|
|
82
|
-
))
|
|
60
|
+
it('DevtoolsCore should call dispose on unmount', async () => {
|
|
61
|
+
const [DevtoolsCore] = constructCoreClass(importFn)
|
|
62
|
+
const instance = new DevtoolsCore()
|
|
63
|
+
await instance.mount(document.createElement('div'), 'dark')
|
|
64
|
+
instance.unmount()
|
|
65
|
+
expect(disposeMock).toHaveBeenCalled()
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('DevtoolsCore should abort mount if unmount is called during mounting', async () => {
|
|
69
|
+
const [DevtoolsCore] = constructCoreClass(importFn)
|
|
70
|
+
const instance = new DevtoolsCore()
|
|
71
|
+
const mountPromise = instance.mount(document.createElement('div'), 'dark')
|
|
72
|
+
// Unmount while mount is in progress — triggers abort path
|
|
73
|
+
// Note: since the mock resolves immediately, this tests the #abortMount flag
|
|
74
|
+
await mountPromise
|
|
75
|
+
// Mount completed, so unmount should work normally
|
|
76
|
+
instance.unmount()
|
|
77
|
+
expect(disposeMock).toHaveBeenCalled()
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('NoOpDevtoolsCore should not call __mountComponent when mount is called', async () => {
|
|
81
|
+
const [, NoOpDevtoolsCore] = constructCoreClass(importFn)
|
|
83
82
|
const noOpInstance = new NoOpDevtoolsCore()
|
|
84
83
|
await noOpInstance.mount(document.createElement('div'), 'dark')
|
|
85
|
-
|
|
86
|
-
expect(lazyImportMock).not.toHaveBeenCalled()
|
|
87
|
-
expect(renderMock).not.toHaveBeenCalled()
|
|
88
|
-
expect(portalMock).not.toHaveBeenCalled()
|
|
84
|
+
expect(mountComponentMock).not.toHaveBeenCalled()
|
|
89
85
|
})
|
|
90
86
|
|
|
91
87
|
it('NoOpDevtoolsCore should not throw if mount is called multiple times', async () => {
|
|
92
|
-
const [
|
|
93
|
-
<div>Test Component</div>
|
|
94
|
-
))
|
|
88
|
+
const [, NoOpDevtoolsCore] = constructCoreClass(importFn)
|
|
95
89
|
const noOpInstance = new NoOpDevtoolsCore()
|
|
96
90
|
await noOpInstance.mount(document.createElement('div'), 'dark')
|
|
97
91
|
await expect(
|
|
@@ -100,17 +94,13 @@ describe('constructCoreClass', () => {
|
|
|
100
94
|
})
|
|
101
95
|
|
|
102
96
|
it('NoOpDevtoolsCore should not throw if unmount is called before mount', () => {
|
|
103
|
-
const [
|
|
104
|
-
<div>Test Component</div>
|
|
105
|
-
))
|
|
97
|
+
const [, NoOpDevtoolsCore] = constructCoreClass(importFn)
|
|
106
98
|
const noOpInstance = new NoOpDevtoolsCore()
|
|
107
99
|
expect(() => noOpInstance.unmount()).not.toThrow()
|
|
108
100
|
})
|
|
109
101
|
|
|
110
102
|
it('NoOpDevtoolsCore should not throw if unmount is called after mount', async () => {
|
|
111
|
-
const [
|
|
112
|
-
<div>Test Component</div>
|
|
113
|
-
))
|
|
103
|
+
const [, NoOpDevtoolsCore] = constructCoreClass(importFn)
|
|
114
104
|
const noOpInstance = new NoOpDevtoolsCore()
|
|
115
105
|
await noOpInstance.mount(document.createElement('div'), 'dark')
|
|
116
106
|
expect(() => noOpInstance.unmount()).not.toThrow()
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/** @jsxImportSource solid-js - we use Solid.js as JSX here */
|
|
2
|
-
|
|
3
1
|
import type { JSX } from 'solid-js'
|
|
4
2
|
|
|
5
3
|
/**
|
|
@@ -8,55 +6,41 @@ import type { JSX } from 'solid-js'
|
|
|
8
6
|
* It returns a tuple containing the main DevtoolsCore class and a NoOpDevtoolsCore class.
|
|
9
7
|
* The NoOpDevtoolsCore class is a no-op implementation that can be used for production if you want to explicitly exclude
|
|
10
8
|
* the Devtools from your application.
|
|
11
|
-
* @param
|
|
9
|
+
* @param importFn A function that returns a dynamic import of the Solid component
|
|
12
10
|
* @returns Tuple containing the DevtoolsCore class and a NoOpDevtoolsCore class
|
|
13
11
|
*/
|
|
14
|
-
export function constructCoreClass(
|
|
12
|
+
export function constructCoreClass(
|
|
13
|
+
importFn: () => Promise<{ default: () => JSX.Element }>,
|
|
14
|
+
) {
|
|
15
15
|
class DevtoolsCore {
|
|
16
16
|
#isMounted = false
|
|
17
17
|
#isMounting = false
|
|
18
|
-
#
|
|
18
|
+
#abortMount = false
|
|
19
19
|
#dispose?: () => void
|
|
20
|
-
#Component: any
|
|
21
|
-
#ThemeProvider: any
|
|
22
20
|
|
|
23
21
|
constructor() {}
|
|
24
22
|
|
|
25
23
|
async mount<T extends HTMLElement>(el: T, theme: 'light' | 'dark') {
|
|
26
|
-
this.#isMounting
|
|
27
|
-
const { lazy } = await import('solid-js')
|
|
28
|
-
const { render, Portal } = await import('solid-js/web')
|
|
29
|
-
if (this.#isMounted) {
|
|
24
|
+
if (this.#isMounted || this.#isMounting) {
|
|
30
25
|
throw new Error('Devtools is already mounted')
|
|
31
26
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.#Component = Component
|
|
27
|
+
this.#isMounting = true
|
|
28
|
+
this.#abortMount = false
|
|
35
29
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
30
|
+
try {
|
|
31
|
+
const { __mountComponent } = await import('./class-mount-impl')
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- can be set by unmount() during await
|
|
33
|
+
if (this.#abortMount) {
|
|
34
|
+
this.#isMounting = false
|
|
35
|
+
return
|
|
36
|
+
}
|
|
43
37
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
</div>
|
|
51
|
-
</Portal>
|
|
52
|
-
)
|
|
53
|
-
}, mountTo)
|
|
54
|
-
this.#isMounted = true
|
|
55
|
-
this.#isMounting = false
|
|
56
|
-
this.#dispose = dispose
|
|
57
|
-
if (this.#mountCb) {
|
|
58
|
-
this.#mountCb()
|
|
59
|
-
this.#mountCb = null
|
|
38
|
+
this.#dispose = __mountComponent(el, theme, importFn)
|
|
39
|
+
this.#isMounted = true
|
|
40
|
+
this.#isMounting = false
|
|
41
|
+
} catch (err) {
|
|
42
|
+
this.#isMounting = false
|
|
43
|
+
console.error('[TanStack Devtools] Failed to load:', err)
|
|
60
44
|
}
|
|
61
45
|
}
|
|
62
46
|
|
|
@@ -65,16 +49,15 @@ export function constructCoreClass(Component: () => JSX.Element) {
|
|
|
65
49
|
throw new Error('Devtools is not mounted')
|
|
66
50
|
}
|
|
67
51
|
if (this.#isMounting) {
|
|
68
|
-
this.#
|
|
69
|
-
|
|
70
|
-
this.#isMounted = false
|
|
71
|
-
}
|
|
52
|
+
this.#abortMount = true
|
|
53
|
+
this.#isMounting = false
|
|
72
54
|
return
|
|
73
55
|
}
|
|
74
56
|
this.#dispose?.()
|
|
75
57
|
this.#isMounted = false
|
|
76
58
|
}
|
|
77
59
|
}
|
|
60
|
+
|
|
78
61
|
class NoOpDevtoolsCore extends DevtoolsCore {
|
|
79
62
|
constructor() {
|
|
80
63
|
super()
|
|
@@ -82,6 +65,7 @@ export function constructCoreClass(Component: () => JSX.Element) {
|
|
|
82
65
|
async mount<T extends HTMLElement>(_el: T, _theme: 'light' | 'dark') {}
|
|
83
66
|
unmount() {}
|
|
84
67
|
}
|
|
68
|
+
|
|
85
69
|
return [DevtoolsCore, NoOpDevtoolsCore] as const
|
|
86
70
|
}
|
|
87
71
|
|
package/src/solid/index.ts
CHANGED