Skip to content

Commit 9b49920

Browse files
committed
chore(core): support finding qrl through dev data WIP
needs to support the absolute path and ?qrl= query
1 parent ecec8a9 commit 9b49920

28 files changed

Lines changed: 405 additions & 226 deletions

flake.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@
644644
}
645645
],
646646
"kind": "TypeAlias",
647-
"content": "```typescript\nexport type SymbolMapperFn = (symbolName: string, mapper: SymbolMapper | undefined) => readonly [symbol: string, chunk: string] | undefined;\n```\n**References:** [SymbolMapper](#symbolmapper)",
647+
"content": "```typescript\nexport type SymbolMapperFn = (symbolName: string, mapper: SymbolMapper | undefined, parent?: string) => readonly [symbol: string, chunk: string] | undefined;\n```\n**References:** [SymbolMapper](#symbolmapper)",
648648
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/optimizer/src/types.ts",
649649
"mdFile": "qwik.symbolmapperfn.md"
650650
},

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2768,6 +2768,7 @@ export type SymbolMapper = Record<
27682768
export type SymbolMapperFn = (
27692769
symbolName: string,
27702770
mapper: SymbolMapper | undefined,
2771+
parent?: string,
27712772
) => readonly [symbol: string, chunk: string] | undefined;
27722773
```
27732774

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@
544544
}
545545
],
546546
"kind": "Interface",
547-
"content": "Low-level API for platform abstraction.\n\nDifferent platforms (browser, node, service workers) may have different ways of handling things such as `requestAnimationFrame` and imports. To make Qwik platform-independent Qwik uses the `CorePlatform` API to access the platform API.\n\n`CorePlatform` also is responsible for importing symbols. The import map is different on the client (browser) then on the server. For this reason, the server has a manifest that is used to map symbols to javascript chunks. The manifest is encapsulated in `CorePlatform`<!-- -->, for this reason, the `CorePlatform` can't be global as there may be multiple applications running at server concurrently.\n\nThis is a low-level API and there should not be a need for you to access this.\n\n\n```typescript\nexport interface CorePlatform \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[chunkForSymbol](#)\n\n\n</td><td>\n\n\n</td><td>\n\n(symbolName: string, chunk: string \\| null) =&gt; readonly \\[symbol: string, chunk: string\\] \\| undefined\n\n\n</td><td>\n\nRetrieve chunk name for the symbol.\n\nWhen the application is running on the server the symbols may be imported from different files (as server build is typically a single javascript chunk.) For this reason, it is necessary to convert the chunks from server format to client (browser) format. This is done by looking up symbols (which are globally unique) in the manifest. (Manifest is the mapping of symbols to the client chunk names.)\n\n\n</td></tr>\n<tr><td>\n\n[importSymbol](#)\n\n\n</td><td>\n\n\n</td><td>\n\n(containerEl: Element \\| undefined, url: string \\| URL \\| undefined \\| null, symbol: string) =&gt; [ValueOrPromise](#valueorpromise)<!-- -->&lt;any&gt;\n\n\n</td><td>\n\nRetrieve a symbol value from QRL.\n\nQwik needs to lazy load data and closures. For this Qwik uses QRLs that are serializable references of resources that are needed. The QRLs contain all the information necessary to retrieve the reference using `importSymbol`<!-- -->.\n\nWhy not use `import()`<!-- -->? Because `import()` is relative to the current file, and the current file is always the Qwik framework. So QRLs have additional information that allows them to serialize imports relative to application base rather than the Qwik framework file.\n\n\n</td></tr>\n<tr><td>\n\n[isServer](#)\n\n\n</td><td>\n\n\n</td><td>\n\nboolean\n\n\n</td><td>\n\nTrue of running on the server platform.\n\n\n</td></tr>\n<tr><td>\n\n[nextTick](#)\n\n\n</td><td>\n\n\n</td><td>\n\n(fn: () =&gt; any) =&gt; Promise&lt;any&gt;\n\n\n</td><td>\n\nPerform operation on next tick.\n\n\n</td></tr>\n<tr><td>\n\n[raf](#)\n\n\n</td><td>\n\n\n</td><td>\n\n(fn: () =&gt; any) =&gt; Promise&lt;any&gt;\n\n\n</td><td>\n\nPerform operation on next request-animation-frame.\n\n\n</td></tr>\n</tbody></table>",
547+
"content": "Low-level API for platform abstraction.\n\nDifferent platforms (browser, node, service workers) may have different ways of handling things such as `requestAnimationFrame` and imports. To make Qwik platform-independent Qwik uses the `CorePlatform` API to access the platform API.\n\n`CorePlatform` also is responsible for importing symbols. The import map is different on the client (browser) then on the server. For this reason, the server has a manifest that is used to map symbols to javascript chunks. The manifest is encapsulated in `CorePlatform`<!-- -->, for this reason, the `CorePlatform` can't be global as there may be multiple applications running at server concurrently.\n\nThis is a low-level API and there should not be a need for you to access this.\n\n\n```typescript\nexport interface CorePlatform \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[chunkForSymbol](#)\n\n\n</td><td>\n\n\n</td><td>\n\n(symbolName: string, chunk: string \\| null, parent?: string) =&gt; readonly \\[symbol: string, chunk: string\\] \\| undefined\n\n\n</td><td>\n\nRetrieve chunk name for the symbol.\n\nWhen the application is running on the server the symbols may be imported from different files (as server build is typically a single javascript chunk.) For this reason, it is necessary to convert the chunks from server format to client (browser) format. This is done by looking up symbols (which are globally unique) in the manifest. (Manifest is the mapping of symbols to the client chunk names.)\n\n\n</td></tr>\n<tr><td>\n\n[importSymbol](#)\n\n\n</td><td>\n\n\n</td><td>\n\n(containerEl: Element \\| undefined, url: string \\| URL \\| undefined \\| null, symbol: string) =&gt; [ValueOrPromise](#valueorpromise)<!-- -->&lt;any&gt;\n\n\n</td><td>\n\nRetrieve a symbol value from QRL.\n\nQwik needs to lazy load data and closures. For this Qwik uses QRLs that are serializable references of resources that are needed. The QRLs contain all the information necessary to retrieve the reference using `importSymbol`<!-- -->.\n\nWhy not use `import()`<!-- -->? Because `import()` is relative to the current file, and the current file is always the Qwik framework. So QRLs have additional information that allows them to serialize imports relative to application base rather than the Qwik framework file.\n\n\n</td></tr>\n<tr><td>\n\n[isServer](#)\n\n\n</td><td>\n\n\n</td><td>\n\nboolean\n\n\n</td><td>\n\nTrue of running on the server platform.\n\n\n</td></tr>\n<tr><td>\n\n[nextTick](#)\n\n\n</td><td>\n\n\n</td><td>\n\n(fn: () =&gt; any) =&gt; Promise&lt;any&gt;\n\n\n</td><td>\n\nPerform operation on next tick.\n\n\n</td></tr>\n<tr><td>\n\n[raf](#)\n\n\n</td><td>\n\n\n</td><td>\n\n(fn: () =&gt; any) =&gt; Promise&lt;any&gt;\n\n\n</td><td>\n\nPerform operation on next request-animation-frame.\n\n\n</td></tr>\n</tbody></table>",
548548
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/platform/types.ts",
549549
"mdFile": "qwik.coreplatform.md"
550550
},
@@ -1760,7 +1760,7 @@
17601760
}
17611761
],
17621762
"kind": "Function",
1763-
"content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nLoad the prefetch graph for the container.\n\nEach Qwik container needs to include its own prefetch graph.\n\n\n```typescript\nPrefetchGraph: (opts?: {\n base?: string;\n manifestHash?: string;\n manifestURL?: string;\n nonce?: string;\n}) => JSXNode<\"script\">\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\nopts\n\n\n</td><td>\n\n{ base?: string; manifestHash?: string; manifestURL?: string; nonce?: string; }\n\n\n</td><td>\n\n_(Optional)_ Options for the loading prefetch graph.\n\n- `base` - Base of the graph. For a default installation this will default to `/build/`<!-- -->. But if more than one MFE is installed on the page, then each MFE needs to have its own base. - `manifestHash` - Hash of the manifest file to load. If not provided the hash will be extracted from the container attribute `q:manifest-hash` and assume the default build file `${base}/q-bundle-graph-${manifestHash}.json`<!-- -->. - `manifestURL` - URL of the manifest file to load if non-standard bundle graph location name.\n\n\n</td></tr>\n</tbody></table>\n**Returns:**\n\nJSXNode&lt;\"script\"&gt;",
1763+
"content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nLoad the prefetch graph for the container.\n\nEach Qwik container needs to include its own prefetch graph.\n\n\n```typescript\nPrefetchGraph: (opts?: {\n base?: string;\n manifestHash?: string;\n manifestURL?: string;\n nonce?: string;\n}) => JSXNode<\"script\">\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\nopts\n\n\n</td><td>\n\n{ base?: string; manifestHash?: string; manifestURL?: string; nonce?: string; }\n\n\n</td><td>\n\n_(Optional)_ Options for the loading prefetch graph.\n\n- `base` - Base of the graph. For a default installation this will default to `/build/`<!-- -->. But if more than one MFE is installed on the page, then each MFE needs to have its own base. - `manifestHash` - Hash of the manifest file to load. If not provided the hash will be extracted from the container attribute `q:manifest-hash` and assume the default build file `${base}/q-bundle-graph-${manifestHash}.json`<!-- -->. - `manifestURL` - URL of the manifest file to load if non-standard bundle graph location name.\n\n\n</td></tr>\n</tbody></table>\n**Returns:**\n\n[JSXNode](#jsxnode)<!-- -->&lt;\"script\"&gt;",
17641764
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/components/prefetch.ts",
17651765
"mdFile": "qwik.prefetchgraph.md"
17661766
},
@@ -1774,7 +1774,7 @@
17741774
}
17751775
],
17761776
"kind": "Function",
1777-
"content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nInstall a service worker which will prefetch the bundles.\n\nThere can only be one service worker per page. Because there can be many separate Qwik Containers on the page each container needs to load its prefetch graph using `PrefetchGraph` component.\n\n\n```typescript\nPrefetchServiceWorker: (opts: {\n base?: string;\n scope?: string;\n path?: string;\n verbose?: boolean;\n fetchBundleGraph?: boolean;\n nonce?: string;\n}) => JSXNode<'script'>\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\nopts\n\n\n</td><td>\n\n{ base?: string; scope?: string; path?: string; verbose?: boolean; fetchBundleGraph?: boolean; nonce?: string; }\n\n\n</td><td>\n\nOptions for the prefetch service worker.\n\n- `base` - Base URL for the service worker `import.meta.env.BASE_URL` or `/`<!-- -->. Default is `import.meta.env.BASE_URL` - `scope` - Base URL for when the service-worker will activate. Default is `/` - `path` - Path to the service worker. Default is `qwik-prefetch-service-worker.js` unless you pass a path that starts with a `/` then the base is ignored. Default is `qwik-prefetch-service-worker.js` - `verbose` - Verbose logging for the service worker installation. Default is `false` - `nonce` - Optional nonce value for security purposes, defaults to `undefined`<!-- -->.\n\n\n</td></tr>\n</tbody></table>\n**Returns:**\n\nJSXNode&lt;'script'&gt;",
1777+
"content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nInstall a service worker which will prefetch the bundles.\n\nThere can only be one service worker per page. Because there can be many separate Qwik Containers on the page each container needs to load its prefetch graph using `PrefetchGraph` component.\n\n\n```typescript\nPrefetchServiceWorker: (opts: {\n base?: string;\n scope?: string;\n path?: string;\n verbose?: boolean;\n fetchBundleGraph?: boolean;\n nonce?: string;\n}) => JSXNode<'script'>\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\nopts\n\n\n</td><td>\n\n{ base?: string; scope?: string; path?: string; verbose?: boolean; fetchBundleGraph?: boolean; nonce?: string; }\n\n\n</td><td>\n\nOptions for the prefetch service worker.\n\n- `base` - Base URL for the service worker `import.meta.env.BASE_URL` or `/`<!-- -->. Default is `import.meta.env.BASE_URL` - `scope` - Base URL for when the service-worker will activate. Default is `/` - `path` - Path to the service worker. Default is `qwik-prefetch-service-worker.js` unless you pass a path that starts with a `/` then the base is ignored. Default is `qwik-prefetch-service-worker.js` - `verbose` - Verbose logging for the service worker installation. Default is `false` - `nonce` - Optional nonce value for security purposes, defaults to `undefined`<!-- -->.\n\n\n</td></tr>\n</tbody></table>\n**Returns:**\n\n[JSXNode](#jsxnode)<!-- -->&lt;'script'&gt;",
17781778
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/components/prefetch.ts",
17791779
"mdFile": "qwik.prefetchserviceworker.md"
17801780
},

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,7 +1558,7 @@ Description
15581558
15591559
</td><td>
15601560
1561-
(symbolName: string, chunk: string \| null) =&gt; readonly [symbol: string, chunk: string] \| undefined
1561+
(symbolName: string, chunk: string \| null, parent?: string) =&gt; readonly [symbol: string, chunk: string] \| undefined
15621562
15631563
</td><td>
15641564
@@ -3617,7 +3617,7 @@ _(Optional)_ Options for the loading prefetch graph.
36173617
</tbody></table>
36183618
**Returns:**
36193619
3620-
JSXNode&lt;"script"&gt;
3620+
[JSXNode](#jsxnode)&lt;"script"&gt;
36213621
36223622
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/components/prefetch.ts)
36233623
@@ -3671,7 +3671,7 @@ Options for the prefetch service worker.
36713671
</tbody></table>
36723672
**Returns:**
36733673
3674-
JSXNode&lt;'script'&gt;
3674+
[JSXNode](#jsxnode)&lt;'script'&gt;
36753675
36763676
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/components/prefetch.ts)
36773677

packages/qwik/src/core/api.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export interface ContextId<STATE> {
142142

143143
// @public
144144
export interface CorePlatform {
145-
chunkForSymbol: (symbolName: string, chunk: string | null) => readonly [symbol: string, chunk: string] | undefined;
145+
chunkForSymbol: (symbolName: string, chunk: string | null, parent?: string) => readonly [symbol: string, chunk: string] | undefined;
146146
importSymbol: (containerEl: Element | undefined, url: string | URL | undefined | null, symbol: string) => ValueOrPromise<any>;
147147
isServer: boolean;
148148
nextTick: (fn: () => any) => Promise<any>;
@@ -542,6 +542,9 @@ export type NativeWheelEvent = WheelEvent;
542542
// @internal (undocumented)
543543
export const _noopQrl: <T>(symbolName: string, lexicalScopeCapture?: any[]) => QRL<T>;
544544

545+
// @internal (undocumented)
546+
export const _noopQrlDEV: <T>(symbolName: string, opts: QRLDev, lexicalScopeCapture?: any[]) => QRL<T>;
547+
545548
// @public
546549
export type NoSerialize<T> = (T & {
547550
__no_serialize__: true;

packages/qwik/src/core/internal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export { _pauseFromContexts, _serializeData } from './container/pause';
2-
export { _noopQrl, _regSymbol } from './qrl/qrl';
2+
export { _noopQrl, _noopQrlDEV, _regSymbol } from './qrl/qrl';
33
export { _renderSSR } from './render/ssr/render-ssr';
44
export { _hW } from './render/dom/notify-render';
55
export { _wrapSignal, _wrapProp } from './state/signal';

packages/qwik/src/core/platform/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ export interface CorePlatform {
9797
// </docs>
9898
chunkForSymbol: (
9999
symbolName: string,
100-
chunk: string | null
100+
chunk: string | null,
101+
parent?: string
101102
) => readonly [symbol: string, chunk: string] | undefined;
102103
}
103104

packages/qwik/src/core/qrl/qrl.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,17 @@ export const _noopQrl = <T>(
124124
return createQRL<T>(null, symbolName, null, null, null, lexicalScopeCapture, null);
125125
};
126126

127+
/** @internal */
128+
export const _noopQrlDEV = <T>(
129+
symbolName: string,
130+
opts: QRLDev,
131+
lexicalScopeCapture: any[] = EMPTY_ARRAY
132+
): QRL<T> => {
133+
const newQrl = _noopQrl(symbolName, lexicalScopeCapture) as QRLInternal<T>;
134+
newQrl.dev = opts;
135+
return newQrl;
136+
};
137+
127138
/** @internal */
128139
export const qrlDEV = <T = any>(
129140
chunkOrFn: string | (() => Promise<any>),
@@ -163,12 +174,15 @@ export const serializeQRL = (qrl: QRLInternal, opts: QRLSerializeOptions = {}) =
163174
const platform = getPlatform();
164175

165176
if (platform) {
166-
const result = platform.chunkForSymbol(refSymbol, chunk);
177+
const result = platform.chunkForSymbol(refSymbol, chunk, qrl.dev?.file);
178+
console.log('serializeQRL', { refSymbol, symbol, chunk, result, dev: qrl.dev });
167179
if (result) {
168180
chunk = result[1];
169181
if (!qrl.$refSymbol$) {
170182
symbol = result[0];
171183
}
184+
} else {
185+
console.error('serializeQRL: Cannot resolve symbol', symbol, 'in', chunk, qrl.dev?.file);
172186
}
173187
}
174188

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,10 @@ const getTaskHandlerQrl = (task: SubscriberEffect): QRL<(ev: Event) => void> =>
792792
[task],
793793
taskQrl.$symbol$
794794
);
795+
// Needed for chunk lookup in dev mode
796+
if (taskQrl.dev) {
797+
taskHandler.dev = taskQrl.dev;
798+
}
795799
return taskHandler;
796800
};
797801

0 commit comments

Comments
 (0)