Skip to content

Commit e65b19f

Browse files
committed
Send fake unowned root
1 parent 4e32e04 commit e65b19f

14 files changed

Lines changed: 318 additions & 274 deletions

File tree

packages/debugger/src/dependency/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ import {defer} from '@solid-primitives/utils'
44
import {msg} from '@solid-devtools/shared/utils'
55
import {DevtoolsMainView, NodeType} from '../main/constants.ts'
66
import {ObjectType, getObjectById} from '../main/id.ts'
7-
import {type NodeID, type Solid} from '../main/types.ts'
7+
import {type InspectedState, type NodeID, type OutputEmit, type Solid} from '../main/types.ts'
88
import {getNodeType} from '../main/utils.ts'
99
import {type OnNodeUpdate, type SerializedDGraph, collectDependencyGraph} from './collect.ts'
10-
import {type OutputEmit, type InspectedState} from '../main/index.ts'
1110

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

packages/debugger/src/inspector/index.ts

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import {msg, warn} from '@solid-devtools/shared/utils'
22
import {scheduleIdle, throttle} from '@solid-primitives/scheduled'
3-
import {type Accessor, createEffect, onCleanup} from 'solid-js'
4-
import {type OutputEmit} from '../main/index.ts'
3+
import {type Accessor, createEffect, createMemo, onCleanup} from 'solid-js'
54
import {ObjectType, getObjectById} from '../main/id.ts'
65
import {addSolidUpdateListener} from '../main/observe.ts'
7-
import {type Mapped, type NodeID, type Solid, type ValueItemID} from '../main/types.ts'
6+
import {type InspectedState, type Mapped, type OutputEmit, type Solid, type ValueItemID} from '../main/types.ts'
87
import {onOwnerDispose} from '../main/utils.ts'
98
import {type ObservedPropsMap, ValueNodeMap, clearOwnerObservers, collectOwnerDetails} from './inspector.ts'
109
import {encodeValue} from './serialize.ts'
@@ -19,7 +18,7 @@ export type ToggleInspectedValueData = {id: ValueItemID; selected: boolean}
1918
* Plugin module
2019
*/
2120
export function createInspector(props: {
22-
inspectedOwnerId: Accessor<NodeID | null>
21+
inspectedState: Accessor<InspectedState>
2322
enabled: Accessor<boolean>
2423
resetInspectedNode: VoidFunction
2524
emit: OutputEmit
@@ -146,39 +145,42 @@ export function createInspector(props: {
146145

147146
let clearPrevDisposeListener: VoidFunction | undefined
148147

148+
const inspectedOwnerId = createMemo(
149+
() => props.enabled()
150+
? props.inspectedState().ownerId
151+
: null
152+
)
149153
createEffect(() => {
150-
if (!props.enabled()) return
151-
const id = props.inspectedOwnerId()
152-
153-
queueMicrotask(() => {
154-
const owner = id && getObjectById(id, ObjectType.Owner)
155-
inspectedOwner && clearOwnerObservers(inspectedOwner, propsMap)
156-
inspectedOwner = owner
157-
valueMap.reset()
158-
clearUpdates()
159-
160-
if (owner) {
161-
const result = collectOwnerDetails(owner, {
162-
onValueUpdate: pushValueUpdate,
163-
onPropStateChange: pushPropState,
164-
observedPropsMap: propsMap,
165-
})
166-
167-
props.emit(msg('InspectedNodeDetails', result.details))
168-
169-
valueMap = result.valueMap
170-
lastDetails = result.details
171-
checkProxyProps = result.checkProxyProps || null
172-
} else {
173-
lastDetails = undefined
174-
checkProxyProps = null
175-
}
154+
const id = inspectedOwnerId()
155+
156+
const owner = id && getObjectById(id, ObjectType.Owner)
157+
if (inspectedOwner) clearOwnerObservers(inspectedOwner, propsMap)
158+
inspectedOwner = owner
159+
160+
valueMap.reset()
161+
clearUpdates()
162+
163+
if (owner) {
164+
const result = collectOwnerDetails(owner, {
165+
onValueUpdate: pushValueUpdate,
166+
onPropStateChange: pushPropState,
167+
observedPropsMap: propsMap,
168+
})
169+
170+
props.emit(msg('InspectedNodeDetails', result.details))
171+
172+
valueMap = result.valueMap
173+
lastDetails = result.details
174+
checkProxyProps = result.checkProxyProps || null
175+
} else {
176+
lastDetails = undefined
177+
checkProxyProps = null
178+
}
176179

177-
clearPrevDisposeListener?.()
178-
clearPrevDisposeListener = owner
179-
? onOwnerDispose(owner, props.resetInspectedNode)
180-
: undefined
181-
})
180+
clearPrevDisposeListener?.()
181+
clearPrevDisposeListener = owner
182+
? onOwnerDispose(owner, props.resetInspectedNode)
183+
: undefined
182184
})
183185

184186
createEffect(() => {

packages/debugger/src/locator/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ import {createKeyHold} from '@solid-primitives/keyboard'
55
import {scheduleIdle} from '@solid-primitives/scheduled'
66
import {makeHoverElementListener} from '@solid-devtools/shared/primitives'
77
import {msg, warn} from '@solid-devtools/shared/utils'
8-
import {type OutputEmit} from '../main/index.ts'
98
import * as registry from '../main/component-registry.ts'
109
import {ObjectType, getObjectById} from '../main/id.ts'
1110
import SolidAPI from '../main/setup.ts'
12-
import {type NodeID} from '../main/types.ts'
11+
import {type NodeID, type OutputEmit} from '../main/types.ts'
1312
import {createElementsOverlay} from './element-overlay.tsx'
1413
import {
1514
type LocatorComponent,

packages/debugger/src/main/index.ts

Lines changed: 51 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,23 @@
1+
import * as s from 'solid-js'
12
import {createStaticStore} from '@solid-primitives/static-store'
23
import {defer} from '@solid-primitives/utils'
3-
import * as s from 'solid-js'
4-
import {log_message, msg, mutate_remove, type Union} from '@solid-devtools/shared/utils'
5-
import {createDependencyGraph, type DGraphUpdate} from '../dependency/index.ts'
6-
import {createInspector, type InspectorUpdate, type ToggleInspectedValueData} from '../inspector/index.ts'
4+
import {log_message, msg, mutate_remove, type Timeout} from '@solid-devtools/shared/utils'
5+
import {createDependencyGraph} from '../dependency/index.ts'
6+
import {createInspector} from '../inspector/index.ts'
77
import {createLocator} from '../locator/index.ts'
8-
import {type HighlightElementPayload} from '../locator/types.ts'
9-
import {createStructure, type StructureUpdates} from '../structure/index.ts'
10-
import {DebuggerModule, DEFAULT_MAIN_VIEW, DevtoolsMainView, TreeWalkerMode} from './constants.ts'
8+
import {createStructure} from '../structure/index.ts'
9+
import {DebuggerModule, DEFAULT_MAIN_VIEW, DevtoolsMainView} from './constants.ts'
1110
import {getObjectById, getSdtId, ObjectType} from './id.ts'
1211
import setup from './setup.ts'
13-
import {type Mapped, type NodeID, type ValueItemID} from './types.ts'
14-
15-
export type InspectedState = {
16-
readonly ownerId: NodeID | null
17-
readonly signalId: NodeID | null
18-
/** closest note to inspected signal/owner on the owner structure */
19-
readonly treeWalkerOwnerId: NodeID | null
20-
}
21-
22-
export type OutputChannels = {
23-
DebuggerEnabled: boolean
24-
ResetPanel: void
25-
InspectedState: InspectedState
26-
InspectedNodeDetails: Mapped.OwnerDetails
27-
StructureUpdates: StructureUpdates
28-
NodeUpdates: NodeID[]
29-
InspectorUpdate: InspectorUpdate[]
30-
LocatorModeChange: boolean
31-
HoveredComponent: {nodeId: NodeID; state: boolean}
32-
InspectedComponent: NodeID
33-
DgraphUpdate: DGraphUpdate
34-
}
35-
36-
export type InputChannels = {
37-
ResetState: void
38-
InspectNode: {ownerId: NodeID | null; signalId: NodeID | null} | null
39-
InspectValue: ToggleInspectedValueData
40-
ConsoleInspectValue: ValueItemID
41-
HighlightElementChange: HighlightElementPayload
42-
OpenLocation: void
43-
TreeViewModeChange: TreeWalkerMode
44-
ViewChange: DevtoolsMainView
45-
ToggleModule: {module: DebuggerModule; enabled: boolean}
46-
}
47-
48-
export type InputMessage = Union<InputChannels>
49-
export type InputListener = (e: InputMessage) => void
50-
51-
export type OutputMessage = Union<OutputChannels>
52-
export type OutputListener = (e: OutputMessage) => void
53-
54-
export type OutputEmit = (e: OutputMessage) => void
12+
import {
13+
INSPECTED_STATE_NULL,
14+
type InputChannels,
15+
type InputMessage,
16+
type InspectedState,
17+
type NodeID,
18+
type OutputListener,
19+
type OutputMessage,
20+
} from './types.ts'
5521

5622
function createDebugger() {
5723

@@ -122,16 +88,10 @@ function createDebugger() {
12288
//
12389

12490
// Current inspected node is shared between modules
125-
const INITIAL_INSPECTED_STATE = {
126-
ownerId: null,
127-
signalId: null,
128-
treeWalkerOwnerId: null,
129-
} as const satisfies OutputChannels['InspectedState']
130-
131-
const [inspectedState, setInspectedState] = s.createSignal<
132-
OutputChannels['InspectedState']
133-
>(INITIAL_INSPECTED_STATE, {equals: false})
134-
const inspectedOwnerId = s.createMemo(() => inspectedState().ownerId)
91+
const [inspectedState, setInspectedState] = s.createSignal<InspectedState>(
92+
INSPECTED_STATE_NULL,
93+
{equals: false},
94+
)
13595

13696
s.createEffect(() => {
13797
emitOutput(msg('InspectedState', inspectedState()))
@@ -143,48 +103,34 @@ function createDebugger() {
143103
return treeWalkerOwner ? getSdtId(treeWalkerOwner, ObjectType.Owner) : null
144104
}
145105

146-
/** Check if the inspected node doesn't need to change (treeview mode changed or sth) */
147-
function updateInspectedNode() {
148-
setInspectedState(p => ({
149-
...p,
150-
treeWalkerOwnerId: getTreeWalkerOwnerId(p.treeWalkerOwnerId),
151-
}))
152-
}
153-
154-
function resetInspectedNode() {
155-
setInspectedState(INITIAL_INSPECTED_STATE)
156-
}
157-
158106
function setInspectedNode(data: InputChannels['InspectNode']): void {
159-
let {ownerId, signalId} = data ?? {ownerId: null, signalId: null}
160-
if (ownerId && !getObjectById(ownerId, ObjectType.Owner)) ownerId = null
161-
if (signalId && !getObjectById(signalId, ObjectType.Signal)) signalId = null
162-
setInspectedState({
163-
ownerId,
164-
signalId,
165-
treeWalkerOwnerId: getTreeWalkerOwnerId(ownerId),
166-
})
107+
if (data == null) {
108+
setInspectedState(INSPECTED_STATE_NULL)
109+
} else {
110+
let ownerId = data.ownerId && getObjectById(data.ownerId, ObjectType.Owner) && data.ownerId
111+
let signalId = data.signalId && getObjectById(data.signalId, ObjectType.Signal) && data.signalId
112+
let treeWalkerOwnerId = getTreeWalkerOwnerId(ownerId)
113+
setInspectedState({ownerId, signalId, treeWalkerOwnerId})
114+
}
167115
}
168116

169-
s.createComputed(
170-
defer(debuggerEnabled, enabled => {
171-
if (!enabled) resetInspectedNode()
172-
}),
173-
)
117+
s.createComputed(defer(debuggerEnabled, enabled => {
118+
if (!enabled) setInspectedState(INSPECTED_STATE_NULL)
119+
}))
174120

175121
// Computation and signal updates
176122
let node_updates_ids: NodeID[] = []
177-
let node_updates_timeout = 0
123+
let node_updates_timeout = null as null | Timeout
178124

179125
function pushNodeUpdate(id: NodeID) {
180126

181127
node_updates_ids.push(id)
182128

183-
if (node_updates_timeout === 0) {
184-
node_updates_timeout = window.setTimeout(() => {
129+
if (node_updates_timeout == null) {
130+
node_updates_timeout = setTimeout(() => {
185131
emitOutput(msg('NodeUpdates', node_updates_ids))
186-
node_updates_ids = []
187-
node_updates_timeout = 0
132+
node_updates_ids = []
133+
node_updates_timeout = null
188134
})
189135
}
190136
}
@@ -195,7 +141,11 @@ function createDebugger() {
195141
const structure = createStructure({
196142
onStructureUpdate(updates) {
197143
emitOutput(msg('StructureUpdates', updates))
198-
updateInspectedNode()
144+
/** Check if the inspected node doesn't need to change */
145+
setInspectedState(p => ({
146+
...p,
147+
treeWalkerOwnerId: getTreeWalkerOwnerId(p.treeWalkerOwnerId),
148+
}))
199149
},
200150
onNodeUpdate: pushNodeUpdate,
201151
enabled: debuggerEnabled,
@@ -206,8 +156,8 @@ function createDebugger() {
206156
//
207157
const inspector = createInspector({
208158
enabled: debuggerEnabled,
209-
inspectedOwnerId: inspectedOwnerId,
210-
resetInspectedNode: resetInspectedNode,
159+
inspectedState: inspectedState,
160+
resetInspectedNode: () => setInspectedState(INSPECTED_STATE_NULL),
211161
emit: emitOutput,
212162
})
213163

@@ -249,6 +199,14 @@ function createDebugger() {
249199
s.createEffect(defer(modules.locatorKeyPressSignal, state => {
250200
emitOutput(msg('LocatorModeChange', state))
251201
}))
202+
203+
console.log(setup.unowned.signals)
204+
setup.unowned.onSignalAdded = (ref, idx) => {
205+
console.log('unowned.onSignalAdded', ref.deref(), idx)
206+
}
207+
setup.unowned.onSignalRemoved = (ref, idx) => {
208+
console.log('unowned.onSignalRemoved', ref.deref(), idx)
209+
}
252210

253211
function emitInput(e: InputMessage) {
254212

@@ -258,7 +216,7 @@ function createDebugger() {
258216
case 'ResetState': {
259217
// reset all the internal state
260218
s.batch(() => {
261-
resetInspectedNode()
219+
setInspectedState(INSPECTED_STATE_NULL)
262220
currentView = DEFAULT_MAIN_VIEW
263221
structure.resetTreeWalkerMode()
264222
locator.setDevtoolsHighlightTarget(null)

packages/debugger/src/main/types.ts

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,55 @@
1-
import type {EncodedValue, PropGetterState} from '../inspector/types.ts'
2-
import type {SourceLocation} from '../locator/types.ts'
3-
import {NodeType, OWNER_LOCATION_PROP, ValueItemType} from './constants.ts'
1+
import type {Union} from '@solid-devtools/shared/utils'
2+
import type {EncodedValue, InspectorUpdate, PropGetterState, ToggleInspectedValueData} from '../inspector/types.ts'
3+
import type {HighlightElementPayload, SourceLocation} from '../locator/types.ts'
4+
import type {StructureUpdates, DGraphUpdate} from '../types.ts'
5+
import {DebuggerModule, DevtoolsMainView, NodeType, OWNER_LOCATION_PROP, TreeWalkerMode, ValueItemType} from './constants.ts'
6+
7+
export type InspectedState = {
8+
readonly ownerId: NodeID | null
9+
readonly signalId: NodeID | null
10+
/** closest note to inspected signal/owner on the owner structure */
11+
readonly treeWalkerOwnerId: NodeID | null
12+
}
13+
14+
export const INSPECTED_STATE_NULL: InspectedState = {
15+
ownerId: null,
16+
signalId: null,
17+
treeWalkerOwnerId: null,
18+
}
19+
20+
export type OutputChannels = {
21+
DebuggerEnabled: boolean
22+
ResetPanel: void
23+
InspectedState: InspectedState
24+
InspectedNodeDetails: Mapped.OwnerDetails
25+
StructureUpdates: StructureUpdates
26+
NodeUpdates: NodeID[]
27+
InspectorUpdate: InspectorUpdate[]
28+
LocatorModeChange: boolean
29+
HoveredComponent: {nodeId: NodeID; state: boolean}
30+
InspectedComponent: NodeID
31+
DgraphUpdate: DGraphUpdate
32+
}
33+
34+
export type InputChannels = {
35+
ResetState: void
36+
InspectNode: {ownerId: NodeID | null; signalId: NodeID | null} | null
37+
InspectValue: ToggleInspectedValueData
38+
ConsoleInspectValue: ValueItemID
39+
HighlightElementChange: HighlightElementPayload
40+
OpenLocation: void
41+
TreeViewModeChange: TreeWalkerMode
42+
ViewChange: DevtoolsMainView
43+
ToggleModule: {module: DebuggerModule; enabled: boolean}
44+
}
45+
46+
export type InputMessage = Union<InputChannels>
47+
export type InputListener = (e: InputMessage) => void
48+
49+
export type OutputMessage = Union<OutputChannels>
50+
export type OutputListener = (e: OutputMessage) => void
51+
52+
export type OutputEmit = (e: OutputMessage) => void
453

554
//
655
// EXPOSED SOLID API

0 commit comments

Comments
 (0)