Skip to content

Commit 3a62e98

Browse files
committed
wip
1 parent 141d15c commit 3a62e98

File tree

9 files changed

+270
-201
lines changed

9 files changed

+270
-201
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export const executeComponent = (
6464
}
6565
if (isQrl(componentQRL)) {
6666
props = props || container.getHostProp(renderHost, ELEMENT_PROPS) || EMPTY_OBJ;
67-
if (props && props.children) {
67+
if (props.children) {
6868
delete props.children;
6969
}
7070
componentFn = componentQRL.getFn(iCtx);

packages/qwik/src/core/shared/qrl/qrl-class.ts

+50-36
Original file line numberDiff line numberDiff line change
@@ -104,28 +104,33 @@ export const createQRL = <TYPE>(
104104
beforeFn?: () => void | boolean
105105
) {
106106
// Note that we bind the current `this`
107-
return (...args: QrlArgs<TYPE>): QrlReturn<TYPE> =>
108-
maybeThen(resolveLazy(), (fn) => {
109-
if (!isFunction(fn)) {
110-
throw qError(QError.qrlIsNotFunction);
111-
}
112-
if (beforeFn && beforeFn() === false) {
113-
return;
114-
}
115-
const context = createOrReuseInvocationContext(currentCtx);
116-
const prevQrl = context.$qrl$;
117-
const prevEvent = context.$event$;
118-
// Note that we set the qrl here instead of in wrapFn because
119-
// it is possible we're called on a copied qrl
120-
context.$qrl$ = qrl;
121-
context.$event$ ||= this as Event;
122-
try {
123-
return invoke.call(this, context, fn, ...(args as Parameters<typeof fn>));
124-
} finally {
125-
context.$qrl$ = prevQrl;
126-
context.$event$ = prevEvent;
127-
}
128-
});
107+
const bound = (...args: QrlArgs<TYPE>): ValueOrPromise<QrlReturn<TYPE> | undefined> => {
108+
if (!qrl.resolved) {
109+
return qrl.resolve().then((fn) => {
110+
if (!isFunction(fn)) {
111+
throw qError(QError.qrlIsNotFunction);
112+
}
113+
return bound(...args);
114+
});
115+
}
116+
if (beforeFn && beforeFn() === false) {
117+
return;
118+
}
119+
const context = createOrReuseInvocationContext(currentCtx);
120+
const prevQrl = context.$qrl$;
121+
const prevEvent = context.$event$;
122+
// Note that we set the qrl here instead of in wrapFn because
123+
// it is possible we're called on a copied qrl
124+
context.$qrl$ = qrl;
125+
context.$event$ ||= this as Event;
126+
try {
127+
return invoke.call(this, context, symbolRef as any, ...(args as any));
128+
} finally {
129+
context.$qrl$ = prevQrl;
130+
context.$event$ = prevEvent;
131+
}
132+
};
133+
return bound;
129134
}
130135

131136
const resolveLazy = (containerEl?: Element): ValueOrPromise<TYPE> => {
@@ -138,18 +143,25 @@ export const createQRL = <TYPE>(
138143
return fn;
139144
}
140145
return function (this: unknown, ...args: QrlArgs<TYPE>) {
141-
const context = tryGetInvokeContext() || newInvokeContext();
142-
const prevQrl = context.$qrl$;
143-
const prevEvent = context.$event$;
146+
let context = tryGetInvokeContext();
147+
// use the given qrl if it is the right one
148+
if (context) {
149+
// TODO check if this is necessary in production
150+
if ((context.$qrl$ as QRLInternal)?.$symbol$ === qrl.$symbol$) {
151+
return fn.apply(this, args);
152+
}
153+
const prevQrl = context.$qrl$;
154+
context.$qrl$ = qrl;
155+
try {
156+
return fn.apply(this, args);
157+
} finally {
158+
context.$qrl$ = prevQrl;
159+
}
160+
}
161+
context = newInvokeContext();
144162
context.$qrl$ = qrl;
145-
// TODO do we use this?
146163
context.$event$ = this as Event;
147-
try {
148-
return invoke.call(this, context, fn as any, ...args);
149-
} finally {
150-
context.$qrl$ = prevQrl;
151-
context.$event$ = prevEvent;
152-
}
164+
return invoke.call(this, context, fn as any, ...args);
153165
} as TYPE;
154166
};
155167

@@ -174,10 +186,12 @@ export const createQRL = <TYPE>(
174186
const start = now();
175187
const ctx = tryGetInvokeContext();
176188
if (symbolFn !== null) {
177-
symbolRef = symbolFn().then((module) => (qrl.resolved = symbolRef = wrapFn(module[symbol])));
189+
symbolRef = symbolFn().then(
190+
(module) => (qrl.resolved = wrapFn((symbolRef = module[symbol])))
191+
);
178192
} else {
179193
const imported = getPlatform().importSymbol(_containerEl, chunk, symbol);
180-
symbolRef = maybeThen(imported, (ref) => (qrl.resolved = symbolRef = wrapFn(ref)));
194+
symbolRef = maybeThen(imported, (ref) => (qrl.resolved = wrapFn((symbolRef = ref))));
181195
}
182196
if (typeof symbolRef === 'object' && isPromise(symbolRef)) {
183197
symbolRef.then(
@@ -223,8 +237,8 @@ export const createQRL = <TYPE>(
223237
resolved: undefined,
224238
});
225239
if (symbolRef) {
226-
// Replace symbolRef with (a promise for) the value or wrapped function
227-
symbolRef = maybeThen(symbolRef, (resolved) => (qrl.resolved = symbolRef = wrapFn(resolved)));
240+
// Unwrap any promises
241+
symbolRef = maybeThen(symbolRef, (resolved) => (qrl.resolved = wrapFn((symbolRef = resolved))));
228242
}
229243

230244
if (isDev) {

0 commit comments

Comments
 (0)