Skip to content

Commit 7c21496

Browse files
authored
Merge pull request #7269 from QwikDev/remove-hW
refactor(core): schedule QRLs instead of direct execution
2 parents 6f4457d + 2d8dc0b commit 7c21496

File tree

97 files changed

+926
-928
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+926
-928
lines changed

.changeset/heavy-radios-dream.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik.dev/core': patch
3+
---
4+
5+
FIX: QRLs are now scheduled instead of directly executed by qwik-loader, so that they are executed in the right order.

.changeset/olive-cameras-collect.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik.dev/core': patch
3+
---
4+
5+
CHORE: replace the `_hW` export in segments with a shared export `_task` in core. This opens up using QRLs from core.

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ jobs:
221221
pnpm install --frozen-lockfile
222222
223223
- name: 'build: qwik'
224-
run: pnpm build --qwik --set-dist-tag="${{ needs.changes.outputs.disttag }}"
224+
run: pnpm build --qwik --insights --set-dist-tag="${{ needs.changes.outputs.disttag }}"
225225

226226
- name: Print Qwik Dist Build
227227
continue-on-error: true

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,20 +182,20 @@
182182
"build.clean": "rm -rf packages/qwik/dist/ && rm -rf packages/qwik-router/lib/ && rm -rf packages/docs/dist/ && rm -rf packages/insights/dist/",
183183
"build.cli": "tsx --require ./scripts/runBefore.ts scripts/index.ts --cli --dev",
184184
"build.cli.prod": "tsx --require ./scripts/runBefore.ts scripts/index.ts --cli",
185-
"build.core": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --build --qwikrouter --api --platform-binding",
185+
"build.core": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --qwik --insights --qwikrouter --api --platform-binding",
186186
"build.eslint": "tsx --require ./scripts/runBefore.ts scripts/index.ts --eslint",
187-
"build.full": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --tsc-docs --qwik --supabaseauthhelpers --api --eslint --qwikrouter --qwikworker --qwikreact --cli --platform-binding --wasm",
188-
"build.local": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --tsc-docs --qwik --supabaseauthhelpers --api --eslint --qwikrouter --qwikworker --qwikreact --cli --platform-binding-wasm-copy",
189-
"build.only_javascript": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --build --api",
187+
"build.full": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --tsc-docs --qwik --insights --supabaseauthhelpers --api --eslint --qwikrouter --qwikworker --qwikreact --cli --platform-binding --wasm",
188+
"build.local": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --tsc-docs --qwik --insights --supabaseauthhelpers --api --eslint --qwikrouter --qwikworker --qwikreact --cli --platform-binding-wasm-copy",
189+
"build.only_javascript": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --qwik --api",
190190
"build.packages.docs": "pnpm -C ./packages/docs/ run build",
191191
"build.packages.insights": "pnpm -C ./packages/insights/ run build",
192192
"build.platform": "tsx --require ./scripts/runBefore.ts scripts/index.ts --platform-binding",
193193
"build.platform.copy": "tsx --require ./scripts/runBefore.ts scripts/index.ts --platform-binding-wasm-copy",
194194
"build.qwik-router": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --qwikrouter",
195-
"build.validate": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --build --api --eslint --qwikrouter --platform-binding --wasm --validate",
196-
"build.vite": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --build --api --qwikrouter --eslint --platform-binding-wasm-copy",
195+
"build.validate": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --qwik --api --eslint --qwikrouter --platform-binding --wasm --validate",
196+
"build.vite": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --qwik --insights --api --qwikrouter --eslint --platform-binding-wasm-copy",
197197
"build.wasm": "tsx --require ./scripts/runBefore.ts scripts/index.ts --wasm",
198-
"build.watch": "tsx --require ./scripts/runBefore.ts scripts/index.ts --build --qwikrouter --watch --dev --platform-binding",
198+
"build.watch": "tsx --require ./scripts/runBefore.ts scripts/index.ts --qwik --qwikrouter --watch --dev --platform-binding",
199199
"change": "changeset",
200200
"cli": "pnpm build.cli && node packages/create-qwik/create-qwik.cjs && tsx --require ./scripts/runBefore.ts scripts/validate-cli.ts --copy-local-qwik-dist",
201201
"cli.qwik": "pnpm build.cli && node packages/qwik/qwik-cli.cjs",

packages/docs/src/routes/api/qwik/api.json

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -277,20 +277,6 @@
277277
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts",
278278
"mdFile": "core.domattributes.md"
279279
},
280-
{
281-
"name": "EagernessOptions",
282-
"id": "eagernessoptions",
283-
"hierarchy": [
284-
{
285-
"name": "EagernessOptions",
286-
"id": "eagernessoptions"
287-
}
288-
],
289-
"kind": "TypeAlias",
290-
"content": "```typescript\nexport type EagernessOptions = 'visible' | 'load' | 'idle';\n```",
291-
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts",
292-
"mdFile": "core.eagernessoptions.md"
293-
},
294280
{
295281
"name": "Element",
296282
"id": "qwikjsx-element",
@@ -2125,24 +2111,10 @@
21252111
}
21262112
],
21272113
"kind": "Function",
2128-
"content": "Reruns the `taskFn` when the observed inputs change.\n\nUse `useTask` to observe changes on a set of inputs, and then re-execute the `taskFn` when those inputs change.\n\nThe `taskFn` only executes if the observed inputs change. To observe the inputs, use the `obs` function to wrap property reads. This creates subscriptions that will trigger the `taskFn` to rerun.\n\n\n```typescript\nuseTask$: (qrl: import(\"./use-task\").TaskFn, opts?: import(\"./use-task\").UseTaskOptions | undefined) => void\n```\n\n\n<table><thead><tr><th>\n\nParameter\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\nqrl\n\n\n</td><td>\n\nimport(\"./use-task\").[TaskFn](#taskfn)\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\nopts\n\n\n</td><td>\n\nimport(\"./use-task\").[UseTaskOptions](#usetaskoptions) \\| undefined\n\n\n</td><td>\n\n_(Optional)_\n\n\n</td></tr>\n</tbody></table>\n**Returns:**\n\nvoid",
2114+
"content": "Reruns the `taskFn` when the observed inputs change.\n\nUse `useTask` to observe changes on a set of inputs, and then re-execute the `taskFn` when those inputs change.\n\nThe `taskFn` only executes if the observed inputs change. To observe the inputs, use the `obs` function to wrap property reads. This creates subscriptions that will trigger the `taskFn` to rerun.\n\n\n```typescript\nuseTask$: (qrl: import(\"./use-task\").TaskFn) => void\n```\n\n\n<table><thead><tr><th>\n\nParameter\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\nqrl\n\n\n</td><td>\n\nimport(\"./use-task\").[TaskFn](#taskfn)\n\n\n</td><td>\n\n\n</td></tr>\n</tbody></table>\n**Returns:**\n\nvoid",
21292115
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task-dollar.ts",
21302116
"mdFile": "core.usetask_.md"
21312117
},
2132-
{
2133-
"name": "UseTaskOptions",
2134-
"id": "usetaskoptions",
2135-
"hierarchy": [
2136-
{
2137-
"name": "UseTaskOptions",
2138-
"id": "usetaskoptions"
2139-
}
2140-
],
2141-
"kind": "Interface",
2142-
"content": "```typescript\nexport interface UseTaskOptions \n```\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[eagerness?](#)\n\n\n</td><td>\n\n\n</td><td>\n\n[EagernessOptions](#eagernessoptions)\n\n\n</td><td>\n\n_(Optional)_ - `visible`<!-- -->: run the effect when the element is visible. - `load`<!-- -->: eagerly run the effect when the application resumes.\n\n\n</td></tr>\n</tbody></table>",
2143-
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts",
2144-
"mdFile": "core.usetaskoptions.md"
2145-
},
21462118
{
21472119
"name": "useVisibleTask$",
21482120
"id": "usevisibletask_",

packages/docs/src/routes/api/qwik/index.md

Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -873,14 +873,6 @@ _(Optional)_
873873
874874
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts)
875875
876-
## EagernessOptions
877-
878-
```typescript
879-
export type EagernessOptions = "visible" | "load" | "idle";
880-
```
881-
882-
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts)
883-
884876
## Element
885877
886878
```typescript
@@ -5252,7 +5244,7 @@ Use `useTask` to observe changes on a set of inputs, and then re-execute the `ta
52525244
The `taskFn` only executes if the observed inputs change. To observe the inputs, use the `obs` function to wrap property reads. This creates subscriptions that will trigger the `taskFn` to rerun.
52535245
52545246
```typescript
5255-
useTask$: (qrl: import("./use-task").TaskFn, opts?: import("./use-task").UseTaskOptions | undefined) => void
5247+
useTask$: (qrl: import("./use-task").TaskFn) => void
52565248
```
52575249
52585250
<table><thead><tr><th>
@@ -5278,19 +5270,6 @@ import("./use-task").[TaskFn](#taskfn)
52785270
52795271
</td><td>
52805272
5281-
</td></tr>
5282-
<tr><td>
5283-
5284-
opts
5285-
5286-
</td><td>
5287-
5288-
import("./use-task").[UseTaskOptions](#usetaskoptions) \| undefined
5289-
5290-
</td><td>
5291-
5292-
_(Optional)_
5293-
52945273
</td></tr>
52955274
</tbody></table>
52965275
**Returns:**
@@ -5299,48 +5278,6 @@ void
52995278
53005279
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task-dollar.ts)
53015280
5302-
## UseTaskOptions
5303-
5304-
```typescript
5305-
export interface UseTaskOptions
5306-
```
5307-
5308-
<table><thead><tr><th>
5309-
5310-
Property
5311-
5312-
</th><th>
5313-
5314-
Modifiers
5315-
5316-
</th><th>
5317-
5318-
Type
5319-
5320-
</th><th>
5321-
5322-
Description
5323-
5324-
</th></tr></thead>
5325-
<tbody><tr><td>
5326-
5327-
[eagerness?](#)
5328-
5329-
</td><td>
5330-
5331-
</td><td>
5332-
5333-
[EagernessOptions](#eagernessoptions)
5334-
5335-
</td><td>
5336-
5337-
_(Optional)_ - `visible`: run the effect when the element is visible. - `load`: eagerly run the effect when the application resumes.
5338-
5339-
</td></tr>
5340-
</tbody></table>
5341-
5342-
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts)
5343-
53445281
## useVisibleTask$
53455282
53465283
```tsx

packages/qwik-router/src/runtime/src/link-component.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,7 @@ export const Link = component$<LinkProps>((props) => {
7373
? $(async (event: Event, elm: HTMLAnchorElement) => {
7474
if (event.defaultPrevented) {
7575
// If default was prevented, than it is up to us to make client side navigation.
76-
if (elm.hasAttribute('q:nbs')) {
77-
// Allow bootstrapping into useNavigate.
78-
await nav(location.href, { type: 'popstate' });
79-
} else if (elm.href) {
76+
if (elm.href) {
8077
elm.setAttribute('aria-pressed', 'true');
8178
await nav(elm.href, { forceReload: reload, replaceState, scroll });
8279
elm.removeAttribute('aria-pressed');

packages/qwik-router/src/runtime/src/qwik-router-component.tsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -624,9 +624,6 @@ export const QwikRouterProvider = component$<QwikRouterProps>((props) => {
624624
removeEventListener('scroll', win._qRouterInitScroll!);
625625
win._qRouterInitScroll = undefined;
626626

627-
win._qRouterBootstrap?.remove();
628-
win._qRouterBootstrap = undefined;
629-
630627
// Cache SPA recovery script.
631628
spaInit.resolve();
632629
}
@@ -760,8 +757,6 @@ export interface ClientSPAWindow extends Window {
760757
_qCityInitVisibility?: () => void;
761758
/** @deprecated Use "_qRouterInitScroll" instead. Will be removed in V3 */
762759
_qCityInitScroll?: () => void;
763-
/** @deprecated Use "_qRouterBootstrap" instead. Will be removed in V3 */
764-
_qCityBootstrap?: HTMLAnchorElement;
765760
_qRouterHistoryPatch?: boolean;
766761
_qRouterSPA?: boolean;
767762
_qRouterScrollEnabled?: boolean;
@@ -770,6 +765,5 @@ export interface ClientSPAWindow extends Window {
770765
_qRouterInitAnchors?: (event: MouseEvent) => void;
771766
_qRouterInitVisibility?: () => void;
772767
_qRouterInitScroll?: () => void;
773-
_qRouterBootstrap?: HTMLAnchorElement;
774768
_qcs?: boolean;
775769
}

packages/qwik-router/src/runtime/src/spa-init.ts

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import type { ContextId, DomContainer, _ContainerElement } from 'packages/qwik/core-internal';
12
import type { ClientSPAWindow } from './qwik-router-component';
23
import type { ScrollHistoryState } from './scroll-restoration';
3-
import type { ScrollState } from './types';
4+
import type { RouteNavigate, ScrollState } from './types';
45

56
import { event$, isDev } from '@qwik.dev/core';
67

@@ -30,7 +31,6 @@ export default event$((_: Event, el: Element) => {
3031
const currentPath = location.pathname + location.search;
3132

3233
const historyPatch = '_qRouterHistoryPatch';
33-
const bootstrap = '_qRouterBootstrap';
3434
const scrollEnabled = '_qRouterScrollEnabled';
3535
const debounceTimeout = '_qRouterScrollDebounce';
3636
const scrollHistory = '_qRouterScroll';
@@ -71,21 +71,17 @@ export default event$((_: Event, el: Element) => {
7171
if (currentPath !== location.pathname + location.search) {
7272
const getContainer = (el: Element) =>
7373
el.closest('[q\\:container]:not([q\\:container=html]):not([q\\:container=text])');
74-
// Hook into useNavigate context, if available.
75-
// We hijack a <Link> here, goes through the loader, resumes, app, etc. Simple.
76-
// TODO Will only work with <Link>, is there a better way?
77-
const link = getContainer(el)?.querySelector('a[q\\:link]');
78-
79-
if (link) {
80-
// Re-acquire container, link may be in a nested container.
81-
const container = getContainer(link)!;
82-
const bootstrapLink = link.cloneNode() as HTMLAnchorElement;
83-
bootstrapLink.setAttribute('q:nbs', '');
84-
bootstrapLink.style.display = 'none';
85-
86-
container.appendChild(bootstrapLink);
87-
win[bootstrap] = bootstrapLink;
88-
bootstrapLink.click();
74+
75+
const container = getContainer(el);
76+
const domContainer = (container as _ContainerElement).qContainer as DomContainer;
77+
const hostElement = domContainer.vNodeLocate(el);
78+
79+
const nav = domContainer?.resolveContext(hostElement, {
80+
id: 'qc--n',
81+
} as ContextId<RouteNavigate>);
82+
83+
if (nav) {
84+
nav(location.href, { type: 'popstate' });
8985
} else {
9086
// No useNavigate ctx available, fallback to reload.
9187
location.reload();

packages/qwik/handlers.mjs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* This re-exports the QRL handlers so that they can be used as QRLs.
3+
*
4+
* In vite dev mode, this file is referenced directly. This ensures that the correct path to core is
5+
* used so that there's only one instance of Qwik.
6+
*
7+
* Make sure that these handlers are listed in manifest.ts
8+
*/
9+
export { _run, _task } from '@qwik.dev/core';

packages/qwik/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"./cli": {
4242
"require": "./dist/cli.cjs"
4343
},
44+
"./handlers.mjs": "./handlers.mjs",
4445
"./internal": {
4546
"types": "./dist/core-internal.d.ts",
4647
"import": {
@@ -144,6 +145,7 @@
144145
"bindings",
145146
"build.d.ts",
146147
"cli.d.ts",
148+
"handlers.mjs",
147149
"jsx-dev-runtime.d.ts",
148150
"jsx-runtime.d.ts",
149151
"loader.d.ts",

packages/qwik/src/core/api.md

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -211,15 +211,14 @@ class DomContainer extends _SharedContainer implements ClientContainer {
211211
setContext<T>(host: HostElement, context: ContextId<T>, value: T): void;
212212
// (undocumented)
213213
setHostProp<T>(host: HostElement, name: string, value: T): void;
214+
// (undocumented)
215+
vNodeLocate: (id: string | Element) => _VNode;
214216
}
215217

216218
// Warning: (ae-internal-missing-underscore) The name "DomContainer" should be prefixed with an underscore because the declaration is marked as @internal
217219
export { DomContainer }
218220
export { DomContainer as _DomContainer }
219221

220-
// @public (undocumented)
221-
export type EagernessOptions = 'visible' | 'load' | 'idle';
222-
223222
// @internal (undocumented)
224223
export class _EffectData {
225224
constructor(data: NodePropData);
@@ -316,9 +315,6 @@ function h<TYPE extends string | FunctionComponent<PROPS>, PROPS extends {} = {}
316315
export { h as createElement }
317316
export { h }
318317

319-
// @internal
320-
export const _hW: () => void;
321-
322318
// @internal @deprecated (undocumented)
323319
export const _IMMUTABLE: unique symbol;
324320

@@ -810,6 +806,9 @@ export type ResourceReturn<T> = ResourcePending<T> | ResourceResolved<T> | Resou
810806
// @internal (undocumented)
811807
export const _restProps: (props: PropsProxy, omit: string[], target?: Props) => Props;
812808

809+
// @internal
810+
export const _run: (...args: unknown[]) => ValueOrPromise<void>;
811+
813812
// @internal
814813
export function _serialize(data: unknown[]): Promise<string>;
815814

@@ -999,6 +998,9 @@ export interface SyncQRL<TYPE extends Function = any> extends QRL<TYPE> {
999998
resolved: TYPE;
1000999
}
10011000

1001+
// @internal
1002+
export const _task: (_event: Event, element: Element) => void;
1003+
10021004
// @public (undocumented)
10031005
export interface TaskCtx {
10041006
// (undocumented)
@@ -1139,17 +1141,12 @@ export interface UseStylesScoped {
11391141
export const useStylesScopedQrl: (styles: QRL<string>) => UseStylesScoped;
11401142

11411143
// @public
1142-
export const useTask$: (qrl: TaskFn, opts?: UseTaskOptions | undefined) => void;
1143-
1144-
// @public (undocumented)
1145-
export interface UseTaskOptions {
1146-
eagerness?: EagernessOptions;
1147-
}
1144+
export const useTask$: (qrl: TaskFn) => void;
11481145

11491146
// Warning: (ae-internal-missing-underscore) The name "useTaskQrl" should be prefixed with an underscore because the declaration is marked as @internal
11501147
//
11511148
// @internal (undocumented)
1152-
export const useTaskQrl: (qrl: QRL<TaskFn>, opts?: UseTaskOptions) => void;
1149+
export const useTaskQrl: (qrl: QRL<TaskFn>) => void;
11531150

11541151
// @public
11551152
export const useVisibleTask$: (qrl: TaskFn, opts?: OnVisibleTaskOptions | undefined) => void;
@@ -1236,17 +1233,9 @@ export const _waitUntilRendered: (elm: Element) => Promise<void>;
12361233
//
12371234
// @internal (undocumented)
12381235
export function _walkJSX(ssr: SSRContainer, value: JSXOutput, options: {
1239-
allowPromises: true;
1240-
currentStyleScoped: string | null;
1241-
parentComponentFrame: ISsrComponentFrame | null;
1242-
}): ValueOrPromise<void>;
1243-
1244-
// @internal (undocumented)
1245-
export function _walkJSX(ssr: SSRContainer, value: JSXOutput, options: {
1246-
allowPromises: false;
12471236
currentStyleScoped: string | null;
12481237
parentComponentFrame: ISsrComponentFrame | null;
1249-
}): false;
1238+
}): Promise<void>;
12501239

12511240
// @internal (undocumented)
12521241
export const _weakSerialize: <T extends object>(input: T) => Partial<T>;

0 commit comments

Comments
 (0)