{_rawProps.foo}{fn()}{20}
@@ -156,10 +156,10 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma
*/
============================= test.tsx_Bar_component_1_0xSyNSnVu3k.jsx (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const Bar_component_1_0xSyNSnVu3k = ()=>{
- const _rawProps = _captures[0];
+ let _rawProps = _capturesObj._[0];
return
{_rawProps.bar}
;
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3542.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3542.snap
index ae02acad1ec..3db03f3523d 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3542.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3542.snap
@@ -24,14 +24,14 @@ export const AtomStatus = component$(({ctx,atom})=>{
============================= test.jsx ==
import { componentQrl } from "@qwik.dev/core";
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import { _noopQrl } from "@qwik.dev/core";
//
const q_AtomStatus_component_hdwpoUtydSA = /*#__PURE__*/ _noopQrl("AtomStatus_component_hdwpoUtydSA");
const q_AtomStatus_component_span_q_e_click_0yqKAycyBF0 = /*#__PURE__*/ _noopQrl("AtomStatus_component_span_q_e_click_0yqKAycyBF0");
//
q_AtomStatus_component_span_q_e_click_0yqKAycyBF0.s((ev)=>{
- const _rawProps = _captures[0];
+ let _rawProps = _capturesObj._[0];
return atomStatusClick(_rawProps.ctx, ev, [
_rawProps.atom
]);
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__example_props_optimization.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__example_props_optimization.snap
index df660f6c882..50f1e846905 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__example_props_optimization.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__example_props_optimization.snap
@@ -52,7 +52,7 @@ export const NoWorks3 = component$(({count, stuff = hola()}) => {
import { _restProps } from "@qwik.dev/core";
import { componentQrl } from "@qwik.dev/core";
import { useTaskQrl } from "@qwik.dev/core";
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import { _noopQrl } from "@qwik.dev/core";
import { _fnSignal } from "@qwik.dev/core";
import { _wrapProp } from "@qwik.dev/core";
@@ -76,7 +76,7 @@ const q_Works_component_t45qL4vNGv0 = /*#__PURE__*/ _noopQrl("Works_component_t4
const q_Works_component_useTask_pjo5U5Ikll0 = /*#__PURE__*/ _noopQrl("Works_component_useTask_pjo5U5Ikll0");
//
q_Works_component_useTask_pjo5U5Ikll0.s(({ track })=>{
- const _rawProps = _captures[0], rest = _captures[1];
+ let _rawProps = _capturesObj._[0], rest = _capturesObj._[1];
track(()=>_rawProps.count);
console.log(_rawProps.count, rest, _rawProps.stuff, _rawProps.some ?? 3, _rawProps.stuffDefault ?? 123);
});
@@ -108,7 +108,7 @@ q_Works_component_t45qL4vNGv0.s((_rawProps)=>{
}, _wrapProp(_rawProps, "count"), 0, "u6_0");
});
q_NoWorks2_component_useTask_lXiqwbxxjq0.s(({ track })=>{
- const count = _captures[0];
+ let count = _capturesObj._[0];
track(()=>count);
console.log(count);
});
@@ -122,7 +122,7 @@ q_NoWorks2_component_JPD9t2HyEKg.s(({ count, stuff: { hey } })=>{
}, null, count, 1, "u6_1");
});
q_NoWorks3_component_useTask_3cQGU0s1VwU.s(({ track })=>{
- const count = _captures[0];
+ let count = _capturesObj._[0];
track(()=>count);
console.log(count);
});
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__example_qwik_router_client.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__example_qwik_router_client.snap
index 7d751eb715c..9c59c2b1c78 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__example_qwik_router_client.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__example_qwik_router_client.snap
@@ -1932,11 +1932,11 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/router/ind
*/
============================= ../node_modules/@qwik.dev/router/index.qwik.mjs_Link_component_useVisibleTask_6K6z063D0C4.mjs (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import { isDev } from "@qwik.dev/core";
//
export const Link_component_useVisibleTask_6K6z063D0C4 = ({ track })=>{
- const anchorRef = _captures[0], handlePrefetch = _captures[1], linkProps = _captures[2], loc = _captures[3];
+ let anchorRef = _capturesObj._[0], handlePrefetch = _capturesObj._[1], linkProps = _capturesObj._[2], loc = _capturesObj._[3];
track(()=>loc.url.pathname);
const handler = linkProps.onQVisible$;
if (handler) {
@@ -2601,10 +2601,10 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/router/ind
*/
============================= ../node_modules/@qwik.dev/router/index.qwik.mjs_ErrorBoundary_component_useOnWindow_GYhPAutMLGk.mjs (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const ErrorBoundary_component_useOnWindow_GYhPAutMLGk = (e)=>{
- const store = _captures[0];
+ let store = _capturesObj._[0];
store.error = e.detail.error;
};
@@ -2793,10 +2793,10 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/router/ind
*/
============================= ../node_modules/@qwik.dev/router/index.qwik.mjs_Form_form_q_e_submit_iIfbMzzXpIA.mjs (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const Form_form_q_e_submit_iIfbMzzXpIA = (evt)=>{
- const action = _captures[0];
+ let action = _capturesObj._[0];
if (!action.submitted) return action.submit(evt);
};
@@ -3159,7 +3159,7 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/router/ind
*/
============================= ../node_modules/@qwik.dev/router/index.qwik.mjs_useQwikRouter_useTask_omhKiQfdzZU.mjs (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import { QWIK_ROUTER_SCROLLER } from "./index.qwik.mjs";
import { _auto_getScrollHistory as getScrollHistory } from "./index.qwik.mjs";
import { _auto_restoreScroll as restoreScroll } from "./index.qwik.mjs";
@@ -3273,7 +3273,7 @@ const startViewTransition = (params)=>{
} else params.update?.();
};
export const useQwikRouter_useTask_omhKiQfdzZU = ({ track })=>{
- const actionState = _captures[0], content = _captures[1], contentInternal = _captures[2], documentHead = _captures[3], env = _captures[4], goto = _captures[5], loaderState = _captures[6], loadersObject = _captures[7], navResolver = _captures[8], props = _captures[9], routeInternal = _captures[10], routeLocation = _captures[11], routeLocationTarget = _captures[12], serverHead = _captures[13];
+ let actionState = _capturesObj._[0], content = _capturesObj._[1], contentInternal = _capturesObj._[2], documentHead = _capturesObj._[3], env = _capturesObj._[4], goto = _capturesObj._[5], loaderState = _capturesObj._[6], loadersObject = _capturesObj._[7], navResolver = _capturesObj._[8], props = _capturesObj._[9], routeInternal = _capturesObj._[10], routeLocation = _capturesObj._[11], routeLocationTarget = _capturesObj._[12], serverHead = _capturesObj._[13];
async function run() {
const navigation = track(routeInternal);
const action = track(actionState);
@@ -3552,10 +3552,10 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/router/ind
*/
============================= ../node_modules/@qwik.dev/router/index.qwik.mjs_usePreventNavigateQrl_useVisibleTask_no0bm2fybZo.mjs (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const usePreventNavigateQrl_useVisibleTask_no0bm2fybZo = ()=>{
- const fn = _captures[0], registerPreventNav = _captures[1];
+ let fn = _capturesObj._[0], registerPreventNav = _capturesObj._[1];
return registerPreventNav(fn);
};
@@ -3587,10 +3587,10 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/router/ind
*/
============================= ../node_modules/@qwik.dev/router/index.qwik.mjs_useQwikMockRouter_useTask_oml2hW1aK6I.mjs (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const useQwikMockRouter_useTask_oml2hW1aK6I = async ({ track })=>{
- const actionState = _captures[0], actionsMocks = _captures[1];
+ let actionState = _capturesObj._[0], actionsMocks = _capturesObj._[1];
const action = track(actionState);
if (!action?.resolve) return;
const mock = actionsMocks?.[action.id];
@@ -3631,7 +3631,7 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/router/ind
*/
============================= ../node_modules/@qwik.dev/router/index.qwik.mjs_serverQrl_RA3PmZ4Oyak.mjs (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import { _auto_useQwikRouterEnv as useQwikRouterEnv } from "./index.qwik.mjs";
import { j as QDATA_KEY } from "./chunks/routing.qwik.mjs";
import { f as QFN_KEY } from "./chunks/routing.qwik.mjs";
@@ -3665,7 +3665,7 @@ const deserializeStream = async function*(stream, abortSignal) {
}
};
export const serverQrl_RA3PmZ4Oyak = async function(...args) {
- const fetchOptions = _captures[0], headers = _captures[1], method = _captures[2], origin = _captures[3], qrl = _captures[4];
+ let fetchOptions = _capturesObj._[0], headers = _capturesObj._[1], method = _capturesObj._[2], origin = _capturesObj._[3], qrl = _capturesObj._[4];
const abortSignal = args.length > 0 && args[0] instanceof AbortSignal ? args.shift() : void 0;
if (isServer) {
let requestEvent = _asyncRequestStore?.getStore();
@@ -3774,10 +3774,10 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/router/ind
*/
============================= ../node_modules/@qwik.dev/router/index.qwik.mjs_Link_component_handleClientSideNavigation_rMfmL7bFMLU.mjs (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const Link_component_handleClientSideNavigation_rMfmL7bFMLU = (event, elm)=>{
- const nav = _captures[0], reload = _captures[1], replaceState = _captures[2], scroll = _captures[3];
+ let nav = _capturesObj._[0], reload = _capturesObj._[1], replaceState = _capturesObj._[2], scroll = _capturesObj._[3];
if (event.defaultPrevented) {
if (elm.href) {
elm.setAttribute('aria-pressed', 'true');
@@ -3929,10 +3929,10 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/router/ind
*/
============================= ../node_modules/@qwik.dev/router/index.qwik.mjs_GetForm_component_form_q_e_submit_D0PAP3eJ0Ng.mjs (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const GetForm_component_form_q_e_submit_D0PAP3eJ0Ng = async (_evt, form)=>{
- const nav = _captures[0];
+ let nav = _capturesObj._[0];
const formData = new FormData(form);
const params = new URLSearchParams();
formData.forEach((value, key)=>{
@@ -3975,7 +3975,7 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/router/ind
*/
============================= ../node_modules/@qwik.dev/router/index.qwik.mjs_useQwikRouter_goto_OSnb99dm7Ow.mjs (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import { QWIK_CITY_SCROLLER } from "./index.qwik.mjs";
import { QWIK_ROUTER_SCROLLER } from "./index.qwik.mjs";
import { _auto_getScrollHistory as getScrollHistory } from "./index.qwik.mjs";
@@ -3992,7 +3992,7 @@ import * as qwikRouterConfig from "@qwik-router-config";
import { t as toUrl } from "./chunks/routing.qwik.mjs";
//
export const useQwikRouter_goto_OSnb99dm7Ow = async (path, opt)=>{
- const actionState = _captures[0], navResolver = _captures[1], routeInternal = _captures[2], routeLocation = _captures[3];
+ let actionState = _capturesObj._[0], navResolver = _capturesObj._[1], routeInternal = _capturesObj._[2], routeLocation = _capturesObj._[3];
const { type = 'link', forceReload = path === void 0, // Hack for nav() because this API is already set.
replaceState = false, scroll = true } = typeof opt === 'object' ? opt : {
forceReload: opt
@@ -4134,12 +4134,12 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/router/ind
*/
============================= ../node_modules/@qwik.dev/router/index.qwik.mjs_routeActionQrl_action_submit_JY3C42B1B08.mjs (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import { isServer } from "@qwik.dev/core";
import { noSerialize } from "@qwik.dev/core";
//
export const routeActionQrl_action_submit_JY3C42B1B08 = (input = {})=>{
- const currentAction = _captures[0], id = _captures[1], loc = _captures[2], state = _captures[3];
+ let currentAction = _capturesObj._[0], id = _capturesObj._[1], loc = _capturesObj._[2], state = _capturesObj._[3];
if (isServer) throw new Error(`Actions can not be invoked within the server during SSR.
Action.run() can only be called on the browser, for example when a user clicks a button, or submits a form.`);
let data;
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__example_renamed_exports.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__example_renamed_exports.snap
index 0b4fe7dd922..d14445f2d29 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__example_renamed_exports.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__example_renamed_exports.snap
@@ -29,12 +29,12 @@ export const App = /*#__PURE__*/ componentQrl(q_App_Component_NuXFTHRjvXE);
Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AAGA,OAAO,MAAM,oBAAM,0CAMhB\"}")
============================= test.tsx_App_Component_1_A08tXHb9pEk.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import { _jsxSorted } from "@qwik.dev/core";
import { _wrapProp } from "@qwik.dev/core";
//
export const App_Component_1_A08tXHb9pEk = ()=>{
- const state = _captures[0];
+ let state = _capturesObj._[0];
return /*#__PURE__*/ _jsxSorted("div", null, null, _wrapProp(state, "thing"), 3, "u6_0");
};
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__example_strip_client_code.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__example_strip_client_code.snap
index 5f3ba0b53a1..2ba3102c636 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__example_strip_client_code.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__example_strip_client_code.snap
@@ -133,7 +133,7 @@ import { useClientMountQrl } from "@qwik.dev/core";
import { _noopQrl } from "@qwik.dev/core";
import { useTaskQrl } from "@qwik.dev/core";
import { _wrapProp } from "@qwik.dev/core";
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import { _jsxSorted } from "@qwik.dev/core";
import { useStore } from '@qwik.dev/core';
//
@@ -150,7 +150,7 @@ q_Parent_component_useTask_ngmvcygWux8.s(()=>{
});
q_Parent_component_div_Div_onClick_kgowuto5dR0.s(()=>console.log('keep'));
q_Parent_component_div_Div_render_CkMybN6xzQk.s(()=>{
- const state = _captures[0];
+ let state = _capturesObj._[0];
return state.text;
});
q_Parent_component_t6Wy3C0Q0XM.s(()=>{
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__example_strip_server_code.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__example_strip_server_code.snap
index 6be3006a7cf..9dcb9eb42c0 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__example_strip_server_code.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__example_strip_server_code.snap
@@ -102,12 +102,12 @@ Some("{\"version\":3,\"sources\":[],\"names\":[],\"mappings\":\"\"}")
*/
============================= test.tsx_Parent_component_useTask_gDH1EtUWqBU.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import mongo from "mongodb";
import redis from "redis";
//
export const s_gDH1EtUWqBU = async ()=>{
- const state = _captures[0];
+ let state = _capturesObj._[0];
state.text = await mongo.users();
redis.set(state.text);
};
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__example_use_client_effect.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__example_use_client_effect.snap
index 81639a70b62..69ed63fb219 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__example_use_client_effect.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__example_use_client_effect.snap
@@ -33,10 +33,10 @@ export const Child = component$(() => {
============================= test.tsx_Child_component_useBrowserVisibleTask_0IGFPOyJmQA.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const Child_component_useBrowserVisibleTask_0IGFPOyJmQA = ()=>{
- const state = _captures[0];
+ let state = _capturesObj._[0];
const timer = setInterval(()=>{
state.count++;
}, 1000);
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__example_use_server_mount.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__example_use_server_mount.snap
index 09b1c06b78b..13272b63323 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__example_use_server_mount.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__example_use_server_mount.snap
@@ -47,12 +47,12 @@ export const Child = component$(() => {
============================= test.tsx_Parent_component_useTask_gDH1EtUWqBU.js ==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import mongo from "mongodb";
import redis from "redis";
//
export const Parent_component_useTask_gDH1EtUWqBU = async ()=>{
- const state = _captures[0];
+ let state = _capturesObj._[0];
state.text = await mongo.users();
redis.set(state.text);
};
@@ -97,11 +97,11 @@ export const Child = /*#__PURE__*/ componentQrl(q_Child_component_9GyF01GDKqw);
Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;AAKA,OAAO,MAAM,uBAAS,6CAgBnB;AAEH,OAAO,MAAM,sBAAQ,4CAelB\"}")
============================= test.tsx_Child_component_useTask_Oh4n7ZeqJkU.js ==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import mongo from "mongodb";
//
export const Child_component_useTask_Oh4n7ZeqJkU = async ()=>{
- const state = _captures[0];
+ let state = _capturesObj._[0];
state.text = await mongo.users();
};
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__fun_with_scopes.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__fun_with_scopes.snap
index 02eb8426b56..e10ee6c0c26 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__fun_with_scopes.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__fun_with_scopes.snap
@@ -1,6 +1,6 @@
---
source: packages/optimizer/core/src/test.rs
-assertion_line: 6512
+assertion_line: 6765
expression: output
---
==INPUT==
@@ -71,7 +71,7 @@ import { _jsxSorted } from "@qwik.dev/core";
import { _noopQrl } from "@qwik.dev/core";
import { _getVarProps } from "@qwik.dev/core";
import { _getConstProps } from "@qwik.dev/core";
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import { _jsxSplit } from "@qwik.dev/core";
import { useStylesScopedQrl } from "@qwik.dev/core";
import { _fnSignal } from "@qwik.dev/core";
@@ -111,7 +111,7 @@ export const rawFn = (event, element)=>{
};
q_Field_Lifecycle_children_1_Bk3lkC2Z00U.s(rawFn);
const Field_Lifecycle_children_4aZ3omfUAIs = (element)=>{
- const field1 = _captures[0];
+ let field1 = _capturesObj._[0];
field1.internal.elements.push(element);
};
q_Field_Lifecycle_children_4aZ3omfUAIs.s(Field_Lifecycle_children_4aZ3omfUAIs);
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__issue_150.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__issue_150.snap
index 4ffc8aaa968..2810b56a7d3 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__issue_150.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__issue_150.snap
@@ -66,12 +66,12 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma
*/
============================= test.tsx_Greeter_component_1_krCndSwhX4U.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import { _jsxSorted } from "@qwik.dev/core";
import { hola } from "sdfds";
//
export const Greeter_component_1_krCndSwhX4U = ()=>{
- const stuff = _captures[0];
+ let stuff = _capturesObj._[0];
return /*#__PURE__*/ _jsxSorted("div", {
class: {
'foo': true,
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__should_convert_rest_props.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__should_convert_rest_props.snap
index ba66d371227..83371236bef 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__should_convert_rest_props.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__should_convert_rest_props.snap
@@ -29,10 +29,10 @@ export default /*#__PURE__*/ componentQrl(q_test_component_LUXeXe0DQrg);
Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AAGE,6BAAe,2CAMb\"}")
============================= test.tsx_test_component_useTask_jewzFYh3XmQ.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const test_component_useTask_jewzFYh3XmQ = ()=>{
- const props = _captures[0];
+ let props = _capturesObj._[0];
props.checked;
};
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_multiple_qrls_with_item_and_index_and_capture_ref.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_multiple_qrls_with_item_and_index_and_capture_ref.snap
index b92f271ace4..7b76966deb3 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_multiple_qrls_with_item_and_index_and_capture_ref.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_multiple_qrls_with_item_and_index_and_capture_ref.snap
@@ -1,6 +1,6 @@
---
source: packages/optimizer/core/src/test.rs
-assertion_line: 5026
+assertion_line: 5212
expression: output
---
==INPUT==
@@ -35,10 +35,10 @@ export default /*#__PURE__*/ componentQrl(q_test_component_LUXeXe0DQrg);
Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AAGA,6BAAe,2CAWZ\"}")
============================= test.tsx_test_component_div_div_q_e_hover_2iHUE4xtgo8.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const test_component_div_div_q_e_hover_2iHUE4xtgo8 = (_, _1, _2, index)=>{
- const bar = _captures[0];
+ let bar = _capturesObj._[0];
return console.log(bar.value, index);
};
@@ -75,10 +75,10 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma
*/
============================= test.tsx_test_component_div_div_q_e_click_Mc600uqO6ps.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const test_component_div_div_q_e_click_Mc600uqO6ps = (_, _1, item)=>{
- const foo = _captures[0];
+ let foo = _capturesObj._[0];
return console.log(item, foo.value);
};
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_single_qrl.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_single_qrl.snap
index a639ab28344..cdc10c27152 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_single_qrl.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_single_qrl.snap
@@ -1,6 +1,6 @@
---
source: packages/optimizer/core/src/test.rs
-assertion_line: 4847
+assertion_line: 5033
expression: output
---
==INPUT==
@@ -64,10 +64,10 @@ export const App = /*#__PURE__*/ componentQrl(q_App_component_ckEPmXZlub0);
Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AAEA,OAAO,MAAM,oBAAM,0CA0CZ\"}")
============================= test.tsx_App_component_div_tr_td_a_q_e_click_1_40fnSAlYI48.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const App_component_div_tr_td_a_q_e_click_1_40fnSAlYI48 = (_, _1, row)=>{
- const data = _captures[0];
+ let data = _capturesObj._[0];
const dataValue = untrack(()=>data.value);
data.value = dataValue.toSpliced(dataValue.findIndex((d)=>d.value.id === row.value.id), 1);
};
@@ -184,10 +184,10 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma
*/
============================= test.tsx_App_component_div_tr_td_a_q_e_click_lgbZkJXyLtg.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const App_component_div_tr_td_a_q_e_click_lgbZkJXyLtg = (_, _1, row)=>{
- const selectedItem = _captures[0];
+ let selectedItem = _capturesObj._[0];
if (selectedItem.value) selectedItem.value.selected.value = false;
selectedItem.value = row.value;
row.value.selected.value = true;
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_single_qrl_2.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_single_qrl_2.snap
index 7b2e9b260ad..a4da0365b06 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_single_qrl_2.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_single_qrl_2.snap
@@ -1,6 +1,6 @@
---
source: packages/optimizer/core/src/test.rs
-assertion_line: 4903
+assertion_line: 5089
expression: output
---
==INPUT==
@@ -140,10 +140,10 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma
*/
============================= test.tsx_Parent_component_div_button_q_e_click_1_rAeuW6OvuXM.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const Parent_component_div_button_q_e_click_1_rAeuW6OvuXM = (_, _1, item)=>{
- const cart = _captures[0];
+ let cart = _capturesObj._[0];
cart.push(item);
};
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_single_qrl_with_index.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_single_qrl_with_index.snap
index e3b53fdce85..36eed764783 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_single_qrl_with_index.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__should_extract_single_qrl_with_index.snap
@@ -1,6 +1,6 @@
---
source: packages/optimizer/core/src/test.rs
-assertion_line: 4944
+assertion_line: 5130
expression: output
---
==INPUT==
@@ -66,10 +66,10 @@ export const App = /*#__PURE__*/ componentQrl(q_App_component_ckEPmXZlub0);
Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AAEA,OAAO,MAAM,oBAAM,0CA4CZ\"}")
============================= test.tsx_App_component_div_tr_td_a_q_e_click_1_40fnSAlYI48.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const App_component_div_tr_td_a_q_e_click_1_40fnSAlYI48 = (_, _1, row)=>{
- const data = _captures[0];
+ let data = _capturesObj._[0];
const dataValue = untrack(()=>data.value);
data.value = dataValue.toSpliced(dataValue.findIndex((d)=>d.value.id === row.value.id), 1);
};
@@ -191,10 +191,10 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma
*/
============================= test.tsx_App_component_div_tr_td_a_q_e_click_lgbZkJXyLtg.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const App_component_div_tr_td_a_q_e_click_lgbZkJXyLtg = (_, _1, row, idx)=>{
- const clickedIndex = _captures[0], selectedItem = _captures[1];
+ let clickedIndex = _capturesObj._[0], selectedItem = _capturesObj._[1];
if (selectedItem.value) selectedItem.value.selected.value = false;
selectedItem.value = row.value;
row.value.selected.value = true;
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__should_mark_props_as_var_props_for_inner_cmp.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__should_mark_props_as_var_props_for_inner_cmp.snap
index 493ab645509..b45ad217ebe 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__should_mark_props_as_var_props_for_inner_cmp.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__should_mark_props_as_var_props_for_inner_cmp.snap
@@ -106,11 +106,11 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma
*/
============================= test.tsx_ModelImg_component_imgLoc_useResource_Ogi9hEJvtmI.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import { serverImg } from "~/routes/(authenticated)/layout";
//
export const ModelImg_component_imgLoc_useResource_Ogi9hEJvtmI = async (_rawProps)=>{
- const props = _captures[0];
+ let props = _capturesObj._[0];
_rawProps.track(()=>props.store.model);
return await serverImg('some.png');
};
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__should_not_generate_conflicting_props_identifiers.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__should_not_generate_conflicting_props_identifiers.snap
index 5356e4630b4..c1a14e103f7 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__should_not_generate_conflicting_props_identifiers.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__should_not_generate_conflicting_props_identifiers.snap
@@ -23,7 +23,7 @@ expression: output
import { _restProps } from "@qwik.dev/core";
import { componentQrl } from "@qwik.dev/core";
import { useComputedQrl } from "@qwik.dev/core";
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
import { _noopQrl } from "@qwik.dev/core";
import { useTaskQrl } from "@qwik.dev/core";
//
@@ -32,12 +32,12 @@ const q_test_component_useComputed_PYU291PvidQ = /*#__PURE__*/ _noopQrl("test_co
const q_test_component_useTask_jewzFYh3XmQ = /*#__PURE__*/ _noopQrl("test_component_useTask_jewzFYh3XmQ");
//
const test_component_useComputed_PYU291PvidQ = ()=>{
- const _rawProps = _captures[0];
+ let _rawProps = _capturesObj._[0];
return _rawProps.color;
};
q_test_component_useComputed_PYU291PvidQ.s(test_component_useComputed_PYU291PvidQ);
const test_component_useTask_jewzFYh3XmQ = ()=>{
- const props = _captures[0];
+ let props = _capturesObj._[0];
props.checked;
};
q_test_component_useTask_jewzFYh3XmQ.s(test_component_useTask_jewzFYh3XmQ);
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__should_preserve_non_ident_explicit_captures.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__should_preserve_non_ident_explicit_captures.snap
index e45dfdf56fc..743a201be81 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__should_preserve_non_ident_explicit_captures.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__should_preserve_non_ident_explicit_captures.snap
@@ -1,36 +1,36 @@
---
source: packages/optimizer/core/src/test.rs
-assertion_line: 7250
+assertion_line: 7607
expression: output
---
==INPUT==
-import { _captures, inlinedQrl } from '@qwik.dev/core';
+import { _capturesObj, inlinedQrl } from '@qwik.dev/core';
const left = 1;
const right = 2;
export const task = inlinedQrl(() => {
- const left = _captures[0];
- const middle = _captures[1];
- const right = _captures[2];
+ const left = _capturesObj._[0];
+ const middle = _capturesObj._[1];
+ const right = _capturesObj._[2];
return middle ? left : right;
}, 'task', [left, true, right]);
============================= test.tsx_task_task.tsx (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const task = ()=>{
- const left = _captures[0];
- const middle = _captures[1];
- const right = _captures[2];
+ const left = _capturesObj._[0];
+ const middle = _capturesObj._[1];
+ const right = _capturesObj._[2];
return middle ? left : right;
};
-Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;oBAM+B;IAC9B,MAAM,OAAO,SAAS,CAAC,EAAE;IACzB,MAAM,SAAS,SAAS,CAAC,EAAE;IAC3B,MAAM,QAAQ,SAAS,CAAC,EAAE;IAC1B,OAAO,SAAS,OAAO;AACxB\"}")
+Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;oBAM+B;IAC9B,MAAM,OAAO,aAAa,CAAC,CAAC,EAAE;IAC9B,MAAM,SAAS,aAAa,CAAC,CAAC,EAAE;IAChC,MAAM,QAAQ,aAAa,CAAC,CAAC,EAAE;IAC/B,OAAO,SAAS,OAAO;AACxB\"}")
/*
{
"origin": "test.tsx",
@@ -46,8 +46,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma
"ctxName": "task",
"captures": true,
"loc": [
- 124,
- 251
+ 127,
+ 269
],
"captureNames": [
"left",
@@ -61,8 +61,8 @@ import { qrlDEV } from "@qwik.dev/core";
//
const q_task = /*#__PURE__*/ qrlDEV(()=>import("./test.tsx_task_task"), "task", {
file: "/user/qwik/src/test.tsx",
- lo: 124,
- hi: 251,
+ lo: 127,
+ hi: 269,
displayName: "test.tsx_task"
});
//
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_handlers_capturing_cross_scope_in_nested_loops.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_handlers_capturing_cross_scope_in_nested_loops.snap
index e0d62a50822..361f543b967 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_handlers_capturing_cross_scope_in_nested_loops.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_handlers_capturing_cross_scope_in_nested_loops.snap
@@ -1,6 +1,6 @@
---
source: packages/optimizer/core/src/test.rs
-assertion_line: 5542
+assertion_line: 5728
expression: output
---
==INPUT==
@@ -46,10 +46,10 @@ export default /*#__PURE__*/ componentQrl(q_test_component_LUXeXe0DQrg);
Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AAGA,6BAAe,2CAuBZ\"}")
============================= test.tsx_test_component_div_div_span_button_q_e_click_oBFNw2cK30o.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const test_component_div_div_span_button_q_e_click_oBFNw2cK30o = (_, _1, cellIndex)=>{
- const rowIndex = _captures[0];
+ let rowIndex = _capturesObj._[0];
return console.log(rowIndex, cellIndex);
};
@@ -85,10 +85,10 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma
*/
============================= test.tsx_test_component_div_div_span_span_q_e_keydown_SBPovprktLQ.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const test_component_div_div_span_span_q_e_keydown_SBPovprktLQ = (_, _1, j, cellKey)=>{
- const i = _captures[0];
+ let i = _capturesObj._[0];
return console.log(cellKey, i, j);
};
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_nested_loops.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_nested_loops.snap
index 0d51c8624ef..bfbad2c57c8 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_nested_loops.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_nested_loops.snap
@@ -1,6 +1,6 @@
---
source: packages/optimizer/core/src/test.rs
-assertion_line: 5095
+assertion_line: 5281
expression: output
---
==INPUT==
@@ -125,10 +125,10 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma
*/
============================= test.tsx_Foo_component_div_div_p_q_e_click_PjMbeUzoAMk.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const Foo_component_div_div_p_q_e_click_PjMbeUzoAMk = (_, _1, item)=>{
- const row = _captures[0];
+ let row = _capturesObj._[0];
return console.log(row.value.id, item.value.id);
};
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_qrls_in_ternary_expression.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_qrls_in_ternary_expression.snap
index b06387fffc2..cea532d2df6 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_qrls_in_ternary_expression.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_qrls_in_ternary_expression.snap
@@ -1,6 +1,6 @@
---
source: packages/optimizer/core/src/test.rs
-assertion_line: 5219
+assertion_line: 5405
expression: output
---
==INPUT==
@@ -120,10 +120,10 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma
*/
============================= test.tsx_FieldInput_component_input_q_e_input_wqR1xEjZjf4.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const FieldInput_component_input_q_e_input_wqR1xEjZjf4 = (ev, el)=>{
- const input = _captures[0];
+ let input = _capturesObj._[0];
input.value = el.value;
};
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_three_nested_loops_handler_captures_outer_only.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_three_nested_loops_handler_captures_outer_only.snap
index 574c36aef79..cb20a6fde41 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_three_nested_loops_handler_captures_outer_only.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__should_transform_three_nested_loops_handler_captures_outer_only.snap
@@ -1,6 +1,6 @@
---
source: packages/optimizer/core/src/test.rs
-assertion_line: 5645
+assertion_line: 5831
expression: output
---
==INPUT==
@@ -48,10 +48,10 @@ export default /*#__PURE__*/ componentQrl(q_test_component_LUXeXe0DQrg);
Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AAGA,6BAAe,2CAyBZ\"}")
============================= test.tsx_test_component_div_div_div_button_q_e_click_7fyCCEiYKFo.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const test_component_div_div_div_button_q_e_click_7fyCCEiYKFo = ()=>{
- const planeId = _captures[0];
+ let planeId = _capturesObj._[0];
return console.log(planeId);
};
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__should_wrap_prop_from_destructured_array.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__should_wrap_prop_from_destructured_array.snap
index 1bf1bed32d3..45fcaf8463b 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__should_wrap_prop_from_destructured_array.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__should_wrap_prop_from_destructured_array.snap
@@ -199,10 +199,10 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma
*/
============================= test.tsx_Input_component_useTask_Sbgs9Wtfkt0.js (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const Input_component_useTask_Sbgs9Wtfkt0 = ({ track })=>{
- const props = _captures[0];
+ let props = _capturesObj._[0];
track(()=>props.error);
track(()=>props.error2);
track(()=>props.error3);
diff --git a/packages/optimizer/core/src/snapshots/qwik_core__test__ternary_prop.snap b/packages/optimizer/core/src/snapshots/qwik_core__test__ternary_prop.snap
index 9a25f963f53..2e752f87182 100644
--- a/packages/optimizer/core/src/snapshots/qwik_core__test__ternary_prop.snap
+++ b/packages/optimizer/core/src/snapshots/qwik_core__test__ternary_prop.snap
@@ -23,10 +23,10 @@ expression: output
============================= test.tsx_Cmp_component_handleClick_WawHV3HwS1A.ts (ENTRY POINT)==
-import { _captures } from "@qwik.dev/core";
+import { _capturesObj } from "@qwik.dev/core";
//
export const Cmp_component_handleClick_WawHV3HwS1A = ()=>{
- const toggleSig = _captures[0];
+ let toggleSig = _capturesObj._[0];
toggleSig.value = !toggleSig.value;
};
diff --git a/packages/optimizer/core/src/test.rs b/packages/optimizer/core/src/test.rs
index 7737a82806d..2b6682f7459 100644
--- a/packages/optimizer/core/src/test.rs
+++ b/packages/optimizer/core/src/test.rs
@@ -6921,10 +6921,10 @@ export const App = component$(() => {
"Expected inlinedQrl first arg to be an inline function expression in lib mode.\nGenerated code:\n{}",
combined_code
);
- // No _captures should be used
+ // No _capturesObj(Obj) should be used
assert!(
- !compact_code.contains("_captures"),
- "Expected no _captures in lib mode output.\nGenerated code:\n{}",
+ !compact_code.contains("_capturesObj"),
+ "Expected no _capturesObj.* in lib mode output.\nGenerated code:\n{}",
combined_code
);
}
@@ -6933,19 +6933,19 @@ export const App = component$(() => {
fn inlined_qrl_preserves_captures() {
// Simulates lib-preprocessed code being processed by the app optimizer.
// The inner inlinedQrl has 5 captures, including variables defined via
- // the outer function's _captures destructuring.
+ // the outer function's _capturesObj reads.
let res = test_input!(TestInput {
code: r#"
-import { componentQrl, inlinedQrl, useTaskQrl, useSignal, _captures } from '@qwik.dev/core';
+import { componentQrl, inlinedQrl, useTaskQrl, useSignal, _capturesObj } from '@qwik.dev/core';
export function qwikifyQrl(reactCmp$, opts) {
return componentQrl(inlinedQrl((props) => {
- const opts2 = _captures[0], reactCmp$2 = _captures[1];
+ const opts2 = _capturesObj._[0], reactCmp$2 = _capturesObj._[1];
const hostRef = useSignal();
const signal = useSignal();
const text = 'hello';
useTaskQrl(inlinedQrl(async ({ track }) => {
- const hostRef2 = _captures[0], reactCmp$3 = _captures[1], opts3 = _captures[2], signal2 = _captures[3], text2 = _captures[4];
+ const hostRef2 = _capturesObj._[0], reactCmp$3 = _capturesObj._[1], opts3 = _capturesObj._[2], signal2 = _capturesObj._[3], text2 = _capturesObj._[4];
track(signal2);
console.log(hostRef2, reactCmp$3, opts3, text2);
}, "s_inner123", [hostRef, reactCmp$2, opts2, signal, text]));
@@ -7026,18 +7026,18 @@ fn inlined_qrl_preserves_destructured_captures() {
// the destructuring because it would break the explicit captures.
let res = test_input!(TestInput {
code: r#"
-import { componentQrl, inlinedQrl, useComputedQrl, useSignal, useTaskQrl, _captures, _jsxSorted } from '@qwik.dev/core';
+import { componentQrl, inlinedQrl, useComputedQrl, useSignal, useTaskQrl, _capturesObj, _jsxSorted } from '@qwik.dev/core';
import { useCustomSignal } from './use-custom-signal.qwik.mjs';
const MyComponent = componentQrl(inlinedQrl((props) => {
const count = useSignal(0);
const { openSig: isOpen } = useCustomSignal(props, { open: false });
const label = useComputedQrl(inlinedQrl(() => {
- const count2 = _captures[0], isOpen2 = _captures[1];
+ const count2 = _capturesObj._[0], isOpen2 = _capturesObj._[1];
return count2.value + isOpen2.value;
}, "MyComponent_component_label_useComputed_ABC123", [count, isOpen]));
useTaskQrl(inlinedQrl(({ track }) => {
- const isOpen3 = _captures[0];
+ const isOpen3 = _capturesObj._[0];
track(() => isOpen3.value);
console.log("isOpen changed:", isOpen3.value);
}, "MyComponent_component_useTask_DEF456", [isOpen]));
@@ -7105,12 +7105,12 @@ fn lib_full_names_shortened_in_prod() {
// When a prod build consumes this lib, names should be shortened to "s_hash".
let res = test_input!(TestInput {
code: r#"
-import { componentQrl, inlinedQrl, useTaskQrl, _captures } from '@qwik.dev/core';
+import { componentQrl, inlinedQrl, useTaskQrl, _capturesObj } from '@qwik.dev/core';
export const Works = componentQrl(inlinedQrl((props) => {
const text = 'hola';
useTaskQrl(inlinedQrl(() => {
- const text = _captures[0];
+ const text = _capturesObj._[0];
console.log(text);
}, "Works_component_useTask_pjo5U5Ikll0", [text]));
}, "Works_component_t45qL4vNGv0"));
@@ -7606,15 +7606,15 @@ impl TestInput {
fn should_preserve_non_ident_explicit_captures() {
let res = test_input!(TestInput {
code: r#"
-import { _captures, inlinedQrl } from '@qwik.dev/core';
+import { _capturesObj, inlinedQrl } from '@qwik.dev/core';
const left = 1;
const right = 2;
export const task = inlinedQrl(() => {
- const left = _captures[0];
- const middle = _captures[1];
- const right = _captures[2];
+ const left = _capturesObj._[0];
+ const middle = _capturesObj._[1];
+ const right = _capturesObj._[2];
return middle ? left : right;
}, 'task', [left, true, right]);
"#
diff --git a/packages/optimizer/core/src/transform.rs b/packages/optimizer/core/src/transform.rs
index 93e8d32fd0f..4ba8a0863ba 100644
--- a/packages/optimizer/core/src/transform.rs
+++ b/packages/optimizer/core/src/transform.rs
@@ -145,6 +145,7 @@ pub struct QwikTransform<'a> {
h_fn: Option
,
fragment_fn: Option,
fn_signal_fn: Option,
+ captures_obj_id: Option,
jsx_mutable: bool,
@@ -310,6 +311,7 @@ impl<'a> QwikTransform<'a> {
fn_signal_fn: options
.global_collect
.get_imported_local(&_INLINED_FN, &options.core_module),
+ captures_obj_id: None,
marker_functions,
jsx_functions,
immutable_function_cmp,
@@ -937,10 +939,10 @@ impl<'a> QwikTransform<'a> {
scoped_idents = vec![];
}
- // Inject _captures destructuring if there are captured variables
+ // Inject _capturesObj reads if there are captured variables
let folded = if !scoped_idents.is_empty() {
- let new_local = self.ensure_core_import(&_CAPTURES);
- transform_function_expr(folded, &new_local, &scoped_idents)
+ let captures_obj = self.ensure_captures_obj();
+ transform_function_expr(folded, &captures_obj, &scoped_idents)
} else {
folded
};
@@ -1008,7 +1010,7 @@ impl<'a> QwikTransform<'a> {
compute_scoped_idents(&descendent_idents, &decl_collect);
// Filter out function parameters from scoped_idents
- // Parameters don't need to be captured via _captures
+ // Parameters don't need to be captured via captures
scoped_idents.retain(|id| !param_idents.contains(id));
if !can_capture && !scoped_idents.is_empty() {
@@ -1063,8 +1065,8 @@ impl<'a> QwikTransform<'a> {
(self.create_noop_qrl(&symbol_name, segment_data), is_const)
} else if self.is_inline() {
let folded = if !segment_data.scoped_idents.is_empty() {
- let new_local = self.ensure_core_import(&_CAPTURES);
- transform_function_expr(folded, &new_local, &segment_data.scoped_idents)
+ let captures_obj = self.ensure_captures_obj();
+ transform_function_expr(folded, &captures_obj, &segment_data.scoped_idents)
} else {
folded
};
@@ -1286,6 +1288,16 @@ impl<'a> QwikTransform<'a> {
.import(new_specifier, &self.options.core_module)
}
+ fn ensure_captures_obj(&mut self) -> Id {
+ if let Some(id) = &self.captures_obj_id {
+ return id.clone();
+ }
+
+ let captures_obj = self.ensure_core_import(&_CAPTURES_OBJ);
+ self.captures_obj_id = Some(captures_obj.clone());
+ captures_obj
+ }
+
fn ensure_export(&mut self, id: &Id) {
let canonical_id = self.options.global_collect.canonical_id_for(id);
let exported_name: Option = Some(format!("_auto_{}", canonical_id.0).into());
@@ -4127,7 +4139,7 @@ impl<'a> Fold for QwikTransform<'a> {
// Also collect top-level `const = ` declarations from the
// callback body. These derived consts (e.g. `const index = i + 1`) are in
// scope at the JSX render site so they can be passed via `q:p`/`q:ps` as
- // positional arguments rather than captured via `_captures`.
+ // positional arguments rather than captured.
if let Some(arg) = node.args.first() {
if let ast::Expr::Arrow(arrow) = &*arg.expr {
if let box ast::BlockStmtOrExpr::BlockStmt(ref block) = arrow.body {
diff --git a/packages/optimizer/core/src/words.rs b/packages/optimizer/core/src/words.rs
index b100902881f..545ad3de9fb 100644
--- a/packages/optimizer/core/src/words.rs
+++ b/packages/optimizer/core/src/words.rs
@@ -26,7 +26,7 @@ lazy_static! {
pub static ref BUILDER_IO_QWIK_JSX_DEV: Atom = Atom::from("@qwik.dev/core/jsx-dev-runtime");
pub static ref QCOMPONENT: Atom = Atom::from("component$");
pub static ref QWORKER: Atom = Atom::from("worker$");
- pub static ref _CAPTURES: Atom = Atom::from("_captures");
+ pub static ref _CAPTURES_OBJ: Atom = Atom::from("_capturesObj");
pub static ref H: Atom = Atom::from("h");
pub static ref FRAGMENT: Atom = Atom::from("Fragment");
pub static ref _INLINED_FN: Atom = Atom::from("_fnSignal");
diff --git a/packages/qwik/src/core/client/run-qrl.ts b/packages/qwik/src/core/client/run-qrl.ts
index 0f9807d425c..fbed6a791ad 100644
--- a/packages/qwik/src/core/client/run-qrl.ts
+++ b/packages/qwik/src/core/client/run-qrl.ts
@@ -1,6 +1,6 @@
import { isDev } from '@qwik.dev/core/build';
import {
- _captures,
+ _capturesObj,
deserializeCaptures,
setCaptures,
type QRLInternal,
@@ -80,7 +80,7 @@ export function _run(this: string, event: Event, element: Element): ValueOrPromi
if (typeof this === 'string') {
setCaptures(deserializeCaptures(ctx.$container$!, this));
}
- const qrlToRun = _captures![0] as QRLInternal<(...args: any[]) => void>;
+ const qrlToRun = _capturesObj._![0] as QRLInternal<(...args: any[]) => void>;
isDev && assertQrl(qrlToRun);
return runEventHandlerQRL(qrlToRun, event, element, ctx);
}
diff --git a/packages/qwik/src/core/client/run-qrl.unit.ts b/packages/qwik/src/core/client/run-qrl.unit.ts
index 95889c4a057..59bde3b799d 100644
--- a/packages/qwik/src/core/client/run-qrl.unit.ts
+++ b/packages/qwik/src/core/client/run-qrl.unit.ts
@@ -11,11 +11,14 @@ import { VNodeFlags } from './types';
vi.mock('../shared/qrl/qrl-class', async () => {
const actual =
await vi.importActual('../shared/qrl/qrl-class');
+ const capturesObj: { _: unknown[] | null } = { _: null };
return {
...actual,
deserializeCaptures: vi.fn(),
- setCaptures: vi.fn(),
- _captures: null,
+ setCaptures: vi.fn((captures: unknown[] | null) => {
+ capturesObj._ = captures;
+ }),
+ _capturesObj: capturesObj,
};
});
@@ -94,11 +97,7 @@ describe('_run', () => {
vi.mocked(useCore.newInvokeContextFromDOM).mockReturnValue(mockContext);
vi.mocked(qrlClass.deserializeCaptures).mockReturnValue([mockQrl]);
- // Mock _captures global
- Object.defineProperty(qrlClass, '_captures', {
- get: () => [mockQrl],
- configurable: true,
- });
+ qrlClass._capturesObj._ = [mockQrl];
});
afterEach(() => {
@@ -137,15 +136,12 @@ describe('_run', () => {
it('should get QRL from first capture', () => {
const mockQrlFromCaptures = vi.fn();
- Object.defineProperty(qrlClass, '_captures', {
- get: () => [mockQrlFromCaptures],
- configurable: true,
- });
+ vi.mocked(qrlClass.deserializeCaptures).mockReturnValue([mockQrlFromCaptures]);
_run.call('captures', mockEvent, mockElement);
- // The function should use the QRL from _captures[0]
- expect(qrlClass._captures![0]).toBe(mockQrlFromCaptures);
+ // The function should use the QRL from _capturesObj._[0]
+ expect(qrlClass._capturesObj._![0]).toBe(mockQrlFromCaptures);
});
it('should handle empty captures string', () => {
diff --git a/packages/qwik/src/core/control-flow/each.ts b/packages/qwik/src/core/control-flow/each.ts
index f317618cdcf..61905307a8a 100644
--- a/packages/qwik/src/core/control-flow/each.ts
+++ b/packages/qwik/src/core/control-flow/each.ts
@@ -11,7 +11,7 @@ import { componentQrl } from '../shared/component.public';
import { type TaskCtx, useTaskQrl } from '../use/use-task';
import { isServer } from '@qwik.dev/core/build';
import { SkipRender } from '../shared/jsx/utils.public';
-import { _captures } from '../shared/qrl/qrl-class';
+import { _capturesObj } from '../shared/qrl/qrl-class';
export interface EachProps {
items: readonly T[];
@@ -28,7 +28,7 @@ export type EachComponent = (
/** @internal */
export const eachCmpTask = async ({ track }: TaskCtx) => {
- const props = _captures![0] as EachProps;
+ const props = _capturesObj._![0] as EachProps;
track(() => props.items);
const context = tryGetInvokeContext()!;
const host = context.$hostElement$!;
diff --git a/packages/qwik/src/core/control-flow/reveal.tsx b/packages/qwik/src/core/control-flow/reveal.tsx
index 1b35806299e..8eeb0064007 100644
--- a/packages/qwik/src/core/control-flow/reveal.tsx
+++ b/packages/qwik/src/core/control-flow/reveal.tsx
@@ -7,7 +7,7 @@ import { _jsxSorted } from '../shared/jsx/jsx-internal';
import { Slot } from '../shared/jsx/slot.public';
import { isServerPlatform } from '../shared/platform/platform';
import { inlinedQrl } from '../shared/qrl/qrl';
-import { _captures } from '../shared/qrl/qrl-class';
+import { _capturesObj } from '../shared/qrl/qrl-class';
import { createContextId, useContext, useContextProvider } from '../use/use-context';
import type { CursorBoundary } from '../use/use-cursor-boundary';
import { useConstant } from '../use/use-signal';
@@ -51,7 +51,7 @@ const createRevealContext = (props: RevealProps): RevealContext => {
/** @internal */
export const revealCanReveal = () => {
- const registration = _captures![0] as RevealRegistration | null;
+ const registration = _capturesObj._![0] as RevealRegistration | null;
if (registration === null) {
return true;
}
@@ -101,7 +101,7 @@ export const revealCanReveal = () => {
/** @internal */
export const revealCleanupTask = ({ cleanup }: TaskCtx) => {
- const registration = _captures![0] as RevealRegistration;
+ const registration = _capturesObj._![0] as RevealRegistration;
cleanup(() => {
// Keep the SSR registry intact so `reveal.items` serializes for resume.
if (qTest ? isServerPlatform() : !isBrowser) {
diff --git a/packages/qwik/src/core/control-flow/suspense.tsx b/packages/qwik/src/core/control-flow/suspense.tsx
index 98c125de64b..824b10098b1 100644
--- a/packages/qwik/src/core/control-flow/suspense.tsx
+++ b/packages/qwik/src/core/control-flow/suspense.tsx
@@ -10,7 +10,7 @@ import type { JSXOutput } from '../shared/jsx/types/jsx-node';
import { isServerPlatform } from '../shared/platform/platform';
import { _fnSignal } from '../shared/qrl/inlined-fn';
import { inlinedQrl } from '../shared/qrl/qrl';
-import { _captures } from '../shared/qrl/qrl-class';
+import { _capturesObj } from '../shared/qrl/qrl-class';
import { QCursorBoundary } from '../shared/utils/markers';
import { useComputedQrl } from '../use/use-computed';
import { useCursorBoundary, type CursorBoundary } from '../use/use-cursor-boundary';
@@ -52,10 +52,10 @@ const _hf1_str =
/** @internal */
export const suspenseTask = ({ track, cleanup }: TaskCtx) => {
- const cursorBoundary = _captures![0] as CursorBoundary,
- props = _captures![1] as { delay?: number },
- state = _captures![2] as Signal,
- revealRegistration = _captures![3] as RevealRegistration | null;
+ const cursorBoundary = _capturesObj._![0] as CursorBoundary,
+ props = _capturesObj._![1] as { delay?: number },
+ state = _capturesObj._![2] as Signal,
+ revealRegistration = _capturesObj._![3] as RevealRegistration | null;
const pendingCount = track(cursorBoundary.pending);
const isBrowserEnv = qTest ? !isServerPlatform() : isBrowser;
if (revealRegistration !== null && isBrowserEnv) {
diff --git a/packages/qwik/src/core/index.ts b/packages/qwik/src/core/index.ts
index d05d435b0a1..b9ab51e3647 100644
--- a/packages/qwik/src/core/index.ts
+++ b/packages/qwik/src/core/index.ts
@@ -1,19 +1,7 @@
//////////////////////////////////////////////////////////////////////////////////////////
-// Protect against duplicate imports
+// Server-side singleton registry — also runs the duplicate-Qwik version check on import
//////////////////////////////////////////////////////////////////////////////////////////
-import { QError, qError } from '../server/qwik-copy';
-import { version } from './version';
-
-if ((globalThis as any).__qwik) {
- qError(QError.duplicateQwik, [(globalThis as any).__qwik, version]);
-}
-(globalThis as any).__qwik = version;
-
-if (import.meta.hot) {
- import.meta.hot.dispose(() => {
- (globalThis as any).__qwik = undefined;
- });
-}
+import './shared/singletons';
//////////////////////////////////////////////////////////////////////////////////////////
// Developer Core API
@@ -44,6 +32,7 @@ export { eventQrl } from './shared/qrl/qrl.public';
export { event$ } from './shared/qrl/qrl.public.dollar';
export { qrl, inlinedQrl, inlinedQrlDEV, qrlDEV } from './shared/qrl/qrl';
+export { _capturesObj } from './shared/qrl/qrl-class';
export type { QRL, PropFunction } from './shared/qrl/qrl.public';
export { implicit$FirstArg } from './shared/qrl/implicit_dollar';
diff --git a/packages/qwik/src/core/internal.ts b/packages/qwik/src/core/internal.ts
index 24cea68ae83..df7de265634 100644
--- a/packages/qwik/src/core/internal.ts
+++ b/packages/qwik/src/core/internal.ts
@@ -78,7 +78,7 @@ export {
} from './use/use-core';
export { useLexicalScope } from './use/use-lexical-scope.public';
export { isTask as _isTask, scheduleTask as _task } from './use/use-task';
-export { _captures } from './shared/qrl/qrl-class';
+export { _capturesObj } from './shared/qrl/qrl-class';
export { _rsc } from './use/use-resource';
export type { AsyncSignalOptions } from './reactive-primitives/types';
export { setEvent as _setEvent } from './ssr/ssr-events';
diff --git a/packages/qwik/src/core/preloader/bundle-graph.ts b/packages/qwik/src/core/preloader/bundle-graph.ts
index 9a7f5f77eac..18da5e2850a 100644
--- a/packages/qwik/src/core/preloader/bundle-graph.ts
+++ b/packages/qwik/src/core/preloader/bundle-graph.ts
@@ -1,9 +1,11 @@
+import { isBrowser } from '@qwik.dev/core/build';
import { createMacroTask } from '../shared/platform/next-tick';
-import { config, isJSRegex, isBrowser, yieldInterval } from './constants';
-import { adjustProbabilities, bundles, shouldResetFactor, nextTriggerMacroTask } from './queue';
+import { config, isJSRegex, yieldInterval } from './constants';
+import { adjustProbabilities, bundles, nextTriggerMacroTask, shouldResetFactor } from './queue';
import type { BundleGraph, BundleImport, ImportProbability } from './types';
-import { BundleImportState_None, BundleImportState_Alias } from './types';
+import { BundleImportState_Alias, BundleImportState_None } from './types';
+// Note, making these singletons pulls in too much code and they are ok being module-scoped
export let base: string | undefined;
export let graph: BundleGraph;
diff --git a/packages/qwik/src/core/preloader/queue.ts b/packages/qwik/src/core/preloader/queue.ts
index 695ec84041a..419e8208509 100644
--- a/packages/qwik/src/core/preloader/queue.ts
+++ b/packages/qwik/src/core/preloader/queue.ts
@@ -1,3 +1,5 @@
+import type { QwikSymbolEvent } from '../shared/jsx/types/jsx-qwik-events';
+import { createMacroTask } from '../shared/platform/next-tick';
import { base, getBundle } from './bundle-graph';
import { config, doc, isBrowser, rel, yieldInterval } from './constants';
import type { BundleImport, BundleImports, ImportProbability } from './types';
@@ -7,8 +9,6 @@ import {
BundleImportState_Preload,
BundleImportState_Queued,
} from './types';
-import type { QwikSymbolEvent } from '../shared/jsx/types/jsx-qwik-events';
-import { createMacroTask } from '../shared/platform/next-tick';
export const bundles: BundleImports = new Map();
export let shouldResetFactor: boolean;
diff --git a/packages/qwik/src/core/preloader/queue.unit.ts b/packages/qwik/src/core/preloader/queue.unit.ts
index f5a16f5d3db..43b1f1f9b81 100644
--- a/packages/qwik/src/core/preloader/queue.unit.ts
+++ b/packages/qwik/src/core/preloader/queue.unit.ts
@@ -1,6 +1,12 @@
import { afterEach, beforeEach, expect, test, vi } from 'vitest';
import { createDocument } from '@qwik.dev/core/testing';
+const importAndResetState = async () => {
+ const { initPreloader } = await import('./bundle-graph');
+ const { preload } = await import('./queue');
+ return { initPreloader, preload };
+};
+
const originalWindow = globalThis.window;
const originalDocument = globalThis.document;
const originalHTMLElement = globalThis.HTMLElement;
@@ -72,8 +78,7 @@ test('appends preloads directly to head within a trigger slice', async () => {
await installTestPlatform();
const headAppend = vi.spyOn(document.head, 'appendChild');
- const { initPreloader } = await import('./bundle-graph');
- const { preload } = await import('./queue');
+ const { initPreloader, preload } = await importAndResetState();
initPreloader(['entry-a.js', 'entry-b.js']);
preload(['entry-a.js', 'entry-b.js'], 1);
@@ -103,8 +108,7 @@ test('yields after the frame budget and resumes later', async () => {
const headAppend = vi.spyOn(document.head, 'appendChild');
const timeoutSpy = vi.spyOn(globalThis, 'setTimeout');
- const { initPreloader } = await import('./bundle-graph');
- const { preload } = await import('./queue');
+ const { initPreloader, preload } = await importAndResetState();
initPreloader(['entry-a.js', 'entry-b.js', 'entry-c.js']);
preload(['entry-a.js', 'entry-b.js', 'entry-c.js'], 1);
@@ -155,8 +159,7 @@ test('yields during dependency propagation and resumes later', async () => {
const headAppend = vi.spyOn(document.head, 'appendChild');
const timeoutSpy = vi.spyOn(globalThis, 'setTimeout');
- const { initPreloader } = await import('./bundle-graph');
- const { preload } = await import('./queue');
+ const { initPreloader, preload } = await importAndResetState();
initPreloader(createLinearGraph(4));
preload('entry-a.js', 1);
@@ -196,8 +199,7 @@ test('can yield more than once while propagating dependencies', async () => {
const headAppend = vi.spyOn(document.head, 'appendChild');
const timeoutSpy = vi.spyOn(globalThis, 'setTimeout');
- const { initPreloader } = await import('./bundle-graph');
- const { preload } = await import('./queue');
+ const { initPreloader, preload } = await importAndResetState();
initPreloader(createLinearGraph(7));
preload('entry-a.js', 1);
diff --git a/packages/qwik/src/core/qwik.core.api.md b/packages/qwik/src/core/qwik.core.api.md
index 38d4684ac65..1e02bd20975 100644
--- a/packages/qwik/src/core/qwik.core.api.md
+++ b/packages/qwik/src/core/qwik.core.api.md
@@ -52,8 +52,10 @@ export interface AsyncSignalOptions extends ComputedOptions {
timeout?: number;
}
-// @internal
-export let _captures: Readonly | null;
+// @internal (undocumented)
+export const _capturesObj: {
+ _: Readonly | null;
+};
// @internal
export function _chk(this: string | undefined, _: any, element: HTMLInputElement): void;
diff --git a/packages/qwik/src/core/readme.md b/packages/qwik/src/core/readme.md
index 887b1114cd8..5f77dfe1596 100644
--- a/packages/qwik/src/core/readme.md
+++ b/packages/qwik/src/core/readme.md
@@ -236,7 +236,7 @@ This method should not be present in the application source code.
NOTE: `useLexicalScope` method can only be used in the synchronous portion of the callback (before any `await` statements.)
-@deprecated Use `_captures` instead.
+@deprecated Use `_capturesObj._` instead.
@internal
# `QRL`
diff --git a/packages/qwik/src/core/shared/jsx/bind-handlers.ts b/packages/qwik/src/core/shared/jsx/bind-handlers.ts
index a276139294a..8e5be71b809 100644
--- a/packages/qwik/src/core/shared/jsx/bind-handlers.ts
+++ b/packages/qwik/src/core/shared/jsx/bind-handlers.ts
@@ -1,4 +1,4 @@
-import { _captures, deserializeCaptures, setCaptures } from '../../shared/qrl/qrl-class';
+import { _capturesObj, deserializeCaptures, setCaptures } from '../../shared/qrl/qrl-class';
import type { Signal } from '../../reactive-primitives/signal.public';
import { getDomContainer } from '../../client/dom-container';
import { AsyncSignalImpl } from '../../reactive-primitives/impl/async-signal-impl';
@@ -23,7 +23,7 @@ const maybeScopeFromQL = (captureIds: string | undefined, element: Element) => {
*/
export function _val(this: string | undefined, _: any, element: HTMLInputElement) {
maybeScopeFromQL(this, element);
- const signal = _captures![0] as Signal;
+ const signal = _capturesObj._![0] as Signal;
signal.value = element.type === 'number' ? element.valueAsNumber : element.value;
}
@@ -34,7 +34,7 @@ export function _val(this: string | undefined, _: any, element: HTMLInputElement
*/
export function _chk(this: string | undefined, _: any, element: HTMLInputElement) {
maybeScopeFromQL(this, element);
- const signal = _captures![0] as Signal;
+ const signal = _capturesObj._![0] as Signal;
signal.value = element.checked;
}
@@ -47,9 +47,10 @@ export function _chk(this: string | undefined, _: any, element: HTMLInputElement
export function _res(this: string | undefined, _: any, element: Element) {
maybeScopeFromQL(this, element);
// Captures are deserialized, now trigger computation on AsyncSignals
- if (_captures) {
- for (let i = 0; i < _captures.length; i++) {
- const capture = _captures[i];
+ const captures = _capturesObj._;
+ if (captures) {
+ for (let i = 0; i < captures.length; i++) {
+ const capture = captures[i];
if (capture instanceof AsyncSignalImpl && capture.$flags$ & AsyncSignalFlags.CLIENT_ONLY) {
capture.$computeIfNeeded$();
}
diff --git a/packages/qwik/src/core/shared/platform/platform.ts b/packages/qwik/src/core/shared/platform/platform.ts
index 60bdfa16ce8..c7532d5192e 100644
--- a/packages/qwik/src/core/shared/platform/platform.ts
+++ b/packages/qwik/src/core/shared/platform/platform.ts
@@ -2,17 +2,23 @@
import { isServer } from '@qwik.dev/core/build';
import { QError, qError } from '../error/error';
import { getSymbolHash } from '../qrl/qrl-utils';
+import { registerSingleton } from '../singletons';
import { QBaseAttr } from '../utils/markers';
import { qDynamicPlatform } from '../utils/qdev';
import type { CorePlatform } from './types';
+// This is see also qrl.ts - importing from there causes loop
+const symbolRegistry = isServer
+ ? registerSingleton('regSymbols', () => new Map())
+ : undefined;
+
export const createPlatform = (): CorePlatform => {
return {
isServer,
importSymbol(containerEl, url, symbolName) {
if (isServer) {
const hash = getSymbolHash(symbolName);
- const regSym = (globalThis as any).__qwik_reg_symbols?.get(hash);
+ const regSym = symbolRegistry!.get(hash);
if (regSym) {
return regSym;
}
diff --git a/packages/qwik/src/core/shared/platform/platform.unit.ts b/packages/qwik/src/core/shared/platform/platform.unit.ts
index 00f015b97bc..ada87df93e5 100644
--- a/packages/qwik/src/core/shared/platform/platform.unit.ts
+++ b/packages/qwik/src/core/shared/platform/platform.unit.ts
@@ -1,16 +1,19 @@
import { describe, test, expect, beforeEach, afterEach, vi } from 'vitest';
import { createPlatform, setPlatform } from './platform';
import { getSymbolHash } from '../qrl/qrl-utils';
+import { getSingleton } from '../singletons';
+
+const symbolRegistry = getSingleton>('regSymbols');
describe('core platform', () => {
beforeEach(() => {
// Initialize a fresh Map for each test to avoid pollution
- (globalThis as any).__qwik_reg_symbols = new Map();
+ symbolRegistry?.clear();
});
afterEach(() => {
// Clean up global state
- delete (globalThis as any).__qwik_reg_symbols;
+ symbolRegistry?.clear();
});
describe('importSymbol - server mode', () => {
@@ -21,7 +24,7 @@ describe('core platform', () => {
const symbolName = 'myComponent_abc123';
const hash = getSymbolHash(symbolName);
const mockFunction = () => 'mock component';
- (globalThis as any).__qwik_reg_symbols.set(hash, mockFunction);
+ symbolRegistry?.set(hash, mockFunction);
// importSymbol should return the registered symbol synchronously
const result = await platform.importSymbol(null as any, '', symbolName);
@@ -76,7 +79,7 @@ describe('core platform', () => {
const symbolName = 'my_component_with_underscores_abc123';
const hash = getSymbolHash(symbolName);
const mockFunction = () => 'mock';
- (globalThis as any).__qwik_reg_symbols.set(hash, mockFunction);
+ symbolRegistry?.set(hash, mockFunction);
const result = await platform.importSymbol(null as any, '', symbolName);
diff --git a/packages/qwik/src/core/shared/qrl/qrl-class.ts b/packages/qwik/src/core/shared/qrl/qrl-class.ts
index a5cc32e5ba5..e1e5e66f02c 100644
--- a/packages/qwik/src/core/shared/qrl/qrl-class.ts
+++ b/packages/qwik/src/core/shared/qrl/qrl-class.ts
@@ -6,6 +6,7 @@ import { isBrowser, isDev } from '@qwik.dev/core/build';
import { invokeApply, tryGetInvokeContext, type InvokeContext } from '../../use/use-core';
import { assertDefined } from '../error/assert';
import { QError, qError } from '../error/error';
+import { registerSingleton } from '../singletons';
import { getQFuncs } from '../utils/markers';
import { isPromise, maybeThen } from '../utils/promises';
import { qDev, qTest } from '../utils/qdev';
@@ -17,7 +18,7 @@ import type { QRL, QrlArgs, QrlReturn } from './qrl.public';
// @ts-expect-error we don't have types for the preloader
import { p as preload } from '@qwik.dev/core/preloader';
import { DomContainer } from '../../client/dom-container';
-import { loading } from '../serdes/inflate';
+import { loadingHolder } from '../serdes/inflate';
import type { Container } from '../types';
import { ElementVNode } from '../vnode/element-vnode';
@@ -407,16 +408,22 @@ const QRL_FUNCTION_PROTO: QRLInternalMethods = Object.create(Function.proto
},
});
+/** @internal */
+export const _capturesObj = registerSingleton<{ _: Readonly | null }>(
+ 'qrlCaptures',
+ () => ({
+ _: null,
+ })
+);
+
/**
- * The current captured scope during QRL invocation. This is used to provide the lexical scope for
- * QRL functions. It is used one time per invocation, synchronously, so it is safe to store it in
- * module scope.
+ * The current captured scope during QRL invocation. Prefer `_capturesObj` for generated code so
+ * duplicated Qwik modules share the same holder object.
*
* @internal
*/
-export let _captures: Readonly | null = null;
export const setCaptures = (captures: Readonly | null) => {
- _captures = captures;
+ _capturesObj._ = captures;
};
export const deserializeCaptures = (container: Container, captures: string) => {
@@ -429,21 +436,27 @@ export const deserializeCaptures = (container: Container, captures: string) => {
return refs;
};
-/** Puts the qrl captures into `_captures`, and returns a Promise that should be awaited if possible */
+/**
+ * Puts the qrl captures into the shared holder, and returns a Promise that should be awaited if
+ * possible
+ */
const ensureQrlCaptures = (qrl: QRLClass) => {
// We read the captures once, synchronously, so no need to keep previous
- _captures = qrl.$captures$ as any;
+ let captures = qrl.$captures$ as Readonly | string | null | undefined;
const container = qrl.$container$;
- if (typeof _captures === 'string') {
+ if (typeof captures === 'string') {
if (!container) {
throw qError(QError.qrlMissingContainer);
}
- const prevLoading = loading;
- _captures = qrl.$captures$ = deserializeCaptures(container, _captures);
- if (loading !== prevLoading) {
+ const prevLoading = loadingHolder.p;
+ captures = qrl.$captures$ = deserializeCaptures(container, captures);
+ setCaptures(captures);
+ if (loadingHolder.p !== prevLoading) {
// return the loading promise so callers can await it
- return loading;
+ return loadingHolder.p;
}
+ } else {
+ setCaptures(captures ?? null);
}
};
diff --git a/packages/qwik/src/core/shared/qrl/qrl.ts b/packages/qwik/src/core/shared/qrl/qrl.ts
index 23ed9b36100..4d5bccaf4c2 100644
--- a/packages/qwik/src/core/shared/qrl/qrl.ts
+++ b/packages/qwik/src/core/shared/qrl/qrl.ts
@@ -1,4 +1,6 @@
+import { isServer } from '@qwik.dev/core/build';
import { QError, qError } from '../error/error';
+import { registerSingleton } from '../singletons';
import { qDev } from '../utils/qdev';
import { isFunction, isString } from '../utils/types';
import { createQRL, type QRLInternal } from './qrl-class';
@@ -131,6 +133,10 @@ export const inlinedQrlDEV = (
return qrl;
};
+// See also ../plaform/platform.ts
+const symbolRegistry = isServer
+ ? registerSingleton('regSymbols', () => new Map())
+ : undefined;
/**
* Register a QRL symbol globally for lookup by its hash. This is used by the optimizer to register
* the names passed in `reg_ctx_name`.
@@ -138,9 +144,6 @@ export const inlinedQrlDEV = (
* @internal
*/
export const _regSymbol = (symbol: any, hash: string) => {
- if (typeof (globalThis as any).__qwik_reg_symbols === 'undefined') {
- (globalThis as any).__qwik_reg_symbols = new Map();
- }
- (globalThis as any).__qwik_reg_symbols.set(hash, symbol);
+ symbolRegistry!.set(hash, symbol);
return symbol;
};
diff --git a/packages/qwik/src/core/shared/qrl/qrl.unit.ts b/packages/qwik/src/core/shared/qrl/qrl.unit.ts
index a7d36892897..2ef532fcd04 100644
--- a/packages/qwik/src/core/shared/qrl/qrl.unit.ts
+++ b/packages/qwik/src/core/shared/qrl/qrl.unit.ts
@@ -3,7 +3,7 @@ import { assert, assertType, describe, expectTypeOf, test } from 'vitest';
import { useLexicalScope } from '../../use/use-lexical-scope.public';
import { createSerializationContext, parseQRL, qrlToString } from '../serdes/index';
import { _regSymbol, inlinedQrl, qrl } from './qrl';
-import { _captures, createQRL } from './qrl-class';
+import { _capturesObj, createQRL } from './qrl-class';
import { type QRL } from './qrl.public';
function matchProps(obj: any, properties: Record) {
@@ -218,7 +218,8 @@ describe('inlinedQrl', () => {
});
describe('w (with captures)', () => {
- const capFn = () => _captures;
+ const capturesObj = _capturesObj;
+ const capFn = () => capturesObj._;
test('should share the same LazyRef', () => {
const q1 = createQRL('chunk', 'symbol', capFn, null, ['a']);
diff --git a/packages/qwik/src/core/shared/serdes/allocate.ts b/packages/qwik/src/core/shared/serdes/allocate.ts
index a4dcd2f01d1..f3ae5c2e686 100644
--- a/packages/qwik/src/core/shared/serdes/allocate.ts
+++ b/packages/qwik/src/core/shared/serdes/allocate.ts
@@ -19,6 +19,7 @@ import { qError, QError } from '../error/error';
import { JSXNodeImpl } from '../jsx/jsx-node';
import { createPropsProxy } from '../jsx/props-proxy';
import type { QRLInternal } from '../qrl/qrl-class';
+import { registerSingleton } from '../singletons';
import type { DeserializeContainer } from '../types';
import { _UNINITIALIZED } from '../utils/constants';
import type { ElementVNode } from '../vnode/element-vnode';
@@ -27,8 +28,14 @@ import { _constants, TypeIds, type Constants } from './constants';
import { needsInflation } from './deser-proxy';
import { createQRLWithBackChannel } from './qrl-to-string';
-export const resolvers = new WeakMap, [Function, Function]>();
-export const pendingStoreTargets = new Map();
+export const resolvers = registerSingleton(
+ 'resolvers',
+ () => new WeakMap, [Function, Function]>()
+);
+export const pendingStoreTargets = registerSingleton(
+ 'pendingStoreTargets',
+ () => new Map()
+);
export const allocate = (container: DeserializeContainer, typeId: number, value: unknown): any => {
switch (typeId) {
diff --git a/packages/qwik/src/core/shared/serdes/deser-proxy.ts b/packages/qwik/src/core/shared/serdes/deser-proxy.ts
index 7f8081d3bd1..ef11d2b93cf 100644
--- a/packages/qwik/src/core/shared/serdes/deser-proxy.ts
+++ b/packages/qwik/src/core/shared/serdes/deser-proxy.ts
@@ -2,13 +2,17 @@ import { TypeIds } from './constants';
import type { DomContainer } from '../../client/dom-container';
import { vnode_isVNode } from '../../client/vnode-utils';
import { isObject } from '../utils/types';
+import { registerSingleton } from '../singletons';
import { allocate } from './allocate';
import { inflate } from './inflate';
/** Arrays/Objects are special-cased so their identifiers is a single digit. */
export const needsInflation = (typeId: TypeIds) =>
typeId >= TypeIds.Error || typeId === TypeIds.Array || typeId === TypeIds.Object;
-const deserializedProxyMap = new WeakMap();
+const deserializedProxyMap = registerSingleton(
+ 'deserializedProxyMap',
+ () => new WeakMap()
+);
type DeserializerProxy = T & { [SERIALIZER_PROXY_UNWRAP]: object };
export const isDeserializerProxy = (value: unknown): value is DeserializerProxy => {
diff --git a/packages/qwik/src/core/shared/serdes/inflate.ts b/packages/qwik/src/core/shared/serdes/inflate.ts
index 277c14d5293..fa7251160f1 100644
--- a/packages/qwik/src/core/shared/serdes/inflate.ts
+++ b/packages/qwik/src/core/shared/serdes/inflate.ts
@@ -39,11 +39,17 @@ import type { DeserializeContainer, HostElement } from '../types';
import { _OWNER, _PROPS_HANDLER, _UNINITIALIZED } from '../utils/constants';
import { isString } from '../utils/types';
import type { VirtualVNode } from '../vnode/virtual-vnode';
+import { registerSingleton } from '../singletons';
import { allocate, pendingStoreTargets, resolvers } from './allocate';
import { TypeIds } from './constants';
import { needsInflation } from './deser-proxy';
-export let loading = Promise.resolve();
+interface LoadingHolder {
+ p: Promise;
+}
+export const loadingHolder = registerSingleton('loadingHolder', () => ({
+ p: Promise.resolve(),
+}));
const dangerousObjectKeys = new Set([
'constructor',
@@ -225,7 +231,7 @@ export const inflate = (
const p = computed.$computeQrl$.resolve(container as any).catch(() => {
// ignore preload errors
});
- loading = loading.finally(() => p);
+ loadingHolder.p = loadingHolder.p.finally(() => p);
if (d[1]) {
computed.$effects$ = new Set(d[1]);
}
diff --git a/packages/qwik/src/core/shared/singletons.ts b/packages/qwik/src/core/shared/singletons.ts
new file mode 100644
index 00000000000..c591a02dc23
--- /dev/null
+++ b/packages/qwik/src/core/shared/singletons.ts
@@ -0,0 +1,46 @@
+import { isServer } from '@qwik.dev/core/build';
+import { qError, QError } from './error/error';
+import { version } from '../version';
+
+type Singletons = Record;
+type QwikGlobal = { version?: string | undefined } & { [version: string]: Singletons };
+
+const QWIK = ((globalThis as any).__qwik__ ||= {}) as QwikGlobal;
+
+// This will probably never happen, but better be safe
+if (import.meta.hot) {
+ import.meta.hot.dispose(() => {
+ (globalThis as any).__qwik__ = undefined;
+ });
+}
+
+let singletons: Singletons;
+
+if (isServer) {
+ // We can only have 1 Qwik version
+ const existing = QWIK.version;
+ if (existing) {
+ if (existing !== version) {
+ // Server allows only one Qwik version per process; same-version coexistence is fine
+ // and gets to share the singleton state.
+ qError(QError.duplicateQwik, [existing, version]);
+ }
+ } else {
+ QWIK.version = version;
+ }
+ singletons = QWIK.singletons ||= {};
+} else {
+ // On the client, we can have multiple Qwik versions coexisting, but they don't share state.
+ singletons = QWIK[version] ||= {};
+}
+
+export const registerSingleton = (key: string, factory: () => T): T => {
+ if (!(key in singletons)) {
+ singletons[key] = factory();
+ }
+ return singletons[key] as T;
+};
+
+export const getSingleton = (key: string): T | undefined => {
+ return singletons[key] as T | undefined;
+};
diff --git a/packages/qwik/src/core/tests/use-computed.spec.tsx b/packages/qwik/src/core/tests/use-computed.spec.tsx
index abd677a3cb8..6e27aae8506 100644
--- a/packages/qwik/src/core/tests/use-computed.spec.tsx
+++ b/packages/qwik/src/core/tests/use-computed.spec.tsx
@@ -10,7 +10,7 @@ import {
untrack,
useComputed$,
useComputedQrl,
- _captures,
+ _capturesObj,
useSignal,
useStore,
useTask$,
@@ -41,7 +41,7 @@ describe.each([
() =>
Promise.resolve({
lazy: () => {
- const [count] = _captures as any;
+ const [count] = _capturesObj._ as any;
return count.value * 2;
},
}),
diff --git a/packages/qwik/src/core/use/use-hmr.ts b/packages/qwik/src/core/use/use-hmr.ts
index 3fda6dc9466..9ad918f470d 100644
--- a/packages/qwik/src/core/use/use-hmr.ts
+++ b/packages/qwik/src/core/use/use-hmr.ts
@@ -1,6 +1,6 @@
import { getDomContainer } from '../client/dom-container';
import {
- _captures,
+ _capturesObj,
deserializeCaptures,
setCaptures,
type QRLInternal,
@@ -18,7 +18,7 @@ import type { QRL } from '../shared/qrl/qrl.public';
*
* When called by the qwikloader or the test dispatch, `this` is the serialized captures string
* which we deserialize to get the host VNode. When called through `_qDispatch` (client-rendered),
- * `_captures` is already set by `ensureQrlCaptures` in the QRL call chain.
+ * `_capturesObj._` is already set by `ensureQrlCaptures` in the QRL call chain.
*
* @internal
*/
@@ -39,7 +39,7 @@ export const _hmr = function (
const container = getDomContainer(element);
setCaptures(deserializeCaptures(container, this));
}
- const host = _captures![0] as VNode;
+ const host = _capturesObj._![0] as VNode;
const container = getDomContainer(element);
markVNodeDirty(container, host, ChoreBits.COMPONENT);
// Mark HMR as handled
diff --git a/packages/qwik/src/core/use/use-lexical-scope.public.ts b/packages/qwik/src/core/use/use-lexical-scope.public.ts
index fba9628e365..e86232f1566 100644
--- a/packages/qwik/src/core/use/use-lexical-scope.public.ts
+++ b/packages/qwik/src/core/use/use-lexical-scope.public.ts
@@ -1,7 +1,7 @@
import { _getQContainerElement } from '../client/dom-container';
import { isDev } from '@qwik.dev/core/build';
import { assertDefined } from '../shared/error/assert';
-import { _captures } from '../shared/qrl/qrl-class';
+import { _capturesObj } from '../shared/qrl/qrl-class';
//
// !!DO NOT EDIT THIS COMMENT DIRECTLY!!!
@@ -14,11 +14,12 @@ import { _captures } from '../shared/qrl/qrl-class';
* NOTE: `useLexicalScope` method can only be used in the synchronous portion of the callback
* (before any `await` statements.)
*
- * @deprecated Use `_captures` instead.
+ * @deprecated Use `_capturesObj._` instead.
* @internal
*/
//
export const useLexicalScope = (): VARS => {
- isDev && assertDefined(_captures, 'invoke: captures must be defined for useLexicalScope()');
- return _captures as VARS;
+ const captures = _capturesObj._;
+ isDev && assertDefined(captures, 'invoke: captures must be defined for useLexicalScope()');
+ return captures as VARS;
};
diff --git a/packages/qwik/src/core/use/use-locale.ts b/packages/qwik/src/core/use/use-locale.ts
index 8f019259862..38ba8b93e5d 100644
--- a/packages/qwik/src/core/use/use-locale.ts
+++ b/packages/qwik/src/core/use/use-locale.ts
@@ -2,15 +2,24 @@ import { tryGetInvokeContext } from './use-core';
import { getAsyncLocalStorage } from '../shared/platform/async-local-storage';
import { isServer } from '@qwik.dev/core/build';
import type { AsyncLocalStorage } from 'node:async_hooks';
+import { registerSingleton } from '../shared/singletons';
-let _locale: string | undefined = undefined;
+interface LocaleStore {
+ locale: string | undefined;
+ asyncStore: AsyncLocalStorage | undefined;
+}
-let localAsyncStore: AsyncLocalStorage | undefined;
+const localeStore = registerSingleton('localeStore', () => ({
+ locale: undefined,
+ asyncStore: undefined,
+}));
if (isServer) {
const AsyncLocalStorage = getAsyncLocalStorage();
if (AsyncLocalStorage) {
- localAsyncStore = new AsyncLocalStorage();
+ if (!localeStore.asyncStore) {
+ localeStore.asyncStore = new AsyncLocalStorage();
+ }
}
}
@@ -24,14 +33,14 @@ if (isServer) {
*/
export function getLocale(defaultLocale?: string): string {
// Prefer per-request locale from local AsyncLocalStorage if available (server-side)
- if (localAsyncStore) {
- const locale = localAsyncStore.getStore();
+ if (localeStore.asyncStore) {
+ const locale = localeStore.asyncStore.getStore();
if (locale) {
return locale;
}
}
- if (_locale === undefined) {
+ if (localeStore.locale === undefined) {
const ctx = tryGetInvokeContext();
if (ctx && ctx.$locale$) {
return ctx.$locale$;
@@ -41,7 +50,7 @@ export function getLocale(defaultLocale?: string): string {
}
throw new Error('Reading `locale` outside of context.');
}
- return _locale;
+ return localeStore.locale;
}
/**
@@ -50,16 +59,16 @@ export function getLocale(defaultLocale?: string): string {
* @public
*/
export function withLocale(locale: string, fn: () => T): T {
- if (localAsyncStore) {
- return localAsyncStore.run(locale, fn);
+ if (localeStore.asyncStore) {
+ return localeStore.asyncStore.run(locale, fn);
}
- const previousLang = _locale;
+ const previousLang = localeStore.locale;
try {
- _locale = locale;
+ localeStore.locale = locale;
return fn();
} finally {
- _locale = previousLang;
+ localeStore.locale = previousLang;
}
}
@@ -72,9 +81,9 @@ export function withLocale(locale: string, fn: () => T): T {
* @public
*/
export function setLocale(locale: string): void {
- if (localAsyncStore) {
- localAsyncStore.enterWith(locale);
+ if (localeStore.asyncStore) {
+ localeStore.asyncStore.enterWith(locale);
return;
}
- _locale = locale;
+ localeStore.locale = locale;
}
diff --git a/packages/qwik/src/core/use/use-resource.ts b/packages/qwik/src/core/use/use-resource.ts
index 3b4f6b07ba5..c5054bcbef3 100644
--- a/packages/qwik/src/core/use/use-resource.ts
+++ b/packages/qwik/src/core/use/use-resource.ts
@@ -1,6 +1,6 @@
import type { QRLInternal, ValueOrPromise } from '../../server/qwik-types';
import { qwikDebugToString } from '../debug';
-import { _captures } from '../internal';
+import { _capturesObj } from '../internal';
import { createStore } from '../reactive-primitives/impl/store';
import {
createAsyncQrl,
@@ -71,7 +71,7 @@ export interface ResourceOptions {
* @internal
*/
export const _rsc = async (arg: ResourceCtx) => {
- const [fn, ref] = _captures as [QRLInternal>, { r: T; i: number }];
+ const [fn, ref] = _capturesObj._ as [QRLInternal>, { r: T; i: number }];
DEBUG && log('invoke resource function');
const result = await fn(arg);
DEBUG && log('resource function resolved', result);
diff --git a/packages/qwik/src/core/use/use-task-dollar.ts b/packages/qwik/src/core/use/use-task-dollar.ts
index b9ba8b0fd42..f025169e1da 100644
--- a/packages/qwik/src/core/use/use-task-dollar.ts
+++ b/packages/qwik/src/core/use/use-task-dollar.ts
@@ -14,6 +14,12 @@ import { useTaskQrl, type TaskFn, type TaskOptions } from './use-task';
* function to wrap property reads. This creates subscriptions that will trigger the `taskFn` to
* rerun.
*
+ * Cleanup callbacks registered with `cleanup()` or returned from the task may be async. When a task
+ * reruns, Qwik waits for the previous cleanup to finish before starting the next invocation.
+ *
+ * During SSR, the cleanup function is called immediately after SSR completes. Therefore, it is not
+ * called on the client side after resuming, but only the second time the task runs on the client.
+ *
* @param task - Function which should be re-executed when changes to the inputs are detected
* @public
*
diff --git a/packages/qwik/src/core/use/use-task.ts b/packages/qwik/src/core/use/use-task.ts
index f6d36d6c8c7..b7abb8ca0c9 100644
--- a/packages/qwik/src/core/use/use-task.ts
+++ b/packages/qwik/src/core/use/use-task.ts
@@ -3,7 +3,7 @@ import { BackRef } from '../reactive-primitives/backref';
import { clearAllEffects } from '../reactive-primitives/cleanup';
import { type Signal } from '../reactive-primitives/signal.public';
import {
- _captures,
+ _capturesObj,
deserializeCaptures,
setCaptures,
type QRLInternal,
@@ -269,7 +269,7 @@ export function scheduleTask(this: string, _event: Event, element: Element) {
if (typeof this === 'string') {
setCaptures(deserializeCaptures(container, this));
}
- const task = _captures![0] as Task;
+ const task = _capturesObj._![0] as Task;
task.$flags$ |= TaskFlags.DIRTY;
markVNodeDirty(container, task.$el$, ChoreBits.TASKS);
}
diff --git a/packages/qwik/src/core/use/use-visible-task-dollar.ts b/packages/qwik/src/core/use/use-visible-task-dollar.ts
index 6f40b84334f..1182ab01bc9 100644
--- a/packages/qwik/src/core/use/use-visible-task-dollar.ts
+++ b/packages/qwik/src/core/use/use-visible-task-dollar.ts
@@ -26,6 +26,14 @@ import { useVisibleTaskQrl, type OnVisibleTaskOptions } from './use-visible-task
* });
* ```
*
+ * Visible Tasks are a variant of Tasks that only run in the browser, and are registered but not
+ * executed during SSR. They are useful for running code that should only execute in the browser,
+ * such as code that interacts with the DOM or browser APIs.
+ *
+ * Cleanup callbacks registered with `cleanup()` or returned from the task may be async. When a
+ * visible task reruns, Qwik waits for the previous cleanup to finish before starting the next
+ * invocation.
+ *
* @public
*/
//
diff --git a/packages/qwik/src/server/platform.ts b/packages/qwik/src/server/platform.ts
index 76c8b2c0291..a542f76de44 100644
--- a/packages/qwik/src/server/platform.ts
+++ b/packages/qwik/src/server/platform.ts
@@ -1,7 +1,7 @@
import { setPlatform } from '@qwik.dev/core';
import { isDev } from '@qwik.dev/core/build';
import type { ResolvedManifest, SymbolMapperFn } from '@qwik.dev/core/optimizer';
-import { QError, qError, SYNC_QRL } from './qwik-copy';
+import { getSingleton, QError, qError, SYNC_QRL } from './qwik-copy';
import type { CorePlatformServer, SymbolMapper } from './qwik-types';
import type { SerializeDocumentOptions } from './types';
@@ -55,8 +55,8 @@ export function createPlatform(
if (hash === SYNC_QRL) {
return [hash, ''] as const;
}
- const isRegistered = (globalThis as any).__qwik_reg_symbols?.has(hash);
- if (isRegistered) {
+ const regSymbols = getSingleton>('regSymbols');
+ if (regSymbols?.has(hash)) {
return [symbolName, '_'] as const;
}
console.error('Cannot resolve symbol', symbolName, 'in', mapper, parent);
@@ -69,7 +69,7 @@ export function createPlatform(
isServer: true,
async importSymbol(_containerEl, url, symbolName) {
const hash = getSymbolHash(symbolName);
- const regSym = (globalThis as any).__qwik_reg_symbols?.get(hash);
+ const regSym = getSingleton>('regSymbols')?.get(hash);
if (regSym) {
return regSym;
}
diff --git a/packages/qwik/src/server/platform.unit.ts b/packages/qwik/src/server/platform.unit.ts
index 826cd8cf228..de88f23d96f 100644
--- a/packages/qwik/src/server/platform.unit.ts
+++ b/packages/qwik/src/server/platform.unit.ts
@@ -1,15 +1,17 @@
import { describe, test, expect, beforeEach, afterEach, vi } from 'vitest';
import { createPlatform, getSymbolHash } from './platform';
+// eslint-disable-next-line @typescript-eslint/no-restricted-imports
+import { _regSymbol } from '../core/shared/qrl/qrl';
describe('server platform', () => {
beforeEach(() => {
- // Initialize a fresh Map for each test to avoid pollution
- (globalThis as any).__qwik_reg_symbols = new Map();
+ // Initialize a fresh global Qwik state for each test to avoid pollution
+ (globalThis as any).__qwik = undefined;
});
afterEach(() => {
// Clean up global state
- delete (globalThis as any).__qwik_reg_symbols;
+ (globalThis as any).__qwik = undefined;
});
describe('importSymbol', () => {
@@ -20,7 +22,7 @@ describe('server platform', () => {
const symbolName = 'myComponent_abc123';
const hash = getSymbolHash(symbolName);
const mockFunction = () => 'mock component';
- (globalThis as any).__qwik_reg_symbols.set(hash, mockFunction);
+ _regSymbol(mockFunction, hash);
// importSymbol should return the registered symbol synchronously
const result = await platform.importSymbol(null as any, '', symbolName);
@@ -80,7 +82,7 @@ describe('server platform', () => {
const symbolName = 'my_component_with_underscores_abc123';
const hash = getSymbolHash(symbolName);
const mockFunction = () => 'mock';
- (globalThis as any).__qwik_reg_symbols.set(hash, mockFunction);
+ _regSymbol(mockFunction, hash);
const result = await platform.importSymbol(null as any, '', symbolName);
diff --git a/packages/qwik/src/server/qwik-copy.ts b/packages/qwik/src/server/qwik-copy.ts
index 9321dd64c14..b5934d75aae 100644
--- a/packages/qwik/src/server/qwik-copy.ts
+++ b/packages/qwik/src/server/qwik-copy.ts
@@ -71,6 +71,7 @@ export { ChoreBits } from '../core/shared/vnode/enums/chore-bits.enum';
export { isHtmlAttributeAnEventName, isPreventDefault } from '../core/shared/utils/event-names';
export { ITERATION_ITEM_SINGLE, ITERATION_ITEM_MULTI } from '../core/shared/utils/markers';
export { isObjectEmpty } from '../core/shared/utils/objects';
+export { getSingleton } from '../core/shared/singletons';
export {
LT,
GT,
diff --git a/packages/qwik/src/testing/platform.ts b/packages/qwik/src/testing/platform.ts
index e6f877cf257..6f75909a795 100644
--- a/packages/qwik/src/testing/platform.ts
+++ b/packages/qwik/src/testing/platform.ts
@@ -2,6 +2,7 @@ import type { TestPlatform } from './types';
import { existsSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { getSymbolHash } from '../core/shared/qrl/qrl-utils';
+import { getSingleton } from '../core/shared/singletons';
function createPlatform() {
const moduleCache = new Map();
@@ -9,7 +10,7 @@ function createPlatform() {
isServer: false,
importSymbol(containerEl, url, symbolName) {
const hash = getSymbolHash(symbolName);
- const regSym = (globalThis as any).__qwik_reg_symbols?.get(hash);
+ const regSym = getSingleton>('regSymbols')?.get(hash);
if (regSym) {
return regSym;
}
diff --git a/scripts/submodule-optimizer.ts b/scripts/submodule-optimizer.ts
index 6130a7e8e3a..52fcb0419ba 100644
--- a/scripts/submodule-optimizer.ts
+++ b/scripts/submodule-optimizer.ts
@@ -61,7 +61,12 @@ export async function submoduleOptimizer(config: BuildConfig) {
enforce: 'pre',
resolveId(id) {
// throws an error if files from src/core are loaded, except for some allowed imports
- if (/src[/\\]core[\\/]/.test(id) && !id.includes('util') && !id.includes('shared')) {
+ if (
+ /src[/\\]core[\\/]/.test(id) &&
+ !id.includes('util') &&
+ !id.includes('shared') &&
+ !id.includes('version')
+ ) {
console.error('forbid-core', id);
throw new Error('Import of core files is not allowed in server builds.');
}
diff --git a/scripts/submodule-server.ts b/scripts/submodule-server.ts
index b900e2b2850..f7f993e87ba 100644
--- a/scripts/submodule-server.ts
+++ b/scripts/submodule-server.ts
@@ -66,6 +66,7 @@ export async function submoduleServer(config: BuildConfig, nameCache?: object) {
args.path.includes('util') ||
args.path.includes('shared') ||
args.path.includes('ssr') ||
+ args.path.includes('version') ||
// we allow building preloader into server builds
args.path.includes('preloader')
) {