Skip to content

Commit 01d87f3

Browse files
committed
wip
1 parent be5dfdc commit 01d87f3

File tree

9 files changed

+150
-168
lines changed

9 files changed

+150
-168
lines changed

packages/qwik/src/core/client/vnode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1718,7 +1718,7 @@ export const vnode_getAttrKeys = (vnode: ElementVNode | VirtualVNode): string[]
17181718
const props = vnode.props;
17191719
if (props) {
17201720
const keys = Object.keys(props);
1721-
for (let i = 0; i < keys.length; i++) {
1721+
for (let i = 0; i < Math.min(keys.length, 20); i++) {
17221722
const key = keys[i];
17231723
if (!key.startsWith(Q_PROPS_SEPARATOR)) {
17241724
keys.push(key);

packages/qwik/src/core/debug.ts

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,51 +11,56 @@ import { isTask } from './use/use-task';
1111

1212
const stringifyPath: any[] = [];
1313
export function qwikDebugToString(value: any): any {
14-
if (value === null) {
15-
return 'null';
16-
} else if (value === undefined) {
17-
return 'undefined';
18-
} else if (typeof value === 'string') {
19-
return '"' + value + '"';
20-
} else if (typeof value === 'number' || typeof value === 'boolean') {
21-
return String(value);
22-
} else if (isTask(value)) {
23-
return `Task(${qwikDebugToString(value.$qrl$)})`;
24-
} else if (isQrl(value)) {
25-
return `Qrl(${value.$symbol$})`;
26-
} else if (typeof value === 'object' || typeof value === 'function') {
27-
if (stringifyPath.includes(value)) {
28-
return '*';
29-
}
30-
if (stringifyPath.length > 10) {
31-
// debugger;
32-
}
33-
try {
34-
stringifyPath.push(value);
35-
if (Array.isArray(value)) {
36-
if (vnode_isVNode(value)) {
14+
try {
15+
if (value === null) {
16+
return 'null';
17+
} else if (value === undefined) {
18+
return 'undefined';
19+
} else if (typeof value === 'string') {
20+
return '"' + value + '"';
21+
} else if (typeof value === 'number' || typeof value === 'boolean') {
22+
return String(value);
23+
} else if (isTask(value)) {
24+
return `Task(${qwikDebugToString(value.$qrl$)})`;
25+
} else if (isQrl(value)) {
26+
return `Qrl(${value.$symbol$})`;
27+
} else if (typeof value === 'object' || typeof value === 'function') {
28+
if (stringifyPath.includes(value)) {
29+
return '*';
30+
}
31+
if (stringifyPath.length > 10) {
32+
// debugger;
33+
}
34+
try {
35+
stringifyPath.push(value);
36+
if (Array.isArray(value)) {
37+
if (vnode_isVNode(value)) {
38+
return '(' + value.getProp(DEBUG_TYPE, null) + ')';
39+
} else {
40+
return value.map(qwikDebugToString);
41+
}
42+
} else if (isSignal(value)) {
43+
if (value instanceof WrappedSignalImpl) {
44+
return 'WrappedSignal';
45+
} else if (value instanceof ComputedSignalImpl) {
46+
return 'ComputedSignal';
47+
} else {
48+
return 'Signal';
49+
}
50+
} else if (isStore(value)) {
51+
return 'Store';
52+
} else if (isJSXNode(value)) {
53+
return jsxToString(value);
54+
} else if (vnode_isVNode(value)) {
3755
return '(' + value.getProp(DEBUG_TYPE, null) + ')';
38-
} else {
39-
return value.map(qwikDebugToString);
40-
}
41-
} else if (isSignal(value)) {
42-
if (value instanceof WrappedSignalImpl) {
43-
return 'WrappedSignal';
44-
} else if (value instanceof ComputedSignalImpl) {
45-
return 'ComputedSignal';
46-
} else {
47-
return 'Signal';
4856
}
49-
} else if (isStore(value)) {
50-
return 'Store';
51-
} else if (isJSXNode(value)) {
52-
return jsxToString(value);
53-
} else if (vnode_isVNode(value)) {
54-
return '(' + value.getProp(DEBUG_TYPE, null) + ')';
57+
} finally {
58+
stringifyPath.pop();
5559
}
56-
} finally {
57-
stringifyPath.pop();
5860
}
61+
} catch (e) {
62+
console.log('ERROR in qwikDebugToString', e);
63+
return '*error*';
5964
}
6065
return value;
6166
}

packages/qwik/src/core/shared/component-execution.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ export const executeComponent = (
7777
}
7878
if (isQrl(componentQRL)) {
7979
props = props || container.getHostProp(renderHost, ELEMENT_PROPS) || EMPTY_OBJ;
80+
// TODO is this possible? JSXNode handles this, no?
8081
if ('children' in props) {
8182
delete props.children;
8283
}

packages/qwik/src/core/shared/cursor/chore-execution.ts

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,12 @@ export function executeTasks(
5656
container: Container,
5757
cursor: Cursor
5858
): ValueOrPromise<void> {
59-
if (!(vNode.dirty & ChoreBits.TASKS)) {
60-
return;
61-
}
59+
vNode.dirty &= ~ChoreBits.TASKS;
6260

6361
const elementSeq = container.getHostProp<unknown[] | null>(vNode, ELEMENT_SEQ);
6462

6563
if (!elementSeq || elementSeq.length === 0) {
6664
// No tasks to execute, clear the bit
67-
vNode.dirty &= ~ChoreBits.TASKS;
6865
return;
6966
}
7067

@@ -87,6 +84,7 @@ export function executeTasks(
8784
runResource(task as ResourceDescriptor<TaskFn>, container, vNode);
8885
} else if (task.$flags$ & TaskFlags.VISIBLE_TASK) {
8986
// VisibleTasks: store for execution after flush (don't execute now)
87+
// no dirty propagation needed, dirtyChildren array is enough
9088
vNode.dirty |= ChoreBits.VISIBLE_TASKS;
9189
} else {
9290
// Regular tasks: chain promises only between each other
@@ -105,9 +103,6 @@ export function executeTasks(
105103
}
106104
}
107105

108-
// Clear the TASKS bit after execution
109-
vNode.dirty &= ~ChoreBits.TASKS;
110-
111106
if (extraPromises) {
112107
setExtraPromises(isServerPlatform() ? vNode : cursor, extraPromises);
113108
}
@@ -125,23 +120,17 @@ export function setNodeDiffPayload(vNode: VNode, payload: JSXOutput | Signal<JSX
125120
}
126121

127122
export function executeNodeDiff(vNode: VNode, container: Container): ValueOrPromise<void> {
128-
if (!(vNode.dirty & ChoreBits.NODE_DIFF)) {
129-
return;
130-
}
123+
vNode.dirty &= ~ChoreBits.NODE_DIFF;
131124

132125
const domVNode = vNode as ElementVNode;
133126
let jsx = getNodeDiffPayload(vNode);
134127
if (!jsx) {
135-
// No node diff payload, clear the bit
136-
vNode.dirty &= ~ChoreBits.NODE_DIFF;
137128
return;
138129
}
139130
if (isSignal(jsx)) {
140131
jsx = jsx.value as any;
141132
}
142133
const result = vnode_diff(container as ClientContainer, jsx, domVNode, null);
143-
//vnode diff done, clear the bit
144-
vNode.dirty &= ~ChoreBits.NODE_DIFF;
145134
return result;
146135
}
147136

@@ -271,14 +260,13 @@ function setNodeProp(
271260
* @returns Void
272261
*/
273262
export function executeNodeProps(vNode: VNode, container: Container): void {
274-
if (!(vNode.dirty & ChoreBits.NODE_PROPS) || !(vNode.flags & VNodeFlags.Element)) {
263+
vNode.dirty &= ~ChoreBits.NODE_PROPS;
264+
if (!(vNode.flags & VNodeFlags.Element)) {
275265
return;
276266
}
277267

278268
const allPropData = getNodePropData(vNode);
279269
if (!allPropData || allPropData.size === 0) {
280-
// No pending prop data, clear the bit
281-
vNode.dirty &= ~ChoreBits.NODE_PROPS;
282270
return;
283271
}
284272

@@ -311,26 +299,23 @@ export function executeNodeProps(vNode: VNode, container: Container): void {
311299

312300
// Clear pending prop data after processing
313301
clearNodePropData(vNode);
314-
vNode.dirty &= ~ChoreBits.NODE_PROPS;
315302
}
316303

317304
/**
318-
* Executes cleanup tasks for a vNode if the CLEANUP dirty bit is set.
305+
* Execute visible task cleanups and add promises to extraPromises.
319306
*
320307
* @param vNode - The vNode to cleanup
321308
* @param container - The container
322309
* @returns Void
323310
*/
324311
export function executeCleanup(vNode: VNode, container: Container): void {
325-
if (!(vNode.dirty & ChoreBits.CLEANUP)) {
326-
return;
327-
}
312+
vNode.dirty &= ~ChoreBits.CLEANUP;
328313

329314
if (vnode_isVNode(vNode)) {
315+
// TODO I dont think this runs the cleanups of visible tasks
316+
// TODO add promises to extraPromises
330317
clearAllEffects(container, vNode);
331318
}
332-
333-
vNode.dirty &= ~ChoreBits.CLEANUP;
334319
}
335320

336321
/**
@@ -342,13 +327,12 @@ export function executeCleanup(vNode: VNode, container: Container): void {
342327
* @returns Promise if computation is async, void otherwise
343328
*/
344329
export function executeCompute(vNode: VNode, container: Container): ValueOrPromise<void> {
345-
if (!(vNode.dirty & ChoreBits.COMPUTE)) {
346-
return;
347-
}
330+
vNode.dirty &= ~ChoreBits.COMPUTE;
348331

349332
// Compute chores are typically handled by the reactive system.
350333
// This is a placeholder for explicit compute chores if needed.
351334

352-
vNode.dirty &= ~ChoreBits.COMPUTE;
335+
// TODO remove or use
336+
353337
return;
354338
}

packages/qwik/src/core/shared/cursor/cursor-props.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { removeCursorFromQueue } from './cursor-queue';
1010
*/
1111
const CURSOR_PRIORITY_KEY = 'q:priority';
1212
const CURSOR_POSITION_KEY = 'q:position';
13+
const CURSOR_CHILD_KEY = 'q:childIndex';
1314
const VNODE_PROMISE_KEY = 'q:promise';
1415
const CURSOR_EXTRA_PROMISES_KEY = 'q:extraPromises';
1516

@@ -52,6 +53,25 @@ export function getCursorPosition(vNode: VNode): VNode | null {
5253
return (props?.[CURSOR_POSITION_KEY] as VNode | null) ?? null;
5354
}
5455

56+
/**
57+
* Set the next child to process index in a vNode.
58+
*
59+
* @param vNode - The vNode
60+
* @param childIndex - The child index to set
61+
*/
62+
export function setNextChildIndex(vNode: VNode, childIndex: number): void {
63+
const props = vNode.props as Props;
64+
// We could also add a dirtycount to avoid checking all children after completion
65+
// perf: we could also use dirtychild index 0 for the index instead
66+
props[CURSOR_CHILD_KEY] = childIndex;
67+
}
68+
69+
/** Gets the next child to process index from a vNode. */
70+
export function getNextChildIndex(vNode: VNode): number | null {
71+
const props = vNode.props as Props;
72+
return (props[CURSOR_CHILD_KEY] as number) ?? null;
73+
}
74+
5575
/**
5676
* Sets the cursor position in a cursor vNode.
5777
*

0 commit comments

Comments
 (0)