11import { Accessor , createEffect , createSignal , untrack } from "solid-js"
2- import { createSimpleEmitter , Listen } from "@solid-primitives/event-bus"
2+ import {
3+ createEventHub ,
4+ createSimpleEmitter ,
5+ EventBus ,
6+ EventHubOn ,
7+ } from "@solid-primitives/event-bus"
38import { throttle } from "@solid-primitives/scheduled"
49import {
510 Mapped ,
@@ -17,9 +22,7 @@ import {
1722 clearOwnerObservers ,
1823 collectOwnerDetails ,
1924 encodeComponentProps ,
20- encodeOwnerValue ,
2125 SignalUpdateHandler ,
22- ValueUpdateHandler ,
2326} from "./inspect"
2427import { makeSolidUpdateListener } from "./update"
2528
@@ -41,52 +44,30 @@ DETAILS:
4144
4245export type BatchComputationUpdatesHandler = ( payload : ComputationUpdate [ ] ) => void
4346
47+ export type EventHubChannels = {
48+ ComputationUpdates : EventBus < ComputationUpdate [ ] >
49+ SignalUpdates : EventBus < { id : NodeID ; value : EncodedValue < boolean > } [ ] >
50+ PropsUpdate : EventBus < Mapped . Props >
51+ ValueUpdate : EventBus < { value : EncodedValue < boolean > ; update : boolean } >
52+ StructureUpdates : EventBus < RootsUpdates >
53+ }
54+
4455export type PluginData = {
4556 readonly triggerUpdate : VoidFunction
4657 readonly forceTriggerUpdate : VoidFunction
47- readonly handleComputationUpdates : ( listener : BatchComputationUpdatesHandler ) => VoidFunction
48- readonly handleSignalUpdates : (
49- listener : ( payload : { id : NodeID ; value : EncodedValue < boolean > } [ ] ) => void ,
50- ) => VoidFunction
51- readonly handlePropsUpdate : Listen < Mapped . Props >
52- readonly handleValueUpdate : Listen < EncodedValue < boolean > >
53- readonly handleStructureUpdates : Listen < RootsUpdates >
58+ readonly listenTo : EventHubOn < EventHubChannels >
5459 readonly components : Accessor < Record < NodeID , Mapped . ResolvedComponent [ ] > >
5560 readonly findComponent : ( rootId : NodeID , nodeId : NodeID ) => Mapped . ResolvedComponent | undefined
5661 readonly inspectedDetails : Accessor < Mapped . OwnerDetails | null >
5762 readonly setInspectedOwner : ( payload : { rootId : NodeID ; nodeId : NodeID } | null ) => void
5863 readonly getElementById : ( id : NodeID ) => HTMLElement | undefined
5964 readonly setInspectedSignal : ( id : NodeID , selected : boolean ) => EncodedValue < boolean > | null
6065 readonly setInspectedProp : ( key : NodeID , selected : boolean ) => void
61- readonly setInspectedValue : ( selected : boolean ) => EncodedValue < boolean > | null
66+ readonly setInspectedValue : ( selected : boolean ) => void
6267}
6368
6469type RootUpdate = { removed : NodeID } | { updated : Mapped . Root }
6570
66- const [ handleStructureUpdates , pushStructureUpdate ] = ( ( ) => {
67- const [ handleStructureUpdate , emitStructureUpdate ] = createSimpleEmitter < RootsUpdates > ( )
68- const updates : Mapped . Root [ ] = [ ]
69- const removedIds = new Set < NodeID > ( )
70- const trigger = throttle ( ( ) => {
71- const updated : Record < NodeID , Mapped . Root > = { }
72- for ( let i = updates . length - 1 ; i >= 0 ; i -- ) {
73- const update = updates [ i ]
74- const { id } = update
75- if ( ! removedIds . has ( id ) && ! updated [ id ] ) updated [ id ] = update
76- }
77- emitStructureUpdate ( { updated, removed : [ ...removedIds ] } )
78- updates . length = 0
79- removedIds . clear ( )
80- } , 50 )
81- const pushStructureUpdate = ( update : RootUpdate ) => {
82- if ( "removed" in update ) removedIds . add ( update . removed )
83- else if ( removedIds . has ( update . updated . id ) ) return
84- else updates . push ( update . updated )
85- trigger ( )
86- }
87- return [ handleStructureUpdate , pushStructureUpdate ]
88- } ) ( )
89-
9071export const debuggerConfig = {
9172 gatherComponents : false ,
9273}
@@ -97,6 +78,14 @@ const exported = createInternalRoot(() => {
9778 /** forced — immediate global update */
9879 const [ onForceUpdate , forceTriggerUpdate ] = createSimpleEmitter ( )
9980
81+ const eventHub = createEventHub < EventHubChannels > ( bus => ( {
82+ ComputationUpdates : bus ( ) ,
83+ SignalUpdates : bus ( ) ,
84+ PropsUpdate : bus ( ) ,
85+ ValueUpdate : bus ( ) ,
86+ StructureUpdates : bus ( ) ,
87+ } ) )
88+
10089 //
10190 // Consumers:
10291 //
@@ -128,6 +117,32 @@ const exported = createInternalRoot(() => {
128117 pushStructureUpdate ( { updated : newRoot } )
129118 }
130119
120+ //
121+ // Structure updates:
122+ //
123+ const pushStructureUpdate = ( ( ) => {
124+ const updates : Mapped . Root [ ] = [ ]
125+ const removedIds = new Set < NodeID > ( )
126+ const trigger = throttle ( ( ) => {
127+ const updated : Record < NodeID , Mapped . Root > = { }
128+ for ( let i = updates . length - 1 ; i >= 0 ; i -- ) {
129+ const update = updates [ i ]
130+ const { id } = update
131+ if ( ! removedIds . has ( id ) && ! updated [ id ] ) updated [ id ] = update
132+ }
133+ eventHub . emit ( "StructureUpdates" , { updated, removed : [ ...removedIds ] } )
134+ updates . length = 0
135+ removedIds . clear ( )
136+ } , 50 )
137+ const pushStructureUpdate = ( update : RootUpdate ) => {
138+ if ( "removed" in update ) removedIds . add ( update . removed )
139+ else if ( removedIds . has ( update . updated . id ) ) return
140+ else updates . push ( update . updated )
141+ trigger ( )
142+ }
143+ return pushStructureUpdate
144+ } ) ( )
145+
131146 //
132147 // Inspected Owner details:
133148 //
@@ -138,38 +153,56 @@ const exported = createInternalRoot(() => {
138153 signals : new Set < NodeID > ( ) ,
139154 props : new Set < string > ( ) ,
140155 value : false ,
156+ getValue : ( ) => null as unknown ,
141157 }
142158
143159 const [ details , setDetails ] = createSignal < Mapped . OwnerDetails | null > ( null )
144160
145161 const getElementById = ( id : NodeID ) : HTMLElement | undefined => inspected . elementMap . get ( id )
146162
147- const [ handleSignalUpdates , pushSignalUpdate ] = createBatchedUpdateEmitter < {
163+ const pushSignalUpdate = createBatchedUpdateEmitter < {
148164 id : NodeID
149165 value : EncodedValue < boolean >
150- } > ( )
166+ } > ( updates => eventHub . emit ( "SignalUpdates" , updates ) )
151167 const onSignalUpdate : SignalUpdateHandler = untrackedCallback ( ( id , value ) => {
152168 if ( ! enabled ( ) || ! inspected . owner ) return
153169 const isSelected = inspected . signals . has ( id )
154170 pushSignalUpdate ( { id, value : encodeValue ( value , isSelected , inspected . elementMap ) } )
155171 } )
156172
157- const [ handleValueUpdate , emitValueUpdate ] = createSimpleEmitter < EncodedValue < boolean > > ( )
158- const onValueUpdate : ValueUpdateHandler = throttle ( value => {
159- if ( ! enabled ( ) || ! inspected . owner ) return
160- emitValueUpdate ( encodeValue ( value , inspected . value , inspected . elementMap ) )
161- } )
173+ const triggerValueUpdate = ( ( ) => {
174+ let updateNext = false
175+ const forceValueUpdate = ( ) => {
176+ if ( ! enabled ( ) || ! inspected . owner ) return ( updateNext = false )
177+ eventHub . emit ( "ValueUpdate" , {
178+ value : encodeValue ( inspected . getValue ( ) , inspected . value , inspected . elementMap ) ,
179+ update : updateNext ,
180+ } )
181+ updateNext = false
182+ }
183+ const triggerValueUpdate = throttle ( forceValueUpdate )
184+ function handleValueUpdate ( update : boolean , force = false ) {
185+ if ( update ) updateNext = true
186+ if ( force ) forceValueUpdate ( )
187+ else triggerValueUpdate ( )
188+ }
189+ return handleValueUpdate
190+ } ) ( )
162191
163192 const setInspectedDetails = untrackedCallback ( ( owner : Solid . Owner ) => {
164193 inspected . owner && clearOwnerObservers ( inspected . owner )
165194 inspected . props . clear ( )
166195 inspected . signals . clear ( )
167196 inspected . owner = owner
168197 inspected . value = false
169- const result = collectOwnerDetails ( owner , { onSignalUpdate, onValueUpdate } )
198+ const result = collectOwnerDetails ( owner , {
199+ onSignalUpdate,
200+ onValueUpdate : ( ) => triggerValueUpdate ( true ) ,
201+ } )
170202 setDetails ( result . details )
171203 inspected . signalMap = result . signalMap
172204 inspected . elementMap = result . elementMap
205+ inspected . getValue = result . getOwnerValue
173206 } )
174207 const clearInspectedDetails = ( ) => {
175208 inspected . owner && clearOwnerObservers ( inspected . owner )
@@ -180,15 +213,13 @@ const exported = createInternalRoot(() => {
180213 inspected . value = false
181214 }
182215
183- const [ handlePropsUpdate , emitPropsUpdate ] = createSimpleEmitter < Mapped . Props > ( )
184-
185216 function updateInspectedProps ( ) {
186217 if ( ! inspected . owner ) return
187218 const props = encodeComponentProps ( inspected . owner , {
188219 inspectedProps : inspected . props ,
189220 elementMap : inspected . elementMap ,
190221 } )
191- props && emitPropsUpdate ( props )
222+ props && eventHub . emit ( "PropsUpdate" , props )
192223 }
193224
194225 createEffect ( ( ) => {
@@ -198,7 +229,12 @@ const exported = createInternalRoot(() => {
198229 else inspected . owner && setInspectedDetails ( inspected . owner )
199230
200231 // update the owner details whenever there is a change in solid's internals
201- makeSolidUpdateListener ( throttle ( updateInspectedProps , 150 ) )
232+ makeSolidUpdateListener (
233+ throttle ( ( ) => {
234+ updateInspectedProps ( )
235+ triggerValueUpdate ( false )
236+ } , 150 ) ,
237+ )
202238 } )
203239
204240 const setInspectedOwner : PluginData [ "setInspectedOwner" ] = payload => {
@@ -225,24 +261,22 @@ const exported = createInternalRoot(() => {
225261 }
226262 const setInspectedValue : PluginData [ "setInspectedValue" ] = selected => {
227263 if ( ! inspected . owner ) return null
228- return encodeOwnerValue ( inspected . owner , ( inspected . value = selected ) , inspected . elementMap )
264+ inspected . value = selected
265+ triggerValueUpdate ( false , true )
229266 }
230267
231268 //
232269 // Computation updates:
233270 //
234- const [ handleComputationUpdates , _pushComputationUpdate ] =
235- createBatchedUpdateEmitter < ComputationUpdate > ( )
271+ const _pushComputationUpdate = createBatchedUpdateEmitter < ComputationUpdate > ( updates =>
272+ eventHub . emit ( "ComputationUpdates" , updates ) ,
273+ )
236274 const pushComputationUpdate : ComputationUpdateHandler = ( rootId , id ) => {
237275 _pushComputationUpdate ( { rootId, id } )
238276 }
239277
240278 const pluginData : PluginData = {
241- handleComputationUpdates,
242- handleSignalUpdates,
243- handlePropsUpdate,
244- handleValueUpdate,
245- handleStructureUpdates,
279+ listenTo : eventHub . on ,
246280 components,
247281 findComponent,
248282 triggerUpdate,
0 commit comments