Skip to content

Commit

Permalink
Refactor useDebugger
Browse files Browse the repository at this point in the history
  • Loading branch information
thetarnav committed Dec 31, 2024
1 parent 458b217 commit 6b1b16d
Show file tree
Hide file tree
Showing 19 changed files with 370 additions and 341 deletions.
12 changes: 12 additions & 0 deletions .changeset/swift-shoes-press.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@solid-devtools/debugger": minor
"@solid-devtools/frontend": patch
"@solid-devtools/overlay": patch
"@solid-devtools/shared": patch
"solid-devtools": patch
"@solid-devtools/extension": patch
---

Refactor `useDebugger`.
`useLocator` is removed, instead use `useDebugger().setLocatorOptions()`.
`debugger.meta.versions` moved to `debugger.versions`
10 changes: 5 additions & 5 deletions extension/src/real_world.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,19 @@ async function attach_debugger() {
const instance = debug.useDebugger()

/* Check versions */
warn_on_version_mismatch(instance.meta.versions.get_client(),
warn_on_version_mismatch(instance.versions.get_client(),
import.meta.env.EXPECTED_CLIENT,
'solid-devtools')

warn_on_version_mismatch(instance.meta.versions.get_solid(),
instance.meta.versions.get_expected_solid(),
warn_on_version_mismatch(instance.versions.get_solid(),
instance.versions.get_expected_solid(),
'solid-js')

// in case of navigation/page reload, reset the locator mode state in the extension
window_post_message('ResetPanel', undefined)
window_post_message('Debugger_Connected', {
client: instance.meta.versions.get_client(),
solid: instance.meta.versions.get_solid(),
client: instance.versions.get_client(),
solid: instance.versions.get_solid(),
})

/* From Content */
Expand Down
4 changes: 2 additions & 2 deletions extension/src/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ export interface GeneralChannels {
ResetPanel: void
}

export type Channels = debug.Debugger.InputChannels
& debug.Debugger.OutputChannels
export type Channels = debug.InputChannels
& debug.OutputChannels
& GeneralChannels

export type Message = {
Expand Down
15 changes: 8 additions & 7 deletions packages/debugger/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,13 @@ const debug = useDebugger()

_Debugger feature inspired by [LocatorJS](https://www.locatorjs.com)_

Locator let's you locate components on the page, and go to their source code in your IDE. All you need to do is configure it by calling `useLocator` with some options.
Locator let's you locate components on the page, and go to their source code in your IDE. All you need to do is configure it by calling `setLocatorOptions` with some options.

```ts
import { useLocator } from '@solid-devtools/debugger' // or 'solid-devtools/setup'
import { useDebugger } from '@solid-devtools/debugger' // or 'solid-devtools/setup'
useLocator()
const debug = useDebugger()
debug.setLocatorOptions()
```

It will not allow you to highlight hovered components on the page and reveal them in the IDE or the Chrome Extension. _(depending of if the extension panel is open or not)_
Expand All @@ -80,7 +81,7 @@ Choose in which IDE the component source code should be revealed.
Out-of-the-box options: `vscode`, `atom`, `webstorm` and `vscode-insiders`

```ts
useLocator({
setLocatorOptions({
targetIDE: 'vscode',
})
```
Expand All @@ -92,7 +93,7 @@ To be able to go the source code, the code location needs to be inlined during b
To target custom URLs (e.g. Github files) the `targetIDE` option accepts an function returning a `string` or `false`.

```ts
useLocator({
setLocatorOptions({
targetIDE: ({ filePath, line }) =>
// will navigate to this link when clicking
`https://github.com/thetarnav/solid-devtools/blob/main/playgrounds/sandbox/${filePath}#L${line}`,
Expand All @@ -102,7 +103,7 @@ useLocator({
Returning `false` will prevent calling `window.open` to navigate to URL, and let you handle the click yourself.

```ts
useLocator({
setLocatorOptions({
targetIDE({ projectPath, filePath, line, column, element }) {
console.log({ projectPath, filePath, line, column, element })
return false
Expand All @@ -117,7 +118,7 @@ Holding which key should enable the locator overlay? It's `"Alt"` by default —
Key options: `"Alt"`, `"Control"`, `"Mete"`, `"Shift"` or `string` to be compared with `e.key` property.

```tsx
useLocator({
setLocatorOptions({
key: 'Control',
})
```
Expand Down
1 change: 0 additions & 1 deletion packages/debugger/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@
"@solid-devtools/shared": "workspace:^",
"@solid-primitives/bounds": "^0.0.122",
"@solid-primitives/cursor": "^0.0.115",
"@solid-primitives/event-bus": "^1.0.11",
"@solid-primitives/event-listener": "^2.3.3",
"@solid-primitives/keyboard": "^1.2.8",
"@solid-primitives/platform": "^0.1.2",
Expand Down
12 changes: 6 additions & 6 deletions packages/debugger/src/dependency/index.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import {type EmitterEmit} from '@solid-primitives/event-bus'
import {throttle} from '@solid-primitives/scheduled'
import {defer} from '@solid-primitives/utils'
import {type Accessor, createEffect, createMemo} from 'solid-js'
import type {Debugger} from '../main/index.ts'
import {DevtoolsMainView, NodeType} from '../main/constants.ts'
import {ObjectType, getObjectById} from '../main/id.ts'
import {type NodeID, type Solid} from '../main/types.ts'
import {getNodeType} from '../main/utils.ts'
import {type OnNodeUpdate, type SerializedDGraph, collectDependencyGraph} from './collect.ts'
import {type OutputEmit, type InspectedState} from '../main/index.ts'

export {type SerializedDGraph} from './collect.ts'

export type DGraphUpdate = SerializedDGraph.Graph | null

export function createDependencyGraph(props: {
emit: EmitterEmit<Debugger.OutputChannels>
enabled: Accessor<boolean>
inspectedState: Accessor<Debugger.InspectedState>
onNodeUpdate: (nodeId: NodeID) => void
enabled: Accessor<boolean>
inspectedState: Accessor<InspectedState>
onNodeUpdate: (nodeId: NodeID) => void
emit: OutputEmit
}) {

let clearListeners: VoidFunction | null = null

const onNodeUpdate: OnNodeUpdate = id => {
Expand Down
2 changes: 1 addition & 1 deletion packages/debugger/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export {useDebugger, useLocator} from './main/index.ts'
export {useDebugger} from './main/index.ts'
export {
addSolidUpdateListener,
interceptComputationRerun,
Expand Down
13 changes: 7 additions & 6 deletions packages/debugger/src/inspector/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import {warn} from '@solid-devtools/shared/utils'
import {type EmitterEmit} from '@solid-primitives/event-bus'
import {scheduleIdle, throttle} from '@solid-primitives/scheduled'
import {type Accessor, createEffect, onCleanup} from 'solid-js'
import type {Debugger} from '../main/index.ts'
import {type OutputEmit} from '../main/index.ts'
import {ObjectType, getObjectById} from '../main/id.ts'
import {addSolidUpdateListener} from '../main/observe.ts'
import {type Mapped, type NodeID, type Solid, type ValueItemID} from '../main/types.ts'
Expand All @@ -20,10 +19,10 @@ export type ToggleInspectedValueData = {id: ValueItemID; selected: boolean}
* Plugin module
*/
export function createInspector(props: {
inspectedOwnerId: Accessor<NodeID | null>
emit: EmitterEmit<Debugger.OutputChannels>
enabled: Accessor<boolean>
inspectedOwnerId: Accessor<NodeID | null>
enabled: Accessor<boolean>
resetInspectedNode: VoidFunction
emit: OutputEmit
}) {
let lastDetails: Mapped.OwnerDetails | undefined
let inspectedOwner: Solid.Owner | null
Expand Down Expand Up @@ -90,7 +89,9 @@ export function createInspector(props: {
}

// Emit updates
batchedUpdates.length && props.emit('InspectorUpdate', batchedUpdates)
if (batchedUpdates.length) {
props.emit('InspectorUpdate', batchedUpdates)
}
})

const flushPropsCheck = throttle(flush, 200)
Expand Down
51 changes: 22 additions & 29 deletions packages/debugger/src/locator/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
import {makeHoverElementListener} from '@solid-devtools/shared/primitives'
import {warn} from '@solid-devtools/shared/utils'
import {type EmitterEmit} from '@solid-primitives/event-bus'
import * as s from 'solid-js'
import {defer} from '@solid-primitives/utils'
import {makeEventListener} from '@solid-primitives/event-listener'
import {createKeyHold} from '@solid-primitives/keyboard'
import {scheduleIdle} from '@solid-primitives/scheduled'
import {defer} from '@solid-primitives/utils'
import {
type Accessor,
createEffect,
createMemo,
createSignal,
getOwner,
onCleanup,
runWithOwner,
} from 'solid-js'
import type {Debugger} from '../main/index.ts'
import {makeHoverElementListener} from '@solid-devtools/shared/primitives'
import {warn} from '@solid-devtools/shared/utils'
import {type OutputEmit} from '../main/index.ts'
import * as registry from '../main/component-registry.ts'
import {ObjectType, getObjectById} from '../main/id.ts'
import SolidAPI from '../main/setup.ts'
Expand All @@ -36,18 +27,18 @@ import {type HighlightElementPayload, type LocatorOptions} from './types.ts'
export {parseLocationString} from './find-components.ts'

export function createLocator(props: {
emit: EmitterEmit<Debugger.OutputChannels>
locatorEnabled: Accessor<boolean>
setLocatorEnabledSignal(signal: Accessor<boolean>): void
locatorEnabled: s.Accessor<boolean>
setLocatorEnabledSignal(signal: s.Accessor<boolean>): void
onComponentClick(componentId: NodeID, next: VoidFunction): void
emit: OutputEmit
}) {
const [enabledByPressingSignal, setEnabledByPressingSignal] = createSignal((): boolean => false)
props.setLocatorEnabledSignal(createMemo(() => enabledByPressingSignal()()))
const [enabledByPressingSignal, setEnabledByPressingSignal] = s.createSignal((): boolean => false)
props.setLocatorEnabledSignal(s.createMemo(() => enabledByPressingSignal()()))

const [hoverTarget, setHoverTarget] = createSignal<HTMLElement | null>(null)
const [devtoolsTarget, setDevtoolsTarget] = createSignal<HighlightElementPayload>(null)
const [hoverTarget, setHoverTarget] = s.createSignal<HTMLElement | null>(null)
const [devtoolsTarget, setDevtoolsTarget] = s.createSignal<HighlightElementPayload>(null)

const [highlightedComponents, setHighlightedComponents] = createSignal<LocatorComponent[]>([])
const [highlightedComponents, setHighlightedComponents] = s.createSignal<LocatorComponent[]>([])

const calcHighlightedComponents = (
target: HTMLElement | HighlightElementPayload,
Expand Down Expand Up @@ -85,7 +76,7 @@ export function createLocator(props: {
}))
}

createEffect(
s.createEffect(
defer(
() => hoverTarget() ?? devtoolsTarget(),
scheduleIdle(target =>
Expand All @@ -97,10 +88,12 @@ export function createLocator(props: {
createElementsOverlay(highlightedComponents)

// notify of component hovered by using the debugger
createEffect((prev: NodeID | undefined) => {
s.createEffect((prev: NodeID | undefined) => {
const target = hoverTarget()
const comp = target && registry.findComponent(target)
if (prev) props.emit('HoveredComponent', {nodeId: prev, state: false})
if (prev) {
props.emit('HoveredComponent', {nodeId: prev, state: false})
}
if (comp) {
const {id} = comp
props.emit('HoveredComponent', {nodeId: id, state: true})
Expand All @@ -110,12 +103,12 @@ export function createLocator(props: {

let targetIDE: TargetIDE | TargetURLFunction | undefined

createEffect(() => {
s.createEffect(() => {
if (!props.locatorEnabled()) return

// set hovered element as target
makeHoverElementListener(el => setHoverTarget(el))
onCleanup(() => setHoverTarget(null))
s.onCleanup(() => setHoverTarget(null))

// go to selected component source code on click
makeEventListener(
Expand Down Expand Up @@ -144,7 +137,7 @@ export function createLocator(props: {
})

let locatorUsed = false
const owner = getOwner()!
const owner = s.getOwner()!
/**
* User function to enable user locator features. Such as element hover and go to source.
*
Expand All @@ -153,7 +146,7 @@ export function createLocator(props: {
* @param options {@link LocatorOptions} for the locator.
*/
function useLocator(options: LocatorOptions): void {
runWithOwner(owner, () => {
s.runWithOwner(owner, () => {
if (locatorUsed) return warn('useLocator can be called only once.')
locatorUsed = true
if (options.targetIDE) targetIDE = options.targetIDE
Expand Down
Loading

0 comments on commit 6b1b16d

Please sign in to comment.