Skip to content

Commit eef06c4

Browse files
committed
Simplify createDevtools interface
1 parent cd277a6 commit eef06c4

File tree

9 files changed

+154
-146
lines changed

9 files changed

+154
-146
lines changed

.changeset/dull-papayas-flow.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@solid-devtools/frontend": minor
3+
"@solid-devtools/overlay": patch
4+
"@solid-devtools/extension": patch
5+
---
6+
7+
Simplify createDevtools interface

extension/src/panel.tsx

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,24 @@ function App() {
2727
}
2828
const [versions, setVersions] = s.createSignal<Versions>(empty_versions)
2929

30-
const devtools = frontend.createDevtools()
30+
const devtools = frontend.createDevtools({
31+
headerSubtitle() {
32+
let {extension, client, client_expected} = versions()
33+
return `#${extension}_${client}/${client_expected}`
34+
},
35+
errorOverlayFooter() {
36+
return <>
37+
<ul>
38+
<li>Solid: {versions().solid}</li>
39+
<li>Extension: {versions().extension}</li>
40+
<li>Client: {versions().client}</li>
41+
<li>Expected client: {versions().client_expected}</li>
42+
</ul>
43+
</>
44+
},
45+
useShortcuts: true,
46+
catchWindowErrors: true,
47+
})
3148

3249
const port = chrome.runtime.connect({name: ConnectionName.Panel})
3350
port_on_message(port, e => {
@@ -38,15 +55,15 @@ function App() {
3855
break
3956
default:
4057
/* Client -> Devtools */
41-
devtools.bridge.input.emit(
58+
devtools.input.emit(
4259
// @ts-expect-error
4360
e
4461
)
4562
}
4663
})
4764

4865
/* Devtools -> Client */
49-
devtools.bridge.output.listen(e => port_post_message_obj(port, e))
66+
devtools.output.listen(e => port_post_message_obj(port, e))
5067

5168
return (
5269
<div
@@ -57,21 +74,7 @@ function App() {
5774
inset: '0',
5875
}}
5976
>
60-
<devtools.Devtools
61-
headerSubtitle={`#${versions().extension}_${versions().client}/${
62-
versions().client_expected
63-
}`}
64-
errorOverlayFooter={
65-
<ul>
66-
<li>Solid: {versions().solid}</li>
67-
<li>Extension: {versions().extension}</li>
68-
<li>Client: {versions().client}</li>
69-
<li>Expected client: {versions().client_expected}</li>
70-
</ul>
71-
}
72-
useShortcuts
73-
catchWindowErrors
74-
/>
77+
<devtools.Devtools />
7578
<frontend.MountIcons />
7679
</div>
7780
)

packages/frontend/src/controller.tsx

Lines changed: 65 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,58 @@ import createInspector from './inspector.tsx'
1010
import {type Structure} from './structure.tsx'
1111
import * as ui from './ui/index.ts'
1212

13-
export type Input_Message = {
13+
14+
export type InputMessage = {
1415
[K in keyof Debugger.OutputChannels]: {
1516
name: K,
1617
details: Debugger.OutputChannels[K],
1718
}
1819
}[keyof Debugger.OutputChannels]
19-
export type Input_Listener = (e: Input_Message) => void
20+
export type InputListener = (e: InputMessage) => void
21+
22+
export type InputEventBus = {
23+
emit: (e: InputMessage) => void,
24+
listen: (fn: InputListener) => void,
25+
}
2026

21-
export type Output_Message = {
27+
export type OutputMessage = {
2228
[K in keyof Debugger.InputChannels]: {
2329
name: K,
2430
details: Debugger.InputChannels[K],
2531
}
2632
}[keyof Debugger.InputChannels]
27-
export type Output_Listener = (e: Output_Message) => void
33+
export type OutputListener = (e: OutputMessage) => void
34+
35+
export type OutputEventBus = {
36+
emit: (e: OutputMessage) => void,
37+
listen: (fn: OutputListener) => void,
38+
}
39+
40+
41+
/**
42+
* devtools options provided to {@link Devtools} component
43+
* with their default values
44+
*/
45+
export type DevtoolsOptionsWithDefaults = {
46+
errorOverlayFooter: () => s.JSX.Element
47+
headerSubtitle: () => s.JSX.Element
48+
useShortcuts: boolean
49+
catchWindowErrors: boolean
50+
}
2851

29-
function createDebuggerBridge() {
30-
31-
let output_listeners: Output_Listener[] = []
32-
const output = {
33-
listen(listener: Output_Listener) {
52+
export type DevtoolsOptions = Partial<DevtoolsOptionsWithDefaults>
53+
54+
export function createDevtools(props: DevtoolsOptions) {
55+
56+
let output_listeners: OutputListener[] = []
57+
const output: OutputEventBus = {
58+
listen(listener) {
3459
output_listeners.push(listener)
3560
s.onCleanup(() => {
3661
mutate_remove(output_listeners, listener)
3762
})
3863
},
39-
emit(e: Output_Message) {
64+
emit(e) {
4065
s.batch(() => {
4166
for (let fn of output_listeners) {
4267
fn(e)
@@ -45,15 +70,15 @@ function createDebuggerBridge() {
4570
},
4671
}
4772

48-
let input_listeners: Input_Listener[] = []
49-
const input = {
50-
listen(listener: Input_Listener) {
73+
let input_listeners: InputListener[] = []
74+
const input: InputEventBus = {
75+
listen(listener) {
5176
input_listeners.push(listener)
5277
s.onCleanup(() => {
5378
mutate_remove(input_listeners, listener)
5479
})
5580
},
56-
emit(e: Input_Message) {
81+
emit(e) {
5782
s.batch(() => {
5883
for (let fn of input_listeners) {
5984
fn(e)
@@ -62,60 +87,29 @@ function createDebuggerBridge() {
6287
},
6388
}
6489

65-
return {input, output}
66-
}
67-
68-
export type DebuggerBridge = ReturnType<typeof createDebuggerBridge>
69-
70-
export type DevtoolsProps = {
71-
errorOverlayFooter?: s.JSX.Element
72-
headerSubtitle?: s.JSX.Element
73-
useShortcuts?: boolean
74-
catchWindowErrors?: boolean
75-
}
76-
77-
/**
78-
* devtools options provided to {@link Devtools} component
79-
* with their default values
80-
*/
81-
export type DevtoolsOptions = {
82-
useShortcuts: boolean
83-
}
84-
85-
const DevtoolsOptionsCtx = s.createContext<DevtoolsOptions>(
86-
'DevtoolsOptionsCtx' as any as DevtoolsOptions,
87-
)
88-
89-
export const useDevtoolsOptions = () => s.useContext(DevtoolsOptionsCtx)
90-
91-
export function devtoolsPropsToOptions(props: DevtoolsProps): DevtoolsOptions {
92-
return {
93-
useShortcuts: props.useShortcuts ?? false,
90+
let options: DevtoolsOptionsWithDefaults = {
91+
errorOverlayFooter: props.errorOverlayFooter ?? (() => null),
92+
headerSubtitle: props.headerSubtitle ?? (() => null),
93+
useShortcuts: props.useShortcuts ?? false,
94+
catchWindowErrors: props.catchWindowErrors ?? false,
9495
}
95-
}
9696

97-
export function createDevtools() {
98-
const bridge = createDebuggerBridge()
97+
const controller = createController(output, input, options)
9998

10099
return {
101-
bridge,
102-
Devtools(props: DevtoolsProps) {
103-
const options = devtoolsPropsToOptions(props)
104-
105-
const controller = createController(bridge, options)
106-
100+
output,
101+
input,
102+
Devtools() {
107103
return (
108104
<div class={ui.devtools_root_class + ' h-inherit'}>
109105
<ui.Styles />
110106
<ui.ErrorOverlay
111-
footer={props.errorOverlayFooter}
112-
catchWindowErrors={props.catchWindowErrors}
107+
footer={options.errorOverlayFooter()}
108+
catchWindowErrors={options.catchWindowErrors}
113109
>
114-
<DevtoolsOptionsCtx.Provider value={options}>
115-
<ControllerCtx.Provider value={controller}>
116-
<App headerSubtitle={props.headerSubtitle} />
117-
</ControllerCtx.Provider>
118-
</DevtoolsOptionsCtx.Provider>
110+
<ControllerCtx.Provider value={controller}>
111+
<App headerSubtitle={options.headerSubtitle()} />
112+
</ControllerCtx.Provider>
119113
</ui.ErrorOverlay>
120114
</div>
121115
)
@@ -163,7 +157,11 @@ function createViewCache() {
163157
return {set: setCacheGetter, get: getCache}
164158
}
165159

166-
function createController(bridge: DebuggerBridge, options: DevtoolsOptions) {
160+
function createController(
161+
output: OutputEventBus,
162+
input: InputEventBus,
163+
options: DevtoolsOptions,
164+
) {
167165
//
168166
// LOCATOR
169167
//
@@ -173,7 +171,7 @@ function createController(bridge: DebuggerBridge, options: DevtoolsOptions) {
173171

174172
// send devtools locator state
175173
s.createEffect(defer(devtoolsLocatorEnabled, enabled => {
176-
bridge.output.emit({
174+
output.emit({
177175
name: 'ToggleModule',
178176
details: {module: DebuggerModule.Locator, enabled}
179177
})
@@ -197,7 +195,7 @@ function createController(bridge: DebuggerBridge, options: DevtoolsOptions) {
197195

198196
// highlight hovered element
199197
s.createEffect(defer(extHoveredNode, node => {
200-
bridge.output.emit({
198+
output.emit({
201199
name: 'HighlightElementChange',
202200
details: node,
203201
})
@@ -231,7 +229,7 @@ function createController(bridge: DebuggerBridge, options: DevtoolsOptions) {
231229
}
232230

233231
s.createEffect(defer(openedView, view => {
234-
bridge.output.emit({name: 'ViewChange', details: view})
232+
output.emit({name: 'ViewChange', details: view})
235233
}))
236234

237235
//
@@ -242,12 +240,12 @@ function createController(bridge: DebuggerBridge, options: DevtoolsOptions) {
242240
//
243241
// INSPECTOR
244242
//
245-
const inspector = createInspector({bridge})
243+
const inspector = createInspector(output, input)
246244

247245
//
248246
// Client events
249247
//
250-
bridge.input.listen(e => {
248+
input.listen(e => {
251249
switch (e.name) {
252250
case 'NodeUpdates':
253251
for (let id of e.details) {
@@ -301,7 +299,8 @@ function createController(bridge: DebuggerBridge, options: DevtoolsOptions) {
301299
},
302300
inspector,
303301
options,
304-
bridge,
302+
output,
303+
input,
305304
viewCache,
306305
listenToNodeUpdate(id: NodeID, fn: VoidFunction) {
307306
return nodeUpdates.listen(updatedId => updatedId === id && fn())

packages/frontend/src/dgraph.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import {useController} from './controller.tsx'
77
import * as ui from './ui/index.ts'
88

99
export function createDependencyGraph() {
10-
const {bridge, inspector} = useController()
10+
const ctx = useController()
1111

1212
const [graph, setGraph] = s.createSignal<debug.DGraphUpdate>(null)
1313

14-
bridge.input.listen(e => {
14+
ctx.input.listen(e => {
1515
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
1616
switch (e.name) {
1717
case 'DgraphUpdate':
@@ -20,12 +20,12 @@ export function createDependencyGraph() {
2020
}
2121
})
2222

23-
bridge.output.emit({
23+
ctx.output.emit({
2424
name: 'ToggleModule',
2525
details: {module: debug.DebuggerModule.Dgraph, enabled: true},
2626
})
2727
s.onCleanup(() => {
28-
bridge.output.emit({
28+
ctx.output.emit({
2929
name: 'ToggleModule',
3030
details: {module: debug.DebuggerModule.Dgraph, enabled: false},
3131
})
@@ -37,9 +37,9 @@ export function createDependencyGraph() {
3737
if (!node) return console.warn('inspectNode: node not found', id)
3838

3939
if (node.type === debug.NodeType.Signal) {
40-
inspector.setInspectedNode(node.graph ?? null, id)
40+
ctx.inspector.setInspectedNode(node.graph ?? null, id)
4141
} else {
42-
inspector.setInspectedOwner(id)
42+
ctx.inspector.setInspectedOwner(id)
4343
}
4444
}
4545

packages/frontend/src/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export {createDevtools} from './controller.tsx'
2-
export type {DebuggerBridge, DevtoolsProps} from './controller.tsx'
2+
export type {OutputEventBus, InputEventBus, DevtoolsOptions as DevtoolsProps} from './controller.tsx'
33
export {Icon, MountIcons} from './ui/index.ts'
44
export type {IconComponent} from './ui/index.ts'

0 commit comments

Comments
 (0)