Skip to content

Commit ac997ba

Browse files
authored
Merge pull request #7730 from QwikDev/v2-fix-loaders-prod
fix: getting invoke context for loaders in production
2 parents 030bf10 + 3677a6c commit ac997ba

File tree

8 files changed

+63
-10
lines changed

8 files changed

+63
-10
lines changed

.changeset/heavy-maps-wash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik.dev/router': patch
3+
---
4+
5+
fix: getting invoke context for loaders in production
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { component$ } from '@qwik.dev/core';
2+
import { Link } from '@qwik.dev/router';
3+
4+
export default component$(() => {
5+
return (
6+
<>
7+
<Link id="subpage-link" href="/loaders/subpage">
8+
Sub page
9+
</Link>
10+
</>
11+
);
12+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { component$ } from '@qwik.dev/core';
2+
import { routeLoader$ } from '@qwik.dev/router';
3+
4+
export const useTest = routeLoader$(async () => {
5+
return 42;
6+
});
7+
8+
export default component$(() => {
9+
const loaded = useTest();
10+
11+
return (
12+
<>
13+
<h1>Sub page</h1>
14+
<p>This is the sub page.</p>
15+
<p id="subpage-loader-value">{loaded.value}</p>
16+
</>
17+
);
18+
});

e2e/adapters-e2e/tests/express.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,15 @@ test.describe('Verifying Express Adapter', () => {
2525

2626
await expect(page.getByRole('heading', { name: 'Profile page' })).toBeVisible();
2727
});
28+
29+
test('should load loaders context in minified prod mode', async ({ page }) => {
30+
page.goto('/loaders');
31+
const subpageLink = page.locator('#subpage-link');
32+
await expect(subpageLink).toBeVisible();
33+
34+
await subpageLink.click();
35+
36+
await expect(page.getByRole('heading', { name: 'Sub page' })).toBeVisible();
37+
await expect(page.locator('#subpage-loader-value')).toHaveText('42');
38+
});
2839
});

packages/qwik-router/src/runtime/src/server-functions.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
_getContextEvent,
1616
_serialize,
1717
_UNINITIALIZED,
18-
_useInvokeContext,
18+
_resolveContextWithoutSequentialScope,
1919
type SerializationStrategy,
2020
} from '@qwik.dev/core/internal';
2121

@@ -201,8 +201,7 @@ export const routeLoaderQrl = ((
201201
): LoaderInternal => {
202202
const { id, validators, serializationStrategy } = getValidators(rest, loaderQrl);
203203
function loader() {
204-
const iCtx = _useInvokeContext();
205-
const state = iCtx.$container$.resolveContext(iCtx.$hostElement$, RouteStateContext)!;
204+
const state = _resolveContextWithoutSequentialScope(RouteStateContext)!;
206205

207206
if (!(id in state)) {
208207
throw new Error(`routeLoader$ "${loaderQrl.getSymbol()}" was invoked in a route where it was not declared.

packages/qwik/src/core/internal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export {
5050
_getContextEvent,
5151
_getContextContainer,
5252
_jsxBranch,
53-
useInvokeContext as _useInvokeContext,
5453
_waitUntilRendered,
5554
} from './use/use-core';
5655
export { scheduleTask as _task } from './use/use-task';
56+
export { _resolveContextWithoutSequentialScope } from './use/use-context';

packages/qwik/src/core/qwik.core.api.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,9 @@ export interface RenderSSROptions {
804804
stream: StreamWriter;
805805
}
806806

807+
// @internal (undocumented)
808+
export const _resolveContextWithoutSequentialScope: <STATE>(context: ContextId<STATE>) => STATE | undefined;
809+
807810
// @public
808811
export const Resource: <T>(props: ResourceProps<T>) => JSXOutput;
809812

@@ -1691,11 +1694,6 @@ export const useErrorBoundary: () => ErrorBoundaryStore;
16911694
// @public (undocumented)
16921695
export const useId: () => string;
16931696

1694-
// Warning: (ae-forgotten-export) The symbol "RenderInvokeContext" needs to be exported by the entry point index.d.ts
1695-
//
1696-
// @internal (undocumented)
1697-
export const _useInvokeContext: () => RenderInvokeContext;
1698-
16991697
// Warning: (ae-internal-missing-underscore) The name "useLexicalScope" should be prefixed with an underscore because the declaration is marked as @internal
17001698
//
17011699
// @internal

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { QError, qError } from '../shared/error/error';
33
import { verifySerializable } from '../shared/utils/serialize-utils';
44
import { qDev, qSerialize } from '../shared/utils/qdev';
55
import { isObject } from '../shared/utils/types';
6-
import { invoke } from './use-core';
6+
import { getInvokeContext, invoke } from './use-core';
77
import { useSequentialScope } from './use-sequential-scope';
88
import { fromCamelToKebabCase } from '../shared/utils/event-names';
99

@@ -284,3 +284,13 @@ export const validateContext = (context: ContextId<any>) => {
284284
throw qError(QError.invalidContext, [context]);
285285
}
286286
};
287+
288+
/** @internal */
289+
export const _resolveContextWithoutSequentialScope = <STATE>(context: ContextId<STATE>) => {
290+
const iCtx = getInvokeContext();
291+
const hostElement = iCtx.$hostElement$;
292+
if (!hostElement) {
293+
return undefined;
294+
}
295+
return iCtx.$container$?.resolveContext(hostElement, context);
296+
};

0 commit comments

Comments
 (0)