Skip to content

Commit d101bce

Browse files
committed
Improve element mapping algorithm
1 parent cfea7b1 commit d101bce

2 files changed

Lines changed: 77 additions & 76 deletions

File tree

packages/debugger/src/main/id.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ export function getSdtId<T extends ObjectType>(obj: ValueMap[T], objType: T): No
4949
return id
5050
}
5151

52+
export const get_id_owner = (o: Solid.Owner): NodeID => getSdtId(o, ObjectType.Owner)
53+
export const get_id_el = (o: object): NodeID => getSdtId(o, ObjectType.Element)
54+
export const get_id_signal = (o: Solid.Signal): NodeID => getSdtId(o, ObjectType.Signal)
55+
export const get_id_store = (o: Solid.Store): NodeID => getSdtId(o, ObjectType.Store)
56+
export const get_id_store_node = (o: Solid.StoreNode): NodeID => getSdtId(o, ObjectType.StoreNode)
57+
export const get_id_custom_value = (o: Solid.SourceMapValue): NodeID => getSdtId(o, ObjectType.CustomValue)
58+
5259
export function getObjectById<T extends ObjectType>(id: NodeID, objType: T): ValueMap[T] | null {
5360
const ref = RefMapMap[objType].get(id)
5461
return ref?.deref() ?? null

packages/debugger/src/structure/walker.ts

Lines changed: 70 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {untrackedCallback} from '@solid-devtools/shared/primitives'
2-
import {ObjectType, getSdtId} from '../main/id.ts'
2+
import {ObjectType, getSdtId, get_id_el} from '../main/id.ts'
33
import {observeComputationUpdate} from '../main/observe.ts'
44
import {
55
type ElementChildren,
@@ -326,6 +326,13 @@ function mapChildren<TEl extends object>(
326326

327327
let element_set = new Set<any>()
328328

329+
const make_el_json = <TEl extends object>(el: TEl, eli: ElementInterface<TEl>): Mapped.Owner => ({
330+
id: get_id_el(el),
331+
type: NodeType.Element,
332+
name: eli.getName(el) ?? UNKNOWN,
333+
children: [],
334+
})
335+
329336
function mapOwner<TEl extends object>(
330337
owner: Solid.Owner,
331338
parent: Mapped.Owner | null,
@@ -387,6 +394,7 @@ function mapOwner<TEl extends object>(
387394

388395
// Map html elements in DOM mode
389396
if (config.mode === TreeWalkerMode.DOM) {
397+
390398
// elements might already be resolved when mapping components
391399
resolved_els ??= resolveElements(owner.value, config.eli)
392400

@@ -412,84 +420,77 @@ function mapOwner<TEl extends object>(
412420
children_stack_idx[children_stack_len-1]! += 1
413421

414422
let child = children[child_idx]!
415-
416-
if (child.type === NodeType.Element) {
417423

418-
// Don't go over added element children
419-
// TODO: add children cap stack
420-
if (children_stack_len-1 === 0) {
424+
/* Other children are already in mapped children so will be skipped */
425+
if (child.type !== NodeType.Element) {
426+
children_stack_arr[children_stack_len] = child.children
427+
children_stack_idx[children_stack_len] = 0
428+
children_stack_len += 1
429+
continue
430+
}
431+
432+
// Don't go over added element children
433+
// TODO: add children cap stack
434+
if (children_stack_len-1 === 0) {
435+
continue
436+
}
437+
438+
while (elements_stack_len > 0) {
439+
440+
let elements = elements_stack_arr [elements_stack_len-1]!
441+
let el_idx = elements_stack_idx [elements_stack_len-1]!
442+
let el_owner = elements_stack_owner[elements_stack_len-1]!
443+
444+
if (el_idx >= elements.length) {
445+
elements_stack_len -= 1
421446
continue
422447
}
423-
424-
while (elements_stack_len > 0) {
425-
426-
let elements = elements_stack_arr [elements_stack_len-1]!
427-
let el_idx = elements_stack_idx [elements_stack_len-1]!
428-
let el_owner = elements_stack_owner[elements_stack_len-1]!
429-
430-
if (el_idx >= elements.length) {
431-
elements_stack_len -= 1
432-
continue
433-
}
434448

435-
elements_stack_idx[elements_stack_len-1]! += 1
436-
437-
let el = elements[el_idx]!
438-
let el_id = getSdtId(el, ObjectType.Element)
439-
440-
// Child has this element
441-
if (el_id === child.id) {
442-
if (elements_stack_len > 1) {
443-
el_owner.children.push(children_stack_arr[0]![children_stack_idx[0]!-1]!)
444-
children_stack_arr[0]!.splice(children_stack_idx[0]!-1, 1)
445-
children_stack_idx[0]! -= 1
446-
}
447-
children_stack_len = 1
448-
449-
// Skip remaining elements from the child
450-
for (let skip_child_idx = child_idx + 1;;) {
451-
let el_idx = elements_stack_idx[elements_stack_len-1]!
452-
453-
if (el_idx >= elements.length ||
454-
skip_child_idx >= children.length ||
455-
children[skip_child_idx]!.id !== getSdtId(elements[el_idx]!, ObjectType.Element)
456-
) {
457-
break
458-
}
449+
elements_stack_idx[elements_stack_len-1]! += 1
459450

460-
elements_stack_idx[elements_stack_len-1]! += 1
461-
skip_child_idx += 1
451+
let el = elements[el_idx]!
452+
let el_id = get_id_el(el)
453+
454+
// Child has this element
455+
if (el_id === child.id) {
456+
/*
457+
Push child to the owner
458+
and previous ones that were not pushed yet
459+
*/
460+
for (let i = 0; i < children_stack_idx[0]!; i++) {
461+
el_owner.children.push(children_stack_arr[0]![i]!)
462+
}
463+
children_stack_arr[0]!.splice(0, children_stack_idx[0])
464+
children_stack_idx[0] = 0
465+
children_stack_len = 1
466+
467+
// Skip remaining elements from the child
468+
for (let ci = child_idx + 1; ci < children.length; ci++) {
469+
let ei = elements_stack_idx[elements_stack_len-1]!
470+
471+
if (ei >= elements.length ||
472+
children[ci]!.id !== get_id_el(elements[ei]!)
473+
) {
474+
break
462475
}
463476

464-
break
477+
elements_stack_idx[elements_stack_len-1]! += 1
465478
}
466479

467-
if (element_set.has(el)) {
468-
continue
469-
}
480+
break
481+
}
470482

471-
else {
472-
let el_json: Mapped.Owner = {
473-
id: el_id,
474-
type: NodeType.Element,
475-
name: config.eli.getName(el) ?? UNKNOWN,
476-
children: [],
477-
}
478-
el_owner.children.push(el_json)
479-
element_set.add(el)
483+
/* Not seen yet */
484+
if (!element_set.has(el)) {
485+
let el_json = make_el_json(el, config.eli)
486+
el_owner.children.push(el_json)
487+
element_set.add(el)
480488

481-
elements_stack_arr [elements_stack_len] = config.eli.getChildren(el)
482-
elements_stack_idx [elements_stack_len] = 0
483-
elements_stack_owner[elements_stack_len] = el_json
484-
elements_stack_len += 1
485-
}
489+
elements_stack_arr [elements_stack_len] = config.eli.getChildren(el)
490+
elements_stack_idx [elements_stack_len] = 0
491+
elements_stack_owner[elements_stack_len] = el_json
492+
elements_stack_len += 1
486493
}
487-
488-
} else {
489-
children_stack_arr[children_stack_len] = child.children
490-
children_stack_idx[children_stack_len] = 0
491-
children_stack_len += 1
492-
continue
493494
}
494495
}
495496

@@ -508,16 +509,9 @@ function mapOwner<TEl extends object>(
508509

509510
let el = elements[idx]!
510511

511-
if (element_set.has(el)) {
512-
continue
513-
}
512+
if (element_set.has(el)) continue
514513

515-
let el_json: Mapped.Owner = {
516-
id: getSdtId(el, ObjectType.Element),
517-
type: NodeType.Element,
518-
name: config.eli.getName(el) ?? UNKNOWN,
519-
children: [],
520-
}
514+
let el_json = make_el_json(el, config.eli)
521515
el_owner.children.push(el_json)
522516
element_set.add(el)
523517

0 commit comments

Comments
 (0)