Skip to content

Commit 808acdf

Browse files
committed
fix: RUN_QRL host object
1 parent 22fd83b commit 808acdf

File tree

6 files changed

+25
-33
lines changed

6 files changed

+25
-33
lines changed

packages/qwik/src/core/client/queue-qrl.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ChoreType } from '../shared/scheduler';
44
import { getInvokeContext } from '../use/use-core';
55
import { useLexicalScope } from '../use/use-lexical-scope.public';
66
import { _getQContainerElement, getDomContainer } from './dom-container';
7+
import type { ElementVNode } from './types';
78

89
/**
910
* This is called by qwik-loader to schedule a QRL. It has to be synchronous.
@@ -14,14 +15,13 @@ export const queueQRL = (...args: unknown[]) => {
1415
// This will already check container
1516
const [runQrl] = useLexicalScope<[QRLInternal<(...args: unknown[]) => unknown>]>();
1617
const context = getInvokeContext();
17-
const el = context.$element$!;
18-
const containerElement = _getQContainerElement(el) as HTMLElement;
19-
const container = getDomContainer(containerElement);
18+
const hostElement = context.$hostElement$ as ElementVNode;
19+
const container = getDomContainer(hostElement);
2020

2121
const scheduler = container.$scheduler$;
2222
if (!scheduler) {
2323
throw qError(QError.schedulerNotFound);
2424
}
2525

26-
return scheduler(ChoreType.RUN_QRL, el, runQrl, args);
26+
return scheduler(ChoreType.RUN_QRL, hostElement, runQrl, args);
2727
};

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ export const vnode_diff = (
766766
if (qrl) {
767767
const value = container.$scheduler$(
768768
ChoreType.RUN_QRL,
769-
element,
769+
vNode,
770770
qrl as QRLInternal<(...args: unknown[]) => unknown>,
771771
[event, element]
772772
) as unknown;

packages/qwik/src/core/shared/scheduler.ts

+7-9
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ import {
8989
type ElementVNode,
9090
type VirtualVNode,
9191
} from '../client/types';
92-
import { VNodeJournalOpCode, vnode_isVNode, vnode_locate, vnode_setAttr } from '../client/vnode';
92+
import { VNodeJournalOpCode, vnode_isVNode, vnode_setAttr } from '../client/vnode';
9393
import { vnode_diff } from '../client/vnode-diff';
9494
import { triggerEffects, type ComputedSignal, type WrappedSignal } from '../signal/signal';
9595
import { isSignal, type Signal } from '../signal/signal.public';
@@ -99,7 +99,7 @@ import { runResource, type ResourceDescriptor } from '../use/use-resource';
9999
import { Task, TaskFlags, cleanupTask, runTask, type TaskFn } from '../use/use-task';
100100
import { executeComponent } from './component-execution';
101101
import type { OnRenderFn } from './component.public';
102-
import { assertEqual } from './error/assert';
102+
import { assertEqual, assertFalse } from './error/assert';
103103
import type { Props } from './jsx/jsx-runtime';
104104
import type { JSXOutput } from './jsx/types/jsx-node';
105105
import { type QRLInternal } from './qrl/qrl-class';
@@ -214,7 +214,7 @@ export const createScheduler = (
214214
): ValueOrPromise<void>;
215215
function schedule(
216216
type: ChoreType.RUN_QRL,
217-
host: Element,
217+
host: HostElement,
218218
target: QRLInternal<(...args: unknown[]) => unknown>,
219219
args: unknown[]
220220
): ValueOrPromise<void>;
@@ -240,7 +240,7 @@ export const createScheduler = (
240240
///// IMPLEMENTATION /////
241241
function schedule(
242242
type: ChoreType,
243-
hostOrTask: HostElement | Task | Element | null = null,
243+
hostOrTask: HostElement | Task | null = null,
244244
targetOrQrl: ChoreTarget | string | null = null,
245245
payload: any = null
246246
): ValueOrPromise<any> {
@@ -436,11 +436,7 @@ export const createScheduler = (
436436
qrlRuns.splice(qrlRuns.indexOf(handled), 1);
437437
})
438438
.catch((error) => {
439-
// TODO test this
440-
const host = isDomContainer(container)
441-
? vnode_locate(container.rootVNode, chore.$host$ as any as Element)
442-
: null!;
443-
container.handleError(error, host);
439+
container.handleError(error, chore.$host$);
444440
});
445441
// Don't wait for the promise to resolve
446442
// TODO come up with a better solution, we also want concurrent signal handling with tasks but serial tasks
@@ -578,6 +574,8 @@ export const createScheduler = (
578574
return hostDiff;
579575
}
580576
} else {
577+
assertFalse(vnode_isVNode(aHost), 'expected aHost to be SSRNode but it is a VNode');
578+
assertFalse(vnode_isVNode(bHost), 'expected bHost to be SSRNode but it is a VNode');
581579
// we are running on the server.
582580
// On server we can't schedule task for a different host!
583581
// Server is SSR, and therefore scheduling for anything but the current host

packages/qwik/src/core/use/use-core.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import type { QRLInternal } from '../shared/qrl/qrl-class';
55
import type { QRL } from '../shared/qrl/qrl.public';
66
import {
77
ComputedEvent,
8-
QContainerSelector,
98
QLocaleAttr,
109
RenderEvent,
1110
ResourceEvent,
@@ -16,9 +15,9 @@ import { seal } from '../shared/utils/qdev';
1615
import { isArray } from '../shared/utils/types';
1716
import { setLocale } from './use-locale';
1817
import type { Container, HostElement } from '../shared/types';
19-
import { vnode_getNode, vnode_isElementVNode, vnode_isVNode } from '../client/vnode';
20-
import { _getQContainerElement } from '../client/dom-container';
21-
import type { ContainerElement } from '../client/types';
18+
import { vnode_getNode, vnode_isElementVNode, vnode_isVNode, vnode_locate } from '../client/vnode';
19+
import { _getQContainerElement, getDomContainer } from '../client/dom-container';
20+
import { type ContainerElement } from '../client/types';
2221
import {
2322
WrappedSignal,
2423
type EffectPropData,
@@ -175,10 +174,12 @@ export const waitAndRun = (ctx: RenderInvokeContext, callback: () => unknown) =>
175174
};
176175

177176
export const newInvokeContextFromTuple = ([element, event, url]: InvokeTuple) => {
178-
const container = element.closest(QContainerSelector);
177+
const domContainer = getDomContainer(element);
178+
const container = domContainer.element;
179+
const vNode = container ? vnode_locate(domContainer.rootVNode, element) : undefined;
179180
const locale = container?.getAttribute(QLocaleAttr) || undefined;
180181
locale && setLocale(locale);
181-
return newInvokeContext(locale, undefined, element, event, url);
182+
return newInvokeContext(locale, vNode, element, event, url);
182183
};
183184

184185
// TODO how about putting url and locale (and event/custom?) in to a "static" object

packages/qwik/src/core/use/use-task.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,11 @@ export const useTaskQrl = (qrl: QRL<TaskFn>): void => {
156156
// deleted and we need to be able to release the task subscriptions.
157157
set(task);
158158
const container = iCtx.$container$;
159-
container.$scheduler$(ChoreType.TASK, task)?.catch(() => {});
160-
161-
// const result = runTask(task, container, iCtx.$hostElement$);
162-
// if (isPromise(result)) {
163-
// throw result;
164-
// }
159+
const promise = container.$scheduler$(ChoreType.TASK, task);
160+
if (isPromise(promise)) {
161+
// TODO: should we handle this differently?
162+
promise.catch(() => {});
163+
}
165164
};
166165

167166
export const runTask = (

packages/qwik/src/testing/element-fixture.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { getDomContainer } from '@qwik.dev/core';
22
import { vi } from 'vitest';
33
import { assertDefined } from '../core/shared/error/assert';
4-
import type { QRLInternal } from '../core/shared/qrl/qrl-class';
54
import type { QElement, QwikLoaderEventScope } from '../core/shared/types';
65
import { fromCamelToKebabCase } from '../core/shared/utils/event-names';
76
import { QFuncsPrefix, QInstanceAttr } from '../core/shared/utils/markers';
@@ -142,7 +141,6 @@ export const dispatch = async (
142141
const preventAttributeName =
143142
PREVENT_DEFAULT + (isDocumentOrWindow ? event.type.substring(1) : event.type);
144143
const stopPropagationName = STOP_PROPAGATION + event.type;
145-
const collectListeners: { element: Element; qrl: QRLInternal }[] = [];
146144
while (element) {
147145
const preventDefault = element.hasAttribute(preventAttributeName);
148146
const stopPropagation = element.hasAttribute(stopPropagationName);
@@ -159,7 +157,7 @@ export const dispatch = async (
159157
} else if (element.hasAttribute(attrName)) {
160158
const container = getDomContainer(element as HTMLElement);
161159
const qrl = element.getAttribute(attrName)!;
162-
const ctx = newInvokeContextFromTuple([element!, event]);
160+
const ctx = newInvokeContextFromTuple([element, event]);
163161
try {
164162
await Promise.all(
165163
qrl
@@ -177,10 +175,6 @@ export const dispatch = async (
177175
}
178176
element = element.parentElement;
179177
}
180-
for (let i = 0; i < collectListeners.length; i++) {
181-
const { element, qrl } = collectListeners[i];
182-
await (qrl.getFn([element, event], () => element.isConnected) as Function)(event, element);
183-
}
184178
};
185179

186180
export async function advanceToNextTimerAndFlush() {

0 commit comments

Comments
 (0)