diff --git a/.REFACTOR_NOTES.md b/.REFACTOR_NOTES.md new file mode 100644 index 00000000000..94fe1b685c5 --- /dev/null +++ b/.REFACTOR_NOTES.md @@ -0,0 +1,44 @@ +1 << 0 | 001 | static listeners +1 << 1 | 002 | static subtree + +## Slots + +```typescript +const Parent = component$(() => { + return ( + + Projection Content + Secondary Content + Other Content + + }; +}); + +const Child = component$(() => { + return ( +
+ Default Primary + Default Secondary +
+ ); +}); +``` + +```html + + +
+ + Projected Content + + + + Secondary Content + +
+
+ +
+``` diff --git a/.changeset/afraid-bags-jam.md b/.changeset/afraid-bags-jam.md new file mode 100644 index 00000000000..fc00f500181 --- /dev/null +++ b/.changeset/afraid-bags-jam.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: Resource without onPending callback diff --git a/.changeset/afraid-garlics-greet.md b/.changeset/afraid-garlics-greet.md new file mode 100644 index 00000000000..bc9283e30da --- /dev/null +++ b/.changeset/afraid-garlics-greet.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: don't escape value attribute diff --git a/.changeset/angry-grapes-itch.md b/.changeset/angry-grapes-itch.md new file mode 100644 index 00000000000..a4af4b3c5d7 --- /dev/null +++ b/.changeset/angry-grapes-itch.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: rendering attribute value from array of classes from spread props diff --git a/.changeset/blue-beans-happen.md b/.changeset/blue-beans-happen.md new file mode 100644 index 00000000000..2767fb83652 --- /dev/null +++ b/.changeset/blue-beans-happen.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/router': patch +--- + +fix: using routeLoader$ result as component prop diff --git a/.changeset/brave-files-grin.md b/.changeset/brave-files-grin.md new file mode 100644 index 00000000000..7b1e6c2bb05 --- /dev/null +++ b/.changeset/brave-files-grin.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: reduced number of errors "Cannot serialize function" during serialization diff --git a/.changeset/brown-ravens-behave.md b/.changeset/brown-ravens-behave.md new file mode 100644 index 00000000000..2753f83f5e3 --- /dev/null +++ b/.changeset/brown-ravens-behave.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: updating signal-based props diff --git a/.changeset/calm-cycles-know.md b/.changeset/calm-cycles-know.md new file mode 100644 index 00000000000..1b0fc3ab1a1 --- /dev/null +++ b/.changeset/calm-cycles-know.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: serialization of an array of refs diff --git a/.changeset/chilled-spoons-wonder.md b/.changeset/chilled-spoons-wonder.md new file mode 100644 index 00000000000..262ae2d7438 --- /dev/null +++ b/.changeset/chilled-spoons-wonder.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: prevent multiple store deserialization diff --git a/.changeset/chilly-fans-shave.md b/.changeset/chilly-fans-shave.md new file mode 100644 index 00000000000..dba9d9d3c20 --- /dev/null +++ b/.changeset/chilly-fans-shave.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: don't wrap template literals with a function call inside them in a signal diff --git a/.changeset/clever-flowers-drum.md b/.changeset/clever-flowers-drum.md new file mode 100644 index 00000000000..f9d34076769 --- /dev/null +++ b/.changeset/clever-flowers-drum.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: using ref inside useContext diff --git a/.changeset/cold-moons-follow.md b/.changeset/cold-moons-follow.md new file mode 100644 index 00000000000..3a97ce6fcc6 --- /dev/null +++ b/.changeset/cold-moons-follow.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: infinity loop while tracking element ref diff --git a/.changeset/config.json b/.changeset/config.json index e45f374add7..9522e2b7f2f 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -2,19 +2,14 @@ "$schema": "https://unpkg.com/@changesets/config@3.0.1/schema.json", "changelog": ["./changelog-github-custom.cjs", { "repo": "QwikDev/qwik" }], "commit": false, - "fixed": [["@builder.io/qwik", "@builder.io/qwik-city", "eslint-plugin-qwik", "create-qwik"]], + "fixed": [ + ["@qwik.dev/core", "@qwik.dev/router", "eslint-plugin-qwik", "create-qwik", "@qwik.dev/react"] + ], "linked": [], "access": "public", - "baseBranch": "origin/upcoming", + "baseBranch": "origin/build/v2", "updateInternalDependencies": "minor", - "ignore": [ - "qwik-docs", - "@builder.io/qwik-labs", - "insights", - "@builder.io/qwik-react", - "@builder.io/qwik-worker", - "qwik-cli-e2e" - ], + "ignore": ["qwik-docs", "insights", "qwik-cli-e2e"], "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { "onlyUpdatePeerDependentsWhenOutOfRange": true } diff --git a/.changeset/cyan-bottles-speak.md b/.changeset/cyan-bottles-speak.md new file mode 100644 index 00000000000..fcdcf0536a7 --- /dev/null +++ b/.changeset/cyan-bottles-speak.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: creating error overlay diff --git a/.changeset/dirty-lemons-shop.md b/.changeset/dirty-lemons-shop.md new file mode 100644 index 00000000000..5d8e229f1a1 --- /dev/null +++ b/.changeset/dirty-lemons-shop.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: reexecute component with null key diff --git a/.changeset/easy-boxes-win.md b/.changeset/easy-boxes-win.md deleted file mode 100644 index a1b9be406d1..00000000000 --- a/.changeset/easy-boxes-win.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'create-qwik': patch ---- - -fix: create-qwik logAppCreated.ts now displays correct next steps for deno. - -After using the create-qwik command, the logAppCreated.ts file was not displaying the correct next steps for deno. Prior to this fix it would display "deno start" instead of "deno task start". This would cause a failure to run, as deno requires the 'task' keyword. This fixes bug 7520 diff --git a/.changeset/eighty-ligers-wink.md b/.changeset/eighty-ligers-wink.md new file mode 100644 index 00000000000..0e5e73b1ac3 --- /dev/null +++ b/.changeset/eighty-ligers-wink.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: correctly handle initial resource state diff --git a/.changeset/every-humans-kiss.md b/.changeset/every-humans-kiss.md deleted file mode 100644 index 743db2f4eca..00000000000 --- a/.changeset/every-humans-kiss.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'eslint-plugin-qwik': minor ---- - -FEAT: our eslint plugin now supports eslint 9 diff --git a/.changeset/fair-cameras-boil.md b/.changeset/fair-cameras-boil.md new file mode 100644 index 00000000000..da52dcd02a7 --- /dev/null +++ b/.changeset/fair-cameras-boil.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: change client side generated ID to start with build base and add convert first character to letter if it is starting from number diff --git a/.changeset/fair-cars-fry.md b/.changeset/fair-cars-fry.md deleted file mode 100644 index 7383613d711..00000000000 --- a/.changeset/fair-cars-fry.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -'@builder.io/qwik': minor ---- - -FEAT: Major improvements to prefetching with automatic bundle preloading - -- This removes the need for service workers, and instead utilize `modulepreload` link tags for better browser integration. -- Improves initial load performance by including dynamic imports in the prefetch -- Reduces complexity while maintaining similar (and even better) functionality -- Enables some preloading capabilities in dev mode (SSR result only) -- Includes path-to-bundle mapping in bundle graph (this improves the experience using the `` component, AKA "single page app" mode) -- Server now has built-in manifest support (so no need to pass `manifest` around) -- Moves insights-related build code to insights plugin - ---- - -⚠️ **ATTENTION:** - -- **Keep** your service worker code as is (either `` or ``). -- **Configure** your server to provide long caching headers. - -Service Worker: - -This new implementation will use it to uninstall the current service worker to reduce the unnecessary duplication. - -The builtin service workers components are deprecated but still exist for backwards compatibility. - -Caching Headers: - -The files under build/ and assets/ are named with their content hash and may therefore be cached indefinitely. Typically you should serve `build/*` and `assets/*` with `Cache-Control: public, max-age=31536000, immutable`. - -However, if you changed the rollup configuration for output filenames, you will have to adjust the caching configuration accordingly. - ---- - -You can configure the preload behavior in your SSR configuration: - -```ts -// entry.ssr.ts -export default function (opts: RenderToStreamOptions) { - return renderToStream(, { - preload: { - // Enable debug logging for preload operations - debug: true, - // Maximum simultaneous preload links - maxBufferedPreloads: 5, - // Minimum probability threshold for preloading - preloadProbability: 0.25 - // ...and more, see the type JSDoc on hover - }, - ...opts, - }); -} -``` - -For legacy apps that still need service worker functionality, you can add it back using: - -```bash -npm run qwik add service-worker -``` - -This will add a basic service worker setup that you can customize for specific caching strategies, offline support, or other PWA features beyond just prefetching. diff --git a/.changeset/fast-baboons-itch.md b/.changeset/fast-baboons-itch.md new file mode 100644 index 00000000000..c143d2a6e8a --- /dev/null +++ b/.changeset/fast-baboons-itch.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': major +--- + +BREAKING: remove HTML-related types. Use PropsOf instead. diff --git a/.changeset/few-mugs-accept.md b/.changeset/few-mugs-accept.md new file mode 100644 index 00000000000..6f9ca38be04 --- /dev/null +++ b/.changeset/few-mugs-accept.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: null or undefined as ref attribute value diff --git a/.changeset/five-kangaroos-matter.md b/.changeset/five-kangaroos-matter.md new file mode 100644 index 00000000000..caa63e24785 --- /dev/null +++ b/.changeset/five-kangaroos-matter.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': major +--- + +💥**BREAKING**: `useComputed` no longer allows Promise returns. (meaning it is strictly sync) Instead, use `useSignal` and `useTask` together to perform async signal updates diff --git a/.changeset/five-shoes-deny.md b/.changeset/five-shoes-deny.md new file mode 100644 index 00000000000..83e3fb8cfa1 --- /dev/null +++ b/.changeset/five-shoes-deny.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: prevent infinity loop by inserting the same projection before itself diff --git a/.changeset/fluffy-poets-raise.md b/.changeset/fluffy-poets-raise.md new file mode 100644 index 00000000000..55c0e6bf676 --- /dev/null +++ b/.changeset/fluffy-poets-raise.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: custom event names and DOMContentLoaded handling diff --git a/.changeset/forty-garlics-train.md b/.changeset/forty-garlics-train.md new file mode 100644 index 00000000000..b45123a890d --- /dev/null +++ b/.changeset/forty-garlics-train.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: store effects cleanup diff --git a/.changeset/fresh-rocks-exercise.md b/.changeset/fresh-rocks-exercise.md new file mode 100644 index 00000000000..28ff44c88d0 --- /dev/null +++ b/.changeset/fresh-rocks-exercise.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': minor +--- + +feat: new integration tests that are running with the optimizer diff --git a/.changeset/friendly-beers-heal.md b/.changeset/friendly-beers-heal.md new file mode 100644 index 00000000000..489f8b4107e --- /dev/null +++ b/.changeset/friendly-beers-heal.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: attribute diffing was not working correctly in some edge cases diff --git a/.changeset/friendly-gorillas-walk.md b/.changeset/friendly-gorillas-walk.md new file mode 100644 index 00000000000..803223e3e70 --- /dev/null +++ b/.changeset/friendly-gorillas-walk.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +FIX: types error when migrating to V2 with `moduleResulution: "node"` diff --git a/.changeset/friendly-sloths-return.md b/.changeset/friendly-sloths-return.md new file mode 100644 index 00000000000..f3cda8ab3a2 --- /dev/null +++ b/.changeset/friendly-sloths-return.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: projection siblings serialization diff --git a/.changeset/funny-apricots-learn.md b/.changeset/funny-apricots-learn.md new file mode 100644 index 00000000000..4fb9c305ffb --- /dev/null +++ b/.changeset/funny-apricots-learn.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: moving existing virtual node during vnode diffing diff --git a/.changeset/fuzzy-jobs-compare.md b/.changeset/fuzzy-jobs-compare.md new file mode 100644 index 00000000000..5b55fe46fe0 --- /dev/null +++ b/.changeset/fuzzy-jobs-compare.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: component props as var props diff --git a/.changeset/gentle-bats-thank.md b/.changeset/gentle-bats-thank.md deleted file mode 100644 index a6f5d56a5bc..00000000000 --- a/.changeset/gentle-bats-thank.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@builder.io/qwik-city': minor ---- - -FIX: qwik-city no longer forces `q-data.json` downloads, instead relying on the cache headers. This means that you have to make sure your `q-data.json` is served with `Cache-Control` headers that suit you. That file contains all the information about the route and is read for each qwik-city navigation. By default the data is cached for one hour. diff --git a/.changeset/gentle-melons-pretend.md b/.changeset/gentle-melons-pretend.md new file mode 100644 index 00000000000..9d490c6017c --- /dev/null +++ b/.changeset/gentle-melons-pretend.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: convert destructured string prop to props variable diff --git a/.changeset/giant-carpets-brake.md b/.changeset/giant-carpets-brake.md deleted file mode 100644 index ee5a6e42808..00000000000 --- a/.changeset/giant-carpets-brake.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'create-qwik': patch -'@builder.io/qwik-city': patch -'@builder.io/qwik': patch ---- - -Fix linting errors which were previously being ignored across the monorepo. diff --git a/.changeset/good-tables-rush.md b/.changeset/good-tables-rush.md new file mode 100644 index 00000000000..e17a3d253fd --- /dev/null +++ b/.changeset/good-tables-rush.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': minor +--- + +feat: allow async operations in useComputed$ hook diff --git a/.changeset/grumpy-ladybugs-wonder.md b/.changeset/grumpy-ladybugs-wonder.md deleted file mode 100644 index 155c8b8a014..00000000000 --- a/.changeset/grumpy-ladybugs-wonder.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'eslint-plugin-qwik': patch ---- - -Improve types and README documentation with clear configuration examples for ESLint 9+ (flat config). Added `globalIgnores` for more clarity and `tseslint.config` for better type inference inside the `parserOptions` option. diff --git a/.changeset/heavy-kids-wave.md b/.changeset/heavy-kids-wave.md new file mode 100644 index 00000000000..30a2e8ac3b2 --- /dev/null +++ b/.changeset/heavy-kids-wave.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: rendering markdown file with Qwik component diff --git a/.changeset/heavy-radios-dream.md b/.changeset/heavy-radios-dream.md new file mode 100644 index 00000000000..8db7e56e562 --- /dev/null +++ b/.changeset/heavy-radios-dream.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +FIX: QRLs are now scheduled instead of directly executed by qwik-loader, so that they are executed in the right order. diff --git a/.changeset/heavy-seas-carry.md b/.changeset/heavy-seas-carry.md new file mode 100644 index 00000000000..d5d1582094b --- /dev/null +++ b/.changeset/heavy-seas-carry.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: encode the `q:subs` property diff --git a/.changeset/hip-hornets-cheer.md b/.changeset/hip-hornets-cheer.md new file mode 100644 index 00000000000..80a614bb89c --- /dev/null +++ b/.changeset/hip-hornets-cheer.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': minor +--- + +feat: new simpler signals implementation with lazy useComputed$ execution, only when is needed diff --git a/.changeset/itchy-comics-develop.md b/.changeset/itchy-comics-develop.md new file mode 100644 index 00000000000..c37c1332be0 --- /dev/null +++ b/.changeset/itchy-comics-develop.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: different component rendering with the same key diff --git a/.changeset/kind-toes-glow.md b/.changeset/kind-toes-glow.md new file mode 100644 index 00000000000..3478fd452d0 --- /dev/null +++ b/.changeset/kind-toes-glow.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: export SVG type from qwik/core diff --git a/.changeset/lemon-tools-bathe.md b/.changeset/lemon-tools-bathe.md new file mode 100644 index 00000000000..3b097d7d35a --- /dev/null +++ b/.changeset/lemon-tools-bathe.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +FIX: optimizer is now better at recognizing constProp diff --git a/.changeset/long-shirts-thank.md b/.changeset/long-shirts-thank.md new file mode 100644 index 00000000000..5204b0320bb --- /dev/null +++ b/.changeset/long-shirts-thank.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: create svg nested children with correct namespace diff --git a/.changeset/loud-dolphins-relate.md b/.changeset/loud-dolphins-relate.md new file mode 100644 index 00000000000..28521f3f36a --- /dev/null +++ b/.changeset/loud-dolphins-relate.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: finding context parent and sorting projections in the scheduler diff --git a/.changeset/mean-dingos-hug.md b/.changeset/mean-dingos-hug.md new file mode 100644 index 00000000000..705ba076cb2 --- /dev/null +++ b/.changeset/mean-dingos-hug.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +feat: move signal invalidation to the scheduler diff --git a/.changeset/mean-parents-buy.md b/.changeset/mean-parents-buy.md new file mode 100644 index 00000000000..ed4f50182e8 --- /dev/null +++ b/.changeset/mean-parents-buy.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: replace inline component with component$ with the same key diff --git a/.changeset/nervous-terms-explode.md b/.changeset/nervous-terms-explode.md new file mode 100644 index 00000000000..3ac190db6c4 --- /dev/null +++ b/.changeset/nervous-terms-explode.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +feat: better node attributes serialization diff --git a/.changeset/nine-otters-repeat.md b/.changeset/nine-otters-repeat.md new file mode 100644 index 00000000000..807574de712 --- /dev/null +++ b/.changeset/nine-otters-repeat.md @@ -0,0 +1,35 @@ +--- +'@qwik.dev/core': major +--- + +`qwik-labs` package has been removed in favor of experimental features. +So the "Insights" vite plugin and components have been moved to core as an experimental feature. + +In order to use it, you need to - + +**1)** add `insights` to the experimental array in `vite.config.ts`: + +```ts +qwikVite({ + experimental: ['insights'] +}), +``` + +**2)** Import and use the `qwikInsights` vite plugin from `@qwik.dev/core/insights/vite`: + +```ts +import { qwikInsights } from '@qwik.dev/core/insights/vite'; +``` + +**3)** import the `` component from `@qwik.dev/core/insights` and use it in your `root.tsx` file: : + +```tsx title="root.tsx" +import { Insights } from '@qwik.dev/core/insights'; + +// ...rest of root.tsx file + +return ( + + /* ...qwik app */ +); +``` diff --git a/.changeset/old-mayflies-fetch.md b/.changeset/old-mayflies-fetch.md new file mode 100644 index 00000000000..1b47c91d512 --- /dev/null +++ b/.changeset/old-mayflies-fetch.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: the use hook didn't work when type is Slot. diff --git a/.changeset/olive-cameras-collect.md b/.changeset/olive-cameras-collect.md new file mode 100644 index 00000000000..4a5cdb5c658 --- /dev/null +++ b/.changeset/olive-cameras-collect.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +CHORE: replace the `_hW` export in segments with a shared export `_task` in core. This opens up using QRLs from core. diff --git a/.changeset/orange-otters-attend.md b/.changeset/orange-otters-attend.md new file mode 100644 index 00000000000..8f1d2f204fe --- /dev/null +++ b/.changeset/orange-otters-attend.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +feat: emit "qrender" event after every render diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 00000000000..88217821272 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,92 @@ +{ + "mode": "pre", + "tag": "alpha", + "initialVersions": { + "create-qwik": "2.0.0-0", + "qwik-docs": "0.0.1", + "eslint-plugin-qwik": "2.0.0-0", + "@qwik.dev/core": "2.0.0-0", + "@qwik.dev/router": "2.0.0-0", + "insights": "0.1.0", + "@qwik.dev/dom": "2.1.19", + "@qwik.dev/react": "2.0.0-0", + "supabase-auth-helpers-qwik": "0.0.3", + "qwik-cli-e2e": "0.0.0" + }, + "branch": "build/v2", + "changesets": [ + "afraid-bags-jam", + "afraid-garlics-greet", + "angry-grapes-itch", + "blue-beans-happen", + "brave-files-grin", + "brown-ravens-behave", + "calm-cycles-know", + "chilled-spoons-wonder", + "chilly-fans-shave", + "clever-flowers-drum", + "cyan-bottles-speak", + "dirty-lemons-shop", + "eighty-ligers-wink", + "fair-cameras-boil", + "fast-baboons-itch", + "few-mugs-accept", + "five-kangaroos-matter", + "five-shoes-deny", + "fluffy-poets-raise", + "forty-garlics-train", + "fresh-rocks-exercise", + "friendly-beers-heal", + "friendly-gorillas-walk", + "friendly-sloths-return", + "funny-apricots-learn", + "fuzzy-jobs-compare", + "gentle-melons-pretend", + "heavy-kids-wave", + "heavy-radios-dream", + "heavy-seas-carry", + "hip-hornets-cheer", + "itchy-comics-develop", + "kind-toes-glow", + "lemon-tools-bathe", + "long-shirts-thank", + "loud-dolphins-relate", + "mean-dingos-hug", + "mean-parents-buy", + "nervous-terms-explode", + "nine-otters-repeat", + "old-mayflies-fetch", + "olive-cameras-collect", + "orange-otters-attend", + "proud-kangaroos-boil", + "proud-pillows-try", + "purple-melons-invent", + "red-trains-deny", + "rich-wasps-tease", + "rotten-penguins-cough", + "rotten-weeks-tickle", + "seven-pumpkins-argue", + "shaggy-poems-appear", + "shaggy-poems-return", + "sharp-apples-relate", + "six-games-float", + "slimy-weeks-hope", + "sour-zebras-tell", + "strange-bottles-sleep", + "sweet-socks-whisper", + "swift-flowers-juggle", + "tame-glasses-explain", + "tasty-penguins-ring", + "thirty-ravens-draw", + "tiny-berries-bow", + "tricky-meals-heal", + "tricky-peaches-buy", + "twenty-goats-flow", + "unlucky-dodos-grab", + "warm-camels-remain", + "wicked-pets-chew", + "wild-cooks-pay", + "witty-balloons-thank", + "young-cameras-hang" + ] +} diff --git a/.changeset/proud-kangaroos-boil.md b/.changeset/proud-kangaroos-boil.md new file mode 100644 index 00000000000..9c44e3d9d53 --- /dev/null +++ b/.changeset/proud-kangaroos-boil.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: finding vnodes on interaction diff --git a/.changeset/proud-pillows-try.md b/.changeset/proud-pillows-try.md new file mode 100644 index 00000000000..52b8001173c --- /dev/null +++ b/.changeset/proud-pillows-try.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +chore: more descriptive HTML streaming error message diff --git a/.changeset/purple-melons-invent.md b/.changeset/purple-melons-invent.md new file mode 100644 index 00000000000..be13abfef7b --- /dev/null +++ b/.changeset/purple-melons-invent.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: find correct context after rendering empty array diff --git a/.changeset/red-trains-deny.md b/.changeset/red-trains-deny.md new file mode 100644 index 00000000000..41418c4a044 --- /dev/null +++ b/.changeset/red-trains-deny.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: textarea with null value diff --git a/.changeset/rich-shirts-thank.md b/.changeset/rich-shirts-thank.md new file mode 100644 index 00000000000..51f3cd948e1 --- /dev/null +++ b/.changeset/rich-shirts-thank.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +FIX: add HTMLElementAttrs and SVGProps types to exports diff --git a/.changeset/rich-wasps-tease.md b/.changeset/rich-wasps-tease.md new file mode 100644 index 00000000000..c0b3baffcaf --- /dev/null +++ b/.changeset/rich-wasps-tease.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': major +--- + +BREAKING: the Typescript exports were trimmed down to the bare minimum. If there are types you are missing, open an issue. diff --git a/.changeset/rotten-penguins-cough.md b/.changeset/rotten-penguins-cough.md new file mode 100644 index 00000000000..2f7854361e4 --- /dev/null +++ b/.changeset/rotten-penguins-cough.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: undefined or null as projection child diff --git a/.changeset/rotten-weeks-tickle.md b/.changeset/rotten-weeks-tickle.md new file mode 100644 index 00000000000..267de3a2bbf --- /dev/null +++ b/.changeset/rotten-weeks-tickle.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: do not trigger effects if computed value is not changed diff --git a/.changeset/seven-pumpkins-argue.md b/.changeset/seven-pumpkins-argue.md new file mode 100644 index 00000000000..d41780171d0 --- /dev/null +++ b/.changeset/seven-pumpkins-argue.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: infinity serialization loop diff --git a/.changeset/shaggy-poems-appear.md b/.changeset/shaggy-poems-appear.md new file mode 100644 index 00000000000..4899a30fc83 --- /dev/null +++ b/.changeset/shaggy-poems-appear.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +feat: log a warning instead of throwing an error for server host mismatch error diff --git a/.changeset/shaggy-poems-return.md b/.changeset/shaggy-poems-return.md new file mode 100644 index 00000000000..1d869f2f7ac --- /dev/null +++ b/.changeset/shaggy-poems-return.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: event handlers in loops diff --git a/.changeset/sharp-apples-relate.md b/.changeset/sharp-apples-relate.md new file mode 100644 index 00000000000..7278588ecfb --- /dev/null +++ b/.changeset/sharp-apples-relate.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: vNode serialization error on server$ diff --git a/.changeset/six-games-float.md b/.changeset/six-games-float.md new file mode 100644 index 00000000000..e5346ede392 --- /dev/null +++ b/.changeset/six-games-float.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: don't wrap and serialize functions that are attribute values diff --git a/.changeset/slick-candies-rhyme.md b/.changeset/slick-candies-rhyme.md deleted file mode 100644 index 029050f07af..00000000000 --- a/.changeset/slick-candies-rhyme.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@builder.io/qwik': patch ---- - -FIX: now qwikloader is loaded only once in all cases diff --git a/.changeset/slimy-weeks-hope.md b/.changeset/slimy-weeks-hope.md new file mode 100644 index 00000000000..1d4087cacd6 --- /dev/null +++ b/.changeset/slimy-weeks-hope.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: retry vnode diffing on promise throw diff --git a/.changeset/sour-zebras-tell.md b/.changeset/sour-zebras-tell.md new file mode 100644 index 00000000000..684e9e5d075 --- /dev/null +++ b/.changeset/sour-zebras-tell.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': minor +--- + +feat: added the scheduler to sort chores execution and have more predictable behavior diff --git a/.changeset/strange-bottles-sleep.md b/.changeset/strange-bottles-sleep.md new file mode 100644 index 00000000000..0b06f61c07c --- /dev/null +++ b/.changeset/strange-bottles-sleep.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: don't execute QRLs for elements marked as deleted diff --git a/.changeset/sweet-hairs-remember.md b/.changeset/sweet-hairs-remember.md new file mode 100644 index 00000000000..a74444f9d41 --- /dev/null +++ b/.changeset/sweet-hairs-remember.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +FIX: Introduce retry logic for QRL resolution to handle potential promise retries, ensuring robustness in asynchronous operations. diff --git a/.changeset/sweet-socks-whisper.md b/.changeset/sweet-socks-whisper.md new file mode 100644 index 00000000000..714ff27f10b --- /dev/null +++ b/.changeset/sweet-socks-whisper.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': minor +--- + +feat: new faster serialization system diff --git a/.changeset/swift-flowers-juggle.md b/.changeset/swift-flowers-juggle.md new file mode 100644 index 00000000000..e13e80886f7 --- /dev/null +++ b/.changeset/swift-flowers-juggle.md @@ -0,0 +1,33 @@ +--- +'@qwik.dev/core': patch +--- + +feat: updated scoped styles prefix to ⚡️ + +# Scoped styles prefix update + +We've updated the `ComponentStylesPrefixContent` from the star symbol (⭐️) to the lightning bolt symbol (⚡️). This prefix is used internally to generate unique CSS class names for components, helping to prevent style collisions. + +**Potential Compatibility Issue (Rare):** + +While this change is expected to be seamless for the vast majority of users, there's a _very small_ possibility of a conflict if your application _directly relies_ on the star symbol (⭐️) for CSS overriding. Specifically, if you're using CSS selectors that include the _literal_ star character (⭐️) as part of a class name (e.g., `.⭐️ComponentName { ... }`), your styles require need to be changed manually to work as expected after this update. + +## How to check if you're affected + +**Search your codebase:** Look for any instances where the star symbol (⭐️) is used as part of a CSS class name or selector. + +## How to fix it if you're affected + +If you find that you are indeed relying on the star symbol (⭐️), you'll need to update your CSS selectors to use the new lightning bolt symbol (⚡️). For example, change `.⭐️ComponentName { ... }` to `.⚡️ComponentName { ... }`. + +```css +/* Example of old, potentially problematic CSS */ +.⭐️MyComponent { + /* ... old styles ... */ +} + +/* Example of updated, correct CSS */ +.⚡️MyComponent { + /* ... updated styles ... */ +} +``` diff --git a/.changeset/tame-glasses-explain.md b/.changeset/tame-glasses-explain.md new file mode 100644 index 00000000000..071ac0504cb --- /dev/null +++ b/.changeset/tame-glasses-explain.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: inserting new node edge case diff --git a/.changeset/tasty-penguins-ring.md b/.changeset/tasty-penguins-ring.md new file mode 100644 index 00000000000..934b4d63136 --- /dev/null +++ b/.changeset/tasty-penguins-ring.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: prevent reusing projection if is marked as deleted diff --git a/.changeset/thirty-ravens-draw.md b/.changeset/thirty-ravens-draw.md new file mode 100644 index 00000000000..770c934d65f --- /dev/null +++ b/.changeset/thirty-ravens-draw.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: destructured props for inline components diff --git a/.changeset/tiny-berries-bow.md b/.changeset/tiny-berries-bow.md new file mode 100644 index 00000000000..46a4ba2ad84 --- /dev/null +++ b/.changeset/tiny-berries-bow.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: serialize virtual props for DOM elements diff --git a/.changeset/tricky-meals-heal.md b/.changeset/tricky-meals-heal.md new file mode 100644 index 00000000000..28de7b4c58f --- /dev/null +++ b/.changeset/tricky-meals-heal.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/router': major +--- + +Renamed "Qwik City" to "Qwik Router" and package to "@qwik.dev/router" diff --git a/.changeset/tricky-peaches-buy.md b/.changeset/tricky-peaches-buy.md new file mode 100644 index 00000000000..2e9fb9218b8 --- /dev/null +++ b/.changeset/tricky-peaches-buy.md @@ -0,0 +1,9 @@ +--- +'@qwik.dev/core': minor +--- + +FEAT: `useSerializer$`, `createSerializer$`: Create a Signal holding a custom serializable value. See {@link useSerializer$} for more details. + +`NoSerializeSymbol`: objects that have this symbol will not be serialized. + +`SerializerSymbol`: When defined on an object, this function will get called with the object and is expected to returned a serializable object literal representing this object. Use this to remove data cached data, consolidate things, integrate with other libraries, etc. diff --git a/.changeset/twenty-goats-flow.md b/.changeset/twenty-goats-flow.md new file mode 100644 index 00000000000..64cbd9ca066 --- /dev/null +++ b/.changeset/twenty-goats-flow.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: replacing projection content with null or undefined diff --git a/.changeset/unlucky-dodos-grab.md b/.changeset/unlucky-dodos-grab.md new file mode 100644 index 00000000000..b40439266a8 --- /dev/null +++ b/.changeset/unlucky-dodos-grab.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: convert destructured array's props to signal diff --git a/.changeset/unlucky-olives-knock.md b/.changeset/unlucky-olives-knock.md new file mode 100644 index 00000000000..b0f0a694b06 --- /dev/null +++ b/.changeset/unlucky-olives-knock.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: signal wrapper should not rerender causing missing child error diff --git a/.changeset/warm-camels-remain.md b/.changeset/warm-camels-remain.md new file mode 100644 index 00000000000..051fd35cedd --- /dev/null +++ b/.changeset/warm-camels-remain.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +Expose missing types into `public.d.ts` and fix types uri for internal export inside `package.json` diff --git a/.changeset/wet-bobcats-decide.md b/.changeset/wet-bobcats-decide.md new file mode 100644 index 00000000000..cc756187a94 --- /dev/null +++ b/.changeset/wet-bobcats-decide.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: inflating text nodes from single shared text node diff --git a/.changeset/wicked-pets-chew.md b/.changeset/wicked-pets-chew.md new file mode 100644 index 00000000000..ae5cfc11a97 --- /dev/null +++ b/.changeset/wicked-pets-chew.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: removing text node from shared text node diff --git a/.changeset/wild-cooks-pay.md b/.changeset/wild-cooks-pay.md new file mode 100644 index 00000000000..f786009b3bb --- /dev/null +++ b/.changeset/wild-cooks-pay.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': minor +--- + +feat: new CSR and SSR rendering written from scratch to speed up performance, improve code readability, and make the code easier to understand for new contributors diff --git a/.changeset/witty-balloons-thank.md b/.changeset/witty-balloons-thank.md new file mode 100644 index 00000000000..66b28520792 --- /dev/null +++ b/.changeset/witty-balloons-thank.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: serialize var prop diff --git a/.changeset/yellow-frogs-repeat.md b/.changeset/yellow-frogs-repeat.md deleted file mode 100644 index cb59a0e4203..00000000000 --- a/.changeset/yellow-frogs-repeat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@builder.io/qwik-city': minor ---- - -CHORE: the service workers have been deprecated and replaced with entries that unregister them. If you have it enabled in production, you can remove it after a while once you are sure all your users have the new version. diff --git a/.changeset/young-cameras-hang.md b/.changeset/young-cameras-hang.md new file mode 100644 index 00000000000..3b5a05ff62f --- /dev/null +++ b/.changeset/young-cameras-hang.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: tracking whole store diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 0528ae65053..23a60937a3c 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -33,5 +33,6 @@ "label": "Serve", "onAutoForward": "openPreview" } - } + }, + "postCreateCommand": "./.devcontainer/post-create.sh" } diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh new file mode 100755 index 00000000000..c1cabb69e5d --- /dev/null +++ b/.devcontainer/post-create.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +git config --global alias.co checkout +git config --global alias.br branch +git config --global alias.ci commit +git config --global alias.st status +git config --global alias.lg "log --oneline" diff --git a/.github/ISSUE_TEMPLATE/bug.yaml b/.github/ISSUE_TEMPLATE/bug.yaml index 75678124cb4..777e9044583 100644 --- a/.github/ISSUE_TEMPLATE/bug.yaml +++ b/.github/ISSUE_TEMPLATE/bug.yaml @@ -17,7 +17,7 @@ body: - Qwik Rollup / Vite plugin - Qwik Optimizer (rust) - Qwik React - - Qwik City (routing) + - Qwik Router - Starters / CLI - Qwik Playground validations: @@ -53,7 +53,7 @@ body: id: system-info attributes: label: System Info - description: Output of `npx envinfo --system --npmPackages '{vite,undici,typescript,@builder.io/*}' --binaries --browsers` + description: Output of `npx envinfo --system --npmPackages '{vite,typescript,@builder.io/*}' --binaries --browsers` render: shell placeholder: System, Binaries, Browsers validations: diff --git a/.github/workflows/cancel.yml b/.github/workflows/cancel.yml new file mode 100644 index 00000000000..c848f75abe4 --- /dev/null +++ b/.github/workflows/cancel.yml @@ -0,0 +1,15 @@ +# Workaround to cancel workflow runs from forked repositories +name: Cancel +on: + workflow_run: + workflows: ['ci'] + types: + - requested +jobs: + cancel: + runs-on: ubuntu-latest + steps: + - uses: styfle/cancel-workflow-action@0.12.1 + if: github.event_name == 'pull_request' + with: + workflow_id: ${{ github.event.workflow.id }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5642afafcd9..aedf77f1381 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,13 +23,12 @@ on: - main - upcoming - next - - qwik-labs - vercelserverless - 'build/**' workflow_dispatch: inputs: disttag: - description: 'Publish "@builder.io/qwik" to NPM using this dist-tag, push the git-tag to the repo and create a GitHub release. The "latest" and "next" dist-tags will use the version number already committed in package.json.' + description: 'Publish "@qwik.dev/core" to NPM using this dist-tag, push the git-tag to the repo and create a GitHub release. The "latest" and "next" dist-tags will use the version number already committed in package.json.' required: true type: choice default: 'dev' @@ -79,7 +78,7 @@ jobs: - name: Set Dist Tag id: set_dist_tag if: | - github.ref == 'refs/heads/upcoming' && ( + github.ref == 'refs/heads/build/v2' && ( github.event_name == 'push' || github.event_name == 'workflow_dispatch' ) @@ -152,14 +151,12 @@ jobs: with: lookup-only: true path: | - packages/qwik-city/lib - packages/qwik-labs/lib - packages/qwik-labs/vite + packages/qwik-router/lib packages/qwik-react/lib packages/eslint-plugin-qwik/dist packages/create-qwik/dist # note that all inputs need to be listed here, including qwik, for correct cache invalidation - key: ${{ hashfiles('qwik-key.txt', 'rust-key.txt', 'packages/qwik-city/**/*', 'packages/qwik-labs/**/*', 'packages/qwik-react/**/*', 'packages/eslint-plugin-qwik/**/*', 'packages/create-qwik/**/*', 'starters/apps/**/*', 'starters/features/**/*', 'starters/adapters/**/*', '!**/*.unit.*') }} + key: ${{ hashfiles('qwik-key.txt', 'rust-key.txt', 'packages/qwik-router/**/*', 'packages/qwik-react/**/*', 'packages/eslint-plugin-qwik/**/*', 'packages/create-qwik/**/*', 'starters/apps/**/*', 'starters/features/**/*', 'starters/adapters/**/*', '!**/*.unit.*') }} - run: 'echo ${{ steps.cache-others.outputs.cache-primary-key }} > others-key.txt' - name: 'check cache: docs' id: cache-docs @@ -224,7 +221,7 @@ jobs: pnpm install --frozen-lockfile - name: 'build: qwik' - run: pnpm build --qwik --set-dist-tag="${{ needs.changes.outputs.disttag }}" + run: pnpm build --qwik --insights --set-dist-tag="${{ needs.changes.outputs.disttag }}" - name: Print Qwik Dist Build continue-on-error: true @@ -275,6 +272,8 @@ jobs: - name: Install Rust toolchain uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + components: clippy,rustfmt - uses: pnpm/action-setup@v4 - name: Setup Node @@ -410,58 +409,40 @@ jobs: if: needs.changes.outputs.build-others == 'true' run: pnpm install - - name: 'build: qwik-city & others' + - name: 'build: qwik-router & others' if: needs.changes.outputs.build-others == 'true' - run: pnpm build --tsc --api --qwikcity --cli --qwiklabs --qwikreact --eslint --set-dist-tag="${{ needs.changes.outputs.disttag }}" + run: pnpm build --tsc --api --qwikrouter --cli --qwikreact --eslint --set-dist-tag="${{ needs.changes.outputs.disttag }}" - name: Save others cache if: needs.changes.outputs.build-others == 'true' uses: actions/cache/save@v4 with: key: ${{ needs.changes.outputs.hash-others }} path: | - packages/qwik-city/lib - packages/qwik-labs/lib - packages/qwik-labs/vite + packages/qwik-router/lib packages/qwik-react/lib packages/eslint-plugin-qwik/dist packages/create-qwik/dist - - name: 'restore: qwik-city & others' + - name: 'restore: qwik-router & others' if: needs.changes.outputs.build-others != 'true' uses: actions/cache/restore@v4 with: path: | - packages/qwik-city/lib - packages/qwik-labs/lib - packages/qwik-labs/vite + packages/qwik-router/lib packages/qwik-react/lib packages/eslint-plugin-qwik/dist packages/create-qwik/dist key: ${{ needs.changes.outputs.hash-others }} - - name: Print QwikCity Lib Build - run: tree -a packages/qwik-city/lib/ - - - name: Upload QwikCity Build Artifacts - uses: actions/upload-artifact@v4 - with: - name: artifact-qwikcity - include-hidden-files: true - path: packages/qwik-city/lib/ - if-no-files-found: error - - - name: Print QwikLabs Lib Build - run: tree -a packages/qwik-labs/lib/ packages/qwik-labs/vite/ + - name: Print QwikRouter Lib Build + run: tree -a packages/qwik-router/lib/ - - name: Upload QwikLabs+React Build Artifacts + - name: Upload QwikRouter Build Artifacts uses: actions/upload-artifact@v4 with: - name: artifact-qwiklabs + name: artifact-qwikrouter include-hidden-files: true - path: | - packages/qwik-labs/lib/ - packages/qwik-labs/vite/ - packages/qwik-labs/package.json + path: packages/qwik-router/lib/ if-no-files-found: error - name: Print qwik-react Lib Build @@ -522,14 +503,12 @@ jobs: - name: Move Distribution Artifacts run: | mv artifact-qwik/* packages/qwik/ - mkdir -p packages/qwik-city/lib/ - mv artifact-qwikcity/* packages/qwik-city/lib/ + mkdir -p packages/qwik-router/lib/ + mv artifact-qwikrouter/* packages/qwik-router/lib/ mkdir -p packages/create-qwik/dist/ mv artifact-create-qwik/* packages/create-qwik/dist/ mkdir -p packages/eslint-plugin-qwik/dist/ mv artifact-eslint-plugin-qwik/* packages/eslint-plugin-qwik/dist/ - mv artifact-qwiklabs/lib packages/qwik-labs/lib - mv artifact-qwiklabs/vite packages/qwik-labs/vite - uses: pnpm/action-setup@v4 - name: Setup Node @@ -582,14 +561,12 @@ jobs: - name: Move Distribution Artifacts run: | mv artifact-qwik/* packages/qwik/ - mkdir -p packages/qwik-city/lib/ - mv artifact-qwikcity/* packages/qwik-city/lib/ + mkdir -p packages/qwik-router/lib/ + mv artifact-qwikrouter/* packages/qwik-router/lib/ mkdir -p packages/create-qwik/dist/ mv artifact-create-qwik/* packages/create-qwik/dist/ mkdir -p packages/eslint-plugin-qwik/dist/ mv artifact-eslint-plugin-qwik/* packages/eslint-plugin-qwik/dist/ - mv artifact-qwiklabs/lib packages/qwik-labs/lib - mv artifact-qwiklabs/vite packages/qwik-labs/vite mv artifact-qwikreact/lib packages/qwik-react/lib - run: pnpm install --frozen-lockfile @@ -642,8 +619,8 @@ jobs: - name: Move Distribution Artifacts run: | mv artifact-qwik/* packages/qwik/ - mkdir -p packages/qwik-city/lib/ - mv artifact-qwikcity/* packages/qwik-city/lib/ + mkdir -p packages/qwik-router/lib/ + mv artifact-qwikrouter/* packages/qwik-router/lib/ mkdir -p packages/create-qwik/dist/ mv artifact-create-qwik/* packages/create-qwik/dist/ mkdir -p packages/eslint-plugin-qwik/dist/ @@ -705,8 +682,8 @@ jobs: - name: Move Distribution Artifacts run: | mv artifact-qwik/* packages/qwik/ - mkdir -p packages/qwik-city/lib/ - mv artifact-qwikcity/* packages/qwik-city/lib/ + mkdir -p packages/qwik-router/lib/ + mv artifact-qwikrouter/* packages/qwik-router/lib/ mkdir -p packages/create-qwik/dist/ mv artifact-create-qwik/* packages/create-qwik/dist/ mkdir -p packages/eslint-plugin-qwik/dist/ @@ -723,9 +700,10 @@ jobs: - name: Playwright E2E Integration Tests run: pnpm run test.e2e.integrations.${{ matrix.settings.browser }} --timeout 60000 --retries 7 --workers 1 - - name: Validate Create Qwik Cli - if: matrix.settings.host != 'windows-latest' - run: pnpm cli.validate + # RE-ENABBLE THIS AFTER qwik.dev/ packages are published + # - name: Validate Create Qwik Cli + # if: matrix.settings.host != 'windows-latest' + # run: pnpm cli.validate ############ E2E CLI TEST ############ test-cli-e2e: @@ -764,8 +742,8 @@ jobs: - name: Move Distribution Artifacts run: | mv artifact-qwik/* packages/qwik/ - mkdir -p packages/qwik-city/lib/ - mv artifact-qwikcity/* packages/qwik-city/lib/ + mkdir -p packages/qwik-router/lib/ + mv artifact-qwikrouter/* packages/qwik-router/lib/ mkdir -p packages/create-qwik/dist/ mv artifact-create-qwik/* packages/create-qwik/dist/ mkdir -p packages/eslint-plugin-qwik/dist/ @@ -826,7 +804,7 @@ jobs: if: | always() && github.repository == 'QwikDev/qwik' && ( - github.ref == 'refs/heads/upcoming' || + github.ref == 'refs/heads/build/v2' || needs.test-unit.result == 'success' ) @@ -878,14 +856,12 @@ jobs: - name: Move Distribution Artifacts run: | mv artifact-qwik/* packages/qwik/ - mkdir -p packages/qwik-city/lib/ - mv artifact-qwikcity/* packages/qwik-city/lib/ + mkdir -p packages/qwik-router/lib/ + mv artifact-qwikrouter/* packages/qwik-router/lib/ mkdir -p packages/create-qwik/dist/ mv artifact-create-qwik/* packages/create-qwik/dist/ mkdir -p packages/eslint-plugin-qwik/dist/ mv artifact-eslint-plugin-qwik/* packages/eslint-plugin-qwik/dist/ - mv artifact-qwiklabs/lib packages/qwik-labs/lib - mv artifact-qwiklabs/vite packages/qwik-labs/vite mv artifact-qwikreact/lib packages/qwik-react/lib rm -rf artifact-* @@ -894,16 +870,30 @@ jobs: # Do this before other release steps to avoid # publishing temporary files - name: Create Release Pull Request or Publish to npm - if: github.ref == 'refs/heads/upcoming' + if: github.ref == 'refs/heads/build/v2' id: changesets uses: changesets/action@v1 with: publish: pnpm release + title: V2 Version Packages + branch: build/v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + # Delete this after V2 is released + - name: Tag with latest + if: steps.changesets.outputs.published == 'true' + run: | + echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > $GITHUB_WORKSPACE/.npmrc + npm dist-tag add @qwik.dev/core@${{ fromJSON(steps.changesets.outputs.publishedPackages)[0].version }} latest + npm dist-tag add @qwik.dev/router@${{ fromJSON(steps.changesets.outputs.publishedPackages)[0].version }} latest + npm dist-tag add @qwik.dev/react@${{ fromJSON(steps.changesets.outputs.publishedPackages)[0].version }} latest + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + NPM_CONFIG_USERCONFIG: ${{ github.workspace }}/.npmrc + - name: Fixup package.json files run: pnpm run release.fixup-package-json @@ -915,12 +905,13 @@ jobs: - name: Publish packages for testing if: github.event_name != 'workflow_dispatch' + # TODO: bring back --compact in the package.json release.pkg-pr-new script after first npm public of V2 alpha run: pnpm release.pkg-pr-new env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ############ TRIGGER QWIKCITY E2E TEST ############ - trigger-qwikcity-e2e: + trigger-qwikrouter-e2e: name: Trigger Qwik City E2E runs-on: ubuntu-latest if: github.ref == 'refs/heads/upcoming' @@ -934,7 +925,7 @@ jobs: uses: peter-evans/repository-dispatch@v2 with: token: ${{ secrets.QWIK_API_TOKEN_GITHUB }} - repository: builderIO/qwik-city-e2e + repository: QwikDev/qwik-city-e2e event-type: main-updated ############ Everything is fine ############ diff --git a/.github/workflows/labeling-issues.yml b/.github/workflows/labeling-issues.yml index ca318abdc19..d347912420d 100644 --- a/.github/workflows/labeling-issues.yml +++ b/.github/workflows/labeling-issues.yml @@ -1,4 +1,4 @@ -name: Labling Issues +name: Labeling Issues on: issues: diff --git a/.gitignore b/.gitignore index b9e7fa07098..010cbe2eb15 100644 --- a/.gitignore +++ b/.gitignore @@ -52,4 +52,7 @@ test-results sandbox # We need to ignore this because "changesets" will try to replace it -/CHANGELOG.md \ No newline at end of file +/CHANGELOG.md + +# Vitest coverage +packages/coverage/* \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index 4ae0a4de10b..74bb951369d 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,4 @@ -**/**.api.md +**/*.api.md **/*.log **/.DS_Store *. @@ -36,8 +36,6 @@ packages/insights/drizzle packages/insights/.netlify packages/insights/scripts packages/insights/**/*.gen.d.ts -packages/qwik-labs/lib-types -packages/qwik-labs/vite # insights cache files **/q-insights.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json index f8bda961746..6fe6446c816 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -6,7 +6,6 @@ "ms-playwright.playwright", "rust-lang.rust-analyzer", "ms-azuretools.vscode-docker", - "manucorporat.vermoji", "vadimcn.vscode-lldb", "streetsidesoftware.code-spell-checker", "vitest.explorer" diff --git a/.vscode/launch.json b/.vscode/launch.json index e81b9434684..361b353c847 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -70,7 +70,7 @@ "internalConsoleOptions": "neverOpen", "program": "${workspaceFolder}/./node_modules/vitest/vitest.mjs", "cwd": "${workspaceFolder}", - "args": ["${file}"] + "args": ["--test-timeout", "999999", "--minWorkers", "1", "--maxWorkers", "1", "${file}"] } ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 093ff9abfc9..3a20cde19ff 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,8 +7,10 @@ "**/cypress/**", "**/.{idea,git,cache,output,temp}/**" ], + "cSpell.words": ["bucketize", "Stringifiable"], "javascript.preferences.autoImportFileExcludePatterns": ["node:test"], "typescript.preferences.preferTypeOnlyAutoImports": true, "typescript.tsdk": "./node_modules/typescript/lib", - "typescript.enablePromptUseWorkspaceTsdk": true + "typescript.enablePromptUseWorkspaceTsdk": true, + "makefile.configureOnOpen": false } diff --git a/CONTINUOUS_BUILD.md b/CONTINUOUS_BUILD.md index 605628e2468..5081b175046 100644 --- a/CONTINUOUS_BUILD.md +++ b/CONTINUOUS_BUILD.md @@ -4,9 +4,8 @@ This repo contains build artifacts that are generated as part of the continues b Currently supported artifacts: -- [`@builder.io/qwik`](https://github.com/QwikDev/qwik-build) -- [`@builder.io/qwik-city`](https://github.com/QwikDev/qwik-city-build) -- [`@builder.io/qwik-labs`](https://github.com/QwikDev/qwik-labs-build) +- [`@qwik.dev/core`](https://github.com/QwikDev/qwik-build) +- [`@qwik.dev/router`](https://github.com/QwikDev/qwik-city-build) The build artifact is created if: @@ -27,9 +26,8 @@ To install a specific build artifact change you `package.json` like so (not all ```json { "dependencies": { - "@builder.io/qwik": "github:QwikDev/qwik-build#SHA", - "@builder.io/qwik-city": "github:QwikDev/qwik-city-build#SHA", - "@builder.io/qwik-labs": "github:QwikDev/qwik-labs-build#SHA" + "@qwik.dev/core": "github:QwikDev/qwik-build#SHA", + "@qwik.dev/router": "github:QwikDev/qwik-city-build#SHA" } } ``` @@ -37,13 +35,11 @@ To install a specific build artifact change you `package.json` like so (not all Where `#SHA` is one of the following: - `#SHA` - Install a specific build SHA. You can get the SHA from: - - [`@builder.io/qwik`](https://github.com/QwikDev/qwik-build/commits/) commits - - [`@builder.io/qwik-city`](https://github.com/QwikDev/qwik-city-build/commits/) commits - - [`@builder.io/qwik-labs`](https://github.com/QwikDev/qwik-labs-build/commits/) commits + - [`@qwik.dev/core`](https://github.com/QwikDev/qwik-build/commits/) commits + - [`@qwik.dev/router`](https://github.com/QwikDev/qwik-city-build/commits/) commits - `#build/name` (or `#main`) - Install a specific `build/*` (or `#main`) branch: - - [`@builder.io/qwik`](https://github.com/QwikDev/qwik-build/branches/) branches - - [`@builder.io/qwik-city`](https://github.com/QwikDev/qwik-city-build/branches/) branches - - [`@builder.io/qwik-labs`](https://github.com/QwikDev/qwik-labs-build/branches/) branches + - [`@qwik.dev/core`](https://github.com/QwikDev/qwik-build/branches/) branches + - [`@qwik.dev/router`](https://github.com/QwikDev/qwik-city-build/branches/) branches > NOTE: Package managers will treat any SHA in the lock file which is on the branch as valid, and so they will not auto upgrade to the latest. For this reason this is not recommended. ## Bisect for regression diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2bca58538b3..b7867e26a48 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -166,7 +166,7 @@ If you want to work on the Rust code, use `build.full` instead of `build.local`. ### Fast build -This will build only Qwik and Qwik City and their types. This is not enough to run the docs. +This will build only Qwik and Qwik Router and their types. This is not enough to run the docs. ```shell pnpm build.core @@ -174,10 +174,10 @@ pnpm build.core ### Custom build -Once you have done a full build, the types are built, and you can build just the code you're working on. For qwik and qwik-city, you can do very fast rebuilds with +Once you have done a full build, the types are built, and you can build just the code you're working on. For qwik and qwik-router, you can do very fast rebuilds with ```shell -pnpm build --dev --qwik --qwikcity +pnpm build --dev --qwik --qwikrouter ``` The `--dev` flag skips type checking and generating. @@ -187,9 +187,8 @@ You can run `pnpm build` without parameters to see which flags are available. No - `--tsc`: build types - `--api`: build API docs and type bundles. Requires `--tsc` to have run. - `--build`: Qwik (you'll probably also need `--dev`) -- `--qwikcity`: Qwik City (you'll probably also need `--dev`) +- `--qwikrouter`: Qwik Router (you'll probably also need `--dev`) - `--qwikreact`: Qwik React -- `--qwiklabs`: Qwik Labs - `--eslint`: Eslint plugin E.g. to build only the React integration, you'd run `pnpm build --qwikreact`. @@ -218,7 +217,7 @@ It will build **everything**, including Rust packages and WASM. pnpm build.full ``` -The build output will be written to `packages/qwik/dist`, which will be the directory that is published to [@builder.io/qwik](https://www.npmjs.com/package/@builder.io/qwik). +The build output will be written to `packages/qwik/dist`, which will be the directory that is published to [@qwik.dev/core](https://www.npmjs.com/package/@qwik.dev/core). To update the Rust test snapshots after you've made changes to the Rust code, run `pnpm test.rust.update`. @@ -231,12 +230,12 @@ Assuming qwik is in `../qwik`, run this inside the root of your app: ```shell pnpm link ../qwik/packages/qwik -pnpm link ../qwik/packages/qwik-city +pnpm link ../qwik/packages/qwik-router ``` -Other package managers probably need to first be told about the packages. For example, with `bun` you need to `cd ../qwik/packages/qwik` and `bun link`, repeat for `qwik-city`. Then in your app run `bun link @builder.io/qwik @builder.io/qwik-city`. +Other package managers probably need to first be told about the packages. For example, with `bun` you need to `cd ../qwik/packages/qwik` and `bun link`, repeat for `qwik-router`. Then in your app run `bun link @qwik.dev/core @qwik.dev/router`. -If you can't use package linking, just copy the contents of `packages/qwik` into your projects' `node_modules/@builder.io/qwik` folder, and/or the contents of `packages/qwik-city` into your projects' `node_modules/@builder.io/qwik-city` folder. +If you can't use package linking, just copy the contents of `packages/qwik` into your projects' `node_modules/@qwik.dev/core` folder, and/or the contents of `packages/qwik-router` into your projects' `node_modules/@qwik.dev/router` folder. ### Working on the docs site @@ -318,7 +317,7 @@ For larger PRs, it would really help if you follow these guidelines. - Keep your commits focused and atomic. Each commit should represent a single, coherent change. - If you have commits like `wip lol` or `fixup`, squash them. Use `git rebase -i`. - Commits must follow the format: `type(scope): description` - For example: `feat(qwik-city): confetti animations` or `chore: pnpm api.update` + For example: `feat(qwik-router): confetti animations` or `chore: pnpm api.update` Common types include: diff --git a/Cargo.lock b/Cargo.lock index feddb1ec0a7..51d6bd69ae5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "ahash" version = "0.8.11" @@ -26,37 +41,26 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anyhow" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "ast_node" -version = "2.0.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94741d66bdda032fcbf33e621b4e3a888d7d11bd3ac4446d82c5593a136936ff" +checksum = "91fb5864e2f5bf9fd9797b94b2dfd1554d4c3092b535008b27d7e15c86675a2f" dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.89", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", + "syn 2.0.90", ] [[package]] @@ -65,6 +69,21 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + [[package]] name = "base64" version = "0.21.7" @@ -95,12 +114,6 @@ dependencies = [ "scoped-tls", ] -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.6.0" @@ -139,9 +152,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" dependencies = [ "shlex", ] @@ -158,30 +171,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "clap" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" -dependencies = [ - "atty", - "bitflags 1.3.2", - "clap_lex", - "indexmap 1.9.3", - "strsim", - "termcolor", - "textwrap", -] - -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] - [[package]] name = "console" version = "0.15.8" @@ -264,7 +253,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -325,7 +314,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -369,7 +358,7 @@ checksum = "8d7ccf961415e7aa17ef93dcb6c2441faaa8e768abe09e659b908089546f74c5" dependencies = [ "proc-macro2", "swc_macros_common", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -402,10 +391,10 @@ dependencies = [ ] [[package]] -name = "hashbrown" -version = "0.12.3" +name = "gimli" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "hashbrown" @@ -429,15 +418,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.3.9" @@ -573,7 +553,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -605,19 +585,9 @@ checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" [[package]] name = "indexmap" -version = "1.9.3" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -644,7 +614,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -655,10 +625,11 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -670,15 +641,15 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.166" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ccc108bbc0b1331bd061864e7cd823c0cab660bbe6970e66e2c0614decde36" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if 1.0.0", "windows-targets", @@ -743,19 +714,29 @@ dependencies = [ "libmimalloc-sys", ] +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + [[package]] name = "napi" version = "2.16.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "214f07a80874bb96a8433b3cdfc84980d56c7b02e1a0d7ba4ba0db5cef785e2b" dependencies = [ - "bitflags 2.6.0", + "bitflags", "ctor", "napi-derive", "napi-sys", "once_cell", "serde", "serde_json", + "tokio", ] [[package]] @@ -766,23 +747,23 @@ checksum = "e1c0f5d67ee408a4685b61f5ab7e58605c8ae3f2b4189f0127d804ff13d5560a" [[package]] name = "napi-derive" -version = "2.16.12" +version = "2.16.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17435f7a00bfdab20b0c27d9c56f58f6499e418252253081bfff448099da31d1" +checksum = "7cbe2585d8ac223f7d34f13701434b9d5f4eb9c332cccce8dee57ea18ab8ab0c" dependencies = [ "cfg-if 1.0.0", "convert_case", "napi-derive-backend", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] name = "napi-derive-backend" -version = "1.0.74" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "967c485e00f0bf3b1bdbe510a38a4606919cf1d34d9a37ad41f25a81aa077abe" +checksum = "1639aaa9eeb76e91c6ae66da8ce3e89e921cd3885e99ec85f4abacae72fc91bf" dependencies = [ "convert_case", "once_cell", @@ -790,7 +771,7 @@ dependencies = [ "quote", "regex", "semver 1.0.23", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -843,21 +824,24 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", ] [[package]] -name = "once_cell" -version = "1.20.2" +name = "object" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] [[package]] -name = "os_str_bytes" -version = "6.6.1" +name = "once_cell" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "outref" @@ -878,24 +862,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "path-absolutize" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4af381fe79fa195b4909485d99f73a80792331df0625188e707854f0b3383f5" -dependencies = [ - "path-dedot", -] - -[[package]] -name = "path-dedot" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ba0ad7e047712414213ff67533e6dd477af0a4e1d14fb52343e53d30ea9397" -dependencies = [ - "once_cell", -] - [[package]] name = "path-slash" version = "0.2.1" @@ -921,7 +887,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.6.0", + "indexmap", ] [[package]] @@ -954,7 +920,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -992,22 +958,22 @@ dependencies = [ [[package]] name = "ptr_meta" -version = "0.1.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +checksum = "fe9e76f66d3f9606f44e45598d155cb13ecf09f4a28199e48daf8c8fc937ea90" dependencies = [ "ptr_meta_derive", ] [[package]] name = "ptr_meta_derive" -version = "0.1.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +checksum = "ca414edb151b4c8d125c12566ab0d74dc9cdba36fb80eb7b848c15f495fd32d1" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.90", ] [[package]] @@ -1019,15 +985,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "qwik" -version = "0.1.0" -dependencies = [ - "clap", - "path-absolutize", - "qwik-core", -] - [[package]] name = "qwik-core" version = "0.2.0" @@ -1074,6 +1031,7 @@ dependencies = [ "napi-build", "napi-derive", "qwik-core", + "tokio", ] [[package]] @@ -1123,7 +1081,7 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 2.6.0", + "bitflags", ] [[package]] @@ -1161,6 +1119,12 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + [[package]] name = "rustc-hash" version = "1.1.0" @@ -1264,7 +1228,7 @@ checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1393,20 +1357,14 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.89", + "syn 2.0.90", ] -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "swc_allocator" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52cacc28f0ada8e4e31a720dd849ff06864b10e6ab0a1aaa99c06456cfe046af" +checksum = "117d5d3289663f53022ebf157df8a42b3872d7ac759e63abf96b5987b85d4af3" dependencies = [ "bumpalo", "hashbrown 0.14.5", @@ -1417,9 +1375,9 @@ dependencies = [ [[package]] name = "swc_atoms" -version = "2.0.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d7211e5c57ea972f32b8a104d7006c4a68d094ec30c6a73bcd20d4d6c473c7c" +checksum = "151a6feb82b989a087433baca7f6a6eb4fcf83f828c479eecd039c9312d60e10" dependencies = [ "hstr", "once_cell", @@ -1443,9 +1401,9 @@ dependencies = [ [[package]] name = "swc_common" -version = "4.0.1" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f87a21612a324493fd065e9c6fea960b4031088a213db782e2ca71d2fabb3ec" +checksum = "a521e8120dc0401580864a643b5bffa035c29fc3fc41697c972743d4f008ed22" dependencies = [ "ast_node", "better_scoped_tls", @@ -1475,7 +1433,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4aa30931f9b26af8edcb4cce605909d15dcfd7577220b22c50a2988f2a53c4c1" dependencies = [ "anyhow", - "indexmap 2.6.0", + "indexmap", "serde", "serde_json", "swc_cached", @@ -1491,16 +1449,16 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] name = "swc_ecma_ast" -version = "4.0.1" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bdab7759509c1b37ec77bd9fc231f525b888d9609c2963ce71995da1b27357c" +checksum = "94cf86f17358b93fcfe2876a9f0f7a7ebbff94cd6eaab4c809c7a0da1f4b892e" dependencies = [ - "bitflags 2.6.0", + "bitflags", "is-macro", "num-bigint", "phf", @@ -1514,9 +1472,9 @@ dependencies = [ [[package]] name = "swc_ecma_codegen" -version = "4.0.2" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e474f6c2671524dbb179b44a36425cb1a58928f0f7211c45043f0951a1842c5d" +checksum = "fb17e77270860f2a975c546c4609e9fa7ae8dbcf85260497e31af19890645800" dependencies = [ "memchr", "num-bigint", @@ -1541,14 +1499,14 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] name = "swc_ecma_parser" -version = "5.0.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c5ab8bd4cc4a4956514699c84d1a25cdb5a33f5ec760ec64ce712e973019c9" +checksum = "c2c361b4153905dc088a6bacfaa944b582305cf94fbfcaa9b3aa61a7dd3adbf9" dependencies = [ "either", "new_debug_unreachable", @@ -1568,9 +1526,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3570a4bbd8596ee82ad6cb35e25b3ba57deda503191c104af98cf9994922fdb" +checksum = "85be851a12e79e29bb4a60175a57de46219d71e662b13b67d5fa97d41a000116" dependencies = [ "swc_atoms", "swc_common", @@ -1585,13 +1543,13 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_base" -version = "5.0.1" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eb4000822f02b54af0be4f668649fa1e5555f1e3392479d17a277eb81a841f0" +checksum = "2409f9c896f99481d9f609de89c7786ccd0dba008650a4116f1aef7a58926422" dependencies = [ "better_scoped_tls", - "bitflags 2.6.0", - "indexmap 2.6.0", + "bitflags", + "indexmap", "once_cell", "phf", "rustc-hash", @@ -1615,17 +1573,17 @@ dependencies = [ "proc-macro2", "quote", "swc_macros_common", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] name = "swc_ecma_transforms_optimization" -version = "5.0.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63d691ccea03a8eb25f37c7498e7609ad76ca3dc2070b630596e49f0b8fd1f4" +checksum = "350a4965abfada7d5b23b3140896652acc11e110ac042a160bcea5bf8b08d367" dependencies = [ "dashmap", - "indexmap 2.6.0", + "indexmap", "once_cell", "petgraph", "rustc-hash", @@ -1644,13 +1602,13 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_react" -version = "5.0.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90002fdbe17f10c84cb29a102154a30ee5ad3e7165f0610d18ba8aa3a592924c" +checksum = "4cabf9375cfb71fc0e3d98e07e6fca39a18daa23d4878d8d2daa4c2b6c07b379" dependencies = [ "base64 0.21.7", "dashmap", - "indexmap 2.6.0", + "indexmap", "once_cell", "serde", "sha1", @@ -1669,9 +1627,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_typescript" -version = "5.0.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f67d5ff2ec723d075db340ac155877fea9607186f179e41ef2116aeef960a2cf" +checksum = "77346c37397fb238f991d6dccc027881caca539628e9a6c629299c7b94bdb08a" dependencies = [ "ryu-js", "serde", @@ -1686,11 +1644,11 @@ dependencies = [ [[package]] name = "swc_ecma_utils" -version = "5.0.1" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eb9a28511d17d1e6c5dfcf209368a1da4a542270c450fba7f27faf22c34df22" +checksum = "527fad9bdb16883782d55291fd3330925b3572f512ef89b3d92a29e2f713fe4f" dependencies = [ - "indexmap 2.6.0", + "indexmap", "num_cpus", "once_cell", "rustc-hash", @@ -1705,9 +1663,9 @@ dependencies = [ [[package]] name = "swc_ecma_visit" -version = "4.0.1" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5af5332117aa0424e418556f74e9cee335dc47eb7ae35dddbd9fd65fc01452c" +checksum = "b04c06c1805bda18c27165560f1617a57453feb9fb0638d90839053641af42d4" dependencies = [ "new_debug_unreachable", "num-bigint", @@ -1720,9 +1678,9 @@ dependencies = [ [[package]] name = "swc_ecmascript" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abce4f9d0b85f46cee2867501f8e8b0dc4585ec270027b242f75fc7e9c7381eb" +checksum = "b2e47bc421453ebe3c316c03ef1cbd5e4b563ae9055e6288e0cec3b669f5d3e1" dependencies = [ "swc_ecma_ast", "swc_ecma_codegen", @@ -1740,16 +1698,16 @@ checksum = "e96e15288bf385ab85eb83cff7f9e2d834348da58d0a31b33bdb572e66ee413e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] name = "swc_fast_graph" -version = "5.0.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f65856acf41991a43d47d19ca947ee34f1152fccc42f048063c64eaf45a8e26" +checksum = "c22e0a0478b1b06610453a97c8371cafa742e371a79aff860ccfbabe1ab160a7" dependencies = [ - "indexmap 2.6.0", + "indexmap", "petgraph", "rustc-hash", "swc_common", @@ -1763,7 +1721,7 @@ checksum = "a509f56fca05b39ba6c15f3e58636c3924c78347d63853632ed2ffcb6f5a0ac7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1789,9 +1747,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.89" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -1806,7 +1764,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1815,21 +1773,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "textwrap" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" - [[package]] name = "tinystr" version = "0.7.6" @@ -1840,6 +1783,16 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tokio" +version = "1.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" +dependencies = [ + "backtrace", + "pin-project-lite", +] + [[package]] name = "tracing" version = "0.1.41" @@ -1859,7 +1812,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1986,7 +1939,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "wasm-bindgen-shared", ] @@ -2008,7 +1961,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2050,15 +2003,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -2188,7 +2132,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "synstructure", ] @@ -2209,7 +2153,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2229,7 +2173,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "synstructure", ] @@ -2252,5 +2196,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] diff --git a/Cargo.toml b/Cargo.toml index f92a0a02909..cb01148c172 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,6 @@ members = [ "packages/qwik/src/napi", "packages/qwik/src/wasm", - "packages/qwik/src/optimizer/cli", "packages/qwik/src/optimizer/core", ] exclude = ["packages/qwik/src/wasm"] diff --git a/Makefile b/Makefile index 8597758b38b..84f3eab9160 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,9 @@ lint: test: cargo test --manifest-path packages/qwik/src/optimizer/core/Cargo.toml +benchmark: + cargo bench --manifest-path packages/qwik/src/optimizer/core/Cargo.toml + test-update: if ! cargo test --manifest-path packages/qwik/src/optimizer/core/Cargo.toml; then \ cd packages/qwik/src/optimizer/core/src/snapshots/; \ diff --git a/cspell.json b/cspell.json index b5fe53abe90..f7a61b211b7 100644 --- a/cspell.json +++ b/cspell.json @@ -187,8 +187,8 @@ "quicktime", "qvisible", "qwik", - "qwikauth", "qwikcity", + "qwikrouter", "qwikdeps", "qwikdom", "qwikevents", diff --git a/e2e/adapters-e2e/adapters/express/vite.config.ts b/e2e/adapters-e2e/adapters/express/vite.config.ts index bb9ee132041..22435517fb0 100644 --- a/e2e/adapters-e2e/adapters/express/vite.config.ts +++ b/e2e/adapters-e2e/adapters/express/vite.config.ts @@ -1,5 +1,5 @@ -import { nodeServerAdapter } from '@builder.io/qwik-city/adapters/node-server/vite'; -import { extendConfig } from '@builder.io/qwik-city/vite'; +import { nodeServerAdapter } from '@qwik.dev/router/adapters/node-server/vite'; +import { extendConfig } from '@qwik.dev/router/vite'; import baseConfig from '../../vite.config'; export default extendConfig(baseConfig, () => { @@ -7,7 +7,7 @@ export default extendConfig(baseConfig, () => { build: { ssr: true, rollupOptions: { - input: ['src/entry.express.tsx', '@qwik-city-plan'], + input: ['src/entry.express.tsx', '@qwik-router-config'], }, }, plugins: [nodeServerAdapter({ name: 'express' })], diff --git a/e2e/adapters-e2e/src/components/click-me/click-me.tsx b/e2e/adapters-e2e/src/components/click-me/click-me.tsx index 1141e7d5e9c..229aaaf1049 100644 --- a/e2e/adapters-e2e/src/components/click-me/click-me.tsx +++ b/e2e/adapters-e2e/src/components/click-me/click-me.tsx @@ -1,4 +1,4 @@ -import { component$, useSignal } from '@builder.io/qwik'; +import { component$, useSignal } from '@qwik.dev/core'; // We need to extract the component to see the bug on 1.5.7 export default component$(() => { diff --git a/e2e/adapters-e2e/src/components/router-head/router-head.tsx b/e2e/adapters-e2e/src/components/router-head/router-head.tsx index 44ee2fd5408..849545cf345 100644 --- a/e2e/adapters-e2e/src/components/router-head/router-head.tsx +++ b/e2e/adapters-e2e/src/components/router-head/router-head.tsx @@ -1,5 +1,5 @@ -import { component$ } from '@builder.io/qwik'; -import { useDocumentHead, useLocation } from '@builder.io/qwik-city'; +import { component$ } from '@qwik.dev/core'; +import { useDocumentHead, useLocation } from '@qwik.dev/router'; export const RouterHead = component$(() => { const head = useDocumentHead(); diff --git a/e2e/adapters-e2e/src/entry.dev.tsx b/e2e/adapters-e2e/src/entry.dev.tsx index 4f8f58fa5c3..6efcd8709c6 100644 --- a/e2e/adapters-e2e/src/entry.dev.tsx +++ b/e2e/adapters-e2e/src/entry.dev.tsx @@ -9,7 +9,7 @@ * - More code is transferred to the browser than in SSR mode. * - Optimizer/Serialization/Deserialization code is not exercised! */ -import { render, type RenderOptions } from '@builder.io/qwik'; +import { render, type RenderOptions } from '@qwik.dev/core'; import Root from './root'; export default function (opts: RenderOptions) { diff --git a/e2e/adapters-e2e/src/entry.express.tsx b/e2e/adapters-e2e/src/entry.express.tsx index 9edba3480c8..b32a8abc2af 100644 --- a/e2e/adapters-e2e/src/entry.express.tsx +++ b/e2e/adapters-e2e/src/entry.express.tsx @@ -7,19 +7,14 @@ * - https://qwik.dev/docs/deployments/node/ * */ -import { createQwikCity, type PlatformNode } from '@builder.io/qwik-city/middleware/node'; +import { createQwikRouter } from '@qwik.dev/router/middleware/node'; import 'dotenv/config'; -import qwikCityPlan from '@qwik-city-plan'; -import { manifest } from '@qwik-client-manifest'; +import qwikRouterConfig from '@qwik-router-config'; import render from './entry.ssr'; import express from 'express'; import { fileURLToPath } from 'node:url'; import { join } from 'node:path'; -declare global { - interface QwikCityPlatform extends PlatformNode {} -} - // Directories where the static assets are located const distDir = join(fileURLToPath(import.meta.url), '..', '..', 'dist'); const buildDir = join(distDir, 'build'); @@ -28,10 +23,9 @@ const buildDir = join(distDir, 'build'); const PORT = process.env.PORT ?? 3000; // Create the Qwik City Node middleware -const { router, notFound } = createQwikCity({ +const { router, notFound } = createQwikRouter({ render, - qwikCityPlan, - manifest, + qwikRouterConfig, // getOrigin(req) { // // If deploying under a proxy, you may need to build the origin from the request headers // // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto diff --git a/e2e/adapters-e2e/src/entry.preview.tsx b/e2e/adapters-e2e/src/entry.preview.tsx index 3882063a3f8..24cd462afb0 100644 --- a/e2e/adapters-e2e/src/entry.preview.tsx +++ b/e2e/adapters-e2e/src/entry.preview.tsx @@ -10,10 +10,10 @@ * - https://vitejs.dev/config/preview-options.html#preview-options * */ -import { createQwikCity } from '@builder.io/qwik-city/middleware/node'; -import qwikCityPlan from '@qwik-city-plan'; +import { createQwikRouter } from '@qwik.dev/router/middleware/node'; +import qwikRouterConfig from '@qwik-router-config'; // make sure qwikCityPlan is imported before entry import render from './entry.ssr'; /** The default export is the QwikCity adapter used by Vite preview. */ -export default createQwikCity({ render, qwikCityPlan }); +export default createQwikRouter({ render, qwikRouterConfig }); diff --git a/e2e/adapters-e2e/src/entry.ssr.tsx b/e2e/adapters-e2e/src/entry.ssr.tsx index cdd6fbe6e59..2b563785e7b 100644 --- a/e2e/adapters-e2e/src/entry.ssr.tsx +++ b/e2e/adapters-e2e/src/entry.ssr.tsx @@ -9,13 +9,11 @@ * - Npm run preview * - Npm run build */ -import { renderToStream, type RenderToStreamOptions } from '@builder.io/qwik/server'; -import { manifest } from '@qwik-client-manifest'; +import { renderToStream, type RenderToStreamOptions } from '@qwik.dev/core/server'; import Root from './root'; export default function (opts: RenderToStreamOptions) { return renderToStream(, { - manifest, ...opts, // Use container attributes to set attributes on the html tag. containerAttributes: { diff --git a/e2e/adapters-e2e/src/root.tsx b/e2e/adapters-e2e/src/root.tsx index 5ac35517c3f..505af2e5942 100644 --- a/e2e/adapters-e2e/src/root.tsx +++ b/e2e/adapters-e2e/src/root.tsx @@ -1,5 +1,5 @@ -import { component$ } from '@builder.io/qwik'; -import { QwikCityProvider, RouterOutlet, ServiceWorkerRegister } from '@builder.io/qwik-city'; +import { component$ } from '@qwik.dev/core'; +import { QwikRouterProvider, RouterOutlet } from '@qwik.dev/router'; import { RouterHead } from './components/router-head/router-head'; export default component$(() => { @@ -11,17 +11,14 @@ export default component$(() => { */ return ( - + - + - {/* - */} - - + ); }); diff --git a/e2e/adapters-e2e/src/routes/index.tsx b/e2e/adapters-e2e/src/routes/index.tsx index d3585ff0a69..0b0d900960a 100644 --- a/e2e/adapters-e2e/src/routes/index.tsx +++ b/e2e/adapters-e2e/src/routes/index.tsx @@ -1,5 +1,5 @@ -import { component$ } from '@builder.io/qwik'; -import { type DocumentHead } from '@builder.io/qwik-city'; +import { component$ } from '@qwik.dev/core'; +import { type DocumentHead } from '@qwik.dev/router'; import ClickMe from '~/components/click-me/click-me'; export default component$(() => { diff --git a/e2e/adapters-e2e/src/routes/layout.tsx b/e2e/adapters-e2e/src/routes/layout.tsx index d0e76e6d853..b34adeb0db8 100644 --- a/e2e/adapters-e2e/src/routes/layout.tsx +++ b/e2e/adapters-e2e/src/routes/layout.tsx @@ -1,4 +1,4 @@ -import { component$, Slot } from '@builder.io/qwik'; +import { component$, Slot } from '@qwik.dev/core'; export default component$(() => { return ; diff --git a/e2e/adapters-e2e/src/routes/profile/index.tsx b/e2e/adapters-e2e/src/routes/profile/index.tsx index 1f6f835a4b2..e210d13b7c8 100644 --- a/e2e/adapters-e2e/src/routes/profile/index.tsx +++ b/e2e/adapters-e2e/src/routes/profile/index.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export default component$(() => { return ( diff --git a/e2e/adapters-e2e/src/routes/service-worker.ts b/e2e/adapters-e2e/src/routes/service-worker.ts index fb1bb3fd75e..e69de29bb2d 100644 --- a/e2e/adapters-e2e/src/routes/service-worker.ts +++ b/e2e/adapters-e2e/src/routes/service-worker.ts @@ -1,18 +0,0 @@ -/* - * WHAT IS THIS FILE? - * - * The service-worker.ts file is used to have state of the art prefetching. - * https://qwik.dev/qwikcity/prefetching/overview/ - * - * Qwik uses a service worker to speed up your site and reduce latency, ie, not used in the traditional way of offline. - * You can also use this file to add more functionality that runs in the service worker. - */ -import { setupServiceWorker } from '@builder.io/qwik-city/service-worker'; - -setupServiceWorker(); - -addEventListener('install', () => self.skipWaiting()); - -addEventListener('activate', () => self.clients.claim()); - -declare const self: ServiceWorkerGlobalScope; diff --git a/e2e/adapters-e2e/tsconfig.json b/e2e/adapters-e2e/tsconfig.json index 634e8d388b9..97ae6fad669 100644 --- a/e2e/adapters-e2e/tsconfig.json +++ b/e2e/adapters-e2e/tsconfig.json @@ -6,7 +6,7 @@ "module": "ES2022", "lib": ["es2022", "DOM", "WebWorker", "DOM.Iterable"], "jsx": "react-jsx", - "jsxImportSource": "@builder.io/qwik", + "jsxImportSource": "@qwik.dev/core", "strict": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, diff --git a/e2e/adapters-e2e/vite.config.ts b/e2e/adapters-e2e/vite.config.ts index 33041ccc0ca..3e34bbef134 100644 --- a/e2e/adapters-e2e/vite.config.ts +++ b/e2e/adapters-e2e/vite.config.ts @@ -2,8 +2,8 @@ * This is the base config for vite. When building, the adapter config is used which loads this file * and extends it. */ -import { qwikCity } from '@builder.io/qwik-city/vite'; -import { qwikVite } from '@builder.io/qwik/optimizer'; +import { qwikRouter } from '@qwik.dev/router/vite'; +import { qwikVite } from '@qwik.dev/core/optimizer'; import { defineConfig, type UserConfig } from 'vite'; import tsconfigPaths from 'vite-tsconfig-paths'; import pkg from './package.json'; @@ -17,13 +17,13 @@ const { dependencies = {}, devDependencies = {} } = pkg as any as { errorOnDuplicatesPkgDeps(devDependencies, dependencies); /** - * Note that Vite normally starts from `index.html` but the qwikCity plugin makes start at + * Note that Vite normally starts from `index.html` but the qwikRouter plugin makes start at * `src/entry.ssr.tsx` instead. */ export default defineConfig(({ command, mode }): UserConfig => { return { plugins: [ - qwikCity(), + qwikRouter(), qwikVite(), tsconfigPaths({ root: '.', diff --git a/e2e/qwik-cli-e2e/README.md b/e2e/qwik-cli-e2e/README.md index 3320cf62cd1..2b360645c50 100644 --- a/e2e/qwik-cli-e2e/README.md +++ b/e2e/qwik-cli-e2e/README.md @@ -10,7 +10,7 @@ Tests can be invoked by running `pnpm run test.e2e.cli`. E2E project does the following internally: -0. Vitest is configured to run a setup function once **PRIOR TO ALL** tests. During the setup `@builder.io/qwik`, `@builder.io/qwik-city` and `eslint-plugin-qwik` packages will be packed with `pnpm pack` Those will be used at a step 2 for every test. Tarballs are located in `temp/tarballs` folder within this repo. It is assumed that packages are built before E2E is executed. +0. Vitest is configured to run a setup function once **PRIOR TO ALL** tests. During the setup `@qwik.dev/core`, `@qwik.dev/router` and `eslint-plugin-qwik` packages will be packed with `pnpm pack` Those will be used at a step 2 for every test. Tarballs are located in `temp/tarballs` folder within this repo. It is assumed that packages are built before E2E is executed. 1. Simulates `npm create qwik` locally using direct command `node packages/create-qwik/create-qwik.cjs playground {outputDir}` @@ -21,7 +21,7 @@ E2E project does the following internally: Note that provided folder should exist. If custom path is used, generated application will not be removed after the test completes, which is helpful for debugging. -2. Uses packed `@builder.io/qwik`, `@builder.io/qwik-city` and `eslint-plugin-qwik` packages to update package.json file of the generated application with `file:path-to-package.tgz`. +2. Uses packed `@qwik.dev/core`, `@qwik.dev/router` and `eslint-plugin-qwik` packages to update package.json file of the generated application with `file:path-to-package.tgz`. 3. Runs actual tests. Please pay attention at the `beforeAll` hook in the spec file @@ -48,4 +48,4 @@ Both `config.cleanupFn();` and `killAllRegisteredProcesses` there are extremely ## Adding new tests -Right now we have only one test file within this project. This means only one test application will be created and used, which is good from the execution time standpoint. If more files are added, it shouldn't potentially be a problem as we have `fileParallelism: false` set in the `vite.config.ts`, which means only one test will be executed at a time. This obviously slows down the execution time, but is safer, because we're working with a real file system. +Right now we have only one test file within this project. This means only one test application will be created and used, which is good from the execution time standpoint. If more files are added, it shouldn't potentially be a problem as we have `fileParallelism: false` set in the `vite.config.mts`, which means only one test will be executed at a time. This obviously slows down the execution time, but is safer, because we're working with a real file system. diff --git a/e2e/qwik-cli-e2e/package.json b/e2e/qwik-cli-e2e/package.json index db74902f146..b0a98646444 100644 --- a/e2e/qwik-cli-e2e/package.json +++ b/e2e/qwik-cli-e2e/package.json @@ -6,7 +6,7 @@ }, "private": true, "scripts": { - "e2e": "vitest run --config=vite.config.ts", - "e2e.watch": "vitest watch --config=vite.config.ts" + "e2e": "vitest run --config=vite.config.mts", + "e2e.watch": "vitest watch --config=vite.config.mts" } } diff --git a/e2e/qwik-cli-e2e/utils/index.ts b/e2e/qwik-cli-e2e/utils/index.ts index 274df26d58d..610703eb5c1 100644 --- a/e2e/qwik-cli-e2e/utils/index.ts +++ b/e2e/qwik-cli-e2e/utils/index.ts @@ -1,10 +1,10 @@ import { ChildProcess, exec, execSync } from 'child_process'; +import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'fs'; +import { yellow } from 'kleur/colors'; +import { dirname, join, resolve } from 'path'; import { dirSync } from 'tmp'; -import { existsSync, mkdirSync, readFileSync, rmSync, rmdirSync, writeFileSync } from 'fs'; -import { promisify } from 'util'; -import { resolve, join, dirname } from 'path'; import treeKill from 'tree-kill'; -import { yellow } from 'kleur/colors'; +import { promisify } from 'util'; import { createDocument } from '../../../packages/qwik/src/testing/document'; export function scaffoldQwikProject(): { tmpDir: string; cleanupFn: () => void } { @@ -106,6 +106,7 @@ export function runCommandUntil( function checkCriteria(c: any) { output += c.toString(); + console.warn(output); if (criteria(stripConsoleColors(output)) && !complete) { complete = true; res(p); diff --git a/e2e/qwik-cli-e2e/utils/setup.ts b/e2e/qwik-cli-e2e/utils/setup.ts index 60096c0b3ad..84e8975c2fe 100644 --- a/e2e/qwik-cli-e2e/utils/setup.ts +++ b/e2e/qwik-cli-e2e/utils/setup.ts @@ -1,16 +1,16 @@ import { execSync } from 'child_process'; +import { existsSync, writeFileSync } from 'fs'; import { join } from 'path'; import { workspaceRoot } from '.'; -import { existsSync, writeFileSync } from 'fs'; const packageCfg = { - '@builder.io/qwik': { + '@qwik.dev/core': { packagePath: 'packages/qwik', distPath: 'packages/qwik/dist', }, - '@builder.io/qwik-city': { - packagePath: 'packages/qwik-city', - distPath: 'packages/qwik-city/lib', + '@qwik.dev/router': { + packagePath: 'packages/qwik-router', + distPath: 'packages/qwik-router/lib', }, 'eslint-plugin-qwik': { packagePath: 'packages/eslint-plugin-qwik', @@ -28,11 +28,12 @@ function packPackages() { const tarballPaths: { name: string; absolutePath: string }[] = []; const tarballOutDir = join(workspaceRoot, 'temp', 'tarballs'); for (const [name, cfg] of Object.entries(packageCfg)) { - const out = execSync(`pnpm pack --pack-destination=${tarballOutDir}`, { + const out = execSync(`pnpm pack --json --pack-destination=${tarballOutDir}`, { cwd: join(workspaceRoot, cfg.packagePath), encoding: 'utf-8', }); - tarballPaths.push({ name, absolutePath: out.replace(/(\r\n|\n|\r)/gm, '') }); + const json = JSON.parse(out); + tarballPaths.push({ name, absolutePath: json.filename }); } writeFileSync(join(tarballOutDir, 'paths.json'), JSON.stringify(tarballPaths)); } diff --git a/e2e/qwik-cli-e2e/vite.config.ts b/e2e/qwik-cli-e2e/vite.config.mts similarity index 100% rename from e2e/qwik-cli-e2e/vite.config.ts rename to e2e/qwik-cli-e2e/vite.config.mts diff --git a/eslint.config.js b/eslint.config.js deleted file mode 100644 index 0ff0bdcfac2..00000000000 --- a/eslint.config.js +++ /dev/null @@ -1,112 +0,0 @@ -import globals from 'globals'; -import js from '@eslint/js'; -import tseslint from 'typescript-eslint'; -import noOnlyTests from 'eslint-plugin-no-only-tests'; -import { globalIgnores } from 'eslint/config'; -// import { qwikEslint9Plugin } from 'eslint-plugin-qwik'; - -const ignores = [ - '**/.history', - '**/.vscode', - '**/dist', - '**/dist-dev', - '**/lib', - '**/node_modules', - '**/tsc-out', - '**/external', - '**/*.', - '**/*.log', - '**/etc', - '**/target', - '**/temp', - '**/tsdoc-metadata.json', - '**/.DS_Store', - '**/*.mp4', - 'scripts', - '**/server/**/*.js', - '**/*.tsbuildinfo', - 'packages/docs/api', - 'packages/docs/public/repl/repl-sw.js*', - 'packages/docs/src/routes/examples/apps', - 'packages/docs/src/routes/playground/app', - 'packages/docs/src/routes/tutorial', - 'packages/qwik-labs/lib', - 'packages/qwik-labs/lib-types', - 'packages/qwik-labs/vite', - 'packages/insights/drizzle.config.ts', - 'packages/insights/panda.config.ts', - 'starters/apps/base', - 'starters/apps/library', - 'starters/templates', - '**/vite.config.ts', - // packages with eslint.config.mjs - 'packages/qwik-labs', - 'packages/insights', - 'starters', - // eslint.config.* - '**/eslint.config.mjs', - '**/eslint.config.js', -]; - -export default tseslint.config( - globalIgnores(ignores), - js.configs.recommended, - tseslint.configs.recommended, - // qwikEslint9Plugin.configs.recommended, - { - languageOptions: { - globals: { - ...globals.browser, - ...globals.node, - ...globals.es2021, - }, - parserOptions: { - // Needed when using the qwik plugin - // projectService: true, - // tsconfigRootDir: import.meta.dirname, - }, - }, - }, - { - plugins: { - 'no-only-tests': noOnlyTests, - }, - rules: { - 'no-only-tests/no-only-tests': 'error', - }, - name: 'no-only-tests', - }, - { - rules: { - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/no-inferrable-types': 'off', - '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/no-empty-interface': 'off', - '@typescript-eslint/no-namespace': 'off', - '@typescript-eslint/no-empty-function': 'off', - '@typescript-eslint/no-this-alias': 'off', - '@typescript-eslint/ban-types': 'off', - '@typescript-eslint/ban-ts-comment': 'off', - 'prefer-spread': 'off', - 'no-case-declarations': 'off', - 'no-console': ['error', { allow: ['warn', 'error'] }], - 'no-only-tests/no-only-tests': 'error', - '@typescript-eslint/no-unused-vars': 'off', - '@typescript-eslint/no-var-requires': 'off', - curly: 'error', - 'no-new-func': 'error', - '@typescript-eslint/no-empty-object-type': 'off', - '@typescript-eslint/no-unused-expressions': 'off', - '@typescript-eslint/no-unsafe-function-type': 'off', - '@typescript-eslint/no-require-imports': 'off', - '@typescript-eslint/no-wrapper-object-types': 'off', - }, - }, - { - files: ['packages/docs/**/*.{ts,tsx}'], - rules: { - 'no-console': 'off', - }, - } -); diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000000..dcc4bcb7897 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,161 @@ +import globals from 'globals'; +import js from '@eslint/js'; +import tseslint from 'typescript-eslint'; +import noOnlyTests from 'eslint-plugin-no-only-tests'; +import { globalIgnores } from 'eslint/config'; +// import { qwikEslint9Plugin } from 'eslint-plugin-qwik'; + +const ignores = [ + '**/.history', + '**/.vscode', + '**/dist', + '**/dist-dev', + '**/lib', + '**/node_modules', + '**/tsc-out', + '**/external', + '**/*.', + '**/*.log', + '**/etc', + '**/target', + '**/temp', + '**/tsdoc-metadata.json', + '**/.DS_Store', + '**/*.mp4', + 'scripts', + '**/server/**/*.js', + '**/*.tsbuildinfo', + 'packages/docs/api', + 'packages/docs/public/repl/repl-sw.js*', + 'packages/docs/src/routes/examples/apps', + 'packages/docs/src/routes/playground/app', + 'packages/docs/src/routes/tutorial', + 'packages/qwik/src/optimizer/core/src/fixtures', + 'packages/qwik/bindings', + 'packages/qwik-labs/lib', + 'packages/qwik-labs/lib-types', + 'packages/qwik-labs/vite', + 'packages/insights/drizzle.config.ts', + 'packages/insights/panda.config.ts', + 'packages/qwik/src/napi', + 'starters/apps/base', + 'starters/apps/library', + 'starters/templates', + '**/vite.config.ts', + // packages with eslint.config.mjs + 'packages/qwik-labs', + 'packages/insights', + 'starters', + // eslint.config.* + '**/eslint.config.mjs', + '**/eslint.config.js', + '.changeset', + 'packages/docs/public/builder', +]; + +export default tseslint.config( + globalIgnores(ignores), + js.configs.recommended, + tseslint.configs.recommended, + // qwikEslint9Plugin.configs.recommended, + { + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + ...globals.es2021, + }, + parserOptions: { + // Needed when using the qwik plugin + // projectService: true, + // tsconfigRootDir: import.meta.dirname, + }, + }, + }, + { + plugins: { + 'no-only-tests': noOnlyTests, + }, + rules: { + 'no-only-tests/no-only-tests': 'error', + }, + name: 'no-only-tests', + }, + { + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-inferrable-types': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-empty-interface': 'off', + '@typescript-eslint/no-namespace': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/no-this-alias': 'off', + '@typescript-eslint/ban-types': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + 'prefer-spread': 'off', + 'no-case-declarations': 'off', + 'no-console': ['error', { allow: ['warn', 'error'] }], + 'no-only-tests/no-only-tests': 'error', + '@typescript-eslint/no-unused-vars': 'off', + '@typescript-eslint/no-var-requires': 'off', + curly: 'error', + 'no-new-func': 'error', + '@typescript-eslint/no-empty-object-type': 'off', + '@typescript-eslint/no-unused-expressions': 'off', + '@typescript-eslint/no-unsafe-function-type': 'off', + '@typescript-eslint/no-require-imports': 'off', + '@typescript-eslint/no-wrapper-object-types': 'off', + }, + }, + { + files: ['packages/docs/**/*.{ts,tsx}'], + rules: { + 'no-console': 'off', + }, + }, + { + files: ['packages/qwik/src/server/**/*.ts'], + ignores: ['packages/qwik/src/server/qwik-copy.ts'], + rules: { + '@typescript-eslint/no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['packages/*'], + message: 'Absolute imports are not allowed.', + }, + { + group: ['../**'], + message: 'Relative imports are not allowed.', + }, + ], + }, + ], + 'no-duplicate-imports': 'error', + }, + }, + { + files: ['packages/qwik/src/server/qwik-types.ts'], + rules: { + '@typescript-eslint/no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['packages/*'], + message: 'Absolute imports are not allowed.', + allowTypeImports: true, + }, + { + group: ['../**'], + message: 'Relative imports are not allowed.', + allowTypeImports: true, + }, + ], + }, + ], + }, + } +); diff --git a/package.json b/package.json index d9c46f24305..87efcc892e3 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,11 @@ { "name": "qwik-monorepo", "version": "0.0.0-read-qwik-package-json", + "author": "Qwik Team", "comments": { - "01": "devDependencies includes reference to @builder.io/qwik: workspace: *. This is needed or e2e tests will fail", + "01": "devDependencies includes reference to @qwik.dev/core: workspace:*. This is needed or e2e tests will fail", "02": " It would be nice to be able to remove this dependency and fix the test.", - "03": "devDependencies can't include reference to @builder.io/qwik-city or e2e test will fail." + "03": "devDependencies can't include reference to @qwik.dev/router or e2e test will fail." }, "config": { "syncpack": { @@ -18,7 +19,7 @@ "dependencies": [ "vite" ], - "pinVersion": "^5" + "pinVersion": ">=5 <7" }, { "label": "use workspace protocol for local packages and allow patch versions (used in e.g. qwik-react)", @@ -39,7 +40,7 @@ "dependencyTypes": [ "dev" ], - "pinVersion": "workspace:^" + "pinVersion": "workspace:*" }, { "label": "Separate prod deps from dev deps", @@ -60,13 +61,6 @@ } ], "semverGroups": [ - { - "label": "Undici should always be * until we remove it", - "dependencies": [ - "undici" - ], - "range": "*" - }, { "label": "use exact version numbers for devDependencies", "dependencyTypes": [ @@ -77,31 +71,12 @@ ] } }, - "contributors": [ - { - "name": "Miško Hevery", - "email": "misko@hevery.com", - "url": "https://twitter.com/mhevery" - }, - { - "name": "Adam Bradley", - "email": "adam@builder.io", - "url": "https://twitter.com/adamdbradley" - }, - { - "name": "Manu Mtz.-Almeida", - "email": "manu@builder.io", - "url": "https://twitter.com/manucorporat" - } - ], "dependencies": { "esbuild-plugin-raw": "^0.1.8" }, "devDependencies": { "@builder.io/partytown": "0.10.2", - "@builder.io/qwik": "workspace:^", - "@builder.io/qwik-city": "workspace:^", - "@changesets/cli": "2.28.1", + "@changesets/cli": "2.29.3", "@changesets/get-github-info": "0.6.0", "@changesets/types": "6.1.0", "@clack/prompts": "0.7.0", @@ -114,6 +89,8 @@ "@node-rs/helper": "1.6.0", "@octokit/action": "6.1.0", "@playwright/test": "1.50.1", + "@qwik.dev/core": "workspace:*", + "@qwik.dev/router": "workspace:*", "@types/brotli": "1.3.4", "@types/bun": "1.1.6", "@types/cross-spawn": "6.0.6", @@ -125,17 +102,19 @@ "@types/semver": "7.5.8", "@types/tmp": "0.2.6", "@types/which-pm-runs": "1.0.2", + "@vitest/coverage-v8": "3.1.1", "all-contributors-cli": "6.26.1", "brotli": "1.3.3", "concurrently": "8.2.2", - "create-qwik": "workspace:^", + "create-qwik": "workspace:*", "cross-spawn": "7.0.3", "csstype": "3.1.3", "dotenv": "16.4.5", "esbuild": "0.25.4", "eslint": "9.25.1", + "eslint-plugin-import": "2.29.1", "eslint-plugin-no-only-tests": "3.3.0", - "eslint-plugin-qwik": "workspace:^", + "eslint-plugin-qwik": "workspace:*", "execa": "8.0.1", "express": "4.20.0", "globals": "16.0.0", @@ -144,8 +123,8 @@ "monaco-editor": "0.45.0", "mri": "1.2.0", "path-browserify": "1.0.1", - "prettier": "3.3.3", - "prettier-plugin-jsdoc": "1.3.0", + "prettier": "3.4.2", + "prettier-plugin-jsdoc": "1.3.2", "pretty-quick": "4.0.0", "prompts": "2.4.2", "rollup": "4.39.0", @@ -155,25 +134,24 @@ "source-map": "0.7.4", "svgo": "3.3.2", "syncpack": "12.3.3", - "terser": "5.31.3", + "terser": "5.37.0", "tmp": "0.2.3", "tree-kill": "1.2.2", - "tsx": "4.19.1", - "typescript": "5.4.5", + "tsx": "4.19.2", + "typescript": "5.8.2", "typescript-eslint": "8.26.1", - "undici": "*", "vfile": "6.0.2", - "vite": "5.3.5", - "vite-imagetools": "7.0.4", - "vite-plugin-dts": "3.9.1", - "vite-tsconfig-paths": "4.3.2", - "vitest": "2.0.5", + "vite": "6.2.6", + "vite-imagetools": "7.0.5", + "vite-plugin-dts": "4.5.3", + "vite-tsconfig-paths": "5.1.4", + "vitest": "3.1.1", "watchlist": "0.3.1", "which-pm-runs": "1.1.0", "zod": "3.22.4" }, "engines": { - "node": ">=16.8.0 <18.0.0 || >=18.11", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", "npm": "please-use-pnpm", "yarn": "please-use-pnpm", "pnpm": ">=9.0.5" @@ -181,12 +159,13 @@ "packageManager": "pnpm@9.15.5", "pnpm": { "overrides": { - "typescript": "5.4.5", + "typescript": "5.8.2", "vfile": "6.0.2", "@supabase/realtime-js": "2.8.4" }, "patchedDependencies": { - "density-clustering@1.3.0": "patches/density-clustering@1.3.0.patch" + "density-clustering@1.3.0": "patches/density-clustering@1.3.0.patch", + "@auth/qwik": "patches/@auth__qwik.patch" } }, "private": true, @@ -197,20 +176,20 @@ "build.clean": "tsx ./scripts/build-clean.ts", "build.cli": "tsx --require ./scripts/runBefore.ts scripts/index.ts --cli --dev", "build.cli.prod": "tsx --require ./scripts/runBefore.ts scripts/index.ts --cli", - "build.core": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --build --qwikcity --api --platform-binding", + "build.core": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --qwik --insights --qwikrouter --api --platform-binding", "build.eslint": "tsx --require ./scripts/runBefore.ts scripts/index.ts --eslint", - "build.full": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --tsc-docs --build --supabaseauthhelpers --api --eslint --qwikcity --qwikworker --qwiklabs --qwikreact --qwikauth --cli --platform-binding --wasm", - "build.local": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --tsc-docs --build --supabaseauthhelpers --api --eslint --qwikcity --qwikworker --qwiklabs --qwikreact --qwikauth --cli --platform-binding-wasm-copy", - "build.only_javascript": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --build --api", + "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", + "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", + "build.only_javascript": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --qwik --api", "build.packages.docs": "pnpm -C ./packages/docs/ run build", "build.packages.insights": "pnpm -C ./packages/insights/ run build", "build.platform": "tsx --require ./scripts/runBefore.ts scripts/index.ts --platform-binding", "build.platform.copy": "tsx --require ./scripts/runBefore.ts scripts/index.ts --platform-binding-wasm-copy", - "build.qwik-city": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --qwikcity", - "build.validate": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --build --api --eslint --qwikcity --platform-binding --wasm --validate", - "build.vite": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --build --api --qwikcity --eslint --platform-binding-wasm-copy", + "build.qwik-router": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --qwikrouter", + "build.validate": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --qwik --api --eslint --qwikrouter --platform-binding --wasm --validate", + "build.vite": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --qwik --insights --api --qwikrouter --eslint --platform-binding-wasm-copy", "build.wasm": "tsx --require ./scripts/runBefore.ts scripts/index.ts --wasm", - "build.watch": "tsx --require ./scripts/runBefore.ts scripts/index.ts --build --qwikcity --watch --dev --platform-binding", + "build.watch": "tsx --require ./scripts/runBefore.ts scripts/index.ts --qwik --qwikrouter --watch --dev --platform-binding", "change": "changeset", "cli": "pnpm build.cli && node packages/create-qwik/create-qwik.cjs && tsx --require ./scripts/runBefore.ts scripts/validate-cli.ts --copy-local-qwik-dist", "cli.qwik": "pnpm build.cli && node packages/qwik/qwik-cli.cjs", @@ -222,9 +201,9 @@ "eslint.update": "tsx --require ./scripts/runBefore.ts scripts/eslint-docs.ts", "fmt": "pnpm prettier.fix && pnpm syncpack format", "fmt.staged": "pretty-quick --staged", - "link.dist": "cd packages/qwik && pnpm link --global && cd ../qwik-city && pnpm link --global && cd ../eslint-plugin-qwik && pnpm link --global && cd ../qwik-react && pnpm link --global", - "link.dist.npm": "cd packages/qwik && npm link && cd ../qwik-city && npm link && cd ../eslint-plugin-qwik && npm link && cd ../qwik-react && npm link", - "link.dist.yarn": "cd packages/qwik && yarn link && cd ../qwik-city && yarn link && cd ../eslint-plugin-qwik && yarn link && cd ../qwik-react && yarn link", + "link.dist": "cd packages/qwik && pnpm link --global && cd ../qwik-router && pnpm link --global && cd ../eslint-plugin-qwik && pnpm link --global && cd ../qwik-react && pnpm link --global", + "link.dist.npm": "cd packages/qwik && npm link && cd ../qwik-router && npm link && cd ../eslint-plugin-qwik && npm link && cd ../qwik-react && npm link", + "link.dist.yarn": "cd packages/qwik && yarn link && cd ../qwik-router && yarn link && cd ../eslint-plugin-qwik && yarn link && cd ../qwik-react && yarn link", "lint": "pnpm lint.eslint && pnpm lint.prettier && pnpm lint.rust", "lint.eslint": "eslint --cache \"**/*.ts*\" && pnpm -r --parallel lint", "lint.fix": "eslint --fix \"**/*.ts*\" && pnpm -r --parallel lint.fix && pnpm prettier.fix", @@ -237,7 +216,7 @@ "qwik-push-build-repos": "tsx --require ./scripts/runBefore.ts ./scripts/qwik-push-build-repos.ts", "release": "changeset publish", "release.fixup-package-json": "syncpack fix-mismatches --config syncpack-release-conf.json", - "release.pkg-pr-new": "pnpm dlx pkg-pr-new@^0.0.9 publish --compact --pnpm ./packages/qwik ./packages/qwik-city ./packages/eslint-plugin-qwik ./packages/create-qwik", + "release.pkg-pr-new": "pnpm dlx pkg-pr-new@^0.0.9 publish --pnpm ./packages/qwik ./packages/qwik-router ./packages/eslint-plugin-qwik ./packages/create-qwik", "release.prepare": "pnpm build --prepare-release", "serve": "tsx --require ./scripts/runBefore.ts --inspect --conditions=development starters/dev-server.ts 3300", "serve.debug": "tsx --require ./scripts/runBefore.ts --inspect-brk --conditions=development starters/dev-server.ts 3300", @@ -246,17 +225,19 @@ "test.e2e": "pnpm test.e2e.chromium && pnpm test.e2e.webkit && test.e2e.integrations", "test.e2e.chromium": "playwright test starters --browser=chromium --config starters/playwright.config.ts", "test.e2e.chromium.debug": "PWDEBUG=1 playwright test starters --browser=chromium --config starters/playwright.config.ts", - "test.e2e.city": "playwright test starters/e2e/qwikcity --browser=chromium --config starters/playwright.config.ts", "test.e2e.cli": "pnpm --filter qwik-cli-e2e e2e", "test.e2e.firefox": "playwright test starters --browser=firefox --config starters/playwright.config.ts", "test.e2e.integrations.chromium": "playwright test e2e/adapters-e2e/tests --project=chromium --config e2e/adapters-e2e/playwright.config.ts", "test.e2e.integrations.webkit": "playwright test e2e/adapters-e2e/tests --project=webkit --config e2e/adapters-e2e/playwright.config.ts", + "test.e2e.router": "playwright test starters/e2e/qwikrouter --browser=chromium --config starters/playwright.config.ts", + "test.e2e.run": "tsm scripts/e2e-cli.ts", "test.e2e.webkit": "playwright test starters --browser=webkit --config starters/playwright.config.ts", "test.rust": "make test", + "test.rust.bench": "make benchmark", "test.rust.update": "make test-update", "test.unit": "vitest packages", "test.unit.debug": "vitest --inspect-brk packages", - "test.vite": "playwright test starters/e2e/qwikcity --browser=chromium --config starters/playwright.config.ts", + "test.vite": "playwright test starters/e2e/qwikrouter --browser=chromium --config starters/playwright.config.ts", "tsc.check": "tsc --noEmit", "tsc.trace": "tsc -p tsconfig.json --traceResolution > tsc.log", "tsc.watch": "tsc --noEmit --watch --preserveWatchOutput", diff --git a/packages/create-qwik/CHANGELOG.md b/packages/create-qwik/CHANGELOG.md index ef02e02883f..c3385f45ad9 100644 --- a/packages/create-qwik/CHANGELOG.md +++ b/packages/create-qwik/CHANGELOG.md @@ -1,5 +1,25 @@ # create-qwik +## 2.0.0-alpha.9 + +## 2.0.0-alpha.8 + +## 2.0.0-alpha.7 + +## 2.0.0-alpha.6 + +## 2.0.0-alpha.5 + +## 2.0.0-alpha.4 + +## 2.0.0-alpha.3 + +## 2.0.0-alpha.2 + +## 2.0.0-alpha.1 + +## 2.0.0-alpha.0 + ## 1.13.0 ## 1.12.1 @@ -42,4 +62,4 @@ - - built files are now under dist/ or lib/. All tools that respect package export maps should just work. (by [@wmertens](https://github.com/wmertens) in [#6715](https://github.com/QwikDev/qwik/pull/6715)) If you have trouble with Typescript, ensure that you use `moduleResolution: "Bundler"` in your `tsconfig.json`. - - `@builder.io/qwik` no longer depends on `undici` + - `@qwik.dev/core` no longer depends on `undici` diff --git a/packages/create-qwik/package.json b/packages/create-qwik/package.json index 49498d2e679..5c0ac318c93 100644 --- a/packages/create-qwik/package.json +++ b/packages/create-qwik/package.json @@ -1,8 +1,8 @@ { "name": "create-qwik", "description": "Interactive CLI for create Qwik projects and adding features.", - "version": "1.13.0", - "author": "Builder.io Team", + "version": "2.0.0-alpha.9", + "author": "Qwik Team", "bin": "./create-qwik.cjs", "bugs": "https://github.com/QwikDev/qwik/issues", "devDependencies": { @@ -25,7 +25,6 @@ ], "homepage": "https://qwik.dev/", "keywords": [ - "builder.io", "generator", "qwik", "starters", diff --git a/packages/docs/adapters/cloudflare-pages/vite.config.mts b/packages/docs/adapters/cloudflare-pages/vite.config.mts deleted file mode 100644 index 7629ebc667c..00000000000 --- a/packages/docs/adapters/cloudflare-pages/vite.config.mts +++ /dev/null @@ -1,27 +0,0 @@ -import { cloudflarePagesAdapter } from '@builder.io/qwik-city/adapters/cloudflare-pages/vite'; -import { extendConfig } from '@builder.io/qwik-city/vite'; -// @ts-ignore -import baseConfig from '../../vite.config.mts'; - -export default extendConfig(baseConfig, () => { - return { - build: { - ssr: true, - rollupOptions: { - input: ['src/entry.cloudflare-pages.tsx', '@qwik-city-plan'], - }, - minify: false, - }, - plugins: [ - cloudflarePagesAdapter({ - ssg: { - include: ['/', '/*'], - exclude: ['/demo/*', '/shop/*'], - origin: - (process.env.CF_PAGES_BRANCH !== 'main' ? process.env.CF_PAGES_URL : null) ?? - 'https://qwik.builder.io', - }, - }), - ], - }; -}); diff --git a/packages/docs/adapters/cloudflare-pages/vite.config.ts b/packages/docs/adapters/cloudflare-pages/vite.config.ts new file mode 100644 index 00000000000..137e1c24cf3 --- /dev/null +++ b/packages/docs/adapters/cloudflare-pages/vite.config.ts @@ -0,0 +1,26 @@ +import { cloudflarePagesAdapter } from '@qwik.dev/router/adapters/cloudflare-pages/vite'; +import { extendConfig } from '@qwik.dev/router/vite'; +import baseConfig from '../../vite.config'; + +export default extendConfig(baseConfig, () => { + return { + build: { + ssr: true, + rollupOptions: { + input: ['src/entry.cloudflare-pages.tsx', '@qwik-router-config'], + }, + minify: false, + }, + plugins: [ + cloudflarePagesAdapter({ + ssg: { + include: ['/', '/*'], + exclude: ['/demo/*', '/shop/*'], + origin: + (process.env.CF_PAGES_BRANCH !== 'main' ? process.env.CF_PAGES_URL : null) ?? + 'https://qwik.builder.io', + }, + }), + ], + }; +}); diff --git a/packages/docs/check-qwik-build.ts b/packages/docs/check-qwik-build.ts index 69ec5771c56..42c4ffa153d 100644 --- a/packages/docs/check-qwik-build.ts +++ b/packages/docs/check-qwik-build.ts @@ -5,8 +5,9 @@ import fs from 'node:fs'; import path from 'node:path'; import { spawnSync } from 'node:child_process'; +import { fileURLToPath } from 'url'; -let __dirname = path.dirname(new URL(import.meta.url).pathname); +let __dirname = path.dirname(fileURLToPath(import.meta.url)); const isWindows = process.platform === 'win32'; if (isWindows && __dirname.startsWith('/')) { // in Windows __dirname starts with a / causing errors @@ -18,7 +19,7 @@ if (isWindows && __dirname.startsWith('/')) { } const qwikPkgDir = path.join(__dirname, '..', 'qwik', 'dist'); -if (!fs.existsSync(path.join(qwikPkgDir, 'core.d.ts'))) { +if (!fs.existsSync(path.join(qwikPkgDir, 'core-internal.d.ts'))) { console.warn( `\n\n=== Running 'pnpm run build.local' to generate missing imports for the docs ===\n` ); diff --git a/packages/docs/contributors.ts b/packages/docs/contributors.ts index 6b91e2726ae..4932f381804 100644 --- a/packages/docs/contributors.ts +++ b/packages/docs/contributors.ts @@ -1,4 +1,3 @@ -import { fetch } from 'undici'; import fs from 'node:fs'; import path from 'node:path'; import url from 'node:url'; diff --git a/packages/docs/package.json b/packages/docs/package.json index 55f65161148..48ffc5df4a3 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -2,24 +2,22 @@ "name": "qwik-docs", "description": "Qwik Docs Site", "version": "0.0.1", - "author": "Builder.io Team", + "author": "Qwik Team", "bugs": "https://github.com/QwikDev/qwik", "devDependencies": { "@algolia/autocomplete-core": "1.7.4", "@algolia/client-search": "4.14.3", "@builder.io/partytown": "0.10.2", - "@builder.io/qwik": "workspace:^", - "@builder.io/qwik-city": "workspace:^", - "@builder.io/qwik-labs": "workspace:^", - "@builder.io/qwik-react": "workspace:^", - "@builder.io/sdk-qwik": "0.14.31", "@emotion/react": "11.13.0", "@emotion/styled": "11.13.0", "@modular-forms/qwik": "0.23.1", "@mui/material": "5.16.4", "@mui/system": "5.16.4", "@mui/x-data-grid": "6.20.4", - "@qwik-ui/headless": "0.5.0", + "@qwik-ui/headless": "0.6.3", + "@qwik.dev/core": "workspace:*", + "@qwik.dev/react": "workspace:*", + "@qwik.dev/router": "workspace:*", "@shikijs/colorized-brackets": "3.1.0", "@shikijs/rehype": "3.1.0", "@shikijs/transformers": "3.1.0", @@ -38,28 +36,28 @@ "leaflet": "1.9.4", "magic-string": "0.30.11", "openai": "3.3.0", - "prettier": "3.3.3", + "prettier": "3.4.2", "prism-themes": "1.9.0", "prismjs": "1.29.0", "puppeteer": "22.13.1", - "qwik-image": "0.0.10", + "qwik-image": "0.0.16", "react": "18.3.1", "react-dom": "18.3.1", "shiki": "3.1.0", "snarkdown": "2.0.0", "tailwindcss": "4.0.12", - "terser": "5.31.3", + "terser": "5.37.0", "tsm": "2.3.0", - "typescript": "5.4.5", + "typescript": "5.8.2", "undici": "*", "valibot": "0.33.3", - "vite": "5.3.5", + "vite": "6.2.6", "vite-plugin-inspect": "0.8.5", - "vite-tsconfig-paths": "4.3.2", + "vite-tsconfig-paths": "5.1.4", "wrangler": "3.65.1" }, "engines": { - "node": ">=18.11", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", "npm": "please-use-pnpm", "yarn": "please-use-pnpm", "pnpm": ">=8.6.12" @@ -68,11 +66,11 @@ "license": "MIT", "private": true, "scripts": { - "build": "qwik build", + "build": "pnpm build.repl-sw && qwik build", "build.client": "vite build", "build.preview": "NODE_OPTIONS=--max-old-space-size=8192 vite build --ssr src/entry.preview.tsx", - "build.repl-sw": "vite --config vite.config-repl-sw.mts build", - "build.server": "NODE_OPTIONS=--max-old-space-size=8192 vite build -c adapters/cloudflare-pages/vite.config.mts", + "build.repl-sw": "vite --config vite.config-repl-sw build", + "build.server": "NODE_OPTIONS=--max-old-space-size=8192 vite build -c adapters/cloudflare-pages/vite.config", "build.showcase": "pnpm node scripts/showcase.js", "codesandbox.sync": "tsx codesandbox.sync.ts", "contributors": "tsx contributors.ts", @@ -84,5 +82,6 @@ "preview.only": "NODE_DEBUG=net,http node --inspect-brk ../../node_modules/vite/bin/vite.js preview", "preview.wrangler": "wrangler pages dev ./dist --compatibility-flags=nodejs_als", "start": "pnpm dev" - } + }, + "type": "module" } diff --git a/packages/docs/public/_redirects b/packages/docs/public/_redirects index ddc89bbb39f..8c9ff564bc0 100644 --- a/packages/docs/public/_redirects +++ b/packages/docs/public/_redirects @@ -31,6 +31,7 @@ /qwikcity/routing/route-parameters/ /docs/routing/ 308 /qwikcity/routing/error-responses/ /docs/advanced/routing/ 308 /qwikcity/loader/ /docs/route-loader/ 308 +/qwikcity/adaptors/ /docs/deployments/ 308 /qwikcity/layout/overview/ /docs/layout/ 308 /qwikcity/layout/nested/ /docs/advanced/routing/ 308 /qwikcity/layout/grouped/ /docs/advanced/routing/ 308 @@ -62,10 +63,14 @@ /docs/components/resource/ /docs/components/state/ 308 /docs/cookbook/re-exporting-loaders/ /docs/re-exporting-loaders/ 308 +/qwikcity/adaptors/* /docs/deployments/:splat 308 /qwikcity/* /docs/:splat 308 +/qwikrouter/* /docs/:splat 308 /integrations/* /docs/integrations/:splat 308 /deployments/* /docs/deployments/:splat 308 /docs/advanced/i18n/ /docs/integrations/i18n/ 308 /docs/components/inline-components/ /docs/components/overview/ 308 /docs/think-qwik/ /docs/concepts/think-qwik/ 308 +/docs/qwikcity/ /docs/qwikrouter/ 308 +/docs/qwikcity-deprecated-features/ /docs/qwikrouter-deprecated-features/ 308 /docs/env-variables/ /docs/guides/env-variables/ 308 diff --git a/packages/docs/public/icons/qwikCity_and_routing.svg b/packages/docs/public/icons/qwikRouter_and_routing.svg similarity index 100% rename from packages/docs/public/icons/qwikCity_and_routing.svg rename to packages/docs/public/icons/qwikRouter_and_routing.svg diff --git a/packages/docs/scripts/showcase.js b/packages/docs/scripts/showcase.js index cb6f24ec73f..d5c5528f4a5 100644 --- a/packages/docs/scripts/showcase.js +++ b/packages/docs/scripts/showcase.js @@ -145,7 +145,6 @@ async function captureMultipleScreenshots() { } async function getPagespeedData(url) { - const { fetch } = await import('undici'); const requestURL = `https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=${encodeURIComponent( url )}&key=AIzaSyApBC9gblaCzWrtEBgHnZkd_B37OF49BfM&category=PERFORMANCE&strategy=MOBILE`; diff --git a/packages/docs/src/components/builder-content/index.tsx b/packages/docs/src/components/builder-content/index.tsx index c915bf32a2d..94eb29bff06 100644 --- a/packages/docs/src/components/builder-content/index.tsx +++ b/packages/docs/src/components/builder-content/index.tsx @@ -1,6 +1,5 @@ -import { component$, Resource, useResource$ } from '@builder.io/qwik'; -import { useLocation } from '@builder.io/qwik-city'; -import { getBuilderSearchParams, fetchOneEntry, Content } from '@builder.io/sdk-qwik'; +import { component$, Resource, useResource$ } from '@qwik.dev/core'; +import { useLocation } from '@qwik.dev/router'; import { QWIK_MODEL } from '../../constants'; export default component$<{ @@ -17,52 +16,24 @@ export default component$<{ ? query.get(name) : (query as unknown as Record)[name]; - const render = queryGet('render'); const contentId = props.model === QWIK_MODEL ? queryGet('content') : undefined; - const isSDK = render === 'sdk'; cache('immutable'); - if (isSDK) { - return getCachedValue( - { - model: props.model!, - apiKey: props.apiKey!, - options: getBuilderSearchParams(query), - userAttributes: { - urlPath: location.url.pathname, - site: 'qwik.dev', - }, - ...(contentId && { - query: { - id: contentId, - }, - }), - }, - fetchOneEntry - ); - } else { - return getCachedValue( - { - apiKey: props.apiKey, - model: props.model, - urlPath: location.url.pathname, - contentId: contentId, - }, - getBuilderContent - ); - } + return getCachedValue( + { + apiKey: props.apiKey, + model: props.model, + urlPath: location.url.pathname, + contentId: contentId, + }, + getBuilderContent + ); }); return (
Loading...
} - onResolved={(content) => - content.html ? ( - - ) : ( - - ) - } + onResolved={(content) => } /> ); }); diff --git a/packages/docs/src/components/code-block/code-block.tsx b/packages/docs/src/components/code-block/code-block.tsx index 8743318e556..ff6fbaf7600 100644 --- a/packages/docs/src/components/code-block/code-block.tsx +++ b/packages/docs/src/components/code-block/code-block.tsx @@ -1,4 +1,4 @@ -import { component$, useStyles$, type QRL, useVisibleTask$, useSignal } from '@builder.io/qwik'; +import { component$, useStyles$, type QRL, useVisibleTask$, useSignal } from '@qwik.dev/core'; import prismjs from 'prismjs'; // Set to global so that prism language plugins can find it. const _global = @@ -15,7 +15,7 @@ import styles from './code-block.css?inline'; import { CopyCode } from '../copy-code/copy-code-block'; interface CodeBlockProps { path?: string; - language?: 'markup' | 'css' | 'javascript' | 'json' | 'jsx' | 'tsx'; + language?: 'markup' | 'css' | 'javascript' | 'json' | 'jsx' | 'tsx' | 'clike'; code: string; pathInView$?: QRL<(name: string) => void>; observerRootId?: string; diff --git a/packages/docs/src/components/code-sandbox/index.tsx b/packages/docs/src/components/code-sandbox/index.tsx index 23f4f82ccb6..1f13741b1a5 100644 --- a/packages/docs/src/components/code-sandbox/index.tsx +++ b/packages/docs/src/components/code-sandbox/index.tsx @@ -1,7 +1,7 @@ -import { component$, useContext, useStylesScoped$, Slot, useSignal } from '@builder.io/qwik'; -import CSS from './index.css?inline'; +import { component$, Slot, useContext, useSignal, useStylesScoped$ } from '@qwik.dev/core'; import { GlobalStore } from '../../context'; import { EditIcon } from '../svgs/edit-icon'; +import CSS from './index.css?inline'; export default component$<{ src?: string; @@ -96,7 +96,7 @@ function examplePath( } = typeof opts === 'string' ? ({ path: opts } as any) : opts; const newPath = path .replace('/(qwik)/', '/') - .replace('/(qwikcity)/', '/') + .replace('/(qwikrouter)/', '/') .replace('/src/routes/demo', '/demo') .replace(/\/[\w\d]+\.tsx?$/, '/'); diff --git a/packages/docs/src/components/content-nav/content-nav.tsx b/packages/docs/src/components/content-nav/content-nav.tsx index a8ba45639ee..87f1c6ac5bd 100644 --- a/packages/docs/src/components/content-nav/content-nav.tsx +++ b/packages/docs/src/components/content-nav/content-nav.tsx @@ -1,5 +1,5 @@ -import { type ContentMenu, useContent, useLocation } from '@builder.io/qwik-city'; -import { component$, useStyles$ } from '@builder.io/qwik'; +import { component$, useStyles$ } from '@qwik.dev/core'; +import { type ContentMenu, useContent, useLocation } from '@qwik.dev/router'; import styles from './content-nav.css?inline'; export const ContentNav = component$(() => { diff --git a/packages/docs/src/components/contributors/index.tsx b/packages/docs/src/components/contributors/index.tsx index b204a76ac93..1c8d3fc7ad2 100644 --- a/packages/docs/src/components/contributors/index.tsx +++ b/packages/docs/src/components/contributors/index.tsx @@ -1,6 +1,6 @@ -import { component$, useStylesScoped$ } from '@builder.io/qwik'; +import { component$, useStylesScoped$ } from '@qwik.dev/core'; +import { useDocumentHead } from '@qwik.dev/router'; import styles from './contributors.css?inline'; -import { useDocumentHead } from '@builder.io/qwik-city'; export default component$(() => { useStylesScoped$(styles); diff --git a/packages/docs/src/components/copy-code/copy-code-block.tsx b/packages/docs/src/components/copy-code/copy-code-block.tsx index 905f3f27f94..c3f9231c157 100644 --- a/packages/docs/src/components/copy-code/copy-code-block.tsx +++ b/packages/docs/src/components/copy-code/copy-code-block.tsx @@ -1,4 +1,4 @@ -import { component$, useSignal, useStyles$ } from '@builder.io/qwik'; +import { component$, useSignal, useStyles$ } from '@qwik.dev/core'; import { CopyCode as CopyCodeIcon } from '../svgs/copy-code-icon'; import styles from './copy-code.css?inline'; diff --git a/packages/docs/src/components/docsearch/algolia-logo.tsx b/packages/docs/src/components/docsearch/algolia-logo.tsx index 01ad2eec853..3fb4f9012c4 100644 --- a/packages/docs/src/components/docsearch/algolia-logo.tsx +++ b/packages/docs/src/components/docsearch/algolia-logo.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; type AlgoliaLogoTranslations = Partial<{ searchByText: string; diff --git a/packages/docs/src/components/docsearch/context.ts b/packages/docs/src/components/docsearch/context.ts index 06d9e061cbd..9aebd4792ba 100644 --- a/packages/docs/src/components/docsearch/context.ts +++ b/packages/docs/src/components/docsearch/context.ts @@ -1,3 +1,3 @@ -import { createContextId } from '@builder.io/qwik'; +import { createContextId } from '@qwik.dev/core'; export const SearchContext = createContextId('docsearch'); diff --git a/packages/docs/src/components/docsearch/doc-search-button.tsx b/packages/docs/src/components/docsearch/doc-search-button.tsx index 0126a623f98..56be8267506 100644 --- a/packages/docs/src/components/docsearch/doc-search-button.tsx +++ b/packages/docs/src/components/docsearch/doc-search-button.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; import { SearchIcon } from './icons/SearchIcon'; export function isAppleDevice() { diff --git a/packages/docs/src/components/docsearch/doc-search-modal.tsx b/packages/docs/src/components/docsearch/doc-search-modal.tsx index 76d36501919..e0889bb7af8 100644 --- a/packages/docs/src/components/docsearch/doc-search-modal.tsx +++ b/packages/docs/src/components/docsearch/doc-search-modal.tsx @@ -5,7 +5,7 @@ import { useContextProvider, useTask$, type Signal, -} from '@builder.io/qwik'; +} from '@qwik.dev/core'; import { MAX_QUERY_SIZE } from './constants'; import { SearchContext } from './context'; import type { DocSearchProps, DocSearchState } from './doc-search'; @@ -19,7 +19,7 @@ import type { DocSearchHit } from './types'; import { identity } from './utils'; import { clearStalled, setStalled } from './utils/stalledControl'; import { AIButton } from './result'; -import { isBrowser } from '@builder.io/qwik'; +import { isBrowser } from '@qwik.dev/core'; export type ModalTranslations = Partial<{ searchBox: SearchBoxTranslations; diff --git a/packages/docs/src/components/docsearch/doc-search.tsx b/packages/docs/src/components/docsearch/doc-search.tsx index f76e9a6f536..b269502fee2 100644 --- a/packages/docs/src/components/docsearch/doc-search.tsx +++ b/packages/docs/src/components/docsearch/doc-search.tsx @@ -9,7 +9,7 @@ import { type Signal, $, sync$, -} from '@builder.io/qwik'; +} from '@qwik.dev/core'; import { Modal } from '@qwik-ui/headless'; import type { DocSearchHit, InternalDocSearchHit } from './types'; import { type ButtonTranslations } from './doc-search-button'; diff --git a/packages/docs/src/components/docsearch/error-screen.tsx b/packages/docs/src/components/docsearch/error-screen.tsx index 2cfe0d9213d..a1d58f9e1b6 100644 --- a/packages/docs/src/components/docsearch/error-screen.tsx +++ b/packages/docs/src/components/docsearch/error-screen.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; import { ErrorIcon } from './icons/ErrorIcon'; export type ErrorScreenTranslations = Partial<{ diff --git a/packages/docs/src/components/docsearch/hit.tsx b/packages/docs/src/components/docsearch/hit.tsx index e66325f0e53..1aa97dd3507 100644 --- a/packages/docs/src/components/docsearch/hit.tsx +++ b/packages/docs/src/components/docsearch/hit.tsx @@ -1,4 +1,4 @@ -import { component$, Slot } from '@builder.io/qwik'; +import { component$, Slot } from '@qwik.dev/core'; import type { InternalDocSearchHit, StoredDocSearchHit } from './types'; interface HitProps { diff --git a/packages/docs/src/components/docsearch/icons/ControlKeyIcon.tsx b/packages/docs/src/components/docsearch/icons/ControlKeyIcon.tsx index 1ebde32bd05..71f8b207f34 100644 --- a/packages/docs/src/components/docsearch/icons/ControlKeyIcon.tsx +++ b/packages/docs/src/components/docsearch/icons/ControlKeyIcon.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const ControlKeyIcon = component$(() => { return ( diff --git a/packages/docs/src/components/docsearch/icons/ErrorIcon.tsx b/packages/docs/src/components/docsearch/icons/ErrorIcon.tsx index 5b2d48a5eda..c91e2808e04 100644 --- a/packages/docs/src/components/docsearch/icons/ErrorIcon.tsx +++ b/packages/docs/src/components/docsearch/icons/ErrorIcon.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const ErrorIcon = component$(() => { return ( diff --git a/packages/docs/src/components/docsearch/icons/NoResultsIcon.tsx b/packages/docs/src/components/docsearch/icons/NoResultsIcon.tsx index 8bfa33f346e..343efc4032e 100644 --- a/packages/docs/src/components/docsearch/icons/NoResultsIcon.tsx +++ b/packages/docs/src/components/docsearch/icons/NoResultsIcon.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const NoResultsIcon = component$(() => { return ( diff --git a/packages/docs/src/components/docsearch/icons/RecentIcon.tsx b/packages/docs/src/components/docsearch/icons/RecentIcon.tsx index d4333fa1b15..caabeb698ec 100644 --- a/packages/docs/src/components/docsearch/icons/RecentIcon.tsx +++ b/packages/docs/src/components/docsearch/icons/RecentIcon.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const RecentIcon = component$(() => { return ( diff --git a/packages/docs/src/components/docsearch/icons/SelectIcon.tsx b/packages/docs/src/components/docsearch/icons/SelectIcon.tsx index c8eb4022ab9..68f188a6f1d 100644 --- a/packages/docs/src/components/docsearch/icons/SelectIcon.tsx +++ b/packages/docs/src/components/docsearch/icons/SelectIcon.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const SelectIcon = component$(() => { return ( diff --git a/packages/docs/src/components/docsearch/icons/SourceIcon.tsx b/packages/docs/src/components/docsearch/icons/SourceIcon.tsx index ba742b00734..96b56766b0e 100644 --- a/packages/docs/src/components/docsearch/icons/SourceIcon.tsx +++ b/packages/docs/src/components/docsearch/icons/SourceIcon.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const LvlIcon = () => { return ( diff --git a/packages/docs/src/components/docsearch/icons/StarIcon.tsx b/packages/docs/src/components/docsearch/icons/StarIcon.tsx index 76d13168d0c..11bceacef8c 100644 --- a/packages/docs/src/components/docsearch/icons/StarIcon.tsx +++ b/packages/docs/src/components/docsearch/icons/StarIcon.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const StarIcon = component$(() => { return ( diff --git a/packages/docs/src/components/docsearch/no-results-screen.tsx b/packages/docs/src/components/docsearch/no-results-screen.tsx index e1bb75de025..124bc9f1e59 100644 --- a/packages/docs/src/components/docsearch/no-results-screen.tsx +++ b/packages/docs/src/components/docsearch/no-results-screen.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; import type { DocSearchState } from './doc-search'; import { NoResultsIcon } from './icons/NoResultsIcon'; diff --git a/packages/docs/src/components/docsearch/result.tsx b/packages/docs/src/components/docsearch/result.tsx index 82d253cdfce..798e630d45f 100644 --- a/packages/docs/src/components/docsearch/result.tsx +++ b/packages/docs/src/components/docsearch/result.tsx @@ -1,10 +1,10 @@ -import { Slot, component$, useContext, useSignal, useStore, useTask$ } from '@builder.io/qwik'; +import { Slot, component$, useContext, useSignal, useStore, useTask$ } from '@qwik.dev/core'; // import { QwikGPT } from '../qwik-gpt'; +import { Link } from '@qwik.dev/router'; import { SearchContext } from './context'; import { AiResultOpenContext, type DocSearchState } from './doc-search'; import { Snippet } from './snippet'; import type { InternalDocSearchHit } from './types'; -import { Link } from '@builder.io/qwik-city'; export const Result = component$( ({ state, item }: { state: DocSearchState; item: InternalDocSearchHit }) => { diff --git a/packages/docs/src/components/docsearch/results-screen.tsx b/packages/docs/src/components/docsearch/results-screen.tsx index a2ea120f1ee..ac08075cd8d 100644 --- a/packages/docs/src/components/docsearch/results-screen.tsx +++ b/packages/docs/src/components/docsearch/results-screen.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; import { Result } from './result'; import { removeHighlightTags } from './utils'; import { SelectIcon } from './icons/SelectIcon'; diff --git a/packages/docs/src/components/docsearch/screen-state.tsx b/packages/docs/src/components/docsearch/screen-state.tsx index 4f1c7846c61..d876cac4fea 100644 --- a/packages/docs/src/components/docsearch/screen-state.tsx +++ b/packages/docs/src/components/docsearch/screen-state.tsx @@ -1,4 +1,4 @@ -import { component$, type Signal } from '@builder.io/qwik'; +import { component$, type Signal } from '@qwik.dev/core'; import type { DocSearchState } from './doc-search'; import type { ErrorScreenTranslations } from './error-screen'; import { ErrorScreen } from './error-screen'; diff --git a/packages/docs/src/components/docsearch/search-box.tsx b/packages/docs/src/components/docsearch/search-box.tsx index 89951874a3b..26ebbf63362 100644 --- a/packages/docs/src/components/docsearch/search-box.tsx +++ b/packages/docs/src/components/docsearch/search-box.tsx @@ -1,4 +1,4 @@ -import { component$, useVisibleTask$, useContext, type Signal } from '@builder.io/qwik'; +import { component$, useVisibleTask$, useContext, type Signal } from '@qwik.dev/core'; import { MAX_QUERY_SIZE } from './constants'; import { SearchContext } from './context'; diff --git a/packages/docs/src/components/docsearch/snippet.tsx b/packages/docs/src/components/docsearch/snippet.tsx index 894248a8491..b8e53828ee9 100644 --- a/packages/docs/src/components/docsearch/snippet.tsx +++ b/packages/docs/src/components/docsearch/snippet.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export function getPropertyByPath(object: Record, path: string): any { const parts = path.split('.'); diff --git a/packages/docs/src/components/docsearch/start-screen.tsx b/packages/docs/src/components/docsearch/start-screen.tsx index cef8e0d677a..f6ca1b0611c 100644 --- a/packages/docs/src/components/docsearch/start-screen.tsx +++ b/packages/docs/src/components/docsearch/start-screen.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const StartScreen = component$(() => { return null; diff --git a/packages/docs/src/components/docsearch/stored-searches.ts b/packages/docs/src/components/docsearch/stored-searches.ts index 57026b5937a..e7d2693e87b 100644 --- a/packages/docs/src/components/docsearch/stored-searches.ts +++ b/packages/docs/src/components/docsearch/stored-searches.ts @@ -1,4 +1,4 @@ -import { noSerialize } from '@builder.io/qwik'; +import { noSerialize } from '@qwik.dev/core'; import type { DocSearchHit, StoredDocSearchHit } from './types'; function isLocalStorageSupported() { diff --git a/packages/docs/src/components/docsearch/useTouchEvents.ts b/packages/docs/src/components/docsearch/useTouchEvents.ts index 8f82e8dce6b..2832dee6fe8 100644 --- a/packages/docs/src/components/docsearch/useTouchEvents.ts +++ b/packages/docs/src/components/docsearch/useTouchEvents.ts @@ -1,5 +1,5 @@ import type { AutocompleteApi } from '@algolia/autocomplete-core'; -import { useTask$ } from '@builder.io/qwik'; +import { useTask$ } from '@qwik.dev/core'; interface UseTouchEventsProps { getEnvironmentProps: AutocompleteApi['getEnvironmentProps']; diff --git a/packages/docs/src/components/docsearch/useTrapFocus.ts b/packages/docs/src/components/docsearch/useTrapFocus.ts index 6324e8f1e35..b62d835f3bd 100644 --- a/packages/docs/src/components/docsearch/useTrapFocus.ts +++ b/packages/docs/src/components/docsearch/useTrapFocus.ts @@ -1,4 +1,4 @@ -import { useTask$, type Signal } from '@builder.io/qwik'; +import { useTask$, type Signal } from '@qwik.dev/core'; interface UseTrapFocusProps { containerRef: Signal; diff --git a/packages/docs/src/components/footer/footer.tsx b/packages/docs/src/components/footer/footer.tsx index cc57d010cb1..8dbe9fadd83 100644 --- a/packages/docs/src/components/footer/footer.tsx +++ b/packages/docs/src/components/footer/footer.tsx @@ -1,7 +1,7 @@ -import { component$ } from '@builder.io/qwik'; -import { QwikLogo } from '~/components/svgs/qwik-logo'; +import { component$ } from '@qwik.dev/core'; import { DiscordLogo } from '~/components/svgs/discord-logo'; import { GithubLogo } from '~/components/svgs/github-logo'; +import { QwikLogo } from '~/components/svgs/qwik-logo'; import { TwitterLogo } from '~/components/svgs/twitter-logo'; import { BlueskyLogo } from '~/components/svgs/bluesky-logo'; @@ -9,7 +9,7 @@ const baseUrl = 'https://qwik.dev'; const linkColumns = [ [ { title: 'Docs', href: `${baseUrl}/docs/` }, - { title: 'Qwik City', href: `${baseUrl}/docs/qwikcity/` }, + { title: 'Qwik Router', href: `${baseUrl}/docs/qwikrouter/` }, { title: 'Ecosystem', href: `${baseUrl}/ecosystem/` }, { title: 'Playground', href: `${baseUrl}/playground/` }, ], diff --git a/packages/docs/src/components/header/header.tsx b/packages/docs/src/components/header/header.tsx index 76afad99b0d..80339a95747 100644 --- a/packages/docs/src/components/header/header.tsx +++ b/packages/docs/src/components/header/header.tsx @@ -1,28 +1,28 @@ -import { useLocation } from '@builder.io/qwik-city'; import { component$, - useStyles$, useContext, + useSignal, + useStyles$, useVisibleTask$, type PropsOf, - useSignal, -} from '@builder.io/qwik'; +} from '@qwik.dev/core'; +import { useLocation } from '@qwik.dev/router'; +import { GlobalStore } from '../../context'; import { DocSearch } from '../docsearch/doc-search'; +import { SearchIcon } from '../docsearch/icons/SearchIcon'; import { CloseIcon } from '../svgs/close-icon'; import { DiscordLogo } from '../svgs/discord-logo'; import { GithubLogo } from '../svgs/github-logo'; import { MoreIcon } from '../svgs/more-icon'; import { QwikLogo } from '../svgs/qwik-logo'; import { TwitterLogo } from '../svgs/twitter-logo'; -import styles from './header.css?inline'; -import { GlobalStore } from '../../context'; import { colorSchemeChangeListener, getColorPreference, setPreference, ThemeToggle, } from '../theme-toggle/theme-toggle'; -import { SearchIcon } from '../docsearch/icons/SearchIcon'; +import styles from './header.css?inline'; export const SearchButton = component$>(({ ...props }) => { return ( diff --git a/packages/docs/src/components/on-this-page/on-this-page.tsx b/packages/docs/src/components/on-this-page/on-this-page.tsx index 35d7923cc44..305cef47f27 100644 --- a/packages/docs/src/components/on-this-page/on-this-page.tsx +++ b/packages/docs/src/components/on-this-page/on-this-page.tsx @@ -1,5 +1,5 @@ -import { $, component$, useContext, useOnDocument, useSignal, useStyles$ } from '@builder.io/qwik'; -import { useContent, useLocation } from '@builder.io/qwik-city'; +import { $, component$, useContext, useOnDocument, useSignal, useStyles$ } from '@qwik.dev/core'; +import { useContent, useLocation } from '@qwik.dev/router'; import { GlobalStore } from '../../context'; import { AlertIcon } from '../svgs/alert-icon'; import { ChatIcon } from '../svgs/chat-icon'; @@ -30,7 +30,7 @@ const QWIK_ADVANCED_GROUP = [ 'vite', ]; -const QWIKCITY_GROUP = [ +const QWIKROUTER_GROUP = [ 'action', 'api', 'caching', @@ -41,7 +41,7 @@ const QWIKCITY_GROUP = [ 'middleware', 'pages', 'project-structure', - 'qwikcity', + 'qwikrouter', 're-exporting-loaders', 'route-loader', 'routing', @@ -49,7 +49,7 @@ const QWIKCITY_GROUP = [ 'validator', ]; -const QWIKCITY_ADVANCED_GROUP = [ +const QWIKROUTER_ADVANCED_GROUP = [ 'complex-forms', 'content-security-policy', 'menu', @@ -76,13 +76,13 @@ const makeEditPageUrl = (url: string): string => { if (segments[1] == 'advanced') { if (QWIK_ADVANCED_GROUP.includes(segments[2])) { group = '(qwik)'; - } else if (QWIKCITY_ADVANCED_GROUP.includes(segments[2])) { - group = '(qwikcity)'; + } else if (QWIKROUTER_ADVANCED_GROUP.includes(segments[2])) { + group = '(qwikrouter)'; } } else if (QWIK_GROUP.includes(segments[1])) { group = '(qwik)'; - } else if (QWIKCITY_GROUP.includes(segments[1])) { - group = '(qwikcity)'; + } else if (QWIKROUTER_GROUP.includes(segments[1])) { + group = '(qwikrouter)'; } if (group) { diff --git a/packages/docs/src/components/package-manager-tabs/index.tsx b/packages/docs/src/components/package-manager-tabs/index.tsx index 50f0f6caca2..25c1d7830ce 100644 --- a/packages/docs/src/components/package-manager-tabs/index.tsx +++ b/packages/docs/src/components/package-manager-tabs/index.tsx @@ -1,5 +1,5 @@ -import { Slot, component$, useContext, useSignal, $, type PropsOf } from '@builder.io/qwik'; import { Tabs } from '@qwik-ui/headless'; +import { $, Slot, component$, useContext, useSignal, type PropsOf } from '@qwik.dev/core'; import { GlobalStore } from '~/context'; const pkgManagers = ['pnpm', 'npm', 'yarn', 'bun'] as const; diff --git a/packages/docs/src/components/panel-toggle/panel-toggle.tsx b/packages/docs/src/components/panel-toggle/panel-toggle.tsx index 1e1b4f04336..85b3157de86 100644 --- a/packages/docs/src/components/panel-toggle/panel-toggle.tsx +++ b/packages/docs/src/components/panel-toggle/panel-toggle.tsx @@ -1,4 +1,4 @@ -import { component$, useStyles$ } from '@builder.io/qwik'; +import { component$, useStyles$ } from '@qwik.dev/core'; import styles from './panel-toggle.css?inline'; export interface PanelToggleProps { diff --git a/packages/docs/src/components/qwik-gpt/gpt.md b/packages/docs/src/components/qwik-gpt/gpt.md index 8c507016c64..c061c8cd268 100644 --- a/packages/docs/src/components/qwik-gpt/gpt.md +++ b/packages/docs/src/components/qwik-gpt/gpt.md @@ -10,7 +10,7 @@ - Content projection is done by the `` component. Slots can be named, and can be projected into using the `q:slot` attribute. ```tsx -import { component$, $, useSignal, useVisibleTask$ } from '@builder.io/qwik'; +import { component$, $, useSignal, useVisibleTask$ } from '@qwik.dev/core'; import US_PRESIDENTS from './us-presidents.json'; import { MyOtherComponent } from './my-other-component'; @@ -87,8 +87,8 @@ Qwik comes with a file-based router, which is similar to Next.js. The router is To link to other routes, you can use the `Link` component, it is like `` but allows for SPA navigation. ```tsx title="src/routes/user/[userID]/index.tsx" -import { component$ } from '@builder.io/qwik'; -import { routeLoader$, useLocation, Link } from '@builder.io/qwik-city'; +import { component$ } from '@qwik.dev/core'; +import { routeLoader$, useLocation, Link } from '@qwik.dev/router'; export const useUserData = routeLoader$(async (requestEvent) => { const { userID } = requestEvent.params; diff --git a/packages/docs/src/components/qwik-gpt/index.tsx b/packages/docs/src/components/qwik-gpt/index.tsx index be0a8a590d9..14904d8c3a9 100644 --- a/packages/docs/src/components/qwik-gpt/index.tsx +++ b/packages/docs/src/components/qwik-gpt/index.tsx @@ -1,7 +1,7 @@ -import { component$, useComputed$, useSignal } from '@builder.io/qwik'; +import { component$, useComputed$, useSignal } from '@qwik.dev/core'; // import { qwikGPT, rateResponse } from './search'; import { CodeBlock } from '../code-block/code-block'; -// import { isBrowser } from '@builder.io/qwik'; +// import { isBrowser } from '@qwik.dev/core'; import snarkdown from 'snarkdown'; const snarkdownEnhanced = (md: string) => { diff --git a/packages/docs/src/components/qwik-gpt/search.tsx b/packages/docs/src/components/qwik-gpt/search.tsx index 416e1325e97..3a1187ce3a8 100644 --- a/packages/docs/src/components/qwik-gpt/search.tsx +++ b/packages/docs/src/components/qwik-gpt/search.tsx @@ -1,4 +1,4 @@ -// import { server$ } from '@builder.io/qwik-city'; +// import { server$ } from '@qwik.dev/router'; // import { createClient } from '@supabase/supabase-js'; import gpt from './gpt.md?raw'; // import { chatCompletion } from './streaming-gpt'; diff --git a/packages/docs/src/components/router-head/router-head.tsx b/packages/docs/src/components/router-head/router-head.tsx index b9b512370d3..a84d5c871ed 100644 --- a/packages/docs/src/components/router-head/router-head.tsx +++ b/packages/docs/src/components/router-head/router-head.tsx @@ -1,8 +1,8 @@ -import { component$ } from '@builder.io/qwik'; -import { useDocumentHead, useLocation } from '@builder.io/qwik-city'; +import { component$ } from '@qwik.dev/core'; +import { useDocumentHead, useLocation } from '@qwik.dev/router'; import { Social } from './social'; -import { Vendor } from './vendor'; import { ThemeScript } from './theme-script'; +import { Vendor } from './vendor'; export const RouterHead = component$(() => { const { url } = useLocation(); diff --git a/packages/docs/src/components/sidebar/sidebar.tsx b/packages/docs/src/components/sidebar/sidebar.tsx index 7b78551beab..97ad33e82be 100644 --- a/packages/docs/src/components/sidebar/sidebar.tsx +++ b/packages/docs/src/components/sidebar/sidebar.tsx @@ -1,5 +1,5 @@ -import { component$, sync$, useContext, useOnDocument, useStyles$ } from '@builder.io/qwik'; -import { type ContentMenu, useContent, useLocation, routeLoader$ } from '@builder.io/qwik-city'; +import { component$, sync$, useContext, useOnDocument, useStyles$ } from '@qwik.dev/core'; +import { routeLoader$, useContent, useLocation, type ContentMenu } from '@qwik.dev/router'; import { GlobalStore } from '../../context'; import { CloseIcon } from '../svgs/close-icon'; import styles from './sidebar.css?inline'; @@ -11,7 +11,7 @@ export const useMarkdownItems = routeLoader$(async () => { return [ k .replace('../../routes', '') - .replace('(qwikcity)/', '') + .replace('(qwikrouter)/', '') .replace('(qwik)/', '') .replaceAll(/([()])/g, '') .replace('index.mdx', '') @@ -65,7 +65,7 @@ export const SideBar = component$((props: { allOpen?: boolean }) => { const { menu } = useContent(); const { url } = useLocation(); const markdownItems = useMarkdownItems(); - const allOpen = url.pathname.startsWith('/qwikcity/') || props.allOpen; + const allOpen = url.pathname.startsWith('/qwikrouter/') || props.allOpen; useOnDocument( 'DOMContentLoaded', diff --git a/packages/docs/src/components/sponsors/sponsors.tsx b/packages/docs/src/components/sponsors/sponsors.tsx index 271ad3014c3..e785a887ad8 100644 --- a/packages/docs/src/components/sponsors/sponsors.tsx +++ b/packages/docs/src/components/sponsors/sponsors.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; import { BuilderLogo } from '../svgs/builder-logo'; export const Sponsors = component$(() => { diff --git a/packages/docs/src/components/svgs/bluesky-logo.tsx b/packages/docs/src/components/svgs/bluesky-logo.tsx index a7ee106ba9a..45bae9ac630 100644 --- a/packages/docs/src/components/svgs/bluesky-logo.tsx +++ b/packages/docs/src/components/svgs/bluesky-logo.tsx @@ -1,9 +1,11 @@ +import { component$ } from '@qwik.dev/core'; + interface Props { width: number; height: number; } -export const BlueskyLogo = ({ width, height }: Props) => ( +export const BlueskyLogo = component$(({ width, height }: Props) => ( ( d="M13.873 3.805C21.21 9.332 29.103 20.537 32 26.55v15.882c0-.338-.13.044-.41.867-1.512 4.456-7.418 21.847-20.923 7.944-7.111-7.32-3.819-14.64 9.125-16.85-7.405 1.264-15.73-.825-18.014-9.015C1.12 23.022 0 8.51 0 6.55 0-3.268 8.579-.182 13.873 3.805zm36.254 0C42.79 9.332 34.897 20.537 32 26.55v15.882c0-.338.13.044.41.867 1.512 4.456 7.418 21.847 20.923 7.944 7.111-7.32 3.819-14.64-9.125-16.85 7.405 1.264 15.73-.825 18.014-9.015C62.88 23.022 64 8.51 64 6.55c0-9.818-8.578-6.732-13.873-2.745z" /> -); +)); diff --git a/packages/docs/src/components/svgs/discord-logo.tsx b/packages/docs/src/components/svgs/discord-logo.tsx index c038b6dc69a..e5ecf5ab144 100644 --- a/packages/docs/src/components/svgs/discord-logo.tsx +++ b/packages/docs/src/components/svgs/discord-logo.tsx @@ -1,11 +1,12 @@ -import type { PropsOf } from '@builder.io/qwik'; +import type { PropsOf } from '@qwik.dev/core'; +import { component$ } from '@qwik.dev/core'; type DiscordLogoProps = { width: number; height: number; } & PropsOf<'svg'>; -export const DiscordLogo = ({ width, height }: DiscordLogoProps) => ( +export const DiscordLogo = component$(({ width, height }: DiscordLogoProps) => ( ( -); +)); diff --git a/packages/docs/src/components/svgs/github-logo.tsx b/packages/docs/src/components/svgs/github-logo.tsx index b1b22df0519..6b50def1c8a 100644 --- a/packages/docs/src/components/svgs/github-logo.tsx +++ b/packages/docs/src/components/svgs/github-logo.tsx @@ -1,9 +1,11 @@ +import { component$ } from '@qwik.dev/core'; + interface GithubLogoProps { width: number; height: number; } -export const GithubLogo = ({ width, height }: GithubLogoProps) => ( +export const GithubLogo = component$(({ width, height }: GithubLogoProps) => ( ( > -); +)); diff --git a/packages/docs/src/components/svgs/qwik-logo.tsx b/packages/docs/src/components/svgs/qwik-logo.tsx index 5dc3bafd85b..164bf872876 100644 --- a/packages/docs/src/components/svgs/qwik-logo.tsx +++ b/packages/docs/src/components/svgs/qwik-logo.tsx @@ -1,4 +1,4 @@ -import { component$, type PropsOf } from '@builder.io/qwik'; +import { component$, type PropsOf } from '@qwik.dev/core'; import QwikUwu from '~/media/images/qwik-uwu.webp?url'; type QwikLogoProps = { width: number; diff --git a/packages/docs/src/components/svgs/twitter-logo.tsx b/packages/docs/src/components/svgs/twitter-logo.tsx index 3cfd2ef1635..a1fbad26459 100644 --- a/packages/docs/src/components/svgs/twitter-logo.tsx +++ b/packages/docs/src/components/svgs/twitter-logo.tsx @@ -1,9 +1,11 @@ +import { component$ } from '@qwik.dev/core'; + interface TwitterLogoProps { width: number; height: number; } -export const TwitterLogo = ({ width, height }: TwitterLogoProps) => ( +export const TwitterLogo = component$(({ width, height }: TwitterLogoProps) => ( ( > -); +)); diff --git a/packages/docs/src/components/theme-toggle/sun-and-moon.tsx b/packages/docs/src/components/theme-toggle/sun-and-moon.tsx index 6aeb969543e..bf78e12a871 100644 --- a/packages/docs/src/components/theme-toggle/sun-and-moon.tsx +++ b/packages/docs/src/components/theme-toggle/sun-and-moon.tsx @@ -1,4 +1,4 @@ -import { component$, useStyles$ } from '@builder.io/qwik'; +import { component$, useStyles$ } from '@qwik.dev/core'; import sunAndMoonStyles from './sun-and-moon.css?inline'; export const SunAndMoon = component$(() => { diff --git a/packages/docs/src/components/theme-toggle/theme-toggle.tsx b/packages/docs/src/components/theme-toggle/theme-toggle.tsx index 2b8433c5f75..ebda4cf742c 100644 --- a/packages/docs/src/components/theme-toggle/theme-toggle.tsx +++ b/packages/docs/src/components/theme-toggle/theme-toggle.tsx @@ -1,4 +1,4 @@ -import { component$, event$, useContext, useStyles$ } from '@builder.io/qwik'; +import { component$, event$, useContext, useStyles$ } from '@qwik.dev/core'; import { SunAndMoon } from './sun-and-moon'; import { themeStorageKey } from '../router-head/theme-script'; import themeToggle from './theme-toggle.css?inline'; diff --git a/packages/docs/src/context.ts b/packages/docs/src/context.ts index 13eb9adca70..85f515cd45c 100644 --- a/packages/docs/src/context.ts +++ b/packages/docs/src/context.ts @@ -1,4 +1,4 @@ -import { createContextId } from '@builder.io/qwik'; +import { createContextId } from '@qwik.dev/core'; import type { ThemePreference } from './components/theme-toggle/theme-toggle'; export interface SiteStore { diff --git a/packages/docs/src/entry.cloudflare-pages.tsx b/packages/docs/src/entry.cloudflare-pages.tsx index 260810ae96f..c9b4f145629 100644 --- a/packages/docs/src/entry.cloudflare-pages.tsx +++ b/packages/docs/src/entry.cloudflare-pages.tsx @@ -1,7 +1,7 @@ -import { createQwikCity } from '@builder.io/qwik-city/middleware/cloudflare-pages'; -import qwikCityPlan from '@qwik-city-plan'; +import qwikRouterConfig from '@qwik-router-config'; +import { createQwikRouter } from '@qwik.dev/router/middleware/cloudflare-pages'; import render from './entry.ssr'; -const fetch = createQwikCity({ render, qwikCityPlan }); +const fetch = createQwikRouter({ render, qwikRouterConfig }); export { fetch }; diff --git a/packages/docs/src/entry.dev.tsx b/packages/docs/src/entry.dev.tsx index 70bf4d77393..4c2c7c0b8d7 100644 --- a/packages/docs/src/entry.dev.tsx +++ b/packages/docs/src/entry.dev.tsx @@ -1,4 +1,4 @@ -import { render, type RenderOptions } from '@builder.io/qwik'; +import { render, type RenderOptions } from '@qwik.dev/core'; import Root from './root'; /** diff --git a/packages/docs/src/entry.preview.tsx b/packages/docs/src/entry.preview.tsx index 7c4a0028bf2..01f08eb6761 100644 --- a/packages/docs/src/entry.preview.tsx +++ b/packages/docs/src/entry.preview.tsx @@ -1,6 +1,6 @@ -import { createQwikCity } from '@builder.io/qwik-city/middleware/node'; -import qwikCityPlan from '@qwik-city-plan'; +import qwikRouterConfig from '@qwik-router-config'; +import { createQwikRouter } from '@qwik.dev/router/middleware/node'; import render from './entry.ssr'; -/** The default export is the QwikCity adapter used by Vite preview. */ -export default createQwikCity({ render, qwikCityPlan }); +/** The default export is the QwikRouter adapter used by Vite preview. */ +export default createQwikRouter({ render, qwikRouterConfig }); diff --git a/packages/docs/src/entry.ssr.tsx b/packages/docs/src/entry.ssr.tsx index dbb6170bb7d..28ba5e395c2 100644 --- a/packages/docs/src/entry.ssr.tsx +++ b/packages/docs/src/entry.ssr.tsx @@ -1,5 +1,5 @@ -import type { PreloaderOptions, RenderToStreamOptions } from '@builder.io/qwik/server'; -import { renderToStream } from '@builder.io/qwik/server'; +import type { PreloaderOptions, RenderToStreamOptions } from '@qwik.dev/core/server'; +import { renderToStream } from '@qwik.dev/core/server'; import Root from './root'; // You can pass these as query parameters, as well as `preloadDebug` diff --git a/packages/docs/src/media/docs/qwikcity/routing-files.png b/packages/docs/src/media/docs/qwikrouter/routing-files.png similarity index 100% rename from packages/docs/src/media/docs/qwikcity/routing-files.png rename to packages/docs/src/media/docs/qwikrouter/routing-files.png diff --git a/packages/docs/src/media/docs/qwikcity/routing.png b/packages/docs/src/media/docs/qwikrouter/routing.png similarity index 100% rename from packages/docs/src/media/docs/qwikcity/routing.png rename to packages/docs/src/media/docs/qwikrouter/routing.png diff --git a/packages/docs/src/media/icons/qwikCity_and_routing.svg b/packages/docs/src/media/icons/qwikRouter_and_routing.svg similarity index 100% rename from packages/docs/src/media/icons/qwikCity_and_routing.svg rename to packages/docs/src/media/icons/qwikRouter_and_routing.svg diff --git a/packages/docs/src/repl/bundled.tsx b/packages/docs/src/repl/bundled.tsx index 5c4626a8935..35bd497b6c1 100644 --- a/packages/docs/src/repl/bundled.tsx +++ b/packages/docs/src/repl/bundled.tsx @@ -1,4 +1,4 @@ -import { version as qwikVersion } from '@builder.io/qwik'; +import { version as qwikVersion } from '@qwik.dev/core'; import type { PkgUrls } from './types'; import prettierPkgJson from 'prettier/package.json'; @@ -8,19 +8,22 @@ import prettierStandaloneJs from '../../node_modules/prettier/standalone.js?raw- import terserPkgJson from 'terser/package.json'; import terserJs from '../../node_modules/terser/dist/bundle.min.js?raw-source'; -import qBuild from '../../node_modules/@builder.io/qwik/dist/build/index.d.ts?raw-source'; -import qCoreCjs from '../../node_modules/@builder.io/qwik/dist/core.cjs?raw-source'; -import qCoreDts from '../../node_modules/@builder.io/qwik/dist/core.d.ts?raw-source'; -import qCoreMinMjs from '../../node_modules/@builder.io/qwik/dist/core.min.mjs?raw-source'; -import qCoreMjs from '../../node_modules/@builder.io/qwik/dist/core.mjs?raw-source'; -import qOptimizerCjs from '../../node_modules/@builder.io/qwik/dist/optimizer.cjs?raw-source'; -import qPreloaderMjs from '../../node_modules/@builder.io/qwik/dist/preloader.mjs?raw-source'; -import qServerCjs from '../../node_modules/@builder.io/qwik/dist/server.cjs?raw-source'; -import qServerDts from '../../node_modules/@builder.io/qwik/dist/server.d.ts?raw-source'; -import qWasmCjs from '../../node_modules/@builder.io/qwik/bindings/qwik.wasm.cjs?raw-source'; -import qWasmBinUrl from '../../node_modules/@builder.io/qwik/bindings/qwik_wasm_bg.wasm?raw-source'; +import qWasmCjs from '../../node_modules/@qwik.dev/core/bindings/qwik.wasm.cjs?raw-source'; +import qWasmBinUrl from '../../node_modules/@qwik.dev/core/bindings/qwik_wasm_bg.wasm?raw-source'; +import qBuild from '../../node_modules/@qwik.dev/core/dist/build/index.d.ts?raw-source'; +import qCoreCjs from '../../node_modules/@qwik.dev/core/dist/core.cjs?raw-source'; +import qPublicDts from '../../node_modules/@qwik.dev/core/public.d.ts?raw-source'; +import qCoreInternalDts from '../../node_modules/@qwik.dev/core/dist/core-internal.d.ts?raw-source'; +import qCoreMinMjs from '../../node_modules/@qwik.dev/core/dist/core.min.mjs?raw-source'; +import qPreloaderMjs from '../../node_modules/@qwik.dev/core/dist/preloader.mjs?raw-source'; +import qHandlersMjs from '../../node_modules/@qwik.dev/core/handlers.mjs?raw-source'; +import qCoreMjs from '../../node_modules/@qwik.dev/core/dist/core.mjs?raw-source'; +import qOptimizerCjs from '../../node_modules/@qwik.dev/core/dist/optimizer.cjs?raw-source'; +import qServerCjs from '../../node_modules/@qwik.dev/core/dist/server.cjs?raw-source'; +import qServerDts from '../../node_modules/@qwik.dev/core/dist/server.d.ts?raw-source'; -export const QWIK_PKG_NAME = '@builder.io/qwik'; +export const QWIK_PKG_NAME = '@qwik.dev/core'; +export const QWIK_PKG_NAME_V1 = '@builder.io/qwik'; const ROLLUP_VERSION = '2.75.6'; export const getNpmCdnUrl = ( @@ -42,6 +45,11 @@ export const getNpmCdnUrl = ( pkgVersion = pkgName === QWIK_PKG_NAME ? qwikVersion.split('-dev')[0] : ''; } } + if (pkgName === QWIK_PKG_NAME) { + if (pkgVersion < '2') { + pkgName = QWIK_PKG_NAME_V1; + } + } return `https://cdn.jsdelivr.net/npm/${pkgName}${pkgVersion ? '@' + pkgVersion : ''}${pkgPath}`; }; @@ -50,13 +58,15 @@ export const bundled: PkgUrls = { version: qwikVersion, '/dist/build/index.d.ts': qBuild, '/dist/core.cjs': qCoreCjs, - '/dist/core.d.ts': qCoreDts, + '/public.d.ts': qPublicDts, + '/dist/core-internal.d.ts': qCoreInternalDts, '/dist/core.min.mjs': qCoreMinMjs, '/dist/core.mjs': qCoreMjs, '/dist/optimizer.cjs': qOptimizerCjs, '/dist/server.cjs': qServerCjs, '/dist/server.d.ts': qServerDts, '/dist/preloader.mjs': qPreloaderMjs, + '/handlers.mjs': qHandlersMjs, '/bindings/qwik.wasm.cjs': qWasmCjs, '/bindings/qwik_wasm_bg.wasm': qWasmBinUrl, }, diff --git a/packages/docs/src/repl/editor.tsx b/packages/docs/src/repl/editor.tsx index cd2d81c86d4..2975216c0e6 100644 --- a/packages/docs/src/repl/editor.tsx +++ b/packages/docs/src/repl/editor.tsx @@ -7,7 +7,7 @@ import { useSignal, useStore, useTask$, -} from '@builder.io/qwik'; +} from '@qwik.dev/core'; import type { IStandaloneCodeEditor } from './monaco'; import { addQwikLibs, diff --git a/packages/docs/src/repl/monaco.tsx b/packages/docs/src/repl/monaco.tsx index d4422c2889d..a6d82629d4c 100644 --- a/packages/docs/src/repl/monaco.tsx +++ b/packages/docs/src/repl/monaco.tsx @@ -1,11 +1,10 @@ -import { noSerialize } from '@builder.io/qwik'; -import type { Diagnostic } from '@builder.io/qwik/optimizer'; +import { isServer, noSerialize } from '@qwik.dev/core'; +import type { Diagnostic } from '@qwik.dev/core/optimizer'; import type MonacoTypes from 'monaco-editor'; +import { getColorPreference } from '../components/theme-toggle/theme-toggle'; +import { QWIK_PKG_NAME, QWIK_PKG_NAME_V1, bundled, getNpmCdnUrl } from './bundled'; import type { EditorProps, EditorStore } from './editor'; import type { ReplStore } from './types'; -import { getColorPreference } from '../components/theme-toggle/theme-toggle'; -import { bundled, getNpmCdnUrl } from './bundled'; -import { isServer } from '@builder.io/qwik'; // We cannot use this, it causes the repl to use imports // import { QWIK_REPL_DEPS_CACHE } from './worker/repl-constants'; const QWIK_REPL_DEPS_CACHE = 'QwikReplDeps'; @@ -26,7 +25,7 @@ export const initMonacoEditor = async ( esModuleInterop: true, isolatedModules: true, jsx: ts.JsxEmit.ReactJSX, - jsxImportSource: '@builder.io/qwik', + jsxImportSource: '@qwik.dev/core', moduleResolution: ts.ModuleResolutionKind.NodeJs, noEmit: true, skipLibCheck: true, @@ -148,7 +147,11 @@ const checkDiagnostics = async ( ) => { if (!monacoCtx.tsWorker) { const getTsWorker = await monaco.languages.typescript.getTypeScriptWorker(); - monacoCtx.tsWorker = await getTsWorker(editor.getModel()!.uri); + const uri = editor.getModel()?.uri; + if (!uri) { + return; + } + monacoCtx.tsWorker = await getTsWorker(uri); } const tsWorker = monacoCtx.tsWorker; @@ -211,41 +214,48 @@ export const addQwikLibs = async (version: string) => { } }); typescriptDefaults.addExtraLib( - `declare module '@builder.io/qwik/jsx-runtime' { export * from '@builder.io/qwik' }`, - '/node_modules/@builder.io/qwik/dist/jsx-runtime.d.ts' + `declare module '@qwik.dev/core/jsx-runtime' { export * from '@qwik.dev/core' }`, + '/node_modules/@qwik.dev/core/dist/jsx-runtime.d.ts' ); typescriptDefaults.addExtraLib(CLIENT_LIB); }; const loadDeps = async (qwikVersion: string) => { const [M, m, p] = qwikVersion.split('-')[0].split('.').map(Number); + const isV1 = M < 2; const prefix = qwikVersion === 'bundled' || M > 1 || (M == 1 && (m > 7 || (m == 7 && p >= 2))) ? '/dist/' : '/'; const deps: NodeModuleDep[] = [ // qwik - { - pkgName: '@builder.io/qwik', + !isV1 && { + pkgName: QWIK_PKG_NAME, pkgVersion: qwikVersion, - pkgPath: `${prefix}core.d.ts`, + pkgPath: `/public.d.ts`, import: '', }, + { + pkgName: isV1 ? QWIK_PKG_NAME_V1 : QWIK_PKG_NAME, + pkgVersion: qwikVersion, + pkgPath: `${prefix}core-internal.d.ts`, + import: isV1 ? '' : '/internal', + }, // server API { - pkgName: '@builder.io/qwik', + pkgName: isV1 ? QWIK_PKG_NAME_V1 : QWIK_PKG_NAME, pkgVersion: qwikVersion, pkgPath: `${prefix}server.d.ts`, import: '/server', }, // build constants { - pkgName: '@builder.io/qwik', + pkgName: isV1 ? QWIK_PKG_NAME_V1 : QWIK_PKG_NAME, pkgVersion: qwikVersion, pkgPath: `${prefix}build/index.d.ts`, import: '/build', }, - ]; + ].filter(Boolean) as NodeModuleDep[]; const cache = await caches.open(QWIK_REPL_DEPS_CACHE); diff --git a/packages/docs/src/repl/repl-console.tsx b/packages/docs/src/repl/repl-console.tsx index a61d5e44ac4..6890ede20a2 100644 --- a/packages/docs/src/repl/repl-console.tsx +++ b/packages/docs/src/repl/repl-console.tsx @@ -1,4 +1,4 @@ -import { component$, jsx } from '@builder.io/qwik'; +import { component$, jsx } from '@qwik.dev/core'; import type { ReplEvent, ReplStore } from './types'; export interface ReplConsoleProps { @@ -7,9 +7,10 @@ export interface ReplConsoleProps { export const ReplConsole = component$(({ store }: ReplConsoleProps) => { return (
- {store.events.filter(Boolean).map((ev) => ( - - ))} + { + // for some reason ev can be null, just skip it + store.events.map((ev) => ev && ) + }
); }); diff --git a/packages/docs/src/repl/repl-input-panel.tsx b/packages/docs/src/repl/repl-input-panel.tsx index dab4e48331e..fb8c8ff0921 100644 --- a/packages/docs/src/repl/repl-input-panel.tsx +++ b/packages/docs/src/repl/repl-input-panel.tsx @@ -1,4 +1,4 @@ -import type { QRL } from '@builder.io/qwik'; +import type { QRL } from '@qwik.dev/core'; import { Editor } from './editor'; import { ReplCommands } from './repl-commands'; import { ReplTabButton } from './repl-tab-button'; diff --git a/packages/docs/src/repl/repl-output-modules.tsx b/packages/docs/src/repl/repl-output-modules.tsx index ea23c62949d..bb1159160db 100644 --- a/packages/docs/src/repl/repl-output-modules.tsx +++ b/packages/docs/src/repl/repl-output-modules.tsx @@ -1,4 +1,4 @@ -import { $, component$, createSignal, useSignal } from '@builder.io/qwik'; +import { $, component$, createSignal, useSignal } from '@qwik.dev/core'; import { CodeBlock } from '../components/code-block/code-block'; import type { ReplModuleOutput } from './types'; const FILE_MODULE_DIV_ID = 'file-modules-client-modules'; diff --git a/packages/docs/src/repl/repl-output-panel.tsx b/packages/docs/src/repl/repl-output-panel.tsx index 06385eb677f..2e1984e2ea1 100644 --- a/packages/docs/src/repl/repl-output-panel.tsx +++ b/packages/docs/src/repl/repl-output-panel.tsx @@ -1,13 +1,67 @@ -import { component$ } from '@builder.io/qwik'; +import { component$, useComputed$ } from '@qwik.dev/core'; import { CodeBlock } from '../components/code-block/code-block'; import { ReplOutputModules } from './repl-output-modules'; -import { ReplOutputSymbols } from './repl-output-symbols'; +import { ReplOutputSegments } from './repl-output-segments'; import { ReplTabButton } from './repl-tab-button'; import { ReplTabButtons } from './repl-tab-buttons'; import type { ReplAppInput, ReplStore } from './types'; +import { _deserialize, _getDomContainer } from '@qwik.dev/core/internal'; +import { _dumpState, _preprocessState, _vnode_toString } from '@qwik.dev/core/internal'; export const ReplOutputPanel = component$(({ input, store }: ReplOutputPanelProps) => { - const diagnosticsLen = store.diagnostics.length + store.monacoDiagnostics.length; + const diagnosticsLen = useComputed$( + () => store.diagnostics.length + store.monacoDiagnostics.length + ); + + const domContainerFromResultHtml = useComputed$(() => { + try { + const parser = new DOMParser(); + const doc = parser.parseFromString(store.htmlResult.rawHtml, 'text/html'); + return _getDomContainer(doc.documentElement); + } catch (err) { + console.error(err); + return null; + } + }); + + const parsedState = useComputed$(() => { + try { + const container = domContainerFromResultHtml.value; + const doc = container!.element; + const qwikStates = doc.querySelectorAll('script[type="qwik/state"]'); + if (qwikStates.length !== 0) { + const data = qwikStates[qwikStates.length - 1]; + const origState = JSON.parse(data?.textContent || '[]'); + _preprocessState(origState, container as any); + return origState + ? _dumpState(origState, false, '', null) + //remove first new line + .replace(/\n/, '') + : 'No state found'; + } + return 'No state found'; + } catch (err) { + console.error(err); + return null; + } + }); + + const vdomTree = useComputed$(() => { + try { + const container = domContainerFromResultHtml.value; + return _vnode_toString.call( + container!.rootVNode as any, + Number.MAX_SAFE_INTEGER, + '', + true, + false, + false + ); + } catch (err) { + console.error(err); + return null; + } + }); return (
@@ -32,10 +86,10 @@ export const ReplOutputPanel = component$(({ input, store }: ReplOutputPanelProp {store.enableClientOutput ? ( { - store.selectedOutputPanel = 'symbols'; + store.selectedOutputPanel = 'segments'; }} /> ) : null} @@ -61,8 +115,8 @@ export const ReplOutputPanel = component$(({ input, store }: ReplOutputPanelProp ) : null} 0 ? ` (${diagnosticsLen})` : ``}`} - cssClass={{ 'repl-tab-diagnostics': true, 'has-errors': diagnosticsLen > 0 }} + text={`Diagnostics${diagnosticsLen.value > 0 ? ` (${diagnosticsLen.value})` : ``}`} + cssClass={{ 'repl-tab-diagnostics': true, 'has-errors': diagnosticsLen.value > 0 }} isActive={store.selectedOutputPanel === 'diagnostics'} onClick$={async () => { store.selectedOutputPanel = 'diagnostics'; @@ -101,13 +155,31 @@ export const ReplOutputPanel = component$(({ input, store }: ReplOutputPanelProp
{store.selectedOutputPanel === 'html' ? ( -
- +
+
+ HTML + +
+ {parsedState.value ? ( +
+ Parsed State + +
+ ) : null} + {vdomTree.value ? ( +
+ VNode Tree + +
+ ) : null}
) : null} - {store.selectedOutputPanel === 'symbols' ? ( - + {store.selectedOutputPanel === 'segments' ? ( + ) : null} {store.selectedOutputPanel === 'clientBundles' ? ( @@ -120,7 +192,7 @@ export const ReplOutputPanel = component$(({ input, store }: ReplOutputPanelProp {store.selectedOutputPanel === 'diagnostics' ? (
- {diagnosticsLen === 0 ? ( + {diagnosticsLen.value === 0 ? (

- No Reported Diagnostics -

) : ( [...store.diagnostics, ...store.monacoDiagnostics].map((d, key) => ( diff --git a/packages/docs/src/repl/repl-output-segments.tsx b/packages/docs/src/repl/repl-output-segments.tsx new file mode 100644 index 00000000000..544cf5c109a --- /dev/null +++ b/packages/docs/src/repl/repl-output-segments.tsx @@ -0,0 +1,73 @@ +import { $, component$, useSignal } from '@qwik.dev/core'; +import type { TransformModule } from '@qwik.dev/core/optimizer'; +import { CodeBlock } from '../components/code-block/code-block'; +const FILE_MODULE_DIV_ID = 'file-modules-symbol'; + +export const ReplOutputSegments = component$(({ outputs }: ReplOutputSegmentsProps) => { + const selectedPath = useSignal(outputs.length ? outputs[0].path : ''); + const pathInView$ = $((path: string) => { + selectedPath.value = path; + }); + + return ( +
+ +
+ {outputs + .filter((o) => !!o.segment) + .map((o, i) => ( +
+
+ {o.segment!.canonicalFilename} + {o.segment!.paramNames && ( +
+ Params: {o.segment!.paramNames.join(', ')} +
+ )} + {o.segment!.captureNames && ( +
+ Captures: {o.segment!.captureNames.join(', ')} +
+ )} +
+
+ +
+
+ ))} +
+
+ ); +}); + +interface ReplOutputSegmentsProps { + outputs: TransformModule[]; +} diff --git a/packages/docs/src/repl/repl-output-symbols.tsx b/packages/docs/src/repl/repl-output-symbols.tsx deleted file mode 100644 index 47846d85e6e..00000000000 --- a/packages/docs/src/repl/repl-output-symbols.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import type { TransformModule } from '@builder.io/qwik/optimizer'; -import { CodeBlock } from '../components/code-block/code-block'; -import { $, component$, useSignal } from '@builder.io/qwik'; -const FILE_MODULE_DIV_ID = 'file-modules-symbol'; - -export const ReplOutputSymbols = component$(({ outputs }: ReplOutputSymbolsProps) => { - const selectedPath = useSignal(outputs.length ? outputs[0].path : ''); - const pathInView$ = $((path: string) => { - selectedPath.value = path; - }); - - return ( - - ); -}); - -interface ReplOutputSymbolsProps { - outputs: TransformModule[]; -} diff --git a/packages/docs/src/repl/repl-output-update.ts b/packages/docs/src/repl/repl-output-update.ts index 1fe666a0dc6..f1d074841e5 100644 --- a/packages/docs/src/repl/repl-output-update.ts +++ b/packages/docs/src/repl/repl-output-update.ts @@ -1,29 +1,45 @@ import type { ReplResult, ReplStore } from './types'; // TODO fix useStore to recursively notify subscribers -const deepUpdate = (prev: any, next: any) => { +const deepUpdate = (prev: any, next: any, matcher?: (a: any, b: any) => boolean) => { for (const key in next) { if (prev[key] && typeof next[key] === 'object' && typeof prev[key] === 'object') { deepUpdate(prev[key], next[key]); } else { - prev[key] = next[key]; + if (prev[key] !== next[key]) { + prev[key] = next[key]; + } } } - for (const key in prev) { - if (!(key in next)) { - delete prev[key]; + if (Array.isArray(prev)) { + for (const item of prev) { + if (!next.some((nextItem: any) => (matcher ? matcher(nextItem, item) : nextItem === item))) { + prev.splice(prev.indexOf(item), 1); + } + } + } else { + for (const key in prev) { + if (!(key in next)) { + delete prev[key]; + } } } }; +const matchByPath = (a: any, b: any) => a.path === b.path; + export const updateReplOutput = async (store: ReplStore, result: ReplResult) => { - store.diagnostics = result.diagnostics; + deepUpdate(store.diagnostics, result.diagnostics); + if (store.htmlResult.rawHtml !== result.htmlResult.rawHtml) { + store.htmlResult.rawHtml = result.htmlResult.rawHtml; + store.htmlResult.prettyHtml = result.htmlResult.prettyHtml; + } - if (store.diagnostics.length === 0) { - store.html = result.html; - deepUpdate(store.transformedModules, result.transformedModules); - deepUpdate(store.clientBundles, result.clientBundles); - deepUpdate(store.ssrModules, result.ssrModules); + if (result.diagnostics.length === 0) { + deepUpdate(store.htmlResult, result.htmlResult); + deepUpdate(store.transformedModules, result.transformedModules, matchByPath); + deepUpdate(store.clientBundles, result.clientBundles, matchByPath); + deepUpdate(store.ssrModules, result.ssrModules, matchByPath); if ( result.events.length !== store.events.length || result.events.some((ev, i) => ev?.start !== store.events[i]?.start) diff --git a/packages/docs/src/repl/repl-share-url.ts b/packages/docs/src/repl/repl-share-url.ts index 6de7babc17e..2ade4edff89 100644 --- a/packages/docs/src/repl/repl-share-url.ts +++ b/packages/docs/src/repl/repl-share-url.ts @@ -85,6 +85,10 @@ export const strToFiles = (str: string) => { // You can add new entries to the beginning though. export const dictionary = strToU8( filesToStr([ + { + path: '/app.tsx', + code: `import { component$ } from '@qwik.dev/core';\n\nexport default component$(() => {\n return (\n
\n

Hello from Qwik!

\n
\n );\n`, + }, { path: '', // Extra words to help with compression @@ -98,7 +102,7 @@ export const dictionary = strToU8( // You need to add a new section like this before this section instead code: `
props: class return ( story component$( store string state export const span type href={ page strong count useSignal< useStore< qwik import { } from searchInput console.log( searchResults builder useTask$( stories style={ news export default data track onClick$= new nav map link debounced controller user useStyles$( useStylesScoped$( url title timeoutId time_ago second response Date.now() minute main item interface hour disabled aria any State update transform the target suggestion setTimeout selectedValue rotate render people number list label https:// header deg debouncedGetPeople debounce component comments_count comments clock background await new Promise args SuggestionsListComponent IStory IState IComment GrandChild Clock Child AutoComplete 360 yellow with view useVisibleTask$( true tmrId timer then swapi styles signal section search results resolve rel prev points parsedResponse null noreferrer name more length json job items isServer index github getPeople function fetch example domain dev delay css container com click clearTimeout async api _blank Star Wars API This The StoryPreview Stories ReturnType Qwik App Page Nav HackerNewsCSS AbortController server$( routeAction$( routeLoader$( useContent( useDocumentHead( useLocation( useNavigate( validator$( zod$( noSerialize( useComputed$( useOnDocument( useOnWindow( useResource$( useContext( useContextProvider( createContextId<`, }, - // The default hello world app + supporting files + // The old default hello world app + supporting files { path: '/app.tsx', code: `import { component$ } from '@builder.io/qwik';\n\nexport default component$(() => {\n return

Hello Qwik

;\n});\n`, diff --git a/packages/docs/src/repl/repl-share-url.unit.ts b/packages/docs/src/repl/repl-share-url.unit.ts index 6d1dec380bc..3c90defd60c 100644 --- a/packages/docs/src/repl/repl-share-url.unit.ts +++ b/packages/docs/src/repl/repl-share-url.unit.ts @@ -1,13 +1,14 @@ -import { assert, test } from 'vitest'; +import { strFromU8 } from 'fflate'; +import { assert, expect, test } from 'vitest'; import { - filesToStr, - strToFiles, - createPlaygroundShareUrl, compressFiles, - parseCompressedFiles, + createPlaygroundShareUrl, dictionary, + filesToStr, + parseCompressedFiles, + parsePlaygroundShareUrl, + strToFiles, } from './repl-share-url'; -import { strFromU8 } from 'fflate'; const data = { version: '1.2.3', @@ -64,8 +65,85 @@ test('createPlaygroundShareUrl 2', () => { }); test('dictionary is unchanged', () => { - assert.equal( - strFromU8(dictionary), - "0||1448|
props: class return ( story component$( store string state export const span type href={ page strong count useSignal< useStore< qwik import { } from searchInput console.log( searchResults builder useTask$( stories style={ news export default data track onClick$= new nav map link debounced controller user useStyles$( useStylesScoped$( url title timeoutId time_ago second response Date.now() minute main item interface hour disabled aria any State update transform the target suggestion setTimeout selectedValue rotate render people number list label https:// header deg debouncedGetPeople debounce component comments_count comments clock background await new Promise args SuggestionsListComponent IStory IState IComment GrandChild Clock Child AutoComplete 360 yellow with view useVisibleTask$( true tmrId timer then swapi styles signal section search results resolve rel prev points parsedResponse null noreferrer name more length json job items isServer index github getPeople function fetch example domain dev delay css container com click clearTimeout async api _blank Star Wars API This The StoryPreview Stories ReturnType Qwik App Page Nav HackerNewsCSS AbortController server$( routeAction$( routeLoader$( useContent( useDocumentHead( useLocation( useNavigate( validator$( zod$( noSerialize( useComputed$( useOnDocument( useOnWindow( useResource$( useContext( useContextProvider( createContextId<|8|/app.tsx|114|import { component$ } from '@builder.io/qwik';\n\nexport default component$(() => {\n return

Hello Qwik

;\n});\n|17|/entry.server.tsx|201|import { renderToString, type RenderOptions } from '@builder.io/qwik/server';\nimport { Root } from './root';\n\nexport default function (opts: RenderOptions) {\n return renderToString(, opts);\n}\n|9|/root.tsx|192|import App from './app';\n\nexport const Root = () => {\n return (\n <>\n \n Hello Qwik\n \n \n \n \n \n );\n};\n" + const dictionaryAsString = strFromU8(dictionary); + expect(dictionaryAsString).toMatchInlineSnapshot(` + "8|/app.tsx|149|import { component$ } from '@qwik.dev/core'; + + export default component$(() => { + return ( +
+

Hello from Qwik!

+
+ ); + |0||1448|
props: class return ( story component$( store string state export const span type href={ page strong count useSignal< useStore< qwik import { } from searchInput console.log( searchResults builder useTask$( stories style={ news export default data track onClick$= new nav map link debounced controller user useStyles$( useStylesScoped$( url title timeoutId time_ago second response Date.now() minute main item interface hour disabled aria any State update transform the target suggestion setTimeout selectedValue rotate render people number list label https:// header deg debouncedGetPeople debounce component comments_count comments clock background await new Promise args SuggestionsListComponent IStory IState IComment GrandChild Clock Child AutoComplete 360 yellow with view useVisibleTask$( true tmrId timer then swapi styles signal section search results resolve rel prev points parsedResponse null noreferrer name more length json job items isServer index github getPeople function fetch example domain dev delay css container com click clearTimeout async api _blank Star Wars API This The StoryPreview Stories ReturnType Qwik App Page Nav HackerNewsCSS AbortController server$( routeAction$( routeLoader$( useContent( useDocumentHead( useLocation( useNavigate( validator$( zod$( noSerialize( useComputed$( useOnDocument( useOnWindow( useResource$( useContext( useContextProvider( createContextId<|8|/app.tsx|114|import { component$ } from '@builder.io/qwik'; + + export default component$(() => { + return

Hello Qwik

; + }); + |17|/entry.server.tsx|201|import { renderToString, type RenderOptions } from '@builder.io/qwik/server'; + import { Root } from './root'; + + export default function (opts: RenderOptions) { + return renderToString(, opts); + } + |9|/root.tsx|192|import App from './app'; + + export const Root = () => { + return ( + <> + + Hello Qwik + + + + + + ); + }; + " + `); +}); + +test('previous URLs still work', () => { + expect(parsePlaygroundShareUrl('f=G000o4mG5EQDAA')).toHaveProperty( + 'files', + // DO NOT UPDATE THIS TEST - all these URLs must work forever + expect.arrayContaining([ + expect.objectContaining({ + path: '/app.tsx', + code: "import { component$ } from '@builder.io/qwik';\n\nexport default component$(() => {\n return

Hello Qwik

;\n});\n", + }), + ]) + ); + expect( + parsePlaygroundShareUrl( + 'f=Q0o0xgaW2BKNDrDkqNCB15QUpyFIgKTl51uBeGA%2BKO%2BBIwaW0W1A6SI%2FDWQzyKm1wKBDVwyU0lAqUNJRqE4GFc3AqLNSCnENDlGq1QTpAGJ43a5RDa6oa0FOgBsDbxkAXQIMCqAWMIktXqqBSvRgNoNMRg7C0XQ%2FJNM9AA' + ) + ).toHaveProperty( + 'files', + // DO NOT UPDATE THIS TEST - all these URLs must work forever + expect.arrayContaining([ + expect.objectContaining({ + path: '/app.tsx', + code: `import { component$, jsx, useTask$ } from '@builder.io/qwik'; + +export default component$(() => { + const foo:{ + contents: ReturnType + } = { + contents: jsx("p", {children:"TEST"}) + } + useTask$(({track}) =>{ + console.log(foo); + }); + return ( + <> + {foo.contents} + + ); +}); +`, + }), + ]) ); }); diff --git a/packages/docs/src/repl/repl-tab-button.tsx b/packages/docs/src/repl/repl-tab-button.tsx index 16274c8cac8..824514e2bb1 100644 --- a/packages/docs/src/repl/repl-tab-button.tsx +++ b/packages/docs/src/repl/repl-tab-button.tsx @@ -1,4 +1,4 @@ -import type { PropsOf, Component } from '@builder.io/qwik'; +import type { PropsOf, Component } from '@qwik.dev/core'; import { CloseIcon } from '../components/svgs/close-icon'; export const ReplTabButton: Component = (props) => { diff --git a/packages/docs/src/repl/repl-version.ts b/packages/docs/src/repl/repl-version.ts index 40608bbac0b..0a659d970c7 100644 --- a/packages/docs/src/repl/repl-version.ts +++ b/packages/docs/src/repl/repl-version.ts @@ -3,7 +3,7 @@ import { QWIK_PKG_NAME, bundled } from './bundled'; const bundledVersion = bundled[QWIK_PKG_NAME].version; // The golden oldies -const keepList = new Set('1.0.0,1.1.5,1.2.13,1.4.5'.split(',')); +const keepList = new Set('1.0.0,1.1.5,1.2.13,1.4.5,1.5.7,1.6.0,1.7.3,1.8.0,1.9.0'.split(',')); // The bad apples - add versions that break the REPL here const blockList = new Set( @@ -97,7 +97,7 @@ export const getReplVersion = async (version: string | undefined, offline: boole }); versions.unshift('bundled'); - if (!hasVersion || !version) { + if ((!offline && !hasVersion) || !version) { version = 'bundled'; } @@ -113,11 +113,11 @@ const isExpiredNpmData = (npmData: NpmData | null) => { return true; }; -const QWIK_NPM_DATA = `https://data.jsdelivr.com/v1/package/npm/@builder.io/qwik`; +const QWIK_NPM_DATA = `https://data.jsdelivr.com/v1/package/npm/@qwik.dev/core`; const NPM_STORAGE_KEY = `qwikNpmData`; -// https://data.jsdelivr.com/v1/package/npm/@builder.io/qwik +// https://data.jsdelivr.com/v1/package/npm/@qwik.dev/core interface NpmData { tags: { latest: string; next: string }; versions: string[]; diff --git a/packages/docs/src/repl/repl.css b/packages/docs/src/repl/repl.css index f5e8e437b4b..46517a129aa 100644 --- a/packages/docs/src/repl/repl.css +++ b/packages/docs/src/repl/repl.css @@ -199,6 +199,15 @@ overflow: auto; } +.output-html .code-block-info { + display: block; + font-weight: bold; + background-color: rgb(33 104 170 / 15%); + padding: 5px 10px; + overflow: hidden; + text-overflow: ellipsis; +} + .output-html pre { height: 100%; } @@ -230,7 +239,7 @@ .output-modules .file-tree { padding: 0 15px 15px 15px; grid-area: repl-file-tree; - overflow-y: auto; + overflow: auto; } .output-modules .file-tree-header { @@ -242,8 +251,6 @@ display: block; margin: 4px 0px 2px 9px; white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; } .output-modules .file-tree-items a:hover, @@ -270,8 +277,7 @@ margin-bottom: 15px; background-color: rgb(33 104 170 / 15%); padding: 5px 10px; - overflow: hidden; - text-overflow: ellipsis; + word-break: break-word; } .output-modules .file-size { diff --git a/packages/docs/src/repl/repl.tsx b/packages/docs/src/repl/repl.tsx index 5213ec856eb..455d465cdc6 100644 --- a/packages/docs/src/repl/repl.tsx +++ b/packages/docs/src/repl/repl.tsx @@ -1,21 +1,21 @@ import { + $, component$, + isServer, noSerialize, - useStyles$, useStore, + useStyles$, useTask$, useVisibleTask$, - $, -} from '@builder.io/qwik'; +} from '@qwik.dev/core'; +import { QWIK_PKG_NAME, QWIK_PKG_NAME_V1, bundled, getNpmCdnUrl } from './bundled'; +import { ReplDetailPanel } from './repl-detail-panel'; import { ReplInputPanel } from './repl-input-panel'; import { ReplOutputPanel } from './repl-output-panel'; -import styles from './repl.css?inline'; -import type { ReplStore, ReplUpdateMessage, ReplMessage, ReplAppInput } from './types'; -import { ReplDetailPanel } from './repl-detail-panel'; -import { getReplVersion } from './repl-version'; import { updateReplOutput } from './repl-output-update'; -import { QWIK_PKG_NAME, bundled, getNpmCdnUrl } from './bundled'; -import { isServer } from '@builder.io/qwik'; +import { getReplVersion } from './repl-version'; +import styles from './repl.css?inline'; +import type { ReplAppInput, ReplMessage, ReplStore, ReplUpdateMessage } from './types'; export const Repl = component$((props: ReplProps) => { useStyles$(styles); @@ -27,7 +27,10 @@ export const Repl = component$((props: ReplProps) => { clientId: Math.round(Math.random() * Number.MAX_SAFE_INTEGER) .toString(36) .toLowerCase(), - html: '', + htmlResult: { + rawHtml: '', + prettyHtml: '', + }, transformedModules: [], clientBundles: [], ssrModules: [], @@ -79,10 +82,6 @@ export const Repl = component$((props: ReplProps) => { useVisibleTask$( async () => { - if (isServer) { - return; - } - // only run on the client // Get the version asap, most likely it will be cached. const v = await getReplVersion(input.version, true); store.versions = v.versions; @@ -169,9 +168,14 @@ const getDependencies = (input: ReplAppInput) => { if (input.version !== 'bundled') { const [M, m, p] = input.version.split('-')[0].split('.').map(Number); const prefix = M > 1 || (M == 1 && (m > 7 || (m == 7 && p >= 2))) ? '/dist/' : '/'; - out[QWIK_PKG_NAME] = { - version: input.version, - }; + // we must always provide the qwik.dev package so the worker can find the version + out[QWIK_PKG_NAME] = { version: input.version }; + let bundles; + if (M < 2) { + bundles = out[QWIK_PKG_NAME_V1] = { version: input.version }; + } else { + bundles = out[QWIK_PKG_NAME]; + } for (const p of [ `${prefix}core.cjs`, `${prefix}core.mjs`, @@ -181,7 +185,7 @@ const getDependencies = (input: ReplAppInput) => { `/bindings/qwik.wasm.cjs`, `/bindings/qwik_wasm_bg.wasm`, ]) { - out[QWIK_PKG_NAME][p] = getNpmCdnUrl(bundled, QWIK_PKG_NAME, input.version, p); + bundles[p] = getNpmCdnUrl(bundled, QWIK_PKG_NAME, input.version, p); } } return out; diff --git a/packages/docs/src/repl/types.ts b/packages/docs/src/repl/types.ts index 11768f1cc4a..fa032c7761f 100644 --- a/packages/docs/src/repl/types.ts +++ b/packages/docs/src/repl/types.ts @@ -1,10 +1,10 @@ -import type { NoSerialize, Signal } from '@builder.io/qwik'; +import type { NoSerialize, Signal } from '@qwik.dev/core'; import type { Diagnostic, QwikManifest, QwikRollupPluginOptions, TransformModule, -} from '@builder.io/qwik/optimizer'; +} from '@qwik.dev/core/optimizer'; export interface ReplAppInput { buildId: number; @@ -27,7 +27,7 @@ export interface ReplInputOptions extends Omit { @@ -44,7 +44,7 @@ export const appBundleSsr = async (options: ReplInputOptions, result: ReplResult const loc = warning.loc; if (loc && loc.file) { diagnostic.file = loc.file; - diagnostic.highlights.push({ + diagnostic.highlights!.push({ startCol: loc.column, endCol: loc.column + 1, startLine: loc.line, diff --git a/packages/docs/src/repl/worker/app-ssr-html.ts b/packages/docs/src/repl/worker/app-ssr-html.ts index 71cfb3df0f7..3b37d63aa60 100644 --- a/packages/docs/src/repl/worker/app-ssr-html.ts +++ b/packages/docs/src/repl/worker/app-ssr-html.ts @@ -1,4 +1,4 @@ -import type { RenderOptions, RenderToStringResult } from '@builder.io/qwik/server'; +import type { RenderOptions, RenderToStringResult } from '@qwik.dev/core/server'; import type { ReplInputOptions, ReplResult } from '../types'; import type { QwikWorkerGlobal } from './repl-service-worker'; @@ -82,7 +82,7 @@ export const appSsrHtml = async (options: ReplInputOptions, cache: Cache, result console.error = error; console.debug = debug; - result.html = ssrResult.html; + result.htmlResult.rawHtml = ssrResult.html; result.events.push({ kind: 'pause', @@ -94,12 +94,12 @@ export const appSsrHtml = async (options: ReplInputOptions, cache: Cache, result if (options.buildMode !== 'production') { try { - const html = await self.prettier?.format(result.html, { + const html = await self.prettier?.format(result.htmlResult.rawHtml, { parser: 'html', plugins: self.prettierPlugins, }); if (html) { - result.html = html; + result.htmlResult.prettyHtml = html; } } catch (e) { console.error(e); diff --git a/packages/docs/src/repl/worker/app-update.ts b/packages/docs/src/repl/worker/app-update.ts index e9f22157d67..b93ec29804a 100644 --- a/packages/docs/src/repl/worker/app-update.ts +++ b/packages/docs/src/repl/worker/app-update.ts @@ -15,7 +15,10 @@ export const appUpdate = async ( type: 'result', clientId, buildId: options.buildId, - html: '', + htmlResult: { + rawHtml: '', + prettyHtml: '', + }, transformedModules: [], clientBundles: [], manifest: undefined, diff --git a/packages/docs/src/repl/worker/repl-constants.ts b/packages/docs/src/repl/worker/repl-constants.ts index 4cf1c064d3a..6bc35d8f9fd 100644 --- a/packages/docs/src/repl/worker/repl-constants.ts +++ b/packages/docs/src/repl/worker/repl-constants.ts @@ -1,4 +1,5 @@ -export const QWIK_PKG_NAME = '@builder.io/qwik'; +export const QWIK_PKG_NAME = '@qwik.dev/core'; +export const QWIK_PKG_NAME_V1 = '@builder.io/qwik'; export const QWIK_REPL_DEPS_CACHE = 'QwikReplDeps'; export const QWIK_REPL_RESULT_CACHE = 'QwikReplResults'; diff --git a/packages/docs/src/repl/worker/repl-dependencies.ts b/packages/docs/src/repl/worker/repl-dependencies.ts index ad2bec490f9..1c42daddb3d 100644 --- a/packages/docs/src/repl/worker/repl-dependencies.ts +++ b/packages/docs/src/repl/worker/repl-dependencies.ts @@ -1,19 +1,26 @@ import type { ReplInputOptions } from '../types'; -import { QWIK_PKG_NAME, QWIK_REPL_DEPS_CACHE } from './repl-constants'; +import { QWIK_PKG_NAME, QWIK_PKG_NAME_V1, QWIK_REPL_DEPS_CACHE } from './repl-constants'; import type { QwikWorkerGlobal } from './repl-service-worker'; let options: ReplInputOptions; let cache: Cache; export const depResponse = async (pkgName: string, pkgPath: string) => { - if (pkgName === QWIK_PKG_NAME && !pkgPath.startsWith('/bindings')) { - const version = options.deps[pkgName].version; + let dep = options.deps[pkgName]; + if (pkgName === QWIK_PKG_NAME) { + const version = dep.version; const [M, m, p] = version.split('-')[0].split('.').map(Number); - if (M > 1 || (M == 1 && (m > 7 || (m == 7 && p >= 2)))) { - pkgPath = `/dist${pkgPath}`; + if (!pkgPath.startsWith('/bindings') && !pkgPath.startsWith('/handlers.mjs')) { + if (M > 1 || (M == 1 && (m > 7 || (m == 7 && p >= 2)))) { + pkgPath = `/dist${pkgPath}`; + } + } + if (version < '2') { + pkgName = QWIK_PKG_NAME_V1; + dep = options.deps[pkgName]; } } - const url = options.deps[pkgName][pkgPath]; + const url = dep[pkgPath]; if (!url) { throw new Error(`No URL given for dep: ${pkgName}${pkgPath}`); } @@ -51,7 +58,7 @@ const _loadDependencies = async (replOptions: ReplInputOptions) => { isServer: true, isBrowser: false, isDev: false, - } as typeof import('@builder.io/qwik/build') as any; + } as typeof self.qwikBuild; const cachedCjsCode = `qwikWasmCjs${realQwikVersion}`; const cachedWasmRsp = `qwikWasmRsp${realQwikVersion}`; @@ -72,27 +79,29 @@ const _loadDependencies = async (replOptions: ReplInputOptions) => { if (!isSameQwikVersion(self.qwikCore?.version)) { await exec(QWIK_PKG_NAME, '/core.cjs'); if (self.qwikCore) { - console.debug(`Loaded @builder.io/qwik: ${self.qwikCore.version}`); + console.debug(`Loaded ${QWIK_PKG_NAME}: ${self.qwikCore.version}`); } else { - throw new Error(`Unable to load @builder.io/qwik ${qwikVersion}`); + throw new Error(`Unable to load ${QWIK_PKG_NAME} ${qwikVersion}`); } } if (!isSameQwikVersion(self.qwikOptimizer?.versions.qwik)) { await exec(QWIK_PKG_NAME, '/optimizer.cjs'); if (self.qwikOptimizer) { - console.debug(`Loaded @builder.io/qwik/optimizer: ${self.qwikOptimizer.versions.qwik}`); + console.debug(`Loaded ${QWIK_PKG_NAME}/optimizer: ${self.qwikOptimizer.versions.qwik}`); } else { - throw new Error(`Unable to load @builder.io/qwik/optimizer ${qwikVersion}`); + throw new Error(`Unable to load ${QWIK_PKG_NAME}/optimizer ${qwikVersion}`); } } if (!isSameQwikVersion(self.qwikServer?.versions.qwik)) { + // clear out the require shim that is version specific + (globalThis as any).require = undefined; await exec(QWIK_PKG_NAME, '/server.cjs'); if (self.qwikServer) { - console.debug(`Loaded @builder.io/qwik/server: ${self.qwikServer.versions.qwik}`); + console.debug(`Loaded ${QWIK_PKG_NAME}/server: ${self.qwikServer.versions.qwik}`); } else { - throw new Error(`Unable to load @builder.io/qwik/server ${qwikVersion}`); + throw new Error(`Unable to load ${QWIK_PKG_NAME}/server ${qwikVersion}`); } } diff --git a/packages/docs/src/repl/worker/repl-messenger.ts b/packages/docs/src/repl/worker/repl-messenger.ts index 98a1f450709..d7c65d658bf 100644 --- a/packages/docs/src/repl/worker/repl-messenger.ts +++ b/packages/docs/src/repl/worker/repl-messenger.ts @@ -3,9 +3,13 @@ import { appUpdate } from './app-update'; export const receiveMessageFromMain = (ev: MessageEvent) => { if (ev.data) { - const msg: ReplMessage = JSON.parse(ev.data); - if (msg.type === 'update') { - appUpdate(ev.source as any as WindowClient, msg.clientId, msg.options); + try { + const msg: ReplMessage = JSON.parse(ev.data); + if (msg.type === 'update') { + appUpdate(ev.source as any as WindowClient, msg.clientId, msg.options); + } + } catch { + // ignore, probably some extension sending non-JSON data } } }; diff --git a/packages/docs/src/repl/worker/repl-plugins.ts b/packages/docs/src/repl/worker/repl-plugins.ts index 3866f685e84..a461f44cc3a 100644 --- a/packages/docs/src/repl/worker/repl-plugins.ts +++ b/packages/docs/src/repl/worker/repl-plugins.ts @@ -1,9 +1,18 @@ +import type { QwikRollupPluginOptions } from '@qwik.dev/core/optimizer'; import type { Plugin } from 'rollup'; -import type { QwikRollupPluginOptions } from '@builder.io/qwik/optimizer'; -import type { QwikWorkerGlobal } from './repl-service-worker'; import type { MinifyOptions } from 'terser'; import type { ReplInputOptions } from '../types'; import { depResponse } from './repl-dependencies'; +import type { QwikWorkerGlobal } from './repl-service-worker'; + +/** + * Use paths that look like the paths ones from node modules. The plugin uses the paths to recognize + * the Qwik packages. + */ +const corePath = '/@qwik.dev/core/dist/core.mjs'; +const handlersPath = '/@qwik.dev/core/handlers.mjs'; +const serverPath = '/@qwik.dev/core/dist/server.mjs'; +const preloaderPath = '/@qwik.dev/core/dist/preloader.mjs'; export const replResolver = (options: ReplInputOptions, buildMode: 'client' | 'ssr'): Plugin => { const srcInputs = options.srcInputs; @@ -19,18 +28,22 @@ export const replResolver = (options: ReplInputOptions, buildMode: 'client' | 's if (!importer) { return id; } - if ( - id === '@builder.io/qwik' || - id === '@builder.io/qwik/jsx-runtime' || - id === '@builder.io/qwik/jsx-dev-runtime' - ) { - return '\0qwikCore'; - } - if (id === '@builder.io/qwik/server') { - return '\0qwikServer'; - } - if (id === '@builder.io/qwik/preloader') { - return '\0qwikPreloader'; + const match = id.match(/(@builder\.io\/qwik|@qwik\.dev\/core)(.*)/); + if (match) { + const pkgPath = match[2]; + if (pkgPath === '/server') { + return serverPath; + } + if (pkgPath === '/preloader') { + return preloaderPath; + } + if (pkgPath === '/handlers.mjs') { + return handlersPath; + } + if (/^(|\/jsx(-dev)?-runtime|\/internal)$/.test(pkgPath)) { + return corePath; + } + console.error(`Unknown package ${id}`, match); } // Simple relative file resolution if (id.startsWith('./')) { @@ -51,29 +64,35 @@ export const replResolver = (options: ReplInputOptions, buildMode: 'client' | 's return input.code; } if (buildMode === 'ssr') { - if (id === '\0qwikCore') { + if (id === corePath || id === handlersPath) { return getRuntimeBundle('qwikCore'); } - if (id === '\0qwikServer') { + if (id === serverPath) { return getRuntimeBundle('qwikServer'); } } - if (id === '\0qwikCore') { + if (id === corePath) { if (options.buildMode === 'production') { - const rsp = await depResponse('@builder.io/qwik', '/core.min.mjs'); + const rsp = await depResponse('@qwik.dev/core', '/core.min.mjs'); if (rsp) { return rsp.text(); } } - const rsp = await depResponse('@builder.io/qwik', '/core.mjs'); + const rsp = await depResponse('@qwik.dev/core', '/core.mjs'); if (rsp) { return rsp.text(); } throw new Error(`Unable to load Qwik core`); } - if (id === '\0qwikPreloader') { - const rsp = await depResponse('@builder.io/qwik', '/preloader.mjs'); + if (id === preloaderPath) { + const rsp = await depResponse('@qwik.dev/core', '/preloader.mjs'); + if (rsp) { + return rsp.text(); + } + } + if (id === handlersPath) { + const rsp = await depResponse('@qwik.dev/core', '/handlers.mjs'); if (rsp) { return rsp.text(); } diff --git a/packages/docs/src/repl/worker/repl-request-handler.ts b/packages/docs/src/repl/worker/repl-request-handler.ts index 87555ce9138..872119fd967 100644 --- a/packages/docs/src/repl/worker/repl-request-handler.ts +++ b/packages/docs/src/repl/worker/repl-request-handler.ts @@ -30,20 +30,6 @@ export const requestHandler = (ev: FetchEvent) => { return htmlRsp; } - // app client modules - // const replEvent: ReplEventMessage = { - // type: 'event', - // clientId, - // event: { - // kind: 'client-module', - // scope: 'network', - // message: [reqUrl.pathname + reqUrl.search], - // start: performance.now(), - // }, - // }; - - // sendMessageToReplServer(replEvent); - return rsp; } @@ -169,5 +155,9 @@ const injectDevHtml = (clientId: string, html?: string) => { }, true); })();`; - return `${html || ''}`; + if (!html) { + return ''; + } + + return html.replace(/<\/body>/i, ``); }; diff --git a/packages/docs/src/repl/worker/repl-server.ts b/packages/docs/src/repl/worker/repl-server.ts index ff447157bb9..cd050c79d96 100644 --- a/packages/docs/src/repl/worker/repl-server.ts +++ b/packages/docs/src/repl/worker/repl-server.ts @@ -81,9 +81,13 @@ export const initReplServer = (win: Window, doc: Document, nav: Navigator) => { return; } if (ev.data) { - const msg: ReplMessage = JSON.parse(ev.data); - if (msg?.type === 'event') { - sendMessageToMain(msg); + try { + const msg: ReplMessage = JSON.parse(ev.data); + if (msg?.type === 'event') { + sendMessageToMain(msg); + } + } catch { + // ignore, probably some extension sending non-JSON data } } }; diff --git a/packages/docs/src/repl/worker/repl-service-worker.ts b/packages/docs/src/repl/worker/repl-service-worker.ts index 051bfae6083..8345bcecabc 100644 --- a/packages/docs/src/repl/worker/repl-service-worker.ts +++ b/packages/docs/src/repl/worker/repl-service-worker.ts @@ -16,10 +16,10 @@ self.oninstall = (ev) => { self.onactivate = () => self.clients.claim(); export interface ReplGlobalApi { - qwikBuild?: typeof import('@builder.io/qwik'); - qwikCore?: typeof import('@builder.io/qwik'); - qwikOptimizer?: typeof import('@builder.io/qwik/optimizer'); - qwikServer?: typeof import('@builder.io/qwik/server'); + qwikBuild?: typeof import('@qwik.dev/core/build'); + qwikCore?: typeof import('@qwik.dev/core'); + qwikOptimizer?: typeof import('@qwik.dev/core/optimizer'); + qwikServer?: typeof import('@qwik.dev/core/server'); prettier?: typeof import('prettier'); prettierPlugins?: any; rollup?: typeof import('rollup'); diff --git a/packages/docs/src/root.tsx b/packages/docs/src/root.tsx index e3c16689546..b3575adf5cc 100644 --- a/packages/docs/src/root.tsx +++ b/packages/docs/src/root.tsx @@ -1,6 +1,6 @@ -import { component$, useContextProvider, useStore } from '@builder.io/qwik'; -import { QwikCityProvider, RouterOutlet, ServiceWorkerRegister } from '@builder.io/qwik-city'; -import { Insights } from '@builder.io/qwik-labs'; +import { component$, useContextProvider, useStore } from '@qwik.dev/core'; +import { Insights } from '@qwik.dev/core/insights'; +import { QwikRouterProvider, RouterOutlet, ServiceWorkerRegister } from '@qwik.dev/router'; import RealMetricsOptimization from './components/real-metrics-optimization/real-metrics-optimization'; import { RouterHead } from './components/router-head/router-head'; import { BUILDER_PUBLIC_API_KEY } from './constants'; @@ -50,7 +50,7 @@ export default component$(() => { useContextProvider(GlobalStore, store); return ( - + ` - ); -}; - -export const onPost: RequestHandler = async ({ parseBody, json }) => { - json(200, { body: await parseBody() }); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/platform/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/platform/index.tsx deleted file mode 100644 index 91f5768e39e..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/platform/index.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async ({ platform, json }) => { - json(200, Object.keys(platform)); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/proxy/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/proxy/index.tsx deleted file mode 100644 index 0335da5e547..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/proxy/index.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import type { RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async ({ send, url }) => { - const response = await fetch( - new URL('/demo/qwikcity/middleware/json/', url) - ); - send(response.status, await response.text()); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/query/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/query/index.tsx deleted file mode 100644 index d2605fe562b..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/query/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async ({ query, json }) => { - const obj: Record = {}; - query.forEach((v, k) => (obj[k] = v)); - json(200, obj); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/redirect/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/redirect/index.tsx deleted file mode 100644 index efeb4f5f415..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/redirect/index.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async ({ redirect, url }) => { - throw redirect( - 308, - new URL('/demo/qwikcity/middleware/status/', url).toString() - ); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/request/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/request/index.tsx deleted file mode 100644 index 73136127718..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/request/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async ({ json, request }) => { - const obj: Record = {}; - request.headers.forEach((v, k) => (obj[k] = v)); - json(200, { headers: obj }); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/send/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/send/index.tsx deleted file mode 100644 index 8de1b0ab5dd..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/send/index.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import type { RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async (requestEvent) => { - const response = new Response('Hello World', { - status: 200, - headers: { - 'Content-Type': 'text/plain', - }, - }); - requestEvent.send(response); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/sharedMap/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/sharedMap/index.tsx deleted file mode 100644 index 08a53d96536..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/sharedMap/index.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { component$ } from '@builder.io/qwik'; -import { - routeLoader$, - type RequestHandler, - type Cookie, -} from '@builder.io/qwik-city'; - -interface User { - username: string; - email: string; -} - -export const onRequest: RequestHandler = async ({ - sharedMap, - cookie, - send, -}) => { - const user = loadUserFromCookie(cookie); - if (user) { - sharedMap.set('user', user); - } else { - throw send(401, 'NOT_AUTHORIZED'); - } -}; - -function loadUserFromCookie(cookie: Cookie): User | null { - // this is where you would check cookie for user. - if (cookie) { - // just return mock user for this demo. - return { - username: `Mock User`, - email: `mock@users.com`, - }; - } else { - return null; - } -} - -export const useUser = routeLoader$(({ sharedMap }) => { - return sharedMap.get('user') as User; -}); - -export default component$(() => { - const log = useUser(); - return ( -
- {log.value.username} ({log.value.email}) -
- ); -}); diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/status/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/status/index.tsx deleted file mode 100644 index 51683374142..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/status/index.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async ({ status, getWritableStream }) => { - status(200); - const stream = getWritableStream(); - const writer = stream.getWriter(); - writer.write(new TextEncoder().encode('Hello World!')); - writer.close(); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/text/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/text/index.tsx deleted file mode 100644 index e3f0599615c..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/text/index.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async ({ text }) => { - text(200, 'Text based response.'); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/throw/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/throw/index.tsx deleted file mode 100644 index 7003894b9ba..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/throw/index.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onRequest: RequestHandler = async ({ next, sharedMap, json }) => { - const log: string[] = []; - sharedMap.set('log', log); - - log.push('onRequest'); - if (isLoggedIn()) { - // normal behavior call next middleware - await next(); - } else { - // If not logged in throw to prevent implicit call to the next middleware. - throw json(404, log); - } -}; - -export const onGet: RequestHandler = async ({ sharedMap }) => { - const log = sharedMap.get('log') as string[]; - log.push('onGET'); -}; - -function isLoggedIn() { - return false; // always return false as mock example -} diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/url/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/url/index.tsx deleted file mode 100644 index 348719931b1..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/url/index.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async ({ url, json }) => { - json(200, { url: url.toString() }); -}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/basePathname/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/basePathname/index.tsx new file mode 100644 index 00000000000..a4ec92faeb8 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/basePathname/index.tsx @@ -0,0 +1,5 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ basePathname, json }) => { + json(200, { basePathname }); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/cacheControl/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/cacheControl/index.tsx new file mode 100644 index 00000000000..6e39c73b58b --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/cacheControl/index.tsx @@ -0,0 +1,12 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ + cacheControl, + headers, + json, +}) => { + cacheControl({ maxAge: 42, public: true }); + const obj: Record = {}; + headers.forEach((value, key) => (obj[key] = value)); + json(200, obj); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/component/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/component/index.tsx new file mode 100644 index 00000000000..8edc31800e4 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/component/index.tsx @@ -0,0 +1,16 @@ +import { type RequestHandler } from '@qwik.dev/router'; +import { component$ } from '@qwik.dev/core'; + +export const onRequest: RequestHandler = async ({ redirect }) => { + if (!isLoggedIn()) { + throw redirect(308, '/login'); + } +}; + +export default component$(() => { + return
You are logged in.
; +}); + +function isLoggedIn() { + return true; // Mock login as true +} diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/cookie/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/cookie/index.tsx new file mode 100644 index 00000000000..0a105bf174e --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/cookie/index.tsx @@ -0,0 +1,8 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ cookie, json }) => { + let count = cookie.get('Qwik.demo.count')?.number() || 0; + count++; + cookie.set('Qwik.demo.count', count); + json(200, { count }); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/env/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/env/index.tsx new file mode 100644 index 00000000000..99ef9228f8c --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/env/index.tsx @@ -0,0 +1,10 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ env, json }) => { + json(200, { + USER: env.get('USER'), + MODE_ENV: env.get('MODE_ENV'), + PATH: env.get('PATH'), + SHELL: env.get('SHELL'), + }); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/error/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/error/index.tsx new file mode 100644 index 00000000000..e20f8a1dd67 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/error/index.tsx @@ -0,0 +1,5 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ error }) => { + throw error(500, 'ERROR: Demonstration of an error response.'); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/exit/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/exit/index.tsx new file mode 100644 index 00000000000..ecf407e58b7 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/exit/index.tsx @@ -0,0 +1,5 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ exit }) => { + throw exit(); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/getWritableStream/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/getWritableStream/index.tsx new file mode 100644 index 00000000000..af1ee620c5f --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/getWritableStream/index.tsx @@ -0,0 +1,18 @@ +import type { RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async (requestEvent) => { + const writableStream = requestEvent.getWritableStream(); + const writer = writableStream.getWriter(); + const encoder = new TextEncoder(); + + writer.write(encoder.encode('Hello World\n')); + await wait(100); + writer.write(encoder.encode('After 100ms\n')); + await wait(100); + writer.write(encoder.encode('After 200ms\n')); + await wait(100); + writer.write(encoder.encode('END')); + writer.close(); +}; + +const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/headerSent/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/headerSent/index.tsx new file mode 100644 index 00000000000..2dec941ffd7 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/headerSent/index.tsx @@ -0,0 +1,11 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ headersSent, json }) => { + if (!headersSent) { + json(200, { response: 'default response' }); + } +}; + +export const onRequest: RequestHandler = async ({ status }) => { + status(200); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/headers/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/headers/index.tsx new file mode 100644 index 00000000000..904ae0484ef --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/headers/index.tsx @@ -0,0 +1,8 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ headers, json }) => { + headers.set('X-SRF-TOKEN', Math.random().toString(36).replace('0.', '')); + const obj: Record = {}; + headers.forEach((value, key) => (obj[key] = value)); + json(200, obj); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/html/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/html/index.tsx new file mode 100644 index 00000000000..13d84d6861f --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/html/index.tsx @@ -0,0 +1,13 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ html }) => { + html( + 200, + ` + + +

HTML response

+ + ` + ); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/json/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/json/index.tsx new file mode 100644 index 00000000000..82cf1e77444 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/json/index.tsx @@ -0,0 +1,5 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ json }) => { + json(200, { hello: 'world' }); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/layout.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/layout.tsx new file mode 100644 index 00000000000..d097368e807 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/layout.tsx @@ -0,0 +1,20 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onRequest: RequestHandler = async ({ next }) => { + try { + await next(); + } catch (error: any) { + if (error?.message === 'ERROR: Demonstration of an error response.') { + return await next(); + } else if ( + error && + typeof error === 'object' && + 'message' in error && + typeof error.message === 'string' + ) { + // ignore this error + return; + } + throw error; + } +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/locale/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/locale/index.tsx new file mode 100644 index 00000000000..574cdd5a1ad --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/locale/index.tsx @@ -0,0 +1,12 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onRequest: RequestHandler = async ({ locale, request }) => { + const acceptLanguage = request.headers.get('accept-language'); + const [languages] = acceptLanguage?.split(';') || ['?', '?']; + const [preferredLanguage] = languages.split(','); + locale(preferredLanguage); +}; + +export const onGet: RequestHandler = async ({ locale, json }) => { + json(200, { locale: locale() }); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/method/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/method/index.tsx new file mode 100644 index 00000000000..b4a09f6b0f5 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/method/index.tsx @@ -0,0 +1,5 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onRequest: RequestHandler = async ({ method, json }) => { + json(200, { method }); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/next/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/next/index.tsx new file mode 100644 index 00000000000..5d5256d5725 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/next/index.tsx @@ -0,0 +1,24 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +// Generic function `onRequest` is executed first +export const onRequest: RequestHandler = async ({ next, sharedMap, json }) => { + const log: string[] = []; + sharedMap.set('log', log); + + log.push('onRequest start'); + await next(); // Execute next middleware function (onGet) + log.push('onRequest end'); + + json(200, log); +}; + +// Specific functions such as `onGet` are executed next +export const onGet: RequestHandler = async ({ next, sharedMap }) => { + const log = sharedMap.get('log') as string[]; + + log.push('onGET start'); + // execute next middleware function + // (in our case, there are no more middleware functions nor components.) + await next(); + log.push('onGET end'); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/params/[myId]/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/params/[myId]/index.tsx new file mode 100644 index 00000000000..ae3f4d0f05d --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/params/[myId]/index.tsx @@ -0,0 +1,5 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ params, json }) => { + json(200, { params }); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/parseBody/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/parseBody/index.tsx new file mode 100644 index 00000000000..5f8b46ec518 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/parseBody/index.tsx @@ -0,0 +1,17 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ html }) => { + html( + 200, + ` +
+ + +
+ ` + ); +}; + +export const onPost: RequestHandler = async ({ parseBody, json }) => { + json(200, { body: await parseBody() }); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/platform/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/platform/index.tsx new file mode 100644 index 00000000000..6a48f0031df --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/platform/index.tsx @@ -0,0 +1,5 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ platform, json }) => { + json(200, Object.keys(platform)); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/proxy/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/proxy/index.tsx new file mode 100644 index 00000000000..d970131f804 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/proxy/index.tsx @@ -0,0 +1,8 @@ +import type { RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ send, url }) => { + const response = await fetch( + new URL('/demo/qwikrouter/middleware/json/', url) + ); + send(response.status, await response.text()); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/query/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/query/index.tsx new file mode 100644 index 00000000000..dfdade351bf --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/query/index.tsx @@ -0,0 +1,7 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ query, json }) => { + const obj: Record = {}; + query.forEach((v, k) => (obj[k] = v)); + json(200, obj); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/redirect/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/redirect/index.tsx new file mode 100644 index 00000000000..1e3027e40c0 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/redirect/index.tsx @@ -0,0 +1,8 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ redirect, url }) => { + throw redirect( + 308, + new URL('/demo/qwikrouter/middleware/status/', url).toString() + ); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/request/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/request/index.tsx new file mode 100644 index 00000000000..abad06db8c2 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/request/index.tsx @@ -0,0 +1,7 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ json, request }) => { + const obj: Record = {}; + request.headers.forEach((v, k) => (obj[k] = v)); + json(200, { headers: obj }); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/send/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/send/index.tsx new file mode 100644 index 00000000000..4079702dcf1 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/send/index.tsx @@ -0,0 +1,11 @@ +import type { RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async (requestEvent) => { + const response = new Response('Hello World', { + status: 200, + headers: { + 'Content-Type': 'text/plain', + }, + }); + requestEvent.send(response); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/sharedMap/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/sharedMap/index.tsx new file mode 100644 index 00000000000..e820fe05648 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/sharedMap/index.tsx @@ -0,0 +1,50 @@ +import { + routeLoader$, + type Cookie, + type RequestHandler, +} from '@qwik.dev/router'; +import { component$ } from '@qwik.dev/core'; + +interface User { + username: string; + email: string; +} + +export const onRequest: RequestHandler = async ({ + sharedMap, + cookie, + send, +}) => { + const user = loadUserFromCookie(cookie); + if (user) { + sharedMap.set('user', user); + } else { + throw send(401, 'NOT_AUTHORIZED'); + } +}; + +function loadUserFromCookie(cookie: Cookie): User | null { + // this is where you would check cookie for user. + if (cookie) { + // just return mock user for this demo. + return { + username: `Mock User`, + email: `mock@users.com`, + }; + } else { + return null; + } +} + +export const useUser = routeLoader$(({ sharedMap }) => { + return sharedMap.get('user') as User; +}); + +export default component$(() => { + const log = useUser(); + return ( +
+ {log.value.username} ({log.value.email}) +
+ ); +}); diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/status/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/status/index.tsx new file mode 100644 index 00000000000..b44adf3edae --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/status/index.tsx @@ -0,0 +1,9 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ status, getWritableStream }) => { + status(200); + const stream = getWritableStream(); + const writer = stream.getWriter(); + writer.write(new TextEncoder().encode('Hello World!')); + writer.close(); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/text/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/text/index.tsx new file mode 100644 index 00000000000..ae387d835c5 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/text/index.tsx @@ -0,0 +1,5 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ text }) => { + text(200, 'Text based response.'); +}; diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/throw/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/throw/index.tsx new file mode 100644 index 00000000000..9a85cd6f174 --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/throw/index.tsx @@ -0,0 +1,24 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onRequest: RequestHandler = async ({ next, sharedMap, json }) => { + const log: string[] = []; + sharedMap.set('log', log); + + log.push('onRequest'); + if (isLoggedIn()) { + // normal behavior call next middleware + await next(); + } else { + // If not logged in throw to prevent implicit call to the next middleware. + throw json(404, log); + } +}; + +export const onGet: RequestHandler = async ({ sharedMap }) => { + const log = sharedMap.get('log') as string[]; + log.push('onGET'); +}; + +function isLoggedIn() { + return false; // always return false as mock example +} diff --git a/packages/docs/src/routes/demo/qwikrouter/middleware/url/index.tsx b/packages/docs/src/routes/demo/qwikrouter/middleware/url/index.tsx new file mode 100644 index 00000000000..c34581121ab --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/url/index.tsx @@ -0,0 +1,5 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onGet: RequestHandler = async ({ url, json }) => { + json(200, { url: url.toString() }); +}; diff --git a/packages/docs/src/routes/demo/react/children/index.tsx b/packages/docs/src/routes/demo/react/children/index.tsx index 2aaaa205fcc..67ff173fe75 100644 --- a/packages/docs/src/routes/demo/react/children/index.tsx +++ b/packages/docs/src/routes/demo/react/children/index.tsx @@ -1,4 +1,4 @@ -import { component$, useSignal } from '@builder.io/qwik'; +import { component$, useSignal } from '@qwik.dev/core'; import { QFrame } from './react'; export default component$(() => { diff --git a/packages/docs/src/routes/demo/react/children/react.tsx b/packages/docs/src/routes/demo/react/children/react.tsx index 40597267175..4cf1d252040 100644 --- a/packages/docs/src/routes/demo/react/children/react.tsx +++ b/packages/docs/src/routes/demo/react/children/react.tsx @@ -1,7 +1,7 @@ /** @jsxImportSource react */ import { type ReactNode } from 'react'; -import { qwikify$ } from '@builder.io/qwik-react'; +import { qwikify$ } from '@qwik.dev/react'; function Frame({ children }: { children?: ReactNode[] }) { console.log('React Render'); diff --git a/packages/docs/src/routes/demo/react/counter-simple-hover/index.tsx b/packages/docs/src/routes/demo/react/counter-simple-hover/index.tsx index 317e0e00913..75fb77414ab 100644 --- a/packages/docs/src/routes/demo/react/counter-simple-hover/index.tsx +++ b/packages/docs/src/routes/demo/react/counter-simple-hover/index.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; import { QCounter } from './react'; export default component$(() => { diff --git a/packages/docs/src/routes/demo/react/counter-simple-hover/react.tsx b/packages/docs/src/routes/demo/react/counter-simple-hover/react.tsx index a8b03e8ac8d..a2fbc058710 100644 --- a/packages/docs/src/routes/demo/react/counter-simple-hover/react.tsx +++ b/packages/docs/src/routes/demo/react/counter-simple-hover/react.tsx @@ -1,6 +1,6 @@ /** @jsxImportSource react */ -import { qwikify$ } from '@builder.io/qwik-react'; +import { qwikify$ } from '@qwik.dev/react'; import { useState } from 'react'; // Create React component standard way diff --git a/packages/docs/src/routes/demo/react/counter-simple/index.tsx b/packages/docs/src/routes/demo/react/counter-simple/index.tsx index c408137febf..af560d041a4 100644 --- a/packages/docs/src/routes/demo/react/counter-simple/index.tsx +++ b/packages/docs/src/routes/demo/react/counter-simple/index.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; import { QCounter } from './react'; export default component$(() => { diff --git a/packages/docs/src/routes/demo/react/counter-simple/react.tsx b/packages/docs/src/routes/demo/react/counter-simple/react.tsx index 7b13adec884..c152882c431 100644 --- a/packages/docs/src/routes/demo/react/counter-simple/react.tsx +++ b/packages/docs/src/routes/demo/react/counter-simple/react.tsx @@ -1,5 +1,5 @@ /** @jsxImportSource react */ -import { qwikify$ } from '@builder.io/qwik-react'; +import { qwikify$ } from '@qwik.dev/react'; import { useState } from 'react'; // Create React component standard way diff --git a/packages/docs/src/routes/demo/react/counter-two-islands-host/index.tsx b/packages/docs/src/routes/demo/react/counter-two-islands-host/index.tsx index 397e250f017..6232245f16d 100644 --- a/packages/docs/src/routes/demo/react/counter-two-islands-host/index.tsx +++ b/packages/docs/src/routes/demo/react/counter-two-islands-host/index.tsx @@ -1,4 +1,4 @@ -import { component$, useSignal } from '@builder.io/qwik'; +import { component$, useSignal } from '@qwik.dev/core'; import { QButton, QDisplay } from './react'; export default component$(() => { diff --git a/packages/docs/src/routes/demo/react/counter-two-islands-host/react.tsx b/packages/docs/src/routes/demo/react/counter-two-islands-host/react.tsx index 28c161bc411..ba19893db46 100644 --- a/packages/docs/src/routes/demo/react/counter-two-islands-host/react.tsx +++ b/packages/docs/src/routes/demo/react/counter-two-islands-host/react.tsx @@ -1,6 +1,6 @@ /** @jsxImportSource react */ -import { qwikify$ } from '@builder.io/qwik-react'; +import { qwikify$ } from '@qwik.dev/react'; import { type ReactNode } from 'react'; function Button({ children }: { children?: ReactNode[] }) { diff --git a/packages/docs/src/routes/demo/react/counter-two-islands/index.tsx b/packages/docs/src/routes/demo/react/counter-two-islands/index.tsx index 9b711bcb22f..8995495d4b0 100644 --- a/packages/docs/src/routes/demo/react/counter-two-islands/index.tsx +++ b/packages/docs/src/routes/demo/react/counter-two-islands/index.tsx @@ -1,4 +1,4 @@ -import { component$, useSignal } from '@builder.io/qwik'; +import { component$, useSignal } from '@qwik.dev/core'; import { QButton, QDisplay } from './react'; export default component$(() => { diff --git a/packages/docs/src/routes/demo/react/counter-two-islands/react.tsx b/packages/docs/src/routes/demo/react/counter-two-islands/react.tsx index de18d5bfbf6..87923bfeba1 100644 --- a/packages/docs/src/routes/demo/react/counter-two-islands/react.tsx +++ b/packages/docs/src/routes/demo/react/counter-two-islands/react.tsx @@ -1,6 +1,6 @@ /** @jsxImportSource react */ -import { qwikify$ } from '@builder.io/qwik-react'; +import { qwikify$ } from '@qwik.dev/react'; function Button({ onClick }: { onClick: () => void }) { console.log('React
+ + + + +
+ serializer-signal-usage + Ensure signals used in update() are also used in deserialize() +
+
+ + ✅ + + @@ -383,7 +411,7 @@ export const Counter = (() => {
```tsx {1,4} /print/#a /$((msg: string)/#b) -import { component$, useTask$, $ } from '@builder.io/qwik'; +import { component$, useTask$, $ } from '@qwik.dev/core'; export const HelloWorld = component$(() => { const print = $((msg: string) => { @@ -402,7 +430,7 @@ export const HelloWorld = component$(() => {
```tsx {1,4} /print/#a /(msg: string)/#b) -import { component$, useTask$ } from '@builder.io/qwik'; +import { component$, useTask$ } from '@qwik.dev/core'; export const HelloWorld = component$(() => { const print = (msg: string) => { @@ -424,7 +452,7 @@ export const HelloWorld = component$(() => {
```tsx {1} /click/#a -import { component$, $ } from '@builder.io/qwik'; +import { component$, $ } from '@qwik.dev/core'; export const HelloWorld = component$(() => { const click = $(() => console.log()); @@ -438,7 +466,7 @@ export const HelloWorld = component$(() => {
```tsx {1} /click/#a -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const HelloWorld = component$(() => { const click = () => console.log(); @@ -455,7 +483,7 @@ export const HelloWorld = component$(() => {
```tsx {4} /person/#a -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const HelloWorld = component$(() => { const person = { name: 'Bob' }; @@ -474,7 +502,7 @@ export const HelloWorld = component$(() => {
```tsx {4} /personName/#a -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const HelloWorld = component$(() => { let personName = 'Bob'; @@ -504,7 +532,7 @@ export const HelloWorld = component$(() => {
```tsx {3} /routeLoader$/#a title="src/routes/product/[productId]/index.tsx" -import { routeLoader$ } from '@builder.io/qwik-city'; +import { routeLoader$ } from '@qwik.dev/router'; export const useProductDetails = routeLoader$(async (requestEvent) => { const res = await fetch(`https://.../products/${requestEvent.params.productId}`); @@ -517,7 +545,7 @@ export const useProductDetails = routeLoader$(async (requestEvent) => {
```tsx {3} /routeLoader$/#a title="src/components/product/product.tsx" -import { routeLoader$ } from '@builder.io/qwik-city'; +import { routeLoader$ } from '@qwik.dev/router'; export const useProductDetails = routeLoader$(async (requestEvent) => { const res = await fetch(`https://.../products/${requestEvent.params.productId}`); @@ -533,7 +561,7 @@ export const useProductDetails = routeLoader$(async (requestEvent) => {
```tsx {3} /export/#a -import { routeLoader$ } from '@builder.io/qwik-city'; +import { routeLoader$ } from '@qwik.dev/router'; export const useProductDetails = routeLoader$(async (requestEvent) => { const res = await fetch(`https://.../products/${requestEvent.params.productId}`); @@ -546,7 +574,7 @@ export const useProductDetails = routeLoader$(async (requestEvent) => {
```tsx {3} -import { routeLoader$ } from '@builder.io/qwik-city'; +import { routeLoader$ } from '@qwik.dev/router'; const useProductDetails = routeLoader$(async (requestEvent) => { const res = await fetch(`https://.../products/${requestEvent.params.productId}`); @@ -562,7 +590,7 @@ const useProductDetails = routeLoader$(async (requestEvent) => {
```tsx {3} /use/#a -import { routeLoader$ } from '@builder.io/qwik-city'; +import { routeLoader$ } from '@qwik.dev/router'; export const useProductDetails = routeLoader$(async (requestEvent) => { const res = await fetch(`https://.../products/${requestEvent.params.productId}`); @@ -575,7 +603,7 @@ export const useProductDetails = routeLoader$(async (requestEvent) => {
```tsx {3} /get/#a -import { routeLoader$ } from '@builder.io/qwik-city'; +import { routeLoader$ } from '@qwik.dev/router'; export const getProductDetails = routeLoader$(async (requestEvent) => { const res = await fetch(`https://.../products/${requestEvent.params.productId}`); @@ -591,7 +619,7 @@ export const getProductDetails = routeLoader$(async (requestEvent) => {
```tsx {3} /=>/#a -import { routeLoader$ } from '@builder.io/qwik-city'; +import { routeLoader$ } from '@qwik.dev/router'; export const useProductDetails = routeLoader$(async (requestEvent) => { const res = await fetch(`https://.../products/${requestEvent.params.productId}`); @@ -604,7 +632,7 @@ export const useProductDetails = routeLoader$(async (requestEvent) => {
```tsx {9} /fetcher/#a -import { routeLoader$ } from '@builder.io/qwik-city'; +import { routeLoader$ } from '@qwik.dev/router'; async function fetcher() { const res = await fetch(`https://.../products/${requestEvent.params.productId}`); @@ -655,7 +683,7 @@ export const useProductDetails = routeLoader$(fetcher);
```tsx {7-10,15,16} /class/#a -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; import styles from './MyComponent.module.css'; export default component$((props) => { @@ -679,7 +707,7 @@ export default component$((props) => {
```tsx {2,7-13} /classnames/#a -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; import classnames from 'classnames'; import styles from './MyComponent.module.css'; @@ -735,7 +763,7 @@ export default component$((props) => {
```tsx {13} /key=/#a -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const Person = component$(() => { const person = { @@ -758,7 +786,7 @@ export const Person = component$(() => {
```tsx {13} -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const Person = component$(() => { const person = { @@ -784,7 +812,7 @@ export const Person = component$(() => {
```tsx {14} /Fragment/#a -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; import Card from './Card'; import Summary from './Summary'; @@ -810,7 +838,7 @@ export const Person = component$(() => {
```tsx {14} -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; import Card from './Card'; import Summary from './Summary'; @@ -839,7 +867,7 @@ export const Person = component$(() => {
```tsx {9} /key=/#a -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const ColorList = component$(() => { const colors = ['red', 'green', 'blue']; @@ -858,7 +886,7 @@ export const ColorList = component$(() => {
```tsx {9} -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const ColorList = component$(() => { const colors = ['red', 'green', 'blue']; @@ -880,7 +908,7 @@ export const ColorList = component$(() => {
```tsx {8,11} /Fragment/#a -import { component$, Fragment } from '@builder.io/qwik'; +import { component$, Fragment } from '@qwik.dev/core'; export const ColorList = component$(() => { const colors = ['red', 'green', 'blue']; @@ -900,7 +928,7 @@ export const ColorList = component$(() => {
```tsx {8,11} -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const ColorList = component$(() => { const colors = ['red', 'green', 'blue']; @@ -923,7 +951,7 @@ export const ColorList = component$(() => {
```tsx {9} /key=/#a -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const ColorList = component$(() => { const colors = ['red', 'green', 'blue']; @@ -942,7 +970,7 @@ export const ColorList = component$(() => {
```tsx {9} /key=/#a /not-a-good-idea/#b -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const ColorList = component$(() => { const colors = ['red', 'green', 'blue']; @@ -972,8 +1000,8 @@ export const ColorList = component$(() => {
```tsx {4,12} /serverGreeter/#a -import { $, component$ } from '@builder.io/qwik'; -import { server$ } from '@builder.io/qwik-city'; +import { component$ } from '@qwik.dev/core'; +import { server$ } from '@qwik.dev/router'; const serverGreeter = server$((firstName: string, lastName: string) => { const greeting = `Hello ${firstName} ${lastName}`; @@ -982,10 +1010,10 @@ const serverGreeter = server$((firstName: string, lastName: string) => { export default component$(() => ( @@ -997,8 +1025,8 @@ export default component$(() => (
```tsx {4,12} /serverGreeter/#a -import { component$ } from '@builder.io/qwik'; -import { server$ } from '@builder.io/qwik-city'; +import { component$ } from '@qwik.dev/core'; +import { server$ } from '@qwik.dev/router'; const serverGreeter = server$((firstName: string, lastName: string) => { const greeting = `Hello ${firstName} ${lastName}`; @@ -1086,5 +1114,61 @@ import Image from '~/media/image.png';
+ +
+

serializer-signal-usage

+ Ensure signals used in update() are also used in deserialize() + +

serializerSignalMismatch

+

Examples of correct code for this rule:

+
+ +```tsx /countSignal/#a +import { useSignal, useSerializer$ } from '@qwik.dev/core'; +import MyClass from './my-class'; + +export default component$(() => { + const countSignal = useSignal(0); + + useSerializer$(() => ({ + deserialize: () => new MyClass(countSignal.value), + update: (myClass) => { + myClass.count = countSignal.value; + return myClass; + } + })); + + return
{myClass.count}
; +}); +``` +
+

Examples of incorrect code for this rule:

+
+ +```tsx /countSignal/#a +import { useSignal, useSerializer$ } from '@qwik.dev/core'; +import MyClass from './my-class'; + +export default component$(() => { + const countSignal = useSignal(0); + + useSerializer$(() => ({ + deserialize: (count) => new MyClass(count), + initial: 2, + update: (myClass) => { + myClass.count = countSignal.value; + return myClass; + } + })); + + return
{myClass.count}
; +}); +``` +

The countSignal is used in update() but not in deserialize()

+
+ + +
+
\ No newline at end of file diff --git a/packages/docs/src/routes/docs/(qwik)/advanced/library/index.mdx b/packages/docs/src/routes/docs/(qwik)/advanced/library/index.mdx index dcfa74a078d..87a5ae2f0f1 100644 --- a/packages/docs/src/routes/docs/(qwik)/advanced/library/index.mdx +++ b/packages/docs/src/routes/docs/(qwik)/advanced/library/index.mdx @@ -57,10 +57,10 @@ This will create a new folder called `my-library` with the following structure: │   ├── index.ts │   └── root.tsx ├── tsconfig.json -└── vite.config.ts +└── vite.config.mts ``` -The most important files of a library are a properly configured `package.json` and `vite.config.ts`. +The most important files of a library are a properly configured `package.json` and `vite.config.mts`. ## package.json @@ -91,11 +91,11 @@ Notice the `qwik` field, this is the entry point for the Qwik Optimizer, it will > The file must be called with the `.qwik.mjs` extension, otherwise the Qwik Optimizer will not recognize it. -## vite.config.ts +## vite.config.mts ```ts {8-12} import { defineConfig } from 'vite'; -import { qwikVite } from '@builder.io/qwik/optimizer'; +import { qwikVite } from '@qwik.dev/core/optimizer'; export default defineConfig(() => { return { @@ -126,7 +126,7 @@ export { Counter } from './components/counter/counter'; ## Libraries are also Apps -The library starter is also a standalone Qwik app (without routing, nor Qwik City), this is the reason why you will find `entry.dev.tsx`, `entry.ssr.tsx` and `root.tsx` files. +The library starter is also a standalone Qwik app (without routing, nor Qwik Router), this is the reason why you will find `entry.dev.tsx`, `entry.ssr.tsx` and `root.tsx` files. Do not worry about them, they won't be part of the final library, but they are useful during development and testing, so you can test your components in a real Qwik app. diff --git a/packages/docs/src/routes/docs/(qwik)/advanced/qrl/index.mdx b/packages/docs/src/routes/docs/(qwik)/advanced/qrl/index.mdx index 7f51e271578..7865e3736e5 100644 --- a/packages/docs/src/routes/docs/(qwik)/advanced/qrl/index.mdx +++ b/packages/docs/src/routes/docs/(qwik)/advanced/qrl/index.mdx @@ -127,7 +127,7 @@ The main thing to note is the `on:click` attribute. This attribute gets read by }; ``` 6. At this point, the execution is handed off from Qwikloader to the lazy-loaded chunk. This is done so that the Qwikloader can be as small as possible as it is inlined into the HTML. -7. `useLexicalScope` is imported from `@builder.io/qwik` and is responsible for retrieving the `count` and `props`. +7. `useLexicalScope` is imported from `@qwik.dev/core` and is responsible for retrieving the `count` and `props`. `const [count, props] = useLexicalScope();` 8. Parse the `` JSON and distribute the deserialized objects per `q:obj` attribute. In our case - `
` gets object with id `123`. This will be the `count` created in the `Counter_onMount` function. diff --git a/packages/docs/src/routes/docs/(qwik)/advanced/vite/index.mdx b/packages/docs/src/routes/docs/(qwik)/advanced/vite/index.mdx index dd92b9f98e7..e9e00150355 100644 --- a/packages/docs/src/routes/docs/(qwik)/advanced/vite/index.mdx +++ b/packages/docs/src/routes/docs/(qwik)/advanced/vite/index.mdx @@ -27,17 +27,17 @@ After scaffolding a new Qwik project, you'll find a `vite.config.js` file in the ## Vite Plugins -Qwik comes with two plugins that make it easy to use Vite with Qwik and Qwik City. +Qwik comes with two plugins that make it easy to use Vite with Qwik and Qwik Router. -```ts title="vite.config.ts" +```ts title="vite.config.mts" import { defineConfig } from 'vite'; -import { qwikCity } from '@builder.io/qwik-city/vite'; -import { qwikVite } from '@builder.io/qwik/optimizer'; +import { qwikRouter } from '@qwik.dev/router/vite'; +import { qwikVite } from '@qwik.dev/core/optimizer'; import tsconfigPaths from 'vite-tsconfig-paths'; export default defineConfig(() => { return { - plugins: [qwikCity(), qwikVite(), tsconfigPaths()], + plugins: [qwikRouter(), qwikVite(), tsconfigPaths()], }; }); ``` @@ -199,9 +199,9 @@ devTools?: { }; ``` -### `qwikCity()` +### `qwikRouter()` -To modify the configuration, you can pass an object to the `qwikCity` function. Possible options are: +To modify the configuration, you can pass an object to the `qwikRouter` function. Possible options are: #### `routesDir` @@ -246,7 +246,7 @@ trailingSlash?: boolean; ```js /** - * Enable or disable MDX plugins included by default in qwik-city. + * Enable or disable MDX plugins included by default in qwik-router. */ mdxPlugins?: MdxPlugins; ``` diff --git a/packages/docs/src/routes/docs/(qwik)/components/context/index.mdx b/packages/docs/src/routes/docs/(qwik)/components/context/index.mdx index da50d4ca22d..21b9d29c1d8 100644 --- a/packages/docs/src/routes/docs/(qwik)/components/context/index.mdx +++ b/packages/docs/src/routes/docs/(qwik)/components/context/index.mdx @@ -24,7 +24,7 @@ import CodeSandbox from '../../../../../components/code-sandbox/index.tsx'; Qwik provides a context API, which solves the problem of props drilling and it is very similar to React's functional `useContext()`. In fact, Qwik's context API is the most efficient way to pass down data to different components, reducing overhead, generating less code, and allowing Qwik to more effectively [treeshake](https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking) unused data. -Qwik's context API is made of 3 methods, importable from `@builder.io/qwik`: +Qwik's context API is made of 3 methods, importable from `@qwik.dev/core`: - [`createContextId(contextName: string): ContextId`](#createcontextid) - [`useContextProvider(ctx: ContextId, value: VALUE): void`](#usecontextprovider) @@ -32,12 +32,12 @@ Qwik's context API is made of 3 methods, importable from `@builder.io/qwik`: ```tsx /createContextId/#a /useContext/#b /useContextProvider/#c -import { type Signal, component$, useSignal } from '@builder.io/qwik'; +import { type Signal, component$, useSignal } from '@qwik.dev/core'; import { useContext, useContextProvider, createContextId, -} from '@builder.io/qwik'; +} from '@qwik.dev/core'; export const ThemeContext = createContextId>( 'docs.theme-context' @@ -79,31 +79,31 @@ export interface GenericType { ... } -export const QwikCityContext = createContextId(name: string): ContextId; +export const QwikRouterContext = createContextId(name: string): ContextId; ``` ### Parameters -- `name`: is a unique string given to `createContextId` as an identifier of the context. This will avoid conflicts when there are multiple contexts. It is advised to use a naming convention like `io.builder.qwik.city`. +- `name`: is a unique string given to `createContextId` as an identifier of the context. This will avoid conflicts when there are multiple contexts. It is advised to use a naming convention like `dev.qwik.router`. ### Returns -Notice that the value returned by `createContextId()` does not hold any state, it is an immutable ID object i.e. `{ id: 'io.builder.qwik.city' }`. It's only used to describe the name and type of the context, like an address or an identifier. Since it doesn't hold any state, it can be initialized as a singleton and exported from a shared module. +Notice that the value returned by `createContextId()` does not hold any state, it is an immutable ID object i.e. `{ id: 'dev.qwik.router' }`. It's only used to describe the name and type of the context, like an address or an identifier. Since it doesn't hold any state, it can be initialized as a singleton and exported from a shared module. ## `useContextProvider()` This method is used to create a Context for a specific component and its descendants, using the `ContextId` as the key identifier of the context. -```tsx {9, 10, 11} /QwikCityContext/#a /PlainArrayContext/#b /AppNameContext/#c title="src/components/Parent.tsx" -import { component$, useStore, useContextProvider } from '@builder.io/qwik'; +```tsx {9, 10, 11} /QwikRouterContext/#a /PlainArrayContext/#b /AppNameContext/#c title="src/components/Parent.tsx" +import { component$, useStore, useContextProvider } from '@qwik.dev/core'; export const Parent = component$(() => { - const qwikCityObject = useStore({ + const qwikRouterObject = useStore({ ... }); - useContextProvider(QwikCityContext, qwikCityObject); + useContextProvider(QwikRouterContext, qwikRouterObject); useContextProvider(PlainArrayContext, [1, 2, 3]) useContextProvider(AppNameContext, "My Qwik App") @@ -128,11 +128,11 @@ export const Parent = component$(() => { This method is used to get the value of `Context` which is **provided** by Parent Component. -```tsx {4,5,6} /useContext/ /QwikCityContext/#a /PlainArrayContext/#b /AppNameContext/#c title="src/components/Children.tsx" -import { component$, useContext } from '@builder.io/qwik'; +```tsx {4,5,6} /useContext/ /QwikRouterContext/#a /PlainArrayContext/#b /AppNameContext/#c title="src/components/Children.tsx" +import { component$, useContext } from '@qwik.dev/core'; export const Children = component$(() => { - const qwikCityObject = useContext(QwikCityContext); + const qwikRouterObject = useContext(QwikRouterContext); const plainArray = useContext(PlainArrayContext); const appName = useContext(AppNameContext); diff --git a/packages/docs/src/routes/docs/(qwik)/components/events/index.mdx b/packages/docs/src/routes/docs/(qwik)/components/events/index.mdx index 7c0cfaf4f29..9d8a0f8aa5b 100644 --- a/packages/docs/src/routes/docs/(qwik)/components/events/index.mdx +++ b/packages/docs/src/routes/docs/(qwik)/components/events/index.mdx @@ -43,7 +43,7 @@ In the following example, the `onClick$` attribute of the `
@@ -88,3 +88,6 @@ Qwik is a new kind of web framework that can deliver instant loading web applica

Qwik delivers sub-second full page loads, even on mobile, by serving pure HTML and executing JavaScript when your users opt-in.

+ + + diff --git a/packages/docs/src/routes/docs/(qwikcity)/action/index.mdx b/packages/docs/src/routes/docs/(qwikcity)/action/index.mdx deleted file mode 100644 index a03601c6e0c..00000000000 --- a/packages/docs/src/routes/docs/(qwikcity)/action/index.mdx +++ /dev/null @@ -1,469 +0,0 @@ ---- -title: RouteAction$ | QwikCity -description: Learn about actions in QwikCity, allowing form submissions, and performing side effects such as writing to a database or sending an email. -contributors: - - manucorporat - - cunzaizhuyi - - forresst - - keuller - - hamatoyogi - - AnthonyPAlicea - - the-r3aper7 - - thejackshelton - - adnanebrahimi - - mhevery - - ulic75 - - CoralWombat - - tzdesign - - igorbabko - - gioboa - - mrhoodz - - VinuB-Dev - - aivarsliepa - - wtlin1228 - - adamdbradley - - gioboa - - jemsco - - tzdesign - - shairez -updated_at: '2023-12-15T11:00:00Z' -created_at: '2023-03-20T23:45:13Z' ---- - -# `routeAction$()` - -`routeAction$()` is used to define functions called actions that execute exclusively on the server, and only when explicitly called. Actions can have side effects such as writing to a database or sending an email, that cannot happen during client-side rendering. This makes them ideal for handling form submissions, performing operations with side effects, and then returning data back to the client/browser where it can be used to update the UI. - -Actions can be declared using `routeAction$()` or `globalAction$()` exported from `@builder.io/qwik-city`. - -```tsx {4,16} /useAddUser/ /firstName/#a /lastName/#b /email/#c title="src/routes/layout.tsx" -import { component$ } from '@builder.io/qwik'; -import { routeAction$, Form } from '@builder.io/qwik-city'; - -export const useAddUser = routeAction$(async (data, requestEvent) => { - // This will only run on the server when the user submits the form (or when the action is called programmatically) - const userID = await db.users.add({ - firstName: data.firstName, - lastName: data.lastName, - }); - return { - success: true, - userID, - }; -}); - -export default component$(() => { - const action = useAddUser(); - - return ( - <> - - - - - - {action.value?.success && ( - // When the action is done successfully, the `action.value` property will contain the return value of the action -

User {action.value.userID} added successfully

- )} - - ); -}); -``` - -> Since actions are not executed during rendering, they can have side effects such as writing to a database, or sending an email. An action only runs when called explicitly. - - -## Using actions with `
` - -The best way to call an action is using the `` component exported in `@builder.io/qwik-city`. - -```tsx title="src/routes/index.tsx" -import { component$ } from '@builder.io/qwik'; -import { routeAction$, Form } from '@builder.io/qwik-city'; - -export const useAddUser = routeAction$(async (user) => { - const userID = await db.users.add(user); - return { - success: true, - userID, - }; -}); - -export default component$(() => { - const action = useAddUser(); - return ( - - - - {action.value?.success &&

User added successfully

} -
- ); -}); -``` - -Under the hood, the `
` component uses a native HTML `` element, so it will work without JavaScript. - -When JS is enabled, the `` component will intercept the form submission and trigger the action in SPA mode. Allowing for a full SPA experience. - -> This is to clarify that the server re-renders the whole page and re-executes everything, so if you have any [routeLoader$](/docs/route-loader/) they will be executed too. - -[Complex forms](/docs/advanced/complex-forms) can be created using dot notation. - -## Using actions programmatically - -Actions can also be triggered programmatically using the `action.submit()` method (i.e. you don't need a `` component). However, you can trigger the action from a button click or any other event, just like you would do with a function. - -```tsx {18} title="src/routes/index.tsx" -import { component$ } from '@builder.io/qwik'; -import { routeAction$ } from '@builder.io/qwik-city'; - -export const useAddUser = routeAction$(async (user) => { - const userID = await db.users.add(user); - return { - success: true, - userID, - }; -}); - -export default component$(() => { - const action = useAddUser(); - return ( -
- - {action.value?.success &&

User added successfully

} -
- ); -}); -``` - -In the example above, the `addUser` action is triggered when the user clicks the button. The `action.submit()` method returns a `Promise` that resolves when the action is done. - -### Uploading files - -When using `` with a file input, the submission will be sent as a `multipart/form-data` request. - -But when using actions programmatically, you can still upload files by passing a `File` object to the `action.submit()` method by creating a `FormData` object and appending the file to it. - -```tsx title="src/routes/index.tsx" - -import { component$ } from '@builder.io/qwik'; -import { routeAction$ } from '@builder.io/qwik-city'; - -export const useUploadFile = routeAction$(async ({file}) => { - // save the file somewhere... - return { - success: true, - }; -}); - -export default component$(() => { - const action = useUploadFile(); - const fileUploadRef = useSignal(); - return ( -
- - - -
- ); -}); - -``` - - - -## Actions with Event Handlers - -The `onSubmitCompleted$` event handler can be used after an action is successfully executed and returns some data. This is useful for performing tasks, such as resetting UI elements or updating the application state, once an action has been completed. - -Here's an example of the `onSubmitCompleted$` handler used to edit an item in a EditForm component of a todo app. - -```tsx title="src/components/EditForm.tsx" -import { component$, type Signal, useSignal } from '@builder.io/qwik'; -import { Form } from '@builder.io/qwik-city'; -import { type ListItem, useEditFromListAction } from '../../routes/index'; - -export interface EditFormProps { - item: listItem; - editingIdSignal: Signal; -} - -const EditForm = component$( - ({ item, editingIdSignal }: EditFormProps) => { - const editAction = useEditFromListAction(); - - return ( -
- { - editingIdSignal.value = ''; - }} - spaReset - > - - {/* Sends item.id with form data on submission. */} - - - - -
- -
-
- ); - } -); - -export default EditForm; -``` - -In this example, `onSubmitCompleted$` is used to reset the editingIdSignal value to an empty string once the form submission is completed successfully. This allows the application to update its state and return to the default view. - -## Validation and type safety - -Qwik comes with built-in support for [Zod](https://zod.dev/), a TypeScript-first schema validation that can be used directly with actions, using the `zod$()` function. - -Actions + [Zod](https://zod.dev/) allows to create type safe forms, where the data is validated server side before the action is executed. - -```tsx {16-20} /firstName/#a /lastName/#b title="src/routes/index.tsx" -import { component$ } from '@builder.io/qwik'; -import { routeAction$, zod$, z, Form } from '@builder.io/qwik-city'; - -export const useAddUser = routeAction$( - async (user) => { - // The "user" is strongly typed: { firstName: string, lastName: string } - const userID = await db.users.add({ - firstName: user.firstName, - lastName: user.lastName, - }); - return { - success: true, - userID, - }; - }, - // Zod schema is used to validate that the FormData includes "firstName" and "lastName" - zod$({ - firstName: z.string(), - lastName: z.string(), - }) -); - -export default component$(() => { - const action = useAddUser(); - return ( - <> -
- - - - {action.value?.failed &&

{action.value.fieldErrors?.firstName}

} - -
- {action.value?.success && ( -

User {action.value.userID} added successfully

- )} - - ); -}); -``` - -When submitting data to a `routeAction()`, the data is validated against the Zod schema. If the data is invalid, the action will put the validation error in the `routeAction.value` property. - -Please refer to the [Zod documentation](https://zod.dev/) for more information on how to use Zod schemas. - -### Advanced event based validation - -The constructor of ```zod$``` can also take a function, as the first argument is zod itself, so you can use this directly to build the schema. -The second parameter is the RequestEvent to construct an event-based zod schema. -Especially in combination with ```refine``` and ```superRefine``` in zod, the only limit is your imagination. - - -```tsx {5-5} /ev/#a title="Advanced event based validation" -export const useAddUser = routeAction$( - async (user) => { - // The "user" is still strongly typed, but firstname - // is now optional: { firstName?: string | undefined, lastName: string } - const userID = await db.users.add({ - firstName: user.firstName, - lastName: user.lastName, - }); - return { - success: true, - userID, - }; - }, - // Zod schema is used to validate that the FormData includes "firstName" and "lastName" - zod$((z, ev) => { - // The first name is optional if the url contains the query parameter "firstname=optional" - const firstName = - ev.url.searchParams.get("firstname") === "optional" - ? z.string().optional() - : z.string().nonempty(); - - return z.object({ - firstName, - lastName: z.string(), - }); - }) -); -``` - -## HTTP request and response - -`routeAction$` and `globalAction$` have access to the `RequestEvent` object which includes information about the current HTTP request and response. - -This allows actions to access the request headers, cookies, url and environment variables within the `routeAction$` function. - -```tsx /requestEvent/ title="src/routes/product/[user]/index.tsx" -import { routeAction$ } from '@builder.io/qwik-city'; - -// The second argument of the action is the `RequestEvent` object -export const useProductRecommendations = routeAction$( - async (_data, requestEvent) => { - console.log('Request headers:', requestEvent.request.headers); - console.log('Request cookies:', requestEvent.cookie); - console.log('Request url:', requestEvent.url); - console.log('Request params:', requestEvent.params); - console.log('MY_ENV_VAR:', requestEvent.env.get('MY_ENV_VAR')); - } -); - -``` - -## Action Failures - -In order to return non-success values, the action must use the `fail()` method. - -```tsx /fail/ -import { routeAction$, zod$, z } from '@builder.io/qwik-city'; - -export const useAddUser = routeAction$( - async (user, { fail }) => { - // `user` is typed { name: string } - const userID = await db.users.add(user); - if (!userID) { - return fail(500, { - message: 'User could not be added', - }); - } - return { - userID, - }; - }, - zod$({ - name: z.string(), - }) -); -``` - -Failures are stored in the `action.value` property, just like the success value. However, the `action.value.failed` property is set to `true` when the action fails. Futhermore, failure messages can be found in the `fieldErrors` object according to properties defined in your Zod schema. - -The `fieldErrors` become a dot notation object. See [Complex forms](/docs/advanced/complex-forms) for more information. - -```tsx -import { component$ } from '@builder.io/qwik'; -import { Form } from '@builder.io/qwik-city'; - -export default component$(() => { - const action = useAddUser(); - return ( -
- - - {action.value?.failed &&

{action.value.fieldErrors.name}

} - {action.value?.userID &&

User added successfully

} -
- ); -}); -``` - -Thanks to Typescript type discrimination, you can use the `action.value.failed` property to discriminate between success and failure. - -## Previous form state - -When an action is triggered, the previous state is stored in the `action.formData` property. This is useful to display a loading state while the action is running. - -```tsx {12} /action.formData/ -import { component$ } from '@builder.io/qwik'; -import { routeAction$, Form, zod$, z } from '@builder.io/qwik-city'; - -export const useAddUser = routeAction$(async (user) => { - // handle action... -}); - -export default component$(() => { - const action = useAddUser(); - return ( -
- - -
- ); -}); -``` - -The `action.formData` is especially useful for retaining user-filled form data even after a page refresh. This enables a seamless SPA experience, even with JS disabled. - -## Route vs Global actions - -Actions can be declared using the `routeAction$()` or `globalAction$()` exported from `@builder.io/qwik-city`, the only difference between the two is that `routeAction$()` is scoped to a route, while `globalAction$()` is globally available across the whole app. - -It's recommended to start with `routeAction$()`. Use `globalAction$()` only when sharing an action across multiple routes, or if you wish to use the action in a component that is not a route. - -### `routeAction$()` - -`routeAction$()` can only be declared inside the `src/routes` folder, in a `layout.tsx` or `index.tsx` file, and they MUST be exported, just like a `routeLoader$()`. Since `routeAction$()`s are only accessible within the route it's declared, they are recommended when the action needs to access some user data, or it's a protected route. Think about it like a "private" action. - -> If you want to manage common reusable routeAction$() it is essential that this function is re-exported from within 'layout.tsx' or 'index.tsx file of the existing route otherwise it will not run or throw exception. For more information [check this section](/docs/(qwikcity)/re-exporting-loaders/index.mdx). - -```tsx title="src/routes/form/index.tsx" -import { routeAction$ } from '@builder.io/qwik-city'; - -export const useChangePassword = routeAction$((data) => { - // ... -}); -``` - -### `globalAction$()` - -`globalAction$()` can be declared anywhere in the `src` folder. Since `globalAction$()` are globally available, they are recommended when the action needs to be shared across multiple routes, or when the action doesn't need to access any user data. For example, a `useLogin` action that logs in a user. Think about it like a "public" action. - -```tsx title="src/components/login/login.tsx" -import { globalAction$ } from '@builder.io/qwik-city'; - -export const useLogin = globalAction$((data) => { - // ... -}); -``` diff --git a/packages/docs/src/routes/docs/(qwikcity)/advanced/content-security-policy/index.mdx b/packages/docs/src/routes/docs/(qwikcity)/advanced/content-security-policy/index.mdx deleted file mode 100644 index 7f61da2335b..00000000000 --- a/packages/docs/src/routes/docs/(qwikcity)/advanced/content-security-policy/index.mdx +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: Content Security Policy | Advanced -description: Learn how to create a content security policy (CSP) to keep your Qwik app safe. -contributors: - - tzdesign - - jordanw66 - - mrhoodz - - the-zimmermann - - hamatoyogi -updated_at: '2023-06-25T19:43:33Z' -created_at: '2023-06-15T11:45:23Z' ---- - -# Content Security Policy - -## What is CSP? - -[Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross-Site Scripting (XSS) and data injection attacks. These attacks are used for everything from data theft, to site defacement, to malware distribution. - -## Steps to integrate - -These steps only work for SSR approach. If you are using the Server Side Generation approach, you don't have an up and running server, so this code will not run during the page request. - -### Add a route plugin - -To add the middleware plugin to your application, simply add a file named ```plugin@your-plugin-name.ts``` to the routes folder. -This file will be loaded with every request, allowing you to add headers, modify the response, and more. - -```bash {3} /plugin@csp\.ts/ title="Add the plugin" -src/ -└── routes/ - ├── plugin@csp.ts # The plugin which runs on every request (route middleware) - ├── contact/ - │ └── index.mdx # https://example.com/contact - ├── about/ - │ └── index.md # https://example.com/about - ├── index.mdx # https://example.com/ - │ - └── layout.tsx # This layout is used for all pages -``` - -#### Example - -> This template provides very permissive backward-compatible defaults. -> It is highly recommended that you customize it to better suit your specific use case. -> As this is an advanced topic, you should take a closer look at [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) or [web.dev](https://web.dev/csp/) to get a better understanding of CSP. -> Please note that in dev mode the Vite scripts have no nonce and will report. For this reason, the example will not add csp in dev mode. - -```typescript title="src/routes/plugin@csp.ts" -import type { RequestHandler } from "@builder.io/qwik-city"; -import { isDev } from "@builder.io/qwik"; - -export const onRequest: RequestHandler = event => { - if (isDev) return; // Will not return CSP headers in dev mode - const nonce = Date.now().toString(36); // Your custom nonce logic here - event.sharedMap.set("@nonce", nonce); - const csp = [ - `default-src 'self' 'unsafe-inline'`, - `font-src 'self'`, - `img-src 'self' 'unsafe-inline' data:`, - `script-src 'self' 'unsafe-inline' https: 'nonce-${nonce}' 'strict-dynamic'`, - `style-src 'self' 'unsafe-inline'`, - `frame-src 'self' 'nonce-${nonce}'`, - `object-src 'none'`, - `base-uri 'self'`, - ]; - - event.headers.set("Content-Security-Policy", csp.join("; ")); -}; -``` - -### Custom scripts - -If you have custom script tags that you need to add the nonce to, you can use the `useServerData` hook to get the nonce from the server and add it to your script tags. - -```tsx {2,5} /nonce/ title="src/components/some-component.tsx" -export default component$(() => { - const nonce = useServerData("nonce"); - return ( -
- -
- ); -}); -``` - - -## Validate your CSP - -There is a great tool to validate your CSP: [https://csp-evaluator.withgoogle.com/](https://csp-evaluator.withgoogle.com/) diff --git a/packages/docs/src/routes/docs/(qwikcity)/advanced/menu/index.mdx b/packages/docs/src/routes/docs/(qwikcity)/advanced/menu/index.mdx deleted file mode 100644 index e54811fc887..00000000000 --- a/packages/docs/src/routes/docs/(qwikcity)/advanced/menu/index.mdx +++ /dev/null @@ -1,138 +0,0 @@ ---- -title: Menu | Advanced -description: How to use menus to define site navigation. -contributors: - - manucorporat - - adamdbradley - - the-r3aper7 - - Oyemade - - mhevery - - nnelgxorz - - jakovljevic-mladen - - cunzaizhuyi - - AnthonyPAlicea - - mrhoodz - - hamatoyogi - - dejurin - - gioboa - - jemsco -updated_at: '2023-06-25T19:43:33Z' -created_at: '2023-03-20T23:45:13Z' ---- - -# Menu - -Menus allow you to describe the site navigation structure in a simple declarative way. Menus come in two steps: - -1. Defining a `menu.md` file that contains the menu structure for the directory it's in. -2. Using the [`useContent()`](/docs/(qwikcity)/api/index.mdx#usecontent) function to retrieve the menu structure in a template for rendering. [Read more here](/docs/(qwikcity)/api/index.mdx#usecontent) - -## File Structure - -First layout files as follows: - -```bash -src/ -└── routes/ - └── some/ - ├── menu.md - ├── layout.tsx - └── path/ - └── index.tsx # https://example.com/some/path -``` - -Navigating to `https://example.com/some/path` activates: - -- `src/routes/some/path/index.tsx`: This component will be used for rendering the page content. -- `src/routes/some/layout.tsx`: This layout will be used to provide content around the `src/routes/some/path/index.tsx`. Internally the layout can use `src/routes/some/menu.md` to render the menus. -- `src/routes/some/menu.md`: This file will be used to declare the menu structure which will be rendered by `src/routes/some/layout.tsx`. - -## Declaring Menu Structure - -Use `menu.md` to declare the menu structure. - -- Use the headings (`#`, `##`, etc..) to define menu depth -- Use the bulleted list (`-`) to define menu items. - -```markdown title="src/route/some/menu.md" -# Docs - -## Getting Started - -- [Introduction](introduction/index.md) - -## Components - -- [Basics](/docs/(qwik)/components/basics/index.mdx) -``` - -## Retrieving Menu Structure - -At runtime, any component can retrieve the menu with [`useContent()`](/docs/(qwikcity)/api/index.mdx#usecontent) hook. The type returned is `ContentMenu`. - -The example above will return: - -```javascript -{ - text: "Docs", - items: [ - { - text: "Getting Started", - items: [ - { - text: "Introduction", - href: "/docs/introduction" - } - ], - }, - { - text: "Components", - items: [ - { - text: "Basics", - href: "/docs/(qwik)/components/basics" - } - ], - }, - ], -} -``` - -## Using `ContentMenu` in a layout - -While [`useContent()`](/docs/(qwikcity)/api/index.mdx#usecontent) can be invoked from any component that is part of the current route, it is typically used in a layout component (or a component used by layout) to render the menu. An example usage is shown here: - -```tsx -import { component$ } from '@builder.io/qwik'; -import { useLocation, useContent } from '@builder.io/qwik-city'; -export default component$(() => { - const { menu } = useContent(); - const { url } = useLocation(); - - return ( -
- ); -}); -``` diff --git a/packages/docs/src/routes/docs/(qwikcity)/advanced/plugins/index.mdx b/packages/docs/src/routes/docs/(qwikcity)/advanced/plugins/index.mdx deleted file mode 100644 index cbd9c0cb352..00000000000 --- a/packages/docs/src/routes/docs/(qwikcity)/advanced/plugins/index.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Qwik Plugins | Qwik City -description: Learn about advanced routing in Qwik City, including 404 page handling, grouped layouts, named layouts, nested layouts, and plugin.ts files. -contributors: - - patrickjs -updated_at: '2024-05-05T16:20:00Z' -created_at: '2024-05-05T16:20:00Z' ---- - -# Qwik Plugins -Qwik plugins, named as `plugin.ts` or `plugin@.ts`, handle incoming requests prior to root layout execution and are located in the `src/routes` directory. Request handlers like `onRequest`, `onGet`, `onPost` in these plugins are called before `server$` functions. For multiple plugins, `plugin.ts` handlers execute first, followed by `plugin@.ts` handlers in alphabetical order. Middleware functions should be defined in `plugin.ts` to ensure execution for all requests. - -### The order of execution of `plugin.ts` files - - If `plugin.ts` file exists and if it has exported request handlers, then they are executed first. - -Then exported request handlers from `plugin@.ts` files are executed in alphabetical order of the file names. For example, `onGet` from `plugin@auth.ts` is executed before `onGet` from `plugin@security.ts` because `auth` is alphabetically before `security`. - -Finally, if a `server$` function exists, it's executed last. - -## Middleware and `server$` - -When using `server$`, it's important to understand how [middleware functions](/docs/middleware/#middleware-function) are executed. Middleware functions defined in `layout` files do not run for `server$` requests. This can lead to confusion, especially when developers expect certain middleware to be executed for both page requests and `server$` requests. - -To ensure that a middleware function runs for both types of requests, it should be defined in the `plugin.ts` file. This ensures that the middleware is executed consistently for all incoming requests, regardless of whether they are normal page requests or `server$` requests. - diff --git a/packages/docs/src/routes/docs/(qwikcity)/advanced/request-handling/index.mdx b/packages/docs/src/routes/docs/(qwikcity)/advanced/request-handling/index.mdx deleted file mode 100644 index 668037865db..00000000000 --- a/packages/docs/src/routes/docs/(qwikcity)/advanced/request-handling/index.mdx +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: Request Handling | Advanced -description: How to handle requests in Qwik City, including REST endpoints, and middlewares. -contributors: - - adamdbradley - - manucorporat - - mhevery - - tzdesign - - mrhoodz - - hamatoyogi - - jemsco -updated_at: '2023-07-01T18:35:24Z' -created_at: '2023-03-20T23:45:13Z' ---- - -# Request Handling - -Each `layout.ts` and `index.ts` file inside the `src/routes` directory has the ability to access the current HTTP request, response, and URL. This allows you to retrieve and modify data, and even respond with custom content. - -Qwik City implements a middleware system based on the hierarchy of the `src/routes` directory. The middleware system is used to handle HTTP requests and responses and is available to pages, layouts, and [endpoints](/docs/(qwikcity)/endpoints/index.mdx). - -Each route can add HTTP request and response handlers, allowing developers to retrieve and modify data. The handlers can also be used by [endpoints](/docs/(qwikcity)/endpoints/index.mdx), which only respond with data rather than a page's HTML. - -This feature enables you to handle any request event, have side effects on the request pipeline, just before you render the component and respond with custom content. It is available to pages, layouts and endpoint routes, but not on regular components. - -## Request and Response Handlers - -On pages, layouts, and [endpoints](/docs/(qwikcity)/endpoints/index.mdx), we can access request data by implementing request handler functions such as `onGet`, `onPost`, `onPut`, etc. These functions are executed according to the [HTTP method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) used for this route. - -Additionally, an `onRequest` function can be used to handle any request method, rather than a specific one, in the form of a [middleware](/docs/(qwikcity)/middleware/index.mdx). For example, if both `onGet` and `onRequest` is provided, for a `GET` request, the `onGet` will be called. However, in this scenario, if a `POST` request method came in, then the `onRequest` handler would be called since an `onPost` was not provided. -The `onRequest` is available as a catch-all to any request methods that do not have a specific method. - -```tsx -import type { RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async ({ params }) => { - // put your DB access here (hard coding data for simplicity) - return { - skuId: params.skuId, - price: 123.45, - description: `Description for ${params.skuId}`, - }; -}; -``` - -## Request Event - -The request handler functions receive a `RequestEvent` argument which has the following properties: - -| Field | Description | -| ---------- | ----------------------------------------------------------------------------- | -| `request` | The request object | -| `response` | The response object, which can be used to set response `headers` and `status` | -| `url` | URL which includes `pathname`, `hostname`, etc. | -| `next` | Next middleware function | -| `abort` | Request abort function | -| `params` | Custom user params found within the URL | -| `cookie` | Get and set cookies. | -| `platform` | Platform data object (useful for Cloudflare, Netlify, etc) | - -### Cookie - -```tsx -interface Cookie { - get: (key: string) => CookieValue | null; - set: (key: string, value: string | number | Record, options?: CookieOptions) => void; - delete: (key: string) => void; - has: (key: string) => boolean; -} -``` - -**get** -Takes a string with the cookie name and returns the `CookieValue`, if present and null if not. - -```tsx -interface CookieValue { - value: string; - json: () => T; - number: () => number; -} -``` - -A cookie value is a simple record with three fields: - -1. `value`: Contains the cookie value as a string -2. `json()`: Runs `JSON.parse()` on the value and returns the result -3. `number()`: Runs `Number()` on the value and returns the result - -**getAll** -Returns an object with all cookies, if any. _This is sometimes required if the names of cookies are unknown and must be parsed through._ - -**set** -Takes a key and value and creates a header that will be appended to the response. Value can be a `string | number | Record` - -As a third argument, you can optionally provide a `CookieOptions` record for setting additional fields. - -```tsx -export interface CookieOptions { - domain?: string; - expires?: Date | string; - httpOnly?: boolean; - maxAge?: number | [number, 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks']; - path?: string; - sameSite?: 'lax' | 'none' | 'strict'; - secure?: boolean; -} -``` - -For more information on these attributes and their values, please refer to [the MDN article on the Set-Cookie header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes). - -**delete** -Appends a header with the provided key to the cookie. The new header will have an expired date in the `expires` field, telling the browsers to remove it. - -```tsx -cookie.delete('my-cookie'); -// equivalent to -cookie.set('my-cookie', 'deleted', new Date(0)); -// or -cookie.set('my-cookie', ''); -``` - -Optionally, you can set the path, sameSite and/or domain when deleting the cookie. If your cookie was created with a path/domain, you must set these fields for the deletion to take effect. - -```tsx -cookie.delete('my-cookie', { domain: 'https://qwik.dev', path: '/docs/' }); -``` - -**has** -A convenience method which returns true or false based on the presence of the provided key in cookie. - -```tsx -cookie.has('my-cookie'); -``` diff --git a/packages/docs/src/routes/docs/(qwikcity)/advanced/routing/index.mdx b/packages/docs/src/routes/docs/(qwikcity)/advanced/routing/index.mdx deleted file mode 100644 index 365669a3baf..00000000000 --- a/packages/docs/src/routes/docs/(qwikcity)/advanced/routing/index.mdx +++ /dev/null @@ -1,265 +0,0 @@ ---- -title: Advanced Routing | Qwik City -description: Learn about advanced routing in Qwik City, including 404 page handling, grouped layouts, named layouts, nested layouts, and plugin.ts files. -contributors: - - manucorporat - - adamdbradley - - cunzaizhuyi - - the-r3aper7 - - mhevery - - jakovljevic-mladen - - vfshera - - thejackshelton - - wtlin1228 - - hamatoyogi - - jemsco - - patrickjs -updated_at: '2023-10-05T21:23:14Z' -created_at: '2023-03-20T23:45:13Z' ---- - -# Advanced Routing - -## 404 Page Handling - -It's possible for any user to visit a URL that doesn't exist on your site. For example, if a user visits `https://example.com/does-not-exist`, then the server should respond with a [404 HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404), and the page should have at least some sort of explanation, rather than just a blank page. - -For any given route, Qwik City can choose how to best handle the 404 response for the user, whether it's with the default 404 page, a custom 404 page, or a dynamically generated 404 page. - -### Default 404 Page - -Rather than showing a blank page, by default Qwik City provides a generic 404 page for any route that isn't handled. The default 404 page is rendered as a fallback when a custom 404 page was not found. We recommend providing a custom 404 page for a better user experience. Including the common header and navigation in a custom 404 page would help the user find the page they're looking for. - -### Custom 404 Page - -Instead of showing the generic (boring) 404 response, it's possible to provide a custom 404 page using the same familiar layouts as the rest of your site. - -To create a custom 404 page, add a `404.tsx` file to the root `src/routes` directory. - -```bash -src/ -└── routes/ - ├── 404.tsx # Custom 404 - ├── layout.tsx # Default layout - └── index.tsx # https://example.com/ -``` - -In the example above, the `404.tsx` page will also use the `layout.tsx` layout, since it is a sibling of the layout in the same directory. - -Additionally, using Qwik City's directory-based routing allows for custom 404 pages to be created at different paths. For example, if `src/routes/account/404.tsx` was also added to the structure, then the custom account 404 page would only be applied to the `/account/*` routes, while all other 404s would use the root `404.tsx` page. - -> Note: During development and in preview mode, the custom 404 pages will not be rendered, but instead the default Qwik City 404 page will show. However, when building the app for production, the custom 404 page will be statically generated as a static `404.html` file. - -```bash -src/ -└── routes/ - ├── account/ - │ └── 404.tsx # Custom Account 404 - │ └── index.tsx # https://example.com/account/ - ├── 404.tsx # Custom 404 - ├── layout.tsx # Default layout - └── index.tsx # https://example.com/ -``` - -It's worth noting that custom 404 pages are statically generated at build time, resulting in a static 404.html file, rather than individually server-side rendered pages. This strategy reduces the load on your HTTP server, avoiding server-side rendering of 404 pages, and thus preserving resources. - -### Dynamic 404 Page - -When rendering a page, the default is to always respond with a [200 HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200), which tells the browser all is good and the route exists. However, it's also possible to handle rendering the page, but manually setting the response status code to something other than 200, such as 404. - -For example, let's say we have a product page with a URL such as `https://example.com/product/abc`. The product page would be handled using `src/routes/product/[id]/index.tsx` directory-based route, and `[id]` is a dynamic param in the URL. - -In this example, `id` is used as a key to load the product data from the database. When the product data is found, great, we'll correctly render data. However, if the product data is not found in the database, we can still handle rendering the page, but instead respond with a 404 HTTP status code. - -```tsx -import { component$ } from '@builder.io/qwik'; -import { routeLoader$ } from '@builder.io/qwik-city'; - -export const useProductLoader = routeLoader$(async ({ params, status }) => { - // Example database call using the id param - // The database could return null if the product is not found - const data = await productDatabase.get(params.id); - - if (!data) { - // Product data was not found - // Set the status code to 404 - status(404); - } - - // return the data (which may be null) - return data; -}); - -export default component$(() => { - // get the product data from the loader - const product = useProductLoader(); - - if (!product.value) { - // no product data found - // so render our own custom product 404 - return

Sorry, looks like we don't have this product.

; - } - - // product data was found, so let's render it - return ( -
-

{product.value.name}

-

{product.value.price}

-

{product.value.description}

-
- ); -}); -``` - -## Grouped Layouts - -Common purpose routes are often placed into directories so they can share layouts, and so related source files are logically grouped next to each other. However, it may be desirable that the directory, which was used to group similar files and share layouts, is excluded from the public-facing URL. This is where "grouped" layouts come in (also referred to as a "pathless" layout route). - -By surrounding any directory name with parentheses, such as `(name)`, then the directory name itself will not be included in the URL pathname. - -For example, let's say an app placed all _account_ routes together in a directory. `/account/` could be dropped from the URL for cleaner, shorter URLs. In the example below, notice that the paths are within the `src/routes/(account)/` directory, but the URL paths exclude `(account)/`. - -```bash -src/ -└── routes/ - └── (account)/ # Notice the parentheses - ├── layout.tsx # Shared account layout - └── profile/ - └── index.tsx # https://example.com/profile - └── settings/ - └── index.tsx # https://example.com/settings -``` - -## Named Layout - -At times related routes need to have drastically different layouts from their siblings. It is possible to define multiple layouts for different sibling routes by using a single default layout and any number of named layouts. The child route can then request a specific named-layout. - -Qwik City defines the convention that layouts are within `src/routes` and the filename starts with `layout`. That's why the default layout is named `layout.tsx`. A named layout also starts with `layout` followed by a dash `-` and a unique name, such as `layout-narrow.tsx`. - -To reference a named layout, the route's `index.tsx` file must be suffixed with `@`. For example, `index@narrow.tsx` would use the `layout-narrow.tsx` layout. - -```bash -src/ -└── routes/ - ├── contact/ - │ └── index@narrow.tsx # https://example.com/contact (Layout: layout-narrow.tsx) - ├── layout.tsx # Default layout - ├── layout-narrow.tsx # Named layout - └── index.tsx # https://example.com/ (Layout: layout.tsx) -``` - -- `https://example.com/` - ``` - ┌──────────────────────────────────────────────────┐ - │ src/routes/layout.tsx │ - │ ┌────────────────────────────────────────────┐ │ - │ │ src/routes/index.tsx │ │ - │ │ │ │ - │ └────────────────────────────────────────────┘ │ - │ │ - └──────────────────────────────────────────────────┘ - ``` -- `https://example.com/contact` - ``` - ┌──────────────────────────────────────────────────┐ - │ src/routes/layout-narrow.tsx │ - │ ┌────────────────────────────────────────────┐ │ - │ │ src/routes/contact/index@narrow.tsx │ │ - │ │ │ │ - │ └────────────────────────────────────────────┘ │ - │ │ - └──────────────────────────────────────────────────┘ - ``` - -## Nested Layout - -Most times it is desirable to nest layouts within each other. A page's content can be nested in numerous wrapping layouts, which is determined by the directory structure. - -```bash -src/ -└── routes/ - ├── layout.tsx # Parent layout - └── about/ - ├── layout.tsx # Child layout - └── index.tsx # https://example.com/about -``` - -In the above example, there are two layouts that apply themselves around the `/about` page component. - -1. `src/routes/layout.tsx` -2. `src/routes/about/layout.tsx` - -In this case, the layouts will be nested within each other on the page. - -``` -┌────────────────────────────────────────────────┐ -│ src/routes/layout.tsx │ -│ ┌──────────────────────────────────────────┐ │ -│ │ src/routes/about/layout.tsx │ │ -│ │ ┌────────────────────────────────────┐ │ │ -│ │ │ src/routes/about/index.tsx │ │ │ -│ │ │ │ │ │ -│ │ └────────────────────────────────────┘ │ │ -│ │ │ │ -│ └──────────────────────────────────────────┘ │ -│ │ -└────────────────────────────────────────────────┘ -``` - -```tsx title="src/routes/layout.tsx" -import { component$, Slot } from '@builder.io/qwik'; - -export default component$(() => { - return ( -
- {/* <== Child layout/route inserted here */} -
- ); -}); -``` - -```tsx title="src/routes/about/layout.tsx" -import { component$, Slot } from '@builder.io/qwik'; - -export default component$(() => { - return ( -
- {/* <== Child layout/route inserted here */} -
- ); -}); -``` - -```tsx title="src/routes/about/index.tsx" -import { component$ } from '@builder.io/qwik'; - -export default component$(() => { - return

About

; -}); -``` - -The above example would render the html: - -```html -
-
-

About

-
-
-``` - -## Plugin with `plugin@.ts` - -`plugin.ts` and `plugin@.ts` files can be created in the root of the `src/routes` directory to handle any incoming request before even the root layout executes. - -You can have multiple `plugin.ts` files, each with a different name. For example, `plugin@auth.ts` and `plugin@security.ts`. The `@` is optional and it's only used for developers to help identify the plugin. - -Requests handlers like `onRequest`, `onGet`, `onPost`, etc. are called before `server$` functions are executed. - -### The order of execution of `plugin.ts` files - - If `plugin.ts` file exists and if it has exported request handlers, then they are executed first. - -Then exported request handlers from `plugin@.ts` files are executed in alphabetical order of the file names. For example, `onGet` from `plugin@auth.ts` is executed before `onGet` from `plugin@security.ts` because `auth` is alphabetically before `security`. - -Finally, if a `server$` function exists, it's executed last. diff --git a/packages/docs/src/routes/docs/(qwikcity)/advanced/sitemaps/index.mdx b/packages/docs/src/routes/docs/(qwikcity)/advanced/sitemaps/index.mdx deleted file mode 100644 index 099a11bb0ab..00000000000 --- a/packages/docs/src/routes/docs/(qwikcity)/advanced/sitemaps/index.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: Generating Sitemaps | Advanced -description: Learn how to generate a sitemap for your site in Qwik City. -contributors: - - adamdbradley - - hbendev - - mrhoodz - - thejackshelton - - hamatoyogi - - devweb13 -updated_at: '2023-07-07T09:31:48Z' -created_at: '2023-04-24T19:40:27Z' ---- - -# Generating Sitemaps - -## Generating Sitemaps in SSG - -By default, when Static Site Generated (SSG) pages are built, a [sitemap](https://en.wikipedia.org/wiki/Sitemaps) is generated for the site. The `sitemap.xml` is automatically generated based on the pages that were built. This means that if you have a page that is not built, it will not be included in the sitemap. - -### Configuration - -The sitemap can be configured using the adapter's vite config file. The example below is configuring the Cloudflare adapter. The default sitemap file path is `sitemap.xml`, but you can use the `sitemapOutFile` option to change the file path. - -```ts - plugins: [ - cloudflarePagesAdapter({ - ssg: { - include: ['/*'], - origin: 'https://qwik.dev', - sitemapOutFile: 'sitemap.xml', - }, - }), - ] -``` - -The `include` option is used to specify which pages should be built, which also adds them to the sitemap. Any pages added to the `exclude` option will also exclude them from the sitemap. - -The `origin` option is used to specify the origin of the site and is used to generate the absolute URLs for the sitemap. - -### robots.txt - -Depending on your site setup, you'll probably want to add a [robots.txt](https://en.wikipedia.org/wiki/Robots.txt) file to your site. This can be done by adding a `robots.txt` file to the `public` directory. Any file in the `public` directory is treated as a static file and deploy alongside the build. The following is an example of a `public/robots.txt` file: - -```bash -User-agent: * -Allow: / - -Sitemap: https:///sitemap.xml -``` - -Note the added `Sitemap` directive to the `robots.txt` file which tells search engines where to find the sitemap for your site. Be sure to replace `` with the hostname of your site. - -## Generating Dynamic Sitemaps in SSR - -In addition to generating sitemaps for Static Site Generation (SSG), you can also generate sitemaps dynamically with Server-Side Rendering (SSR). This is useful if your site has content that is not known at build time or is frequently updated. - -To generate a dynamic sitemap in SSR, you can create a route that serves a `dynamic-sitemap.xml` file based on your site’s routes and other dynamic content. Below is an example of how to set this up. - -### Create a Sitemap Function - -First, create a function that generates the sitemap XML based on the routes you want to include. You can create this function in a file such as `src/routes/dynamic-sitemap.xml/create-sitemap.ts`: - -```typescript -// src/routes/dynamic-sitemap.xml/create-sitemap.ts - -export interface SitemapEntry { - loc: string; - priority: number; -} - -export function createSitemap(entries: SitemapEntry[]) { - const baseUrl = "https://"; - - return ` - -${entries.map( - (entry) => ` - - ${baseUrl}${entry.loc.startsWith("/") ? "" : "/"}${entry.loc} - ${entry.priority} - `, -)} -`.trim(); -} -``` - -### Set Up a Route for the Dynamic Sitemap - -Next, set up a route that will use the sitemap function to generate the sitemap dynamically. Create a file like src/routes/dynamic-sitemap.xml/index.tsx: - -```tsx -// src/routes/dynamic-sitemap.xml/index.tsx - -import type { RequestHandler } from "@builder.io/qwik-city"; -import { routes } from "@qwik-city-plan"; -import { createSitemap } from "./create-sitemap"; - -export const onGet: RequestHandler = (ev) => { - const siteRoutes = routes - .map(([route]) => route as string) - .filter(route => route !== "/"); // Exclude the '/' route - - const sitemap = createSitemap([ - { loc: "/", priority: 1 }, // Manually include the root route - ...siteRoutes.map((route) => ({ - loc: route, - priority: 0.9, // Default priority, adjust as needed - })), - ]); - - const response = new Response(sitemap, { - status: 200, - headers: { "Content-Type": "text/xml" }, - }); - - ev.send(response); -}; -``` - -This route dynamically creates the sitemap XML based on the routes in your Qwik City application. - -### robots.txt - -To ensure that search engines know where to find your dynamic sitemap, you should also add or update your robots.txt file. Add the following line to your robots.txt file, which is typically located in your public directory: - - -```bash -User-agent: * -Allow: / - -# Uncomment the following line and replace with the actual folder name you want to disallow -# Disallow: // - -Sitemap: https:///dynamic-sitemap.xml -``` - -Be sure to replace `` with your actual site URL. - -This setup will dynamically generate and serve a dynamic.sitemap.xml whenever it is requested, keeping it up to date with the latest routes and changes to your site. diff --git a/packages/docs/src/routes/docs/(qwikcity)/api/index.mdx b/packages/docs/src/routes/docs/(qwikcity)/api/index.mdx deleted file mode 100644 index ae99b7d8f02..00000000000 --- a/packages/docs/src/routes/docs/(qwikcity)/api/index.mdx +++ /dev/null @@ -1,492 +0,0 @@ ---- -title: API Reference | Qwik City -description: Qwik City API reference. -contributors: - - manucorporat - - adamdbradley - - the-r3aper7 - - nnelgxorz - - cunzaizhuyi - - jakovljevic-mladen - - barbosajlm - - Eucer - - eltociear - - literalpie - - Mhmdrza - - ulic75 - - mhevery - - jordanw66 - - igorbabko - - mrhoodz - - VinuB-Dev - - billykwok - - julianobrasil - - hamatoyogi - - srapport -updated_at: '2023-10-03T18:53:23Z' -created_at: '2023-03-20T23:45:13Z' ---- - -# API reference - -## `useContent()` - -The [`useContent()`](/docs/(qwikcity)/api/index.mdx#usecontent) function retrieves the nearest content information for the current route. The returned object includes: - -```ts -headings: ContentHeading[] | undefined; -menu: ContentMenu | undefined; -``` - -The `headings` array includes data about a markdown file's `

` to `

` [html heading elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Heading_Elements). - -Menus are contextual data declared with `menu.md` files. See [menus file definition](/docs/(qwikcity)/advanced/menu/index.mdx) for more information on the file format and location. - -## `useDocumentHead()` - -Use the `useDocumentHead()` function to read the document [head metadata](/docs/(qwikcity)/pages/index.mdx#head-export). - -`useDocumentHead()` retrieves a readonly `DocumentHead` object that includes: - -```ts -export interface DocumentHead { - /** - * Represents the `` element of the document. - */ - readonly title?: string; - /** - * Used to manually set meta tags in the head. Additionally, the `data` - * property could be used to set arbitrary data which the `<head>` component - * could later use to generate `<meta>` tags. - */ - readonly meta?: readonly DocumentMeta[]; - /** - * Used to manually append `<link>` elements to the `<head>`. - */ - readonly links?: readonly DocumentLink[]; - /** - * Used to manually append `<style>` elements to the `<head>`. - */ - readonly styles?: readonly DocumentStyle[]; - /** - * Arbitrary object containing custom data. When the document head is created from - * markdown files, the frontmatter attributes that are not recognized as a well-known - * meta names (such as title, description, author, etc...), are stored in this property. - */ - readonly frontmatter?: Readonly<Record<string, any>>; -} -``` - -All starters include a `<RouterHead>` component that is responsible for generating the `<head>` element of the document. It uses the `useDocumentHead()` function to retrieve the current head metadata and render the appropriate `<meta>`, `<link>`, `<style>` and `<title>` elements. - -```tsx title="src/components/router-head/router-head.tsx" -import { component$ } from '@builder.io/qwik'; -import { useDocumentHead } from '@builder.io/qwik-city'; - -/** - * The RouterHead component is placed inside of the document `<head>` element. - */ -export const RouterHead = component$(() => { - const head = useDocumentHead(); - - return ( - <> - <title>{head.title} - - - - - {head.meta.map((m) => ( - - ))} - - {head.links.map((l) => ( - - ))} - - {head.styles.map((s) => ( - - - Hello World - - ` - ); - }); - - test('should render Counter and accept events', async () => { - const { screen, render, userEvent } = await createDOM(); - - await render(); - await expectDOM( - screen, - ` - - - - - 15 - - - - ` - ); - await userEvent('button.decrement', 'click'); - await expectDOM( - screen, - ` - - - - - 10 - - - -` - ); - }); - - test('should render a collection of todo items', async () => { - const { screen, render } = await createDOM(); - - const items = { - items: [ - { - done: true, - title: 'Task 1', - }, - { - done: false, - title: 'Task 2', - }, - ], - }; - await render(); - await delay(0); - await expectDOM( - screen, - ` - - - - - - - Task 1 - - - - - - Task 2 - - - Total: 2 - - - - ` - ); - }); - - test('types work as expected', () => () => { - // Let's keep one of these old type exports around for now. - const Input1 = component$>((props) => { - return ; - }); - - const Input2 = component$((props: PropsOf<'input'>) => { - return ; - }); - - type Input3Props = { - type: 'text' | 'number'; - } & Partial>; - - const Input3 = component$(({ type, ...props }) => { - return ; - }); - - type Input4Props = { - type: 'text' | 'number'; - } & QwikIntrinsicElements['input']; - - const Input4 = component$(({ type, ...props }) => { - return ( -
- -
- ); - }); - - component$(() => { - return ( - <> - - - - - - ); - }); - }); - - test('custom function types should work', () => () => { - type TestProps = PropsOf<'h1'> & { - qrl$?: QRL<() => void>; - }; - const Test1 = component$(({ qrl$, ...props }) => { - return ( - <> -

- Hi 👋 -

- - ); - }); - expectTypeOf().toMatchTypeOf[0]['qrl$']>(); - expectTypeOf[0]['qrl$']>().toEqualTypeOf< - (() => void) | QRL<() => void> | undefined - >(); - - const Test2 = component$(({ qrl$, ...props }: TestProps) => { - return ( - <> -

- Hi 👋 -

- - ); - }); - expectTypeOf().toMatchTypeOf[0]['qrl$']>(); - expectTypeOf[0]['qrl$']>().toEqualTypeOf< - (() => void) | QRL<() => void> | undefined - >(); - component$(() => { - return ( - <> - - - - ); - }); - }); - - test('PropFunction should work', () => () => { - type TestProps = PropsOf<'h1'> & { - test$?: PropFunction<() => void>; - }; - const Test1 = component$(({ test$, ...props }) => { - return ( - <> -

- Hi 👋 -

- - ); - }); - expectTypeOf().toMatchTypeOf[0]['test$']>(); - expectTypeOf void>>().toMatchTypeOf[0]['test$']>(); - }); - - test('Inline Components should be able to use Component', () => () => { - const InlineComponent: Component> = (props) => { - expectTypeOf(props).not.toBeAny(); - return
; - }; - // Passing a plain function should not error - return {}} />; - }); -}); - -///////////////////////////////////////////////////////////////////////////// -export const HelloWorld = component$(() => { - useStylesQrl(inlinedQrl(`{}`, 'named-style')); - return Hello World; -}); - -///////////////////////////////////////////////////////////////////////////// -// - -export const Greeter = component$((props: { salutation?: string; name?: string }) => { - const state = useStore({ count: 0 }); - return ( -
- {' '} - {props.salutation} {props.name} ({state.count}){' '} -
- ); -}); - -////////////////////////////////////////////// -// import { QComponent, component, qView, qHandler, getState, markDirty } from '@builder.io/qwik'; - -// Component view may need additional handlers describing the component's behavior. -export const MyCounter_update = () => { - const [props, state, args] = - useLexicalScope<[PropsOf, { count: number }, { dir: number }]>(); - state.count += args.dir * (props.step || 1); -}; - -// Finally tie it all together into a component. -export const MyCounter = component$((props: { step?: number; value?: number }) => { - const state = useStore({ count: props.value || 0 }); - return ( - - - {state.count} - - - ); -}); - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// - -interface ItemObj { - title: string; - done: boolean; -} - -interface ItemsObj { - items: ItemObj[]; -} - -///////////////////////////////////////////////////////////////////////////// - -export const ItemDetail = component$((props: { itemObj: ItemObj }) => { - // const state = useStore({ editing: false }); - return ( - - - {props.itemObj.title || 'loading...'} - - ); -}); - -///////////////////////////////////////////////////////////////////////////// - -export const Items = component$((props: { items: ItemsObj }) => { - // const state = useStore({ editing: false }); - return ( - - {props.items.items.map((item) => ( - - ))} - Total: {props.items.items.length} - - ); -}); - -function delay(milliseconds: number): Promise { - return new Promise((res) => setTimeout(res, milliseconds)); -} diff --git a/packages/qwik/src/core/container/container.ts b/packages/qwik/src/core/container/container.ts deleted file mode 100644 index d1a403f25e4..00000000000 --- a/packages/qwik/src/core/container/container.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { qError, QError_invalidRefValue } from '../error/error'; -import type { ResourceReturnInternal, SubscriberEffect } from '../use/use-task'; -import { seal } from '../util/qdev'; -import { isFunction } from '../util/types'; -import type { QRL } from '../qrl/qrl.public'; -import { fromKebabToCamelCase } from '../util/case'; -import { QContainerAttr } from '../util/markers'; -import { isElement } from '../util/element'; -import { - createSubscriptionManager, - type SubscriberSignal, - type SubscriptionManager, -} from '../state/common'; -import { isSignal, type Signal, type SignalImpl } from '../state/signal'; -import { directGetAttribute } from '../render/fast-calls'; -import type { QContext } from '../state/context'; -import { isServerPlatform } from '../platform/platform'; - -export type GetObject = (id: string) => any; -export type GetObjID = (obj: any) => string | null; -export type MustGetObjID = (obj: any) => string; - -/** @public */ -export interface SnapshotMetaValue { - w?: string; // q:watches - s?: string; // q:seq - h?: string; // q:host - c?: string; // q:context -} - -/** @public */ -export type SnapshotMeta = Record; - -/** @public */ -export interface SnapshotState { - ctx: SnapshotMeta; - refs: Record; - objs: any[]; - subs: any[]; -} - -/** @public */ -export interface SnapshotListener { - key: string; - qrl: QRL; - el: Element; -} - -/** @public */ -export interface SnapshotResult { - state: SnapshotState; - funcs: string[]; - qrls: QRL[]; - objs: any[]; - resources: ResourceReturnInternal[]; - mode: 'render' | 'listeners' | 'static'; -} - -export type ObjToProxyMap = WeakMap; - -/** @public */ -export interface PauseContext { - getObject: GetObject; - meta: SnapshotMeta; - refs: Record; -} - -/** @public */ -export interface ContainerState { - readonly $containerEl$: Element; - - readonly $proxyMap$: ObjToProxyMap; - $subsManager$: SubscriptionManager; - - readonly $taskNext$: Set; - readonly $taskStaging$: Set; - - readonly $opsNext$: Set; - - readonly $hostsNext$: Set; - readonly $hostsStaging$: Set; - readonly $base$: string; - - $hostsRendering$: Set | undefined; - $renderPromise$: Promise | undefined; - - $serverData$: Record; - $elementIndex$: number; - - $pauseCtx$: PauseContext | undefined; - $styleMoved$: boolean; - readonly $styleIds$: Set; - readonly $events$: Set; - readonly $inlineFns$: Map; -} - -const CONTAINER_STATE = Symbol('ContainerState'); - -/** @internal */ -export const _getContainerState = (containerEl: Element): ContainerState => { - let state = (containerEl as any)[CONTAINER_STATE] as ContainerState; - if (!state) { - (containerEl as any)[CONTAINER_STATE] = state = createContainerState( - containerEl, - directGetAttribute(containerEl, 'q:base') ?? '/' - ); - } - return state; -}; - -export const createContainerState = (containerEl: Element, base: string) => { - const containerAttributes: Record = {}; - if (containerEl) { - const attrs = containerEl.attributes; - if (attrs) { - for (let index = 0; index < attrs.length; index++) { - const attr = attrs[index]; - containerAttributes[attr.name] = attr.value; - } - } - } - const containerState: ContainerState = { - $containerEl$: containerEl, - - $elementIndex$: 0, - $styleMoved$: false, - - $proxyMap$: new WeakMap(), - - $opsNext$: new Set(), - - $taskNext$: new Set(), - $taskStaging$: new Set(), - - $hostsNext$: new Set(), - $hostsStaging$: new Set(), - - $styleIds$: new Set(), - $events$: new Set(), - - $serverData$: { containerAttributes }, - $base$: base, - $renderPromise$: undefined, - $hostsRendering$: undefined, - $pauseCtx$: undefined, - $subsManager$: null as any, - $inlineFns$: new Map(), - }; - seal(containerState); - containerState.$subsManager$ = createSubscriptionManager(containerState); - return containerState; -}; - -export const removeContainerState = (containerEl: Element) => { - delete (containerEl as any)[CONTAINER_STATE]; -}; - -export const setRef = (value: any, elm: Element) => { - if (isFunction(value)) { - return value(elm); - } else if (isSignal(value)) { - if (isServerPlatform()) { - // During SSR, assigning a ref should not cause reactivity because - // the expectation is that the ref is filled in on the client - return ((value as SignalImpl).untrackedValue = elm); - } else { - return ((value as Signal).value = elm); - } - } - throw qError(QError_invalidRefValue, value); -}; - -export const SHOW_ELEMENT = 1; -export const SHOW_COMMENT = 128; -export const FILTER_ACCEPT = 1; -export const FILTER_REJECT = 2; -export const FILTER_SKIP = 3; - -export const isContainer = (el: Node) => { - return isElement(el) && el.hasAttribute(QContainerAttr); -}; - -export const intToStr = (nu: number) => { - return nu.toString(36); -}; - -export const strToInt = (nu: string) => { - return parseInt(nu, 36); -}; - -export const getEventName = (attribute: string) => { - const colonPos = attribute.indexOf(':'); - if (attribute) { - return fromKebabToCamelCase(attribute.slice(colonPos + 1)); - } else { - return attribute; - } -}; - -export interface QContainerElement extends Element { - _qwikjson_?: any; -} diff --git a/packages/qwik/src/core/container/index.html b/packages/qwik/src/core/container/index.html deleted file mode 100644 index 6f355e38dad..00000000000 --- a/packages/qwik/src/core/container/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - Document - - -
-
-
-
-
-
-
-
-
-
- - diff --git a/packages/qwik/src/core/container/pause.ts b/packages/qwik/src/core/container/pause.ts deleted file mode 100644 index e7165fbd4dd..00000000000 --- a/packages/qwik/src/core/container/pause.ts +++ /dev/null @@ -1,995 +0,0 @@ -import { assertDefined, assertElement, assertEqual } from '../error/assert'; -import { getDocument } from '../util/dom'; -import { - isComment, - isDocument, - isElement, - isNode, - isQwikElement, - isText, - isVirtualElement, -} from '../util/element'; -import { logWarn } from '../util/log'; -import { ELEMENT_ID, ELEMENT_ID_PREFIX, QContainerAttr, QScopedStyle } from '../util/markers'; -import { qDev } from '../util/qdev'; - -import { - QError_containerAlreadyPaused, - QError_missingObjectId, - QError_verifySerializable, - qError, -} from '../error/error'; -import { serializeQRLs } from '../qrl/qrl'; -import type { QRL } from '../qrl/qrl.public'; -import { - processVirtualNodes, - type QwikElement, - type VirtualElement, -} from '../render/dom/virtual-element'; -import { directGetAttribute, directSetAttribute } from '../render/fast-calls'; -import { - LocalSubscriptionManager, - fastSkipSerialize, - fastWeakSerialize, - getProxyFlags, - getProxyTarget, - getSubscriptionManager, - isConnected, - serializeSubscription, - type Subscriptions, - type SubscriberSignal, -} from '../state/common'; -import { QObjectImmutable, QObjectRecursive } from '../state/constants'; -import { HOST_FLAG_DYNAMIC, tryGetContext, type QContext } from '../state/context'; -import { groupListeners } from '../state/listeners'; -import { SignalImpl } from '../state/signal'; -import { serializeSStyle } from '../style/qrl-styles'; -import { - TaskFlagsIsDirty, - destroyTask, - isResourceTask, - type ResourceReturnInternal, -} from '../use/use-task'; -import { isNotNullable, isPromise } from '../util/promises'; -import { isArray, isObject, isSerializableObject } from '../util/types'; -import { - FILTER_REJECT, - FILTER_SKIP, - SHOW_COMMENT, - SHOW_ELEMENT, - _getContainerState, - intToStr, - type ContainerState, - type GetObjID, - type SnapshotMeta, - type SnapshotMetaValue, - type SnapshotResult, - createContainerState, -} from './container'; -import { UNDEFINED_PREFIX, collectDeps, serializeValue } from './serializers'; -import { isQrl } from '../qrl/qrl-class'; - -/** @internal */ -export const _serializeData = async (data: any, pureQRL?: boolean) => { - const containerState = createContainerState(null!, null!); - const collector = createCollector(containerState); - collectValue(data, collector, false); - - // Wait for remaining promises - let promises: Promise[]; - while ((promises = collector.$promises$).length > 0) { - collector.$promises$ = []; - const results = await Promise.allSettled(promises); - for (const result of results) { - if (result.status === 'rejected') { - console.error(result.reason); - } - } - } - - const objs = Array.from(collector.$objSet$.keys()); - let count = 0; - - const objToId = new Map(); - for (const obj of objs) { - objToId.set(obj, intToStr(count)); - count++; - } - if (collector.$noSerialize$.length > 0) { - const undefinedID = objToId.get(undefined); - assertDefined(undefinedID, 'undefined ID must be defined'); - for (const obj of collector.$noSerialize$) { - objToId.set(obj, undefinedID); - } - } - - const mustGetObjId = (obj: any): string => { - let suffix = ''; - if (isPromise(obj)) { - const promiseValue = getPromiseValue(obj); - if (!promiseValue) { - throw qError(QError_missingObjectId, obj); - } - obj = promiseValue.value; - if (promiseValue.resolved) { - suffix += '~'; - } else { - suffix += '_'; - } - } - if (isObject(obj)) { - const target = getProxyTarget(obj); - if (target) { - suffix += '!'; - obj = target; - } - } - const key = objToId.get(obj); - if (key === undefined) { - throw qError(QError_missingObjectId, obj); - } - return key + suffix; - }; - - const convertedObjs = serializeObjects(objs, mustGetObjId, null, collector, containerState); - - return JSON.stringify({ - _entry: mustGetObjId(data), - _objs: convertedObjs, - }); -}; - -// -// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#pauseContainer instead) -// -/** This pauses a running container in the browser. It is not used for SSR */ -// TODO(mhevery): this is a remnant when you could have paused on client. Should be deleted. -export const pauseContainer = async ( - elmOrDoc: Element | Document, - defaultParentJSON?: Element -): Promise => { - const doc = getDocument(elmOrDoc); - const documentElement = doc.documentElement; - const containerEl = isDocument(elmOrDoc) ? documentElement : elmOrDoc; - if (directGetAttribute(containerEl, QContainerAttr) === 'paused') { - throw qError(QError_containerAlreadyPaused); - } - const parentJSON = - defaultParentJSON ?? (containerEl === doc.documentElement ? doc.body : containerEl); - - const containerState = _getContainerState(containerEl); - const contexts = getNodesInScope(containerEl, hasContext); - - // Set container to paused - directSetAttribute(containerEl, QContainerAttr, 'paused'); - - // Update elements with context - for (const elCtx of contexts) { - const elm = elCtx.$element$; - const listeners = elCtx.li; - if (elCtx.$scopeIds$) { - const value = serializeSStyle(elCtx.$scopeIds$); - if (value) { - elm.setAttribute(QScopedStyle, value); - } - } - if (elCtx.$id$) { - elm.setAttribute(ELEMENT_ID, elCtx.$id$); - } - if (isElement(elm) && listeners.length > 0) { - const groups = groupListeners(listeners); - for (const listener of groups) { - elm.setAttribute(listener[0], serializeQRLs(listener[1], containerState, elCtx)); - } - } - } - - // Serialize data - const data = await _pauseFromContexts(contexts, containerState, (el) => { - if (isNode(el) && isText(el)) { - return getTextID(el, containerState); - } - return null; - }); - - // Emit Qwik JSON - const qwikJson = doc.createElement('script'); - directSetAttribute(qwikJson, 'type', 'qwik/json'); - qwikJson.textContent = escapeText(JSON.stringify(data.state, undefined, qDev ? ' ' : undefined)); - parentJSON.appendChild(qwikJson); - - // Emit event registration - const extraListeners = Array.from(containerState.$events$, (s) => JSON.stringify(s)); - const eventsScript = doc.createElement('script'); - eventsScript.textContent = `(window.qwikevents||=[]).push(${extraListeners.join(', ')})`; - parentJSON.appendChild(eventsScript); - - return data; -}; - -/** - * Grab all state needed to resume the container later. - * - * @internal - */ -export const _pauseFromContexts = async ( - allContexts: QContext[], - containerState: ContainerState, - fallbackGetObjId?: GetObjID, - textNodes?: Map -): Promise => { - const collector = createCollector(containerState); - textNodes?.forEach((_, key) => { - collector.$seen$.add(key); - }); - let hasListeners = false; - - // Collect resources - // TODO: optimize - for (const ctx of allContexts) { - if (ctx.$tasks$) { - for (const task of ctx.$tasks$) { - if (qDev) { - if (task.$flags$ & TaskFlagsIsDirty) { - logWarn( - `Serializing dirty task. Looks like an internal error. -Task Symbol: ${task.$qrl$.$symbol$} -` - ); - } - if (!isConnected(task)) { - logWarn('Serializing disconnected task. Looks like an internal error.'); - } - } - if (isResourceTask(task)) { - collector.$resources$.push(task.$state$!); - } - destroyTask(task); - } - } - } - - // Find all listeners. They are the "entries" for resuming the container. - // Any lexical scope they reference must be serialized. - for (const ctx of allContexts) { - const el = ctx.$element$; - const ctxListeners = ctx.li; - for (const listener of ctxListeners) { - if (isElement(el)) { - const qrl = listener[1]; - const captured = qrl.$captureRef$; - if (captured) { - for (const obj of captured) { - /** - * Collect the lexical scope used by the listener. This also collects all the - * subscribers of any reactive state in scope, since the listener might change that - * state - */ - collectValue(obj, collector, true); - } - } - collector.$qrls$.push(qrl); - hasListeners = true; - } - } - } - - // No listeners implies static page - if (!hasListeners) { - return { - state: { - refs: {}, - ctx: {}, - objs: [], - subs: [], - }, - objs: [], - funcs: [], - qrls: [], - resources: collector.$resources$, - mode: 'static', - }; - } - - // Wait for remaining promises - let promises: Promise[]; - while ((promises = collector.$promises$).length > 0) { - collector.$promises$ = []; - await Promise.all(promises); - } - - // If at this point any component can render, we need to capture Context and Props - const canRender = collector.$elements$.length > 0; - if (canRender) { - for (const elCtx of collector.$deferElements$) { - collectElementData(elCtx, collector, elCtx.$element$); - } - - for (const ctx of allContexts) { - collectProps(ctx, collector); - } - } - - // Wait for remaining promises - while ((promises = collector.$promises$).length > 0) { - collector.$promises$ = []; - await Promise.all(promises); - } - - // Convert objSet to array - const elementToIndex = new Map(); - const objs = Array.from(collector.$objSet$.keys()); - const objToId = new Map(); - - const getElementID = (el: QwikElement): string | null => { - let id = elementToIndex.get(el); - if (id === undefined) { - id = getQId(el); - if (!id) { - console.warn('Missing ID', el); - } - elementToIndex.set(el, id); - } - return id; - }; - - const getObjId: GetObjID = (obj) => { - let suffix = ''; - if (isPromise(obj)) { - const promiseValue = getPromiseValue(obj); - if (!promiseValue) { - return null; - } - obj = promiseValue.value; - if (promiseValue.resolved) { - suffix += '~'; - } else { - suffix += '_'; - } - } - - if (isObject(obj)) { - const target = getProxyTarget(obj); - if (target) { - suffix += '!'; - obj = target; - } else if (isQwikElement(obj)) { - const elID = getElementID(obj); - if (elID) { - return ELEMENT_ID_PREFIX + elID + suffix; - } - return null; - } - } - const id = objToId.get(obj); - if (id) { - return id + suffix; - } - const textId = textNodes?.get(obj); - if (textId) { - return '*' + textId; - } - if (fallbackGetObjId) { - return fallbackGetObjId(obj); - } - return null; - }; - - const mustGetObjId = (obj: any): string => { - const key = getObjId(obj); - if (key === null) { - // TODO(mhevery): this is a hack as we should never get here. - // This as a workaround for https://github.com/QwikDev/qwik/issues/4979 - if (isQrl(obj)) { - const id = intToStr(objToId.size); - objToId.set(obj, id); - return id; - } else { - throw qError(QError_missingObjectId, obj); - } - } - return key; - }; - - // Compute subscriptions - const subsMap = new Map(); - for (const obj of objs) { - const subs = getManager(obj, containerState)?.$subs$; - if (!subs) { - continue; - } - const flags = getProxyFlags(obj) ?? 0; - const converted: (Subscriptions | number)[] = []; - if (flags & QObjectRecursive) { - converted.push(flags); - } - for (const sub of subs) { - const host = sub[1]; - if (sub[0] === 0 && isNode(host) && isVirtualElement(host)) { - if (!collector.$elements$.includes(tryGetContext(host)!)) { - continue; - } - } - converted.push(sub); - } - if (converted.length > 0) { - subsMap.set(obj, converted); - } - } - - // Sort objects: the ones with subscriptions go first - objs.sort((a, b) => { - const isProxyA = subsMap.has(a) ? 0 : 1; - const isProxyB = subsMap.has(b) ? 0 : 1; - return isProxyA - isProxyB; - }); - - // Generate object ID by using a monotonic counter - let count = 0; - for (const obj of objs) { - objToId.set(obj, intToStr(count)); - count++; - } - if (collector.$noSerialize$.length > 0) { - const undefinedID = objToId.get(undefined); - assertDefined(undefinedID, 'undefined ID must be defined'); - for (const obj of collector.$noSerialize$) { - objToId.set(obj, undefinedID); - } - } - - // Serialize object subscriptions - const subs: string[][] = []; - for (const obj of objs) { - const value = subsMap.get(obj); - if (value == null) { - break; - } - subs.push( - value - .map((s) => { - if (typeof s === 'number') { - return `_${s}`; - } - return serializeSubscription(s, getObjId); - }) - .filter(isNotNullable) - ); - } - assertEqual(subs.length, subsMap.size, 'missing subscriptions to serialize', subs, subsMap); - - const convertedObjs = serializeObjects(objs, mustGetObjId, getObjId, collector, containerState); - - const meta: SnapshotMeta = {}; - const refs: Record = {}; - - // Write back to the dom - for (const ctx of allContexts) { - const node = ctx.$element$; - const elementID = ctx.$id$; - const ref = ctx.$refMap$; - const props = ctx.$props$; - const contexts = ctx.$contexts$; - const tasks = ctx.$tasks$; - const renderQrl = ctx.$componentQrl$; - const seq = ctx.$seq$; - const metaValue: SnapshotMetaValue = {}; - const elementCaptured = isVirtualElement(node) && collector.$elements$.includes(ctx); - assertDefined(elementID, `pause: can not generate ID for dom node`, node); - - if (ref.length > 0) { - assertElement(node); - const value = mapJoin(ref, mustGetObjId, ' '); - if (value) { - refs[elementID] = value; - } - } else if (canRender) { - let add = false; - if (elementCaptured) { - assertDefined(renderQrl, 'renderQrl must be defined'); - const propsId = getObjId(props); - metaValue.h = mustGetObjId(renderQrl) + (propsId ? ' ' + propsId : ''); - add = true; - } else { - const propsId = getObjId(props); - if (propsId) { - metaValue.h = ' ' + propsId; - add = true; - } - } - - if (tasks && tasks.length > 0) { - const value = mapJoin(tasks, getObjId, ' '); - if (value) { - metaValue.w = value; - add = true; - } - } - - if (elementCaptured && seq && seq.length > 0) { - const value = mapJoin(seq, mustGetObjId, ' '); - metaValue.s = value; - add = true; - } - - if (contexts) { - const serializedContexts: string[] = []; - contexts.forEach((value, key) => { - const id = getObjId(value); - if (id) { - serializedContexts.push(`${key}=${id}`); - } - }); - const value = serializedContexts.join(' '); - if (value) { - metaValue.c = value; - add = true; - } - } - if (add) { - meta[elementID] = metaValue; - } - } - } - - // Sanity check of serialized element - if (qDev) { - elementToIndex.forEach((value, el) => { - if (!value) { - logWarn('unconnected element', el.nodeName, '\n'); - } - }); - } - - return { - state: { - refs, - ctx: meta, - objs: convertedObjs, - subs, - }, - objs, - funcs: collector.$inlinedFunctions$, - resources: collector.$resources$, - qrls: collector.$qrls$, - mode: canRender ? 'render' : 'listeners', - }; -}; - -export const mapJoin = (objects: any[], getObjectId: GetObjID, sep: string): string => { - let output = ''; - for (const obj of objects) { - const id = getObjectId(obj); - if (id !== null) { - if (output !== '') { - output += sep; - } - output += id; - } - } - return output; -}; - -export const getNodesInScope = ( - parent: Element, - predicate: (el: Node) => T | undefined -): T[] => { - const results: T[] = []; - const v = predicate(parent); - if (v !== undefined) { - results.push(v); - } - const walker = parent.ownerDocument.createTreeWalker(parent, SHOW_ELEMENT | SHOW_COMMENT, { - acceptNode(node) { - if (isContainer(node)) { - return FILTER_REJECT; - } - const v = predicate(node); - if (v !== undefined) { - results.push(v); - } - return FILTER_SKIP; - }, - }); - while (walker.nextNode()) { - // do nothing - } - - return results; -}; - -export interface Collector { - $seen$: Set; - $objSet$: Set; - $noSerialize$: any[]; - $elements$: QContext[]; - $qrls$: QRL[]; - $inlinedFunctions$: string[]; - $resources$: ResourceReturnInternal[]; - $prefetch$: number; - $deferElements$: QContext[]; - $containerState$: ContainerState; - $promises$: Promise[]; -} - -// Collect props proxy objects -const collectProps = (elCtx: QContext, collector: Collector) => { - const parentCtx = elCtx.$realParentCtx$ || elCtx.$parentCtx$; - const props = elCtx.$props$; - // Collect only if the parent (which changes the props) is part of the listener graph - if (parentCtx && props && !isEmptyObj(props) && collector.$elements$.includes(parentCtx)) { - const subs = getSubscriptionManager(props)?.$subs$; - const el = elCtx.$element$ as VirtualElement; - if (subs) { - for (const [type, host] of subs) { - if (type === 0) { - if (host !== el) { - collectSubscriptions(getSubscriptionManager(props)!, collector, false); - } - if (isNode(host)) { - collectElement(host, collector); - } else { - collectValue(host, collector, true); - } - } else { - collectValue(props, collector, false); - collectSubscriptions(getSubscriptionManager(props)!, collector, false); - } - } - } - } -}; - -const createCollector = (containerState: ContainerState): Collector => { - const inlinedFunctions: string[] = []; - containerState.$inlineFns$.forEach((id, fnStr) => { - while (inlinedFunctions.length <= id) { - inlinedFunctions.push(''); - } - inlinedFunctions[id] = fnStr; - }); - return { - $containerState$: containerState, - $seen$: new Set(), - $objSet$: new Set(), - $prefetch$: 0, - $noSerialize$: [], - $inlinedFunctions$: inlinedFunctions, - $resources$: [], - $elements$: [], - $qrls$: [], - $deferElements$: [], - $promises$: [], - }; -}; - -const collectDeferElement = (el: VirtualElement, collector: Collector) => { - const ctx = tryGetContext(el)!; - if (collector.$elements$.includes(ctx)) { - return; - } - collector.$elements$.push(ctx); - if (ctx.$flags$ & HOST_FLAG_DYNAMIC) { - collector.$prefetch$++; - collectElementData(ctx, collector, true); - collector.$prefetch$--; - } else { - collector.$deferElements$.push(ctx); - } -}; - -const collectElement = (el: QwikElement, collector: Collector) => { - const ctx = tryGetContext(el); - if (ctx) { - if (collector.$elements$.includes(ctx)) { - return; - } - collector.$elements$.push(ctx); - collectElementData(ctx, collector, el); - } -}; - -export const collectElementData = ( - elCtx: QContext, - collector: Collector, - dynamicCtx: QwikElement | boolean -) => { - if (elCtx.$props$ && !isEmptyObj(elCtx.$props$)) { - collectValue(elCtx.$props$, collector, dynamicCtx); - collectSubscriptions(getSubscriptionManager(elCtx.$props$)!, collector, dynamicCtx); - } - if (elCtx.$componentQrl$) { - collectValue(elCtx.$componentQrl$, collector, dynamicCtx); - } - if (elCtx.$seq$) { - for (const obj of elCtx.$seq$) { - collectValue(obj, collector, dynamicCtx); - } - } - if (elCtx.$tasks$) { - const map = collector.$containerState$.$subsManager$.$groupToManagers$; - for (const obj of elCtx.$tasks$) { - if (map.has(obj)) { - collectValue(obj, collector, dynamicCtx); - } - } - } - - if (dynamicCtx === true) { - collectContext(elCtx, collector); - if (elCtx.$dynamicSlots$) { - for (const slotCtx of elCtx.$dynamicSlots$) { - collectContext(slotCtx, collector); - } - } - } -}; - -const collectContext = (elCtx: QContext | null | undefined, collector: Collector) => { - while (elCtx) { - if (elCtx.$contexts$) { - for (const obj of elCtx.$contexts$.values()) { - collectValue(obj, collector, true); - } - } - elCtx = elCtx.$parentCtx$; - } -}; - -export const escapeText = (str: string) => { - return str.replace(/<(\/?script)/gi, '\\x3C$1'); -}; - -// Collect all the subscribers of this manager -export const collectSubscriptions = ( - manager: LocalSubscriptionManager, - collector: Collector, - leaks: boolean | QwikElement -) => { - // if (!leaks) { - // return; - // } - if (collector.$seen$.has(manager)) { - return; - } - collector.$seen$.add(manager); - - const subs = manager.$subs$; - assertDefined(subs, 'subs must be defined'); - for (const sub of subs) { - const type = sub[0]; - if (type > 0) { - collectValue((sub as SubscriberSignal)[2], collector, leaks); - } - if (leaks === true) { - const host = sub[1]; - if (isNode(host) && isVirtualElement(host)) { - if (sub[0] === 0) { - collectDeferElement(host, collector); - } - } else { - collectValue(host, collector, true); - } - } - } -}; - -const PROMISE_VALUE = Symbol(); - -interface PromiseValue { - resolved: boolean; - value: any; -} -const resolvePromise = (promise: Promise) => { - return promise.then( - (value) => { - const v: PromiseValue = { - resolved: true, - value, - }; - (promise as any)[PROMISE_VALUE] = v; - return value; - }, - (value) => { - const v: PromiseValue = { - resolved: false, - value, - }; - (promise as any)[PROMISE_VALUE] = v; - return value; - } - ); -}; - -const getPromiseValue = (promise: Promise): PromiseValue | undefined => { - return (promise as any)[PROMISE_VALUE]; -}; - -export const collectValue = (obj: unknown, collector: Collector, leaks: boolean | QwikElement) => { - if (obj != null) { - const objType = typeof obj; - switch (objType) { - case 'function': - case 'object': { - if (collector.$seen$.has(obj)) { - return; - } - collector.$seen$.add(obj); - if (fastSkipSerialize(obj)) { - collector.$objSet$.add(undefined); - collector.$noSerialize$.push(obj); - return; - } - - /** The possibly proxied `obj` */ - const input = obj; - const target = getProxyTarget(obj); - if (target) { - // `obj` is now the non-proxied object - obj = target; - // NOTE: You may be tempted to add the `target` to the `seen` set, - // but that would not work as it is possible for the `target` object - // to already be in `seen` set if it was passed in directly, so - // we can't short circuit and need to do the work. - // Issue: https://github.com/QwikDev/qwik/issues/5001 - const mutable = (getProxyFlags(obj)! & QObjectImmutable) === 0; - if (leaks && mutable) { - collectSubscriptions(getSubscriptionManager(input)!, collector, leaks); - } - if (fastWeakSerialize(input)) { - collector.$objSet$.add(obj); - return; - } - } - const collected = collectDeps(obj, collector, leaks); - if (collected) { - collector.$objSet$.add(obj); - return; - } - - if (isPromise(obj)) { - collector.$promises$.push( - resolvePromise(obj).then((value) => { - collectValue(value, collector, leaks); - }) - ); - return; - } - - if (objType === 'object') { - if (isNode(obj)) { - return; - } - if (isArray(obj)) { - for (let i = 0; i < obj.length; i++) { - collectValue((input as typeof obj)[i], collector, leaks); - } - } else if (isSerializableObject(obj)) { - for (const key in obj) { - collectValue((input as typeof obj)[key], collector, leaks); - } - } - } - break; - } - } - } - collector.$objSet$.add(obj); -}; - -export const isContainer = (el: Node) => { - return isElement(el) && el.hasAttribute(QContainerAttr); -}; - -const hasContext = (el: Node) => { - const node = processVirtualNodes(el); - if (isQwikElement(node)) { - const ctx = tryGetContext(node); - if (ctx && ctx.$id$) { - return ctx; - } - } - return undefined; -}; - -const getManager = (obj: any, containerState: ContainerState) => { - if (!isObject(obj)) { - return undefined; - } - if (obj instanceof SignalImpl) { - return getSubscriptionManager(obj); - } - const proxy = containerState.$proxyMap$.get(obj); - if (proxy) { - return getSubscriptionManager(proxy); - } - return undefined; -}; - -const getQId = (el: QwikElement): string | null => { - const ctx = tryGetContext(el); - if (ctx) { - return ctx.$id$; - } - return null; -}; - -const getTextID = (node: Text, containerState: ContainerState) => { - const prev = node.previousSibling; - if (prev && isComment(prev)) { - if (prev.data.startsWith('t=')) { - return ELEMENT_ID_PREFIX + prev.data.slice(2); - } - } - const doc = node.ownerDocument; - const id = intToStr(containerState.$elementIndex$++); - const open = doc.createComment(`t=${id}`); - const close = doc.createComment(''); - const parent = node.parentElement!; - parent.insertBefore(open, node); - parent.insertBefore(close, node.nextSibling); - return ELEMENT_ID_PREFIX + id; -}; - -const isEmptyObj = (obj: Record) => { - return Object.keys(obj).length === 0; -}; -function serializeObjects( - objs: any[], - mustGetObjId: (obj: any) => string, - getObjId: GetObjID | null, - collector: Collector, - containerState: any -) { - return objs.map((obj) => { - if (obj === null) { - return null; - } - const typeObj = typeof obj; - switch (typeObj) { - case 'undefined': - return UNDEFINED_PREFIX; - case 'number': - if (!Number.isFinite(obj)) { - break; - } - return obj; - case 'string': - if ((obj as string).charCodeAt(0) < 32 /* space */) { - // if strings starts with a special character let the string serializer handle it - // to deal with escape sequences. - break; - } else { - // Fast path of just serializing the string. - return obj; - } - case 'boolean': - return obj; - } - const value = serializeValue(obj, mustGetObjId, collector, containerState); - if (value !== undefined) { - return value; - } - if (typeObj === 'object') { - if (isArray(obj)) { - return obj.map(mustGetObjId); - } - if (isSerializableObject(obj)) { - const output: Record = {}; - for (const key in obj) { - if (getObjId) { - const id = getObjId(obj[key]); - if (id !== null) { - output[key] = id; - } - } else { - output[key] = mustGetObjId(obj[key]); - } - } - return output; - } - } - throw qError(QError_verifySerializable, obj); - }); -} diff --git a/packages/qwik/src/core/container/pause.unit.tsx b/packages/qwik/src/core/container/pause.unit.tsx deleted file mode 100644 index 865de528373..00000000000 --- a/packages/qwik/src/core/container/pause.unit.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import type { SymbolMapper, SymbolMapperFn } from '../../optimizer/src/types'; -import { componentQrl } from '../component/component.public'; -import { useComputedQrl } from '../use/use-task'; -import { useSignal } from '../use/use-signal'; -import { renderToString } from '../../server/render'; -import { assert, test } from 'vitest'; -import { inlinedQrl } from '../qrl/qrl'; - -const symbolMapper: SymbolMapperFn = (symbolName: string, mapper: SymbolMapper | undefined) => { - return [symbolName, `q-${symbolName}.js`]; -}; - -test('issue-4979', async () => { - await renderToString(, { - containerTagName: 'div', - symbolMapper: symbolMapper, - manifest: {} as any, - }); - - assert(true, 'Serialized successfully'); -}); - -export const Issue4979Inner = componentQrl<{ value: number }>( - inlinedQrl( - (props) => { - const foo = useComputedQrl( - inlinedQrl( - () => { - return Object.entries(props); - }, - 's_foo', - [props] - ) - ); - - return ; - }, - 's_issue4979Inner', - [] - ) -); - -export const Issue4979 = componentQrl( - inlinedQrl( - () => { - const pageSig = useSignal(1); - - const currentDataSig = useComputedQrl( - inlinedQrl( - () => { - return [pageSig.value]; - }, - 's_currentData', - [pageSig] - ) - ); - - return ( - <> - - {currentDataSig.value.map((o) => ( - - ))} - - ); - }, - 's_issue4979', - [] - ) -); diff --git a/packages/qwik/src/core/container/render.unit.tsx b/packages/qwik/src/core/container/render.unit.tsx deleted file mode 100644 index ac0fd4de2aa..00000000000 --- a/packages/qwik/src/core/container/render.unit.tsx +++ /dev/null @@ -1,138 +0,0 @@ -import { assert, suite, test } from 'vitest'; -import { renderToString } from '../../server/render'; -import { createDocument } from '../../testing/document'; -import { createDOM } from '../../testing/library'; -import { component$ } from '../component/component.public'; -import { _fnSignal } from '../internal'; -import { useSignal } from '../use/use-signal'; -import type { JSXOutput } from '../render/jsx/types/jsx-node'; - -suite('jsx signals', () => { - const RenderJSX = component$(() => { - const jsx = useSignal(SSR); - return ( - <> - - - ); -}; - -export const LexicalScope = component$(() => { - const state = useStore({ - count: 0, - }); - const signal = useSignal(0); - const signalFromFn = useSignal(() => 'ok'); - const nu = 1; - const str = 'hola'; - const obj = { - a: { thing: 12 }, - b: 'hola', - c: 123, - d: false, - e: true, - f: null, - g: undefined, - h: [1, 'string', false, { hola: 1 }, ['hello']], - i: LexicalScope, - }; - const noserialize = noSerialize({ text: 'not included', window: () => {} }); - const undef = undefined; - const nulll = null; - const array = [1, 2, 'hola', {}]; - const boolTrue = true; - const boolFalse = false; - const qrl = $(() => logDebug('qrl')); - const thing = inlinedQrl(LexicalScope_render, 'LexicalScope_render', [ - nu, - str, - obj, - undef, - nulll, - array, - boolTrue, - boolFalse, - state, - noserialize, - qrl, - signal, - signalFromFn, - ]); - return
{signal as any}
; -}); diff --git a/packages/qwik/src/core/debug.ts b/packages/qwik/src/core/debug.ts new file mode 100644 index 00000000000..920bf007381 --- /dev/null +++ b/packages/qwik/src/core/debug.ts @@ -0,0 +1,94 @@ +import { isSignal } from './reactive-primitives/utils'; +// ^ keep this first to avoid circular dependency breaking class extend +import { vnode_getProp, vnode_isVNode } from './client/vnode'; +import { ComputedSignalImpl } from './reactive-primitives/impl/computed-signal-impl'; +import { isStore } from './reactive-primitives/impl/store'; +import { WrappedSignalImpl } from './reactive-primitives/impl/wrapped-signal-impl'; +import { isJSXNode } from './shared/jsx/jsx-runtime'; +import { isQrl } from './shared/qrl/qrl-utils'; +import { DEBUG_TYPE } from './shared/types'; +import { isTask } from './use/use-task'; + +const stringifyPath: any[] = []; +export function qwikDebugToString(value: any): any { + if (value === null) { + return 'null'; + } else if (value === undefined) { + return 'undefined'; + } else if (typeof value === 'string') { + return '"' + value + '"'; + } else if (typeof value === 'number' || typeof value === 'boolean') { + return String(value); + } else if (isTask(value)) { + return `Task(${qwikDebugToString(value.$qrl$)})`; + } else if (isQrl(value)) { + return `Qrl(${value.$symbol$})`; + } else if (typeof value === 'object' || typeof value === 'function') { + if (stringifyPath.includes(value)) { + return '*'; + } + if (stringifyPath.length > 10) { + // debugger; + } + try { + stringifyPath.push(value); + if (Array.isArray(value)) { + if (vnode_isVNode(value)) { + return '(' + vnode_getProp(value, DEBUG_TYPE, null) + ')'; + } else { + return value.map(qwikDebugToString); + } + } else if (isSignal(value)) { + if (value instanceof WrappedSignalImpl) { + return 'WrappedSignal'; + } else if (value instanceof ComputedSignalImpl) { + return 'ComputedSignal'; + } else { + return 'Signal'; + } + } else if (isStore(value)) { + return 'Store'; + } else if (isJSXNode(value)) { + return jsxToString(value); + } + } finally { + stringifyPath.pop(); + } + } + return value; +} + +export const pad = (text: string, prefix: string) => { + return String(text) + .split('\n') + .map((line, idx) => (idx ? prefix : '') + line) + .join('\n'); +}; + +export const jsxToString = (value: any): string => { + if (isJSXNode(value)) { + let str = '<' + value.type; + if (value.props) { + for (const [key, val] of Object.entries(value.props)) { + str += ' ' + key + '=' + qwikDebugToString(val); + } + const children = value.children; + if (children != null) { + str += '>'; + if (Array.isArray(children)) { + children.forEach((child) => { + str += jsxToString(child); + }); + } else { + str += jsxToString(children); + } + str += ''; + } else { + str += '/>'; + } + } + return str; + } else { + return String(value); + } +}; diff --git a/packages/qwik/src/core/error/assert.ts b/packages/qwik/src/core/error/assert.ts deleted file mode 100644 index 50554f49459..00000000000 --- a/packages/qwik/src/core/error/assert.ts +++ /dev/null @@ -1,85 +0,0 @@ -import type { QwikElement, VirtualElement } from '../render/dom/virtual-element'; -import { isElement, isQwikElement } from '../util/element'; -import { throwErrorAndStop } from '../util/log'; -import { qDev } from '../util/qdev'; - -const ASSERT_DISCLAIMER = 'Internal assert, this is likely caused by a bug in Qwik: '; - -export function assertDefined( - value: T, - text: string, - ...parts: any[] -): asserts value is NonNullable { - if (qDev) { - if (value != null) { - return; - } - throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts); - } -} - -export function assertEqual( - value1: any, - value2: any, - text: string, - ...parts: any[] -): asserts value1 is typeof value2 { - if (qDev) { - if (value1 === value2) { - return; - } - throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts); - } -} - -export function assertFail(text: string, ...parts: any[]): never; -export function assertFail(text: string, ...parts: any[]) { - if (qDev) { - throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts); - } -} - -export function assertTrue(value1: any, text: string, ...parts: any[]): asserts value1 is true { - if (qDev) { - if (value1 === true) { - return; - } - throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts); - } -} - -export function assertNumber(value1: any, text: string, ...parts: any[]): asserts value1 is number { - if (qDev) { - if (typeof value1 === 'number') { - return; - } - throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts); - } -} - -export function assertString(value1: any, text: string, ...parts: any[]): asserts value1 is string { - if (qDev) { - if (typeof value1 === 'string') { - return; - } - throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts); - } -} - -export function assertQwikElement(el: any): asserts el is QwikElement { - if (qDev) { - if (!isQwikElement(el)) { - console.error('Not a Qwik Element, got', el); - throwErrorAndStop(ASSERT_DISCLAIMER + 'Not a Qwik Element'); - } - } -} - -export function assertElement(el: Node | VirtualElement): asserts el is Element { - if (qDev) { - if (!isElement(el)) { - console.error('Not a Element, got', el); - throwErrorAndStop(ASSERT_DISCLAIMER + 'Not an Element'); - } - } -} diff --git a/packages/qwik/src/core/error/error.ts b/packages/qwik/src/core/error/error.ts deleted file mode 100644 index 53482935148..00000000000 --- a/packages/qwik/src/core/error/error.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { logErrorAndStop } from '../util/log'; -import { qDev } from '../util/qdev'; - -export const codeToText = (code: number, ...parts: any[]): string => { - if (qDev) { - // Keep one error, one line to make it easier to search for the error message. - const MAP = [ - 'Error while serializing class or style attributes', // 0 - 'Can not serialize a HTML Node that is not an Element', // 1 - 'Runtime but no instance found on element.', // 2 - 'Only primitive and object literals can be serialized', // 3 - 'Crash while rendering', // 4 - 'You can render over a existing q:container. Skipping render().', // 5 - 'Set property {{0}}', // 6 - "Only function's and 'string's are supported.", // 7 - "Only objects can be wrapped in 'QObject'", // 8 - `Only objects literals can be wrapped in 'QObject'`, // 9 - 'QRL is not a function', // 10 - 'Dynamic import not found', // 11 - 'Unknown type argument', // 12 - `Actual value for useContext({{0}}) can not be found, make sure some ancestor component has set a value using useContextProvider(). In the browser make sure that the context was used during SSR so its state was serialized.`, // 13 - "Invoking 'use*()' method outside of invocation context.", // 14 - 'Cant access renderCtx for existing context', // 15 - 'Cant access document for existing context', // 16 - 'props are immutable', // 17 - '
component can only be used at the root of a Qwik component$()', // 18 - 'Props are immutable by default.', // 19 - `Calling a 'use*()' method outside 'component$(() => { HERE })' is not allowed. 'use*()' methods provide hooks to the 'component$' state and lifecycle, ie 'use' hooks can only be called synchronously within the 'component$' function or another 'use' method.\nSee https://qwik.dev/docs/components/tasks/#use-method-rules`, // 20 - 'Container is already paused. Skipping', // 21 - '', // 22 -- unused - 'When rendering directly on top of Document, the root node must be a ', // 23 - 'A node must have 2 children. The first one and the second one a ', // 24 - 'Invalid JSXNode type "{{0}}". It must be either a function or a string. Found:', // 25 - 'Tracking value changes can only be done to useStore() objects and component props', // 26 - 'Missing Object ID for captured object', // 27 - 'The provided Context reference "{{0}}" is not a valid context created by createContextId()', // 28 - ' is the root container, it can not be rendered inside a component', // 29 - 'QRLs can not be resolved because it does not have an attached container. This means that the QRL does not know where it belongs inside the DOM, so it cant dynamically import() from a relative path.', // 30 - 'QRLs can not be dynamically resolved, because it does not have a chunk path', // 31 - 'The JSX ref attribute must be a Signal', // 32 - ]; - let text = MAP[code] ?? ''; - if (parts.length) { - text = text.replaceAll(/{{(\d+)}}/g, (_, index) => { - let v = parts[index]; - if (v && typeof v === 'object' && v.constructor === Object) { - v = JSON.stringify(v).slice(0, 50); - } - return v; - }); - } - return `Code(${code}): ${text}`; - } else { - // cute little hack to give roughly the correct line number. Update the line number if it shifts. - return `Code(${code}) https://github.com/QwikDev/qwik/blob/main/packages/qwik/src/core/error/error.ts#L${8 + code}`; - } -}; - -export const QError_stringifyClassOrStyle = 0; -export const QError_cannotSerializeNode = 1; -export const QError_runtimeQrlNoElement = 2; -export const QError_verifySerializable = 3; -export const QError_errorWhileRendering = 4; -export const QError_cannotRenderOverExistingContainer = 5; -export const QError_setProperty = 6; -export const QError_qrlOrError = 7; -export const QError_onlyObjectWrapped = 8; -export const QError_onlyLiteralWrapped = 9; -export const QError_qrlIsNotFunction = 10; -export const QError_dynamicImportFailed = 11; -export const QError_unknownTypeArgument = 12; -export const QError_notFoundContext = 13; -export const QError_useMethodOutsideContext = 14; -export const QError_missingRenderCtx = 15; -export const QError_missingDoc = 16; -export const QError_immutableProps = 17; -export const QError_hostCanOnlyBeAtRoot = 18; -export const QError_immutableJsxProps = 19; -export const QError_useInvokeContext = 20; -export const QError_containerAlreadyPaused = 21; -export const QError_unused_please_reuse = 22; -export const QError_rootNodeMustBeHTML = 23; -export const QError_strictHTMLChildren = 24; -export const QError_invalidJsxNodeType = 25; -export const QError_trackUseStore = 26; -export const QError_missingObjectId = 27; -export const QError_invalidContext = 28; -export const QError_canNotRenderHTML = 29; -export const QError_qrlMissingContainer = 30; -export const QError_qrlMissingChunk = 31; -export const QError_invalidRefValue = 32; -export const qError = (code: number, ...parts: any[]): Error => { - const text = codeToText(code, ...parts); - return logErrorAndStop(text, ...parts); -}; diff --git a/packages/qwik/src/core/examples.tsx b/packages/qwik/src/core/examples.tsx index 80f1fa67600..0f2559129bf 100644 --- a/packages/qwik/src/core/examples.tsx +++ b/packages/qwik/src/core/examples.tsx @@ -6,14 +6,15 @@ // it to the desired comment location // -import { component$ } from './component/component.public'; -import { qrl } from './qrl/qrl'; -import { $, type QRL } from './qrl/qrl.public'; +import { component$ } from './shared/component.public'; +import { qrl } from './shared/qrl/qrl'; +import { $, type QRL } from './shared/qrl/qrl.public'; import { useOn, useOnDocument, useOnWindow } from './use/use-on'; import { useStore } from './use/use-store.public'; import { useStyles$, useStylesScoped$ } from './use/use-styles'; -import { useVisibleTask$, useTask$ } from './use/use-task'; -import { implicit$FirstArg } from './util/implicit_dollar'; +import { useTask$ } from './use/use-task-dollar'; +import { useVisibleTask$ } from './use/use-visible-task-dollar'; +import { implicit$FirstArg } from './shared/qrl/implicit_dollar'; import { isServer, isBrowser } from '../build'; ////////////////////////////////////////////////////////// @@ -474,7 +475,8 @@ function doExtraStuff() { // import { createContextId, useContext, useContextProvider } from './use/use-context'; -import { Resource, useResource$ } from './use/use-resource'; +import { Resource } from './use/use-resource'; +import { useResource$ } from './use/use-resource-dollar'; import { useSignal } from './use/use-signal'; export const greet = () => console.log('greet'); diff --git a/packages/qwik/src/core/index.ts b/packages/qwik/src/core/index.ts index 7fb3c218639..51a9565ea71 100644 --- a/packages/qwik/src/core/index.ts +++ b/packages/qwik/src/core/index.ts @@ -1,19 +1,11 @@ ////////////////////////////////////////////////////////////////////////////////////////// // Developer Core API ////////////////////////////////////////////////////////////////////////////////////////// -export { componentQrl, component$ } from './component/component.public'; +export { componentQrl, component$ } from './shared/component.public'; -export type { - PropsOf, - OnRenderFn, - Component, - PublicProps, - PropFunctionProps, - _AllowPlainQrl, - _Only$, -} from './component/component.public'; +export type { PropsOf, OnRenderFn, Component, PublicProps } from './shared/component.public'; -export { isBrowser, isDev, isServer } from '@builder.io/qwik/build'; +export { isBrowser, isDev, isServer } from '@qwik.dev/core/build'; ////////////////////////////////////////////////////////////////////////////////////////// // Developer Event API @@ -24,40 +16,49 @@ export type { SnapshotMeta, SnapshotMetaValue, SnapshotListener, -} from './container/container'; + ISsrComponentFrame, +} from './ssr/ssr-types'; ////////////////////////////////////////////////////////////////////////////////////////// // Internal Runtime ////////////////////////////////////////////////////////////////////////////////////////// -export { $, sync$, _qrlSync, type SyncQRL } from './qrl/qrl.public'; -export { event$, eventQrl } from './qrl/qrl.public'; +export { $, sync$, _qrlSync, type SyncQRL } from './shared/qrl/qrl.public'; +export { eventQrl } from './shared/qrl/qrl.public'; +export { event$ } from './shared/qrl/qrl.public.dollar'; -export { qrl, inlinedQrl, inlinedQrlDEV, qrlDEV } from './qrl/qrl'; -export type { QRL, PropFunction, PropFnInterface } from './qrl/qrl.public'; -export { implicit$FirstArg } from './util/implicit_dollar'; +export { qrl, inlinedQrl, inlinedQrlDEV, qrlDEV } from './shared/qrl/qrl'; +export type { QRL, PropFunction } from './shared/qrl/qrl.public'; +export { implicit$FirstArg } from './shared/qrl/implicit_dollar'; ////////////////////////////////////////////////////////////////////////////////////////// // PLATFORM ////////////////////////////////////////////////////////////////////////////////////////// -export { getPlatform, setPlatform } from './platform/platform'; -export type { CorePlatform } from './platform/types'; +export { getPlatform, setPlatform } from './shared/platform/platform'; +export type { CorePlatform } from './shared/platform/types'; +export type { ClientContainer } from './client/types'; +export type { DomContainer } from './client/dom-container'; ////////////////////////////////////////////////////////////////////////////////////////// // JSX Runtime ////////////////////////////////////////////////////////////////////////////////////////// -export { h, h as createElement } from './render/jsx/factory'; export { SSRStreamBlock, SSRRaw, SSRStream, SSRComment, - SSRHint, SkipRender, -} from './render/jsx/utils.public'; -export type { SSRStreamProps, SSRHintProps } from './render/jsx/utils.public'; -export { Slot } from './render/jsx/slot.public'; -export { Fragment, HTMLFragment, RenderOnce, jsx, jsxDEV, jsxs } from './render/jsx/jsx-runtime'; -export type * from './render/jsx/types/jsx-generated'; +} from './shared/jsx/utils.public'; +export type { SSRStreamProps, SSRHintProps, SSRStreamChildren } from './shared/jsx/utils.public'; +export { Slot } from './shared/jsx/slot.public'; +export { + Fragment, + RenderOnce, + jsx, + jsxDEV, + jsxs, + h, + h as createElement, +} from './shared/jsx/jsx-runtime'; export type { DOMAttributes, QwikAttributes, @@ -68,73 +69,103 @@ export type { CorrectedToggleEvent, EventHandler, QRLEventHandlerMulti, -} from './render/jsx/types/jsx-qwik-attributes'; -export type { JSXOutput, FunctionComponent, JSXNode, DevJSX } from './render/jsx/types/jsx-node'; -export type { QwikDOMAttributes, QwikJSX, QwikJSX as JSX } from './render/jsx/types/jsx-qwik'; +} from './shared/jsx/types/jsx-qwik-attributes'; +export type { + JSXOutput, + FunctionComponent, + JSXNode, + JSXNodeInternal, + DevJSX, +} from './shared/jsx/types/jsx-node'; +export type { QwikDOMAttributes, QwikJSX, QwikJSX as JSX } from './shared/jsx/types/jsx-qwik'; -export type { QwikIntrinsicElements } from './render/jsx/types/jsx-qwik-elements'; -export type { QwikHTMLElements, QwikSVGElements } from './render/jsx/types/jsx-generated'; -export { render } from './render/dom/render.public'; -export type { RenderSSROptions, StreamWriter } from './render/ssr/render-ssr'; -export type { RenderOptions, RenderResult } from './render/dom/render.public'; +export type { QwikIntrinsicElements } from './shared/jsx/types/jsx-qwik-elements'; +export type { + CSSProperties, + QwikHTMLElements, + QwikSVGElements, + SVGAttributes, + HTMLElementAttrs, + SVGProps, +} from './shared/jsx/types/jsx-generated'; +export { render } from './client/dom-render'; +export { getDomContainer, _getQContainerElement } from './client/dom-container'; +export type { StreamWriter, RenderSSROptions } from './ssr/ssr-types'; +export type { RenderOptions, RenderResult } from './client/types'; ////////////////////////////////////////////////////////////////////////////////////////// // use API ////////////////////////////////////////////////////////////////////////////////////////// export { useLexicalScope } from './use/use-lexical-scope.public'; -export { useStore } from './use/use-store.public'; +export { useStore, unwrapStore } from './use/use-store.public'; export { untrack } from './use/use-core'; export { useId } from './use/use-id'; export { useContext, useContextProvider, createContextId } from './use/use-context'; export { useServerData } from './use/use-env-data'; export { useStylesQrl, useStyles$, useStylesScopedQrl, useStylesScoped$ } from './use/use-styles'; export { useOn, useOnDocument, useOnWindow } from './use/use-on'; -export { useSignal, useConstant, createSignal } from './use/use-signal'; +export { useSignal, useConstant } from './use/use-signal'; export { withLocale, getLocale } from './use/use-locale'; export type { UseStylesScoped } from './use/use-styles'; export type { UseSignal } from './use/use-signal'; export type { ContextId } from './use/use-context'; export type { UseStoreOptions } from './use/use-store.public'; +export type { ComputedFn, ComputedReturnType } from './use/use-computed'; +export { useComputedQrl } from './use/use-computed'; +export { useSerializerQrl, useSerializer$ } from './use/use-serializer'; +export type { OnVisibleTaskOptions, VisibleTaskStrategy } from './use/use-visible-task'; +export { useVisibleTaskQrl } from './use/use-visible-task'; +export type { TaskCtx, TaskFn, Tracker } from './use/use-task'; export type { - ComputedFn, - EagernessOptions, - OnVisibleTaskOptions, + ResourceProps, + ResourceOptions, ResourceCtx, ResourceFn, ResourcePending, ResourceRejected, ResourceResolved, ResourceReturn, - TaskCtx, - TaskFn, - Tracker, - UseTaskOptions, - VisibleTaskStrategy, -} from './use/use-task'; -export type { ResourceProps, ResourceOptions } from './use/use-resource'; -export { useResource$, useResourceQrl, Resource } from './use/use-resource'; -export { useTask$, useTaskQrl } from './use/use-task'; -export { useVisibleTask$, useVisibleTaskQrl } from './use/use-task'; -export { useComputed$, useComputedQrl, createComputed$, createComputedQrl } from './use/use-task'; +} from './use/use-resource'; +export { useResourceQrl, Resource } from './use/use-resource'; +export { useResource$ } from './use/use-resource-dollar'; +export { useTaskQrl } from './use/use-task'; +export { useTask$ } from './use/use-task-dollar'; +export { useVisibleTask$ } from './use/use-visible-task-dollar'; +export { useComputed$ } from './use/use-computed'; export { useErrorBoundary } from './use/use-error-boundary'; -export type { ErrorBoundaryStore } from './render/error-handling'; +export type { ErrorBoundaryStore } from './shared/error/error-handling'; +export { + type ReadonlySignal, + type Signal, + type ComputedSignal, +} from './reactive-primitives/signal.public'; +export { + isSignal, + createSignal, + createComputedQrl, + createComputed$, + createSerializerQrl, + createSerializer$, +} from './reactive-primitives/signal.public'; ////////////////////////////////////////////////////////////////////////////////////////// // Developer Low-Level API ////////////////////////////////////////////////////////////////////////////////////////// -export type { ValueOrPromise } from './util/types'; -export type { Signal, ReadonlySignal } from './state/signal'; -export type { NoSerialize } from './state/common'; -export { noSerialize, unwrapProxy as unwrapStore } from './state/common'; -export { isSignal } from './state/signal'; +export type { ValueOrPromise } from './shared/utils/types'; +export { + NoSerializeSymbol, + SerializerSymbol, + type NoSerialize, +} from './shared/utils/serialize-utils'; +export { noSerialize } from './shared/utils/serialize-utils'; export { version } from './version'; ////////////////////////////////////////////////////////////////////////////////////////// // Qwik Events ////////////////////////////////////////////////////////////////////////////////////////// export type { - KnownEventNames as KnownEventNames, + KnownEventNames, QwikSymbolEvent, QwikVisibleEvent, QwikIdleEvent, @@ -167,12 +198,12 @@ export type { QwikTouchEvent, QwikUIEvent, QwikWheelEvent, -} from './render/jsx/types/jsx-qwik-events'; +} from './shared/jsx/types/jsx-qwik-events'; ////////////////////////////////////////////////////////////////////////////////////////// // Components ////////////////////////////////////////////////////////////////////////////////////////// -export { PrefetchServiceWorker, PrefetchGraph } from './components/prefetch'; +export { PrefetchServiceWorker, PrefetchGraph } from './shared/prefetch-service-worker/prefetch'; ////////////////////////////////////////////////////////////////////////////////////////// // INTERNAL diff --git a/packages/qwik/src/core/internal.ts b/packages/qwik/src/core/internal.ts index cad738b5834..8c2ae802e92 100644 --- a/packages/qwik/src/core/internal.ts +++ b/packages/qwik/src/core/internal.ts @@ -1,18 +1,57 @@ -export { _pauseFromContexts, _serializeData } from './container/pause'; -export { _noopQrl, _noopQrlDEV, _regSymbol } from './qrl/qrl'; -export { _renderSSR } from './render/ssr/render-ssr'; -export { _hW } from './render/dom/notify-render'; -export { _wrapSignal, _wrapProp } from './state/signal'; -export { _restProps } from './state/store'; -export { _IMMUTABLE } from './state/constants'; -export { _weakSerialize } from './state/common'; -export { _deserializeData } from './container/resume'; -export { verifySerializable as _verifySerializable } from './state/common'; +export { _noopQrl, _noopQrlDEV, _regSymbol } from './shared/qrl/qrl'; +// ^ keep this above to avoid circular dependency issues + +export { + DomContainer as _DomContainer, + getDomContainer as _getDomContainer, +} from './client/dom-container'; +export { queueQRL as _run } from './client/queue-qrl'; +export type { + ContainerElement as _ContainerElement, + ElementVNode as _ElementVNode, + QDocument as _QDocument, + TextVNode as _TextVNode, + VirtualVNode as _VirtualVNode, + VNode as _VNode, + VNodeFlags as _VNodeFlags, +} from './client/types'; +export { vnode_toString as _vnode_toString } from './client/vnode'; +export { _wrapProp, _wrapSignal, _wrapStore } from './reactive-primitives/internal-api'; +export { SubscriptionData as _SubscriptionData } from './reactive-primitives/subscription-data'; +export { _EFFECT_BACK_REF } from './reactive-primitives/types'; +export { + isStringifiable as _isStringifiable, + type Stringifiable as _Stringifiable, +} from './shared-types'; +export { + isJSXNode as _isJSXNode, + _jsxC, + _jsxQ, + _jsxS, + _jsxSorted, + _jsxSplit, +} from './shared/jsx/jsx-runtime'; +export { _fnSignal } from './shared/qrl/inlined-fn'; +export { _SharedContainer } from './shared/shared-container'; +export { + _deserialize, + dumpState as _dumpState, + preprocessState as _preprocessState, + _serialize, + _addLoc, +} from './shared/shared-serialization'; +export { _CONST_PROPS, _IMMUTABLE, _VAR_PROPS } from './shared/utils/constants'; +export { EMPTY_ARRAY as _EMPTY_ARRAY } from './shared/utils/flyweight'; +export { _restProps } from './shared/utils/prop'; +export { + verifySerializable as _verifySerializable, + _weakSerialize, +} from './shared/utils/serialize-utils'; +export { _walkJSX } from './ssr/ssr-render-jsx'; export { _getContextElement, _getContextEvent, _jsxBranch, _waitUntilRendered, } from './use/use-core'; -export { _jsxQ, _jsxC, _jsxS } from './render/jsx/jsx-runtime'; -export { _fnSignal } from './qrl/inlined-fn'; +export { scheduleTask as _task } from './use/use-task'; diff --git a/packages/qwik/src/core/platform/types.ts b/packages/qwik/src/core/platform/types.ts deleted file mode 100644 index 2dd7fecec54..00000000000 --- a/packages/qwik/src/core/platform/types.ts +++ /dev/null @@ -1,107 +0,0 @@ -import type { ValueOrPromise } from '../util/types'; - -// -// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ./readme.md#CorePlatform instead) -/** - * Low-level API for platform abstraction. - * - * Different 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. - * - * `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. - * - * This is a low-level API and there should not be a need for you to access this. - * - * @public - */ -// -export interface CorePlatform { - // - // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! - // (edit ./readme.md#CorePlatform.isServer instead) - /** - * True of running on the server platform. - * - * @returns True if we are running on the server (not the browser.) - */ - // - isServer: boolean; - // - // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! - // (edit ./readme.md#CorePlatform.importSymbol instead) - /** - * Retrieve a symbol value from QRL. - * - * Qwik 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`. - * - * Why 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. - * - * @param element - The element against which the `url` is resolved. Used to locate the container - * root and `q:base` attribute. - * @param url - Relative URL retrieved from the attribute that needs to be resolved against the - * container `q:base` attribute. - * @param symbol - The name of the symbol to import. - * @returns A promise that resolves to the imported symbol. - */ - // - importSymbol: ( - containerEl: Element | undefined, - url: string | URL | undefined | null, - symbol: string - ) => ValueOrPromise; - // - // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! - // (edit ./readme.md#CorePlatform.raf instead) - /** - * Perform operation on next request-animation-frame. - * - * @param fn - The function to call when the next animation frame is ready. - */ - // - raf: (fn: () => any) => Promise; - // - // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! - // (edit ./readme.md#CorePlatform.nextTick instead) - /** - * Perform operation on next tick. - * - * @param fn - The function to call when the tick is ready. - */ - // - nextTick: (fn: () => any) => Promise; - // - // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! - // (edit ./readme.md#CorePlatform.chunkForSymbol instead) - /** - * Retrieve chunk name for the symbol. - * - * When 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.) - * - * @param symbolName - Resolve `symbolName` against the manifest and return the chunk that - * contains the symbol. - */ - // - chunkForSymbol: ( - symbolName: string, - chunk: string | null, - parent?: string - ) => readonly [symbol: string, chunk: string] | undefined; -} - -export interface CorePlatformServer extends CorePlatform { - isServer: true; -} diff --git a/packages/qwik/src/core/preloader/bundle-graph.ts b/packages/qwik/src/core/preloader/bundle-graph.ts index 555db389288..8f82640cf2b 100644 --- a/packages/qwik/src/core/preloader/bundle-graph.ts +++ b/packages/qwik/src/core/preloader/bundle-graph.ts @@ -1,4 +1,4 @@ -import { isBrowser } from '@builder.io/qwik/build'; +import { isBrowser } from '@qwik.dev/core/build'; import { config, doc } from './constants'; import { adjustProbabilities, bundles, log, shouldResetFactor, trigger } from './queue'; import type { BundleGraph, BundleImport, ImportProbability } from './types'; diff --git a/packages/qwik/src/core/preloader/constants.ts b/packages/qwik/src/core/preloader/constants.ts index e05264d7580..f4cfa48079a 100644 --- a/packages/qwik/src/core/preloader/constants.ts +++ b/packages/qwik/src/core/preloader/constants.ts @@ -1,9 +1,7 @@ -import { isBrowser } from '@builder.io/qwik/build'; +import { isBrowser } from '@qwik.dev/core/build'; // Browser-specific setup export const doc = isBrowser ? document : undefined!; -export const modulePreloadStr = 'modulepreload'; -export const preloadStr = 'preload'; export const config = { $DEBUG$: false, @@ -13,9 +11,9 @@ export const config = { // Determine which rel attribute to use based on browser support export const rel = - isBrowser && doc.createElement('link').relList.supports(modulePreloadStr) - ? modulePreloadStr - : preloadStr; + isBrowser && doc.createElement('link').relList.supports('modulepreload') + ? 'modulePreload' + : 'preload'; // Global state export const loadStart = Date.now(); diff --git a/packages/qwik/src/core/preloader/index.ts b/packages/qwik/src/core/preloader/index.ts index 77a4eb55455..8a4b411dd53 100644 --- a/packages/qwik/src/core/preloader/index.ts +++ b/packages/qwik/src/core/preloader/index.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-console */ /** * Note: this file gets built separately from the rest of the core module, and is then kept separate * in the dist directory via manualChunks. This way it can run before the rest of the core module is diff --git a/packages/qwik/src/core/preloader/preloader.unit.ts b/packages/qwik/src/core/preloader/preloader.unit.ts index 97e2f2144fa..0c8a19daa11 100644 --- a/packages/qwik/src/core/preloader/preloader.unit.ts +++ b/packages/qwik/src/core/preloader/preloader.unit.ts @@ -21,6 +21,6 @@ test('preloader script', () => { * dereference objects etc, but that actually results in worse compression */ const compressed = compress(Buffer.from(preLoader), { mode: 1, quality: 11 }); - expect(compressed.length).toBe(1716); - expect(preLoader.length).toBe(5114); + expect(compressed.length).toBe(1709); + expect(preLoader.length).toBe(5037); }); diff --git a/packages/qwik/src/core/preloader/queue.ts b/packages/qwik/src/core/preloader/queue.ts index edc7ec33b4a..94b999c719e 100644 --- a/packages/qwik/src/core/preloader/queue.ts +++ b/packages/qwik/src/core/preloader/queue.ts @@ -1,4 +1,4 @@ -import { isBrowser } from '@builder.io/qwik/build'; +import { isBrowser } from '@qwik.dev/core/build'; import { base, getBundle, graph } from './bundle-graph'; import { config, doc, loadStart, rel } from './constants'; import type { BundleImport, BundleImports } from './types'; diff --git a/packages/qwik/src/core/qrl/inlined-fn.ts b/packages/qwik/src/core/qrl/inlined-fn.ts deleted file mode 100644 index 9a742bca716..00000000000 --- a/packages/qwik/src/core/qrl/inlined-fn.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { assertDefined } from '../error/assert'; -import { SignalDerived } from '../state/signal'; -import { qSerialize } from '../util/qdev'; - -/** @internal */ -export const _fnSignal = any>( - fn: T, - args: Parameters, - fnStr?: string -) => { - return new SignalDerived, Parameters>(fn, args, fnStr); -}; - -export const serializeDerivedSignalFunc = (signal: SignalDerived) => { - const fnBody = qSerialize ? signal.$funcStr$ : 'null'; - assertDefined(fnBody, 'If qSerialize is true then fnStr must be provided.'); - let args = ''; - for (let i = 0; i < signal.$args$.length; i++) { - args += `p${i},`; - } - return `(${args})=>(${fnBody})`; -}; diff --git a/packages/qwik/src/core/qrl/qrl-class.ts b/packages/qwik/src/core/qrl/qrl-class.ts deleted file mode 100644 index 5f73755f45f..00000000000 --- a/packages/qwik/src/core/qrl/qrl-class.ts +++ /dev/null @@ -1,297 +0,0 @@ -import { assertDefined } from '../error/assert'; -import { qError, QError_qrlIsNotFunction } from '../error/error'; -import { getPlatform, isServerPlatform } from '../platform/platform'; -import { verifySerializable } from '../state/common'; -import { isSignal, type SignalInternal } from '../state/signal'; -import { - invoke, - newInvokeContext, - newInvokeContextFromTuple, - tryGetInvokeContext, - type InvokeContext, - type InvokeTuple, -} from '../use/use-core'; -import { getQFuncs, QInstance } from '../util/markers'; -import { isPromise, maybeThen } from '../util/promises'; -import { qDev, qSerialize, qTest, seal } from '../util/qdev'; -import { isArray, isFunction, type ValueOrPromise } from '../util/types'; -// @ts-expect-error we don't have types for the preloader -import { p as preload } from '@builder.io/qwik/preloader'; -import type { QRLDev } from './qrl'; -import type { QRL, QrlArgs, QrlReturn } from './qrl.public'; -import { isBrowser } from '@builder.io/qwik/build'; - -export const isQrl = (value: unknown): value is QRLInternal => { - return typeof value === 'function' && typeof (value as any).getSymbol === 'function'; -}; - -// Make sure this value is same as value in `platform.ts` -export const SYNC_QRL = ''; - -/** Sync QRL is a function which is serialized into ` will escape the content, effectively breaking the inlined JS. -In order to disable content escaping use ' - , - ` - - - - ` - ); -}); - -test('single complex children', async () => { - await testSSR( -
-

hola

-
, - '

hola

', - { - containerTagName: 'container', - } - ); - await testSSR( -
- hola {2} -

hola

-
, - '
hola 2

hola

', - { - containerTagName: 'container', - } - ); -}); - -test('single multiple children', async () => { - await testSSR( -
    -
  • 1
  • -
  • 2
  • -
  • 3
  • -
  • 4
  • -
  • 5
  • -
  • 6
  • -
  • 7
  • -
  • 8
  • -
, - '
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
', - { - containerTagName: 'container', - } - ); -}); - -test('sanity', async () => { - await testSSR( - -
{`.rule > thing{}`}
- , - ` - -
.rule > thing{}
- - ` - ); -}); - -test('using fragment', async () => { - await testSSR( -
    - <> -
  • 1
  • -
  • 2
  • - -
  • 3
  • - <> -
  • 4
  • - <> -
  • 5
  • - <> - <> -
  • 6
  • - - - -
  • 7
  • - -
  • 8
  • -
, - '
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
', - { - containerTagName: 'container', - } - ); -}); - -test('using promises', async () => { - await testSSR( - {Promise.resolve('hola')}, - 'hola' - ); - await testSSR( - {Promise.resolve(

hola

)}, - '

hola

' - ); - - await testSSR( -
    - {Promise.resolve(
  • 1
  • )} -
  • 2
  • - {delay(100).then(() => ( -
  • 3
  • - ))} - {delay(10).then(() => ( -
  • 4
  • - ))} -
, - [ - '', - '
    ', - '', - '
  • ', - '1', - '
  • ', - '
  • ', - '2', - '
  • ', - '', - '
  • ', - '3', - '
  • ', - '', - '
  • ', - '4', - '
  • ', - '
', - '
', - ], - { - containerTagName: 'container', - } - ); -}); - -test('mixed children', async () => { - await testSSR( -
    -
  • 0
  • -
  • 1
  • -
  • 2
  • - {Promise.resolve(
  • 3
  • )} -
  • 4
  • - {delay(100).then(() => ( -
  • 5
  • - ))} - {delay(10).then(() => ( -
  • 6
  • - ))} -
, - ` - -
    -
  • 0
  • -
  • 1
  • -
  • 2
  • - -
  • 3
  • -
  • 4
  • - -
  • 5
  • - -
  • 6
  • -
-
`, - { - containerTagName: 'container', - } - ); -}); - -test('DelayResource', async () => { - await testSSR( - -
    - - -
- , - ` - -
    - - -
    thing
    - - -
    thing
    - -
- - ` - ); -}); - -test('using promises with DelayResource', async () => { - await testSSR( - -
    - {delay(10).then(() => ( -
  • thing
  • - ))} - -
- , - ` - -
    - -
  • thing
  • - - -
    thing
    - -
- - ` - ); -}); - -test('using component', async () => { - await testSSR( - , - ` - -
MyCmp{}
- -
`, - { - containerTagName: 'container', - } - ); -}); - -test('using component with key', async () => { - await testSSR( - - - , - ` - - -
MyCmp{}
- - - ` - ); -}); - -test('using element with key', async () => { - await testSSR( - -
- , - ` - -
- - ` - ); -}); - -test('using element with key containing double quotes', async () => { - await testSSR( - -
- , - ` - -
- - ` - ); -}); - -test('using component props', async () => { - await testSSR( - - stuff - , - ` - - -
-
MyCmp{"id":"12","host:prop":"attribute","innerHTML":"123","dangerouslySetInnerHTML":"432","onClick":"lazy.js","prop":"12"}
-
- - -
- `, - { - containerTagName: 'container', - } - ); -}); - -test('using component project content', async () => { - await testSSR( - -
slot
-
, - ` - - -
MyCmp{}
- - -
-`, - { - containerTagName: 'container', - } - ); -}); - -test('using complex component', async () => { - await testSSR( - - - , - ` - - -
- - -
- - - ` - ); -}); - -test('using complex component with slot', async () => { - await testSSR( - Hola, - ` - - -
- - - Hola - -
- -
`, - { - containerTagName: 'container', - } - ); -}); - -test('', async () => { - await testSSR( - - hola - <> - - - , - ` - - - hola - - - ` - ); -}); - -test('named slots', async () => { - await testSSR( - - Text -
START: 1
- <> -
END: 1
- from -
START: 2
- -
END: 2
- default -
, - ` - - -
- -
START: 1
-
START: 2
- -
Textfromdefault
- -
END: 1
-
END: 2
- -
- -
-`, - { - containerTagName: 'container', - } - ); -}); - -test('nested slots', async () => { - await testSSR( - - - - BEFORE CONTENT -
Content
- AFTER CONTENT -
-
-
, - ` - - -
- Before root - - -
- Before level 1 - - -
- Before level 2 - - BEFORE CONTENT -
Content
- AFTER CONTENT - - After level 2 -
- - - After level 1 -
- - - After root -
- -
`, - { - containerTagName: 'container', - } - ); -}); - -test('mixes slots', async () => { - await testSSR( - Content, - ` - - - -
Before 1 - - - Content - - - After 1 -
- - -
`, - { - containerTagName: 'container', - } - ); -}); - -test('component RenderSignals()', async () => { - vi.spyOn(console, 'warn'); - await testSSR( - , - ` - - - - value - - - - - ` - ); - expect(console.warn).toHaveBeenCalledTimes(2); -}); - -test('component useContextProvider()', async () => { - await testSSR( - - - , - ` - - - hello bye - - hello bye - - ` - ); -}); - -test('component useContextProvider() + useContext()', async () => { - await testSSR( - , - ` - hello bye - ` - ); -}); - -test('component slotted context', async () => { - await testSSR( - - - - - - - , - ` - - - - - - - - start - - - - - - - - - default - - - - - - - - - end - - - - - - - ` - ); -}); - -test('component useOn()', async () => { - await testSSR( - - - , - ` - - -
- - - ` - ); -}); - -test('component useOn([array])', async () => { - await testSSR( - - - , - ` - - - -
- - - ` - ); -}); - -test('component useStyles()', async () => { - await testSSR( - <> - - - - , - ` - - - -
- Text -
- - - ` - ); -}); - -test('component useStylesScoped()', async () => { - await testSSR( - <> - - -
projected
-
- - , - ` - - - - - -
-
- Scoped1 - -
projected
- -

Que tal?

-
- - -
-
- Scoped2 -

Bien

-
-
- - -
-
- Scoped2 -

Bien

-
-
- -
- - - - ` - ); -}); - -test('component useStylesScoped() + slot', async () => { - await testSSR( - <> - - , - ` - - - - - -
- -
One
- -
- - - - - - ` - ); -}); - -test('component useBrowserVisibleTask()', async () => { - await testSSR( - , - ` - -
- -
`, - { - containerTagName: 'container', - } - ); -}); - -test('component useBrowserVisibleTask() without elements', async () => { - await testSSR( - - - , - ` - - - - Hola - - - - - ` - ); -}); - -test('component useBrowserVisibleTask() inside ', async () => { - await testSSR( - - - - , - ` - - - - Hola - - - - - - - ` - ); -}); - -test('nested html', async () => { - await testSSR( - <> - - , - `` - ); -}); - -test('root html component', async () => { - await testSSR( - - - , - ` - - - - hola - - - - - - - ` - ); -}); - -test('containerTagName', async () => { - await testSSR( - <> - - -
- , - ` - - - -
Text
- - -
- -
-
`, - { - containerTagName: 'container', - base: '/manu/folder', - beforeContent: [jsx('link', { rel: 'stylesheet', href: '/global.css' })], - } - ); -}); - -test('containerAttributes', async () => { - await testSSR( - <> - - , - ` - - - - `, - { - containerAttributes: { - prefix: 'something', - }, - } - ); - await testSSR( - <> -
- , - ` - -
-
- `, - { - containerTagName: 'app', - containerAttributes: { - prefix: 'something', - class: 'thing', - }, - } - ); -}); - -test('custom q:render', async () => { - await testSSR( - <> - - , - ` - - - - `, - { - containerAttributes: { - 'q:render': 'static', - }, - } - ); - await testSSR( - <> - - , - ` - - - - `, - { - containerAttributes: { - 'q:render': '', - }, - } - ); -}); - -test('ssr marks', async () => { - await testSSR( - - {delay(100).then(() => ( -
  • 1
  • - ))} - {delay(10).then(() => ( -
  • 2
  • - ))} - -
    - -
    - {delay(120).then(() => ( -
  • 3
  • - ))} - , - ` - - -
  • 1
  • - -
  • 2
  • - -
    - -
    - -
  • 3
  • - - ` - ); -}); - -test('ssr raw', async () => { - await testSSR( - - - , - ` - - -
    hello
    - - ` - ); -}); - -test('html fragment', async () => { - await testSSR( - - - , - ` - - - -
    hello
    - - - ` - ); -}); - -test('html slot', async () => { - await testSSR( - - - - Qwik - - -
    - -
    , - ` - - - - - - Qwik - - - - -
    - - - - `, - { - beforeContent: [jsx('link', { rel: 'stylesheet', href: '/global.css' })], - base: '/manu/folder', - } - ); -}); - -test('null component', async () => { - await testSSR( - <> - - , - `` - ); -}); - -test('cleanse attribute name', async () => { - const o = { - '">': 'xss', - }; - await testSSR( - , - '' - ); -}); - -test('cleanse class attribute', async () => { - const o = { - class: '">', - }; - await testSSR( - , - '' - ); -}); - -test('class emoji valid', async () => { - const o = { - class: 'package📦', - }; - await testSSR( - , - '' - ); -}); - -test('issue 4283', async () => { - await testSSR( - - -

    index page

    -
    - , - ` - - - - -
    - - - - - - ` - ); -}); - -// TODO -// Merge props on host -// - host events -// - class -// - style -// Container with tagName -// End-to-end with qwikcity -// SVG rendering -// Performance metrics - -export const MyCmp = component$((props: Record) => { - return ( -
    -
    - MyCmp - {JSON.stringify(props)} -
    -
    - ); -}); - -export const MyCmpComplex = component$(() => { - const ref = useSignal(); - return ( -
    console.warn('from component')}> - - -
    - ); -}); - -export const SimpleSlot = component$((props: { name: string }) => { - return ( -
    - Before {props.name} - - After {props.name} -
    - ); -}); - -export const MixedSlot = component$(() => { - return ( - - - - ); -}); - -export const NamedSlot = component$(() => { - return ( -
    - -
    - -
    - -
    - ); -}); - -export const Events = component$(() => { - useOn( - 'click', - $(() => console.warn('click')) - ); - useOnWindow( - 'click', - $(() => console.warn('window:click')) - ); - useOnDocument( - 'click', - $(() => console.warn('document:click')) - ); - - return
    console.warn('scroll')}>
    ; -}); - -export const UseOnMultiple = component$(() => { - useOn( - ['click', 'scroll'], - $(() => console.warn('click or scroll')) - ); - useOnWindow( - ['click', 'scroll'], - $(() => console.warn('window:click or scroll')) - ); - useOnDocument( - ['click', 'scroll'], - $(() => console.warn('document:click or scroll')) - ); - - return
    console.warn('scroll')}>
    ; -}); - -export const Styles = component$(() => { - useStylesQrl(inlinedQrl('.host {color: red}', 'styles_987')); - - return
    Text
    ; -}); - -export const ScopedStyles1 = component$(() => { - useStylesScopedQrl(inlinedQrl('.host {color: red}', 'styles_scoped_1')); - useStylesScopedQrl(inlinedQrl('.blue {color: blue}', 'styles_scoped_2')); - - return ( -
    -
    - Scoped1 - -

    Que tal?

    -
    - - -
    - ); -}); - -export const ScopedStyles2 = component$(() => { - useStylesScopedQrl(inlinedQrl('.host {color: blue}', '20_styles_scoped')); - - return ( -
    -
    - Scoped2 -

    Bien

    -
    -
    - ); -}); - -export const RootStyles = component$(() => { - useStylesScopedQrl(inlinedQrl('.host {background: blue}', '20_stylesscopedblue')); - - return ( - - -
    One
    -
    Two
    -
    - - ); -}); - -export const ComponentA = component$(() => { - useStylesScopedQrl(inlinedQrl('.host {background: green}', '20_stylesscopedgreen')); - - return ( -
    - -
    - ); -}); - -const CTX_INTERNAL = createContextId<{ value: string }>('internal'); -const CTX_QWIK_CITY = createContextId<{ value: string }>('qwikcity'); -const CTX_VALUE = createContextId<{ value: string }>('value'); - -export const VariadicContext = component$(() => { - return ( - <> - - - - - - - - - - - ); -}); - -export const ReadValue = component$(() => { - const ctx = useContext(CTX_VALUE); - return {ctx.value}; -}); - -export const ContextWithValue = component$((props: { value: string }) => { - const value = { - value: props.value, - }; - useContextProvider(CTX_VALUE, value); - return ( - <> - - - ); -}); - -export const ContextWithValueAndUse = component$((props: { value: string }) => { - const value = { - value: props.value, - }; - useContextProvider(CTX_VALUE, value); - const ctx = useContext(CTX_VALUE); - return <>{ctx.value}; -}); - -export const Context = component$(() => { - useContextProvider(CTX_INTERNAL, { - value: 'hello', - }); - useContextProvider(CTX_QWIK_CITY, { - value: 'bye', - }); - return ( - <> - - - - ); -}); - -export const ContextConsumer = component$(() => { - const internal = useContext(CTX_INTERNAL); - const qwikCity = useContext(CTX_QWIK_CITY); - - return ( - <> - {internal.value} {qwikCity.value} - - ); -}); - -export const UseClientEffect = component$((props: any) => { - useVisibleTask$(() => { - console.warn('client effect'); - }); - useVisibleTask$(() => { - console.warn('second client effect'); - }); - useTask$(async () => { - await delay(10); - }); - - const Div = props.as ?? 'div'; - return
    ; -}); - -export const UseEmptyClientEffect = component$(() => { - useVisibleTask$(() => { - console.warn('client effect'); - }); - useVisibleTask$(() => { - console.warn('second client effect'); - }); - useTask$(async () => { - await delay(10); - }); - - return <>Hola; -}); - -export const HeadCmp = component$(() => { - useVisibleTask$(() => { - console.warn('client effect'); - }); - return ( - - hola - - - ); -}); - -export const RenderSignals = component$(() => { - const signal = useSignal('value'); - return ( - <> - - {signal.value} - - - - - ); -}); - -export const HtmlContext = component$(() => { - const store = useStore({}); - useStylesQrl(inlinedQrl(`body {background: blue}`, 'styles_DelayResource')); - useContextProvider(CTX_INTERNAL, store); - - return ; -}); - -async function testSSR( - node: JSXOutput, - expected: string | string[], - opts?: Partial -) { - let chunks: string[] = []; - const stream: StreamWriter = { - write(chunk) { - chunks.push(chunk); - }, - }; - await _renderSSR(node, { - stream, - containerTagName: 'html', - containerAttributes: {}, - manifestHash: 'test', - ...opts, - }); - chunks = chunks.map((c) => c.replace(/ q:instance="[^"]+"/, '')); - if (typeof expected === 'string') { - const options = { parser: 'html', htmlWhitespaceSensitivity: 'ignore' } as const; - expect(await format(chunks.join(''), options)).toBe( - await format(expected.replace(/(\n|^)\s+/gm, ''), options) - ); - } else { - expect(chunks).toEqual(expected); - } -} - -export const DelayResource = component$((props: { text: string; delay: number }) => { - useStylesQrl(inlinedQrl(`.cmp {background: blue}`, 'styles_DelayResource')); - - const resource = useResource$(async ({ track }) => { - track(() => props.text); - await delay(props.delay); - return props.text; - }); - return ( -
    - {value}} /> -
    - ); -}); - -export const NullCmp = component$(() => { - return null; -}); - -export const EffectTransparent = component$(() => { - useVisibleTask$(() => { - console.warn('log'); - }); - return ; -}); - -export const EffectTransparentRoot = component$(() => { - useVisibleTask$(() => { - console.warn('log'); - }); - return ( - -
    Hello
    -
    - ); -}); - -export const HideUntilVisible = component$(() => { - const isNotVisible = useSignal(true); - - useVisibleTask$(() => { - if (isNotVisible.value) { - isNotVisible.value = false; - } - }); - - // NOTE: if you comment the line below, - // there will only be one "Content" - if (isNotVisible.value) { - return
    ; - } - - return ( -
    -

    Hide until visible

    - -
    - ); -}); - -export const Issue4283 = component$(() => { - return ( - -

    Content

    - -
    - ); -}); - -async function throws(fn: () => T, expected?: string | RegExp): Promise { - try { - await fn(); - expect.unreachable('Expression should throw'); - } catch (e) { - if (expected) { - expect(String(e)).toBe(expected); - } - } -} diff --git a/packages/qwik/src/core/render/sync-qrl.unit.tsx b/packages/qwik/src/core/render/sync-qrl.unit.tsx deleted file mode 100644 index b2b35510591..00000000000 --- a/packages/qwik/src/core/render/sync-qrl.unit.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { assert, suite, test } from 'vitest'; -import { createDOM } from '../../testing/library'; -import { sync$ } from '../qrl/qrl.public'; -import { renderToString } from '../../server/render'; - -suite('sync-qrl', () => { - test('default updates the checkbox', async () => { - const { screen, render } = await createDOM(); - await render(); - const input = screen.querySelector('input')!; - assert.equal(input.checked, false); - input.click(); - assert.equal(input.checked, true); - }); - - test('default prevents updates the checkbox', async () => { - const { screen, userEvent, render } = await createDOM(); - await render( - { - if (target.getAttribute('shouldPreventDefault')) { - e.preventDefault(); - } - target.setAttribute('prevented', String(e.defaultPrevented)); - }), - ]} - /> - ); - const input = screen.querySelector('input')!; - await userEvent(input, 'click'); - assert.equal(input.getAttribute('prevented'), 'false'); - input.setAttribute('shouldPreventDefault', 'true'); - await userEvent(input, 'click'); - assert.equal(input.getAttribute('prevented'), 'true'); - }); - - // Currently the testing does not support resuming from SSR - test.skip('render SSR', async () => { - const response = await renderToString( - , - { containerTagName: 'container' } - ); - - const { screen, userEvent } = await createDOM({ html: response.html }); - const input = screen.querySelector('input')!; - await userEvent(input, 'click'); - assert.equal(input.getAttribute('prevented'), 'false'); - input.setAttribute('shouldPreventDefault', 'true'); - await userEvent(input, 'click'); - assert.equal(input.getAttribute('prevented'), 'true'); - }); -}); diff --git a/packages/qwik/src/core/render/types.ts b/packages/qwik/src/core/render/types.ts deleted file mode 100644 index b67de4e8d1f..00000000000 --- a/packages/qwik/src/core/render/types.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { ContainerState } from '../container/container'; -import type { QContext } from '../state/context'; -import type { QwikElement } from './dom/virtual-element'; - -/** @public */ -export interface RenderOperation { - $operation$: (...args: any[]) => void; - $args$: any[]; -} - -/** @public */ -export interface RenderContext { - readonly $static$: RenderStaticContext; - /** Current Qwik component */ - $cmpCtx$: QContext | null; - /** Current Slot parent */ - $slotCtx$: QContext | undefined; -} - -export interface RenderStaticContext { - readonly $locale$: string; - readonly $doc$: Document; - readonly $roots$: QContext[]; - readonly $hostElements$: Set; - readonly $visited$: (Node | QwikElement)[]; - readonly $operations$: RenderOperation[]; - readonly $postOperations$: RenderOperation[]; - readonly $containerState$: ContainerState; - readonly $addSlots$: [QwikElement, QwikElement][]; - readonly $rmSlots$: QwikElement[]; -} - -// Polyfills for ViewTransition API & scroll restoration -declare global { - interface ViewTransition { - ready: Promise; - finished: Promise; - updateCallbackDone: Promise; - skipTransition: () => void; - } - - interface Document { - startViewTransition?: (callback: () => void | Promise) => ViewTransition; - __q_view_transition__?: true | undefined; - __q_scroll_restore__?: (() => void) | undefined; - } -} diff --git a/packages/qwik/src/core/shared-types.ts b/packages/qwik/src/core/shared-types.ts new file mode 100644 index 00000000000..bcadfe0c511 --- /dev/null +++ b/packages/qwik/src/core/shared-types.ts @@ -0,0 +1,14 @@ +/** @file Shared types */ + +/** @internal */ +export type Stringifiable = string | boolean | number | null; + +/** @internal */ +export function isStringifiable(value: unknown): value is Stringifiable { + return ( + value === null || + typeof value === 'string' || + typeof value === 'number' || + typeof value === 'boolean' + ); +} diff --git a/packages/qwik/src/core/shared/README.md b/packages/qwik/src/core/shared/README.md new file mode 100644 index 00000000000..fe194a37994 --- /dev/null +++ b/packages/qwik/src/core/shared/README.md @@ -0,0 +1,3 @@ +Contains code which is shared between server and client. + +(This means that the code con't depend on server or client specific API) diff --git a/packages/qwik/src/core/shared/component-execution.ts b/packages/qwik/src/core/shared/component-execution.ts new file mode 100644 index 00000000000..64a3f079962 --- /dev/null +++ b/packages/qwik/src/core/shared/component-execution.ts @@ -0,0 +1,269 @@ +import { isDev } from '@qwik.dev/core/build'; +import { vnode_isVNode } from '../client/vnode'; +import { Slot } from '../shared/jsx/slot.public'; +import { isSignal } from '../reactive-primitives/utils'; +import { clearAllEffects } from '../reactive-primitives/cleanup'; +import { invokeApply, newInvokeContext, untrack } from '../use/use-core'; +import { type EventQRL, type UseOnMap } from '../use/use-on'; +import { isQwikComponent, type OnRenderFn } from './component.public'; +import { assertDefined } from './error/assert'; +import { Fragment, JSXNodeImpl, _jsxSorted, isJSXNode, type Props } from './jsx/jsx-runtime'; +import type { JSXNodeInternal, JSXOutput } from './jsx/types/jsx-node'; +import type { KnownEventNames } from './jsx/types/jsx-qwik-events'; +import type { QRLInternal } from './qrl/qrl-class'; +import { isQrl } from './qrl/qrl-utils'; +import type { Container, HostElement } from './types'; +import { EMPTY_OBJ } from './utils/flyweight'; +import { logWarn } from './utils/log'; +import { + ELEMENT_PROPS, + ELEMENT_SEQ_IDX, + OnRenderProp, + RenderEvent, + USE_ON_LOCAL, + USE_ON_LOCAL_SEQ_IDX, +} from './utils/markers'; +import { MAX_RETRY_ON_PROMISE_COUNT, isPromise, maybeThen, safeCall } from './utils/promises'; +import type { ValueOrPromise } from './utils/types'; +import { getSubscriber } from '../reactive-primitives/subscriber'; +import { EffectProperty } from '../reactive-primitives/types'; + +/** + * Use `executeComponent` to execute a component. + * + * Component execution can be complex because of: + * + * - It can by async + * - It can contain many tasks which need to be awaited + * - Each task can run multiple times if they track signals which change. + * - The JSX may be re-generated multiple times of a task needs to be rerun due to signal change. + * - It needs to keep track of hook state. + * + * For `component$`: `renderHost` === `subscriptionHost` For inlined-components: the + * `subscriptionHost` is a parent `component$` which needs to re-execute. + * + * @param container + * @param renderHost - VNode into which the component is rendered into. + * @param subscriptionHost - VNode which will be re-executed if the component needs to re-render. + * @param componentQRL + * @param props + * @returns + */ +export const executeComponent = ( + container: Container, + renderHost: HostElement, + subscriptionHost: HostElement | null, + componentQRL: OnRenderFn | QRLInternal> | null, + props: Props | null +): ValueOrPromise => { + const iCtx = newInvokeContext( + container.$locale$, + subscriptionHost || undefined, + undefined, + RenderEvent + ); + if (subscriptionHost) { + iCtx.$effectSubscriber$ = getSubscriber(subscriptionHost, EffectProperty.COMPONENT); + iCtx.$container$ = container; + } + let componentFn: (props: unknown) => ValueOrPromise; + container.ensureProjectionResolved(renderHost); + let isInlineComponent = false; + if (componentQRL === null) { + componentQRL = container.getHostProp(renderHost, OnRenderProp)!; + assertDefined(componentQRL, 'No Component found at this location'); + } + if (isQrl(componentQRL)) { + props = props || container.getHostProp(renderHost, ELEMENT_PROPS) || EMPTY_OBJ; + if (props.children) { + delete props.children; + } + componentFn = componentQRL.getFn(iCtx); + } else if (isQwikComponent(componentQRL)) { + const qComponentFn = componentQRL as any as ( + props: Props, + key: string | null, + flags: number + ) => JSXNodeInternal; + componentFn = () => invokeApply(iCtx, qComponentFn, [props || EMPTY_OBJ, null, 0]); + } else { + isInlineComponent = true; + const inlineComponent = componentQRL as (props: Props) => JSXOutput; + componentFn = () => invokeApply(iCtx, inlineComponent, [props || EMPTY_OBJ]); + } + + const executeComponentWithPromiseExceptionRetry = (retryCount = 0): ValueOrPromise => + safeCall( + () => { + if (!isInlineComponent) { + container.setHostProp(renderHost, ELEMENT_SEQ_IDX, null); + container.setHostProp(renderHost, USE_ON_LOCAL_SEQ_IDX, null); + container.setHostProp(renderHost, ELEMENT_PROPS, props); + } + + if (vnode_isVNode(renderHost)) { + clearAllEffects(container, renderHost); + } + + return componentFn(props); + }, + (jsx) => { + const useOnEvents = container.getHostProp(renderHost, USE_ON_LOCAL); + if (useOnEvents) { + return addUseOnEvents(jsx, useOnEvents); + } + return jsx; + }, + (err) => { + if (isPromise(err) && retryCount < MAX_RETRY_ON_PROMISE_COUNT) { + return err.then(() => + executeComponentWithPromiseExceptionRetry(retryCount++) + ) as Promise; + } else { + throw err; + } + } + ); + return executeComponentWithPromiseExceptionRetry(); +}; + +/** + * Stores the JSX output of the last execution of the component. + * + * Component can execute multiple times because: + * + * - Component can have multiple tasks + * - Tasks can track signals + * - Task A can change signal which causes Task B to rerun. + * + * So when executing a component we only care about its last JSX Output. + */ + +function addUseOnEvents( + jsx: JSXOutput, + useOnEvents: UseOnMap +): ValueOrPromise | null | JSXOutput> { + const jsxElement = findFirstStringJSX(jsx); + let jsxResult = jsx; + return maybeThen(jsxElement, (jsxElement) => { + let isInvisibleComponent = false; + if (!jsxElement) { + /** + * We did not find any jsx node with a string tag. This means that we should append: + * + * ```html + * + * ``` + * + * This is needed because use on events should have a node to attach them to. + */ + isInvisibleComponent = true; + } + for (const key in useOnEvents) { + if (Object.prototype.hasOwnProperty.call(useOnEvents, key)) { + if (isInvisibleComponent) { + if (key === 'onQvisible$') { + const [jsxElement, jsx] = addScriptNodeForInvisibleComponents(jsxResult); + jsxResult = jsx; + if (jsxElement) { + addUseOnEvent(jsxElement, 'document:onQinit$', useOnEvents[key]); + } + } else if (key.startsWith('document:') || key.startsWith('window:')) { + const [jsxElement, jsx] = addScriptNodeForInvisibleComponents(jsxResult); + jsxResult = jsx; + if (jsxElement) { + addUseOnEvent(jsxElement, key, useOnEvents[key]); + } + } else if (isDev) { + logWarn( + 'You are trying to add an event "' + + key + + '" using `useOn` hook, ' + + 'but a node to which you can add an event is not found. ' + + 'Please make sure that the component has a valid element node. ' + ); + } + } else if (jsxElement) { + addUseOnEvent(jsxElement, key, useOnEvents[key]); + } + } + } + return jsxResult; + }); +} + +function addUseOnEvent( + jsxElement: JSXNodeInternal, + key: string, + value: EventQRL[] +) { + let props = jsxElement.props; + if (props === EMPTY_OBJ) { + props = jsxElement.props = {}; + } + let propValue = props[key] as UseOnMap['any'] | UseOnMap['any'][0] | undefined; + if (propValue === undefined) { + propValue = []; + } else if (!Array.isArray(propValue)) { + propValue = [propValue]; + } + propValue.push(...value); + props[key] = propValue; +} + +function findFirstStringJSX(jsx: JSXOutput): ValueOrPromise | null> { + const queue: any[] = [jsx]; + while (queue.length) { + const jsx = queue.shift(); + if (isJSXNode(jsx)) { + if (typeof jsx.type === 'string') { + return jsx as JSXNodeInternal; + } + queue.push(jsx.children); + } else if (Array.isArray(jsx)) { + queue.push(...jsx); + } else if (isPromise(jsx)) { + return maybeThen | null>(jsx, (jsx) => + findFirstStringJSX(jsx) + ); + } else if (isSignal(jsx)) { + return findFirstStringJSX(untrack(() => jsx.value as JSXOutput)); + } + } + return null; +} + +function addScriptNodeForInvisibleComponents( + jsx: JSXOutput +): [JSXNodeInternal | null, JSXOutput | null] { + if (isJSXNode(jsx)) { + const jsxElement = new JSXNodeImpl( + 'script', + {}, + { + type: 'placeholder', + hidden: '', + }, + null, + 3 + ); + if (jsx.type === Slot) { + return [jsxElement, _jsxSorted(Fragment, null, null, [jsx, jsxElement], 0, null)]; + } + + if (jsx.children == null) { + jsx.children = jsxElement; + } else if (Array.isArray(jsx.children)) { + jsx.children.push(jsxElement); + } else { + jsx.children = [jsx.children, jsxElement]; + } + return [jsxElement, jsx]; + } else if (Array.isArray(jsx) && jsx.length) { + // get first element + const [jsxElement, _] = addScriptNodeForInvisibleComponents(jsx[0]); + return [jsxElement, jsx]; + } + + return [null, null]; +} diff --git a/packages/qwik/src/core/shared/component.public.ts b/packages/qwik/src/core/shared/component.public.ts new file mode 100644 index 00000000000..cd9e29c69c8 --- /dev/null +++ b/packages/qwik/src/core/shared/component.public.ts @@ -0,0 +1,214 @@ +import { dollar, type QRL } from './qrl/qrl.public'; +import type { JSXNodeInternal, JSXOutput } from './jsx/types/jsx-node'; +import type { + ComponentBaseProps, + EventHandler, + JSXChildren, + QRLEventHandlerMulti, +} from './jsx/types/jsx-qwik-attributes'; +import type { FunctionComponent } from './jsx/types/jsx-node'; +import { _jsxSplit } from '../internal'; +import type { QwikIntrinsicElements } from './jsx/types/jsx-qwik-elements'; +import { assertNumber } from './error/assert'; +import { qTest } from './utils/qdev'; +import { assertQrl } from './qrl/qrl-utils'; + +// TS way to check for any +type IsAny = 0 extends T & 1 ? true : false; + +type ObjectProps = + IsAny extends true + ? any + : // unknown means we don't accept any props + unknown extends T + ? never + : T extends Record + ? T + : never; + +/** + * Infers `Props` from the component or tag. + * + * @example + * + * ```tsx + * const Desc = component$(({desc, ...props}: { desc: string } & PropsOf<'div'>) => { + * return
    {desc}
    ; + * }); + * + * const TitleBox = component$(({title, ...props}: { title: string } & PropsOf) => { + * return

    {title}

    ; + * }); + * ``` + * + * @public + */ +// +export type PropsOf = COMP extends string + ? COMP extends keyof QwikIntrinsicElements + ? QwikIntrinsicElements[COMP] + : // `` has no special attributes + QwikIntrinsicElements['span'] + : NonNullable extends never + ? never + : COMP extends FunctionComponent + ? PROPS extends Record + ? IsAny extends true + ? // we couldn't figure it out + never + : ObjectProps + : COMP extends Component + ? ObjectProps + : // something complex, just return as-is + PROPS + : never; + +/** + * Type representing the Qwik component. + * + * `Component` is the type returned by invoking `component$`. + * + * ```tsx + * interface MyComponentProps { + * someProp: string; + * } + * const MyComponent: Component = component$((props: MyComponentProps) => { + * return {props.someProp}; + * }); + * ``` + * + * @public + */ +// In reality, Component is a QRL but that makes the types too complex +export type Component = FunctionComponent>; + +export type ComponentChildren = PROPS extends { + children: any; +} + ? never + : { children?: JSXChildren }; +/** + * Extends the defined component PROPS, adding the default ones (children and q:slot) and allowing + * plain functions to QRL arguments. + * + * @public + */ +export type PublicProps = + // Use Omit + _Only$ so that inferring polymorpic components works + // Mapping the entire PROPS doesn't work, maybe TS doesn't like inferring through conditional types + (PROPS extends Record + ? Omit & _Only$ + : unknown extends PROPS + ? {} + : PROPS) & + ComponentBaseProps & + ComponentChildren; + +type _AllowPlainQrl = + // QRLEventHandlerMulti gets a special case to simplify the result + // It needs to be handled carefully because it matches regular functions too + QRLEventHandlerMulti extends Q + ? Q extends QRLEventHandlerMulti + ? + | Q + // It can infer unknown and that breaks things + | (EL extends Element ? EventHandler : never) + : Q + : Q extends QRL + ? Q | U + : NonNullable extends never + ? Q + : QRL | Q; + +type _Only$

    = { + [K in keyof P as K extends `${string}$` ? K : never]: _AllowPlainQrl; +}; + +/** @internal */ +export const componentQrl = >( + componentQrl: QRL> +): Component => { + // Return a QComponent Factory function. + function QwikComponent( + props: PublicProps, + key: string | null, + flags: number = 0 + ): JSXNodeInternal { + assertQrl(componentQrl); + assertNumber(flags, 'The Qwik Component was not invoked correctly'); + const hash = qTest ? 'sX' : componentQrl.$hash$.slice(0, 4); + const finalKey = hash + ':' + (key ? key : ''); + const InnerCmp = () => {}; + (InnerCmp as any)[SERIALIZABLE_STATE] = [componentQrl]; + return _jsxSplit(InnerCmp as any, props, null, props.children, flags, finalKey); + } + (QwikComponent as any)[SERIALIZABLE_STATE] = [componentQrl]; + return QwikComponent as any; +}; + +export const SERIALIZABLE_STATE = Symbol('serializable-data'); + +export const isQwikComponent = >(component: unknown): component is T => { + return typeof component == 'function' && (component as any)[SERIALIZABLE_STATE] !== undefined; +}; + +// +// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! +// (edit ../readme.md#component instead and run `pnpm docs.sync`) +/** + * Declare a Qwik component that can be used to create UI. + * + * Use `component$` to declare a Qwik component. A Qwik component is a special kind of component + * that allows the Qwik framework to lazy load and execute the component independently of other Qwik + * components as well as lazy load the component's life-cycle hooks and event handlers. + * + * Side note: You can also declare regular (standard JSX) components that will have standard + * synchronous behavior. + * + * Qwik component is a facade that describes how the component should be used without forcing the + * implementation of the component to be eagerly loaded. A minimum Qwik definition consists of: + * + * ### Example + * + * An example showing how to create a counter component: + * + * ```tsx + * export interface CounterProps { + * initialValue?: number; + * step?: number; + * } + * export const Counter = component$((props: CounterProps) => { + * const state = useStore({ count: props.initialValue || 0 }); + * return ( + *

    + * {state.count} + * + *
    + * ); + * }); + * ``` + * + * - `component$` is how a component gets declared. + * - `{ value?: number; step?: number }` declares the public (props) interface of the component. + * - `{ count: number }` declares the private (state) interface of the component. + * + * The above can then be used like so: + * + * ```tsx + * export const OtherComponent = component$(() => { + * return ; + * }); + * ``` + * + * See also: `component`, `useCleanup`, `onResume`, `onPause`, `useOn`, `useOnDocument`, + * `useOnWindow`, `useStyles` + * + * @public + */ +// +export const component$ = (onMount: OnRenderFn): Component => { + return componentQrl(dollar(onMount)); +}; + +/** @public */ +export type OnRenderFn = (props: PROPS) => JSXOutput; diff --git a/packages/qwik/src/core/shared/error/assert.ts b/packages/qwik/src/core/shared/error/assert.ts new file mode 100644 index 00000000000..c0220ca6919 --- /dev/null +++ b/packages/qwik/src/core/shared/error/assert.ts @@ -0,0 +1,74 @@ +import { throwErrorAndStop } from '../utils/log'; +import { qDev } from '../utils/qdev'; + +const ASSERT_DISCLAIMER = 'Internal assert, this is likely caused by a bug in Qwik: '; + +export function assertDefined( + value: T, + text: string, + ...parts: any[] +): asserts value is NonNullable { + if (qDev) { + if (value != null) { + return; + } + throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts); + } +} + +export function assertEqual( + value1: any, + value2: any, + text: string, + ...parts: any[] +): asserts value1 is typeof value2 { + if (qDev) { + if (value1 === value2) { + return; + } + throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts); + } +} + +export function assertFail(text: string, ...parts: any[]): never; +export function assertFail(text: string, ...parts: any[]) { + if (qDev) { + throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts); + } +} + +export function assertTrue(value1: any, text: string, ...parts: any[]): asserts value1 is true { + if (qDev) { + if (value1 === true) { + return; + } + throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts); + } +} + +export function assertFalse(value1: any, text: string, ...parts: any[]): asserts value1 is true { + if (qDev) { + if (value1 === false) { + return; + } + throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts); + } +} + +export function assertNumber(value1: any, text: string, ...parts: any[]): asserts value1 is number { + if (qDev) { + if (typeof value1 === 'number') { + return; + } + throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts); + } +} + +export function assertString(value1: any, text: string, ...parts: any[]): asserts value1 is string { + if (qDev) { + if (typeof value1 === 'string') { + return; + } + throwErrorAndStop(ASSERT_DISCLAIMER + text, ...parts); + } +} diff --git a/packages/qwik/src/core/shared/error/error-handling.ts b/packages/qwik/src/core/shared/error/error-handling.ts new file mode 100644 index 00000000000..cb2701fa25b --- /dev/null +++ b/packages/qwik/src/core/shared/error/error-handling.ts @@ -0,0 +1,17 @@ +import { createContextId } from '../../use/use-context'; + +/** @public */ +export interface ErrorBoundaryStore { + error: any | undefined; +} + +export const ERROR_CONTEXT = /*#__PURE__*/ createContextId('qk-error'); + +export const isRecoverable = (err: any) => { + if (err && err instanceof Error) { + if ('plugin' in err) { + return false; + } + } + return true; +}; diff --git a/packages/qwik/src/core/shared/error/error.ts b/packages/qwik/src/core/shared/error/error.ts new file mode 100644 index 00000000000..80b37de8fe0 --- /dev/null +++ b/packages/qwik/src/core/shared/error/error.ts @@ -0,0 +1,134 @@ +import { logErrorAndStop } from '../utils/log'; +import { qDev } from '../utils/qdev'; + +export const codeToText = (code: number, ...parts: any[]): string => { + if (qDev) { + // Keep one error, one line to make it easier to search for the error message. + const MAP = [ + 'Error while serializing class or style attributes', // 0 + 'Scheduler not found', // 1 + 'track() received object, without prop to track', // 2 + 'Only primitive and object literals can be serialized. {{0}}', // 3 + '', // 4 unused + 'You can render over a existing q:container. Skipping render().', // 5 + '', // 6 unused + '', // 7 unused + '', // 8 unused + '', // 9 unused + 'QRL is not a function', // 10 + 'Dynamic import not found', // 11 + 'Unknown type argument', // 12 + `Actual value for useContext({{0}}) can not be found, make sure some ancestor component has set a value using useContextProvider(). In the browser make sure that the context was used during SSR so its state was serialized.`, // 13 + "Invoking 'use*()' method outside of invocation context.", // 14 + '', // 15 unused + '', // 16 unused + '', // 17 unused + '', // 18 unused + '', // 19 unused + `Calling a 'use*()' method outside 'component$(() => { HERE })' is not allowed. 'use*()' methods provide hooks to the 'component$' state and lifecycle, ie 'use' hooks can only be called synchronously within the 'component$' function or another 'use' method.\nSee https://qwik.dev/docs/components/tasks/#use-method-rules`, // 20 + '', // 21 unused + '', // 22 unused + '', // 23 unused + '', // 24 unused + '', // 25 unused + '', // 26 unused + '', // 27 unused + 'The provided Context reference "{{0}}" is not a valid context created by createContextId()', // 28 + 'SsrError(tag): {{0}}', // 29 + 'QRLs can not be resolved because it does not have an attached container. This means that the QRL does not know where it belongs inside the DOM, so it cant dynamically import() from a relative path.', // 30 + 'QRLs can not be dynamically resolved, because it does not have a chunk path', // 31 + '{{0}}\nThe JSX ref attribute must be a Signal', // 32 + 'Serialization Error: Deserialization of data type {{0}} is not implemented', // 33 + 'Serialization Error: Expected vnode for ref prop, but got {{0}}', // 34 + 'Serialization Error: Cannot allocate data type {{0}}', // 35 + 'Serialization Error: Missing root id for {{0}}', // 36 + 'Serialization Error: Serialization of data type {{0}} is not implemented', // 37 + 'Serialization Error: Unvisited {{0}}', // 38 + 'Serialization Error: Missing QRL chunk for {{0}}', // 39 + '{{0}}\nThe value of the textarea must be a string found {{1}}', // 40 + 'Unable to find q:container', // 41 + "Element must have 'q:container' attribute.", // 42 + 'Unknown vnode type {{0}}.', // 43 + 'Materialize error: missing element: {{0}} {{1}} {{2}}', // 44 + 'Cannot coerce a Signal, use `.value` instead', // 45 + '', // 46 unused + 'ComputedSignal is read-only', // 47 + 'WrappedSignal is read-only', // 48 + 'Attribute value is unsafe for SSR', // 49 + 'SerializerSymbol function returned rejected promise', // 50 + ]; + let text = MAP[code] ?? ''; + if (parts.length) { + text = text.replaceAll(/{{(\d+)}}/g, (_, index) => { + let v = parts[index]; + if (v && typeof v === 'object' && v.constructor === Object) { + v = JSON.stringify(v).slice(0, 50); + } + return v; + }); + } + return `Code(Q${code}): ${text}`; + } else { + // cute little hack to give roughly the correct line number. Update the line number if it shifts. + return `Code(Q${code}) https://github.com/QwikDev/qwik/blob/main/packages/qwik/src/core/error/error.ts#L${8 + code}`; + } +}; + +export const enum QError { + stringifyClassOrStyle = 0, + schedulerNotFound = 1, + trackObjectWithoutProp = 2, + verifySerializable = 3, + UNUSED_4 = 4, + cannotRenderOverExistingContainer = 5, + UNUSED_6 = 6, + UNUSED_7 = 7, + UNUSED_8 = 8, + UNUSED_9 = 9, + qrlIsNotFunction = 10, + dynamicImportFailed = 11, + unknownTypeArgument = 12, + notFoundContext = 13, + useMethodOutsideContext = 14, + UNUSED_15 = 15, + UNUSED_16 = 16, + UNUSED_17 = 17, + UNUSED_18 = 18, + UNUSED_19 = 19, + useInvokeContext = 20, + UNUSED_21 = 21, + UNUSED_22 = 22, + UNUSED_23 = 23, + UNUSED_24 = 24, + UNUSED_25 = 25, + UNUSED_26 = 26, + UNUSED_27 = 27, + invalidContext = 28, + tagError = 29, + qrlMissingContainer = 30, + qrlMissingChunk = 31, + invalidRefValue = 32, + serializeErrorNotImplemented = 33, + serializeErrorExpectedVNode = 34, + serializeErrorCannotAllocate = 35, + serializeErrorMissingRootId = 36, + serializeErrorUnknownType = 37, + serializeErrorUnvisited = 38, + serializeErrorMissingChunk = 39, + wrongTextareaValue = 40, + containerNotFound = 41, + elementWithoutContainer = 42, + invalidVNodeType = 43, + materializeVNodeDataError = 44, + cannotCoerceSignal = 45, + UNUSED_46 = 46, + computedReadOnly = 47, + wrappedReadOnly = 48, + unsafeAttr = 49, + serializerSymbolRejectedPromise = 50, +} + +export const qError = (code: number, errorMessageArgs: any[] = []): Error => { + const text = codeToText(code, ...errorMessageArgs); + return logErrorAndStop(text, ...errorMessageArgs); +}; diff --git a/packages/qwik/src/core/render/jsx/README.md b/packages/qwik/src/core/shared/jsx/README.md similarity index 100% rename from packages/qwik/src/core/render/jsx/README.md rename to packages/qwik/src/core/shared/jsx/README.md diff --git a/packages/qwik/src/core/shared/jsx/factory.unit.ts b/packages/qwik/src/core/shared/jsx/factory.unit.ts new file mode 100644 index 00000000000..1ca4eeff580 --- /dev/null +++ b/packages/qwik/src/core/shared/jsx/factory.unit.ts @@ -0,0 +1,51 @@ +import { h, isJSXNode, Fragment } from './jsx-runtime'; +import type { FunctionComponent } from './types/jsx-node'; +import { test, assert } from 'vitest'; + +test('key', () => { + //
    + const v = h('div', { key: 'val' }); + assert.deepEqual(v.props, {}); + assert.deepEqual(v.key, 'val'); +}); + +test('name/value props', () => { + //
    + const v = h('div', { id: 'val' }); + assert.deepEqual(v.props, { id: 'val' }); +}); + +test('boolean props', () => { + // + const v = h('input', { checked: true }); + assert.deepEqual(v.props, { checked: true }); +}); + +test('no props', () => { + //
    + const v = h('div', null); + assert.deepEqual(v.props, {}); + assert.deepEqual(v.key, null); +}); + +test('tag', () => { + const v = h('div', null); + assert.deepEqual(v.type, 'div'); +}); + +test('Function Component', () => { + const Cmp: FunctionComponent = () => h('fn-cmp', null); + const v = h(Cmp, {}); + assert.deepEqual(v.type, Cmp); +}); + +test('Fragment', () => { + // <>
    + const v = h(Fragment, null, h('div', null)); + assert.deepEqual(v.type, Fragment); +}); +test('valid JSXNode', () => { + //
    + const v = h('div', null); + assert.deepEqual(isJSXNode(v), true); +}); diff --git a/packages/qwik/src/core/shared/jsx/jsx-runtime.ts b/packages/qwik/src/core/shared/jsx/jsx-runtime.ts new file mode 100644 index 00000000000..1c32f15f1dd --- /dev/null +++ b/packages/qwik/src/core/shared/jsx/jsx-runtime.ts @@ -0,0 +1,430 @@ +import { type OnRenderFn } from '../component.public'; +import { _CONST_PROPS } from '../../internal'; +import { type QRLInternal } from '../qrl/qrl-class'; +import { _VAR_PROPS } from '../utils/constants'; +import { untrack } from '../../use/use-core'; +import { EMPTY_OBJ } from '../utils/flyweight'; +import { logOnceWarn, logWarn } from '../utils/log'; +import { ELEMENT_ID, OnRenderProp, QScopedStyle, QSlot, QSlotS } from '../utils/markers'; +import { qDev, seal } from '../utils/qdev'; +import { isArray, isObject, isString } from '../utils/types'; +import { WrappedSignalImpl } from '../../reactive-primitives/impl/wrapped-signal-impl'; +import { WrappedSignalFlags } from '../../reactive-primitives/types'; +import type { DevJSX, FunctionComponent, JSXNode, JSXNodeInternal } from './types/jsx-node'; +import type { QwikJSX } from './types/jsx-qwik'; +import type { JSXChildren } from './types/jsx-qwik-attributes'; + +export type Props = Record; +export type PropsProxy = { [_VAR_PROPS]: Props; [_CONST_PROPS]: Props | null }; + +/** + * Create a JSXNode with the properties fully split into variable and constant parts, and children + * separated out. Furthermore, the varProps must be a sorted object, that is, the keys must be + * sorted in ascending utf-8 value order. + * + * The constant parts are expected to be the same on every render, and are not checked for changes. + * This means that they are constant scalars or refs. When the ref is a signal or a store, it can + * still update the attribute on the vnode. + * + * @param type - The JSX type + * @param varProps - The properties of the tag, sorted, excluding children, excluding any constProps + * @param constProps - The properties of the tag that are known to be constant references and don't + * need checking for changes on re-render + * @param children - JSX children. Any `children` in the props objects are ignored. + * @internal + */ +export const _jsxSorted = ( + type: T, + varProps: Props | null, + constProps: Props | null, + children: JSXChildren | null, + flags: number, + key: string | number | null | undefined, + dev?: DevJSX +): JSXNodeInternal => { + const processed = key == null ? null : String(key); + const node = new JSXNodeImpl( + type, + varProps || {}, + constProps || null, + children, + flags, + processed + ); + if (qDev && dev) { + node.dev = { + stack: new Error().stack, + ...dev, + }; + } + seal(node); + return node; +}; + +/** + * Create a JSXNode, with the properties split into variable and constant parts, but the variable + * parts could include keys from constProps, as well as `key` and `children`. + * + * The constant parts are expected to be the same on every render, and are not checked for changes. + * This means that they are constant scalars or refs. When the ref is a signal or a store, it can + * still update the attribute on the vnode. + * + * If `children` is defined, any `children` in the props will be ignored. + * + * @param type - The tag type + * @param varProps - The properties of the tag that could change, including children + * @param constProps - The properties of the tag that are known to be static and don't need checking + * for changes on re-render + * @internal + */ +export const _jsxSplit = >( + type: T, + varProps: Props | null, + constProps: Props | null, + children: JSXChildren | null | undefined, + flags: number, + key: string | number | null, + dev?: DevJSX +): JSXNodeInternal => { + let sortedProps; + if (varProps) { + // filter and sort + sortedProps = Object.fromEntries( + untrack(() => Object.entries(varProps!)) + .filter((entry) => { + const attr = entry[0]; + if (attr === 'children') { + // side-effect! + children ??= entry[1] as JSXChildren; + return false; + } else if (attr === 'key') { + key = entry[1] as string; + return false; + } + return ( + !constProps || + !(attr in constProps) || + // special case for event handlers, they merge + /^on[A-Z].*\$$/.test(attr) + ); + }) + // sort for fast compare in vNodes + // keys can never be the same so we don't check for that + .sort(([a], [b]) => (a < b ? -1 : 1)) + ); + } else { + sortedProps = typeof type === 'string' ? EMPTY_OBJ : {}; + } + if (constProps && 'children' in constProps) { + children = constProps.children as JSXChildren; + constProps.children = undefined; + } + return _jsxSorted(type, sortedProps, constProps, children, flags, key, dev); +}; + +/** @internal @deprecated v1 compat */ +export const _jsxC = (type: any, mutable: any, _flags: any, key: any) => jsx(type, mutable, key); +/** @internal @deprecated v1 compat */ +export const _jsxS = (type: any, mutable: any, immutable: any, _flags: any, key: any) => + jsx(type, { ...immutable, ...mutable }, key); +/** @internal @deprecated v1 compat */ +export const _jsxQ = ( + type: any, + mutable: any, + immutable: any, + children: any, + _flags: any, + key: any +) => jsx(type, { ...immutable, ...mutable, children }, key); + +/** + * @public + * Used by the JSX transpilers to create a JSXNode. + * Note that the optimizer will not use this, instead using _jsxSplit and _jsxSorted directly. + */ +export const jsx = >( + type: T, + props: T extends FunctionComponent ? PROPS : Props, + key?: string | number | null +): JSXNode => { + return _jsxSplit(type, props, null, null, 0, key || null); +}; + +export const flattenArray = (array: (T | T[])[], dst?: T[]): T[] => { + // Yes this function is just Array.flat, but we need to run on old versions of Node. + if (!dst) { + dst = []; + } + for (const item of array) { + if (isArray(item)) { + flattenArray(item, dst); + } else { + dst.push(item); + } + } + return dst; +}; + +/** + * The legacy transform, used in special cases like `
    `. Note that the + * children are spread arguments, instead of a prop like in jsx() calls. + * + * Also note that this disables optimizations. + * + * @public + */ +export function h, PROPS extends {} = {}>( + type: TYPE, + props?: PROPS | null, + ...children: any[] +): JSXNode { + const normalizedProps: any = { + children: arguments.length > 2 ? flattenArray(children) : null, + }; + + let key: any = null; + + for (const i in props) { + if (i == 'key') { + key = (props as Record)[i]; + } else { + normalizedProps[i] = (props as Record)[i]; + } + } + + if (typeof type === 'string' && !key && 'dangerouslySetInnerHTML' in normalizedProps) { + key = 'innerhtml'; + } + return _jsxSplit(type, props!, null, normalizedProps.children, 0, key); +} + +export const isPropsProxy = (obj: any): obj is PropsProxy => { + return obj && obj[_VAR_PROPS] !== undefined; +}; + +export class JSXNodeImpl implements JSXNodeInternal { + dev?: DevJSX; + constructor( + public type: T, + public varProps: Props, + public constProps: Props | null, + public children: JSXChildren, + public flags: number, + public key: string | null = null + ) { + if (qDev) { + if (typeof varProps !== 'object') { + throw new Error(`JSXNodeImpl: varProps must be objects: ` + JSON.stringify(varProps)); + } + if (typeof constProps !== 'object') { + throw new Error(`JSXNodeImpl: constProps must be objects: ` + JSON.stringify(constProps)); + } + } + } + + private _proxy: Props | null = null; + get props(): T extends FunctionComponent ? PROPS : Props { + // We use a proxy to merge the constProps if they exist and to evaluate derived signals + if (!this._proxy) { + this._proxy = createPropsProxy(this.varProps, this.constProps, this.children); + } + return this._proxy as typeof this.props; + } +} + +/** @private */ +export const Virtual: FunctionComponent<{ + children?: JSXChildren; + dangerouslySetInnerHTML?: string; + [OnRenderProp]?: QRLInternal>; + [QSlot]?: string; + [QSlotS]?: string; + props?: Props; + [QScopedStyle]?: string; + [ELEMENT_ID]?: string; +}> = (props: any) => props.children; + +/** @public */ +export const RenderOnce: FunctionComponent<{ + children?: unknown; + key?: string | number | null | undefined; +}> = (props: any, key) => { + return new JSXNodeImpl(Virtual, EMPTY_OBJ, null, props.children, 2, key); +}; + +/** @internal */ +export const isJSXNode = (n: unknown): n is JSXNodeInternal => { + if (qDev) { + if (n instanceof JSXNodeImpl) { + return true; + } + if (isObject(n) && 'key' in n && 'props' in n && 'type' in n) { + logWarn(`Duplicate implementations of "JSXNode" found`); + return true; + } + return false; + } else { + return n instanceof JSXNodeImpl; + } +}; + +/** @public */ +export const Fragment: FunctionComponent<{ children?: any; key?: string | number | null }> = ( + props +) => props.children; + +interface JsxDevOpts { + fileName: string; + lineNumber: number; + columnNumber: number; +} + +/** @public */ +export const jsxDEV = >( + type: T, + props: T extends FunctionComponent ? PROPS : Props, + key: string | number | null | undefined, + _isStatic: boolean, + opts: JsxDevOpts, + _ctx: unknown +): JSXNode => { + const processed = key == null ? null : String(key); + const children = untrack(() => { + const c = props.children; + if (typeof type === 'string') { + delete props.children; + } + return c; + }) as JSXChildren; + if (isString(type)) { + if ('className' in props) { + (props as any).class = props.className; + delete props.className; + if (qDev) { + logOnceWarn('jsx: `className` is deprecated. Use `class` instead.'); + } + } + } + const node = new JSXNodeImpl(type, props, null, children, 0, processed); + node.dev = { + stack: new Error().stack, + ...opts, + }; + seal(node); + return node; +}; + +export type { QwikJSX as JSX }; + +export function createPropsProxy( + varProps: Props, + constProps: Props | null, + children?: JSXChildren | undefined +): Props { + return new Proxy({}, new PropsProxyHandler(varProps, constProps, children)); +} + +class PropsProxyHandler implements ProxyHandler { + constructor( + private $varProps$: Props, + private $constProps$: Props | null, + private $children$: JSXChildren | undefined + ) {} + get(_: any, prop: string | symbol) { + // escape hatch to get the separated props from a component + if (prop === _CONST_PROPS) { + return this.$constProps$; + } + if (prop === _VAR_PROPS) { + return this.$varProps$; + } + if (this.$children$ != null && prop === 'children') { + return this.$children$; + } + const value = + this.$constProps$ && prop in this.$constProps$ + ? this.$constProps$[prop as string] + : this.$varProps$[prop as string]; + // a proxied value that the optimizer made + return value instanceof WrappedSignalImpl && value.$flags$ & WrappedSignalFlags.UNWRAP + ? value.value + : value; + } + set(_: any, prop: string | symbol, value: any) { + if (prop === _CONST_PROPS) { + this.$constProps$ = value; + return true; + } + if (prop === _VAR_PROPS) { + this.$varProps$ = value; + return true; + } + if (this.$constProps$ && prop in this.$constProps$) { + this.$constProps$[prop as string] = value; + } else { + this.$varProps$[prop as string] = value; + } + return true; + } + deleteProperty(_: any, prop: string | symbol) { + if (typeof prop !== 'string') { + return false; + } + let didDelete = delete this.$varProps$[prop]; + if (this.$constProps$) { + didDelete = delete this.$constProps$[prop as string] || didDelete; + } + if (this.$children$ != null && prop === 'children') { + this.$children$ = null; + } + return didDelete; + } + has(_: any, prop: string | symbol) { + const hasProp = + (prop === 'children' && this.$children$ != null) || + prop === _CONST_PROPS || + prop === _VAR_PROPS || + prop in this.$varProps$ || + (this.$constProps$ ? prop in this.$constProps$ : false); + return hasProp; + } + getOwnPropertyDescriptor(_: any, p: string | symbol): PropertyDescriptor | undefined { + const value = + p === 'children' && this.$children$ != null + ? this.$children$ + : this.$constProps$ && p in this.$constProps$ + ? this.$constProps$[p as string] + : this.$varProps$[p as string]; + return { + configurable: true, + enumerable: true, + value: value, + }; + } + ownKeys() { + const out = Object.keys(this.$varProps$); + if (this.$children$ != null && out.indexOf('children') === -1) { + out.push('children'); + } + if (this.$constProps$) { + for (const key in this.$constProps$) { + if (out.indexOf(key) === -1) { + out.push(key); + } + } + } + return out; + } +} + +/** + * Instead of using PropsProxyHandler getter (which could create a component-level subscription). + * Use this function to get the props directly from a const or var props. + */ +export const directGetPropsProxyProp = (jsx: JSXNodeInternal, prop: string): T => { + return ( + jsx.constProps && prop in jsx.constProps ? jsx.constProps[prop] : jsx.varProps[prop] + ) as T; +}; + +export { jsx as jsxs }; diff --git a/packages/qwik/src/core/shared/jsx/jsx-runtime.unit.ts b/packages/qwik/src/core/shared/jsx/jsx-runtime.unit.ts new file mode 100644 index 00000000000..88411057c5f --- /dev/null +++ b/packages/qwik/src/core/shared/jsx/jsx-runtime.unit.ts @@ -0,0 +1,61 @@ +import { assert, test } from 'vitest'; +import { jsx, isJSXNode, Fragment } from './jsx-runtime'; +import type { FunctionComponent } from './types/jsx-node'; + +test('key', () => { + //
    + const v = jsx('div', {}, 'val'); + assert.deepEqual(v.props, {}); + assert.deepEqual(v.key, 'val'); +}); + +test('name/value props', () => { + //
    + const v = jsx('div', { id: 'val' }); + assert.deepEqual(v.props, { id: 'val' }); +}); + +test('boolean props', () => { + // + const v = jsx('input', { checked: true }); + assert.deepEqual(v.props, { checked: true }); +}); + +test('no props', () => { + //
    + const v = jsx('div', {}); + assert.deepEqual(v.props, {}); + assert.deepEqual(v.key, null); +}); +test('tag', () => { + const v = jsx('div', {}); + assert.deepEqual(v.type, 'div'); +}); + +test('Function Component', () => { + const Cmp: FunctionComponent = () => jsx('fn-cmp', {}); + const v = jsx(Cmp, {}); + assert.deepEqual(v.type, Cmp); +}); + +test('Fragment', () => { + const v = jsx(Fragment, {}); + assert.deepEqual(v.type, Fragment); +}); +test('valid JSXNode', () => { + const v = jsx('div', {}); + assert.deepEqual(isJSXNode(v), true); +}); +test('invalid string', () => { + assert.deepEqual(isJSXNode('text'), false); +}); +test('invalid class', () => { + assert.deepEqual(isJSXNode(class {}), false); +}); +test('invalid array', () => { + assert.deepEqual(isJSXNode([]), false); +}); +test('invalid null/undefined', () => { + assert.deepEqual(isJSXNode(null), false); + assert.deepEqual(isJSXNode(undefined), false); +}); diff --git a/packages/qwik/src/core/shared/jsx/slot.public.ts b/packages/qwik/src/core/shared/jsx/slot.public.ts new file mode 100644 index 00000000000..1b812b9919c --- /dev/null +++ b/packages/qwik/src/core/shared/jsx/slot.public.ts @@ -0,0 +1,17 @@ +import { QSlotS } from '../utils/markers'; +import { Virtual, _jsxSorted } from './jsx-runtime'; +import type { FunctionComponent } from './types/jsx-node'; +import type { JSXChildren } from './types/jsx-qwik-attributes'; + +/** + * Allows to project the children of the current component. `` can only be used within the + * context of a component defined with `component$`. + * + * @public + */ +export const Slot: FunctionComponent<{ + name?: string; + children?: JSXChildren; +}> = (props) => { + return _jsxSorted(Virtual, null, { [QSlotS]: '' }, props.children, 0, props.name ?? ''); +}; diff --git a/packages/qwik/src/core/render/jsx/types/jsx-generated.ts b/packages/qwik/src/core/shared/jsx/types/jsx-generated.ts similarity index 99% rename from packages/qwik/src/core/render/jsx/types/jsx-generated.ts rename to packages/qwik/src/core/shared/jsx/types/jsx-generated.ts index ac9e037459b..04bdfff7a99 100644 --- a/packages/qwik/src/core/render/jsx/types/jsx-generated.ts +++ b/packages/qwik/src/core/shared/jsx/types/jsx-generated.ts @@ -1,6 +1,6 @@ import * as CSS from 'csstype'; -import type { Signal } from '../../../state/signal'; import type { DOMAttributes, ClassList, QwikAttributes } from './jsx-qwik-attributes'; +import type { Signal } from '../../../reactive-primitives/signal.public'; /** @public */ export type Booleanish = boolean | `${boolean}`; /** @public */ @@ -1233,7 +1233,7 @@ export interface SVGAttributes extends AriaAttribut } /** @public */ export interface SVGProps extends SVGAttributes, QwikAttributes {} -/** @internal */ +/** @public */ export interface LenientSVGProps extends SVGAttributes, DOMAttributes {} /** @public */ export interface IntrinsicElements extends IntrinsicHTMLElements, IntrinsicSVGElements {} @@ -1241,7 +1241,7 @@ export interface IntrinsicElements extends IntrinsicHTMLElements, IntrinsicSVGEl /** * These are the HTML tags with handlers allowing plain callbacks, to be used for the JSX interface * - * @internal + * @public */ export type IntrinsicHTMLElements = { // Generating it this way shows the special props for each element in editor hover @@ -1254,7 +1254,7 @@ export type IntrinsicHTMLElements = { /** * These are the SVG tags with handlers allowing plain callbacks, to be used for the JSX interface * - * @internal + * @public */ export type IntrinsicSVGElements = { [K in keyof Omit]: LenientSVGProps< diff --git a/packages/qwik/src/core/render/jsx/types/jsx-node.ts b/packages/qwik/src/core/shared/jsx/types/jsx-node.ts similarity index 90% rename from packages/qwik/src/core/render/jsx/types/jsx-node.ts rename to packages/qwik/src/core/shared/jsx/types/jsx-node.ts index f6733b52a90..e566d3627aa 100644 --- a/packages/qwik/src/core/render/jsx/types/jsx-node.ts +++ b/packages/qwik/src/core/shared/jsx/types/jsx-node.ts @@ -40,12 +40,13 @@ export interface JSXNode extends JSXNode { - immutableProps: Record | null; + varProps: Record; + constProps: Record | null; flags: number; } diff --git a/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts b/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts similarity index 98% rename from packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts rename to packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts index b713873224c..1adce0bbc36 100644 --- a/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts +++ b/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts @@ -1,5 +1,5 @@ -import type { QRL } from '../../../qrl/qrl.public'; -import type { Signal } from '../../../state/signal'; +import type { QRL } from '../../qrl/qrl.public'; +import type { Signal } from '../../../reactive-primitives/signal.public'; import type { JSXNode } from './jsx-node'; import type { QwikIdleEvent, @@ -174,7 +174,7 @@ export type EventHandler = { /** * An event handler for Qwik events, can be a handler QRL or an array of handler QRLs. * - * @beta + * @public */ export type QRLEventHandlerMulti = | QRL> diff --git a/packages/qwik/src/core/render/jsx/types/jsx-qwik-elements.ts b/packages/qwik/src/core/shared/jsx/types/jsx-qwik-elements.ts similarity index 98% rename from packages/qwik/src/core/render/jsx/types/jsx-qwik-elements.ts rename to packages/qwik/src/core/shared/jsx/types/jsx-qwik-elements.ts index dd2f144d793..b3ba3623dd8 100644 --- a/packages/qwik/src/core/render/jsx/types/jsx-qwik-elements.ts +++ b/packages/qwik/src/core/shared/jsx/types/jsx-qwik-elements.ts @@ -12,7 +12,7 @@ export type { QwikIntrinsicAttributes } from './jsx-qwik-attributes'; * example showing how to define a customizable wrapper component: * * ```tsx - * import { component$, Slot, type QwikIntrinsicElements } from "@builder.io/qwik"; + * import { component$, Slot, type QwikIntrinsicElements } from "@qwik.dev/core"; * * type WrapperProps = { * attributes?: QwikIntrinsicElements["div"]; diff --git a/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts b/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts similarity index 97% rename from packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts rename to packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts index a4e020ae00e..d365a508736 100644 --- a/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts +++ b/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts @@ -3,7 +3,15 @@ import type { AllEventKeys } from './jsx-qwik-attributes'; /** Emitted by qwik-loader when an element becomes visible. Used by `useVisibleTask$` @public */ export type QwikVisibleEvent = CustomEvent; /** Emitted by qwik-loader when a module was lazily loaded @public */ -export type QwikSymbolEvent = CustomEvent<{ symbol: string; element: Element; reqTime: number }>; +export type QwikSymbolEvent = CustomEvent<{ + qBase: string; + qManifest: string; + qVersion: string; + href: string; + symbol: string; + element: Element; + reqTime: number; +}>; /** Emitted by qwik-loader on document when the document first becomes interactive @public */ export type QwikInitEvent = CustomEvent<{}>; /** Emitted by qwik-loader on document when the document first becomes idle @public */ diff --git a/packages/qwik/src/core/render/jsx/types/jsx-qwik.ts b/packages/qwik/src/core/shared/jsx/types/jsx-qwik.ts similarity index 100% rename from packages/qwik/src/core/render/jsx/types/jsx-qwik.ts rename to packages/qwik/src/core/shared/jsx/types/jsx-qwik.ts diff --git a/packages/qwik/src/core/render/jsx/types/jsx-types.unit.tsx b/packages/qwik/src/core/shared/jsx/types/jsx-types.unit.tsx similarity index 93% rename from packages/qwik/src/core/render/jsx/types/jsx-types.unit.tsx rename to packages/qwik/src/core/shared/jsx/types/jsx-types.unit.tsx index d3c21b8fe04..43ca119a727 100644 --- a/packages/qwik/src/core/render/jsx/types/jsx-types.unit.tsx +++ b/packages/qwik/src/core/shared/jsx/types/jsx-types.unit.tsx @@ -1,13 +1,15 @@ import { assertType, describe, expectTypeOf, test } from 'vitest'; -import { $, type PropFunction } from '../../../qrl/qrl.public'; +import { $, type PropFunction } from '../../qrl/qrl.public'; import type { EventHandler, QRLEventHandlerMulti } from './jsx-qwik-attributes'; import type { FunctionComponent, JSXOutput } from './jsx-node'; import type { QwikIntrinsicElements } from './jsx-qwik-elements'; import type { JSXChildren } from './jsx-qwik-attributes'; -import { component$, type PropsOf, type PublicProps } from '../../../component/component.public'; +import { component$, type PropsOf, type PublicProps } from '../../component.public'; import type { QwikHTMLElements, QwikSVGElements, Size } from './jsx-generated'; import type { JSX } from '../jsx-runtime'; +const Fn = () =>
    ; + describe('types', () => { // Note, these type checks happen at compile time. We don't need to call anything, so we do ()=>()=>. We just need to // make sure the type check runs. @@ -42,7 +44,6 @@ describe('types', () => { ); }); - const Fn = () =>
    ; expectTypeOf>().toEqualTypeOf(); const Cmp = component$(Fn); expectTypeOf(Cmp).toEqualTypeOf>>(); @@ -248,7 +249,6 @@ describe('types', () => { > Bar - ); @@ -289,17 +289,10 @@ describe('types', () => { expectTypeOf>().toEqualTypeOf(); // functions - const NoProps = () =>
    ; expectTypeOf>().toEqualTypeOf(); - const UnknownProps = (p: unknown) =>
    ; expectTypeOf>().toEqualTypeOf(); - const AnyProps = (p: any) =>
    ; expectTypeOf>().toEqualTypeOf(); - const DefProps = (props: { foo: string }) =>
    ; expectTypeOf>().toEqualTypeOf<{ foo: string }>(); - const PolyProps = ( - p: { as?: C; b: boolean } & (C extends 'hi' ? { foo: boolean } : never) - ) =>
    ; expectTypeOf>>().toMatchTypeOf<{ as?: 'hi'; b: boolean; @@ -307,15 +300,10 @@ describe('types', () => { }>(); // components - const NoProps$ = component$(NoProps); expectTypeOf>().toEqualTypeOf(); - const UnknownProps$ = component$(UnknownProps); expectTypeOf>().toEqualTypeOf(); - const AnyProps$ = component$(AnyProps); expectTypeOf>().toEqualTypeOf(); - const DefProps$ = component$(DefProps); expectTypeOf>().toEqualTypeOf<{ foo: string }>(); - const PolyProps$ = component$(PolyProps); expectTypeOf>>().toMatchTypeOf<{ as?: 'hi'; b: boolean; @@ -328,3 +316,17 @@ describe('types', () => { expectTypeOf>().toEqualTypeOf(); }); }); + +const NoProps = () =>
    ; +const UnknownProps = (p: unknown) =>
    ; +const AnyProps = (p: any) =>
    ; +const DefProps = (props: { foo: string }) =>
    ; +const PolyProps = ( + p: { as?: C; b: boolean } & (C extends 'hi' ? { foo: boolean } : never) +) =>
    ; + +const NoProps$ = component$(NoProps); +const UnknownProps$ = component$(UnknownProps); +const AnyProps$ = component$(AnyProps); +const DefProps$ = component$(DefProps); +const PolyProps$ = component$(PolyProps); diff --git a/packages/qwik/src/core/shared/jsx/utils.public.ts b/packages/qwik/src/core/shared/jsx/utils.public.ts new file mode 100644 index 00000000000..72232db443f --- /dev/null +++ b/packages/qwik/src/core/shared/jsx/utils.public.ts @@ -0,0 +1,45 @@ +import { STREAM_BLOCK_END_COMMENT, STREAM_BLOCK_START_COMMENT } from '../utils/markers'; +import type { StreamWriter } from '../../ssr/ssr-types'; +import { jsx, RenderOnce } from './jsx-runtime'; +import type { FunctionComponent, JSXNode, JSXOutput } from './types/jsx-node'; +import type { JSXChildren } from './types/jsx-qwik-attributes'; + +/** @public */ +export const SkipRender: JSXNode = Symbol('skip render') as any; + +/** @public */ +export const SSRRaw: FunctionComponent<{ data: string }> = () => null; + +/** @public */ +export const SSRComment: FunctionComponent<{ data: string }> = () => null; + +/** @public */ +export const SSRStreamBlock: FunctionComponent<{ children?: JSXOutput }> = (props) => { + return [ + jsx(SSRComment, { data: STREAM_BLOCK_START_COMMENT }), + props.children, + jsx(SSRComment, { data: STREAM_BLOCK_END_COMMENT }), + ]; +}; + +/** @public */ +export type SSRStreamProps = { + children: SSRStreamChildren; +}; + +/** @public */ +export type SSRStreamChildren = + | AsyncGenerator + | ((stream: StreamWriter) => Promise) + | (() => AsyncGenerator); + +/** @public */ +export const SSRStream: FunctionComponent = (props, key) => + jsx(RenderOnce, { children: jsx(InternalSSRStream, props) }, key); + +/** @public */ +export type SSRHintProps = { + dynamic?: boolean; +}; + +export const InternalSSRStream: FunctionComponent = () => null; diff --git a/packages/qwik/src/core/platform/platform.ts b/packages/qwik/src/core/shared/platform/platform.ts similarity index 80% rename from packages/qwik/src/core/platform/platform.ts rename to packages/qwik/src/core/shared/platform/platform.ts index 9808a76fe55..9e0797d52d4 100644 --- a/packages/qwik/src/core/platform/platform.ts +++ b/packages/qwik/src/core/shared/platform/platform.ts @@ -1,9 +1,9 @@ -// keep this import from qwik/build so the cjs build works -import { isServer } from '@builder.io/qwik/build'; -import { qError, QError_qrlMissingChunk, QError_qrlMissingContainer } from '../error/error'; -import { getSymbolHash } from '../qrl/qrl-class'; -import type { QwikElement } from '../render/dom/virtual-element'; -import { qDynamicPlatform } from '../util/qdev'; +// keep this import from core/build so the cjs build works +import { isServer } from '@qwik.dev/core/build'; +import { QError, qError } from '../error/error'; +import { getSymbolHash } from '../qrl/qrl-utils'; +import { QBaseAttr } from '../utils/markers'; +import { qDynamicPlatform } from '../utils/qdev'; import type { CorePlatform } from './types'; export const createPlatform = (): CorePlatform => { @@ -18,10 +18,10 @@ export const createPlatform = (): CorePlatform => { } } if (!url) { - throw qError(QError_qrlMissingChunk, symbolName); + throw qError(QError.qrlMissingChunk, [symbolName]); } if (!containerEl) { - throw qError(QError_qrlMissingContainer, url, symbolName); + throw qError(QError.qrlMissingContainer, [url, symbolName]); } const urlDoc = toUrl(containerEl.ownerDocument, containerEl, url).toString(); const urlCopy = new URL(urlDoc); @@ -64,9 +64,9 @@ export const createPlatform = (): CorePlatform => { * @param url - Relative URL * @returns Fully qualified URL. */ -export const toUrl = (doc: Document, containerEl: QwikElement, url: string | URL): URL => { +export const toUrl = (doc: Document, containerEl: Element, url: string | URL): URL => { const baseURI = doc.baseURI; - const base = new URL(containerEl.getAttribute('q:base') ?? baseURI, baseURI); + const base = new URL(containerEl.getAttribute(QBaseAttr) ?? baseURI, baseURI); return new URL(url, base); }; @@ -74,7 +74,7 @@ let _platform = /*#__PURE__ */ createPlatform(); // // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ./readme.md#setPlatform instead) +// (edit ./readme.md#setPlatform instead and run `pnpm docs.sync`) /** * Sets the `CorePlatform`. * @@ -90,7 +90,7 @@ export const setPlatform = (plt: CorePlatform) => (_platform = plt); // // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ./readme.md#getPlatform instead) +// (edit ./readme.md#getPlatform instead and run `pnpm docs.sync`) /** * Retrieve the `CorePlatform`. * diff --git a/packages/qwik/src/core/platform/readme.md b/packages/qwik/src/core/shared/platform/readme.md similarity index 100% rename from packages/qwik/src/core/platform/readme.md rename to packages/qwik/src/core/shared/platform/readme.md diff --git a/packages/qwik/src/core/shared/platform/types.ts b/packages/qwik/src/core/shared/platform/types.ts new file mode 100644 index 00000000000..4a3870fdaea --- /dev/null +++ b/packages/qwik/src/core/shared/platform/types.ts @@ -0,0 +1,107 @@ +import type { ValueOrPromise } from '../utils/types'; + +// +// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! +// (edit ./readme.md#CorePlatform instead and run `pnpm docs.sync`) +/** + * Low-level API for platform abstraction. + * + * Different 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. + * + * `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. + * + * This is a low-level API and there should not be a need for you to access this. + * + * @public + */ +// +export interface CorePlatform { + // + // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! + // (edit ./readme.md#CorePlatform.isServer instead and run `pnpm docs.sync`) + /** + * True of running on the server platform. + * + * @returns True if we are running on the server (not the browser.) + */ + // + isServer: boolean; + // + // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! + // (edit ./readme.md#CorePlatform.importSymbol instead and run `pnpm docs.sync`) + /** + * Retrieve a symbol value from QRL. + * + * Qwik 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`. + * + * Why 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. + * + * @param element - The element against which the `url` is resolved. Used to locate the container + * root and `q:base` attribute. + * @param url - Relative URL retrieved from the attribute that needs to be resolved against the + * container `q:base` attribute. + * @param symbol - The name of the symbol to import. + * @returns A promise that resolves to the imported symbol. + */ + // + importSymbol: ( + containerEl: Element | undefined, + url: string | URL | undefined | null, + symbol: string + ) => ValueOrPromise; + // + // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! + // (edit ./readme.md#CorePlatform.raf instead and run `pnpm docs.sync`) + /** + * Perform operation on next request-animation-frame. + * + * @param fn - The function to call when the next animation frame is ready. + */ + // + raf: (fn: () => any) => Promise; + // + // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! + // (edit ./readme.md#CorePlatform.nextTick instead and run `pnpm docs.sync`) + /** + * Perform operation on next tick. + * + * @param fn - The function to call when the tick is ready. + */ + // + nextTick: (fn: () => any) => Promise; + // + // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! + // (edit ./readme.md#CorePlatform.chunkForSymbol instead and run `pnpm docs.sync`) + /** + * Retrieve chunk name for the symbol. + * + * When 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.) + * + * @param symbolName - Resolve `symbolName` against the manifest and return the chunk that + * contains the symbol. + */ + // + chunkForSymbol: ( + symbolName: string, + chunk: string | null, + parent?: string + ) => readonly [symbol: string, chunk: string] | undefined; +} + +export interface CorePlatformServer extends CorePlatform { + isServer: true; +} diff --git a/packages/qwik/src/core/components/prefetch.ts b/packages/qwik/src/core/shared/prefetch-service-worker/prefetch.ts similarity index 81% rename from packages/qwik/src/core/components/prefetch.ts rename to packages/qwik/src/core/shared/prefetch-service-worker/prefetch.ts index b6d48834541..c0a83ccb6d3 100644 --- a/packages/qwik/src/core/components/prefetch.ts +++ b/packages/qwik/src/core/shared/prefetch-service-worker/prefetch.ts @@ -1,8 +1,7 @@ -// keep this import from qwik/build so the cjs build works -import { isDev } from '@builder.io/qwik/build'; -import type { JSXNode } from '@builder.io/qwik/jsx-runtime'; -import { _jsxC } from '../internal'; -import type { JSXOutput } from '../render/jsx/types/jsx-node'; +// keep this import from core/build so the cjs build works +import { isDev } from '@qwik.dev/core/build'; +import { _jsxSorted } from '../../internal'; +import type { JSXOutput } from '../jsx/types/jsx-node'; /** * @deprecated This is no longer needed as the preloading happens automatically in qrl-class.ts. @@ -17,13 +16,13 @@ export const PrefetchServiceWorker = (opts: { verbose?: boolean; fetchBundleGraph?: boolean; nonce?: string; -}): JSXNode<'script'> => { +}): JSXOutput => { const isTest = import.meta.env.TEST; if (isDev && !isTest) { const props = { dangerouslySetInnerHTML: '', }; - return _jsxC('script', props, 0, 'prefetch-service-worker'); + return _jsxSorted('script', null, props, null, 0, 'prefetch-service-worker'); } // if an MFE app has a custom BASE_URL then this will be the correct value @@ -56,7 +55,7 @@ export const PrefetchServiceWorker = (opts: { ].join(''), nonce: resolvedOpts.nonce, }; - return _jsxC('script', props, 0, 'prefetch-service-worker'); + return _jsxSorted('script', null, props, null, 0, 'prefetch-service-worker'); }; const PREFETCH_CODE = /*#__PURE__*/ (( @@ -81,5 +80,5 @@ const PREFETCH_CODE = /*#__PURE__*/ (( * @alpha */ export const PrefetchGraph = ( - opts: { base?: string; manifestHash?: string; manifestURL?: string; nonce?: string } = {} + _opts: { base?: string; manifestHash?: string; manifestURL?: string; nonce?: string } = {} ): JSXOutput => null; diff --git a/packages/qwik/src/core/util/implicit_dollar.ts b/packages/qwik/src/core/shared/qrl/implicit_dollar.ts similarity index 85% rename from packages/qwik/src/core/util/implicit_dollar.ts rename to packages/qwik/src/core/shared/qrl/implicit_dollar.ts index 3bfa0b31d3b..a1a3dfa5b14 100644 --- a/packages/qwik/src/core/util/implicit_dollar.ts +++ b/packages/qwik/src/core/shared/qrl/implicit_dollar.ts @@ -1,8 +1,8 @@ -import { $, type QRL } from '../qrl/qrl.public'; +import { dollar, type QRL } from './qrl.public'; -// +// // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#implicit$FirstArg instead) +// (edit ../../readme.md#implicit$FirstArg instead and run `pnpm docs.sync`) /** * Create a `____$(...)` convenience method from `___(...)`. * @@ -44,6 +44,6 @@ export const implicit$FirstArg = ( fn: (qrl: QRL, ...rest: REST) => RET ): ((qrl: FIRST, ...rest: REST) => RET) => { return function (first: FIRST, ...rest: REST): RET { - return fn.call(null, $(first), ...rest); + return fn.call(null, dollar(first), ...rest); }; }; diff --git a/packages/qwik/src/core/shared/qrl/inlined-fn.ts b/packages/qwik/src/core/shared/qrl/inlined-fn.ts new file mode 100644 index 00000000000..1f418258132 --- /dev/null +++ b/packages/qwik/src/core/shared/qrl/inlined-fn.ts @@ -0,0 +1,10 @@ +import { WrappedSignalImpl } from '../../reactive-primitives/impl/wrapped-signal-impl'; + +/** @internal */ +export const _fnSignal = any>( + fn: T, + args: Parameters, + fnStr?: string +) => { + return new WrappedSignalImpl(null, fn, args, fnStr || null); +}; diff --git a/packages/qwik/src/core/shared/qrl/qrl-class.ts b/packages/qwik/src/core/shared/qrl/qrl-class.ts new file mode 100644 index 00000000000..fc1e47faf57 --- /dev/null +++ b/packages/qwik/src/core/shared/qrl/qrl-class.ts @@ -0,0 +1,291 @@ +import { getPlatform, isServerPlatform } from '../platform/platform'; +import { verifySerializable } from '../utils/serialize-utils'; +// ^ keep these above to prevent circular dep issues +import { isBrowser, isDev } from '@qwik.dev/core/build'; +// @ts-expect-error we don't have types for the preloader +import { p as preload } from '@qwik.dev/core/preloader'; +import { + invoke, + newInvokeContext, + newInvokeContextFromTuple, + tryGetInvokeContext, + type InvokeContext, + type InvokeTuple, +} from '../../use/use-core'; +import { assertDefined } from '../error/assert'; +import { QError, qError } from '../error/error'; +import { getQFuncs, QInstanceAttr } from '../utils/markers'; +import { isPromise, maybeThen, retryOnPromise } from '../utils/promises'; +import { qDev, qSerialize, qTest, seal } from '../utils/qdev'; +import { isArray, isFunction, type ValueOrPromise } from '../utils/types'; +import type { QRLDev } from './qrl'; +import { getSymbolHash, SYNC_QRL } from './qrl-utils'; +import type { QRL, QrlArgs, QrlReturn } from './qrl.public'; + +interface SyncQRLSymbol { + $symbol$: typeof SYNC_QRL; +} + +export type SyncQRLInternal = QRLInternal & SyncQRLSymbol; + +export type QRLInternalMethods = { + readonly $chunk$: string | null; + readonly $symbol$: string; + readonly $hash$: string; + + $capture$: string[] | null; + $captureRef$: unknown[] | null; + dev: QRLDev | null; + + resolved: undefined | TYPE; + + resolve(): Promise; + getSymbol(): string; + getHash(): string; + getCaptured(): unknown[] | null; + getFn( + currentCtx?: InvokeContext | InvokeTuple, + beforeFn?: () => void + ): TYPE extends (...args: any) => any + ? (...args: Parameters) => ValueOrPromise> + : // unknown so we allow assigning function QRLs to any + unknown; + + $setContainer$(containerEl: Element | undefined): Element | undefined; + $resolveLazy$(containerEl?: Element): ValueOrPromise; +}; + +export type QRLInternal = QRL & QRLInternalMethods; + +export const createQRL = ( + chunk: string | null, + symbol: string, + symbolRef: null | ValueOrPromise, + symbolFn: null | (() => Promise>), + capture: null | Readonly, + captureRef: Readonly | null +): QRLInternal => { + if (qDev && qSerialize) { + if (captureRef) { + for (const item of captureRef) { + verifySerializable(item, 'Captured variable in the closure can not be serialized'); + } + } + } + + let _containerEl: Element | undefined; + + const qrl = async function (this: unknown, ...args: QrlArgs) { + const boundedFn = bindFnToContext.call(this, tryGetInvokeContext()); + const result = await boundedFn(...args); + return result; + } as QRLInternal; + + const setContainer = (el: Element | undefined) => { + if (!_containerEl) { + _containerEl = el; + } + return _containerEl; + }; + + function bindFnToContext( + this: unknown, + currentCtx?: InvokeContext | InvokeTuple, + beforeFn?: () => void | boolean + ) { + // Note that we bind the current `this` + const bound = (...args: QrlArgs): ValueOrPromise | undefined> => { + if (!qrl.resolved) { + const promise = retryOnPromise(() => qrl.resolve()) as Promise; + return promise.then((fn) => { + if (!isFunction(fn)) { + throw qError(QError.qrlIsNotFunction); + } + return bound(...args); + }); + } + if (beforeFn && beforeFn() === false) { + return; + } + const context = createOrReuseInvocationContext(currentCtx); + const prevQrl = context.$qrl$; + const prevEvent = context.$event$; + // Note that we set the qrl here instead of in wrapFn because + // it is possible we're called on a copied qrl + context.$qrl$ = qrl; + context.$event$ ||= this as Event; + try { + return invoke.call(this, context, symbolRef as any, ...(args as any)); + } finally { + context.$qrl$ = prevQrl; + context.$event$ = prevEvent; + } + }; + return bound; + } + + const resolveLazy = (containerEl?: Element): ValueOrPromise => { + return symbolRef !== null ? symbolRef : resolve(containerEl); + }; + + // Wrap functions to provide their lexical scope + const wrapFn = (fn: TYPE): TYPE => { + if (typeof fn !== 'function' || (!capture?.length && !captureRef?.length)) { + return fn; + } + return function (this: unknown, ...args: QrlArgs) { + let context = tryGetInvokeContext(); + // use the given qrl if it is the right one + if (context) { + // TODO check if this is necessary in production + if ((context.$qrl$ as QRLInternal)?.$symbol$ === qrl.$symbol$) { + return fn.apply(this, args); + } + const prevQrl = context.$qrl$; + context.$qrl$ = qrl; + try { + return fn.apply(this, args); + } finally { + context.$qrl$ = prevQrl; + } + } + context = newInvokeContext(); + context.$qrl$ = qrl; + context.$event$ = this as Event; + return invoke.call(this, context, fn as any, ...args); + } as TYPE; + }; + + const resolve = async (containerEl?: Element): Promise => { + if (symbolRef !== null) { + // Resolving (Promise) or already resolved (value) + return symbolRef; + } + if (containerEl) { + setContainer(containerEl); + } + if (chunk === '') { + // Sync QRL + assertDefined(_containerEl, 'Sync QRL must have container element'); + const hash = _containerEl.getAttribute(QInstanceAttr)!; + const doc = _containerEl.ownerDocument!; + const qFuncs = getQFuncs(doc, hash); + // No need to wrap, syncQRLs can't have captured scope + return (qrl.resolved = symbolRef = qFuncs[Number(symbol)] as TYPE); + } + + if (isBrowser && chunk) { + /** We run the QRL, so now the probability of the chunk is 100% */ + preload(chunk, 1); + } + + const start = now(); + const ctx = tryGetInvokeContext(); + if (symbolFn !== null) { + symbolRef = symbolFn().then( + (module) => (qrl.resolved = wrapFn((symbolRef = module[symbol]))) + ); + } else { + const imported = getPlatform().importSymbol(_containerEl, chunk, symbol); + symbolRef = maybeThen(imported, (ref) => (qrl.resolved = wrapFn((symbolRef = ref)))); + } + if (typeof symbolRef === 'object' && isPromise(symbolRef)) { + symbolRef.then( + () => emitUsedSymbol(symbol, ctx?.$element$, start), + (err) => { + console.error(`qrl ${symbol} failed to load`, err); + // We shouldn't cache rejections, we can try again later + symbolRef = null; + } + ); + } + return symbolRef; + }; + + const createOrReuseInvocationContext = (invoke: InvokeContext | InvokeTuple | undefined) => { + if (invoke == null) { + return newInvokeContext(); + } else if (isArray(invoke)) { + return newInvokeContextFromTuple(invoke); + } else { + return invoke; + } + }; + + const hash = getSymbolHash(symbol); + + Object.assign(qrl, { + getSymbol: () => symbol, + getHash: () => hash, + getCaptured: () => captureRef, + resolve, + $resolveLazy$: resolveLazy, + $setContainer$: setContainer, + $chunk$: chunk, + $symbol$: symbol, + $hash$: hash, + getFn: bindFnToContext, + + $capture$: capture, + $captureRef$: captureRef, + dev: null, + resolved: undefined, + }); + if (symbolRef) { + // Unwrap any promises + symbolRef = maybeThen(symbolRef, (resolved) => (qrl.resolved = wrapFn((symbolRef = resolved)))); + } + + if (isDev) { + Object.defineProperty(qrl, '_devOnlySymbolRef', { + get() { + return symbolRef; + }, + }); + } + if (qDev) { + seal(qrl); + } + if (isBrowser && symbol) { + /** + * Preloading the symbol instead of the chunk allows us to get probabilities for the bundle + * based on its contents. + */ + preload(symbol, 0.8); + } + return qrl; +}; + +const EMITTED = /*#__PURE__*/ new Set(); + +export const emitUsedSymbol = (symbol: string, element: Element | undefined, reqTime: number) => { + if (!EMITTED.has(symbol)) { + EMITTED.add(symbol); + emitEvent('qsymbol', { + symbol, + element, + reqTime, + }); + } +}; + +export const emitEvent = (eventName: string, detail: T['detail']) => { + if (!qTest && !isServerPlatform() && typeof document === 'object') { + document.dispatchEvent( + new CustomEvent(eventName, { + bubbles: false, + detail, + }) as T + ); + } +}; + +const now = () => { + if (qTest || isServerPlatform()) { + return 0; + } + if (typeof performance === 'object') { + return performance.now(); + } + return 0; +}; diff --git a/packages/qwik/src/core/shared/qrl/qrl-utils.ts b/packages/qwik/src/core/shared/qrl/qrl-utils.ts new file mode 100644 index 00000000000..d7a48a7f247 --- /dev/null +++ b/packages/qwik/src/core/shared/qrl/qrl-utils.ts @@ -0,0 +1,32 @@ +/** QRL related utilities that you can import without importing all of Qwik. */ + +import { isDev } from '@qwik.dev/core/build'; +import type { QRLInternal, SyncQRLInternal } from './qrl-class'; +import type { QRL } from './qrl.public'; + +export const SYNC_QRL = ''; + +/** Sync QRL is a function which is serialized into `'; + return ( + + ); + }); + + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + + await expect(document.querySelector('button')).toMatchDOM( + + ); + + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + + await expect(document.querySelector('button')).toMatchDOM( + + ); + }); + + it('should render correctly with comment nodes', async () => { + const Cmp = component$(() => { + const counter = useSignal(0); + const doubleCounter = useComputed$(() => counter.value * 2); + return ( + <> + + + {counter.value} + +
    {doubleCounter.value}
    + + + ); + }); + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + 0 +
    + 0 +
    +
    +
    + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + 1 +
    + 2 +
    +
    +
    + ); + }); + + it('should rerender components with the same key and different props', async () => { + const Child = component$<{ value: number; active: boolean }>((props) => { + return ( +
    + Child {props.value}, active: {props.active ? 'true' : 'false'} +
    + ); + }); + + const Cmp = component$(() => { + const signal = useSignal(1); + + const children = [1, 2]; + + return ( +
    + + + + <> + {children.map((value) => { + return ; + })} + +
    + ); + }); + + const { vNode, document } = await render(, { debug }); + await trigger(document.body, '#button-2', 'click'); + expect(vNode).toMatchVDOM( + +
    + + + + +
    + {'Child '} + {'1'} + {', active: '} + {'false'} +
    +
    + +
    + {'Child '} + {'2'} + {', active: '} + {'true'} +
    +
    +
    +
    +
    + ); + await trigger(document.body, '#button-1', 'click'); + expect(vNode).toMatchVDOM( + +
    + + + + +
    + {'Child '} + {'1'} + {', active: '} + {'true'} +
    +
    + +
    + {'Child '} + {'2'} + {', active: '} + {'false'} +
    +
    +
    +
    +
    + ); + }); + + it('should preserve the same elements', async () => { + const Cmp = component$(() => { + const keys = useSignal(['A', 'B', 'C']); + + return ( +
    (keys.value = ['B', 'C', 'A'])}> + {keys.value.map((key) => ( + + {key} + + ))} +
    + ); + }); + + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + +
    + A + B + C +
    +
    + ); + const a1 = document.getElementById('A'); + const b1 = document.getElementById('B'); + const c1 = document.getElementById('C'); + await trigger(document.body, 'div', 'click'); + expect(vNode).toMatchVDOM( + +
    + B + C + A +
    +
    + ); + const a2 = document.getElementById('A'); + const b2 = document.getElementById('B'); + const c2 = document.getElementById('C'); + expect(a1).toBe(a2); + expect(b1).toBe(b2); + expect(c1).toBe(c2); + }); + + it('should render correctly component only with text node and node sibling', async () => { + const Child = component$(() => { + return <>0; + }); + const Parent = component$(() => { + return ( + <> +
    + +
    + test + + ); + }); + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + +
    + + 0 + +
    + test +
    +
    + ); + }); + + it('should rerender both text nodes', async () => { + const SecretForm = component$(() => { + const message = useSignal(''); + const secret = useSignal(''); + + return ( + <> + {message.value &&

    {message.value}

    } + {secret.value &&

    {secret.value}

    } + + + ); + }); + + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + {''} + {''} + + + + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + +

    + {'foo'} +

    +

    + {'bar'} +

    + +
    +
    + ); + }); + + it('should render all components', async () => { + const Ref = component$((props: { id: string }) => { + return
    ; + }); + + const Cmp = component$(() => { + const state = useStore({ + visible: false, + }); + + useVisibleTask$(() => { + state.visible = true; + }); + return ( +
    + + {state.visible && } + + + {state.visible && } + + + {state.visible && } +
    + ); + }); + + const { vNode, document } = await render(, { debug }); + + if (render === ssrRenderToDom) { + expect(vNode).toMatchVDOM( + +
    +
    +
    +
    +
    +
    + ); + await trigger(document.body, '#parent', 'qvisible'); + } + + expect(vNode).toMatchVDOM( + +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + ); + }); + + it('should destructure arguments', async () => { + const PropsDestructuring = component$( + ({ message, id, count: c, ...rest }: Record) => { + const renders = useStore( + { renders: 0 }, + { + reactive: false, + } + ); + renders.renders++; + const rerenders = renders.renders + 0; + return ( +
    + + {message} {c} + +
    {rerenders}
    +
    + ); + } + ); + + const MyComp = component$(() => { + const state = useSignal(0); + return ( + <> + +
    + ); + }); + + const { vNode, container } = await render(, { debug }); + + expect(vNode).toMatchVDOM( + +
    + +
    + Abcd +
    +
    +
    +
    + ); + + await trigger(container.element, 'button', 'click'); + + expect(vNode).toMatchVDOM( + +
    + +
    + Abcd +
    +
    +
    +
    + ); + }); +}); diff --git a/packages/qwik/src/core/tests/ssr-render.spec.tsx b/packages/qwik/src/core/tests/ssr-render.spec.tsx new file mode 100644 index 00000000000..513182c47c3 --- /dev/null +++ b/packages/qwik/src/core/tests/ssr-render.spec.tsx @@ -0,0 +1,244 @@ +import { Slot, useSignal } from '@qwik.dev/core'; +import { ssrRenderToDom, trigger } from '@qwik.dev/core/testing'; +import { describe, expect, it } from 'vitest'; +import { component$ } from '../shared/component.public'; +import { + Fragment as Component, + Fragment, + Fragment as InlineComponent, + Fragment as Projection, +} from '../shared/jsx/jsx-runtime'; +import { SSRComment, SSRRaw, SSRStream, SSRStreamBlock } from '../shared/jsx/utils.public'; +import { delay } from '../shared/utils/promises'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +describe('v2 ssr render', () => { + it('should render jsx', async () => { + const { vNode } = await ssrRenderToDom( + + <>Hello World! + , + { + debug, + } + ); + expect(vNode).toMatchVDOM( + + Hello World! + + ); + }); + it('should render void element correctly', async () => { + const { vNode, container } = await ssrRenderToDom( + , + { + debug, + } + ); + expect(vNode).toMatchVDOM(); + await expect(container.document.querySelector('meta')).toMatchDOM( + + ); + }); + + it('should render SSRRaw', async () => { + const TestCmp = component$(() => { + return ( +
    + +
    + ); + }); + const Cmp = component$(() => { + const rerender = useSignal(0); + return ( +
    + + + + + + a + +
    + ); + }); + const { vNode, document } = await ssrRenderToDom(, { debug }); + expect(vNode).toMatchVDOM( + +
    + + +
    + + a + +
    +
    +
    +
    + ); + expect(document.querySelector('div[data-render]')?.outerHTML).toContain( + '
    hello
    ' + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + +
    + + +
    + + a + +
    +
    +
    +
    + ); + expect(document.querySelector('div[data-render]')?.outerHTML).not.toContain( + '
    hello
    ' + ); + }); + + describe('component', () => { + describe('inline', () => { + it('should render inline component', async () => { + const HelloWorld = (props: { name: string }) => { + return Hello {props.name}!; + }; + + const { vNode } = await ssrRenderToDom(, { debug }); + expect(vNode).toMatchVDOM( + + Hello {'World'}! + + ); + }); + }); + describe('component$', () => { + it('should render simple component', async () => { + const HelloWorld = component$((props: { name: string }) => { + return Hello {props.name}!; + }); + + const { vNode } = await ssrRenderToDom(, { debug }); + expect(vNode).toMatchVDOM( + + Hello {'World'}! + + ); + }); + }); + it('should render nested components', async () => { + const Child = component$((props: { name: string }) => { + return Hello Child: {props.name}; + }); + const Parent = component$((props: { name: string }) => { + return ; + }); + + const { vNode } = await ssrRenderToDom(, { debug }); + expect(vNode).toMatchVDOM( + + + Hello Child: {'World'} + + + ); + }); + }); + describe('stream', () => { + it('should render comment', async () => { + const CommentCmp = component$(() => { + return ; + }); + + const { vNode, document } = await ssrRenderToDom(, { debug }); + expect(vNode).toBe(null); + expect((document.body.firstChild as Element).outerHTML).toEqual(''); + }); + + it('should render SSRStreamBlock', async () => { + const Cmp = component$(() => { + return ( +
    + +
    stream content
    +
    +
    + ); + }); + const { vNode, document } = await ssrRenderToDom(, { debug }); + expect(vNode).toMatchVDOM( + +
    + +
    stream content
    +
    +
    +
    + ); + // we should not stream the comment nodes of the SSRStreamBlock + await expect(document.querySelector('#stream-block')).toMatchDOM( +
    +
    stream content
    +
    + ); + }); + + it('should render values from generator', async () => { + const { vNode } = await ssrRenderToDom( +
      + + {async function* () { + for (let i = 0; i < 5; i++) { + yield
    • yield: {i}
    • ; + await delay(10); + } + }} +
      +
    , + { debug } + ); + + expect(vNode).toMatchVDOM( +
      +
    • yield: 0
    • +
    • yield: 1
    • +
    • yield: 2
    • +
    • yield: 3
    • +
    • yield: 4
    • +
    + ); + }); + + it('should render values from generator with stream', async () => { + const { vNode } = await ssrRenderToDom( +
      + + {async function (stream: any) { + for (let i = 0; i < 5; i++) { + stream.write(
    • raw: {i}
    • ); + await delay(10); + } + }} +
      +
    , + { debug } + ); + + expect(vNode).toMatchVDOM( +
      +
    • raw: 0
    • +
    • raw: 1
    • +
    • raw: 2
    • +
    • raw: 3
    • +
    • raw: 4
    • +
    + ); + }); + }); +}); diff --git a/packages/qwik/src/core/tests/sync-qrl.spec.tsx b/packages/qwik/src/core/tests/sync-qrl.spec.tsx new file mode 100644 index 00000000000..d73ff967adc --- /dev/null +++ b/packages/qwik/src/core/tests/sync-qrl.spec.tsx @@ -0,0 +1,39 @@ +import { component$, sync$ } from '@qwik.dev/core'; +import { domRender, ssrRenderToDom, trigger } from '@qwik.dev/core/testing'; +import { describe, expect, it } from 'vitest'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +describe.each([ + { render: ssrRenderToDom }, // + { render: domRender }, // +])('$render.name: sync-qrl', ({ render }) => { + it('should prevent updates the checkbox', async () => { + const Cmp = component$(() => { + return ( + { + if (target.getAttribute('shouldPreventDefault')) { + e.preventDefault(); + } + target.setAttribute('prevented', String(e.defaultPrevented)); + }), + ]} + /> + ); + }); + + const { document } = await render(, { debug }); + const input = document.querySelector('input'); + + await trigger(document.body, input, 'click'); + expect(input?.getAttribute('prevented')).toBe('false'); + + input?.setAttribute('shouldPreventDefault', 'true'); + await trigger(document.body, input, 'click'); + expect(input?.getAttribute('prevented')).toBe('true'); + }); +}); diff --git a/packages/qwik/src/core/tests/use-computed.spec.tsx b/packages/qwik/src/core/tests/use-computed.spec.tsx new file mode 100644 index 00000000000..bcf30c593cf --- /dev/null +++ b/packages/qwik/src/core/tests/use-computed.spec.tsx @@ -0,0 +1,503 @@ +import { + Fragment, + Fragment as Signal, + component$, + createComputed$, + createSignal, + noSerialize, + qrl, + untrack, + useComputed$, + useComputedQrl, + useLexicalScope, + useSignal, + useStore, + useTask$, +} from '@qwik.dev/core'; +import { domRender, ssrRenderToDom, trigger } from '@qwik.dev/core/testing'; +import { describe, expect, it } from 'vitest'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +describe.each([ + { render: ssrRenderToDom }, // + { render: domRender }, // +])('$render.name: useComputed', ({ render }) => { + const isSsr = render === ssrRenderToDom; + + it('should compute signals synchronously', async () => { + const Counter = component$(() => { + const count = useSignal(123); + const doubleCount = useComputedQrl( + qrl( + // pretend to be an async import + () => + Promise.resolve({ + lazy: () => { + const [count] = useLexicalScope(); + return count.value * 2; + }, + }), + 'lazy', + [count] + ) + ); + return {doubleCount.value}; + }); + + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + {'246'} + + + ); + }); + it('should render correctly with falsy value', async () => { + const Cmp = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + const doubleCount = useComputed$(() => count.value * 2); + return ( +
    + Double count: {doubleCount.value}! {count.value} +
    + ); + }); + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> +
    + Double count: {'0'}! {'0'} +
    + + ); + }); + it('should update value based on signal', async () => { + const DoubleCounter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + const doubleCount = useComputed$(() => count.value * 2); + return ( + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + + ); + expect(container.document.querySelector('button[id=123]')).toBeTruthy(); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + expect(container.document.querySelector('button[id=124]')).toBeTruthy(); + }); + + it('should update value based on another computed', async () => { + const QuadrupleCounter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + const doubleCount = useComputed$(() => count.value * 2); + const quadrupleCount = useComputed$(() => doubleCount.value * 2); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + }); + + it('should not rerun if there are no signal dependencies', async () => { + (globalThis as any).runCount = 0; + const DoubleCounter = component$((props: { initial: number }) => { + const count = props.initial; + const doubleCount = useComputed$(() => { + (globalThis as any).runCount++; + return count * 2; + }); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + + ); + expect((globalThis as any).runCount).toBe(1); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + expect((globalThis as any).runCount).toBe(1); + }); + + it('should not rerun if value did not change', async () => { + (globalThis as any).runCount = 0; + const DoubleCounter = component$(() => { + const count = useSignal(1); + const doubleCount = useComputed$(() => { + (globalThis as any).runCount++; + return count.value * 2; + }); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + + ); + expect((globalThis as any).runCount).toBe(1); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + expect((globalThis as any).runCount).toBe(1); + }); + + it('should allow return signal inside computed', async () => { + const Counter = component$(() => { + const foo = useSignal(1); + const count = useComputed$(() => foo); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + }); + + describe('async computed', () => { + it('should resolve promise in computed result', async () => { + const Counter = component$(() => { + const count = useSignal(1); + const doubleCount = useComputed$(() => Promise.resolve(count.value * 2)); + return ; + }); + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + }); + + it('should resolve delayed promise in computed result', async () => { + const Counter = component$(() => { + const count = useSignal(1); + const doubleCount = useComputed$( + () => + new Promise((resolve) => { + // TODO: hack: for some reason inside set timeout invoke context is undefined + const value = count.value * 2; + setTimeout(() => { + resolve(value); + }); + }) + ); + return ; + }); + const { vNode, container } = await render(, { debug }); + + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + }); + }); + + describe('createComputed$', () => { + it('can be created anywhere', async () => { + const count = createSignal(1); + const doubleCount = createComputed$(() => count.value * 2); + + const Counter = component$(() => { + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + }); + }); + + describe('regression', () => { + it('#4979 - should work with inner computed', async () => { + const InnerComponent = component$((props: { value: number }) => { + const foo = useComputed$(() => props.value); + return
    {JSON.stringify(foo.value)}
    ; + }); + + const OuterComponent = component$(() => { + const count = useSignal(123); + return ( + <> + + {[count.value].map((o) => ( + + ))} + + ); + }); + + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + +
    {'123'}
    +
    +
    +
    + ); + }); + + it('#3294 - should lazily evaluate the function with useSignal', async () => { + (globalThis as any).useComputedCount = 0; + const Issue3294 = component$(() => { + const firstName = useSignal('Misko'); + const lastName = useSignal('Hevery'); + const execFirstUseComputed = useSignal(true); + const firstUseComputed = useComputed$(() => { + (globalThis as any).useComputedCount++; + return lastName.value + ' ' + firstName.value; + }); + const secondUseComputed = useComputed$(() => { + (globalThis as any).useComputedCount++; + return firstName.value + ' ' + lastName.value; + }); + return ( +
    + {execFirstUseComputed.value ? ( + {firstUseComputed.value} + ) : ( + {secondUseComputed.value} + )} +
    + ); + }); + + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> +
    + + Hevery Misko + +
    + + ); + expect((globalThis as any).useComputedCount).toBe(1); + }); + + it('#3294 - should lazily evaluate the function with store', async () => { + (globalThis as any).useComputedCount = 0; + const Issue3294 = component$(() => { + const store = useStore({ firstName: 'Misko', lastName: 'Hevery' }); + const execFirstUseComputed = useSignal(true); + const firstUseComputed = useComputed$(() => { + (globalThis as any).useComputedCount++; + return store.lastName + ' ' + store.firstName; + }); + const secondUseComputed = useComputed$(() => { + (globalThis as any).useComputedCount++; + return store.firstName + ' ' + store.lastName; + }); + return ( +
    + {execFirstUseComputed.value ? ( + {firstUseComputed.value} + ) : ( + {secondUseComputed.value} + )} +
    + ); + }); + + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> +
    + + Hevery Misko + +
    + + ); + expect((globalThis as any).useComputedCount).toBe(1); + }); + + it('#4918 - should not trigger track fn if value is not changed', async () => { + (globalThis as any).logCount = 0; + const Issue4918 = component$(() => { + const countRef = useSignal(0); + const isGreetOneRef = useComputed$(() => { + return countRef.value > 1; + }); + useTask$(({ track }) => { + track(isGreetOneRef); + (globalThis as any).logCount++; + }); + return ( +
    + +
    + ); + }); + + const { document } = await render(, { debug }); + expect((globalThis as any).logCount).toBe(1); + + await trigger(document.body, 'button', 'click'); + expect((globalThis as any).logCount).toBe(1); + await trigger(document.body, 'button', 'click'); + expect((globalThis as any).logCount).toBe(2); + await trigger(document.body, 'button', 'click'); + expect((globalThis as any).logCount).toBe(2); + await trigger(document.body, 'button', 'click'); + expect((globalThis as any).logCount).toBe(2); + }); + }); + + it('should mark noSerialize as invalid after deserialization', async () => { + const Counter = component$(() => { + const count = useSignal(1); + const runCount = useSignal(0); + const showCount = useSignal(false); + const doubleCount = useComputed$(() => { + untrack(() => runCount.value++); + return noSerialize({ double: count.value * 2 }); + }); + return ( +
    + Double count: {doubleCount.value?.double} + + {showCount.value ? {doubleCount.value?.double} : '-'} +
    Ran {runCount.value} times.
    +
    + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + +
    + Double count: {'2'} + + - +
    + Ran {'1'} times. +
    +
    +
    + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> +
    + Double count: {'2'} + + + {'2'} + +
    + Ran {isSsr ? '2' : '1'} times. +
    +
    + , + true + ); + }); +}); diff --git a/packages/qwik/src/core/tests/use-context.spec.tsx b/packages/qwik/src/core/tests/use-context.spec.tsx new file mode 100644 index 00000000000..9bbf32a7bdc --- /dev/null +++ b/packages/qwik/src/core/tests/use-context.spec.tsx @@ -0,0 +1,420 @@ +import { + $, + Fragment as Awaited, + Fragment as Component, + Fragment, + Fragment as Projection, + Slot, + Fragment as WrappedSignal, + _getDomContainer, + component$, + createContextId, + getPlatform, + noSerialize, + setPlatform, + useContext, + useContextProvider, + useSignal, + type NoSerialize, +} from '@qwik.dev/core'; +import { renderToString } from '@qwik.dev/core/server'; +import { + createDocument, + domRender, + emulateExecutionOfQwikFuncs, + ssrRenderToDom, + trigger, +} from '@qwik.dev/core/testing'; +import { describe, expect, it, vi } from 'vitest'; +import type { Signal } from '../reactive-primitives/signal.public'; +import { ErrorProvider } from '../../testing/rendering.unit-util'; +import * as qError from '../shared/error/error'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +/** + * Below are helper functions that are constant. They have to be in the top level scope so that the + * optimizer doesn't consider them as captured scope. It would be great if the optimizer could + * detect that these are constant and don't require capturing. + */ +interface MyStore { + value: number; +} +const myFooFnContext = createContextId('mytitle'); +const useFooFn = () => { + const state = useContext(myFooFnContext); + + return $((val: number) => { + return (state.value + val).toString(); + }); +}; + +describe.each([ + { render: ssrRenderToDom }, // + { render: domRender }, // +])('$render.name: useContext', ({ render }) => { + it('should provide and retrieve a context', async () => { + const contextId = createContextId<{ value: string }>('myTest'); + const Consumer = component$(() => { + const ctxValue = useContext(contextId); + return {ctxValue.value}; + }); + const Provider = component$(() => { + useContextProvider(contextId, { value: 'CONTEXT_VALUE' }); + return ; + }); + + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + CONTEXT_VALUE + + + + ); + }); + it('should provide and retrieve a context on client change', async () => { + const contextId = createContextId<{ value: string }>('myTest'); + const Consumer = component$(() => { + const ctxValue = useContext(contextId); + return {ctxValue.value}; + }); + const Provider = component$(() => { + useContextProvider(contextId, { value: 'CONTEXT_VALUE' }); + const show = useSignal(false); + return show.value ? : + + ); + }); + + try { + const { document } = await render( + + + , + { debug } + ); + await trigger(document.body, 'button', 'click'); + expect(qErrorSpy).not.toHaveBeenCalled(); + } catch (e) { + expect(qErrorSpy).not.toHaveBeenCalled(); + } + }); + + it('should find context parent from Slot inside Slot', async () => { + const qErrorSpy = vi.spyOn(qError, 'qError'); + const contextId = createContextId('contextId'); + + const ContextProducer = component$(() => { + const context = { + disabled: false, + }; + useContextProvider(contextId, context); + return ; + }); + + const ProducerParent = component$(() => { + return ( + + + + ); + }); + + const ContextConsumer = component$(() => { + useContext(contextId); + return ; + }); + + const Parent = component$(() => { + return ( + + + + ); + }); + + try { + await render( + + + , + { debug } + ); + expect(qErrorSpy).not.toHaveBeenCalled(); + } catch (e) { + expect(qErrorSpy).not.toHaveBeenCalled(); + } + }); + + describe('regression', () => { + it('#4038', async () => { + interface IMyComponent { + val: string; + } + const MyComponent = component$((props: IMyComponent) => { + const count = useSignal(0); + const c = useFooFn(); + + return ( + <> +

    {props.val}

    +

    {c(count.value)}

    +

    {count.value}

    + + + ); + }); + + const Parent = component$(() => { + const c = useFooFn(); + + return ( +
    + {c(1).then((val) => ( + + ))} +
    + ); + }); + + const Layout = component$(() => { + useContextProvider(myFooFnContext, { + value: 0, + }); + return ; + }); + const { vNode, document } = await render( + + + , + { debug } + ); + expect(vNode).toMatchVDOM( + + + +
    + + + +

    + 1 +

    +

    + 0 +

    +

    + 0 +

    + +
    +
    +
    +
    +
    +
    +
    + ); + await trigger(document.body, 'button', 'click'); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + +
    + + + +

    + 1 +

    +

    + 2 +

    +

    + 2 +

    + +
    +
    +
    +
    +
    +
    +
    + ); + }); + it('#5270 - retrieve context on un-projected component', async () => { + const Issue5270Context = createContextId<{ hi: string }>('5270'); + const ProviderParent = component$(() => { + useContextProvider(Issue5270Context, { hi: 'hello' }); + const projectSlot = useSignal(false); + return ( +
    + +
    + {projectSlot.value && } +
    + ); + }); + const ContextChild = component$(() => { + // return ; + const t = useContext(Issue5270Context); + return
    Ctx: {t.hi}
    ; + }); + const Issue5270 = component$(() => { + useContextProvider(Issue5270Context, { hi: 'wrong' }); + return ( + + + + ); + }); + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + +
    + +

    + {'' /** Slot not projected */} +
    +
    +
    + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + +
    + +

    + + +
    + {'Ctx: '} + {'hello'} +
    +
    +
    +
    +
    +
    + ); + }); + }); +}); + +describe('html wrapper', () => { + it('should provide and retrieve a context in client', async () => { + const contextId = createContextId>>('myTest'); + const Consumer = component$(() => { + const ctxValue = useContext(contextId); + return {ctxValue.value?.value}; + }); + const Test = component$(() => { + const data = useContext(contextId); + const show = useSignal(false); + + return ( + <> + + {show.value && } + + ); + }); + const Provider = component$(() => { + const data = useSignal(); + useContextProvider(contextId, data); + + return ; + }); + + let document = createDocument(); + const platform = getPlatform(); + try { + const result = await renderToString( + + + + + + + ); + document = createDocument({ html: result.html }); + } finally { + setPlatform(platform); + } + + emulateExecutionOfQwikFuncs(document); + const container = _getDomContainer(document.querySelector('[q\\:container]')!); + + await trigger(container.document.body, 'button', 'click'); + + expect(document.querySelector('span')?.innerHTML).toContain('CONTEXT_VALUE'); + }); +}); diff --git a/packages/qwik/src/core/tests/use-id.spec.tsx b/packages/qwik/src/core/tests/use-id.spec.tsx new file mode 100644 index 00000000000..244eb453859 --- /dev/null +++ b/packages/qwik/src/core/tests/use-id.spec.tsx @@ -0,0 +1,44 @@ +import { component$, componentQrl, inlinedQrl, useId } from '@qwik.dev/core'; +import { describe, expect, it } from 'vitest'; +import { domRender, ssrRenderToDom } from '@qwik.dev/core/testing'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +describe.each([ + { render: ssrRenderToDom }, // + { render: domRender }, // +])('$render.name: useId', ({ render }) => { + it('should generate id', async () => { + const Cmp = componentQrl( + inlinedQrl(() => { + const id = useId(); + return
    {id}
    ; + }, 's_cmpHash') + ); + const Cmp2 = componentQrl( + inlinedQrl(() => { + const id = useId(); + return
    {id}
    ; + }, 's_2cmpHash') + ); + + const Parent = component$(() => { + return ( + <> + + + + ); + }); + + const { document } = await render(, { debug }); + if (render === ssrRenderToDom) { + expect(document.querySelector('#cmp1')?.textContent).toMatch(/^\w{3}cmp0$/); + expect(document.querySelector('#cmp2')?.textContent).toMatch(/^\w{3}2cm1$/); + } else { + expect(document.querySelector('#cmp1')?.textContent).toMatch(/^cmp0$/); + expect(document.querySelector('#cmp2')?.textContent).toMatch(/^Ccm1$/); + } + }); +}); diff --git a/packages/qwik/src/core/tests/use-lexical-scope.spec.tsx b/packages/qwik/src/core/tests/use-lexical-scope.spec.tsx new file mode 100644 index 00000000000..935dd5fddf2 --- /dev/null +++ b/packages/qwik/src/core/tests/use-lexical-scope.spec.tsx @@ -0,0 +1,147 @@ +import { domRender, ssrRenderToDom, trigger } from '@qwik.dev/core/testing'; +import { describe, expect, it } from 'vitest'; +import { + component$, + useStore, + useSignal, + Fragment as Component, + Fragment as Signal, +} from '@qwik.dev/core'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +describe.each([ + { render: ssrRenderToDom }, // + { render: domRender }, // +])('$render.name: useLexicalScope', ({ render }) => { + it('should update const prop event value', async () => { + type Cart = string[]; + + const Parent = component$(() => { + const cart = useStore([]); + const results = useSignal(['foo', 'bar']); + + return ( +
    + + + {results.value.map((item, key) => ( + + ))} +
      + {cart.map((item) => ( +
    • + {item} +
    • + ))} +
    +
    + ); + }); + + const { vNode, document } = await render(, { debug }); + + expect(vNode).toMatchVDOM( + +
    + + + +
      +
      +
      + ); + + await trigger(document.body, 'button#first', 'click'); + + expect(vNode).toMatchVDOM( + +
      + + + +
        +
        +
        + ); + + await trigger(document.body, 'button#second-1', 'click'); + + expect(vNode).toMatchVDOM( + +
        + + + +
          +
        • + item2 +
        • +
        +
        +
        + ); + }); + + describe('regression', () => { + it('#5662 - should update value in the list', async () => { + /** + * ROOT CAUSE ANALYSIS: This is a bug in Optimizer. The optimizer incorrectly marks the + * `onClick` listener as 'const'/'immutable'. Because it is const, the QRL associated with the + * click handler always points to the original object, and it is not updated. + */ + const Cmp = component$(() => { + const store = useStore<{ users: { name: string }[] }>({ users: [{ name: 'Giorgio' }] }); + + return ( +
        + {store.users.map((user, key) => ( + { + store.users = store.users.map(({ name }: { name: string }) => ({ + name: name === user.name ? name + '!' : name, + })); + }} + > + {user.name} + + ))} +
        + ); + }); + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + +
        + + {'Giorgio'} + +
        +
        + ); + await trigger(container.element, 'span', 'click'); + await trigger(container.element, 'span', 'click'); + await trigger(container.element, 'span', 'click'); + await trigger(container.element, 'span', 'click'); + await trigger(container.element, 'span', 'click'); + expect(vNode).toMatchVDOM( + +
        + + {'Giorgio!!!!!'} + +
        +
        + ); + }); + }); +}); diff --git a/packages/qwik/src/core/tests/use-on.spec.tsx b/packages/qwik/src/core/tests/use-on.spec.tsx new file mode 100644 index 00000000000..04e06829285 --- /dev/null +++ b/packages/qwik/src/core/tests/use-on.spec.tsx @@ -0,0 +1,884 @@ +import { + $, + Fragment as Awaited, + Fragment as Component, + Fragment as Projection, + component$, + Fragment, + Fragment as Signal, + Slot, + useOn, + useOnDocument, + useOnWindow, + useSignal, + useTask$, + useVisibleTask$, +} from '@qwik.dev/core'; +import { domRender, ssrRenderToDom, trigger } from '@qwik.dev/core/testing'; +import { describe, expect, it } from 'vitest'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +describe.each([ + { render: ssrRenderToDom }, // + { render: domRender }, // +])('$render.name: useOn', ({ render }) => { + it('should update value', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + useOn( + 'click', + $(() => count.value++) + ); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + }); + + it('should update value with multiple useOn', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + useOn( + 'click', + $(() => count.value++) + ); + useOn( + 'focus', + $(() => { + count.value += 2; + }) + ); + useVisibleTask$(() => { + count.value += 2; + }); + return ; + }); + + const { vNode, container } = await render(, { debug }); + if (render === ssrRenderToDom) { + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'qvisible'); + } + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'focus'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should update value with mixed listeners', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + useOn( + 'click', + $(() => count.value++) + ); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'focus'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + describe('useOnDocument', () => { + it('should update value', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + useOnDocument( + 'click', + $(() => count.value++) + ); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + + await trigger(container.element, 'button', ':document:click'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should update value with multiple useOnDocument', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + useOnDocument( + 'click', + $(() => count.value++) + ); + useOnDocument( + 'focus', + $(() => { + count.value += 2; + }) + ); + useVisibleTask$(() => { + count.value += 2; + }); + return ; + }); + + const { vNode, container } = await render(, { debug }); + if (render === ssrRenderToDom) { + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'qvisible'); + } + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', ':document:click'); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', ':document:focus'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should work with empty component', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + useOnDocument( + 'click', + $(() => count.value++) + ); + return <>Count: {count.value}!; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + Count: {'123'}! + + + ); + + await trigger(container.element, 'script', ':document:click'); + expect(vNode).toMatchVDOM( + + + Count: {'124'}! + + + ); + }); + + it('should update value with mixed listeners', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + useOnWindow( + 'click', + $(() => count.value++) + ); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', ':window:click'); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'focus'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should update value for DOMContentLoaded event', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + useOnDocument( + 'DOMContentLoaded', + $(() => count.value++) + ); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', ':document:DOMContentLoaded'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should update value for DOMContentLoaded jsx event', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + return ( + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', ':document:DOMContentLoaded'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should not execute custom event QRL for deleted vnode', async () => { + (globalThis as any).dispatchCustomEvent = () => {}; + (globalThis as any).receivedLog = []; + const DispatchChild = component$(() => { + useTask$(() => { + (globalThis as any).dispatchCustomEvent(); + }); + return <>; + }); + const ReceiveChild = component$(() => { + useOnDocument( + 'child', + $(() => { + (globalThis as any).receivedLog.push('child event'); + }) + ); + return <>; + }); + const Parent = component$(() => { + const toggle = useSignal(true); + return ( + <> + + {toggle.value ? ( + <> + + + + ) : ( + <> + + + + )} + + ); + }); + + const { container, document } = await render(, { debug }); + (globalThis as any).dispatchCustomEvent = () => { + // don't await for this event + trigger(document.documentElement, '[on-document\\:child]', ':document:child'); + }; + // trigger the change + await trigger(container.element, 'button', 'click'); + // event should not be executed for deleted vnodes + expect((globalThis as any).receivedLog).toEqual([]); + }); + }); + + describe('useOnWindow', () => { + it('should update value', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + useOnWindow( + 'click', + $(() => count.value++) + ); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + + await trigger(container.element, 'button', ':window:click'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should work with empty component', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + useOnWindow( + 'click', + $(() => count.value++) + ); + return <>Count: {count.value}!; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + Count: {'123'}! + + + ); + + await trigger(container.element, 'script', ':window:click'); + expect(vNode).toMatchVDOM( + + + Count: {'124'}! + + + ); + }); + + it('should update value for window event on element and useOnWindow', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + useOnWindow( + 'dblclick', + $(() => count.value++) + ); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + + await trigger(container.element, 'button', ':window:dblclick'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should update value with multiple useOnWindow', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + useOnWindow( + 'click', + $(() => count.value++) + ); + useOnWindow( + 'focus', + $(() => { + count.value += 2; + }) + ); + useVisibleTask$(() => { + count.value += 2; + }); + return ; + }); + + const { vNode, container } = await render(, { debug }); + if (render === ssrRenderToDom) { + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'qvisible'); + } + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', ':window:click'); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', ':window:focus'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should update value with mixed listeners', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + useOnDocument( + 'click', + $(() => count.value++) + ); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', ':document:click'); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'focus'); + expect(vNode).toMatchVDOM( + + + + ); + }); + }); + + describe('custom events', () => { + it('should update counter for useOn', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + useOn( + '-SomeCustomEvent', + $(() => count.value++) + ); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + + await trigger(container.element, 'button', 'SomeCustomEvent'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should update counter for jsx event', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + + await trigger(container.element, 'button', 'SomeCustomEvent'); + expect(vNode).toMatchVDOM( + + + + ); + }); + }); + + it('should update value with useOn, useOnDocument and useOnWindow', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + useOn( + 'click', + $(() => count.value++) + ); + useOnWindow( + 'focus', + $(() => { + count.value += 2; + }) + ); + useOnDocument( + 'blur', + $(() => { + count.value += 3; + }) + ); + useVisibleTask$(() => { + count.value += 2; + }); + return ; + }); + + const { vNode, container } = await render(, { debug }); + if (render === ssrRenderToDom) { + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'qvisible'); + } + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', ':window:focus'); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', ':document:blur'); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'resize'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should not add script node in empty components for specific events', async () => { + const Cmp = component$(() => { + const signal = useSignal('empty'); + useOn( + 'click', + $(() => { + signal.value = 'run'; + }) + ); + return <>{signal.value}; + }); + const { vNode, document } = await render(, { debug }); + await trigger(document.body, 'script', 'click'); + expect(vNode).toMatchVDOM( + + + {'empty'} + + + ); + }); + + it('should add event to element returned by promise', async () => { + const Cmp = component$(() => { + const signal = useSignal('empty'); + useOn( + 'click', + $(() => { + signal.value = 'run'; + }) + ); + return <>{Promise.resolve(
        {signal.value}
        )}; + }); + const { vNode, document } = await render(, { debug }); + await trigger(document.body, 'div', 'click'); + expect(vNode).toMatchVDOM( + + + +
        + {'run'} +
        +
        +
        +
        + ); + }); + + it('should add event to element returned by signal', async () => { + const Cmp = component$(() => { + const signal = useSignal('empty'); + const jsx = useSignal(
        {signal.value}
        ); + useOn( + 'click', + $(() => { + signal.value = 'run'; + }) + ); + return <>{jsx.value}; + }); + const { vNode, document } = await render(, { debug }); + await trigger(document.body, 'div', 'click'); + expect(vNode).toMatchVDOM( + + + +
        + {'run'} +
        +
        +
        +
        + ); + }); + + it('should add only one event', async () => { + const Cmp = component$(() => { + const signal = useSignal(0); + useOn( + 'click', + $(() => { + signal.value++; + }) + ); + + useTask$(async ({ track }) => { + track(() => signal); + // rerender component twice + await Promise.resolve(); + await Promise.resolve(); + }); + return <>{Promise.resolve(
        {signal.value}
        )}; + }); + const { document } = await render(, { debug }); + await trigger(document.body, 'div', 'click'); + await expect(document.querySelector('div')).toMatchDOM(
        1
        ); + }); + + describe('regression', () => { + it('#7230 - when multiple useOn are used in a component that is not rendered, it should add multiple script nodes', async () => { + const BreakpointProvider = component$(() => { + useOnDocument( + 'click', + $(() => {}) + ); + + useOnWindow( + 'resize', + $(() => {}) + ); + + useVisibleTask$(() => {}); + + return ; + }); + + const LayoutTest = component$(() => { + return ( + +
        test
        +
        + ); + }); + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + +
        test
        +
        + + + +
        +
        +
        + ); + }); + it('#7230 - when useOnDocument is used in a component that is not rendered, it should add a script node', async () => { + const BreakpointProvider = component$(() => { + useOnDocument( + 'click', + $(() => {}) + ); + + return ; + }); + + const Layout = component$(() => { + return ( + +
        test
        +
        + ); + }); + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + +
        test
        +
        + +
        +
        +
        + ); + }); + }); +}); diff --git a/packages/qwik/src/core/tests/use-resource.spec.tsx b/packages/qwik/src/core/tests/use-resource.spec.tsx new file mode 100644 index 00000000000..8fcc8a93382 --- /dev/null +++ b/packages/qwik/src/core/tests/use-resource.spec.tsx @@ -0,0 +1,590 @@ +import { + Fragment as Awaited, + Fragment as Component, + Fragment, + Fragment as InlineComponent, + Resource, + Fragment as Signal, + component$, + useResource$, + useSignal, + useStore, + type ResourceReturn, +} from '@qwik.dev/core'; +import { domRender, getTestPlatform, ssrRenderToDom, trigger } from '@qwik.dev/core/testing'; +import { describe, expect, it } from 'vitest'; +import '../../testing/vdom-diff.unit-util'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +export function mutable(value: any) { + return value; +} + +describe.each([ + { render: ssrRenderToDom }, // + { render: domRender }, // +])('$render.name: useResource', ({ render }) => { + it('should execute resource task', async () => { + const TestCmp = component$(() => { + const rsrc = useResource$(() => 'RESOURCE_VALUE'); + return ( +
        + {v}} /> +
        + ); + }); + + const { vNode } = await render(, { debug }); + const result = RESOURCE_VALUE; + expect(vNode).toMatchVDOM( + +
        + + + {result} + + +
        +
        + ); + }); + + it('should update resource task', async () => { + const TestCmp = component$(() => { + const count = useSignal(0); + const rsrc = useResource$(async ({ track }) => { + return track(count); + }); + return ( + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should show loading state', async () => { + (global as any).delay = () => new Promise((res) => ((global as any).delay.resolve = res)); + const ResourceCmp = component$(() => { + const count = useSignal(0); + const rsrc = useResource$(async ({ track }) => { + const value = track(() => count.value); + if (count.value === 1) { + await (global as any).delay(); + } + return value; + }); + return ( + + ); + }); + const { vNode, container } = await render(, { debug }); + + expect(vNode).toMatchVDOM( + + + + ); + + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + await (global as any).delay.resolve(); + await getTestPlatform().flush(); + + expect(vNode).toMatchVDOM( + + + + ); + (global as any).delay = undefined; + }); + + it('should immediately increment button count', async () => { + (global as any).delay = () => new Promise((res) => ((global as any).delay.resolve = res)); + const ResourceCmp = component$(() => { + const count = useSignal(0); + const resource = useResource$(async ({ track }) => { + track(count); + const value = count.value; + if (count.value >= 1) { + await (global as any).delay(); + } + return value; + }); + + return ( + <> + +
        {data}
        } /> + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + + + +
        0
        +
        +
        +
        +
        +
        + ); + await trigger(container.element, 'button', 'click'); + + expect(vNode).toMatchVDOM( + + + + + + +
        0
        +
        +
        +
        +
        +
        + ); + await (global as any).delay.resolve(); + await getTestPlatform().flush(); + + expect(vNode).toMatchVDOM( + + + + + + +
        1
        +
        +
        +
        +
        +
        + ); + (global as any).delay = undefined; + }); + + it('should handle multiple the same resource tasks', async () => { + (global as any).delay = () => new Promise((res) => ((global as any).delay.resolve = res)); + + const ResourceRaceCondition = component$(() => { + const count = useSignal(0); + const resource = useResource$(async ({ track }) => { + track(count); + const value = count.value; + if (count.value === 1) { + await (global as any).delay(); + } + return value; + }); + + return ( + <> + +
        {data}
        } /> + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + + + +
        0
        +
        +
        +
        +
        +
        + ); + // double click + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + await (global as any).delay.resolve(); + await getTestPlatform().flush(); + + expect(vNode).toMatchVDOM( + + + + + + +
        2
        +
        +
        +
        +
        +
        + ); + }); + + it('should render component on resolved', async () => { + const MyButton = component$(() => { + return
        ; + }); + + const Cmp = component$(() => { + const text = useSignal(''); + + const textResource = useResource$(async (ctx) => { + return ctx.track(() => text.value); + }); + + return ( + <> + ( + <> + + + )} + /> + + ); + }); + + const { vNode } = await render(, { debug }); + + expect(vNode).toMatchVDOM( + + + + + + + +
        +
        +
        +
        +
        +
        +
        +
        + ); + }); + + it('should update elements correctly inside onResolved fn', async () => { + const ResourceCmp = component$(() => { + const count = useSignal(0); + const resource = useResource$(async ({ track }) => { + track(count); + return count.value + 10; + }); + + return ( + <> + +

        Loading..

        } + onRejected={() =>

        error ...

        } + onResolved={(data) => ( + <> +
        {data}
        + + + )} + /> + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + + + + +
        10
        + +
        +
        +
        +
        +
        +
        + ); + await trigger(container.element, 'button', 'click'); + + expect(vNode).toMatchVDOM( + + + + + + + +
        11
        + +
        +
        +
        +
        +
        +
        + ); + }); + + it('should track subscription', async () => { + const Results = component$((props: { result: ResourceReturn }) => { + const state = useStore({ + count: 0, + }); + return ( +
        + { + return ( + <> +
        resource 1 is {number}
        + + + ); + }} + /> +
        + ); + }); + + const ResourceApp = component$(() => { + const resource = useResource$(() => { + return 0; + }); + + return ; + }); + + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + +
        + + + + +
        + {'resource 1 is '} + {'0'} +
        + +
        +
        +
        +
        +
        +
        +
        + ); + + await trigger(document.body, 'button', 'click'); + + expect(vNode).toMatchVDOM( + + +
        + + + + +
        + {'resource 1 is '} + {'0'} +
        + +
        +
        +
        +
        +
        +
        +
        + ); + + await trigger(document.body, 'button', 'click'); + + expect(vNode).toMatchVDOM( + + +
        + + + + +
        + {'resource 1 is '} + {'0'} +
        + +
        +
        +
        +
        +
        +
        +
        + ); + }); + + it('should render array from resource', async () => { + const Cmp = component$(() => { + const resource = useResource$(() => { + return [ + { + id: 1, + name: 'John Doe', + age: 30, + }, + { + id: 2, + name: 'Jane Smith', + age: 25, + }, + ]; + }); + + return ( + { + return res.map((val, index) => ( +
        +

        {val.id}

        +

        {val.name}

        +

        {val.age}

        +
        + )); + }} + /> + ); + }); + + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + +
        +

        + 1 +

        +

        + John Doe +

        +

        + 30 +

        +
        +
        +

        + 2 +

        +

        + Jane Smith +

        +

        + 25 +

        +
        +
        +
        +
        +
        + ); + }); +}); diff --git a/packages/qwik/src/core/tests/use-sequential-scope.spec.tsx b/packages/qwik/src/core/tests/use-sequential-scope.spec.tsx new file mode 100644 index 00000000000..9be7acca6a3 --- /dev/null +++ b/packages/qwik/src/core/tests/use-sequential-scope.spec.tsx @@ -0,0 +1,41 @@ +import { componentQrl, inlinedQrl } from '@qwik.dev/core'; +import { domRender, trigger } from '@qwik.dev/core/testing'; +import { describe, expect, it } from 'vitest'; +import { rerenderComponent } from '../../testing/rendering.unit-util'; +import { useSequentialScope } from '../use/use-sequential-scope'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +describe('useSequentialScope', () => { + it('should update value', async () => { + const MyComp = componentQrl( + inlinedQrl(() => { + const { set, i, val } = useSequentialScope(); + if (val == null) { + set('first_value'); + } + + return ( + + ); + }, 'MyComp') + ); + + const { vNode, container } = await domRender(, { debug }); + await trigger(container.element, 'button', 'click'); + + expect(vNode).toMatchVDOM( + <> + + + ); + }); +}); diff --git a/packages/qwik/src/core/tests/use-serialized.spec.tsx b/packages/qwik/src/core/tests/use-serialized.spec.tsx new file mode 100644 index 00000000000..209dc8b9807 --- /dev/null +++ b/packages/qwik/src/core/tests/use-serialized.spec.tsx @@ -0,0 +1,246 @@ +import { + SerializerSymbol, + Fragment, + Fragment as Signal, + Fragment as Component, + component$, + useSignal, +} from '@qwik.dev/core'; +import { domRender, ssrRenderToDom, trigger } from '@qwik.dev/core/testing'; +import { describe, expect, it } from 'vitest'; +import { useSerializer$ } from '../use/use-serializer'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +// This is almost the same as useComputed, so we only test the custom serialization +describe.each([ + { render: ssrRenderToDom }, // + { render: domRender }, // +])('$render.name: useSerializer$', ({ render }) => { + it('should do custom serialization', async () => { + const Counter = component$(() => { + const myCount = useSerializer$({ + deserialize: (count) => new CustomSerialized(count), + serialize: (data) => data.count, + initial: 2, + }); + const spy = useSignal(myCount.value.count); + return ( + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + }); + it('should update reactively', async () => { + const Counter = component$(() => { + const sig = useSignal(1); + const myCount = useSerializer$(() => ({ + deserialize: () => new CustomSerialized(sig.value * 2), + update: (current) => { + current.count = sig.value * 2; + return current; + }, + })); + return ( + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + // We need to click again because after SSR the first click will run the deserialize, not the update + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + }); + it('should support [SerializerSymbol]', async () => { + const Counter = component$(() => { + const count = useSerializer$({ + deserialize: (data: number) => new WithSerialize(data), + }); + return ( + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + }); + + it('should not crash when used many times', async () => { + // We don't have the Signal type here + const MyComponent = component$(({ foo }: { foo: { value: number } }) => { + const custom = useSerializer$(() => ({ + initial: { bar: 'bar' }, + serialize: (c: Custom) => { + return { foo: c.foo, bar: c.bar }; + }, + deserialize: (d) => new Custom(foo.value, d.bar), + update: (c) => { + c.foo = foo.value; + return c; + }, + })); + + return ( + + ); + }); + + const App = component$(() => { + const foo = useSignal(0); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + + + ); + }); +}); + +class CustomSerialized { + constructor(public count = 0) {} + inc() { + this.count++; + } +} + +class WithSerialize { + constructor(public count = 0) {} + inc() { + this.count++; + } + [SerializerSymbol](obj: this) { + return obj.count; + } +} + +class Custom { + constructor( + private _foo: number, + private _bar: string + ) {} + get foo() { + return this._foo; + } + set foo(value) { + this._foo = value; + } + get bar() { + return this._bar; + } + set bar(value) { + this._bar = value; + } +} diff --git a/packages/qwik/src/core/tests/use-signal.spec.tsx b/packages/qwik/src/core/tests/use-signal.spec.tsx new file mode 100644 index 00000000000..e3808ca3eaf --- /dev/null +++ b/packages/qwik/src/core/tests/use-signal.spec.tsx @@ -0,0 +1,690 @@ +import { + Fragment as Awaited, + Fragment as Component, + Fragment, + Fragment as Projection, + Fragment as Signal, + useVisibleTask$, +} from '@qwik.dev/core'; +import { describe, expect, it } from 'vitest'; +import { trigger, domRender, ssrRenderToDom } from '@qwik.dev/core/testing'; +import { component$, Slot, type Signal as SignalType, untrack, useSignal } from '@qwik.dev/core'; +import { _EFFECT_BACK_REF } from '@qwik.dev/core/internal'; +import { vnode_getFirstChild, vnode_locate } from '../client/vnode'; +import { EffectSubscriptionProp } from '../reactive-primitives/types'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +describe.each([ + { render: ssrRenderToDom }, // + { render: domRender }, // +])('$render.name: useSignal', ({ render }) => { + it('should update value', async () => { + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + return ( + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + }); + it('should rerender child', async () => { + const log: string[] = []; + const Display = component$((props: { dValue: number }) => { + log.push('Display'); + return Count: {props.dValue}!; + }); + const Counter = component$((props: { initial: number }) => { + log.push('Counter'); + const count = useSignal(props.initial); + return ( + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(log).toEqual(['Counter', 'Display']); + expect(vNode).toMatchVDOM( + <> + + + ); + }); + it('should update from JSX', async () => { + const Child = component$(() => { + return ( + + + + ); + }); + + const Counter = component$((props: { initial: number }) => { + const jsx = useSignal(content); + const show = useSignal(false); + return ( + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + }); + it('should render promise values', async () => { + const MyCmp = component$(() => { + const promise = Promise.resolve('const '); + const signal = useSignal(Promise.resolve(0)); + return ( + + ); + }); + + const { vNode, container, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await expect(document.querySelector('button')).toMatchDOM(); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + await expect(document.querySelector('button')).toMatchDOM(); + }); + it('should handle all ClassList cases', async () => { + const Cmp = component$(() => { + const enable = useSignal(true); + return ( +
        + +
        + + +
        + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + +
        + +
        + + +
        + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + +
        + +
        + + +
        + + ); + }); + + it('should not execute signal when not used', async () => { + const Cmp = component$(() => { + const data = useSignal<{ price: number } | null>({ price: 100 }); + return ( +
        + + {data.value == null && not found} + {data.value != null && {data.value.price}} +
        + ); + }); + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + +
        + + {''} + + 100 + +
        +
        + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + +
        + + not found + {''} +
        +
        + ); + }); + + it('should deserialize signal without effects', async () => { + const Cmp = component$(() => { + const counter = useSignal(0); + useVisibleTask$(() => { + counter.value++; + }); + return
        ; + }); + + const { vNode, document } = await render(, { debug }); + if (render === ssrRenderToDom) { + await trigger(document.body, 'div', 'qvisible'); + } + expect(vNode).toMatchVDOM( + +
        +
        + ); + }); + + describe('signals cleanup', () => { + it('should not add multiple same subscribers for virtual node', async () => { + const Child = component$(() => { + return <>; + }); + + const Cmp = component$(() => { + const counter = useSignal(0); + const cleanupCounter = useSignal(0); + + return ( + <> + + +
        {cleanupCounter.value + ''}
        + + ); + }); + + const { container } = await render(, { debug }); + + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + + const signalVNode = vnode_getFirstChild( + vnode_locate(container.rootVNode, container.element.querySelector('pre')!) + )!; + const subscribers = (signalVNode as any)[_EFFECT_BACK_REF]; + expect(subscribers).toHaveLength(1); + }); + + it('should not add multiple same subscribers for element node', async () => { + (globalThis as any).signal = undefined; + + const Cmp = component$(() => { + const show = useSignal(true); + const cleanupCounter = useSignal(0); + + useVisibleTask$(() => { + untrack(() => ((globalThis as any).signal = cleanupCounter)); + }); + + return ( +
        + + {show.value &&
        }
        +          
        + ); + }); + + const { container } = await render(, { debug }); + + if (render === ssrRenderToDom) { + await trigger(container.element, 'div', 'qvisible'); + } + + expect( + // wrapped signal on the pre element + (globalThis as any).signal.$effects$.values().next().value[EffectSubscriptionProp.CONSUMER] + .$effects$ + ).toHaveLength(1); + expect((globalThis as any).signal.$effects$).toHaveLength(1); + + await trigger(container.element, 'button', 'click'); + expect((globalThis as any).signal.$effects$).toHaveLength(0); + + await trigger(container.element, 'button', 'click'); // <-- this should not add another subscriber + expect((globalThis as any).signal.$effects$).toHaveLength(1); + expect( + (globalThis as any).signal.$effects$.values().next().value[EffectSubscriptionProp.CONSUMER] + .$effects$ + ).toHaveLength(1); + + await trigger(container.element, 'button', 'click'); + expect((globalThis as any).signal.$effects$).toHaveLength(0); + + await trigger(container.element, 'button', 'click'); // <-- this should not add another subscriber + expect((globalThis as any).signal.$effects$).toHaveLength(1); + expect( + (globalThis as any).signal.$effects$.values().next().value[EffectSubscriptionProp.CONSUMER] + .$effects$ + ).toHaveLength(1); + + (globalThis as any).signal = undefined; + }); + }); + + describe('derived', () => { + it('should update value directly in DOM', async () => { + const log: string[] = []; + const Counter = component$((props: { initial: number }) => { + const count = useSignal(props.initial); + log.push('Counter: ' + untrack(() => count.value)); + return ; + }); + + const { vNode, container } = await render(, { + debug, + // oldSSR: true, + }); + expect(log).toEqual(['Counter: 123']); + log.length = 0; + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'click'); + expect(log).toEqual([]); + log.length = 0; + expect(vNode).toMatchVDOM( + <> + + + ); + }); + it('should allow signal to deliver value or JSX', async () => { + const log: string[] = []; + const Counter = component$(() => { + const count = useSignal('initial'); + log.push('Counter: ' + untrack(() => count.value)); + return ( + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(log).toEqual(['Counter: initial']); + log.length = 0; + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'click'); + expect(log).toEqual([]); + log.length = 0; + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(log).toEqual([]); + log.length = 0; + expect(vNode).toMatchVDOM( + <> + + + ); + }); + it('should update value when store, update and render are separated', async () => { + const renderLog: string[] = []; + const Display = component$((props: { displayValue: number }) => { + renderLog.push('Display'); + return <>Count: {props.displayValue}!; + }); + const Incrementor = component$((props: { countSignal: SignalType }) => { + renderLog.push('Incrementor'); + return ( + + ); + }); + const Counter = component$(() => { + renderLog.push('Counter'); + const count = useSignal(123); + return ( + <> + + + + ); + }); + const { vNode, container } = await render(, { debug }); + expect(renderLog).toEqual(['Counter', 'Display', 'Incrementor']); + renderLog.length = 0; + await trigger(container.element, 'button', 'click'); + expect(renderLog).toEqual([]); + expect(vNode).toMatchVDOM( + + + + + Count: {'124'}! + + + + + + + + ); + }); + it('should pass signal as prop into child component', async () => { + const Display = component$((props: { value: number }) => { + return
        {props.value}
        ; + }); + const Counter = component$(() => { + // const count = useStore({ value: 123 }); + const count = useSignal(123); + return ( + <> + + +
        + 123 +
        +
        + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + +
        + 124 +
        +
        +
        +
        + ); + }); + }); + + describe('regression', () => { + it('#4249 - should render signal text with double condition', async () => { + const Issue4249 = component$(() => { + const first = useSignal(''); + const second = useSignal(''); + + return ( + <> + +
        + {first.value && second.value && first.value === second.value ? 'equal' : 'not-equal'} +
        + + ); + }); + + const { vNode, document } = await render(, { debug }); + + expect(vNode).toMatchVDOM( + + + +
        + not-equal +
        +
        +
        + ); + + await trigger(document.body, 'button', 'click'); + + expect(vNode).toMatchVDOM( + + + +
        + equal +
        +
        +
        + ); + }); + + it('#4249 - should render signal value with double condition', async () => { + const Issue4249 = component$(() => { + const first = useSignal(''); + const second = useSignal(''); + + return ( + <> + +
        + {first.value && second.value && first.value === second.value ? 'equal' : 'not-equal'} +
        + + ); + }); + + const { vNode, document } = await render(, { debug }); + + expect(vNode).toMatchVDOM( + + + +
        + not-equal +
        +
        +
        + ); + + await trigger(document.body, 'button', 'click'); + + expect(vNode).toMatchVDOM( + + + +
        + equal +
        +
        +
        + ); + }); + + it('should update the sum when input values change', async () => { + const AppTest = component$(() => { + const a = useSignal(1); + const b = useSignal(2); + return ( +
        + {a.value} + {b.value} = {a.value + b.value} + + +
        + ); + }); + + const { document } = await render(, { debug: debug }); + + await expect(document.querySelector('div')).toMatchDOM( +
        + 1 + 2 = 3 + + +
        + ); + + const input1 = document.querySelector('#input1')! as HTMLInputElement; + + input1.value = '10'; + input1.valueAsNumber = 10; + + await trigger(document.body, input1, 'input'); + await expect(document.querySelector('div')).toMatchDOM( +
        + 10 + 2 = 12 + + +
        + ); + }); + }); +}); diff --git a/packages/qwik/src/core/tests/use-store.spec.tsx b/packages/qwik/src/core/tests/use-store.spec.tsx new file mode 100644 index 00000000000..9f7a8091cf0 --- /dev/null +++ b/packages/qwik/src/core/tests/use-store.spec.tsx @@ -0,0 +1,1231 @@ +import { + Fragment as Component, + Fragment as InlineComponent, + component$, + Fragment, + Fragment as Signal, + untrack, + useSignal, + useStore, + useTask$, + useVisibleTask$, + type PropsOf, +} from '@qwik.dev/core'; +import { domRender, ssrRenderToDom, trigger } from '@qwik.dev/core/testing'; +import { describe, expect, it, vi } from 'vitest'; +import { advanceToNextTimerAndFlush } from '../../testing/element-fixture'; +import { getStoreHandler } from '../reactive-primitives/impl/store'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +describe.each([ + { render: ssrRenderToDom }, // + { render: domRender }, // +])('$render.name: useStore', ({ render }) => { + it('should render value', async () => { + const Cmp = component$(() => { + const store = useStore({ items: [{ num: 0 }] }); + return ( + <> + {store.items.map((item, key) => ( +
        {item.num}
        + ))} + + ); + }); + + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + +
        + 0 +
        +
        +
        + ); + }); + it('should update value', async () => { + const Counter = component$(() => { + const count = useStore({ count: 123 }); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + }); + it('should update deep value', async () => { + const Counter = component$(() => { + const count = useStore({ obj: { count: 123 } }); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + }); + + it('should update array value', async () => { + const Counter = component$(() => { + const count = useStore([123]); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should rerender child', async () => { + const log: string[] = []; + const Display = component$((props: { dValue: number }) => { + log.push('Display'); + return Count: {props.dValue}!; + }); + const Counter = component$((props: { initial: number }) => { + log.push('Counter'); + const count = useStore({ obj: { value: props.initial } }); + return ( + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(log).toEqual(['Counter', 'Display']); + expect(vNode).toMatchVDOM( + <> + + + ); + }); + describe('derived', () => { + it('should update value directly in DOM', async () => { + const log: string[] = []; + const Counter = component$((props: { initial: number }) => { + const count = useStore({ value: props.initial }); + log.push('Counter: ' + untrack(() => count.value)); + return ; + }); + + const { vNode, container } = await render(, { + debug, + // oldSSR: true, + }); + expect(log).toEqual(['Counter: 123']); + log.length = 0; + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'click'); + expect(log).toEqual([]); + log.length = 0; + expect(vNode).toMatchVDOM( + <> + + + ); + }); + it('should allow signal to deliver value or JSX', async () => { + const log: string[] = []; + const Counter = component$(() => { + const count = useStore({ jsx: 'initial' }); + log.push('Counter: ' + untrack(() => count.jsx)); + return ( + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(log).toEqual(['Counter: initial']); + log.length = 0; + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'click'); + expect(log).toEqual([]); + log.length = 0; + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(container.element, 'button', 'click'); + expect(log).toEqual([]); + log.length = 0; + expect(vNode).toMatchVDOM( + <> + + + ); + }); + it('should update value when store, update and render are separated', async () => { + const renderLog: string[] = []; + const Display = component$((props: { displayValue: number }) => { + renderLog.push('Display'); + return <>Count: {props.displayValue}!; + }); + const Incrementor = component$((props: { countSignal: { value: number } }) => { + renderLog.push('Incrementor'); + return ( + + ); + }); + const Counter = component$(() => { + renderLog.push('Counter'); + const count = useStore({ value: 123 }); + return ( + <> + + + + ); + }); + const { vNode, container } = await render(, { debug }); + expect(renderLog).toEqual(['Counter', 'Display', 'Incrementor']); + renderLog.length = 0; + await trigger(container.element, 'button', 'click'); + expect(renderLog).toEqual([]); + expect(vNode).toMatchVDOM( + + + + + Count: {'124'}! + + + + + + + + ); + }); + + it('should rerender inner component with store as a prop', async () => { + interface InnerButtonProps { + text: string; + isActive: boolean; + onClick$: PropsOf<'button'>['onClick$']; + } + const InnerButton = component$((props: InnerButtonProps) => { + return ( + + ); + }); + + const InnerButtonWrapper = component$((props: { data: any }) => { + return ( + { + props.data.selectedOutputDetail = 'options'; + }} + /> + ); + }); + + const Parent = component$(() => { + const store = useStore({ + selectedOutputDetail: 'console', + }); + + return ; + }); + + const { vNode, document } = await render(, { debug }); + + expect(vNode).toMatchVDOM( + + + + + + + + ); + + await trigger(document.body, 'button', 'click'); + + expect(vNode).toMatchVDOM( + + + + + + + + ); + }); + + it('should rerender inner inline component with destructured props', async () => { + interface InnerButtonProps { + text: string; + isActive: boolean; + onClick$: PropsOf<'button'>['onClick$']; + } + + const Parent = component$(() => { + const store = useStore({ + selectedOutputDetail: 'console', + }); + + const InnerButton = (props: InnerButtonProps) => { + return ( + + ); + }; + + const InnerButtonWrapper = ({ data }: { data: any }) => { + return ( + { + data.selectedOutputDetail = 'options'; + }} + /> + ); + }; + + return ; + }); + + const { vNode, document } = await render(, { debug }); + + expect(vNode).toMatchVDOM( + + + + + + + + ); + + await trigger(document.body, 'button', 'click'); + + expect(vNode).toMatchVDOM( + + + + + + + + ); + }); + }); + + describe('SerializationConstant at the start', () => { + it('should set the value with SerializationConstant at the start for initial empty value', async () => { + const DataCmp = component$(() => { + const data = useStore({ logs: '' }); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should set the value with SerializationConstant at the start', async () => { + const DataCmp = component$(() => { + const data = useStore({ logs: '\n abcd' }); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should update the value with SerializationConstant at the start', async () => { + const DataCmp = component$(() => { + const data = useStore({ logs: '\n abcd' }); + return ; + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should push the value with SerializationConstant at the start to array', async () => { + const DataCmp = component$(() => { + const data = useStore({ logs: ['\n abcd'] }); + return ( + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + }); + }); + + it('should deep watch store', async () => { + const Cmp = component$(() => { + const store = useStore({ + nested: { + fields: { are: 'also tracked' }, + }, + list: ['Item 1'], + }); + + return ( + <> +

        {store.nested.fields.are}

        + + +
          + {store.list.map((item, key) => ( +
        • {item}
        • + ))} +
        + + ); + }); + + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + +

        + also tracked +

        + + +
          +
        • Item 1
        • +
        +
        +
        + ); + await trigger(document.body, 'button#add-item', 'click'); + await trigger(document.body, 'button#add-item', 'click'); + expect(vNode).toMatchVDOM( + + +

        + also tracked +

        + + +
          +
        • Item 1
        • +
        • Item 1
        • +
        • Item 2
        • +
        +
        +
        + ); + }); + + it('should render value via JSON.stringify', async () => { + const Stringify = component$<{ + data: any; + style?: any; + }>((props) => { + return <>{JSON.stringify(props.data)}; + }); + + const Cmp = component$(() => { + const group = useStore({ + controls: { + ctrl: { + value: '', + }, + }, + }); + + return ( + + ); + }); + + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should work with frozen store', async () => { + const Cmp = component$(() => { + const store = useStore({ items: [{ num: 0 }] }); + Object.freeze(store); + return ( + <> + {store.items.map((item, key) => ( +
        {item.num}
        + ))} + + ); + }); + + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + +
        + 0 +
        +
        +
        + ); + }); + + it('should deserialize store without effects', async () => { + const Cmp = component$(() => { + const store = useStore({ counter: 0 }); + useVisibleTask$(() => { + store.counter++; + }); + return
        ; + }); + + const { vNode, document } = await render(, { debug }); + if (render === ssrRenderToDom) { + await trigger(document.body, 'div', 'qvisible'); + } + expect(vNode).toMatchVDOM( + +
        +
        + ); + }); + + it('should assign a store property to undefined', async () => { + (global as any).logs = [] as string[]; + + const Cmp = component$(() => { + const store = useStore>({}); + useTask$(({ track }) => { + track(() => store.someId); + (global as any).logs.push('someId' in store); + }); + + return ; + }); + + const { document } = await render(, { debug }); + await trigger(document.body, 'button', 'click'); + expect((global as any).logs).toEqual([false, true]); + }); + + it('should trigger effects on property delete', async () => { + const Cmp = component$(() => { + const store = useStore<{ delete?: string }>({ delete: 'test' }); + return
        delete store.delete}>{store.delete}
        ; + }); + + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + +
        + {'test'} +
        +
        + ); + await trigger(document.body, 'div', 'click'); + expect(vNode).toMatchVDOM( + +
        + +
        +
        + ); + }); + + it('should update deep nested array of arrays inside object with inner component', async () => { + const Item = component$(({ item }: any) => { + return ( +
        (item.completed = true)}> + {item.title} +
        + ); + }); + + const Cmp = component$(() => { + const todos = useStore( + { + filter: 'all', + items: [ + { completed: false, title: 'Read Qwik docs', id: '0' }, + { completed: false, title: 'Build HelloWorld', id: '1' }, + { completed: false, title: 'Profit', id: '2' }, + ], + }, + { deep: true } + ); + const remaining = todos.items.filter((item) => item.completed === false).length; + + return ( +
        + {remaining} + {todos.items.map((item, key) => ( + + ))} +
        + ); + }); + + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + +
        + {'3'} + +
        + Read Qwik docs +
        +
        + +
        + Build HelloWorld +
        +
        + +
        + Profit +
        +
        +
        +
        + ); + + await trigger(document.body, 'div[id="0"]', 'click'); + expect(vNode).toMatchVDOM( + +
        + {'2'} + +
        + Read Qwik docs +
        +
        + +
        + Build HelloWorld +
        +
        + +
        + Profit +
        +
        +
        +
        + ); + }); + it('should update deep nested array of arrays inside object', async () => { + const Cmp = component$(() => { + const todos = useStore( + { + filter: 'all', + items: [ + { completed: false, title: 'Read Qwik docs', id: '0' }, + { completed: false, title: 'Build HelloWorld', id: '1' }, + { completed: false, title: 'Profit', id: '2' }, + ], + }, + { deep: true } + ); + const remaining = todos.items.filter((item) => item.completed === false).length; + + return ( +
        + {remaining} + +
        + ); + }); + + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + +
        + {'3'} + +
        +
        + ); + + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + +
        + {'2'} + +
        +
        + ); + }); + + it('should cleanup store effects on vNode/component remove', async () => { + (globalThis as any).store = undefined; + + const Child = component$<{ store: { message?: string } }>((props) => { + return
        {props.store.message && {props.store.message}}
        ; + }); + + const Parent = component$(() => { + const store = useStore<{ message?: string }>({ + message: undefined, + }); + + useVisibleTask$(() => { + (globalThis as any).store = store; + }); + + return ( +
        + + +
        + ); + }); + + const { vNode, document } = await render(, { debug }); + + if (render === ssrRenderToDom) { + await trigger(document.body, 'div', 'qvisible'); + } + expect(vNode).toMatchVDOM( + +
        + + +
        +
        +
        +
        + ); + + const storeHandler = getStoreHandler((globalThis as any).store); + expect(storeHandler?.$effects$?.get('message')).toHaveLength(2); + + await trigger(document.body, 'button', 'click'); + expect(storeHandler?.$effects$?.get('message')).toHaveLength(3); + await trigger(document.body, 'button', 'click'); + expect(storeHandler?.$effects$?.get('message')).toHaveLength(2); + await trigger(document.body, 'button', 'click'); + expect(storeHandler?.$effects$?.get('message')).toHaveLength(3); + await trigger(document.body, 'button', 'click'); + expect(storeHandler?.$effects$?.get('message')).toHaveLength(2); + await trigger(document.body, 'button', 'click'); + expect(storeHandler?.$effects$?.get('message')).toHaveLength(3); + + expect(vNode).toMatchVDOM( + +
        + + +
        + + Hello + +
        +
        +
        +
        + ); + }); + + describe('regression', () => { + it('#5597 - should update value', async () => { + (globalThis as any).clicks = 0; + const Issue5597 = component$(() => { + const count = useSignal(0); + const store = useStore({ items: [{ num: 0 }] }); + return ( + <> + + {store.items.map((item, key) => ( +
        {item.num}
        + ))} + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + +
        + {(globalThis as any).clicks} +
        +
        +
        + ); + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + +
        + {(globalThis as any).clicks} +
        +
        +
        + ); + }); + + it('#5597 - should update value with setInterval', async () => { + const Cmp = component$(() => { + const count = useSignal(0); + const store = useStore({ items: [{ num: 0 }] }); + useVisibleTask$(({ cleanup }) => { + const intervalId = setInterval(() => { + count.value++; + store.items = store.items.map((i: { num: number }) => ({ num: i.num + 1 })); + }, 500); + + cleanup(() => clearInterval(intervalId)); + }); + return ( + <> +
        Count: {count.value}!
        + {store.items.map((item, key) => ( +
        {item.num}
        + ))} + + ); + }); + vi.useFakeTimers({ + toFake: ['setInterval', 'clearInterval'], + }); + const { vNode, document } = await render(, { debug }); + if (render === ssrRenderToDom) { + await trigger(document.body, 'div', 'qvisible'); + } + expect(vNode).toMatchVDOM( + + +
        + {'Count: '} + {'0'} + {'!'} +
        +
        + 0 +
        +
        +
        + ); + await advanceToNextTimerAndFlush(); + expect(vNode).toMatchVDOM( + + +
        + {'Count: '} + {'1'} + {'!'} +
        +
        + 1 +
        +
        +
        + ); + await advanceToNextTimerAndFlush(); + expect(vNode).toMatchVDOM( + + +
        + {'Count: '} + {'2'} + {'!'} +
        +
        + 2 +
        +
        +
        + ); + vi.clearAllTimers(); + vi.useRealTimers(); + }); + + it('#5017 - should update child nodes for direct array', async () => { + const Child = component$<{ columns: string }>(({ columns }) => { + return
        Child: {columns}
        ; + }); + + const Parent = component$(() => { + const state = useStore([{ columns: 'INITIAL' }]); + return ( + <> + + + {state.map((block, idx) => { + return ; + })} + + ); + }); + + const { vNode, container } = await render(, { debug }); + + expect(vNode).toMatchVDOM( + + + + +
        + {'Child: '} + {'INITIAL'} +
        +
        + +
        + {'Child: '} + {'INITIAL'} +
        +
        +
        +
        + ); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + +
        + {'Child: '} + {'UPDATE'} +
        +
        + +
        + {'Child: '} + {'UPDATE'} +
        +
        +
        +
        + ); + }); + + it('#5001 - should serialize naked value', async () => { + const Button = component$<{ unusedValue?: [number]; state: [number] }>(({ state }) => { + return ( +
        + +
        + ); + }); + const Parent = component$<{ nakedState: [number] }>(({ nakedState }) => { + // STEP 2 + // We wrap the `nakedState` into `state`. + // This means that Qwik needs to serialize the Proxy for the `nakedState`. + const state = useStore(nakedState); + // const signal = useSignal(0); + return ( + <> + +
        +
        + {'Count: '} + + 0 + + + + + ); + + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + +
        + +
        +
        + {'Count: '} + + 1 + +
        +
        +
        + ); + }); + }); +}); diff --git a/packages/qwik/src/core/tests/use-styles-scoped.spec.tsx b/packages/qwik/src/core/tests/use-styles-scoped.spec.tsx new file mode 100644 index 00000000000..ed47673f041 --- /dev/null +++ b/packages/qwik/src/core/tests/use-styles-scoped.spec.tsx @@ -0,0 +1,719 @@ +import { + Fragment as Component, + component$, + Fragment, + inlinedQrl, + Fragment as Projection, + Fragment as Signal, + Slot, + useSignal, + useStylesScopedQrl, +} from '@qwik.dev/core'; +import { renderToString } from '@qwik.dev/core/server'; +import { createDocument, domRender, ssrRenderToDom, trigger } from '@qwik.dev/core/testing'; +import { cleanupAttrs } from 'packages/qwik/src/testing/element-fixture'; +import { afterEach, describe, expect, it } from 'vitest'; +import { useStore } from '..'; +import { getPlatform, setPlatform } from '../shared/platform/platform'; +import { QStyleSelector } from '../shared/utils/markers'; +import { getScopedStyles } from '../shared/utils/scoped-stylesheet'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +describe.each([ + { render: ssrRenderToDom }, // + { render: domRender }, // +])('$render.name: useStylesScoped', ({ render }) => { + const STYLE_RED = `.container {background-color: red;}`; + const STYLE_BLUE = `.container {background-color: blue;}`; + + afterEach(() => { + (globalThis as any).rawStyleId = undefined; + (globalThis as any).rawStyleId1 = undefined; + (globalThis as any).rawStyleId2 = undefined; + (globalThis as any).rawStyleId3 = undefined; + (globalThis as any).rawStyleId4 = undefined; + }); + + it('should render style', async () => { + (globalThis as any).rawStyleId = ''; + + const StyledComponent = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped')); + (globalThis as any).rawStyleId = stylesScopedData.scopeId; + return
        Hello world
        ; + }); + + const { vNode, getStyles } = await render(, { debug }); + const styleId = (globalThis as any).rawStyleId.substring(2); + const scopeStyle = getScopedStyles(STYLE_RED, styleId); + expect(getStyles()).toEqual({ + [styleId]: scopeStyle, + }); + expect(vNode).toMatchVDOM( + <> +
        Hello world
        + + ); + }); + + it('should render object style', async () => { + (globalThis as any).rawStyleId = ''; + + const StyledComponent = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped')); + (globalThis as any).rawStyleId = stylesScopedData.scopeId; + + const store = useStore({ + count: 10, + }); + + return ( + + ); + }); + + const { vNode, getStyles, document } = await render(, { debug }); + const styleId = (globalThis as any).rawStyleId.substring(2); + const scopeStyle = getScopedStyles(STYLE_RED, styleId); + expect(getStyles()).toEqual({ + [styleId]: scopeStyle, + }); + expect(vNode).toMatchVDOM( + <> + + + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + }); + + it('should move style to on rerender', async () => { + (globalThis as any).rawStyleId = ''; + + const StyledComponent = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped')); + const count = useSignal(0); + (globalThis as any).rawStyleId = stylesScopedData.scopeId; + return ( + + ); + }); + + const { vNode, container } = await render(, { debug }); + const styleId = (globalThis as any).rawStyleId.substring(2); + const scopeStyle = getScopedStyles(STYLE_RED, styleId); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + const style = container.document.querySelector(QStyleSelector); + expect(cleanupAttrs(style?.outerHTML)).toEqual( + `` + ); + }); + + it('should save styles when JSX deleted', async () => { + (globalThis as any).rawStyleId = ''; + + const StyledComponent = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped')); + (globalThis as any).rawStyleId = stylesScopedData.scopeId; + return
        Hello world
        ; + }); + + const Parent = component$(() => { + const show = useSignal(true); + return ( +
        (show.value = false)}> + {show.value && } +
        + ); + }); + + const { vNode, container } = await render(, { debug }); + const styleId = (globalThis as any).rawStyleId.substring(2); + const scopeStyle = getScopedStyles(STYLE_RED, styleId); + await trigger(container.element, 'div.parent', 'click'); + expect(vNode).toMatchVDOM( + +
        {''}
        +
        + ); + const style = container.document.querySelector(QStyleSelector); + expect(cleanupAttrs(style?.outerHTML)).toEqual( + `` + ); + }); + + it('style node should contain q:style attribute', async () => { + const StyledComponent = component$(() => { + useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped')); + return
        Hello world
        ; + }); + const { container } = await render(, { debug }); + const allStyles = container.document.querySelectorAll('style'); + const qStyles = container.document.querySelectorAll(QStyleSelector); + expect(allStyles.length).toBe(qStyles.length); + }); + + it('should render styles for multiple components', async () => { + (globalThis as any).rawStyleId1 = ''; + (globalThis as any).rawStyleId2 = ''; + const StyledComponent1 = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped1')); + (globalThis as any).rawStyleId1 = stylesScopedData.scopeId; + return
        Hello world 1
        ; + }); + const StyledComponent2 = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_BLUE, 's_stylesScoped2')); + (globalThis as any).rawStyleId2 = stylesScopedData.scopeId; + return
        Hello world 2
        ; + }); + const Parent = component$(() => { + return ( +
        + + +
        + ); + }); + const { vNode, getStyles } = await render(, { debug }); + const firstStyleId = (globalThis as any).rawStyleId1.substring(2); + const firstScopeStyle = getScopedStyles(STYLE_RED, firstStyleId); + const secondStyleId = (globalThis as any).rawStyleId2.substring(2); + const secondScopeStyle = getScopedStyles(STYLE_BLUE, secondStyleId); + expect(getStyles()).toEqual({ + [firstStyleId]: firstScopeStyle, + [secondStyleId]: secondScopeStyle, + }); + expect(vNode).toMatchVDOM( + <> +
        + +
        Hello world 1
        +
        + +
        Hello world 2
        +
        +
        + + ); + }); + + it('should save styles for all child components', async () => { + (globalThis as any).rawStyleId1 = ''; + (globalThis as any).rawStyleId2 = ''; + const StyledComponent1 = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped1')); + (globalThis as any).rawStyleId1 = stylesScopedData.scopeId; + return
        Hello world 1
        ; + }); + const StyledComponent2 = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_BLUE, 's_stylesScoped2')); + (globalThis as any).rawStyleId2 = stylesScopedData.scopeId; + return
        Hello world 2
        ; + }); + const Parent = component$(() => { + const show = useSignal(true); + return ( +
        (show.value = false)}> + {show.value && } + +
        + ); + }); + const { vNode, container } = await render(, { debug }); + const firstStyleId = (globalThis as any).rawStyleId1.substring(2); + const firstScopeStyle = getScopedStyles(STYLE_RED, firstStyleId); + const secondStyleId = (globalThis as any).rawStyleId2.substring(2); + const secondScopeStyle = getScopedStyles(STYLE_BLUE, secondStyleId); + await trigger(container.element, 'div.parent', 'click'); + expect(vNode).toMatchVDOM( + +
        + {''} + +
        Hello world 2
        +
        +
        +
        + ); + const qStyles = container.document.querySelectorAll(QStyleSelector); + expect(qStyles).toHaveLength(2); + expect(Array.from(qStyles).map((style) => cleanupAttrs(style.outerHTML))).toEqual( + expect.arrayContaining([ + ``, + ``, + ]) + ); + }); + + it('should generate different styleIds for components', async () => { + (globalThis as any).rawStyleId1 = ''; + (globalThis as any).rawStyleId2 = ''; + const StyledComponent1 = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped1')); + (globalThis as any).rawStyleId1 = stylesScopedData.scopeId; + return
        Hello world 1
        ; + }); + const StyledComponent2 = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped2')); + (globalThis as any).rawStyleId2 = stylesScopedData.scopeId; + return
        Hello world 2
        ; + }); + const Parent = component$(() => { + return ( + <> + + + + ); + }); + await render(, { debug }); + const firstStyleId = (globalThis as any).rawStyleId1.substring(2); + const secondStyleId = (globalThis as any).rawStyleId2.substring(2); + expect(firstStyleId).not.toEqual(secondStyleId); + }); + + it('should render styles with multiple useStylesScoped', async () => { + (globalThis as any).rawStyleId1 = ''; + (globalThis as any).rawStyleId2 = ''; + const StyledComponent = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped1')); + (globalThis as any).rawStyleId1 = stylesScopedData.scopeId; + const stylesScopedData2 = useStylesScopedQrl(inlinedQrl(STYLE_BLUE, 's_stylesScoped2')); + (globalThis as any).rawStyleId2 = stylesScopedData2.scopeId; + return
        Hello world
        ; + }); + const { vNode, getStyles } = await render(, { debug }); + const firstStyleId = (globalThis as any).rawStyleId1.substring(2); + const firstScopeStyle = getScopedStyles(STYLE_RED, firstStyleId); + const secondStyleId = (globalThis as any).rawStyleId2.substring(2); + const secondScopeStyle = getScopedStyles(STYLE_BLUE, secondStyleId); + expect(getStyles()).toEqual({ + [firstStyleId]: firstScopeStyle, + [secondStyleId]: secondScopeStyle, + }); + expect(vNode).toMatchVDOM( + <> +
        + Hello world +
        + + ); + }); + + it('should generate only one style for the same components', async () => { + const StyledComponent1 = component$(() => { + useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_styles', [])); + return
        Hello world 1
        ; + }); + const Parent = component$(() => { + return ( + <> + + + + ); + }); + const { container } = await render(, { debug }); + const qStyles = container.document.querySelectorAll(QStyleSelector); + expect(qStyles).toHaveLength(1); + }); + + it('should render styles for component inside slot', async () => { + (globalThis as any).rawStyleId1 = ''; + (globalThis as any).rawStyleId2 = ''; + + const Child = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_BLUE, 's_stylesScoped2')); + (globalThis as any).rawStyleId2 = stylesScopedData.scopeId; + return
        Hello world 2
        ; + }); + + const Parent = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped1')); + (globalThis as any).rawStyleId1 = stylesScopedData.scopeId; + return ( +
        + +
        + ); + }); + + const { vNode, getStyles } = await render( + + + , + { debug } + ); + const firstStyleId = (globalThis as any).rawStyleId1.substring(2); + const firstScopeStyle = getScopedStyles(STYLE_RED, firstStyleId); + const secondStyleId = (globalThis as any).rawStyleId2.substring(2); + const secondScopeStyle = getScopedStyles(STYLE_BLUE, secondStyleId); + expect(getStyles()).toEqual({ + [firstStyleId]: firstScopeStyle, + [secondStyleId]: secondScopeStyle, + }); + expect(vNode).toMatchVDOM( + +
        + + +
        Hello world 2
        +
        +
        +
        +
        + ); + }); + + it('should render styles for multiple slots', async () => { + (globalThis as any).rawStyleId1 = ''; + (globalThis as any).rawStyleId2 = ''; + (globalThis as any).rawStyleId3 = ''; + + const ComponentA = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_BLUE, 's_stylesScoped2')); + + (globalThis as any).rawStyleId2 = stylesScopedData.scopeId; + return ( +
        + + +
        + ); + }); + + const ComponentB = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped3')); + + (globalThis as any).rawStyleId3 = stylesScopedData.scopeId; + return ( +
        + + +
        + ); + }); + + const RootStyles = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped1')); + (globalThis as any).rawStyleId1 = stylesScopedData.scopeId; + return ( + + +
        One
        +
        Two
        +
        +
        + Four +
        +
        + ); + }); + + const { vNode, getStyles } = await render(, { debug }); + + const firstStyleId = (globalThis as any).rawStyleId1.substring(2); + const firstScopeStyle = getScopedStyles(STYLE_RED, firstStyleId); + const secondStyleId = (globalThis as any).rawStyleId2.substring(2); + const secondScopeStyle = getScopedStyles(STYLE_BLUE, secondStyleId); + const thirdStyleId = (globalThis as any).rawStyleId3.substring(2); + const thirdScopeStyle = getScopedStyles(STYLE_RED, thirdStyleId); + expect(getStyles()).toEqual({ + [firstStyleId]: firstScopeStyle, + [secondStyleId]: secondScopeStyle, + [thirdStyleId]: thirdScopeStyle, + }); + + expect(vNode).toMatchVDOM( + + +
        + + +
        + +
        + One +
        +
        + +
        + Two +
        +
        +
        +
        +
        + +
        + Four +
        +
        +
        +
        +
        + ); + }); + + it('should render styles for all nested components and elements', async () => { + (globalThis as any).rawStyleId1 = ''; + (globalThis as any).rawStyleId2 = ''; + (globalThis as any).rawStyleId3 = ''; + (globalThis as any).rawStyleId4 = ''; + + const StyledComponent2 = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_BLUE, 's_stylesScoped2')); + (globalThis as any).rawStyleId2 = stylesScopedData.scopeId; + return ( +
        + Hello world 2 +
        Nested 2
        +
        + ); + }); + const StyledComponent3 = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped3')); + (globalThis as any).rawStyleId3 = stylesScopedData.scopeId; + return ( +
        + Hello world 3 + +
        + ); + }); + const StyledComponent4 = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_BLUE, 's_stylesScoped4')); + (globalThis as any).rawStyleId4 = stylesScopedData.scopeId; + return
        Hello world 4
        ; + }); + + const StyledComponent1 = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped1')); + (globalThis as any).rawStyleId1 = stylesScopedData.scopeId; + return ( +
        + Hello world 1 +
        Nested 1
        + + + + +
        + ); + }); + + const Parent = component$(() => { + return ( +
        + +
        + ); + }); + const { vNode, getStyles } = await render(, { debug }); + const firstStyleId = (globalThis as any).rawStyleId1.substring(2); + const firstScopeStyle = getScopedStyles(STYLE_RED, firstStyleId); + const secondStyleId = (globalThis as any).rawStyleId2.substring(2); + const secondScopeStyle = getScopedStyles(STYLE_BLUE, secondStyleId); + const thirdStyleId = (globalThis as any).rawStyleId3.substring(2); + const thirdScopeStyle = getScopedStyles(STYLE_RED, thirdStyleId); + const fourthStyleId = (globalThis as any).rawStyleId4.substring(2); + const fourthScopeStyle = getScopedStyles(STYLE_BLUE, fourthStyleId); + expect(getStyles()).toEqual({ + [firstStyleId]: firstScopeStyle, + [secondStyleId]: secondScopeStyle, + [thirdStyleId]: thirdScopeStyle, + [fourthStyleId]: fourthScopeStyle, + }); + expect(vNode).toMatchVDOM( + +
        + +
        + Hello world 1 +
        Nested 1
        + +
        + Hello world 2 +
        Nested 2
        +
        +
        + +
        + Hello world 3 + + +
        + Hello world 4 +
        +
        +
        +
        +
        +
        +
        +
        +
        + ); + }); + + it('should render style scoped id for element without class attribute', async () => { + (globalThis as any).rawStyleId = ''; + + const StyledComponent = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped')); + (globalThis as any).rawStyleId = stylesScopedData.scopeId; + return
        Hello world
        ; + }); + + const { vNode, getStyles } = await render(, { debug }); + const styleId = (globalThis as any).rawStyleId.substring(2); + const scopeStyle = getScopedStyles(STYLE_RED, styleId); + expect(getStyles()).toEqual({ + [styleId]: scopeStyle, + }); + expect(vNode).toMatchVDOM( + <> +
        Hello world
        + + ); + }); + + describe('regression', () => { + it('#1945 - should add styles to conditionally rendered slots', async () => { + (globalThis as any).rawStyleId1 = ''; + (globalThis as any).rawStyleId2 = ''; + + const Child = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_BLUE, 's_stylesScoped2')); + (globalThis as any).rawStyleId2 = stylesScopedData.scopeId; + const show = useSignal(false); + return ( + <> + + {show.value ? : null} + + ); + }); + + const Parent = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE_RED, 's_stylesScoped')); + (globalThis as any).rawStyleId1 = stylesScopedData.scopeId; + return ( + + content + + ); + }); + + const { vNode, getStyles, document } = await render(, { debug }); + const styleId1 = (globalThis as any).rawStyleId1.substring(2); + const scopeStyle1 = getScopedStyles(STYLE_RED, styleId1); + const styleId2 = (globalThis as any).rawStyleId2.substring(2); + const scopeStyle2 = getScopedStyles(STYLE_BLUE, styleId2); + expect(getStyles()).toEqual({ + [styleId1]: scopeStyle1, + [styleId2]: scopeStyle2, + }); + expect(vNode).toMatchVDOM( + + + + + {''} + + + + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + + + content + + + + + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + + {''} + + + + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + + + content + + + + + ); + }); + }); +}); + +describe('html wrapper', () => { + it('should append scoped style to head', async () => { + const STYLE = `.container{color: blue;}`; + (globalThis as any).rawStyleId = ''; + const Wrapper = component$(() => { + const stylesScopedData = useStylesScopedQrl(inlinedQrl(STYLE, 's_styles1')); + (globalThis as any).rawStyleId = stylesScopedData.scopeId; + return ; + }); + let document = createDocument(); + const platform = getPlatform(); + try { + const result = await renderToString( + + + + + +
        content
        + +
        + ); + document = createDocument({ html: result.html }); + } finally { + setPlatform(platform); + } + + const styleId = (globalThis as any).rawStyleId.substring(2); + const scopeStyle = getScopedStyles(STYLE, styleId); + const styleElement = document.head.lastChild as HTMLElement; + expect(styleElement.textContent).toContain(scopeStyle); + }); +}); diff --git a/packages/qwik/src/core/tests/use-styles.spec.tsx b/packages/qwik/src/core/tests/use-styles.spec.tsx new file mode 100644 index 00000000000..29959237b86 --- /dev/null +++ b/packages/qwik/src/core/tests/use-styles.spec.tsx @@ -0,0 +1,221 @@ +import { + Fragment as Component, + component$, + inlinedQrl, + Fragment as Signal, + Slot, + useSignal, + useStylesQrl, +} from '@qwik.dev/core'; +import { renderToString } from '@qwik.dev/core/server'; +import { createDocument, domRender, ssrRenderToDom, trigger } from '@qwik.dev/core/testing'; +import { afterEach, describe, expect, it } from 'vitest'; +import { getPlatform, setPlatform } from '../shared/platform/platform'; +import { QStyleSelector } from '../shared/utils/markers'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +describe.each([ + { render: ssrRenderToDom }, // + { render: domRender }, // +])('$render.name: useStyles', ({ render }) => { + afterEach(() => { + (globalThis as any).rawStyleId = undefined; + (globalThis as any).rawStyleId1 = undefined; + (globalThis as any).rawStyleId2 = undefined; + }); + + const STYLE_RED = `.container {background-color: red;}`; + const STYLE_BLUE = `.container {background-color: blue;}`; + + it('should render style', async () => { + (globalThis as any).rawStyleId = ''; + const StyledComponent = component$(() => { + const styleData = useStylesQrl(inlinedQrl(STYLE_RED, 's_styles')); + (globalThis as any).rawStyleId = styleData.styleId; + return
        Hello world
        ; + }); + + const { vNode, getStyles } = await render(, { debug }); + expect(getStyles()).toEqual({ + [(globalThis as any).rawStyleId]: STYLE_RED, + }); + expect(vNode).toMatchVDOM( + <> +
        Hello world
        + + ); + }); + + it('should move style to on rerender', async () => { + (globalThis as any).rawStyleId = ''; + const StyledComponent = component$(() => { + const styleData = useStylesQrl(inlinedQrl(STYLE_RED, 's_styles')); + (globalThis as any).rawStyleId = styleData.styleId; + const count = useSignal(0); + return ( + + ); + }); + + const { vNode, container } = await render(, { debug }); + await trigger(container.element, 'button', 'click'); + expect(vNode).toMatchVDOM( + <> + + + ); + const style = container.document.querySelector(QStyleSelector); + const attrs = { 'q:style': (globalThis as any).rawStyleId }; + await expect(style).toMatchDOM(); + }); + + it('should save styles when JSX deleted', async () => { + (globalThis as any).rawStyleId = ''; + const StyledComponent = component$(() => { + const styleData = useStylesQrl(inlinedQrl(STYLE_RED, 's_styles')); + (globalThis as any).rawStyleId = styleData.styleId; + return
        Hello world
        ; + }); + + const Parent = component$(() => { + const show = useSignal(true); + return ( +
        (show.value = false)}> + {show.value && } +
        + ); + }); + + const { vNode, container } = await render(, { debug }); + await trigger(container.element, 'div.parent', 'click'); + expect(vNode).toMatchVDOM( + +
        {''}
        +
        + ); + const style = container.document.querySelector(QStyleSelector); + const attrs = { 'q:style': (globalThis as any).rawStyleId }; + await expect(style).toMatchDOM(); + }); + + it('style node should contain q:style attribute', async () => { + const StyledComponent = component$(() => { + useStylesQrl(inlinedQrl(STYLE_RED, 's_styles')); + return
        Hello world
        ; + }); + const { container } = await render(, { debug }); + const allStyles = container.document.querySelectorAll('style'); + const qStyles = container.document.querySelectorAll(QStyleSelector); + expect(allStyles.length).toBe(qStyles.length); + }); + + it('should render styles for multiple components', async () => { + (globalThis as any).rawStyleId1 = ''; + (globalThis as any).rawStyleId2 = ''; + const StyledComponent1 = component$(() => { + const styleData = useStylesQrl(inlinedQrl(STYLE_RED, 's_styles1')); + (globalThis as any).rawStyleId1 = styleData.styleId; + return
        Hello world 1
        ; + }); + const StyledComponent2 = component$(() => { + const styleData = useStylesQrl(inlinedQrl(STYLE_BLUE, 's_styles2')); + (globalThis as any).rawStyleId2 = styleData.styleId; + return
        Hello world 2
        ; + }); + const Parent = component$(() => { + return ( +
        + + +
        + ); + }); + const { vNode, getStyles } = await render(, { debug }); + + expect(getStyles()).toEqual({ + [(globalThis as any).rawStyleId1]: STYLE_RED, + [(globalThis as any).rawStyleId2]: STYLE_BLUE, + }); + expect(vNode).toMatchVDOM( + <> +
        + +
        Hello world 1
        +
        + +
        Hello world 2
        +
        +
        + + ); + }); + + it('should save styles for all child components', async () => { + const StyledComponent1 = component$(() => { + useStylesQrl(inlinedQrl(STYLE_RED, 's_styles1')); + return
        Hello world 1
        ; + }); + const StyledComponent2 = component$(() => { + useStylesQrl(inlinedQrl(STYLE_BLUE, 's_styles2')); + return
        Hello world 2
        ; + }); + const Parent = component$(() => { + const show = useSignal(true); + return ( +
        (show.value = false)}> + {show.value && } + +
        + ); + }); + const { vNode, container } = await render(, { debug }); + await trigger(container.element, 'div.parent', 'click'); + expect(vNode).toMatchVDOM( + +
        + {''} + +
        Hello world 2
        +
        +
        +
        + ); + const qStyles = container.document.querySelectorAll(QStyleSelector); + expect(qStyles).toHaveLength(2); + }); +}); + +describe('html wrapper', () => { + it('should append style to head', async () => { + const STYLE = `.container{color: blue;}`; + const Wrapper = component$(() => { + useStylesQrl(inlinedQrl(STYLE, 's_styles1')); + return ; + }); + let document = createDocument(); + const platform = getPlatform(); + try { + const result = await renderToString( + + + + + +
        content
        + +
        + ); + document = createDocument({ html: result.html }); + } finally { + setPlatform(platform); + } + const styleElement = document.head.lastChild as HTMLElement; + expect(styleElement.textContent).toContain(STYLE); + }); +}); diff --git a/packages/qwik/src/core/tests/use-task.spec.tsx b/packages/qwik/src/core/tests/use-task.spec.tsx new file mode 100644 index 00000000000..97e51c1c4e0 --- /dev/null +++ b/packages/qwik/src/core/tests/use-task.spec.tsx @@ -0,0 +1,813 @@ +import { + Fragment as Component, + Fragment, + Fragment as Signal, + component$, + useSignal, + useStore, + useTask$, + type Signal as SignalType, +} from '@qwik.dev/core'; +import { domRender, getTestPlatform, ssrRenderToDom, trigger } from '@qwik.dev/core/testing'; +import { describe, expect, it } from 'vitest'; +import { ErrorProvider } from '../../testing/rendering.unit-util'; +import { delay } from '../shared/utils/promises'; +import { WrappedSignalImpl } from '../reactive-primitives/impl/wrapped-signal-impl'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +describe.each([ + { render: ssrRenderToDom }, // + { render: domRender }, // +])('$render.name: useTask', ({ render }) => { + it('should execute task', async () => { + const Counter = component$(() => { + const count = useSignal('wrong'); + useTask$(() => { + count.value = 'WORKS'; + }); + return {count.value}; + }); + + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + WORKS + + + ); + }); + it('should execute async task', async () => { + const log: string[] = []; + const Counter = component$(() => { + log.push('Counter'); + const count = useSignal('wrong'); + useTask$(async () => { + log.push('task'); + await delay(10); + log.push('resolved'); + count.value = 'WORKS'; + }); + log.push('render'); + return {count.value}; + }); + + const { vNode } = await render(, { debug }); + expect(log).toEqual(['Counter', 'render', 'task', 'resolved']); + expect(vNode).toMatchVDOM( + + + WORKS + + + ); + }); + it('should handle exceptions', async () => { + const error = new Error('HANDLE ME'); + const ThrowError = component$(() => { + useTask$(() => { + throw error; + }); + return OK; + }); + try { + await render( + + + , + { debug } + ); + expect(render).toBe(domRender); + expect(ErrorProvider.error).toBe(error); + } catch (e) { + expect(render).toBe(ssrRenderToDom); + expect(e).toBe(error); + } + }); + it('should handle async exceptions', async () => { + const error = new Error('HANDLE ME'); + const ThrowError = component$(() => { + useTask$(async () => { + await delay(1); + throw error; + }); + return OK; + }); + try { + await render( + + + , + { debug } + ); + expect(render).toBe(domRender); + expect(ErrorProvider.error).toBe(error); + } catch (e) { + expect(render).toBe(ssrRenderToDom); + expect(e).toBe(error); + } + }); + it('should not run next task until previous async task is finished', async () => { + const log: string[] = []; + const Counter = component$(() => { + log.push('Counter'); + const count = useSignal(''); + useTask$(async () => { + log.push('1:task'); + await delay(10); + log.push('1:resolved'); + count.value += 'A'; + }); + useTask$(async () => { + log.push('2:task'); + await delay(10); + log.push('2:resolved'); + count.value += 'B'; + }); + log.push('render'); + return {count.value}; + }); + + const { vNode } = await render(, { debug }); + expect(log).toEqual(['Counter', 'render', '1:task', '1:resolved', '2:task', '2:resolved']); + expect(vNode).toMatchVDOM( + + + AB + + + ); + }); + describe('track', () => { + it('should rerun on track', async () => { + const Counter = component$(() => { + const count = useSignal(10); + const double = useSignal(0); + useTask$(({ track }) => { + double.value = 2 * track(() => count.value); + }); + return ( + + ); + }); + + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + await getTestPlatform().flush(); + }); + it('should rerun on track derived signal', async () => { + const Counter = component$(() => { + const countRaw = useStore({ count: 10 }); + const count = new WrappedSignalImpl( + null, + (o: any, prop: string) => o[prop], + [countRaw, 'count'], + null + ); + const double = useSignal(0); + useTask$(({ track }) => { + double.value = 2 * track(() => count.value); + }); + return ; + }); + + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + await getTestPlatform().flush(); + }); + it('should track store property', async () => { + const Counter = component$(() => { + const store = useStore({ count: 1, double: 0 }); + useTask$(({ track }) => { + const count = track(store, 'count'); + store.double = 2 * count; + }); + return ; + }); + + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + }); + it('should track store', async () => { + const Counter = component$(() => { + const store = useStore({ count: 1, double: 0 }); + useTask$(({ track }) => { + const storeCounter = track(store); + store.double = 2 * storeCounter.count; + }); + return ; + }); + + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should unsubscribe from removed component', async () => { + (global as any).logs = [] as string[]; + + const ToggleChild = component$((props: { name: string; count: number }) => { + useTask$(({ track }) => { + const count = track(() => props.count); + const logText = `Child of "${props.name}" (${count})`; + (global as any).logs.push(logText); + }); + + return ( +
        +

        Toggle {props.name}

        +
        + ); + }); + + const Toggle = component$(() => { + const store = useStore({ + count: 0, + cond: false, + }); + return ( +
        + +
        + {!store.cond ? ( + + ) : ( + + )} + +
        +
        + ); + }); + + const { document } = await render(, { debug }); + + await trigger(document.body, '#increment', 'click'); + await trigger(document.body, '#toggle', 'click'); + await trigger(document.body, '#increment', 'click'); + await trigger(document.body, '#toggle', 'click'); + + expect((global as any).logs).toEqual([ + 'Child of "A" (0)', // init + 'Child of "A" (1)', // increment + 'Child of "B" (1)', // toggle + 'Child of "B" (2)', // increment + 'Child of "A" (2)', // toggle + ]); + }); + }); + describe('queue', () => { + it('should execute dependant tasks', async () => { + (globalThis as any).log = [] as string[]; + const Counter = component$(() => { + const store = useStore({ count: 1, double: 0, quadruple: 0 }); + // Quadruple runs first, but will run again after double is updated + useTask$(({ track }) => { + (globalThis as any).log.push('quadruple'); + const trackingValue = track(store, 'double') * 2; + store.quadruple = trackingValue; + }); + useTask$(({ track }) => { + (globalThis as any).log.push('double'); + store.double = track(store, 'count') * 2; + }); + (globalThis as any).log.push('Counter'); + return ( + + ); + }); + + const { vNode, document } = await render(, { debug }); + expect((globalThis as any).log).toEqual(['Counter', 'quadruple', 'double', 'quadruple']); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log.length = 0; + await trigger(document.body, 'button', 'click'); + // console.log('log', log); + expect((globalThis as any).log).toEqual(['double', 'quadruple']); + expect(vNode).toMatchVDOM( + + + + ); + }); + }); + describe('cleanup', () => { + it('should execute cleanup task rerun on track', async () => { + (globalThis as any).log = [] as string[]; + const Counter = component$(() => { + const count = useSignal(0); + useTask$(({ track }) => { + const _count = track(() => count.value); + (globalThis as any).log.push('task: ' + _count); + return () => (globalThis as any).log.push('cleanup: ' + _count); + }); + (globalThis as any).log.push('Counter: ' + count.value); + return ; + }); + const isCSR = render === domRender; + + const { vNode, document } = await render(, { debug }); + // console.log('log', log); + expect((globalThis as any).log).toEqual( + isCSR ? ['Counter: 0', 'task: 0'] : ['Counter: 0', 'task: 0', 'cleanup: 0'] + ); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log.length = 0; + await trigger(document.body, 'button', 'click'); + // console.log('log', log); + expect((globalThis as any).log).toEqual( + isCSR ? ['cleanup: 0', 'task: 1', 'Counter: 1'] : ['task: 1', 'Counter: 1'] + ); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log.length = 0; + await trigger(document.body, 'button', 'click'); + // console.log('log', log); + expect((globalThis as any).log).toEqual(['cleanup: 1', 'task: 2', 'Counter: 2']); + expect(vNode).toMatchVDOM( + + + + ); + }); + it('should execute cleanup task on unmount', async () => { + (globalThis as any).log = [] as string[]; + const Child = component$(() => { + useTask$(({ cleanup }) => { + (globalThis as any).log.push('task:'); + cleanup(() => (globalThis as any).log.push('cleanup:')); + }); + (globalThis as any).log.push('Child'); + return Child; + }); + const Parent = component$(() => { + const show = useSignal(true); + return ( + + ); + }); + const isCSR = render === domRender; + + const { vNode, document } = await render(, { debug }); + // console.log('log', log); + expect((globalThis as any).log).toEqual( + isCSR ? ['Child', 'task:'] : ['Child', 'task:', 'cleanup:'] + ); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log = []; + await trigger(document.body, 'button', 'click'); + // console.log('log', log); + expect((globalThis as any).log).toEqual(isCSR ? ['cleanup:'] : []); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log = []; + await trigger(document.body, 'button', 'click'); + + expect((globalThis as any).log).toEqual(['Child', 'task:']); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log = []; + await trigger(document.body, 'button', 'click'); + // console.log('log', log); + expect((globalThis as any).log).toEqual(['cleanup:']); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log = undefined; + }); + it('should handle promises and tasks', async () => { + (global as any).log = [] as string[]; + const MyComp = component$(() => { + const promise = useSignal>(); + (global as any).log.push('render'); + + // Tasks should run one after the other, awaiting returned promises. + // Here we "sideload" a promise via the signal + useTask$(() => { + promise.value = Promise.resolve(0) + .then(() => { + (global as any).log.push('inside.1'); + return delay(10); + }) + .then(() => { + (global as any).log.push('1b'); + return 1; + }); + (global as any).log.push('1a'); + }); + + useTask$(async () => { + (global as any).log.push('2a'); + await delay(10); + (global as any).log.push('2b'); + }); + + useTask$(() => { + promise.value = promise.value!.then(() => { + (global as any).log.push('3b'); + return 3; + }); + (global as any).log.push('3a'); + }); + + return

        Should have a number: "{promise.value}"

        ; + }); + const { vNode } = await render(, { debug }); + expect((global as any).log).toEqual([ + // 1st render + 'render', + // task 1 returns sync and sideloads promise + '1a', + // task 2 runs sync after that and returns a promise + '2a', + // async microtasks run, task 1 queues a delay + 'inside.1', + '2b', + // task 3 runs sync and attaches to the promise + '3a', + // microtasks run + '1b', + '3b', + ]); + // The DOM should have the final value of the sideloaded promise + expect(vNode).toMatchVDOM( + +

        + Should have a number: " + + 3 + + " +

        +
        + ); + }); + }); + + it('should run cleanup with component rerender', async () => { + const Child = component$((props: { cleanupCounter: SignalType }) => { + useTask$(({ cleanup }) => { + cleanup(() => { + props.cleanupCounter.value++; + }); + }); + return ; + }); + + const Cmp = component$(() => { + const counter = useSignal(0); + const cleanupCounter = useSignal(0); + return ( +
        + + + {cleanupCounter.value} +
        + ); + }); + + const { vNode, container } = await render(, { debug }); + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + + expect(vNode).toMatchVDOM( + +
        + + + + + {'6'} +
        +
        + ); + }); + + describe('regression', () => { + it('#5782', async () => { + const Child = component$(({ sig }: { sig: SignalType> }) => { + const counter = useSignal(0); + useTask$(({ track }) => { + track(sig); + sig.value = counter; + }); + return

        {counter.value}

        ; + }); + + const Issue5782 = component$(() => { + const counterDefault = useSignal(0); + const sig = useSignal(counterDefault); + const showChild = useSignal(false); + return ( + <> + + {sig.value.value} + + + {showChild.value && } + + ); + }); + + const { vNode, document } = await render(, { debug }); + + expect(vNode).toMatchVDOM( + + + + {'0'} + + + {''} + + + ); + + await trigger(document.body, '#toggle', 'click'); + + expect(vNode).toMatchVDOM( + + + + {'0'} + + + +

        + 0 +

        +
        +
        +
        + ); + + await trigger(document.body, '#increase', 'click'); + await trigger(document.body, '#increase', 'click'); + + expect(vNode).toMatchVDOM( + + + + {'2'} + + + +

        + 2 +

        +
        +
        +
        + ); + await trigger(document.body, '#decrease', 'click'); + expect(vNode).toMatchVDOM( + + + + {'1'} + + + +

        + 1 +

        +
        +
        +
        + ); + + await trigger(document.body, '#toggle', 'click'); + expect(vNode).toMatchVDOM( + + + + {'1'} + + + {''} + + + ); + + await trigger(document.body, '#toggle', 'click'); + expect(vNode).toMatchVDOM( + + + + {'0'} + + + +

        + 0 +

        +
        +
        +
        + ); + }); + + it('#4332', async () => { + const Child = component$((props: { val: string }) => { + useTask$(({ track }) => { + track(() => props.val); + }); + return <>{props.val}; + }); + + const Parent = component$(() => { + const sig = useSignal<{ data: string } | undefined>({ data: 'abcd' }); + + return ( + <> + + {sig.value && } + + ); + }); + const { vNode, document } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + + + abcd + + + + + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + {''} + + + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + + + abcd + + + + + ); + }); + }); + + it('should rerender component after task', async () => { + const Cmp = component$(() => { + const sort = useSignal<'id' | 'size'>('size'); + const table = useSignal([ + { id: 1, size: 4 }, + { id: 2, size: 3 }, + { id: 3, size: 2 }, + { id: 4, size: 1 }, + { id: 5, size: 7 }, + { id: 6, size: 8 }, + { id: 7, size: 9 }, + ]); + + useTask$(({ track }) => { + track(() => sort.value); + table.value = table.value.sort((a, b) => a[sort.value] - b[sort.value]).slice(); + }); + + return table.value.map((row) => row.size).join(' '); + }); + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM(1 2 3 4 7 8 9); + }); +}); diff --git a/packages/qwik/src/core/tests/use-visible-task.spec.tsx b/packages/qwik/src/core/tests/use-visible-task.spec.tsx new file mode 100644 index 00000000000..8db87b0fa7f --- /dev/null +++ b/packages/qwik/src/core/tests/use-visible-task.spec.tsx @@ -0,0 +1,817 @@ +import { + Fragment as Component, + component$, + createContextId, + Fragment, + Fragment as Projection, + Fragment as Signal, + type Signal as SignalType, + Slot, + useComputed$, + useContext, + useContextProvider, + useSignal, + useStore, + useVisibleTask$, +} from '@qwik.dev/core'; +import { domRender, ssrRenderToDom, trigger } from '@qwik.dev/core/testing'; +import { describe, expect, it } from 'vitest'; +import { ErrorProvider } from '../../testing/rendering.unit-util'; +import { delay } from '../shared/utils/promises'; + +const debug = false; //true; +Error.stackTraceLimit = 100; + +export function useDelay(value: string) { + const ready = useSignal('---'); + useVisibleTask$(() => { + ready.value = value; + }); + return ready; +} + +describe.each([ + { render: ssrRenderToDom }, // + { render: domRender }, // +])('$render.name: useVisibleTask', ({ render }) => { + it('should execute visible task', async () => { + const VisibleCmp = component$(() => { + const state = useSignal('SSR'); + useVisibleTask$(() => { + state.value = 'CSR'; + }); + return {state.value}; + }); + + const { vNode, document } = await render(, { debug }); + if (render === ssrRenderToDom) { + await trigger(document.body, 'span', 'qvisible'); + } + expect(vNode).toMatchVDOM( + + + CSR + + + ); + }); + + it('should execute visible task with strategy document-ready', async () => { + const VisibleCmp = component$(() => { + const state = useSignal('SSR'); + useVisibleTask$( + () => { + state.value = 'CSR'; + }, + { + strategy: 'document-ready', + } + ); + return {state.value}; + }); + + const { vNode, document } = await render(, { debug }); + await trigger(document.body, 'span', ':document:qinit'); + expect(vNode).toMatchVDOM( + + + CSR + + + ); + }); + + it('should execute visible task with strategy document-idle', async () => { + const VisibleCmp = component$(() => { + const state = useSignal('SSR'); + useVisibleTask$( + () => { + state.value = 'CSR'; + }, + { + strategy: 'document-idle', + } + ); + return {state.value}; + }); + + const { vNode, document } = await render(, { debug }); + await trigger(document.body, 'span', ':document:qidle'); + + expect(vNode).toMatchVDOM( + + + CSR + + + ); + }); + + it('should execute async visible task', async () => { + (globalThis as any).log = [] as string[]; + const VisibleCmp = component$(() => { + (globalThis as any).log.push('VisibleCmp'); + const state = useSignal('SSR'); + + useVisibleTask$(async () => { + (globalThis as any).log.push('task'); + await delay(10); + (globalThis as any).log.push('resolved'); + state.value = 'CSR'; + }); + + (globalThis as any).log.push('render'); + return {state.value}; + }); + const { vNode, document } = await render(, { debug }); + if (render === ssrRenderToDom) { + await trigger(document.body, 'span', 'qvisible'); + } + expect((globalThis as any).log).toEqual(['VisibleCmp', 'render', 'task', 'resolved']); + expect(vNode).toMatchVDOM( + + + CSR + + + ); + (globalThis as any).log = undefined; + }); + + it('should handle exception', async () => { + const error = new Error('HANDLE ME'); + const VisibleCmp = component$(() => { + const state = useSignal('SSR'); + useVisibleTask$(() => { + throw error; + }); + return {state.value}; + }); + const { document } = await render( + + + , + { debug } + ); + if (render === ssrRenderToDom) { + await trigger(document.body, 'span', 'qvisible'); + } + expect(ErrorProvider.error).toBe(render === domRender ? error : null); + }); + + it('should handle async exception', async () => { + const error = new Error('HANDLE ME'); + const VisibleCmp = component$(() => { + const state = useSignal('SSR'); + useVisibleTask$(async () => { + await delay(1); + throw error; + }); + return {state.value}; + }); + + const { document } = await render( + + + , + { debug } + ); + if (render === ssrRenderToDom) { + await trigger(document.body, 'span', 'qvisible'); + } + expect(ErrorProvider.error).toBe(render === domRender ? error : null); + }); + + it('should not run next visible task until previous async visible task is finished', async () => { + (globalThis as any).log = [] as string[]; + const Counter = component$(() => { + (globalThis as any).log.push('Counter'); + const count = useSignal(''); + + useVisibleTask$(async () => { + (globalThis as any).log.push('1:task'); + await delay(10); + (globalThis as any).log.push('1:resolved'); + count.value += 'A'; + }); + + useVisibleTask$(async () => { + (globalThis as any).log.push('2:task'); + await delay(10); + (globalThis as any).log.push('2:resolved'); + count.value += 'B'; + }); + (globalThis as any).log.push('render'); + return {count.value}; + }); + + const { vNode, document } = await render(, { debug }); + if (render === ssrRenderToDom) { + await trigger(document.body, 'span', 'qvisible'); + } + expect((globalThis as any).log).toEqual([ + 'Counter', + 'render', + '1:task', + '1:resolved', + '2:task', + '2:resolved', + ]); + expect(vNode).toMatchVDOM( + + + AB + + + ); + }); + + it('should trigger in empty components', async () => { + const Cmp = component$(() => { + const signal = useSignal('empty'); + useVisibleTask$(() => { + signal.value = 'run'; + }); + return <>{signal.value}; + }); + const { vNode, document } = await render(, { debug }); + if (render === ssrRenderToDom) { + await trigger(document.body, 'script', ':document:qinit'); + } + expect(vNode).toMatchVDOM( + + + {'run'} + + + + ); + }); + + it('should trigger in empty components array', async () => { + const Cmp = component$(() => { + const signal = useSignal('empty'); + useVisibleTask$(() => { + signal.value = 'run'; + }); + return [<>{signal.value}, <>{signal.value}]; + }); + const { vNode, document } = await render(, { debug }); + if (render === ssrRenderToDom) { + await trigger(document.body, 'script', ':document:qinit'); + } + expect(vNode).toMatchVDOM( + + + {'run'} + + + + {'run'} + + + ); + }); + + it('should trigger in full empty component', async () => { + const Cmp = component$(() => { + const signal = useSignal('empty'); + useVisibleTask$(() => { + signal.value = 'run'; + }); + return <>; + }); + const { vNode, document } = await render(, { debug }); + if (render === ssrRenderToDom) { + await trigger(document.body, 'script', ':document:qinit'); + } + expect(vNode).toMatchVDOM( + + + + + + ); + }); + + describe(render.name + ': track', () => { + it('should rerun on track', async () => { + const Counter = component$(() => { + const count = useSignal(10); + const double = useSignal(0); + + useVisibleTask$(({ track }) => { + double.value = 2 * track(() => count.value); + }); + return ( + + ); + }); + + const { vNode, document } = await render(, { debug }); + if (render === ssrRenderToDom) { + await trigger(document.body, 'button', 'qvisible'); + } + expect(vNode).toMatchVDOM( + + + + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + }); + + it('should track store property', async () => { + const Counter = component$(() => { + const store = useStore({ count: 1, double: 0 }); + useVisibleTask$(({ track }) => { + const count = track(store, 'count'); + store.double = 2 * count; + }); + return ; + }); + + const { vNode, document } = await render(, { debug }); + if (render === ssrRenderToDom) { + await trigger(document.body, 'button', 'qvisible'); + } + expect(vNode).toMatchVDOM( + + + + ); + await trigger(document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + ); + }); + }); + + describe(render.name + ': queue', () => { + it('should execute dependant visible tasks', async () => { + (globalThis as any).log = [] as string[]; + const Counter = component$(() => { + const store = useStore({ count: 1, double: 0, quadruple: 0 }); + useVisibleTask$(({ track }) => { + (globalThis as any).log.push('quadruple'); + store.quadruple = track(store, 'double') * 2; + }); + useVisibleTask$(({ track }) => { + (globalThis as any).log.push('double'); + store.double = track(store, 'count') * 2; + }); + (globalThis as any).log.push('Counter'); + return ( + + ); + }); + + const { vNode, document } = await render(, { debug }); + if (render === ssrRenderToDom) { + await trigger(document.body, 'button', 'qvisible'); + } + expect((globalThis as any).log).toEqual([ + 'Counter', + 'quadruple', + 'double', + 'quadruple', + // not called with the optimizer + // 'Counter', + ]); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log = []; + await trigger(document.body, 'button', 'click'); + expect((globalThis as any).log).toEqual([ + 'double', + 'quadruple', + // not called with the optimizer + // 'Counter', + ]); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log = []; + }); + }); + + describe(render.name + ': cleanup', () => { + it('should execute cleanup visible task rerun on track', async () => { + (globalThis as any).log = [] as string[]; + const Counter = component$(() => { + const count = useSignal(0); + useVisibleTask$(({ track }) => { + const _count = track(() => count.value); + (globalThis as any).log.push('visible task: ' + _count); + return () => (globalThis as any).log.push('cleanup: ' + _count); + }); + (globalThis as any).log.push('Counter: ' + count.value); + return ( + + ); + }); + + const { vNode, document } = await render(, { debug }); + if (render === ssrRenderToDom) { + await trigger(document.body, 'button', 'qvisible'); + } + expect((globalThis as any).log).toEqual(['Counter: 0', 'visible task: 0']); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log = []; + await trigger(document.body, 'button', 'click'); + // expect(log).toEqual(['cleanup: 0', 'task: 1', 'Counter: 1']); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log = []; + await trigger(document.body, 'button', 'click'); + expect((globalThis as any).log).toEqual(['Counter: 2', 'cleanup: 1', 'visible task: 2']); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log = undefined; + }); + + it('should execute cleanup visible task on unmount', async () => { + (globalThis as any).log = [] as string[]; + const Child = component$(() => { + useVisibleTask$(({ cleanup }) => { + (globalThis as any).log.push('visible_task:'); + cleanup(() => (globalThis as any).log.push('cleanup:')); + }); + (globalThis as any).log.push('Child'); + return Child; + }); + const Parent = component$(() => { + const show = useSignal(true); + return ( + + ); + }); + + const { vNode, document } = await render(, { debug }); + if (render === ssrRenderToDom) { + // only if it is SSR do we need to trigger the qvisible event, in CSR visibleTasks run automatically + await trigger(document.body, 'span', 'qvisible'); + } + expect((globalThis as any).log).toEqual(['Child', 'visible_task:']); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log = []; + await trigger(document.body, 'button', 'click'); + + expect((globalThis as any).log).toEqual(['cleanup:']); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log = []; + await trigger(document.body, 'button', 'click'); + + expect((globalThis as any).log).toEqual(['Child', 'visible_task:']); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log = []; + await trigger(document.body, 'button', 'click'); + + expect((globalThis as any).log).toEqual(['cleanup:']); + expect(vNode).toMatchVDOM( + + + + ); + (globalThis as any).log = undefined; + }); + + it('should run cleanup with component rerender', async () => { + const Child = component$((props: { cleanupCounter: SignalType }) => { + useVisibleTask$(({ cleanup }) => { + cleanup(() => { + props.cleanupCounter.value++; + }); + }); + return ; + }); + + const Cmp = component$(() => { + const counter = useSignal(0); + const cleanupCounter = useSignal(0); + return ( +
        + + + {cleanupCounter.value} +
        + ); + }); + + const { vNode, container } = await render(, { debug }); + + if (render === ssrRenderToDom) { + await trigger(container.element, 'span', 'qvisible'); + } + + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + await trigger(container.element, 'button', 'click'); + + expect(vNode).toMatchVDOM( + +
        + + + + + {'6'} +
        +
        + ); + }); + + it('should handle promises and visible tasks', async () => { + // vi.useFakeTimers(); + const MyComp = component$(() => { + const promise = useSignal>(Promise.resolve(0)); + + useVisibleTask$(() => { + promise.value = promise.value + .then(() => { + return delay(10); + }) + .then(() => { + return 1; + }); + }); + + useVisibleTask$(() => { + promise.value = promise.value.then(() => { + return 2; + }); + }); + + return

        Should have a number: "{promise.value}"

        ; + }); + const { vNode, document } = await render(, { debug }); + + if (render === ssrRenderToDom) { + await trigger(document.body, 'p', 'qvisible'); + } + expect(vNode).toMatchVDOM( + +

        + Should have a number: " + + {'2'} + + " +

        +
        + ); + }); + }); + + it('should not add useOn props as slot name', async () => { + const InnerCmp = component$(() => { + return
        ; + }); + + const Cmp = component$(() => { + useVisibleTask$(() => {}); + return ( +
        + +
        + ); + }); + + const Parent = component$(() => { + const show = useSignal(false); + return ( + <> + + {show.value && } + + ); + }); + + const { vNode, container } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + +
        + {render === ssrRenderToDom ? '' : null} +
        +
        +
        +
        + ); + await trigger(container.document.body, 'button', 'click'); + expect(vNode).toMatchVDOM( + + + + +
        + + +
        +
        +
        +
        +
        +
        +
        + ); + }); + + describe('regression', () => { + it('#1717 - custom hooks should work', async () => { + const Issue1717 = component$(() => { + const val1 = useDelay('valueA'); + const val2 = useDelay('valueB'); + return ( +
        +

        {val1.value}

        +

        {val2.value}

        +
        + ); + }); + + const { vNode, document } = await render(, { debug }); + + if (render === ssrRenderToDom) { + await trigger(document.body, 'div', 'qvisible'); + } + + expect(vNode).toMatchVDOM( + +
        +

        + {'valueA'} +

        +

        + {'valueB'} +

        +
        +
        + ); + }); + + it('#4432 - should cleanup child visible task with correct value', async () => { + const ContextIssue4432 = createContextId<{ url: URL; logs: string }>('issue-4432'); + + const Issue4432Child = component$(() => { + const state = useContext(ContextIssue4432); + + const pathname = useComputed$(() => state.url.pathname); + + useVisibleTask$(({ track, cleanup }) => { + track(() => pathname.value); + + // This should only run on page load for path '/' + state.logs += `VisibleTask ChildA ${pathname.value}\n`; + + // This should only run when leaving the page + cleanup(() => { + state.logs += `Cleanup ChildA ${pathname.value}\n`; + }); + }); + + return

        Child A

        ; + }); + + const Issue4432 = component$(() => { + const loc = useStore({ + url: new URL('http://localhost:3000/'), + logs: '', + }); + useContextProvider(ContextIssue4432, loc); + + return ( + <> + +
        {loc.logs}
        + {loc.url.pathname === '/' && } + + ); + }); + + const { vNode, document } = await render(, { debug }); + + if (render === ssrRenderToDom) { + await trigger(document.body, 'p', 'qvisible'); + } + + expect(vNode).toMatchVDOM( + + + +
        +              {'VisibleTask ChildA /\n'}
        +            
        + +

        Child A

        +
        +
        +
        + ); + + await trigger(document.body, 'button', 'click'); + + expect(vNode).toMatchVDOM( + + + +
        +              {'VisibleTask ChildA /\nCleanup ChildA /other\n'}
        +            
        + {''} +
        +
        + ); + }); + }); +}); diff --git a/packages/qwik/src/core/use/use-computed.ts b/packages/qwik/src/core/use/use-computed.ts new file mode 100644 index 00000000000..59c7c79c950 --- /dev/null +++ b/packages/qwik/src/core/use/use-computed.ts @@ -0,0 +1,49 @@ +import { implicit$FirstArg } from '../shared/qrl/implicit_dollar'; +import { assertQrl } from '../shared/qrl/qrl-utils'; +import type { QRL } from '../shared/qrl/qrl.public'; +import { ComputedSignalImpl } from '../reactive-primitives/impl/computed-signal-impl'; +import { throwIfQRLNotResolved } from '../reactive-primitives/utils'; +import type { ReadonlySignal, Signal } from '../reactive-primitives/signal.public'; +import { useSequentialScope } from './use-sequential-scope'; + +/** @public */ +export type ComputedFn = () => T; +/** @public */ +export type ComputedReturnType = + T extends Promise ? ReadonlySignal : ReadonlySignal; + +export const useComputedCommon = ( + qrl: QRL>, + Class: typeof ComputedSignalImpl +): ComputedReturnType => { + const { val, set } = useSequentialScope>(); + if (val) { + return val as any; + } + assertQrl(qrl); + const signal = new Class(null, qrl); + set(signal); + + // Note that we first save the signal + // and then we throw to load the qrl + // This is why we can't use useConstant, we need to keep using the same qrl object + throwIfQRLNotResolved(qrl); + return signal as any; +}; + +/** @internal */ +export const useComputedQrl = (qrl: QRL>): ComputedReturnType => { + return useComputedCommon(qrl, ComputedSignalImpl); +}; + +/** + * Creates a computed signal which is calculated from the given function. A computed signal is a + * signal which is calculated from other signals. When the signals change, the computed signal is + * recalculated, and if the result changed, all tasks which are tracking the signal will be re-run + * and all components that read the signal will be re-rendered. + * + * The function must be synchronous and must not have any side effects. + * + * @public + */ +export const useComputed$ = implicit$FirstArg(useComputedQrl); diff --git a/packages/qwik/src/core/use/use-context.ts b/packages/qwik/src/core/use/use-context.ts index 12ec3281cb7..d02f50b77d9 100644 --- a/packages/qwik/src/core/use/use-context.ts +++ b/packages/qwik/src/core/use/use-context.ts @@ -1,24 +1,15 @@ -import { fromCamelToKebabCase } from '../util/case'; -import { qError, QError_invalidContext, QError_notFoundContext } from '../error/error'; -import { qDev, qSerialize } from '../util/qdev'; -import { isObject } from '../util/types'; -import { useSequentialScope } from './use-sequential-scope'; -import { assertTrue } from '../error/assert'; -import { verifySerializable } from '../state/common'; -import { getContext, type QContext } from '../state/context'; -import type { ContainerState } from '../container/container'; +import { assertTrue } from '../shared/error/assert'; +import { QError, qError } from '../shared/error/error'; +import { verifySerializable } from '../shared/utils/serialize-utils'; +import { qDev, qSerialize } from '../shared/utils/qdev'; +import { isObject } from '../shared/utils/types'; import { invoke } from './use-core'; -import { - type QwikElement, - type VirtualElement, - getVirtualElement, -} from '../render/dom/virtual-element'; -import { isComment } from '../util/element'; -import { Q_CTX, VIRTUAL_SYMBOL } from '../state/constants'; +import { useSequentialScope } from './use-sequential-scope'; +import { fromCamelToKebabCase } from '../shared/utils/event-names'; // // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#ContextId instead) +// (edit ../readme.md#ContextId instead and run `pnpm docs.sync`) /** * ContextId is a typesafe ID for your context. * @@ -78,7 +69,7 @@ export interface ContextId { // // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#createContextId instead) +// (edit ../readme.md#createContextId instead and run `pnpm docs.sync`) /** * Create a context ID to be used in your application. The name should be written with no spaces. * @@ -139,7 +130,7 @@ export const createContextId = (name: string): ContextId // // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useContextProvider instead) +// (edit ../readme.md#useContextProvider instead and run `pnpm docs.sync`) /** * Assign a value to a Context. * @@ -193,19 +184,18 @@ export const createContextId = (name: string): ContextId */ // export const useContextProvider = (context: ContextId, newValue: STATE) => { - const { val, set, elCtx } = useSequentialScope(); + const { val, set, iCtx } = useSequentialScope<1>(); if (val !== undefined) { return; } if (qDev) { validateContext(context); } - const contexts = (elCtx.$contexts$ ||= new Map()); if (qDev && qSerialize) { verifySerializable(newValue); } - contexts.set(context.id, newValue); - set(true); + iCtx.$container$.setContext(iCtx.$hostElement$, context, newValue); + set(1); }; export interface UseContext { @@ -216,7 +206,7 @@ export interface UseContext { // // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useContext instead) +// (edit ../readme.md#useContext instead and run `pnpm docs.sync`) /** * Retrieve Context value. * @@ -268,7 +258,7 @@ export const useContext: UseContext = ( context: ContextId, defaultValue?: STATE | ((current: STATE | undefined) => STATE) ) => { - const { val, set, iCtx, elCtx } = useSequentialScope(); + const { val, set, iCtx } = useSequentialScope(); if (val !== undefined) { return val; } @@ -276,7 +266,7 @@ export const useContext: UseContext = ( validateContext(context); } - const value = resolveContext(context, elCtx, iCtx.$renderCtx$.$static$.$containerState$); + const value: STATE | undefined = iCtx.$container$.resolveContext(iCtx.$hostElement$, context); if (typeof defaultValue === 'function') { return set(invoke(undefined, defaultValue as any, value)); } @@ -286,85 +276,11 @@ export const useContext: UseContext = ( if (defaultValue !== undefined) { return set(defaultValue); } - throw qError(QError_notFoundContext, context.id); -}; - -/** Find a wrapping Virtual component in the DOM */ -const findParentCtx = (el: QwikElement | null, containerState: ContainerState) => { - let node = el; - let stack = 1; - while (node && !node.hasAttribute?.('q:container')) { - // Walk the siblings backwards, each comment might be the Virtual wrapper component - while ((node = node.previousSibling as QwikElement | null)) { - if (isComment(node)) { - const virtual = (node as any)[VIRTUAL_SYMBOL] as VirtualElement; - if (virtual) { - const qtx = (virtual as any)[Q_CTX] as QContext | undefined; - if (node === virtual.open) { - // We started inside this node so this is our parent - return qtx ?? getContext(virtual, containerState); - } - // This is a sibling, check if it knows our parent - if (qtx?.$parentCtx$) { - return qtx.$parentCtx$; - } - // Skip over this entire virtual sibling - node = virtual; - continue; - } - if (node.data === '/qv') { - stack++; - } else if (node.data.startsWith('qv ')) { - stack--; - if (stack === 0) { - return getContext(getVirtualElement(node)!, containerState); - } - } - } - } - // No more siblings, walk up the DOM tree. The parent will never be a Virtual component. - node = el!.parentElement; - el = node; - } - return null; -}; - -const getParentProvider = (ctx: QContext, containerState: ContainerState): QContext | null => { - // `null` means there's no parent, `undefined` means we don't know yet. - if (ctx.$parentCtx$ === undefined) { - // Not fully resumed container, find context from DOM - // We cannot recover $realParentCtx$ from this but that's fine because we don't need to pause on the client - ctx.$parentCtx$ = findParentCtx(ctx.$element$, containerState); - } - /** - * Note, the parentCtx is used during pause to to get the immediate parent, so we can't shortcut - * the search for $contexts$ here. If that turns out to be needed, it needs to be cached in a - * separate property. - */ - return ctx.$parentCtx$; -}; - -export const resolveContext = ( - context: ContextId, - hostCtx: QContext, - containerState: ContainerState -): STATE | undefined => { - const contextID = context.id; - if (!hostCtx) { - return; - } - let ctx = hostCtx; - while (ctx) { - const found = ctx.$contexts$?.get(contextID); - if (found) { - return found; - } - ctx = getParentProvider(ctx, containerState)!; - } + throw qError(QError.notFoundContext, [context.id]); }; export const validateContext = (context: ContextId) => { if (!isObject(context) || typeof context.id !== 'string' || context.id.length === 0) { - throw qError(QError_invalidContext, context); + throw qError(QError.invalidContext, [context]); } }; diff --git a/packages/qwik/src/core/use/use-core.ts b/packages/qwik/src/core/use/use-core.ts index 0b7d9b81a7e..bcb1721ef9e 100644 --- a/packages/qwik/src/core/use/use-core.ts +++ b/packages/qwik/src/core/use/use-core.ts @@ -1,48 +1,32 @@ -import { _getContainerState } from '../container/container'; import type { QwikDocument } from '../document'; -import { assertDefined } from '../error/assert'; -import { qError, QError_useInvokeContext, QError_useMethodOutsideContext } from '../error/error'; -import type { QRLInternal } from '../qrl/qrl-class'; -import type { QRL } from '../qrl/qrl.public'; -import type { QwikElement } from '../render/dom/virtual-element'; -import type { RenderContext } from '../render/types'; -import { getContext, HOST_FLAG_DYNAMIC } from '../state/context'; -import { - ComputedEvent, - QContainerSelector, - QLocaleAttr, - RenderEvent, - ResourceEvent, - TaskEvent, -} from '../util/markers'; -import { isPromise } from '../util/promises'; -import { seal } from '../util/qdev'; -import { isArray } from '../util/types'; +import { assertDefined } from '../shared/error/assert'; +import { QError, qError } from '../shared/error/error'; +import type { QRLInternal } from '../shared/qrl/qrl-class'; +import type { QRL } from '../shared/qrl/qrl.public'; +import { ComputedEvent, RenderEvent, ResourceEvent, TaskEvent } from '../shared/utils/markers'; +import { seal } from '../shared/utils/qdev'; +import { isArray } from '../shared/utils/types'; import { setLocale } from './use-locale'; -import type { Subscriber } from '../state/common'; -import type { Signal } from '../state/signal'; +import type { Container, HostElement } from '../shared/types'; +import { vnode_getNode, vnode_isElementVNode, vnode_isVNode, vnode_locate } from '../client/vnode'; +import { _getQContainerElement, getDomContainer } from '../client/dom-container'; +import { type ContainerElement } from '../client/types'; +import { WrappedSignalImpl } from '../reactive-primitives/impl/wrapped-signal-impl'; +import { type EffectSubscription, type EffectSubscriptionProp } from '../reactive-primitives/types'; +import type { Signal } from '../reactive-primitives/signal.public'; +import type { ISsrNode } from 'packages/qwik/src/server/qwik-types'; +import { getSubscriber } from '../reactive-primitives/subscriber'; +import type { SubscriptionData } from '../reactive-primitives/subscription-data'; declare const document: QwikDocument; -// Simplified version of `ServerRequestEvent` from `@builder.io/qwik-city` package. +// Simplified version of `ServerRequestEvent` from `@qwik.dev/router` package. export interface SimplifiedServerRequestEvent { url: URL; locale: string | undefined; request: Request; } -export interface StyleAppend { - styleId: string; - content: string | null; -} - -// Simplified version of `ServerRequestEvent` from `@builder.io/qwik-city` package. -export interface ServerRequestEvent { - url: URL; - locale: string | undefined; - request: Request; -} - export type PossibleEvents = | Event | SimplifiedServerRequestEvent @@ -52,14 +36,11 @@ export type PossibleEvents = | typeof ResourceEvent; export interface RenderInvokeContext extends InvokeContext { - $renderCtx$: RenderContext; - /** The parent document */ - $doc$: Document; // The below are just always-defined attributes of InvokeContext. - $hostElement$: QwikElement; + $hostElement$: HostElement; $event$: PossibleEvents; $waitOn$: Promise[]; - $subscriber$: Subscriber | null; + $container$: Container; } export type InvokeTuple = [Element, Event, URL?]; @@ -71,19 +52,16 @@ export interface InvokeContext { /** The next available index for the sequentialScope array */ $i$: number; /** The Virtual parent component for the current component code */ - $hostElement$: QwikElement | undefined; + $hostElement$: HostElement | undefined; /** The current DOM element */ $element$: Element | undefined; /** The event we're currently handling */ $event$: PossibleEvents | undefined; /** The QRL function we're currently executing */ $qrl$: QRL | undefined; - /** Promises that need awaiting before the current invocation is done */ - $waitOn$: Promise[] | undefined; - /** The current subscriber for registering signal reads */ - $subscriber$: Subscriber | null | undefined; - $renderCtx$: RenderContext | undefined; + $effectSubscriber$: EffectSubscription | undefined; $locale$: string | undefined; + $container$: Container | undefined; } let _context: InvokeContext | undefined; @@ -106,7 +84,7 @@ export const tryGetInvokeContext = (): InvokeContext | undefined => { export const getInvokeContext = (): InvokeContext => { const ctx = tryGetInvokeContext(); if (!ctx) { - throw qError(QError_useMethodOutsideContext); + throw qError(QError.useMethodOutsideContext); } return ctx; }; @@ -114,19 +92,13 @@ export const getInvokeContext = (): InvokeContext => { export const useInvokeContext = (): RenderInvokeContext => { const ctx = tryGetInvokeContext(); if (!ctx || ctx.$event$ !== RenderEvent) { - throw qError(QError_useInvokeContext); + throw qError(QError.useInvokeContext); } assertDefined(ctx.$hostElement$, `invoke: $hostElement$ must be defined`, ctx); - assertDefined(ctx.$waitOn$, `invoke: $waitOn$ must be defined`, ctx); - assertDefined(ctx.$renderCtx$, `invoke: $renderCtx$ must be defined`, ctx); - assertDefined(ctx.$subscriber$, `invoke: $subscriber$ must be defined`, ctx); + assertDefined(ctx.$effectSubscriber$, `invoke: $effectSubscriber$ must be defined`, ctx); return ctx as RenderInvokeContext; }; -export const useContainerState = () => { - const ctx = useInvokeContext(); - return ctx.$renderCtx$.$static$.$containerState$; -}; export function useBindInvokeContext any>( this: unknown, @@ -169,29 +141,18 @@ export function invokeApply any>( return returnValue; } -export const waitAndRun = (ctx: RenderInvokeContext, callback: () => unknown) => { - const waitOn = ctx.$waitOn$; - if (waitOn.length === 0) { - const result = callback(); - if (isPromise(result)) { - waitOn.push(result); - } - } else { - waitOn.push(Promise.all(waitOn).then(callback)); - } -}; - export const newInvokeContextFromTuple = ([element, event, url]: InvokeTuple) => { - const container = element.closest(QContainerSelector); - const locale = container?.getAttribute(QLocaleAttr) || undefined; + const domContainer = getDomContainer(element); + const hostElement = vnode_locate(domContainer.rootVNode, element); + const locale = domContainer.$locale$; locale && setLocale(locale); - return newInvokeContext(locale, undefined, element, event, url); + return newInvokeContext(locale, hostElement, element, event, url); }; // TODO how about putting url and locale (and event/custom?) in to a "static" object export const newInvokeContext = ( locale?: string, - hostElement?: QwikElement, + hostElement?: HostElement, element?: Element, event?: PossibleEvents, url?: URL @@ -206,19 +167,14 @@ export const newInvokeContext = ( $element$: element, $event$: event, $qrl$: undefined, - $waitOn$: undefined, - $subscriber$: undefined, - $renderCtx$: undefined, + $effectSubscriber$: undefined, $locale$, + $container$: undefined, }; seal(ctx); return ctx; }; -export const getWrappingContainer = (el: QwikElement): Element | null => { - return el.closest(QContainerSelector); -}; - /** * Don't track listeners for this callback * @@ -236,22 +192,65 @@ const trackInvocation = /*#__PURE__*/ newInvokeContext( ); /** - * Mark sub as a listener for the signal - * - * @public + * @param fn + * @param subscriber + * @param property `true` - subscriber is component `false` - subscriber is VNode `string` - + * subscriber is property + * @param container + * @param data - Additional subscription data + * @returns */ -export const trackSignal = (signal: Signal, sub: Subscriber): T => { - trackInvocation.$subscriber$ = sub; - return invoke(trackInvocation, () => signal.value); +export const trackSignal = ( + fn: () => T, + subscriber: EffectSubscription[EffectSubscriptionProp.CONSUMER], + property: EffectSubscription[EffectSubscriptionProp.PROPERTY], + container: Container, + data?: SubscriptionData +): T => { + const previousSubscriber = trackInvocation.$effectSubscriber$; + const previousContainer = trackInvocation.$container$; + try { + trackInvocation.$effectSubscriber$ = getSubscriber(subscriber, property, data); + trackInvocation.$container$ = container; + return invoke(trackInvocation, fn); + } finally { + trackInvocation.$effectSubscriber$ = previousSubscriber; + trackInvocation.$container$ = previousContainer; + } +}; + +export const trackSignalAndAssignHost = ( + value: Signal, + host: HostElement, + property: EffectSubscription[EffectSubscriptionProp.PROPERTY], + container: Container, + data?: SubscriptionData +) => { + if (value instanceof WrappedSignalImpl && value.$hostElement$ !== host && host) { + value.$hostElement$ = host; + } + return trackSignal(() => value.value, host, property, container, data); }; /** @internal */ export const _getContextElement = (): unknown => { const iCtx = tryGetInvokeContext(); if (iCtx) { - return ( - iCtx.$element$ ?? iCtx.$hostElement$ ?? (iCtx.$qrl$ as QRLInternal)?.$setContainer$(undefined) - ); + const hostElement = iCtx.$hostElement$; + let element: Element | ISsrNode | null = null; + + if (hostElement != null) { + if (vnode_isVNode(hostElement)) { + if (vnode_isElementVNode(hostElement)) { + element = vnode_getNode(hostElement) as Element; + } + } else { + // isSSRnode + element = hostElement; + } + } + + return element ?? (iCtx.$qrl$ as QRLInternal)?.$setContainer$(undefined); } }; @@ -265,21 +264,15 @@ export const _getContextEvent = (): unknown => { /** @internal */ export const _jsxBranch = (input?: T) => { - const iCtx = tryGetInvokeContext(); - if (iCtx && iCtx.$hostElement$ && iCtx.$renderCtx$) { - const hostElement = iCtx.$hostElement$; - const elCtx = getContext(hostElement, iCtx.$renderCtx$.$static$.$containerState$); - elCtx.$flags$ |= HOST_FLAG_DYNAMIC; - } return input; }; /** @internal */ export const _waitUntilRendered = (elm: Element) => { - const containerEl = getWrappingContainer(elm); + const containerEl = _getQContainerElement(elm); if (!containerEl) { return Promise.resolve(); } - const containerState = _getContainerState(containerEl); - return containerState.$renderPromise$ ?? Promise.resolve(); + const container = (containerEl as ContainerElement).qContainer; + return container?.renderDone ?? Promise.resolve(); }; diff --git a/packages/qwik/src/core/use/use-env-data.ts b/packages/qwik/src/core/use/use-env-data.ts index 130ee28c0bc..32d14476857 100644 --- a/packages/qwik/src/core/use/use-env-data.ts +++ b/packages/qwik/src/core/use/use-env-data.ts @@ -9,5 +9,5 @@ export function useServerData(key: string, defaultValue: B): T | B; /** @public */ export function useServerData(key: string, defaultValue?: any) { const ctx = tryGetInvokeContext(); - return ctx?.$renderCtx$?.$static$.$containerState$.$serverData$[key] ?? defaultValue; + return ctx?.$container$?.$serverData$[key] ?? defaultValue; } diff --git a/packages/qwik/src/core/use/use-error-boundary.ts b/packages/qwik/src/core/use/use-error-boundary.ts index 36e750a2f93..dc5398c27d5 100644 --- a/packages/qwik/src/core/use/use-error-boundary.ts +++ b/packages/qwik/src/core/use/use-error-boundary.ts @@ -1,4 +1,4 @@ -import { type ErrorBoundaryStore, ERROR_CONTEXT } from '../render/error-handling'; +import { ERROR_CONTEXT, type ErrorBoundaryStore } from '../shared/error/error-handling'; import { useContextProvider } from './use-context'; import { useStore } from './use-store.public'; diff --git a/packages/qwik/src/core/use/use-id.ts b/packages/qwik/src/core/use/use-id.ts index ae1c24a213e..ade683f5c68 100644 --- a/packages/qwik/src/core/use/use-id.ts +++ b/packages/qwik/src/core/use/use-id.ts @@ -1,18 +1,29 @@ -import { getNextIndex } from '../render/execute-component'; -import { hashCode } from '../util/hash_code'; +import type { QRL } from '..'; +import { hashCode } from '../shared/utils/hash_code'; +import { OnRenderProp } from '../shared/utils/markers'; import { useSequentialScope } from './use-sequential-scope'; +import { getNextUniqueIndex } from '../shared/utils/unique-index-generator'; /** @public */ export const useId = (): string => { - const { val, set, elCtx, iCtx } = useSequentialScope(); + const { val, set, iCtx } = useSequentialScope(); if (val != null) { return val; } + const containerBase = iCtx.$container$.$buildBase$ || ''; + const base = containerBase ? hashCode(containerBase).substring(0, 3) : ''; + const componentQrl = iCtx.$container$.getHostProp(iCtx.$hostElement$, OnRenderProp); + const hash = componentQrl?.getHash().substring(0, 3) || ''; + const counter = getNextUniqueIndex(iCtx.$container$) || ''; + let id = `${base}${hash}${counter}`; - const containerBase = iCtx.$renderCtx$?.$static$?.$containerState$?.$base$ || ''; - const base = containerBase ? hashCode(containerBase) : ''; - const hash = elCtx.$componentQrl$?.getHash() || ''; - const counter = getNextIndex(iCtx.$renderCtx$) || ''; - const id = `${base}-${hash}-${counter}`; // If no base and no hash, then "--#" + let firstChar = id.charCodeAt(0); + // convert first char to letter if starts with a number, because CSS does not allow class names to start with a number + if (firstChar >= 48 /* 0 */ && firstChar <= 57 /* 9 */) { + // 48 is char code for '0', 65 is char code for 'A' + // 65 - 48 = 17, so we add 17 to the char code of the first char to convert it to a letter + firstChar += 17; + id = String.fromCharCode(firstChar) + id.substring(1); + } return set(id); }; 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 dfa85969f25..92fa8acfe9a 100644 --- a/packages/qwik/src/core/use/use-lexical-scope.public.ts +++ b/packages/qwik/src/core/use/use-lexical-scope.public.ts @@ -1,14 +1,12 @@ -import { assertDefined } from '../error/assert'; -import { inflateQrl, parseQRL } from '../qrl/qrl'; -import { getWrappingContainer, getInvokeContext } from './use-core'; -import { assertQrl } from '../qrl/qrl-class'; -import { getContext } from '../state/context'; -import { resumeIfNeeded } from '../container/resume'; -import { _getContainerState } from '../container/container'; +import { assertDefined } from '../shared/error/assert'; +import { getInvokeContext } from './use-core'; +import type { QRLInternal } from '../shared/qrl/qrl-class'; +import { _getQContainerElement, getDomContainer } from '../client/dom-container'; +import { assertQrl } from '../shared/qrl/qrl-utils'; // // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useLexicalScope instead) +// (edit ../readme.md#useLexicalScope instead and run `pnpm docs.sync`) /** * Used by the Qwik Optimizer to restore the lexically scoped variables. * @@ -22,17 +20,14 @@ import { _getContainerState } from '../container/container'; // export const useLexicalScope = (): VARS => { const context = getInvokeContext(); - let qrl = context.$qrl$; + let qrl = context.$qrl$ as QRLInternal | undefined; if (!qrl) { const el = context.$element$; assertDefined(el, 'invoke: element must be defined inside useLexicalScope()', context); - const container = getWrappingContainer(el); - assertDefined(container, `invoke: cant find parent q:container of`, el); - qrl = parseQRL(decodeURIComponent(String(context.$url$)), container); - assertQrl(qrl); - resumeIfNeeded(container); - const elCtx = getContext(el, _getContainerState(container)); - inflateQrl(qrl, elCtx); + const containerElement = _getQContainerElement(el) as HTMLElement; + assertDefined(containerElement, `invoke: cant find parent q:container of`, el); + const container = getDomContainer(containerElement); + qrl = container.parseQRL(decodeURIComponent(String(context.$url$))) as QRLInternal; } else { assertQrl(qrl); assertDefined( @@ -41,5 +36,5 @@ export const useLexicalScope = (): VARS => { qrl ); } - return qrl.$captureRef$ as VARS; + return qrl!.$captureRef$ as VARS; }; diff --git a/packages/qwik/src/core/use/use-locale.ts b/packages/qwik/src/core/use/use-locale.ts index 2e2d7719926..5e3efdddabb 100644 --- a/packages/qwik/src/core/use/use-locale.ts +++ b/packages/qwik/src/core/use/use-locale.ts @@ -8,7 +8,7 @@ let _locale: string | undefined = undefined; * If no current locale and there is no `defaultLocale` the function throws an error. * * @returns The locale. - * @internal + * @public */ export function getLocale(defaultLocale?: string): string { if (_locale === undefined) { @@ -27,7 +27,7 @@ export function getLocale(defaultLocale?: string): string { /** * Override the `getLocale` with `lang` within the `fn` execution. * - * @internal + * @public */ export function withLocale(locale: string, fn: () => T): T { const previousLang = _locale; @@ -45,7 +45,7 @@ export function withLocale(locale: string, fn: () => T): T { * This can be used only in browser. Server execution requires that each request could potentially * be a different lang, therefore setting a global lang would produce incorrect responses. * - * @param lang + * @public */ export function setLocale(locale: string): void { _locale = locale; diff --git a/packages/qwik/src/core/use/use-on.ts b/packages/qwik/src/core/use/use-on.ts index b3d876fa85f..6d7c67ee5d3 100644 --- a/packages/qwik/src/core/use/use-on.ts +++ b/packages/qwik/src/core/use/use-on.ts @@ -1,14 +1,18 @@ -import { assertQrl } from '../qrl/qrl-class'; -import type { QRL } from '../qrl/qrl.public'; -import { getContext, HOST_FLAG_NEED_ATTACH_LISTENER } from '../state/context'; -import { type Listener, normalizeOnProp } from '../state/listeners'; +import type { QRL } from '../shared/qrl/qrl.public'; import { useInvokeContext } from './use-core'; -import { type KnownEventNames } from '../render/jsx/types/jsx-qwik-events'; +import { type KnownEventNames } from '../shared/jsx/types/jsx-qwik-events'; import type { EventHandler, EventFromName, AllEventKeys, -} from '../render/jsx/types/jsx-qwik-attributes'; +} from '../shared/jsx/types/jsx-qwik-attributes'; +import type { HostElement } from '../shared/types'; +import { USE_ON_LOCAL, USE_ON_LOCAL_FLAGS, USE_ON_LOCAL_SEQ_IDX } from '../shared/utils/markers'; +import { + DOMContentLoadedEvent, + EventNameJSXScope, + eventNameToJsxEvent, +} from '../shared/utils/event-names'; export type EventQRL = | QRL, Element>> @@ -16,7 +20,7 @@ export type EventQRL = // // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useOn instead) +// (edit ../readme.md#useOn instead and run `pnpm docs.sync`) /** * Register a listener on the current component's host element. * @@ -28,12 +32,12 @@ export type EventQRL = */ // export const useOn = (event: T | T[], eventQrl: EventQRL) => { - _useOn(createEventName(event, undefined), eventQrl); + _useOn(createEventName(event, EventNameJSXScope.on), eventQrl); }; // // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useOnDocument instead) +// (edit ../readme.md#useOnDocument instead and run `pnpm docs.sync`) /** * Register a listener on `document`. * @@ -61,12 +65,12 @@ export const useOn = (event: T | T[], eventQrl: Event */ // export const useOnDocument = (event: T | T[], eventQrl: EventQRL) => { - _useOn(createEventName(event, 'document'), eventQrl); + _useOn(createEventName(event, EventNameJSXScope.document), eventQrl); }; // // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useOnWindow instead) +// (edit ../readme.md#useOnWindow instead and run `pnpm docs.sync`) /** * Register a listener on `window`. * @@ -95,33 +99,81 @@ export const useOnDocument = (event: T | T[], eventQr */ // export const useOnWindow = (event: T | T[], eventQrl: EventQRL) => { - _useOn(createEventName(event, 'window'), eventQrl); + _useOn(createEventName(event, EventNameJSXScope.window), eventQrl); }; const createEventName = ( event: KnownEventNames | KnownEventNames[], - eventType: 'window' | 'document' | undefined + eventScope: EventNameJSXScope ) => { - const formattedEventType = eventType !== undefined ? eventType + ':' : ''; - const res = Array.isArray(event) - ? event.map((e) => `${formattedEventType}on-${e}`) - : `${formattedEventType}on-${event}`; - return res; + const map = (name: string) => { + let prefix: string = eventScope; + if (name === DOMContentLoadedEvent) { + prefix += '-'; // Add hyphen at the start if case-sensitive + } + return eventNameToJsxEvent(name, prefix); + }; + return Array.isArray(event) ? event.map(map) : map(event); }; const _useOn = (eventName: string | string[], eventQrl: EventQRL) => { + const { isAdded, addEvent } = useOnEventsSequentialScope(); + if (isAdded) { + return; + } if (eventQrl) { - const invokeCtx = useInvokeContext(); - const elCtx = getContext( - invokeCtx.$hostElement$, - invokeCtx.$renderCtx$.$static$.$containerState$ - ); - assertQrl(eventQrl as any); - if (typeof eventName === 'string') { - elCtx.li.push([normalizeOnProp(eventName), eventQrl] as Listener); - } else { - elCtx.li.push(...eventName.map((name) => [normalizeOnProp(name), eventQrl] as Listener)); - } - elCtx.$flags$ |= HOST_FLAG_NEED_ATTACH_LISTENER; + Array.isArray(eventName) + ? eventName.forEach((event) => addEvent(event, eventQrl)) + : addEvent(eventName, eventQrl); } }; + +/** + * This hook is like the `useSequentialScope` but it is specifically for `useOn`. This is needed + * because we want to execute the `useOn` hooks only once and store the event listeners on the host + * element. From Qwik V2 the component is rerunning when the promise is thrown, so we need to make + * sure that the event listeners are not added multiple times. + * + * - The event listeners are stored in the `USE_ON_LOCAL` property. + * - The `USE_ON_LOCAL_SEQ_IDX` is used to keep track of the index of the hook that calls this. + * - The `USE_ON_LOCAL_FLAGS` is used to keep track of whether the event listener has been added or + * not. + */ +const useOnEventsSequentialScope = () => { + const iCtx = useInvokeContext(); + const hostElement = iCtx.$hostElement$; + const host: HostElement = hostElement as any; + let onMap = iCtx.$container$.getHostProp(host, USE_ON_LOCAL); + if (onMap === null) { + onMap = {}; + iCtx.$container$.setHostProp(host, USE_ON_LOCAL, onMap); + } + let seqIdx = iCtx.$container$.getHostProp(host, USE_ON_LOCAL_SEQ_IDX); + if (seqIdx === null) { + seqIdx = 0; + } + iCtx.$container$.setHostProp(host, USE_ON_LOCAL_SEQ_IDX, seqIdx + 1); + let addedFlags = iCtx.$container$.getHostProp(host, USE_ON_LOCAL_FLAGS); + if (addedFlags === null) { + addedFlags = []; + iCtx.$container$.setHostProp(host, USE_ON_LOCAL_FLAGS, addedFlags); + } + while (addedFlags.length <= seqIdx) { + addedFlags.push(false); + } + const addEvent = (eventName: string, eventQrl: EventQRL) => { + addedFlags[seqIdx] = true; + let events = onMap![eventName]; + if (!events) { + onMap![eventName] = events = []; + } + events.push(eventQrl); + }; + + return { + isAdded: addedFlags[seqIdx], + addEvent, + }; +}; + +export type UseOnMap = Record[]>; diff --git a/packages/qwik/src/core/use/use-on.unit.ts b/packages/qwik/src/core/use/use-on.unit.ts index 50666c68d52..2bd580335b2 100644 --- a/packages/qwik/src/core/use/use-on.unit.ts +++ b/packages/qwik/src/core/use/use-on.unit.ts @@ -1,6 +1,6 @@ import { assertType, describe, expectTypeOf, test } from 'vitest'; import { useOn, type EventQRL } from './use-on'; -import { $, type QRL, type QrlReturn } from '../qrl/qrl.public'; +import { $, type QRL, type QrlReturn } from '../shared/qrl/qrl.public'; describe('types', () => { // Note, these type checks happen at compile time. We don't need to call anything, so we do ()=>()=>. We just need to diff --git a/packages/qwik/src/core/use/use-resource-dollar.ts b/packages/qwik/src/core/use/use-resource-dollar.ts new file mode 100644 index 00000000000..7e2a595c216 --- /dev/null +++ b/packages/qwik/src/core/use/use-resource-dollar.ts @@ -0,0 +1,72 @@ +import { dollar } from '../shared/qrl/qrl.public'; +import { + useResourceQrl, + type ResourceFn, + type ResourceOptions, + type ResourceReturn, +} from './use-resource'; + +// +// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! +// (edit ../readme.md#useResource instead and run `pnpm docs.sync`) +/** + * This method works like an async memoized function that runs whenever some tracked value changes + * and returns some data. + * + * `useResource` however returns immediate a `ResourceReturn` object that contains the data and a + * state that indicates if the data is available or not. + * + * The status can be one of the following: + * + * - `pending` - the data is not yet available. + * - `resolved` - the data is available. + * - `rejected` - the data is not available due to an error or timeout. + * + * Be careful when using a `try/catch` statement in `useResource$`. If you catch the error and don't + * re-throw it (or a new Error), the resource status will never be `rejected`. + * + * ### Example + * + * Example showing how `useResource` to perform a fetch to request the weather, whenever the input + * city name changes. + * + * ```tsx + * const Cmp = component$(() => { + * const cityS = useSignal(''); + * + * const weatherResource = useResource$(async ({ track, cleanup }) => { + * const cityName = track(cityS); + * const abortController = new AbortController(); + * cleanup(() => abortController.abort('cleanup')); + * const res = await fetch(`http://weatherdata.com?city=${cityName}`, { + * signal: abortController.signal, + * }); + * const data = await res.json(); + * return data as { temp: number }; + * }); + * + * return ( + *
        + * + * { + * return
        Temperature: {weather.temp}
        ; + * }} + * /> + *
        + * ); + * }); + * ``` + * + * @public + * @see Resource + * @see ResourceReturn + */ +//
        +export const useResource$ = ( + generatorFn: ResourceFn, + opts?: ResourceOptions +): ResourceReturn => { + return useResourceQrl(dollar(generatorFn), opts); +}; diff --git a/packages/qwik/src/core/use/use-resource.ts b/packages/qwik/src/core/use/use-resource.ts index 743b2df8db2..9d3197ad99b 100644 --- a/packages/qwik/src/core/use/use-resource.ts +++ b/packages/qwik/src/core/use/use-resource.ts @@ -1,27 +1,75 @@ -import { $, type QRL } from '../qrl/qrl.public'; -import { assertQrl } from '../qrl/qrl-class'; -import { - type ResourceReturn, - type ResourceDescriptor, - type ResourceFn, - runResource, - TaskFlagsIsDirty, - TaskFlagsIsResource, - Task, - type ResourceReturnInternal, -} from './use-task'; -import { Fragment, jsx } from '../render/jsx/jsx-runtime'; -import { isServerPlatform } from '../platform/platform'; -import { untrack, useBindInvokeContext } from './use-core'; - -import type { ContainerState, GetObjID } from '../container/container'; +import { isServerPlatform } from '../shared/platform/platform'; +import { assertQrl } from '../shared/qrl/qrl-utils'; +import { type QRL } from '../shared/qrl/qrl.public'; +import { Fragment, _jsxSorted } from '../shared/jsx/jsx-runtime'; +import { invoke, newInvokeContext, untrack, useBindInvokeContext } from './use-core'; +import { Task, TaskFlags, cleanupTask, type DescriptorBase, type Tracker } from './use-task'; + +import type { Container, HostElement, ValueOrPromise } from '../../server/qwik-types'; +import type { JSXOutput } from '../shared/jsx/types/jsx-node'; +import { delay, isPromise, safeCall } from '../shared/utils/promises'; +import { isFunction, isObject } from '../shared/utils/types'; +import { createStore, getStoreTarget, unwrapStore } from '../reactive-primitives/impl/store'; import { useSequentialScope } from './use-sequential-scope'; -import { createProxy } from '../state/store'; -import { getProxyTarget } from '../state/common'; -import { isSignal, type Signal } from '../state/signal'; -import { isObject } from '../util/types'; -import { isPromise } from '../util/promises'; -import type { JSXOutput } from '../render/jsx/types/jsx-node'; +import { isSignal } from '../reactive-primitives/utils'; +import type { Signal } from '../reactive-primitives/signal.public'; +import { clearAllEffects } from '../reactive-primitives/cleanup'; +import { ResourceEvent } from '../shared/utils/markers'; +import { assertDefined } from '../shared/error/assert'; +import { noSerialize } from '../shared/utils/serialize-utils'; +import { ChoreType } from '../shared/util-chore-type'; +import { getSubscriber } from '../reactive-primitives/subscriber'; +import { EffectProperty, StoreFlags } from '../reactive-primitives/types'; + +const DEBUG: boolean = false; + +function debugLog(...arg: any) { + // eslint-disable-next-line no-console + console.log(arg.join(', ')); +} + +/** @public */ +export interface ResourceCtx { + readonly track: Tracker; + cleanup(callback: () => void): void; + cache(policyOrMilliseconds: number | 'immutable'): void; + readonly previous: T | undefined; +} + +/** @public */ +export type ResourceFn = (ctx: ResourceCtx) => ValueOrPromise; + +/** @public */ +export type ResourceReturn = ResourcePending | ResourceResolved | ResourceRejected; + +/** @public */ +export interface ResourcePending { + readonly value: Promise; + readonly loading: boolean; +} + +/** @public */ +export interface ResourceResolved { + readonly value: Promise; + readonly loading: boolean; +} + +/** @public */ +export interface ResourceRejected { + readonly value: Promise; + readonly loading: boolean; +} + +export interface ResourceReturnInternal { + __brand: 'resource'; + _state: 'pending' | 'resolved' | 'rejected'; + _resolved: T | undefined; + _error: Error | undefined; + _cache: number; + _timeout: number; + value: Promise; + loading: boolean; +} /** * Options to pass to `useResource$()` @@ -37,157 +85,34 @@ export interface ResourceOptions { timeout?: number; } -// -// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useResource instead) -/** - * This method works like an async memoized function that runs whenever some tracked value changes - * and returns some data. - * - * `useResource` however returns immediate a `ResourceReturn` object that contains the data and a - * state that indicates if the data is available or not. - * - * The status can be one of the following: - * - * - `pending` - the data is not yet available. - * - `resolved` - the data is available. - * - `rejected` - the data is not available due to an error or timeout. - * - * Avoid using a `try/catch` statement in `useResource$`. If you catch the error instead of passing - * it, the resource status will never be `rejected`. - * - * ### Example - * - * Example showing how `useResource` to perform a fetch to request the weather, whenever the input - * city name changes. - * - * ```tsx - * const Cmp = component$(() => { - * const cityS = useSignal(''); - * - * const weatherResource = useResource$(async ({ track, cleanup }) => { - * const cityName = track(cityS); - * const abortController = new AbortController(); - * cleanup(() => abortController.abort('cleanup')); - * const res = await fetch(`http://weatherdata.com?city=${cityName}`, { - * signal: abortController.signal, - * }); - * const data = await res.json(); - * return data as { temp: number }; - * }); - * - * return ( - *
        - * - * { - * return
        Temperature: {weather.temp}
        ; - * }} - * /> - *
        - * ); - * }); - * ``` - * - * @public - * @see Resource - * @see ResourceReturn - */ -//
        +/** @internal */ export const useResourceQrl = ( qrl: QRL>, opts?: ResourceOptions ): ResourceReturn => { - const { val, set, i, iCtx, elCtx } = useSequentialScope>(); + const { val, set, i, iCtx } = useSequentialScope>(); if (val != null) { return val; } assertQrl(qrl); - const containerState = iCtx.$renderCtx$.$static$.$containerState$; - const resource = createResourceReturn(containerState, opts); - const el = elCtx.$element$; + const container = iCtx.$container$; + const resource = createResourceReturn(container, opts); + const el = iCtx.$hostElement$; const task = new Task( - TaskFlagsIsDirty | TaskFlagsIsResource, + TaskFlags.DIRTY | TaskFlags.RESOURCE, i, el, qrl, - resource + resource, + null ) as ResourceDescriptor; - const previousWait = Promise.all(iCtx.$waitOn$.slice()); - runResource(task, containerState, iCtx.$renderCtx$, previousWait); - if (!elCtx.$tasks$) { - elCtx.$tasks$ = []; - } - elCtx.$tasks$.push(task); + container.$scheduler$(ChoreType.TASK, task); set(resource); return resource; }; -// -// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useResource instead) -/** - * This method works like an async memoized function that runs whenever some tracked value changes - * and returns some data. - * - * `useResource` however returns immediate a `ResourceReturn` object that contains the data and a - * state that indicates if the data is available or not. - * - * The status can be one of the following: - * - * - 'pending' - the data is not yet available. - * - 'resolved' - the data is available. - * - 'rejected' - the data is not available due to an error or timeout. - * - * ### Example - * - * Example showing how `useResource` to perform a fetch to request the weather, whenever the input - * city name changes. - * - * ```tsx - * const Cmp = component$(() => { - * const cityS = useSignal(''); - * - * const weatherResource = useResource$(async ({ track, cleanup }) => { - * const cityName = track(cityS); - * const abortController = new AbortController(); - * cleanup(() => abortController.abort('cleanup')); - * const res = await fetch(`http://weatherdata.com?city=${cityName}`, { - * signal: abortController.signal, - * }); - * const data = await res.json(); - * return data as { temp: number }; - * }); - * - * return ( - *
        - * - * { - * return
        Temperature: {weather.temp}
        ; - * }} - * /> - *
        - * ); - * }); - * ``` - * - * @public - * @see Resource - * @see ResourceReturn - */ -//
        -export const useResource$ = ( - generatorFn: ResourceFn, - opts?: ResourceOptions -): ResourceReturn => { - return useResourceQrl($(generatorFn), opts); -}; - /** @public */ export interface ResourceProps { readonly value: ResourceReturn | Signal | T> | Promise; @@ -198,7 +123,7 @@ export interface ResourceProps { // // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useResource instead) +// (edit ../readme.md#useResource instead and run `pnpm docs.sync`) /** * This method works like an async memoized function that runs whenever some tracked value changes * and returns some data. @@ -208,9 +133,12 @@ export interface ResourceProps { * * The status can be one of the following: * - * - 'pending' - the data is not yet available. - * - 'resolved' - the data is available. - * - 'rejected' - the data is not available due to an error or timeout. + * - `pending` - the data is not yet available. + * - `resolved` - the data is available. + * - `rejected` - the data is not available due to an error or timeout. + * + * Be careful when using a `try/catch` statement in `useResource$`. If you catch the error and don't + * re-throw it (or a new Error), the resource status will never be `rejected`. * * ### Example * @@ -252,48 +180,58 @@ export interface ResourceProps { */ // export const Resource = (props: ResourceProps): JSXOutput => { - const isBrowser = !isServerPlatform(); + // Resource path + return _jsxSorted(Fragment, null, null, getResourceValueAsPromise(props), 0, null); +}; + +function getResourceValueAsPromise(props: ResourceProps): Promise | JSXOutput { const resource = props.value as ResourceReturnInternal | Promise | Signal; - let promise: Promise | undefined; if (isResourceReturn(resource)) { + const isBrowser = !isServerPlatform(); if (isBrowser) { - if (props.onRejected) { - resource.value.catch(() => {}); - if (resource._state === 'rejected') { - return props.onRejected(resource._error!); - } - } - if (props.onPending) { - const state = resource._state; - if (state === 'resolved') { - return props.onResolved(resource._resolved!); - } else if (state === 'pending') { - return props.onPending(); - } else if (state === 'rejected') { - throw resource._error; + // create a subscription for the resource._state changes + const state = resource._state; + DEBUG && debugLog(`RESOURCE_CMP.${state}`, 'VALUE: ' + untrack(() => resource._resolved)); + + if (state === 'pending' && props.onPending) { + return Promise.resolve().then(useBindInvokeContext(props.onPending)); + } else if (state === 'rejected' && props.onRejected) { + return Promise.resolve(resource._error!).then(useBindInvokeContext(props.onRejected)); + } else { + const resolvedValue = untrack(() => resource._resolved) as T; + if (resolvedValue !== undefined) { + // resolved, pending without onPending prop or rejected without onRejected prop + return Promise.resolve(resolvedValue).then(useBindInvokeContext(props.onResolved)); } } - if (untrack(() => resource._resolved) !== undefined) { - return props.onResolved(resource._resolved!); - } } - promise = resource.value; + const value = resource.value; + if (value) { + return value.then( + useBindInvokeContext(props.onResolved), + useBindInvokeContext(props.onRejected) + ); + } else { + // this is temporary value until the `runResource` is executed and promise is assigned to the value + return Promise.resolve(undefined); + } } else if (isPromise(resource)) { - promise = resource; + return resource.then( + useBindInvokeContext(props.onResolved), + useBindInvokeContext(props.onRejected) + ); } else if (isSignal(resource)) { - promise = Promise.resolve(resource.value); + return Promise.resolve(resource.value).then( + useBindInvokeContext(props.onResolved), + useBindInvokeContext(props.onRejected) + ); } else { - return props.onResolved(resource as T); - } - - // Resource path - return jsx(Fragment, { - children: promise.then( + return Promise.resolve(resource as T).then( useBindInvokeContext(props.onResolved), useBindInvokeContext(props.onRejected) - ), - }); -}; + ); + } +} export const _createResourceReturn = (opts?: ResourceOptions): ResourceReturnInternal => { const resource: ResourceReturnInternal = { @@ -310,54 +248,173 @@ export const _createResourceReturn = (opts?: ResourceOptions): ResourceReturn }; export const createResourceReturn = ( - containerState: ContainerState, + container: Container, opts?: ResourceOptions, initialPromise?: Promise ): ResourceReturnInternal => { const result = _createResourceReturn(opts); - result.value = initialPromise as any; - const resource = createProxy(result, containerState, undefined); - return resource; -}; + result.value = initialPromise as Promise; -export const getInternalResource = (resource: ResourceReturn): ResourceReturnInternal => { - return getProxyTarget(resource) as any; + return createStore(container, result, StoreFlags.RECURSIVE); }; export const isResourceReturn = (obj: any): obj is ResourceReturn => { - return isObject(obj) && (obj as any).__brand === 'resource'; + return isObject(obj) && (getStoreTarget(obj as any) || obj).__brand === 'resource'; }; -export const serializeResource = ( - resource: ResourceReturnInternal, - getObjId: GetObjID -) => { - const state = resource._state; - if (state === 'resolved') { - return `0 ${getObjId(resource._resolved)}`; - } else if (state === 'pending') { - return `1`; - } else { - return `2 ${getObjId(resource._error)}`; +export interface ResourceDescriptor + extends DescriptorBase, ResourceReturnInternal> {} + +export const runResource = ( + task: ResourceDescriptor, + container: Container, + host: HostElement +): ValueOrPromise => { + task.$flags$ &= ~TaskFlags.DIRTY; + cleanupTask(task); + + const iCtx = newInvokeContext(container.$locale$, host, undefined, ResourceEvent); + iCtx.$container$ = container; + + const taskFn = task.$qrl$.getFn(iCtx, () => clearAllEffects(container, task)); + + const resource = task.$state$; + assertDefined( + resource, + 'useResource: when running a resource, "task.resource" must be a defined.', + task + ); + + const track: Tracker = (obj: (() => unknown) | object | Signal, prop?: string) => { + const ctx = newInvokeContext(); + ctx.$effectSubscriber$ = getSubscriber(task, EffectProperty.COMPONENT); + ctx.$container$ = container; + return invoke(ctx, () => { + if (isFunction(obj)) { + return obj(); + } + if (prop) { + return (obj as Record)[prop]; + } else if (isSignal(obj)) { + return obj.value; + } else { + return obj; + } + }); + }; + + const handleError = (reason: unknown) => container.handleError(reason, host); + + const cleanups: (() => void)[] = []; + task.$destroy$ = noSerialize(() => { + cleanups.forEach((fn) => { + try { + fn(); + } catch (err) { + handleError(err); + } + }); + done = true; + }); + + const resourceTarget = unwrapStore(resource); + const opts: ResourceCtx = { + track, + cleanup(fn) { + if (typeof fn === 'function') { + cleanups.push(fn); + } + }, + cache(policy) { + let milliseconds = 0; + if (policy === 'immutable') { + milliseconds = Infinity; + } else { + milliseconds = policy; + } + resource._cache = milliseconds; + }, + previous: resourceTarget._resolved, + }; + + let resolve: (v: T) => void; + let reject: (v: unknown) => void; + let done = false; + + const setState = (resolved: boolean, value: T | Error) => { + if (!done) { + done = true; + if (resolved) { + done = true; + resource.loading = false; + resource._state = 'resolved'; + resource._resolved = value as T; + resource._error = undefined; + resolve(value as T); + } else { + done = true; + resource.loading = false; + resource._state = 'rejected'; + resource._error = value as Error; + reject(value as Error); + } + return true; + } + return false; + }; + + /** + * Add cleanup to resolve the resource if we are trying to run the same resource again while the + * previous one is not resolved yet. The next `runResource` run will call this cleanup + */ + cleanups.push(() => { + if (untrack(() => resource.loading) === true) { + const value = untrack(() => resource._resolved) as T; + setState(true, value); + } + }); + + // Execute mutation inside empty invocation + invoke(iCtx, () => { + // console.log('RESOURCE.pending: '); + resource._state = 'pending'; + resource.loading = !isServerPlatform(); + const promise = (resource.value = new Promise((r, re) => { + resolve = r; + reject = re; + })); + promise.catch(ignoreErrorToPreventNodeFromCrashing); + }); + + const promise: ValueOrPromise = safeCall( + () => Promise.resolve(taskFn(opts)), + (value) => { + setState(true, value); + }, + (err) => { + if (isPromise(err)) { + return err.then(() => runResource(task, container, host)); + } else { + setState(false, err); + } + } + ); + + const timeout = resourceTarget._timeout; + if (timeout > 0) { + return Promise.race([ + promise, + delay(timeout).then(() => { + if (setState(false, new Error('timeout'))) { + cleanupTask(task); + } + }), + ]); } + return promise; }; -export const parseResourceReturn = (data: string): ResourceReturnInternal => { - const [first, id] = data.split(' '); - const result = _createResourceReturn(undefined); - result.value = Promise.resolve() as any; - if (first === '0') { - result._state = 'resolved'; - result._resolved = id as any; - result.loading = false; - } else if (first === '1') { - result._state = 'pending'; - result.value = new Promise(() => {}); - result.loading = true; - } else if (first === '2') { - result._state = 'rejected'; - result._error = id as any; - result.loading = false; - } - return result; +const ignoreErrorToPreventNodeFromCrashing = (err: unknown) => { + // ignore error to prevent node from crashing + // node will crash in promise is rejected and no one is listening to the rejection. }; diff --git a/packages/qwik/src/core/use/use-sequential-scope.ts b/packages/qwik/src/core/use/use-sequential-scope.ts index a6ead3de839..3594753ef82 100644 --- a/packages/qwik/src/core/use/use-sequential-scope.ts +++ b/packages/qwik/src/core/use/use-sequential-scope.ts @@ -1,7 +1,8 @@ -import { verifySerializable } from '../state/common'; -import { getContext, type QContext } from '../state/context'; -import { qDev, qSerialize } from '../util/qdev'; -import { type RenderInvokeContext, useInvokeContext } from './use-core'; +import { verifySerializable } from '../shared/utils/serialize-utils'; +import { ELEMENT_SEQ, ELEMENT_SEQ_IDX } from '../shared/utils/markers'; +import { qDev, qSerialize } from '../shared/utils/qdev'; +import type { HostElement } from '../shared/types'; +import { useInvokeContext, type RenderInvokeContext } from './use-core'; export interface SequentialScope { /** The currently stored data for the hook that calls this */ @@ -11,7 +12,6 @@ export interface SequentialScope { /** Index of the hook */ readonly i: number; readonly iCtx: RenderInvokeContext; - readonly elCtx: QContext; } /** @@ -21,22 +21,31 @@ export interface SequentialScope { export const useSequentialScope = (): SequentialScope => { const iCtx = useInvokeContext(); const hostElement = iCtx.$hostElement$; - const elCtx = getContext(hostElement, iCtx.$renderCtx$.$static$.$containerState$); - const seq = (elCtx.$seq$ ||= []); - const i = iCtx.$i$++; - + const host: HostElement = hostElement as any; + let seq = iCtx.$container$.getHostProp(host, ELEMENT_SEQ); + if (seq === null) { + seq = []; + iCtx.$container$.setHostProp(host, ELEMENT_SEQ, seq); + } + let seqIdx = iCtx.$container$.getHostProp(host, ELEMENT_SEQ_IDX); + if (seqIdx === null) { + seqIdx = 0; + } + iCtx.$container$.setHostProp(host, ELEMENT_SEQ_IDX, seqIdx + 1); + while (seq.length <= seqIdx) { + seq.push(undefined); + } const set = (value: T) => { if (qDev && qSerialize) { verifySerializable(value); } - return (seq[i] = value); + return (seq![seqIdx!] = value); }; return { - val: seq[i], + val: seq[seqIdx], set, - i, + i: seqIdx, iCtx, - elCtx, }; }; diff --git a/packages/qwik/src/core/use/use-serializer.ts b/packages/qwik/src/core/use/use-serializer.ts new file mode 100644 index 00000000000..a398736ae95 --- /dev/null +++ b/packages/qwik/src/core/use/use-serializer.ts @@ -0,0 +1,74 @@ +import { implicit$FirstArg } from '../shared/qrl/implicit_dollar'; +import type { QRL } from '../shared/qrl/qrl.public'; +import type { ComputedSignalImpl } from '../reactive-primitives/impl/computed-signal-impl'; +import { SerializerSignalImpl } from '../reactive-primitives/impl/serializer-signal-impl'; +import type { SerializerArg } from '../reactive-primitives/types'; +import type { createSerializer$ } from '../reactive-primitives/signal.public'; +import { useComputedCommon } from './use-computed'; + +/** @internal */ +export const useSerializerQrl = (qrl: QRL>) => + useComputedCommon(qrl as any, SerializerSignalImpl as typeof ComputedSignalImpl); + +/** + * Creates a signal which holds a custom serializable value. It requires that the value implements + * the `CustomSerializable` type, which means having a function under the `[SerializeSymbol]` + * property that returns a serializable value when called. + * + * The `fn` you pass is called with the result of the serialization (in the browser, only when the + * value is needed), or `undefined` when not yet initialized. If you refer to other signals, `fn` + * will be called when those change just like computed signals, and then the argument will be the + * previous output, not the serialized result. + * + * This is useful when using third party libraries that use custom objects that are not + * serializable. + * + * Note that the `fn` is called lazily, so it won't impact container resume. + * + * @example + * + * ```tsx + * class MyCustomSerializable { + * constructor(public n: number) {} + * inc() { + * this.n++; + * } + * } + * const Cmp = component$(() => { + * const custom = useSerializer$({ + * deserialize: (data) => new MyCustomSerializable(data), + * serialize: (data) => data.n, + * initial: 2, + * }); + * return
        custom.value.inc()}>{custom.value.n}
        ; + * }); + * ``` + * + * @example + * + * When using a Signal as the data to create the object, you need to pass the configuration as a + * function, and you can then also provide the `update` function to update the object when the + * signal changes. + * + * By returning an object from `update`, you signal that the listeners have to be notified. You can + * mutate the current object but you should return it so that it will trigger listeners. + * + * ```tsx + * const Cmp = component$(() => { + * const n = useSignal(2); + * const custom = useSerializer$(() => + * ({ + * deserialize: () => new MyCustomSerializable(n.value), + * update: (current) => { + * current.n = n.value; + * return current; + * } + * }) + * ); + * return
        n.value++}>{custom.value.n}
        ; + * }); + * ``` + * + * @public + */ +export const useSerializer$: typeof createSerializer$ = implicit$FirstArg(useSerializerQrl as any); diff --git a/packages/qwik/src/core/use/use-signal.ts b/packages/qwik/src/core/use/use-signal.ts index 7fbd04fe7c1..78b2ad3d087 100644 --- a/packages/qwik/src/core/use/use-signal.ts +++ b/packages/qwik/src/core/use/use-signal.ts @@ -1,7 +1,7 @@ -import { isQwikComponent } from '../component/component.public'; -import { _createSignal, type Signal } from '../state/signal'; -import { isFunction } from '../util/types'; -import { invoke, useContainerState } from './use-core'; +import { isQwikComponent } from '../shared/component.public'; +import { isFunction } from '../shared/utils/types'; +import { createSignal, type Signal } from '../reactive-primitives/signal.public'; +import { invoke } from './use-core'; import { useSequentialScope } from './use-sequential-scope'; /** @public */ @@ -10,30 +10,23 @@ export interface UseSignal { (value: T | (() => T)): Signal; } -/** - * Creates a signal. - * - * If the initial state is a function, the function is invoked to calculate the actual initial - * state. - * - * @deprecated This is a technology preview - * @public - */ -export const createSignal: UseSignal = (initialState?: STATE): Signal => { - const containerState = useContainerState(); - const value = - isFunction(initialState) && !isQwikComponent(initialState) - ? invoke(undefined, initialState as any) - : initialState; - return _createSignal(value, containerState, 0) as Signal; +/** @public */ +export const useSignal: UseSignal = (initialState?: STATE): Signal => { + return useConstant(() => { + const value = + isFunction(initialState) && !isQwikComponent(initialState) + ? invoke(undefined, initialState as any) + : initialState; + return createSignal(value); + }); }; /** - * Stores a value which is retained for the lifetime of the component. + * Stores a value which is retained for the lifetime of the component. Subsequent calls to + * `useConstant` will always return the first value given. * - * If the value is a function, the function is invoked to calculate the actual value. + * If the value is a function, the function is invoked once to calculate the actual value. * - * @deprecated This is a technology preview * @public */ export const useConstant = (value: (() => T) | T): T => { @@ -45,12 +38,3 @@ export const useConstant = (value: (() => T) | T): T => { value = isFunction(value) && !isQwikComponent(value) ? value() : value; return set(value as T); }; - -/** - * Hook that creates a signal that is retained for the lifetime of the component. - * - * @public - */ -export const useSignal: UseSignal = (initialState?: any) => { - return useConstant(() => createSignal(initialState)); -}; diff --git a/packages/qwik/src/core/use/use-store.public.ts b/packages/qwik/src/core/use/use-store.public.ts index c2b937f59ae..62e5c0a3853 100644 --- a/packages/qwik/src/core/use/use-store.public.ts +++ b/packages/qwik/src/core/use/use-store.public.ts @@ -1,9 +1,11 @@ -import { QObjectRecursive } from '../state/constants'; -import { getOrCreateProxy } from '../state/store'; -import { isFunction } from '../util/types'; +import { isFunction } from '../shared/utils/types'; +import { getOrCreateStore } from '../reactive-primitives/impl/store'; +import { StoreFlags } from '../reactive-primitives/types'; import { invoke } from './use-core'; import { useSequentialScope } from './use-sequential-scope'; +export { unwrapStore } from '../reactive-primitives/impl/store'; + /** @public */ export interface UseStoreOptions { /** If `true` then all nested objects and arrays will be tracked as well. Default is `true`. */ @@ -15,7 +17,7 @@ export interface UseStoreOptions { // // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useStore instead) +// (edit ../readme.md#useStore instead and run `pnpm docs.sync`) /** * Creates an object that Qwik can track across serializations. * @@ -89,10 +91,10 @@ export const useStore = ( set(value); return value; } else { - const containerState = iCtx.$renderCtx$.$static$.$containerState$; + const containerState = iCtx.$container$; const recursive = opts?.deep ?? true; - const flags = recursive ? QObjectRecursive : 0; - const newStore = getOrCreateProxy(value, containerState, flags); + const flags = recursive ? StoreFlags.RECURSIVE : StoreFlags.NONE; + const newStore = getOrCreateStore(value, flags, containerState); set(newStore); return newStore; } diff --git a/packages/qwik/src/core/use/use-styles.ts b/packages/qwik/src/core/use/use-styles.ts index 831f6282036..c5d2483ea4e 100644 --- a/packages/qwik/src/core/use/use-styles.ts +++ b/packages/qwik/src/core/use/use-styles.ts @@ -1,48 +1,32 @@ -import { styleContent, styleKey } from '../style/qrl-styles'; -import type { QRL } from '../qrl/qrl.public'; -import { implicit$FirstArg } from '../util/implicit_dollar'; -import { getScopedStyles } from '../style/scoped-stylesheet'; +import { type QRL } from '../shared/qrl/qrl.public'; +import { implicit$FirstArg } from '../shared/qrl/implicit_dollar'; +import { getScopedStyles } from '../shared/utils/scoped-stylesheet'; import { useSequentialScope } from './use-sequential-scope'; -import { assertQrl } from '../qrl/qrl-class'; -import { isPromise } from '../util/promises'; -import { assertDefined } from '../error/assert'; -import { ComponentStylesPrefixContent } from '../util/markers'; +import { assertQrl } from '../shared/qrl/qrl-utils'; +import { isPromise } from '../shared/utils/promises'; +import { ComponentStylesPrefixContent } from '../shared/utils/markers'; +import { styleKey } from '../shared/utils/styles'; /** @public */ export interface UseStylesScoped { scopeId: string; } -// -// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useStyles instead) -/** - * A lazy-loadable reference to a component's styles. - * - * Component styles allow Qwik to lazy load the style information for the component only when - * needed. (And avoid double loading it in case of SSR hydration.) - * - * ```tsx - * import styles from './code-block.css?inline'; - * - * export const CmpStyles = component$(() => { - * useStyles$(styles); - * - * return
        Some text
        ; - * }); - * ``` - * - * @public - * @see `useStylesScoped` - */ -//
        -export const useStylesQrl = (styles: QRL): void => { - _useStyles(styles, (str) => str, false); +/** @public */ +export interface UseStyles { + styleId: string; +} + +/** @internal */ +export const useStylesQrl = (styles: QRL): UseStyles => { + return { + styleId: _useStyles(styles, (str) => str, false), + }; }; // // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useStyles instead) +// (edit ../readme.md#useStyles instead and run `pnpm docs.sync`) /** * A lazy-loadable reference to a component's styles. * @@ -65,29 +49,7 @@ export const useStylesQrl = (styles: QRL): void => { // export const useStyles$ = /*#__PURE__*/ implicit$FirstArg(useStylesQrl); -// -// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useStylesScoped instead) -/** - * A lazy-loadable reference to a component's styles, that is scoped to the component. - * - * Component styles allow Qwik to lazy load the style information for the component only when - * needed. (And avoid double loading it in case of SSR hydration.) - * - * ```tsx - * import scoped from './code-block.css?inline'; - * - * export const CmpScopedStyles = component$(() => { - * useStylesScoped$(scoped); - * - * return
        Some text
        ; - * }); - * ``` - * - * @public - * @see `useStyles` - */ -//
        +/** @internal */ export const useStylesScopedQrl = (styles: QRL): UseStylesScoped => { return { scopeId: ComponentStylesPrefixContent + _useStyles(styles, getScopedStyles, true), @@ -96,7 +58,7 @@ export const useStylesScopedQrl = (styles: QRL): UseStylesScoped => { // // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useStylesScoped instead) +// (edit ../readme.md#useStylesScoped instead and run `pnpm docs.sync`) /** * A lazy-loadable reference to a component's styles, that is scoped to the component. * @@ -126,39 +88,23 @@ const _useStyles = ( ): string => { assertQrl(styleQrl); - const { val, set, iCtx, i, elCtx } = useSequentialScope(); + const { val, set, iCtx, i } = useSequentialScope(); if (val) { return val; } const styleId = styleKey(styleQrl, i); - const containerState = iCtx.$renderCtx$.$static$.$containerState$; + const host = iCtx.$hostElement$; set(styleId); - if (!elCtx.$appendStyles$) { - elCtx.$appendStyles$ = []; - } - if (!elCtx.$scopeIds$) { - elCtx.$scopeIds$ = []; - } - if (scoped) { - elCtx.$scopeIds$.push(styleContent(styleId)); - } - if (containerState.$styleIds$.has(styleId)) { - return styleId; - } - containerState.$styleIds$.add(styleId); - const value = styleQrl.$resolveLazy$(containerState.$containerEl$); - const appendStyle = (styleText: string) => { - assertDefined(elCtx.$appendStyles$, 'appendStyles must be defined'); - elCtx.$appendStyles$.push({ - styleId, - content: transform(styleText, styleId), - }); - }; + const value = styleQrl.$resolveLazy$(iCtx.$element$); if (isPromise(value)) { - iCtx.$waitOn$.push(value.then(appendStyle)); + value.then((val) => + iCtx.$container$.$appendStyle$(transform(val, styleId), styleId, host, scoped) + ); + throw value; } else { - appendStyle(value); + iCtx.$container$.$appendStyle$(transform(value, styleId), styleId, host, scoped); } + return styleId; }; diff --git a/packages/qwik/src/core/use/use-task-dollar.ts b/packages/qwik/src/core/use/use-task-dollar.ts new file mode 100644 index 00000000000..e26ad32c3bb --- /dev/null +++ b/packages/qwik/src/core/use/use-task-dollar.ts @@ -0,0 +1,66 @@ +import { implicit$FirstArg } from '../shared/qrl/implicit_dollar'; +import { useTaskQrl, type TaskFn } from './use-task'; + +// +// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! +// (edit ../readme.md#useTask instead and run `pnpm docs.sync`) +/** + * Reruns the `taskFn` when the observed inputs change. + * + * Use `useTask` to observe changes on a set of inputs, and then re-execute the `taskFn` when those + * inputs change. + * + * 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. + * + * @param task - Function which should be re-executed when changes to the inputs are detected + * @public + * + * ### Example + * + * The `useTask` function is used to observe the `store.count` property. Any changes to the + * `store.count` cause the `taskFn` to execute which in turn updates the `store.doubleCount` to + * the double of `store.count`. + * + * ```tsx + * const Cmp = component$(() => { + * const store = useStore({ + * count: 0, + * doubleCount: 0, + * debounced: 0, + * }); + * + * // Double count task + * useTask$(({ track }) => { + * const count = track(() => store.count); + * store.doubleCount = 2 * count; + * }); + * + * // Debouncer task + * useTask$(({ track }) => { + * const doubleCount = track(() => store.doubleCount); + * const timer = setTimeout(() => { + * store.debounced = doubleCount; + * }, 2000); + * return () => { + * clearTimeout(timer); + * }; + * }); + * return ( + *
        + *
        + * {store.count} / {store.doubleCount} + *
        + *
        {store.debounced}
        + *
        + * ); + * }); + * ``` + * + * @public + * @see `Tracker` + */ +//
        +// We need to cast to help out the api extractor +export const useTask$ = /*#__PURE__*/ implicit$FirstArg(useTaskQrl) as (fn: TaskFn) => void; diff --git a/packages/qwik/src/core/use/use-task.ts b/packages/qwik/src/core/use/use-task.ts index 85eca6b64c9..626eae58948 100644 --- a/packages/qwik/src/core/use/use-task.ts +++ b/packages/qwik/src/core/use/use-task.ts @@ -1,51 +1,41 @@ -import { type ContainerState, intToStr, type MustGetObjID, strToInt } from '../container/container'; -import { assertDefined, assertEqual } from '../error/assert'; -import { codeToText, QError_trackUseStore } from '../error/error'; -import { isServerPlatform } from '../platform/platform'; -import { assertQrl, assertSignal, createQRL, type QRLInternal } from '../qrl/qrl-class'; -import type { QRL } from '../qrl/qrl.public'; -import { _hW, notifyTask } from '../render/dom/notify-render'; -import type { QwikElement } from '../render/dom/virtual-element'; -import { handleError } from '../render/error-handling'; -import type { RenderContext } from '../render/types'; -import { - getSubscriptionManager, - noSerialize, - type NoSerialize, - unwrapProxy, -} from '../state/common'; -import { QObjectManagerSymbol } from '../state/constants'; -import { getContext } from '../state/context'; -import { - _createSignal, - isSignal, - QObjectSignalFlags, - type ReadonlySignal, - type Signal, - SIGNAL_IMMUTABLE, - SIGNAL_UNASSIGNED, - type SignalInternal, -} from '../state/signal'; -import { implicit$FirstArg } from '../util/implicit_dollar'; -import { logError, logErrorAndStop, logOnceWarn } from '../util/log'; -import { ComputedEvent, TaskEvent } from '../util/markers'; -import { delay, isPromise, maybeThen, safeCall } from '../util/promises'; -import { isFunction, isObject, type ValueOrPromise } from '../util/types'; -import { invoke, newInvokeContext, untrack, useInvokeContext, waitAndRun } from './use-core'; -import { useOn, useOnDocument } from './use-on'; +import { getDomContainer } from '../client/dom-container'; +import { QError, qError } from '../shared/error/error'; +import { type QRLInternal } from '../shared/qrl/qrl-class'; +import { assertQrl } from '../shared/qrl/qrl-utils'; +import type { QRL } from '../shared/qrl/qrl.public'; +import { ChoreType } from '../shared/util-chore-type'; +import { type Container, type HostElement } from '../shared/types'; +import { logError } from '../shared/utils/log'; +import { TaskEvent } from '../shared/utils/markers'; +import { isPromise, safeCall } from '../shared/utils/promises'; +import { noSerialize, type NoSerialize } from '../shared/utils/serialize-utils'; +import { isFunction, type ValueOrPromise } from '../shared/utils/types'; +import { isSignal } from '../reactive-primitives/utils'; +import { BackRef, clearAllEffects } from '../reactive-primitives/cleanup'; +import { type Signal } from '../reactive-primitives/signal.public'; +import { invoke, newInvokeContext } from './use-core'; +import { useLexicalScope } from './use-lexical-scope.public'; +import type { ResourceReturnInternal } from './use-resource'; import { useSequentialScope } from './use-sequential-scope'; -import { useConstant } from './use-signal'; - -export const TaskFlagsIsVisibleTask = 1 << 0; -export const TaskFlagsIsTask = 1 << 1; -export const TaskFlagsIsResource = 1 << 2; -export const TaskFlagsIsComputed = 1 << 3; -export const TaskFlagsIsDirty = 1 << 4; -export const TaskFlagsIsCleanup = 1 << 5; +import { getSubscriber } from '../reactive-primitives/subscriber'; +import { + addStoreEffect, + getStoreHandler, + getStoreTarget, + isStore, +} from '../reactive-primitives/impl/store'; +import { EffectProperty, STORE_ALL_PROPS } from '../reactive-primitives/types'; + +export const enum TaskFlags { + VISIBLE_TASK = 1 << 0, + TASK = 1 << 1, + RESOURCE = 1 << 2, + DIRTY = 1 << 3, +} // // !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#Tracker instead) +// (edit ../readme.md#Tracker instead and run `pnpm docs.sync`) /** * Used to signal to Qwik which state should be watched for changes. * @@ -120,6 +110,18 @@ export interface Tracker { * ``` */ (obj: T): T extends Signal ? U : T; + + /** + * Used to track to track a specific property of an object. + * + * Note that the change tracking is not deep. If you want to track changes to nested properties, + * you need to use `track` on each of them. + * + * ```tsx + * track(store, 'propA'); // returns store.propA + * ``` + */ + (obj: T, prop: P): T[P]; } /** @public */ @@ -128,663 +130,126 @@ export interface TaskCtx { cleanup(callback: () => void): void; } -/** @public */ -export interface ResourceCtx { - readonly track: Tracker; - cleanup(callback: () => void): void; - cache(policyOrMilliseconds: number | 'immutable'): void; - readonly previous: T | undefined; -} - /** @public */ export type TaskFn = (ctx: TaskCtx) => ValueOrPromise void)>; /** @public */ -export type ComputedFn = () => T; - -/** @public */ -export type ResourceFn = (ctx: ResourceCtx) => ValueOrPromise; - -/** @public */ -export type ResourceReturn = ResourcePending | ResourceResolved | ResourceRejected; - -/** @public */ -export interface ResourcePending { - readonly value: Promise; - readonly loading: boolean; -} - -/** @public */ -export interface ResourceResolved { - readonly value: Promise; - readonly loading: boolean; -} - -/** @public */ -export interface ResourceRejected { - readonly value: Promise; - readonly loading: boolean; -} - -export interface ResourceReturnInternal { - __brand: 'resource'; - _state: 'pending' | 'resolved' | 'rejected'; - _resolved: T | undefined; - _error: Error | undefined; - _cache: number; - _timeout: number; - value: Promise; - loading: boolean; -} -/** @public */ -export interface DescriptorBase { - $qrl$: QRLInternal; - $el$: QwikElement; +export interface DescriptorBase extends BackRef { $flags$: number; $index$: number; - $destroy$?: NoSerialize<() => void>; + $el$: HostElement; + $qrl$: QRLInternal; $state$: B | undefined; + $destroy$: NoSerialize<() => void> | null; } -/** @public @deprecated use useVisibleTask$ or useResource$, useTask$ is for running tasks as part of the initial SSR render */ -export type EagernessOptions = 'visible' | 'load' | 'idle'; - -/** @public */ -export type VisibleTaskStrategy = 'intersection-observer' | 'document-ready' | 'document-idle'; - -/** @public */ -export interface OnVisibleTaskOptions { - /** - * The strategy to use to determine when the "VisibleTask" should first execute. - * - * - `intersection-observer`: the task will first execute when the element is visible in the - * viewport, under the hood it uses the IntersectionObserver API. - * - `document-ready`: the task will first execute when the document is ready, under the hood it - * uses the document `load` event. - * - `document-idle`: the task will first execute when the document is idle, under the hood it uses - * the requestIdleCallback API. - */ - strategy?: VisibleTaskStrategy; -} - -/** @public @deprecated use useVisibleTask$ or useResource$, useTask$ is for running tasks as part of the initial SSR render */ -export interface UseTaskOptions { - /** - * - `visible`: run the effect when the element is visible. - * - `load`: eagerly run the effect when the application resumes. - */ - eagerness?: EagernessOptions; -} - -// -// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useTask instead) -/** - * Reruns the `taskFn` when the observed inputs change. - * - * Use `useTask` to observe changes on a set of inputs, and then re-execute the `taskFn` when those - * inputs change. - * - * 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. - * - * @param task - Function which should be re-executed when changes to the inputs are detected - * @public - * - * ### Example - * - * The `useTask` function is used to observe the `store.count` property. Any changes to the - * `store.count` cause the `taskFn` to execute which in turn updates the `store.doubleCount` to - * the double of `store.count`. - * - * ```tsx - * const Cmp = component$(() => { - * const store = useStore({ - * count: 0, - * doubleCount: 0, - * debounced: 0, - * }); - * - * // Double count task - * useTask$(({ track }) => { - * const count = track(() => store.count); - * store.doubleCount = 2 * count; - * }); - * - * // Debouncer task - * useTask$(({ track }) => { - * const doubleCount = track(() => store.doubleCount); - * const timer = setTimeout(() => { - * store.debounced = doubleCount; - * }, 2000); - * return () => { - * clearTimeout(timer); - * }; - * }); - * return ( - *
        - *
        - * {store.count} / {store.doubleCount} - *
        - *
        {store.debounced}
        - *
        - * ); - * }); - * ``` - * - * @public - * @see `Tracker` - */ -//
        -export const useTaskQrl = (qrl: QRL, opts?: UseTaskOptions): void => { - const { val, set, iCtx, i, elCtx } = useSequentialScope(); +/** @internal */ +export const useTaskQrl = (qrl: QRL): void => { + const { val, set, iCtx, i } = useSequentialScope<1 | Task>(); if (val) { return; } assertQrl(qrl); - - const containerState = iCtx.$renderCtx$.$static$.$containerState$; - const task = new Task(TaskFlagsIsDirty | TaskFlagsIsTask, i, elCtx.$element$, qrl, undefined); - set(true); - qrl.$resolveLazy$(containerState.$containerEl$); - if (!elCtx.$tasks$) { - elCtx.$tasks$ = []; - } - elCtx.$tasks$.push(task); - waitAndRun(iCtx, () => runTask(task, containerState, iCtx.$renderCtx$)); - if (isServerPlatform()) { - useRunTask(task, opts?.eagerness); - } -}; - -/** @public */ -export const createComputedQrl = (qrl: QRL>): Signal> => { - assertQrl(qrl); - const iCtx = useInvokeContext(); - const hostElement = iCtx.$hostElement$; - const containerState = iCtx.$renderCtx$.$static$.$containerState$; - const elCtx = getContext(hostElement, containerState); - const signal = _createSignal( - undefined as Awaited, - containerState, - SIGNAL_UNASSIGNED | SIGNAL_IMMUTABLE, - undefined - ); + set(1); const task = new Task( - TaskFlagsIsDirty | TaskFlagsIsTask | TaskFlagsIsComputed, - // Computed signals should update immediately - 0, - elCtx.$element$, + TaskFlags.DIRTY | TaskFlags.TASK, + i, + iCtx.$hostElement$, qrl, - signal + undefined, + null ); - qrl.$resolveLazy$(containerState.$containerEl$); - (elCtx.$tasks$ ||= []).push(task); - - waitAndRun(iCtx, () => runComputed(task, containerState, iCtx.$renderCtx$)); - return signal as ReadonlySignal>; -}; -/** @public */ -export const useComputedQrl = (qrl: QRL>): Signal> => { - return useConstant(() => createComputedQrl(qrl)); -}; - -/** - * Returns a computed signal which is calculated from the given function. A computed signal is a - * signal which is calculated from other signals. When the signals change, the computed signal is - * recalculated, and if the result changed, all tasks which are tracking the signal will be re-run - * and all components that read the signal will be re-rendered. - * - * The function must be synchronous and must not have any side effects. - * - * Async functions are deprecated because: - * - * - When calculating the first time, it will see it's a promise and it will restart the render - * function. - * - Qwik can't track used signals after the first await, which leads to subtle bugs. - * - Both `useTask$` and `useResource$` are available, without these problems. - * - * In v2, async functions won't work. - * - * @public - */ -export const useComputed$ = implicit$FirstArg(useComputedQrl); -/** - * Returns read-only signal that updates when signals used in the `ComputedFn` change. Unlike - * useComputed$, this is not a hook and it always creates a new signal. - * - * @deprecated This is a technology preview - * @public - */ -export const createComputed$ = implicit$FirstArg(createComputedQrl); - -// -// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useTask instead) -/** - * Reruns the `taskFn` when the observed inputs change. - * - * Use `useTask` to observe changes on a set of inputs, and then re-execute the `taskFn` when those - * inputs change. - * - * 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. - * - * @param task - Function which should be re-executed when changes to the inputs are detected - * @public - * - * ### Example - * - * The `useTask` function is used to observe the `store.count` property. Any changes to the - * `store.count` cause the `taskFn` to execute which in turn updates the `store.doubleCount` to - * the double of `store.count`. - * - * ```tsx - * const Cmp = component$(() => { - * const store = useStore({ - * count: 0, - * doubleCount: 0, - * debounced: 0, - * }); - * - * // Double count task - * useTask$(({ track }) => { - * const count = track(() => store.count); - * store.doubleCount = 2 * count; - * }); - * - * // Debouncer task - * useTask$(({ track }) => { - * const doubleCount = track(() => store.doubleCount); - * const timer = setTimeout(() => { - * store.debounced = doubleCount; - * }, 2000); - * return () => { - * clearTimeout(timer); - * }; - * }); - * return ( - *
        - *
        - * {store.count} / {store.doubleCount} - *
        - *
        {store.debounced}
        - *
        - * ); - * }); - * ``` - * - * @public - * @see `Tracker` - */ -//
        -export const useTask$ = /*#__PURE__*/ implicit$FirstArg(useTaskQrl); - -// -// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useVisibleTask instead) -/** - * ```tsx - * const Timer = component$(() => { - * const store = useStore({ - * count: 0, - * }); - * - * useVisibleTask$(() => { - * // Only runs in the client - * const timer = setInterval(() => { - * store.count++; - * }, 500); - * return () => { - * clearInterval(timer); - * }; - * }); - * - * return
        {store.count}
        ; - * }); - * ``` - * - * @public - */ -//
        -export const useVisibleTaskQrl = (qrl: QRL, opts?: OnVisibleTaskOptions): void => { - const { val, set, i, iCtx, elCtx } = useSequentialScope>(); - const eagerness = opts?.strategy ?? 'intersection-observer'; - if (val) { - if (isServerPlatform()) { - useRunTask(val, eagerness); - } - return; - } - assertQrl(qrl); - const task = new Task(TaskFlagsIsVisibleTask, i, elCtx.$element$, qrl, undefined); - const containerState = iCtx.$renderCtx$.$static$.$containerState$; - if (!elCtx.$tasks$) { - elCtx.$tasks$ = []; - } - elCtx.$tasks$.push(task); + // In V2 we add the task to the sequential scope. We need to do this + // in order to be able to retrieve it later when the parent element is + // deleted and we need to be able to release the task subscriptions. set(task); - useRunTask(task, eagerness); - if (!isServerPlatform()) { - qrl.$resolveLazy$(containerState.$containerEl$); - notifyTask(task, containerState); - } -}; - -// -// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#useVisibleTask instead) -/** - * ```tsx - * const Timer = component$(() => { - * const store = useStore({ - * count: 0, - * }); - * - * useVisibleTask$(() => { - * // Only runs in the client - * const timer = setInterval(() => { - * store.count++; - * }, 500); - * return () => { - * clearInterval(timer); - * }; - * }); - * - * return
        {store.count}
        ; - * }); - * ``` - * - * @public - */ -//
        -export const useVisibleTask$ = /*#__PURE__*/ implicit$FirstArg(useVisibleTaskQrl); - -export type TaskDescriptor = DescriptorBase; - -export interface ResourceDescriptor - extends DescriptorBase, ResourceReturnInternal> {} - -export interface ComputedDescriptor extends DescriptorBase, Signal> {} - -export type SubscriberHost = QwikElement; - -export type SubscriberEffect = - | TaskDescriptor - | ResourceDescriptor - | ComputedDescriptor; - -export const isResourceTask = (task: SubscriberEffect): task is ResourceDescriptor => { - return (task.$flags$ & TaskFlagsIsResource) !== 0; -}; - -export const isComputedTask = (task: SubscriberEffect): task is ComputedDescriptor => { - return (task.$flags$ & TaskFlagsIsComputed) !== 0; -}; -export const runSubscriber = async ( - task: SubscriberEffect, - containerState: ContainerState, - rCtx: RenderContext -) => { - assertEqual(!!(task.$flags$ & TaskFlagsIsDirty), true, 'Resource is not dirty', task); - if (isResourceTask(task)) { - return runResource(task, containerState, rCtx); - } else if (isComputedTask(task)) { - return runComputed(task, containerState, rCtx); - } else { - return runTask(task, containerState, rCtx); + const container = iCtx.$container$; + const promise = container.$scheduler$(ChoreType.TASK, task); + if (isPromise(promise)) { + // TODO: should we handle this differently? + promise.catch(() => {}); } }; -export const runResource = ( - task: ResourceDescriptor, - containerState: ContainerState, - rCtx: RenderContext, - waitOn?: Promise +export const runTask = ( + task: Task, + container: Container, + host: HostElement ): ValueOrPromise => { - task.$flags$ &= ~TaskFlagsIsDirty; + task.$flags$ &= ~TaskFlags.DIRTY; cleanupTask(task); - - const el = task.$el$; - const iCtx = newInvokeContext(rCtx.$static$.$locale$, el, undefined, TaskEvent); - const { $subsManager$: subsManager } = containerState; - iCtx.$renderCtx$ = rCtx; - const taskFn = task.$qrl$.getFn(iCtx, () => { - subsManager.$clearSub$(task); - }); - - const cleanups: (() => void)[] = []; - const resource = task.$state$; - assertDefined( - resource, - 'useResource: when running a resource, "task.r" must be a defined.', - task - ); - - const track: Tracker = (obj: (() => unknown) | object | Signal, prop?: string) => { - if (isFunction(obj)) { - const ctx = newInvokeContext(); - ctx.$renderCtx$ = rCtx; - ctx.$subscriber$ = [0, task]; - return invoke(ctx, obj); - } - const manager = getSubscriptionManager(obj); - if (manager) { - manager.$addSub$([0, task], prop); - } else { - logErrorAndStop(codeToText(QError_trackUseStore), obj); - } - if (prop) { - return (obj as Record)[prop]; - } else if (isSignal(obj)) { - return obj.value; - } else { - return obj; - } - }; - const resourceTarget = unwrapProxy(resource); - const opts: ResourceCtx = { - track, - cleanup(callback) { - cleanups.push(callback); - }, - cache(policy) { - let milliseconds = 0; - if (policy === 'immutable') { - milliseconds = Infinity; - } else { - milliseconds = policy; + const iCtx = newInvokeContext(container.$locale$, host, undefined, TaskEvent); + iCtx.$container$ = container; + const taskFn = task.$qrl$.getFn(iCtx, () => clearAllEffects(container, task)) as TaskFn; + + const track: Tracker = (obj: (() => unknown) | object | Signal, prop?: string) => { + const ctx = newInvokeContext(); + ctx.$effectSubscriber$ = getSubscriber(task, EffectProperty.COMPONENT); + ctx.$container$ = container; + return invoke(ctx, () => { + if (isFunction(obj)) { + return obj(); } - resource._cache = milliseconds; - }, - previous: resourceTarget._resolved, - }; - - let resolve: (v: T) => void; - let reject: (v: unknown) => void; - let done = false; - - const setState = (resolved: boolean, value: T | Error) => { - if (!done) { - done = true; - if (resolved) { - done = true; - resource.loading = false; - resource._state = 'resolved'; - resource._resolved = value as T; - resource._error = undefined; - - resolve(value as T); + if (prop) { + return (obj as Record)[prop]; + } else if (isSignal(obj)) { + return obj.value; + } else if (isStore(obj)) { + // track whole store + addStoreEffect( + getStoreTarget(obj)!, + STORE_ALL_PROPS, + getStoreHandler(obj)!, + ctx.$effectSubscriber$! + ); + return obj; } else { - done = true; - resource.loading = false; - resource._state = 'rejected'; - resource._error = value as Error; - reject(value as Error); + throw qError(QError.trackObjectWithoutProp); } - return true; - } - return false; - }; - - // Execute mutation inside empty invocation - invoke(iCtx, () => { - resource._state = 'pending'; - resource.loading = !isServerPlatform(); - resource.value = new Promise((r, re) => { - resolve = r; - reject = re; }); - }); - - task.$destroy$ = noSerialize(() => { - done = true; - cleanups.forEach((fn) => fn()); - }); - - const promise = safeCall( - () => maybeThen(waitOn, () => taskFn(opts)), - (value) => { - setState(true, value); - }, - (reason) => { - setState(false, reason); - } - ); - - const timeout = resourceTarget._timeout; - if (timeout > 0) { - return Promise.race([ - promise, - delay(timeout).then(() => { - if (setState(false, new Error('timeout'))) { - cleanupTask(task); - } - }), - ]); - } - return promise; -}; - -export const runTask = ( - task: TaskDescriptor | ComputedDescriptor, - containerState: ContainerState, - rCtx: RenderContext -): ValueOrPromise => { - task.$flags$ &= ~TaskFlagsIsDirty; - - cleanupTask(task); - const hostElement = task.$el$; - const iCtx = newInvokeContext(rCtx.$static$.$locale$, hostElement, undefined, TaskEvent); - iCtx.$renderCtx$ = rCtx; - const { $subsManager$: subsManager } = containerState; - const taskFn = task.$qrl$.getFn(iCtx, () => { - subsManager.$clearSub$(task); - }) as TaskFn; - const track: Tracker = (obj: (() => unknown) | object | Signal, prop?: string) => { - if (isFunction(obj)) { - const ctx = newInvokeContext(); - ctx.$subscriber$ = [0, task]; - return invoke(ctx, obj); - } - const manager = getSubscriptionManager(obj); - if (manager) { - manager.$addSub$([0, task], prop); - } else { - logErrorAndStop(codeToText(QError_trackUseStore), obj); - } - if (prop) { - return (obj as Record)[prop]; - } else if (isSignal(obj)) { - return obj.value; - } else { - return obj; - } - }; - const cleanups: (() => void)[] = []; - task.$destroy$ = noSerialize(() => { - cleanups.forEach((fn) => fn()); - }); - - const opts: TaskCtx = { - track, - cleanup(callback) { - cleanups.push(callback); - }, }; - return safeCall( - () => taskFn(opts), - (returnValue) => { - if (isFunction(returnValue)) { - cleanups.push(returnValue); + const handleError = (reason: unknown) => container.handleError(reason, host); + let cleanupFns: (() => void)[] | null = null; + const cleanup = (fn: () => void) => { + if (typeof fn == 'function') { + if (!cleanupFns) { + cleanupFns = []; + task.$destroy$ = noSerialize(() => { + task.$destroy$ = null; + cleanupFns!.forEach((fn) => { + try { + fn(); + } catch (err) { + handleError(err); + } + }); + }); } - }, - (reason) => { - handleError(reason, hostElement, rCtx); + cleanupFns.push(fn); } - ); -}; - -export const runComputed = ( - task: ComputedDescriptor, - containerState: ContainerState, - rCtx: RenderContext -): ValueOrPromise => { - assertSignal(task.$state$); - task.$flags$ &= ~TaskFlagsIsDirty; - cleanupTask(task); - const hostElement = task.$el$; - const iCtx = newInvokeContext(rCtx.$static$.$locale$, hostElement, undefined, ComputedEvent); - iCtx.$subscriber$ = [0, task]; - iCtx.$renderCtx$ = rCtx; - - const { $subsManager$: subsManager } = containerState; - const taskFn = task.$qrl$.getFn(iCtx, () => { - subsManager.$clearSub$(task); - }) as ComputedFn; - - const ok = (returnValue: any) => { - untrack(() => { - const signal = task.$state$! as SignalInternal; - signal[QObjectSignalFlags] &= ~SIGNAL_UNASSIGNED; - signal.untrackedValue = returnValue; - signal[QObjectManagerSymbol].$notifySubs$(); - }); }; - const fail = (reason: unknown) => { - handleError(reason, hostElement, rCtx); - }; - try { - return maybeThen(task.$qrl$.$resolveLazy$(containerState.$containerEl$), () => { - const result = taskFn(); - if (isPromise(result)) { - const warningMessage = - 'useComputed$: Async functions in computed tasks are deprecated and will stop working in v2. Use useTask$ or useResource$ instead.'; - const stack = new Error(warningMessage).stack; - if (!stack) { - logOnceWarn(warningMessage); - } else { - const lessScaryStack = stack.replace(/^Error:\s*/, ''); - logOnceWarn(lessScaryStack); - } - return result.then(ok, fail); + const taskApi: TaskCtx = { track, cleanup }; + const result: ValueOrPromise = safeCall( + () => taskFn(taskApi), + cleanup, + (err: unknown) => { + // If a Promise is thrown, that means we need to re-run the task. + if (isPromise(err)) { + return err.then(() => runTask(task, container, host)); } else { - ok(result); + throw err; } - }); - } catch (reason) { - fail(reason); - } + } + ); + return result; }; -export const cleanupTask = (task: SubscriberEffect) => { +export const cleanupTask = (task: Task) => { const destroy = task.$destroy$; if (destroy) { - task.$destroy$ = undefined; + task.$destroy$ = null; try { destroy(); } catch (err) { @@ -793,76 +258,34 @@ export const cleanupTask = (task: SubscriberEffect) => { } }; -export const destroyTask = (task: SubscriberEffect) => { - if (task.$flags$ & TaskFlagsIsCleanup) { - task.$flags$ &= ~TaskFlagsIsCleanup; - const cleanup = task.$qrl$; - (cleanup as Function)(); - } else { - cleanupTask(task); - } -}; - -const useRunTask = ( - task: SubscriberEffect, - eagerness: VisibleTaskStrategy | EagernessOptions | undefined -) => { - if (eagerness === 'visible' || eagerness === 'intersection-observer') { - useOn('qvisible', getTaskHandlerQrl(task)); - } else if (eagerness === 'load' || eagerness === 'document-ready') { - useOnDocument('qinit', getTaskHandlerQrl(task)); - } else if (eagerness === 'idle' || eagerness === 'document-idle') { - useOnDocument('qidle', getTaskHandlerQrl(task)); - } -}; - -const getTaskHandlerQrl = (task: SubscriberEffect): QRL<(ev: Event) => void> => { - const taskQrl = task.$qrl$; - const taskHandler = createQRL<(ev: Event) => void>( - taskQrl.$chunk$, - '_hW', - _hW, - null, - null, - [task], - taskQrl.$symbol$ - ); - // Needed for chunk lookup in dev mode - if (taskQrl.dev) { - taskHandler.dev = taskQrl.dev; - } - return taskHandler; -}; - -export const isTaskCleanup = (obj: unknown): obj is TaskDescriptor => { - return isSubscriberDescriptor(obj) && !!(obj.$flags$ & TaskFlagsIsCleanup); -}; - -export const isSubscriberDescriptor = (obj: unknown): obj is SubscriberEffect => { - return isObject(obj) && obj instanceof Task; -}; - -export const serializeTask = (task: SubscriberEffect, getObjId: MustGetObjID) => { - let value = `${intToStr(task.$flags$)} ${intToStr(task.$index$)} ${getObjId( - task.$qrl$ - )} ${getObjId(task.$el$)}`; - if (task.$state$) { - value += ` ${getObjId(task.$state$)}`; - } - return value; -}; - -export const parseTask = (data: string) => { - const [flags, index, qrl, el, resource] = data.split(' '); - return new Task(strToInt(flags), strToInt(index), el as any, qrl as any, resource as any); -}; - -export class Task implements DescriptorBase> { +export class Task + extends BackRef + implements DescriptorBase | ResourceReturnInternal> +{ constructor( public $flags$: number, public $index$: number, - public $el$: QwikElement, + public $el$: HostElement, public $qrl$: QRLInternal, - public $state$: Signal | undefined - ) {} + public $state$: Signal | ResourceReturnInternal | undefined, + public $destroy$: NoSerialize<() => void> | null + ) { + super(); + } } + +export const isTask = (value: any): value is Task => { + return value instanceof Task; +}; + +/** + * Used internally as a qrl event handler to schedule a task. + * + * @internal + */ +export const scheduleTask = (_event: Event, element: Element) => { + const [task] = useLexicalScope<[Task]>(); + const type = task.$flags$ & TaskFlags.VISIBLE_TASK ? ChoreType.VISIBLE : ChoreType.TASK; + const container = getDomContainer(element); + container.$scheduler$(type, task); +}; diff --git a/packages/qwik/src/core/use/use-task.unit.ts b/packages/qwik/src/core/use/use-task.unit.ts index 6074c2c7370..318eab5613a 100644 --- a/packages/qwik/src/core/use/use-task.unit.ts +++ b/packages/qwik/src/core/use/use-task.unit.ts @@ -1,9 +1,9 @@ import { describe, expectTypeOf, test } from 'vitest'; -import { component$ } from '../component/component.public'; -import { useResource$ } from './use-resource'; +import { component$ } from '../shared/component.public'; import { useSignal } from './use-signal'; import { useStore } from './use-store.public'; -import { useTask$ } from './use-task'; +import { useTask$ } from './use-task-dollar'; +import { useResource$ } from './use-resource-dollar'; describe('types', () => { test('track', () => () => { diff --git a/packages/qwik/src/core/use/use-visible-task-dollar.ts b/packages/qwik/src/core/use/use-visible-task-dollar.ts new file mode 100644 index 00000000000..6f40b84334f --- /dev/null +++ b/packages/qwik/src/core/use/use-visible-task-dollar.ts @@ -0,0 +1,36 @@ +import { implicit$FirstArg } from '../shared/qrl/implicit_dollar'; +import type { TaskFn } from './use-task'; +import { useVisibleTaskQrl, type OnVisibleTaskOptions } from './use-visible-task'; + +// +// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! +// (edit ../readme.md#useVisibleTask instead and run `pnpm docs.sync`) +/** + * ```tsx + * const Timer = component$(() => { + * const store = useStore({ + * count: 0, + * }); + * + * useVisibleTask$(() => { + * // Only runs in the client + * const timer = setInterval(() => { + * store.count++; + * }, 500); + * return () => { + * clearInterval(timer); + * }; + * }); + * + * return
        {store.count}
        ; + * }); + * ``` + * + * @public + */ +//
        +// We need to cast to help out the api extractor +export const useVisibleTask$ = /*#__PURE__*/ implicit$FirstArg(useVisibleTaskQrl) as ( + fn: TaskFn, + opts?: OnVisibleTaskOptions +) => void; diff --git a/packages/qwik/src/core/use/use-visible-task.ts b/packages/qwik/src/core/use/use-visible-task.ts new file mode 100644 index 00000000000..dd3c953e80d --- /dev/null +++ b/packages/qwik/src/core/use/use-visible-task.ts @@ -0,0 +1,63 @@ +import type { EventHandler } from '../shared/jsx/types/jsx-qwik-attributes'; +import { isServerPlatform } from '../shared/platform/platform'; +import { createQRL } from '../shared/qrl/qrl-class'; +import { assertQrl } from '../shared/qrl/qrl-utils'; +import type { QRL } from '../shared/qrl/qrl.public'; +import { ChoreType } from '../shared/util-chore-type'; +import { useOn, useOnDocument } from './use-on'; +import { useSequentialScope } from './use-sequential-scope'; +import { Task, TaskFlags, scheduleTask, type TaskFn } from './use-task'; + +/** @public */ +export type VisibleTaskStrategy = 'intersection-observer' | 'document-ready' | 'document-idle'; + +/** @public */ +export interface OnVisibleTaskOptions { + /** + * The strategy to use to determine when the "VisibleTask" should first execute. + * + * - `intersection-observer`: the task will first execute when the element is visible in the + * viewport, under the hood it uses the IntersectionObserver API. + * - `document-ready`: the task will first execute when the document is ready, under the hood it + * uses the document `load` event. + * - `document-idle`: the task will first execute when the document is idle, under the hood it uses + * the requestIdleCallback API. + */ + strategy?: VisibleTaskStrategy; +} + +/** @internal */ +export const useVisibleTaskQrl = (qrl: QRL, opts?: OnVisibleTaskOptions): void => { + const { val, set, i, iCtx } = useSequentialScope>(); + const eagerness = opts?.strategy ?? 'intersection-observer'; + if (val) { + if (isServerPlatform()) { + useRunTask(val, eagerness); + } + return; + } + assertQrl(qrl); + + const task = new Task(TaskFlags.VISIBLE_TASK, i, iCtx.$hostElement$, qrl, undefined, null); + set(task); + useRunTask(task, eagerness); + if (!isServerPlatform()) { + qrl.$resolveLazy$(iCtx.$element$); + iCtx.$container$.$scheduler$(ChoreType.VISIBLE, task); + } +}; + +export const useRunTask = (task: Task, eagerness: VisibleTaskStrategy | undefined) => { + if (eagerness === 'intersection-observer') { + useOn('qvisible', getTaskHandlerQrl(task)); + } else if (eagerness === 'document-ready') { + useOnDocument('qinit', getTaskHandlerQrl(task)); + } else if (eagerness === 'document-idle') { + useOnDocument('qidle', getTaskHandlerQrl(task)); + } +}; + +const getTaskHandlerQrl = (task: Task): QRL => { + const taskHandler = createQRL(null, '_task', scheduleTask, null, null, [task]); + return taskHandler; +}; diff --git a/packages/qwik/src/core/util/case.ts b/packages/qwik/src/core/util/case.ts deleted file mode 100644 index a9dc7bc4c1f..00000000000 --- a/packages/qwik/src/core/util/case.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const fromCamelToKebabCase = (text: string): string => { - return text.replace(/([A-Z])/g, '-$1').toLowerCase(); -}; - -export const fromKebabToCamelCase = (text: string): string => { - return text.replace(/-./g, (x) => x[1].toUpperCase()); -}; diff --git a/packages/qwik/src/core/util/case.unit.ts b/packages/qwik/src/core/util/case.unit.ts deleted file mode 100644 index 06064e493b2..00000000000 --- a/packages/qwik/src/core/util/case.unit.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { assert, test } from 'vitest'; -import { fromCamelToKebabCase } from './case'; - -test('should convert to kebab', () => { - assert.equal(fromCamelToKebabCase('HelloWorld'), '-hello-world'); - assert.equal(fromCamelToKebabCase('on:ClicK'), 'on:-clic-k'); - assert.equal(fromCamelToKebabCase('a:b'), 'a:b'); -}); diff --git a/packages/qwik/src/core/util/dom.ts b/packages/qwik/src/core/util/dom.ts deleted file mode 100644 index 7a2572fab75..00000000000 --- a/packages/qwik/src/core/util/dom.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { assertDefined } from '../error/assert'; -import type { QwikElement } from '../render/dom/virtual-element'; -import { qDynamicPlatform } from './qdev'; - -export const getDocument = (node: QwikElement | Document): Document => { - if (!qDynamicPlatform) { - return document; - } - if (typeof document !== 'undefined') { - return document; - } - if (node.nodeType === 9) { - return node as any as Document; - } - const doc = node.ownerDocument; - assertDefined(doc, 'doc must be defined'); - return doc!; -}; diff --git a/packages/qwik/src/core/util/element.ts b/packages/qwik/src/core/util/element.ts deleted file mode 100644 index 249e3022e86..00000000000 --- a/packages/qwik/src/core/util/element.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { QwikElement, VirtualElement } from '../render/dom/virtual-element'; - -export const isNode = (value: any): value is Node => { - return value && typeof value.nodeType === 'number'; -}; - -export const isDocument = (value: Node): value is Document => { - return (value as any).nodeType === 9; -}; - -export const isElement = (value: object): value is Element => { - return (value as any).nodeType === 1; -}; - -export const isQwikElement = (value: object): value is QwikElement => { - const nodeType = (value as any).nodeType; - return nodeType === 1 || nodeType === 111; -}; - -export const isNodeElement = (value: object): value is QwikElement => { - const nodeType = (value as any).nodeType; - return nodeType === 1 || nodeType === 111 || nodeType === 3; -}; - -export const isVirtualElement = (value: object): value is VirtualElement => { - return (value as any).nodeType === 111; -}; - -export const isVirtualElementOpenComment = (value: Node | VirtualElement): value is Comment => { - return isComment(value) && value.data.startsWith('qv '); -}; - -export const isText = (value: Node | QwikElement): value is Text => { - return (value as any).nodeType === 3; -}; - -export const isComment = (value: Node | QwikElement): value is Comment => { - return (value as any).nodeType === 8; -}; diff --git a/packages/qwik/src/core/util/event.ts b/packages/qwik/src/core/util/event.ts deleted file mode 100644 index 41fed117c6a..00000000000 --- a/packages/qwik/src/core/util/event.ts +++ /dev/null @@ -1,22 +0,0 @@ -// keep this import from qwik/build so the cjs build works -import { isBrowser } from '@builder.io/qwik/build'; -import { qTest } from './qdev'; - -export const emitEvent = ( - el: Element | undefined, - eventName: string, - detail: any, - bubbles: boolean -) => { - if (!qTest && (isBrowser || typeof CustomEvent === 'function')) { - if (el) { - el.dispatchEvent( - new CustomEvent(eventName, { - detail, - bubbles: bubbles, - composed: bubbles, - }) - ); - } - } -}; diff --git a/packages/qwik/src/core/util/flyweight.ts b/packages/qwik/src/core/util/flyweight.ts deleted file mode 100644 index 9db46411033..00000000000 --- a/packages/qwik/src/core/util/flyweight.ts +++ /dev/null @@ -1,11 +0,0 @@ -// import { qDev } from './qdev'; - -import { qDev } from './qdev'; - -export const EMPTY_ARRAY = [] as any[]; -export const EMPTY_OBJ = {} as Record; - -if (qDev) { - Object.freeze(EMPTY_ARRAY); - Object.freeze(EMPTY_OBJ); -} diff --git a/packages/qwik/src/core/util/log.ts b/packages/qwik/src/core/util/log.ts deleted file mode 100644 index 8ec0ad6d5b6..00000000000 --- a/packages/qwik/src/core/util/log.ts +++ /dev/null @@ -1,99 +0,0 @@ -import type { QwikElement } from '../render/dom/virtual-element'; -import type { QContext } from '../state/context'; -import { isElement, isNode } from './element'; -import { qDev, qTest } from './qdev'; - -const STYLE = qDev - ? `background: #564CE0; color: white; padding: 2px 3px; border-radius: 2px; font-size: 0.8em;` - : ''; - -export const logError = (message?: any, ...optionalParams: any[]) => { - return createAndLogError(false, message, ...optionalParams); -}; - -export const throwErrorAndStop = (message?: any, ...optionalParams: any[]): never => { - const error = createAndLogError(false, message, ...optionalParams); - // eslint-disable-next-line no-debugger - debugger; - throw error; -}; - -export const logErrorAndStop = (message?: any, ...optionalParams: any[]) => { - const err = createAndLogError(qDev, message, ...optionalParams); - // eslint-disable-next-line no-debugger - debugger; - return err; -}; - -const _printed = /*#__PURE__*/ new Set(); - -export const logOnceWarn = (message?: any, ...optionalParams: any[]) => { - if (qDev) { - const key = 'warn' + String(message); - if (!_printed.has(key)) { - _printed.add(key); - logWarn(message, ...optionalParams); - } - } -}; - -export const logWarn = (message?: any, ...optionalParams: any[]) => { - if (qDev) { - console.warn('%cQWIK WARN', STYLE, message, ...printParams(optionalParams)); - } -}; - -export const logDebug = (message?: string, ...optionalParams: any[]) => { - if (qDev) { - // eslint-disable-next-line no-console - console.debug('%cQWIK', STYLE, message, ...printParams(optionalParams)); - } -}; - -export const tryGetContext = (element: QwikElement): QContext | undefined => { - return (element as any)['_qc_']; -}; - -const printParams = (optionalParams: any[]) => { - if (qDev) { - return optionalParams.map((p) => { - if (isNode(p) && isElement(p)) { - return printElement(p); - } - return p; - }); - } - return optionalParams; -}; - -const printElement = (el: Element) => { - const ctx = tryGetContext(el); - const isServer: boolean = /*#__PURE__*/ (() => - typeof process !== 'undefined' && !!process.versions && !!process.versions.node)(); - - return { - tagName: el.tagName, - renderQRL: ctx?.$componentQrl$?.getSymbol(), - element: isServer ? undefined : el, - ctx: isServer ? undefined : ctx, - }; -}; - -const createAndLogError = (asyncThrow: boolean, message?: any, ...optionalParams: any[]) => { - const err = message instanceof Error ? message : new Error(message); - - // display the error message first, then the optional params, and finally the stack trace - // the stack needs to be displayed last because the given params will be lost among large stack traces so it will - // provide a bad developer experience - console.error('%cQWIK ERROR', STYLE, err.message, ...printParams(optionalParams), err.stack); - - asyncThrow && - !qTest && - setTimeout(() => { - // throwing error asynchronously to avoid breaking the current call stack. - // We throw so that the error is delivered to the global error handler for - // reporting it to a third-party tools such as Qwik Insights, Sentry or New Relic. - throw err; - }, 0); - return err; -}; diff --git a/packages/qwik/src/core/util/markers.ts b/packages/qwik/src/core/util/markers.ts deleted file mode 100644 index 187b27ee1e8..00000000000 --- a/packages/qwik/src/core/util/markers.ts +++ /dev/null @@ -1,46 +0,0 @@ -/** State factory of the component. */ -export const OnRenderProp = 'q:renderFn'; - -/** Component style host prefix */ -export const ComponentStylesPrefixHost = '💎'; - -/** Component style content prefix */ -export const ComponentStylesPrefixContent = '⭐️'; - -/** Prefix used to identify on listeners. */ -export const EventPrefix = 'on:'; - -/** Attribute used to mark that an event listener is attached. */ -export const EventAny = 'on:.'; -/** `` */ -export const QSlot = 'q:slot'; -export const QSlotRef = 'q:sref'; -export const QSlotS = 'q:s'; -export const QStyle = 'q:style'; -export const QScopedStyle = 'q:sstyle'; -export const QCtxAttr = 'q:ctx'; -export const QManifestHash = 'q:manifest-hash'; -export const QInstance = 'q:instance'; -export const QFuncsPrefix = 'qFuncs_'; - -export const getQFuncs = (document: Document, hash: string): Function[] => { - return (document as any)[QFuncsPrefix + hash] || []; -}; - -export const QLocaleAttr = 'q:locale'; -export const QContainerAttr = 'q:container'; -export const QBaseAttr = 'q:base'; -export const QContainerSelector = '[q\\:container]'; - -export const ResourceEvent = 'qResource'; -export const ComputedEvent = 'qComputed'; -export const RenderEvent = 'qRender'; -export const TaskEvent = 'qTask'; - -/** `` */ -export const QSlotInertName = '\u0000'; - -export const ELEMENT_ID = 'q:id'; -export const ELEMENT_ID_SELECTOR = '[q\\:id]'; -export const ELEMENT_ID_PREFIX = '#'; -export const INLINE_FN_PREFIX = '@'; diff --git a/packages/qwik/src/core/util/promises.ts b/packages/qwik/src/core/util/promises.ts deleted file mode 100644 index 8f5006c8f0c..00000000000 --- a/packages/qwik/src/core/util/promises.ts +++ /dev/null @@ -1,61 +0,0 @@ -import type { ValueOrPromise } from './types'; - -export type PromiseTree = T | Promise | Promise | Array>; - -export const isPromise = (value: any): value is Promise => { - // not using "value instanceof Promise" to have zone.js support - return value && typeof value.then === 'function'; -}; - -export const safeCall = ( - call: () => ValueOrPromise, - thenFn: { f(arg: Awaited): ValueOrPromise }['f'], - rejectFn: { f(reason: any): ValueOrPromise }['f'] -): ValueOrPromise => { - try { - const promise = call(); - if (isPromise(promise)) { - return promise.then(thenFn as any, rejectFn); - } else { - return thenFn(promise as any); - } - } catch (e) { - return rejectFn(e); - } -}; - -export const maybeThen = ( - promise: ValueOrPromise, - thenFn: (arg: Awaited) => ValueOrPromise -): ValueOrPromise => { - return isPromise(promise) ? promise.then(thenFn as any) : thenFn(promise as any); -}; - -export const promiseAll = ( - promises: T -): ValueOrPromise<{ -readonly [P in keyof T]: Awaited }> => { - const hasPromise = promises.some(isPromise); - if (hasPromise) { - return Promise.all(promises); - } - return promises as any; -}; - -export const promiseAllLazy = ( - promises: T -): ValueOrPromise => { - if (promises.length > 0) { - return Promise.all(promises) as any; - } - return promises as any; -}; - -export const isNotNullable = (v: T): v is NonNullable => { - return v != null; -}; - -export const delay = (timeout: number) => { - return new Promise((resolve) => { - setTimeout(resolve, timeout); - }); -}; diff --git a/packages/qwik/src/core/util/types.ts b/packages/qwik/src/core/util/types.ts deleted file mode 100644 index ec8d09610d8..00000000000 --- a/packages/qwik/src/core/util/types.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** @private */ -export const isHtmlElement = (node: unknown): node is Element => { - return node ? (node as Node).nodeType === 1 : false; -}; - -export const isSerializableObject = (v: unknown): v is Record => { - const proto = Object.getPrototypeOf(v); - return proto === Object.prototype || proto === null; -}; - -export const isObject = (v: unknown): v is object => { - return !!v && typeof v === 'object'; -}; - -export const isArray = (v: unknown): v is unknown[] => { - return Array.isArray(v); -}; - -export const isString = (v: unknown): v is string => { - return typeof v === 'string'; -}; - -export const isFunction = any>(v: unknown): v is T => { - return typeof v === 'function'; -}; - -/** - * Type representing a value which is either resolve or a promise. - * - * @public - */ -export type ValueOrPromise = T | Promise; diff --git a/packages/qwik/src/devtools/index.ts b/packages/qwik/src/devtools/index.ts new file mode 100644 index 00000000000..f23a25e2830 --- /dev/null +++ b/packages/qwik/src/devtools/index.ts @@ -0,0 +1,7 @@ +import { qwikJsonDebug, runQwikJsonDebug } from './json'; + +/** + * @beta + * @experimental + */ +export const devtoolsJsonSRC = `${runQwikJsonDebug}\n${qwikJsonDebug}\nrunQwikJsonDebug(window, document, qwikJsonDebug);`; diff --git a/packages/qwik/src/devtools/json.ts b/packages/qwik/src/devtools/json.ts new file mode 100644 index 00000000000..0ddc11b8d5a --- /dev/null +++ b/packages/qwik/src/devtools/json.ts @@ -0,0 +1,530 @@ +// IMPORTANT: This file should have no external imports!!! + +export function runQwikJsonDebug(window: Window, document: Document, debug: typeof qwikJsonDebug) { + const parseQwikJSON = () => { + const rawData = JSON.parse(document.querySelector('script[type="qwik/json"]')!.textContent!); + // TODO: update qFuncs with hash! + const derivedFns = + ( + document.querySelector('script[q\\:func="qwik/json"]') as any as { + qFuncs: Function[]; + } | null + )?.qFuncs || []; + const debugData = debug(document, rawData, derivedFns); + (window as any).qwikJson = debugData; + // eslint-disable-next-line no-console + console.log(debugData); + }; + if (document.querySelector('script[type="qwik/json"]')) { + parseQwikJSON(); + } else { + document.addEventListener('DOMContentLoaded', parseQwikJSON); + } +} + +export function qwikJsonDebug( + document: Document, + qwikJson: QwikJson, + derivedFns: Function[] +): DebugState { + class Base { + constructor( + public __id: number, + public __backRefs: any[] = [] + ) {} + } + + class number_ extends Base { + constructor( + public __id: number, + public __value: number + ) { + super(__id); + } + } + + class boolean_ extends Base { + constructor( + public __id: number, + public __value: boolean + ) { + super(__id); + } + } + + class string_ extends Base { + constructor( + public __id: number, + public __value: string + ) { + super(__id); + } + } + + class undefined_ extends Base { + constructor(public __id: number) { + super(__id); + } + } + class Object_ extends Base { + constructor(public __id: number) { + super(__id); + } + } + + class Array_ extends Array implements Base { + public __id: number; + public __backRefs: any[] = []; + constructor(__id: number) { + super(); + this.__id = __id; + } + } + + class Task extends Base { + constructor( + public __id: number, + public flags: string, + public index: number, + public obj: any + ) { + super(__id); + } + } + + class Listener { + constructor( + public event: string, + public qrl: QRL + ) {} + } + + interface SubscriberEffect {} + // interface StyleAppend {} + // interface ProcessedJSXNode {} + + class QContext { + element: Node | null = null; + // refMap: any[] = []; + // flags: string = ''; + props: Record | null = null; + componentQrl: QRL | null = null; + listeners: Listener[] = []; + seq: any[] | null = []; + tasks: SubscriberEffect[] | null = null; + contexts: Map | null = null; + // appendStyles: StyleAppend[] | null = null; + scopeIds: string[] | null = null; + // vdom: ProcessedJSXNode | null = null; + // slots: ProcessedJSXNode[] | null = null; + // dynamicSlots: QContext[] | null = null; + // parent: QContext | null = null; + // slotParent: QContext | null = null; + } + + class QRefs { + constructor( + public element: Element, + public refMap: any[], + public listeners: Listener[] + ) {} + } + + class Component extends Base { + constructor( + public __id: number, + public qrl: string + ) { + super(__id); + } + } + + class SignalWrapper extends Base { + constructor( + public __id: number, + public id: string, + public prop: string + ) { + super(__id); + } + } + + class DerivedSignal extends Base { + constructor( + public __id: number, + public fn: Function, + public args: any[] + ) { + super(__id); + } + } + + class QRL extends Base { + constructor( + public __id: number, + public chunk: string, + public symbol: string, + public capture: any[] + ) { + super(__id); + } + } + + const nodeMap = getNodeMap(); + const refs: Record = {}; + const contexts: Record = {}; + const objs: any[] = []; + const subs: any[] = []; + qwikJson.objs.forEach((_, idx) => getObject(idx, null)); + Object.keys(qwikJson.ctx).forEach((idx) => getContext(idx)); + Object.keys(qwikJson.refs).forEach((idx) => getRef(idx)); + qwikJson.subs; + return { + refs, + ctx: contexts, + objs, + subs, + }; + ////////////////////////////////////////////////////////////////////////////////// + function getContext(idx: string): any { + const rawCtx = qwikJson.ctx[idx]; + const ctx = (contexts[idx] = new QContext()); + const node = (ctx.element = nodeMap.get(idx) || null); + if (isElement(node)) { + const rawRefs = qwikJson.refs[idx]; + const refMap = splitParse(rawRefs, ' ', (id) => getObject(id, node)); + ctx.listeners = getDomListeners(refMap, node); + } else if (isComment(node)) { + const attrs = new Map(); + node.textContent!.split(' ').forEach((keyValue) => { + const [key, value] = keyValue.split('='); + attrs.set(key, value); + }); + const sstyle = attrs.get('q:sstyle'); + if (sstyle) { + ctx.scopeIds = sstyle.split('|'); + } + } + if (rawCtx.h) { + const [qrl, props] = rawCtx.h.split(' ').map((h: string) => (h ? getObject(h, ctx) : null)); + ctx.componentQrl = qrl; + ctx.props = props; + } + if (rawCtx.c) { + const contexts = (ctx.contexts = new Map()); + for (const part of rawCtx.c.split(' ')) { + const [key, value] = part.split('='); + contexts.set(key, getObject(value, ctx)); + } + } + if (rawCtx.s) { + ctx.seq = rawCtx.s.split(' ').map((s) => getObject(parseNumber(s), ctx)); + } + if (rawCtx.w) { + ctx.tasks = rawCtx.w.split(' ').map((s) => getObject(parseNumber(s), ctx)); + } + } + ////////////////////////////////////////////////////////////////////////////////// + function getRef(idx: string): any { + const rawRefs = qwikJson.refs[idx]; + const node = nodeMap.get(idx) || null; + if (isElement(node)) { + const refMap = splitParse(rawRefs, ' ', (id) => getObject(id, node)); + const listeners = getDomListeners(refMap, node); + refs[idx] = new QRefs(node, refMap, listeners); + } + } + ////////////////////////////////////////////////////////////////////////////////// + function getObject(idx: number | string, parent: any): any { + if (typeof idx == 'string') { + if (idx.startsWith('#')) { + const node = nodeMap.get(idx.substring(1)); + if (!(node as unknown as Base).__backRefs) { + (node as unknown as Base).__backRefs = []; + } + if ((node as unknown as Base).__backRefs.indexOf(parent) === -1) { + (node as unknown as Base).__backRefs.push(parent); + } + return node; + } + const num = parseNumber(idx); + if (isNaN(num)) { + throw new Error('Invalid index: ' + idx); + } + idx = num; + } + while (objs.length < idx) { + objs.push(null); + } + let obj: undefined | Base = objs[idx]; + if (!obj) { + const rawValue = qwikJson.objs[idx]; + let value: any = rawValue; + if (typeof value === 'number') { + obj = new number_(idx, value); + } else if (typeof value === 'boolean') { + obj = new boolean_(idx, value); + } else if (typeof value === 'undefined') { + obj = new undefined_(idx); + } else if (typeof value === 'object') { + obj = Array.isArray(value) ? new Array_(idx) : new Object_(idx); + for (const key in value) { + if (Object.prototype.hasOwnProperty.call(value, key)) { + (obj as any)[key] = getObject(parseNumber(value[key]), obj); + } + } + } else if (typeof rawValue === 'string') { + const data = rawValue.substring(1); + switch (rawValue.charCodeAt(0)) { + case 0x01: // UndefinedSerializer, ///////// \u0001 + value = new undefined_(idx); + break; + case 0x02: // QRLSerializer, ////////////// \u0002 + const [chunk, symbol, ...capture] = data.split(/[#[\]\s]/); + obj = new QRL( + idx, + chunk, + symbol, + capture.map((id) => getObject(parseNumber(id), parent)) + ); + break; + case 0x03: // TaskSerializer, ///////////// \u0003 + const [flags, index, objId] = data.split(' '); + const flagString = [ + parseNumber(flags) & (1 << 0) ? 'Visible' : '', + parseNumber(flags) & (1 << 1) ? 'Task' : '', + parseNumber(flags) & (1 << 2) ? 'Resource' : '', + parseNumber(flags) & (1 << 3) ? 'Computed' : '', + parseNumber(flags) & (1 << 4) ? 'Dirty' : '', + parseNumber(flags) & (1 << 5) ? 'Cleanup' : '', + ] + .filter(Boolean) + .join('|'); + obj = new Task(idx, flagString, parseNumber(index), getObject(objId, parent)); + break; + case 0x12: // SignalSerializer, /////////// \u0012 + obj = getObject(data, parent); + break; + case 0x11: // DerivedSignalSerializer, //// \u0011 + const fnParts = data.split(' '); + const fn = derivedFns[parseNumber(fnParts.pop()!.substring(1))]; + obj = new DerivedSignal( + idx, + fn, + fnParts.map((id) => getObject(id, parent)) + ); + break; + case 0x05: // URLSerializer, ////////////// \u0005 + obj = new URL(data) as any; + (obj as Base).__id = idx; + (obj as Base).__backRefs = []; + break; + case 0x10: // ComponentSerializer, //////// \u0010 + obj = new Component(idx, data); + break; + case 0x13: // SignalWrapperSerializer, //// \u0013 + const [id, prop] = data.split(' '); + obj = new SignalWrapper(idx, id as any, prop); + break; + case 0x04: // ResourceSerializer, ///////// \u0004 + case 0x06: // DateSerializer, ///////////// \u0006 + case 0x16: // FormDataSerializer, ///////// \u0016 + case 0x07: // RegexSerializer, //////////// \u0007 + case 0x0e: // ErrorSerializer, //////////// \u000E + case 0x15: // URLSearchParamsSerializer, // \u0015 + case 0x14: // NoFiniteNumberSerializer, /// \u0014 + case 0x17: // JSXNodeSerializer, ////////// \u0017 + case 0x18: // BigIntSerializer, /////////// \u0018 + case 0x19: // SetSerializer, ////////////// \u0019 + case 0x1a: // MapSerializer, ////////////// \u001a + case 0x0f: // DocumentSerializer, ///////// \u000F + throw new Error( + 'Not Implemented: ' + + rawValue.charCodeAt(0).toString(16) + + ' ' + + JSON.stringify(rawValue) + ); + // console.error((value = 'Not Implemented: ' + rawValue.charCodeAt(0))); + // break; + default: + obj = new string_(idx, rawValue); + } + } else { + throw new Error('Unexpected type: ' + JSON.stringify(rawValue)); + } + objs[idx] = obj; + } + if (parent && obj && obj.__backRefs.indexOf(parent) === -1) { + obj.__backRefs.push(parent); + } + return obj; + } + + function getNodeMap() { + const map = new Map(); + const walker = document.createTreeWalker( + document.firstElementChild!, + NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_ELEMENT + ); + for (let node = walker.firstChild(); node !== null; node = walker.nextNode()) { + const id = getId(node); + id && map.set(id, node); + } + return map; + } + + function getId(node: Node): string | null { + if (isElement(node)) { + return node.getAttribute('q:id'); + } else if (isComment(node)) { + const text = node.nodeValue || ''; + if (text.startsWith('t=')) { + return text.substring(2); + } else if (text.startsWith('qv ')) { + const parts = text.split(' '); + for (let i = 0; i < parts.length; i++) { + const part = parts[i]; + if (part.startsWith('q:id=')) { + return part.substring(5); + } + } + } + return null; + } else { + throw new Error('Unexpected node type: ' + node.nodeType); + } + } + + function isElement(node: any): node is Element { + return node && typeof node == 'object' && node.nodeType === Node.ELEMENT_NODE; + } + function isComment(node: any): node is Comment { + return node && typeof node == 'object' && node.nodeType === Node.COMMENT_NODE; + } + + function splitParse(text: string | null, sep: string, fn: (part: string) => any): any[] { + if (!text) { + return []; + } + return text.split(sep).map(fn); + } + + function getDomListeners(refMap: any[], containerEl: Element): Listener[] { + const attributes = containerEl.attributes; + const listeners: Listener[] = []; + for (let i = 0; i < attributes.length; i++) { + const { name, value } = attributes.item(i)!; + if ( + name.startsWith('on:') || + name.startsWith('on-window:') || + name.startsWith('on-document:') + ) { + const urls = value.split('\n'); + for (const url of urls) { + const [chunk, symbol, capture] = url.split(/[#[\]]/); + const qrl = new QRL( + -1, + chunk, + symbol, + (capture || '').split(' ').map((id) => refMap[parseInt(id, 10)]) + ); + listeners.push(new Listener(name, qrl)); + } + } + } + return listeners; + } + + function parseNumber(value: string) { + return parseInt(value, 36); + } +} + +export interface QwikJson { + refs: Record; + ctx: Record< + string, + { + w?: string; // q:watches + s?: string; // q:seq + h?: string; // q:host + c?: string; // q:context + } + >; + objs: Array; + subs: Array>; +} +export type QwikJsonObjsPrimitives = string | boolean | number | null; +export type QwikJsonObjsObj = Record; + +export interface Base { + __id: number; + __backRefs: any[]; +} + +export interface QRL extends Base { + chunk: string; + symbol: string; + capture: any[]; +} + +export interface QRefs { + element: Element; + refMap: any[]; + listeners: Listener[]; +} + +export interface Listener { + event: string; + qrl: QRL; +} + +export interface SubscriberEffect {} + +export interface QContext { + element: Node | null; + props: Record | null; + componentQrl: QRL | null; + listeners: Listener[]; + seq: any[] | null; + tasks: SubscriberEffect[] | null; + contexts: Map | null; + scopeIds: string[] | null; +} + +export interface DebugState { + refs: Record; + ctx: Record; + objs: any[]; + subs: unknown; +} + +export type QwikType = + | 'string' + | 'number' + | 'bigint' + | 'boolean' + | 'function' + | 'undefined' + | 'object' + | 'symbol' + // Qwik custom types + | 'QRL' + | 'Signal' + | 'SignalWrapper' + | 'Task' + | 'Resource' + | 'URL' + | 'Date' + | 'Regex' + | 'Error' + | 'DerivedSignal' + | 'FormData' + | 'URLSearchParams' + | 'Component' + | 'NoFiniteNumber' + | 'JSXNode' + | 'BigInt' + | 'Set' + | 'Map' + | 'Document'; diff --git a/packages/qwik/src/insights/api-extractor.json b/packages/qwik/src/insights/api-extractor.json new file mode 100644 index 00000000000..1aea45bab21 --- /dev/null +++ b/packages/qwik/src/insights/api-extractor.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + "extends": "../api-extractor.json", + "mainEntryPointFilePath": "/../../dist-dev/dts-out/packages/qwik/src/insights/index.d.ts", + "newlineKind": "lf", + "apiReport": { + "enabled": true, + "reportFileName": "qwik.insights", + "reportFolder": "/src/insights/", + "reportTempFolder": "/../../dist-dev/api-extractor/insights/" + }, + "dtsRollup": { + "enabled": true, + "untrimmedFilePath": "/dist/insights.d.ts" + }, + "docModel": { + "enabled": true, + "apiJsonFilePath": "../../dist-dev/api/qwik/insights/docs.api.json" + } +} diff --git a/packages/qwik/src/insights/index.ts b/packages/qwik/src/insights/index.ts new file mode 100644 index 00000000000..b5f2b1370d2 --- /dev/null +++ b/packages/qwik/src/insights/index.ts @@ -0,0 +1 @@ +export * from './insights'; diff --git a/packages/qwik/src/insights/insights.ts b/packages/qwik/src/insights/insights.ts new file mode 100644 index 00000000000..7c5879225be --- /dev/null +++ b/packages/qwik/src/insights/insights.ts @@ -0,0 +1,205 @@ +import { component$, isDev, sync$ } from '@qwik.dev/core'; +import { jsx } from '@qwik.dev/core/jsx-runtime'; + +/** @public */ +export interface InsightsPayload { + /** Qwik version */ + qVersion: string; + + /** Manifest Hash of the container. */ + manifestHash: string; + + /** + * API key of the application which we are trying to profile. + * + * This key can be used for sharding the data. + */ + publicApiKey: string; + + /** + * Previous symbol received on the client. + * + * Client periodically sends symbol log to the server. Being able to connect the order of symbols + * is useful for server clustering. Sending previous symbol name allows the server to stitch the + * symbol list together. + */ + previousSymbol?: string | null; + + /** List of symbols which have been received since last update. */ + symbols: InsightSymbol[]; +} + +/** @public */ +export interface InsightSymbol { + /** Symbol name */ + symbol: string; + + /** Current route so we can have a better understanding of which symbols are needed for each route. */ + route: string; + + /** Time delta since last symbol. Can be used to stich symbol requests together */ + delay: number; + + /** Number of ms between the time the symbol was requested and it was loaded. */ + latency: number; + + /** Number of ms between the q:route attribute change and the qsymbol event */ + timeline: number; + + /** + * Was this symbol as a result of user interaction. User interactions represent roots for + * clouters. + */ + interaction: boolean; +} + +/** @public */ +export interface InsightsError { + /** Manifest Hash of the container. */ + manifestHash: string; + timestamp: number; + url: string; + source: string; + line: number; + column: number; + error: string; + message: string; + stack: string; +} + +interface QwikSymbolTrackerWindow extends Window { + qSymbolTracker: { + symbols: InsightSymbol[]; + publicApiKey: string; + }; +} + +interface QSymbolDetail { + element: HTMLElement | undefined; + reqTime: number; + symbol: string; +} + +// Injected by the vite plugin +// eslint-disable-next-line no-var +declare var __QI_KEY__: string; +// eslint-disable-next-line no-var +declare var __QI_URL__: string; + +// We use a self-invoking function to minify the code, renaming long globals and attributes +// the qwik optimizer only minifies somewhat, so put all var declarations in the same line +/** @internal */ +export const insightsPing = sync$(() => + ((w: QwikSymbolTrackerWindow, d, l, n, p, r, S) => { + /* eslint-disable no-var -- better minification */ + var publicApiKey = __QI_KEY__, + postUrl = __QI_URL__, + qVersion = d.querySelector(`[q\\:version]`)?.getAttribute(`q:version`) || 'unknown', + manifestHash = + d.querySelector(`[q\\:manifest-hash]`)?.getAttribute(`q:manifest-hash`) || 'dev', + qSymbols: InsightSymbol[] = [], + existingSymbols: Set = new Set(), + flushSymbolIndex: number = 0, + lastReqTime: number = 0, + timeoutID: ReturnType | undefined, + qRouteChangeTime = p.now(), + qRouteEl = d.querySelector(`[q\\:route]`), + flush = () => { + timeoutID = undefined; + if (qSymbols.length > flushSymbolIndex) { + var payload = { + qVersion, + publicApiKey, + manifestHash, + previousSymbol: + flushSymbolIndex == 0 ? undefined : qSymbols[flushSymbolIndex - 1].symbol, + symbols: qSymbols.slice(flushSymbolIndex), + } satisfies InsightsPayload; + n.sendBeacon(postUrl, S(payload)); + flushSymbolIndex = qSymbols.length; + } + }, + debounceFlush = () => { + timeoutID != undefined && clearTimeout(timeoutID); + timeoutID = setTimeout(flush, 1000); + }; + + w.qSymbolTracker = { + symbols: qSymbols, + publicApiKey, + }; + if (qRouteEl) { + new MutationObserver((mutations) => { + var mutation = mutations.find((m) => m.attributeName === `q:route`); + if (mutation) { + qRouteChangeTime = p.now(); + } + }).observe(qRouteEl, { attributes: true }); + } + d.addEventListener('visibilitychange', () => d.visibilityState === 'hidden' && flush()); + d.addEventListener(`qsymbol`, (_event) => { + var event = _event as CustomEvent, + detail = event.detail, + symbolRequestTime = detail.reqTime, + symbolDeliveredTime = event.timeStamp, + symbol = detail.symbol; + if (!existingSymbols.has(symbol)) { + existingSymbols.add(symbol); + var route = qRouteEl?.getAttribute(`q:route`) || '/'; + qSymbols.push({ + symbol, + route, + delay: r(0 - lastReqTime + symbolRequestTime), + latency: r(symbolDeliveredTime - symbolRequestTime), + timeline: r(0 - qRouteChangeTime + symbolRequestTime), + interaction: !!detail.element, + }); + lastReqTime = symbolDeliveredTime; + debounceFlush(); + } + }); + w.addEventListener('error', (event: ErrorEvent) => { + var error = event.error; + if (!(error && typeof error === 'object')) { + return; + } + var payload = { + url: `${l}`, + manifestHash, + timestamp: new Date().getTime(), + source: event.filename, + line: event.lineno, + column: event.colno, + message: event.message, + error: 'message' in error ? (error as Error).message : `${error}`, + stack: 'stack' in error ? (error as Error).stack || '' : '', + } satisfies InsightsError; + n.sendBeacon(`${postUrl}error/`, S(payload)); + }); + })(window as any, document, location, navigator, performance, Math.round, JSON.stringify) +); + +/** + * @beta + * @experimental + */ +export const Insights = component$(() => { + if (!__EXPERIMENTAL__.insights) { + throw new Error( + 'Insights is experimental and must be enabled with `experimental: ["insights"]` in the `qwikVite` plugin.' + ); + } + const key = (globalThis as any).__QI_KEY__; + const url = (globalThis as any).__QI_URL__; + if (!key || !url) { + if (!isDev) { + console.warn(': no config from qwikInsights plugin, skipping...'); + } + return null; + } + return /* @__PURE__ */ jsx('script', { + 'document:onQInit$': insightsPing, + // We must pass the vite injected variables via window because sync$ code doesn't get replaced by the vite plugin + dangerouslySetInnerHTML: `__QI_KEY__=${JSON.stringify(key)};__QI_URL__=${JSON.stringify(url)}`, + }); +}); diff --git a/packages/qwik/src/insights/insights.unit.ts b/packages/qwik/src/insights/insights.unit.ts new file mode 100644 index 00000000000..ced95b8094b --- /dev/null +++ b/packages/qwik/src/insights/insights.unit.ts @@ -0,0 +1,15 @@ +import { expect, test } from 'vitest'; +import { insightsPing } from './insights'; +import compress from 'brotli/compress.js'; + +test('insightsPing size', () => { + const pingSrc = (insightsPing as any).resolved.serialized; + const compressed = compress(Buffer.from(pingSrc), { mode: 1, quality: 11 }); + + expect(compressed.length).toBe(792); + expect(pingSrc.length).toBe(2099); + // Just to a sanity check + expect(pingSrc).toMatchInlineSnapshot( + `"()=>((w,d,l,n,p,r,S)=>{var publicApiKey=__QI_KEY__,postUrl=__QI_URL__,qVersion=d.querySelector(\`[q\\\\:version]\`)?.getAttribute(\`q:version\`)||"unknown",manifestHash=d.querySelector(\`[q\\\\:manifest-hash]\`)?.getAttribute(\`q:manifest-hash\`)||"dev",qSymbols=[],existingSymbols=new Set,flushSymbolIndex=0,lastReqTime=0,timeoutID,qRouteChangeTime=p.now(),qRouteEl=d.querySelector(\`[q\\\\:route]\`),flush=()=>{timeoutID=undefined;if(qSymbols.length>flushSymbolIndex){var payload={qVersion,publicApiKey,manifestHash,previousSymbol:flushSymbolIndex==0?undefined:qSymbols[flushSymbolIndex-1].symbol,symbols:qSymbols.slice(flushSymbolIndex)};n.sendBeacon(postUrl,S(payload));flushSymbolIndex=qSymbols.length;}},debounceFlush=()=>{timeoutID!=undefined&&clearTimeout(timeoutID);timeoutID=setTimeout(flush,1e3);};w.qSymbolTracker={symbols:qSymbols,publicApiKey};if(qRouteEl){new MutationObserver(mutations=>{var mutation=mutations.find(m=>m.attributeName===\`q:route\`);if(mutation){qRouteChangeTime=p.now();}}).observe(qRouteEl,{attributes:true});}d.addEventListener("visibilitychange",()=>d.visibilityState==="hidden"&&flush());d.addEventListener(\`qsymbol\`,_event=>{var event=_event,detail=event.detail,symbolRequestTime=detail.reqTime,symbolDeliveredTime=event.timeStamp,symbol=detail.symbol;if(!existingSymbols.has(symbol)){existingSymbols.add(symbol);var route=qRouteEl?.getAttribute(\`q:route\`)||"/";qSymbols.push({symbol,route,delay:r(0-lastReqTime+symbolRequestTime),latency:r(symbolDeliveredTime-symbolRequestTime),timeline:r(0-qRouteChangeTime+symbolRequestTime),interaction:!!detail.element});lastReqTime=symbolDeliveredTime;debounceFlush();}});w.addEventListener("error",event=>{var error=event.error;if(!(error&&typeof error==="object")){return;}var payload={url:\`\${l}\`,manifestHash,timestamp:new Date().getTime(),source:event.filename,line:event.lineno,column:event.colno,message:event.message,error:"message"in error?error.message:\`\${error}\`,stack:"stack"in error?error.stack||"":""};n.sendBeacon(\`\${postUrl}error/\`,S(payload));});})(window,document,location,navigator,performance,Math.round,JSON.stringify)"` + ); +}); diff --git a/packages/qwik/src/insights/qwik.insights.api.md b/packages/qwik/src/insights/qwik.insights.api.md new file mode 100644 index 00000000000..4ab06783871 --- /dev/null +++ b/packages/qwik/src/insights/qwik.insights.api.md @@ -0,0 +1,60 @@ +## API Report File for "@qwik.dev/core" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { Component } from '@qwik.dev/core'; +import { SyncQRL } from '@qwik.dev/core'; + +// @beta (undocumented) +export const Insights: Component; + +// @public (undocumented) +export interface InsightsError { + // (undocumented) + column: number; + // (undocumented) + error: string; + // (undocumented) + line: number; + manifestHash: string; + // (undocumented) + message: string; + // (undocumented) + source: string; + // (undocumented) + stack: string; + // (undocumented) + timestamp: number; + // (undocumented) + url: string; +} + +// @public (undocumented) +export interface InsightsPayload { + manifestHash: string; + previousSymbol?: string | null; + publicApiKey: string; + qVersion: string; + symbols: InsightSymbol[]; +} + +// Warning: (ae-internal-missing-underscore) The name "insightsPing" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal (undocumented) +export const insightsPing: SyncQRL<() => void>; + +// @public (undocumented) +export interface InsightSymbol { + delay: number; + interaction: boolean; + latency: number; + route: string; + symbol: string; + timeline: number; +} + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/qwik/src/insights/vite/api-extractor.json b/packages/qwik/src/insights/vite/api-extractor.json new file mode 100644 index 00000000000..aa51deb13e9 --- /dev/null +++ b/packages/qwik/src/insights/vite/api-extractor.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + "extends": "../api-extractor.json", + "mainEntryPointFilePath": "/../../dist-dev/dts-out/packages/qwik/src/insights/vite/index.d.ts", + "newlineKind": "lf", + "apiReport": { + "enabled": true, + "reportFileName": "qwik.insights.vite", + "reportFolder": "/src/insights/vite/", + "reportTempFolder": "/../../dist-dev/api-extractor/insights/vite/" + }, + "dtsRollup": { + "enabled": true, + "untrimmedFilePath": "/dist/insights/vite.d.ts" + }, + "docModel": { + "enabled": true, + "apiJsonFilePath": "../../dist-dev/api/qwik/insights/vite/docs.api.json" + } +} diff --git a/packages/qwik/src/insights/vite/index.ts b/packages/qwik/src/insights/vite/index.ts new file mode 100644 index 00000000000..7bd9692a6c1 --- /dev/null +++ b/packages/qwik/src/insights/vite/index.ts @@ -0,0 +1 @@ +export * from './insights-plugin'; diff --git a/packages/qwik/src/insights/vite/insights-plugin.ts b/packages/qwik/src/insights/vite/insights-plugin.ts new file mode 100644 index 00000000000..2f8f430f0a5 --- /dev/null +++ b/packages/qwik/src/insights/vite/insights-plugin.ts @@ -0,0 +1,149 @@ +import type { QwikVitePlugin, SmartEntryStrategy } from '@qwik.dev/core/optimizer'; +import { existsSync, mkdirSync } from 'node:fs'; +import { readFile, writeFile } from 'node:fs/promises'; +import { join, resolve } from 'node:path'; +import type { PluginOption } from 'vite'; + +const logWarn = (message?: any, ...rest: any[]) => { + console.warn('\x1b[33m%s\x1b[0m', `qwikInsight()[WARN]: ${message}`, ...rest); +}; + +const log = (message?: any) => { + // eslint-disable-next-line no-console + console.log('\x1b[35m%s\x1b[0m', `qwikInsight(): ${message}`); +}; + +/** @public */ +export interface InsightManifest { + manual: Record; + prefetch: { route: string; symbols: string[] }[]; +} + +/** + * @beta + * @experimental + */ +export async function qwikInsights(qwikInsightsOpts: { + publicApiKey: string; + baseUrl?: string; + outDir?: string; +}): Promise { + const { publicApiKey, baseUrl = 'https://insights.qwik.dev', outDir = '' } = qwikInsightsOpts; + + if (!publicApiKey) { + console.warn('qwikInsights: publicApiKey is required, skipping...'); + return; + } + let isProd = false; + let jsonDir: string; + let jsonFile: string; + let data: InsightManifest | null = null; + let qwikVitePlugin: QwikVitePlugin | null = null; + + const apiUrl = `${baseUrl}/api/v1/${publicApiKey}`; + const postUrl = `${apiUrl}/post/`; + + async function loadQwikInsights(): Promise { + if (data) { + return data; + } + if (existsSync(jsonFile)) { + log('Reading Qwik Insight data from: ' + jsonFile); + return (data = JSON.parse(await readFile(jsonFile, 'utf-8')) as InsightManifest); + } + return null; + } + + const vitePlugin: PluginOption = { + name: 'vite-plugin-qwik-insights', + enforce: 'pre', + // Only activate in production builds + apply: 'build', + async config(viteConfig) { + jsonDir = resolve(viteConfig.root || '.', outDir); + jsonFile = join(jsonDir, 'q-insights.json'); + isProd = viteConfig.mode !== 'ssr'; + + return { + define: { + 'globalThis.__QI_KEY__': JSON.stringify(publicApiKey), + 'globalThis.__QI_URL__': JSON.stringify(postUrl), + }, + }; + }, + configResolved: { + // we want to register the bundle graph adder last so we overwrite existing routes + order: 'post', + async handler(config) { + qwikVitePlugin = config.plugins.find( + (p) => p.name === 'vite-plugin-qwik' + ) as QwikVitePlugin; + if (!qwikVitePlugin) { + throw new Error('Missing vite-plugin-qwik'); + } + const opts = qwikVitePlugin.api.getOptions(); + if (isProd) { + try { + const qManifest: InsightManifest = { manual: {}, prefetch: [] }; + const response = await fetch(`${apiUrl}/bundles/strategy/`); + const strategy = await response.json(); + Object.assign(qManifest, strategy); + data = qManifest; + mkdirSync(jsonDir, { recursive: true }); + log('Fetched latest Qwik Insight data into: ' + jsonFile); + await writeFile(jsonFile, JSON.stringify(qManifest)); + } catch (e) { + logWarn(`Failed to fetch manifest from Insights DB at ${apiUrl}/bundles/strategy/`, e); + await loadQwikInsights(); + } + } else { + await loadQwikInsights(); + } + + if (data) { + (opts.entryStrategy as SmartEntryStrategy).manual = { + ...data.manual, + ...(opts.entryStrategy as SmartEntryStrategy).manual, + }; + + qwikVitePlugin.api.registerBundleGraphAdder((manifest) => { + const result: Record< + string, + { imports?: string[] | undefined; dynamicImports?: string[] | undefined } + > = {}; + for (const item of data?.prefetch || []) { + if (item.symbols) { + let route = item.route; + if (route.startsWith('/')) { + route = route.slice(1); + } + if (!route.endsWith('/')) { + route += '/'; + } + result[route] = { ...manifest.bundles[route], imports: item.symbols }; + } + } + return result; + }); + } + }, + }, + + closeBundle: async () => { + const path = resolve(outDir, 'q-manifest.json'); + if (isProd && existsSync(path)) { + const qManifest = await readFile(path, 'utf-8'); + + try { + await fetch(`${postUrl}manifest`, { + method: 'post', + body: qManifest, + }); + } catch (e) { + logWarn(`Failed to post manifest to Insights DB at ${postUrl}manifest`, e); + } + } + }, + }; + return vitePlugin; +} diff --git a/packages/qwik/src/insights/vite/qwik.insights.vite.api.md b/packages/qwik/src/insights/vite/qwik.insights.vite.api.md new file mode 100644 index 00000000000..8ffe6a8ad99 --- /dev/null +++ b/packages/qwik/src/insights/vite/qwik.insights.vite.api.md @@ -0,0 +1,29 @@ +## API Report File for "@qwik.dev/core" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import type { PluginOption } from 'vite'; + +// @public (undocumented) +export interface InsightManifest { + // (undocumented) + manual: Record; + // (undocumented) + prefetch: { + route: string; + symbols: string[]; + }[]; +} + +// @beta (undocumented) +export function qwikInsights(qwikInsightsOpts: { + publicApiKey: string; + baseUrl?: string; + outDir?: string; +}): Promise; + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/qwik/src/jsx-runtime.ts b/packages/qwik/src/jsx-runtime.ts index 9f5b5fe711d..4c46330f418 100644 --- a/packages/qwik/src/jsx-runtime.ts +++ b/packages/qwik/src/jsx-runtime.ts @@ -1,2 +1 @@ -export { jsx, jsxs, jsxDEV, Fragment } from './core'; -export type { JSX, JSXNode, FunctionComponent } from './core'; +export { jsx, jsx as jsxs, jsxDEV, Fragment, type QwikJSX as JSX } from '@qwik.dev/core'; diff --git a/packages/qwik/src/napi/Cargo.toml b/packages/qwik/src/napi/Cargo.toml index 6620462c175..e254b915609 100644 --- a/packages/qwik/src/napi/Cargo.toml +++ b/packages/qwik/src/napi/Cargo.toml @@ -8,9 +8,10 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -napi = { version = "2", features = ["serde-json"] } +tokio = { version = "1", features = ["rt-multi-thread"] } +napi = { version = "2", features = ["serde-json", "tokio_rt"] } napi-derive = "2" -qwik-core = { path = "../optimizer/core", features = ["fs", "parallel"] } +qwik-core = { path = "../optimizer/core" } [target.'cfg(windows)'.dependencies] mimalloc = { version = "0.1.25", default-features = false } diff --git a/packages/qwik/src/napi/src/lib.rs b/packages/qwik/src/napi/src/lib.rs index faab5c69c83..5aba427d00a 100644 --- a/packages/qwik/src/napi/src/lib.rs +++ b/packages/qwik/src/napi/src/lib.rs @@ -6,7 +6,8 @@ extern crate napi; #[macro_use] extern crate napi_derive; -use napi::{CallContext, JsObject, JsUnknown, Result}; +use napi::{CallContext, JsObject, Result}; +use tokio::task; #[cfg(windows)] #[global_allocator] @@ -14,27 +15,26 @@ static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; #[allow(clippy::needless_pass_by_value)] #[js_function(1)] -fn transform_fs(ctx: CallContext) -> Result { - let opts = ctx.get::(0)?; - let config: qwik_core::TransformFsOptions = ctx.env.from_js_value(opts)?; - - let result = qwik_core::transform_fs(config).unwrap(); - ctx.env.to_js_value(&result) -} - -#[allow(clippy::needless_pass_by_value)] -#[js_function(1)] -fn transform_modules(ctx: CallContext) -> Result { +fn transform_modules(ctx: CallContext) -> Result { let opts = ctx.get::(0)?; let config: qwik_core::TransformModulesOptions = ctx.env.from_js_value(opts)?; - let result = qwik_core::transform_modules(config).unwrap(); - ctx.env.to_js_value(&result) + ctx.env.execute_tokio_future( + async move { + // Spawn the CPU-intensive work onto a separate thread in the thread pool + let result = task::spawn_blocking(move || qwik_core::transform_modules(config)) + .await + .unwrap() + .map_err(|e| napi::Error::from_reason(e.to_string()))?; + + Ok(result) + }, + |env, result| env.to_js_value(&result), + ) } #[module_exports] fn init(mut exports: JsObject) -> Result<()> { - exports.create_named_method("transform_fs", transform_fs)?; exports.create_named_method("transform_modules", transform_modules)?; Ok(()) diff --git a/packages/qwik/src/optimizer/cli/Cargo.toml b/packages/qwik/src/optimizer/cli/Cargo.toml deleted file mode 100644 index 50888cc2910..00000000000 --- a/packages/qwik/src/optimizer/cli/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "qwik" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -clap = "3.1.8" -qwik-core = { path = "../core", features = ["fs", "parallel"] } -path-absolutize = "3.0.11" \ No newline at end of file diff --git a/packages/qwik/src/optimizer/cli/src/main.rs b/packages/qwik/src/optimizer/cli/src/main.rs deleted file mode 100644 index 8f757bbfd2b..00000000000 --- a/packages/qwik/src/optimizer/cli/src/main.rs +++ /dev/null @@ -1,169 +0,0 @@ -#![deny(clippy::all)] -#![deny(clippy::perf)] -#![deny(clippy::nursery)] - -use std::path::PathBuf; - -use clap::{Arg, Command}; -use path_absolutize::Absolutize; -use qwik_core::{transform_fs, EmitMode, EntryStrategy, MinifyMode, TransformFsOptions}; - -struct OptimizerInput { - glob: Option, - manifest: Option, - core_module: Option, - scope: Option, - src: PathBuf, - dest: PathBuf, - mode: EmitMode, - strategy: EntryStrategy, - transpile_ts: bool, - transpile_jsx: bool, - preserve_filenames: bool, - minify: MinifyMode, - sourcemaps: bool, - explicit_extensions: bool, -} - -fn main() -> Result<(), Box> { - let matches = Command::new("qwik") - .version("1.0") - .arg_required_else_help(true) - .subcommand_required(true) - .infer_subcommands(true) - .disable_help_subcommand(true) - .subcommand_required(true).arg_required_else_help(true) - .about("Qwik CLI allows to optimize qwik projects before bundling") - .subcommand( - Command::new("optimize") - .about("takes a source directory of qwik code and outputs an optimized version that lazy loads") - .arg_required_else_help(true) - .arg( - Arg::new("src") - .short('s') - .long("src") - .default_value(".") - .takes_value(true) - .help("relative path to the source directory"), - ) - .arg( - Arg::new("dest") - .short('d') - .long("dest") - .required(true) - .takes_value(true) - .help("relative path to the output directory"), - ) - .arg( - Arg::new("strategy") - .long("strategy") - .possible_values(["inline","single", "hook", "segment", "smart", "component"]) - .takes_value(true) - .help("entry strategy used to group segments"), - ) - .arg( - Arg::new("manifest") - .short('m') - .long("manifest") - .takes_value(true) - .help("filename of the manifest"), - ) - .arg( - Arg::new("no-ts") - .long("no-ts") - .help("no transpile TS").takes_value(false) - ) - .arg( - Arg::new("no-jsx") - .long("no-jsx") - .help("no transpile JSX").takes_value(false) - ) - .arg(Arg::new("preserve-filenames").long("preserve-filenames").help("preserves original filename").takes_value(false)) - .arg(Arg::new("minify").long("minify").possible_values(["minify", "simplify", "none"]).takes_value(true).help("outputs minified source code")) - .arg(Arg::new("sourcemaps").long("sourcemaps").help("generates sourcemaps").takes_value(false)) - .arg(Arg::new("extensions").long("extensions").help("keep explicit extensions on imports").takes_value(false)), - ) - .get_matches(); - - // You can check for the existence of subcommands, and if found use their - // matches just as you would the top level app - if let Some(matches) = matches.subcommand_matches("optimize") { - // "$ myapp test" was run - let strategy = match matches.value_of("strategy") { - Some("inline") => EntryStrategy::Inline, - Some("hook") => EntryStrategy::Segment, - Some("segment") => EntryStrategy::Segment, - Some("single") => EntryStrategy::Single, - Some("component") => EntryStrategy::Component, - Some("smart") | None => EntryStrategy::Smart, - _ => panic!("Invalid strategy option"), - }; - - let minify = match matches.value_of("minify") { - Some("none") => MinifyMode::None, - Some("simplify") | None => MinifyMode::Simplify, - _ => panic!("Invalid minify option"), - }; - - let mode = match matches.value_of("mode") { - Some("dev") => EmitMode::Dev, - Some("prod") => EmitMode::Prod, - Some("lib") | None => EmitMode::Lib, - _ => panic!("Invalid mode option"), - }; - optimize(OptimizerInput { - src: matches.value_of_t_or_exit("src"), - dest: matches.value_of_t_or_exit("dest"), - manifest: matches.value_of("manifest").map(|s| s.into()), - core_module: matches.value_of("core_module").map(|s| s.into()), - scope: matches.value_of("scope").map(|s| s.into()), - mode, - glob: None, - strategy, - minify, - explicit_extensions: matches.is_present("extensions"), - transpile_jsx: !matches.is_present("no-jsx"), - transpile_ts: !matches.is_present("no-ts"), - preserve_filenames: matches.is_present("preserve-filenames"), - sourcemaps: matches.is_present("sourcemaps"), - })?; - } - Ok(()) -} - -fn optimize( - optimizer_input: OptimizerInput, -) -> Result> { - let current_dir = std::env::current_dir()?; - let src_dir = current_dir.join(optimizer_input.src).canonicalize()?; - - let result = transform_fs(TransformFsOptions { - src_dir: src_dir.to_string_lossy().to_string(), - vendor_roots: vec![], - glob: optimizer_input.glob, - source_maps: optimizer_input.sourcemaps, - minify: optimizer_input.minify, - transpile_jsx: optimizer_input.transpile_jsx, - transpile_ts: optimizer_input.transpile_ts, - preserve_filenames: optimizer_input.preserve_filenames, - entry_strategy: optimizer_input.strategy, - explicit_extensions: optimizer_input.explicit_extensions, - core_module: optimizer_input.core_module, - root_dir: None, - - mode: optimizer_input.mode, - scope: optimizer_input.scope, - - strip_exports: None, - strip_ctx_name: None, - strip_event_handlers: false, - reg_ctx_name: None, - is_server: None, - })?; - - result.write_to_fs( - ¤t_dir.join(optimizer_input.dest).absolutize()?, - optimizer_input.manifest, - )?; - Ok(result) -} diff --git a/packages/qwik/src/optimizer/core/Cargo.toml b/packages/qwik/src/optimizer/core/Cargo.toml index dba37a3cbd0..125c9062bd2 100644 --- a/packages/qwik/src/optimizer/core/Cargo.toml +++ b/packages/qwik/src/optimizer/core/Cargo.toml @@ -31,7 +31,3 @@ path-slash="0.2.1" [dev-dependencies] insta = "1.29.0" - -[features] -fs=[] -parallel=[] diff --git a/packages/qwik/src/optimizer/core/README.md b/packages/qwik/src/optimizer/core/README.md index 108d068e053..0ebecc5b4e8 100644 --- a/packages/qwik/src/optimizer/core/README.md +++ b/packages/qwik/src/optimizer/core/README.md @@ -1,33 +1,7 @@ -# qwik-core +# Qwik Optimizer -## 1. Install rust +See the contributing guide for more install information. If you want to updat the tests, run `pnpm run test.rust.update`. If you want to run a single test with dbg output: -https://www.rust-lang.org/tools/install - -``` -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -``` - -## 2. Build library - -``` -make build -``` - -or - -``` -cargo build -``` - -## 3. Run tests - -``` -make test -``` - -or - -``` -cargo test +```shell +cargo test --manifest-path packages/qwik/src/optimizer/core/Cargo.toml PARTIAL_NAME_OF_TEST -- --nocapture ``` diff --git a/packages/qwik/src/optimizer/core/benches/transform.rs b/packages/qwik/src/optimizer/core/benches/transform.rs index bf24beb6813..6ccb2971fb8 100644 --- a/packages/qwik/src/optimizer/core/benches/transform.rs +++ b/packages/qwik/src/optimizer/core/benches/transform.rs @@ -17,7 +17,7 @@ fn transform_todo_app(b: &mut Bencher) { useStore, useHostElement, useEvent, - } from '@builder.io/qwik'; + } from '@qwik.dev/core'; import { addItem, clearCompleted, diff --git a/packages/qwik/src/optimizer/core/src/add_locs.rs b/packages/qwik/src/optimizer/core/src/add_locs.rs new file mode 100644 index 00000000000..a6972384a4a --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/add_locs.rs @@ -0,0 +1,75 @@ +use crate::words::_ADD_LOC; +use swc_atoms::JsWord; +use swc_common::{SourceMap, Spanned, SyntaxContext, DUMMY_SP}; +use swc_ecmascript::{ + ast::{self}, + visit::{VisitMut, VisitMutWith}, +}; + +pub struct AddLocs<'a> { + pub source_map: &'a SourceMap, + pub file_name: String, + pub did_add_loc: bool, +} + +impl<'a> AddLocs<'a> { + pub const fn new(source_map: &'a SourceMap, file_name: String) -> Self { + Self { + source_map, + file_name, + did_add_loc: false, + } + } +} + +impl<'a> VisitMut for AddLocs<'a> { + fn visit_mut_var_declarator(&mut self, node: &mut ast::VarDeclarator) { + node.visit_mut_children_with(self); + + if let (Some(init), ast::Pat::Ident(_)) = (&node.init, &node.name) { + let loc = self.source_map.lookup_char_pos(init.span_lo()); + node.init = Some(Box::new(ast::Expr::Call(ast::CallExpr { + span: init.span(), + callee: ast::Callee::Expr(Box::new(ast::Expr::Ident(ast::Ident { + span: init.span(), + sym: _ADD_LOC.clone(), + optional: false, + ctxt: SyntaxContext::default(), + }))), + args: vec![ + ast::ExprOrSpread { + spread: None, + expr: init.clone(), + }, + ast::ExprOrSpread { + spread: None, + expr: Box::new(ast::Expr::Lit(ast::Lit::Str(ast::Str { + span: DUMMY_SP, + value: JsWord::from(self.file_name.clone()), + raw: None, + }))), + }, + ast::ExprOrSpread { + spread: None, + expr: Box::new(ast::Expr::Lit(ast::Lit::Num(ast::Number { + span: DUMMY_SP, + value: (loc.line + 1) as f64, + raw: None, + }))), + }, + ast::ExprOrSpread { + spread: None, + expr: Box::new(ast::Expr::Lit(ast::Lit::Num(ast::Number { + span: DUMMY_SP, + value: (loc.col.0 + 1) as f64, + raw: None, + }))), + }, + ], + type_args: None, + ctxt: SyntaxContext::default(), + }))); + self.did_add_loc = true; + } + } +} diff --git a/packages/qwik/src/optimizer/core/src/code_move.rs b/packages/qwik/src/optimizer/core/src/code_move.rs index f36fdf0c959..f22bcb13154 100644 --- a/packages/qwik/src/optimizer/core/src/code_move.rs +++ b/packages/qwik/src/optimizer/core/src/code_move.rs @@ -1,6 +1,6 @@ use crate::collector::{new_ident_from_id, GlobalCollect, Id, ImportKind}; use crate::parse::PathData; -use crate::transform::{add_handle_watch, create_synthetic_named_import}; +use crate::transform::create_synthetic_named_import; use crate::words::*; use anyhow::Error; @@ -24,7 +24,6 @@ pub struct NewModuleCtx<'a> { pub scoped_idents: &'a [Id], pub global: &'a GlobalCollect, pub core_module: &'a JsWord, - pub need_handle_watch: bool, pub need_transform: bool, pub explicit_extensions: bool, pub leading_comments: SingleThreadedCommentsMap, @@ -144,10 +143,6 @@ pub fn new_module(ctx: NewModuleCtx) -> Result<(ast::Module, SingleThreadedComme }; module.body.push(create_named_export(expr, ctx.name)); - if ctx.need_handle_watch { - // Inject qwik internal import - add_handle_watch(&mut module.body, ctx.core_module); - } Ok((module, comments)) } diff --git a/packages/qwik/src/optimizer/core/src/collector.rs b/packages/qwik/src/optimizer/core/src/collector.rs index d6fdf715ed7..896e034dd3a 100644 --- a/packages/qwik/src/optimizer/core/src/collector.rs +++ b/packages/qwik/src/optimizer/core/src/collector.rs @@ -297,6 +297,7 @@ enum ExprOrSkip { Skip, } +/// Collects all identifiers while visiting the AST. #[derive(Debug)] pub struct IdentCollector { pub local_idents: HashSet, @@ -369,6 +370,10 @@ impl Visit for IdentCollector { fn visit_ident(&mut self, node: &ast::Ident) { if matches!(self.expr_ctxt.last(), Some(ExprOrSkip::Expr)) && node.ctxt != SyntaxContext::empty() + && (node.sym != *"undefined" + && node.sym != *"NaN" + && node.sym != *"Infinity" + && node.sym != *"null") { self.local_idents.insert(id!(node)); } @@ -379,6 +384,13 @@ impl Visit for IdentCollector { node.visit_children_with(self); self.expr_ctxt.pop(); } + + // props.foo + fn visit_member_expr(&mut self, member: &ast::MemberExpr) { + self.expr_ctxt.push(ExprOrSkip::Skip); + member.visit_children_with(self); + self.expr_ctxt.pop(); + } } pub fn collect_from_pat(pat: &ast::Pat, identifiers: &mut Vec<(Id, Span)>) -> bool { diff --git a/packages/qwik/src/optimizer/core/src/const_replace.rs b/packages/qwik/src/optimizer/core/src/const_replace.rs index 6e905701954..c52f8b89f60 100644 --- a/packages/qwik/src/optimizer/core/src/const_replace.rs +++ b/packages/qwik/src/optimizer/core/src/const_replace.rs @@ -19,15 +19,12 @@ impl ConstReplacerVisitor { Self { is_server, is_dev, - is_server_ident: global_collector - .get_imported_local(&IS_SERVER, &BUILDER_IO_QWIK_BUILD), - is_browser_ident: global_collector - .get_imported_local(&IS_BROWSER, &BUILDER_IO_QWIK_BUILD), - is_dev_ident: global_collector.get_imported_local(&IS_DEV, &BUILDER_IO_QWIK_BUILD), - is_core_server_ident: global_collector.get_imported_local(&IS_SERVER, &BUILDER_IO_QWIK), - is_core_browser_ident: global_collector - .get_imported_local(&IS_BROWSER, &BUILDER_IO_QWIK), - is_core_dev_ident: global_collector.get_imported_local(&IS_DEV, &BUILDER_IO_QWIK), + is_server_ident: global_collector.get_imported_local(&IS_SERVER, &QWIK_CORE_BUILD), + is_browser_ident: global_collector.get_imported_local(&IS_BROWSER, &QWIK_CORE_BUILD), + is_dev_ident: global_collector.get_imported_local(&IS_DEV, &QWIK_CORE_BUILD), + is_core_server_ident: global_collector.get_imported_local(&IS_SERVER, &QWIK_CORE), + is_core_browser_ident: global_collector.get_imported_local(&IS_BROWSER, &QWIK_CORE), + is_core_dev_ident: global_collector.get_imported_local(&IS_DEV, &QWIK_CORE), } } } diff --git a/packages/qwik/src/optimizer/core/src/fixtures/index.qwik.mjs b/packages/qwik/src/optimizer/core/src/fixtures/index.qwik.mjs index 3bbcd0aab36..70f66f48220 100644 --- a/packages/qwik/src/optimizer/core/src/fixtures/index.qwik.mjs +++ b/packages/qwik/src/optimizer/core/src/fixtures/index.qwik.mjs @@ -1,41 +1,38 @@ +import * as qwikRouterConfig from '@qwik-router-config'; +import swRegister from '@qwik-router-sw-register'; import { - createContextId, - componentQrl, - inlinedQrl, + _deserializeData, + _fnSignal, + _getContextElement, _jsxBranch, - useOnDocument, + _jsxSplit, + _restProps, + _serializeData, + _weakSerialize, + _wrapSignal, + componentQrl, + createContextId, eventQrl, - useContext, - _jsxC, - SkipRender, - withLocale, - _deserializeData, + getLocale, + implicit$FirstArg, + inlinedQrl, noSerialize, + SkipRender, + Slot, + untrack, + useContext, + useContextProvider, + useLexicalScope, + useOnDocument, useServerData, - useStylesQrl, - useStore, - _weakSerialize, useSignal, - useLexicalScope, - _getContextElement, - useContextProvider, + useStore, + useStylesQrl, useTaskQrl, - Slot, - getLocale, - untrack, - _jsxS, - _jsxQ, - _wrapSignal, - implicit$FirstArg, - _serializeData, - _restProps, - _fnSignal, -} from '@builder.io/qwik'; -import { isBrowser, isServer, isDev } from '@builder.io/qwik/build'; -import * as qwikCity from '@qwik-city-plan'; -import swRegister from '@qwik-city-sw-register'; -import { z } from 'zod'; -import { z as z2 } from 'zod'; + withLocale, +} from '@qwik.dev/core'; +import { isBrowser, isDev, isServer } from '@qwik.dev/core/build'; +import { z, z as z2 } from 'zod'; const RouteStateContext = /* @__PURE__ */ createContextId('qc-s'); const ContentContext = /* @__PURE__ */ createContextId('qc-c'); const ContentInternalContext = /* @__PURE__ */ createContextId('qc-ic'); @@ -50,8 +47,8 @@ const RouterOutlet = /* @__PURE__ */ componentQrl( 'qinit', eventQrl( /* @__PURE__ */ inlinedQrl(() => { - const POPSTATE_FALLBACK_INITIALIZED = '_qCityPopstateFallback'; - const CLIENT_HISTORY_INITIALIZED = '_qCityHistory'; + const POPSTATE_FALLBACK_INITIALIZED = '_qRouterPopstateFallback'; + const CLIENT_HISTORY_INITIALIZED = '_qRouterHistory'; if (!window[POPSTATE_FALLBACK_INITIALIZED]) { window[POPSTATE_FALLBACK_INITIALIZED] = () => { if (!window[CLIENT_HISTORY_INITIALIZED]) location.reload(); @@ -68,7 +65,7 @@ const RouterOutlet = /* @__PURE__ */ componentQrl( const contentsLen = context.value.length; let cmp = null; for (let i = contentsLen - 1; i >= 0; i--) - cmp = _jsxC( + cmp = _jsxSplit( context.value[i].default, { children: cmp, @@ -121,8 +118,8 @@ const clientNavigate = (win, newUrl, routeNavigate) => { handleScroll(win, currentUrl, newUrl); win.history.pushState('', '', toPath(newUrl)); } - if (!win._qCityHistory) { - win._qCityHistory = 1; + if (!win._qRouterHistory) { + win._qRouterHistory = 1; win.addEventListener('popstate', () => { const currentUrl2 = win.location; const previousUrl = toUrl(routeNavigate.value, currentUrl2); @@ -131,7 +128,7 @@ const clientNavigate = (win, newUrl, routeNavigate) => { routeNavigate.value = toPath(new URL(currentUrl2.href)); } }); - win.removeEventListener('popstate', win._qCityPopstateFallback); + win.removeEventListener('popstate', win._qRouterPopstateFallback); } }; const handleScroll = async (win, previousUrl, newUrl) => { @@ -373,17 +370,17 @@ const useDocumentHead = () => useContext(DocumentHeadContext); const useLocation = () => useContext(RouteLocationContext); const useNavigate = () => useContext(RouteNavigateContext); const useAction = () => useContext(RouteActionContext); -const useQwikCityEnv = () => noSerialize(useServerData('qwikcity')); -const QwikCityProvider = /* @__PURE__ */ componentQrl( +const useQwikRouterEnv = () => noSerialize(useServerData('qwikrouter')); +const QwikRouterProvider = /* @__PURE__ */ componentQrl( /* @__PURE__ */ inlinedQrl((props) => { useStylesQrl( /* @__PURE__ */ inlinedQrl( `:root{view-transition-name: none}`, - 'QwikCityProvider_component_useStyles_RPDJAz33WLA' + 'QwikRouterProvider_component_useStyles_RPDJAz33WLA' ) ); - const env = useQwikCityEnv(); - if (!env?.params) throw new Error(`Missing Qwik City Env Data`); + const env = useQwikRouterEnv(); + if (!env?.params) throw new Error(`Missing Qwik Router Env Data`); const urlEnv = useServerData('url'); if (!urlEnv) throw new Error(`Missing Qwik URL Env Data`); const url = new URL(urlEnv); @@ -437,12 +434,17 @@ const QwikCityProvider = /* @__PURE__ */ componentQrl( navPath2.value = path; if (isBrowser) { loadClientData(resolvedURL, _getContextElement()); - loadRoute(qwikCity.routes, qwikCity.menus, qwikCity.cacheModules, resolvedURL.pathname); + loadRoute( + qwikRouterConfig.routes, + qwikRouterConfig.menus, + qwikRouterConfig.cacheModules, + resolvedURL.pathname + ); } actionState2.value = void 0; routeLocation2.isNavigating = true; }, - 'QwikCityProvider_component_goto_event_cBcjROynRVg', + 'QwikRouterProvider_component_goto_event_cBcjROynRVg', [actionState, navPath, routeLocation] ) ); @@ -481,12 +483,13 @@ const QwikCityProvider = /* @__PURE__ */ componentQrl( } else { trackUrl = new URL(path, location); if (trackUrl.pathname.endsWith('/')) { - if (!qwikCity.trailingSlash) trackUrl.pathname = trackUrl.pathname.slice(0, -1); - } else if (qwikCity.trailingSlash) trackUrl.pathname += '/'; + if (!qwikRouterConfig.trailingSlash) + trackUrl.pathname = trackUrl.pathname.slice(0, -1); + } else if (qwikRouterConfig.trailingSlash) trackUrl.pathname += '/'; let loadRoutePromise = loadRoute( - qwikCity.routes, - qwikCity.menus, - qwikCity.cacheModules, + qwikRouterConfig.routes, + qwikRouterConfig.menus, + qwikRouterConfig.cacheModules, trackUrl.pathname ); const element = _getContextElement(); @@ -505,9 +508,9 @@ const QwikCityProvider = /* @__PURE__ */ componentQrl( if (newURL.pathname !== trackUrl.pathname) { trackUrl = newURL; loadRoutePromise = loadRoute( - qwikCity.routes, - qwikCity.menus, - qwikCity.cacheModules, + qwikRouterConfig.routes, + qwikRouterConfig.menus, + qwikRouterConfig.cacheModules, trackUrl.pathname ); } @@ -554,7 +557,7 @@ const QwikCityProvider = /* @__PURE__ */ componentQrl( if (isServer) return promise; else return; }, - 'QwikCityProvider_component_useTask_02wMImzEAbk', + 'QwikRouterProvider_component_useTask_02wMImzEAbk', [ actionState, content, @@ -569,10 +572,10 @@ const QwikCityProvider = /* @__PURE__ */ componentQrl( ] ) ); - return /* @__PURE__ */ _jsxC(Slot, null, 3, 'qY_0'); - }, 'QwikCityProvider_component_TxCFOy819ag') + return /* @__PURE__ */ _jsxSplit(Slot, null, 3, 'qY_0'); + }, 'QwikRouterProvider_component_TxCFOy819ag') ); -const QwikCityMockProvider = /* @__PURE__ */ componentQrl( +const QwikRouterMockProvider = /* @__PURE__ */ componentQrl( /* @__PURE__ */ inlinedQrl((props) => { const urlEnv = props.url ?? 'http://localhost/'; const url = new URL(urlEnv); @@ -589,7 +592,7 @@ const QwikCityMockProvider = /* @__PURE__ */ componentQrl( const loaderState = useSignal({}); const goto = /* @__PURE__ */ inlinedQrl(async (path) => { throw new Error('Not implemented'); - }, 'QwikCityMockProvider_component_goto_BUbtvTyvVRE'); + }, 'QwikRouterMockProvider_component_goto_BUbtvTyvVRE'); const documentHead = useStore(createDocumentHead, { deep: false, }); @@ -609,8 +612,8 @@ const QwikCityMockProvider = /* @__PURE__ */ componentQrl( useContextProvider(RouteLocationContext, routeLocation); useContextProvider(RouteNavigateContext, goto); useContextProvider(RouteStateContext, loaderState); - return /* @__PURE__ */ _jsxC(Slot, null, 3, 'qY_1'); - }, 'QwikCityMockProvider_component_WmYC5H00wtI') + return /* @__PURE__ */ _jsxSplit(Slot, null, 3, 'qY_1'); + }, 'QwikRouterMockProvider_component_WmYC5H00wtI') ); const Link = /* @__PURE__ */ componentQrl( /* @__PURE__ */ inlinedQrl((props) => { @@ -630,12 +633,12 @@ const Link = /* @__PURE__ */ componentQrl( 'Link_component_event_event_5g4B0Gd1Wck' ) ); - return /* @__PURE__ */ _jsxS( + return /* @__PURE__ */ _jsxSplit( 'a', { ...linkProps, 'data-prefetch': prefetchDataset, - children: /* @__PURE__ */ _jsxC(Slot, null, 3, 'AD_0'), + children: /* @__PURE__ */ _jsxSplit(Slot, null, null, 3, 'AD_0'), onClick$: /* @__PURE__ */ inlinedQrl( (_, elm) => { const [nav2, reload2] = useLexicalScope(); @@ -663,15 +666,13 @@ const prefetchLinkResources = (elm, isOnVisible) => { }; let windowInnerWidth = 0; const ServiceWorkerRegister = (props) => - _jsxQ( + _jsxSplit( 'script', + null, { nonce: _wrapSignal(props, 'nonce'), - }, - { dangerouslySetInnerHTML: swRegister, }, - null, 3, '1Z_0' ); @@ -784,7 +785,7 @@ const routeLoaderQrl = (loaderQrl, ...rest) => { if (!(id in state)) throw new Error(`Loader (${id}) was used in a path where the 'loader$' was not declared. This is likely because the used loader was not exported in a layout.tsx or index.tsx file of the existing route. - For more information check: https://qwik.dev/qwikcity/route-loader/`); + For more information check: https://qwik.dev/docs/route-loader/`); return _wrapSignal(state, id); }); } @@ -846,7 +847,7 @@ const serverQrl = (qrl) => { async (...args) => { const [qrl2] = useLexicalScope(); if (isServer) { - const requestEvent = useQwikCityEnv()?.ev; + const requestEvent = useQwikRouterEnv()?.ev; return qrl2.apply(requestEvent, args); } else { const ctxElm = _getContextElement(); @@ -965,7 +966,7 @@ async function* streamAsyncIterator(stream, ctxElm) { const Form = ({ action, spaReset, reloadDocument, onSubmit$, ...rest }, key) => { _jsxBranch(); if (action) - return _jsxS( + return _jsxSplit( 'form', { ...rest, @@ -981,7 +982,7 @@ const Form = ({ action, spaReset, reloadDocument, onSubmit$, ...rest }, key) => key ); else - return /* @__PURE__ */ _jsxC( + return /* @__PURE__ */ _jsxSplit( GetForm, { spaReset, @@ -997,11 +998,11 @@ const GetForm = /* @__PURE__ */ componentQrl( /* @__PURE__ */ inlinedQrl((props) => { const rest = _restProps(props, ['action', 'spaReset', 'reloadDocument', 'onSubmit$']); const nav = useNavigate(); - return /* @__PURE__ */ _jsxS( + return /* @__PURE__ */ _jsxSplit( 'form', { ...rest, - children: /* @__PURE__ */ _jsxC(Slot, null, 3, 'BC_0'), + children: /* @__PURE__ */ _jsxSplit(Slot, null, 3, 'BC_0'), onSubmit$: /* @__PURE__ */ inlinedQrl( async (_, form) => { const [nav2] = useLexicalScope(); @@ -1048,19 +1049,19 @@ const GetForm = /* @__PURE__ */ componentQrl( ); export { Form, - Link, - QwikCityMockProvider, - QwikCityProvider, - RouterOutlet, - ServiceWorkerRegister, globalAction$, globalActionQrl, + Link, + QwikRouterMockProvider, + QwikRouterProvider as QwikRouterProvider, routeAction$, routeActionQrl, routeLoader$, routeLoaderQrl, + RouterOutlet, server$, serverQrl, + ServiceWorkerRegister, useContent, useDocumentHead, useLocation, diff --git a/packages/qwik/src/optimizer/core/src/has_branches.rs b/packages/qwik/src/optimizer/core/src/has_branches.rs deleted file mode 100644 index 42b4ece909f..00000000000 --- a/packages/qwik/src/optimizer/core/src/has_branches.rs +++ /dev/null @@ -1,143 +0,0 @@ -use std::collections::HashSet; - -use crate::collector::Id; -use swc_ecmascript::ast; -use swc_ecmascript::visit::{noop_visit_type, Visit, VisitWith}; - -macro_rules! id { - ($ident: expr) => { - ($ident.sym.clone(), $ident.ctxt) - }; -} - -pub fn is_conditional_jsx( - expr: &ast::BlockStmtOrExpr, - jsx_functions: &HashSet, - immutable_function_cmp: &HashSet, -) -> bool { - let mut collector = HasBranches::new(jsx_functions, immutable_function_cmp); - expr.visit_with(&mut collector); - collector.conditional -} - -pub fn is_conditional_jsx_block( - expr: &ast::BlockStmt, - jsx_functions: &HashSet, - immutable_function_cmp: &HashSet, -) -> bool { - let mut collector = HasBranches::new(jsx_functions, immutable_function_cmp); - expr.visit_with(&mut collector); - collector.conditional -} - -pub struct HasBranches<'a> { - under_conditional: i32, - jsx_functions: &'a HashSet, - immutable_function_cmp: &'a HashSet, - conditional: bool, - found_return: bool, -} - -impl<'a> HasBranches<'a> { - const fn new(jsx_functions: &'a HashSet, immutable_function_cmp: &'a HashSet) -> Self { - Self { - jsx_functions, - immutable_function_cmp, - under_conditional: 0, - conditional: false, - found_return: false, - } - } -} - -impl<'a> Visit for HasBranches<'a> { - noop_visit_type!(); - - fn visit_arrow_expr(&mut self, _: &ast::ArrowExpr) {} - fn visit_fn_expr(&mut self, _: &ast::FnExpr) {} - fn visit_fn_decl(&mut self, _: &ast::FnDecl) {} - - fn visit_return_stmt(&mut self, node: &ast::ReturnStmt) { - node.visit_children_with(self); - self.found_return = true; - } - - fn visit_for_in_stmt(&mut self, node: &ast::ForInStmt) { - self.under_conditional += 1; - node.visit_children_with(self); - self.under_conditional -= 1; - } - - fn visit_for_of_stmt(&mut self, node: &ast::ForOfStmt) { - self.under_conditional += 1; - node.visit_children_with(self); - self.under_conditional -= 1; - } - - fn visit_for_stmt(&mut self, node: &ast::ForStmt) { - self.under_conditional += 1; - node.visit_children_with(self); - self.under_conditional -= 1; - } - - fn visit_if_stmt(&mut self, node: &ast::IfStmt) { - self.under_conditional += 1; - node.visit_children_with(self); - self.under_conditional -= 1; - } - - fn visit_while_stmt(&mut self, node: &ast::WhileStmt) { - self.under_conditional += 1; - node.visit_children_with(self); - self.under_conditional -= 1; - } - - fn visit_do_while_stmt(&mut self, node: &ast::DoWhileStmt) { - self.under_conditional += 1; - node.visit_children_with(self); - self.under_conditional -= 1; - } - - fn visit_switch_stmt(&mut self, node: &ast::SwitchStmt) { - self.under_conditional += 1; - node.visit_children_with(self); - self.under_conditional -= 1; - } - - fn visit_cond_expr(&mut self, node: &ast::CondExpr) { - self.under_conditional += 1; - node.visit_children_with(self); - self.under_conditional -= 1; - } - - fn visit_bin_expr(&mut self, node: &ast::BinExpr) { - if matches!( - node.op, - ast::BinaryOp::LogicalAnd | ast::BinaryOp::LogicalOr | ast::BinaryOp::NullishCoalescing - ) { - self.under_conditional += 1; - node.visit_children_with(self); - self.under_conditional -= 1; - } else { - node.visit_children_with(self); - } - } - - fn visit_call_expr(&mut self, node: &ast::CallExpr) { - if self.under_conditional > 0 || self.found_return { - if let ast::Callee::Expr(box ast::Expr::Ident(ident)) = &node.callee { - if self.jsx_functions.contains(&id!(ident)) { - let first_arg = node.args.first(); - if let Some(name) = first_arg { - if let ast::Expr::Ident(jsx_id) = &*name.expr { - if !self.immutable_function_cmp.contains(&id!(jsx_id)) { - self.conditional = true; - } - } - } - } - } - } - node.visit_children_with(self); - } -} diff --git a/packages/qwik/src/optimizer/core/src/inlined_fn.rs b/packages/qwik/src/optimizer/core/src/inlined_fn.rs index 0162a9b8d76..3139fc19d07 100644 --- a/packages/qwik/src/optimizer/core/src/inlined_fn.rs +++ b/packages/qwik/src/optimizer/core/src/inlined_fn.rs @@ -8,6 +8,7 @@ use swc_ecmascript::ast; use swc_ecmascript::codegen::text_writer::JsWriter; use swc_ecmascript::transforms::fixer; use swc_ecmascript::transforms::hygiene::hygiene_with_config; +use swc_ecmascript::visit::{Visit, VisitWith}; use swc_ecmascript::{ utils::private_ident, visit::{VisitMut, VisitMutWith}, @@ -19,12 +20,14 @@ macro_rules! id { }; } +// This generates the `_fnSignal` function call in JSX pub fn convert_inlined_fn( mut expr: ast::Expr, scoped_idents: Vec, qqsegment: &Id, accept_call_expr: bool, serialize_fn: bool, + is_const: bool, ) -> (Option, bool) { let mut identifiers = HashMap::new(); let params: Vec = scoped_idents @@ -41,7 +44,11 @@ pub fn convert_inlined_fn( .collect(); if matches!(expr, ast::Expr::Arrow(_)) { - return (None, false); + return (None, is_const); + } + + if !is_used_as_object(&expr, &scoped_idents) { + return (None, is_const); } // Replace identifier @@ -49,11 +56,13 @@ pub fn convert_inlined_fn( expr.visit_mut_with(&mut replace_identifiers); if replace_identifiers.abort { - return (None, false); + return (None, is_const); } let rendered_expr = render_expr(&expr); if rendered_expr.len() > 150 { + // It isn't guaranteed const if we don't wrap it + // TODO make this be a wrapped computedsignal? return (None, false); } @@ -97,7 +106,7 @@ pub fn convert_inlined_fn( args, ..Default::default() })), - true, + is_const, ) } @@ -198,3 +207,33 @@ pub fn render_expr(expr: &ast::Expr) -> String { .trim_end_matches(';') .to_string() } + +struct ObjectUsageChecker<'a> { + identifiers: &'a Vec, + used_as_object: bool, +} + +impl<'a> Visit for ObjectUsageChecker<'a> { + fn visit_member_expr(&mut self, node: &ast::MemberExpr) { + if let ast::Expr::Ident(obj_ident) = &*node.obj { + for id in self.identifiers { + if obj_ident.sym == id.0 { + self.used_as_object = true; + return; + } + } + } + node.visit_children_with(self); + } +} + +fn is_used_as_object(expr: &ast::Expr, identifiers: &Vec) -> bool { + let mut checker = ObjectUsageChecker { + identifiers, + used_as_object: false, + }; + + expr.visit_with(&mut checker); + + checker.used_as_object +} diff --git a/packages/qwik/src/optimizer/core/src/is_const.rs b/packages/qwik/src/optimizer/core/src/is_const.rs new file mode 100644 index 00000000000..c7a3f296dc0 --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/is_const.rs @@ -0,0 +1,74 @@ +use crate::collector::GlobalCollect; +use crate::transform::{IdPlusType, IdentType}; +use swc_ecmascript::ast; +use swc_ecmascript::visit::{noop_visit_type, Visit}; + +macro_rules! id { + ($ident: expr) => { + ($ident.sym.clone(), $ident.ctxt) + }; +} + +pub fn is_const_expr( + expr: &ast::Expr, + global: &GlobalCollect, + current_stack: Option<&Vec>, +) -> bool { + let mut collector = ConstCollector::new(global, current_stack); + collector.visit_expr(expr); + collector.is_const +} + +pub struct ConstCollector<'a> { + global: &'a GlobalCollect, + const_idents: Option<&'a Vec>, + + pub is_const: bool, +} + +impl<'a> ConstCollector<'a> { + const fn new(global: &'a GlobalCollect, const_idents: Option<&'a Vec>) -> Self { + Self { + global, + is_const: true, + const_idents, + } + } +} + +// A prop is considered var if it: +// - calls a function +// - accesses a member +// - is a variable that is not an import, an export, or in the const stack +impl<'a> Visit for ConstCollector<'a> { + noop_visit_type!(); + + fn visit_call_expr(&mut self, _: &ast::CallExpr) { + self.is_const = false; + } + + fn visit_member_expr(&mut self, _: &ast::MemberExpr) { + self.is_const = false; + } + + fn visit_arrow_expr(&mut self, _: &ast::ArrowExpr) {} + + fn visit_ident(&mut self, ident: &ast::Ident) { + let id = id!(ident); + if self.global.imports.contains_key(&id) { + return; + } + if self.global.exports.contains_key(&id) { + return; + } + if let Some(current_stack) = self.const_idents { + if current_stack + .iter() + .any(|item| item.1 == IdentType::Var(true) && item.0 == id) + { + return; + } + } + self.is_const = false; + } +} diff --git a/packages/qwik/src/optimizer/core/src/is_immutable.rs b/packages/qwik/src/optimizer/core/src/is_immutable.rs deleted file mode 100644 index 2c68736eed6..00000000000 --- a/packages/qwik/src/optimizer/core/src/is_immutable.rs +++ /dev/null @@ -1,74 +0,0 @@ -use crate::collector::GlobalCollect; -use crate::transform::{IdPlusType, IdentType}; -use swc_ecmascript::ast; -use swc_ecmascript::visit::{noop_visit_type, Visit}; - -macro_rules! id { - ($ident: expr) => { - ($ident.sym.clone(), $ident.ctxt) - }; -} - -pub fn is_immutable_expr( - expr: &ast::Expr, - global: &GlobalCollect, - current_stack: Option<&Vec>, -) -> bool { - let mut collector = ImmutableCollector::new(global, current_stack); - collector.visit_expr(expr); - collector.is_immutable -} - -pub struct ImmutableCollector<'a> { - global: &'a GlobalCollect, - immutable_idents: Option<&'a Vec>, - - pub is_immutable: bool, -} - -impl<'a> ImmutableCollector<'a> { - const fn new(global: &'a GlobalCollect, immutable_idents: Option<&'a Vec>) -> Self { - Self { - global, - is_immutable: true, - immutable_idents, - } - } -} - -// A prop is considered mutable if it: -// - calls a function -// - accesses a member -// - is a variable that is not an import, an export, or in the immutable stack -impl<'a> Visit for ImmutableCollector<'a> { - noop_visit_type!(); - - fn visit_call_expr(&mut self, _: &ast::CallExpr) { - self.is_immutable = false; - } - - fn visit_member_expr(&mut self, _: &ast::MemberExpr) { - self.is_immutable = false; - } - - fn visit_arrow_expr(&mut self, _: &ast::ArrowExpr) {} - - fn visit_ident(&mut self, ident: &ast::Ident) { - let id = id!(ident); - if self.global.imports.contains_key(&id) { - return; - } - if self.global.exports.contains_key(&id) { - return; - } - if let Some(current_stack) = self.immutable_idents { - if current_stack - .iter() - .any(|item| item.1 == IdentType::Var(true) && item.0 == id) - { - return; - } - } - self.is_immutable = false; - } -} diff --git a/packages/qwik/src/optimizer/core/src/lib.rs b/packages/qwik/src/optimizer/core/src/lib.rs index f49be1472d1..46601c896ba 100644 --- a/packages/qwik/src/optimizer/core/src/lib.rs +++ b/packages/qwik/src/optimizer/core/src/lib.rs @@ -8,6 +8,7 @@ #[cfg(test)] mod test; +mod add_locs; mod add_side_effect; mod clean_side_effects; mod code_move; @@ -16,25 +17,16 @@ mod const_replace; mod entry_strategy; mod errors; mod filter_exports; -mod has_branches; mod inlined_fn; -mod is_immutable; -mod package_json; +mod is_const; mod parse; mod props_destructuring; +mod rename_imports; mod transform; mod utils; mod words; -#[cfg(feature = "parallel")] -use rayon::prelude::*; - -#[cfg(feature = "parallel")] -use anyhow::Context; -use words::BUILDER_IO_QWIK; - -#[cfg(feature = "fs")] -use std::fs; +use words::QWIK_CORE; use anyhow::Error; use serde::{Deserialize, Serialize}; @@ -49,33 +41,6 @@ use crate::parse::{transform_code, TransformCodeOptions}; pub use crate::parse::{ ErrorBuffer, MinifyMode, SegmentAnalysis, TransformModule, TransformOutput, }; - -#[cfg(feature = "fs")] -#[derive(Serialize, Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct TransformFsOptions { - pub src_dir: String, - pub root_dir: Option, - pub vendor_roots: Vec, - pub glob: Option, - pub minify: MinifyMode, - pub entry_strategy: EntryStrategy, - pub source_maps: bool, - pub transpile_ts: bool, - pub transpile_jsx: bool, - pub preserve_filenames: bool, - pub explicit_extensions: bool, - pub mode: EmitMode, - pub scope: Option, - - pub core_module: Option, - pub strip_exports: Option>, - pub strip_ctx_name: Option>, - pub strip_event_handlers: bool, - pub reg_ctx_name: Option>, - pub is_server: Option, -} - #[derive(Serialize, Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub struct TransformModuleInput { @@ -108,73 +73,13 @@ pub struct TransformModulesOptions { pub is_server: Option, } -#[cfg(feature = "fs")] -pub fn transform_fs(config: TransformFsOptions) -> Result { - let core_module = config - .core_module - .map_or(BUILDER_IO_QWIK.clone(), |s| s.into()); - let src_dir = Path::new(&config.src_dir); - let root_dir = config.root_dir.as_ref().map(Path::new); - - let mut paths = vec![]; - let entry_policy = &*parse_entry_strategy(&config.entry_strategy); - crate::package_json::find_modules(src_dir, config.vendor_roots, &mut paths)?; - - #[cfg(feature = "parallel")] - let iterator = paths.par_iter(); - - #[cfg(not(feature = "parallel"))] - let iterator = paths.iter(); - let mut final_output = iterator - .map(|path| -> Result { - let code = fs::read_to_string(path) - .with_context(|| format!("Opening {}", &path.to_string_lossy()))?; - - let relative_path = pathdiff::diff_paths(path, &config.src_dir).unwrap(); - transform_code(TransformCodeOptions { - src_dir, - root_dir, - relative_path: relative_path.to_str().unwrap(), - dev_path: None, - minify: config.minify, - code: &code, - explicit_extensions: config.explicit_extensions, - source_maps: config.source_maps, - transpile_jsx: config.transpile_jsx, - transpile_ts: config.transpile_ts, - preserve_filenames: config.preserve_filenames, - scope: config.scope.as_ref(), - entry_policy, - mode: config.mode, - core_module: core_module.clone(), - entry_strategy: config.entry_strategy, - reg_ctx_name: config.reg_ctx_name.as_deref(), - strip_exports: config.strip_exports.as_deref(), - strip_ctx_name: config.strip_ctx_name.as_deref(), - strip_event_handlers: config.strip_event_handlers, - // If you don't specify is_server, the safe value is true - is_server: config.is_server.unwrap_or(true), - }) - }) - .reduce(|| Ok(TransformOutput::new()), |x, y| Ok(x?.append(&mut y?)))?; - - final_output.modules.sort_unstable_by_key(|key| key.order); - - Ok(final_output) -} - pub fn transform_modules(config: TransformModulesOptions) -> Result { - let core_module = config - .core_module - .map_or(BUILDER_IO_QWIK.clone(), |s| s.into()); + let core_module = config.core_module.map_or(QWIK_CORE.clone(), |s| s.into()); let src_dir = std::path::Path::new(&config.src_dir); let root_dir = config.root_dir.as_ref().map(Path::new); let entry_policy = &*parse_entry_strategy(&config.entry_strategy); - #[cfg(feature = "parallel")] - let iterator = config.input.par_iter(); - #[cfg(not(feature = "parallel"))] let iterator = config.input.iter(); let iterator = iterator.map(|input| -> Result { @@ -204,11 +109,6 @@ pub fn transform_modules(config: TransformModulesOptions) -> Result = - iterator.reduce(|| Ok(TransformOutput::new()), |x, y| Ok(x?.append(&mut y?))); - - #[cfg(not(feature = "parallel"))] #[allow(clippy::manual_try_fold)] let final_output: Result = iterator.fold(Ok(TransformOutput::new()), |x, y| Ok(x?.append(&mut y?))); diff --git a/packages/qwik/src/optimizer/core/src/package_json.rs b/packages/qwik/src/optimizer/core/src/package_json.rs deleted file mode 100644 index 5dc9242bc1a..00000000000 --- a/packages/qwik/src/optimizer/core/src/package_json.rs +++ /dev/null @@ -1,38 +0,0 @@ -#[cfg(feature = "fs")] -pub fn find_modules( - src_dir: &std::path::Path, - vendor_dirs: Vec, - files: &mut Vec, -) -> std::io::Result<()> { - for root in &vendor_dirs { - find_files(std::path::Path::new(root), files)?; - } - find_files(src_dir, files) -} - -#[cfg(feature = "fs")] -fn find_files(dir: &std::path::Path, files: &mut Vec) -> std::io::Result<()> { - if dir.is_dir() { - for entry in std::fs::read_dir(dir)? { - let entry = entry?; - let path = entry.path(); - if path.is_dir() { - find_files(&path, files)?; - } else if should_capture_file(&path) { - files.push(path); - } - } - } else if should_capture_file(dir) { - files.push(dir.to_path_buf()); - } - Ok(()) -} - -#[cfg(feature = "fs")] -fn should_capture_file(path: &std::path::Path) -> bool { - let ext = path.extension().and_then(|p| p.to_str()); - matches!( - ext, - Some("ts" | "tsx" | "js" | "jsx" | "mjs" | "mts" | "mtsx" | "mjsx") - ) -} diff --git a/packages/qwik/src/optimizer/core/src/parse.rs b/packages/qwik/src/optimizer/core/src/parse.rs index 2bdea66400d..917b2e7a9fa 100644 --- a/packages/qwik/src/optimizer/core/src/parse.rs +++ b/packages/qwik/src/optimizer/core/src/parse.rs @@ -5,6 +5,7 @@ use std::hash::Hasher; use std::path::{Component, Path, PathBuf}; use std::str; +use crate::add_locs::AddLocs; use crate::add_side_effect::SideEffectVisitor; use crate::clean_side_effects::Treeshaker; use crate::code_move::{new_module, NewModuleCtx}; @@ -13,20 +14,20 @@ use crate::const_replace::ConstReplacerVisitor; use crate::entry_strategy::EntryPolicy; use crate::filter_exports::StripExportsVisitor; use crate::props_destructuring::transform_props_destructuring; +use crate::rename_imports::RenameTransform; use crate::transform::{QwikTransform, QwikTransformOptions, Segment, SegmentKind}; use crate::utils::{Diagnostic, DiagnosticCategory, DiagnosticScope, SourceLocation}; +use crate::words::{QWIK_CORE_INTERNAL, _ADD_LOC}; use crate::EntryStrategy; use path_slash::PathExt; use serde::{Deserialize, Serialize}; -#[cfg(feature = "fs")] -use std::fs; - use anyhow::{Context, Error}; use swc_atoms::JsWord; use swc_common::comments::SingleThreadedComments; use swc_common::errors::{DiagnosticBuilder, DiagnosticId, Emitter, Handler}; +use swc_common::DUMMY_SP; use swc_common::{sync::Lrc, FileName, Globals, Mark, SourceMap}; use swc_ecmascript::ast; use swc_ecmascript::codegen::text_writer::JsWriter; @@ -53,6 +54,10 @@ pub struct SegmentAnalysis { pub ctx_name: JsWord, pub captures: bool, pub loc: (u32, u32), + #[serde(skip_serializing_if = "Option::is_none")] + pub param_names: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub capture_names: Option>, } #[derive(Debug, Serialize, Deserialize, Copy, Clone, PartialEq, Eq)] @@ -164,28 +169,6 @@ impl TransformOutput { } manifest } - - #[cfg(feature = "fs")] - pub fn write_to_fs( - &self, - destination: &Path, - manifest: Option, - ) -> Result { - for module in &self.modules { - let write_path = destination.join(&module.path); - fs::create_dir_all(write_path.parent().with_context(|| { - format!("Computing path parent of {}", write_path.to_string_lossy()) - })?)?; - fs::write(write_path, &module.code)?; - } - if let Some(manifest) = manifest { - let write_path = destination.join(manifest); - let manifest = self.get_manifest(); - let json = serde_json::to_string(&manifest)?; - fs::write(write_path, json)?; - } - Ok(self.modules.len()) - } } #[derive(Debug, Serialize, Deserialize, Default)] @@ -273,7 +256,7 @@ pub fn transform_code(config: TransformCodeOptions) -> Result Result Result Result Result Result Err(err), - Ok(result) => Ok((result, comments, is_type_script, is_jsx)), + Ok(mut program) => { + let file_name = path_data.rel_path.to_slash_lossy().to_string(); + let mut add_locs = AddLocs::new(&source_map, file_name); + program.visit_mut_with(&mut add_locs); + + if add_locs.did_add_loc { + if let ast::Program::Module(module) = &mut program { + let import_decl = + ast::ModuleItem::ModuleDecl(ast::ModuleDecl::Import(ast::ImportDecl { + span: DUMMY_SP, + specifiers: vec![ast::ImportSpecifier::Named( + ast::ImportNamedSpecifier { + local: ast::Ident::new( + _ADD_LOC.clone(), + DUMMY_SP, + swc_common::SyntaxContext::empty(), + ), + imported: None, + span: DUMMY_SP, + is_type_only: false, + }, + )], + src: Box::new(ast::Str { + span: DUMMY_SP, + value: QWIK_CORE_INTERNAL.clone(), + raw: None, + }), + type_only: false, + with: None, + phase: ast::ImportPhase::Evaluation, + })); + module.body.insert(0, import_decl); + } + } + Ok((program, comments, is_type_script, is_jsx)) + } } } @@ -767,13 +811,3 @@ pub fn normalize_path>(path: P) -> PathBuf { } normalized } - -pub fn might_need_handle_watch(ctx_kind: &SegmentKind, ctx_name: &str) -> bool { - if !matches!(ctx_kind, SegmentKind::Function) { - return false; - } - matches!( - ctx_name, - "useTask$" | "useVisibleTask$" | "useBrowserVisibleTask$" | "useClientEffect$" | "$" - ) -} diff --git a/packages/qwik/src/optimizer/core/src/props_destructuring.rs b/packages/qwik/src/optimizer/core/src/props_destructuring.rs index eb49eaa7aa1..5fe5ebab9f2 100644 --- a/packages/qwik/src/optimizer/core/src/props_destructuring.rs +++ b/packages/qwik/src/optimizer/core/src/props_destructuring.rs @@ -2,8 +2,9 @@ use std::collections::HashMap; use crate::code_move::create_return_stmt; use crate::collector::{new_ident_from_id, GlobalCollect, Id}; -use crate::is_immutable::is_immutable_expr; +use crate::is_const::is_const_expr; use crate::words::*; +use swc_atoms::Atom; use swc_atoms::JsWord; use swc_common::DUMMY_SP; use swc_ecmascript::ast; @@ -238,6 +239,27 @@ impl<'a> PropsDestructuring<'a> { } impl<'a> VisitMut for PropsDestructuring<'a> { + fn visit_mut_arrow_expr(&mut self, node: &mut ast::ArrowExpr) { + if node.params.len() == 1 { + // probably an inline component + if matches!( + &node.body, + box ast::BlockStmtOrExpr::Expr(box ast::Expr::Call(_)) + ) { + // function without return statement + self.transform_component_props(node); + } else if matches!( + &node.body, + box ast::BlockStmtOrExpr::BlockStmt(ast::BlockStmt { stmts, .. }) + if stmts.iter().any(|stmt| matches!(stmt, ast::Stmt::Return(_))) + ) { + // function with return statement + self.transform_component_props(node); + } + } + node.visit_mut_children_with(self); + } + fn visit_mut_call_expr(&mut self, node: &mut ast::CallExpr) { if let ast::Callee::Expr(box ast::Expr::Ident(ref ident)) = &node.callee { if id_eq!(ident, &self.component_ident) { @@ -296,7 +318,7 @@ fn transform_pat( span: DUMMY_SP, }); if let Some(value) = &v.value { - if is_immutable_expr(value.as_ref(), props_transform.global_collect, None) { + if is_const_expr(value.as_ref(), props_transform.global_collect, None) { local.push(( id!(v.key), v.key.sym.clone(), @@ -315,34 +337,54 @@ fn transform_pat( } } ast::ObjectPatProp::KeyValue(ref v) => { - if let ast::PropName::Ident(ref key) = v.key { + if matches!(v.key, ast::PropName::Ident(_) | ast::PropName::Str(_)) { + let (key_atom, prop) = match &v.key { + ast::PropName::Str(ref key) => { + let key_str: &str = &key.value; + let key_atom = Atom::from(key_str); + ( + key_atom.clone(), + ast::MemberProp::Computed(ast::ComputedPropName { + span: DUMMY_SP, + expr: Box::new(ast::Expr::Lit(ast::Lit::Str(ast::Str { + span: DUMMY_SP, + value: key_atom, + raw: None, + }))), + }), + ) + } + ast::PropName::Ident(ref key) => { + (key.sym.clone(), ast::MemberProp::Ident(key.clone())) + } + _ => { + continue; + } + }; match &v.value { box ast::Pat::Ident(ref ident) => { let access = ast::Expr::Member(ast::MemberExpr { obj: Box::new(new_ident.clone()), - prop: ast::MemberProp::Ident(key.clone()), + prop, span: DUMMY_SP, }); - local.push((id!(ident), key.sym.clone(), access)); + + local.push((id!(ident), key_atom.clone(), access)); } box ast::Pat::Assign(ast::AssignPat { left: box ast::Pat::Ident(ident), right: value, .. }) => { - if is_immutable_expr( - value.as_ref(), - props_transform.global_collect, - None, - ) { + if is_const_expr(value.as_ref(), props_transform.global_collect, None) { let access = ast::Expr::Member(ast::MemberExpr { obj: Box::new(new_ident.clone()), - prop: ast::MemberProp::Ident(key.clone()), + prop, span: DUMMY_SP, }); local.push(( id!(ident.id), - key.sym.clone(), + key_atom.clone(), ast::Expr::Bin(ast::BinExpr { span: DUMMY_SP, op: ast::BinaryOp::NullishCoalescing, diff --git a/packages/qwik/src/optimizer/core/src/rename_imports.rs b/packages/qwik/src/optimizer/core/src/rename_imports.rs new file mode 100644 index 00000000000..ccf05668fe9 --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/rename_imports.rs @@ -0,0 +1,17 @@ +/// Rename imports from @builder.io to @qwik.dev +use swc_ecmascript::ast; +use swc_ecmascript::visit::VisitMut; + +pub struct RenameTransform; + +impl VisitMut for RenameTransform { + fn visit_mut_import_decl(&mut self, node: &mut ast::ImportDecl) { + if node.src.value.starts_with("@builder.io/qwik-city") { + node.src.value = ("@qwik.dev/router".to_string() + &node.src.value[21..]).into(); + } else if node.src.value.starts_with("@builder.io/qwik-react") { + node.src.value = ("@qwik.dev/react".to_string() + &node.src.value[22..]).into(); + } else if node.src.value.starts_with("@builder.io/qwik") { + node.src.value = ("@qwik.dev/core".to_string() + &node.src.value[16..]).into(); + } + } +} diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_colon_props.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_colon_props.snap new file mode 100644 index 00000000000..18278f315de --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_colon_props.snap @@ -0,0 +1,64 @@ +--- +source: packages/qwik/src/optimizer/core/src/test.rs +assertion_line: 3715 +expression: output +snapshot_kind: text +--- +==INPUT== + + + import { component$ } from "@qwik.dev/core"; + export default component$((props) => { + const { 'bind:value': bindValue } = props; + return ( + <> + {bindValue} + + ); + }); + +============================= test.js == + +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +export default /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_test_component_LUXeXe0DQrg"), "test_component_LUXeXe0DQrg")); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAEE,6BAAe,mHAOZ\"}") +============================= test.tsx_test_component_LUXeXe0DQrg.js (ENTRY POINT)== + +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +export const test_component_LUXeXe0DQrg = (props)=>{ + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, _wrapProp(props, "bind:value"), 1, "u6_0"); +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;0CAE4B,CAAC;IAE1B,qBACC,4CAFmC;AAMrC\"}") +/* +{ + "origin": "test.tsx", + "name": "test_component_LUXeXe0DQrg", + "entry": null, + "displayName": "test.tsx_test_component", + "hash": "LUXeXe0DQrg", + "canonicalFilename": "test.tsx_test_component_LUXeXe0DQrg", + "path": "", + "extension": "js", + "parent": null, + "ctxKind": "function", + "ctxName": "component$", + "captures": false, + "loc": [ + 77, + 188 + ], + "paramNames": [ + "props" + ] +} +*/ +== DIAGNOSTICS == + +[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_colon_props2.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_colon_props2.snap new file mode 100644 index 00000000000..c8717ce6e9d --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_colon_props2.snap @@ -0,0 +1,68 @@ +--- +source: packages/qwik/src/optimizer/core/src/test.rs +assertion_line: 3736 +expression: output +snapshot_kind: text +--- +==INPUT== + + + import { component$, useSignal } from "@qwik.dev/core"; + export default component$((props) => { + const { 'bind:value': bindValue } = props; + const test = useSignal(bindValue); + return ( + <> + {test.value} + + ); + }); + +============================= test.js == + +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +export default /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_test_component_LUXeXe0DQrg"), "test_component_LUXeXe0DQrg")); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAEE,6BAAe,mHAQZ\"}") +============================= test.tsx_test_component_LUXeXe0DQrg.js (ENTRY POINT)== + +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { useSignal } from "@qwik.dev/core"; +export const test_component_LUXeXe0DQrg = (props)=>{ + const test = _addLoc(useSignal(props["bind:value"]), "test.tsx", 6, 17); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, _wrapProp(test), 1, "u6_0"); +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;0CAE4B,CAAC;IAE1B,MAAM,OAAO,QAAA,UADuB;IAEpC,qBACC,4CACC;AAGH\"}") +/* +{ + "origin": "test.tsx", + "name": "test_component_LUXeXe0DQrg", + "entry": null, + "displayName": "test.tsx_test_component", + "hash": "LUXeXe0DQrg", + "canonicalFilename": "test.tsx_test_component_LUXeXe0DQrg", + "path": "", + "extension": "js", + "parent": null, + "ctxKind": "function", + "ctxName": "component$", + "captures": false, + "loc": [ + 88, + 238 + ], + "paramNames": [ + "props" + ] +} +*/ +== DIAGNOSTICS == + +[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_colon_props3.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_colon_props3.snap new file mode 100644 index 00000000000..127f84c4529 --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_colon_props3.snap @@ -0,0 +1,74 @@ +--- +source: packages/qwik/src/optimizer/core/src/test.rs +assertion_line: 3758 +expression: output +snapshot_kind: text +--- +==INPUT== + + + import { component$, useSignal } from "@qwik.dev/core"; + export default component$((props) => { + const { test, ...rest } = props; + const test = useSignal(rest['bind:value']); + return ( + <> + {test.value} + + ); + }); + +============================= test.js == + +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +export default /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_test_component_LUXeXe0DQrg"), "test_component_LUXeXe0DQrg")); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAEE,6BAAe,mHAQZ\"}") +============================= test.tsx_test_component_LUXeXe0DQrg.js (ENTRY POINT)== + +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { _fnSignal } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _restProps } from "@qwik.dev/core"; +import { useSignal } from "@qwik.dev/core"; +export const test_component_LUXeXe0DQrg = (props)=>{ + const rest = _restProps(props, [ + "test" + ]); + _addLoc(useSignal(rest['bind:value']), "test.tsx", 6, 17); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, _fnSignal((p0)=>p0.test.value, [ + props + ], "p0.test.value"), 1, "u6_0"); +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;0CAE4B,CAAC;4BACA;;;IACb,QAAA,UAAU,IAAI,CAAC,aAAa;IACzC,qBACC,kDACC,GAJM,KAID,KAAK;;;AAGb\"}") +/* +{ + "origin": "test.tsx", + "name": "test_component_LUXeXe0DQrg", + "entry": null, + "displayName": "test.tsx_test_component", + "hash": "LUXeXe0DQrg", + "canonicalFilename": "test.tsx_test_component_LUXeXe0DQrg", + "path": "", + "extension": "js", + "parent": null, + "ctxKind": "function", + "ctxName": "component$", + "captures": false, + "loc": [ + 88, + 237 + ], + "paramNames": [ + "props" + ] +} +*/ +== DIAGNOSTICS == + +[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_block_stmt.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_block_stmt.snap new file mode 100644 index 00000000000..4cba4a32caf --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_block_stmt.snap @@ -0,0 +1,74 @@ +--- +source: packages/qwik/src/optimizer/core/src/test.rs +assertion_line: 3651 +expression: output +snapshot_kind: text +--- +==INPUT== + + + export default ({ data }: { data: any }) => { + return ( +
        { + data.selectedOutputDetail = 'options'; + }} + /> + ); + }; + +============================= test.js == + +import { _fnSignal } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +export default ((props)=>{ + return /*#__PURE__*/ _jsxSorted("div", { + "data-is-active": _fnSignal((p0)=>p0.data.selectedOutputDetail === 'options', [ + props + ], 'p0.data.selectedOutputDetail==="options"'), + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_test_div_onClick_GbMO6TGQv9M"), "test_div_onClick_GbMO6TGQv9M", [ + props + ]) + }, null, null, 2, "u6_0"); +}); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AACE,eAAe,CAAA;IACP,qBACE,WAAC;QACC,gBAAc,kBAAE,GAHV,KAGe,oBAAoB,KAAK;;;QAC9C,QAAQ;;;;AAKpB,CAAA,EAAE\"}") +============================= test.tsx_test_div_onClick_GbMO6TGQv9M.js (ENTRY POINT)== + +import { useLexicalScope } from "@qwik.dev/core"; +export const test_div_onClick_GbMO6TGQv9M = ()=>{ + const [props] = useLexicalScope(); + props.data.selectedOutputDetail = 'options'; +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAKwB;;IACR,MALI,KAKC,oBAAoB,GAAG\"}") +/* +{ + "origin": "test.tsx", + "name": "test_div_onClick_GbMO6TGQv9M", + "entry": null, + "displayName": "test.tsx_test_div_onClick", + "hash": "GbMO6TGQv9M", + "canonicalFilename": "test.tsx_test_div_onClick_GbMO6TGQv9M", + "path": "", + "extension": "js", + "parent": null, + "ctxKind": "eventHandler", + "ctxName": "onClick$", + "captures": true, + "loc": [ + 181, + 259 + ], + "captureNames": [ + "props" + ] +} +*/ +== DIAGNOSTICS == + +[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_block_stmt2.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_block_stmt2.snap new file mode 100644 index 00000000000..070cc9b63c4 --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_block_stmt2.snap @@ -0,0 +1,75 @@ +--- +source: packages/qwik/src/optimizer/core/src/test.rs +assertion_line: 3673 +expression: output +snapshot_kind: text +--- +==INPUT== + + + export default (props: { data: any }) => { + const { data } = props; + return ( +
        { + data.selectedOutputDetail = 'options'; + }} + /> + ); + }; + +============================= test.js == + +import { _fnSignal } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +export default ((props)=>{ + return /*#__PURE__*/ _jsxSorted("div", { + "data-is-active": _fnSignal((p0)=>p0.data.selectedOutputDetail === 'options', [ + props + ], 'p0.data.selectedOutputDetail==="options"'), + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_test_div_onClick_GbMO6TGQv9M"), "test_div_onClick_GbMO6TGQv9M", [ + props + ]) + }, null, null, 2, "u6_0"); +}); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AACE,eAAe,CAAA,CAAC;IAER,qBACE,WAAC;QACC,gBAAc,kBAAE,GAHlB,KAGuB,oBAAoB,KAAK;;;QAC9C,QAAQ;;;;AAKpB,CAAA,EAAE\"}") +============================= test.tsx_test_div_onClick_GbMO6TGQv9M.js (ENTRY POINT)== + +import { useLexicalScope } from "@qwik.dev/core"; +export const test_div_onClick_GbMO6TGQv9M = ()=>{ + const [props] = useLexicalScope(); + props.data.selectedOutputDetail = 'options'; +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAMwB;;IAJH,MAAT,KAKS,oBAAoB,GAAG\"}") +/* +{ + "origin": "test.tsx", + "name": "test_div_onClick_GbMO6TGQv9M", + "entry": null, + "displayName": "test.tsx_test_div_onClick", + "hash": "GbMO6TGQv9M", + "canonicalFilename": "test.tsx_test_div_onClick_GbMO6TGQv9M", + "path": "", + "extension": "js", + "parent": null, + "ctxKind": "eventHandler", + "ctxName": "onClick$", + "captures": true, + "loc": [ + 206, + 284 + ], + "captureNames": [ + "props" + ] +} +*/ +== DIAGNOSTICS == + +[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_expr_stmt.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_expr_stmt.snap new file mode 100644 index 00000000000..b40bbe1983e --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_expr_stmt.snap @@ -0,0 +1,69 @@ +--- +source: packages/qwik/src/optimizer/core/src/test.rs +assertion_line: 3696 +expression: output +snapshot_kind: text +--- +==INPUT== + + + export default ({ data }: { data: any }) => +
        { + data.selectedOutputDetail = 'options'; + }} + />; + +============================= test.js == + +import { _fnSignal } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +export default ((props)=>/*#__PURE__*/ _jsxSorted("div", { + "data-is-active": _fnSignal((p0)=>p0.data.selectedOutputDetail === 'options', [ + props + ], 'p0.data.selectedOutputDetail==="options"'), + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_test_div_onClick_GbMO6TGQv9M"), "test_div_onClick_GbMO6TGQv9M", [ + props + ]) + }, null, null, 2, "u6_0")); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AACE,eAAe,CAAA,uBACL,WAAC;QACC,gBAAc,kBAAE,GAFV,KAEe,oBAAoB,KAAK;;;QAC9C,QAAQ;;;6BAGT,EAAE\"}") +============================= test.tsx_test_div_onClick_GbMO6TGQv9M.js (ENTRY POINT)== + +import { useLexicalScope } from "@qwik.dev/core"; +export const test_div_onClick_GbMO6TGQv9M = ()=>{ + const [props] = useLexicalScope(); + props.data.selectedOutputDetail = 'options'; +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAIwB;;IACR,MAJI,KAIC,oBAAoB,GAAG\"}") +/* +{ + "origin": "test.tsx", + "name": "test_div_onClick_GbMO6TGQv9M", + "entry": null, + "displayName": "test.tsx_test_div_onClick", + "hash": "GbMO6TGQv9M", + "canonicalFilename": "test.tsx_test_div_onClick_GbMO6TGQv9M", + "path": "", + "extension": "js", + "parent": null, + "ctxKind": "eventHandler", + "ctxName": "onClick$", + "captures": true, + "loc": [ + 160, + 238 + ], + "captureNames": [ + "props" + ] +} +*/ +== DIAGNOSTICS == + +[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_1.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_1.snap index 3c6ca2229d3..a2284591663 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_1.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_1.snap @@ -7,28 +7,27 @@ snapshot_kind: text ==INPUT== -import { $, component, onRender } from '@builder.io/qwik'; +import { $, component, onRender } from '@qwik.dev/core'; export const renderHeader = $(() => { - return ( -
        console.log(ctx))}/> - ); + return ( +
        console.log(ctx))}/> + ); }); const renderHeader = component($(() => { - console.log("mount"); - return render; + console.log("mount"); + return render; })); ============================= test.tsx_renderHeader_zBbHWn4e8Cg.tsx (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const renderHeader_zBbHWn4e8Cg = ()=>{ return
        import("./test.tsx_renderHeader_div_onClick_fV2uzAL99u4"), "renderHeader_div_onClick_fV2uzAL99u4")}/>; }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";wCAG8B;IAC1B,QACK,IAAI;AAEb\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";wCAG8B;IAC7B,QACE,IAAI;AAEP\"}") /* { "origin": "test.tsx", @@ -44,8 +43,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 92, - 175 + 90, + 161 ] } */ @@ -55,10 +54,9 @@ export const renderHeader_component_U6Kkv07sbpQ = ()=>{ console.log("mount"); return render; }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"kDAQiC;IAC/B,QAAQ,GAAG,CAAC;IACZ,OAAO;AACT\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"kDAQiC;IAChC,QAAQ,GAAG,CAAC;IACZ,OAAO;AACR\"}") /* { "origin": "test.tsx", @@ -74,27 +72,27 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 211, - 261 + 197, + 245 ] } */ ============================= test.tsx == -import { qrl } from "@builder.io/qwik"; -import { component } from '@builder.io/qwik'; -export const renderHeader = /*#__PURE__*/ qrl(()=>import("./test.tsx_renderHeader_zBbHWn4e8Cg"), "renderHeader_zBbHWn4e8Cg"); -const renderHeader = component(/*#__PURE__*/ qrl(()=>import("./test.tsx_renderHeader_component_U6Kkv07sbpQ"), "renderHeader_component_U6Kkv07sbpQ")); +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { component } from '@qwik.dev/core'; +export const renderHeader = /*#__PURE__*/ _addLoc(/*#__PURE__*/ qrl(()=>import("./test.tsx_renderHeader_zBbHWn4e8Cg"), "renderHeader_zBbHWn4e8Cg"), "test.tsx", 5, 29); +const renderHeader = _addLoc(component(/*#__PURE__*/ qrl(()=>import("./test.tsx_renderHeader_component_U6Kkv07sbpQ"), "renderHeader_component_U6Kkv07sbpQ")), "test.tsx", 10, 22); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";AACA,SAAY,SAAS,QAAkB,mBAAmB;AAE1D,OAAO,MAAM,gHAIV;AACH,MAAM,eAAe\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AACA,SAAY,SAAS,QAAkB,iBAAiB;AAExD,OAAO,MAAM,6BAAe,6HAIzB;AACH,MAAM,eAAe,QAAA\"}") ============================= test.tsx_renderHeader_div_onClick_fV2uzAL99u4.tsx (ENTRY POINT)== export const renderHeader_div_onClick_fV2uzAL99u4 = (ctx)=>console.log(ctx); -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"oDAKwB,CAAC,MAAQ,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"oDAKkB,CAAC,MAAQ,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", @@ -110,8 +108,11 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 137, - 162 + 126, + 151 + ], + "paramNames": [ + "ctx" ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_10.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_10.snap index d78580e912a..5dc77c696b6 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_10.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_10.snap @@ -7,33 +7,34 @@ snapshot_kind: text ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; const Header = $((decl1, {decl2}, [decl3]) => { - const hola = ident1.no; - ident2; - const a = ident1 + ident3; - const b = ident1 + ident3; - ident4(ident5, [ident6], {ident7}, {key: ident8}); - class Some { - prop = ident9; - method() { - return ident10; - } - } + const hola = ident1.no; + ident2; + const a = ident1 + ident3; + const b = ident1 + ident3; + ident4(ident5, [ident6], {ident7}, {key: ident8}); + class Some { + prop = ident9; + method() { + return ident10; + } + } - return ( -
        ident11 + ident12} required={false}/> - ) + return ( +
        ident11 + ident12} required={false}/> + ) }); ============================= project/test.tsx_Header_WlR3xnI6u38.tsx (ENTRY POINT)== +import { _addLoc } from "@qwik.dev/core/internal"; export const Header_WlR3xnI6u38 = (decl1, { decl2 }, [decl3])=>{ - ident1.no; + _addLoc(ident1.no, "project/test.tsx", 6, 15); ident2; - ident1, ident3; - ident1, ident3; + _addLoc(ident1 + ident3, "project/test.tsx", 8, 12); + _addLoc(ident1 + ident3, "project/test.tsx", 9, 12); ident4(ident5, [ ident6 ], { @@ -49,10 +50,9 @@ export const Header_WlR3xnI6u38 = (decl1, { decl2 }, [decl3])=>{ } return
        ident11 + ident12} required={false}/>; }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\"kCAEiB,CAAC,OAAO,EAAC,KAAK,EAAC,EAAE,CAAC,MAAM;IAExB,OAAO,EAAE;IACtB;IACU,QAAS;IACT,QAAS;IACnB,OAAO,QAAQ;QAAC;KAAO,EAAE;QAAC;IAAM,GAAG;QAAC,KAAK;IAAM;IAC/C,MAAM;QACF,OAAO,OAAO;QACd,SAAS;YACL,OAAO;QACX;IACJ;IAEA,QACK,IAAI,SAAS,CAAC,UAAY,UAAU,SAAS,UAAU;AAEhE\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";kCAEiB,CAAC,OAAO,EAAC,KAAK,EAAC,EAAE,CAAC,MAAM;IAE3B,QAAA,OAAO,EAAE;IACtB;IACU,QAAA,SAAS;IACT,QAAA,SAAS;IACnB,OAAO,QAAQ;QAAC;KAAO,EAAE;QAAC;IAAM,GAAG;QAAC,KAAK;IAAM;IAC/C,MAAM;QACL,OAAO,OAAO;QACd,SAAS;YACR,OAAO;QACR;IACD;IAEA,QACE,IAAI,SAAS,CAAC,UAAY,UAAU,SAAS,UAAU;AAE1D\"}") /* { "origin": "project/test.tsx", @@ -68,18 +68,24 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\" "ctxName": "$", "captures": false, "loc": [ - 69, - 455 + 67, + 393 + ], + "paramNames": [ + "decl1", + "{decl2}", + "[decl3]" ] } */ ============================= project/test.tsx == -import { qrl } from "@builder.io/qwik"; -/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_WlR3xnI6u38"), "Header_WlR3xnI6u38"); +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +/*#__PURE__*/ _addLoc(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_WlR3xnI6u38"), "Header_WlR3xnI6u38"), "project/test.tsx", 4, 16); -Some("{\"version\":3,\"sources\":[],\"names\":[],\"mappings\":\"\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";;cAEe\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_11.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_11.snap index ff20af8b3a9..04ed0edbb47 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_11.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_11.snap @@ -7,33 +7,32 @@ snapshot_kind: text ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; import {foo, bar as bbar} from "../state"; import * as dep2 from "dep2"; import dep3 from "dep3/something"; export const Header = component$(() => { - return ( -
        dep3(ev))}> - {dep2.stuff()}{bbar()} -
        - ); + return ( +
        dep3(ev))}> + {dep2.stuff()}{bbar()} +
        + ); }); export const App = component$(() => { - return ( -
        {foo()}
        - ); + return ( +
        {foo()}
        + ); }); ============================= project/test.tsx_Header_component_Header_onClick_KjD9TCNkNxY.tsx == import dep3 from "dep3/something"; export const Header_component_Header_onClick_KjD9TCNkNxY = (ev)=>dep3(ev); -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";2DAQ2B,CAAC,KAAO,KAAK\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";2DAQqB,CAAC,KAAO,KAAK\"}") /* { "origin": "project/test.tsx", @@ -49,8 +48,11 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\" "ctxName": "$", "captures": false, "loc": [ - 242, - 258 + 231, + 247 + ], + "paramNames": [ + "ev" ] } */ @@ -59,15 +61,15 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\" import { Header } from "./test"; import { bar as bbar } from "../state"; import * as dep2 from "dep2"; -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const Header_component_UVBJuFYfvDo = ()=>{ return
        import("./test.tsx_Header_component_Header_onClick_KjD9TCNkNxY"), "Header_component_Header_onClick_KjD9TCNkNxY")}> - {dep2.stuff()}{bbar()} -
        ; + {dep2.stuff()}{bbar()} + ; }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";;;;4CAMiC;IAC7B,QACK,OAAO,iJAA8B;YAClC,CAAC,KAAK,KAAK,IAAI,OAAO;QAC1B,EAAE;AAEV\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";;;;4CAMiC;IAChC,QACE,OAAO,iJAA8B;GACrC,CAAC,KAAK,KAAK,IAAI,OAAO;EACvB,EAAE;AAEJ\"}") /* { "origin": "project/test.tsx", @@ -83,8 +85,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\" "ctxName": "component$", "captures": false, "loc": [ - 194, - 323 + 192, + 294 ] } */ @@ -97,7 +99,7 @@ export const App_component_wGkRHWXaqjs = ()=>{ }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";;yCAc8B;IAC1B,QACK,QAAQ,QAAQ;AAEzB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";;yCAc8B;IAC7B,QACE,QAAQ,QAAQ;AAEnB\"}") /* { "origin": "project/test.tsx", @@ -113,20 +115,21 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\" "ctxName": "component$", "captures": false, "loc": [ - 357, - 419 + 328, + 378 ] } */ ============================= project/test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const Header = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_UVBJuFYfvDo"), "Header_component_UVBJuFYfvDo")); -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_wGkRHWXaqjs"), "App_component_wGkRHWXaqjs")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Header = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_UVBJuFYfvDo"), "Header_component_UVBJuFYfvDo")), "project/test.tsx", 8, 23); +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_wGkRHWXaqjs"), "App_component_wGkRHWXaqjs")), "project/test.tsx", 16, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";;AAMA,OAAO,MAAM,uBAAS,uHAMnB;AAEH,OAAO,MAAM,oBAAM,iHAIhB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";;;AAMA,OAAO,MAAM,uBAAS,QAAA,mJAMnB;AAEH,OAAO,MAAM,oBAAM,QAAA,8IAIhB\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_2.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_2.snap index 58e9d295f5b..abd685bd44b 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_2.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_2.snap @@ -7,24 +7,24 @@ snapshot_kind: text ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; export const Header = component$(() => { - console.log("mount"); - return ( -
        console.log(ctx))}/> - ); + console.log("mount"); + return ( +
        console.log(ctx))}/> + ); }); ============================= test.tsx_Header_component_J4uyIhaBNR4.tsx (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const Header_component_J4uyIhaBNR4 = ()=>{ console.log("mount"); return
        import("./test.tsx_Header_component_div_onClick_i7ekvWH3674"), "Header_component_div_onClick_i7ekvWH3674")}/>; }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAEiC;IAC7B,QAAQ,GAAG,CAAC;IACZ,QACK,IAAI;AAEb\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAEiC;IAChC,QAAQ,GAAG,CAAC;IACZ,QACE,IAAI;AAEP\"}") /* { "origin": "test.tsx", @@ -40,26 +40,26 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 85, - 194 + 83, + 177 ] } */ ============================= test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const Header = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_J4uyIhaBNR4"), "Header_component_J4uyIhaBNR4")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Header = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_J4uyIhaBNR4"), "Header_component_J4uyIhaBNR4")), "test.tsx", 4, 23); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAEA,OAAO,MAAM,uBAAS,uHAKnB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAEA,OAAO,MAAM,uBAAS,QAAA,2IAKnB\"}") ============================= test.tsx_Header_component_div_onClick_i7ekvWH3674.tsx (ENTRY POINT)== export const Header_component_div_onClick_i7ekvWH3674 = (ctx)=>console.log(ctx); -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"wDAKwB,CAAC,MAAQ,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"wDAKkB,CAAC,MAAQ,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", @@ -75,8 +75,11 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 156, - 181 + 142, + 167 + ], + "paramNames": [ + "ctx" ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_3.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_3.snap index 01cf3cb1c3f..28c75dd1b64 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_3.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_3.snap @@ -7,27 +7,27 @@ snapshot_kind: text ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; export const App = () => { - const Header = component$(() => { - console.log("mount"); - return ( -
        console.log(ctx))}/> - ); - }); - return Header; + const Header = component$(() => { + console.log("mount"); + return ( +
        console.log(ctx))}/> + ); + }); + return Header; }); ============================= test.tsx_App_Header_component_B9F3YeqcO1w.tsx (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const App_Header_component_B9F3YeqcO1w = ()=>{ console.log("mount"); return
        import("./test.tsx_App_Header_component_div_onClick_aO7uI7Iw6oQ"), "App_Header_component_div_onClick_aO7uI7Iw6oQ")}/>; }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";gDAG8B;IACtB,QAAQ,GAAG,CAAC;IACZ,QACK,IAAI;AAEb\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";gDAG2B;IACzB,QAAQ,GAAG,CAAC;IACZ,QACE,IAAI;AAEP\"}") /* { "origin": "test.tsx", @@ -43,18 +43,17 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 109, - 238 + 104, + 203 ] } */ ============================= test.tsx_App_Header_component_div_onClick_aO7uI7Iw6oQ.tsx (ENTRY POINT)== export const App_Header_component_div_onClick_aO7uI7Iw6oQ = (ctx)=>console.log(ctx); -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"4DAM4B,CAAC,MAAQ,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"4DAMmB,CAAC,MAAQ,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", @@ -70,22 +69,26 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 192, - 217 + 166, + 191 + ], + "paramNames": [ + "ctx" ] } */ ============================= test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const App = ()=>{ - const Header = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_Header_component_B9F3YeqcO1w"), "App_Header_component_B9F3YeqcO1w")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = _addLoc(()=>{ + const Header = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_Header_component_B9F3YeqcO1w"), "App_Header_component_B9F3YeqcO1w")), "test.tsx", 5, 17); return Header; -}; +}, "test.tsx", 4, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAEA,OAAO,MAAM,MAAM;IACf,MAAM,uBAAS;IAMf,OAAO;AACX,EAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAEA,OAAO,MAAM,MAAM,QAAA;IAClB,MAAM,uBAAS,QAAA;IAMf,OAAO;AACR,sBAAG\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_4.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_4.snap index f59414d1392..43473464103 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_4.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_4.snap @@ -7,27 +7,27 @@ snapshot_kind: text ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; export function App() { - const Header = component$(() => { - console.log("mount"); - return ( -
        console.log(ctx))}/> - ); - }); - return Header; + const Header = component$(() => { + console.log("mount"); + return ( +
        console.log(ctx))}/> + ); + }); + return Header; } ============================= test.tsx_App_Header_component_B9F3YeqcO1w.tsx (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const App_Header_component_B9F3YeqcO1w = ()=>{ console.log("mount"); return
        import("./test.tsx_App_Header_component_div_onClick_aO7uI7Iw6oQ"), "App_Header_component_div_onClick_aO7uI7Iw6oQ")}/>; }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";gDAG8B;IACtB,QAAQ,GAAG,CAAC;IACZ,QACK,IAAI;AAEb\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";gDAG2B;IACzB,QAAQ,GAAG,CAAC;IACZ,QACE,IAAI;AAEP\"}") /* { "origin": "test.tsx", @@ -43,18 +43,17 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 106, - 235 + 101, + 200 ] } */ ============================= test.tsx_App_Header_component_div_onClick_aO7uI7Iw6oQ.tsx (ENTRY POINT)== export const App_Header_component_div_onClick_aO7uI7Iw6oQ = (ctx)=>console.log(ctx); -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"4DAM4B,CAAC,MAAQ,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"4DAMmB,CAAC,MAAQ,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", @@ -70,22 +69,26 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 189, - 214 + 163, + 188 + ], + "paramNames": [ + "ctx" ] } */ ============================= test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; export function App() { - const Header = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_Header_component_B9F3YeqcO1w"), "App_Header_component_B9F3YeqcO1w")); + const Header = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_Header_component_B9F3YeqcO1w"), "App_Header_component_B9F3YeqcO1w")), "test.tsx", 5, 17); return Header; } -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAEA,OAAO,SAAS;IACZ,MAAM,uBAAS;IAMf,OAAO;AACX\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAEA,OAAO,SAAS;IACf,MAAM,uBAAS,QAAA;IAMf,OAAO;AACR\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_5.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_5.snap index 7a23a0e8627..3b96b66df4e 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_5.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_5.snap @@ -7,28 +7,28 @@ snapshot_kind: text ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; export const Header = component$(() => { - return ( - <> -
        console.log("1")}/> -
        console.log("2"))}/> - - ); + return ( + <> +
        console.log("1")}/> +
        console.log("2"))}/> + + ); }); ============================= test.tsx_Header_component_J4uyIhaBNR4.tsx (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const Header_component_J4uyIhaBNR4 = ()=>{ return <> -
        console.log("1")}/> -
        import("./test.tsx_Header_component_div_onClick_i7ekvWH3674"), "Header_component_div_onClick_i7ekvWH3674")}/> - ; +
        console.log("1")}/> +
        import("./test.tsx_Header_component_div_onClick_i7ekvWH3674"), "Header_component_div_onClick_i7ekvWH3674")}/> + ; }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAEiC;IAC7B,SACM;YACE,CAAC,IAAI,SAAS,CAAC,MAAQ,QAAQ,GAAG,CAAC,OAAO;YAC1C,CAAC,IAAI,4IAAwC;QACjD;AAER\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAEiC;IAChC,SACG;GACD,CAAC,IAAI,SAAS,CAAC,MAAQ,QAAQ,GAAG,CAAC,OAAO;GAC1C,CAAC,IAAI,4IAAwC;EAC9C;AAEF\"}") /* { "origin": "test.tsx", @@ -44,26 +44,26 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 85, - 250 + 83, + 212 ] } */ ============================= test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const Header = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_J4uyIhaBNR4"), "Header_component_J4uyIhaBNR4")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Header = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_J4uyIhaBNR4"), "Header_component_J4uyIhaBNR4")), "test.tsx", 4, 23); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAEA,OAAO,MAAM,uBAAS,uHAOnB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAEA,OAAO,MAAM,uBAAS,QAAA,2IAOnB\"}") ============================= test.tsx_Header_component_div_onClick_i7ekvWH3674.tsx (ENTRY POINT)== export const Header_component_div_onClick_i7ekvWH3674 = (ctx)=>console.log("2"); -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"wDAM4B,CAAC,MAAQ,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"wDAMmB,CAAC,MAAQ,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", @@ -79,8 +79,11 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 200, - 225 + 171, + 196 + ], + "paramNames": [ + "ctx" ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_6.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_6.snap index 1552f8c4475..cc2487ee25c 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_6.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_6.snap @@ -7,13 +7,12 @@ snapshot_kind: text ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; export const sym1 = $((ctx) => console.log("1")); ============================= test.tsx_sym1_aXUrPXX5Lak.tsx (ENTRY POINT)== export const sym1_aXUrPXX5Lak = (ctx)=>console.log("1"); -export { _hW } from "@builder.io/qwik"; Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"gCAEsB,CAAC,MAAQ,QAAQ,GAAG,CAAC\"}") @@ -32,18 +31,22 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 74, - 99 + 72, + 97 + ], + "paramNames": [ + "ctx" ] } */ ============================= test.tsx == -import { qrl } from "@builder.io/qwik"; -export const sym1 = /*#__PURE__*/ qrl(()=>import("./test.tsx_sym1_aXUrPXX5Lak"), "sym1_aXUrPXX5Lak"); +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const sym1 = /*#__PURE__*/ _addLoc(/*#__PURE__*/ qrl(()=>import("./test.tsx_sym1_aXUrPXX5Lak"), "sym1_aXUrPXX5Lak"), "test.tsx", 4, 21); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";AAEA,OAAO,MAAM,wFAAoC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAEA,OAAO,MAAM,qBAAO,6GAA6B\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_7.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_7.snap index 49bc274ae63..98f9d5d6f78 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_7.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_7.snap @@ -7,31 +7,31 @@ snapshot_kind: text ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; export const Header = component$(() => { - console.log("mount"); - return ( -
        console.log(ctx))}/> - ); - }); + console.log("mount"); + return ( +
        console.log(ctx))}/> + ); + }); const App = component$(() => { - return ( -
        - ); + return ( +
        + ); }); ============================= test.tsx_Header_component_J4uyIhaBNR4.tsx (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const Header_component_J4uyIhaBNR4 = ()=>{ console.log("mount"); return
        import("./test.tsx_Header_component_div_onClick_i7ekvWH3674"), "Header_component_div_onClick_i7ekvWH3674")}/>; }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAGiC;IAC7B,QAAQ,GAAG,CAAC;IACZ,QACK,IAAI;AAEX\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAGiC;IAChC,QAAQ,GAAG,CAAC;IACZ,QACE,IAAI;AAEN\"}") /* { "origin": "test.tsx", @@ -47,20 +47,21 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 86, - 197 + 84, + 179 ] } */ ============================= test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const Header = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_J4uyIhaBNR4"), "Header_component_J4uyIhaBNR4")); -/*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Header = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_J4uyIhaBNR4"), "Header_component_J4uyIhaBNR4")), "test.tsx", 5, 23); +/*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")), "test.tsx", 12, 13); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,uBAAS,uHAKjB;cAEO\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,uBAAS,QAAA,2IAKlB;cAEQ,QAAA\"}") ============================= test.tsx_App_component_ckEPmXZlub0.tsx (ENTRY POINT)== import { Header } from "./test"; @@ -69,7 +70,7 @@ export const App_component_ckEPmXZlub0 = ()=>{ }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";yCAUuB;IACnB,QACK;AAET\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";yCAUuB;IACtB,QACE;AAEH\"}") /* { "origin": "test.tsx", @@ -85,18 +86,17 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 224, - 271 + 206, + 241 ] } */ ============================= test.tsx_Header_component_div_onClick_i7ekvWH3674.tsx (ENTRY POINT)== export const Header_component_div_onClick_i7ekvWH3674 = (ctx)=>console.log(ctx); -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"wDAMwB,CAAC,MAAQ,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"wDAMkB,CAAC,MAAQ,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", @@ -112,8 +112,11 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 157, - 182 + 143, + 168 + ], + "paramNames": [ + "ctx" ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_8.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_8.snap index ca8fcd731e0..39799961810 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_8.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_8.snap @@ -7,28 +7,28 @@ snapshot_kind: text ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; export const Header = component$(() => { - return $((hola) => { - const hola = this; - const {something, styff} = hola; - const hello = hola.nothere.stuff[global]; - return ( -
        - ); - }); + return $((hola) => { + const hola = this; + const {something, styff} = hola; + const hello = hola.nothere.stuff[global]; + return ( +
        + ); + }); }); ============================= test.tsx_Header_component_J4uyIhaBNR4.tsx (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const Header_component_J4uyIhaBNR4 = ()=>{ return /*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_1_2B8d0oH9ZWc"), "Header_component_1_2B8d0oH9ZWc"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAGiC;IAC7B;AAQJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAGiC;IAChC;AAQD\"}") /* { "origin": "test.tsx", @@ -44,24 +44,23 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 86, - 296 + 84, + 249 ] } */ ============================= test.tsx_Header_component_1_2B8d0oH9ZWc.tsx (ENTRY POINT)== import { Header } from "./test"; +import { _addLoc } from "@qwik.dev/core/internal"; export const Header_component_1_2B8d0oH9ZWc = (hola)=>{ - const hola = this; - const { something, styff } = hola; - hola.nothere.stuff[global]; + const hola = _addLoc(this, "test.tsx", 7, 16); + _addLoc(hola.nothere.stuff[global], "test.tsx", 9, 17); return
        ; }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";8CAIa,CAAC;IACN,MAAM,OAAO,IAAI;IACjB,MAAM,EAAC,SAAS,EAAE,KAAK,EAAC,GAAG;IACb,KAAK,OAAO,CAAC,KAAK,CAAC,OAAO;IACxC,QACK;AAET\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;8CAIU,CAAC;IACT,MAAM,OAAO,QAAA,IAAI;IAEH,QAAA,KAAK,OAAO,CAAC,KAAK,CAAC,OAAO;IACxC,QACE;AAEH\"}") /* { "origin": "test.tsx", @@ -77,19 +76,23 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 107, - 292 + 102, + 245 + ], + "paramNames": [ + "hola" ] } */ ============================= test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const Header = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_J4uyIhaBNR4"), "Header_component_J4uyIhaBNR4")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Header = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_J4uyIhaBNR4"), "Header_component_J4uyIhaBNR4")), "test.tsx", 5, 23); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,uBAAS,uHASnB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,uBAAS,QAAA,2IASnB\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_9.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_9.snap index 916fadedbe6..d83816b2dce 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_9.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_9.snap @@ -7,29 +7,30 @@ snapshot_kind: text ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; const Header = $((decl1, {decl2}, [decl3]) => { - const {decl4, key: decl5} = this; - let [decl6, ...decl7] = stuff; - const decl8 = 1, decl9; - function decl10(decl11, {decl12}, [decl13]) {} - class decl14 { - method(decl15, {decl16}, [decl17]) {} - } - try{}catch(decl18){} - try{}catch({decl19}){} + const {decl4, key: decl5} = this; + let [decl6, ...decl7] = stuff; + const decl8 = 1, decl9; + function decl10(decl11, {decl12}, [decl13]) {} + class decl14 { + method(decl15, {decl16}, [decl17]) {} + } + try{}catch(decl18){} + try{}catch({decl19}){} }); ============================= test.tsx_Header_WjUaUQN7Oxg.tsx (ENTRY POINT)== +import { _addLoc } from "@qwik.dev/core/internal"; export const Header_WjUaUQN7Oxg = (decl1, { decl2 }, [decl3])=>{ const { decl4, key: decl5 } = this; let [decl6, ...decl7] = stuff; + _addLoc(1, "test.tsx", 7, 16); }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"kCAEiB,CAAC,OAAO,EAAC,KAAK,EAAC,EAAE,CAAC,MAAM;IACrC,MAAM,EAAC,KAAK,EAAE,KAAK,KAAK,EAAC,GAAG,IAAI;IAChC,IAAI,CAAC,OAAO,GAAG,MAAM,GAAG;AAQ5B\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";kCAEiB,CAAC,OAAO,EAAC,KAAK,EAAC,EAAE,CAAC,MAAM;IACxC,MAAM,EAAC,KAAK,EAAE,KAAK,KAAK,EAAC,GAAG,IAAI;IAChC,IAAI,CAAC,OAAO,GAAG,MAAM,GAAG;IACV,QAAA;AAOf\"}") /* { "origin": "test.tsx", @@ -45,18 +46,24 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 69, - 376 + 67, + 344 + ], + "paramNames": [ + "decl1", + "{decl2}", + "[decl3]" ] } */ ============================= test.tsx == -import { qrl } from "@builder.io/qwik"; -/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_WjUaUQN7Oxg"), "Header_WjUaUQN7Oxg"); +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +/*#__PURE__*/ _addLoc(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_WjUaUQN7Oxg"), "Header_WjUaUQN7Oxg"), "test.tsx", 4, 16); -Some("{\"version\":3,\"sources\":[],\"names\":[],\"mappings\":\"\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;cAEe\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_build_server.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_build_server.snap index 590b6c0e397..231884fa10f 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_build_server.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_build_server.snap @@ -1,14 +1,14 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2620 +assertion_line: 2731 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore, isDev, isServer as isServer2 } from '@builder.io/qwik'; -import { isServer, isBrowser as isb } from '@builder.io/qwik/build'; +import { component$, useStore, isDev, isServer as isServer2 } from '@qwik.dev/core'; +import { isServer, isBrowser as isb } from '@qwik.dev/core/build'; import { mongodb } from 'mondodb'; import { threejs } from 'threejs'; @@ -23,31 +23,32 @@ export const functionThatNeedsWindow = () => { }; export const App = component$(() => { - useMount$(() => { - if (isServer) { - console.log('server', mongodb()); - } - if (isb) { - console.log('browser', new threejs()); - } - }); - return ( - - {isServer2 &&

        server

        } - {isb &&

        server

        } -
        - ); + useMount$(() => { + if (isServer) { + console.log('server', mongodb()); + } + if (isb) { + console.log('browser', new threejs()); + } + }); + return ( + + {isServer2 &&

        server

        } + {isb &&

        server

        } +
        + ); }); ============================= test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const functionThatNeedsWindow = ()=>{}; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "s_ckEPmXZlub0")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const functionThatNeedsWindow = _addLoc(()=>{}, "test.tsx", 10, 40); +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "s_ckEPmXZlub0")), "test.tsx", 18, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAQA,OAAO,MAAM,0BAA0B,KAMvC,EAAE;AAEF,OAAO,MAAM,oBAAM,qGAehB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAQA,OAAO,MAAM,0BAA0B,QAAA,KAMvC,uBAAE;AAEF,OAAO,MAAM,oBAAM,QAAA,0HAehB\"}") ============================= test.tsx_App_component_ckEPmXZlub0.tsx (ENTRY POINT)== import { mongodb } from "mondodb"; @@ -56,13 +57,13 @@ export const s_ckEPmXZlub0 = ()=>{ console.log('server', mongodb()); }); return - {

        server

        } - {false} -
        ; + {

        server

        } + {false} + ; }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";6BAgB8B;IAC1B,UAAU;QAEF,QAAQ,GAAG,CAAC,UAAU;IAK9B;IACA,QACK,IAAI;YACD,EAAe,EAAE,MAAM,EAAE,GAAG;YAC5B,OAAsB;QAC1B,EAAE;AAEV\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";6BAgB8B;IAC7B,UAAU;QAER,QAAQ,GAAG,CAAC,UAAU;IAKxB;IACA,QACE,IAAI;GACJ,EAAe,EAAE,MAAM,EAAE,GAAG;GAC5B,OAAsB;EACvB,EAAE;AAEJ\"}") /* { "origin": "test.tsx", @@ -78,8 +79,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 427, - 751 + 423, + 663 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_capture_imports.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_capture_imports.snap index 6720f326772..28050e3c19d 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_capture_imports.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_capture_imports.snap @@ -1,30 +1,31 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 914 +assertion_line: 1024 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStyles$ } from '@builder.io/qwik'; +import { component$, useStyles$ } from '@qwik.dev/core'; import css1 from './global.css'; import css2 from './style.css'; import css3 from './style.css'; export const App = component$(() => { - useStyles$(`${css1}${css2}`); - useStyles$(css3); + useStyles$(`${css1}${css2}`); + useStyles$(css3); }) ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")), "test.tsx", 8, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAMA,OAAO,MAAM,oBAAM,iHAGjB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAMA,OAAO,MAAM,oBAAM,QAAA,qIAGjB\"}") ============================= test.tsx_App_component_useStyles_t35nSa5UV7U.js (ENTRY POINT)== import css1 from "./global.css"; @@ -32,7 +33,7 @@ import css2 from "./style.css"; export const App_component_useStyles_t35nSa5UV7U = `${css1}${css2}`; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;mDAOe,GAAG,OAAO,MAAM\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;mDAOY,GAAG,OAAO,MAAM\"}") /* { "origin": "test.tsx", @@ -48,22 +49,22 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "useStyles$", "captures": false, "loc": [ - 212, - 228 + 207, + 223 ] } */ ============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; -import { useStylesQrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; +import { useStylesQrl } from "@qwik.dev/core"; export const App_component_ckEPmXZlub0 = ()=>{ useStylesQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_useStyles_t35nSa5UV7U"), "App_component_useStyles_t35nSa5UV7U")); useStylesQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_useStyles_1_xBK4W0ZKWe8"), "App_component_useStyles_1_xBK4W0ZKWe8")); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;yCAM8B;IAC1B;IACA;AACJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;yCAM8B;IAC7B;IACA;AACD\"}") /* { "origin": "test.tsx", @@ -79,8 +80,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 189, - 254 + 187, + 246 ] } */ @@ -90,7 +91,7 @@ import css3 from "./style.css"; export const App_component_useStyles_1_xBK4W0ZKWe8 = css3; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";qDAQe\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";qDAQY\"}") /* { "origin": "test.tsx", @@ -106,8 +107,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "useStyles$", "captures": false, "loc": [ - 246, - 250 + 238, + 242 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_capturing_fn_class.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_capturing_fn_class.snap index e0fc95f191e..36fd57d8d5a 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_capturing_fn_class.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_capturing_fn_class.snap @@ -1,47 +1,48 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 935 +assertion_line: 1045 expression: output snapshot_kind: text --- ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; export const App = component$(() => { - function hola() { - console.log('hola'); - } - class Thing {} - class Other {} + function hola() { + console.log('hola'); + } + class Thing {} + class Other {} - return $(() => { - hola(); - new Thing(); - return ( -
        - ) - }); + return $(() => { + hola(); + new Thing(); + return ( +
        + ) + }); }) ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")), "test.tsx", 5, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,iHAcjB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,oBAAM,QAAA,qIAcjB\"}") ============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const App_component_ckEPmXZlub0 = ()=>{ return /*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_1_w0t0o3QMovU"), "App_component_1_w0t0o3QMovU"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";yCAG8B;IAO1B;AAOJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";yCAG8B;IAO7B;AAOD\"}") /* { "origin": "test.tsx", @@ -57,23 +58,22 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 83, - 293 + 81, + 246 ] } */ ============================= test.tsx_App_component_1_w0t0o3QMovU.js (ENTRY POINT)== -import { _jsxQ } from "@builder.io/qwik"; +import { _jsxSorted } from "@qwik.dev/core"; export const App_component_1_w0t0o3QMovU = ()=>{ hola(); new Thing(); - return /*#__PURE__*/ _jsxQ("div", null, null, null, 3, "u6_0"); + return /*#__PURE__*/ _jsxSorted("div", null, null, null, 3, "u6_0"); }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";2CAUa;IACP;IACA,IAAI;IACJ,qBACI,MAAC;AAEP\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";2CAUU;IACR;IACA,IAAI;IACJ,qBACC,WAAC;AAEH\"}") /* { "origin": "test.tsx", @@ -89,8 +89,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 198, - 289 + 177, + 242 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_class_name.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_class_name.snap index 120ca106cb2..34c02ef237a 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_class_name.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_class_name.snap @@ -1,97 +1,80 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2537 +assertion_line: 2648 expression: output snapshot_kind: text --- ==INPUT== -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const App2 = component$(() => { - const signal = useSignal(); - const computed = signal.value + 'foo'; - return ( - <> -
        -
        -
        -
        + const signal = useSignal(); + const computed = signal.value + 'foo'; + return ( + <> +
        +
        +
        +
        - - - - - - ); + + + + + + ); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const App2 = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App2_component_3yveMqbQ3Fs.js"), "App2_component_3yveMqbQ3Fs")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App2 = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App2_component_3yveMqbQ3Fs.js"), "App2_component_3yveMqbQ3Fs")), "test.tsx", 5, 21); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,qBAAO,sHAgBjB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,qBAAO,QAAA,0IAgBjB\"}") ============================= test.tsx_App2_component_3yveMqbQ3Fs.js (ENTRY POINT)== -import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime"; -import { _IMMUTABLE } from "@builder.io/qwik"; -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; export const App2_component_3yveMqbQ3Fs = ()=>{ - const signal = useSignal(); - const computed = signal.value + 'foo'; - return /*#__PURE__*/ _jsxC(_Fragment, { - children: [ - /*#__PURE__*/ _jsxQ("div", null, { - className: "hola" - }, null, 3, null), - /*#__PURE__*/ _jsxQ("div", null, { - className: _fnSignal((p0)=>p0.value, [ - signal - ], "p0.value") - }, null, 3, null), - /*#__PURE__*/ _jsxQ("div", null, { - className: signal - }, null, 3, null), - /*#__PURE__*/ _jsxQ("div", { - className: computed - }, null, null, 3, null), - /*#__PURE__*/ _jsxC(Foo, { - className: "hola", - [_IMMUTABLE]: { - className: _IMMUTABLE - } - }, 3, "u6_0"), - /*#__PURE__*/ _jsxC(Foo, { - get className () { - return signal.value; - }, - [_IMMUTABLE]: { - className: _fnSignal((p0)=>p0.value, [ - signal - ], "p0.value") - } - }, 3, "u6_1"), - /*#__PURE__*/ _jsxC(Foo, { - className: signal, - [_IMMUTABLE]: { - className: _IMMUTABLE - } - }, 3, "u6_2"), - /*#__PURE__*/ _jsxC(Foo, { - className: computed - }, 3, "u6_3") - ] - }, 1, "u6_4"); + const signal = _addLoc(useSignal(), "test.tsx", 6, 17); + const computed = _addLoc(signal.value + 'foo', "test.tsx", 7, 19); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, [ + /*#__PURE__*/ _jsxSorted("div", null, { + className: "hola" + }, null, 3, null), + /*#__PURE__*/ _jsxSorted("div", { + className: _wrapProp(signal) + }, null, null, 3, null), + /*#__PURE__*/ _jsxSorted("div", { + className: signal + }, null, null, 3, null), + /*#__PURE__*/ _jsxSorted("div", { + className: computed + }, null, null, 3, null), + /*#__PURE__*/ _jsxSorted(Foo, null, { + className: "hola" + }, null, 3, "u6_0"), + /*#__PURE__*/ _jsxSorted(Foo, null, { + className: _wrapProp(signal) + }, null, 3, "u6_1"), + /*#__PURE__*/ _jsxSorted(Foo, { + className: signal + }, null, null, 3, "u6_2"), + /*#__PURE__*/ _jsxSorted(Foo, { + className: computed + }, null, null, 3, "u6_3") + ], 1, "u6_4"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;0CAG+B;IAC3B,MAAM,SAAS;IACf,MAAM,WAAW,OAAO,KAAK,GAAG;IAChC,qBACI;;0BACI,MAAC;gBAAI,WAAU;;0BACf,MAAC;gBAAI,SAAS,kBAAE,GAAO,KAAK;;;;0BAC5B,MAAC;gBAAI,WAAW;;0BAChB,MAAC;gBAAI,WAAW;;0BAEhB,MAAC;gBAAI,WAAU;;oBAAV,SAAS;;;0BACd,MAAC;oBAAI;2BAAW,OAAO,KAAK;;;oBAAvB,SAAS,kBAAE,GAAO,KAAK;;;;;0BAC5B,MAAC;gBAAI,WAAW;;oBAAX,SAAS;;;0BACd,MAAC;gBAAI,WAAW;;;;AAG5B\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;0CAG+B;IAC9B,MAAM,SAAS,QAAA;IACf,MAAM,WAAW,QAAA,OAAO,KAAK,GAAG;IAChC,qBACC;sBACC,WAAC;YAAI,WAAU;;sBACf,WAAC;YAAI,SAAS,YAAE;;sBAChB,WAAC;YAAI,WAAW;;sBAChB,WAAC;YAAI,WAAW;;sBAEhB,WAAC;YAAI,WAAU;;sBACf,WAAC;YAAI,SAAS,YAAE;;sBAChB,WAAC;YAAI,WAAW;;sBAChB,WAAC;YAAI,WAAW;;;AAGnB\"}") /* { "origin": "test.tsx", @@ -107,8 +90,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 81, - 565 + 79, + 467 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_component_with_event_listeners_inside_loop.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_component_with_event_listeners_inside_loop.snap new file mode 100644 index 00000000000..8475f68d1b2 --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_component_with_event_listeners_inside_loop.snap @@ -0,0 +1,442 @@ +--- +source: packages/qwik/src/optimizer/core/src/test.rs +assertion_line: 3979 +expression: output +snapshot_kind: text +--- +==INPUT== + + +import { $, component$, useStore, useSignal } from '@qwik.dev/core'; +export const App = component$(() => { + const cart = useStore([]); + const results = useSignal(['foo']); + function loopArrowFn(results: string[]) { + return results.map((item) => ( + { + cart.push(item); + }} + > + {item} + + )); + } + function loopForI(results: string[]) { + const items = []; + for (let i = 0; i < results.length; i++) { + items.push( + { + cart.push(results[i]); + }} + > + {results[i]} + + ); + } + return items; + } + function loopForOf(results: string[]) { + const items = []; + for (const item of results) { + items.push( + { + cart.push(item); + }} + > + {item} + + ); + } + return items; + } + function loopForIn(results: string[]) { + const items = []; + for (const key in results) { + items.push( + { + cart.push(results[key]); + }} + > + {results[key]} + + ); + } + return items; + } + function loopWhile(results: string[]) { + const items = []; + let i = 0; + while (i < results.length) { + items.push( + { + cart.push(results[i]); + }} + > + {results[i]} + + ); + i++; + } + return items; + } + return ( +
        + {results.value.map((item) => ( + + ))} + {loopArrowFn(results.value)} + {loopForI(results.value)} + {loopForOf(results.value)} + {loopForIn(results.value)} + {loopWhile(results.value)} +
        + ); + }); + +============================= test.js == + +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")), "test.tsx", 4, 20); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAEA,OAAO,MAAM,oBAAM,QAAA,qIA+FZ\"}") +============================= test.tsx_span_onClick_3_SNi9ryRSSHk.js (ENTRY POINT)== + +import { useLexicalScope } from "@qwik.dev/core"; +export const span_onClick_3_SNi9ryRSSHk = ()=>{ + const [cart, i, results] = useLexicalScope(); + cart.push(results[i]); +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";0CAmEwB;;IACR,KAAK,IAAI,CAAC,OAAO,CAAC,EAAE\"}") +/* +{ + "origin": "test.tsx", + "name": "span_onClick_3_SNi9ryRSSHk", + "entry": null, + "displayName": "test.tsx_span_onClick_3", + "hash": "SNi9ryRSSHk", + "canonicalFilename": "test.tsx_span_onClick_3_SNi9ryRSSHk", + "path": "", + "extension": "js", + "parent": "App_component_ckEPmXZlub0", + "ctxKind": "eventHandler", + "ctxName": "onClick$", + "captures": true, + "loc": [ + 1693, + 1755 + ], + "captureNames": [ + "cart", + "i", + "results" + ] +} +*/ +============================= test.tsx_div_button_onClick_fM2x0QeHwqY.js (ENTRY POINT)== + +import { useLexicalScope } from "@qwik.dev/core"; +export const div_button_onClick_fM2x0QeHwqY = ()=>{ + const [cart, item] = useLexicalScope(); + cart.push(item); +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";8CAmFwB;;IACR,KAAK,IAAI,CAAC\"}") +/* +{ + "origin": "test.tsx", + "name": "div_button_onClick_fM2x0QeHwqY", + "entry": null, + "displayName": "test.tsx_div_button_onClick", + "hash": "fM2x0QeHwqY", + "canonicalFilename": "test.tsx_div_button_onClick_fM2x0QeHwqY", + "path": "", + "extension": "js", + "parent": "App_component_ckEPmXZlub0", + "ctxKind": "eventHandler", + "ctxName": "onClick$", + "captures": true, + "loc": [ + 2026, + 2082 + ], + "captureNames": [ + "cart", + "item" + ] +} +*/ +============================= test.tsx_loopArrowFn_span_onClick_dZY4CbPeza8.js (ENTRY POINT)== + +import { useLexicalScope } from "@qwik.dev/core"; +export const loopArrowFn_span_onClick_dZY4CbPeza8 = ()=>{ + const [cart, item] = useLexicalScope(); + cart.push(item); +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";oDAQsB;;IACR,KAAK,IAAI,CAAC\"}") +/* +{ + "origin": "test.tsx", + "name": "loopArrowFn_span_onClick_dZY4CbPeza8", + "entry": null, + "displayName": "test.tsx_loopArrowFn_span_onClick", + "hash": "dZY4CbPeza8", + "canonicalFilename": "test.tsx_loopArrowFn_span_onClick_dZY4CbPeza8", + "path": "", + "extension": "js", + "parent": "App_component_ckEPmXZlub0", + "ctxKind": "eventHandler", + "ctxName": "onClick$", + "captures": true, + "loc": [ + 319, + 371 + ], + "captureNames": [ + "cart", + "item" + ] +} +*/ +============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== + +import { _addLoc } from "@qwik.dev/core/internal"; +import { _fnSignal } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { useSignal } from "@qwik.dev/core"; +import { useStore } from "@qwik.dev/core"; +export const App_component_ckEPmXZlub0 = ()=>{ + const cart = _addLoc(useStore([]), "test.tsx", 5, 20); + const results = _addLoc(useSignal([ + 'foo' + ]), "test.tsx", 6, 23); + function loopArrowFn(results) { + return results.map((item)=>/*#__PURE__*/ _jsxSorted("span", { + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_loopArrowFn_span_onClick_dZY4CbPeza8"), "loopArrowFn_span_onClick_dZY4CbPeza8", [ + cart, + item + ]) + }, null, item, 0, "u6_0")); + } + function loopForI(results) { + const items = _addLoc([], "test.tsx", 19, 23); + for(let i = _addLoc(0, "test.tsx", 20, 22); i < results.length; i++)items.push(/*#__PURE__*/ _jsxSorted("span", { + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_span_onClick_bnc9pPZyjck"), "span_onClick_bnc9pPZyjck", [ + cart, + i, + results + ]) + }, null, _fnSignal((p0, p1)=>p1[p0], [ + i, + results + ], "p1[p0]"), 0, "u6_1")); + return items; + } + function loopForOf(results) { + const items = _addLoc([], "test.tsx", 34, 23); + for (const item of results)items.push(/*#__PURE__*/ _jsxSorted("span", { + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_span_onClick_1_VGRWU5xRxes"), "span_onClick_1_VGRWU5xRxes", [ + cart, + item + ]) + }, null, item, 2, "u6_2")); + return items; + } + function loopForIn(results) { + const items = _addLoc([], "test.tsx", 49, 23); + for(const key in results)items.push(/*#__PURE__*/ _jsxSorted("span", { + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_span_onClick_2_YbCllFwPBNk"), "span_onClick_2_YbCllFwPBNk", [ + cart, + key, + results + ]) + }, null, _fnSignal((p0, p1)=>p1[p0], [ + key, + results + ], "p1[p0]"), 0, "u6_3")); + return items; + } + function loopWhile(results) { + const items = _addLoc([], "test.tsx", 64, 23); + let i = _addLoc(0, "test.tsx", 65, 17); + while(i < results.length){ + items.push(/*#__PURE__*/ _jsxSorted("span", { + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_span_onClick_3_SNi9ryRSSHk"), "span_onClick_3_SNi9ryRSSHk", [ + cart, + i, + results + ]) + }, null, _fnSignal((p0, p1)=>p1[p0], [ + i, + results + ], "p1[p0]"), 0, "u6_4")); + i++; + } + return items; + } + return /*#__PURE__*/ _jsxSorted("div", null, null, [ + results.value.map((item)=>/*#__PURE__*/ _jsxSorted("button", { + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_div_button_onClick_fM2x0QeHwqY"), "div_button_onClick_fM2x0QeHwqY", [ + cart, + item + ]) + }, { + id: "second" + }, item, 0, "u6_5")), + loopArrowFn(results.value), + loopForI(results.value), + loopForOf(results.value), + loopForIn(results.value), + loopWhile(results.value) + ], 1, "u6_6"); +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;yCAE8B;IACxB,MAAM,OAAO,QAAA,SAAmB,EAAE;IAClC,MAAM,UAAU,QAAA,UAAU;QAAC;KAAM;IACjC,SAAS,YAAY,OAAiB;QACpC,OAAO,QAAQ,GAAG,CAAC,CAAC,qBAClB,WAAC;gBACC,QAAQ;;;;qBAIP;IAGP;IACA,SAAS,SAAS,OAAiB;QACjC,MAAM,QAAQ,QAAA,EAAE;QAChB,IAAK,IAAI,IAAI,QAAA,wBAAG,IAAI,QAAQ,MAAM,EAAE,IAClC,MAAM,IAAI,eACR,WAAC;YACC,QAAQ;;;;;qCAIP,EAAO,IAAG;;;;QAIjB,OAAO;IACT;IACA,SAAS,UAAU,OAAiB;QAClC,MAAM,QAAQ,QAAA,EAAE;QAChB,KAAK,MAAM,QAAQ,QACjB,MAAM,IAAI,eACR,WAAC;YACC,QAAQ;;;;iBAIP;QAIP,OAAO;IACT;IACA,SAAS,UAAU,OAAiB;QAClC,MAAM,QAAQ,QAAA,EAAE;QAChB,IAAK,MAAM,OAAO,QAChB,MAAM,IAAI,eACR,WAAC;YACC,QAAQ;;;;;qCAIP,EAAO,IAAK;;;;QAInB,OAAO;IACT;IACA,SAAS,UAAU,OAAiB;QAClC,MAAM,QAAQ,QAAA,EAAE;QAChB,IAAI,IAAI,QAAA;QACR,MAAO,IAAI,QAAQ,MAAM,CAAE;YACzB,MAAM,IAAI,eACR,WAAC;gBACC,QAAQ;;;;;yCAIP,EAAO,IAAG;;;;YAGf;QACF;QACA,OAAO;IACT;IACA,qBACE,WAAC;QACE,QAAQ,KAAK,CAAC,GAAG,CAAC,CAAC,qBAClB,WAAC;gBAEC,QAAQ;;;;;gBADR,IAAG;eAKF;QAGJ,YAAY,QAAQ,KAAK;QACzB,SAAS,QAAQ,KAAK;QACtB,UAAU,QAAQ,KAAK;QACvB,UAAU,QAAQ,KAAK;QACvB,UAAU,QAAQ,KAAK;;AAG9B\"}") +/* +{ + "origin": "test.tsx", + "name": "App_component_ckEPmXZlub0", + "entry": null, + "displayName": "test.tsx_App_component", + "hash": "ckEPmXZlub0", + "canonicalFilename": "test.tsx_App_component_ckEPmXZlub0", + "path": "", + "extension": "js", + "parent": null, + "ctxKind": "function", + "ctxName": "component$", + "captures": false, + "loc": [ + 101, + 2370 + ] +} +*/ +============================= test.tsx_span_onClick_bnc9pPZyjck.js (ENTRY POINT)== + +import { useLexicalScope } from "@qwik.dev/core"; +export const span_onClick_bnc9pPZyjck = ()=>{ + const [cart, i, results] = useLexicalScope(); + cart.push(results[i]); +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";wCAqBwB;;IACR,KAAK,IAAI,CAAC,OAAO,CAAC,EAAE\"}") +/* +{ + "origin": "test.tsx", + "name": "span_onClick_bnc9pPZyjck", + "entry": null, + "displayName": "test.tsx_span_onClick", + "hash": "bnc9pPZyjck", + "canonicalFilename": "test.tsx_span_onClick_bnc9pPZyjck", + "path": "", + "extension": "js", + "parent": "App_component_ckEPmXZlub0", + "ctxKind": "eventHandler", + "ctxName": "onClick$", + "captures": true, + "loc": [ + 628, + 690 + ], + "captureNames": [ + "cart", + "i", + "results" + ] +} +*/ +============================= test.tsx_span_onClick_2_YbCllFwPBNk.js (ENTRY POINT)== + +import { useLexicalScope } from "@qwik.dev/core"; +export const span_onClick_2_YbCllFwPBNk = ()=>{ + const [cart, key, results] = useLexicalScope(); + cart.push(results[key]); +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";0CAmDwB;;IACR,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI\"}") +/* +{ + "origin": "test.tsx", + "name": "span_onClick_2_YbCllFwPBNk", + "entry": null, + "displayName": "test.tsx_span_onClick_2", + "hash": "YbCllFwPBNk", + "canonicalFilename": "test.tsx_span_onClick_2_YbCllFwPBNk", + "path": "", + "extension": "js", + "parent": "App_component_ckEPmXZlub0", + "ctxKind": "eventHandler", + "ctxName": "onClick$", + "captures": true, + "loc": [ + 1319, + 1383 + ], + "captureNames": [ + "cart", + "key", + "results" + ] +} +*/ +============================= test.tsx_span_onClick_1_VGRWU5xRxes.js (ENTRY POINT)== + +import { useLexicalScope } from "@qwik.dev/core"; +export const span_onClick_1_VGRWU5xRxes = ()=>{ + const [cart, item] = useLexicalScope(); + cart.push(item); +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";0CAoCwB;;IACR,KAAK,IAAI,CAAC\"}") +/* +{ + "origin": "test.tsx", + "name": "span_onClick_1_VGRWU5xRxes", + "entry": null, + "displayName": "test.tsx_span_onClick_1", + "hash": "VGRWU5xRxes", + "canonicalFilename": "test.tsx_span_onClick_1_VGRWU5xRxes", + "path": "", + "extension": "js", + "parent": "App_component_ckEPmXZlub0", + "ctxKind": "eventHandler", + "ctxName": "onClick$", + "captures": true, + "loc": [ + 980, + 1036 + ], + "captureNames": [ + "cart", + "item" + ] +} +*/ +== DIAGNOSTICS == + +[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_custom_inlined_functions.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_custom_inlined_functions.snap index 05b25035161..cf844ffd187 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_custom_inlined_functions.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_custom_inlined_functions.snap @@ -1,82 +1,53 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1197 +assertion_line: 1307 expression: output snapshot_kind: text --- ==INPUT== -import { component$, $, useStore, wrap, useEffect } from '@builder.io/qwik'; +import { component$, $, useStore, wrap, useEffect } from '@qwik.dev/core'; export const useMemoQrl = (qrt) => { - useEffect(qrt); + useEffect(qrt); }; export const useMemo$ = wrap(useMemoQrl); export const App = component$((props) => { - const state = useStore({count: 0}); - useMemo$(() => { - console.log(state.count); - }); - return $(() => ( -
        {state.count}
        - )); + const state = useStore({count: 0}); + useMemo$(() => { + console.log(state.count); + }); + return $(() => ( +
        {state.count}
        + )); }); export const Lightweight = (props) => { - useMemo$(() => { - console.log(state.count); - }); + useMemo$(() => { + console.log(state.count); + }); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -import { wrap, useEffect } from '@builder.io/qwik'; -export const useMemoQrl = (qrt)=>{ +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { wrap, useEffect } from '@qwik.dev/core'; +export const useMemoQrl = _addLoc((qrt)=>{ useEffect(qrt); -}; -export const useMemo$ = wrap(useMemoQrl); -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")); -export const Lightweight = (props)=>{ +}, "test.tsx", 5, 27); +export const useMemo$ = _addLoc(wrap(useMemoQrl), "test.tsx", 9, 25); +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")), "test.tsx", 11, 20); +export const Lightweight = _addLoc((props)=>{ useMemoQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Lightweight_useMemo_UIcxVTQF1a8"), "Lightweight_useMemo_UIcxVTQF1a8")); -}; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AACA,SAAkC,IAAI,EAAE,SAAS,QAAQ,mBAAmB;AAE5E,OAAO,MAAM,aAAa,CAAC;IACvB,UAAU;AACd,EAAE;AAEF,OAAO,MAAM,WAAW,KAAK,YAAY;AAEzC,OAAO,MAAM,oBAAM,iHAQhB;AAEH,OAAO,MAAM,cAAc,CAAC;IACxB;AAGJ,EAAG\"}") -============================= test.tsx_App_component_useMemo_6Sc9KVki3Y0.js (ENTRY POINT)== +}, "test.tsx", 21, 28); -import { useLexicalScope } from "@builder.io/qwik"; -export const App_component_useMemo_6Sc9KVki3Y0 = ()=>{ - const [state] = useLexicalScope(); - console.log(state.count); -}; - -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";iDAWa;;IACL,QAAQ,GAAG,CAAC,MAAM,KAAK\"}") -/* -{ - "origin": "test.tsx", - "name": "App_component_useMemo_6Sc9KVki3Y0", - "entry": null, - "displayName": "test.tsx_App_component_useMemo", - "hash": "6Sc9KVki3Y0", - "canonicalFilename": "test.tsx_App_component_useMemo_6Sc9KVki3Y0", - "path": "", - "extension": "js", - "parent": "App_component_ckEPmXZlub0", - "ctxKind": "function", - "ctxName": "useMemo$", - "captures": true, - "loc": [ - 280, - 327 - ] -} -*/ +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AACA,SAAkC,IAAI,EAAE,SAAS,QAAQ,iBAAiB;AAE1E,OAAO,MAAM,aAAa,QAAA,CAAC;IAC1B,UAAU;AACX,sBAAE;AAEF,OAAO,MAAM,WAAW,QAAA,KAAK,gCAAY;AAEzC,OAAO,MAAM,oBAAM,QAAA,sIAQhB;AAEH,OAAO,MAAM,cAAc,QAAA,CAAC;IAC3B;AAGD,uBAAG\"}") ============================= test.tsx_Lightweight_useMemo_UIcxVTQF1a8.js (ENTRY POINT)== export const Lightweight_useMemo_UIcxVTQF1a8 = ()=>{ @@ -84,7 +55,7 @@ export const Lightweight_useMemo_UIcxVTQF1a8 = ()=>{ }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"+CAoBa;IACL,QAAQ,GAAG,CAAC,MAAM,KAAK;AAC3B\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"+CAoBU;IACR,QAAQ,GAAG,CAAC,MAAM,KAAK;AACxB\"}") /* { "origin": "test.tsx", @@ -100,30 +71,31 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "useMemo$", "captures": false, "loc": [ - 450, - 497 + 415, + 453 ] } */ ============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { qrl } from "@qwik.dev/core"; import { useMemoQrl } from "./test"; -import { useStore } from "@builder.io/qwik"; +import { useStore } from "@qwik.dev/core"; export const App_component_ckEPmXZlub0 = (props)=>{ - const state = useStore({ + const state = _addLoc(useStore({ count: 0 - }); - useMemoQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_useMemo_6Sc9KVki3Y0"), "App_component_useMemo_6Sc9KVki3Y0", [ + }), "test.tsx", 12, 16); + useMemoQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_useMemo_0Fw1Fv1C3tY"), "App_useMemo_0Fw1Fv1C3tY", [ state ])); - return /*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_1_w0t0o3QMovU"), "App_component_1_w0t0o3QMovU", [ + return /*#__PURE__*/ qrl(()=>import("./test.tsx_App_Jlq9hNxnCvw"), "App_Jlq9hNxnCvw", [ state ]); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;yCAS8B,CAAC;IAC3B,MAAM,QAAQ,SAAS;QAAC,OAAO;IAAC;IAChC;;;IAGA;;;AAGJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;yCAS8B,CAAC;IAC9B,MAAM,QAAQ,QAAA,SAAS;QAAC,OAAO;IAAC;IAChC;;;IAGA;;;AAGD\"}") /* { "origin": "test.tsx", @@ -139,34 +111,67 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 214, - 393 + 209, + 361 + ], + "paramNames": [ + "props" ] } */ -============================= test.tsx_App_component_1_w0t0o3QMovU.js (ENTRY POINT)== +============================= test.tsx_App_useMemo_0Fw1Fv1C3tY.js (ENTRY POINT)== -import { useLexicalScope } from "@builder.io/qwik"; -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -export const App_component_1_w0t0o3QMovU = ()=>{ +import { useLexicalScope } from "@qwik.dev/core"; +export const App_useMemo_0Fw1Fv1C3tY = ()=>{ const [state] = useLexicalScope(); - return /*#__PURE__*/ _jsxQ("div", null, null, _fnSignal((p0)=>p0.count, [ - state - ], "p0.count"), 3, "u6_0"); + console.log(state.count); +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";uCAWU;;IACR,QAAQ,GAAG,CAAC,MAAM,KAAK\"}") +/* +{ + "origin": "test.tsx", + "name": "App_useMemo_0Fw1Fv1C3tY", + "entry": null, + "displayName": "test.tsx_App_useMemo", + "hash": "0Fw1Fv1C3tY", + "canonicalFilename": "test.tsx_App_useMemo_0Fw1Fv1C3tY", + "path": "", + "extension": "js", + "parent": "App_component_ckEPmXZlub0", + "ctxKind": "function", + "ctxName": "useMemo$", + "captures": true, + "loc": [ + 269, + 307 + ], + "captureNames": [ + "state" + ] +} +*/ +============================= test.tsx_App_Jlq9hNxnCvw.js (ENTRY POINT)== + +import { useLexicalScope } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +export const App_Jlq9hNxnCvw = ()=>{ + const [state] = useLexicalScope(); + return /*#__PURE__*/ _jsxSorted("div", null, null, _wrapProp(state, "count"), 1, "u6_0"); }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;2CAca;;yBACL,MAAC,mCAAK,GAAM,KAAK\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;+BAcU;;yBACR,WAAC,6BAAK\"}") /* { "origin": "test.tsx", - "name": "App_component_1_w0t0o3QMovU", + "name": "App_Jlq9hNxnCvw", "entry": null, - "displayName": "test.tsx_App_component_1", - "hash": "w0t0o3QMovU", - "canonicalFilename": "test.tsx_App_component_1_w0t0o3QMovU", + "displayName": "test.tsx_App", + "hash": "Jlq9hNxnCvw", + "canonicalFilename": "test.tsx_App_Jlq9hNxnCvw", "path": "", "extension": "js", "parent": "App_component_ckEPmXZlub0", @@ -174,8 +179,11 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": true, "loc": [ - 343, - 389 + 320, + 357 + ], + "captureNames": [ + "state" ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_dead_code.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_dead_code.snap index 247c7548f95..2b0bcc3b438 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_dead_code.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_dead_code.snap @@ -7,18 +7,18 @@ snapshot_kind: text ==INPUT== -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; import { deps } from 'deps'; export const Foo = component$(({foo}) => { - useMount$(() => { - if (false) { - deps(); - } - }); - return ( -
        - ); + useMount$(() => { + if (false) { + deps(); + } + }); + return ( +
        + ); }) ============================= test.tsx_Foo_component_HTDRsvUbLiE.tsx (ENTRY POINT)== @@ -29,7 +29,7 @@ export const Foo_component_HTDRsvUbLiE = (props)=>{ }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"yCAI8B;IAC1B,UAAU,KAIV;IACA,QACK;AAET\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"yCAI8B;IAC7B,UAAU,KAIV;IACA,QACE;AAEH\"}") /* { "origin": "test.tsx", @@ -45,19 +45,23 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 109, - 240 + 107, + 199 + ], + "paramNames": [ + "props" ] } */ ============================= test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const Foo = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_HTDRsvUbLiE"), "Foo_component_HTDRsvUbLiE")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Foo = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_HTDRsvUbLiE"), "Foo_component_HTDRsvUbLiE")), "test.tsx", 6, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAIA,OAAO,MAAM,oBAAM,iHASjB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAIA,OAAO,MAAM,oBAAM,QAAA,qIASjB\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_default_export.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_default_export.snap index 7b251c52e14..f43def19ba6 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_default_export.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_default_export.snap @@ -1,27 +1,27 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1438 +assertion_line: 1548 expression: output snapshot_kind: text --- ==INPUT== -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; import { sibling } from './sibling'; export default component$(() => { - return ( -
        console.log(mongodb, sibling)}> -
        - ); + return ( +
        console.log(mongodb, sibling)}> +
        + ); }); ============================= src/routes/_repl/[id]/[[...slug]].js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; export default /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./[[...slug]].tsx_slug_component_0AM8HPnkNs4.js"), "slug_component_0AM8HPnkNs4")); @@ -32,7 +32,7 @@ import { sibling } from "./sibling"; export const slug_component_div_onClick_xevvy0Qc7pA = ()=>console.log(mongodb, sibling); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/routes/_repl/[id]/[[...slug]].tsx\"],\"names\":[],\"mappings\":\";sDAMuB,IAAM,QAAQ,GAAG,CAAC,SAAS\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/routes/_repl/[id]/[[...slug]].tsx\"],\"names\":[],\"mappings\":\";sDAMiB,IAAM,QAAQ,GAAG,CAAC,SAAS\"}") /* { "origin": "src/routes/_repl/[id]/[[...slug]].tsx", @@ -48,23 +48,23 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/routes/_repl/[id]/[[...sl "ctxName": "onClick$", "captures": false, "loc": [ - 157, - 192 + 146, + 181 ] } */ ============================= src/routes/_repl/[id]/[[...slug]].tsx_slug_component_0AM8HPnkNs4.js == -import { _jsxQ } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; +import { _jsxSorted } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; export const slug_component_0AM8HPnkNs4 = ()=>{ - return /*#__PURE__*/ _jsxQ("div", null, { + return /*#__PURE__*/ _jsxSorted("div", null, { onClick$: /*#__PURE__*/ qrl(()=>import("./[[...slug]].tsx_slug_component_div_onClick_xevvy0Qc7pA.js"), "slug_component_div_onClick_xevvy0Qc7pA") }, null, 3, "W4_0"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/routes/_repl/[id]/[[...slug]].tsx\"],\"names\":[],\"mappings\":\";;0CAI0B;IACtB,qBACI,MAAC;QAAI,QAAQ;;AAGrB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/routes/_repl/[id]/[[...slug]].tsx\"],\"names\":[],\"mappings\":\";;0CAI0B;IACzB,qBACC,WAAC;QAAI,QAAQ;;AAGf\"}") /* { "origin": "src/routes/_repl/[id]/[[...slug]].tsx", @@ -80,8 +80,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/routes/_repl/[id]/[[...sl "ctxName": "component$", "captures": false, "loc": [ - 113, - 218 + 111, + 198 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_default_export_index.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_default_export_index.snap index d6de89676b9..a83da1e3f64 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_default_export_index.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_default_export_index.snap @@ -1,33 +1,33 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1463 +assertion_line: 1573 expression: output snapshot_kind: text --- ==INPUT== -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export default component$(() => { - return ( -
        console.log(mongodb)}> -
        - ); + return ( +
        console.log(mongodb)}> +
        + ); }); ============================= src/components/mongo/index.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; +import { componentQrl } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; export default /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(()=>{ return
        console.log(mongodb), "mongo_component_div_onClick_2EK0wZbP8qw")}> -
        ; +
        ; }, "mongo_component_ouWLj4jA2oI")); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/components/mongo/index.tsx\"],\"names\":[],\"mappings\":\";;AAGA,6BAAe,sCAAW;IACtB,QACK,IAAI,mCAAU,IAAM,QAAQ,GAAG,CAAC,sDAAU;QAC3C,EAAE;AAEV,mCAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/components/mongo/index.tsx\"],\"names\":[],\"mappings\":\";;AAGA,6BAAe,sCAAW;IACzB,QACE,IAAI,mCAAU,IAAM,QAAQ,GAAG,CAAC,sDAAU;EAC3C,EAAE;AAEJ,mCAAG\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_default_export_invalid_ident.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_default_export_invalid_ident.snap index 8e8ab6c6746..c5e849c6d27 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_default_export_invalid_ident.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_default_export_invalid_ident.snap @@ -1,40 +1,40 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1484 +assertion_line: 1594 expression: output snapshot_kind: text --- ==INPUT== -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export default component$(() => { - return ( -
        console.log(mongodb)}> -
        - ); + return ( +
        console.log(mongodb)}> +
        + ); }); ============================= src/components/mongo/404.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; export default /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./404.tsx__404_component_zRvoWc98eqo"), "_404_component_zRvoWc98eqo")); Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/components/mongo/404.tsx\"],\"names\":[],\"mappings\":\";;AAGA,6BAAe,kHAKZ\"}") ============================= src/components/mongo/404.tsx__404_component_zRvoWc98eqo.tsx (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const _404_component_zRvoWc98eqo = ()=>{ return
        import("./404.tsx__404_component_div_onClick_OiMo9dvEW9Q"), "_404_component_div_onClick_OiMo9dvEW9Q")}> -
        ; +
        ; }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/components/mongo/404.tsx\"],\"names\":[],\"mappings\":\";0CAG0B;IACtB,QACK,IAAI,uIAAsC;QAC3C,EAAE;AAEV\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/components/mongo/404.tsx\"],\"names\":[],\"mappings\":\";0CAG0B;IACzB,QACE,IAAI,uIAAsC;EAC3C,EAAE;AAEJ\"}") /* { "origin": "src/components/mongo/404.tsx", @@ -50,8 +50,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/components/mongo/404.tsx\ "ctxName": "component$", "captures": false, "loc": [ - 76, - 172 + 74, + 152 ] } */ @@ -60,7 +60,7 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/components/mongo/404.tsx\ export const _404_component_div_onClick_OiMo9dvEW9Q = ()=>console.log(mongodb); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/components/mongo/404.tsx\"],\"names\":[],\"mappings\":\"sDAKuB,IAAM,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/components/mongo/404.tsx\"],\"names\":[],\"mappings\":\"sDAKiB,IAAM,QAAQ,GAAG,CAAC\"}") /* { "origin": "src/components/mongo/404.tsx", @@ -76,8 +76,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/src/components/mongo/404.tsx\ "ctxName": "onClick$", "captures": false, "loc": [ - 120, - 146 + 109, + 135 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_children.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_children.snap index 042c0fa8ae0..d00014c32e0 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_children.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_children.snap @@ -1,125 +1,116 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2751 +assertion_line: 2862 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore, mutable } from '@builder.io/qwik'; +import { component$, useStore, mutable } from '@qwik.dev/core'; import {dep} from './file'; export const TextContent = component$((props) => { - return ( - <> -
        data-nu: {props['data-nu']}
        -
        class: {props.class}
        - - ); + return ( + <> +
        data-nu: {props['data-nu']}
        +
        class: {props.class}
        + + ); }); export const App = component$(() => { - const signal = useSignal(0); - const store = useStore({}); - return ( - <> -
        text
        -
        {`text`}
        -
        {1}
        -
        {true}
        -
        {`text${12}`}
        -
        {typeof `text${12}` === 'string' ? 12 : 43}
        -
        {signal}
        -
        {signal.value}
        -
        {12 + signal.value}
        -
        {store.address.city.name}
        -
        {store.address.city.name ? 'true' : 'false'}
        -
        {dep}
        -
        {dep.thing}
        -
        {dep.thing + 'stuff'}
        -
        {globalThing}
        -
        {globalThing.thing}
        -
        {globalThing.thing + 'stuff'}
        -
        {signal.value()}
        -
        {signal.value + unknown()}
        -
        {mutable(signal)}
        -
        {signal.value + dep}
        - - ); + const signal = useSignal(0); + const store = useStore({}); + return ( + <> +
        text
        +
        {`text`}
        +
        {1}
        +
        {true}
        +
        {`text${12}`}
        +
        {typeof `text${12}` === 'string' ? 12 : 43}
        +
        {signal}
        +
        {signal.value}
        +
        {12 + signal.value}
        +
        {store.address.city.name}
        +
        {store.address.city.name ? 'true' : 'false'}
        +
        {dep}
        +
        {dep.thing}
        +
        {dep.thing + 'stuff'}
        +
        {globalThing}
        +
        {globalThing.thing}
        +
        {globalThing.thing + 'stuff'}
        +
        {signal.value()}
        +
        {signal.value + unknown()}
        +
        {mutable(signal)}
        +
        {signal.value + dep}
        + + ); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime"; -import { useStore, mutable } from '@builder.io/qwik'; +import { componentQrl } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _fnSignal } from "@qwik.dev/core"; +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { useStore, mutable } from '@qwik.dev/core'; import { dep } from './file'; const TextContent_component_puSwpKXO7Kg = (props)=>{ - return /*#__PURE__*/ _jsxC(_Fragment, { - children: [ - /*#__PURE__*/ _jsxQ("div", null, null, [ - "data-nu: ", - _fnSignal((p0)=>p0['data-nu'], [ - props - ], 'p0["data-nu"]') - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "class: ", - _fnSignal((p0)=>p0.class, [ - props - ], "p0.class") - ], 3, null) - ] - }, 3, "u6_0"); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, [ + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "data-nu: ", + _wrapProp(props, "data-nu") + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "class: ", + _wrapProp(props, "class") + ], 1, null) + ], 1, "u6_0"); }; -export const TextContent = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(TextContent_component_puSwpKXO7Kg, "TextContent_component_puSwpKXO7Kg")); +export const TextContent = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(TextContent_component_puSwpKXO7Kg, "TextContent_component_puSwpKXO7Kg")), "test.tsx", 7, 28); const App_component_ckEPmXZlub0 = ()=>{ - const signal = useSignal(0); - const store = useStore({}); - return /*#__PURE__*/ _jsxC(_Fragment, { - children: [ - /*#__PURE__*/ _jsxQ("div", null, null, "text", 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, `text`, 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, 1, 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, true, 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, `text${12}`, 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, typeof `text${12}` === 'string' ? 12 : 43, 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, signal, 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, _fnSignal((p0)=>p0.value, [ - signal - ], "p0.value"), 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, _fnSignal((p0)=>12 + p0.value, [ - signal - ], "12+p0.value"), 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, _fnSignal((p0)=>p0.address.city.name, [ - store - ], "p0.address.city.name"), 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, _fnSignal((p0)=>p0.address.city.name ? 'true' : 'false', [ - store - ], 'p0.address.city.name?"true":"false"'), 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, dep, 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, dep.thing, 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, dep.thing + 'stuff', 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, globalThing, 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, globalThing.thing, 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, globalThing.thing + 'stuff', 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, signal.value(), 1, null), - /*#__PURE__*/ _jsxQ("div", null, null, signal.value + unknown(), 1, null), - /*#__PURE__*/ _jsxQ("div", null, null, mutable(signal), 1, null), - /*#__PURE__*/ _jsxQ("div", null, null, signal.value + dep, 1, null) - ] - }, 1, "u6_1"); + const signal = _addLoc(useSignal(0), "test.tsx", 17, 17); + const store = _addLoc(useStore({}), "test.tsx", 18, 16); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, [ + /*#__PURE__*/ _jsxSorted("div", null, null, "text", 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, `text`, 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, 1, 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, true, 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, `text${12}`, 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, typeof `text${12}` === 'string' ? 12 : 43, 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, signal, 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, _wrapProp(signal), 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, _fnSignal((p0)=>12 + p0.value, [ + signal + ], "12+p0.value"), 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, _fnSignal((p0)=>p0.address.city.name, [ + store + ], "p0.address.city.name"), 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, _fnSignal((p0)=>p0.address.city.name ? 'true' : 'false', [ + store + ], 'p0.address.city.name?"true":"false"'), 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, dep, 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, dep.thing, 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, dep.thing + 'stuff', 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, globalThing, 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, globalThing.thing, 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, globalThing.thing + 'stuff', 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, signal.value(), 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, signal.value + unknown(), 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, mutable(signal), 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, signal.value + dep, 1, null) + ], 1, "u6_1"); }; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(App_component_ckEPmXZlub0, "App_component_ckEPmXZlub0")); +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(App_component_ckEPmXZlub0, "App_component_ckEPmXZlub0")), "test.tsx", 16, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;AACA,SAAqB,QAAQ,EAAE,OAAO,QAAQ,mBAAmB;AAEjE,SAAQ,GAAG,QAAO,SAAS;0CAEW,CAAC;IACnC,qBACI;;0BACI,MAAC;gBAAI;gCAAU,EAAK,CAAC,UAAU;;;;0BAC/B,MAAC;gBAAI;gCAAQ,GAAM,KAAK;;;;;;AAGpC;AAPA,OAAO,MAAM,4BAAc,+GAOxB;kCAE2B;IAC1B,MAAM,SAAS,UAAU;IACzB,MAAM,QAAQ,SAAS,CAAC;IACxB,qBACI;;0BACI,MAAC,mBAAI;0BACL,MAAC,mBAAK,CAAC,IAAI,CAAC;0BACZ,MAAC,mBAAK;0BACN,MAAC,mBAAK;0BACN,MAAC,mBAAK,CAAC,IAAI,EAAE,IAAI;0BACjB,MAAC,mBAAK,OAAO,CAAC,IAAI,EAAE,IAAI,KAAK,WAAW,KAAK;0BAC7C,MAAC,mBAAK;0BACN,MAAC,mCAAK,GAAO,KAAK;;;0BAClB,MAAC,mCAAK,KAAK,GAAO,KAAK;;;0BACvB,MAAC,mCAAK,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI;;;0BAC7B,MAAC,mCAAK,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,SAAS;;;0BACzC,MAAC,mBAAK;0BACN,MAAC,mBAAK,IAAI,KAAK;0BACf,MAAC,mBAAK,IAAI,KAAK,GAAG;0BAClB,MAAC,mBAAK;0BACN,MAAC,mBAAK,YAAY,KAAK;0BACvB,MAAC,mBAAK,YAAY,KAAK,GAAG;0BAC1B,MAAC,mBAAK,OAAO,KAAK;0BAClB,MAAC,mBAAK,OAAO,KAAK,GAAG;0BACrB,MAAC,mBAAK,QAAQ;0BACd,MAAC,mBAAK,OAAO,KAAK,GAAG;;;AAGjC;AA5BA,OAAO,MAAM,oBAAM,+FA4BhB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;AACA,SAAqB,QAAQ,EAAE,OAAO,QAAQ,iBAAiB;AAE/D,SAAQ,GAAG,QAAO,SAAS;0CAEW,CAAC;IACtC,qBACC;sBACC,WAAC;YAAI;sBAAU;;sBACf,WAAC;YAAI;sBAAQ;;;AAGhB;AAPA,OAAO,MAAM,4BAAc,QAAA,mIAOxB;kCAE2B;IAC7B,MAAM,SAAS,QAAA,UAAU;IACzB,MAAM,QAAQ,QAAA,SAAS,CAAC;IACxB,qBACC;sBACC,WAAC,mBAAI;sBACL,WAAC,mBAAK,CAAC,IAAI,CAAC;sBACZ,WAAC,mBAAK;sBACN,WAAC,mBAAK;sBACN,WAAC,mBAAK,CAAC,IAAI,EAAE,IAAI;sBACjB,WAAC,mBAAK,OAAO,CAAC,IAAI,EAAE,IAAI,KAAK,WAAW,KAAK;sBAC7C,WAAC,mBAAK;sBACN,WAAC,6BAAK;sBACN,WAAC,mCAAK,KAAK,GAAO,KAAK;;;sBACvB,WAAC,mCAAK,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI;;;sBAC7B,WAAC,mCAAK,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,SAAS;;;sBACzC,WAAC,mBAAK;sBACN,WAAC,mBAAK,IAAI,KAAK;sBACf,WAAC,mBAAK,IAAI,KAAK,GAAG;sBAClB,WAAC,mBAAK;sBACN,WAAC,mBAAK,YAAY,KAAK;sBACvB,WAAC,mBAAK,YAAY,KAAK,GAAG;sBAC1B,WAAC,mBAAK,OAAO,KAAK;sBAClB,WAAC,mBAAK,OAAO,KAAK,GAAG;sBACrB,WAAC,mBAAK,QAAQ;sBACd,WAAC,mBAAK,OAAO,KAAK,GAAG;;AAGxB;AA5BA,OAAO,MAAM,oBAAM,QAAA,oHA4BhB\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_cmp.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_cmp.snap index e67c9a21b48..1f0cea74cef 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_cmp.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_cmp.snap @@ -1,149 +1,102 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2884 +assertion_line: 2995 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore, mutable } from '@builder.io/qwik'; +import { component$, useStore, mutable } from '@qwik.dev/core'; import {dep} from './file'; import {Cmp} from './cmp'; export const App = component$(() => { - const signal = useSignal(0); - const store = useStore({}); - return ( - - ); + noInline={signal.value()} + noInline2={signal.value + unknown()} + noInline3={mutable(signal)} + noInline4={signal.value + dep} + /> + ); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { _IMMUTABLE } from "@builder.io/qwik"; -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { useStore, mutable } from '@builder.io/qwik'; +import { componentQrl } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { _fnSignal } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { useStore, mutable } from '@qwik.dev/core'; import { dep } from './file'; import { Cmp } from './cmp'; const App_component_ckEPmXZlub0 = ()=>{ - const signal = useSignal(0); - const store = useStore({}); - return /*#__PURE__*/ _jsxC(Cmp, { + const signal = _addLoc(useSignal(0), "test.tsx", 9, 17); + const store = _addLoc(useStore({}), "test.tsx", 10, 16); + return /*#__PURE__*/ _jsxSorted(Cmp, { + global: globalThing, + globalAccess: globalThing.thing, + globalComputed: globalThing.thing + 'stuff', + noInline: signal.value(), + noInline2: signal.value + unknown(), + noInline3: mutable(signal), + noInline4: signal.value + dep, + signal: signal + }, { staticText: "text", staticText2: `text`, staticNumber: 1, staticBoolean: true, staticExpr: `text${12}`, staticExpr2: typeof `text${12}` === 'string' ? 12 : 43, - signal: signal, - get signalValue () { - return signal.value; - }, - get signalComputedValue () { - return 12 + signal.value; - }, - get store () { - return store.address.city.name; - }, - get storeComputed () { - return store.address.city.name ? 'true' : 'false'; - }, + signalValue: _wrapProp(signal), + signalComputedValue: _fnSignal((p0)=>12 + p0.value, [ + signal + ], "12+p0.value"), + store: _fnSignal((p0)=>p0.address.city.name, [ + store + ], "p0.address.city.name"), + storeComputed: _fnSignal((p0)=>p0.address.city.name ? 'true' : 'false', [ + store + ], 'p0.address.city.name?"true":"false"'), dep: dep, - get depAccess () { - return dep.thing; - }, - get depComputed () { - return dep.thing + 'stuff'; - }, - get global () { - return globalThing; - }, - get globalAccess () { - return globalThing.thing; - }, - get globalComputed () { - return globalThing.thing + 'stuff'; - }, - get noInline () { - return signal.value(); - }, - get noInline2 () { - return signal.value + unknown(); - }, - noInline3: mutable(signal), - noInline4: signal.value + dep, - [_IMMUTABLE]: { - staticText: _IMMUTABLE, - staticText2: _IMMUTABLE, - staticNumber: _IMMUTABLE, - staticBoolean: _IMMUTABLE, - staticExpr: _IMMUTABLE, - staticExpr2: _IMMUTABLE, - signal: _IMMUTABLE, - signalValue: _fnSignal((p0)=>p0.value, [ - signal - ], "p0.value"), - signalComputedValue: _fnSignal((p0)=>12 + p0.value, [ - signal - ], "12+p0.value"), - store: _fnSignal((p0)=>p0.address.city.name, [ - store - ], "p0.address.city.name"), - storeComputed: _fnSignal((p0)=>p0.address.city.name ? 'true' : 'false', [ - store - ], 'p0.address.city.name?"true":"false"'), - dep: _IMMUTABLE, - depAccess: _IMMUTABLE, - depComputed: _IMMUTABLE, - global: _IMMUTABLE, - globalAccess: _IMMUTABLE, - globalComputed: _IMMUTABLE, - noInline: _fnSignal((p0)=>p0.value(), [ - signal - ], "p0.value()"), - noInline2: _fnSignal((p0)=>p0.value + unknown(), [ - signal - ], "p0.value+unknown()") - } - }, 3, "u6_0"); + depAccess: dep.thing, + depComputed: dep.thing + 'stuff' + }, null, 3, "u6_0"); }; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(App_component_ckEPmXZlub0, "App_component_ckEPmXZlub0")); +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(App_component_ckEPmXZlub0, "App_component_ckEPmXZlub0")), "test.tsx", 8, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AACA,SAAqB,QAAQ,EAAE,OAAO,QAAQ,mBAAmB;AAEjE,SAAQ,GAAG,QAAO,SAAS;AAC3B,SAAQ,GAAG,QAAO,QAAQ;kCAEI;IAC1B,MAAM,SAAS,UAAU;IACzB,MAAM,QAAQ,SAAS,CAAC;IACxB,qBACI,MAAC;QACG,YAAW;QACX,aAAa,CAAC,IAAI,CAAC;QACnB,cAAc;QACd,eAAe;QACf,YAAY,CAAC,IAAI,EAAE,IAAI;QACvB,aAAa,OAAO,CAAC,IAAI,EAAE,IAAI,KAAK,WAAW,KAAK;QAEpD,QAAQ;YACR;mBAAa,OAAO,KAAK;;YACzB;mBAAqB,KAAK,OAAO,KAAK;;YAEtC;mBAAO,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI;;YAC9B;mBAAe,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,SAAS;;QAElD,KAAK;YACL;mBAAW,IAAI,KAAK;;YACpB;mBAAa,IAAI,KAAK,GAAG;;YAEzB;mBAAQ;;YACR;mBAAc,YAAY,KAAK;;YAC/B;mBAAgB,YAAY,KAAK,GAAG;;YAGpC;mBAAU,OAAO,KAAK;;YACtB;mBAAW,OAAO,KAAK,GAAG;;QAC1B,WAAW,QAAQ;QACnB,WAAW,OAAO,KAAK,GAAG;;YA1B1B,UAAU;YACV,WAAW;YACX,YAAY;YACZ,aAAa;YACb,UAAU;YACV,WAAW;YAEX,MAAM;YACN,WAAW,kBAAE,GAAO,KAAK;;;YACzB,mBAAmB,kBAAE,KAAK,GAAO,KAAK;;;YAEtC,KAAK,kBAAE,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI;;;YAC9B,aAAa,kBAAE,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,SAAS;;;YAElD,GAAG;YACH,SAAS;YACT,WAAW;YAEX,MAAM;YACN,YAAY;YACZ,cAAc;YAGd,QAAQ,kBAAE,GAAO,KAAK;;;YACtB,SAAS,kBAAE,GAAO,KAAK,GAAG;;;;;AAKtC;AAlCA,OAAO,MAAM,oBAAM,+FAkChB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;AACA,SAAqB,QAAQ,EAAE,OAAO,QAAQ,iBAAiB;AAE/D,SAAQ,GAAG,QAAO,SAAS;AAC3B,SAAQ,GAAG,QAAO,QAAQ;kCAEI;IAC7B,MAAM,SAAS,QAAA,UAAU;IACzB,MAAM,QAAQ,QAAA,SAAS,CAAC;IACxB,qBACC,WAAC;QAmBA,QAAQ;QACR,cAAc,YAAY,KAAK;QAC/B,gBAAgB,YAAY,KAAK,GAAG;QAGpC,UAAU,OAAO,KAAK;QACtB,WAAW,OAAO,KAAK,GAAG;QAC1B,WAAW,QAAQ;QACnB,WAAW,OAAO,KAAK,GAAG;QAnB1B,QAAQ;;QAPR,YAAW;QACX,aAAa,CAAC,IAAI,CAAC;QACnB,cAAc;QACd,eAAe;QACf,YAAY,CAAC,IAAI,EAAE,IAAI;QACvB,aAAa,OAAO,CAAC,IAAI,EAAE,IAAI,KAAK,WAAW,KAAK;QAGpD,WAAW,YAAE;QACb,mBAAmB,kBAAE,KAAK,GAAO,KAAK;;;QAEtC,KAAK,kBAAE,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI;;;QAC9B,aAAa,kBAAE,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,SAAS;;;QAElD,KAAK;QACL,WAAW,IAAI,KAAK;QACpB,aAAa,IAAI,KAAK,GAAG;;AAa5B;AAlCA,OAAO,MAAM,oBAAM,QAAA,mHAkChB\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_complext_children.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_complext_children.snap index 85e45ed4337..1d40e44ab58 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_complext_children.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_complext_children.snap @@ -1,57 +1,55 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2852 +assertion_line: 2963 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore, mutable } from '@builder.io/qwik'; +import { component$, useStore, mutable } from '@qwik.dev/core'; import {dep} from './file'; export const App = component$(() => { - const signal = useSignal(0); - const store = useStore({}); - return ( - <> -
          - {Object.entries(store).map(([key, value]) => ( -
        • - {key} - {value} -
        • - ))} -
        - - ); + const signal = useSignal(0); + const store = useStore({}); + return ( + <> +
          + {Object.entries(store).map(([key, value]) => ( +
        • + {key} - {value} +
        • + ))} +
        + + ); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime"; -import { useStore } from '@builder.io/qwik'; +import { componentQrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { useStore } from '@qwik.dev/core'; const App_component_ckEPmXZlub0 = ()=>{ - useSignal(0); - const store = useStore({}); - return /*#__PURE__*/ _jsxC(_Fragment, { - children: /*#__PURE__*/ _jsxQ("ul", null, { - id: "issue-2800-result" - }, Object.entries(store).map(([key, value])=>/*#__PURE__*/ _jsxQ("li", null, null, [ - key, - " - ", - value - ], 1, "u6_0")), 1, null) - }, 1, "u6_1"); + _addLoc(useSignal(0), "test.tsx", 8, 17); + const store = _addLoc(useStore({}), "test.tsx", 9, 16); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, /*#__PURE__*/ _jsxSorted("ul", null, { + id: "issue-2800-result" + }, Object.entries(store).map(([key, value])=>/*#__PURE__*/ _jsxSorted("li", null, null, [ + key, + " - ", + value + ], 1, "u6_0")), 1, null), 1, "u6_1"); }; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(App_component_ckEPmXZlub0, "App_component_ckEPmXZlub0")); +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(App_component_ckEPmXZlub0, "App_component_ckEPmXZlub0")), "test.tsx", 7, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AACA,SAAqB,QAAQ,QAAiB,mBAAmB;kCAInC;IACX,UAAU;IACzB,MAAM,QAAQ,SAAS,CAAC;IACxB,qBACI;kBACI,cAAA,MAAC;YAAG,IAAG;WACF,OAAO,OAAO,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,MAAM,iBACxC,MAAC;gBACI;gBAAI;gBAAI;;;AAM7B;AAdA,OAAO,MAAM,oBAAM,+FAchB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AACA,SAAqB,QAAQ,QAAiB,iBAAiB;kCAIjC;IACd,QAAA,UAAU;IACzB,MAAM,QAAQ,QAAA,SAAS,CAAC;IACxB,qBACC,gDACC,WAAC;QAAG,IAAG;OACL,OAAO,OAAO,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,MAAM,iBACxC,WAAC;YACC;YAAI;YAAI;;AAMd;AAdA,OAAO,MAAM,oBAAM,QAAA,mHAchB\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_div.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_div.snap index e19fc17f659..4a2e7b7239d 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_div.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_div.snap @@ -1,126 +1,122 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2663 +assertion_line: 2774 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore, mutable } from '@builder.io/qwik'; +import { component$, useStore, mutable } from '@qwik.dev/core'; import {dep} from './file'; import styles from './styles.module.css'; export const App = component$((props) => { - const signal = useSignal(0); - const store = useStore({}); - const count = props.counter.count; - - return ( -
        - - ); + const signal = useSignal(0); + const store = useStore({}); + const count = props.counter.count; + + return ( +
        + + ); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { useStore, mutable } from '@builder.io/qwik'; +import { componentQrl } from "@qwik.dev/core"; +import { _fnSignal } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { useStore, mutable } from '@qwik.dev/core'; import { dep } from './file'; import styles from './styles.module.css'; const App_component_ckEPmXZlub0 = (props)=>{ - const signal = useSignal(0); - const store = useStore({}); - const count = props.counter.count; - return /*#__PURE__*/ _jsxQ("div", { + const signal = _addLoc(useSignal(0), "test.tsx", 9, 17); + const store = _addLoc(useStore({}), "test.tsx", 10, 16); + const count = _addLoc(props.counter.count, "test.tsx", 11, 16); + return /*#__PURE__*/ _jsxSorted("div", { class: { even: count % 2 === 0, odd: count % 2 === 1, stable0: true, hidden: false }, + global: globalThing, + globalAccess: globalThing.thing, + globalComputed: globalThing.thing + 'stuff', + noInline: signal.value(), + noInline2: signal.value + unknown(), noInline3: mutable(signal), - noInline4: signal.value + dep - }, { - staticClass: styles.foo, - staticDocument: window.document, - staticText: "text", - staticText2: `text`, - staticNumber: 1, - staticBoolean: true, - staticExpr: `text${12}`, - staticExpr2: typeof `text${12}` === 'string' ? 12 : 43, + noInline4: signal.value + dep, signal: signal, - signalValue: _fnSignal((p0)=>p0.value, [ - signal - ], "p0.value"), signalComputedValue: _fnSignal((p0)=>12 + p0.value, [ signal ], "12+p0.value"), + signalValue: _wrapProp(signal), + staticDocument: window.document, store: _fnSignal((p0)=>p0.address.city.name, [ store ], "p0.address.city.name"), storeComputed: _fnSignal((p0)=>p0.address.city.name ? 'true' : 'false', [ store - ], 'p0.address.city.name?"true":"false"'), + ], 'p0.address.city.name?"true":"false"') + }, { + staticClass: styles.foo, + staticText: "text", + staticText2: `text`, + staticNumber: 1, + staticBoolean: true, + staticExpr: `text${12}`, + staticExpr2: typeof `text${12}` === 'string' ? 12 : 43, dep: dep, depAccess: dep.thing, - depComputed: dep.thing + 'stuff', - global: globalThing, - globalAccess: globalThing.thing, - globalComputed: globalThing.thing + 'stuff', - noInline: _fnSignal((p0)=>p0.value(), [ - signal - ], "p0.value()"), - noInline2: _fnSignal((p0)=>p0.value + unknown(), [ - signal - ], "p0.value+unknown()") + depComputed: dep.thing + 'stuff' }, null, 3, "u6_0"); }; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(App_component_ckEPmXZlub0, "App_component_ckEPmXZlub0")); +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(App_component_ckEPmXZlub0, "App_component_ckEPmXZlub0")), "test.tsx", 8, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;AACA,SAAqB,QAAQ,EAAE,OAAO,QAAQ,mBAAmB;AAEjE,SAAQ,GAAG,QAAO,SAAS;AAC3B,OAAO,YAAY,sBAAsB;kCAEX,CAAC;IAC3B,MAAM,SAAS,UAAU;IACzB,MAAM,QAAQ,SAAS,CAAC;IACxB,MAAM,QAAQ,MAAM,OAAO,CAAC,KAAK;IAEjC,qBACI,MAAC;QACG,OAAO;YACH,MAAM,QAAQ,MAAM;YACpB,KAAK,QAAQ,MAAM;YACnB,SAAS;YACT,QAAQ;QACZ;QA4BA,WAAW,QAAQ;QACnB,WAAW,OAAO,KAAK,GAAG;;QA5B1B,aAAa,OAAO,GAAG;QACvB,gBAAgB,OAAO,QAAQ;QAC/B,YAAW;QACX,aAAa,CAAC,IAAI,CAAC;QACnB,cAAc;QACd,eAAe;QACf,YAAY,CAAC,IAAI,EAAE,IAAI;QACvB,aAAa,OAAO,CAAC,IAAI,EAAE,IAAI,KAAK,WAAW,KAAK;QAEpD,QAAQ;QACR,WAAW,kBAAE,GAAO,KAAK;;;QACzB,mBAAmB,kBAAE,KAAK,GAAO,KAAK;;;QAEtC,KAAK,kBAAE,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI;;;QAC9B,aAAa,kBAAE,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,SAAS;;;QAElD,KAAK;QACL,WAAW,IAAI,KAAK;QACpB,aAAa,IAAI,KAAK,GAAG;QAEzB,QAAQ;QACR,cAAc,YAAY,KAAK;QAC/B,gBAAgB,YAAY,KAAK,GAAG;QAGpC,QAAQ,kBAAE,GAAO,KAAK;;;QACtB,SAAS,kBAAE,GAAO,KAAK,GAAG;;;;AAMtC;AA7CA,OAAO,MAAM,oBAAM,+FA6ChB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;AACA,SAAqB,QAAQ,EAAE,OAAO,QAAQ,iBAAiB;AAE/D,SAAQ,GAAG,QAAO,SAAS;AAC3B,OAAO,YAAY,sBAAsB;kCAEX,CAAC;IAC9B,MAAM,SAAS,QAAA,UAAU;IACzB,MAAM,QAAQ,QAAA,SAAS,CAAC;IACxB,MAAM,QAAQ,QAAA,MAAM,OAAO,CAAC,KAAK;IAEjC,qBACC,WAAC;QACA,OAAO;YACN,MAAM,QAAQ,MAAM;YACpB,KAAK,QAAQ,MAAM;YACnB,SAAS;YACT,QAAQ;QACT;QAqBA,QAAQ;QACR,cAAc,YAAY,KAAK;QAC/B,gBAAgB,YAAY,KAAK,GAAG;QAGpC,UAAU,OAAO,KAAK;QACtB,WAAW,OAAO,KAAK,GAAG;QAC1B,WAAW,QAAQ;QACnB,WAAW,OAAO,KAAK,GAAG;QAnB1B,QAAQ;QAER,mBAAmB,kBAAE,KAAK,GAAO,KAAK;;;QADtC,WAAW,YAAE;QATb,gBAAgB,OAAO,QAAQ;QAY/B,KAAK,kBAAE,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI;;;QAC9B,aAAa,kBAAE,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,SAAS;;;;QAdlD,aAAa,OAAO,GAAG;QAEvB,YAAW;QACX,aAAa,CAAC,IAAI,CAAC;QACnB,cAAc;QACd,eAAe;QACf,YAAY,CAAC,IAAI,EAAE,IAAI;QACvB,aAAa,OAAO,CAAC,IAAI,EAAE,IAAI,KAAK,WAAW,KAAK;QASpD,KAAK;QACL,WAAW,IAAI,KAAK;QACpB,aAAa,IAAI,KAAK,GAAG;;AAc5B;AA7CA,OAAO,MAAM,oBAAM,QAAA,mHA6ChB\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_multiple_children.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_multiple_children.snap index 17ab5d79ef1..698df6bfe9f 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_multiple_children.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_derived_signals_multiple_children.snap @@ -1,157 +1,154 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2806 +assertion_line: 2917 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore, mutable } from '@builder.io/qwik'; +import { component$, useStore, mutable } from '@qwik.dev/core'; import {dep} from './file'; export const App = component$(() => { - const signal = useSignal(0); - const store = useStore({}); - return ( - <> -
        First text
        -
        First {`text`}
        -
        First {1}
        -
        First {true}
        -
        First {`text${12}`}
        -
        First {typeof `text${12}` === 'string' ? 12 : 43}
        -
        First {signal}
        -
        First {signal.value}
        -
        First {12 + signal.value}
        -
        First {store.address.city.name}
        -
        First {store.address.city.name ? 'true' : 'false'}
        -
        First {dep}
        -
        First {dep.thing}
        -
        First {dep.thing + 'stuff'}
        -
        First {globalThing}
        -
        First {globalThing.thing}
        -
        First {globalThing.thing + 'stuff'}
        -
        First {signal.value()}
        -
        First {signal.value + unknown()}
        -
        First {mutable(signal)}
        -
        First {signal.value + dep}
        - - ); + const signal = useSignal(0); + const store = useStore({}); + return ( + <> +
        First text
        +
        First {`text`}
        +
        First {1}
        +
        First {true}
        +
        First {`text${12}`}
        +
        First {typeof `text${12}` === 'string' ? 12 : 43}
        +
        First {signal}
        +
        First {signal.value}
        +
        First {12 + signal.value}
        +
        First {store.address.city.name}
        +
        First {store.address.city.name ? 'true' : 'false'}
        +
        First {dep}
        +
        First {dep.thing}
        +
        First {dep.thing + 'stuff'}
        +
        First {globalThing}
        +
        First {globalThing.thing}
        +
        First {globalThing.thing + 'stuff'}
        +
        First {signal.value()}
        +
        First {signal.value + unknown()}
        +
        First {mutable(signal)}
        +
        First {signal.value + dep}
        + + ); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime"; -import { useStore, mutable } from '@builder.io/qwik'; +import { componentQrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { _fnSignal } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { useStore, mutable } from '@qwik.dev/core'; import { dep } from './file'; const App_component_ckEPmXZlub0 = ()=>{ - const signal = useSignal(0); - const store = useStore({}); - return /*#__PURE__*/ _jsxC(_Fragment, { - children: [ - /*#__PURE__*/ _jsxQ("div", null, null, "First text", 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - `text` - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - 1 - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - true - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - `text${12}` - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - typeof `text${12}` === 'string' ? 12 : 43 - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", + const signal = _addLoc(useSignal(0), "test.tsx", 8, 17); + const store = _addLoc(useStore({}), "test.tsx", 9, 16); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, [ + /*#__PURE__*/ _jsxSorted("div", null, null, "First text", 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + `text` + ], 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + 1 + ], 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + true + ], 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + `text${12}` + ], 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + typeof `text${12}` === 'string' ? 12 : 43 + ], 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + signal + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + _wrapProp(signal) + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + _fnSignal((p0)=>12 + p0.value, [ signal - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - _fnSignal((p0)=>p0.value, [ - signal - ], "p0.value") - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - _fnSignal((p0)=>12 + p0.value, [ - signal - ], "12+p0.value") - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - _fnSignal((p0)=>p0.address.city.name, [ - store - ], "p0.address.city.name") - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - _fnSignal((p0)=>p0.address.city.name ? 'true' : 'false', [ - store - ], 'p0.address.city.name?"true":"false"') - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - dep - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - dep.thing - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - dep.thing + 'stuff' - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - globalThing - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - globalThing.thing - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - globalThing.thing + 'stuff' - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - signal.value() - ], 1, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - signal.value + unknown() - ], 1, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - mutable(signal) - ], 1, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "First ", - signal.value + dep - ], 1, null) - ] - }, 1, "u6_0"); + ], "12+p0.value") + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + _fnSignal((p0)=>p0.address.city.name, [ + store + ], "p0.address.city.name") + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + _fnSignal((p0)=>p0.address.city.name ? 'true' : 'false', [ + store + ], 'p0.address.city.name?"true":"false"') + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + dep + ], 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + dep.thing + ], 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + dep.thing + 'stuff' + ], 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + globalThing + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + globalThing.thing + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + globalThing.thing + 'stuff' + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + signal.value() + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + signal.value + unknown() + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + mutable(signal) + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "First ", + signal.value + dep + ], 1, null) + ], 1, "u6_0"); }; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(App_component_ckEPmXZlub0, "App_component_ckEPmXZlub0")); +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(App_component_ckEPmXZlub0, "App_component_ckEPmXZlub0")), "test.tsx", 7, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;AACA,SAAqB,QAAQ,EAAE,OAAO,QAAQ,mBAAmB;AAEjE,SAAQ,GAAG,QAAO,SAAS;kCAEG;IAC1B,MAAM,SAAS,UAAU;IACzB,MAAM,QAAQ,SAAS,CAAC;IACxB,qBACI;;0BACI,MAAC,mBAAI;0BACL,MAAC;gBAAI;gBAAO,CAAC,IAAI,CAAC;;0BAClB,MAAC;gBAAI;gBAAO;;0BACZ,MAAC;gBAAI;gBAAO;;0BACZ,MAAC;gBAAI;gBAAO,CAAC,IAAI,EAAE,IAAI;;0BACvB,MAAC;gBAAI;gBAAO,OAAO,CAAC,IAAI,EAAE,IAAI,KAAK,WAAW,KAAK;;0BACnD,MAAC;gBAAI;gBAAO;;0BACZ,MAAC;gBAAI;gCAAO,GAAO,KAAK;;;;0BACxB,MAAC;gBAAI;gCAAO,KAAK,GAAO,KAAK;;;;0BAC7B,MAAC;gBAAI;gCAAO,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI;;;;0BACnC,MAAC;gBAAI;gCAAO,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,SAAS;;;;0BAC/C,MAAC;gBAAI;gBAAO;;0BACZ,MAAC;gBAAI;gBAAO,IAAI,KAAK;;0BACrB,MAAC;gBAAI;gBAAO,IAAI,KAAK,GAAG;;0BACxB,MAAC;gBAAI;gBAAO;;0BACZ,MAAC;gBAAI;gBAAO,YAAY,KAAK;;0BAC7B,MAAC;gBAAI;gBAAO,YAAY,KAAK,GAAG;;0BAChC,MAAC;gBAAI;gBAAO,OAAO,KAAK;;0BACxB,MAAC;gBAAI;gBAAO,OAAO,KAAK,GAAG;;0BAC3B,MAAC;gBAAI;gBAAO,QAAQ;;0BACpB,MAAC;gBAAI;gBAAO,OAAO,KAAK,GAAG;;;;AAGvC;AA5BA,OAAO,MAAM,oBAAM,+FA4BhB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;AACA,SAAqB,QAAQ,EAAE,OAAO,QAAQ,iBAAiB;AAE/D,SAAQ,GAAG,QAAO,SAAS;kCAEG;IAC7B,MAAM,SAAS,QAAA,UAAU;IACzB,MAAM,QAAQ,QAAA,SAAS,CAAC;IACxB,qBACC;sBACC,WAAC,mBAAI;sBACL,WAAC;YAAI;YAAO,CAAC,IAAI,CAAC;;sBAClB,WAAC;YAAI;YAAO;;sBACZ,WAAC;YAAI;YAAO;;sBACZ,WAAC;YAAI;YAAO,CAAC,IAAI,EAAE,IAAI;;sBACvB,WAAC;YAAI;YAAO,OAAO,CAAC,IAAI,EAAE,IAAI,KAAK,WAAW,KAAK;;sBACnD,WAAC;YAAI;YAAO;;sBACZ,WAAC;YAAI;sBAAO;;sBACZ,WAAC;YAAI;4BAAO,KAAK,GAAO,KAAK;;;;sBAC7B,WAAC;YAAI;4BAAO,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI;;;;sBACnC,WAAC;YAAI;4BAAO,GAAM,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,SAAS;;;;sBAC/C,WAAC;YAAI;YAAO;;sBACZ,WAAC;YAAI;YAAO,IAAI,KAAK;;sBACrB,WAAC;YAAI;YAAO,IAAI,KAAK,GAAG;;sBACxB,WAAC;YAAI;YAAO;;sBACZ,WAAC;YAAI;YAAO,YAAY,KAAK;;sBAC7B,WAAC;YAAI;YAAO,YAAY,KAAK,GAAG;;sBAChC,WAAC;YAAI;YAAO,OAAO,KAAK;;sBACxB,WAAC;YAAI;YAAO,OAAO,KAAK,GAAG;;sBAC3B,WAAC;YAAI;YAAO,QAAQ;;sBACpB,WAAC;YAAI;YAAO,OAAO,KAAK,GAAG;;;AAG9B;AA5BA,OAAO,MAAM,oBAAM,QAAA,mHA4BhB\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_dev_mode.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_dev_mode.snap index 817278a1a71..b63305570bc 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_dev_mode.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_dev_mode.snap @@ -1,64 +1,62 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2188 +assertion_line: 2299 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore } from '@builder.io/qwik'; +import { component$, useStore } from '@qwik.dev/core'; export const App = component$(() => { - return ( - -

        console.log('warn')}>Hello Qwik

        -
        - ); + return ( + +

        console.log('warn')}>Hello Qwik

        +
        + ); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrlDEV } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrlDEV(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0", { +import { componentQrl } from "@qwik.dev/core"; +import { qrlDEV } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrlDEV(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0", { file: "/user/qwik/src/test.tsx", - lo: 90, - hi: 229, + lo: 88, + hi: 200, displayName: "test.tsx_App_component" -})); +})), "test.tsx", 5, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM;;;;;IAMhB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,oBAAM,QAAA;;;;;wBAMhB\"}") ============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== -import { _jsxC } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { qrlDEV } from "@builder.io/qwik"; +import { _jsxSorted } from "@qwik.dev/core"; +import { qrlDEV } from "@qwik.dev/core"; export const App_component_ckEPmXZlub0 = ()=>{ - return /*#__PURE__*/ _jsxC(Cmp, { - children: /*#__PURE__*/ _jsxQ("p", null, { - class: "stuff", - onClick$: /*#__PURE__*/ qrlDEV(()=>import("./test.tsx_App_component_Cmp_p_onClick_vuXzfUTkpto"), "App_component_Cmp_p_onClick_vuXzfUTkpto", { - file: "/user/qwik/src/test.tsx", - lo: 164, - hi: 189, - displayName: "test.tsx_App_component_Cmp_p_onClick" - }) - }, "Hello Qwik", 3, null, { - fileName: "test.tsx", - lineNumber: 7, - columnNumber: 13 + return /*#__PURE__*/ _jsxSorted(Cmp, null, null, /*#__PURE__*/ _jsxSorted("p", null, { + class: "stuff", + onClick$: /*#__PURE__*/ qrlDEV(()=>import("./test.tsx_App_component_Cmp_p_onClick_vuXzfUTkpto"), "App_component_Cmp_p_onClick_vuXzfUTkpto", { + file: "/user/qwik/src/test.tsx", + lo: 144, + hi: 169, + displayName: "test.tsx_App_component_Cmp_p_onClick" }) - }, 3, "u6_0", { + }, "Hello Qwik", 3, null, { + fileName: "test.tsx", + lineNumber: 7, + columnNumber: 4 + }), 3, "u6_0", { fileName: "test.tsx", lineNumber: 6, - columnNumber: 9 + columnNumber: 3 }); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;yCAG8B;IAC1B,qBACI,MAAC;kBACG,cAAA,MAAC;YAAE,OAAM;YAAQ,QAAQ;;;;;;WAA6B;;;;;;;;;;AAGlE\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;yCAG8B;IAC7B,qBACC,WAAC,+BACA,WAAC;QAAE,OAAM;QAAQ,QAAQ;;;;;;OAA6B;;;;;;;;;AAGzD\"}") /* { "origin": "test.tsx", @@ -74,8 +72,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 90, - 229 + 88, + 200 ] } */ @@ -84,7 +82,7 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma export const App_component_Cmp_p_onClick_vuXzfUTkpto = ()=>console.log('warn'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"uDAMuC,IAAM,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"uDAM8B,IAAM,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", @@ -100,8 +98,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "onClick$", "captures": false, "loc": [ - 164, - 189 + 144, + 169 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_dev_mode_inlined.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_dev_mode_inlined.snap index 65833b3681a..05410561c2a 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_dev_mode_inlined.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_dev_mode_inlined.snap @@ -1,57 +1,55 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2210 +assertion_line: 2321 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore } from '@builder.io/qwik'; +import { component$, useStore } from '@qwik.dev/core'; export const App = component$(() => { - return ( - -

        console.log('warn')}>Hello Qwik

        -
        - ); + return ( + +

        console.log('warn')}>Hello Qwik

        +
        + ); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { inlinedQrlDEV } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrlDEV(()=>{ - return /*#__PURE__*/ _jsxC(Cmp, { - children: /*#__PURE__*/ _jsxQ("p", null, { - class: "stuff", - onClick$: /*#__PURE__*/ inlinedQrlDEV(()=>console.log('warn'), "App_component_Cmp_p_onClick_vuXzfUTkpto", { - file: "/user/qwik/src/test.tsx", - lo: 164, - hi: 189, - displayName: "test.tsx_App_component_Cmp_p_onClick" - }) - }, "Hello Qwik", 3, null, { - fileName: "test.tsx", - lineNumber: 7, - columnNumber: 13 +import { componentQrl } from "@qwik.dev/core"; +import { inlinedQrlDEV } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrlDEV(()=>{ + return /*#__PURE__*/ _jsxSorted(Cmp, null, null, /*#__PURE__*/ _jsxSorted("p", null, { + class: "stuff", + onClick$: /*#__PURE__*/ inlinedQrlDEV(()=>console.log('warn'), "App_component_Cmp_p_onClick_vuXzfUTkpto", { + file: "/user/qwik/src/test.tsx", + lo: 144, + hi: 169, + displayName: "test.tsx_App_component_Cmp_p_onClick" }) - }, 3, "u6_0", { + }, "Hello Qwik", 3, null, { + fileName: "test.tsx", + lineNumber: 7, + columnNumber: 4 + }), 3, "u6_0", { fileName: "test.tsx", lineNumber: 6, - columnNumber: 9 + columnNumber: 3 }); }, "App_component_ckEPmXZlub0", { file: "/user/qwik/src/test.tsx", - lo: 90, - hi: 229, + lo: 88, + hi: 200, displayName: "test.tsx_App_component" -})); +})), "test.tsx", 5, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;AAGA,OAAO,MAAM,oBAAM,yCAAW;IAC1B,qBACI,MAAC;kBACG,cAAA,MAAC;YAAE,OAAM;YAAQ,QAAQ,8BAAE,IAAM,QAAQ,GAAG,CAAC;;;;;;WAAS;;;;;;;;;;AAGlE;;;;;IAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;AAGA,OAAO,MAAM,oBAAM,QAAA,yCAAW;IAC7B,qBACC,WAAC,+BACA,WAAC;QAAE,OAAM;QAAQ,QAAQ,8BAAE,IAAM,QAAQ,GAAG,CAAC;;;;;;OAAS;;;;;;;;;AAGzD;;;;;wBAAG\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_drop_side_effects.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_drop_side_effects.snap index 30e61047c3d..efd8148118f 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_drop_side_effects.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_drop_side_effects.snap @@ -1,14 +1,14 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 711 +assertion_line: 821 expression: output snapshot_kind: text --- ==INPUT== -import { component$ } from '@builder.io/qwik'; -import { server$ } from '@builder.io/qwik-city'; +import { component$ } from '@qwik.dev/core'; +import { server$ } from '@qwik.dev/router'; import { clientSupabase } from 'supabase'; import { Client } from 'openai'; import { secret } from './secret'; @@ -18,30 +18,31 @@ const supabase = clientSupabase(); const dfd = new Client(secret); (function() { - console.log('run'); - })(); - (() => { - console.log('run'); - })(); + console.log('run'); + })(); + (() => { + console.log('run'); + })(); sideEffect(); export const api = server$(() => { - supabase.from('ffg').do(dfd); + supabase.from('ffg').do(dfd); }); export default component$(() => { - return ( - - ) - }); + return ( + + ) + }); ============================= test.js == -import { serverQrl } from "@builder.io/qwik-city"; -import { _noopQrlDEV } from "@builder.io/qwik"; -import { componentQrl } from "@builder.io/qwik"; -import { qrlDEV } from "@builder.io/qwik"; +import { serverQrl } from "@qwik.dev/router"; +import { _noopQrlDEV } from "@qwik.dev/core"; +import { componentQrl } from "@qwik.dev/core"; +import { qrlDEV } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; import { sideEffect } from './secret'; (function() { console.log('run'); @@ -50,28 +51,28 @@ import { sideEffect } from './secret'; console.log('run'); })(); sideEffect(); -export const api = serverQrl(/*#__PURE__*/ _noopQrlDEV("api_server_JonPp043gH0", { +export const api = _addLoc(serverQrl(/*#__PURE__*/ _noopQrlDEV("api_server_JonPp043gH0", { file: "/user/qwik/src/test.tsx", lo: 0, hi: 0, displayName: "test.tsx_api_server" -})); +})), "test.tsx", 22, 20); export default /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrlDEV(()=>import("./test.tsx_test_component_LUXeXe0DQrg"), "test_component_LUXeXe0DQrg", { file: "/user/qwik/src/test.tsx", - lo: 522, - hi: 605, + lo: 503, + hi: 575, displayName: "test.tsx_test_component" })); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;AAMA,SAAS,UAAU,QAAQ,WAAW;AAKtC,CAAC;IACG,QAAQ,GAAG,CAAC;AACd,CAAC;AACD,CAAC;IACC,QAAQ,GAAG,CAAC;AACd,CAAC;AAEH;AAEA,OAAO,MAAM,MAAM;;;;;IAEhB;AAEH,6BAAe;;;;;IAIV\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AAMA,SAAS,UAAU,QAAQ,WAAW;AAKtC,CAAC;IACA,QAAQ,GAAG,CAAC;AACZ,CAAC;AACD,CAAC;IACD,QAAQ,GAAG,CAAC;AACZ,CAAC;AAEF;AAEA,OAAO,MAAM,MAAM,QAAA;;;;;yBAEhB;AAEH,6BAAe;;;;;IAIX\"}") ============================= test.tsx_test_component_button_onClick_DGk9xLyRokA.js (ENTRY POINT)== import { api } from "./test"; export const test_component_button_onClick_DGk9xLyRokA = ()=>await api(); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";yDA0BwB,IAAM,MAAM\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";yDA0BoB,IAAM,MAAM\"}") /* { "origin": "test.tsx", @@ -87,32 +88,32 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "onClick$", "captures": false, "loc": [ - 567, - 584 + 541, + 558 ] } */ ============================= test.tsx_test_component_LUXeXe0DQrg.js (ENTRY POINT)== -import { _jsxQ } from "@builder.io/qwik"; -import { qrlDEV } from "@builder.io/qwik"; +import { _jsxSorted } from "@qwik.dev/core"; +import { qrlDEV } from "@qwik.dev/core"; export const test_component_LUXeXe0DQrg = ()=>{ - return /*#__PURE__*/ _jsxQ("button", null, { + return /*#__PURE__*/ _jsxSorted("button", null, { onClick$: /*#__PURE__*/ qrlDEV(()=>import("./test.tsx_test_component_button_onClick_DGk9xLyRokA"), "test_component_button_onClick_DGk9xLyRokA", { file: "/user/qwik/src/test.tsx", - lo: 567, - hi: 584, + lo: 541, + hi: 558, displayName: "test.tsx_test_component_button_onClick" }) }, null, 3, "u6_0", { fileName: "test.tsx", lineNumber: 27, - columnNumber: 7 + columnNumber: 3 }); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;0CAwB0B;IACtB,qBACE,MAAC;QAAO,QAAQ;;;;;;;;;;;AAEpB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;0CAwB0B;IACzB,qBACC,WAAC;QAAO,QAAQ;;;;;;;;;;;AAEjB\"}") /* { "origin": "test.tsx", @@ -128,8 +129,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 522, - 605 + 503, + 575 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_explicit_ext_no_transpile.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_explicit_ext_no_transpile.snap index 0341e72d874..61263b04aee 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_explicit_ext_no_transpile.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_explicit_ext_no_transpile.snap @@ -1,35 +1,36 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1303 +assertion_line: 1413 expression: output snapshot_kind: text --- ==INPUT== -import { component$, $, useStyles$ } from '@builder.io/qwik'; +import { component$, $, useStyles$ } from '@qwik.dev/core'; export const App = component$((props) => { - useStyles$('hola'); - return $(() => ( -
        - )); + useStyles$('hola'); + return $(() => ( +
        + )); }); ============================= test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0.tsx"), "App_component_ckEPmXZlub0")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0.tsx"), "App_component_ckEPmXZlub0")), "test.tsx", 5, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,qHAKhB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,oBAAM,QAAA,yIAKhB\"}") ============================= test.tsx_App_component_useStyles_t35nSa5UV7U.tsx == export const App_component_useStyles_t35nSa5UV7U = 'hola'; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"mDAIe\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"mDAIY\"}") /* { "origin": "test.tsx", @@ -45,22 +46,22 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "useStyles$", "captures": false, "loc": [ - 123, - 129 + 118, + 124 ] } */ ============================= test.tsx_App_component_ckEPmXZlub0.tsx == -import { qrl } from "@builder.io/qwik"; -import { useStylesQrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; +import { useStylesQrl } from "@qwik.dev/core"; export const App_component_ckEPmXZlub0 = (props)=>{ useStylesQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_useStyles_t35nSa5UV7U.tsx"), "App_component_useStyles_t35nSa5UV7U")); return /*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_1_w0t0o3QMovU.tsx"), "App_component_1_w0t0o3QMovU"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;yCAG8B,CAAC;IAC3B;IACA;AAGJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;yCAG8B,CAAC;IAC9B;IACA;AAGD\"}") /* { "origin": "test.tsx", @@ -76,18 +77,20 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 95, - 182 + 93, + 165 + ], + "paramNames": [ + "props" ] } */ ============================= test.tsx_App_component_1_w0t0o3QMovU.tsx == export const App_component_1_w0t0o3QMovU = ()=>
        ; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"2CAKa,KACJ,MAAM\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"2CAKU,KACP,MAAM\"}") /* { "origin": "test.tsx", @@ -103,8 +106,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 145, - 178 + 137, + 161 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_explicit_ext_transpile.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_explicit_ext_transpile.snap index 4aefd1e7cf9..691e13d0038 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_explicit_ext_transpile.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_explicit_ext_transpile.snap @@ -1,35 +1,36 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1282 +assertion_line: 1392 expression: output snapshot_kind: text --- ==INPUT== -import { component$, $, useStyles$ } from '@builder.io/qwik'; +import { component$, $, useStyles$ } from '@qwik.dev/core'; export const App = component$((props) => { - useStyles$('hola'); - return $(() => ( -
        - )); + useStyles$('hola'); + return $(() => ( +
        + )); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0.js"), "App_component_ckEPmXZlub0")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0.js"), "App_component_ckEPmXZlub0")), "test.tsx", 5, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,oHAKhB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,oBAAM,QAAA,wIAKhB\"}") ============================= test.tsx_App_component_useStyles_t35nSa5UV7U.js (ENTRY POINT)== export const App_component_useStyles_t35nSa5UV7U = 'hola'; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"mDAIe\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"mDAIY\"}") /* { "origin": "test.tsx", @@ -45,22 +46,22 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "useStyles$", "captures": false, "loc": [ - 123, - 129 + 118, + 124 ] } */ ============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; -import { useStylesQrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; +import { useStylesQrl } from "@qwik.dev/core"; export const App_component_ckEPmXZlub0 = (props)=>{ useStylesQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_useStyles_t35nSa5UV7U.js"), "App_component_useStyles_t35nSa5UV7U")); return /*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_1_w0t0o3QMovU.js"), "App_component_1_w0t0o3QMovU"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;yCAG8B,CAAC;IAC3B;IACA;AAGJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;yCAG8B,CAAC;IAC9B;IACA;AAGD\"}") /* { "origin": "test.tsx", @@ -76,19 +77,21 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 95, - 182 + 93, + 165 + ], + "paramNames": [ + "props" ] } */ ============================= test.tsx_App_component_1_w0t0o3QMovU.js (ENTRY POINT)== -import { _jsxQ } from "@builder.io/qwik"; -export const App_component_1_w0t0o3QMovU = ()=>/*#__PURE__*/ _jsxQ("div", null, null, null, 3, "u6_0"); -export { _hW } from "@builder.io/qwik"; +import { _jsxSorted } from "@qwik.dev/core"; +export const App_component_1_w0t0o3QMovU = ()=>/*#__PURE__*/ _jsxSorted("div", null, null, null, 3, "u6_0"); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";2CAKa,kBACL,MAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";2CAKU,kBACR,WAAC\"}") /* { "origin": "test.tsx", @@ -104,8 +107,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 145, - 178 + 137, + 161 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_export_issue.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_export_issue.snap index 8463cb8034d..03df54dba66 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_export_issue.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_export_issue.snap @@ -1,25 +1,25 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2298 +assertion_line: 2409 expression: output snapshot_kind: text --- ==INPUT== -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; const App = component$(() => { - return ( -
        hola
        - ); + return ( +
        hola
        + ); }); export const Root = component$((props: Stuff) => { - return ( - - ); + return ( + + ); }); const Other = 12; @@ -29,27 +29,28 @@ export default App; ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")); -export const Root = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Root_component_royhjYaCbYE"), "Root_component_royhjYaCbYE")); -const Other = 12; +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")), "test.tsx", 5, 13); +export const Root = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Root_component_royhjYaCbYE"), "Root_component_royhjYaCbYE")), "test.tsx", 12, 21); +const Other = _addLoc(12, "test.tsx", 18, 15); export { Other as App }; export default App; export { App as _auto_App }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,MAAM,oBAAM;AAOZ,OAAO,MAAM,qBAAO,mHAIjB;AAEH,MAAM,QAAQ;AACd,SAAS,SAAS,GAAG,GAAG;AAExB,eAAe,IAAI\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,MAAM,oBAAM,QAAA;AAOZ,OAAO,MAAM,qBAAO,QAAA,wIAIjB;AAEH,MAAM,QAAQ,QAAA;AACd,SAAS,SAAS,GAAG,GAAG;AAExB,eAAe,IAAI\"}") ============================= test.tsx_Root_component_royhjYaCbYE.js (ENTRY POINT)== import { _auto_App as App } from "./test"; -import { _jsxC } from "@builder.io/qwik"; +import { _jsxSorted } from "@qwik.dev/core"; export const Root_component_royhjYaCbYE = (props)=>{ - return /*#__PURE__*/ _jsxC(App, null, 3, "u6_1"); + return /*#__PURE__*/ _jsxSorted(App, null, null, null, 3, "u6_1"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;0CAU+B,CAAC;IAC5B,qBACI,MAAC;AAET\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;0CAU+B,CAAC;IAC/B,qBACC,WAAC;AAEH\"}") /* { "origin": "test.tsx", @@ -65,20 +66,23 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 162, - 218 + 148, + 192 + ], + "paramNames": [ + "props" ] } */ ============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== -import { _jsxQ } from "@builder.io/qwik"; +import { _jsxSorted } from "@qwik.dev/core"; export const App_component_ckEPmXZlub0 = ()=>{ - return /*#__PURE__*/ _jsxQ("div", null, null, "hola", 3, "u6_0"); + return /*#__PURE__*/ _jsxSorted("div", null, null, "hola", 3, "u6_0"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";yCAGuB;IACnB,qBACI,MAAC,mBAAI;AAEb\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";yCAGuB;IACtB,qBACC,WAAC,mBAAI;AAEP\"}") /* { "origin": "test.tsx", @@ -94,8 +98,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 73, - 126 + 71, + 112 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_exports.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_exports.snap index f4a429ad40a..cbff28f43d8 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_exports.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_exports.snap @@ -1,13 +1,13 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 985 +assertion_line: 1095 expression: output snapshot_kind: text --- ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; export const [a, {b, v1: [c], d=v2, ...e}, f=v3, ...g] = obj; @@ -21,25 +21,25 @@ export class bar {} export default function DefaultFn() {} export const Header = component$(() => { - return $(() => ( -
        -
        {a}{b}{c}{d}{e}{f}{exp1}{internal}{foo}{bar}{DefaultFn}
        -
        {v1}{v2}{v3}{obj}
        -
        - )) + return $(() => ( +
        +
        {a}{b}{c}{d}{e}{f}{exp1}{internal}{foo}{bar}{DefaultFn}
        +
        {v1}{v2}{v3}{obj}
        +
        + )) }); export const Footer = component$(); ============================= project/test.tsx_Header_component_UVBJuFYfvDo.jsx (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const Header_component_UVBJuFYfvDo = ()=>{ return /*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_1_uWM1kg0IGO0"), "Header_component_1_uWM1kg0IGO0"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";4CAciC;IAC7B;AAMJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";4CAciC;IAChC;AAMD\"}") /* { "origin": "project/test.tsx", @@ -55,28 +55,29 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\" "ctxName": "component$", "captures": false, "loc": [ - 307, - 499 + 305, + 461 ] } */ ============================= project/test.jsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; export const [a, { b, v1: [c], d = v2, ...e }, f = v3, ...g] = obj; -const exp1 = 1; -const internal = 2; +const exp1 = _addLoc(1, "project/test.tsx", 7, 14); +const internal = _addLoc(2, "project/test.tsx", 8, 18); export { exp1, internal as expr2 }; export function foo() {} export class bar { } export default function DefaultFn() {} -export const Header = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_UVBJuFYfvDo"), "Header_component_UVBJuFYfvDo")); -export const Footer = /*#__PURE__*/ componentQrl(); +export const Header = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_UVBJuFYfvDo"), "Header_component_UVBJuFYfvDo")), "project/test.tsx", 16, 23); +export const Footer = /*#__PURE__*/ _addLoc(componentQrl(), "project/test.tsx", 25, 23); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,CAAC,GAAG,EAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,IAAE,EAAE,EAAE,GAAG,GAAE,EAAE,IAAE,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;AAE7D,MAAM,OAAO;AACb,MAAM,WAAW;AACjB,SAAQ,IAAI,EAAE,YAAY,KAAK,GAAE;AAEjC,OAAO,SAAS,OAAQ;AACxB,OAAO,MAAM;AAAK;AAElB,eAAe,SAAS,aAAa;AAErC,OAAO,MAAM,uBAAS,uHAOnB;AAEH,OAAO,MAAM,uBAAS,eAAa\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,CAAC,GAAG,EAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,IAAE,EAAE,EAAE,GAAG,GAAE,EAAE,IAAE,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;AAE7D,MAAM,OAAO,QAAA;AACb,MAAM,WAAW,QAAA;AACjB,SAAQ,IAAI,EAAE,YAAY,KAAK,GAAE;AAEjC,OAAO,SAAS,OAAQ;AACxB,OAAO,MAAM;AAAK;AAElB,eAAe,SAAS,aAAa;AAErC,OAAO,MAAM,uBAAS,QAAA,oJAOnB;AAEH,OAAO,MAAM,uBAAS,QAAA,4CAAa\"}") ============================= project/test.tsx_Header_component_1_uWM1kg0IGO0.jsx (ENTRY POINT)== import { default as DefaultFn } from "./test"; @@ -92,13 +93,12 @@ import { f } from "./test"; import { foo } from "./test"; import { expr2 as internal } from "./test"; export const Header_component_1_uWM1kg0IGO0 = ()=>
        -
        {a}{b}{c}{d}{e}{f}{exp1}{internal}{foo}{bar}{DefaultFn}
        -
        {v1}{v2}{v3}{obj}
        -
        ; -export { _hW } from "@builder.io/qwik"; +
        {a}{b}{c}{d}{e}{f}{exp1}{internal}{foo}{bar}{DefaultFn}
        +
        {v1}{v2}{v3}{obj}
        + ; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;;;;;;8CAea,KACJ,OAAO;YACJ,CAAC,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,MAAM,UAAU,KAAK,KAAK,YAAY,IAAI;YAClE,CAAC,KAAK,IAAI,IAAI,IAAI,MAAM,IAAI;QAChC,EAAE\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;;;;;;8CAeU,KACP,OAAO;GACP,CAAC,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,MAAM,UAAU,KAAK,KAAK,YAAY,IAAI;GAClE,CAAC,KAAK,IAAI,IAAI,IAAI,MAAM,IAAI;EAC7B,EAAE\"}") /* { "origin": "project/test.tsx", @@ -114,8 +114,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/test.tsx\"],\"names\" "ctxName": "$", "captures": false, "loc": [ - 328, - 496 + 323, + 458 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_fix_dynamic_import.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_fix_dynamic_import.snap index e61796a692b..b52b2321659 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_fix_dynamic_import.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_fix_dynamic_import.snap @@ -1,26 +1,26 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1170 +assertion_line: 1280 expression: output snapshot_kind: text --- ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; import thing from "../state"; export function foo() { - return import("../foo/state2") + return import("../foo/state2") } export const Header = component$(() => { - return ( -
        - {import("../folder/state3")} - {thing} -
        - ); + return ( +
        + {import("../folder/state3")} + {thing} +
        + ); }); ============================= project/folder/test.tsx_Header_component_RGgm7Ks9QWI.tsx == @@ -28,13 +28,13 @@ export const Header = component$(() => { import thing from "../state"; export const Header_component_RGgm7Ks9QWI = ()=>{ return
        - {import("../folder/state3")} - {thing} -
        ; + {import("../folder/state3")} + {thing} +
        ; }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/folder/test.tsx\"],\"names\":[],\"mappings\":\";4CAQiC;IAC7B,QACK,IAAI;YACD,CAAC,MAAM,CAAC,oBAAoB;YAC5B,CAAC,MAAM;QACX,EAAE;AAEV\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/folder/test.tsx\"],\"names\":[],\"mappings\":\";4CAQiC;IAChC,QACE,IAAI;GACJ,CAAC,MAAM,CAAC,oBAAoB;GAC5B,CAAC,MAAM;EACR,EAAE;AAEJ\"}") /* { "origin": "project/folder/test.tsx", @@ -50,22 +50,23 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/folder/test.tsx\"],\" "ctxName": "component$", "captures": false, "loc": [ - 178, - 297 + 173, + 256 ] } */ ============================= project/folder/test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; export function foo() { return import("../foo/state2"); } -export const Header = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_RGgm7Ks9QWI"), "Header_component_RGgm7Ks9QWI")); +export const Header = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_RGgm7Ks9QWI"), "Header_component_RGgm7Ks9QWI")), "project/folder/test.tsx", 10, 23); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/folder/test.tsx\"],\"names\":[],\"mappings\":\";;AAIA,OAAO,SAAS;IACZ,OAAO,MAAM,CAAC;AAClB;AAEA,OAAO,MAAM,uBAAS,uHAOnB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/project/folder/test.tsx\"],\"names\":[],\"mappings\":\";;;AAIA,OAAO,SAAS;IACf,OAAO,MAAM,CAAC;AACf;AAEA,OAAO,MAAM,uBAAS,QAAA,2JAOnB\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_functional_component.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_functional_component.snap index 03567d12d4d..cae49acf345 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_functional_component.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_functional_component.snap @@ -7,27 +7,28 @@ snapshot_kind: text ==INPUT== -import { $, component$, useStore } from '@builder.io/qwik'; +import { $, component$, useStore } from '@qwik.dev/core'; const Header = component$(() => { - const thing = useStore(); - const {foo, bar} = foo(); + const thing = useStore(); + const {foo, bar} = foo(); - return ( -
        {thing}
        - ); + return ( +
        {thing}
        + ); }); ============================= test.tsx_Header_component_J4uyIhaBNR4.tsx (ENTRY POINT)== -import { useStore } from "@builder.io/qwik"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { useStore } from "@qwik.dev/core"; export const Header_component_J4uyIhaBNR4 = ()=>{ - const thing = useStore(); + const thing = _addLoc(useStore(), "test.tsx", 5, 16); const { foo, bar } = foo(); return
        {thing}
        ; }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAE0B;IACtB,MAAM,QAAQ;IACd,MAAM,EAAC,GAAG,EAAE,GAAG,EAAC,GAAG;IAEnB,QACK,KAAK,QAAQ;AAEtB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;4CAE0B;IACzB,MAAM,QAAQ,QAAA;IACd,MAAM,EAAC,GAAG,EAAE,GAAG,EAAC,GAAG;IAEnB,QACE,KAAK,QAAQ;AAEhB\"}") /* { "origin": "test.tsx", @@ -43,20 +44,21 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 88, - 205 + 86, + 185 ] } */ ============================= test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -import { $, component$, useStore } from '@builder.io/qwik'; -const Header = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_J4uyIhaBNR4"), "Header_component_J4uyIhaBNR4")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { $, component$, useStore } from '@qwik.dev/core'; +const Header = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Header_component_J4uyIhaBNR4"), "Header_component_J4uyIhaBNR4")), "test.tsx", 4, 16); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AACA,SAAS,CAAC,EAAE,UAAU,EAAE,QAAQ,QAAQ,mBAAmB;AAC3D,MAAM,uBAAS\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AACA,SAAS,CAAC,EAAE,UAAU,EAAE,QAAQ,QAAQ,iBAAiB;AACzD,MAAM,uBAAS,QAAA\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_functional_component_2.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_functional_component_2.snap index c02f4cc5a53..72286bc542b 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_functional_component_2.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_functional_component_2.snap @@ -7,68 +7,69 @@ snapshot_kind: text ==INPUT== -import { $, component$, useStore } from '@builder.io/qwik'; +import { $, component$, useStore } from '@qwik.dev/core'; export const useCounter = () => { - return useStore({count: 0}); + return useStore({count: 0}); } export const STEP = 1; export const App = component$((props) => { - const state = useCounter(); - const thing = useStore({thing: 0}); - const STEP_2 = 2; - - const count2 = state.count * 2; - return ( -
        state.count+=count2 }> - {state.count} - {buttons.map(btn => ( - - ))} - -
        - - ); + const state = useCounter(); + const thing = useStore({thing: 0}); + const STEP_2 = 2; + + const count2 = state.count * 2; + return ( +
        state.count+=count2 }> + {state.count} + {buttons.map(btn => ( + + ))} + +
        + + ); }) ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -import { useStore } from '@builder.io/qwik'; -export const useCounter = ()=>{ +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { useStore } from '@qwik.dev/core'; +export const useCounter = _addLoc(()=>{ return useStore({ count: 0 }); -}; -export const STEP = 1; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")); +}, "test.tsx", 4, 27); +export const STEP = _addLoc(1, "test.tsx", 8, 21); +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")), "test.tsx", 10, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AACA,SAAwB,QAAQ,QAAQ,mBAAmB;AAC3D,OAAO,MAAM,aAAa;IACtB,OAAO,SAAS;QAAC,OAAO;IAAC;AAC7B,EAAC;AAED,OAAO,MAAM,OAAO,EAAE;AAEtB,OAAO,MAAM,oBAAM,iHAoBjB\"}") -============================= test.tsx_App_component_div_onClick_1CGetmFZx0g.js (ENTRY POINT)== +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AACA,SAAwB,QAAQ,QAAQ,iBAAiB;AACzD,OAAO,MAAM,aAAa,QAAA;IACzB,OAAO,SAAS;QAAC,OAAO;IAAC;AAC1B,sBAAC;AAED,OAAO,MAAM,OAAO,QAAA,sBAAE;AAEtB,OAAO,MAAM,oBAAM,QAAA,sIAoBjB\"}") +============================= test.tsx_div_onClick_xGBE9Cbd8Ik.js (ENTRY POINT)== -import { useLexicalScope } from "@builder.io/qwik"; -export const App_component_div_onClick_1CGetmFZx0g = ()=>{ +import { useLexicalScope } from "@qwik.dev/core"; +export const div_onClick_xGBE9Cbd8Ik = ()=>{ const [count2, state] = useLexicalScope(); return state.count += count2; }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";qDAeuB;;WAAM,MAAM,KAAK,IAAE\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";uCAeiB;;WAAM,MAAM,KAAK,IAAE\"}") /* { "origin": "test.tsx", - "name": "App_component_div_onClick_1CGetmFZx0g", + "name": "div_onClick_xGBE9Cbd8Ik", "entry": null, - "displayName": "test.tsx_App_component_div_onClick", - "hash": "1CGetmFZx0g", - "canonicalFilename": "test.tsx_App_component_div_onClick_1CGetmFZx0g", + "displayName": "test.tsx_div_onClick", + "hash": "xGBE9Cbd8Ik", + "canonicalFilename": "test.tsx_div_onClick_xGBE9Cbd8Ik", "path": "", "extension": "js", "parent": "App_component_ckEPmXZlub0", @@ -76,30 +77,34 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "onClick$", "captures": true, "loc": [ - 366, - 391 + 340, + 365 + ], + "captureNames": [ + "count2", + "state" ] } */ -============================= test.tsx_App_component_div_button_onClick_f5NwW9e63a4.js (ENTRY POINT)== +============================= test.tsx_div_button_onClick_fM2x0QeHwqY.js (ENTRY POINT)== -import { useLexicalScope } from "@builder.io/qwik"; +import { useLexicalScope } from "@qwik.dev/core"; import { STEP } from "./test"; -export const App_component_div_button_onClick_f5NwW9e63a4 = ()=>{ - const [btn, props, state, thing] = useLexicalScope(); - return state.count += btn.offset + thing + STEP + 2 + props.step; +export const div_button_onClick_fM2x0QeHwqY = ()=>{ + const [STEP_2, btn, props, state, thing] = useLexicalScope(); + return state.count += btn.offset + thing + STEP + STEP_2 + props.step; }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;4DAmB8B;;WAAM,MAAM,KAAK,IAAI,IAAI,MAAM,GAAG,QAAQ,OARrD,IAQqE,MAAM,IAAI\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;8CAmBe;;WAAM,MAAM,KAAK,IAAI,IAAI,MAAM,GAAG,QAAQ,OAAO,SAAS,MAAM,IAAI\"}") /* { "origin": "test.tsx", - "name": "App_component_div_button_onClick_f5NwW9e63a4", + "name": "div_button_onClick_fM2x0QeHwqY", "entry": null, - "displayName": "test.tsx_App_component_div_button_onClick", - "hash": "f5NwW9e63a4", - "canonicalFilename": "test.tsx_App_component_div_button_onClick_f5NwW9e63a4", + "displayName": "test.tsx_div_button_onClick", + "hash": "fM2x0QeHwqY", + "canonicalFilename": "test.tsx_div_button_onClick_fM2x0QeHwqY", "path": "", "extension": "js", "parent": "App_component_ckEPmXZlub0", @@ -107,47 +112,54 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "onClick$", "captures": true, "loc": [ - 522, - 590 + 451, + 519 + ], + "captureNames": [ + "STEP_2", + "btn", + "props", + "state", + "thing" ] } */ ============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { _wrapSignal } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; import { useCounter } from "./test"; -import { useStore } from "@builder.io/qwik"; +import { useStore } from "@qwik.dev/core"; export const App_component_ckEPmXZlub0 = (props)=>{ - const state = useCounter(); - const thing = useStore({ + const state = _addLoc(useCounter(), "test.tsx", 11, 16); + const thing = _addLoc(useStore({ thing: 0 - }); - const count2 = state.count * 2; - return /*#__PURE__*/ _jsxQ("div", { - onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_div_onClick_1CGetmFZx0g"), "App_component_div_onClick_1CGetmFZx0g", [ + }), "test.tsx", 12, 16); + const STEP_2 = _addLoc(2, "test.tsx", 13, 17); + const count2 = _addLoc(state.count * 2, "test.tsx", 15, 17); + return /*#__PURE__*/ _jsxSorted("div", { + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_div_onClick_xGBE9Cbd8Ik"), "div_onClick_xGBE9Cbd8Ik", [ count2, state ]) }, null, [ - /*#__PURE__*/ _jsxQ("span", null, null, _fnSignal((p0)=>p0.count, [ - state - ], "p0.count"), 3, null), - buttons.map((btn)=>/*#__PURE__*/ _jsxQ("button", { - onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_div_button_onClick_f5NwW9e63a4"), "App_component_div_button_onClick_f5NwW9e63a4", [ + /*#__PURE__*/ _jsxSorted("span", null, null, _wrapProp(state, "count"), 1, null), + buttons.map((btn)=>/*#__PURE__*/ _jsxSorted("button", { + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_div_button_onClick_fM2x0QeHwqY"), "div_button_onClick_fM2x0QeHwqY", [ + STEP_2, btn, props, state, thing ]) - }, null, _wrapSignal(btn, "name"), 0, "u6_0")) + }, null, _wrapProp(btn, "name"), 0, "u6_0")) ], 0, "u6_1"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;yCAQ8B,CAAC;IAC3B,MAAM,QAAQ;IACd,MAAM,QAAQ,SAAS;QAAC,OAAO;IAAC;IAGhC,MAAM,SAAS,MAAM,KAAK,GAAG;IAC7B,qBACI,MAAC;QAAI,QAAQ;;;;;sBACT,MAAC,oCAAM,GAAM,KAAK;;;QACjB,QAAQ,GAAG,CAAC,CAAA,oBACT,MAAC;gBACG,QAAQ;;;;;;iCAEP;;AAOrB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;yCAQ8B,CAAC;IAC9B,MAAM,QAAQ,QAAA;IACd,MAAM,QAAQ,QAAA,SAAS;QAAC,OAAO;IAAC;IAChC,MAAM,SAAS,QAAA;IAEf,MAAM,SAAS,QAAA,MAAM,KAAK,GAAG;IAC7B,qBACC,WAAC;QAAI,QAAQ;;;;;sBACZ,WAAC,8BAAM;QACN,QAAQ,GAAG,CAAC,CAAA,oBACZ,WAAC;gBACA,QAAQ;;;;;;;+BAEP;;AAON\"}") /* { "origin": "test.tsx", @@ -163,8 +175,11 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 186, - 708 + 181, + 580 + ], + "paramNames": [ + "props" ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_functional_component_capture_props.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_functional_component_capture_props.snap index 8a12ffd2db8..d26bfd6df6f 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_functional_component_capture_props.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_functional_component_capture_props.snap @@ -7,70 +7,42 @@ snapshot_kind: text ==INPUT== -import { $, component$, useStore } from '@builder.io/qwik'; +import { $, component$, useStore } from '@qwik.dev/core'; export const App = component$(({count, rest: [I2, {I3, v1: [I4], I5=v2, ...I6}, I7=v3, ...I8]}) => { - const state = useStore({count: 0}); - const {rest: [C2, {C3, v1: [C4], C5=v2, ...C6}, C7=v3, ...C8]} = foo(); - return $(() => { - return ( -
        state.count += count + total }> - {I2}{I3}{I4}{I5}{I6}{I7}{I8} - {C2}{C3}{C4}{C5}{C6}{C7}{C8} - {v1}{v2}{v3} -
        - ) - }); + const state = useStore({count: 0}); + const {rest: [C2, {C3, v1: [C4], C5=v2, ...C6}, C7=v3, ...C8]} = foo(); + return $(() => { + return ( +
        state.count += count + total }> + {I2}{I3}{I4}{I5}{I6}{I7}{I8} + {C2}{C3}{C4}{C5}{C6}{C7}{C8} + {v1}{v2}{v3} +
        + ) + }); }) ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")), "test.tsx", 5, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,iHAYjB\"}") -============================= test.tsx_App_component_div_onClick_1CGetmFZx0g.js (ENTRY POINT)== - -import { useLexicalScope } from "@builder.io/qwik"; -export const App_component_div_onClick_1CGetmFZx0g = ()=>{ - const [count, state] = useLexicalScope(); - return state.count += count + total; -}; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";qDAQ2B;;WAAM,MAAM,KAAK,IAAI,QAAQ\"}") -/* -{ - "origin": "test.tsx", - "name": "App_component_div_onClick_1CGetmFZx0g", - "entry": null, - "displayName": "test.tsx_App_component_div_onClick", - "hash": "1CGetmFZx0g", - "canonicalFilename": "test.tsx_App_component_div_onClick_1CGetmFZx0g", - "path": "", - "extension": "js", - "parent": "App_component_1_w0t0o3QMovU", - "ctxKind": "eventHandler", - "ctxName": "onClick$", - "captures": true, - "loc": [ - 345, - 379 - ] -} -*/ +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,oBAAM,QAAA,qIAYjB\"}") ============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; -import { useStore } from "@builder.io/qwik"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { qrl } from "@qwik.dev/core"; +import { useStore } from "@qwik.dev/core"; export const App_component_ckEPmXZlub0 = ({ count, rest: [I2, { I3, v1: [I4], I5 = v2, ...I6 }, I7 = v3, ...I8] })=>{ - const state = useStore({ + const state = _addLoc(useStore({ count: 0 - }); + }), "test.tsx", 6, 16); const { rest: [C2, { C3, v1: [C4], C5 = v2, ...C6 }, C7 = v3, ...C8] } = foo(); - return /*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_1_w0t0o3QMovU"), "App_component_1_w0t0o3QMovU", [ + return /*#__PURE__*/ qrl(()=>import("./test.tsx_App_Jlq9hNxnCvw"), "App_Jlq9hNxnCvw", [ C2, C3, C4, @@ -91,7 +63,7 @@ export const App_component_ckEPmXZlub0 = ({ count, rest: [I2, { I3, v1: [I4], I5 }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;yCAG8B,CAAC,EAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAC,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,KAAG,EAAE,EAAE,GAAG,IAAG,EAAE,KAAG,EAAE,EAAE,GAAG,GAAG,EAAC;IAC1F,MAAM,QAAQ,SAAS;QAAC,OAAO;IAAC;IAChC,MAAM,EAAC,MAAM,CAAC,IAAI,EAAC,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,KAAG,EAAE,EAAE,GAAG,IAAG,EAAE,KAAG,EAAE,EAAE,GAAG,GAAG,EAAC,GAAG;IACjE;;;;;;;;;;;;;;;;;;AASJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;yCAG8B,CAAC,EAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAC,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,KAAG,EAAE,EAAE,GAAG,IAAG,EAAE,KAAG,EAAE,EAAE,GAAG,GAAG,EAAC;IAC7F,MAAM,QAAQ,QAAA,SAAS;QAAC,OAAO;IAAC;IAChC,MAAM,EAAC,MAAM,CAAC,IAAI,EAAC,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,KAAG,EAAE,EAAE,GAAG,IAAG,EAAE,KAAG,EAAE,EAAE,GAAG,GAAG,EAAC,GAAG;IACjE;;;;;;;;;;;;;;;;;;AASD\"}") /* { "origin": "test.tsx", @@ -107,20 +79,57 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 93, - 540 + 91, + 460 + ], + "paramNames": [ + "{count, rest: [I2, {I3, v1: [I4], I5}, ...I8]}" + ] +} +*/ +============================= test.tsx_App_div_onClick_ooDUXFGjp9U.js (ENTRY POINT)== + +import { useLexicalScope } from "@qwik.dev/core"; +export const App_div_onClick_ooDUXFGjp9U = ()=>{ + const [count, state] = useLexicalScope(); + return state.count += count + total; +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";2CAQkB;;WAAM,MAAM,KAAK,IAAI,QAAQ\"}") +/* +{ + "origin": "test.tsx", + "name": "App_div_onClick_ooDUXFGjp9U", + "entry": null, + "displayName": "test.tsx_App_div_onClick", + "hash": "ooDUXFGjp9U", + "canonicalFilename": "test.tsx_App_div_onClick_ooDUXFGjp9U", + "path": "", + "extension": "js", + "parent": "App_Jlq9hNxnCvw", + "ctxKind": "eventHandler", + "ctxName": "onClick$", + "captures": true, + "loc": [ + 319, + 353 + ], + "captureNames": [ + "count", + "state" ] } */ -============================= test.tsx_App_component_1_w0t0o3QMovU.js (ENTRY POINT)== +============================= test.tsx_App_Jlq9hNxnCvw.js (ENTRY POINT)== -import { useLexicalScope } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const App_component_1_w0t0o3QMovU = ()=>{ +import { useLexicalScope } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +export const App_Jlq9hNxnCvw = ()=>{ const [C2, C3, C4, C5, C6, C7, C8, I2, I3, I4, I5, I6, I7, I8, count, state] = useLexicalScope(); - return /*#__PURE__*/ _jsxQ("div", { - onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_div_onClick_1CGetmFZx0g"), "App_component_div_onClick_1CGetmFZx0g", [ + return /*#__PURE__*/ _jsxSorted("div", { + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_App_div_onClick_ooDUXFGjp9U"), "App_div_onClick_ooDUXFGjp9U", [ count, state ]) @@ -144,18 +153,17 @@ export const App_component_1_w0t0o3QMovU = ()=>{ v3 ], 0, "u6_0"); }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;2CAMa;;IACL,qBACI,MAAC;QAAI,QAAQ;;;;;QACR;QAAI;QAAI;QAAI;QAAI;QAAI;QAAI;QACxB;QAAI;QAAI;QAAI;QAAI;QAAI;QAAI;QACxB;QAAI;QAAI\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;+BAMU;;IACR,qBACC,WAAC;QAAI,QAAQ;;;;;QACX;QAAI;QAAI;QAAI;QAAI;QAAI;QAAI;QACxB;QAAI;QAAI;QAAI;QAAI;QAAI;QAAI;QACxB;QAAI;QAAI\"}") /* { "origin": "test.tsx", - "name": "App_component_1_w0t0o3QMovU", + "name": "App_Jlq9hNxnCvw", "entry": null, - "displayName": "test.tsx_App_component_1", - "hash": "w0t0o3QMovU", - "canonicalFilename": "test.tsx_App_component_1_w0t0o3QMovU", + "displayName": "test.tsx_App", + "hash": "Jlq9hNxnCvw", + "canonicalFilename": "test.tsx_App_Jlq9hNxnCvw", "path": "", "extension": "js", "parent": "App_component_ckEPmXZlub0", @@ -163,8 +171,26 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": true, "loc": [ - 293, - 536 + 282, + 456 + ], + "captureNames": [ + "C2", + "C3", + "C4", + "C5", + "C6", + "C7", + "C8", + "I2", + "I3", + "I4", + "I5", + "I6", + "I7", + "I8", + "count", + "state" ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_getter_generation.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_getter_generation.snap index a229e3cde9d..fb21ce10e97 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_getter_generation.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_getter_generation.snap @@ -1,83 +1,78 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2964 +assertion_line: 3075 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore } from '@builder.io/qwik'; +import { component$, useStore } from '@qwik.dev/core'; export const App = component$(() => { - const store = useStore({ - count: 0, - stuff: 0, - nested: { - count: 0 - } - }); - const signal = useSignal(0); - return ( - - - ); + const store = useStore({ + count: 0, + stuff: 0, + nested: { + count: 0 + } + }); + const signal = useSignal(0); + return ( + + + ); }); export const Cmp = component$((props) => { - return ( - <> -

        {props.nested.count}

        -

        Value {props.count}

        - - ); + return ( + <> +

        {props.nested.count}

        +

        Value {props.count}

        + + ); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")); -export const Cmp = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Cmp_component_4ryKJTOKjWE"), "Cmp_component_4ryKJTOKjWE")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")), "test.tsx", 5, 20); +export const Cmp = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Cmp_component_4ryKJTOKjWE"), "Cmp_component_4ryKJTOKjWE")), "test.tsx", 27, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,iHAoBhB;AAEH,OAAO,MAAM,oBAAM,iHAOhB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,oBAAM,QAAA,qIAoBhB;AAEH,OAAO,MAAM,oBAAM,QAAA,sIAOhB\"}") ============================= test.tsx_Cmp_component_4ryKJTOKjWE.js (ENTRY POINT)== -import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime"; -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _fnSignal } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; export const Cmp_component_4ryKJTOKjWE = (props)=>{ - return /*#__PURE__*/ _jsxC(_Fragment, { - children: [ - /*#__PURE__*/ _jsxQ("p", null, { - "data-value": _fnSignal((p0)=>p0.count, [ - props - ], "p0.count") - }, _fnSignal((p0)=>p0.nested.count, [ - props - ], "p0.nested.count"), 3, null), - /*#__PURE__*/ _jsxQ("p", null, null, [ - "Value ", - _fnSignal((p0)=>p0.count, [ - props - ], "p0.count"), - /*#__PURE__*/ _jsxQ("span", null, null, null, 3, null) - ], 3, null) - ] - }, 3, "u6_1"); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, [ + /*#__PURE__*/ _jsxSorted("p", { + "data-value": _wrapProp(props, "count") + }, null, _fnSignal((p0)=>p0.nested.count, [ + props + ], "p0.nested.count"), 1, null), + /*#__PURE__*/ _jsxSorted("p", null, null, [ + "Value ", + _wrapProp(props, "count"), + /*#__PURE__*/ _jsxSorted("span", null, null, null, 3, null) + ], 1, null) + ], 1, "u6_1"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;yCAyB8B,CAAC;IAC3B,qBACI;;0BACI,MAAC;gBAAE,YAAU,kBAAE,GAAM,KAAK;;;+BAAG,GAAM,MAAM,CAAC,KAAK;;;0BAC/C,MAAC;gBAAE;gCAAO,GAAM,KAAK;;;8BAAC,MAAC;;;;AAGnC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;yCAyB8B,CAAC;IAC9B,qBACC;sBACC,WAAC;YAAE,YAAU,YAAE;iCAAc,GAAM,MAAM,CAAC,KAAK;;;sBAC/C,WAAC;YAAE;sBAAO;0BAAY,WAAC;;;AAG1B\"}") /* { "origin": "test.tsx", @@ -93,63 +88,50 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 580, - 754 + 458, + 596 + ], + "paramNames": [ + "props" ] } */ ============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== import { Cmp } from "./test"; -import { _IMMUTABLE } from "@builder.io/qwik"; -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { useStore } from "@builder.io/qwik"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { _fnSignal } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { useStore } from "@qwik.dev/core"; export const App_component_ckEPmXZlub0 = ()=>{ - const store = useStore({ + const store = _addLoc(useStore({ count: 0, stuff: 0, nested: { count: 0 } - }); - const signal = useSignal(0); - return /*#__PURE__*/ _jsxC(Cmp, { + }), "test.tsx", 6, 16); + const signal = _addLoc(useSignal(0), "test.tsx", 13, 17); + return /*#__PURE__*/ _jsxSorted(Cmp, { + signal: signal + }, { prop: 'true', - get count () { - return store.count; - }, - get nested () { - return store.nested.count; - }, - signal: signal, - get store () { - return store.stuff + 12; - }, - get value () { - return signal.formData?.get('username'); - }, - [_IMMUTABLE]: { - prop: _IMMUTABLE, - count: _fnSignal((p0)=>p0.count, [ - store - ], "p0.count"), - nested: _fnSignal((p0)=>p0.nested.count, [ - store - ], "p0.nested.count"), - signal: _IMMUTABLE, - store: _fnSignal((p0)=>p0.stuff + 12, [ - store - ], "p0.stuff+12"), - value: _fnSignal((p0)=>p0.formData?.get('username'), [ - signal - ], 'p0.formData?.get("username")') - } - }, 3, "u6_0"); + count: _wrapProp(store, "count"), + nested: _fnSignal((p0)=>p0.nested.count, [ + store + ], "p0.nested.count"), + store: _fnSignal((p0)=>p0.stuff + 12, [ + store + ], "p0.stuff+12"), + value: _fnSignal((p0)=>p0.formData?.get('username'), [ + signal + ], 'p0.formData?.get("username")') + }, null, 3, "u6_0"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;yCAG8B;IAC1B,MAAM,QAAQ,SAAS;QACnB,OAAO;QACP,OAAO;QACP,QAAQ;YACJ,OAAO;QACX;IACJ;IACA,MAAM,SAAS,UAAU;IACzB,qBACI,MAAC;QACG,MAAmB;YACnB;mBAAO,MAAM,KAAK;;YAClB;mBAAQ,MAAM,MAAM,CAAC,KAAK;;QAC1B,QAAQ;YACR;mBAAO,MAAM,KAAK,GAAG;;YACrB;mBAAO,OAAO,QAAQ,EAAE,IAAI;;;YAL5B,IAAI;YACJ,KAAK,kBAAE,GAAM,KAAK;;;YAClB,MAAM,kBAAE,GAAM,MAAM,CAAC,KAAK;;;YAC1B,MAAM;YACN,KAAK,kBAAE,GAAM,KAAK,GAAG;;;YACrB,KAAK,kBAAE,GAAO,QAAQ,EAAE,IAAI;;;;;AAIxC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;yCAG8B;IAC7B,MAAM,QAAQ,QAAA,SAAS;QACtB,OAAO;QACP,OAAO;QACP,QAAQ;YACP,OAAO;QACR;IACD;IACA,MAAM,SAAS,QAAA,UAAU;IACzB,qBACC,WAAC;QAIA,QAAQ;;QAHR,MAAmB;QACnB,KAAK,YAAE;QACP,MAAM,kBAAE,GAAM,MAAM,CAAC,KAAK;;;QAE1B,KAAK,kBAAE,GAAM,KAAK,GAAG;;;QACrB,KAAK,kBAAE,GAAO,QAAQ,EAAE,IAAI;;;;AAI/B\"}") /* { "origin": "test.tsx", @@ -165,8 +147,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 90, - 546 + 88, + 424 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_immutable_analysis.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_immutable_analysis.snap index eebead7f33e..1555be9dc24 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_immutable_analysis.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_immutable_analysis.snap @@ -1,255 +1,246 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2026 +assertion_line: 2137 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore, $ } from '@builder.io/qwik'; +import { component$, useStore, $ } from '@qwik.dev/core'; import importedValue from 'v'; import styles from './styles.module.css'; export const App = component$((props) => { - const {Model} = props; - const state = useStore({count: 0}); - const remove = $((id: number) => { - const d = state.data; - d.splice( - d.findIndex((d) => d.id === id), - 1 - ) - }); - return ( - <> -

        Hello Qwik

        -
        console.log('stuff')} - transparent$={() => {console.log('stuff')}} - immutable1="stuff" - immutable2={{ - foo: 'bar', - baz: importedValue ? true : false, - }} - immutable3={2} - immutable4$={(ev) => console.log(state.count)} - immutable5={[1, 2, importedValue, null, {}]} - > -

        Hello Qwik

        -
        - [].map(() => ( - console.log(state.count))()} - mutable3={[1, 2, state, null, {}]} - /> - )); - - ); + const {Model} = props; + const state = useStore({count: 0}); + const remove = $((id: number) => { + const d = state.data; + d.splice( + d.findIndex((d) => d.id === id), + 1 + ) + }); + return ( + <> +

        Hello Qwik

        +
        console.log('stuff')} + transparent$={() => {console.log('stuff')}} + immutable1="stuff" + immutable2={{ + foo: 'bar', + baz: importedValue ? true : false, + }} + immutable3={2} + immutable4$={(ev) => console.log(state.count)} + immutable5={[1, 2, importedValue, null, {}]} + > +

        Hello Qwik

        +
        + [].map(() => ( + console.log(state.count))()} + mutable3={[1, 2, state, null, {}]} + /> + )); + + ); }); -============================= test.tsx_App_component_Fragment_Div_onEvent_zrFduYbT3xM.js (ENTRY POINT)== +============================= test.js == + +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")), "test.tsx", 7, 20); -export const App_component_Fragment_Div_onEvent_zrFduYbT3xM = ()=>console.log('stuff'); +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAKA,OAAO,MAAM,oBAAM,QAAA,qIA4ChB\"}") +============================= test.tsx_App_remove_NObvahcWVrA.js (ENTRY POINT)== -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"8DAsB0B,IAAM,QAAQ,GAAG,CAAC\"}") +import { useLexicalScope } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App_remove_NObvahcWVrA = (id)=>{ + const [state] = useLexicalScope(); + const d = _addLoc(state.data, "test.tsx", 11, 13); + d.splice(d.findIndex((d)=>d.id === id), 1); +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;sCAQkB,CAAC;;IACjB,MAAM,IAAI,QAAA,MAAM,IAAI;IACpB,EAAE,MAAM,CACP,EAAE,SAAS,CAAC,CAAC,IAAM,EAAE,EAAE,KAAK,KAC5B\"}") /* { "origin": "test.tsx", - "name": "App_component_Fragment_Div_onEvent_zrFduYbT3xM", + "name": "App_remove_NObvahcWVrA", "entry": null, - "displayName": "test.tsx_App_component_Fragment_Div_onEvent", - "hash": "zrFduYbT3xM", - "canonicalFilename": "test.tsx_App_component_Fragment_Div_onEvent_zrFduYbT3xM", + "displayName": "test.tsx_App_remove", + "hash": "NObvahcWVrA", + "canonicalFilename": "test.tsx_App_remove_NObvahcWVrA", "path": "", "extension": "js", "parent": "App_component_ckEPmXZlub0", - "ctxKind": "jSXProp", - "ctxName": "onEvent$", - "captures": false, + "ctxKind": "function", + "ctxName": "$", + "captures": true, "loc": [ - 665, - 691 + 256, + 358 + ], + "paramNames": [ + "id" + ], + "captureNames": [ + "state" ] } */ -============================= test.js == - -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")); +============================= test.tsx_Fragment_Div_transparent_CgtVz30uKLg.js (ENTRY POINT)== - -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAKA,OAAO,MAAM,oBAAM,iHA4ChB\"}") -============================= test.tsx_App_component_Fragment_Div_immutable4_2zF7jA3Yti0.js (ENTRY POINT)== - -import { useLexicalScope } from "@builder.io/qwik"; -export const App_component_Fragment_Div_immutable4_2zF7jA3Yti0 = (ev)=>{ - const [state] = useLexicalScope(); - return console.log(state.count); +export const Fragment_Div_transparent_CgtVz30uKLg = ()=>{ + console.log('stuff'); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";iEA8B6B,CAAC;;WAAO,QAAQ,GAAG,CAAC,MAAM,KAAK\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"oDAuBkB;IAAO,QAAQ,GAAG,CAAC;AAAQ\"}") /* { "origin": "test.tsx", - "name": "App_component_Fragment_Div_immutable4_2zF7jA3Yti0", + "name": "Fragment_Div_transparent_CgtVz30uKLg", "entry": null, - "displayName": "test.tsx_App_component_Fragment_Div_immutable4", - "hash": "2zF7jA3Yti0", - "canonicalFilename": "test.tsx_App_component_Fragment_Div_immutable4_2zF7jA3Yti0", + "displayName": "test.tsx_Fragment_Div_transparent", + "hash": "CgtVz30uKLg", + "canonicalFilename": "test.tsx_Fragment_Div_transparent_CgtVz30uKLg", "path": "", "extension": "js", "parent": "App_component_ckEPmXZlub0", "ctxKind": "jSXProp", - "ctxName": "immutable4$", - "captures": true, + "ctxName": "transparent$", + "captures": false, "loc": [ - 984, - 1016 + 589, + 617 ] } */ -============================= test.tsx_App_component_Fragment_Div_transparent_eeDEK6EM1oo.js (ENTRY POINT)== +============================= test.tsx_Fragment_Div_immutable4_ISGLxo6Xf7w.js (ENTRY POINT)== -export const App_component_Fragment_Div_transparent_eeDEK6EM1oo = ()=>{ - console.log('stuff'); +import { useLexicalScope } from "@qwik.dev/core"; +export const Fragment_Div_immutable4_ISGLxo6Xf7w = (ev)=>{ + const [state] = useLexicalScope(); + return console.log(state.count); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"kEAuB8B;IAAO,QAAQ,GAAG,CAAC;AAAQ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";mDA8BiB,CAAC;;WAAO,QAAQ,GAAG,CAAC,MAAM,KAAK\"}") /* { "origin": "test.tsx", - "name": "App_component_Fragment_Div_transparent_eeDEK6EM1oo", + "name": "Fragment_Div_immutable4_ISGLxo6Xf7w", "entry": null, - "displayName": "test.tsx_App_component_Fragment_Div_transparent", - "hash": "eeDEK6EM1oo", - "canonicalFilename": "test.tsx_App_component_Fragment_Div_transparent_eeDEK6EM1oo", + "displayName": "test.tsx_Fragment_Div_immutable4", + "hash": "ISGLxo6Xf7w", + "canonicalFilename": "test.tsx_Fragment_Div_immutable4_ISGLxo6Xf7w", "path": "", "extension": "js", "parent": "App_component_ckEPmXZlub0", "ctxKind": "jSXProp", - "ctxName": "transparent$", - "captures": false, + "ctxName": "immutable4$", + "captures": true, "loc": [ - 723, - 751 + 760, + 792 + ], + "paramNames": [ + "ev" + ], + "captureNames": [ + "state" ] } */ ============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== -import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime"; -import { _IMMUTABLE } from "@builder.io/qwik"; -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { _fnSignal } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; import importedValue from "v"; -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; import styles from "./styles.module.css"; -import { useStore } from "@builder.io/qwik"; +import { useStore } from "@qwik.dev/core"; export const App_component_ckEPmXZlub0 = (props)=>{ - const state = useStore({ + const state = _addLoc(useStore({ count: 0 - }); - const remove = /*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_remove_pU6yOC5P6sY"), "App_component_remove_pU6yOC5P6sY", [ + }), "test.tsx", 9, 16); + const remove = /*#__PURE__*/ _addLoc(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_remove_NObvahcWVrA"), "App_remove_NObvahcWVrA", [ state - ]); - return /*#__PURE__*/ _jsxC(_Fragment, { - children: [ - /*#__PURE__*/ _jsxQ("p", { - onClick$: props.onClick$ - }, { - class: "stuff" - }, "Hello Qwik", 2, null), - /*#__PURE__*/ _jsxC(Div, { - get class () { - return styles.foo; - }, - get document () { - return window.document; - }, - onClick$: props.onClick$, - onEvent$: /*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_Fragment_Div_onEvent_zrFduYbT3xM"), "App_component_Fragment_Div_onEvent_zrFduYbT3xM"), - transparent$: /*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_Fragment_Div_transparent_eeDEK6EM1oo"), "App_component_Fragment_Div_transparent_eeDEK6EM1oo"), - immutable1: "stuff", - immutable2: { + ]), "test.tsx", 10, 17); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, [ + /*#__PURE__*/ _jsxSorted("p", { + onClick$: props.onClick$ + }, { + class: "stuff" + }, "Hello Qwik", 2, null), + /*#__PURE__*/ _jsxSorted(Div, { + document: window.document, + immutable4$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Fragment_Div_immutable4_ISGLxo6Xf7w"), "Fragment_Div_immutable4_ISGLxo6Xf7w", [ + state + ]), + onClick$: props.onClick$ + }, { + class: styles.foo, + onEvent$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Fragment_Div_onEvent_lvYQZ8b7FtM"), "Fragment_Div_onEvent_lvYQZ8b7FtM"), + transparent$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Fragment_Div_transparent_CgtVz30uKLg"), "Fragment_Div_transparent_CgtVz30uKLg"), + immutable1: "stuff", + immutable2: { + foo: 'bar', + baz: importedValue ? true : false + }, + immutable3: 2, + immutable5: [ + 1, + 2, + importedValue, + null, + {} + ] + }, /*#__PURE__*/ _jsxSorted("p", null, null, "Hello Qwik", 3, null), 2, "u6_0"), + "[].map(() => (", + /*#__PURE__*/ _jsxSorted(props.Model, { + class: state, + mutable2: (()=>console.log(state.count))(), + mutable3: [ + 1, + 2, + state, + null, + {} + ], + remove$: remove + }, { + mutable1: _fnSignal((p0)=>({ foo: 'bar', - baz: importedValue ? true : false - }, - immutable3: 2, - immutable4$: /*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_Fragment_Div_immutable4_2zF7jA3Yti0"), "App_component_Fragment_Div_immutable4_2zF7jA3Yti0", [ - state - ]), - immutable5: [ - 1, - 2, - importedValue, - null, - {} - ], - children: /*#__PURE__*/ _jsxQ("p", null, null, "Hello Qwik", 3, null), - [_IMMUTABLE]: { - class: _IMMUTABLE, - document: _IMMUTABLE, - onEvent$: _IMMUTABLE, - transparent$: _IMMUTABLE, - immutable1: _IMMUTABLE, - immutable2: _IMMUTABLE, - immutable3: _IMMUTABLE, - immutable4$: _IMMUTABLE, - immutable5: _IMMUTABLE - } - }, 2, "u6_0"), - "[].map(() => (", - /*#__PURE__*/ _jsxC(props.Model, { - class: state, - remove$: remove, - get mutable1 () { - return { - foo: 'bar', - baz: state.count ? true : false - }; - }, - mutable2: (()=>console.log(state.count))(), - mutable3: [ - 1, - 2, - state, - null, - {} - ], - [_IMMUTABLE]: { - class: _IMMUTABLE, - remove$: _IMMUTABLE, - mutable1: _fnSignal((p0)=>({ - foo: 'bar', - baz: p0.count ? true : false - }), [ - state - ], '{foo:"bar",baz:p0.count?true:false}'), - mutable3: _IMMUTABLE - } - }, 3, "u6_1"), - "));" - ] - }, 1, "u6_2"); + baz: p0.count ? true : false + }), [ + state + ], '{foo:"bar",baz:p0.count?true:false}') + }, null, 2, "u6_1"), + "));" + ], 1, "u6_2"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;;;yCAK8B,CAAC;IAE3B,MAAM,QAAQ,SAAS;QAAC,OAAO;IAAC;IAChC,MAAM;;;IAON,qBACI;;0BACI,MAAC;gBAAgB,UAAU,MAAM,QAAQ;;gBAAtC,OAAM;eAAkC;0BAC3C,MAAC;oBACG;2BAAO,OAAO,GAAG;;oBACjB;2BAAU,OAAO,QAAQ;;gBACzB,UAAU,MAAM,QAAQ;gBACxB,QAAQ;gBACR,YAAY;gBACZ,YAAW;gBACX,YAAY;oBACR,KAAK;oBACL,KAAK,gBAAgB,OAAO;gBAChC;gBACA,YAAY;gBACZ,WAAW;;;gBACX,YAAY;oBAAC;oBAAG;oBAAG;oBAAe;oBAAM,CAAC;iBAAE;0BAE3C,cAAA,MAAC,iBAAE;;oBAdH,KAAK;oBACL,QAAQ;oBAER,QAAQ;oBACR,YAAY;oBACZ,UAAU;oBACV,UAAU;oBAIV,UAAU;oBACV,WAAW;oBACX,UAAU;;;YAGR;0BAEF,MA9BI,MAAT;gBA+BS,OAAO;gBACP,SAAS;oBACT;2BAAU;wBACN,KAAK;wBACL,KAAK,MAAM,KAAK,GAAG,OAAO;oBAC9B;;gBACA,UAAU,CAAC,IAAM,QAAQ,GAAG,CAAC,MAAM,KAAK,CAAC;gBACzC,UAAU;oBAAC;oBAAG;oBAAG;oBAAO;oBAAM,CAAC;iBAAE;;oBAPjC,KAAK;oBACL,OAAO;oBACP,QAAQ,kBAAE,CAAA;4BACN,KAAK;4BACL,KAAK,GAAM,KAAK,GAAG,OAAO;wBAC9B,CAAA;;;oBAEA,QAAQ;;;YACV;;;AAIlB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;;yCAK8B,CAAC;IAE9B,MAAM,QAAQ,QAAA,SAAS;QAAC,OAAO;IAAC;IAChC,MAAM,uBAAS;;;IAOf,qBACC;sBACC,WAAC;YAAgB,UAAU,MAAM,QAAQ;;YAAtC,OAAM;WAAkC;sBAC3C,WAAC;YAEA,UAAU,OAAO,QAAQ;YAUzB,WAAW;;;YATX,UAAU,MAAM,QAAQ;;YAFxB,OAAO,OAAO,GAAG;YAGjB,QAAQ;YACR,YAAY;YACZ,YAAW;YACX,YAAY;gBACX,KAAK;gBACL,KAAK,gBAAgB,OAAO;YAC7B;YACA,YAAY;YAEZ,YAAY;gBAAC;gBAAG;gBAAG;gBAAe;gBAAM,CAAC;aAAE;yBAE3C,WAAC,iBAAE;QACE;sBAEL,WA9Ba,MAAT;YA+BH,OAAO;YAMP,UAAU,CAAC,IAAM,QAAQ,GAAG,CAAC,MAAM,KAAK,CAAC;YACzC,UAAU;gBAAC;gBAAG;gBAAG;gBAAO;gBAAM,CAAC;aAAE;YANjC,SAAS;;YACT,QAAQ,kBAAE,CAAA;oBACT,KAAK;oBACL,KAAK,GAAM,KAAK,GAAG,OAAO;gBAC3B,CAAA;;;;QAGC;;AAIN\"}") /* { "origin": "test.tsx", @@ -265,40 +256,37 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 166, - 1591 + 164, + 1148 + ], + "paramNames": [ + "props" ] } */ -============================= test.tsx_App_component_remove_pU6yOC5P6sY.js (ENTRY POINT)== +============================= test.tsx_Fragment_Div_onEvent_lvYQZ8b7FtM.js (ENTRY POINT)== -import { useLexicalScope } from "@builder.io/qwik"; -export const App_component_remove_pU6yOC5P6sY = (id)=>{ - const [state] = useLexicalScope(); - const d = state.data; - d.splice(d.findIndex((d)=>d.id === id), 1); -}; -export { _hW } from "@builder.io/qwik"; +export const Fragment_Div_onEvent_lvYQZ8b7FtM = ()=>console.log('stuff'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";gDAQqB,CAAC;;IACd,MAAM,IAAI,MAAM,IAAI;IACpB,EAAE,MAAM,CACN,EAAE,SAAS,CAAC,CAAC,IAAM,EAAE,EAAE,KAAK,KAC5B\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"gDAsBc,IAAM,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", - "name": "App_component_remove_pU6yOC5P6sY", + "name": "Fragment_Div_onEvent_lvYQZ8b7FtM", "entry": null, - "displayName": "test.tsx_App_component_remove", - "hash": "pU6yOC5P6sY", - "canonicalFilename": "test.tsx_App_component_remove_pU6yOC5P6sY", + "displayName": "test.tsx_Fragment_Div_onEvent", + "hash": "lvYQZ8b7FtM", + "canonicalFilename": "test.tsx_Fragment_Div_onEvent_lvYQZ8b7FtM", "path": "", "extension": "js", "parent": "App_component_ckEPmXZlub0", - "ctxKind": "function", - "ctxName": "$", - "captures": true, + "ctxKind": "jSXProp", + "ctxName": "onEvent$", + "captures": false, "loc": [ - 267, - 405 + 543, + 569 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_immutable_function_components.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_immutable_function_components.snap index a6ad2022bac..f584bda888a 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_immutable_function_components.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_immutable_function_components.snap @@ -1,36 +1,36 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2492 +assertion_line: 2603 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore, Slot } from '@builder.io/qwik'; +import { component$, useStore, Slot } from '@qwik.dev/core'; export const App = component$((props: Stuff) => { - return ( -
        - -
        - ); + return ( +
        + +
        + ); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { Slot } from '@builder.io/qwik'; +import { componentQrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { Slot } from '@qwik.dev/core'; const App_component_ckEPmXZlub0 = (props)=>{ - return /*#__PURE__*/ _jsxQ("div", null, null, /*#__PURE__*/ _jsxC(Slot, null, 3, "u6_0"), 1, "u6_1"); + return /*#__PURE__*/ _jsxSorted("div", null, null, /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 3, "u6_0"), 1, "u6_1"); }; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(App_component_ckEPmXZlub0, "App_component_ckEPmXZlub0")); +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(App_component_ckEPmXZlub0, "App_component_ckEPmXZlub0")), "test.tsx", 5, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;AACA,SAA+B,IAAI,QAAQ,mBAAmB;kCAEhC,CAAC;IAC3B,qBACI,MAAC,iCACG,MAAC;AAGb;AANA,OAAO,MAAM,oBAAM,+FAMhB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;AACA,SAA+B,IAAI,QAAQ,iBAAiB;kCAE9B,CAAC;IAC9B,qBACC,WAAC,iCACA,WAAC;AAGJ;AANA,OAAO,MAAM,oBAAM,QAAA,mHAMhB\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_import_assertion.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_import_assertion.snap index c2c50494591..1fddcb903ac 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_import_assertion.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_import_assertion.snap @@ -1,27 +1,28 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1932 +assertion_line: 2043 expression: output snapshot_kind: text --- ==INPUT== -import { component$, $ } from '@builder.io/qwik'; +import { component$, $ } from '@qwik.dev/core'; import json from "./foo.json" assert { type: "json" }; export const Greeter = component$(() => { - return json; + return json; }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const Greeter = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Greeter_component_n7HuG2hhU0Q"), "Greeter_component_n7HuG2hhU0Q")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Greeter = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Greeter_component_n7HuG2hhU0Q"), "Greeter_component_n7HuG2hhU0Q")), "test.tsx", 6, 24); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAIA,OAAO,MAAM,wBAAU,yHAEpB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAIA,OAAO,MAAM,wBAAU,QAAA,6IAEpB\"}") ============================= test.tsx_Greeter_component_n7HuG2hhU0Q.js (ENTRY POINT)== import json from "./foo.json" with { @@ -32,7 +33,7 @@ export const Greeter_component_n7HuG2hhU0Q = ()=>{ }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"mCAEqC;IAAE,MAAM;AAAO;6CAElB;IAC9B,OAAO;AACX\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"mCAEqC;IAAE,MAAM;AAAO;6CAElB;IACjC,OAAO;AACR\"}") /* { "origin": "test.tsx", @@ -48,8 +49,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 142, - 168 + 140, + 163 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_inlined_entry_strategy.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_inlined_entry_strategy.snap index a4575034757..9657d44e07f 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_inlined_entry_strategy.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_inlined_entry_strategy.snap @@ -1,63 +1,64 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1405 +assertion_line: 1515 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useBrowserVisibleTask$, useStore, useStyles$ } from '@builder.io/qwik'; +import { component$, useBrowserVisibleTask$, useStore, useStyles$ } from '@qwik.dev/core'; import { thing } from './sibling'; import mongodb from 'mongodb'; export const Child = component$(() => { - useStyles$('somestring'); - const state = useStore({ - count: 0 - }); + useStyles$('somestring'); + const state = useStore({ + count: 0 + }); - // Double count watch - useBrowserVisibleTask$(() => { - state.count = thing.doStuff() + import("./sibling"); - }); + // Double count watch + useBrowserVisibleTask$(() => { + state.count = thing.doStuff() + import("./sibling"); + }); - return ( -
        console.log(mongodb)}> -
        - ); + return ( +
        console.log(mongodb)}> +
        + ); }); ============================= test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { useStylesQrl } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { useBrowserVisibleTaskQrl } from "@builder.io/qwik"; -import { useLexicalScope } from "@builder.io/qwik"; -import { useStore } from '@builder.io/qwik'; +import { componentQrl } from "@qwik.dev/core"; +import { useStylesQrl } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { useBrowserVisibleTaskQrl } from "@qwik.dev/core"; +import { useLexicalScope } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { useStore } from '@qwik.dev/core'; import { thing } from './sibling'; import mongodb from 'mongodb'; -export const Child = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(()=>{ +export const Child = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(()=>{ useStylesQrl(/*#__PURE__*/ inlinedQrl('somestring', "Child_component_useStyles_qBZTuFM0160")); - const state = useStore({ + const state = _addLoc(useStore({ count: 0 - }); + }), "test.tsx", 10, 16); // Double count watch useBrowserVisibleTaskQrl(/*#__PURE__*/ inlinedQrl(()=>{ const [state] = useLexicalScope(); state.count = thing.doStuff() + import("./sibling"); - }, "Child_component_useBrowserVisibleTask_0IGFPOyJmQA", [ + }, "Child_useBrowserVisibleTask_QswObL3QPE0", [ state ])); - return
        console.log(mongodb), "Child_component_div_onClick_elliVSnAiOQ")}> -
        ; -}, "Child_component_9GyF01GDKqw")); + return
        console.log(mongodb), "Child_div_onClick_pV1ddhigrLs")}> +
        ; +}, "Child_component_9GyF01GDKqw")), "test.tsx", 7, 22); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AACA,SAA6C,QAAQ,QAAoB,mBAAmB;AAC5F,SAAS,KAAK,QAAQ,YAAY;AAClC,OAAO,aAAa,UAAU;AAE9B,OAAO,MAAM,sBAAQ,sCAAW;IAE5B,sCAAW;IACX,MAAM,QAAQ,SAAS;QACnB,OAAO;IACX;IAEA,qBAAqB;IACrB,kDAAuB;;QACnB,MAAM,KAAK,GAAG,MAAM,OAAO,KAAK,MAAM,CAAC;;;;IAG3C,QACK,IAAI,mCAAU,IAAM,QAAQ,GAAG,CAAC,sDAAU;QAC3C,EAAE;AAEV,mCAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;AACA,SAA6C,QAAQ,QAAoB,iBAAiB;AAC1F,SAAS,KAAK,QAAQ,YAAY;AAClC,OAAO,aAAa,UAAU;AAE9B,OAAO,MAAM,sBAAQ,QAAA,sCAAW;IAE/B,sCAAW;IACX,MAAM,QAAQ,QAAA,SAAS;QACtB,OAAO;IACR;IAEA,qBAAqB;IACrB,kDAAuB;;QACtB,MAAM,KAAK,GAAG,MAAM,OAAO,KAAK,MAAM,CAAC;;;;IAGxC,QACE,IAAI,mCAAU,IAAM,QAAQ,GAAG,CAAC,4CAAU;EAC3C,EAAE;AAEJ,uDAAG\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_input_bind.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_input_bind.snap index 20e4d9f16c7..62e57a6ddce 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_input_bind.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_input_bind.snap @@ -1,82 +1,81 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1901 +assertion_line: 2012 expression: output snapshot_kind: text --- ==INPUT== -import { component$, $ } from '@builder.io/qwik'; +import { component$, $ } from '@qwik.dev/core'; export const Greeter = component$(() => { - const value = useSignal(0); - const checked = useSignal(false); - const stuff = useSignal(); - return ( - <> - - - -
        {value}
        -
        {value.value}
        - + const value = useSignal(0); + const checked = useSignal(false); + const stuff = useSignal(); + return ( + <> + + + +
        {value}
        +
        {value.value}
        + - ) + ) }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { useLexicalScope } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime"; -export const Greeter = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(()=>{ - const value = useSignal(0); - const checked = useSignal(false); - const stuff = useSignal(); - return /*#__PURE__*/ _jsxC(_Fragment, { - children: [ - /*#__PURE__*/ _jsxQ("input", null, { - "value": value, - "onInput$": /*#__PURE__*/ inlinedQrl((_, elm)=>{ - const [value] = useLexicalScope(); - return value.value = elm.type == "number" ? elm.valueAsNumber : elm.value; - }, "s_6IZeYpXCNXA", [ - value - ]) - }, null, 3, null), - /*#__PURE__*/ _jsxQ("input", null, { - "checked": checked, - "onInput$": /*#__PURE__*/ inlinedQrl((_, elm)=>{ - const [checked] = useLexicalScope(); - return checked.value = elm.type == "number" ? elm.valueAsNumber : elm.checked; - }, "s_JPI3bLCVnso", [ - checked - ]) - }, null, 3, null), - /*#__PURE__*/ _jsxQ("input", null, { - "stuff": stuff, - "onChange$": /*#__PURE__*/ inlinedQrl((_, elm)=>{ - const [stuff] = useLexicalScope(); - return stuff.value = elm.type == "number" ? elm.valueAsNumber : elm.stuff; - }, "s_eyREJ0lZTFw", [ - stuff - ]) - }, null, 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, value, 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, _fnSignal((p0)=>p0.value, [ +import { componentQrl } from "@qwik.dev/core"; +import { useLexicalScope } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Greeter = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(()=>{ + const value = _addLoc(useSignal(0), "test.tsx", 6, 16); + const checked = _addLoc(useSignal(false), "test.tsx", 7, 18); + const stuff = _addLoc(useSignal(), "test.tsx", 8, 16); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, [ + /*#__PURE__*/ _jsxSorted("input", { + "onInput$": /*#__PURE__*/ inlinedQrl((_, elm)=>{ + const [value] = useLexicalScope(); + return value.value = elm.type == "number" ? elm.valueAsNumber : elm.value; + }, "s_b85ZKAd2j00", [ value - ], "p0.value"), 3, null) - ] - }, 3, "u6_0"); -}, "s_n7HuG2hhU0Q")); + ]) + }, { + "value": value + }, null, 2, null), + /*#__PURE__*/ _jsxSorted("input", { + "onInput$": /*#__PURE__*/ inlinedQrl((_, elm)=>{ + const [checked] = useLexicalScope(); + return checked.value = elm.type == "number" ? elm.valueAsNumber : elm.checked; + }, "s_7TWZmNIt2nQ", [ + checked + ]) + }, { + "checked": checked + }, null, 2, null), + /*#__PURE__*/ _jsxSorted("input", { + "onChange$": /*#__PURE__*/ inlinedQrl((_, elm)=>{ + const [stuff] = useLexicalScope(); + return stuff.value = elm.type == "number" ? elm.valueAsNumber : elm.stuff; + }, "s_CtufvifGdmw", [ + stuff + ]) + }, { + "stuff": stuff + }, null, 2, null), + /*#__PURE__*/ _jsxSorted("div", null, null, value, 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, _wrapProp(value), 1, null) + ], 1, "u6_0"); +}, "s_n7HuG2hhU0Q")), "test.tsx", 5, 24); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;AAGA,OAAO,MAAM,wBAAU,sCAAW;IAC9B,MAAM,QAAQ,UAAU;IACxB,MAAM,UAAU,UAAU;IAC1B,MAAM,QAAQ;IACd,qBACI;;0BACI,MAAC;yBAAkB;;;2BAAA;;;;;0BACnB,MAAC;2BAAoB;;;2BAAA;;;;;0BACrB,MAAC;yBAAkB;;;2BAAA;;;;;0BACnB,MAAC,mBAAK;0BACN,MAAC,mCAAK,GAAM,KAAK;;;;;AAI7B,qBAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;AAGA,OAAO,MAAM,wBAAU,QAAA,sCAAW;IACjC,MAAM,QAAQ,QAAA,UAAU;IACxB,MAAM,UAAU,QAAA,UAAU;IAC1B,MAAM,QAAQ,QAAA;IACd,qBACC;sBACC,WAAC;;;uBAAkB;;;;;qBAAA;;sBACnB,WAAC;;;uBAAoB;;;;;uBAAA;;sBACrB,WAAC;;;uBAAkB;;;;;qBAAA;;sBACnB,WAAC,mBAAK;sBACN,WAAC,6BAAK;;AAIT,yCAAG\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_invalid_references.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_invalid_references.snap index 32852c55b38..fe7dc357fb7 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_invalid_references.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_invalid_references.snap @@ -1,13 +1,13 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 860 +assertion_line: 970 expression: output snapshot_kind: text --- ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; const I1 = 12; const [I2, {I3, v1: [I4], I5=v2, ...I6}, I7=v3, ...I8] = obj; @@ -15,25 +15,26 @@ function I9() {} class I10 {} export const App = component$(({count}) => { - console.log(I1, I2, I3, I4, I5, I6, I7, I8, I9); - console.log(itsok, v1, v2, v3, obj); - return $(() => { - return ( - - ) - }); + console.log(I1, I2, I3, I4, I5, I6, I7, I8, I9); + console.log(itsok, v1, v2, v3, obj); + return $(() => { + return ( + + ) + }); }) ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -const I1 = 12; +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +const I1 = _addLoc(12, "test.tsx", 5, 12); const [I2, { I3, v1: [I4], I5 = v2, ...I6 }, I7 = v3, ...I8] = obj; function I9() {} class I10 { } -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")); +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")), "test.tsx", 10, 20); export { I1 as _auto_I1 }; export { I10 as _auto_I10 }; export { I2 as _auto_I2 }; @@ -46,7 +47,7 @@ export { I8 as _auto_I8 }; export { I9 as _auto_I9 }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,MAAM,KAAK;AACX,MAAM,CAAC,IAAI,EAAC,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,KAAG,EAAE,EAAE,GAAG,IAAG,EAAE,KAAG,EAAE,EAAE,GAAG,GAAG,GAAG;AACzD,SAAS,MAAM;AACf,MAAM;AAAK;AAEX,OAAO,MAAM,oBAAM,iHAQjB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,MAAM,KAAK,QAAA;AACX,MAAM,CAAC,IAAI,EAAC,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,KAAG,EAAE,EAAE,GAAG,IAAG,EAAE,KAAG,EAAE,EAAE,GAAG,GAAG,GAAG;AACzD,SAAS,MAAM;AACf,MAAM;AAAK;AAEX,OAAO,MAAM,oBAAM,QAAA,sIAQjB\"}") ============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== import { _auto_I1 as I1 } from "./test"; @@ -58,7 +59,7 @@ import { _auto_I6 as I6 } from "./test"; import { _auto_I7 as I7 } from "./test"; import { _auto_I8 as I8 } from "./test"; import { _auto_I9 as I9 } from "./test"; -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const App_component_ckEPmXZlub0 = (props)=>{ console.log(I1, I2, I3, I4, I5, I6, I7, I8, I9); console.log(itsok, v1, v2, v3, obj); @@ -66,7 +67,7 @@ export const App_component_ckEPmXZlub0 = (props)=>{ }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;;;;yCAQ8B;IAC1B,QAAQ,GAAG,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;IAC5C,QAAQ,GAAG,CAAC,OAAO,IAAI,IAAI,IAAI;IAC/B;AAKJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;;;;yCAQ8B;IAC7B,QAAQ,GAAG,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;IAC5C,QAAQ,GAAG,CAAC,OAAO,IAAI,IAAI,IAAI;IAC/B;AAKD\"}") /* { "origin": "test.tsx", @@ -82,22 +83,24 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 191, - 381 + 189, + 346 + ], + "paramNames": [ + "props" ] } */ ============================= test.tsx_App_component_1_w0t0o3QMovU.js (ENTRY POINT)== import { _auto_I10 as I10 } from "./test"; -import { _jsxC } from "@builder.io/qwik"; +import { _jsxSorted } from "@qwik.dev/core"; export const App_component_1_w0t0o3QMovU = ()=>{ - return /*#__PURE__*/ _jsxC(I10, null, 3, "u6_0"); + return /*#__PURE__*/ _jsxSorted(I10, null, null, null, 3, "u6_0"); }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;2CAWa;IACL,qBACI,MAAC;AAET\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;2CAWU;IACR,qBACC,WAAC;AAEH\"}") /* { "origin": "test.tsx", @@ -113,8 +116,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 313, - 377 + 302, + 342 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_invalid_segment_expr1.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_invalid_segment_expr1.snap index f2f610c5e0b..c5a7f0f6719 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_invalid_segment_expr1.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_invalid_segment_expr1.snap @@ -1,107 +1,115 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 888 +assertion_line: 998 expression: output snapshot_kind: text --- ==INPUT== -import { $, component$, useStyles$ } from '@builder.io/qwik'; +import { $, component$, useStyles$ } from '@qwik.dev/core'; import css1 from './global.css'; import css2 from './style.css'; export const App = component$(() => { - const style = `${css1}${css2}`; - useStyles$(style); - const render = () => { - return ( -
        - ) - }; - return $(render); + const style = `${css1}${css2}`; + useStyles$(style); + const render = () => { + return ( +
        + ) + }; + return $(render); }) ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0")), "test.tsx", 7, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAKA,OAAO,MAAM,oBAAM,iHASjB\"}") -============================= test.tsx_App_component_useStyles_t35nSa5UV7U.js (ENTRY POINT)== +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAKA,OAAO,MAAM,oBAAM,QAAA,qIASjB\"}") +============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== -export const App_component_useStyles_t35nSa5UV7U = style; +import { _addLoc } from "@qwik.dev/core/internal"; +import { _jsxSorted } from "@qwik.dev/core"; +import css1 from "./global.css"; +import css2 from "./style.css"; +import { qrl } from "@qwik.dev/core"; +import { useStylesQrl } from "@qwik.dev/core"; +export const App_component_ckEPmXZlub0 = ()=>{ + _addLoc(`${css1}${css2}`, "test.tsx", 8, 16); + useStylesQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_useStyles_wEd040bJX9U"), "App_useStyles_wEd040bJX9U")); + _addLoc(()=>{ + return /*#__PURE__*/ _jsxSorted("div", null, null, null, 3, "u6_0"); + }, "test.tsx", 10, 17); + return /*#__PURE__*/ qrl(()=>import("./test.tsx_s_PYvpO3S4b98"), "s_PYvpO3S4b98"); +}; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"mDAOe\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;yCAK8B;IACf,QAAA,GAAG,OAAO,MAAM;IAC9B;IACe,QAAA;QACd,qBACC,WAAC;IAEH;IACA;AACD\"}") /* { "origin": "test.tsx", - "name": "App_component_useStyles_t35nSa5UV7U", + "name": "App_component_ckEPmXZlub0", "entry": null, - "displayName": "test.tsx_App_component_useStyles", - "hash": "t35nSa5UV7U", - "canonicalFilename": "test.tsx_App_component_useStyles_t35nSa5UV7U", + "displayName": "test.tsx_App_component", + "hash": "ckEPmXZlub0", + "canonicalFilename": "test.tsx_App_component_ckEPmXZlub0", "path": "", "extension": "js", - "parent": "App_component_ckEPmXZlub0", + "parent": null, "ctxKind": "function", - "ctxName": "useStyles$", + "ctxName": "component$", "captures": false, "loc": [ - 219, - 224 + 158, + 297 ] } */ -============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== +============================= test.tsx_App_useStyles_wEd040bJX9U.js (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; -import { useStylesQrl } from "@builder.io/qwik"; -export const App_component_ckEPmXZlub0 = ()=>{ - useStylesQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_useStyles_t35nSa5UV7U"), "App_component_useStyles_t35nSa5UV7U")); - return /*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_1_w0t0o3QMovU"), "App_component_1_w0t0o3QMovU"); -}; +export const App_useStyles_wEd040bJX9U = style; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;yCAK8B;IAE1B;IAMA;AACJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"yCAOY\"}") /* { "origin": "test.tsx", - "name": "App_component_ckEPmXZlub0", + "name": "App_useStyles_wEd040bJX9U", "entry": null, - "displayName": "test.tsx_App_component", - "hash": "ckEPmXZlub0", - "canonicalFilename": "test.tsx_App_component_ckEPmXZlub0", + "displayName": "test.tsx_App_useStyles", + "hash": "wEd040bJX9U", + "canonicalFilename": "test.tsx_App_useStyles_wEd040bJX9U", "path": "", "extension": "js", - "parent": null, + "parent": "App_component_ckEPmXZlub0", "ctxKind": "function", - "ctxName": "component$", + "ctxName": "useStyles$", "captures": false, "loc": [ - 160, - 335 + 211, + 216 ] } */ -============================= test.tsx_App_component_1_w0t0o3QMovU.js (ENTRY POINT)== +============================= test.tsx_s_PYvpO3S4b98.js (ENTRY POINT)== -export const App_component_1_w0t0o3QMovU = render; -export { _hW } from "@builder.io/qwik"; +export const s_PYvpO3S4b98 = render; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"2CAaa\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"6BAaU\"}") /* { "origin": "test.tsx", - "name": "App_component_1_w0t0o3QMovU", + "name": "s_PYvpO3S4b98", "entry": null, - "displayName": "test.tsx_App_component_1", - "hash": "w0t0o3QMovU", - "canonicalFilename": "test.tsx_App_component_1_w0t0o3QMovU", + "displayName": "test.tsx_s", + "hash": "PYvpO3S4b98", + "canonicalFilename": "test.tsx_s_PYvpO3S4b98", "path": "", "extension": "js", "parent": "App_component_ckEPmXZlub0", @@ -109,8 +117,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 325, - 331 + 287, + 293 ] } */ @@ -124,8 +132,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "message": "Qrl($) scope is not a function, but it's capturing local identifiers: style", "highlights": [ { - "lo": 219, - "hi": 224, + "lo": 211, + "hi": 216, "startLine": 8, "startCol": 16, "endLine": 8, @@ -142,8 +150,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "message": "Qrl($) scope is not a function, but it's capturing local identifiers: render", "highlights": [ { - "lo": 325, - "hi": 331, + "lo": 287, + "hi": 293, "startLine": 14, "startCol": 14, "endLine": 14, diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_issue_33443.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_issue_33443.snap index 4e5d953e725..577552400ad 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_issue_33443.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_issue_33443.snap @@ -1,60 +1,61 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2937 +assertion_line: 3048 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useSignal } from '@builder.io/qwik'; +import { component$, useSignal } from '@qwik.dev/core'; export const Issue3742 = component$(({description = '', other}: any) => { - const counter = useSignal(0); - return ( -
        - Issue3742 - -
        - ) - }); - + const counter = useSignal(0); + return ( +
        + Issue3742 + +
        + ) + }); + ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { _fnSignal } from "@builder.io/qwik"; -import { useLexicalScope } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { useSignal } from '@builder.io/qwik'; -const Issue3742_component_div_button_onClick_a504K2BCEXg = ()=>{ +import { componentQrl } from "@qwik.dev/core"; +import { _fnSignal } from "@qwik.dev/core"; +import { useLexicalScope } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { useSignal } from '@qwik.dev/core'; +const Issue3742_div_button_onClick_B8vBpxEj9AQ = ()=>{ const [counter] = useLexicalScope(); return counter.value++; }; const Issue3742_component_svSy0PlWTAw = (props)=>{ - const counter = useSignal(0); - return /*#__PURE__*/ _jsxQ("div", null, { + const counter = _addLoc(useSignal(0), "test.tsx", 6, 18); + return /*#__PURE__*/ _jsxSorted("div", { title: _fnSignal((p0, p1)=>(p1.description ?? '') && 'description' in p1.other ? `Hello ${p0.value}` : `Bye ${p0.value}`, [ counter, props ], '(p1.description??"")&&"description"in p1.other?`Hello ${p0.value}`:`Bye ${p0.value}`') - }, [ + }, null, [ "Issue3742", - /*#__PURE__*/ _jsxQ("button", null, { - onClick$: /*#__PURE__*/ inlinedQrl(Issue3742_component_div_button_onClick_a504K2BCEXg, "Issue3742_component_div_button_onClick_a504K2BCEXg", [ + /*#__PURE__*/ _jsxSorted("button", { + onClick$: /*#__PURE__*/ inlinedQrl(Issue3742_div_button_onClick_B8vBpxEj9AQ, "Issue3742_div_button_onClick_B8vBpxEj9AQ", [ counter ]) - }, "Increment", 3, null) - ], 3, "u6_0"); + }, null, "Increment", 2, null) + ], 1, "u6_0"); }; -export const Issue3742 = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(Issue3742_component_svSy0PlWTAw, "Issue3742_component_svSy0PlWTAw")); +export const Issue3742 = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(Issue3742_component_svSy0PlWTAw, "Issue3742_component_svSy0PlWTAw")), "test.tsx", 5, 26); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AACA,SAAqB,SAAS,QAAQ,mBAAmB;2DAS/B;;WAAM,QAAQ,KAAK;;wCAPT;IAChC,MAAM,UAAU,UAAU;IAC1B,qBACE,MAAC;QACC,KAAK,sBAAE,AAAC,IAJsB,eAAc,OAIrB,oBAJyB,QAIC,CAAC,MAAM,EAAE,GAAQ,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,GAAQ,KAAK,EAAE;;;;;QACnG;sBAEC,MAAC;YAAO,QAAQ;;;WAAyB;;AAK/C;AAZF,OAAO,MAAM,0BAAY,2GAYpB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;AACA,SAAqB,SAAS,QAAQ,iBAAiB;iDASnC;;WAAM,QAAQ,KAAK;;wCAPH;IACnC,MAAM,UAAU,QAAA,UAAU;IAC1B,qBACC,WAAC;QACD,KAAK,sBAAE,AAAC,IAJ4B,eAAc,OAI3B,oBAJ+B,QAIL,CAAC,MAAM,EAAE,GAAQ,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,GAAQ,KAAK,EAAE;;;;;QACjG;sBAED,WAAC;YAAO,QAAQ;;;iBAAyB;;AAK1C;AAZD,OAAO,MAAM,0BAAY,QAAA,+HAYrB\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_issue_4438.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_issue_4438.snap index 0179d9ebbf3..1ccb1e2a221 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_issue_4438.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_issue_4438.snap @@ -1,47 +1,45 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2727 +assertion_line: 2838 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useSignal } from '@builder.io/qwik'; +import { component$, useSignal } from '@qwik.dev/core'; export const App = component$(() => { - const toggle = useSignal(false); - return ( - <> -
        -
        {toggle.value ? $localize`singular` : $localize`plural`}
        - - ); + const toggle = useSignal(false); + return ( + <> +
        +
        {toggle.value ? $localize`singular` : $localize`plural`}
        + + ); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime"; -import { useSignal } from '@builder.io/qwik'; +import { componentQrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { useSignal } from '@qwik.dev/core'; const App_component_ckEPmXZlub0 = ()=>{ - const toggle = useSignal(false); - return /*#__PURE__*/ _jsxC(_Fragment, { - children: [ - /*#__PURE__*/ _jsxQ("div", { - "data-nu": toggle.value ? $localize`singular` : 'plural' - }, null, null, 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, toggle.value ? $localize`singular` : $localize`plural`, 1, null) - ] - }, 1, "u6_0"); + const toggle = _addLoc(useSignal(false), "test.tsx", 6, 17); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, [ + /*#__PURE__*/ _jsxSorted("div", { + "data-nu": toggle.value ? $localize`singular` : 'plural' + }, null, null, 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, toggle.value ? $localize`singular` : $localize`plural`, 1, null) + ], 1, "u6_0"); }; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(App_component_ckEPmXZlub0, "App_component_ckEPmXZlub0")); +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(App_component_ckEPmXZlub0, "App_component_ckEPmXZlub0")), "test.tsx", 5, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AACA,SAAqB,SAAS,QAAQ,mBAAmB;kCAE3B;IAC1B,MAAM,SAAS,UAAU;IACzB,qBACI;;0BACI,MAAC;gBAAI,WAAS,OAAO,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG;;0BACnD,MAAC,mBAAK,OAAO,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC;;;AAGxE;AARA,OAAO,MAAM,oBAAM,+FAQhB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AACA,SAAqB,SAAS,QAAQ,iBAAiB;kCAEzB;IAC7B,MAAM,SAAS,QAAA,UAAU;IACzB,qBACC;sBACC,WAAC;YAAI,WAAS,OAAO,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG;;sBACnD,WAAC,mBAAK,OAAO,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC;;AAG/D;AARA,OAAO,MAAM,oBAAM,QAAA,mHAQhB\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx.snap index 9ee6035c369..dceff93765b 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx.snap @@ -1,79 +1,77 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1033 +assertion_line: 1143 expression: output snapshot_kind: text --- ==INPUT== -import { $, component$, h, Fragment } from '@builder.io/qwik'; +import { $, component$, h, Fragment } from '@qwik.dev/core'; export const Lightweight = (props) => { - return ( -
        - <> -
        -
        - ) + return ( +
        + <> +
        +
        + ) }; export const Foo = component$((props) => { - return $(() => { - return ( -
        - <> -
        -
        -
        12
        - -
        - -
        -
        -
        -
        -
        -
        -
        - {children} -
        -
        - ) - }); + return $(() => { + return ( +
        + <> +
        +
        +
        12
        + +
        + +
        +
        +
        +
        +
        +
        +
        + {children} +
        +
        + ) + }); }, { - tagName: "my-foo", + tagName: "my-foo", }); ============================= test.js == -import { _jsxQ } from "@builder.io/qwik"; -import { _jsxS } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime"; -export const Lightweight = (props)=>{ - return /*#__PURE__*/ _jsxQ("div", null, null, /*#__PURE__*/ _jsxC(_Fragment, { - children: [ - /*#__PURE__*/ _jsxQ("div", null, null, null, 3, null), - /*#__PURE__*/ _jsxS("button", { - ...props - }, null, 0, null) - ] - }, 1, "u6_0"), 1, "u6_1"); -}; -export const Foo = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_HTDRsvUbLiE"), "Foo_component_HTDRsvUbLiE"), { +import { _jsxSorted } from "@qwik.dev/core"; +import { _jsxSplit } from "@qwik.dev/core"; +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Lightweight = _addLoc((props)=>{ + return /*#__PURE__*/ _jsxSorted("div", null, null, /*#__PURE__*/ _jsxSorted(_Fragment, null, null, [ + /*#__PURE__*/ _jsxSorted("div", null, null, null, 3, null), + /*#__PURE__*/ _jsxSplit("button", { + ...props + }, null, null, 0, null) + ], 1, "u6_0"), 1, "u6_1"); +}, "test.tsx", 5, 28); +export const Foo = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_HTDRsvUbLiE"), "Foo_component_HTDRsvUbLiE"), { tagName: "my-foo" -}); +}), "test.tsx", 16, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;AAGA,OAAO,MAAM,cAAc,CAAC;IACxB,qBACI,MAAC,iCACG;;0BACI,MAAC;0BACD,MAAC;gBAAQ,GAAG,KAAK;;;;AAIjC,EAAE;AAEF,OAAO,MAAM,oBAAM,iHAuBhB;IACC,SAAS;AACb,GAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;AAGA,OAAO,MAAM,cAAc,QAAA,CAAC;IAC3B,qBACC,WAAC,iCACA;sBACC,WAAC;sBACD,UAAC;YAAQ,GAAG,KAAK;;;AAIrB,sBAAE;AAEF,OAAO,MAAM,oBAAM,QAAA,iHAuBhB;IACF,SAAS;AACV,wBAAG\"}") ============================= test.tsx_Foo_component_HTDRsvUbLiE.js (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const Foo_component_HTDRsvUbLiE = (props)=>{ return /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_1_DvU6FitWglY"), "Foo_component_1_DvU6FitWglY", [ props @@ -81,7 +79,7 @@ export const Foo_component_HTDRsvUbLiE = (props)=>{ }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";yCAc8B,CAAC;IAC3B;;;AAsBJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";yCAc8B,CAAC;IAC9B;;;AAsBD\"}") /* { "origin": "test.tsx", @@ -97,55 +95,55 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 279, - 895 + 217, + 581 + ], + "paramNames": [ + "props" ] } */ ============================= test.tsx_Foo_component_1_DvU6FitWglY.js (ENTRY POINT)== -import { useLexicalScope } from "@builder.io/qwik"; +import { useLexicalScope } from "@qwik.dev/core"; import { Lightweight } from "./test"; -import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime"; -import { _jsxC } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _jsxSplit } from "@qwik.dev/core"; export const Foo_component_1_DvU6FitWglY = ()=>{ const [props] = useLexicalScope(); - return /*#__PURE__*/ _jsxQ("div", null, null, [ - /*#__PURE__*/ _jsxC(_Fragment, { - children: [ - /*#__PURE__*/ _jsxQ("div", null, { - class: "class" - }, null, 3, null), - /*#__PURE__*/ _jsxQ("div", null, { - class: "class" - }, null, 3, null), - /*#__PURE__*/ _jsxQ("div", null, { - class: "class" - }, "12", 3, null) - ] - }, 3, "u6_2"), - /*#__PURE__*/ _jsxQ("div", null, { + return /*#__PURE__*/ _jsxSorted("div", null, null, [ + /*#__PURE__*/ _jsxSorted(_Fragment, null, null, [ + /*#__PURE__*/ _jsxSorted("div", null, { + class: "class" + }, null, 3, null), + /*#__PURE__*/ _jsxSorted("div", null, { + class: "class" + }, null, 3, null), + /*#__PURE__*/ _jsxSorted("div", null, { + class: "class" + }, "12", 3, null) + ], 3, "u6_2"), + /*#__PURE__*/ _jsxSorted("div", null, { class: "class" - }, /*#__PURE__*/ _jsxC(Lightweight, { + }, /*#__PURE__*/ _jsxSplit(Lightweight, { ...props - }, 0, "u6_3"), 1, null), - /*#__PURE__*/ _jsxQ("div", null, { + }, null, null, 0, "u6_3"), 1, null), + /*#__PURE__*/ _jsxSorted("div", null, { class: "class" }, [ - /*#__PURE__*/ _jsxQ("div", null, null, null, 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, null, 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, null, 3, null) + /*#__PURE__*/ _jsxSorted("div", null, null, null, 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, null, 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, null, 3, null) ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, { + /*#__PURE__*/ _jsxSorted("div", null, { class: "class" - }, children, 3, null) + }, children, 1, null) ], 1, "u6_4"); }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;2CAea;;IACL,qBACI,MAAC;sBACG;;8BACI,MAAC;oBAAI,OAAM;;8BACX,MAAC;oBAAI,OAAM;;8BACX,MAAC;oBAAI,OAAM;mBAAQ;;;sBAEvB,MAAC;YAAI,OAAM;yBACP,MAAC;YAAa,GAAG,KAAK;;sBAE1B,MAAC;YAAI,OAAM;;0BACP,MAAC;0BACD,MAAC;0BACD,MAAC;;sBAEL,MAAC;YAAI,OAAM;WACN\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;2CAeU;;IACR,qBACC,WAAC;sBACA;0BACC,WAAC;gBAAI,OAAM;;0BACX,WAAC;gBAAI,OAAM;;0BACX,WAAC;gBAAI,OAAM;eAAQ;;sBAEpB,WAAC;YAAI,OAAM;yBACV,UAAC;YAAa,GAAG,KAAK;;sBAEvB,WAAC;YAAI,OAAM;;0BACV,WAAC;0BACD,WAAC;0BACD,WAAC;;sBAEF,WAAC;YAAI,OAAM;WACT\"}") /* { "origin": "test.tsx", @@ -161,8 +159,11 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": true, "loc": [ - 305, - 891 + 240, + 577 + ], + "captureNames": [ + "props" ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_import_source.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_import_source.snap index b25c86bf0b5..64cb156d8fc 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_import_source.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_import_source.snap @@ -1,6 +1,6 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1323 +assertion_line: 1433 expression: output snapshot_kind: text --- @@ -12,25 +12,26 @@ snapshot_kind: text import { qwikify$ } from './qwikfy'; export const App = () => ( -
        console.log('App')}>
        +
        console.log('App')}>
        ); export const App2 = qwikify$(() => ( -
        console.log('App2')}>
        +
        console.log('App2')}>
        )); ============================= test.js == /* @jsxImportSource react */ import { qwikifyQrl } from "./qwikfy"; -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; import { jsx as _jsx } from "react/jsx-runtime"; -export const App = ()=>/*#__PURE__*/ _jsx("div", { +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = _addLoc(()=>/*#__PURE__*/ _jsx("div", { onClick$: ()=>console.log('App') - }); -export const App2 = qwikifyQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App2_qwikify_RKJW7oCMdS4.js"), "App2_qwikify_RKJW7oCMdS4")); + }), "test.tsx", 7, 20); +export const App2 = _addLoc(qwikifyQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App2_qwikify_RKJW7oCMdS4.js"), "App2_qwikify_RKJW7oCMdS4")), "test.tsx", 11, 21); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"AACA,0BAA0B;;;AAI1B,OAAO,MAAM,MAAM,kBACf,KAAC;QAAI,UAAU,IAAI,QAAQ,GAAG,CAAC;OACjC;AAEF,OAAO,MAAM,OAAO,gHAEjB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"AACA,0BAA0B;;;;AAI1B,OAAO,MAAM,MAAM,QAAA,kBAClB,KAAC;QAAI,UAAU,IAAI,QAAQ,GAAG,CAAC;2BAC9B;AAEF,OAAO,MAAM,OAAO,QAAA,qIAEjB\"}") ============================= test.tsx_App2_qwikify_RKJW7oCMdS4.js (ENTRY POINT)== import { jsx as _jsx } from "react/jsx-runtime"; @@ -39,7 +40,7 @@ export const App2_qwikify_RKJW7oCMdS4 = ()=>/*#__PURE__*/ _jsx("div", { }); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";wCAS6B,kBACzB,KAAC;QAAI,UAAU,IAAI,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";wCAS6B,kBAC5B,KAAC;QAAI,UAAU,IAAI,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", @@ -55,8 +56,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "qwikify$", "captures": false, "loc": [ - 180, - 240 + 177, + 234 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_keyed.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_keyed.snap index 65134eb564a..fa1ca3d0cf7 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_keyed.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_keyed.snap @@ -1,64 +1,55 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2329 +assertion_line: 2440 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore } from '@builder.io/qwik'; +import { component$, useStore } from '@qwik.dev/core'; export const App = component$((props: Stuff) => { - return ( - <> - - - - -

        Hello Qwik

        - - ); + return ( + <> + + + + +

        Hello Qwik

        + + ); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0.js"), "App_component_ckEPmXZlub0")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0.js"), "App_component_ckEPmXZlub0")), "test.tsx", 5, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,oHAUhB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,oBAAM,QAAA,wIAUhB\"}") ============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== -import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime"; -import { _IMMUTABLE } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _jsxSorted } from "@qwik.dev/core"; export const App_component_ckEPmXZlub0 = (props)=>{ - return /*#__PURE__*/ _jsxC(_Fragment, { - children: [ - /*#__PURE__*/ _jsxC(Cmp, null, 3, "stuff"), - /*#__PURE__*/ _jsxC(Cmp, null, 3, "u6_0"), - /*#__PURE__*/ _jsxC(Cmp, { - prop: "23", - [_IMMUTABLE]: { - prop: _IMMUTABLE - } - }, 3, "u6_1"), - /*#__PURE__*/ _jsxC(Cmp, { - prop: "23", - [_IMMUTABLE]: { - prop: _IMMUTABLE - } - }, 3, props.stuff), - /*#__PURE__*/ _jsxQ("p", null, null, "Hello Qwik", 3, props.stuff) - ] - }, 1, "u6_2"); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, [ + /*#__PURE__*/ _jsxSorted(Cmp, null, null, null, 3, "stuff"), + /*#__PURE__*/ _jsxSorted(Cmp, null, null, null, 3, "u6_0"), + /*#__PURE__*/ _jsxSorted(Cmp, null, { + prop: "23" + }, null, 3, "u6_1"), + /*#__PURE__*/ _jsxSorted(Cmp, null, { + prop: "23" + }, null, 3, props.stuff), + /*#__PURE__*/ _jsxSorted("p", null, null, "Hello Qwik", 3, props.stuff) + ], 1, "u6_2"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;yCAG8B,CAAC;IAC3B,qBACI;;0BACI,MAAC,cAAQ;0BACT,MAAC;0BACD,MAAC;gBAAI,MAAK;;oBAAL,IAAI;;;0BACT,MAAC;gBAAI,MAAK;;oBAAL,IAAI;;kBAAW,MAAM,KAAK;0BAC/B,MAAC,iBAAoB,iBAAb,MAAM,KAAK;;;AAG/B\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;yCAG8B,CAAC;IAC9B,qBACC;sBACC,WAAC,0BAAQ;sBACT,WAAC;sBACD,WAAC;YAAI,MAAK;;sBACV,WAAC;YAAI,MAAK;oBAAU,MAAM,KAAK;sBAC/B,WAAC,iBAAoB,iBAAb,MAAM,KAAK;;AAGtB\"}") /* { "origin": "test.tsx", @@ -74,8 +65,11 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 90, - 348 + 88, + 283 + ], + "paramNames": [ + "props" ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_keyed_dev.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_keyed_dev.snap index 399df049f81..327b69a8836 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_keyed_dev.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_keyed_dev.snap @@ -1,93 +1,84 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2355 +assertion_line: 2466 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore } from '@builder.io/qwik'; +import { component$, useStore } from '@qwik.dev/core'; export const App = component$((props: Stuff) => { - return ( - <> - - - - -

        Hello Qwik

        - - ); + return ( + <> + + + + +

        Hello Qwik

        + + ); }); ============================= project/index.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrlDEV } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrlDEV(()=>import("./index.tsx_App_component_KGLYFBhvJc0.js"), "App_component_KGLYFBhvJc0", { +import { componentQrl } from "@qwik.dev/core"; +import { qrlDEV } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrlDEV(()=>import("./index.tsx_App_component_KGLYFBhvJc0.js"), "App_component_KGLYFBhvJc0", { file: "/src/project/project/index.tsx", - lo: 90, - hi: 348, + lo: 88, + hi: 283, displayName: "index.tsx_App_component" -})); +})), "project/index.tsx", 5, 20); -Some("{\"version\":3,\"sources\":[\"/src/project/project/index.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM;;;;;IAUhB\"}") +Some("{\"version\":3,\"sources\":[\"/src/project/project/index.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,oBAAM,QAAA;;;;;iCAUhB\"}") ============================= project/index.tsx_App_component_KGLYFBhvJc0.js (ENTRY POINT)== -import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime"; -import { _IMMUTABLE } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _jsxSorted } from "@qwik.dev/core"; export const App_component_KGLYFBhvJc0 = (props)=>{ - return /*#__PURE__*/ _jsxC(_Fragment, { - children: [ - /*#__PURE__*/ _jsxC(Cmp, null, 3, "stuff", { - fileName: "project/index.tsx", - lineNumber: 7, - columnNumber: 13 - }), - /*#__PURE__*/ _jsxC(Cmp, null, 3, "Q6_0", { - fileName: "project/index.tsx", - lineNumber: 8, - columnNumber: 13 - }), - /*#__PURE__*/ _jsxC(Cmp, { - prop: "23", - [_IMMUTABLE]: { - prop: _IMMUTABLE - } - }, 3, "Q6_1", { - fileName: "project/index.tsx", - lineNumber: 9, - columnNumber: 13 - }), - /*#__PURE__*/ _jsxC(Cmp, { - prop: "23", - [_IMMUTABLE]: { - prop: _IMMUTABLE - } - }, 3, props.stuff, { - fileName: "project/index.tsx", - lineNumber: 10, - columnNumber: 13 - }), - /*#__PURE__*/ _jsxQ("p", null, null, "Hello Qwik", 3, props.stuff, { - fileName: "project/index.tsx", - lineNumber: 11, - columnNumber: 13 - }) - ] - }, 1, "Q6_2", { + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, [ + /*#__PURE__*/ _jsxSorted(Cmp, null, null, null, 3, "stuff", { + fileName: "project/index.tsx", + lineNumber: 7, + columnNumber: 4 + }), + /*#__PURE__*/ _jsxSorted(Cmp, null, null, null, 3, "Q6_0", { + fileName: "project/index.tsx", + lineNumber: 8, + columnNumber: 4 + }), + /*#__PURE__*/ _jsxSorted(Cmp, null, { + prop: "23" + }, null, 3, "Q6_1", { + fileName: "project/index.tsx", + lineNumber: 9, + columnNumber: 4 + }), + /*#__PURE__*/ _jsxSorted(Cmp, null, { + prop: "23" + }, null, 3, props.stuff, { + fileName: "project/index.tsx", + lineNumber: 10, + columnNumber: 4 + }), + /*#__PURE__*/ _jsxSorted("p", null, null, "Hello Qwik", 3, props.stuff, { + fileName: "project/index.tsx", + lineNumber: 11, + columnNumber: 4 + }) + ], 1, "Q6_2", { fileName: "project/index.tsx", lineNumber: 6, - columnNumber: 9 + columnNumber: 3 }); }; -Some("{\"version\":3,\"sources\":[\"/src/project/project/index.tsx\"],\"names\":[],\"mappings\":\";;;;yCAG8B,CAAC;IAC3B,qBACI;;0BACI,MAAC,cAAQ;;;;;0BACT,MAAC;;;;;0BACD,MAAC;gBAAI,MAAK;;oBAAL,IAAI;;;;;;;0BACT,MAAC;gBAAI,MAAK;;oBAAL,IAAI;;kBAAW,MAAM,KAAK;;;;;0BAC/B,MAAC,iBAAoB,iBAAb,MAAM,KAAK;;;;;;;;;;;AAG/B\"}") +Some("{\"version\":3,\"sources\":[\"/src/project/project/index.tsx\"],\"names\":[],\"mappings\":\";;yCAG8B,CAAC;IAC9B,qBACC;sBACC,WAAC,0BAAQ;;;;;sBACT,WAAC;;;;;sBACD,WAAC;YAAI,MAAK;;;;;;sBACV,WAAC;YAAI,MAAK;oBAAU,MAAM,KAAK;;;;;sBAC/B,WAAC,iBAAoB,iBAAb,MAAM,KAAK;;;;;;;;;;AAGtB\"}") /* { "origin": "project/index.tsx", @@ -103,8 +94,11 @@ Some("{\"version\":3,\"sources\":[\"/src/project/project/index.tsx\"],\"names\": "ctxName": "component$", "captures": false, "loc": [ - 90, - 348 + 88, + 283 + ], + "paramNames": [ + "props" ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_listeners.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_listeners.snap index 99cdcc5ace0..37e7d737d6d 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_listeners.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_jsx_listeners.snap @@ -1,89 +1,116 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1084 +assertion_line: 1194 expression: output snapshot_kind: text --- ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; export const Foo = component$(() => { - return $(() => { - const handler = $(() => console.log('reused')); - return ( -
        console.log('onClick$')} - onDocumentScroll$={()=>console.log('onDocumentScroll')} - onDocumentScroll$={()=>console.log('onWindowScroll')} - - on-cLick$={()=>console.log('on-cLick$')} - onDocument-sCroll$={()=>console.log('onDocument-sCroll')} - onDocument-scroLL$={()=>console.log('onDocument-scroLL')} - - host:onClick$={()=>console.log('host:onClick$')} - host:onDocumentScroll$={()=>console.log('host:onDocument:scroll')} - host:onDocumentScroll$={()=>console.log('host:onWindow:scroll')} - - onKeyup$={handler} - onDocument:keyup$={handler} - onWindow:keyup$={handler} - - custom$={()=>console.log('custom')} - /> - ) - }); + return $(() => { + const handler = $(() => console.log('reused')); + return ( +
        console.log('onClick$')} + onDocumentScroll$={()=>console.log('onDocumentScroll')} + onDocumentScroll$={()=>console.log('onWindowScroll')} + + on-cLick$={()=>console.log('on-cLick$')} + onDocument-sCroll$={()=>console.log('onDocument-sCroll')} + onDocument-scroLL$={()=>console.log('onDocument-scroLL')} + + host:onClick$={()=>console.log('host:onClick$')} + host:onDocumentScroll$={()=>console.log('host:onDocument:scroll')} + host:onDocumentScroll$={()=>console.log('host:onWindow:scroll')} + + onKeyup$={handler} + onDocument:keyup$={handler} + onWindow:keyup$={handler} + + custom$={()=>console.log('custom')} + /> + ) + }); }, { - tagName: "my-foo", + tagName: "my-foo", }); -============================= test.tsx_Foo_component_div_host_onDocumentScroll_Zip7mifsjRY.js (ENTRY POINT)== +============================= test.tsx_Foo_div_custom_0aBC7DwC5wU.js (ENTRY POINT)== -export const Foo_component_div_host_onDocumentScroll_Zip7mifsjRY = ()=>console.log('host:onDocument:scroll'); +export const Foo_div_custom_0aBC7DwC5wU = ()=>console.log('custom'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"mEAkBwC,IAAI,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"0CAyBa,IAAI,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", - "name": "Foo_component_div_host_onDocumentScroll_Zip7mifsjRY", + "name": "Foo_div_custom_0aBC7DwC5wU", "entry": null, - "displayName": "test.tsx_Foo_component_div_host_onDocumentScroll", - "hash": "Zip7mifsjRY", - "canonicalFilename": "test.tsx_Foo_component_div_host_onDocumentScroll_Zip7mifsjRY", + "displayName": "test.tsx_Foo_div_custom", + "hash": "0aBC7DwC5wU", + "canonicalFilename": "test.tsx_Foo_div_custom_0aBC7DwC5wU", "path": "", "extension": "js", "parent": "Foo_component_1_DvU6FitWglY", "ctxKind": "eventHandler", - "ctxName": "host:onDocumentScroll$", + "ctxName": "custom$", "captures": false, "loc": [ - 712, - 753 + 802, + 827 ] } */ ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const Foo = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_HTDRsvUbLiE"), "Foo_component_HTDRsvUbLiE"), { +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Foo = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_HTDRsvUbLiE"), "Foo_component_HTDRsvUbLiE"), { tagName: "my-foo" -}); +}), "test.tsx", 5, 20); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,oBAAM,QAAA,iHA0BhB;IACF,SAAS;AACV,uBAAG\"}") +============================= test.tsx_Foo_div_onDocument_scroLL_XUFvJrCL7yA.js (ENTRY POINT)== +export const Foo_div_onDocument_scroLL_XUFvJrCL7yA = ()=>console.log('onDocument-scroLL'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,iHA0BhB;IACC,SAAS;AACb,GAAG\"}") + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"qDAewB,IAAI,QAAQ,GAAG,CAAC\"}") +/* +{ + "origin": "test.tsx", + "name": "Foo_div_onDocument_scroLL_XUFvJrCL7yA", + "entry": null, + "displayName": "test.tsx_Foo_div_onDocument_scroLL", + "hash": "XUFvJrCL7yA", + "canonicalFilename": "test.tsx_Foo_div_onDocument_scroLL_XUFvJrCL7yA", + "path": "", + "extension": "js", + "parent": "Foo_component_1_DvU6FitWglY", + "ctxKind": "eventHandler", + "ctxName": "onDocument-scroLL$", + "captures": false, + "loc": [ + 470, + 506 + ] +} +*/ ============================= test.tsx_Foo_component_HTDRsvUbLiE.js (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const Foo_component_HTDRsvUbLiE = ()=>{ return /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_1_DvU6FitWglY"), "Foo_component_1_DvU6FitWglY"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";yCAG8B;IAE1B;AAwBJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";yCAG8B;IAE7B;AAwBD\"}") /* { "origin": "test.tsx", @@ -99,63 +126,64 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 83, - 1045 + 81, + 845 ] } */ -============================= test.tsx_Foo_component_div_host_onClick_cPEH970JbEY.js (ENTRY POINT)== +============================= test.tsx_Foo_div_host_onDocumentScroll_QDhZi1GjXUk.js (ENTRY POINT)== -export const Foo_component_div_host_onClick_cPEH970JbEY = ()=>console.log('host:onClick$'); +export const Foo_div_host_onDocumentScroll_QDhZi1GjXUk = ()=>console.log('host:onDocument:scroll'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"0DAiB+B,IAAI,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"yDAkB4B,IAAI,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", - "name": "Foo_component_div_host_onClick_cPEH970JbEY", + "name": "Foo_div_host_onDocumentScroll_QDhZi1GjXUk", "entry": null, - "displayName": "test.tsx_Foo_component_div_host_onClick", - "hash": "cPEH970JbEY", - "canonicalFilename": "test.tsx_Foo_component_div_host_onClick_cPEH970JbEY", + "displayName": "test.tsx_Foo_div_host_onDocumentScroll", + "hash": "QDhZi1GjXUk", + "canonicalFilename": "test.tsx_Foo_div_host_onDocumentScroll_QDhZi1GjXUk", "path": "", "extension": "js", "parent": "Foo_component_1_DvU6FitWglY", "ctxKind": "eventHandler", - "ctxName": "host:onClick$", + "ctxName": "host:onDocumentScroll$", "captures": false, "loc": [ - 638, - 670 + 590, + 631 ] } */ ============================= test.tsx_Foo_component_1_DvU6FitWglY.js (ENTRY POINT)== -import { _jsxQ } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { _jsxSorted } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; export const Foo_component_1_DvU6FitWglY = ()=>{ - const handler = /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_handler_H10xZtD0e7w"), "Foo_component_handler_H10xZtD0e7w"); - return /*#__PURE__*/ _jsxQ("div", null, { - onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_div_onClick_M48DYiidSJw"), "Foo_component_div_onClick_M48DYiidSJw"), - onDocumentScroll$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_div_onDocumentScroll_rwFFtFiVuKc"), "Foo_component_div_onDocumentScroll_rwFFtFiVuKc"), - onDocumentScroll$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_div_onDocumentScroll_1_CwneoGpmTZI"), "Foo_component_div_onDocumentScroll_1_CwneoGpmTZI"), - "on-cLick$": /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_div_on_cLick_IoAsJW8vYJc"), "Foo_component_div_on_cLick_IoAsJW8vYJc"), - "onDocument-sCroll$": /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_div_onDocument_sCroll_5VNik61PZOM"), "Foo_component_div_onDocument_sCroll_5VNik61PZOM"), - "onDocument-scroLL$": /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_div_onDocument_scroLL_1q0Sgr8te3g"), "Foo_component_div_onDocument_scroLL_1q0Sgr8te3g"), - "host:onClick$": /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_div_host_onClick_cPEH970JbEY"), "Foo_component_div_host_onClick_cPEH970JbEY"), - "host:onDocumentScroll$": /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_div_host_onDocumentScroll_Zip7mifsjRY"), "Foo_component_div_host_onDocumentScroll_Zip7mifsjRY"), - "host:onDocumentScroll$": /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_div_host_onDocumentScroll_1_Em1LspK7JVg"), "Foo_component_div_host_onDocumentScroll_1_Em1LspK7JVg"), - onKeyup$: handler, + const handler = /*#__PURE__*/ _addLoc(/*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_handler_H10xZtD0e7w"), "Foo_component_handler_H10xZtD0e7w"), "test.tsx", 8, 19); + return /*#__PURE__*/ _jsxSorted("div", { "onDocument:keyup$": handler, - "onWindow:keyup$": handler, - custom$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_div_custom_pyHnxab17ms"), "Foo_component_div_custom_pyHnxab17ms") - }, null, 3, "u6_0"); + onKeyup$: handler, + "onWindow:keyup$": handler + }, { + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_div_onClick_FaeKlHF3HdE"), "Foo_div_onClick_FaeKlHF3HdE"), + onDocumentScroll$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_div_onDocumentScroll_0LL6A9YcMeE"), "Foo_div_onDocumentScroll_0LL6A9YcMeE"), + onDocumentScroll$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_div_onDocumentScroll_1_Vp39eYXzD8M"), "Foo_div_onDocumentScroll_1_Vp39eYXzD8M"), + "on-cLick$": /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_div_on_cLick_KkdRIICJbm4"), "Foo_div_on_cLick_KkdRIICJbm4"), + "onDocument-sCroll$": /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_div_onDocument_sCroll_VYzXH4S4Kfg"), "Foo_div_onDocument_sCroll_VYzXH4S4Kfg"), + "onDocument-scroLL$": /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_div_onDocument_scroLL_XUFvJrCL7yA"), "Foo_div_onDocument_scroLL_XUFvJrCL7yA"), + "host:onClick$": /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_div_host_onClick_E0xiPVoj1PU"), "Foo_div_host_onClick_E0xiPVoj1PU"), + "host:onDocumentScroll$": /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_div_host_onDocumentScroll_QDhZi1GjXUk"), "Foo_div_host_onDocumentScroll_QDhZi1GjXUk"), + "host:onDocumentScroll$": /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_div_host_onDocumentScroll_1_L4jqGHGQ0a4"), "Foo_div_host_onDocumentScroll_1_L4jqGHGQ0a4"), + custom$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_div_custom_0aBC7DwC5wU"), "Foo_div_custom_0aBC7DwC5wU") + }, null, 2, "u6_0"); }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;2CAKa;IACL,MAAM;IACN,qBACI,MAAC;QACG,QAAQ;QACR,iBAAiB;QACjB,iBAAiB;QAEjB,WAAS;QACT,oBAAkB;QAClB,oBAAkB;QAPtB,eAkBE;QAlBF,wBAkBE;QAlBF,wBAkBE;QALE,UAAU;QAbd,qBAcuB;QAdvB,mBAeqB;QAEjB,OAAO;;AAGnB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;2CAKU;IACR,MAAM,wBAAU;IAChB,qBACC,WAAC;QAAD,qBAcoB;QADnB,UAAU;QAbX,mBAekB;;QAdjB,QAAQ;QACR,iBAAiB;QACjB,iBAAiB;QAEjB,WAAS;QACT,oBAAkB;QAClB,oBAAkB;QAPnB,eAkBE;QAlBF,wBAkBE;QAlBF,wBAkBE;QADD,OAAO;;AAGV\"}") /* { "origin": "test.tsx", @@ -171,103 +199,103 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 105, - 1041 + 100, + 841 ] } */ -============================= test.tsx_Foo_component_div_host_onDocumentScroll_1_Em1LspK7JVg.js (ENTRY POINT)== +============================= test.tsx_Foo_div_on_cLick_KkdRIICJbm4.js (ENTRY POINT)== -export const Foo_component_div_host_onDocumentScroll_1_Em1LspK7JVg = ()=>console.log('host:onWindow:scroll'); +export const Foo_div_on_cLick_KkdRIICJbm4 = ()=>console.log('on-cLick$'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"qEAmBwC,IAAI,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"4CAae,IAAI,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", - "name": "Foo_component_div_host_onDocumentScroll_1_Em1LspK7JVg", + "name": "Foo_div_on_cLick_KkdRIICJbm4", "entry": null, - "displayName": "test.tsx_Foo_component_div_host_onDocumentScroll_1", - "hash": "Em1LspK7JVg", - "canonicalFilename": "test.tsx_Foo_component_div_host_onDocumentScroll_1_Em1LspK7JVg", + "displayName": "test.tsx_Foo_div_on_cLick", + "hash": "KkdRIICJbm4", + "canonicalFilename": "test.tsx_Foo_div_on_cLick_KkdRIICJbm4", "path": "", "extension": "js", "parent": "Foo_component_1_DvU6FitWglY", "ctxKind": "eventHandler", - "ctxName": "host:onDocumentScroll$", + "ctxName": "on-cLick$", "captures": false, "loc": [ - 795, - 834 + 354, + 382 ] } */ -============================= test.tsx_Foo_component_div_custom_pyHnxab17ms.js (ENTRY POINT)== +============================= test.tsx_Foo_div_host_onDocumentScroll_1_L4jqGHGQ0a4.js (ENTRY POINT)== -export const Foo_component_div_custom_pyHnxab17ms = ()=>console.log('custom'); +export const Foo_div_host_onDocumentScroll_1_L4jqGHGQ0a4 = ()=>console.log('host:onWindow:scroll'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"oDAyByB,IAAI,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"2DAmB4B,IAAI,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", - "name": "Foo_component_div_custom_pyHnxab17ms", + "name": "Foo_div_host_onDocumentScroll_1_L4jqGHGQ0a4", "entry": null, - "displayName": "test.tsx_Foo_component_div_custom", - "hash": "pyHnxab17ms", - "canonicalFilename": "test.tsx_Foo_component_div_custom_pyHnxab17ms", + "displayName": "test.tsx_Foo_div_host_onDocumentScroll_1", + "hash": "L4jqGHGQ0a4", + "canonicalFilename": "test.tsx_Foo_div_host_onDocumentScroll_1_L4jqGHGQ0a4", "path": "", "extension": "js", "parent": "Foo_component_1_DvU6FitWglY", "ctxKind": "eventHandler", - "ctxName": "custom$", + "ctxName": "host:onDocumentScroll$", "captures": false, "loc": [ - 984, - 1009 + 661, + 700 ] } */ -============================= test.tsx_Foo_component_div_onDocument_scroLL_1q0Sgr8te3g.js (ENTRY POINT)== +============================= test.tsx_Foo_component_handler_H10xZtD0e7w.js (ENTRY POINT)== -export const Foo_component_div_onDocument_scroLL_1q0Sgr8te3g = ()=>console.log('onDocument-scroLL'); +export const Foo_component_handler_H10xZtD0e7w = ()=>console.log('reused'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"+DAeoC,IAAI,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"iDAMoB,IAAM,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", - "name": "Foo_component_div_onDocument_scroLL_1q0Sgr8te3g", + "name": "Foo_component_handler_H10xZtD0e7w", "entry": null, - "displayName": "test.tsx_Foo_component_div_onDocument_scroLL", - "hash": "1q0Sgr8te3g", - "canonicalFilename": "test.tsx_Foo_component_div_onDocument_scroLL_1q0Sgr8te3g", + "displayName": "test.tsx_Foo_component_handler", + "hash": "H10xZtD0e7w", + "canonicalFilename": "test.tsx_Foo_component_handler_H10xZtD0e7w", "path": "", "extension": "js", "parent": "Foo_component_1_DvU6FitWglY", - "ctxKind": "eventHandler", - "ctxName": "onDocument-scroLL$", + "ctxKind": "function", + "ctxName": "$", "captures": false, "loc": [ - 568, - 604 + 128, + 155 ] } */ -============================= test.tsx_Foo_component_div_onDocumentScroll_1_CwneoGpmTZI.js (ENTRY POINT)== +============================= test.tsx_Foo_div_onDocumentScroll_1_Vp39eYXzD8M.js (ENTRY POINT)== -export const Foo_component_div_onDocumentScroll_1_CwneoGpmTZI = ()=>console.log('onWindowScroll'); +export const Foo_div_onDocumentScroll_1_Vp39eYXzD8M = ()=>console.log('onWindowScroll'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"gEAWmC,IAAI,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"sDAWuB,IAAI,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", - "name": "Foo_component_div_onDocumentScroll_1_CwneoGpmTZI", + "name": "Foo_div_onDocumentScroll_1_Vp39eYXzD8M", "entry": null, - "displayName": "test.tsx_Foo_component_div_onDocumentScroll_1", - "hash": "CwneoGpmTZI", - "canonicalFilename": "test.tsx_Foo_component_div_onDocumentScroll_1_CwneoGpmTZI", + "displayName": "test.tsx_Foo_div_onDocumentScroll_1", + "hash": "Vp39eYXzD8M", + "canonicalFilename": "test.tsx_Foo_div_onDocumentScroll_1_Vp39eYXzD8M", "path": "", "extension": "js", "parent": "Foo_component_1_DvU6FitWglY", @@ -275,51 +303,25 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "onDocumentScroll$", "captures": false, "loc": [ - 365, - 398 - ] -} -*/ -============================= test.tsx_Foo_component_div_on_cLick_IoAsJW8vYJc.js (ENTRY POINT)== - -export const Foo_component_div_on_cLick_IoAsJW8vYJc = ()=>console.log('on-cLick$'); - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"sDAa2B,IAAI,QAAQ,GAAG,CAAC\"}") -/* -{ - "origin": "test.tsx", - "name": "Foo_component_div_on_cLick_IoAsJW8vYJc", - "entry": null, - "displayName": "test.tsx_Foo_component_div_on_cLick", - "hash": "IoAsJW8vYJc", - "canonicalFilename": "test.tsx_Foo_component_div_on_cLick_IoAsJW8vYJc", - "path": "", - "extension": "js", - "parent": "Foo_component_1_DvU6FitWglY", - "ctxKind": "eventHandler", - "ctxName": "on-cLick$", - "captures": false, - "loc": [ - 428, - 456 + 303, + 336 ] } */ -============================= test.tsx_Foo_component_div_onClick_M48DYiidSJw.js (ENTRY POINT)== +============================= test.tsx_Foo_div_onClick_FaeKlHF3HdE.js (ENTRY POINT)== -export const Foo_component_div_onClick_M48DYiidSJw = ()=>console.log('onClick$'); +export const Foo_div_onClick_FaeKlHF3HdE = ()=>console.log('onClick$'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"qDAS0B,IAAI,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"2CASc,IAAI,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", - "name": "Foo_component_div_onClick_M48DYiidSJw", + "name": "Foo_div_onClick_FaeKlHF3HdE", "entry": null, - "displayName": "test.tsx_Foo_component_div_onClick", - "hash": "M48DYiidSJw", - "canonicalFilename": "test.tsx_Foo_component_div_onClick_M48DYiidSJw", + "displayName": "test.tsx_Foo_div_onClick", + "hash": "FaeKlHF3HdE", + "canonicalFilename": "test.tsx_Foo_div_onClick_FaeKlHF3HdE", "path": "", "extension": "js", "parent": "Foo_component_1_DvU6FitWglY", @@ -327,25 +329,25 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "onClick$", "captures": false, "loc": [ - 229, - 256 + 191, + 218 ] } */ -============================= test.tsx_Foo_component_div_onDocumentScroll_rwFFtFiVuKc.js (ENTRY POINT)== +============================= test.tsx_Foo_div_onDocumentScroll_0LL6A9YcMeE.js (ENTRY POINT)== -export const Foo_component_div_onDocumentScroll_rwFFtFiVuKc = ()=>console.log('onDocumentScroll'); +export const Foo_div_onDocumentScroll_0LL6A9YcMeE = ()=>console.log('onDocumentScroll'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"8DAUmC,IAAI,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"oDAUuB,IAAI,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", - "name": "Foo_component_div_onDocumentScroll_rwFFtFiVuKc", + "name": "Foo_div_onDocumentScroll_0LL6A9YcMeE", "entry": null, - "displayName": "test.tsx_Foo_component_div_onDocumentScroll", - "hash": "rwFFtFiVuKc", - "canonicalFilename": "test.tsx_Foo_component_div_onDocumentScroll_rwFFtFiVuKc", + "displayName": "test.tsx_Foo_div_onDocumentScroll", + "hash": "0LL6A9YcMeE", + "canonicalFilename": "test.tsx_Foo_div_onDocumentScroll_0LL6A9YcMeE", "path": "", "extension": "js", "parent": "Foo_component_1_DvU6FitWglY", @@ -353,52 +355,51 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "onDocumentScroll$", "captures": false, "loc": [ - 293, - 328 + 243, + 278 ] } */ -============================= test.tsx_Foo_component_handler_H10xZtD0e7w.js (ENTRY POINT)== +============================= test.tsx_Foo_div_host_onClick_E0xiPVoj1PU.js (ENTRY POINT)== -export const Foo_component_handler_H10xZtD0e7w = ()=>console.log('reused'); -export { _hW } from "@builder.io/qwik"; +export const Foo_div_host_onClick_E0xiPVoj1PU = ()=>console.log('host:onClick$'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"iDAM0B,IAAM,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"gDAiBmB,IAAI,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", - "name": "Foo_component_handler_H10xZtD0e7w", + "name": "Foo_div_host_onClick_E0xiPVoj1PU", "entry": null, - "displayName": "test.tsx_Foo_component_handler", - "hash": "H10xZtD0e7w", - "canonicalFilename": "test.tsx_Foo_component_handler_H10xZtD0e7w", + "displayName": "test.tsx_Foo_div_host_onClick", + "hash": "E0xiPVoj1PU", + "canonicalFilename": "test.tsx_Foo_div_host_onClick_E0xiPVoj1PU", "path": "", "extension": "js", "parent": "Foo_component_1_DvU6FitWglY", - "ctxKind": "function", - "ctxName": "$", + "ctxKind": "eventHandler", + "ctxName": "host:onClick$", "captures": false, "loc": [ - 139, - 166 + 528, + 560 ] } */ -============================= test.tsx_Foo_component_div_onDocument_sCroll_5VNik61PZOM.js (ENTRY POINT)== +============================= test.tsx_Foo_div_onDocument_sCroll_VYzXH4S4Kfg.js (ENTRY POINT)== -export const Foo_component_div_onDocument_sCroll_5VNik61PZOM = ()=>console.log('onDocument-sCroll'); +export const Foo_div_onDocument_sCroll_VYzXH4S4Kfg = ()=>console.log('onDocument-sCroll'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"+DAcoC,IAAI,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"qDAcwB,IAAI,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", - "name": "Foo_component_div_onDocument_sCroll_5VNik61PZOM", + "name": "Foo_div_onDocument_sCroll_VYzXH4S4Kfg", "entry": null, - "displayName": "test.tsx_Foo_component_div_onDocument_sCroll", - "hash": "5VNik61PZOM", - "canonicalFilename": "test.tsx_Foo_component_div_onDocument_sCroll_5VNik61PZOM", + "displayName": "test.tsx_Foo_div_onDocument_sCroll", + "hash": "VYzXH4S4Kfg", + "canonicalFilename": "test.tsx_Foo_div_onDocument_sCroll_VYzXH4S4Kfg", "path": "", "extension": "js", "parent": "Foo_component_1_DvU6FitWglY", @@ -406,8 +407,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "onDocument-sCroll$", "captures": false, "loc": [ - 494, - 530 + 408, + 444 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_lightweight_functional.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_lightweight_functional.snap index 99e6ea1c3ad..ed5a55eb8ba 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_lightweight_functional.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_lightweight_functional.snap @@ -1,50 +1,50 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 826 +assertion_line: 936 expression: output snapshot_kind: text --- ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; -export const Foo = component$(({color}) => { - return ( -
        -
        - ); +export const Foo = component$((props) => { + return ( +
        +
        + ); }, { - tagName: "my-foo", + tagName: "my-foo", }); export function Button({text, color}) { - return ( - - ); + return ( + + ); } export const ButtonArrow = ({text, color}) => { - return ( - - ); + return ( + + ); } ============================= test.tsx_Foo_component_HTDRsvUbLiE.tsx (ENTRY POINT)== import { Button } from "./test"; import { ButtonArrow } from "./test"; -export const Foo_component_HTDRsvUbLiE = (props1)=>{ +export const Foo_component_HTDRsvUbLiE = (props)=>{ return
        -
        ; +
        ; }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;yCAG8B;IAC1B,QACK,IAAI;YACD,CAAC,QAAQ,GAAG,KAAK,GAAI;YACrB,CAAC,aAAa,GAAG,KAAK,GAAI;QAC9B,EAAE;AAEV\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;yCAG8B,CAAC;IAC9B,QACE,IAAI;GACJ,CAAC,QAAQ,GAAG,KAAK,GAAI;GACrB,CAAC,aAAa,GAAG,KAAK,GAAI;EAC3B,EAAE;AAEJ\"}") /* { "origin": "test.tsx", @@ -60,21 +60,24 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 83, - 221 + 81, + 181 + ], + "paramNames": [ + "props" ] } */ ============================= test.tsx_ButtonArrow_button_onClick_9npo43fIGik.tsx (ENTRY POINT)== -import { useLexicalScope } from "@builder.io/qwik"; +import { useLexicalScope } from "@qwik.dev/core"; export const ButtonArrow_button_onClick_9npo43fIGik = ()=>{ - const [color, text] = useLexicalScope(); - return console.log(text, color); + const [props] = useLexicalScope(); + return console.log(props.text, props.color); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";sDAsB2C;;WAAI,QAAQ,GAAG,CAAC,MAAM\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";sDAsBqC;;WAAI,QAAQ,GAAG,OAFvB,YAAM\"}") /* { "origin": "test.tsx", @@ -90,21 +93,24 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "onClick$", "captures": true, "loc": [ - 509, - 537 + 445, + 473 + ], + "captureNames": [ + "props" ] } */ ============================= test.tsx_Button_button_onClick_NsM0JYV00Jw.tsx (ENTRY POINT)== -import { useLexicalScope } from "@builder.io/qwik"; +import { useLexicalScope } from "@qwik.dev/core"; export const Button_button_onClick_NsM0JYV00Jw = ()=>{ const [color, text] = useLexicalScope(); return console.log(text, color); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";iDAgB2C;;WAAI,QAAQ,GAAG,CAAC,MAAM\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";iDAgBqC;;WAAI,QAAQ,GAAG,CAAC,MAAM\"}") /* { "origin": "test.tsx", @@ -120,33 +126,37 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "onClick$", "captures": true, "loc": [ - 349, - 377 + 297, + 325 + ], + "captureNames": [ + "color", + "text" ] } */ ============================= test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const Foo = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_HTDRsvUbLiE"), "Foo_component_HTDRsvUbLiE"), { +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Foo = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_HTDRsvUbLiE"), "Foo_component_HTDRsvUbLiE"), { tagName: "my-foo" -}); +}), "test.tsx", 5, 20); export function Button({ text, color }) { return ; } -export const ButtonArrow = ({ text, color })=>{ - return ; -}; +export const ButtonArrow = _addLoc((props)=>{ + return ; +}, "test.tsx", 22, 28); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,iHAOhB;IACC,SAAS;AACb,GAAG;AAEH,OAAO,SAAS,OAAO,EAAC,IAAI,EAAE,KAAK,EAAC;IAChC,QACK,OAAO,UAAU,OAAO;;;SAAyC,OAAO;AAEjF;AAEA,OAAO,MAAM,cAAc,CAAC,EAAC,IAAI,EAAE,KAAK,EAAC;IACrC,QACK,OAAO,UAAU,OAAO;;;SAAyC,OAAO;AAEjF,EAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,oBAAM,QAAA,iHAOhB;IACF,SAAS;AACV,uBAAG;AAEH,OAAO,SAAS,OAAO,EAAC,IAAI,EAAE,KAAK,EAAC;IACnC,QACE,OAAO,UAAU,OAAO;;;SAAyC,OAAO;AAE3E;AAEA,OAAO,MAAM,cAAc,QAAA;IAC1B,QACE,OAAO,gBAFyB,OAER;;eAFE,OAE8C;AAE3E,uBAAC\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_manual_chunks.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_manual_chunks.snap index 3f9e32e44e3..de8bda4746a 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_manual_chunks.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_manual_chunks.snap @@ -1,73 +1,72 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1602 +assertion_line: 1712 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useTask$, useStore, useStyles$ } from '@builder.io/qwik'; +import { component$, useTask$, useStore, useStyles$ } from '@qwik.dev/core'; import mongo from 'mongodb'; import redis from 'redis'; export const Parent = component$(() => { - const state = useStore({ - text: '' - }); + const state = useStore({ + text: '' + }); - // Double count watch - useTask$(async () => { - state.text = await mongo.users(); - redis.set(state.text); - }); + // Double count watch + useTask$(async () => { + state.text = await mongo.users(); + redis.set(state.text); + }); - return ( -
        console.log('parent')}> - {state.text} -
        - ); + return ( +
        console.log('parent')}> + {state.text} +
        + ); }); export const Child = component$(() => { - const state = useStore({ - text: '' - }); + const state = useStore({ + text: '' + }); - // Double count watch - useTask$(async () => { - state.text = await mongo.users(); - }); + // Double count watch + useTask$(async () => { + state.text = await mongo.users(); + }); - return ( -
        console.log('child')}> - {state.text} -
        - ); + return ( +
        console.log('child')}> + {state.text} +
        + ); }); -============================= test.tsx_Parent_component_useTask_gDH1EtUWqBU.js == +============================= test.tsx_Parent_useTask_2FGtjOskTRQ.js == -import { useLexicalScope } from "@builder.io/qwik"; +import { useLexicalScope } from "@qwik.dev/core"; import mongo from "mongodb"; import redis from "redis"; -export const Parent_component_useTask_gDH1EtUWqBU = async ()=>{ +export const Parent_useTask_2FGtjOskTRQ = async ()=>{ const [state] = useLexicalScope(); state.text = await mongo.users(); redis.set(state.text); }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;oDAWa;;IACL,MAAM,IAAI,GAAG,MAAM,MAAM,KAAK;IAC9B,MAAM,GAAG,CAAC,MAAM,IAAI\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;0CAWU;;IACR,MAAM,IAAI,GAAG,MAAM,MAAM,KAAK;IAC9B,MAAM,GAAG,CAAC,MAAM,IAAI\"}") /* { "origin": "test.tsx", - "name": "Parent_component_useTask_gDH1EtUWqBU", + "name": "Parent_useTask_2FGtjOskTRQ", "entry": "test.tsx_entry_Parent", - "displayName": "test.tsx_Parent_component_useTask", - "hash": "gDH1EtUWqBU", - "canonicalFilename": "test.tsx_Parent_component_useTask_gDH1EtUWqBU", + "displayName": "test.tsx_Parent_useTask", + "hash": "2FGtjOskTRQ", + "canonicalFilename": "test.tsx_Parent_useTask_2FGtjOskTRQ", "path": "", "extension": "js", "parent": "Parent_component_0TaiDayHrlo", @@ -75,40 +74,69 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "useTask$", "captures": true, "loc": [ - 273, - 365 + 253, + 330 + ], + "captureNames": [ + "state" ] } */ ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const Parent = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Parent_component_0TaiDayHrlo"), "Parent_component_0TaiDayHrlo")); -export const Child = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Child_component_9GyF01GDKqw"), "Child_component_9GyF01GDKqw")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Parent = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Parent_component_0TaiDayHrlo"), "Parent_component_0TaiDayHrlo")), "test.tsx", 7, 23); +export const Child = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Child_component_9GyF01GDKqw"), "Child_component_9GyF01GDKqw")), "test.tsx", 25, 22); + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAKA,OAAO,MAAM,uBAAS,QAAA,2IAgBnB;AAEH,OAAO,MAAM,sBAAQ,QAAA,0IAelB\"}") +============================= test.tsx_Parent_div_onClick_oBBb9T5cGSs.js (ENTRY POINT)== -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAKA,OAAO,MAAM,uBAAS,uHAgBnB;AAEH,OAAO,MAAM,sBAAQ,qHAelB\"}") -============================= test.tsx_Child_component_useTask_Oh4n7ZeqJkU.js == +export const Parent_div_onClick_oBBb9T5cGSs = ()=>console.log('parent'); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"8CAiBiB,IAAM,QAAQ,GAAG,CAAC\"}") +/* +{ + "origin": "test.tsx", + "name": "Parent_div_onClick_oBBb9T5cGSs", + "entry": null, + "displayName": "test.tsx_Parent_div_onClick", + "hash": "oBBb9T5cGSs", + "canonicalFilename": "test.tsx_Parent_div_onClick_oBBb9T5cGSs", + "path": "", + "extension": "js", + "parent": "Parent_component_0TaiDayHrlo", + "ctxKind": "eventHandler", + "ctxName": "onClick$", + "captures": false, + "loc": [ + 361, + 388 + ] +} +*/ +============================= test.tsx_Child_useTask_FwM471n7n0s.js == -import { useLexicalScope } from "@builder.io/qwik"; +import { useLexicalScope } from "@qwik.dev/core"; import mongo from "mongodb"; -export const Child_component_useTask_Oh4n7ZeqJkU = async ()=>{ +export const Child_useTask_FwM471n7n0s = async ()=>{ const [state] = useLexicalScope(); state.text = await mongo.users(); }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;mDA6Ba;;IACL,MAAM,IAAI,GAAG,MAAM,MAAM,KAAK\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;yCA6BU;;IACR,MAAM,IAAI,GAAG,MAAM,MAAM,KAAK\"}") /* { "origin": "test.tsx", - "name": "Child_component_useTask_Oh4n7ZeqJkU", + "name": "Child_useTask_FwM471n7n0s", "entry": "test.tsx_entry_Child", - "displayName": "test.tsx_Child_component_useTask", - "hash": "Oh4n7ZeqJkU", - "canonicalFilename": "test.tsx_Child_component_useTask_Oh4n7ZeqJkU", + "displayName": "test.tsx_Child_useTask", + "hash": "FwM471n7n0s", + "canonicalFilename": "test.tsx_Child_useTask_FwM471n7n0s", "path": "", "extension": "js", "parent": "Child_component_9GyF01GDKqw", @@ -116,35 +144,37 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "useTask$", "captures": true, "loc": [ - 621, - 682 + 541, + 593 + ], + "captureNames": [ + "state" ] } */ ============================= test.tsx_Parent_component_0TaiDayHrlo.js == -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -import { useStore } from "@builder.io/qwik"; -import { useTaskQrl } from "@builder.io/qwik"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { useStore } from "@qwik.dev/core"; +import { useTaskQrl } from "@qwik.dev/core"; export const Parent_component_0TaiDayHrlo = ()=>{ - const state = useStore({ + const state = _addLoc(useStore({ text: '' - }); + }), "test.tsx", 8, 16); // Double count watch - useTaskQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Parent_component_useTask_gDH1EtUWqBU"), "Parent_component_useTask_gDH1EtUWqBU", [ + useTaskQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Parent_useTask_2FGtjOskTRQ"), "Parent_useTask_2FGtjOskTRQ", [ state ])); - return /*#__PURE__*/ _jsxQ("div", null, { - onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Parent_component_div_onClick_C5XE49Nqd3A"), "Parent_component_div_onClick_C5XE49Nqd3A") - }, _fnSignal((p0)=>p0.text, [ - state - ], "p0.text"), 3, "u6_0"); + return /*#__PURE__*/ _jsxSorted("div", null, { + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Parent_div_onClick_oBBb9T5cGSs"), "Parent_div_onClick_oBBb9T5cGSs") + }, _wrapProp(state, "text"), 1, "u6_0"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;4CAKiC;IAC7B,MAAM,QAAQ,SAAS;QACnB,MAAM;IACV;IAEA,qBAAqB;IACrB;;;IAKA,qBACI,MAAC;QAAI,QAAQ;uBACR,GAAM,IAAI;;;AAGvB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;4CAKiC;IAChC,MAAM,QAAQ,QAAA,SAAS;QACtB,MAAM;IACP;IAEA,qBAAqB;IACrB;;;IAKA,qBACC,WAAC;QAAI,QAAQ;iBACX;AAGJ\"}") /* { "origin": "test.tsx", @@ -160,61 +190,34 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 171, - 483 - ] -} -*/ -============================= test.tsx_Parent_component_div_onClick_C5XE49Nqd3A.js (ENTRY POINT)== - -export const Parent_component_div_onClick_C5XE49Nqd3A = ()=>console.log('parent'); - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"wDAiBuB,IAAM,QAAQ,GAAG,CAAC\"}") -/* -{ - "origin": "test.tsx", - "name": "Parent_component_div_onClick_C5XE49Nqd3A", - "entry": null, - "displayName": "test.tsx_Parent_component_div_onClick", - "hash": "C5XE49Nqd3A", - "canonicalFilename": "test.tsx_Parent_component_div_onClick_C5XE49Nqd3A", - "path": "", - "extension": "js", - "parent": "Parent_component_0TaiDayHrlo", - "ctxKind": "eventHandler", - "ctxName": "onClick$", - "captures": false, - "loc": [ - 405, - 432 + 169, + 421 ] } */ ============================= test.tsx_Child_component_9GyF01GDKqw.js == -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -import { useStore } from "@builder.io/qwik"; -import { useTaskQrl } from "@builder.io/qwik"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { useStore } from "@qwik.dev/core"; +import { useTaskQrl } from "@qwik.dev/core"; export const Child_component_9GyF01GDKqw = ()=>{ - const state = useStore({ + const state = _addLoc(useStore({ text: '' - }); + }), "test.tsx", 26, 16); // Double count watch - useTaskQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Child_component_useTask_Oh4n7ZeqJkU"), "Child_component_useTask_Oh4n7ZeqJkU", [ + useTaskQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Child_useTask_FwM471n7n0s"), "Child_useTask_FwM471n7n0s", [ state ])); - return /*#__PURE__*/ _jsxQ("div", null, { - onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Child_component_div_onClick_elliVSnAiOQ"), "Child_component_div_onClick_elliVSnAiOQ") - }, _fnSignal((p0)=>p0.text, [ - state - ], "p0.text"), 3, "u6_1"); + return /*#__PURE__*/ _jsxSorted("div", null, { + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Child_div_onClick_pV1ddhigrLs"), "Child_div_onClick_pV1ddhigrLs") + }, _wrapProp(state, "text"), 1, "u6_1"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;2CAuBgC;IAC5B,MAAM,QAAQ,SAAS;QACnB,MAAM;IACV;IAEA,qBAAqB;IACrB;;;IAIA,qBACI,MAAC;QAAI,QAAQ;uBACR,GAAM,IAAI;;;AAGvB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;2CAuBgC;IAC/B,MAAM,QAAQ,QAAA,SAAS;QACtB,MAAM;IACP;IAEA,qBAAqB;IACrB;;;IAIA,qBACC,WAAC;QAAI,QAAQ;iBACX;AAGJ\"}") /* { "origin": "test.tsx", @@ -230,25 +233,25 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 519, - 799 + 457, + 683 ] } */ -============================= test.tsx_Child_component_div_onClick_elliVSnAiOQ.js (ENTRY POINT)== +============================= test.tsx_Child_div_onClick_pV1ddhigrLs.js (ENTRY POINT)== -export const Child_component_div_onClick_elliVSnAiOQ = ()=>console.log('child'); +export const Child_div_onClick_pV1ddhigrLs = ()=>console.log('child'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"uDAkCuB,IAAM,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"6CAkCiB,IAAM,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", - "name": "Child_component_div_onClick_elliVSnAiOQ", + "name": "Child_div_onClick_pV1ddhigrLs", "entry": null, - "displayName": "test.tsx_Child_component_div_onClick", - "hash": "elliVSnAiOQ", - "canonicalFilename": "test.tsx_Child_component_div_onClick_elliVSnAiOQ", + "displayName": "test.tsx_Child_div_onClick", + "hash": "pV1ddhigrLs", + "canonicalFilename": "test.tsx_Child_div_onClick_pV1ddhigrLs", "path": "", "extension": "js", "parent": "Child_component_9GyF01GDKqw", @@ -256,8 +259,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "onClick$", "captures": false, "loc": [ - 722, - 748 + 624, + 650 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_missing_custom_inlined_functions.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_missing_custom_inlined_functions.snap index b36c64ba6bd..ca131c9ee43 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_missing_custom_inlined_functions.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_missing_custom_inlined_functions.snap @@ -1,51 +1,50 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1232 +assertion_line: 1342 expression: output snapshot_kind: text --- ==INPUT== -import { component$ as Component, $ as onRender, useStore, wrap, useEffect } from '@builder.io/qwik'; +import { component$ as Component, $ as onRender, useStore, wrap, useEffect } from '@qwik.dev/core'; export const useMemo$ = (qrt) => { - useEffect(qrt); + useEffect(qrt); }; export const App = component$((props) => { - const state = useStore({count: 0}); - useMemo$(() => { - console.log(state.count); - }); - return $(() => ( -
        {state.count}
        - )); + const state = useStore({count: 0}); + useMemo$(() => { + console.log(state.count); + }); + return $(() => ( +
        {state.count}
        + )); }); ============================= test.js == -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { useStore, useEffect } from '@builder.io/qwik'; -export const useMemo$ = (qrt)=>{ +import { _wrapProp } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { useStore, useEffect } from '@qwik.dev/core'; +export const useMemo$ = _addLoc((qrt)=>{ useEffect(qrt); -}; -export const App = component$((props)=>{ - const state = useStore({ +}, "test.tsx", 6, 25); +export const App = _addLoc(component$((props)=>{ + const state = _addLoc(useStore({ count: 0 - }); + }), "test.tsx", 11, 16); useMemo$(()=>{ console.log(state.count); }); - return $(()=>/*#__PURE__*/ _jsxQ("div", null, null, _fnSignal((p0)=>p0.count, [ - state - ], "p0.count"), 3, "u6_0")); -}); + return $(()=>/*#__PURE__*/ _jsxSorted("div", null, null, _wrapProp(state, "count"), 1, "u6_0")); +}), "test.tsx", 10, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AACA,SAAiD,QAAQ,EAAQ,SAAS,QAAQ,mBAAmB;AAGrG,OAAO,MAAM,WAAW,CAAC;IACrB,UAAU;AACd,EAAE;AAEF,OAAO,MAAM,MAAM,WAAW,CAAC;IAC3B,MAAM,QAAQ,SAAS;QAAC,OAAO;IAAC;IAChC,SAAS;QACL,QAAQ,GAAG,CAAC,MAAM,KAAK;IAC3B;IACA,OAAO,EAAE,kBACL,MAAC,mCAAK,GAAM,KAAK;;;AAEzB,GAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AACA,SAAiD,QAAQ,EAAQ,SAAS,QAAQ,iBAAiB;AAGnG,OAAO,MAAM,WAAW,QAAA,CAAC;IACxB,UAAU;AACX,sBAAE;AAEF,OAAO,MAAM,MAAM,QAAA,WAAW,CAAC;IAC9B,MAAM,QAAQ,QAAA,SAAS;QAAC,OAAO;IAAC;IAChC,SAAS;QACR,QAAQ,GAAG,CAAC,MAAM,KAAK;IACxB;IACA,OAAO,EAAE,kBACR,WAAC,6BAAK;AAER,wBAAG\"}") == DIAGNOSTICS == [ @@ -56,8 +55,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "message": "Found 'useMemo$' but did not find the corresponding 'useMemoQrl' exported in the same file. Please check that it is exported and spelled correctly", "highlights": [ { - "lo": 252, - "hi": 260, + "lo": 241, + "hi": 249, "startLine": 11, "startCol": 5, "endLine": 11, diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_multi_capture.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_multi_capture.snap index 692aba5e8c7..b3b7b99839d 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_multi_capture.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_multi_capture.snap @@ -7,41 +7,44 @@ snapshot_kind: text ==INPUT== -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; export const Foo = component$(({foo}) => { - const arg0 = 20; - return $(() => { - const fn = ({aaa}) => aaa; - return ( -
        - {foo}{fn()}{arg0} -
        - ) - }); + const arg0 = 20; + return $(() => { + const fn = ({aaa}) => aaa; + return ( +
        + {foo}{fn()}{arg0} +
        + ) + }); }) export const Bar = component$(({bar}) => { - return $(() => { - return ( -
        - {bar} -
        - ) - }); + return $(() => { + return ( +
        + {bar} +
        + ) + }); }) ============================= test.tsx_Foo_component_HTDRsvUbLiE.jsx (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { qrl } from "@qwik.dev/core"; export const Foo_component_HTDRsvUbLiE = (props)=>{ - return /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_1_DvU6FitWglY"), "Foo_component_1_DvU6FitWglY", [ + const arg0 = _addLoc(20, "test.tsx", 6, 15); + return /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_n07hoBxfni0"), "Foo_n07hoBxfni0", [ + arg0, props ]); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";yCAG8B;IAE1B;;;AAQJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;yCAG8B;IAC7B,MAAM,OAAO,QAAA;IACb;;;;AAQD\"}") /* { "origin": "test.tsx", @@ -57,23 +60,65 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 83, - 278 + 81, + 221 + ], + "paramNames": [ + "props" + ] +} +*/ +============================= test.tsx_Foo_n07hoBxfni0.jsx (ENTRY POINT)== + +import { useLexicalScope } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Foo_n07hoBxfni0 = ()=>{ + const [arg0, props] = useLexicalScope(); + const fn = _addLoc(({ aaa })=>aaa, "test.tsx", 8, 14); + return
        + {props.foo}{fn()}{arg0} +
        ; +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;+BAKU;;IACR,MAAM,KAAK,QAAA,CAAC,EAAC,GAAG,EAAC,GAAK;IACtB,QACE,IAAI;IACJ,OAN4B,KAMtB,MAAM,KAAK;GAClB,EAAE\"}") +/* +{ + "origin": "test.tsx", + "name": "Foo_n07hoBxfni0", + "entry": null, + "displayName": "test.tsx_Foo", + "hash": "n07hoBxfni0", + "canonicalFilename": "test.tsx_Foo_n07hoBxfni0", + "path": "", + "extension": "jsx", + "parent": "Foo_component_HTDRsvUbLiE", + "ctxKind": "function", + "ctxName": "$", + "captures": true, + "loc": [ + 122, + 217 + ], + "captureNames": [ + "arg0", + "props" ] } */ ============================= test.jsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const Foo = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_HTDRsvUbLiE"), "Foo_component_HTDRsvUbLiE")); -export const Bar = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Bar_component_L80pS8Hxf1Y"), "Bar_component_L80pS8Hxf1Y")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Foo = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_HTDRsvUbLiE"), "Foo_component_HTDRsvUbLiE")), "test.tsx", 5, 20); +export const Bar = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Bar_component_L80pS8Hxf1Y"), "Bar_component_L80pS8Hxf1Y")), "test.tsx", 17, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,iHAUjB;AAEF,OAAO,MAAM,oBAAM,iHAQjB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,oBAAM,QAAA,qIAUjB;AAEF,OAAO,MAAM,oBAAM,QAAA,sIAQjB\"}") ============================= test.tsx_Bar_component_L80pS8Hxf1Y.jsx (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const Bar_component_L80pS8Hxf1Y = (props)=>{ return /*#__PURE__*/ qrl(()=>import("./test.tsx_Bar_component_1_0xSyNSnVu3k"), "Bar_component_1_0xSyNSnVu3k", [ props @@ -81,7 +126,7 @@ export const Bar_component_L80pS8Hxf1Y = (props)=>{ }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";yCAe8B;IAC1B;;;AAOJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";yCAe8B;IAC7B;;;AAOD\"}") /* { "origin": "test.tsx", @@ -97,58 +142,26 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 311, - 438 - ] -} -*/ -============================= test.tsx_Foo_component_1_DvU6FitWglY.jsx (ENTRY POINT)== - -import { useLexicalScope } from "@builder.io/qwik"; -export const Foo_component_1_DvU6FitWglY = ()=>{ - const [props] = useLexicalScope(); - const fn = ({ aaa })=>aaa; - return
        - {props.foo}{fn()}{20} -
        ; -}; -export { _hW } from "@builder.io/qwik"; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";2CAKa;;IACL,MAAM,KAAK,CAAC,EAAC,GAAG,EAAC,GAAK;IACtB,QACK,IAAI;cACH,OANkB,KAMZ,MALH,GAKc;YACnB,EAAE\"}") -/* -{ - "origin": "test.tsx", - "name": "Foo_component_1_DvU6FitWglY", - "entry": null, - "displayName": "test.tsx_Foo_component_1", - "hash": "DvU6FitWglY", - "canonicalFilename": "test.tsx_Foo_component_1_DvU6FitWglY", - "path": "", - "extension": "jsx", - "parent": "Foo_component_HTDRsvUbLiE", - "ctxKind": "function", - "ctxName": "$", - "captures": true, - "loc": [ - 130, - 274 + 254, + 335 + ], + "paramNames": [ + "props" ] } */ ============================= test.tsx_Bar_component_1_0xSyNSnVu3k.jsx (ENTRY POINT)== -import { useLexicalScope } from "@builder.io/qwik"; +import { useLexicalScope } from "@qwik.dev/core"; export const Bar_component_1_0xSyNSnVu3k = ()=>{ const [props] = useLexicalScope(); return
        - {props.bar} -
        ; + {props.bar} +
        ; }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";2CAgBa;;IACL,QACK,IAAI;cACH,OAJkB,IAIb;YACP,EAAE\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";2CAgBU;;IACR,QACE,IAAI;IACJ,OAJ4B,IAIvB;GACN,EAAE\"}") /* { "origin": "test.tsx", @@ -164,8 +177,11 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": true, "loc": [ - 337, - 434 + 277, + 331 + ], + "captureNames": [ + "props" ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_mutable_children.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_mutable_children.snap index 680a46322ed..7dfc932be40 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_mutable_children.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_mutable_children.snap @@ -1,218 +1,190 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2384 +assertion_line: 2495 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore, Slot, Fragment } from '@builder.io/qwik'; +import { component$, useStore, Slot, Fragment } from '@qwik.dev/core'; import Image from './image.jpg?jsx'; export function Fn1(props: Stuff) { - return ( - <> -
        {prop < 2 ?

        1

        : 2}
        - - ); + return ( + <> +
        {prop < 2 ?

        1

        : 2}
        + + ); } export function Fn2(props: Stuff) { - return ( -
        {prop.value && }
        - ); + return ( +
        {prop.value && }
        + ); } export function Fn3(props: Stuff) { - if (prop.value) { - return ( - - ); - } - return ( -
        - ); + if (prop.value) { + return ( + + ); + } + return ( +
        + ); } export function Fn4(props: Stuff) { - if (prop.value) { - return ( -
        - ); - } - return ( - - ); + if (prop.value) { + return ( +
        + ); + } + return ( + + ); } export const Arrow = (props: Stuff) =>
        {prop < 2 ?

        1

        : 2}
        ; export const AppDynamic1 = component$((props: Stuff) => { - return ( - <> -
        {prop < 2 ?

        1

        : 2}
        - - ); + return ( + <> +
        {prop < 2 ?

        1

        : 2}
        + + ); }); export const AppDynamic2 = component$((props: Stuff) => { - return ( -
        {prop.value && }
        - ); + return ( +
        {prop.value && }
        + ); }); export const AppDynamic3 = component$((props: Stuff) => { - if (prop.value) { - return ( - - ); - } - return ( -
        - ); + if (prop.value) { + return ( + + ); + } + return ( +
        + ); }); export const AppDynamic4 = component$((props: Stuff) => { - if (prop.value) { - return ( -
        - ); - } - return ( - - ); + if (prop.value) { + return ( +
        + ); + } + return ( + + ); }); export const AppStatic = component$((props: Stuff) => { - return ( - <> -
        Static {f ? 1 : 3}
        -
        {prop < 2 ?

        1

        :

        2

        }
        - -
        {prop.value &&
        }
        -
        {prop.value && }
        -
        {prop.value && <>
        }
        -
        {prop.value && }
        -
        Static {f ? 1 : 3}
        -
        Static
        -
        Static {props.value}
        -
        Static {stuff()}
        -
        Static {stuff()}
        - - ); + return ( + <> +
        Static {f ? 1 : 3}
        +
        {prop < 2 ?

        1

        :

        2

        }
        + +
        {prop.value &&
        }
        +
        {prop.value && }
        +
        {prop.value && <>
        }
        +
        {prop.value && }
        +
        Static {f ? 1 : 3}
        +
        Static
        +
        Static {props.value}
        +
        Static {stuff()}
        +
        Static {stuff()}
        + + ); }); ============================= test.js == -import { _jsxQ } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { _jsxBranch } from "@builder.io/qwik"; -import { componentQrl } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { _fnSignal } from "@builder.io/qwik"; -import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime"; -import { Slot, Fragment } from '@builder.io/qwik'; +import { _jsxSorted } from "@qwik.dev/core"; +import { componentQrl } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { Slot, Fragment } from '@qwik.dev/core'; import Image from './image.jpg?jsx'; export function Fn1(props) { - _jsxBranch(); - return /*#__PURE__*/ _jsxC(_Fragment, { - children: /*#__PURE__*/ _jsxQ("div", null, null, prop < 2 ? /*#__PURE__*/ _jsxQ("p", null, null, "1", 3, "u6_0") : /*#__PURE__*/ _jsxC(Stuff, { - children: "2" - }, 3, "u6_1"), 1, null) - }, 1, "u6_2"); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, /*#__PURE__*/ _jsxSorted("div", null, null, prop < 2 ? /*#__PURE__*/ _jsxSorted("p", null, null, "1", 3, "u6_0") : /*#__PURE__*/ _jsxSorted(Stuff, null, null, "2", 3, "u6_1"), 1, null), 1, "u6_2"); } export function Fn2(props) { - _jsxBranch(); - return /*#__PURE__*/ _jsxQ("div", null, null, [ - prop.value && /*#__PURE__*/ _jsxC(Stuff, null, 3, "u6_3"), - /*#__PURE__*/ _jsxQ("div", null, null, null, 3, null) + return /*#__PURE__*/ _jsxSorted("div", null, null, [ + prop.value && /*#__PURE__*/ _jsxSorted(Stuff, null, null, null, 3, "u6_3"), + /*#__PURE__*/ _jsxSorted("div", null, null, null, 3, null) ], 1, "u6_4"); } export function Fn3(props) { - _jsxBranch(); - if (prop.value) return /*#__PURE__*/ _jsxC(Stuff, null, 3, "u6_5"); - return /*#__PURE__*/ _jsxQ("div", null, null, null, 3, "u6_6"); + if (prop.value) return /*#__PURE__*/ _jsxSorted(Stuff, null, null, null, 3, "u6_5"); + return /*#__PURE__*/ _jsxSorted("div", null, null, null, 3, "u6_6"); } export function Fn4(props) { - _jsxBranch(); - if (prop.value) return /*#__PURE__*/ _jsxQ("div", null, null, null, 3, "u6_7"); - return /*#__PURE__*/ _jsxC(Stuff, null, 3, "u6_8"); + if (prop.value) return /*#__PURE__*/ _jsxSorted("div", null, null, null, 3, "u6_7"); + return /*#__PURE__*/ _jsxSorted(Stuff, null, null, null, 3, "u6_8"); } -export const Arrow = (props)=>/*#__PURE__*/ _jsxBranch(/*#__PURE__*/ _jsxQ("div", null, null, prop < 2 ? /*#__PURE__*/ _jsxQ("p", null, null, "1", 3, "u6_9") : /*#__PURE__*/ _jsxC(Stuff, { - children: "2" - }, 3, "u6_10"), 1, "u6_11")); +export const Arrow = _addLoc((props)=>/*#__PURE__*/ _jsxSorted("div", null, null, prop < 2 ? /*#__PURE__*/ _jsxSorted("p", null, null, "1", 3, "u6_9") : /*#__PURE__*/ _jsxSorted(Stuff, null, null, "2", 3, "u6_10"), 1, "u6_11"), "test.tsx", 42, 22); const AppDynamic1_component_R00UJ05gbes = (props)=>{ - _jsxBranch(); - return /*#__PURE__*/ _jsxC(_Fragment, { - children: /*#__PURE__*/ _jsxQ("div", null, null, prop < 2 ? /*#__PURE__*/ _jsxQ("p", null, null, "1", 3, "u6_12") : /*#__PURE__*/ _jsxC(Stuff, { - children: "2" - }, 3, "u6_13"), 1, null) - }, 1, "u6_14"); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, /*#__PURE__*/ _jsxSorted("div", null, null, prop < 2 ? /*#__PURE__*/ _jsxSorted("p", null, null, "1", 3, "u6_12") : /*#__PURE__*/ _jsxSorted(Stuff, null, null, "2", 3, "u6_13"), 1, null), 1, "u6_14"); }; -export const AppDynamic1 = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(AppDynamic1_component_R00UJ05gbes, "AppDynamic1_component_R00UJ05gbes")); +export const AppDynamic1 = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(AppDynamic1_component_R00UJ05gbes, "AppDynamic1_component_R00UJ05gbes")), "test.tsx", 44, 28); const AppDynamic2_component_3EY2zm0v00A = (props)=>{ - _jsxBranch(); - return /*#__PURE__*/ _jsxQ("div", null, null, [ - prop.value && /*#__PURE__*/ _jsxC(Stuff, null, 3, "u6_15"), - /*#__PURE__*/ _jsxQ("div", null, null, null, 3, null) + return /*#__PURE__*/ _jsxSorted("div", null, null, [ + prop.value && /*#__PURE__*/ _jsxSorted(Stuff, null, null, null, 3, "u6_15"), + /*#__PURE__*/ _jsxSorted("div", null, null, null, 3, null) ], 1, "u6_16"); }; -export const AppDynamic2 = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(AppDynamic2_component_3EY2zm0v00A, "AppDynamic2_component_3EY2zm0v00A")); +export const AppDynamic2 = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(AppDynamic2_component_3EY2zm0v00A, "AppDynamic2_component_3EY2zm0v00A")), "test.tsx", 51, 28); const AppDynamic3_component_FVq83NlbTDQ = (props)=>{ - _jsxBranch(); - if (prop.value) return /*#__PURE__*/ _jsxC(Stuff, null, 3, "u6_17"); - return /*#__PURE__*/ _jsxQ("div", null, null, null, 3, "u6_18"); + if (prop.value) return /*#__PURE__*/ _jsxSorted(Stuff, null, null, null, 3, "u6_17"); + return /*#__PURE__*/ _jsxSorted("div", null, null, null, 3, "u6_18"); }; -export const AppDynamic3 = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(AppDynamic3_component_FVq83NlbTDQ, "AppDynamic3_component_FVq83NlbTDQ")); +export const AppDynamic3 = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(AppDynamic3_component_FVq83NlbTDQ, "AppDynamic3_component_FVq83NlbTDQ")), "test.tsx", 57, 28); const AppDynamic4_component_IO0yr8UvWEI = (props)=>{ - _jsxBranch(); - if (prop.value) return /*#__PURE__*/ _jsxQ("div", null, null, null, 3, "u6_19"); - return /*#__PURE__*/ _jsxC(Stuff, null, 3, "u6_20"); + if (prop.value) return /*#__PURE__*/ _jsxSorted("div", null, null, null, 3, "u6_19"); + return /*#__PURE__*/ _jsxSorted(Stuff, null, null, null, 3, "u6_20"); }; -export const AppDynamic4 = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(AppDynamic4_component_IO0yr8UvWEI, "AppDynamic4_component_IO0yr8UvWEI")); +export const AppDynamic4 = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(AppDynamic4_component_IO0yr8UvWEI, "AppDynamic4_component_IO0yr8UvWEI")), "test.tsx", 68, 28); const AppStatic_component_gYRXqF3G5nE = (props)=>{ - _jsxBranch(); - return /*#__PURE__*/ _jsxC(_Fragment, { - children: [ - /*#__PURE__*/ _jsxQ("div", null, null, [ - "Static ", - f ? 1 : 3 - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, prop < 2 ? /*#__PURE__*/ _jsxQ("p", null, null, "1", 3, "u6_21") : /*#__PURE__*/ _jsxQ("p", null, null, "2", 3, null), 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, prop.value && /*#__PURE__*/ _jsxQ("div", null, null, null, 3, "u6_22"), 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, prop.value && /*#__PURE__*/ _jsxC(Fragment, { - children: /*#__PURE__*/ _jsxC(Slot, null, 3, "u6_23") - }, 1, "u6_24"), 1, null), - /*#__PURE__*/ _jsxQ("div", null, null, prop.value && /*#__PURE__*/ _jsxC(_Fragment, { - children: /*#__PURE__*/ _jsxQ("div", null, null, null, 3, null) - }, 3, "u6_25"), 1, null), - /*#__PURE__*/ _jsxQ("div", null, null, prop.value && /*#__PURE__*/ _jsxC(Image, null, 3, "u6_26"), 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "Static ", - f ? 1 : 3 - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, "Static", 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "Static ", - _fnSignal((p0)=>p0.value, [ - props - ], "p0.value") - ], 3, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "Static ", - stuff() - ], 1, null), - /*#__PURE__*/ _jsxQ("div", null, null, [ - "Static ", - stuff() - ], 1, null) - ] - }, 1, "u6_27"); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, [ + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "Static ", + f ? 1 : 3 + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, prop < 2 ? /*#__PURE__*/ _jsxSorted("p", null, null, "1", 3, "u6_21") : /*#__PURE__*/ _jsxSorted("p", null, null, "2", 3, "u6_22"), 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, prop.value && /*#__PURE__*/ _jsxSorted("div", null, null, null, 3, "u6_23"), 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, prop.value && /*#__PURE__*/ _jsxSorted(Fragment, null, null, /*#__PURE__*/ _jsxSorted(Slot, null, null, null, 3, "u6_24"), 1, "u6_25"), 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, prop.value && /*#__PURE__*/ _jsxSorted(_Fragment, null, null, /*#__PURE__*/ _jsxSorted("div", null, null, null, 3, null), 3, "u6_26"), 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, prop.value && /*#__PURE__*/ _jsxSorted(Image, null, null, null, 3, "u6_27"), 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "Static ", + f ? 1 : 3 + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, "Static", 3, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "Static ", + _wrapProp(props) + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "Static ", + stuff() + ], 1, null), + /*#__PURE__*/ _jsxSorted("div", null, null, [ + "Static ", + stuff() + ], 1, null) + ], 1, "u6_28"); }; -export const AppStatic = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(AppStatic_component_gYRXqF3G5nE, "AppStatic_component_gYRXqF3G5nE")); +export const AppStatic = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(AppStatic_component_gYRXqF3G5nE, "AppStatic_component_gYRXqF3G5nE")), "test.tsx", 79, 26); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;AACA,SAA+B,IAAI,EAAE,QAAQ,QAAQ,mBAAmB;AACxE,OAAO,WAAW,kBAAkB;AAEpC,OAAO,SAAS,IAAI,KAAY;;IAC5B,qBACI;kBACI,cAAA,MAAC,mBAAK,OAAO,kBAAI,MAAC,iBAAE,gCAAQ,MAAC;sBAAM;;;AAG/C;AAEA,OAAO,SAAS,IAAI,KAAY;;IAC5B,qBACI,MAAC;QAAK,KAAK,KAAK,kBAAI,MAAC;sBAAe,MAAC;;AAE7C;AAEA,OAAO,SAAS,IAAI,KAAY;;IAC5B,IAAI,KAAK,KAAK,EACV,qBACI,MAAC;IAGT,qBACI,MAAC;AAET;AAEA,OAAO,SAAS,IAAI,KAAY;;IAC5B,IAAI,KAAK,KAAK,EACV,qBACI,MAAC;IAGT,qBACI,MAAC;AAET;AAEA,OAAO,MAAM,QAAQ,CAAC,+CAAiB,MAAC,mBAAK,OAAO,kBAAI,MAAC,iBAAE,gCAAQ,MAAC;kBAAM;iCAAiB;0CAErD,CAAC;;IACnC,qBACI;kBACI,cAAA,MAAC,mBAAK,OAAO,kBAAI,MAAC,iBAAE,iCAAQ,MAAC;sBAAM;;;AAG/C;AANA,OAAO,MAAM,4BAAc,+GAMxB;0CACmC,CAAC;;IACnC,qBACI,MAAC;QAAK,KAAK,KAAK,kBAAI,MAAC;sBAAe,MAAC;;AAE7C;AAJA,OAAO,MAAM,4BAAc,+GAIxB;0CAEmC,CAAC;;IACnC,IAAI,KAAK,KAAK,EACV,qBACI,MAAC;IAGT,qBACI,MAAC;AAET;AATA,OAAO,MAAM,4BAAc,+GASxB;0CAEmC,CAAC;;IACnC,IAAI,KAAK,KAAK,EACV,qBACI,MAAC;IAGT,qBACI,MAAC;AAET;AATA,OAAO,MAAM,4BAAc,+GASxB;wCAEiC,CAAC;;IACjC,qBACI;;0BACI,MAAC;gBAAI;gBAAQ,IAAI,IAAI;;0BACrB,MAAC,mBAAK,OAAO,kBAAI,MAAC,iBAAE,iCAAQ,MAAC,iBAAE;0BAE/B,MAAC,mBAAK,KAAK,KAAK,kBAAI,MAAC;0BACrB,MAAC,mBAAK,KAAK,KAAK,kBAAI,MAAC;0BAAS,cAAA,MAAC;;0BAC/B,MAAC,mBAAK,KAAK,KAAK,kBAAI;0BAAE,cAAA,MAAC;;0BACvB,MAAC,mBAAK,KAAK,KAAK,kBAAI,MAAC;0BACrB,MAAC;gBAAI;gBAAQ,IAAI,IAAI;;0BACrB,MAAC,mBAAI;0BACL,MAAC;gBAAI;gCAAQ,GAAM,KAAK;;;;0BACxB,MAAC;gBAAI;gBAAQ;;0BACb,MAAC;gBAAI;gBAAQ;;;;AAGzB;AAjBA,OAAO,MAAM,0BAAY,2GAiBtB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;AACA,SAA+B,IAAI,EAAE,QAAQ,QAAQ,iBAAiB;AACtE,OAAO,WAAW,kBAAkB;AAEpC,OAAO,SAAS,IAAI,KAAY;IAC/B,qBACC,gDACC,WAAC,mBAAK,OAAO,kBAAI,WAAC,iBAAE,gCAAQ,WAAC,mBAAM;AAGtC;AAEA,OAAO,SAAS,IAAI,KAAY;IAC/B,qBACC,WAAC;QAAK,KAAK,KAAK,kBAAI,WAAC;sBAAe,WAAC;;AAEvC;AAEA,OAAO,SAAS,IAAI,KAAY;IAC/B,IAAI,KAAK,KAAK,EACb,qBACC,WAAC;IAGH,qBACC,WAAC;AAEH;AAEA,OAAO,SAAS,IAAI,KAAY;IAC/B,IAAI,KAAK,KAAK,EACb,qBACC,WAAC;IAGH,qBACC,WAAC;AAEH;AAEA,OAAO,MAAM,QAAQ,QAAA,CAAC,sBAAiB,WAAC,mBAAK,OAAO,kBAAI,WAAC,iBAAE,gCAAQ,WAAC,mBAAM,mDAAiB;0CAErD,CAAC;IACtC,qBACC,gDACC,WAAC,mBAAK,OAAO,kBAAI,WAAC,iBAAE,iCAAQ,WAAC,mBAAM;AAGtC;AANA,OAAO,MAAM,4BAAc,QAAA,oIAMxB;0CACmC,CAAC;IACtC,qBACC,WAAC;QAAK,KAAK,KAAK,kBAAI,WAAC;sBAAe,WAAC;;AAEvC;AAJA,OAAO,MAAM,4BAAc,QAAA,oIAIxB;0CAEmC,CAAC;IACtC,IAAI,KAAK,KAAK,EACb,qBACC,WAAC;IAGH,qBACC,WAAC;AAEH;AATA,OAAO,MAAM,4BAAc,QAAA,oIASxB;0CAEmC,CAAC;IACtC,IAAI,KAAK,KAAK,EACb,qBACC,WAAC;IAGH,qBACC,WAAC;AAEH;AATA,OAAO,MAAM,4BAAc,QAAA,oIASxB;wCAEiC,CAAC;IACpC,qBACC;sBACC,WAAC;YAAI;YAAQ,IAAI,IAAI;;sBACrB,WAAC,mBAAK,OAAO,kBAAI,WAAC,iBAAE,iCAAQ,WAAC,iBAAE;sBAE/B,WAAC,mBAAK,KAAK,KAAK,kBAAI,WAAC;sBACrB,WAAC,mBAAK,KAAK,KAAK,kBAAI,WAAC,oCAAS,WAAC;sBAC/B,WAAC,mBAAK,KAAK,KAAK,kBAAI,gDAAE,WAAC;sBACvB,WAAC,mBAAK,KAAK,KAAK,kBAAI,WAAC;sBACrB,WAAC;YAAI;YAAQ,IAAI,IAAI;;sBACrB,WAAC,mBAAI;sBACL,WAAC;YAAI;sBAAQ;;sBACb,WAAC;YAAI;YAAQ;;sBACb,WAAC;YAAI;YAAQ;;;AAGhB;AAjBA,OAAO,MAAM,0BAAY,QAAA,gIAiBtB\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_noop_dev_mode.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_noop_dev_mode.snap index 4fb82612240..b4c42829400 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_noop_dev_mode.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_noop_dev_mode.snap @@ -1,103 +1,103 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 3510 +assertion_line: 3814 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore, serverStuff$, $ } from '@builder.io/qwik'; +import { component$, useStore, serverStuff$, $ } from '@qwik.dev/core'; export const App = component$(() => { - const stuff = useStore(); - serverStuff$(async () => { - // should be removed but keep scope - console.log(stuff.count) - }) - serverStuff$(async () => { - // should be removed - }) + const stuff = useStore(); + serverStuff$(async () => { + // should be removed but keep scope + console.log(stuff.count) + }) + serverStuff$(async () => { + // should be removed + }) - return ( - -

        stuff.count} - onClick$={() => console.log('warn')} - > - Hello Qwik -

        -
        - ); + return ( + +

        stuff.count} + onClick$={() => console.log('warn')} + > + Hello Qwik +

        +
        + ); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrlDEV } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrlDEV(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0", { +import { componentQrl } from "@qwik.dev/core"; +import { qrlDEV } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrlDEV(()=>import("./test.tsx_App_component_ckEPmXZlub0"), "App_component_ckEPmXZlub0", { file: "/hello/from/dev/test.tsx", - lo: 107, - hi: 569, + lo: 105, + hi: 452, displayName: "test.tsx_App_component" -})); +})), "test.tsx", 5, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM;;;;;IAoBhB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,oBAAM,QAAA;;;;;wBAoBhB\"}") ============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== -import { _jsxC } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { _noopQrlDEV } from "@builder.io/qwik"; -import { serverStuffQrl } from "@builder.io/qwik"; -import { useStore } from "@builder.io/qwik"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _noopQrlDEV } from "@qwik.dev/core"; +import { serverStuffQrl } from "@qwik.dev/core"; +import { useStore } from "@qwik.dev/core"; export const App_component_ckEPmXZlub0 = ()=>{ - const stuff = useStore(); - serverStuffQrl(/*#__PURE__*/ _noopQrlDEV("App_component_serverStuff_ebyHaP15ytQ", { + const stuff = _addLoc(useStore(), "test.tsx", 6, 16); + serverStuffQrl(/*#__PURE__*/ _noopQrlDEV("App_serverStuff_K7K22eBny0w", { file: "/hello/from/dev/test.tsx", lo: 0, hi: 0, - displayName: "test.tsx_App_component_serverStuff" + displayName: "test.tsx_App_serverStuff" }, [ stuff ])); - serverStuffQrl(/*#__PURE__*/ _noopQrlDEV("App_component_serverStuff_1_PQCqO0ANabY", { + serverStuffQrl(/*#__PURE__*/ _noopQrlDEV("App_serverStuff_1_QuvWp0Ur0XM", { file: "/hello/from/dev/test.tsx", lo: 0, hi: 0, - displayName: "test.tsx_App_component_serverStuff_1" + displayName: "test.tsx_App_serverStuff_1" })); - return /*#__PURE__*/ _jsxC(Cmp, { - children: /*#__PURE__*/ _jsxQ("p", null, { - class: "stuff", - shouldRemove$: /*#__PURE__*/ _noopQrlDEV("App_component_Cmp_p_shouldRemove_uU0MG0jvQD4", { - file: "/hello/from/dev/test.tsx", - lo: 0, - hi: 0, - displayName: "test.tsx_App_component_Cmp_p_shouldRemove" - }, [ - stuff - ]), - onClick$: /*#__PURE__*/ _noopQrlDEV("App_component_Cmp_p_onClick_vuXzfUTkpto", { - file: "/hello/from/dev/test.tsx", - lo: 0, - hi: 0, - displayName: "test.tsx_App_component_Cmp_p_onClick" - }) - }, "Hello Qwik", 3, null, { - fileName: "/hello/from/dev/test.tsx", - lineNumber: 16, - columnNumber: 13 + return /*#__PURE__*/ _jsxSorted(Cmp, null, null, /*#__PURE__*/ _jsxSorted("p", { + shouldRemove$: /*#__PURE__*/ _noopQrlDEV("App_Cmp_p_shouldRemove_WSgJcFdaGSM", { + file: "/hello/from/dev/test.tsx", + lo: 0, + hi: 0, + displayName: "test.tsx_App_Cmp_p_shouldRemove" + }, [ + stuff + ]) + }, { + class: "stuff", + onClick$: /*#__PURE__*/ _noopQrlDEV("App_Cmp_p_onClick_Hst6NasRaBo", { + file: "/hello/from/dev/test.tsx", + lo: 0, + hi: 0, + displayName: "test.tsx_App_Cmp_p_onClick" }) - }, 3, "u6_0", { + }, "Hello Qwik", 2, null, { + fileName: "/hello/from/dev/test.tsx", + lineNumber: 16, + columnNumber: 4 + }), 1, "u6_0", { fileName: "/hello/from/dev/test.tsx", lineNumber: 15, - columnNumber: 9 + columnNumber: 3 }); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;yCAG8B;IAC1B,MAAM,QAAQ;IACd;;;;;;;;IAIA;;;;;;IAIA,qBACI,MAAC;kBACG,cAAA,MAAC;YAAE,OAAM;YACL,aAAa;;;;;;;;YACb,QAAQ;;;;;;WACX;;;;;;;;;;AAKb\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;yCAG8B;IAC7B,MAAM,QAAQ,QAAA;IACd;;;;;;;;IAIA;;;;;;IAIA,qBACC,WAAC,+BACA,WAAC;QACA,aAAa;;;;;;;;;QADX,OAAM;QAER,QAAQ;;;;;;OACR;;;;;;;;;AAKJ\"}") /* { "origin": "test.tsx", @@ -113,8 +113,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 107, - 569 + 105, + 452 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_of_synchronous_qrl.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_of_synchronous_qrl.snap index 74db25cb25b..a3b716912a1 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_of_synchronous_qrl.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_of_synchronous_qrl.snap @@ -1,66 +1,63 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 3482 +assertion_line: 3593 expression: output snapshot_kind: text --- ==INPUT== - import { sync$, component$ } from "@builder.io/qwik"; + import { sync$, component$ } from "@qwik.dev/core"; - export default component$(() => { - return ( - <> - - { - event.preventDefault(); - })}/> - event.preventDefault())}/> - - ); - }); - + export default component$(() => { + return ( + <> + + { + event.preventDefault(); + })}/> + event.preventDefault())}/> + + ); + }); + ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; export default /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_test_component_LUXeXe0DQrg"), "test_component_LUXeXe0DQrg")); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGQ,6BAAe,mHAaZ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGE,6BAAe,mHAaZ\"}") ============================= test.tsx_test_component_LUXeXe0DQrg.js (ENTRY POINT)== -import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime"; -import { _jsxC } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { _qrlSync } from "@builder.io/qwik"; +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _qrlSync } from "@qwik.dev/core"; export const test_component_LUXeXe0DQrg = ()=>{ - return /*#__PURE__*/ _jsxC(_Fragment, { - children: [ - /*#__PURE__*/ _jsxQ("input", { - onClick$: _qrlSync(function(event, target) { - // comment should be removed - event.preventDefault(); - }, "function(event,target){event.preventDefault();}") - }, null, null, 2, null), - /*#__PURE__*/ _jsxQ("input", { - onClick$: _qrlSync((event, target)=>{ - event.preventDefault(); - }, "(event,target)=>{event.preventDefault();}") - }, null, null, 2, null), - /*#__PURE__*/ _jsxQ("input", { - onClick$: _qrlSync((event, target)=>event.preventDefault(), "(event,target)=>event.preventDefault()") - }, null, null, 2, null) - ] - }, 1, "u6_0"); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, [ + /*#__PURE__*/ _jsxSorted("input", { + onClick$: _qrlSync(function(event, target) { + // comment should be removed + event.preventDefault(); + }, "function(event,target){event.preventDefault();}") + }, null, null, 2, null), + /*#__PURE__*/ _jsxSorted("input", { + onClick$: _qrlSync((event, target)=>{ + event.preventDefault(); + }, "(event,target)=>{event.preventDefault();}") + }, null, null, 2, null), + /*#__PURE__*/ _jsxSorted("input", { + onClick$: _qrlSync((event, target)=>event.preventDefault(), "(event,target)=>event.preventDefault()") + }, null, null, 2, null) + ], 1, "u6_0"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;0CAGkC;IAC1B,qBACI;;0BACI,MAAC;gBAAM,QAAQ,WAAQ,SAAS,KAAK,EAAE,MAAM;oBACzC,4BAA4B;oBAC5B,MAAM,cAAc;gBACxB;;0BACA,MAAC;gBAAM,QAAQ,WAAQ,CAAC,OAAO;oBAC3B,MAAM,cAAc;gBACxB;;0BACA,MAAC;gBAAM,QAAQ,WAAQ,CAAC,OAAO,SAAW,MAAM,cAAc;;;;AAGtE\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;0CAG4B;IAC1B,qBACC;sBACC,WAAC;YAAM,QAAQ,WAAQ,SAAS,KAAK,EAAE,MAAM;gBAC5C,4BAA4B;gBAC5B,MAAM,cAAc;YACrB;;sBACA,WAAC;YAAM,QAAQ,WAAQ,CAAC,OAAO;gBAC9B,MAAM,cAAc;YACrB;;sBACA,WAAC;YAAM,QAAQ,WAAQ,CAAC,OAAO,SAAW,MAAM,cAAc;;;AAGhE\"}") /* { "origin": "test.tsx", @@ -76,8 +73,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 99, - 566 + 85, + 411 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3542.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3542.snap index 7850fef0b10..0dd1adbcc1a 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3542.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3542.snap @@ -1,34 +1,35 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 658 +assertion_line: 768 expression: output snapshot_kind: text --- ==INPUT== -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const AtomStatus = component$(({ctx,atom})=>{ - let status = atom.status; - if(!atom.real) { - status="WILL-VANISH" - } else if (JSON.stringify(atom.atom)==JSON.stringify(atom.real)) { - status="WTFED" - } - return ( - atomStatusClick(ctx,ev,[atom])} class={["atom",status,ctx.store[atom.ID]?"selected":null]}> - - ); + let status = atom.status; + if(!atom.real) { + status="WILL-VANISH" + } else if (JSON.stringify(atom.atom)==JSON.stringify(atom.real)) { + status="WTFED" + } + return ( + atomStatusClick(ctx,ev,[atom])} class={["atom",status,ctx.store[atom.ID]?"selected":null]}> + + ); }) ============================= test.jsx == -import { componentQrl } from "@builder.io/qwik"; -import { useLexicalScope } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -export const AtomStatus = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props)=>{ - let status = props.atom.status; +import { componentQrl } from "@qwik.dev/core"; +import { useLexicalScope } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const AtomStatus = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl((props)=>{ + let status = _addLoc(props.atom.status, "test.tsx", 6, 15); if (!props.atom.real) status = "WILL-VANISH"; else if (JSON.stringify(props.atom.atom) == JSON.stringify(props.atom.real)) status = "WTFED"; return { @@ -36,18 +37,18 @@ export const AtomStatus = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((p return atomStatusClick(props.ctx, ev, [ props.atom ]); - }, "AtomStatus_component_span_onClick_Owf5fKaOlF0", [ + }, "AtomStatus_span_onClick_wXVqmvw3zkE", [ props ])} class={[ "atom", status, props.ctx.store[props.atom.ID] ? "selected" : null ]}> - ; -}, "AtomStatus_component_hdwpoUtydSA")); + ; +}, "AtomStatus_component_hdwpoUtydSA")), "test.tsx", 5, 27); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,2BAAa,sCAAW;IACjC,IAAI,SAAS,MAD0B,KACrB,MAAM;IACxB,IAAG,CAAC,MAFmC,KAE9B,IAAI,EACT,SAAO;SACJ,IAAI,KAAK,SAAS,CAAC,MAJa,KAIR,IAAI,KAAG,KAAK,SAAS,CAAC,MAJd,KAImB,IAAI,GAC1D,SAAO;IAEX,QACK,KAAK,OAAO,MARsB,KAQjB,EAAE,EAAE,mCAAU,CAAC;;eAAK,sBARP,KAQ2B,IAAG;kBAR1B;SAQgC;;;QAAG,OAAO;QAAC;QAAO;QAAO,MAR7D,IAQiE,KAAK,CAAC,MARnE,KAQwE,EAAE,CAAC,GAAC,aAAW;KAAK,EAAE;QACjI,EAAE;AAEV,wCAAE\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;AAGA,OAAO,MAAM,2BAAa,QAAA,sCAAW;IACpC,IAAI,SAAS,QAAA,MAD6B,KACxB,MAAM;IACxB,IAAG,CAAC,MAFsC,KAEjC,IAAI,EACZ,SAAO;SACD,IAAI,KAAK,SAAS,CAAC,MAJgB,KAIX,IAAI,KAAG,KAAK,SAAS,CAAC,MAJX,KAIgB,IAAI,GAC7D,SAAO;IAER,QACE,KAAK,OAAO,MAR4B,KAQvB,EAAE,EAAE,mCAAU,CAAC;;eAAK,sBARD,KAQqB,IAAG;kBARpB;SAQ0B;;;QAAG,OAAO;QAAC;QAAO;QAAO,MARvD,IAQ2D,KAAK,CAAC,MAR7D,KAQkE,EAAE,CAAC,GAAC,aAAW;KAAK,EAAE;EACjI,EAAE;AAEJ,4DAAE\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3561.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3561.snap index 7d26f8bb7e4..27dcbb46bc5 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3561.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3561.snap @@ -1,39 +1,40 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 596 +assertion_line: 706 expression: output snapshot_kind: text --- ==INPUT== -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const Issue3561 = component$(() => { - const props = useStore({ - product: { - currentVariant: { - variantImage: 'image', - variantNumber: 'number', - setContents: 'contents', - }, - }, - }); - const { - currentVariant: { variantImage, variantNumber, setContents } = {}, - } = props.product; - - console.log(variantImage, variantNumber, setContents) - - return

        ; - }); + const props = useStore({ + product: { + currentVariant: { + variantImage: 'image', + variantNumber: 'number', + setContents: 'contents', + }, + }, + }); + const { + currentVariant: { variantImage, variantNumber, setContents } = {}, + } = props.product; + + console.log(variantImage, variantNumber, setContents) + + return

        ; + }); ============================= test.jsx == -import { componentQrl } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -export const Issue3561 = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(()=>{ - const props = useStore({ +import { componentQrl } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Issue3561 = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(()=>{ + const props = _addLoc(useStore({ product: { currentVariant: { variantImage: 'image', @@ -41,14 +42,14 @@ export const Issue3561 = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(()= setContents: 'contents' } } - }); + }), "test.tsx", 6, 16); const { currentVariant: { variantImage, variantNumber, setContents } = {} } = props.product; console.log(variantImage, variantNumber, setContents); return

        ; -}, "Issue3561_component_hHTw654BZB8")); +}, "Issue3561_component_hHTw654BZB8")), "test.tsx", 5, 26); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,0BAAY,sCAAW;IAChC,MAAM,QAAQ,SAAS;QACrB,SAAS;YACP,gBAAgB;gBACd,cAAc;gBACd,eAAe;gBACf,aAAa;YACf;QACF;IACF;IACA,MAAM,EACJ,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC,EAClE,GAAG,MAAM,OAAO;IAEjB,QAAQ,GAAG,CAAC,cAAc,eAAe;IAEzC,QAAQ,IAAI;AACd,uCAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,0BAAY,QAAA,sCAAW;IACnC,MAAM,QAAQ,QAAA,SAAS;QACtB,SAAS;YACT,gBAAgB;gBACf,cAAc;gBACd,eAAe;gBACf,aAAa;YACd;QACA;IACD;IACA,MAAM,EACL,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC,EACjE,GAAG,MAAM,OAAO;IAEjB,QAAQ,GAAG,CAAC,cAAc,eAAe;IAEzC,QAAQ,IAAI;AACZ,2DAAG\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3795.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3795.snap index 5e1687cc6bc..ac47cd29c51 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3795.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_3795.snap @@ -1,45 +1,46 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 686 +assertion_line: 796 expression: output snapshot_kind: text --- ==INPUT== -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const Issue3795 = component$(() => { - let base = "foo"; - const firstAssignment = base; - base += "bar"; - const secondAssignment = base; - return ( -
        {firstAssignment} {secondAssignment}
        - ) - }); + let base = "foo"; + const firstAssignment = base; + base += "bar"; + const secondAssignment = base; + return ( +
        {firstAssignment} {secondAssignment}
        + ) + }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -export const Issue3795 = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(()=>{ - let base = "foo"; - const firstAssignment = base; +import { componentQrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Issue3795 = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(()=>{ + let base = _addLoc("foo", "test.tsx", 6, 13); + const firstAssignment = _addLoc(base, "test.tsx", 7, 26); base += "bar"; - const secondAssignment = base; - return /*#__PURE__*/ _jsxQ("div", null, { + const secondAssignment = _addLoc(base, "test.tsx", 9, 27); + return /*#__PURE__*/ _jsxSorted("div", null, { id: "issue-3795-result" }, [ firstAssignment, " ", secondAssignment ], 1, "u6_0"); -}, "Issue3795_component_wsE8beycatI")); +}, "Issue3795_component_wsE8beycatI")), "test.tsx", 5, 26); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,0BAAY,sCAAW;IAChC,IAAI,OAAO;IACX,MAAM,kBAAkB;IACxB,QAAQ;IACR,MAAM,mBAAmB;IACzB,qBACE,MAAC;QAAI,IAAG;;QAAqB;QAAgB;QAAE;;AAEnD,uCAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;AAGA,OAAO,MAAM,0BAAY,QAAA,sCAAW;IACnC,IAAI,OAAO,QAAA;IACX,MAAM,kBAAkB,QAAA;IACxB,QAAQ;IACR,MAAM,mBAAmB,QAAA;IACzB,qBACC,WAAC;QAAI,IAAG;;QAAqB;QAAgB;QAAE;;AAEhD,2DAAG\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_4386.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_4386.snap index b773a38c1ac..696def1efc0 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_4386.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_optimization_issue_4386.snap @@ -1,42 +1,45 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 630 +assertion_line: 740 expression: output snapshot_kind: text --- ==INPUT== -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const FOO_MAPPING = { - A: 1, - B: 2, - C: 3, - }; + A: 1, + B: 2, + C: 3, + }; - export default component$(() => { - const key = 'A'; - const value = FOO_MAPPING[key]; + export default component$(() => { + const key = 'A'; + const value = FOO_MAPPING[key]; - return <>{value}; - }); + return <>{value}; + }); ============================= test.jsx == -import { componentQrl } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -export const FOO_MAPPING = { +import { componentQrl } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const FOO_MAPPING = _addLoc({ A: 1, B: 2, C: 3 -}; +}, "test.tsx", 5, 28); export default /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(()=>{ - return <>{FOO_MAPPING['A']}; + const key = _addLoc('A', "test.tsx", 12, 14); + const value = _addLoc(FOO_MAPPING[key], "test.tsx", 13, 16); + return <>{value}; }, "test_component_LUXeXe0DQrg")); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,cAAc;IACvB,GAAG;IACH,GAAG;IACH,GAAG;AACL,EAAE;AAEF,6BAAe,sCAAW;IAIxB,UAFc,WAAW,CADb,IACkB;AAGhC,kCAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,cAAc,QAAA;IAC1B,GAAG;IACH,GAAG;IACH,GAAG;AACH,sBAAE;AAEF,6BAAe,sCAAW;IAC1B,MAAM,MAAM,QAAA;IACZ,MAAM,QAAQ,QAAA,WAAW,CAAC,IAAI;IAE9B,UAAU;AACV,kCAAG\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_parsed_inlined_qrls.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_parsed_inlined_qrls.snap index a1d023d740e..46b5eada031 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_parsed_inlined_qrls.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_parsed_inlined_qrls.snap @@ -1,42 +1,42 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1504 +assertion_line: 1614 expression: output snapshot_kind: text --- ==INPUT== -import { componentQrl, inlinedQrl, useStore, jsxs, jsx, useLexicalScope } from '@builder.io/qwik'; +import { componentQrl, inlinedQrl, useStore, jsxs, jsx, useLexicalScope } from '@qwik.dev/core'; export const App = /*#__PURE__*/ componentQrl(inlinedQrl(()=>{ - useStyles$(inlinedQrl(STYLES, "STYLES_odz7dfdfdM")); - useStyles$(inlinedQrl(STYLES, "STYLES_odzdfdfdM")); + useStyles$(inlinedQrl(STYLES, "STYLES_odz7dfdfdM")); + useStyles$(inlinedQrl(STYLES, "STYLES_odzdfdfdM")); - const store = useStore({ - count: 0 - }); - return /*#__PURE__*/ jsxs("div", { - children: [ - /*#__PURE__*/ jsxs("p", { - children: [ - "Count: ", - store.count - ] - }), - /*#__PURE__*/ jsx("p", { - children: /*#__PURE__*/ jsx("button", { - onClick$: inlinedQrl(()=>{ - const [store] = useLexicalScope(); - return store.count++; - }, "App_component_div_p_button_onClick_odz7eidI4GM", [ - store - ]), - children: "Click" - }) - }) - ] - }); + const store = useStore({ + count: 0 + }); + return /*#__PURE__*/ jsxs("div", { + children: [ + /*#__PURE__*/ jsxs("p", { + children: [ + "Count: ", + store.count + ] + }), + /*#__PURE__*/ jsx("p", { + children: /*#__PURE__*/ jsx("button", { + onClick$: inlinedQrl(()=>{ + const [store] = useLexicalScope(); + return store.count++; + }, "App_component_div_p_button_onClick_odz7eidI4GM", [ + store + ]), + children: "Click" + }) + }) + ] + }); }, "App_component_Fh88JClhbC0")); export const STYLES = ".red { color: red; }"; @@ -44,23 +44,22 @@ export const STYLES = ".red { color: red; }"; ============================= test.tsx == -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { componentQrl, inlinedQrl, useStore, useLexicalScope } from '@builder.io/qwik'; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(()=>{ +import { _wrapProp } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { componentQrl, inlinedQrl, useStore, useLexicalScope } from '@qwik.dev/core'; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(()=>{ useStyles$(/*#__PURE__*/ inlinedQrl(STYLES, "s_odz7dfdfdM")); useStyles$(/*#__PURE__*/ inlinedQrl(STYLES, "s_odzdfdfdM")); - const store = useStore({ + const store = _addLoc(useStore({ count: 0 - }); - return /*#__PURE__*/ _jsxQ("div", null, null, [ - /*#__PURE__*/ _jsxQ("p", null, null, [ + }), "test.tsx", 9, 16); + return /*#__PURE__*/ _jsxSorted("div", null, null, [ + /*#__PURE__*/ _jsxSorted("p", null, null, [ "Count: ", - _fnSignal((p0)=>p0.count, [ - store - ], "p0.count") - ], 3, null), - /*#__PURE__*/ _jsxQ("p", null, null, /*#__PURE__*/ _jsxQ("button", { + _wrapProp(store, "count") + ], 1, null), + /*#__PURE__*/ _jsxSorted("p", null, null, /*#__PURE__*/ _jsxSorted("button", { onClick$: /*#__PURE__*/ inlinedQrl(()=>{ const [store] = useLexicalScope(); return store.count++; @@ -69,11 +68,11 @@ export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(()=>{ ]) }, null, "Click", 2, null), 1, null) ], 1, "u6_0"); -}, "s_Fh88JClhbC0")); -export const STYLES = ".red { color: red; }"; +}, "s_Fh88JClhbC0")), "test.tsx", 5, 34); +export const STYLES = _addLoc(".red { color: red; }", "test.tsx", 35, 23); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AACA,SAAS,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAa,eAAe,QAAQ,mBAAmB;AAElG,OAAO,MAAM,MAAM,WAAW,GAAG,sCAAwB;IACrD,oCAAsB;IACtB,oCAAsB;IAEtB,MAAM,QAAQ,SAAS;QACnB,OAAO;IACX;IACA,OAAO,WAAW,GAAG,MAAK,mBACZ;QACN,WAAW,GAAG,MAAK,iBACL;YACN;4BACA,GAAM,KAAK;;;SACd;QAEL,WAAW,GAAG,MAAI,iBACJ,WAAW,GAAG,MAAI;YACxB,QAAQ,2BAAa;gBACjB,MAAM,CAAC,MAAM,GAAG;gBAChB,OAAO,MAAM,KAAK;YACtB;;;iBAGU;KAGrB;AAET,qBAAiC;AAEjC,OAAO,MAAM,SAAS,uBAAuB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AACA,SAAS,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAa,eAAe,QAAQ,iBAAiB;AAEhG,OAAO,MAAM,MAAM,WAAW,GAAG,QAAA,sCAAwB;IACxD,oCAAsB;IACtB,oCAAsB;IAEtB,MAAM,QAAQ,QAAA,SAAS;QACtB,OAAO;IACR;IACA,OAAO,WAAW,GAAG,WAAK,mBACf;QACT,WAAW,GAAG,WAAK,iBACR;YACT;sBACA;SACA;QAEF,WAAW,GAAG,WAAI,iBACP,WAAW,GAAG,WAAI;YAC3B,QAAQ,2BAAa;gBACpB,MAAM,CAAC,MAAM,GAAG;gBAChB,OAAO,MAAM,KAAK;YACnB;;;iBAGU;KAGZ;AAEH,yCAAiC;AAEjC,OAAO,MAAM,SAAS,QAAA,4CAAuB\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_preserve_filenames.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_preserve_filenames.snap index 7c4248feb9e..1da940588aa 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_preserve_filenames.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_preserve_filenames.snap @@ -1,39 +1,37 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2569 +assertion_line: 2680 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore } from '@builder.io/qwik'; +import { component$, useStore } from '@qwik.dev/core'; export const App = component$((props) => { - return ( - -

        console.log('warn')}>Hello Qwik

        -
        - ); + return ( + +

        console.log('warn')}>Hello Qwik

        +
        + ); }); ============================= test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props)=>{ - return /*#__PURE__*/ _jsxC(Cmp, { - children: /*#__PURE__*/ _jsxQ("p", null, { - class: "stuff", - onClick$: /*#__PURE__*/ inlinedQrl(()=>console.log('warn'), "App_component_Cmp_p_onClick_vuXzfUTkpto") - }, "Hello Qwik", 3, null) - }, 3, "u6_0"); -}, "App_component_ckEPmXZlub0")); - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;AAGA,OAAO,MAAM,oBAAM,sCAAW,CAAC;IAC3B,qBACI,MAAC;kBACG,cAAA,MAAC;YAAE,OAAM;YAAQ,QAAQ,2BAAE,IAAM,QAAQ,GAAG,CAAC;WAAS;;AAGlE,iCAAG\"}") +import { componentQrl } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl((props)=>{ + return /*#__PURE__*/ _jsxSorted(Cmp, null, null, /*#__PURE__*/ _jsxSorted("p", null, { + class: "stuff", + onClick$: /*#__PURE__*/ inlinedQrl(()=>console.log('warn'), "App_component_Cmp_p_onClick_vuXzfUTkpto") + }, "Hello Qwik", 3, null), 3, "u6_0"); +}, "App_component_ckEPmXZlub0")), "test.tsx", 5, 20); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;AAGA,OAAO,MAAM,oBAAM,QAAA,sCAAW,CAAC;IAC9B,qBACC,WAAC,+BACA,WAAC;QAAE,OAAM;QAAQ,QAAQ,2BAAE,IAAM,QAAQ,GAAG,CAAC;OAAS;AAGzD,qDAAG\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_preserve_filenames_segments.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_preserve_filenames_segments.snap index 8d44c15f43d..4bdefcd174a 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_preserve_filenames_segments.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_preserve_filenames_segments.snap @@ -1,52 +1,50 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2593 +assertion_line: 2704 expression: output snapshot_kind: text --- ==INPUT== -import { component$, useStore } from '@builder.io/qwik'; +import { component$, useStore } from '@qwik.dev/core'; export const App = component$((props: Stuff) => { - foo(); - return ( - -

        console.log('warn')}>Hello Qwik

        -
        - ); + foo(); + return ( + +

        console.log('warn')}>Hello Qwik

        +
        + ); }); export const foo = () => console.log('foo'); ============================= test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0.js"), "App_component_ckEPmXZlub0")); -export const foo = ()=>console.log('foo'); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_ckEPmXZlub0.js"), "App_component_ckEPmXZlub0")), "test.tsx", 5, 20); +export const foo = _addLoc(()=>console.log('foo'), "test.tsx", 14, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,oHAOhB;AAEH,OAAO,MAAM,MAAM,IAAM,QAAQ,GAAG,CAAC,OAAO\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,oBAAM,QAAA,wIAOhB;AAEH,OAAO,MAAM,MAAM,QAAA,IAAM,QAAQ,GAAG,CAAC,4BAAO\"}") ============================= test.tsx_App_component_ckEPmXZlub0.js (ENTRY POINT)== -import { _jsxC } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; +import { _jsxSorted } from "@qwik.dev/core"; import { foo } from "./test.tsx"; -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const App_component_ckEPmXZlub0 = (props)=>{ foo(); - return /*#__PURE__*/ _jsxC(Cmp, { - children: /*#__PURE__*/ _jsxQ("p", null, { - class: "stuff", - onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_Cmp_p_onClick_vuXzfUTkpto.js"), "App_component_Cmp_p_onClick_vuXzfUTkpto") - }, "Hello Qwik", 3, null) - }, 3, "u6_0"); + return /*#__PURE__*/ _jsxSorted(Cmp, null, null, /*#__PURE__*/ _jsxSorted("p", null, { + class: "stuff", + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_App_component_Cmp_p_onClick_vuXzfUTkpto.js"), "App_component_Cmp_p_onClick_vuXzfUTkpto") + }, "Hello Qwik", 3, null), 3, "u6_0"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;yCAG8B,CAAC;IAC3B;IACA,qBACI,MAAC;kBACG,cAAA,MAAC;YAAE,OAAM;YAAQ,QAAQ;WAA6B;;AAGlE\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;yCAG8B,CAAC;IAC9B;IACA,qBACC,WAAC,+BACA,WAAC;QAAE,OAAM;QAAQ,QAAQ;OAA6B;AAGzD\"}") /* { "origin": "test.tsx", @@ -62,8 +60,11 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 90, - 252 + 88, + 220 + ], + "paramNames": [ + "props" ] } */ @@ -72,7 +73,7 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma export const App_component_Cmp_p_onClick_vuXzfUTkpto = ()=>console.log('warn'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"uDAOuC,IAAM,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"uDAO8B,IAAM,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", @@ -88,8 +89,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "onClick$", "captures": false, "loc": [ - 187, - 212 + 164, + 189 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_prod_node.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_prod_node.snap index 337d5aad434..35233d9c976 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_prod_node.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_prod_node.snap @@ -1,37 +1,37 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1347 +assertion_line: 1457 expression: output snapshot_kind: text --- ==INPUT== -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const Foo = component$(() => { - return ( -
        -
        console.log('first')}/> -
        console.log('second')}/> -
        console.log('third')}/> -
        - ); + return ( +
        +
        console.log('first')}/> +
        console.log('second')}/> +
        console.log('third')}/> +
        + ); }); ============================= test.tsx_Foo_component_HTDRsvUbLiE.tsx (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const s_HTDRsvUbLiE = ()=>{ return
        -
        import("./test.tsx_Foo_component_div_div_onClick_9DcJc0uJDDo"), "s_9DcJc0uJDDo")}/> -
        import("./test.tsx_Foo_component_div_div_onClick_1_RjQdy8I0MXc"), "s_RjQdy8I0MXc")}/> -
        import("./test.tsx_Foo_component_div_div_onClick_2_w9ptFRBVK1E"), "s_w9ptFRBVK1E")}/> -
        ; +
        import("./test.tsx_Foo_component_div_div_onClick_9DcJc0uJDDo"), "s_9DcJc0uJDDo")}/> +
        import("./test.tsx_Foo_component_div_div_onClick_1_RjQdy8I0MXc"), "s_RjQdy8I0MXc")}/> +
        import("./test.tsx_Foo_component_div_div_onClick_2_w9ptFRBVK1E"), "s_w9ptFRBVK1E")}/> +
        ; }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";6BAG8B;IAC1B,QACK,IAAI;YACD,CAAC,IAAI,mHAAuC;YAC5C,CAAC,IAAI,qHAAwC;YAC7C,CAAC,IAAI,qHAAuC;QAChD,EAAE;AAEV\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";6BAG8B;IAC7B,QACE,IAAI;GACJ,CAAC,IAAI,mHAAuC;GAC5C,CAAC,IAAI,qHAAwC;GAC7C,CAAC,IAAI,qHAAuC;EAC7C,EAAE;AAEJ\"}") /* { "origin": "test.tsx", @@ -47,8 +47,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 80, - 310 + 78, + 263 ] } */ @@ -57,7 +57,7 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma export const s_9DcJc0uJDDo = ()=>console.log('first'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"6BAM2B,IAAM,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"6BAMkB,IAAM,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", @@ -73,8 +73,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "onClick$", "captures": false, "loc": [ - 142, - 168 + 122, + 148 ] } */ @@ -83,7 +83,7 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma export const s_w9ptFRBVK1E = ()=>console.log('third'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"6BAQ2B,IAAM,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"6BAQkB,IAAM,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", @@ -99,8 +99,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "onClick$", "captures": false, "loc": [ - 257, - 283 + 219, + 245 ] } */ @@ -109,7 +109,7 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma export const s_RjQdy8I0MXc = ()=>console.log('second'); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"6BAO2B,IAAM,QAAQ,GAAG,CAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"6BAOkB,IAAM,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", @@ -125,19 +125,20 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "onClick$", "captures": false, "loc": [ - 199, - 226 + 170, + 197 ] } */ ============================= test.tsx == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const Foo = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_HTDRsvUbLiE"), "s_HTDRsvUbLiE")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Foo = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_HTDRsvUbLiE"), "s_HTDRsvUbLiE")), "test.tsx", 5, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,qGAQhB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,oBAAM,QAAA,yHAQhB\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_optimization.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_optimization.snap index e4462285112..2d541148c79 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_optimization.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_optimization.snap @@ -7,59 +7,60 @@ snapshot_kind: text ==INPUT== -import { $, component$, useTask$ } from '@builder.io/qwik'; +import { $, component$, useTask$ } from '@qwik.dev/core'; import { CONST } from 'const'; export const Works = component$(({ - count, - some = 1+2, - hello = CONST, - stuff: hey, - stuffDefault: hey2 = 123, - ...rest}) => { - console.log(hey, some); - useTask$(({track}) => { - track(() => count); - console.log(count, rest, hey, some, hey2); - }); - return ( -
        {count}
        - ); + count, + some = 1+2, + hello = CONST, + stuff: hey, + stuffDefault: hey2 = 123, + ...rest}) => { + console.log(hey, some); + useTask$(({track}) => { + track(() => count); + console.log(count, rest, hey, some, hey2); + }); + return ( +
        {count}
        + ); }); export const NoWorks2 = component$(({count, stuff: {hey}}) => { - console.log(hey); - useTask$(({track}) => { - track(() => count); - console.log(count); - }); - return ( -
        {count}
        - ); + console.log(hey); + useTask$(({track}) => { + track(() => count); + console.log(count); + }); + return ( +
        {count}
        + ); }); export const NoWorks3 = component$(({count, stuff = hola()}) => { - console.log(stuff); - useTask$(({track}) => { - track(() => count); - console.log(count); - }); - return ( -
        {count}
        - ); + console.log(stuff); + useTask$(({track}) => { + track(() => count); + console.log(count); + }); + return ( +
        {count}
        + ); }); ============================= test.js == -import { _restProps } from "@builder.io/qwik"; -import { componentQrl } from "@builder.io/qwik"; -import { useTaskQrl } from "@builder.io/qwik"; -import { useLexicalScope } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { _fnSignal } from "@builder.io/qwik"; -import { _IMMUTABLE } from "@builder.io/qwik"; -import { _jsxS } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -export const Works = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props)=>{ +import { _restProps } from "@qwik.dev/core"; +import { componentQrl } from "@qwik.dev/core"; +import { useTaskQrl } from "@qwik.dev/core"; +import { useLexicalScope } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _fnSignal } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { _jsxSplit } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Works = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl((props)=>{ const rest = _restProps(props, [ "count", "some", @@ -76,24 +77,7 @@ export const Works = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props) props, rest ])); - return /*#__PURE__*/ _jsxS("div", { - get some () { - return props.some ?? 3; - }, - get params () { - return { - some: props.some ?? 3 - }; - }, - get class () { - return props.count; - }, - ...rest, - override: true, - children: _fnSignal((p0)=>p0.count, [ - props - ], "p0.count") - }, { + return /*#__PURE__*/ _jsxSplit("div", { some: _fnSignal((p0)=>p0.some ?? 3, [ props ], "p0.some??1+2"), @@ -102,13 +86,13 @@ export const Works = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props) }), [ props ], "{some:p0.some??1+2}"), - class: _fnSignal((p0)=>p0.count, [ - props - ], "p0.count"), - override: _IMMUTABLE - }, 0, "u6_0"); -}, "Works_component_t45qL4vNGv0")); -export const NoWorks2 = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(({ count, stuff: { hey } })=>{ + class: _wrapProp(props, "count"), + ...rest + }, { + override: true + }, _wrapProp(props, "count"), 0, "u6_0"); +}, "Works_component_t45qL4vNGv0")), "test.tsx", 5, 22); +export const NoWorks2 = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(({ count, stuff: { hey } })=>{ console.log(hey); useTaskQrl(/*#__PURE__*/ inlinedQrl(({ track })=>{ const [count] = useLexicalScope(); @@ -117,11 +101,11 @@ export const NoWorks2 = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(({ c }, "NoWorks2_component_useTask_lXiqwbxxjq0", [ count ])); - return /*#__PURE__*/ _jsxQ("div", { + return /*#__PURE__*/ _jsxSorted("div", { class: count }, null, count, 1, "u6_1"); -}, "NoWorks2_component_JPD9t2HyEKg")); -export const NoWorks3 = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(({ count, stuff = hola() })=>{ +}, "NoWorks2_component_JPD9t2HyEKg")), "test.tsx", 22, 25); +export const NoWorks3 = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(({ count, stuff = hola() })=>{ console.log(stuff); useTaskQrl(/*#__PURE__*/ inlinedQrl(({ track })=>{ const [count] = useLexicalScope(); @@ -130,13 +114,13 @@ export const NoWorks3 = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(({ c }, "NoWorks3_component_useTask_3cQGU0s1VwU", [ count ])); - return /*#__PURE__*/ _jsxQ("div", { + return /*#__PURE__*/ _jsxSorted("div", { class: count }, null, count, 1, "u6_2"); -}, "NoWorks3_component_fc13h5yYn14")); +}, "NoWorks3_component_fc13h5yYn14")), "test.tsx", 33, 25); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;;;AAGA,OAAO,MAAM,sBAAQ,sCAAW;;;;;;;;IAO5B,QAAQ,GAAG,OAHX,aAFA,QAAO;IAMP,oCAAS,CAAC,EAAC,KAAK,EAAC;;QACb,MAAM,UARV;QASI,QAAQ,GAAG,OATf,OASuB,YANvB,aAFA,QAAO,SAGP,gBAAqB;;;;;IAOrB,qBACI,MAAC;YAAI;yBAXT,QAAO;;YAWc;mBAAQ;gBAAE,IAAI,QAXnC,QAAO;YAW6B;;YAAG;yBAZvC;;QAYsD,GAAG,IAAI;QAAE,QAAQ;qCAZvE;;;;QAYS,IAAI,qBAXb,QAAO;;;QAWc,MAAM,kBAAE,CAAA;gBAAE,IAAI,KAXnC,QAAO;YAW6B,CAAA;;;QAAG,KAAK,qBAZ5C;;;QAY+D,QAAQ;;AAE3E,mCAAG;AAEH,OAAO,MAAM,yBAAW,sCAAW,CAAC,EAAC,KAAK,EAAE,OAAO,EAAC,GAAG,EAAC,EAAC;IACrD,QAAQ,GAAG,CAAC;IACZ,oCAAS,CAAC,EAAC,KAAK,EAAC;;QACb,MAAM,IAAM;QACZ,QAAQ,GAAG,CAAC;;;;IAEhB,qBACI,MAAC;QAAI,OAAO;aAAQ;AAE5B,sCAAG;AAEH,OAAO,MAAM,yBAAW,sCAAW,CAAC,EAAC,KAAK,EAAE,QAAQ,MAAM,EAAC;IACvD,QAAQ,GAAG,CAAC;IACZ,oCAAS,CAAC,EAAC,KAAK,EAAC;;QACb,MAAM,IAAM;QACZ,QAAQ,GAAG,CAAC;;;;IAEhB,qBACI,MAAC;QAAI,OAAO;aAAQ;AAE5B,sCAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;;;;AAGA,OAAO,MAAM,sBAAQ,QAAA,sCAAW;;;;;;;;IAO/B,QAAQ,GAAG,OAHX,aAFA,QAAO;IAMP,oCAAS,CAAC,EAAC,KAAK,EAAC;;QAChB,MAAM,UARP;QASC,QAAQ,GAAG,OATZ,OASoB,YANpB,aAFA,QAAO,SAGP,gBAAqB;;;;;IAOrB,qBACC,UAAC;QAAI,IAAI,qBAXV,QAAO;;;QAWW,MAAM,kBAAE,CAAA;gBAAE,IAAI,KAXhC,QAAO;YAW0B,CAAA;;;QAAG,KAAK;QAAU,GAAG,IAAI;;QAAE,QAAQ;;AAErE,uDAAG;AAEH,OAAO,MAAM,yBAAW,QAAA,sCAAW,CAAC,EAAC,KAAK,EAAE,OAAO,EAAC,GAAG,EAAC,EAAC;IACxD,QAAQ,GAAG,CAAC;IACZ,oCAAS,CAAC,EAAC,KAAK,EAAC;;QAChB,MAAM,IAAM;QACZ,QAAQ,GAAG,CAAC;;;;IAEb,qBACC,WAAC;QAAI,OAAO;aAAQ;AAEtB,2DAAG;AAEH,OAAO,MAAM,yBAAW,QAAA,sCAAW,CAAC,EAAC,KAAK,EAAE,QAAQ,MAAM,EAAC;IAC1D,QAAQ,GAAG,CAAC;IACZ,oCAAS,CAAC,EAAC,KAAK,EAAC;;QAChB,MAAM,IAAM;QACZ,QAAQ,GAAG,CAAC;;;;IAEb,qBACC,WAAC;QAAI,OAAO;aAAQ;AAEtB,2DAAG\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_wrapping.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_wrapping.snap new file mode 100644 index 00000000000..b54fc461884 --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_wrapping.snap @@ -0,0 +1,62 @@ +--- +source: packages/qwik/src/optimizer/core/src/test.rs +assertion_line: 568 +expression: output +snapshot_kind: text +--- +==INPUT== + + +import { $, component$, useSignal } from '@qwik.dev/core'; +export const Works = component$(({fromProps}) => { + let fromLocal = useSignal(0); + return ( +
        +
        + ); +}); + +============================= test.js == + +import { componentQrl } from "@qwik.dev/core"; +import { _fnSignal } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { useSignal } from '@qwik.dev/core'; +export const Works = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl((props)=>{ + let fromLocal = _addLoc(useSignal(0), "test.tsx", 5, 18); + return /*#__PURE__*/ _jsxSorted("div", { + computed: _fnSignal((p0, p1)=>p0 + p1.fromProps, [ + fromLocal, + props + ], "p0+p1.fromProps"), + local: fromLocal, + props: _fnSignal((p0, p1)=>({ + props: p1.fromProps, + local: p0 + }), [ + fromLocal, + props + ], "{props:p1.fromProps,local:p0}"), + "props-only": _fnSignal((p0)=>({ + props: p0.fromProps + }), [ + props + ], "{props:p0.fromProps}"), + "props-wrap": _wrapProp(props, "fromProps") + }, null, null, 3, "u6_0"); +}, "Works_component_t45qL4vNGv0")), "test.tsx", 4, 22); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;AACA,SAAwB,SAAS,QAAQ,iBAAiB;AAC1D,OAAO,MAAM,sBAAQ,QAAA,sCAAW;IAC/B,IAAI,YAAY,QAAA,UAAU;IAC1B,qBACC,WAAC;QACA,QAAQ,sBAAE,QAJqB;;;;QAK/B,OAAO;QAGP,KAAK,sBAAE,CAAA;gBAAC,KAAK,KARkB;gBAQL,KAAK;YAAW,CAAA;;;;QAD1C,YAAU,kBAAE,CAAA;gBAAC,KAAK,KAPa;YAOF,CAAA;;;QAD7B,YAAU;;AAMb,uDAAG\"}") +== DIAGNOSTICS == + +[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_wrapping2.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_wrapping2.snap new file mode 100644 index 00000000000..1f298776381 --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_wrapping2.snap @@ -0,0 +1,62 @@ +--- +source: packages/qwik/src/optimizer/core/src/test.rs +assertion_line: 595 +expression: output +snapshot_kind: text +--- +==INPUT== + + +import { $, component$, useSignal } from '@qwik.dev/core'; +export const Works = component$((props: { fromProps: number }) => { + let fromLocal = useSignal(0); + return ( +
        +
        + ); +}); + +============================= test.js == + +import { componentQrl } from "@qwik.dev/core"; +import { _fnSignal } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { useSignal } from '@qwik.dev/core'; +export const Works = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl((props)=>{ + let fromLocal = _addLoc(useSignal(0), "test.tsx", 5, 18); + return /*#__PURE__*/ _jsxSorted("div", { + computed: _fnSignal((p0, p1)=>p0 + p1.fromProps, [ + fromLocal, + props + ], "p0+p1.fromProps"), + local: fromLocal, + props: _fnSignal((p0, p1)=>({ + props: p1.fromProps, + local: p0 + }), [ + fromLocal, + props + ], "{props:p1.fromProps,local:p0}"), + "props-only": _fnSignal((p0)=>({ + props: p0.fromProps + }), [ + props + ], "{props:p0.fromProps}"), + "props-wrap": _wrapProp(props, "fromProps") + }, null, null, 3, "u6_0"); +}, "Works_component_t45qL4vNGv0")), "test.tsx", 4, 22); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;AACA,SAAwB,SAAS,QAAQ,iBAAiB;AAC1D,OAAO,MAAM,sBAAQ,QAAA,sCAAW,CAAC;IAChC,IAAI,YAAY,QAAA,UAAU;IAC1B,qBACC,WAAC;QACA,QAAQ,sBAAE,KAAY,GAAM,SAAS;;;;QACrC,OAAO;QAGP,KAAK,sBAAE,CAAA;gBAAC,OAAO,GAAM,SAAS;gBAAE,KAAK;YAAW,CAAA;;;;QADhD,YAAU,kBAAE,CAAA;gBAAC,OAAO,GAAM,SAAS;YAAA,CAAA;;;QADnC,YAAU,YAAE;;AAMf,uDAAG\"}") +== DIAGNOSTICS == + +[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_wrapping_children.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_wrapping_children.snap new file mode 100644 index 00000000000..52e252c8905 --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_wrapping_children.snap @@ -0,0 +1,65 @@ +--- +source: packages/qwik/src/optimizer/core/src/test.rs +assertion_line: 622 +expression: output +snapshot_kind: text +--- +==INPUT== + + +import { $, component$, useSignal } from '@qwik.dev/core'; +export const Works = component$(({fromProps}) => { + let fromLocal = useSignal(0); + return ( +
        + {fromLocal} + {fromProps} + {fromLocal + fromProps} + {{props: fromProps}} + {{local: fromLocal}} + {{props: fromProps, local: fromLocal}} +
        + ); +}); + +============================= test.js == + +import { componentQrl } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { _fnSignal } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { useSignal } from '@qwik.dev/core'; +export const Works = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl((props)=>{ + let fromLocal = _addLoc(useSignal(0), "test.tsx", 5, 18); + return /*#__PURE__*/ _jsxSorted("div", null, null, [ + fromLocal, + _wrapProp(props, "fromProps"), + _fnSignal((p0, p1)=>p0 + p1.fromProps, [ + fromLocal, + props + ], "p0+p1.fromProps"), + _fnSignal((p0)=>({ + props: p0.fromProps + }), [ + props + ], "{props:p0.fromProps}"), + { + local: fromLocal + }, + _fnSignal((p0, p1)=>({ + props: p1.fromProps, + local: p0 + }), [ + fromLocal, + props + ], "{props:p1.fromProps,local:p0}") + ], 1, "u6_0"); +}, "Works_component_t45qL4vNGv0")), "test.tsx", 4, 22); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;AACA,SAAwB,SAAS,QAAQ,iBAAiB;AAC1D,OAAO,MAAM,sBAAQ,QAAA,sCAAW;IAC/B,IAAI,YAAY,QAAA,UAAU;IAC1B,qBACC,WAAC;QACC;;4BAEA,QAN8B;;;;wBAO9B,CAAA;gBAAC,KAAK,KAPwB;YAOb,CAAA;;;QACjB;YAAC,OAAO;QAAS;4BACjB,CAAA;gBAAC,KAAK,KATwB;gBASX,KAAK;YAAW,CAAA;;;;;AAGvC,uDAAG\"}") +== DIAGNOSTICS == + +[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_wrapping_children2.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_wrapping_children2.snap new file mode 100644 index 00000000000..6cba8d8b2e0 --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_props_wrapping_children2.snap @@ -0,0 +1,69 @@ +--- +source: packages/qwik/src/optimizer/core/src/test.rs +assertion_line: 649 +expression: output +snapshot_kind: text +--- +==INPUT== + + +import { $, component$, useSignal } from '@qwik.dev/core'; +export const Works = component$((props) => { + let fromLocal = useSignal(0); + return ( +
        + before- + {fromLocal} + {props.fromProps} + {fromLocal + props.fromProps} + {{props: props.fromProps}} + {{local: fromLocal}} + {{props: props.fromProps, local: fromLocal}} + -after +
        + ); +}); + +============================= test.js == + +import { componentQrl } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +import { _fnSignal } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { useSignal } from '@qwik.dev/core'; +export const Works = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl((props)=>{ + let fromLocal = _addLoc(useSignal(0), "test.tsx", 5, 18); + return /*#__PURE__*/ _jsxSorted("div", null, null, [ + "before-", + fromLocal, + _wrapProp(props, "fromProps"), + _fnSignal((p0, p1)=>p0 + p1.fromProps, [ + fromLocal, + props + ], "p0+p1.fromProps"), + _fnSignal((p0)=>({ + props: p0.fromProps + }), [ + props + ], "{props:p0.fromProps}"), + { + local: fromLocal + }, + _fnSignal((p0, p1)=>({ + props: p1.fromProps, + local: p0 + }), [ + fromLocal, + props + ], "{props:p1.fromProps,local:p0}"), + "-after" + ], 1, "u6_0"); +}, "Works_component_t45qL4vNGv0")), "test.tsx", 4, 22); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;AACA,SAAwB,SAAS,QAAQ,iBAAiB;AAC1D,OAAO,MAAM,sBAAQ,QAAA,sCAAW,CAAC;IAChC,IAAI,YAAY,QAAA,UAAU;IAC1B,qBACC,WAAC;QAAI;QAEH;kBACA;4BACA,KAAY,GAAM,SAAS;;;;wBAC3B,CAAA;gBAAC,OAAO,GAAM,SAAS;YAAA,CAAA;;;QACvB;YAAC,OAAO;QAAS;4BACjB,CAAA;gBAAC,OAAO,GAAM,SAAS;gBAAE,KAAK;YAAW,CAAA;;;;QAAE;;AAI/C,uDAAG\"}") +== DIAGNOSTICS == + +[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_conflict.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_conflict.snap index 7d6258b662e..bba3e135d45 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_conflict.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_conflict.snap @@ -1,14 +1,14 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1127 +assertion_line: 1237 expression: output snapshot_kind: text --- ==INPUT== -import { $, component$, useStyles } from '@builder.io/qwik'; -import { qrl } from '@builder.io/qwik/what'; +import { $, component$, useStyles } from '@qwik.dev/core'; +import { qrl } from '@qwik.dev/core/what'; export const hW = 12; export const handleWatch = 42; @@ -17,63 +17,68 @@ const componentQrl = () => console.log('not this', qrl()); componentQrl(); export const Foo = component$(() => { - useStyles$('thing'); - const qwik = hW + handleWatch; - console.log(qwik); - const qrl = 23; - return ( -
        console.log(qrl)}/> - ) + useStyles$('thing'); + const qwik = hW + handleWatch; + console.log(qwik); + const qrl = 23; + return ( +
        console.log(qrl)}/> + ) }, { - tagName: "my-foo", + tagName: "my-foo", }); export const Root = component$(() => { - useStyles($('thing')); - return $(() => { - return ( -
        - ) - }); + useStyles($('thing')); + return $(() => { + return ( +
        + ) + }); }, { - tagName: "my-foo", + tagName: "my-foo", }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -import { qrl as qrl1 } from '@builder.io/qwik/what'; -export const hW = 12; -export const handleWatch = 42; -const componentQrl1 = ()=>console.log('not this', qrl1()); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { qrl as qrl1 } from '@qwik.dev/core/what'; +export const hW = _addLoc(12, "test.tsx", 6, 19); +export const handleWatch = _addLoc(42, "test.tsx", 7, 28); +const componentQrl1 = _addLoc(()=>console.log('not this', qrl1()), "test.tsx", 9, 22); componentQrl1(); -export const Foo = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_HTDRsvUbLiE"), "Foo_component_HTDRsvUbLiE"), { +export const Foo = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_HTDRsvUbLiE"), "Foo_component_HTDRsvUbLiE"), { tagName: "my-foo" -}); -export const Root = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Root_component_royhjYaCbYE"), "Root_component_royhjYaCbYE"), { +}), "test.tsx", 12, 20); +export const Root = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_Root_component_royhjYaCbYE"), "Root_component_royhjYaCbYE"), { tagName: "my-foo" -}); +}), "test.tsx", 24, 21); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAEA,SAAS,OAAA,IAAG,QAAQ,wBAAwB;AAE5C,OAAO,MAAM,KAAK,GAAG;AACrB,OAAO,MAAM,cAAc,GAAG;AAE9B,MAAM,gBAAe,IAAM,QAAQ,GAAG,CAAC,YAAY;AAEnD;AACA,OAAO,MAAM,oBAAM,iHAQhB;IACC,SAAS;AACb,GAAG;AAEH,OAAO,MAAM,qBAAO,mHAOjB;IACC,SAAS;AACb,GAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAEA,SAAS,OAAA,IAAG,QAAQ,sBAAsB;AAE1C,OAAO,MAAM,KAAK,QAAA,uBAAG;AACrB,OAAO,MAAM,cAAc,QAAA,uBAAG;AAE9B,MAAM,gBAAe,QAAA,IAAM,QAAQ,GAAG,CAAC,YAAY;AAEnD;AACA,OAAO,MAAM,oBAAM,QAAA,iHAQhB;IACF,SAAS;AACV,wBAAG;AAEH,OAAO,MAAM,qBAAO,QAAA,mHAOjB;IACF,SAAS;AACV,wBAAG\"}") ============================= test.tsx_Foo_component_HTDRsvUbLiE.js (ENTRY POINT)== -import { _jsxQ } from "@builder.io/qwik"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { _jsxSorted } from "@qwik.dev/core"; import { hW } from "./test"; import { handleWatch } from "./test"; -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; export const Foo_component_HTDRsvUbLiE = ()=>{ useStyles$('thing'); - const qwik = hW + handleWatch; + const qwik = _addLoc(hW + handleWatch, "test.tsx", 14, 15); console.log(qwik); - return /*#__PURE__*/ _jsxQ("div", null, { - onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_Foo_component_div_onClick_M48DYiidSJw"), "Foo_component_div_onClick_M48DYiidSJw") - }, null, 3, "u6_0"); + const qrl1 = _addLoc(23, "test.tsx", 16, 14); + return /*#__PURE__*/ _jsxSorted("div", { + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_div_onClick_xGBE9Cbd8Ik"), "div_onClick_xGBE9Cbd8Ik", [ + qrl1 + ]) + }, null, null, 2, "u6_0"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;yCAU8B;IAC1B,WAAW;IACX,MAAM,OAAO,KAAK;IAClB,QAAQ,GAAG,CAAC;IAEZ,qBACI,MAAC;QAAI,QAAQ;;AAErB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;yCAU8B;IAC7B,WAAW;IACX,MAAM,OAAO,QAAA,KAAK;IAClB,QAAQ,GAAG,CAAC;IACZ,MAAM,OAAM,QAAA;IACZ,qBACC,WAAC;QAAI,QAAQ;;;;AAEf\"}") /* { "origin": "test.tsx", @@ -89,18 +94,17 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 269, - 448 + 265, + 420 ] } */ ============================= test.tsx_Root_component_useStyles_u5DkUxGrGnU.js (ENTRY POINT)== export const Root_component_useStyles_u5DkUxGrGnU = 'thing'; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"oDAuBgB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"oDAuBa\"}") /* { "origin": "test.tsx", @@ -116,22 +120,22 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "$", "captures": false, "loc": [ - 535, - 542 + 501, + 508 ] } */ ============================= test.tsx_Root_component_royhjYaCbYE.js (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; -import { useStyles } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; +import { useStyles } from "@qwik.dev/core"; export const Root_component_royhjYaCbYE = ()=>{ useStyles(/*#__PURE__*/ qrl(()=>import("./test.tsx_Root_component_useStyles_u5DkUxGrGnU"), "Root_component_useStyles_u5DkUxGrGnU")); return /*#__PURE__*/ qrl(()=>import("./test.tsx_Root_component_1_cBpQNYDUHI4"), "Root_component_1_cBpQNYDUHI4"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;0CAsB+B;IAC3B;IACA;AAKJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;0CAsB+B;IAC9B;IACA;AAKD\"}") /* { "origin": "test.tsx", @@ -147,64 +151,70 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "component$", "captures": false, "loc": [ - 511, - 622 + 480, + 561 ] } */ -============================= test.tsx_Root_component_1_cBpQNYDUHI4.js (ENTRY POINT)== +============================= test.tsx_div_onClick_xGBE9Cbd8Ik.js (ENTRY POINT)== -import { _jsxQ } from "@builder.io/qwik"; -export const Root_component_1_cBpQNYDUHI4 = ()=>{ - return /*#__PURE__*/ _jsxQ("div", null, null, null, 3, "u6_1"); +import { useLexicalScope } from "@qwik.dev/core"; +export const div_onClick_xGBE9Cbd8Ik = ()=>{ + const [qrl] = useLexicalScope(); + return console.log(qrl); }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAwBa;IACL,qBACI,MAAC;AAET\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";uCAgBiB;;WAAK,QAAQ,GAAG,CAAC\"}") /* { "origin": "test.tsx", - "name": "Root_component_1_cBpQNYDUHI4", + "name": "div_onClick_xGBE9Cbd8Ik", "entry": null, - "displayName": "test.tsx_Root_component_1", - "hash": "cBpQNYDUHI4", - "canonicalFilename": "test.tsx_Root_component_1_cBpQNYDUHI4", + "displayName": "test.tsx_div_onClick", + "hash": "xGBE9Cbd8Ik", + "canonicalFilename": "test.tsx_div_onClick_xGBE9Cbd8Ik", "path": "", "extension": "js", - "parent": "Root_component_royhjYaCbYE", - "ctxKind": "function", - "ctxName": "$", - "captures": false, + "parent": "Foo_component_HTDRsvUbLiE", + "ctxKind": "eventHandler", + "ctxName": "onClick$", + "captures": true, "loc": [ - 559, - 618 + 391, + 412 + ], + "captureNames": [ + "qrl" ] } */ -============================= test.tsx_Foo_component_div_onClick_M48DYiidSJw.js (ENTRY POINT)== +============================= test.tsx_Root_component_1_cBpQNYDUHI4.js (ENTRY POINT)== -export const Foo_component_div_onClick_M48DYiidSJw = ()=>console.log(23); +import { _jsxSorted } from "@qwik.dev/core"; +export const Root_component_1_cBpQNYDUHI4 = ()=>{ + return /*#__PURE__*/ _jsxSorted("div", null, null, null, 3, "u6_1"); +}; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\"qDAgBuB,IAAK,QAAQ,GAAG,CAFvB\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAwBU;IACR,qBACC,WAAC;AAEH\"}") /* { "origin": "test.tsx", - "name": "Foo_component_div_onClick_M48DYiidSJw", + "name": "Root_component_1_cBpQNYDUHI4", "entry": null, - "displayName": "test.tsx_Foo_component_div_onClick", - "hash": "M48DYiidSJw", - "canonicalFilename": "test.tsx_Foo_component_div_onClick_M48DYiidSJw", + "displayName": "test.tsx_Root_component_1", + "hash": "cBpQNYDUHI4", + "canonicalFilename": "test.tsx_Root_component_1_cBpQNYDUHI4", "path": "", "extension": "js", - "parent": "Foo_component_HTDRsvUbLiE", - "ctxKind": "eventHandler", - "ctxName": "onClick$", + "parent": "Root_component_royhjYaCbYE", + "ctxKind": "function", + "ctxName": "$", "captures": false, "loc": [ - 416, - 437 + 522, + 557 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_react.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_react.snap index a8793088678..8d87902c1c1 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_react.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_react.snap @@ -1,109 +1,109 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 3008 +assertion_line: 3119 expression: output snapshot_kind: text --- ==INPUT== -import { componentQrl, inlinedQrl, useLexicalScope, useHostElement, useStore, useTaskQrl, noSerialize, SkipRerender, implicit$FirstArg } from '@builder.io/qwik'; -import { jsx, Fragment } from '@builder.io/qwik/jsx-runtime'; -import { isBrowser, isServer } from '@builder.io/qwik/build'; +import { componentQrl, inlinedQrl, useLexicalScope, useHostElement, useStore, useTaskQrl, noSerialize, SkipRerender, implicit$FirstArg } from '@qwik.dev/core'; +import { jsx, Fragment } from '@qwik.dev/core/jsx-runtime'; +import { isBrowser, isServer } from '@qwik.dev/core'; function qwikifyQrl(reactCmpQrl) { - return /*#__PURE__*/ componentQrl(inlinedQrl((props)=>{ - const [reactCmpQrl] = useLexicalScope(); - const hostElement = useHostElement(); - const store = useStore({}); - let run; - if (props['client:visible']) run = 'visible'; - else if (props['client:load'] || props['client:only']) run = 'load'; - useTaskQrl(inlinedQrl(async (track)=>{ - const [hostElement, props, reactCmpQrl, store] = useLexicalScope(); - track(props); - if (isBrowser) { - if (store.data) store.data.root.render(store.data.client.Main(store.data.cmp, filterProps(props))); - else { - const [Cmp, client] = await Promise.all([ - reactCmpQrl.resolve(), - import('./client-f762f78c.js') - ]); - let root; - if (hostElement.childElementCount > 0) root = client.hydrateRoot(hostElement, client.Main(Cmp, filterProps(props), store.event)); - else { - root = client.createRoot(hostElement); - root.render(client.Main(Cmp, filterProps(props))); - } - store.data = noSerialize({ - client, - cmp: Cmp, - root - }); - } - } - }, "qwikifyQrl_component_useWatch_x04JC5xeP1U", [ - hostElement, - props, - reactCmpQrl, - store - ]), { - run - }); - if (isServer && !props['client:only']) { - const jsx$1 = Promise.all([ - reactCmpQrl.resolve(), - import('./server-9ac6caad.js') - ]).then(([Cmp, server])=>{ - const html = server.render(Cmp, filterProps(props)); - return /*#__PURE__*/ jsx(Host, { - dangerouslySetInnerHTML: html, - [_IMMUTABLE]: [ - "dangerouslySetInnerHTML" - ] - }); - }); - return /*#__PURE__*/ jsx(Fragment, { - children: jsx$1 - }); - } - return /*#__PURE__*/ jsx(Host, { - children: /*#__PURE__*/ jsx(SkipRerender, {}) - }); - }, "qwikifyQrl_component_zH94hIe0Ick", [ - reactCmpQrl - ]), { - tagName: 'qwik-wrap' - }); + return /*#__PURE__*/ componentQrl(inlinedQrl((props)=>{ + const [reactCmpQrl] = useLexicalScope(); + const hostElement = useHostElement(); + const store = useStore({}); + let run; + if (props['client:visible']) run = 'visible'; + else if (props['client:load'] || props['client:only']) run = 'load'; + useTaskQrl(inlinedQrl(async (track)=>{ + const [hostElement, props, reactCmpQrl, store] = useLexicalScope(); + track(props); + if (isBrowser) { + if (store.data) store.data.root.render(store.data.client.Main(store.data.cmp, filterProps(props))); + else { + const [Cmp, client] = await Promise.all([ + reactCmpQrl.resolve(), + import('./client-f762f78c.js') + ]); + let root; + if (hostElement.childElementCount > 0) root = client.hydrateRoot(hostElement, client.Main(Cmp, filterProps(props), store.event)); + else { + root = client.createRoot(hostElement); + root.render(client.Main(Cmp, filterProps(props))); + } + store.data = noSerialize({ + client, + cmp: Cmp, + root + }); + } + } + }, "qwikifyQrl_component_useWatch_x04JC5xeP1U", [ + hostElement, + props, + reactCmpQrl, + store + ]), { + run + }); + if (isServer && !props['client:only']) { + const jsx$1 = Promise.all([ + reactCmpQrl.resolve(), + import('./server-9ac6caad.js') + ]).then(([Cmp, server])=>{ + const html = server.render(Cmp, filterProps(props)); + return /*#__PURE__*/ jsx(Host, { + dangerouslySetInnerHTML: html, + [_IMMUTABLE]: [ + "dangerouslySetInnerHTML" + ] + }); + }); + return /*#__PURE__*/ jsx(Fragment, { + children: jsx$1 + }); + } + return /*#__PURE__*/ jsx(Host, { + children: /*#__PURE__*/ jsx(SkipRerender, {}) + }); + }, "qwikifyQrl_component_zH94hIe0Ick", [ + reactCmpQrl + ]), { + tagName: 'qwik-wrap' + }); } const filterProps = (props)=>{ - const obj = {}; - Object.keys(props).forEach((key)=>{ - if (!key.startsWith('client:')) obj[key] = props[key]; - }); - return obj; + const obj = {}; + Object.keys(props).forEach((key)=>{ + if (!key.startsWith('client:')) obj[key] = props[key]; + }); + return obj; }; const qwikify$ = implicit$FirstArg(qwikifyQrl); async function renderToString(rootNode, opts) { - const mod = await import('./server-9ac6caad.js'); - const result = await mod.renderToString(rootNode, opts); - const styles = mod.getGlobalStyleTag(result.html); - const finalHtml = styles + result.html; - return { - ...result, - html: finalHtml - }; + const mod = await import('./server-9ac6caad.js'); + const result = await mod.renderToString(rootNode, opts); + const styles = mod.getGlobalStyleTag(result.html); + const finalHtml = styles + result.html; + return { + ...result, + html: finalHtml + }; } export { qwikify$, qwikifyQrl, renderToString }; - -============================= ../node_modules/@builder.io/qwik-react/index.qwik.mjs_qwikifyQrl_component_useWatch_x04JC5xeP1U.mjs (ENTRY POINT)== + +============================= ../node_modules/@qwik.dev/react/index.qwik.mjs_qwikifyQrl_component_useWatch_x04JC5xeP1U.mjs (ENTRY POINT)== import { _auto_filterProps as filterProps } from "./index.qwik.mjs"; -import { isBrowser } from "@builder.io/qwik/build"; -import { noSerialize } from "@builder.io/qwik"; -import { useLexicalScope } from "@builder.io/qwik"; +import { isBrowser } from "@qwik.dev/core"; +import { noSerialize } from "@qwik.dev/core"; +import { useLexicalScope } from "@qwik.dev/core"; export const qwikifyQrl_component_useWatch_x04JC5xeP1U = async (track)=>{ const [hostElement, props, reactCmpQrl, store] = useLexicalScope(); track(props); @@ -128,48 +128,55 @@ export const qwikifyQrl_component_useWatch_x04JC5xeP1U = async (track)=>{ } } }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-react/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;;;yDAa8B,OAAO;IACzB,MAAM,CAAC,aAAa,OAAO,aAAa,MAAM,GAAG;IACjD,MAAM;IACN,IAAI;QACA,IAAI,MAAM,IAAI,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,YAAY;aACrF;YACD,MAAM,CAAC,KAAK,OAAO,GAAG,MAAM,QAAQ,GAAG,CAAC;gBACpC,YAAY,OAAO;gBACnB,MAAM,CAAC;aACV;YACD,IAAI;YACJ,IAAI,YAAY,iBAAiB,GAAG,GAAG,OAAO,OAAO,WAAW,CAAC,aAAa,OAAO,IAAI,CAAC,KAAK,YAAY,QAAQ,MAAM,KAAK;iBACzH;gBACD,OAAO,OAAO,UAAU,CAAC;gBACzB,KAAK,MAAM,CAAC,OAAO,IAAI,CAAC,KAAK,YAAY;YAC7C;YACA,MAAM,IAAI,GAAG,YAAY;gBACrB;gBACA,KAAK;gBACL;YACJ;QACJ;;AAER\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/react/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;;;yDAawB,OAAO;IAC5B,MAAM,CAAC,aAAa,OAAO,aAAa,MAAM,GAAG;IACjD,MAAM;IACN,IAAI;QACH,IAAI,MAAM,IAAI,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,YAAY;aACrF;YACJ,MAAM,CAAC,KAAK,OAAO,GAAG,MAAM,QAAQ,GAAG,CAAC;gBACvC,YAAY,OAAO;gBACnB,MAAM,CAAC;aACP;YACD,IAAI;YACJ,IAAI,YAAY,iBAAiB,GAAG,GAAG,OAAO,OAAO,WAAW,CAAC,aAAa,OAAO,IAAI,CAAC,KAAK,YAAY,QAAQ,MAAM,KAAK;iBACzH;gBACJ,OAAO,OAAO,UAAU,CAAC;gBACzB,KAAK,MAAM,CAAC,OAAO,IAAI,CAAC,KAAK,YAAY;YAC1C;YACA,MAAM,IAAI,GAAG,YAAY;gBACxB;gBACA,KAAK;gBACL;YACD;QACD;;AAEF\"}") /* { - "origin": "../node_modules/@builder.io/qwik-react/index.qwik.mjs", + "origin": "../node_modules/@qwik.dev/react/index.qwik.mjs", "name": "qwikifyQrl_component_useWatch_x04JC5xeP1U", "entry": null, "displayName": "index.qwik.mjs_qwikifyQrl_component_useWatch", "hash": "x04JC5xeP1U", "canonicalFilename": "index.qwik.mjs_qwikifyQrl_component_useWatch_x04JC5xeP1U", - "path": "../node_modules/@builder.io/qwik-react", + "path": "../node_modules/@qwik.dev/react", "extension": "mjs", "parent": "qwikifyQrl_component_zH94hIe0Ick", "ctxKind": "function", "ctxName": "useTask$", "captures": true, "loc": [ - 693, - 1746 + 636, + 1365 + ], + "paramNames": [ + "track" + ], + "captureNames": [ + "hostElement", + "props", + "reactCmpQrl", + "store" ] } */ -============================= ../node_modules/@builder.io/qwik-react/index.qwik.mjs_qwikifyQrl_component_zH94hIe0Ick.mjs (ENTRY POINT)== +============================= ../node_modules/@qwik.dev/react/index.qwik.mjs_qwikifyQrl_component_zH94hIe0Ick.mjs (ENTRY POINT)== -import { Fragment } from "@builder.io/qwik/jsx-runtime"; -import { SkipRerender } from "@builder.io/qwik"; -import { _jsxBranch } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; +import { Fragment } from "@qwik.dev/core/jsx-runtime"; +import { SkipRerender } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { _jsxSorted } from "@qwik.dev/core"; import { _auto_filterProps as filterProps } from "./index.qwik.mjs"; -import { isServer } from "@builder.io/qwik/build"; -import { qrl } from "@builder.io/qwik"; -import { useHostElement } from "@builder.io/qwik"; -import { useLexicalScope } from "@builder.io/qwik"; -import { useStore } from "@builder.io/qwik"; -import { useTaskQrl } from "@builder.io/qwik"; +import { isServer } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { useHostElement } from "@qwik.dev/core"; +import { useLexicalScope } from "@qwik.dev/core"; +import { useStore } from "@qwik.dev/core"; +import { useTaskQrl } from "@qwik.dev/core"; export const qwikifyQrl_component_zH94hIe0Ick = (props)=>{ - _jsxBranch(); const [reactCmpQrl] = useLexicalScope(); - const hostElement = useHostElement(); - const store = useStore({}); + const hostElement = _addLoc(useHostElement(), "../node_modules/@qwik.dev/react/index.qwik.mjs", 10, 23); + const store = _addLoc(useStore({}), "../node_modules/@qwik.dev/react/index.qwik.mjs", 11, 17); let run; if (props['client:visible']) run = 'visible'; else if (props['client:load'] || props['client:only']) run = 'load'; @@ -182,53 +189,56 @@ export const qwikifyQrl_component_zH94hIe0Ick = (props)=>{ run }); if (isServer && !props['client:only']) { - const jsx$1 = Promise.all([ + const jsx$1 = _addLoc(Promise.all([ reactCmpQrl.resolve(), import('./server-9ac6caad.js') ]).then(([Cmp, server])=>{ - const html = server.render(Cmp, filterProps(props)); - return /*#__PURE__*/ _jsxC(Host, { + const html = _addLoc(server.render(Cmp, filterProps(props)), "../node_modules/@qwik.dev/react/index.qwik.mjs", 51, 18); + return /*#__PURE__*/ _jsxSorted(Host, { dangerouslySetInnerHTML: html, [_IMMUTABLE]: [ "dangerouslySetInnerHTML" ] - }, 3, "mR_0"); - }); - return /*#__PURE__*/ _jsxC(Fragment, { - children: jsx$1 - }, 1, "mR_1"); + }, null, null, 3, "8p_0"); + }), "../node_modules/@qwik.dev/react/index.qwik.mjs", 47, 18); + return /*#__PURE__*/ _jsxSorted(Fragment, null, null, jsx$1, 1, "8p_1"); } - return /*#__PURE__*/ _jsxC(Host, { - children: /*#__PURE__*/ _jsxC(SkipRerender, null, 3, "mR_2") - }, 1, "mR_3"); + return /*#__PURE__*/ _jsxSorted(Host, null, null, /*#__PURE__*/ _jsxSorted(SkipRerender, null, null, null, 3, "8p_2"), 1, "8p_3"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-react/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;;;;;;;;;;gDAMiD,CAAC;;IAC1C,MAAM,CAAC,YAAY,GAAG;IACtB,MAAM,cAAc;IACpB,MAAM,QAAQ,SAAS,CAAC;IACxB,IAAI;IACJ,IAAI,KAAK,CAAC,iBAAiB,EAAE,MAAM;SAC9B,IAAI,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,EAAE,MAAM;IAC7D;;;;;QA4BI;QACA;IACJ;IACA,IAAI,YAAY,CAAC,KAAK,CAAC,cAAc,EAAE;QACnC,MAAM,QAAQ,QAAQ,GAAG,CAAC;YACtB,YAAY,OAAO;YACnB,MAAM,CAAC;SACV,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO;YAClB,MAAM,OAAO,OAAO,MAAM,CAAC,KAAK,YAAY;YAC5C,OAAO,WAAW,GAAG,MAAI;gBACrB,yBAAyB;gBACzB,CAAC,WAAW,EAAE;oBACV;iBACH;;QAET;QACA,OAAO,WAAW,GAAG,MAAI;YACrB,UAAU;;IAElB;IACA,OAAO,WAAW,GAAG,MAAI;QACrB,UAAU,WAAW,GAAG,MAAI;;AAEpC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/react/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;;;;;;;;;;gDAM8C,CAAC;IAC7C,MAAM,CAAC,YAAY,GAAG;IACtB,MAAM,cAAc,QAAA;IACpB,MAAM,QAAQ,QAAA,SAAS,CAAC;IACxB,IAAI;IACJ,IAAI,KAAK,CAAC,iBAAiB,EAAE,MAAM;SAC9B,IAAI,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,EAAE,MAAM;IAC7D;;;;;QA4BI;QACH;IACD;IACA,IAAI,YAAY,CAAC,KAAK,CAAC,cAAc,EAAE;QACtC,MAAM,QAAQ,QAAA,QAAQ,GAAG,CAAC;YACzB,YAAY,OAAO;YACnB,MAAM,CAAC;SACP,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO;YACrB,MAAM,OAAO,QAAA,OAAO,MAAM,CAAC,KAAK,YAAY;YAC5C,OAAO,WAAW,GAAG,WAAI;gBACxB,yBAAyB;gBACzB,CAAC,WAAW,EAAE;oBACb;iBACA;;QAEH;QACA,OAAO,WAAW,GAAG,WAAI,sBACd;IAEZ;IACA,OAAO,WAAW,GAAG,WAAI,kBACd,WAAW,GAAG,WAAI;AAE9B\"}") /* { - "origin": "../node_modules/@builder.io/qwik-react/index.qwik.mjs", + "origin": "../node_modules/@qwik.dev/react/index.qwik.mjs", "name": "qwikifyQrl_component_zH94hIe0Ick", "entry": null, "displayName": "index.qwik.mjs_qwikifyQrl_component", "hash": "zH94hIe0Ick", "canonicalFilename": "index.qwik.mjs_qwikifyQrl_component_zH94hIe0Ick", - "path": "../node_modules/@builder.io/qwik-react", + "path": "../node_modules/@qwik.dev/react", "extension": "mjs", "parent": null, "ctxKind": "function", "ctxName": "component$", "captures": true, "loc": [ - 373, - 2674 + 358, + 2020 + ], + "paramNames": [ + "props" + ], + "captureNames": [ + "reactCmpQrl" ] } */ -============================= ../node_modules/@builder.io/qwik-react/index.qwik.mjs == +============================= ../node_modules/@qwik.dev/react/index.qwik.mjs == -import { qrl } from "@builder.io/qwik"; -import { componentQrl, implicit$FirstArg } from '@builder.io/qwik'; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { componentQrl, implicit$FirstArg } from '@qwik.dev/core'; function qwikifyQrl(reactCmpQrl) { return /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_qwikifyQrl_component_zH94hIe0Ick.mjs"), "qwikifyQrl_component_zH94hIe0Ick", [ reactCmpQrl @@ -236,19 +246,19 @@ function qwikifyQrl(reactCmpQrl) { tagName: 'qwik-wrap' }); } -const filterProps = (props)=>{ - const obj = {}; +const filterProps = _addLoc((props)=>{ + const obj = _addLoc({}, "../node_modules/@qwik.dev/react/index.qwik.mjs", 73, 14); Object.keys(props).forEach((key)=>{ if (!key.startsWith('client:')) obj[key] = props[key]; }); return obj; -}; -const qwikify$ = implicit$FirstArg(qwikifyQrl); +}, "../node_modules/@qwik.dev/react/index.qwik.mjs", 72, 21); +const qwikify$ = _addLoc(implicit$FirstArg(qwikifyQrl), "../node_modules/@qwik.dev/react/index.qwik.mjs", 79, 18); async function renderToString(rootNode, opts) { - const mod = await import('./server-9ac6caad.js'); - const result = await mod.renderToString(rootNode, opts); - const styles = mod.getGlobalStyleTag(result.html); - const finalHtml = styles + result.html; + const mod = _addLoc(await import('./server-9ac6caad.js'), "../node_modules/@qwik.dev/react/index.qwik.mjs", 82, 14); + const result = _addLoc(await mod.renderToString(rootNode, opts), "../node_modules/@qwik.dev/react/index.qwik.mjs", 83, 17); + const styles = _addLoc(mod.getGlobalStyleTag(result.html), "../node_modules/@qwik.dev/react/index.qwik.mjs", 84, 17); + const finalHtml = _addLoc(styles + result.html, "../node_modules/@qwik.dev/react/index.qwik.mjs", 85, 20); return { ...result, html: finalHtml @@ -258,7 +268,7 @@ export { qwikify$, qwikifyQrl, renderToString }; export { filterProps as _auto_filterProps }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-react/index.qwik.mjs\"],\"names\":[],\"mappings\":\";AACA,SAAS,YAAY,EAAgG,iBAAiB,QAAQ,mBAAmB;AAIjK,SAAS,WAAW,WAAW;IAC3B,OAAO,WAAW,GAAG;;QA4DjB;QACA,SAAS;IACb;AACJ;AACA,MAAM,cAAc,CAAC;IACjB,MAAM,MAAM,CAAC;IACb,OAAO,IAAI,CAAC,OAAO,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,UAAU,CAAC,YAAY,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;IACzD;IACA,OAAO;AACX;AACA,MAAM,WAAW,kBAAkB;AAEnC,eAAe,eAAe,QAAQ,EAAE,IAAI;IACxC,MAAM,MAAM,MAAM,MAAM,CAAC;IACzB,MAAM,SAAS,MAAM,IAAI,cAAc,CAAC,UAAU;IAClD,MAAM,SAAS,IAAI,iBAAiB,CAAC,OAAO,IAAI;IAChD,MAAM,YAAY,SAAS,OAAO,IAAI;IACtC,OAAO;QACH,GAAG,MAAM;QACT,MAAM;IACV;AACJ;AAEA,SAAS,QAAQ,EAAE,UAAU,EAAE,cAAc,GAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/react/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;AACA,SAAS,YAAY,EAAgG,iBAAiB,QAAQ,iBAAiB;AAI/J,SAAS,WAAW,WAAW;IAC9B,OAAO,WAAW,GAAG;;QA4DjB;QACH,SAAS;IACV;AACD;AACA,MAAM,cAAc,QAAA,CAAC;IACpB,MAAM,MAAM,QAAA,CAAC;IACb,OAAO,IAAI,CAAC,OAAO,OAAO,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,UAAU,CAAC,YAAY,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;IACtD;IACA,OAAO;AACR;AACA,MAAM,WAAW,QAAA,kBAAkB;AAEnC,eAAe,eAAe,QAAQ,EAAE,IAAI;IAC3C,MAAM,MAAM,QAAA,MAAM,MAAM,CAAC;IACzB,MAAM,SAAS,QAAA,MAAM,IAAI,cAAc,CAAC,UAAU;IAClD,MAAM,SAAS,QAAA,IAAI,iBAAiB,CAAC,OAAO,IAAI;IAChD,MAAM,YAAY,QAAA,SAAS,OAAO,IAAI;IACtC,OAAO;QACN,GAAG,MAAM;QACT,MAAM;IACP;AACD;AAEA,SAAS,QAAQ,EAAE,UAAU,EAAE,cAAc,GAAG\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_react_inline.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_react_inline.snap index 614d3992ed7..28272ea23a2 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_react_inline.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_react_inline.snap @@ -1,116 +1,115 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 3111 +assertion_line: 3222 expression: output snapshot_kind: text --- ==INPUT== -import { componentQrl, inlinedQrl, useLexicalScope, useHostElement, useStore, useTaskQrl, noSerialize, SkipRerender, implicit$FirstArg } from '@builder.io/qwik'; -import { jsx, Fragment } from '@builder.io/qwik/jsx-runtime'; -import { isBrowser, isServer } from '@builder.io/qwik/build'; +import { componentQrl, inlinedQrl, useLexicalScope, useHostElement, useStore, useTaskQrl, noSerialize, SkipRerender, implicit$FirstArg } from '@qwik.dev/core'; +import { jsx, Fragment } from '@qwik.dev/core/jsx-runtime'; +import { isBrowser, isServer } from '@qwik.dev/core'; function qwikifyQrl(reactCmpQrl) { - return /*#__PURE__*/ componentQrl(inlinedQrl((props)=>{ - const [reactCmpQrl] = useLexicalScope(); - const hostElement = useHostElement(); - const store = useStore({}); - let run; - if (props['client:visible']) run = 'visible'; - else if (props['client:load'] || props['client:only']) run = 'load'; - useTaskQrl(inlinedQrl(async (track)=>{ - const [hostElement, props, reactCmpQrl, store] = useLexicalScope(); - track(props); - if (isBrowser) { - if (store.data) store.data.root.render(store.data.client.Main(store.data.cmp, filterProps(props))); - else { - const [Cmp, client] = await Promise.all([ - reactCmpQrl.resolve(), - import('./client-f762f78c.js') - ]); - let root; - if (hostElement.childElementCount > 0) root = client.hydrateRoot(hostElement, client.Main(Cmp, filterProps(props), store.event)); - else { - root = client.createRoot(hostElement); - root.render(client.Main(Cmp, filterProps(props))); - } - store.data = noSerialize({ - client, - cmp: Cmp, - root - }); - } - } - }, "qwikifyQrl_component_useWatch_x04JC5xeP1U", [ - hostElement, - props, - reactCmpQrl, - store - ]), { - run - }); - if (isServer && !props['client:only']) { - const jsx$1 = Promise.all([ - reactCmpQrl.resolve(), - import('./server-9ac6caad.js') - ]).then(([Cmp, server])=>{ - const html = server.render(Cmp, filterProps(props)); - return /*#__PURE__*/ jsx(Host, { - dangerouslySetInnerHTML: html, - [_IMMUTABLE]: [ - "dangerouslySetInnerHTML" - ] - }); - }); - return /*#__PURE__*/ jsx(Fragment, { - children: jsx$1 - }); - } - return /*#__PURE__*/ jsx(Host, { - children: /*#__PURE__*/ jsx(SkipRerender, {}) - }); - }, "qwikifyQrl_component_zH94hIe0Ick", [ - reactCmpQrl - ]), { - tagName: 'qwik-wrap' - }); + return /*#__PURE__*/ componentQrl(inlinedQrl((props)=>{ + const [reactCmpQrl] = useLexicalScope(); + const hostElement = useHostElement(); + const store = useStore({}); + let run; + if (props['client:visible']) run = 'visible'; + else if (props['client:load'] || props['client:only']) run = 'load'; + useTaskQrl(inlinedQrl(async (track)=>{ + const [hostElement, props, reactCmpQrl, store] = useLexicalScope(); + track(props); + if (isBrowser) { + if (store.data) store.data.root.render(store.data.client.Main(store.data.cmp, filterProps(props))); + else { + const [Cmp, client] = await Promise.all([ + reactCmpQrl.resolve(), + import('./client-f762f78c.js') + ]); + let root; + if (hostElement.childElementCount > 0) root = client.hydrateRoot(hostElement, client.Main(Cmp, filterProps(props), store.event)); + else { + root = client.createRoot(hostElement); + root.render(client.Main(Cmp, filterProps(props))); + } + store.data = noSerialize({ + client, + cmp: Cmp, + root + }); + } + } + }, "qwikifyQrl_component_useWatch_x04JC5xeP1U", [ + hostElement, + props, + reactCmpQrl, + store + ]), { + run + }); + if (isServer && !props['client:only']) { + const jsx$1 = Promise.all([ + reactCmpQrl.resolve(), + import('./server-9ac6caad.js') + ]).then(([Cmp, server])=>{ + const html = server.render(Cmp, filterProps(props)); + return /*#__PURE__*/ jsx(Host, { + dangerouslySetInnerHTML: html, + [_IMMUTABLE]: [ + "dangerouslySetInnerHTML" + ] + }); + }); + return /*#__PURE__*/ jsx(Fragment, { + children: jsx$1 + }); + } + return /*#__PURE__*/ jsx(Host, { + children: /*#__PURE__*/ jsx(SkipRerender, {}) + }); + }, "qwikifyQrl_component_zH94hIe0Ick", [ + reactCmpQrl + ]), { + tagName: 'qwik-wrap' + }); } const filterProps = (props)=>{ - const obj = {}; - Object.keys(props).forEach((key)=>{ - if (!key.startsWith('client:')) obj[key] = props[key]; - }); - return obj; + const obj = {}; + Object.keys(props).forEach((key)=>{ + if (!key.startsWith('client:')) obj[key] = props[key]; + }); + return obj; }; const qwikify$ = implicit$FirstArg(qwikifyQrl); async function renderToString(rootNode, opts) { - const mod = await import('./server-9ac6caad.js'); - const result = await mod.renderToString(rootNode, opts); - const styles = mod.getGlobalStyleTag(result.html); - const finalHtml = styles + result.html; - return { - ...result, - html: finalHtml - }; + const mod = await import('./server-9ac6caad.js'); + const result = await mod.renderToString(rootNode, opts); + const styles = mod.getGlobalStyleTag(result.html); + const finalHtml = styles + result.html; + return { + ...result, + html: finalHtml + }; } export { qwikify$, qwikifyQrl, renderToString }; - -============================= ../node_modules/@builder.io/qwik-react/index.qwik.mjs == + +============================= ../node_modules/@qwik.dev/react/index.qwik.mjs == -import { _jsxC } from "@builder.io/qwik"; -import { _jsxBranch } from "@builder.io/qwik"; -import { componentQrl, inlinedQrl, useLexicalScope, useHostElement, useStore, useTaskQrl, noSerialize, SkipRerender, implicit$FirstArg } from '@builder.io/qwik'; -import { Fragment } from '@builder.io/qwik/jsx-runtime'; -import { isBrowser, isServer } from '@builder.io/qwik/build'; +import { _jsxSorted } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +import { componentQrl, inlinedQrl, useLexicalScope, useHostElement, useStore, useTaskQrl, noSerialize, SkipRerender, implicit$FirstArg } from '@qwik.dev/core'; +import { Fragment } from '@qwik.dev/core/jsx-runtime'; +import { isBrowser, isServer } from '@qwik.dev/core'; function qwikifyQrl(reactCmpQrl) { return /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props)=>{ - _jsxBranch(); const [reactCmpQrl] = useLexicalScope(); - const hostElement = useHostElement(); - const store = useStore({}); + const hostElement = _addLoc(useHostElement(), "../node_modules/@qwik.dev/react/index.qwik.mjs", 10, 23); + const store = _addLoc(useStore({}), "../node_modules/@qwik.dev/react/index.qwik.mjs", 11, 17); let run; if (props['client:visible']) run = 'visible'; else if (props['client:load'] || props['client:only']) run = 'load'; @@ -146,44 +145,40 @@ function qwikifyQrl(reactCmpQrl) { run }); if (isServer && !props['client:only']) { - const jsx$1 = Promise.all([ + const jsx$1 = _addLoc(Promise.all([ reactCmpQrl.resolve(), import('./server-9ac6caad.js') ]).then(([Cmp, server])=>{ - const html = server.render(Cmp, filterProps(props)); - return /*#__PURE__*/ _jsxC(Host, { + const html = _addLoc(server.render(Cmp, filterProps(props)), "../node_modules/@qwik.dev/react/index.qwik.mjs", 51, 18); + return /*#__PURE__*/ _jsxSorted(Host, { dangerouslySetInnerHTML: html, [_IMMUTABLE]: [ "dangerouslySetInnerHTML" ] - }, 3, "mR_0"); - }); - return /*#__PURE__*/ _jsxC(Fragment, { - children: jsx$1 - }, 1, "mR_1"); + }, null, null, 3, "8p_0"); + }), "../node_modules/@qwik.dev/react/index.qwik.mjs", 47, 18); + return /*#__PURE__*/ _jsxSorted(Fragment, null, null, jsx$1, 1, "8p_1"); } - return /*#__PURE__*/ _jsxC(Host, { - children: /*#__PURE__*/ _jsxC(SkipRerender, null, 3, "mR_2") - }, 1, "mR_3"); + return /*#__PURE__*/ _jsxSorted(Host, null, null, /*#__PURE__*/ _jsxSorted(SkipRerender, null, null, null, 3, "8p_2"), 1, "8p_3"); }, "qwikifyQrl_component_zH94hIe0Ick", [ reactCmpQrl ]), { tagName: 'qwik-wrap' }); } -const filterProps = (props)=>{ - const obj = {}; +const filterProps = _addLoc((props)=>{ + const obj = _addLoc({}, "../node_modules/@qwik.dev/react/index.qwik.mjs", 73, 14); Object.keys(props).forEach((key)=>{ if (!key.startsWith('client:')) obj[key] = props[key]; }); return obj; -}; -const qwikify$ = implicit$FirstArg(qwikifyQrl); +}, "../node_modules/@qwik.dev/react/index.qwik.mjs", 72, 21); +const qwikify$ = _addLoc(implicit$FirstArg(qwikifyQrl), "../node_modules/@qwik.dev/react/index.qwik.mjs", 79, 18); async function renderToString(rootNode, opts) { - const mod = await import('./server-9ac6caad.js'); - const result = await mod.renderToString(rootNode, opts); - const styles = mod.getGlobalStyleTag(result.html); - const finalHtml = styles + result.html; + const mod = _addLoc(await import('./server-9ac6caad.js'), "../node_modules/@qwik.dev/react/index.qwik.mjs", 82, 14); + const result = _addLoc(await mod.renderToString(rootNode, opts), "../node_modules/@qwik.dev/react/index.qwik.mjs", 83, 17); + const styles = _addLoc(mod.getGlobalStyleTag(result.html), "../node_modules/@qwik.dev/react/index.qwik.mjs", 84, 17); + const finalHtml = _addLoc(styles + result.html, "../node_modules/@qwik.dev/react/index.qwik.mjs", 85, 20); return { ...result, html: finalHtml @@ -193,7 +188,7 @@ export { qwikify$, qwikifyQrl, renderToString }; export { filterProps as _auto_filterProps }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-react/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;AACA,SAAS,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,iBAAiB,QAAQ,mBAAmB;AACjK,SAAc,QAAQ,QAAQ,+BAA+B;AAC7D,SAAS,SAAS,EAAE,QAAQ,QAAQ,yBAAyB;AAE7D,SAAS,WAAW,WAAW;IAC3B,OAAO,WAAW,GAAG,sCAAwB,CAAC;;QAC1C,MAAM,CAAC,YAAY,GAAG;QACtB,MAAM,cAAc;QACpB,MAAM,QAAQ,SAAS,CAAC;QACxB,IAAI;QACJ,IAAI,KAAK,CAAC,iBAAiB,EAAE,MAAM;aAC9B,IAAI,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,EAAE,MAAM;QAC7D,oCAAsB,OAAO;YACzB,MAAM,CAAC,aAAa,OAAO,aAAa,MAAM,GAAG;YACjD,MAAM;YACN,IAAI;gBACA,IAAI,MAAM,IAAI,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,YAAY;qBACrF;oBACD,MAAM,CAAC,KAAK,OAAO,GAAG,MAAM,QAAQ,GAAG,CAAC;wBACpC,YAAY,OAAO;wBACnB,MAAM,CAAC;qBACV;oBACD,IAAI;oBACJ,IAAI,YAAY,iBAAiB,GAAG,GAAG,OAAO,OAAO,WAAW,CAAC,aAAa,OAAO,IAAI,CAAC,KAAK,YAAY,QAAQ,MAAM,KAAK;yBACzH;wBACD,OAAO,OAAO,UAAU,CAAC;wBACzB,KAAK,MAAM,CAAC,OAAO,IAAI,CAAC,KAAK,YAAY;oBAC7C;oBACA,MAAM,IAAI,GAAG,YAAY;wBACrB;wBACA,KAAK;wBACL;oBACJ;gBACJ;;QAER;;;;;YAKI;YACA;QACJ;QACA,IAAI,YAAY,CAAC,KAAK,CAAC,cAAc,EAAE;YACnC,MAAM,QAAQ,QAAQ,GAAG,CAAC;gBACtB,YAAY,OAAO;gBACnB,MAAM,CAAC;aACV,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO;gBAClB,MAAM,OAAO,OAAO,MAAM,CAAC,KAAK,YAAY;gBAC5C,OAAO,WAAW,GAAG,MAAI;oBACrB,yBAAyB;oBACzB,CAAC,WAAW,EAAE;wBACV;qBACH;;YAET;YACA,OAAO,WAAW,GAAG,MAAI;gBACrB,UAAU;;QAElB;QACA,OAAO,WAAW,GAAG,MAAI;YACrB,UAAU,WAAW,GAAG,MAAI;;IAEpC;;QAEI;QACA,SAAS;IACb;AACJ;AACA,MAAM,cAAc,CAAC;IACjB,MAAM,MAAM,CAAC;IACb,OAAO,IAAI,CAAC,OAAO,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,UAAU,CAAC,YAAY,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;IACzD;IACA,OAAO;AACX;AACA,MAAM,WAAW,kBAAkB;AAEnC,eAAe,eAAe,QAAQ,EAAE,IAAI;IACxC,MAAM,MAAM,MAAM,MAAM,CAAC;IACzB,MAAM,SAAS,MAAM,IAAI,cAAc,CAAC,UAAU;IAClD,MAAM,SAAS,IAAI,iBAAiB,CAAC,OAAO,IAAI;IAChD,MAAM,YAAY,SAAS,OAAO,IAAI;IACtC,OAAO;QACH,GAAG,MAAM;QACT,MAAM;IACV;AACJ;AAEA,SAAS,QAAQ,EAAE,UAAU,EAAE,cAAc,GAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/react/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;AACA,SAAS,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,iBAAiB,QAAQ,iBAAiB;AAC/J,SAAc,QAAQ,QAAQ,6BAA6B;AAC3D,SAAS,SAAS,EAAE,QAAQ,QAAQ,iBAAiB;AAErD,SAAS,WAAW,WAAW;IAC9B,OAAO,WAAW,GAAG,sCAAwB,CAAC;QAC7C,MAAM,CAAC,YAAY,GAAG;QACtB,MAAM,cAAc,QAAA;QACpB,MAAM,QAAQ,QAAA,SAAS,CAAC;QACxB,IAAI;QACJ,IAAI,KAAK,CAAC,iBAAiB,EAAE,MAAM;aAC9B,IAAI,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,EAAE,MAAM;QAC7D,oCAAsB,OAAO;YAC5B,MAAM,CAAC,aAAa,OAAO,aAAa,MAAM,GAAG;YACjD,MAAM;YACN,IAAI;gBACH,IAAI,MAAM,IAAI,EAAE,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,YAAY;qBACrF;oBACJ,MAAM,CAAC,KAAK,OAAO,GAAG,MAAM,QAAQ,GAAG,CAAC;wBACvC,YAAY,OAAO;wBACnB,MAAM,CAAC;qBACP;oBACD,IAAI;oBACJ,IAAI,YAAY,iBAAiB,GAAG,GAAG,OAAO,OAAO,WAAW,CAAC,aAAa,OAAO,IAAI,CAAC,KAAK,YAAY,QAAQ,MAAM,KAAK;yBACzH;wBACJ,OAAO,OAAO,UAAU,CAAC;wBACzB,KAAK,MAAM,CAAC,OAAO,IAAI,CAAC,KAAK,YAAY;oBAC1C;oBACA,MAAM,IAAI,GAAG,YAAY;wBACxB;wBACA,KAAK;wBACL;oBACD;gBACD;;QAEF;;;;;YAKI;YACH;QACD;QACA,IAAI,YAAY,CAAC,KAAK,CAAC,cAAc,EAAE;YACtC,MAAM,QAAQ,QAAA,QAAQ,GAAG,CAAC;gBACzB,YAAY,OAAO;gBACnB,MAAM,CAAC;aACP,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO;gBACrB,MAAM,OAAO,QAAA,OAAO,MAAM,CAAC,KAAK,YAAY;gBAC5C,OAAO,WAAW,GAAG,WAAI;oBACxB,yBAAyB;oBACzB,CAAC,WAAW,EAAE;wBACb;qBACA;;YAEH;YACA,OAAO,WAAW,GAAG,WAAI,sBACd;QAEZ;QACA,OAAO,WAAW,GAAG,WAAI,kBACd,WAAW,GAAG,WAAI;IAE9B;;QAEI;QACH,SAAS;IACV;AACD;AACA,MAAM,cAAc,QAAA,CAAC;IACpB,MAAM,MAAM,QAAA,CAAC;IACb,OAAO,IAAI,CAAC,OAAO,OAAO,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,UAAU,CAAC,YAAY,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;IACtD;IACA,OAAO;AACR;AACA,MAAM,WAAW,QAAA,kBAAkB;AAEnC,eAAe,eAAe,QAAQ,EAAE,IAAI;IAC3C,MAAM,MAAM,QAAA,MAAM,MAAM,CAAC;IACzB,MAAM,SAAS,QAAA,MAAM,IAAI,cAAc,CAAC,UAAU;IAClD,MAAM,SAAS,QAAA,IAAI,iBAAiB,CAAC,OAAO,IAAI;IAChD,MAAM,YAAY,QAAA,SAAS,OAAO,IAAI;IACtC,OAAO;QACN,GAAG,MAAM;QACT,MAAM;IACP;AACD;AAEA,SAAS,QAAQ,EAAE,UAAU,EAAE,cAAc,GAAG\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_router_inline.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_router_inline.snap new file mode 100644 index 00000000000..bbf5a17fa64 --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_router_inline.snap @@ -0,0 +1,1942 @@ +--- +source: packages/qwik/src/optimizer/core/src/test.rs +assertion_line: 3325 +expression: output +snapshot_kind: text +--- +==INPUT== + +import * as qwikRouterConfig from '@qwik-router-config'; +import swRegister from '@qwik-router-sw-register'; +import { + _deserializeData, + _fnSignal, + _getContextElement, + _jsxBranch, + _jsxSplit, + _restProps, + _serializeData, + _weakSerialize, + _wrapSignal, + componentQrl, + createContextId, + eventQrl, + getLocale, + implicit$FirstArg, + inlinedQrl, + noSerialize, + SkipRender, + Slot, + untrack, + useContext, + useContextProvider, + useLexicalScope, + useOnDocument, + useServerData, + useSignal, + useStore, + useStylesQrl, + useTaskQrl, + withLocale, +} from '@qwik.dev/core'; +import { isBrowser, isDev, isServer } from '@qwik.dev/core/build'; +import { z, z as z2 } from 'zod'; +const RouteStateContext = /* @__PURE__ */ createContextId('qc-s'); +const ContentContext = /* @__PURE__ */ createContextId('qc-c'); +const ContentInternalContext = /* @__PURE__ */ createContextId('qc-ic'); +const DocumentHeadContext = /* @__PURE__ */ createContextId('qc-h'); +const RouteLocationContext = /* @__PURE__ */ createContextId('qc-l'); +const RouteNavigateContext = /* @__PURE__ */ createContextId('qc-n'); +const RouteActionContext = /* @__PURE__ */ createContextId('qc-a'); +const RouterOutlet = /* @__PURE__ */ componentQrl( + /* @__PURE__ */ inlinedQrl(() => { + _jsxBranch(); + useOnDocument( + 'qinit', + eventQrl( + /* @__PURE__ */ inlinedQrl(() => { + const POPSTATE_FALLBACK_INITIALIZED = '_qRouterPopstateFallback'; + const CLIENT_HISTORY_INITIALIZED = '_qRouterHistory'; + if (!window[POPSTATE_FALLBACK_INITIALIZED]) { + window[POPSTATE_FALLBACK_INITIALIZED] = () => { + if (!window[CLIENT_HISTORY_INITIALIZED]) location.reload(); + }; + setTimeout(() => { + addEventListener('popstate', window[POPSTATE_FALLBACK_INITIALIZED]); + }, 0); + } + }, 'RouterOutlet_component_useOnDocument_event_KnNE9eL0qfc') + ) + ); + const context = useContext(ContentInternalContext); + if (context.value && context.value.length > 0) { + const contentsLen = context.value.length; + let cmp = null; + for (let i = contentsLen - 1; i >= 0; i--) + cmp = _jsxSplit( + context.value[i].default, + { + children: cmp, + }, + 1, + 'k8_0' + ); + return cmp; + } + return SkipRender; + }, 'RouterOutlet_component_AKetNByE5TM') +); +const MODULE_CACHE = /* @__PURE__ */ new WeakMap(); +const CLIENT_DATA_CACHE = /* @__PURE__ */ new Map(); +const QACTION_KEY = 'qaction'; +const toPath = (url) => url.pathname + url.search + url.hash; +const toUrl = (url, baseUrl) => new URL(url, baseUrl.href); +const isSameOrigin = (a, b) => a.origin === b.origin; +const isSamePath = (a, b) => a.pathname + a.search === b.pathname + b.search; +const isSamePathname = (a, b) => a.pathname === b.pathname; +const isSameOriginDifferentPathname = (a, b) => isSameOrigin(a, b) && !isSamePath(a, b); +const getClientDataPath = (pathname, pageSearch, action) => { + let search = pageSearch ?? ''; + if (action) search += (search ? '&' : '?') + QACTION_KEY + '=' + encodeURIComponent(action.id); + return pathname + (pathname.endsWith('/') ? '' : '/') + 'q-data.json' + search; +}; +const getClientNavPath = (props, baseUrl) => { + const href = props.href; + if (typeof href === 'string' && href.trim() !== '' && typeof props.target !== 'string') + try { + const linkUrl = toUrl(href, baseUrl.url); + const currentUrl = toUrl('', baseUrl.url); + if (isSameOrigin(linkUrl, currentUrl)) return toPath(linkUrl); + } catch (e) { + console.error(e); + } + else if (props.reload) return toPath(toUrl('', baseUrl.url)); + return null; +}; +const getPrefetchDataset = (props, clientNavPath, currentLoc) => { + if (props.prefetch === true && clientNavPath) { + const prefetchUrl = toUrl(clientNavPath, currentLoc.url); + if (!isSamePathname(prefetchUrl, toUrl('', currentLoc.url))) return ''; + } + return null; +}; +const clientNavigate = (win, newUrl, routeNavigate) => { + const currentUrl = win.location; + if (isSameOriginDifferentPathname(currentUrl, newUrl)) { + handleScroll(win, currentUrl, newUrl); + win.history.pushState('', '', toPath(newUrl)); + } + if (!win._qRouterHistory) { + win._qRouterHistory = 1; + win.addEventListener('popstate', () => { + const currentUrl2 = win.location; + const previousUrl = toUrl(routeNavigate.value, currentUrl2); + if (isSameOriginDifferentPathname(currentUrl2, previousUrl)) { + handleScroll(win, previousUrl, currentUrl2); + routeNavigate.value = toPath(new URL(currentUrl2.href)); + } + }); + win.removeEventListener('popstate', win._qRouterPopstateFallback); + } +}; +const handleScroll = async (win, previousUrl, newUrl) => { + const doc = win.document; + const newHash = newUrl.hash; + if (isSamePath(previousUrl, newUrl)) { + if (previousUrl.hash !== newHash) { + await domWait(); + if (newHash) scrollToHashId(doc, newHash); + else win.scrollTo(0, 0); + } + } else { + if (newHash) + for (let i = 0; i < 24; i++) { + await domWait(); + if (scrollToHashId(doc, newHash)) break; + } + else { + await domWait(); + win.scrollTo(0, 0); + } + } +}; +const domWait = () => new Promise((resolve) => setTimeout(resolve, 12)); +const scrollToHashId = (doc, hash) => { + const elmId = hash.slice(1); + const elm = doc.getElementById(elmId); + if (elm) elm.scrollIntoView(); + return elm; +}; +const dispatchPrefetchEvent = (prefetchData) => { + if (typeof document !== 'undefined') + document.dispatchEvent( + new CustomEvent('qprefetch', { + detail: prefetchData, + }) + ); +}; +const resolveHead = (endpoint, routeLocation, contentModules, locale) => { + const head = createDocumentHead(); + const getData = (loaderOrAction) => { + const id = loaderOrAction.__id; + if (loaderOrAction.__brand === 'server_loader') { + if (!(id in endpoint.loaders)) + throw new Error( + 'You can not get the returned data of a loader that has not been executed for this request.' + ); + } + const data = endpoint.loaders[id]; + if (data instanceof Promise) + throw new Error('Loaders returning a function can not be referred to in the head function.'); + return data; + }; + const headProps = { + head, + withLocale: (fn) => withLocale(locale, fn), + resolveValue: getData, + ...routeLocation, + }; + for (let i = contentModules.length - 1; i >= 0; i--) { + const contentModuleHead = contentModules[i] && contentModules[i].head; + if (contentModuleHead) { + if (typeof contentModuleHead === 'function') + resolveDocumentHead( + head, + withLocale(locale, () => contentModuleHead(headProps)) + ); + else if (typeof contentModuleHead === 'object') resolveDocumentHead(head, contentModuleHead); + } + } + return headProps.head; +}; +const resolveDocumentHead = (resolvedHead, updatedHead) => { + if (typeof updatedHead.title === 'string') resolvedHead.title = updatedHead.title; + mergeArray(resolvedHead.meta, updatedHead.meta); + mergeArray(resolvedHead.links, updatedHead.links); + mergeArray(resolvedHead.styles, updatedHead.styles); + Object.assign(resolvedHead.frontmatter, updatedHead.frontmatter); +}; +const mergeArray = (existingArr, newArr) => { + if (Array.isArray(newArr)) + for (const newItem of newArr) { + if (typeof newItem.key === 'string') { + const existingIndex = existingArr.findIndex((i) => i.key === newItem.key); + if (existingIndex > -1) { + existingArr[existingIndex] = newItem; + continue; + } + } + existingArr.push(newItem); + } +}; +const createDocumentHead = () => ({ + title: '', + meta: [], + links: [], + styles: [], + frontmatter: {}, +}); +const loadRoute = async (routes, menus, cacheModules, pathname) => { + if (Array.isArray(routes)) + for (const route of routes) { + const match = route[0].exec(pathname); + if (match) { + const loaders = route[1]; + const params = getPathParams(route[2], match); + const routeBundleNames = route[4]; + const mods = new Array(loaders.length); + const pendingLoads = []; + const menuLoader = getMenuLoader(menus, pathname); + let menu = void 0; + loaders.forEach((moduleLoader, i) => { + loadModule( + moduleLoader, + pendingLoads, + (routeModule) => (mods[i] = routeModule), + cacheModules + ); + }); + loadModule( + menuLoader, + pendingLoads, + (menuModule) => (menu = menuModule?.default), + cacheModules + ); + if (pendingLoads.length > 0) await Promise.all(pendingLoads); + return [params, mods, menu, routeBundleNames]; + } + } + return null; +}; +const loadModule = (moduleLoader, pendingLoads, moduleSetter, cacheModules) => { + if (typeof moduleLoader === 'function') { + const loadedModule = MODULE_CACHE.get(moduleLoader); + if (loadedModule) moduleSetter(loadedModule); + else { + const l = moduleLoader(); + if (typeof l.then === 'function') + pendingLoads.push( + l.then((loadedModule2) => { + if (cacheModules !== false) MODULE_CACHE.set(moduleLoader, loadedModule2); + moduleSetter(loadedModule2); + }) + ); + else if (l) moduleSetter(l); + } + } +}; +const getMenuLoader = (menus, pathname) => { + if (menus) { + pathname = pathname.endsWith('/') ? pathname : pathname + '/'; + const menu = menus.find( + (m) => m[0] === pathname || pathname.startsWith(m[0] + (pathname.endsWith('/') ? '' : '/')) + ); + if (menu) return menu[1]; + } +}; +const getPathParams = (paramNames, match) => { + const params = {}; + if (paramNames) + for (let i = 0; i < paramNames.length; i++) { + const param = match?.[i + 1] ?? ''; + const v = param.endsWith('/') ? param.slice(0, -1) : param; + params[paramNames[i]] = decodeURIComponent(v); + } + return params; +}; +const loadClientData = async (url, element, clearCache, action) => { + const pagePathname = url.pathname; + const pageSearch = url.search; + const clientDataPath = getClientDataPath(pagePathname, pageSearch, action); + let qData = void 0; + if (!action) qData = CLIENT_DATA_CACHE.get(clientDataPath); + dispatchPrefetchEvent({ + links: [pagePathname], + }); + if (!qData) { + const options = getFetchOptions(action); + if (action) action.data = void 0; + qData = fetch(clientDataPath, options).then((rsp) => { + const redirectedURL = new URL(rsp.url); + if (redirectedURL.origin !== location.origin || !isQDataJson(redirectedURL.pathname)) { + location.href = redirectedURL.href; + return; + } + if ((rsp.headers.get('content-type') || '').includes('json')) + return rsp.text().then((text) => { + const clientData = _deserializeData(text, element); + if (!clientData) { + location.href = url.href; + return; + } + if (clearCache) CLIENT_DATA_CACHE.delete(clientDataPath); + if (clientData.redirect) location.href = clientData.redirect; + else if (action) { + const actionData = clientData.loaders[action.id]; + action.resolve({ + status: rsp.status, + result: actionData, + }); + } + return clientData; + }); + else { + location.href = url.href; + return void 0; + } + }); + if (!action) CLIENT_DATA_CACHE.set(clientDataPath, qData); + } + return qData.then((v) => { + if (!v) CLIENT_DATA_CACHE.delete(clientDataPath); + return v; + }); +}; +const getFetchOptions = (action) => { + const actionData = action?.data; + if (!actionData) return void 0; + if (actionData instanceof FormData) + return { + method: 'POST', + body: actionData, + }; + else + return { + method: 'POST', + body: JSON.stringify(actionData), + headers: { + 'Content-Type': 'application/json, charset=UTF-8', + }, + }; +}; +const isQDataJson = (pathname) => { + return pathname.endsWith(QDATA_JSON); +}; +const QDATA_JSON = '/q-data.json'; +const useContent = () => useContext(ContentContext); +const useDocumentHead = () => useContext(DocumentHeadContext); +const useLocation = () => useContext(RouteLocationContext); +const useNavigate = () => useContext(RouteNavigateContext); +const useAction = () => useContext(RouteActionContext); +const useQwikRouterEnv = () => noSerialize(useServerData('qwikrouter')); +const QwikRouterProvider = /* @__PURE__ */ componentQrl( + /* @__PURE__ */ inlinedQrl((props) => { + useStylesQrl( + /* @__PURE__ */ inlinedQrl( + `:root{view-transition-name: none}`, + 'QwikRouterProvider_component_useStyles_RPDJAz33WLA' + ) + ); + const env = useQwikRouterEnv(); + if (!env?.params) throw new Error(`Missing Qwik Router Env Data`); + const urlEnv = useServerData('url'); + if (!urlEnv) throw new Error(`Missing Qwik URL Env Data`); + const url = new URL(urlEnv); + const routeLocation = useStore( + { + url, + params: env.params, + isNavigating: false, + }, + { + deep: false, + } + ); + const loaderState = _weakSerialize( + useStore(env.response.loaders, { + deep: false, + }) + ); + const navPath = useSignal(toPath(url)); + const documentHead = useStore(createDocumentHead); + const content = useStore({ + headings: void 0, + menu: void 0, + }); + const contentInternal = useSignal(); + const currentActionId = env.response.action; + const currentAction = currentActionId ? env.response.loaders[currentActionId] : void 0; + const actionState = useSignal( + currentAction + ? { + id: currentActionId, + data: env.response.formData, + output: { + result: currentAction, + status: env.response.status, + }, + } + : void 0 + ); + const goto = eventQrl( + /* @__PURE__ */ inlinedQrl( + async (path, forceReload) => { + const [actionState2, navPath2, routeLocation2] = useLexicalScope(); + if (path === void 0) { + path = navPath2.value; + navPath2.value = ''; + } else if (forceReload) navPath2.value = ''; + const resolvedURL = new URL(path, routeLocation2.url); + path = toPath(resolvedURL); + if (!forceReload && navPath2.value === path) return; + navPath2.value = path; + if (isBrowser) { + loadClientData(resolvedURL, _getContextElement()); + loadRoute( + qwikRouterConfig.routes, + qwikRouterConfig.menus, + qwikRouterConfig.cacheModules, + resolvedURL.pathname + ); + } + actionState2.value = void 0; + routeLocation2.isNavigating = true; + }, + 'QwikRouterProvider_component_goto_event_cBcjROynRVg', + [actionState, navPath, routeLocation] + ) + ); + useContextProvider(ContentContext, content); + useContextProvider(ContentInternalContext, contentInternal); + useContextProvider(DocumentHeadContext, documentHead); + useContextProvider(RouteLocationContext, routeLocation); + useContextProvider(RouteNavigateContext, goto); + useContextProvider(RouteStateContext, loaderState); + useContextProvider(RouteActionContext, actionState); + useTaskQrl( + /* @__PURE__ */ inlinedQrl( + ({ track }) => { + const [ + actionState2, + content2, + contentInternal2, + documentHead2, + env2, + loaderState2, + navPath2, + props2, + routeLocation2, + url2, + ] = useLexicalScope(); + async function run() { + const [path, action] = track(() => [navPath2.value, actionState2.value]); + const locale = getLocale(''); + let trackUrl; + let clientPageData; + let loadedRoute = null; + if (isServer) { + trackUrl = new URL(path, routeLocation2.url); + loadedRoute = env2.loadedRoute; + clientPageData = env2.response; + } else { + trackUrl = new URL(path, location); + if (trackUrl.pathname.endsWith('/')) { + if (!qwikRouterConfig.trailingSlash) + trackUrl.pathname = trackUrl.pathname.slice(0, -1); + } else if (qwikRouterConfig.trailingSlash) trackUrl.pathname += '/'; + let loadRoutePromise = loadRoute( + qwikRouterConfig.routes, + qwikRouterConfig.menus, + qwikRouterConfig.cacheModules, + trackUrl.pathname + ); + const element = _getContextElement(); + const pageData = (clientPageData = await loadClientData( + trackUrl, + element, + true, + action + )); + if (!pageData) { + navPath2.untrackedValue = toPath(trackUrl); + return; + } + const newHref = pageData.href; + const newURL = new URL(newHref, trackUrl.href); + if (newURL.pathname !== trackUrl.pathname) { + trackUrl = newURL; + loadRoutePromise = loadRoute( + qwikRouterConfig.routes, + qwikRouterConfig.menus, + qwikRouterConfig.cacheModules, + trackUrl.pathname + ); + } + loadedRoute = await loadRoutePromise; + } + if (loadedRoute) { + const [params, mods, menu] = loadedRoute; + const contentModules = mods; + const pageModule = contentModules[contentModules.length - 1]; + routeLocation2.url = trackUrl; + routeLocation2.params = { + ...params, + }; + navPath2.untrackedValue = toPath(trackUrl); + const resolvedHead = resolveHead( + clientPageData, + routeLocation2, + contentModules, + locale + ); + content2.headings = pageModule.headings; + content2.menu = menu; + contentInternal2.value = noSerialize(contentModules); + documentHead2.links = resolvedHead.links; + documentHead2.meta = resolvedHead.meta; + documentHead2.styles = resolvedHead.styles; + documentHead2.title = resolvedHead.title; + documentHead2.frontmatter = resolvedHead.frontmatter; + if (isBrowser) { + if ( + (props2.viewTransition ?? true) && + isSameOriginDifferentPathname(window.location, url2) + ) + document.__q_view_transition__ = true; + const loaders = clientPageData?.loaders; + if (loaders) Object.assign(loaderState2, loaders); + CLIENT_DATA_CACHE.clear(); + clientNavigate(window, trackUrl, navPath2); + routeLocation2.isNavigating = false; + } + } + } + const promise = run(); + if (isServer) return promise; + else return; + }, + 'QwikRouterProvider_component_useTask_02wMImzEAbk', + [ + actionState, + content, + contentInternal, + documentHead, + env, + loaderState, + navPath, + props, + routeLocation, + url, + ] + ) + ); + return /* @__PURE__ */ _jsxSplit(Slot, null, 3, 'qY_0'); + }, 'QwikRouterProvider_component_TxCFOy819ag') +); +const QwikRouterMockProvider = /* @__PURE__ */ componentQrl( + /* @__PURE__ */ inlinedQrl((props) => { + const urlEnv = props.url ?? 'http://localhost/'; + const url = new URL(urlEnv); + const routeLocation = useStore( + { + url, + params: props.params ?? {}, + isNavigating: false, + }, + { + deep: false, + } + ); + const loaderState = useSignal({}); + const goto = /* @__PURE__ */ inlinedQrl(async (path) => { + throw new Error('Not implemented'); + }, 'QwikRouterMockProvider_component_goto_BUbtvTyvVRE'); + const documentHead = useStore(createDocumentHead, { + deep: false, + }); + const content = useStore( + { + headings: void 0, + menu: void 0, + }, + { + deep: false, + } + ); + const contentInternal = useSignal(); + useContextProvider(ContentContext, content); + useContextProvider(ContentInternalContext, contentInternal); + useContextProvider(DocumentHeadContext, documentHead); + useContextProvider(RouteLocationContext, routeLocation); + useContextProvider(RouteNavigateContext, goto); + useContextProvider(RouteStateContext, loaderState); + return /* @__PURE__ */ _jsxSplit(Slot, null, 3, 'qY_1'); + }, 'QwikRouterMockProvider_component_WmYC5H00wtI') +); +const Link = /* @__PURE__ */ componentQrl( + /* @__PURE__ */ inlinedQrl((props) => { + const nav = useNavigate(); + const loc = useLocation(); + const linkProps = { + ...props, + }; + const clientNavPath = untrack(() => getClientNavPath(linkProps, loc)); + const prefetchDataset = untrack(() => getPrefetchDataset(props, clientNavPath, loc)); + const reload = !!linkProps.reload; + linkProps['preventdefault:click'] = !!clientNavPath; + linkProps.href = clientNavPath || props.href; + const event = eventQrl( + /* @__PURE__ */ inlinedQrl( + (ev, elm) => prefetchLinkResources(elm, ev.type === 'qvisible'), + 'Link_component_event_event_5g4B0Gd1Wck' + ) + ); + return /* @__PURE__ */ _jsxSplit( + 'a', + { + ...linkProps, + 'data-prefetch': prefetchDataset, + children: /* @__PURE__ */ _jsxSplit(Slot, null, null, 3, 'AD_0'), + onClick$: /* @__PURE__ */ inlinedQrl( + (_, elm) => { + const [nav2, reload2] = useLexicalScope(); + if (elm.href) nav2(elm.href, reload2); + }, + 'Link_component_a_onClick_kzjavhDI3L0', + [nav, reload] + ), + onMouseOver$: event, + onFocus$: event, + onQVisible$: event, + }, + null, + 0, + 'AD_1' + ); + }, 'Link_component_8gdLBszqbaM') +); +const prefetchLinkResources = (elm, isOnVisible) => { + if (elm && elm.href && elm.hasAttribute('data-prefetch')) { + if (!windowInnerWidth) windowInnerWidth = innerWidth; + if (!isOnVisible || (isOnVisible && windowInnerWidth < 520)) + loadClientData(new URL(elm.href), elm); + } +}; +let windowInnerWidth = 0; +const ServiceWorkerRegister = (props) => + _jsxSplit( + 'script', + null, + { + nonce: _wrapSignal(props, 'nonce'), + dangerouslySetInnerHTML: swRegister, + }, + 3, + '1Z_0' + ); +const routeActionQrl = (actionQrl, ...rest) => { + const { id, validators } = getValidators(rest, actionQrl); + function action() { + const loc = useLocation(); + const currentAction = useAction(); + const initialState = { + actionPath: `?${QACTION_KEY}=${id}`, + isRunning: false, + status: void 0, + value: void 0, + formData: void 0, + }; + const state = useStore(() => { + const value = currentAction.value; + if (value && value?.id === id) { + const data = value.data; + if (data instanceof FormData) initialState.formData = data; + if (value.output) { + const { status, result } = value.output; + initialState.status = status; + initialState.value = result; + } + } + return initialState; + }); + const submit = /* @__PURE__ */ inlinedQrl( + (input = {}) => { + const [currentAction2, id2, loc2, state2] = useLexicalScope(); + 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; + let form; + if (input instanceof SubmitEvent) { + form = input.target; + data = new FormData(form); + if ( + (input.submitter instanceof HTMLInputElement || + input.submitter instanceof HTMLButtonElement) && + input.submitter.name + ) { + if (input.submitter.name) data.append(input.submitter.name, input.submitter.value); + } + } else data = input; + return new Promise((resolve) => { + if (data instanceof FormData) state2.formData = data; + state2.isRunning = true; + loc2.isNavigating = true; + currentAction2.value = { + data, + id: id2, + resolve: noSerialize(resolve), + }; + }).then(({ result, status }) => { + state2.isRunning = false; + state2.status = status; + state2.value = result; + if (form) { + if (form.getAttribute('data-spa-reset') === 'true') form.reset(); + const detail = { + status, + value: result, + }; + form.dispatchEvent( + new CustomEvent('submitcompleted', { + bubbles: false, + cancelable: false, + composed: false, + detail, + }) + ); + } + return { + status, + value: result, + }; + }); + }, + 'routeActionQrl_action_submit_A5bZC7WO00A', + [currentAction, id, loc, state] + ); + initialState.submit = submit; + return state; + } + action.__brand = 'server_action'; + action.__validators = validators; + action.__qrl = actionQrl; + action.__id = id; + Object.freeze(action); + return action; +}; +const globalActionQrl = (actionQrl, ...rest) => { + const action = routeActionQrl(actionQrl, ...rest); + if (isServer) { + if (typeof globalThis._qwikActionsMap === 'undefined') + globalThis._qwikActionsMap = /* @__PURE__ */ new Map(); + globalThis._qwikActionsMap.set(action.__id, action); + } + return action; +}; +const routeAction$ = /* @__PURE__ */ implicit$FirstArg(routeActionQrl); +const globalAction$ = /* @__PURE__ */ implicit$FirstArg(globalActionQrl); +const routeLoaderQrl = (loaderQrl, ...rest) => { + const { id, validators } = getValidators(rest, loaderQrl); + function loader() { + return useContext(RouteStateContext, (state) => { + if (!(id in state)) + throw new Error(`Loader (${id}) was used in a path where the 'loader$' was not declared. + This is likely because the used loader was not exported in a layout.tsx or index.tsx file of the existing route. + For more information check: https://qwik.dev/docs/route-loader/`); + return _wrapSignal(state, id); + }); + } + loader.__brand = 'server_loader'; + loader.__qrl = loaderQrl; + loader.__validators = validators; + loader.__id = id; + Object.freeze(loader); + return loader; +}; +const routeLoader$ = /* @__PURE__ */ implicit$FirstArg(routeLoaderQrl); +const validatorQrl = (validator) => { + if (isServer) + return { + validate: validator, + }; + return void 0; +}; +const validator$ = /* @__PURE__ */ implicit$FirstArg(validatorQrl); +const zodQrl = (qrl) => { + if (isServer) { + const schema = qrl.resolve().then((obj) => { + if (typeof obj === 'function') obj = obj(z); + if (obj instanceof z.Schema) return obj; + else return z.object(obj); + }); + return { + async validate(ev, inputData) { + const data = inputData ?? (await ev.parseBody()); + const result = await (await schema).safeParseAsync(data); + if (result.success) return result; + else { + if (isDev) + console.error( + '\nVALIDATION ERROR\naction$() zod validated failed', + '\n - Issues:', + result.error.issues + ); + return { + success: false, + status: 400, + error: result.error.flatten(), + }; + } + }, + }; + } + return void 0; +}; +const zod$ = /* @__PURE__ */ implicit$FirstArg(zodQrl); +const serverQrl = (qrl) => { + if (isServer) { + const captured = qrl.getCaptured(); + if (captured && captured.length > 0 && !_getContextElement()) + throw new Error('For security reasons, we cannot serialize QRLs that capture lexical scope.'); + } + function stuff() { + return /* @__PURE__ */ inlinedQrl( + async (...args) => { + const [qrl2] = useLexicalScope(); + if (isServer) { + const requestEvent = useQwikRouterEnv()?.ev; + return qrl2.apply(requestEvent, args); + } else { + const ctxElm = _getContextElement(); + const filtered = args.map((arg) => { + if (arg instanceof SubmitEvent && arg.target instanceof HTMLFormElement) + return new FormData(arg.target); + else if (arg instanceof Event) return null; + else if (arg instanceof Node) return null; + return arg; + }); + const hash = qrl2.getHash(); + const path = `?qfunc=${qrl2.getHash()}`; + const body = await _serializeData([qrl2, ...filtered], false); + const res = await fetch(path, { + method: 'POST', + headers: { + 'Content-Type': 'application/qwik-json', + 'X-QRL': hash, + }, + body, + }); + const contentType = res.headers.get('Content-Type'); + if (res.ok && contentType === 'text/event-stream') { + const { writable, readable } = getSSETransformer(); + res.body?.pipeTo(writable); + return streamAsyncIterator(readable, ctxElm ?? document.documentElement); + } else if (contentType === 'application/qwik-json') { + const str = await res.text(); + const obj = await _deserializeData(str, ctxElm ?? document.documentElement); + if (res.status === 500) throw obj; + return obj; + } + } + }, + 'serverQrl_stuff_wOIPfiQ04l4', + [qrl] + ); + } + return stuff(); +}; +const server$ = /* @__PURE__ */ implicit$FirstArg(serverQrl); +const getValidators = (rest, qrl) => { + let id; + const validators = []; + if (rest.length === 1) { + const options = rest[0]; + if (options && typeof options === 'object') { + if ('validate' in options) validators.push(options); + else { + id = options.id; + if (options.validation) validators.push(...options.validation); + } + } + } else if (rest.length > 1) validators.push(...rest.filter((v) => !!v)); + if (typeof id === 'string') { + if (isDev) { + if (!/^[\w/.-]+$/.test(id)) + throw new Error(`Invalid id: ${id}, id can only contain [a-zA-Z0-9_.-]`); + } + id = `id_${id}`; + } else id = qrl.getHash(); + return { + validators: validators.reverse(), + id, + }; +}; +const getSSETransformer = () => { + let currentLine = ''; + const encoder = new TextDecoder(); + const transformer = new TransformStream({ + transform(chunk, controller) { + const lines = encoder.decode(chunk).split('\n\n'); + for (let i = 0; i < lines.length - 1; i++) { + const line = currentLine + lines[i]; + if (line.length === 0) { + controller.terminate(); + break; + } else { + controller.enqueue(parseEvent(line)); + currentLine = ''; + } + } + currentLine += lines[lines.length - 1]; + }, + }); + return transformer; +}; +const parseEvent = (message) => { + const lines = message.split('\n'); + const event = { + data: '', + }; + let data = ''; + for (const line of lines) + if (line.startsWith('data: ')) data += line.slice(6) + '\n'; + else { + const [key, value] = line.split(':'); + if (typeof key === 'string' && typeof value === 'string') event[key] = value.trim(); + } + event.data = data; + return event; +}; +async function* streamAsyncIterator(stream, ctxElm) { + const reader = stream.getReader(); + try { + while (true) { + const { done, value } = await reader.read(); + if (done) return; + const obj = await _deserializeData(value.data, ctxElm); + yield obj; + } + } finally { + reader.releaseLock(); + } +} +const Form = ({ action, spaReset, reloadDocument, onSubmit$, ...rest }, key) => { + _jsxBranch(); + if (action) + return _jsxSplit( + 'form', + { + ...rest, + action: _wrapSignal(action, 'actionPath'), + 'preventdefault:submit': !reloadDocument, + ['data-spa-reset']: spaReset ? 'true' : void 0, + onSubmit$: [!reloadDocument ? action.submit : void 0, onSubmit$], + }, + { + method: 'post', + }, + 0, + key + ); + else + return /* @__PURE__ */ _jsxSplit( + GetForm, + { + spaReset, + reloadDocument, + onSubmit$, + ...rest, + }, + 0, + key + ); +}; +const GetForm = /* @__PURE__ */ componentQrl( + /* @__PURE__ */ inlinedQrl((props) => { + const rest = _restProps(props, ['action', 'spaReset', 'reloadDocument', 'onSubmit$']); + const nav = useNavigate(); + return /* @__PURE__ */ _jsxSplit( + 'form', + { + ...rest, + children: /* @__PURE__ */ _jsxSplit(Slot, null, 3, 'BC_0'), + onSubmit$: /* @__PURE__ */ inlinedQrl( + async (_, form) => { + const [nav2] = useLexicalScope(); + const formData = new FormData(form); + const params = new URLSearchParams(); + formData.forEach((value, key) => { + if (typeof value === 'string') params.append(key, value); + }); + nav2('?' + params.toString(), true).then(() => { + if (form.getAttribute('data-spa-reset') === 'true') form.reset(); + form.dispatchEvent( + new CustomEvent('submitcompleted', { + bubbles: false, + cancelable: false, + composed: false, + detail: { + status: 200, + }, + }) + ); + }); + }, + 'GetForm_component_form_onSubmit_p9MSze0ojs4', + [nav] + ), + }, + { + action: 'get', + 'preventdefault:submit': _fnSignal( + (p0) => !p0.reloadDocument, + [props], + '!p0.reloadDocument' + ), + 'data-spa-reset': _fnSignal( + (p0) => (p0.spaReset ? 'true' : void 0), + [props], + 'p0.spaReset?"true":undefined' + ), + }, + 0, + 'BC_1' + ); + }, 'GetForm_component_Nk9PlpjQm9Y') +); +export { + Form, + globalAction$, + globalActionQrl, + Link, + QwikRouterMockProvider, + QwikRouterProvider as QwikRouterProvider, + routeAction$, + routeActionQrl, + routeLoader$, + routeLoaderQrl, + RouterOutlet, + server$, + serverQrl, + ServiceWorkerRegister, + useContent, + useDocumentHead, + useLocation, + useNavigate, + validator$, + validatorQrl, + z2 as z, + zod$, + zodQrl, +}; + +============================= ../node_modules/@qwik.dev/router/index.qwik.mjs == + +import { _addLoc } from "@qwik.dev/core/internal"; +import * as qwikRouterConfig from '@qwik-router-config'; +import swRegister from '@qwik-router-sw-register'; +import { _deserializeData, _fnSignal, _getContextElement, _jsxBranch, _jsxSplit, _restProps, _serializeData, _weakSerialize, _wrapSignal, componentQrl, createContextId, eventQrl, getLocale, implicit$FirstArg, inlinedQrl, noSerialize, SkipRender, Slot, untrack, useContext, useContextProvider, useLexicalScope, useOnDocument, useServerData, useSignal, useStore, useStylesQrl, useTaskQrl, withLocale } from '@qwik.dev/core'; +import { isBrowser, isDev, isServer } from '@qwik.dev/core/build'; +import { z, z as z2 } from 'zod'; +const RouteStateContext = /* @__PURE__ */ _addLoc(createContextId('qc-s'), "../node_modules/@qwik.dev/router/index.qwik.mjs", 37, 43); +const ContentContext = /* @__PURE__ */ _addLoc(createContextId('qc-c'), "../node_modules/@qwik.dev/router/index.qwik.mjs", 38, 40); +const ContentInternalContext = /* @__PURE__ */ _addLoc(createContextId('qc-ic'), "../node_modules/@qwik.dev/router/index.qwik.mjs", 39, 48); +const DocumentHeadContext = /* @__PURE__ */ _addLoc(createContextId('qc-h'), "../node_modules/@qwik.dev/router/index.qwik.mjs", 40, 45); +const RouteLocationContext = /* @__PURE__ */ _addLoc(createContextId('qc-l'), "../node_modules/@qwik.dev/router/index.qwik.mjs", 41, 46); +const RouteNavigateContext = /* @__PURE__ */ _addLoc(createContextId('qc-n'), "../node_modules/@qwik.dev/router/index.qwik.mjs", 42, 46); +const RouteActionContext = /* @__PURE__ */ _addLoc(createContextId('qc-a'), "../node_modules/@qwik.dev/router/index.qwik.mjs", 43, 44); +const RouterOutlet = /* @__PURE__ */ _addLoc(componentQrl(/* @__PURE__ */ inlinedQrl(()=>{ + _jsxBranch(); + useOnDocument('qinit', eventQrl(/* @__PURE__ */ inlinedQrl(()=>{ + const POPSTATE_FALLBACK_INITIALIZED = _addLoc('_qRouterPopstateFallback', "../node_modules/@qwik.dev/router/index.qwik.mjs", 51, 49); + const CLIENT_HISTORY_INITIALIZED = _addLoc('_qRouterHistory', "../node_modules/@qwik.dev/router/index.qwik.mjs", 52, 46); + if (!window[POPSTATE_FALLBACK_INITIALIZED]) { + window[POPSTATE_FALLBACK_INITIALIZED] = ()=>{ + if (!window[CLIENT_HISTORY_INITIALIZED]) location.reload(); + }; + setTimeout(()=>{ + addEventListener('popstate', window[POPSTATE_FALLBACK_INITIALIZED]); + }, 0); + } + }, 'RouterOutlet_component_useOnDocument_event_KnNE9eL0qfc'))); + const context = _addLoc(useContext(ContentInternalContext), "../node_modules/@qwik.dev/router/index.qwik.mjs", 64, 21); + if (context.value && context.value.length > 0) { + const contentsLen = _addLoc(context.value.length, "../node_modules/@qwik.dev/router/index.qwik.mjs", 66, 27); + let cmp = _addLoc(null, "../node_modules/@qwik.dev/router/index.qwik.mjs", 67, 17); + for(let i = _addLoc(contentsLen - 1, "../node_modules/@qwik.dev/router/index.qwik.mjs", 68, 20); i >= 0; i--)cmp = _jsxSplit(context.value[i].default, { + children: cmp + }, 1, 'k8_0'); + return cmp; + } + return SkipRender; +}, 'RouterOutlet_component_AKetNByE5TM')), "../node_modules/@qwik.dev/router/index.qwik.mjs", 44, 38); +const MODULE_CACHE = /* @__PURE__ */ _addLoc(new WeakMap(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 82, 38); +const CLIENT_DATA_CACHE = /* @__PURE__ */ _addLoc(new Map(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 83, 43); +const QACTION_KEY = _addLoc('qaction', "../node_modules/@qwik.dev/router/index.qwik.mjs", 84, 21); +const toPath = _addLoc((url)=>url.pathname + url.search + url.hash, "../node_modules/@qwik.dev/router/index.qwik.mjs", 85, 16); +const toUrl = _addLoc((url, baseUrl)=>new URL(url, baseUrl.href), "../node_modules/@qwik.dev/router/index.qwik.mjs", 86, 15); +const isSameOrigin = _addLoc((a, b)=>a.origin === b.origin, "../node_modules/@qwik.dev/router/index.qwik.mjs", 87, 22); +const isSamePath = _addLoc((a, b)=>a.pathname + a.search === b.pathname + b.search, "../node_modules/@qwik.dev/router/index.qwik.mjs", 88, 20); +const isSamePathname = _addLoc((a, b)=>a.pathname === b.pathname, "../node_modules/@qwik.dev/router/index.qwik.mjs", 89, 24); +const isSameOriginDifferentPathname = _addLoc((a, b)=>isSameOrigin(a, b) && !isSamePath(a, b), "../node_modules/@qwik.dev/router/index.qwik.mjs", 90, 39); +const getClientDataPath = _addLoc((pathname, pageSearch, action)=>{ + let search = _addLoc(pageSearch ?? '', "../node_modules/@qwik.dev/router/index.qwik.mjs", 92, 16); + if (action) search += (search ? '&' : '?') + QACTION_KEY + '=' + encodeURIComponent(action.id); + return pathname + (pathname.endsWith('/') ? '' : '/') + 'q-data.json' + search; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 91, 27); +const getClientNavPath = _addLoc((props, baseUrl)=>{ + const href = _addLoc(props.href, "../node_modules/@qwik.dev/router/index.qwik.mjs", 97, 16); + if (typeof href === 'string' && href.trim() !== '' && typeof props.target !== 'string') try { + const linkUrl = _addLoc(toUrl(href, baseUrl.url), "../node_modules/@qwik.dev/router/index.qwik.mjs", 100, 23); + const currentUrl = _addLoc(toUrl('', baseUrl.url), "../node_modules/@qwik.dev/router/index.qwik.mjs", 101, 26); + if (isSameOrigin(linkUrl, currentUrl)) return toPath(linkUrl); + } catch (e) { + console.error(e); + } + else if (props.reload) return toPath(toUrl('', baseUrl.url)); + return null; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 96, 26); +const getPrefetchDataset = _addLoc((props, clientNavPath, currentLoc)=>{ + if (props.prefetch === true && clientNavPath) { + const prefetchUrl = _addLoc(toUrl(clientNavPath, currentLoc.url), "../node_modules/@qwik.dev/router/index.qwik.mjs", 111, 25); + if (!isSamePathname(prefetchUrl, toUrl('', currentLoc.url))) return ''; + } + return null; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 109, 28); +const clientNavigate = _addLoc((win, newUrl, routeNavigate)=>{ + const currentUrl = _addLoc(win.location, "../node_modules/@qwik.dev/router/index.qwik.mjs", 117, 22); + if (isSameOriginDifferentPathname(currentUrl, newUrl)) { + handleScroll(win, currentUrl, newUrl); + win.history.pushState('', '', toPath(newUrl)); + } + if (!win._qRouterHistory) { + win._qRouterHistory = 1; + win.addEventListener('popstate', ()=>{ + const currentUrl2 = _addLoc(win.location, "../node_modules/@qwik.dev/router/index.qwik.mjs", 125, 27); + const previousUrl = _addLoc(toUrl(routeNavigate.value, currentUrl2), "../node_modules/@qwik.dev/router/index.qwik.mjs", 126, 27); + if (isSameOriginDifferentPathname(currentUrl2, previousUrl)) { + handleScroll(win, previousUrl, currentUrl2); + routeNavigate.value = toPath(new URL(currentUrl2.href)); + } + }); + win.removeEventListener('popstate', win._qRouterPopstateFallback); + } +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 116, 24); +const handleScroll = _addLoc(async (win, previousUrl, newUrl)=>{ + const doc = _addLoc(win.document, "../node_modules/@qwik.dev/router/index.qwik.mjs", 136, 15); + const newHash = _addLoc(newUrl.hash, "../node_modules/@qwik.dev/router/index.qwik.mjs", 137, 19); + if (isSamePath(previousUrl, newUrl)) { + if (previousUrl.hash !== newHash) { + await domWait(); + if (newHash) scrollToHashId(doc, newHash); + else win.scrollTo(0, 0); + } + } else { + if (newHash) for(let i = _addLoc(0, "../node_modules/@qwik.dev/router/index.qwik.mjs", 146, 20); i < 24; i++){ + await domWait(); + if (scrollToHashId(doc, newHash)) break; + } + else { + await domWait(); + win.scrollTo(0, 0); + } + } +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 135, 22); +const domWait = _addLoc(()=>new Promise((resolve)=>setTimeout(resolve, 12)), "../node_modules/@qwik.dev/router/index.qwik.mjs", 156, 17); +const scrollToHashId = _addLoc((doc, hash)=>{ + const elmId = _addLoc(hash.slice(1), "../node_modules/@qwik.dev/router/index.qwik.mjs", 158, 17); + const elm = _addLoc(doc.getElementById(elmId), "../node_modules/@qwik.dev/router/index.qwik.mjs", 159, 15); + if (elm) elm.scrollIntoView(); + return elm; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 157, 24); +const dispatchPrefetchEvent = _addLoc((prefetchData)=>{ + if (typeof document !== 'undefined') document.dispatchEvent(new CustomEvent('qprefetch', { + detail: prefetchData + })); +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 163, 31); +const resolveHead = _addLoc((endpoint, routeLocation, contentModules, locale)=>{ + const head = _addLoc(createDocumentHead(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 172, 16); + const getData = _addLoc((loaderOrAction)=>{ + const id = _addLoc(loaderOrAction.__id, "../node_modules/@qwik.dev/router/index.qwik.mjs", 174, 16); + if (loaderOrAction.__brand === 'server_loader') { + if (!(id in endpoint.loaders)) throw new Error('You can not get the returned data of a loader that has not been executed for this request.'); + } + const data = _addLoc(endpoint.loaders[id], "../node_modules/@qwik.dev/router/index.qwik.mjs", 181, 18); + if (data instanceof Promise) throw new Error('Loaders returning a function can not be referred to in the head function.'); + return data; + }, "../node_modules/@qwik.dev/router/index.qwik.mjs", 173, 19); + const headProps = _addLoc({ + head, + withLocale: (fn)=>withLocale(locale, fn), + resolveValue: getData, + ...routeLocation + }, "../node_modules/@qwik.dev/router/index.qwik.mjs", 186, 21); + for(let i = _addLoc(contentModules.length - 1, "../node_modules/@qwik.dev/router/index.qwik.mjs", 192, 16); i >= 0; i--){ + const contentModuleHead = _addLoc(contentModules[i] && contentModules[i].head, "../node_modules/@qwik.dev/router/index.qwik.mjs", 193, 31); + if (contentModuleHead) { + if (typeof contentModuleHead === 'function') resolveDocumentHead(head, withLocale(locale, ()=>contentModuleHead(headProps))); + else if (typeof contentModuleHead === 'object') resolveDocumentHead(head, contentModuleHead); + } + } + return headProps.head; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 171, 21); +const resolveDocumentHead = _addLoc((resolvedHead, updatedHead)=>{ + if (typeof updatedHead.title === 'string') resolvedHead.title = updatedHead.title; + mergeArray(resolvedHead.meta, updatedHead.meta); + mergeArray(resolvedHead.links, updatedHead.links); + mergeArray(resolvedHead.styles, updatedHead.styles); + Object.assign(resolvedHead.frontmatter, updatedHead.frontmatter); +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 205, 29); +const mergeArray = _addLoc((existingArr, newArr)=>{ + if (Array.isArray(newArr)) for (const newItem of newArr){ + if (typeof newItem.key === 'string') { + const existingIndex = _addLoc(existingArr.findIndex((i)=>i.key === newItem.key), "../node_modules/@qwik.dev/router/index.qwik.mjs", 216, 31); + if (existingIndex > -1) { + existingArr[existingIndex] = newItem; + continue; + } + } + existingArr.push(newItem); + } +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 212, 20); +const createDocumentHead = _addLoc(()=>({ + title: '', + meta: [], + links: [], + styles: [], + frontmatter: {} + }), "../node_modules/@qwik.dev/router/index.qwik.mjs", 225, 28); +const loadRoute = _addLoc(async (routes, menus, cacheModules, pathname)=>{ + if (Array.isArray(routes)) for (const route of routes){ + const match = _addLoc(route[0].exec(pathname), "../node_modules/@qwik.dev/router/index.qwik.mjs", 235, 21); + if (match) { + const loaders = _addLoc(route[1], "../node_modules/@qwik.dev/router/index.qwik.mjs", 237, 25); + const params = _addLoc(getPathParams(route[2], match), "../node_modules/@qwik.dev/router/index.qwik.mjs", 238, 24); + const routeBundleNames = _addLoc(route[4], "../node_modules/@qwik.dev/router/index.qwik.mjs", 239, 34); + const mods = _addLoc(new Array(loaders.length), "../node_modules/@qwik.dev/router/index.qwik.mjs", 240, 22); + const pendingLoads = _addLoc([], "../node_modules/@qwik.dev/router/index.qwik.mjs", 241, 30); + const menuLoader = _addLoc(getMenuLoader(menus, pathname), "../node_modules/@qwik.dev/router/index.qwik.mjs", 242, 28); + let menu = _addLoc(void 0, "../node_modules/@qwik.dev/router/index.qwik.mjs", 243, 20); + loaders.forEach((moduleLoader, i)=>{ + loadModule(moduleLoader, pendingLoads, (routeModule)=>mods[i] = routeModule, cacheModules); + }); + loadModule(menuLoader, pendingLoads, (menuModule)=>menu = menuModule?.default, cacheModules); + if (pendingLoads.length > 0) await Promise.all(pendingLoads); + return [ + params, + mods, + menu, + routeBundleNames + ]; + } + } + return null; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 232, 19); +const loadModule = _addLoc((moduleLoader, pendingLoads, moduleSetter, cacheModules)=>{ + if (typeof moduleLoader === 'function') { + const loadedModule = _addLoc(MODULE_CACHE.get(moduleLoader), "../node_modules/@qwik.dev/router/index.qwik.mjs", 266, 26); + if (loadedModule) moduleSetter(loadedModule); + else { + const l = _addLoc(moduleLoader(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 269, 17); + if (typeof l.then === 'function') pendingLoads.push(l.then((loadedModule2)=>{ + if (cacheModules !== false) MODULE_CACHE.set(moduleLoader, loadedModule2); + moduleSetter(loadedModule2); + })); + else if (l) moduleSetter(l); + } + } +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 264, 20); +const getMenuLoader = _addLoc((menus, pathname)=>{ + if (menus) { + pathname = pathname.endsWith('/') ? pathname : pathname + '/'; + const menu = _addLoc(menus.find((m)=>m[0] === pathname || pathname.startsWith(m[0] + (pathname.endsWith('/') ? '' : '/'))), "../node_modules/@qwik.dev/router/index.qwik.mjs", 284, 18); + if (menu) return menu[1]; + } +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 281, 23); +const getPathParams = _addLoc((paramNames, match)=>{ + const params = _addLoc({}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 291, 18); + if (paramNames) for(let i = _addLoc(0, "../node_modules/@qwik.dev/router/index.qwik.mjs", 293, 18); i < paramNames.length; i++){ + const param = _addLoc(match?.[i + 1] ?? '', "../node_modules/@qwik.dev/router/index.qwik.mjs", 294, 21); + const v = _addLoc(param.endsWith('/') ? param.slice(0, -1) : param, "../node_modules/@qwik.dev/router/index.qwik.mjs", 295, 17); + params[paramNames[i]] = decodeURIComponent(v); + } + return params; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 290, 23); +const loadClientData = _addLoc(async (url, element, clearCache, action)=>{ + const pagePathname = _addLoc(url.pathname, "../node_modules/@qwik.dev/router/index.qwik.mjs", 301, 24); + const pageSearch = _addLoc(url.search, "../node_modules/@qwik.dev/router/index.qwik.mjs", 302, 22); + const clientDataPath = _addLoc(getClientDataPath(pagePathname, pageSearch, action), "../node_modules/@qwik.dev/router/index.qwik.mjs", 303, 26); + let qData = _addLoc(void 0, "../node_modules/@qwik.dev/router/index.qwik.mjs", 304, 15); + if (!action) qData = CLIENT_DATA_CACHE.get(clientDataPath); + dispatchPrefetchEvent({ + links: [ + pagePathname + ] + }); + if (!qData) { + const options = _addLoc(getFetchOptions(action), "../node_modules/@qwik.dev/router/index.qwik.mjs", 310, 21); + if (action) action.data = void 0; + qData = fetch(clientDataPath, options).then((rsp)=>{ + const redirectedURL = _addLoc(new URL(rsp.url), "../node_modules/@qwik.dev/router/index.qwik.mjs", 313, 29); + if (redirectedURL.origin !== location.origin || !isQDataJson(redirectedURL.pathname)) { + location.href = redirectedURL.href; + return; + } + if ((rsp.headers.get('content-type') || '').includes('json')) return rsp.text().then((text)=>{ + const clientData = _addLoc(_deserializeData(text, element), "../node_modules/@qwik.dev/router/index.qwik.mjs", 320, 30); + if (!clientData) { + location.href = url.href; + return; + } + if (clearCache) CLIENT_DATA_CACHE.delete(clientDataPath); + if (clientData.redirect) location.href = clientData.redirect; + else if (action) { + const actionData = _addLoc(clientData.loaders[action.id], "../node_modules/@qwik.dev/router/index.qwik.mjs", 328, 32); + action.resolve({ + status: rsp.status, + result: actionData + }); + } + return clientData; + }); + else { + location.href = url.href; + return void 0; + } + }); + if (!action) CLIENT_DATA_CACHE.set(clientDataPath, qData); + } + return qData.then((v)=>{ + if (!v) CLIENT_DATA_CACHE.delete(clientDataPath); + return v; + }); +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 300, 24); +const getFetchOptions = _addLoc((action)=>{ + const actionData = _addLoc(action?.data, "../node_modules/@qwik.dev/router/index.qwik.mjs", 349, 22); + if (!actionData) return void 0; + if (actionData instanceof FormData) return { + method: 'POST', + body: actionData + }; + else return { + method: 'POST', + body: JSON.stringify(actionData), + headers: { + 'Content-Type': 'application/json, charset=UTF-8' + } + }; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 348, 25); +const isQDataJson = _addLoc((pathname)=>{ + return pathname.endsWith(QDATA_JSON); +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 365, 21); +const QDATA_JSON = _addLoc('/q-data.json', "../node_modules/@qwik.dev/router/index.qwik.mjs", 368, 20); +const useContent = _addLoc(()=>useContext(ContentContext), "../node_modules/@qwik.dev/router/index.qwik.mjs", 369, 20); +const useDocumentHead = _addLoc(()=>useContext(DocumentHeadContext), "../node_modules/@qwik.dev/router/index.qwik.mjs", 370, 25); +const useLocation = _addLoc(()=>useContext(RouteLocationContext), "../node_modules/@qwik.dev/router/index.qwik.mjs", 371, 21); +const useNavigate = _addLoc(()=>useContext(RouteNavigateContext), "../node_modules/@qwik.dev/router/index.qwik.mjs", 372, 21); +const useAction = _addLoc(()=>useContext(RouteActionContext), "../node_modules/@qwik.dev/router/index.qwik.mjs", 373, 19); +const useQwikRouterEnv = _addLoc(()=>noSerialize(useServerData('qwikrouter')), "../node_modules/@qwik.dev/router/index.qwik.mjs", 374, 26); +const QwikRouterProvider = /* @__PURE__ */ _addLoc(componentQrl(/* @__PURE__ */ inlinedQrl((props)=>{ + useStylesQrl(/* @__PURE__ */ inlinedQrl(`:root{view-transition-name: none}`, 'QwikRouterProvider_component_useStyles_RPDJAz33WLA')); + const env = _addLoc(useQwikRouterEnv(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 383, 17); + if (!env?.params) throw new Error(`Missing Qwik Router Env Data`); + const urlEnv = _addLoc(useServerData('url'), "../node_modules/@qwik.dev/router/index.qwik.mjs", 385, 20); + if (!urlEnv) throw new Error(`Missing Qwik URL Env Data`); + const url = _addLoc(new URL(urlEnv), "../node_modules/@qwik.dev/router/index.qwik.mjs", 387, 17); + const routeLocation = _addLoc(useStore({ + url, + params: env.params, + isNavigating: false + }, { + deep: false + }), "../node_modules/@qwik.dev/router/index.qwik.mjs", 388, 27); + const loaderState = _addLoc(_weakSerialize(useStore(env.response.loaders, { + deep: false + })), "../node_modules/@qwik.dev/router/index.qwik.mjs", 398, 25); + const navPath = _addLoc(useSignal(toPath(url)), "../node_modules/@qwik.dev/router/index.qwik.mjs", 403, 21); + const documentHead = _addLoc(useStore(createDocumentHead), "../node_modules/@qwik.dev/router/index.qwik.mjs", 404, 26); + const content = _addLoc(useStore({ + headings: void 0, + menu: void 0 + }), "../node_modules/@qwik.dev/router/index.qwik.mjs", 405, 21); + const contentInternal = _addLoc(useSignal(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 409, 29); + const currentActionId = _addLoc(env.response.action, "../node_modules/@qwik.dev/router/index.qwik.mjs", 410, 29); + const currentAction = _addLoc(currentActionId ? env.response.loaders[currentActionId] : void 0, "../node_modules/@qwik.dev/router/index.qwik.mjs", 411, 27); + const actionState = _addLoc(useSignal(currentAction ? { + id: currentActionId, + data: env.response.formData, + output: { + result: currentAction, + status: env.response.status + } + } : void 0), "../node_modules/@qwik.dev/router/index.qwik.mjs", 412, 25); + const goto = _addLoc(eventQrl(/* @__PURE__ */ inlinedQrl(async (path, forceReload)=>{ + const [actionState2, navPath2, routeLocation2] = useLexicalScope(); + if (path === void 0) { + path = navPath2.value; + navPath2.value = ''; + } else if (forceReload) navPath2.value = ''; + const resolvedURL = _addLoc(new URL(path, routeLocation2.url), "../node_modules/@qwik.dev/router/index.qwik.mjs", 432, 31); + path = toPath(resolvedURL); + if (!forceReload && navPath2.value === path) return; + navPath2.value = path; + if (isBrowser) { + loadClientData(resolvedURL, _getContextElement()); + loadRoute(qwikRouterConfig.routes, qwikRouterConfig.menus, qwikRouterConfig.cacheModules, resolvedURL.pathname); + } + actionState2.value = void 0; + routeLocation2.isNavigating = true; + }, 'QwikRouterProvider_component_goto_event_cBcjROynRVg', [ + actionState, + navPath, + routeLocation + ])), "../node_modules/@qwik.dev/router/index.qwik.mjs", 424, 18); + useContextProvider(ContentContext, content); + useContextProvider(ContentInternalContext, contentInternal); + useContextProvider(DocumentHeadContext, documentHead); + useContextProvider(RouteLocationContext, routeLocation); + useContextProvider(RouteNavigateContext, goto); + useContextProvider(RouteStateContext, loaderState); + useContextProvider(RouteActionContext, actionState); + useTaskQrl(/* @__PURE__ */ inlinedQrl(({ track })=>{ + const [actionState2, content2, contentInternal2, documentHead2, env2, loaderState2, navPath2, props2, routeLocation2, url2] = useLexicalScope(); + async function run() { + const [path, action] = track(()=>[ + navPath2.value, + actionState2.value + ]); + const locale = _addLoc(getLocale(''), "../node_modules/@qwik.dev/router/index.qwik.mjs", 476, 28); + let trackUrl; + let clientPageData; + let loadedRoute = _addLoc(null, "../node_modules/@qwik.dev/router/index.qwik.mjs", 479, 31); + if (isServer) { + trackUrl = new URL(path, routeLocation2.url); + loadedRoute = env2.loadedRoute; + clientPageData = env2.response; + } else { + trackUrl = new URL(path, location); + if (trackUrl.pathname.endsWith('/')) { + if (!qwikRouterConfig.trailingSlash) trackUrl.pathname = trackUrl.pathname.slice(0, -1); + } else if (qwikRouterConfig.trailingSlash) trackUrl.pathname += '/'; + let loadRoutePromise = _addLoc(loadRoute(qwikRouterConfig.routes, qwikRouterConfig.menus, qwikRouterConfig.cacheModules, trackUrl.pathname), "../node_modules/@qwik.dev/router/index.qwik.mjs", 490, 38); + const element = _addLoc(_getContextElement(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 496, 31); + const pageData = _addLoc(clientPageData = await loadClientData(trackUrl, element, true, action), "../node_modules/@qwik.dev/router/index.qwik.mjs", 497, 32); + if (!pageData) { + navPath2.untrackedValue = toPath(trackUrl); + return; + } + const newHref = _addLoc(pageData.href, "../node_modules/@qwik.dev/router/index.qwik.mjs", 507, 31); + const newURL = _addLoc(new URL(newHref, trackUrl.href), "../node_modules/@qwik.dev/router/index.qwik.mjs", 508, 30); + if (newURL.pathname !== trackUrl.pathname) { + trackUrl = newURL; + loadRoutePromise = loadRoute(qwikRouterConfig.routes, qwikRouterConfig.menus, qwikRouterConfig.cacheModules, trackUrl.pathname); + } + loadedRoute = await loadRoutePromise; + } + if (loadedRoute) { + const [params, mods, menu] = loadedRoute; + const contentModules = _addLoc(mods, "../node_modules/@qwik.dev/router/index.qwik.mjs", 522, 38); + const pageModule = _addLoc(contentModules[contentModules.length - 1], "../node_modules/@qwik.dev/router/index.qwik.mjs", 523, 34); + routeLocation2.url = trackUrl; + routeLocation2.params = { + ...params + }; + navPath2.untrackedValue = toPath(trackUrl); + const resolvedHead = _addLoc(resolveHead(clientPageData, routeLocation2, contentModules, locale), "../node_modules/@qwik.dev/router/index.qwik.mjs", 529, 36); + content2.headings = pageModule.headings; + content2.menu = menu; + contentInternal2.value = noSerialize(contentModules); + documentHead2.links = resolvedHead.links; + documentHead2.meta = resolvedHead.meta; + documentHead2.styles = resolvedHead.styles; + documentHead2.title = resolvedHead.title; + documentHead2.frontmatter = resolvedHead.frontmatter; + if (isBrowser) { + if ((props2.viewTransition ?? true) && isSameOriginDifferentPathname(window.location, url2)) document.__q_view_transition__ = true; + const loaders = _addLoc(clientPageData?.loaders, "../node_modules/@qwik.dev/router/index.qwik.mjs", 549, 33); + if (loaders) Object.assign(loaderState2, loaders); + CLIENT_DATA_CACHE.clear(); + clientNavigate(window, trackUrl, navPath2); + routeLocation2.isNavigating = false; + } + } + } + const promise = _addLoc(run(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 557, 27); + if (isServer) return promise; + else return; + }, 'QwikRouterProvider_component_useTask_02wMImzEAbk', [ + actionState, + content, + contentInternal, + documentHead, + env, + loaderState, + navPath, + props, + routeLocation, + url + ])); + return /* @__PURE__ */ _jsxSplit(Slot, null, 3, 'qY_0'); +}, 'QwikRouterProvider_component_TxCFOy819ag')), "../node_modules/@qwik.dev/router/index.qwik.mjs", 375, 44); +const QwikRouterMockProvider = /* @__PURE__ */ _addLoc(componentQrl(/* @__PURE__ */ inlinedQrl((props)=>{ + const urlEnv = _addLoc(props.url ?? 'http://localhost/', "../node_modules/@qwik.dev/router/index.qwik.mjs", 581, 20); + const url = _addLoc(new URL(urlEnv), "../node_modules/@qwik.dev/router/index.qwik.mjs", 582, 17); + const routeLocation = _addLoc(useStore({ + url, + params: props.params ?? {}, + isNavigating: false + }, { + deep: false + }), "../node_modules/@qwik.dev/router/index.qwik.mjs", 583, 27); + const loaderState = _addLoc(useSignal({}), "../node_modules/@qwik.dev/router/index.qwik.mjs", 593, 25); + const goto = /* @__PURE__ */ _addLoc(inlinedQrl(async (path)=>{ + throw new Error('Not implemented'); + }, 'QwikRouterMockProvider_component_goto_BUbtvTyvVRE'), "../node_modules/@qwik.dev/router/index.qwik.mjs", 594, 34); + const documentHead = _addLoc(useStore(createDocumentHead, { + deep: false + }), "../node_modules/@qwik.dev/router/index.qwik.mjs", 597, 26); + const content = _addLoc(useStore({ + headings: void 0, + menu: void 0 + }, { + deep: false + }), "../node_modules/@qwik.dev/router/index.qwik.mjs", 600, 21); + const contentInternal = _addLoc(useSignal(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 609, 29); + useContextProvider(ContentContext, content); + useContextProvider(ContentInternalContext, contentInternal); + useContextProvider(DocumentHeadContext, documentHead); + useContextProvider(RouteLocationContext, routeLocation); + useContextProvider(RouteNavigateContext, goto); + useContextProvider(RouteStateContext, loaderState); + return /* @__PURE__ */ _jsxSplit(Slot, null, 3, 'qY_1'); +}, 'QwikRouterMockProvider_component_WmYC5H00wtI')), "../node_modules/@qwik.dev/router/index.qwik.mjs", 579, 48); +const Link = /* @__PURE__ */ _addLoc(componentQrl(/* @__PURE__ */ inlinedQrl((props)=>{ + const nav = _addLoc(useNavigate(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 621, 17); + const loc = _addLoc(useLocation(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 622, 17); + const linkProps = _addLoc({ + ...props + }, "../node_modules/@qwik.dev/router/index.qwik.mjs", 623, 23); + const clientNavPath = _addLoc(untrack(()=>getClientNavPath(linkProps, loc)), "../node_modules/@qwik.dev/router/index.qwik.mjs", 626, 27); + const prefetchDataset = _addLoc(untrack(()=>getPrefetchDataset(props, clientNavPath, loc)), "../node_modules/@qwik.dev/router/index.qwik.mjs", 627, 29); + const reload = _addLoc(!!linkProps.reload, "../node_modules/@qwik.dev/router/index.qwik.mjs", 628, 20); + linkProps['preventdefault:click'] = !!clientNavPath; + linkProps.href = clientNavPath || props.href; + const event = _addLoc(eventQrl(/* @__PURE__ */ inlinedQrl((ev, elm)=>prefetchLinkResources(elm, ev.type === 'qvisible'), 'Link_component_event_event_5g4B0Gd1Wck')), "../node_modules/@qwik.dev/router/index.qwik.mjs", 631, 19); + return /* @__PURE__ */ _jsxSplit('a', { + ...linkProps, + 'data-prefetch': prefetchDataset, + children: /* @__PURE__ */ _jsxSplit(Slot, null, null, 3, 'AD_0'), + onClick$: /* @__PURE__ */ inlinedQrl((_, elm)=>{ + const [nav2, reload2] = useLexicalScope(); + if (elm.href) nav2(elm.href, reload2); + }, 'Link_component_a_onClick_kzjavhDI3L0', [ + nav, + reload + ]), + onMouseOver$: event, + onFocus$: event, + onQVisible$: event + }, null, 0, 'AD_1'); +}, 'Link_component_8gdLBszqbaM')), "../node_modules/@qwik.dev/router/index.qwik.mjs", 619, 30); +const prefetchLinkResources = _addLoc((elm, isOnVisible)=>{ + if (elm && elm.href && elm.hasAttribute('data-prefetch')) { + if (!windowInnerWidth) windowInnerWidth = innerWidth; + if (!isOnVisible || isOnVisible && windowInnerWidth < 520) loadClientData(new URL(elm.href), elm); + } +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 661, 31); +let windowInnerWidth = _addLoc(0, "../node_modules/@qwik.dev/router/index.qwik.mjs", 668, 24); +const ServiceWorkerRegister = _addLoc((props)=>_jsxSplit('script', null, { + nonce: _wrapSignal(props, 'nonce'), + dangerouslySetInnerHTML: swRegister + }, 3, '1Z_0'), "../node_modules/@qwik.dev/router/index.qwik.mjs", 669, 31); +const routeActionQrl = _addLoc((actionQrl, ...rest)=>{ + const { id, validators } = getValidators(rest, actionQrl); + function action() { + const loc = _addLoc(useLocation(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 683, 17); + const currentAction = _addLoc(useAction(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 684, 27); + const initialState = _addLoc({ + actionPath: `?${QACTION_KEY}=${id}`, + isRunning: false, + status: void 0, + value: void 0, + formData: void 0 + }, "../node_modules/@qwik.dev/router/index.qwik.mjs", 685, 26); + const state = _addLoc(useStore(()=>{ + const value = _addLoc(currentAction.value, "../node_modules/@qwik.dev/router/index.qwik.mjs", 693, 21); + if (value && value?.id === id) { + const data = _addLoc(value.data, "../node_modules/@qwik.dev/router/index.qwik.mjs", 695, 22); + if (data instanceof FormData) initialState.formData = data; + if (value.output) { + const { status, result } = value.output; + initialState.status = status; + initialState.value = result; + } + } + return initialState; + }), "../node_modules/@qwik.dev/router/index.qwik.mjs", 692, 19); + const submit = /* @__PURE__ */ _addLoc(inlinedQrl((input = {})=>{ + const [currentAction2, id2, loc2, state2] = useLexicalScope(); + 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; + let form; + if (input instanceof SubmitEvent) { + form = input.target; + data = new FormData(form); + if ((input.submitter instanceof HTMLInputElement || input.submitter instanceof HTMLButtonElement) && input.submitter.name) { + if (input.submitter.name) data.append(input.submitter.name, input.submitter.value); + } + } else data = input; + return new Promise((resolve)=>{ + if (data instanceof FormData) state2.formData = data; + state2.isRunning = true; + loc2.isNavigating = true; + currentAction2.value = { + data, + id: id2, + resolve: noSerialize(resolve) + }; + }).then(({ result, status })=>{ + state2.isRunning = false; + state2.status = status; + state2.value = result; + if (form) { + if (form.getAttribute('data-spa-reset') === 'true') form.reset(); + const detail = _addLoc({ + status, + value: result + }, "../node_modules/@qwik.dev/router/index.qwik.mjs", 739, 28); + form.dispatchEvent(new CustomEvent('submitcompleted', { + bubbles: false, + cancelable: false, + composed: false, + detail + })); + } + return { + status, + value: result + }; + }); + }, 'routeActionQrl_action_submit_A5bZC7WO00A', [ + currentAction, + id, + loc, + state + ]), "../node_modules/@qwik.dev/router/index.qwik.mjs", 705, 36); + initialState.submit = submit; + return state; + } + action.__brand = 'server_action'; + action.__validators = validators; + action.__qrl = actionQrl; + action.__id = id; + Object.freeze(action); + return action; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 680, 24); +const globalActionQrl = _addLoc((actionQrl, ...rest)=>{ + const action = _addLoc(routeActionQrl(actionQrl, ...rest), "../node_modules/@qwik.dev/router/index.qwik.mjs", 772, 18); + if (isServer) { + if (typeof globalThis._qwikActionsMap === 'undefined') globalThis._qwikActionsMap = /* @__PURE__ */ new Map(); + globalThis._qwikActionsMap.set(action.__id, action); + } + return action; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 771, 25); +const routeAction$ = /* @__PURE__ */ _addLoc(implicit$FirstArg(routeActionQrl), "../node_modules/@qwik.dev/router/index.qwik.mjs", 780, 38); +const globalAction$ = /* @__PURE__ */ _addLoc(implicit$FirstArg(globalActionQrl), "../node_modules/@qwik.dev/router/index.qwik.mjs", 781, 39); +const routeLoaderQrl = _addLoc((loaderQrl, ...rest)=>{ + const { id, validators } = getValidators(rest, loaderQrl); + function loader() { + return useContext(RouteStateContext, (state)=>{ + if (!(id in state)) throw new Error(`Loader (${id}) was used in a path where the 'loader$' was not declared. + This is likely because the used loader was not exported in a layout.tsx or index.tsx file of the existing route. + For more information check: https://qwik.dev/docs/route-loader/`); + return _wrapSignal(state, id); + }); + } + loader.__brand = 'server_loader'; + loader.__qrl = loaderQrl; + loader.__validators = validators; + loader.__id = id; + Object.freeze(loader); + return loader; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 782, 24); +const routeLoader$ = /* @__PURE__ */ _addLoc(implicit$FirstArg(routeLoaderQrl), "../node_modules/@qwik.dev/router/index.qwik.mjs", 800, 38); +const validatorQrl = _addLoc((validator)=>{ + if (isServer) return { + validate: validator + }; + return void 0; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 801, 22); +const validator$ = /* @__PURE__ */ _addLoc(implicit$FirstArg(validatorQrl), "../node_modules/@qwik.dev/router/index.qwik.mjs", 808, 36); +const zodQrl = _addLoc((qrl)=>{ + if (isServer) { + const schema = _addLoc(qrl.resolve().then((obj)=>{ + if (typeof obj === 'function') obj = obj(z); + if (obj instanceof z.Schema) return obj; + else return z.object(obj); + }), "../node_modules/@qwik.dev/router/index.qwik.mjs", 811, 20); + return { + async validate (ev, inputData) { + const data = _addLoc(inputData ?? await ev.parseBody(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 818, 22); + const result = _addLoc(await (await schema).safeParseAsync(data), "../node_modules/@qwik.dev/router/index.qwik.mjs", 819, 24); + if (result.success) return result; + else { + if (isDev) console.error('\nVALIDATION ERROR\naction$() zod validated failed', '\n - Issues:', result.error.issues); + return { + success: false, + status: 400, + error: result.error.flatten() + }; + } + } + }; + } + return void 0; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 809, 16); +const zod$ = /* @__PURE__ */ _addLoc(implicit$FirstArg(zodQrl), "../node_modules/@qwik.dev/router/index.qwik.mjs", 839, 30); +const serverQrl = _addLoc((qrl)=>{ + if (isServer) { + const captured = _addLoc(qrl.getCaptured(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 842, 22); + if (captured && captured.length > 0 && !_getContextElement()) throw new Error('For security reasons, we cannot serialize QRLs that capture lexical scope.'); + } + function stuff() { + return /* @__PURE__ */ inlinedQrl(async (...args)=>{ + const [qrl2] = useLexicalScope(); + if (isServer) { + const requestEvent = _addLoc(useQwikRouterEnv()?.ev, "../node_modules/@qwik.dev/router/index.qwik.mjs", 851, 32); + return qrl2.apply(requestEvent, args); + } else { + const ctxElm = _addLoc(_getContextElement(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 854, 26); + const filtered = _addLoc(args.map((arg)=>{ + if (arg instanceof SubmitEvent && arg.target instanceof HTMLFormElement) return new FormData(arg.target); + else if (arg instanceof Event) return null; + else if (arg instanceof Node) return null; + return arg; + }), "../node_modules/@qwik.dev/router/index.qwik.mjs", 855, 28); + const hash = _addLoc(qrl2.getHash(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 862, 24); + const path = _addLoc(`?qfunc=${qrl2.getHash()}`, "../node_modules/@qwik.dev/router/index.qwik.mjs", 863, 24); + const body = _addLoc(await _serializeData([ + qrl2, + ...filtered + ], false), "../node_modules/@qwik.dev/router/index.qwik.mjs", 864, 24); + const res = _addLoc(await fetch(path, { + method: 'POST', + headers: { + 'Content-Type': 'application/qwik-json', + 'X-QRL': hash + }, + body + }), "../node_modules/@qwik.dev/router/index.qwik.mjs", 865, 23); + const contentType = _addLoc(res.headers.get('Content-Type'), "../node_modules/@qwik.dev/router/index.qwik.mjs", 873, 31); + if (res.ok && contentType === 'text/event-stream') { + const { writable, readable } = getSSETransformer(); + res.body?.pipeTo(writable); + return streamAsyncIterator(readable, ctxElm ?? document.documentElement); + } else if (contentType === 'application/qwik-json') { + const str = _addLoc(await res.text(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 879, 25); + const obj = _addLoc(await _deserializeData(str, ctxElm ?? document.documentElement), "../node_modules/@qwik.dev/router/index.qwik.mjs", 880, 25); + if (res.status === 500) throw obj; + return obj; + } + } + }, 'serverQrl_stuff_wOIPfiQ04l4', [ + qrl + ]); + } + return stuff(); +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 840, 19); +const server$ = /* @__PURE__ */ _addLoc(implicit$FirstArg(serverQrl), "../node_modules/@qwik.dev/router/index.qwik.mjs", 892, 33); +const getValidators = _addLoc((rest, qrl)=>{ + let id; + const validators = _addLoc([], "../node_modules/@qwik.dev/router/index.qwik.mjs", 895, 22); + if (rest.length === 1) { + const options = _addLoc(rest[0], "../node_modules/@qwik.dev/router/index.qwik.mjs", 897, 21); + if (options && typeof options === 'object') { + if ('validate' in options) validators.push(options); + else { + id = options.id; + if (options.validation) validators.push(...options.validation); + } + } + } else if (rest.length > 1) validators.push(...rest.filter((v)=>!!v)); + if (typeof id === 'string') { + if (isDev) { + if (!/^[\w/.-]+$/.test(id)) throw new Error(`Invalid id: ${id}, id can only contain [a-zA-Z0-9_.-]`); + } + id = `id_${id}`; + } else id = qrl.getHash(); + return { + validators: validators.reverse(), + id + }; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 893, 23); +const getSSETransformer = _addLoc(()=>{ + let currentLine = _addLoc('', "../node_modules/@qwik.dev/router/index.qwik.mjs", 919, 21); + const encoder = _addLoc(new TextDecoder(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 920, 19); + const transformer = _addLoc(new TransformStream({ + transform (chunk, controller) { + const lines = _addLoc(encoder.decode(chunk).split('\n\n'), "../node_modules/@qwik.dev/router/index.qwik.mjs", 923, 21); + for(let i = _addLoc(0, "../node_modules/@qwik.dev/router/index.qwik.mjs", 924, 20); i < lines.length - 1; i++){ + const line = _addLoc(currentLine + lines[i], "../node_modules/@qwik.dev/router/index.qwik.mjs", 925, 22); + if (line.length === 0) { + controller.terminate(); + break; + } else { + controller.enqueue(parseEvent(line)); + currentLine = ''; + } + } + currentLine += lines[lines.length - 1]; + } + }), "../node_modules/@qwik.dev/router/index.qwik.mjs", 921, 23); + return transformer; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 918, 27); +const parseEvent = _addLoc((message)=>{ + const lines = _addLoc(message.split('\n'), "../node_modules/@qwik.dev/router/index.qwik.mjs", 940, 17); + const event = _addLoc({ + data: '' + }, "../node_modules/@qwik.dev/router/index.qwik.mjs", 941, 17); + let data = _addLoc('', "../node_modules/@qwik.dev/router/index.qwik.mjs", 944, 14); + for (const line of lines)if (line.startsWith('data: ')) data += line.slice(6) + '\n'; + else { + const [key, value] = line.split(':'); + if (typeof key === 'string' && typeof value === 'string') event[key] = value.trim(); + } + event.data = data; + return event; +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 939, 20); +async function* streamAsyncIterator(stream, ctxElm) { + const reader = _addLoc(stream.getReader(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 955, 18); + try { + while(true){ + const { done, value } = await reader.read(); + if (done) return; + const obj = _addLoc(await _deserializeData(value.data, ctxElm), "../node_modules/@qwik.dev/router/index.qwik.mjs", 960, 19); + yield obj; + } + } finally{ + reader.releaseLock(); + } +} +const Form = _addLoc(({ action, spaReset, reloadDocument, onSubmit$, ...rest }, key)=>{ + _jsxBranch(); + if (action) return _jsxSplit('form', { + ...rest, + action: _wrapSignal(action, 'actionPath'), + 'preventdefault:submit': !reloadDocument, + ['data-spa-reset']: spaReset ? 'true' : void 0, + onSubmit$: [ + !reloadDocument ? action.submit : void 0, + onSubmit$ + ] + }, { + method: 'post' + }, 0, key); + else return /* @__PURE__ */ _jsxSplit(GetForm, { + spaReset, + reloadDocument, + onSubmit$, + ...rest + }, 0, key); +}, "../node_modules/@qwik.dev/router/index.qwik.mjs", 967, 14); +const GetForm = /* @__PURE__ */ _addLoc(componentQrl(/* @__PURE__ */ inlinedQrl((props)=>{ + const rest = _addLoc(_restProps(props, [ + 'action', + 'spaReset', + 'reloadDocument', + 'onSubmit$' + ]), "../node_modules/@qwik.dev/router/index.qwik.mjs", 1000, 18); + const nav = _addLoc(useNavigate(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 1001, 17); + return /* @__PURE__ */ _jsxSplit('form', { + ...rest, + children: /* @__PURE__ */ _jsxSplit(Slot, null, 3, 'BC_0'), + onSubmit$: /* @__PURE__ */ inlinedQrl(async (_, form)=>{ + const [nav2] = useLexicalScope(); + const formData = _addLoc(new FormData(form), "../node_modules/@qwik.dev/router/index.qwik.mjs", 1010, 30); + const params = _addLoc(new URLSearchParams(), "../node_modules/@qwik.dev/router/index.qwik.mjs", 1011, 28); + formData.forEach((value, key)=>{ + if (typeof value === 'string') params.append(key, value); + }); + nav2('?' + params.toString(), true).then(()=>{ + if (form.getAttribute('data-spa-reset') === 'true') form.reset(); + form.dispatchEvent(new CustomEvent('submitcompleted', { + bubbles: false, + cancelable: false, + composed: false, + detail: { + status: 200 + } + })); + }); + }, 'GetForm_component_form_onSubmit_p9MSze0ojs4', [ + nav + ]) + }, { + action: 'get', + 'preventdefault:submit': _fnSignal((p0)=>!p0.reloadDocument, [ + props + ], '!p0.reloadDocument'), + 'data-spa-reset': _fnSignal((p0)=>p0.spaReset ? 'true' : void 0, [ + props + ], 'p0.spaReset?"true":undefined') + }, 0, 'BC_1'); +}, 'GetForm_component_Nk9PlpjQm9Y')), "../node_modules/@qwik.dev/router/index.qwik.mjs", 998, 33); +export { Form, globalAction$, globalActionQrl, Link, QwikRouterMockProvider, QwikRouterProvider as QwikRouterProvider, routeAction$, routeActionQrl, routeLoader$, routeLoaderQrl, RouterOutlet, server$, serverQrl, ServiceWorkerRegister, useContent, useDocumentHead, useLocation, useNavigate, validator$, validatorQrl, z2 as z, zod$, zodQrl }; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@qwik.dev/router/index.qwik.mjs\"],\"names\":[],\"mappings\":\";AAAA,YAAY,sBAAsB,sBAAsB;AACxD,OAAO,gBAAgB,2BAA2B;AAClD,SACE,gBAAgB,EAChB,SAAS,EACT,kBAAkB,EAClB,UAAU,EACV,SAAS,EACT,UAAU,EACV,cAAc,EACd,cAAc,EACd,WAAW,EACX,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,UAAU,EACV,IAAI,EACJ,OAAO,EACP,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,aAAa,EACb,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,UAAU,QACL,iBAAiB;AACxB,SAAS,SAAS,EAAE,KAAK,EAAE,QAAQ,QAAQ,uBAAuB;AAClE,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,MAAM;AACjC,MAAM,oBAAoB,aAAa,GAAG,QAAA,gBAAgB;AAC1D,MAAM,iBAAiB,aAAa,GAAG,QAAA,gBAAgB;AACvD,MAAM,yBAAyB,aAAa,GAAG,QAAA,gBAAgB;AAC/D,MAAM,sBAAsB,aAAa,GAAG,QAAA,gBAAgB;AAC5D,MAAM,uBAAuB,aAAa,GAAG,QAAA,gBAAgB;AAC7D,MAAM,uBAAuB,aAAa,GAAG,QAAA,gBAAgB;AAC7D,MAAM,qBAAqB,aAAa,GAAG,QAAA,gBAAgB;AAC3D,MAAM,eAAe,aAAa,GAAG,QAAA,aACnC,aAAa,GAAG,WAAW;IACzB;IACA,cACE,SACA,SACE,aAAa,GAAG,WAAW;QACzB,MAAM,gCAAgC,QAAA;QACtC,MAAM,6BAA6B,QAAA;QACnC,IAAI,CAAC,MAAM,CAAC,8BAA8B,EAAE;YAC1C,MAAM,CAAC,8BAA8B,GAAG;gBACtC,IAAI,CAAC,MAAM,CAAC,2BAA2B,EAAE,SAAS,MAAM;YAC1D;YACA,WAAW;gBACT,iBAAiB,YAAY,MAAM,CAAC,8BAA8B;YACpE,GAAG;QACL;IACF,GAAG;IAGP,MAAM,UAAU,QAAA,WAAW;IAC3B,IAAI,QAAQ,KAAK,IAAI,QAAQ,KAAK,CAAC,MAAM,GAAG,GAAG;QAC7C,MAAM,cAAc,QAAA,QAAQ,KAAK,CAAC,MAAM;QACxC,IAAI,MAAM,QAAA;QACV,IAAK,IAAI,IAAI,QAAA,cAAc,+DAAG,KAAK,GAAG,IACpC,MAAM,UACJ,QAAQ,KAAK,CAAC,EAAE,CAAC,OAAO,EACxB;YACE,UAAU;QACZ,GACA,GACA;QAEJ,OAAO;IACT;IACA,OAAO;AACT,GAAG;AAEL,MAAM,eAAe,aAAa,GAAG,QAAA,IAAI;AACzC,MAAM,oBAAoB,aAAa,GAAG,QAAA,IAAI;AAC9C,MAAM,cAAc,QAAA;AACpB,MAAM,SAAS,QAAA,CAAC,MAAQ,IAAI,QAAQ,GAAG,IAAI,MAAM,GAAG,IAAI,IAAI;AAC5D,MAAM,QAAQ,QAAA,CAAC,KAAK,UAAY,IAAI,IAAI,KAAK,QAAQ,IAAI;AACzD,MAAM,eAAe,QAAA,CAAC,GAAG,IAAM,EAAE,MAAM,KAAK,EAAE,MAAM;AACpD,MAAM,aAAa,QAAA,CAAC,GAAG,IAAM,EAAE,QAAQ,GAAG,EAAE,MAAM,KAAK,EAAE,QAAQ,GAAG,EAAE,MAAM;AAC5E,MAAM,iBAAiB,QAAA,CAAC,GAAG,IAAM,EAAE,QAAQ,KAAK,EAAE,QAAQ;AAC1D,MAAM,gCAAgC,QAAA,CAAC,GAAG,IAAM,aAAa,GAAG,MAAM,CAAC,WAAW,GAAG;AACrF,MAAM,oBAAoB,QAAA,CAAC,UAAU,YAAY;IAC/C,IAAI,SAAS,QAAA,cAAc;IAC3B,IAAI,QAAQ,UAAU,CAAC,SAAS,MAAM,GAAG,IAAI,cAAc,MAAM,mBAAmB,OAAO,EAAE;IAC7F,OAAO,WAAW,CAAC,SAAS,QAAQ,CAAC,OAAO,KAAK,GAAG,IAAI,gBAAgB;AAC1E;AACA,MAAM,mBAAmB,QAAA,CAAC,OAAO;IAC/B,MAAM,OAAO,QAAA,MAAM,IAAI;IACvB,IAAI,OAAO,SAAS,YAAY,KAAK,IAAI,OAAO,MAAM,OAAO,MAAM,MAAM,KAAK,UAC5E,IAAI;QACF,MAAM,UAAU,QAAA,MAAM,MAAM,QAAQ,GAAG;QACvC,MAAM,aAAa,QAAA,MAAM,IAAI,QAAQ,GAAG;QACxC,IAAI,aAAa,SAAS,aAAa,OAAO,OAAO;IACvD,EAAE,OAAO,GAAG;QACV,QAAQ,KAAK,CAAC;IAChB;SACG,IAAI,MAAM,MAAM,EAAE,OAAO,OAAO,MAAM,IAAI,QAAQ,GAAG;IAC1D,OAAO;AACT;AACA,MAAM,qBAAqB,QAAA,CAAC,OAAO,eAAe;IAChD,IAAI,MAAM,QAAQ,KAAK,QAAQ,eAAe;QAC5C,MAAM,cAAc,QAAA,MAAM,eAAe,WAAW,GAAG;QACvD,IAAI,CAAC,eAAe,aAAa,MAAM,IAAI,WAAW,GAAG,IAAI,OAAO;IACtE;IACA,OAAO;AACT;AACA,MAAM,iBAAiB,QAAA,CAAC,KAAK,QAAQ;IACnC,MAAM,aAAa,QAAA,IAAI,QAAQ;IAC/B,IAAI,8BAA8B,YAAY,SAAS;QACrD,aAAa,KAAK,YAAY;QAC9B,IAAI,OAAO,CAAC,SAAS,CAAC,IAAI,IAAI,OAAO;IACvC;IACA,IAAI,CAAC,IAAI,eAAe,EAAE;QACxB,IAAI,eAAe,GAAG;QACtB,IAAI,gBAAgB,CAAC,YAAY;YAC/B,MAAM,cAAc,QAAA,IAAI,QAAQ;YAChC,MAAM,cAAc,QAAA,MAAM,cAAc,KAAK,EAAE;YAC/C,IAAI,8BAA8B,aAAa,cAAc;gBAC3D,aAAa,KAAK,aAAa;gBAC/B,cAAc,KAAK,GAAG,OAAO,IAAI,IAAI,YAAY,IAAI;YACvD;QACF;QACA,IAAI,mBAAmB,CAAC,YAAY,IAAI,wBAAwB;IAClE;AACF;AACA,MAAM,eAAe,QAAA,OAAO,KAAK,aAAa;IAC5C,MAAM,MAAM,QAAA,IAAI,QAAQ;IACxB,MAAM,UAAU,QAAA,OAAO,IAAI;IAC3B,IAAI,WAAW,aAAa,SAAS;QACnC,IAAI,YAAY,IAAI,KAAK,SAAS;YAChC,MAAM;YACN,IAAI,SAAS,eAAe,KAAK;iBAC5B,IAAI,QAAQ,CAAC,GAAG;QACvB;IACF,OAAO;QACL,IAAI,SACF,IAAK,IAAI,IAAI,QAAA,gEAAG,IAAI,IAAI,IAAK;YAC3B,MAAM;YACN,IAAI,eAAe,KAAK,UAAU;QACpC;aACG;YACH,MAAM;YACN,IAAI,QAAQ,CAAC,GAAG;QAClB;IACF;AACF;AACA,MAAM,UAAU,QAAA,IAAM,IAAI,QAAQ,CAAC,UAAY,WAAW,SAAS;AACnE,MAAM,iBAAiB,QAAA,CAAC,KAAK;IAC3B,MAAM,QAAQ,QAAA,KAAK,KAAK,CAAC;IACzB,MAAM,MAAM,QAAA,IAAI,cAAc,CAAC;IAC/B,IAAI,KAAK,IAAI,cAAc;IAC3B,OAAO;AACT;AACA,MAAM,wBAAwB,QAAA,CAAC;IAC7B,IAAI,OAAO,aAAa,aACtB,SAAS,aAAa,CACpB,IAAI,YAAY,aAAa;QAC3B,QAAQ;IACV;AAEN;AACA,MAAM,cAAc,QAAA,CAAC,UAAU,eAAe,gBAAgB;IAC5D,MAAM,OAAO,QAAA;IACb,MAAM,UAAU,QAAA,CAAC;QACf,MAAM,KAAK,QAAA,eAAe,IAAI;QAC9B,IAAI,eAAe,OAAO,KAAK,iBAAiB;YAC9C,IAAI,CAAC,CAAC,MAAM,SAAS,OAAO,GAC1B,MAAM,IAAI,MACR;QAEN;QACA,MAAM,OAAO,QAAA,SAAS,OAAO,CAAC,GAAG;QACjC,IAAI,gBAAgB,SAClB,MAAM,IAAI,MAAM;QAClB,OAAO;IACT;IACA,MAAM,YAAY,QAAA;QAChB;QACA,YAAY,CAAC,KAAO,WAAW,QAAQ;QACvC,cAAc;QACd,GAAG,aAAa;IAClB;IACA,IAAK,IAAI,IAAI,QAAA,eAAe,MAAM,GAAG,gEAAG,KAAK,GAAG,IAAK;QACnD,MAAM,oBAAoB,QAAA,cAAc,CAAC,EAAE,IAAI,cAAc,CAAC,EAAE,CAAC,IAAI;QACrE,IAAI,mBAAmB;YACrB,IAAI,OAAO,sBAAsB,YAC/B,oBACE,MACA,WAAW,QAAQ,IAAM,kBAAkB;iBAE1C,IAAI,OAAO,sBAAsB,UAAU,oBAAoB,MAAM;QAC5E;IACF;IACA,OAAO,UAAU,IAAI;AACvB;AACA,MAAM,sBAAsB,QAAA,CAAC,cAAc;IACzC,IAAI,OAAO,YAAY,KAAK,KAAK,UAAU,aAAa,KAAK,GAAG,YAAY,KAAK;IACjF,WAAW,aAAa,IAAI,EAAE,YAAY,IAAI;IAC9C,WAAW,aAAa,KAAK,EAAE,YAAY,KAAK;IAChD,WAAW,aAAa,MAAM,EAAE,YAAY,MAAM;IAClD,OAAO,MAAM,CAAC,aAAa,WAAW,EAAE,YAAY,WAAW;AACjE;AACA,MAAM,aAAa,QAAA,CAAC,aAAa;IAC/B,IAAI,MAAM,OAAO,CAAC,SAChB,KAAK,MAAM,WAAW,OAAQ;QAC5B,IAAI,OAAO,QAAQ,GAAG,KAAK,UAAU;YACnC,MAAM,gBAAgB,QAAA,YAAY,SAAS,CAAC,CAAC,IAAM,EAAE,GAAG,KAAK,QAAQ,GAAG;YACxE,IAAI,gBAAgB,CAAC,GAAG;gBACtB,WAAW,CAAC,cAAc,GAAG;gBAC7B;YACF;QACF;QACA,YAAY,IAAI,CAAC;IACnB;AACJ;AACA,MAAM,qBAAqB,QAAA,IAAM,CAAC;QAChC,OAAO;QACP,MAAM,EAAE;QACR,OAAO,EAAE;QACT,QAAQ,EAAE;QACV,aAAa,CAAC;IAChB,CAAC;AACD,MAAM,YAAY,QAAA,OAAO,QAAQ,OAAO,cAAc;IACpD,IAAI,MAAM,OAAO,CAAC,SAChB,KAAK,MAAM,SAAS,OAAQ;QAC1B,MAAM,QAAQ,QAAA,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC;QAC5B,IAAI,OAAO;YACT,MAAM,UAAU,QAAA,KAAK,CAAC,EAAE;YACxB,MAAM,SAAS,QAAA,cAAc,KAAK,CAAC,EAAE,EAAE;YACvC,MAAM,mBAAmB,QAAA,KAAK,CAAC,EAAE;YACjC,MAAM,OAAO,QAAA,IAAI,MAAM,QAAQ,MAAM;YACrC,MAAM,eAAe,QAAA,EAAE;YACvB,MAAM,aAAa,QAAA,cAAc,OAAO;YACxC,IAAI,OAAO,QAAA,KAAK;YAChB,QAAQ,OAAO,CAAC,CAAC,cAAc;gBAC7B,WACE,cACA,cACA,CAAC,cAAiB,IAAI,CAAC,EAAE,GAAG,aAC5B;YAEJ;YACA,WACE,YACA,cACA,CAAC,aAAgB,OAAO,YAAY,SACpC;YAEF,IAAI,aAAa,MAAM,GAAG,GAAG,MAAM,QAAQ,GAAG,CAAC;YAC/C,OAAO;gBAAC;gBAAQ;gBAAM;gBAAM;aAAiB;QAC/C;IACF;IACF,OAAO;AACT;AACA,MAAM,aAAa,QAAA,CAAC,cAAc,cAAc,cAAc;IAC5D,IAAI,OAAO,iBAAiB,YAAY;QACtC,MAAM,eAAe,QAAA,aAAa,GAAG,CAAC;QACtC,IAAI,cAAc,aAAa;aAC1B;YACH,MAAM,IAAI,QAAA;YACV,IAAI,OAAO,EAAE,IAAI,KAAK,YACpB,aAAa,IAAI,CACf,EAAE,IAAI,CAAC,CAAC;gBACN,IAAI,iBAAiB,OAAO,aAAa,GAAG,CAAC,cAAc;gBAC3D,aAAa;YACf;iBAEC,IAAI,GAAG,aAAa;QAC3B;IACF;AACF;AACA,MAAM,gBAAgB,QAAA,CAAC,OAAO;IAC5B,IAAI,OAAO;QACT,WAAW,SAAS,QAAQ,CAAC,OAAO,WAAW,WAAW;QAC1D,MAAM,OAAO,QAAA,MAAM,IAAI,CACrB,CAAC,IAAM,CAAC,CAAC,EAAE,KAAK,YAAY,SAAS,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,QAAQ,CAAC,OAAO,KAAK,GAAG;QAE3F,IAAI,MAAM,OAAO,IAAI,CAAC,EAAE;IAC1B;AACF;AACA,MAAM,gBAAgB,QAAA,CAAC,YAAY;IACjC,MAAM,SAAS,QAAA,CAAC;IAChB,IAAI,YACF,IAAK,IAAI,IAAI,QAAA,gEAAG,IAAI,WAAW,MAAM,EAAE,IAAK;QAC1C,MAAM,QAAQ,QAAA,OAAO,CAAC,IAAI,EAAE,IAAI;QAChC,MAAM,IAAI,QAAA,MAAM,QAAQ,CAAC,OAAO,MAAM,KAAK,CAAC,GAAG,CAAC,KAAK;QACrD,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,mBAAmB;IAC7C;IACF,OAAO;AACT;AACA,MAAM,iBAAiB,QAAA,OAAO,KAAK,SAAS,YAAY;IACtD,MAAM,eAAe,QAAA,IAAI,QAAQ;IACjC,MAAM,aAAa,QAAA,IAAI,MAAM;IAC7B,MAAM,iBAAiB,QAAA,kBAAkB,cAAc,YAAY;IACnE,IAAI,QAAQ,QAAA,KAAK;IACjB,IAAI,CAAC,QAAQ,QAAQ,kBAAkB,GAAG,CAAC;IAC3C,sBAAsB;QACpB,OAAO;YAAC;SAAa;IACvB;IACA,IAAI,CAAC,OAAO;QACV,MAAM,UAAU,QAAA,gBAAgB;QAChC,IAAI,QAAQ,OAAO,IAAI,GAAG,KAAK;QAC/B,QAAQ,MAAM,gBAAgB,SAAS,IAAI,CAAC,CAAC;YAC3C,MAAM,gBAAgB,QAAA,IAAI,IAAI,IAAI,GAAG;YACrC,IAAI,cAAc,MAAM,KAAK,SAAS,MAAM,IAAI,CAAC,YAAY,cAAc,QAAQ,GAAG;gBACpF,SAAS,IAAI,GAAG,cAAc,IAAI;gBAClC;YACF;YACA,IAAI,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,EAAE,QAAQ,CAAC,SACnD,OAAO,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC;gBACtB,MAAM,aAAa,QAAA,iBAAiB,MAAM;gBAC1C,IAAI,CAAC,YAAY;oBACf,SAAS,IAAI,GAAG,IAAI,IAAI;oBACxB;gBACF;gBACA,IAAI,YAAY,kBAAkB,MAAM,CAAC;gBACzC,IAAI,WAAW,QAAQ,EAAE,SAAS,IAAI,GAAG,WAAW,QAAQ;qBACvD,IAAI,QAAQ;oBACf,MAAM,aAAa,QAAA,WAAW,OAAO,CAAC,OAAO,EAAE,CAAC;oBAChD,OAAO,OAAO,CAAC;wBACb,QAAQ,IAAI,MAAM;wBAClB,QAAQ;oBACV;gBACF;gBACA,OAAO;YACT;iBACG;gBACH,SAAS,IAAI,GAAG,IAAI,IAAI;gBACxB,OAAO,KAAK;YACd;QACF;QACA,IAAI,CAAC,QAAQ,kBAAkB,GAAG,CAAC,gBAAgB;IACrD;IACA,OAAO,MAAM,IAAI,CAAC,CAAC;QACjB,IAAI,CAAC,GAAG,kBAAkB,MAAM,CAAC;QACjC,OAAO;IACT;AACF;AACA,MAAM,kBAAkB,QAAA,CAAC;IACvB,MAAM,aAAa,QAAA,QAAQ;IAC3B,IAAI,CAAC,YAAY,OAAO,KAAK;IAC7B,IAAI,sBAAsB,UACxB,OAAO;QACL,QAAQ;QACR,MAAM;IACR;SAEA,OAAO;QACL,QAAQ;QACR,MAAM,KAAK,SAAS,CAAC;QACrB,SAAS;YACP,gBAAgB;QAClB;IACF;AACJ;AACA,MAAM,cAAc,QAAA,CAAC;IACnB,OAAO,SAAS,QAAQ,CAAC;AAC3B;AACA,MAAM,aAAa,QAAA;AACnB,MAAM,aAAa,QAAA,IAAM,WAAW;AACpC,MAAM,kBAAkB,QAAA,IAAM,WAAW;AACzC,MAAM,cAAc,QAAA,IAAM,WAAW;AACrC,MAAM,cAAc,QAAA,IAAM,WAAW;AACrC,MAAM,YAAY,QAAA,IAAM,WAAW;AACnC,MAAM,mBAAmB,QAAA,IAAM,YAAY,cAAc;AACzD,MAAM,qBAAqB,aAAa,GAAG,QAAA,aACzC,aAAa,GAAG,WAAW,CAAC;IAC1B,aACE,aAAa,GAAG,WACd,CAAC,iCAAiC,CAAC,EACnC;IAGJ,MAAM,MAAM,QAAA;IACZ,IAAI,CAAC,KAAK,QAAQ,MAAM,IAAI,MAAM,CAAC,4BAA4B,CAAC;IAChE,MAAM,SAAS,QAAA,cAAc;IAC7B,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,CAAC,yBAAyB,CAAC;IACxD,MAAM,MAAM,QAAA,IAAI,IAAI;IACpB,MAAM,gBAAgB,QAAA,SACpB;QACE;QACA,QAAQ,IAAI,MAAM;QAClB,cAAc;IAChB,GACA;QACE,MAAM;IACR;IAEF,MAAM,cAAc,QAAA,eAClB,SAAS,IAAI,QAAQ,CAAC,OAAO,EAAE;QAC7B,MAAM;IACR;IAEF,MAAM,UAAU,QAAA,UAAU,OAAO;IACjC,MAAM,eAAe,QAAA,SAAS;IAC9B,MAAM,UAAU,QAAA,SAAS;QACvB,UAAU,KAAK;QACf,MAAM,KAAK;IACb;IACA,MAAM,kBAAkB,QAAA;IACxB,MAAM,kBAAkB,QAAA,IAAI,QAAQ,CAAC,MAAM;IAC3C,MAAM,gBAAgB,QAAA,kBAAkB,IAAI,QAAQ,CAAC,OAAO,CAAC,gBAAgB,GAAG,KAAK;IACrF,MAAM,cAAc,QAAA,UAClB,gBACI;QACE,IAAI;QACJ,MAAM,IAAI,QAAQ,CAAC,QAAQ;QAC3B,QAAQ;YACN,QAAQ;YACR,QAAQ,IAAI,QAAQ,CAAC,MAAM;QAC7B;IACF,IACA,KAAK;IAEX,MAAM,OAAO,QAAA,SACX,aAAa,GAAG,WACd,OAAO,MAAM;QACX,MAAM,CAAC,cAAc,UAAU,eAAe,GAAG;QACjD,IAAI,SAAS,KAAK,GAAG;YACnB,OAAO,SAAS,KAAK;YACrB,SAAS,KAAK,GAAG;QACnB,OAAO,IAAI,aAAa,SAAS,KAAK,GAAG;QACzC,MAAM,cAAc,QAAA,IAAI,IAAI,MAAM,eAAe,GAAG;QACpD,OAAO,OAAO;QACd,IAAI,CAAC,eAAe,SAAS,KAAK,KAAK,MAAM;QAC7C,SAAS,KAAK,GAAG;QACjB,IAAI,WAAW;YACb,eAAe,aAAa;YAC5B,UACE,iBAAiB,MAAM,EACvB,iBAAiB,KAAK,EACtB,iBAAiB,YAAY,EAC7B,YAAY,QAAQ;QAExB;QACA,aAAa,KAAK,GAAG,KAAK;QAC1B,eAAe,YAAY,GAAG;IAChC,GACA,uDACA;QAAC;QAAa;QAAS;KAAc;IAGzC,mBAAmB,gBAAgB;IACnC,mBAAmB,wBAAwB;IAC3C,mBAAmB,qBAAqB;IACxC,mBAAmB,sBAAsB;IACzC,mBAAmB,sBAAsB;IACzC,mBAAmB,mBAAmB;IACtC,mBAAmB,oBAAoB;IACvC,WACE,aAAa,GAAG,WACd,CAAC,EAAE,KAAK,EAAE;QACR,MAAM,CACJ,cACA,UACA,kBACA,eACA,MACA,cACA,UACA,QACA,gBACA,KACD,GAAG;QACJ,eAAe;YACb,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,IAAM;oBAAC,SAAS,KAAK;oBAAE,aAAa,KAAK;iBAAC;YACvE,MAAM,SAAS,QAAA,UAAU;YACzB,IAAI;YACJ,IAAI;YACJ,IAAI,cAAc,QAAA;YAClB,IAAI,UAAU;gBACZ,WAAW,IAAI,IAAI,MAAM,eAAe,GAAG;gBAC3C,cAAc,KAAK,WAAW;gBAC9B,iBAAiB,KAAK,QAAQ;YAChC,OAAO;gBACL,WAAW,IAAI,IAAI,MAAM;gBACzB,IAAI,SAAS,QAAQ,CAAC,QAAQ,CAAC,MAAM;oBACnC,IAAI,CAAC,iBAAiB,aAAa,EACjC,SAAS,QAAQ,GAAG,SAAS,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;gBACpD,OAAO,IAAI,iBAAiB,aAAa,EAAE,SAAS,QAAQ,IAAI;gBAChE,IAAI,mBAAmB,QAAA,UACrB,iBAAiB,MAAM,EACvB,iBAAiB,KAAK,EACtB,iBAAiB,YAAY,EAC7B,SAAS,QAAQ;gBAEnB,MAAM,UAAU,QAAA;gBAChB,MAAM,WAAW,QAAC,iBAAiB,MAAM,eACvC,UACA,SACA,MACA;gBAEF,IAAI,CAAC,UAAU;oBACb,SAAS,cAAc,GAAG,OAAO;oBACjC;gBACF;gBACA,MAAM,UAAU,QAAA,SAAS,IAAI;gBAC7B,MAAM,SAAS,QAAA,IAAI,IAAI,SAAS,SAAS,IAAI;gBAC7C,IAAI,OAAO,QAAQ,KAAK,SAAS,QAAQ,EAAE;oBACzC,WAAW;oBACX,mBAAmB,UACjB,iBAAiB,MAAM,EACvB,iBAAiB,KAAK,EACtB,iBAAiB,YAAY,EAC7B,SAAS,QAAQ;gBAErB;gBACA,cAAc,MAAM;YACtB;YACA,IAAI,aAAa;gBACf,MAAM,CAAC,QAAQ,MAAM,KAAK,GAAG;gBAC7B,MAAM,iBAAiB,QAAA;gBACvB,MAAM,aAAa,QAAA,cAAc,CAAC,eAAe,MAAM,GAAG,EAAE;gBAC5D,eAAe,GAAG,GAAG;gBACrB,eAAe,MAAM,GAAG;oBACtB,GAAG,MAAM;gBACX;gBACA,SAAS,cAAc,GAAG,OAAO;gBACjC,MAAM,eAAe,QAAA,YACnB,gBACA,gBACA,gBACA;gBAEF,SAAS,QAAQ,GAAG,WAAW,QAAQ;gBACvC,SAAS,IAAI,GAAG;gBAChB,iBAAiB,KAAK,GAAG,YAAY;gBACrC,cAAc,KAAK,GAAG,aAAa,KAAK;gBACxC,cAAc,IAAI,GAAG,aAAa,IAAI;gBACtC,cAAc,MAAM,GAAG,aAAa,MAAM;gBAC1C,cAAc,KAAK,GAAG,aAAa,KAAK;gBACxC,cAAc,WAAW,GAAG,aAAa,WAAW;gBACpD,IAAI,WAAW;oBACb,IACE,CAAC,OAAO,cAAc,IAAI,IAAI,KAC9B,8BAA8B,OAAO,QAAQ,EAAE,OAE/C,SAAS,qBAAqB,GAAG;oBACnC,MAAM,UAAU,QAAA,gBAAgB;oBAChC,IAAI,SAAS,OAAO,MAAM,CAAC,cAAc;oBACzC,kBAAkB,KAAK;oBACvB,eAAe,QAAQ,UAAU;oBACjC,eAAe,YAAY,GAAG;gBAChC;YACF;QACF;QACA,MAAM,UAAU,QAAA;QAChB,IAAI,UAAU,OAAO;aAChB;IACP,GACA,oDACA;QACE;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;KACD;IAGL,OAAO,aAAa,GAAG,UAAU,MAAM,MAAM,GAAG;AAClD,GAAG;AAEL,MAAM,yBAAyB,aAAa,GAAG,QAAA,aAC7C,aAAa,GAAG,WAAW,CAAC;IAC1B,MAAM,SAAS,QAAA,MAAM,GAAG,IAAI;IAC5B,MAAM,MAAM,QAAA,IAAI,IAAI;IACpB,MAAM,gBAAgB,QAAA,SACpB;QACE;QACA,QAAQ,MAAM,MAAM,IAAI,CAAC;QACzB,cAAc;IAChB,GACA;QACE,MAAM;IACR;IAEF,MAAM,cAAc,QAAA,UAAU,CAAC;IAC/B,MAAM,OAAO,aAAa,GAAG,QAAA,WAAW,OAAO;QAC7C,MAAM,IAAI,MAAM;IAClB,GAAG;IACH,MAAM,eAAe,QAAA,SAAS,oBAAoB;QAChD,MAAM;IACR;IACA,MAAM,UAAU,QAAA,SACd;QACE,UAAU,KAAK;QACf,MAAM,KAAK;IACb,GACA;QACE,MAAM;IACR;IAEF,MAAM,kBAAkB,QAAA;IACxB,mBAAmB,gBAAgB;IACnC,mBAAmB,wBAAwB;IAC3C,mBAAmB,qBAAqB;IACxC,mBAAmB,sBAAsB;IACzC,mBAAmB,sBAAsB;IACzC,mBAAmB,mBAAmB;IACtC,OAAO,aAAa,GAAG,UAAU,MAAM,MAAM,GAAG;AAClD,GAAG;AAEL,MAAM,OAAO,aAAa,GAAG,QAAA,aAC3B,aAAa,GAAG,WAAW,CAAC;IAC1B,MAAM,MAAM,QAAA;IACZ,MAAM,MAAM,QAAA;IACZ,MAAM,YAAY,QAAA;QAChB,GAAG,KAAK;IACV;IACA,MAAM,gBAAgB,QAAA,QAAQ,IAAM,iBAAiB,WAAW;IAChE,MAAM,kBAAkB,QAAA,QAAQ,IAAM,mBAAmB,OAAO,eAAe;IAC/E,MAAM,SAAS,QAAA,CAAC,CAAC,UAAU,MAAM;IACjC,SAAS,CAAC,uBAAuB,GAAG,CAAC,CAAC;IACtC,UAAU,IAAI,GAAG,iBAAiB,MAAM,IAAI;IAC5C,MAAM,QAAQ,QAAA,SACZ,aAAa,GAAG,WACd,CAAC,IAAI,MAAQ,sBAAsB,KAAK,GAAG,IAAI,KAAK,aACpD;IAGJ,OAAO,aAAa,GAAG,UACrB,KACA;QACE,GAAG,SAAS;QACZ,iBAAiB;QACjB,UAAU,aAAa,GAAG,UAAU,MAAM,MAAM,MAAM,GAAG;QACzD,UAAU,aAAa,GAAG,WACxB,CAAC,GAAG;YACF,MAAM,CAAC,MAAM,QAAQ,GAAG;YACxB,IAAI,IAAI,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE;QAC/B,GACA,wCACA;YAAC;YAAK;SAAO;QAEf,cAAc;QACd,UAAU;QACV,aAAa;IACf,GACA,MACA,GACA;AAEJ,GAAG;AAEL,MAAM,wBAAwB,QAAA,CAAC,KAAK;IAClC,IAAI,OAAO,IAAI,IAAI,IAAI,IAAI,YAAY,CAAC,kBAAkB;QACxD,IAAI,CAAC,kBAAkB,mBAAmB;QAC1C,IAAI,CAAC,eAAgB,eAAe,mBAAmB,KACrD,eAAe,IAAI,IAAI,IAAI,IAAI,GAAG;IACtC;AACF;AACA,IAAI,mBAAmB,QAAA;AACvB,MAAM,wBAAwB,QAAA,CAAC,QAC7B,UACE,UACA,MACA;QACE,OAAO,YAAY,OAAO;QAC1B,yBAAyB;IAC3B,GACA,GACA;AAEJ,MAAM,iBAAiB,QAAA,CAAC,WAAW,GAAG;IACpC,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,cAAc,MAAM;IAC/C,SAAS;QACP,MAAM,MAAM,QAAA;QACZ,MAAM,gBAAgB,QAAA;QACtB,MAAM,eAAe,QAAA;YACnB,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,IAAI;YACnC,WAAW;YACX,QAAQ,KAAK;YACb,OAAO,KAAK;YACZ,UAAU,KAAK;QACjB;QACA,MAAM,QAAQ,QAAA,SAAS;YACrB,MAAM,QAAQ,QAAA,cAAc,KAAK;YACjC,IAAI,SAAS,OAAO,OAAO,IAAI;gBAC7B,MAAM,OAAO,QAAA,MAAM,IAAI;gBACvB,IAAI,gBAAgB,UAAU,aAAa,QAAQ,GAAG;gBACtD,IAAI,MAAM,MAAM,EAAE;oBAChB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM;oBACvC,aAAa,MAAM,GAAG;oBACtB,aAAa,KAAK,GAAG;gBACvB;YACF;YACA,OAAO;QACT;QACA,MAAM,SAAS,aAAa,GAAG,QAAA,WAC7B,CAAC,QAAQ,CAAC,CAAC;YACT,MAAM,CAAC,gBAAgB,KAAK,MAAM,OAAO,GAAG;YAC5C,IAAI,UACF,MAAM,IAAI,MAAM,CAAC;2GACgF,CAAC;YACpG,IAAI;YACJ,IAAI;YACJ,IAAI,iBAAiB,aAAa;gBAChC,OAAO,MAAM,MAAM;gBACnB,OAAO,IAAI,SAAS;gBACpB,IACE,CAAC,MAAM,SAAS,YAAY,oBAC1B,MAAM,SAAS,YAAY,iBAAiB,KAC9C,MAAM,SAAS,CAAC,IAAI,EACpB;oBACA,IAAI,MAAM,SAAS,CAAC,IAAI,EAAE,KAAK,MAAM,CAAC,MAAM,SAAS,CAAC,IAAI,EAAE,MAAM,SAAS,CAAC,KAAK;gBACnF;YACF,OAAO,OAAO;YACd,OAAO,IAAI,QAAQ,CAAC;gBAClB,IAAI,gBAAgB,UAAU,OAAO,QAAQ,GAAG;gBAChD,OAAO,SAAS,GAAG;gBACnB,KAAK,YAAY,GAAG;gBACpB,eAAe,KAAK,GAAG;oBACrB;oBACA,IAAI;oBACJ,SAAS,YAAY;gBACvB;YACF,GAAG,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE;gBACzB,OAAO,SAAS,GAAG;gBACnB,OAAO,MAAM,GAAG;gBAChB,OAAO,KAAK,GAAG;gBACf,IAAI,MAAM;oBACR,IAAI,KAAK,YAAY,CAAC,sBAAsB,QAAQ,KAAK,KAAK;oBAC9D,MAAM,SAAS,QAAA;wBACb;wBACA,OAAO;oBACT;oBACA,KAAK,aAAa,CAChB,IAAI,YAAY,mBAAmB;wBACjC,SAAS;wBACT,YAAY;wBACZ,UAAU;wBACV;oBACF;gBAEJ;gBACA,OAAO;oBACL;oBACA,OAAO;gBACT;YACF;QACF,GACA,4CACA;YAAC;YAAe;YAAI;YAAK;SAAM;QAEjC,aAAa,MAAM,GAAG;QACtB,OAAO;IACT;IACA,OAAO,OAAO,GAAG;IACjB,OAAO,YAAY,GAAG;IACtB,OAAO,KAAK,GAAG;IACf,OAAO,IAAI,GAAG;IACd,OAAO,MAAM,CAAC;IACd,OAAO;AACT;AACA,MAAM,kBAAkB,QAAA,CAAC,WAAW,GAAG;IACrC,MAAM,SAAS,QAAA,eAAe,cAAc;IAC5C,IAAI,UAAU;QACZ,IAAI,OAAO,WAAW,eAAe,KAAK,aACxC,WAAW,eAAe,GAAG,aAAa,GAAG,IAAI;QACnD,WAAW,eAAe,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE;IAC9C;IACA,OAAO;AACT;AACA,MAAM,eAAe,aAAa,GAAG,QAAA,kBAAkB;AACvD,MAAM,gBAAgB,aAAa,GAAG,QAAA,kBAAkB;AACxD,MAAM,iBAAiB,QAAA,CAAC,WAAW,GAAG;IACpC,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,cAAc,MAAM;IAC/C,SAAS;QACP,OAAO,WAAW,mBAAmB,CAAC;YACpC,IAAI,CAAC,CAAC,MAAM,KAAK,GACf,MAAM,IAAI,MAAM,CAAC,QAAQ,EAAE,GAAG;;mEAE6B,CAAC;YAC9D,OAAO,YAAY,OAAO;QAC5B;IACF;IACA,OAAO,OAAO,GAAG;IACjB,OAAO,KAAK,GAAG;IACf,OAAO,YAAY,GAAG;IACtB,OAAO,IAAI,GAAG;IACd,OAAO,MAAM,CAAC;IACd,OAAO;AACT;AACA,MAAM,eAAe,aAAa,GAAG,QAAA,kBAAkB;AACvD,MAAM,eAAe,QAAA,CAAC;IACpB,IAAI,UACF,OAAO;QACL,UAAU;IACZ;IACF,OAAO,KAAK;AACd;AACA,MAAM,aAAa,aAAa,GAAG,QAAA,kBAAkB;AACrD,MAAM,SAAS,QAAA,CAAC;IACd,IAAI,UAAU;QACZ,MAAM,SAAS,QAAA,IAAI,OAAO,GAAG,IAAI,CAAC,CAAC;YACjC,IAAI,OAAO,QAAQ,YAAY,MAAM,IAAI;YACzC,IAAI,eAAe,EAAE,MAAM,EAAE,OAAO;iBAC/B,OAAO,EAAE,MAAM,CAAC;QACvB;QACA,OAAO;YACL,MAAM,UAAS,EAAE,EAAE,SAAS;gBAC1B,MAAM,OAAO,QAAA,aAAc,MAAM,GAAG,SAAS;gBAC7C,MAAM,SAAS,QAAA,MAAM,CAAC,MAAM,MAAM,EAAE,cAAc,CAAC;gBACnD,IAAI,OAAO,OAAO,EAAE,OAAO;qBACtB;oBACH,IAAI,OACF,QAAQ,KAAK,CACX,sDACA,iBACA,OAAO,KAAK,CAAC,MAAM;oBAEvB,OAAO;wBACL,SAAS;wBACT,QAAQ;wBACR,OAAO,OAAO,KAAK,CAAC,OAAO;oBAC7B;gBACF;YACF;QACF;IACF;IACA,OAAO,KAAK;AACd;AACA,MAAM,OAAO,aAAa,GAAG,QAAA,kBAAkB;AAC/C,MAAM,YAAY,QAAA,CAAC;IACjB,IAAI,UAAU;QACZ,MAAM,WAAW,QAAA,IAAI,WAAW;QAChC,IAAI,YAAY,SAAS,MAAM,GAAG,KAAK,CAAC,sBACtC,MAAM,IAAI,MAAM;IACpB;IACA,SAAS;QACP,OAAO,aAAa,GAAG,WACrB,OAAO,GAAG;YACR,MAAM,CAAC,KAAK,GAAG;YACf,IAAI,UAAU;gBACZ,MAAM,eAAe,QAAA,oBAAoB;gBACzC,OAAO,KAAK,KAAK,CAAC,cAAc;YAClC,OAAO;gBACL,MAAM,SAAS,QAAA;gBACf,MAAM,WAAW,QAAA,KAAK,GAAG,CAAC,CAAC;oBACzB,IAAI,eAAe,eAAe,IAAI,MAAM,YAAY,iBACtD,OAAO,IAAI,SAAS,IAAI,MAAM;yBAC3B,IAAI,eAAe,OAAO,OAAO;yBACjC,IAAI,eAAe,MAAM,OAAO;oBACrC,OAAO;gBACT;gBACA,MAAM,OAAO,QAAA,KAAK,OAAO;gBACzB,MAAM,OAAO,QAAA,CAAC,OAAO,EAAE,KAAK,OAAO,IAAI;gBACvC,MAAM,OAAO,QAAA,MAAM,eAAe;oBAAC;uBAAS;iBAAS,EAAE;gBACvD,MAAM,MAAM,QAAA,MAAM,MAAM,MAAM;oBAC5B,QAAQ;oBACR,SAAS;wBACP,gBAAgB;wBAChB,SAAS;oBACX;oBACA;gBACF;gBACA,MAAM,cAAc,QAAA,IAAI,OAAO,CAAC,GAAG,CAAC;gBACpC,IAAI,IAAI,EAAE,IAAI,gBAAgB,qBAAqB;oBACjD,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG;oBAC/B,IAAI,IAAI,EAAE,OAAO;oBACjB,OAAO,oBAAoB,UAAU,UAAU,SAAS,eAAe;gBACzE,OAAO,IAAI,gBAAgB,yBAAyB;oBAClD,MAAM,MAAM,QAAA,MAAM,IAAI,IAAI;oBAC1B,MAAM,MAAM,QAAA,MAAM,iBAAiB,KAAK,UAAU,SAAS,eAAe;oBAC1E,IAAI,IAAI,MAAM,KAAK,KAAK,MAAM;oBAC9B,OAAO;gBACT;YACF;QACF,GACA,+BACA;YAAC;SAAI;IAET;IACA,OAAO;AACT;AACA,MAAM,UAAU,aAAa,GAAG,QAAA,kBAAkB;AAClD,MAAM,gBAAgB,QAAA,CAAC,MAAM;IAC3B,IAAI;IACJ,MAAM,aAAa,QAAA,EAAE;IACrB,IAAI,KAAK,MAAM,KAAK,GAAG;QACrB,MAAM,UAAU,QAAA,IAAI,CAAC,EAAE;QACvB,IAAI,WAAW,OAAO,YAAY,UAAU;YAC1C,IAAI,cAAc,SAAS,WAAW,IAAI,CAAC;iBACtC;gBACH,KAAK,QAAQ,EAAE;gBACf,IAAI,QAAQ,UAAU,EAAE,WAAW,IAAI,IAAI,QAAQ,UAAU;YAC/D;QACF;IACF,OAAO,IAAI,KAAK,MAAM,GAAG,GAAG,WAAW,IAAI,IAAI,KAAK,MAAM,CAAC,CAAC,IAAM,CAAC,CAAC;IACpE,IAAI,OAAO,OAAO,UAAU;QAC1B,IAAI,OAAO;YACT,IAAI,CAAC,aAAa,IAAI,CAAC,KACrB,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE,GAAG,oCAAoC,CAAC;QAC3E;QACA,KAAK,CAAC,GAAG,EAAE,IAAI;IACjB,OAAO,KAAK,IAAI,OAAO;IACvB,OAAO;QACL,YAAY,WAAW,OAAO;QAC9B;IACF;AACF;AACA,MAAM,oBAAoB,QAAA;IACxB,IAAI,cAAc,QAAA;IAClB,MAAM,UAAU,QAAA,IAAI;IACpB,MAAM,cAAc,QAAA,IAAI,gBAAgB;QACtC,WAAU,KAAK,EAAE,UAAU;YACzB,MAAM,QAAQ,QAAA,QAAQ,MAAM,CAAC,OAAO,KAAK,CAAC;YAC1C,IAAK,IAAI,IAAI,QAAA,gEAAG,IAAI,MAAM,MAAM,GAAG,GAAG,IAAK;gBACzC,MAAM,OAAO,QAAA,cAAc,KAAK,CAAC,EAAE;gBACnC,IAAI,KAAK,MAAM,KAAK,GAAG;oBACrB,WAAW,SAAS;oBACpB;gBACF,OAAO;oBACL,WAAW,OAAO,CAAC,WAAW;oBAC9B,cAAc;gBAChB;YACF;YACA,eAAe,KAAK,CAAC,MAAM,MAAM,GAAG,EAAE;QACxC;IACF;IACA,OAAO;AACT;AACA,MAAM,aAAa,QAAA,CAAC;IAClB,MAAM,QAAQ,QAAA,QAAQ,KAAK,CAAC;IAC5B,MAAM,QAAQ,QAAA;QACZ,MAAM;IACR;IACA,IAAI,OAAO,QAAA;IACX,KAAK,MAAM,QAAQ,MACjB,IAAI,KAAK,UAAU,CAAC,WAAW,QAAQ,KAAK,KAAK,CAAC,KAAK;SAClD;QACH,MAAM,CAAC,KAAK,MAAM,GAAG,KAAK,KAAK,CAAC;QAChC,IAAI,OAAO,QAAQ,YAAY,OAAO,UAAU,UAAU,KAAK,CAAC,IAAI,GAAG,MAAM,IAAI;IACnF;IACF,MAAM,IAAI,GAAG;IACb,OAAO;AACT;AACA,gBAAgB,oBAAoB,MAAM,EAAE,MAAM;IAChD,MAAM,SAAS,QAAA,OAAO,SAAS;IAC/B,IAAI;QACF,MAAO,KAAM;YACX,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,IAAI;YACzC,IAAI,MAAM;YACV,MAAM,MAAM,QAAA,MAAM,iBAAiB,MAAM,IAAI,EAAE;YAC/C,MAAM;QACR;IACF,SAAU;QACR,OAAO,WAAW;IACpB;AACF;AACA,MAAM,OAAO,QAAA,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE;IACtE;IACA,IAAI,QACF,OAAO,UACL,QACA;QACE,GAAG,IAAI;QACP,QAAQ,YAAY,QAAQ;QAC5B,yBAAyB,CAAC;QAC1B,CAAC,iBAAiB,EAAE,WAAW,SAAS,KAAK;QAC7C,WAAW;YAAC,CAAC,iBAAiB,OAAO,MAAM,GAAG,KAAK;YAAG;SAAU;IAClE,GACA;QACE,QAAQ;IACV,GACA,GACA;SAGF,OAAO,aAAa,GAAG,UACrB,SACA;QACE;QACA;QACA;QACA,GAAG,IAAI;IACT,GACA,GACA;AAEN;AACA,MAAM,UAAU,aAAa,GAAG,QAAA,aAC9B,aAAa,GAAG,WAAW,CAAC;IAC1B,MAAM,OAAO,QAAA,WAAW,OAAO;QAAC;QAAU;QAAY;QAAkB;KAAY;IACpF,MAAM,MAAM,QAAA;IACZ,OAAO,aAAa,GAAG,UACrB,QACA;QACE,GAAG,IAAI;QACP,UAAU,aAAa,GAAG,UAAU,MAAM,MAAM,GAAG;QACnD,WAAW,aAAa,GAAG,WACzB,OAAO,GAAG;YACR,MAAM,CAAC,KAAK,GAAG;YACf,MAAM,WAAW,QAAA,IAAI,SAAS;YAC9B,MAAM,SAAS,QAAA,IAAI;YACnB,SAAS,OAAO,CAAC,CAAC,OAAO;gBACvB,IAAI,OAAO,UAAU,UAAU,OAAO,MAAM,CAAC,KAAK;YACpD;YACA,KAAK,MAAM,OAAO,QAAQ,IAAI,MAAM,IAAI,CAAC;gBACvC,IAAI,KAAK,YAAY,CAAC,sBAAsB,QAAQ,KAAK,KAAK;gBAC9D,KAAK,aAAa,CAChB,IAAI,YAAY,mBAAmB;oBACjC,SAAS;oBACT,YAAY;oBACZ,UAAU;oBACV,QAAQ;wBACN,QAAQ;oBACV;gBACF;YAEJ;QACF,GACA,+CACA;YAAC;SAAI;IAET,GACA;QACE,QAAQ;QACR,yBAAyB,UACvB,CAAC,KAAO,CAAC,GAAG,cAAc,EAC1B;YAAC;SAAM,EACP;QAEF,kBAAkB,UAChB,CAAC,KAAQ,GAAG,QAAQ,GAAG,SAAS,KAAK,GACrC;YAAC;SAAM,EACP;IAEJ,GACA,GACA;AAEJ,GAAG;AAEL,SACE,IAAI,EACJ,aAAa,EACb,eAAe,EACf,IAAI,EACJ,sBAAsB,EACtB,sBAAsB,kBAAkB,EACxC,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,OAAO,EACP,SAAS,EACT,qBAAqB,EACrB,UAAU,EACV,eAAe,EACf,WAAW,EACX,WAAW,EACX,UAAU,EACV,YAAY,EACZ,MAAM,CAAC,EACP,IAAI,EACJ,MAAM,GACN\"}") +== DIAGNOSTICS == + +[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_sdk_inline.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_sdk_inline.snap deleted file mode 100644 index 15694b48d39..00000000000 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_qwik_sdk_inline.snap +++ /dev/null @@ -1,2448 +0,0 @@ ---- -source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 3214 -expression: output -snapshot_kind: text ---- -==INPUT== - -import { - createContextId, - componentQrl, - inlinedQrl, - _jsxBranch, - useOnDocument, - eventQrl, - useContext, - _jsxC, - SkipRender, - withLocale, - _deserializeData, - noSerialize, - useServerData, - useStylesQrl, - useStore, - _weakSerialize, - useSignal, - useLexicalScope, - _getContextElement, - useContextProvider, - useTaskQrl, - Slot, - getLocale, - untrack, - _jsxS, - _jsxQ, - _wrapSignal, - implicit$FirstArg, - _serializeData, - _restProps, - _fnSignal, -} from '@builder.io/qwik'; -import { isBrowser, isServer, isDev } from '@builder.io/qwik/build'; -import * as qwikCity from '@qwik-city-plan'; -import swRegister from '@qwik-city-sw-register'; -import { z } from 'zod'; -import { z as z2 } from 'zod'; -const RouteStateContext = /* @__PURE__ */ createContextId('qc-s'); -const ContentContext = /* @__PURE__ */ createContextId('qc-c'); -const ContentInternalContext = /* @__PURE__ */ createContextId('qc-ic'); -const DocumentHeadContext = /* @__PURE__ */ createContextId('qc-h'); -const RouteLocationContext = /* @__PURE__ */ createContextId('qc-l'); -const RouteNavigateContext = /* @__PURE__ */ createContextId('qc-n'); -const RouteActionContext = /* @__PURE__ */ createContextId('qc-a'); -const RouterOutlet = /* @__PURE__ */ componentQrl( - /* @__PURE__ */ inlinedQrl(() => { - _jsxBranch(); - useOnDocument( - 'qinit', - eventQrl( - /* @__PURE__ */ inlinedQrl(() => { - const POPSTATE_FALLBACK_INITIALIZED = '_qCityPopstateFallback'; - const CLIENT_HISTORY_INITIALIZED = '_qCityHistory'; - if (!window[POPSTATE_FALLBACK_INITIALIZED]) { - window[POPSTATE_FALLBACK_INITIALIZED] = () => { - if (!window[CLIENT_HISTORY_INITIALIZED]) location.reload(); - }; - setTimeout(() => { - addEventListener('popstate', window[POPSTATE_FALLBACK_INITIALIZED]); - }, 0); - } - }, 'RouterOutlet_component_useOnDocument_event_KnNE9eL0qfc') - ) - ); - const context = useContext(ContentInternalContext); - if (context.value && context.value.length > 0) { - const contentsLen = context.value.length; - let cmp = null; - for (let i = contentsLen - 1; i >= 0; i--) - cmp = _jsxC( - context.value[i].default, - { - children: cmp, - }, - 1, - 'k8_0' - ); - return cmp; - } - return SkipRender; - }, 'RouterOutlet_component_AKetNByE5TM') -); -const MODULE_CACHE = /* @__PURE__ */ new WeakMap(); -const CLIENT_DATA_CACHE = /* @__PURE__ */ new Map(); -const QACTION_KEY = 'qaction'; -const toPath = (url) => url.pathname + url.search + url.hash; -const toUrl = (url, baseUrl) => new URL(url, baseUrl.href); -const isSameOrigin = (a, b) => a.origin === b.origin; -const isSamePath = (a, b) => a.pathname + a.search === b.pathname + b.search; -const isSamePathname = (a, b) => a.pathname === b.pathname; -const isSameOriginDifferentPathname = (a, b) => isSameOrigin(a, b) && !isSamePath(a, b); -const getClientDataPath = (pathname, pageSearch, action) => { - let search = pageSearch ?? ''; - if (action) search += (search ? '&' : '?') + QACTION_KEY + '=' + encodeURIComponent(action.id); - return pathname + (pathname.endsWith('/') ? '' : '/') + 'q-data.json' + search; -}; -const getClientNavPath = (props, baseUrl) => { - const href = props.href; - if (typeof href === 'string' && href.trim() !== '' && typeof props.target !== 'string') - try { - const linkUrl = toUrl(href, baseUrl.url); - const currentUrl = toUrl('', baseUrl.url); - if (isSameOrigin(linkUrl, currentUrl)) return toPath(linkUrl); - } catch (e) { - console.error(e); - } - else if (props.reload) return toPath(toUrl('', baseUrl.url)); - return null; -}; -const getPrefetchDataset = (props, clientNavPath, currentLoc) => { - if (props.prefetch === true && clientNavPath) { - const prefetchUrl = toUrl(clientNavPath, currentLoc.url); - if (!isSamePathname(prefetchUrl, toUrl('', currentLoc.url))) return ''; - } - return null; -}; -const clientNavigate = (win, newUrl, routeNavigate) => { - const currentUrl = win.location; - if (isSameOriginDifferentPathname(currentUrl, newUrl)) { - handleScroll(win, currentUrl, newUrl); - win.history.pushState('', '', toPath(newUrl)); - } - if (!win._qCityHistory) { - win._qCityHistory = 1; - win.addEventListener('popstate', () => { - const currentUrl2 = win.location; - const previousUrl = toUrl(routeNavigate.value, currentUrl2); - if (isSameOriginDifferentPathname(currentUrl2, previousUrl)) { - handleScroll(win, previousUrl, currentUrl2); - routeNavigate.value = toPath(new URL(currentUrl2.href)); - } - }); - win.removeEventListener('popstate', win._qCityPopstateFallback); - } -}; -const handleScroll = async (win, previousUrl, newUrl) => { - const doc = win.document; - const newHash = newUrl.hash; - if (isSamePath(previousUrl, newUrl)) { - if (previousUrl.hash !== newHash) { - await domWait(); - if (newHash) scrollToHashId(doc, newHash); - else win.scrollTo(0, 0); - } - } else { - if (newHash) - for (let i = 0; i < 24; i++) { - await domWait(); - if (scrollToHashId(doc, newHash)) break; - } - else { - await domWait(); - win.scrollTo(0, 0); - } - } -}; -const domWait = () => new Promise((resolve) => setTimeout(resolve, 12)); -const scrollToHashId = (doc, hash) => { - const elmId = hash.slice(1); - const elm = doc.getElementById(elmId); - if (elm) elm.scrollIntoView(); - return elm; -}; -const dispatchPrefetchEvent = (prefetchData) => { - if (typeof document !== 'undefined') - document.dispatchEvent( - new CustomEvent('qprefetch', { - detail: prefetchData, - }) - ); -}; -const resolveHead = (endpoint, routeLocation, contentModules, locale) => { - const head = createDocumentHead(); - const getData = (loaderOrAction) => { - const id = loaderOrAction.__id; - if (loaderOrAction.__brand === 'server_loader') { - if (!(id in endpoint.loaders)) - throw new Error( - 'You can not get the returned data of a loader that has not been executed for this request.' - ); - } - const data = endpoint.loaders[id]; - if (data instanceof Promise) - throw new Error('Loaders returning a function can not be referred to in the head function.'); - return data; - }; - const headProps = { - head, - withLocale: (fn) => withLocale(locale, fn), - resolveValue: getData, - ...routeLocation, - }; - for (let i = contentModules.length - 1; i >= 0; i--) { - const contentModuleHead = contentModules[i] && contentModules[i].head; - if (contentModuleHead) { - if (typeof contentModuleHead === 'function') - resolveDocumentHead( - head, - withLocale(locale, () => contentModuleHead(headProps)) - ); - else if (typeof contentModuleHead === 'object') resolveDocumentHead(head, contentModuleHead); - } - } - return headProps.head; -}; -const resolveDocumentHead = (resolvedHead, updatedHead) => { - if (typeof updatedHead.title === 'string') resolvedHead.title = updatedHead.title; - mergeArray(resolvedHead.meta, updatedHead.meta); - mergeArray(resolvedHead.links, updatedHead.links); - mergeArray(resolvedHead.styles, updatedHead.styles); - Object.assign(resolvedHead.frontmatter, updatedHead.frontmatter); -}; -const mergeArray = (existingArr, newArr) => { - if (Array.isArray(newArr)) - for (const newItem of newArr) { - if (typeof newItem.key === 'string') { - const existingIndex = existingArr.findIndex((i) => i.key === newItem.key); - if (existingIndex > -1) { - existingArr[existingIndex] = newItem; - continue; - } - } - existingArr.push(newItem); - } -}; -const createDocumentHead = () => ({ - title: '', - meta: [], - links: [], - styles: [], - frontmatter: {}, -}); -const loadRoute = async (routes, menus, cacheModules, pathname) => { - if (Array.isArray(routes)) - for (const route of routes) { - const match = route[0].exec(pathname); - if (match) { - const loaders = route[1]; - const params = getPathParams(route[2], match); - const routeBundleNames = route[4]; - const mods = new Array(loaders.length); - const pendingLoads = []; - const menuLoader = getMenuLoader(menus, pathname); - let menu = void 0; - loaders.forEach((moduleLoader, i) => { - loadModule( - moduleLoader, - pendingLoads, - (routeModule) => (mods[i] = routeModule), - cacheModules - ); - }); - loadModule( - menuLoader, - pendingLoads, - (menuModule) => (menu = menuModule?.default), - cacheModules - ); - if (pendingLoads.length > 0) await Promise.all(pendingLoads); - return [params, mods, menu, routeBundleNames]; - } - } - return null; -}; -const loadModule = (moduleLoader, pendingLoads, moduleSetter, cacheModules) => { - if (typeof moduleLoader === 'function') { - const loadedModule = MODULE_CACHE.get(moduleLoader); - if (loadedModule) moduleSetter(loadedModule); - else { - const l = moduleLoader(); - if (typeof l.then === 'function') - pendingLoads.push( - l.then((loadedModule2) => { - if (cacheModules !== false) MODULE_CACHE.set(moduleLoader, loadedModule2); - moduleSetter(loadedModule2); - }) - ); - else if (l) moduleSetter(l); - } - } -}; -const getMenuLoader = (menus, pathname) => { - if (menus) { - pathname = pathname.endsWith('/') ? pathname : pathname + '/'; - const menu = menus.find( - (m) => m[0] === pathname || pathname.startsWith(m[0] + (pathname.endsWith('/') ? '' : '/')) - ); - if (menu) return menu[1]; - } -}; -const getPathParams = (paramNames, match) => { - const params = {}; - if (paramNames) - for (let i = 0; i < paramNames.length; i++) { - const param = match?.[i + 1] ?? ''; - const v = param.endsWith('/') ? param.slice(0, -1) : param; - params[paramNames[i]] = decodeURIComponent(v); - } - return params; -}; -const loadClientData = async (url, element, clearCache, action) => { - const pagePathname = url.pathname; - const pageSearch = url.search; - const clientDataPath = getClientDataPath(pagePathname, pageSearch, action); - let qData = void 0; - if (!action) qData = CLIENT_DATA_CACHE.get(clientDataPath); - dispatchPrefetchEvent({ - links: [pagePathname], - }); - if (!qData) { - const options = getFetchOptions(action); - if (action) action.data = void 0; - qData = fetch(clientDataPath, options).then((rsp) => { - const redirectedURL = new URL(rsp.url); - if (redirectedURL.origin !== location.origin || !isQDataJson(redirectedURL.pathname)) { - location.href = redirectedURL.href; - return; - } - if ((rsp.headers.get('content-type') || '').includes('json')) - return rsp.text().then((text) => { - const clientData = _deserializeData(text, element); - if (!clientData) { - location.href = url.href; - return; - } - if (clearCache) CLIENT_DATA_CACHE.delete(clientDataPath); - if (clientData.redirect) location.href = clientData.redirect; - else if (action) { - const actionData = clientData.loaders[action.id]; - action.resolve({ - status: rsp.status, - result: actionData, - }); - } - return clientData; - }); - else { - location.href = url.href; - return void 0; - } - }); - if (!action) CLIENT_DATA_CACHE.set(clientDataPath, qData); - } - return qData.then((v) => { - if (!v) CLIENT_DATA_CACHE.delete(clientDataPath); - return v; - }); -}; -const getFetchOptions = (action) => { - const actionData = action?.data; - if (!actionData) return void 0; - if (actionData instanceof FormData) - return { - method: 'POST', - body: actionData, - }; - else - return { - method: 'POST', - body: JSON.stringify(actionData), - headers: { - 'Content-Type': 'application/json, charset=UTF-8', - }, - }; -}; -const isQDataJson = (pathname) => { - return pathname.endsWith(QDATA_JSON); -}; -const QDATA_JSON = '/q-data.json'; -const useContent = () => useContext(ContentContext); -const useDocumentHead = () => useContext(DocumentHeadContext); -const useLocation = () => useContext(RouteLocationContext); -const useNavigate = () => useContext(RouteNavigateContext); -const useAction = () => useContext(RouteActionContext); -const useQwikCityEnv = () => noSerialize(useServerData('qwikcity')); -const QwikCityProvider = /* @__PURE__ */ componentQrl( - /* @__PURE__ */ inlinedQrl((props) => { - useStylesQrl( - /* @__PURE__ */ inlinedQrl( - `:root{view-transition-name: none}`, - 'QwikCityProvider_component_useStyles_RPDJAz33WLA' - ) - ); - const env = useQwikCityEnv(); - if (!env?.params) throw new Error(`Missing Qwik City Env Data`); - const urlEnv = useServerData('url'); - if (!urlEnv) throw new Error(`Missing Qwik URL Env Data`); - const url = new URL(urlEnv); - const routeLocation = useStore( - { - url, - params: env.params, - isNavigating: false, - }, - { - deep: false, - } - ); - const loaderState = _weakSerialize( - useStore(env.response.loaders, { - deep: false, - }) - ); - const navPath = useSignal(toPath(url)); - const documentHead = useStore(createDocumentHead); - const content = useStore({ - headings: void 0, - menu: void 0, - }); - const contentInternal = useSignal(); - const currentActionId = env.response.action; - const currentAction = currentActionId ? env.response.loaders[currentActionId] : void 0; - const actionState = useSignal( - currentAction - ? { - id: currentActionId, - data: env.response.formData, - output: { - result: currentAction, - status: env.response.status, - }, - } - : void 0 - ); - const goto = eventQrl( - /* @__PURE__ */ inlinedQrl( - async (path, forceReload) => { - const [actionState2, navPath2, routeLocation2] = useLexicalScope(); - if (path === void 0) { - path = navPath2.value; - navPath2.value = ''; - } else if (forceReload) navPath2.value = ''; - const resolvedURL = new URL(path, routeLocation2.url); - path = toPath(resolvedURL); - if (!forceReload && navPath2.value === path) return; - navPath2.value = path; - if (isBrowser) { - loadClientData(resolvedURL, _getContextElement()); - loadRoute(qwikCity.routes, qwikCity.menus, qwikCity.cacheModules, resolvedURL.pathname); - } - actionState2.value = void 0; - routeLocation2.isNavigating = true; - }, - 'QwikCityProvider_component_goto_event_cBcjROynRVg', - [actionState, navPath, routeLocation] - ) - ); - useContextProvider(ContentContext, content); - useContextProvider(ContentInternalContext, contentInternal); - useContextProvider(DocumentHeadContext, documentHead); - useContextProvider(RouteLocationContext, routeLocation); - useContextProvider(RouteNavigateContext, goto); - useContextProvider(RouteStateContext, loaderState); - useContextProvider(RouteActionContext, actionState); - useTaskQrl( - /* @__PURE__ */ inlinedQrl( - ({ track }) => { - const [ - actionState2, - content2, - contentInternal2, - documentHead2, - env2, - loaderState2, - navPath2, - props2, - routeLocation2, - url2, - ] = useLexicalScope(); - async function run() { - const [path, action] = track(() => [navPath2.value, actionState2.value]); - const locale = getLocale(''); - let trackUrl; - let clientPageData; - let loadedRoute = null; - if (isServer) { - trackUrl = new URL(path, routeLocation2.url); - loadedRoute = env2.loadedRoute; - clientPageData = env2.response; - } else { - trackUrl = new URL(path, location); - if (trackUrl.pathname.endsWith('/')) { - if (!qwikCity.trailingSlash) trackUrl.pathname = trackUrl.pathname.slice(0, -1); - } else if (qwikCity.trailingSlash) trackUrl.pathname += '/'; - let loadRoutePromise = loadRoute( - qwikCity.routes, - qwikCity.menus, - qwikCity.cacheModules, - trackUrl.pathname - ); - const element = _getContextElement(); - const pageData = (clientPageData = await loadClientData( - trackUrl, - element, - true, - action - )); - if (!pageData) { - navPath2.untrackedValue = toPath(trackUrl); - return; - } - const newHref = pageData.href; - const newURL = new URL(newHref, trackUrl.href); - if (newURL.pathname !== trackUrl.pathname) { - trackUrl = newURL; - loadRoutePromise = loadRoute( - qwikCity.routes, - qwikCity.menus, - qwikCity.cacheModules, - trackUrl.pathname - ); - } - loadedRoute = await loadRoutePromise; - } - if (loadedRoute) { - const [params, mods, menu] = loadedRoute; - const contentModules = mods; - const pageModule = contentModules[contentModules.length - 1]; - routeLocation2.url = trackUrl; - routeLocation2.params = { - ...params, - }; - navPath2.untrackedValue = toPath(trackUrl); - const resolvedHead = resolveHead( - clientPageData, - routeLocation2, - contentModules, - locale - ); - content2.headings = pageModule.headings; - content2.menu = menu; - contentInternal2.value = noSerialize(contentModules); - documentHead2.links = resolvedHead.links; - documentHead2.meta = resolvedHead.meta; - documentHead2.styles = resolvedHead.styles; - documentHead2.title = resolvedHead.title; - documentHead2.frontmatter = resolvedHead.frontmatter; - if (isBrowser) { - if ( - (props2.viewTransition ?? true) && - isSameOriginDifferentPathname(window.location, url2) - ) - document.__q_view_transition__ = true; - const loaders = clientPageData?.loaders; - if (loaders) Object.assign(loaderState2, loaders); - CLIENT_DATA_CACHE.clear(); - clientNavigate(window, trackUrl, navPath2); - routeLocation2.isNavigating = false; - } - } - } - const promise = run(); - if (isServer) return promise; - else return; - }, - 'QwikCityProvider_component_useTask_02wMImzEAbk', - [ - actionState, - content, - contentInternal, - documentHead, - env, - loaderState, - navPath, - props, - routeLocation, - url, - ] - ) - ); - return /* @__PURE__ */ _jsxC(Slot, null, 3, 'qY_0'); - }, 'QwikCityProvider_component_TxCFOy819ag') -); -const QwikCityMockProvider = /* @__PURE__ */ componentQrl( - /* @__PURE__ */ inlinedQrl((props) => { - const urlEnv = props.url ?? 'http://localhost/'; - const url = new URL(urlEnv); - const routeLocation = useStore( - { - url, - params: props.params ?? {}, - isNavigating: false, - }, - { - deep: false, - } - ); - const loaderState = useSignal({}); - const goto = /* @__PURE__ */ inlinedQrl(async (path) => { - throw new Error('Not implemented'); - }, 'QwikCityMockProvider_component_goto_BUbtvTyvVRE'); - const documentHead = useStore(createDocumentHead, { - deep: false, - }); - const content = useStore( - { - headings: void 0, - menu: void 0, - }, - { - deep: false, - } - ); - const contentInternal = useSignal(); - useContextProvider(ContentContext, content); - useContextProvider(ContentInternalContext, contentInternal); - useContextProvider(DocumentHeadContext, documentHead); - useContextProvider(RouteLocationContext, routeLocation); - useContextProvider(RouteNavigateContext, goto); - useContextProvider(RouteStateContext, loaderState); - return /* @__PURE__ */ _jsxC(Slot, null, 3, 'qY_1'); - }, 'QwikCityMockProvider_component_WmYC5H00wtI') -); -const Link = /* @__PURE__ */ componentQrl( - /* @__PURE__ */ inlinedQrl((props) => { - const nav = useNavigate(); - const loc = useLocation(); - const linkProps = { - ...props, - }; - const clientNavPath = untrack(() => getClientNavPath(linkProps, loc)); - const prefetchDataset = untrack(() => getPrefetchDataset(props, clientNavPath, loc)); - const reload = !!linkProps.reload; - linkProps['preventdefault:click'] = !!clientNavPath; - linkProps.href = clientNavPath || props.href; - const event = eventQrl( - /* @__PURE__ */ inlinedQrl( - (ev, elm) => prefetchLinkResources(elm, ev.type === 'qvisible'), - 'Link_component_event_event_5g4B0Gd1Wck' - ) - ); - return /* @__PURE__ */ _jsxS( - 'a', - { - ...linkProps, - 'data-prefetch': prefetchDataset, - children: /* @__PURE__ */ _jsxC(Slot, null, 3, 'AD_0'), - onClick$: /* @__PURE__ */ inlinedQrl( - (_, elm) => { - const [nav2, reload2] = useLexicalScope(); - if (elm.href) nav2(elm.href, reload2); - }, - 'Link_component_a_onClick_kzjavhDI3L0', - [nav, reload] - ), - onMouseOver$: event, - onFocus$: event, - onQVisible$: event, - }, - null, - 0, - 'AD_1' - ); - }, 'Link_component_8gdLBszqbaM') -); -const prefetchLinkResources = (elm, isOnVisible) => { - if (elm && elm.href && elm.hasAttribute('data-prefetch')) { - if (!windowInnerWidth) windowInnerWidth = innerWidth; - if (!isOnVisible || (isOnVisible && windowInnerWidth < 520)) - loadClientData(new URL(elm.href), elm); - } -}; -let windowInnerWidth = 0; -const ServiceWorkerRegister = (props) => - _jsxQ( - 'script', - { - nonce: _wrapSignal(props, 'nonce'), - }, - { - dangerouslySetInnerHTML: swRegister, - }, - null, - 3, - '1Z_0' - ); -const routeActionQrl = (actionQrl, ...rest) => { - const { id, validators } = getValidators(rest, actionQrl); - function action() { - const loc = useLocation(); - const currentAction = useAction(); - const initialState = { - actionPath: `?${QACTION_KEY}=${id}`, - isRunning: false, - status: void 0, - value: void 0, - formData: void 0, - }; - const state = useStore(() => { - const value = currentAction.value; - if (value && value?.id === id) { - const data = value.data; - if (data instanceof FormData) initialState.formData = data; - if (value.output) { - const { status, result } = value.output; - initialState.status = status; - initialState.value = result; - } - } - return initialState; - }); - const submit = /* @__PURE__ */ inlinedQrl( - (input = {}) => { - const [currentAction2, id2, loc2, state2] = useLexicalScope(); - 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; - let form; - if (input instanceof SubmitEvent) { - form = input.target; - data = new FormData(form); - if ( - (input.submitter instanceof HTMLInputElement || - input.submitter instanceof HTMLButtonElement) && - input.submitter.name - ) { - if (input.submitter.name) data.append(input.submitter.name, input.submitter.value); - } - } else data = input; - return new Promise((resolve) => { - if (data instanceof FormData) state2.formData = data; - state2.isRunning = true; - loc2.isNavigating = true; - currentAction2.value = { - data, - id: id2, - resolve: noSerialize(resolve), - }; - }).then(({ result, status }) => { - state2.isRunning = false; - state2.status = status; - state2.value = result; - if (form) { - if (form.getAttribute('data-spa-reset') === 'true') form.reset(); - const detail = { - status, - value: result, - }; - form.dispatchEvent( - new CustomEvent('submitcompleted', { - bubbles: false, - cancelable: false, - composed: false, - detail, - }) - ); - } - return { - status, - value: result, - }; - }); - }, - 'routeActionQrl_action_submit_A5bZC7WO00A', - [currentAction, id, loc, state] - ); - initialState.submit = submit; - return state; - } - action.__brand = 'server_action'; - action.__validators = validators; - action.__qrl = actionQrl; - action.__id = id; - Object.freeze(action); - return action; -}; -const globalActionQrl = (actionQrl, ...rest) => { - const action = routeActionQrl(actionQrl, ...rest); - if (isServer) { - if (typeof globalThis._qwikActionsMap === 'undefined') - globalThis._qwikActionsMap = /* @__PURE__ */ new Map(); - globalThis._qwikActionsMap.set(action.__id, action); - } - return action; -}; -const routeAction$ = /* @__PURE__ */ implicit$FirstArg(routeActionQrl); -const globalAction$ = /* @__PURE__ */ implicit$FirstArg(globalActionQrl); -const routeLoaderQrl = (loaderQrl, ...rest) => { - const { id, validators } = getValidators(rest, loaderQrl); - function loader() { - return useContext(RouteStateContext, (state) => { - if (!(id in state)) - throw new Error(`Loader (${id}) was used in a path where the 'loader$' was not declared. - This is likely because the used loader was not exported in a layout.tsx or index.tsx file of the existing route. - For more information check: https://qwik.dev/qwikcity/route-loader/`); - return _wrapSignal(state, id); - }); - } - loader.__brand = 'server_loader'; - loader.__qrl = loaderQrl; - loader.__validators = validators; - loader.__id = id; - Object.freeze(loader); - return loader; -}; -const routeLoader$ = /* @__PURE__ */ implicit$FirstArg(routeLoaderQrl); -const validatorQrl = (validator) => { - if (isServer) - return { - validate: validator, - }; - return void 0; -}; -const validator$ = /* @__PURE__ */ implicit$FirstArg(validatorQrl); -const zodQrl = (qrl) => { - if (isServer) { - const schema = qrl.resolve().then((obj) => { - if (typeof obj === 'function') obj = obj(z); - if (obj instanceof z.Schema) return obj; - else return z.object(obj); - }); - return { - async validate(ev, inputData) { - const data = inputData ?? (await ev.parseBody()); - const result = await (await schema).safeParseAsync(data); - if (result.success) return result; - else { - if (isDev) - console.error( - '\nVALIDATION ERROR\naction$() zod validated failed', - '\n - Issues:', - result.error.issues - ); - return { - success: false, - status: 400, - error: result.error.flatten(), - }; - } - }, - }; - } - return void 0; -}; -const zod$ = /* @__PURE__ */ implicit$FirstArg(zodQrl); -const serverQrl = (qrl) => { - if (isServer) { - const captured = qrl.getCaptured(); - if (captured && captured.length > 0 && !_getContextElement()) - throw new Error('For security reasons, we cannot serialize QRLs that capture lexical scope.'); - } - function stuff() { - return /* @__PURE__ */ inlinedQrl( - async (...args) => { - const [qrl2] = useLexicalScope(); - if (isServer) { - const requestEvent = useQwikCityEnv()?.ev; - return qrl2.apply(requestEvent, args); - } else { - const ctxElm = _getContextElement(); - const filtered = args.map((arg) => { - if (arg instanceof SubmitEvent && arg.target instanceof HTMLFormElement) - return new FormData(arg.target); - else if (arg instanceof Event) return null; - else if (arg instanceof Node) return null; - return arg; - }); - const hash = qrl2.getHash(); - const path = `?qfunc=${qrl2.getHash()}`; - const body = await _serializeData([qrl2, ...filtered], false); - const res = await fetch(path, { - method: 'POST', - headers: { - 'Content-Type': 'application/qwik-json', - 'X-QRL': hash, - }, - body, - }); - const contentType = res.headers.get('Content-Type'); - if (res.ok && contentType === 'text/event-stream') { - const { writable, readable } = getSSETransformer(); - res.body?.pipeTo(writable); - return streamAsyncIterator(readable, ctxElm ?? document.documentElement); - } else if (contentType === 'application/qwik-json') { - const str = await res.text(); - const obj = await _deserializeData(str, ctxElm ?? document.documentElement); - if (res.status === 500) throw obj; - return obj; - } - } - }, - 'serverQrl_stuff_wOIPfiQ04l4', - [qrl] - ); - } - return stuff(); -}; -const server$ = /* @__PURE__ */ implicit$FirstArg(serverQrl); -const getValidators = (rest, qrl) => { - let id; - const validators = []; - if (rest.length === 1) { - const options = rest[0]; - if (options && typeof options === 'object') { - if ('validate' in options) validators.push(options); - else { - id = options.id; - if (options.validation) validators.push(...options.validation); - } - } - } else if (rest.length > 1) validators.push(...rest.filter((v) => !!v)); - if (typeof id === 'string') { - if (isDev) { - if (!/^[\w/.-]+$/.test(id)) - throw new Error(`Invalid id: ${id}, id can only contain [a-zA-Z0-9_.-]`); - } - id = `id_${id}`; - } else id = qrl.getHash(); - return { - validators: validators.reverse(), - id, - }; -}; -const getSSETransformer = () => { - let currentLine = ''; - const encoder = new TextDecoder(); - const transformer = new TransformStream({ - transform(chunk, controller) { - const lines = encoder.decode(chunk).split('\n\n'); - for (let i = 0; i < lines.length - 1; i++) { - const line = currentLine + lines[i]; - if (line.length === 0) { - controller.terminate(); - break; - } else { - controller.enqueue(parseEvent(line)); - currentLine = ''; - } - } - currentLine += lines[lines.length - 1]; - }, - }); - return transformer; -}; -const parseEvent = (message) => { - const lines = message.split('\n'); - const event = { - data: '', - }; - let data = ''; - for (const line of lines) - if (line.startsWith('data: ')) data += line.slice(6) + '\n'; - else { - const [key, value] = line.split(':'); - if (typeof key === 'string' && typeof value === 'string') event[key] = value.trim(); - } - event.data = data; - return event; -}; -async function* streamAsyncIterator(stream, ctxElm) { - const reader = stream.getReader(); - try { - while (true) { - const { done, value } = await reader.read(); - if (done) return; - const obj = await _deserializeData(value.data, ctxElm); - yield obj; - } - } finally { - reader.releaseLock(); - } -} -const Form = ({ action, spaReset, reloadDocument, onSubmit$, ...rest }, key) => { - _jsxBranch(); - if (action) - return _jsxS( - 'form', - { - ...rest, - action: _wrapSignal(action, 'actionPath'), - 'preventdefault:submit': !reloadDocument, - ['data-spa-reset']: spaReset ? 'true' : void 0, - onSubmit$: [!reloadDocument ? action.submit : void 0, onSubmit$], - }, - { - method: 'post', - }, - 0, - key - ); - else - return /* @__PURE__ */ _jsxC( - GetForm, - { - spaReset, - reloadDocument, - onSubmit$, - ...rest, - }, - 0, - key - ); -}; -const GetForm = /* @__PURE__ */ componentQrl( - /* @__PURE__ */ inlinedQrl((props) => { - const rest = _restProps(props, ['action', 'spaReset', 'reloadDocument', 'onSubmit$']); - const nav = useNavigate(); - return /* @__PURE__ */ _jsxS( - 'form', - { - ...rest, - children: /* @__PURE__ */ _jsxC(Slot, null, 3, 'BC_0'), - onSubmit$: /* @__PURE__ */ inlinedQrl( - async (_, form) => { - const [nav2] = useLexicalScope(); - const formData = new FormData(form); - const params = new URLSearchParams(); - formData.forEach((value, key) => { - if (typeof value === 'string') params.append(key, value); - }); - nav2('?' + params.toString(), true).then(() => { - if (form.getAttribute('data-spa-reset') === 'true') form.reset(); - form.dispatchEvent( - new CustomEvent('submitcompleted', { - bubbles: false, - cancelable: false, - composed: false, - detail: { - status: 200, - }, - }) - ); - }); - }, - 'GetForm_component_form_onSubmit_p9MSze0ojs4', - [nav] - ), - }, - { - action: 'get', - 'preventdefault:submit': _fnSignal( - (p0) => !p0.reloadDocument, - [props], - '!p0.reloadDocument' - ), - 'data-spa-reset': _fnSignal( - (p0) => (p0.spaReset ? 'true' : void 0), - [props], - 'p0.spaReset?"true":undefined' - ), - }, - 0, - 'BC_1' - ); - }, 'GetForm_component_Nk9PlpjQm9Y') -); -export { - Form, - Link, - QwikCityMockProvider, - QwikCityProvider, - RouterOutlet, - ServiceWorkerRegister, - globalAction$, - globalActionQrl, - routeAction$, - routeActionQrl, - routeLoader$, - routeLoaderQrl, - server$, - serverQrl, - useContent, - useDocumentHead, - useLocation, - useNavigate, - validator$, - validatorQrl, - z2 as z, - zod$, - zodQrl, -}; - -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs_RouterOutlet_component_useOnDocument_event_KnNE9eL0qfc.mjs (ENTRY POINT)== - -export const RouterOutlet_component_useOnDocument_event_KnNE9eL0qfc = ()=>{ - const POPSTATE_FALLBACK_INITIALIZED = '_qCityPopstateFallback'; - const CLIENT_HISTORY_INITIALIZED = '_qCityHistory'; - if (!window[POPSTATE_FALLBACK_INITIALIZED]) { - window[POPSTATE_FALLBACK_INITIALIZED] = ()=>{ - if (!window[CLIENT_HISTORY_INITIALIZED]) location.reload(); - }; - setTimeout(()=>{ - addEventListener('popstate', window[POPSTATE_FALLBACK_INITIALIZED]); - }, 0); - } -}; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\"sEAmDmC;IACzB,MAAM,gCAAgC;IACtC,MAAM,6BAA6B;IACnC,IAAI,CAAC,MAAM,CAAC,8BAA8B,EAAE;QAC1C,MAAM,CAAC,8BAA8B,GAAG;YACtC,IAAI,CAAC,MAAM,CAAC,2BAA2B,EAAE,SAAS,MAAM;QAC1D;QACA,WAAW;YACT,iBAAiB,YAAY,MAAM,CAAC,8BAA8B;QACpE,GAAG;IACL;AACF\"}") -/* -{ - "origin": "../node_modules/@builder.io/qwik-city/index.qwik.mjs", - "name": "RouterOutlet_component_useOnDocument_event_KnNE9eL0qfc", - "entry": null, - "displayName": "index.qwik.mjs_RouterOutlet_component_useOnDocument_event", - "hash": "KnNE9eL0qfc", - "canonicalFilename": "index.qwik.mjs_RouterOutlet_component_useOnDocument_event_KnNE9eL0qfc", - "path": "../node_modules/@builder.io/qwik-city", - "extension": "mjs", - "parent": "RouterOutlet_component_AKetNByE5TM", - "ctxKind": "function", - "ctxName": "event$", - "captures": false, - "loc": [ - 1390, - 1893 - ] -} -*/ -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs_RouterOutlet_component_AKetNByE5TM.mjs == - -import { _auto_ContentInternalContext as ContentInternalContext } from "./index.qwik.mjs"; -import { SkipRender } from "@builder.io/qwik"; -import { _jsxBranch } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { eventQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -import { useContext } from "@builder.io/qwik"; -import { useOnDocument } from "@builder.io/qwik"; -export const RouterOutlet_component_AKetNByE5TM = ()=>{ - _jsxBranch(); - useOnDocument('qinit', eventQrl(/*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_RouterOutlet_component_useOnDocument_event_KnNE9eL0qfc.mjs"), "RouterOutlet_component_useOnDocument_event_KnNE9eL0qfc"))); - const context = useContext(ContentInternalContext); - if (context.value && context.value.length > 0) { - const contentsLen = context.value.length; - let cmp = null; - for(let i = contentsLen - 1; i >= 0; i--)cmp = _jsxC(context.value[i].default, { - children: cmp - }, 1, 'k8_0'); - return cmp; - } - return SkipRender; -}; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;;;;;;;kDA8C6B;IACzB;IACA,cACE,SACA;IAeF,MAAM,UAAU,WAAW;IAC3B,IAAI,QAAQ,KAAK,IAAI,QAAQ,KAAK,CAAC,MAAM,GAAG,GAAG;QAC7C,MAAM,cAAc,QAAQ,KAAK,CAAC,MAAM;QACxC,IAAI,MAAM;QACV,IAAK,IAAI,IAAI,cAAc,GAAG,KAAK,GAAG,IACpC,MAAM,MACJ,QAAQ,KAAK,CAAC,EAAE,CAAC,OAAO,EACxB;YACE,UAAU;QACZ,GACA,GACA;QAEJ,OAAO;IACT;IACA,OAAO;AACT\"}") -/* -{ - "origin": "../node_modules/@builder.io/qwik-city/index.qwik.mjs", - "name": "RouterOutlet_component_AKetNByE5TM", - "entry": "../node_modules/@builder.io/qwik-city/index.qwik.mjs_entry_RouterOutlet", - "displayName": "index.qwik.mjs_RouterOutlet_component", - "hash": "AKetNByE5TM", - "canonicalFilename": "index.qwik.mjs_RouterOutlet_component_AKetNByE5TM", - "path": "../node_modules/@builder.io/qwik-city", - "extension": "mjs", - "parent": null, - "ctxKind": "function", - "ctxName": "component$", - "captures": false, - "loc": [ - 1279, - 2396 - ] -} -*/ -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs_QwikCityProvider_component_useStyles_RPDJAz33WLA.mjs == - -export const QwikCityProvider_component_useStyles_RPDJAz33WLA = `:root{view-transition-name: none}`; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\"gEA4XQ,CAAC,iCAAiC,CAAC\"}") -/* -{ - "origin": "../node_modules/@builder.io/qwik-city/index.qwik.mjs", - "name": "QwikCityProvider_component_useStyles_RPDJAz33WLA", - "entry": "../node_modules/@builder.io/qwik-city/index.qwik.mjs_entry_QwikCityProvider", - "displayName": "index.qwik.mjs_QwikCityProvider_component_useStyles", - "hash": "RPDJAz33WLA", - "canonicalFilename": "index.qwik.mjs_QwikCityProvider_component_useStyles_RPDJAz33WLA", - "path": "../node_modules/@builder.io/qwik-city", - "extension": "mjs", - "parent": "QwikCityProvider_component_TxCFOy819ag", - "ctxKind": "function", - "ctxName": "useStyles$", - "captures": false, - "loc": [ - 12723, - 12758 - ] -} -*/ -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs_QwikCityProvider_component_goto_event_cBcjROynRVg.mjs == - -import { _getContextElement } from "@builder.io/qwik"; -import { isBrowser } from "@builder.io/qwik/build"; -import { _auto_loadClientData as loadClientData } from "./index.qwik.mjs"; -import { _auto_loadRoute as loadRoute } from "./index.qwik.mjs"; -import * as qwikCity from "@qwik-city-plan"; -import { _auto_toPath as toPath } from "./index.qwik.mjs"; -import { useLexicalScope } from "@builder.io/qwik"; -export const QwikCityProvider_component_goto_event_cBcjROynRVg = async (path, forceReload)=>{ - const [actionState2, navPath2, routeLocation2] = useLexicalScope(); - if (path === void 0) { - path = navPath2.value; - navPath2.value = ''; - } else if (forceReload) navPath2.value = ''; - const resolvedURL = new URL(path, routeLocation2.url); - path = toPath(resolvedURL); - if (!forceReload && navPath2.value === path) return; - navPath2.value = path; - if (isBrowser) { - loadClientData(resolvedURL, _getContextElement()); - loadRoute(qwikCity.routes, qwikCity.menus, qwikCity.cacheModules, resolvedURL.pathname); - } - actionState2.value = void 0; - routeLocation2.isNavigating = true; -}; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;;;;;;iEA2aQ,OAAO,MAAM;IACX,MAAM,CAAC,cAAc,UAAU,eAAe,GAAG;IACjD,IAAI,SAAS,KAAK,GAAG;QACnB,OAAO,SAAS,KAAK;QACrB,SAAS,KAAK,GAAG;IACnB,OAAO,IAAI,aAAa,SAAS,KAAK,GAAG;IACzC,MAAM,cAAc,IAAI,IAAI,MAAM,eAAe,GAAG;IACpD,OAAO,OAAO;IACd,IAAI,CAAC,eAAe,SAAS,KAAK,KAAK,MAAM;IAC7C,SAAS,KAAK,GAAG;IACjB,IAAI,WAAW;QACb,eAAe,aAAa;QAC5B,UAAU,SAAS,MAAM,EAAE,SAAS,KAAK,EAAE,SAAS,YAAY,EAAE,YAAY,QAAQ;IACxF;IACA,aAAa,KAAK,GAAG,KAAK;IAC1B,eAAe,YAAY,GAAG;AAChC\"}") -/* -{ - "origin": "../node_modules/@builder.io/qwik-city/index.qwik.mjs", - "name": "QwikCityProvider_component_goto_event_cBcjROynRVg", - "entry": "../node_modules/@builder.io/qwik-city/index.qwik.mjs_entry_QwikCityProvider", - "displayName": "index.qwik.mjs_QwikCityProvider_component_goto_event", - "hash": "cBcjROynRVg", - "canonicalFilename": "index.qwik.mjs_QwikCityProvider_component_goto_event_cBcjROynRVg", - "path": "../node_modules/@builder.io/qwik-city", - "extension": "mjs", - "parent": "QwikCityProvider_component_TxCFOy819ag", - "ctxKind": "function", - "ctxName": "event$", - "captures": true, - "loc": [ - 14084, - 14845 - ] -} -*/ -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs_QwikCityProvider_component_useTask_02wMImzEAbk.mjs == - -import { _auto_CLIENT_DATA_CACHE as CLIENT_DATA_CACHE } from "./index.qwik.mjs"; -import { _getContextElement } from "@builder.io/qwik"; -import { _auto_clientNavigate as clientNavigate } from "./index.qwik.mjs"; -import { getLocale } from "@builder.io/qwik"; -import { isBrowser } from "@builder.io/qwik/build"; -import { _auto_isSameOriginDifferentPathname as isSameOriginDifferentPathname } from "./index.qwik.mjs"; -import { isServer } from "@builder.io/qwik/build"; -import { _auto_loadClientData as loadClientData } from "./index.qwik.mjs"; -import { _auto_loadRoute as loadRoute } from "./index.qwik.mjs"; -import { noSerialize } from "@builder.io/qwik"; -import * as qwikCity from "@qwik-city-plan"; -import { _auto_resolveHead as resolveHead } from "./index.qwik.mjs"; -import { _auto_toPath as toPath } from "./index.qwik.mjs"; -import { useLexicalScope } from "@builder.io/qwik"; -export const QwikCityProvider_component_useTask_02wMImzEAbk = ({ track })=>{ - const [actionState2, content2, contentInternal2, documentHead2, env2, loaderState2, navPath2, props2, routeLocation2, url2] = useLexicalScope(); - async function run() { - const [path, action] = track(()=>[ - navPath2.value, - actionState2.value - ]); - const locale = getLocale(''); - let trackUrl; - let clientPageData; - let loadedRoute = null; - if (isServer) { - trackUrl = new URL(path, routeLocation2.url); - loadedRoute = env2.loadedRoute; - clientPageData = env2.response; - } else { - trackUrl = new URL(path, location); - if (trackUrl.pathname.endsWith('/')) { - if (!qwikCity.trailingSlash) trackUrl.pathname = trackUrl.pathname.slice(0, -1); - } else if (qwikCity.trailingSlash) trackUrl.pathname += '/'; - let loadRoutePromise = loadRoute(qwikCity.routes, qwikCity.menus, qwikCity.cacheModules, trackUrl.pathname); - const element = _getContextElement(); - const pageData = clientPageData = await loadClientData(trackUrl, element, true, action); - if (!pageData) { - navPath2.untrackedValue = toPath(trackUrl); - return; - } - const newHref = pageData.href; - const newURL = new URL(newHref, trackUrl.href); - if (newURL.pathname !== trackUrl.pathname) { - trackUrl = newURL; - loadRoutePromise = loadRoute(qwikCity.routes, qwikCity.menus, qwikCity.cacheModules, trackUrl.pathname); - } - loadedRoute = await loadRoutePromise; - } - if (loadedRoute) { - const [params, mods, menu] = loadedRoute; - const contentModules = mods; - const pageModule = contentModules[contentModules.length - 1]; - routeLocation2.url = trackUrl; - routeLocation2.params = { - ...params - }; - navPath2.untrackedValue = toPath(trackUrl); - const resolvedHead = resolveHead(clientPageData, routeLocation2, contentModules, locale); - content2.headings = pageModule.headings; - content2.menu = menu; - contentInternal2.value = noSerialize(contentModules); - documentHead2.links = resolvedHead.links; - documentHead2.meta = resolvedHead.meta; - documentHead2.styles = resolvedHead.styles; - documentHead2.title = resolvedHead.title; - documentHead2.frontmatter = resolvedHead.frontmatter; - if (isBrowser) { - if ((props2.viewTransition ?? true) && isSameOriginDifferentPathname(window.location, url2)) document.__q_view_transition__ = true; - const loaders = clientPageData?.loaders; - if (loaders) Object.assign(loaderState2, loaders); - CLIENT_DATA_CACHE.clear(); - clientNavigate(window, trackUrl, navPath2); - routeLocation2.isNavigating = false; - } - } - } - const promise = run(); - if (isServer) return promise; - else return; -}; -export { _hW } from "@builder.io/qwik"; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;;;;;;;;;;;;;8DAycQ,CAAC,EAAE,KAAK,EAAE;IACR,MAAM,CACJ,cACA,UACA,kBACA,eACA,MACA,cACA,UACA,QACA,gBACA,KACD,GAAG;IACJ,eAAe;QACb,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,IAAM;gBAAC,SAAS,KAAK;gBAAE,aAAa,KAAK;aAAC;QACvE,MAAM,SAAS,UAAU;QACzB,IAAI;QACJ,IAAI;QACJ,IAAI,cAAc;QAClB,IAAI,UAAU;YACZ,WAAW,IAAI,IAAI,MAAM,eAAe,GAAG;YAC3C,cAAc,KAAK,WAAW;YAC9B,iBAAiB,KAAK,QAAQ;QAChC,OAAO;YACL,WAAW,IAAI,IAAI,MAAM;YACzB,IAAI,SAAS,QAAQ,CAAC,QAAQ,CAAC,MAC7B;gBAAA,IAAI,CAAC,SAAS,aAAa,EAAE,SAAS,QAAQ,GAAG,SAAS,QAAQ,CAAC,KAAK,CAAC,GAAG;YAAG,OAC1E,IAAI,SAAS,aAAa,EAAE,SAAS,QAAQ,IAAI;YACxD,IAAI,mBAAmB,UACrB,SAAS,MAAM,EACf,SAAS,KAAK,EACd,SAAS,YAAY,EACrB,SAAS,QAAQ;YAEnB,MAAM,UAAU;YAChB,MAAM,WAAY,iBAAiB,MAAM,eACvC,UACA,SACA,MACA;YAEF,IAAI,CAAC,UAAU;gBACb,SAAS,cAAc,GAAG,OAAO;gBACjC;YACF;YACA,MAAM,UAAU,SAAS,IAAI;YAC7B,MAAM,SAAS,IAAI,IAAI,SAAS,SAAS,IAAI;YAC7C,IAAI,OAAO,QAAQ,KAAK,SAAS,QAAQ,EAAE;gBACzC,WAAW;gBACX,mBAAmB,UACjB,SAAS,MAAM,EACf,SAAS,KAAK,EACd,SAAS,YAAY,EACrB,SAAS,QAAQ;YAErB;YACA,cAAc,MAAM;QACtB;QACA,IAAI,aAAa;YACf,MAAM,CAAC,QAAQ,MAAM,KAAK,GAAG;YAC7B,MAAM,iBAAiB;YACvB,MAAM,aAAa,cAAc,CAAC,eAAe,MAAM,GAAG,EAAE;YAC5D,eAAe,GAAG,GAAG;YACrB,eAAe,MAAM,GAAG;gBACtB,GAAG,MAAM;YACX;YACA,SAAS,cAAc,GAAG,OAAO;YACjC,MAAM,eAAe,YACnB,gBACA,gBACA,gBACA;YAEF,SAAS,QAAQ,GAAG,WAAW,QAAQ;YACvC,SAAS,IAAI,GAAG;YAChB,iBAAiB,KAAK,GAAG,YAAY;YACrC,cAAc,KAAK,GAAG,aAAa,KAAK;YACxC,cAAc,IAAI,GAAG,aAAa,IAAI;YACtC,cAAc,MAAM,GAAG,aAAa,MAAM;YAC1C,cAAc,KAAK,GAAG,aAAa,KAAK;YACxC,cAAc,WAAW,GAAG,aAAa,WAAW;YACpD,IAAI,WAAW;gBACb,IACE,CAAC,OAAO,cAAc,IAAI,IAAI,KAC9B,8BAA8B,OAAO,QAAQ,EAAE,OAE/C,SAAS,qBAAqB,GAAG;gBACnC,MAAM,UAAU,gBAAgB;gBAChC,IAAI,SAAS,OAAO,MAAM,CAAC,cAAc;gBACzC,kBAAkB,KAAK;gBACvB,eAAe,QAAQ,UAAU;gBACjC,eAAe,YAAY,GAAG;YAChC;QACF;IACF;IACA,MAAM,UAAU;IAChB,IAAI,UAAU,OAAO;SAChB;AACP\"}") -/* -{ - "origin": "../node_modules/@builder.io/qwik-city/index.qwik.mjs", - "name": "QwikCityProvider_component_useTask_02wMImzEAbk", - "entry": "../node_modules/@builder.io/qwik-city/index.qwik.mjs_entry_QwikCityProvider", - "displayName": "index.qwik.mjs_QwikCityProvider_component_useTask", - "hash": "02wMImzEAbk", - "canonicalFilename": "index.qwik.mjs_QwikCityProvider_component_useTask_02wMImzEAbk", - "path": "../node_modules/@builder.io/qwik-city", - "extension": "mjs", - "parent": "QwikCityProvider_component_TxCFOy819ag", - "ctxKind": "function", - "ctxName": "useTask$", - "captures": true, - "loc": [ - 15426, - 19233 - ] -} -*/ -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs_QwikCityProvider_component_TxCFOy819ag.mjs == - -import { _auto_ContentContext as ContentContext } from "./index.qwik.mjs"; -import { _auto_ContentInternalContext as ContentInternalContext } from "./index.qwik.mjs"; -import { _auto_DocumentHeadContext as DocumentHeadContext } from "./index.qwik.mjs"; -import { _auto_RouteActionContext as RouteActionContext } from "./index.qwik.mjs"; -import { _auto_RouteLocationContext as RouteLocationContext } from "./index.qwik.mjs"; -import { _auto_RouteNavigateContext as RouteNavigateContext } from "./index.qwik.mjs"; -import { _auto_RouteStateContext as RouteStateContext } from "./index.qwik.mjs"; -import { Slot } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { _weakSerialize } from "@builder.io/qwik"; -import { _auto_createDocumentHead as createDocumentHead } from "./index.qwik.mjs"; -import { eventQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -import { _auto_toPath as toPath } from "./index.qwik.mjs"; -import { useContextProvider } from "@builder.io/qwik"; -import { _auto_useQwikCityEnv as useQwikCityEnv } from "./index.qwik.mjs"; -import { useServerData } from "@builder.io/qwik"; -import { useSignal } from "@builder.io/qwik"; -import { useStore } from "@builder.io/qwik"; -import { useStylesQrl } from "@builder.io/qwik"; -import { useTaskQrl } from "@builder.io/qwik"; -export const QwikCityProvider_component_TxCFOy819ag = (props)=>{ - useStylesQrl(/*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_QwikCityProvider_component_useStyles_RPDJAz33WLA.mjs"), "QwikCityProvider_component_useStyles_RPDJAz33WLA")); - const env = useQwikCityEnv(); - if (!env?.params) throw new Error(`Missing Qwik City Env Data`); - const urlEnv = useServerData('url'); - if (!urlEnv) throw new Error(`Missing Qwik URL Env Data`); - const url = new URL(urlEnv); - const routeLocation = useStore({ - url, - params: env.params, - isNavigating: false - }, { - deep: false - }); - const loaderState = _weakSerialize(useStore(env.response.loaders, { - deep: false - })); - const navPath = useSignal(toPath(url)); - const documentHead = useStore(createDocumentHead); - const content = useStore({ - headings: void 0, - menu: void 0 - }); - const contentInternal = useSignal(); - const currentActionId = env.response.action; - const currentAction = currentActionId ? env.response.loaders[currentActionId] : void 0; - const actionState = useSignal(currentAction ? { - id: currentActionId, - data: env.response.formData, - output: { - result: currentAction, - status: env.response.status - } - } : void 0); - const goto = eventQrl(/*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_QwikCityProvider_component_goto_event_cBcjROynRVg.mjs"), "QwikCityProvider_component_goto_event_cBcjROynRVg", [ - actionState, - navPath, - routeLocation - ])); - useContextProvider(ContentContext, content); - useContextProvider(ContentInternalContext, contentInternal); - useContextProvider(DocumentHeadContext, documentHead); - useContextProvider(RouteLocationContext, routeLocation); - useContextProvider(RouteNavigateContext, goto); - useContextProvider(RouteStateContext, loaderState); - useContextProvider(RouteActionContext, actionState); - useTaskQrl(/*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_QwikCityProvider_component_useTask_02wMImzEAbk.mjs"), "QwikCityProvider_component_useTask_02wMImzEAbk", [ - actionState, - content, - contentInternal, - documentHead, - env, - loaderState, - navPath, - props, - routeLocation, - url - ])); - return /* @__PURE__ */ _jsxC(Slot, null, 3, 'qY_0'); -}; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;;;;;;;;;;;;;;;;;;;;sDAyX6B,CAAC;IAC1B;IAMA,MAAM,MAAM;IACZ,IAAI,CAAC,KAAK,QAAQ,MAAM,IAAI,MAAM,CAAC,0BAA0B,CAAC;IAC9D,MAAM,SAAS,cAAc;IAC7B,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,CAAC,yBAAyB,CAAC;IACxD,MAAM,MAAM,IAAI,IAAI;IACpB,MAAM,gBAAgB,SACpB;QACE;QACA,QAAQ,IAAI,MAAM;QAClB,cAAc;IAChB,GACA;QACE,MAAM;IACR;IAEF,MAAM,cAAc,eAClB,SAAS,IAAI,QAAQ,CAAC,OAAO,EAAE;QAC7B,MAAM;IACR;IAEF,MAAM,UAAU,UAAU,OAAO;IACjC,MAAM,eAAe,SAAS;IAC9B,MAAM,UAAU,SAAS;QACvB,UAAU,KAAK;QACf,MAAM,KAAK;IACb;IACA,MAAM,kBAAkB;IACxB,MAAM,kBAAkB,IAAI,QAAQ,CAAC,MAAM;IAC3C,MAAM,gBAAgB,kBAAkB,IAAI,QAAQ,CAAC,OAAO,CAAC,gBAAgB,GAAG,KAAK;IACrF,MAAM,cAAc,UAClB,gBACI;QACE,IAAI;QACJ,MAAM,IAAI,QAAQ,CAAC,QAAQ;QAC3B,QAAQ;YACN,QAAQ;YACR,QAAQ,IAAI,QAAQ,CAAC,MAAM;QAC7B;IACF,IACA,KAAK;IAEX,MAAM,OAAO;;;;;IAuBb,mBAAmB,gBAAgB;IACnC,mBAAmB,wBAAwB;IAC3C,mBAAmB,qBAAqB;IACxC,mBAAmB,sBAAsB;IACzC,mBAAmB,sBAAsB;IACzC,mBAAmB,mBAAmB;IACtC,mBAAmB,oBAAoB;IACvC;;;;;;;;;;;;IAoHA,OAAO,aAAa,GAAG,MAAM,MAAM,MAAM,GAAG;AAC9C\"}") -/* -{ - "origin": "../node_modules/@builder.io/qwik-city/index.qwik.mjs", - "name": "QwikCityProvider_component_TxCFOy819ag", - "entry": "../node_modules/@builder.io/qwik-city/index.qwik.mjs_entry_QwikCityProvider", - "displayName": "index.qwik.mjs_QwikCityProvider_component", - "hash": "TxCFOy819ag", - "canonicalFilename": "index.qwik.mjs_QwikCityProvider_component_TxCFOy819ag", - "path": "../node_modules/@builder.io/qwik-city", - "extension": "mjs", - "parent": null, - "ctxKind": "function", - "ctxName": "component$", - "captures": false, - "loc": [ - 12650, - 19595 - ] -} -*/ -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs_QwikCityMockProvider_component_goto_BUbtvTyvVRE.mjs == - -export const QwikCityMockProvider_component_goto_BUbtvTyvVRE = async (path)=>{ - throw new Error('Not implemented'); -}; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\"+DA6kB4C,OAAO;IAC7C,MAAM,IAAI,MAAM;AAClB\"}") -/* -{ - "origin": "../node_modules/@builder.io/qwik-city/index.qwik.mjs", - "name": "QwikCityMockProvider_component_goto_BUbtvTyvVRE", - "entry": "../node_modules/@builder.io/qwik-city/index.qwik.mjs_entry_QwikCityMockProvider", - "displayName": "index.qwik.mjs_QwikCityMockProvider_component_goto", - "hash": "BUbtvTyvVRE", - "canonicalFilename": "index.qwik.mjs_QwikCityMockProvider_component_goto_BUbtvTyvVRE", - "path": "../node_modules/@builder.io/qwik-city", - "extension": "mjs", - "parent": "QwikCityMockProvider_component_WmYC5H00wtI", - "ctxKind": "function", - "ctxName": "goto", - "captures": false, - "loc": [ - 20087, - 20152 - ] -} -*/ -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs_QwikCityMockProvider_component_WmYC5H00wtI.mjs == - -import { _auto_ContentContext as ContentContext } from "./index.qwik.mjs"; -import { _auto_ContentInternalContext as ContentInternalContext } from "./index.qwik.mjs"; -import { _auto_DocumentHeadContext as DocumentHeadContext } from "./index.qwik.mjs"; -import { _auto_RouteLocationContext as RouteLocationContext } from "./index.qwik.mjs"; -import { _auto_RouteNavigateContext as RouteNavigateContext } from "./index.qwik.mjs"; -import { _auto_RouteStateContext as RouteStateContext } from "./index.qwik.mjs"; -import { Slot } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { _auto_createDocumentHead as createDocumentHead } from "./index.qwik.mjs"; -import { qrl } from "@builder.io/qwik"; -import { useContextProvider } from "@builder.io/qwik"; -import { useSignal } from "@builder.io/qwik"; -import { useStore } from "@builder.io/qwik"; -export const QwikCityMockProvider_component_WmYC5H00wtI = (props)=>{ - const urlEnv = props.url ?? 'http://localhost/'; - const url = new URL(urlEnv); - const routeLocation = useStore({ - url, - params: props.params ?? {}, - isNavigating: false - }, { - deep: false - }); - const loaderState = useSignal({}); - const goto = /*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_QwikCityMockProvider_component_goto_BUbtvTyvVRE.mjs"), "QwikCityMockProvider_component_goto_BUbtvTyvVRE"); - const documentHead = useStore(createDocumentHead, { - deep: false - }); - const content = useStore({ - headings: void 0, - menu: void 0 - }, { - deep: false - }); - const contentInternal = useSignal(); - useContextProvider(ContentContext, content); - useContextProvider(ContentInternalContext, contentInternal); - useContextProvider(DocumentHeadContext, documentHead); - useContextProvider(RouteLocationContext, routeLocation); - useContextProvider(RouteNavigateContext, goto); - useContextProvider(RouteStateContext, loaderState); - return /* @__PURE__ */ _jsxC(Slot, null, 3, 'qY_1'); -}; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;;;;;;;;;;;;0DA+jB6B,CAAC;IAC1B,MAAM,SAAS,MAAM,GAAG,IAAI;IAC5B,MAAM,MAAM,IAAI,IAAI;IACpB,MAAM,gBAAgB,SACpB;QACE;QACA,QAAQ,MAAM,MAAM,IAAI,CAAC;QACzB,cAAc;IAChB,GACA;QACE,MAAM;IACR;IAEF,MAAM,cAAc,UAAU,CAAC;IAC/B,MAAM;IAGN,MAAM,eAAe,SAAS,oBAAoB;QAChD,MAAM;IACR;IACA,MAAM,UAAU,SACd;QACE,UAAU,KAAK;QACf,MAAM,KAAK;IACb,GACA;QACE,MAAM;IACR;IAEF,MAAM,kBAAkB;IACxB,mBAAmB,gBAAgB;IACnC,mBAAmB,wBAAwB;IAC3C,mBAAmB,qBAAqB;IACxC,mBAAmB,sBAAsB;IACzC,mBAAmB,sBAAsB;IACzC,mBAAmB,mBAAmB;IACtC,OAAO,aAAa,GAAG,MAAM,MAAM,MAAM,GAAG;AAC9C\"}") -/* -{ - "origin": "../node_modules/@builder.io/qwik-city/index.qwik.mjs", - "name": "QwikCityMockProvider_component_WmYC5H00wtI", - "entry": "../node_modules/@builder.io/qwik-city/index.qwik.mjs_entry_QwikCityMockProvider", - "displayName": "index.qwik.mjs_QwikCityMockProvider_component", - "hash": "WmYC5H00wtI", - "canonicalFilename": "index.qwik.mjs_QwikCityMockProvider_component_WmYC5H00wtI", - "path": "../node_modules/@builder.io/qwik-city", - "extension": "mjs", - "parent": null, - "ctxKind": "function", - "ctxName": "component$", - "captures": false, - "loc": [ - 19730, - 20871 - ] -} -*/ -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs_Link_component_event_event_5g4B0Gd1Wck.mjs (ENTRY POINT)== - -import { _auto_prefetchLinkResources as prefetchLinkResources } from "./index.qwik.mjs"; -export const Link_component_event_event_5g4B0Gd1Wck = (ev, elm)=>prefetchLinkResources(elm, ev.type === 'qvisible'); - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\";sDAonBQ,CAAC,IAAI,MAAQ,sBAAsB,KAAK,GAAG,IAAI,KAAK\"}") -/* -{ - "origin": "../node_modules/@builder.io/qwik-city/index.qwik.mjs", - "name": "Link_component_event_event_5g4B0Gd1Wck", - "entry": null, - "displayName": "index.qwik.mjs_Link_component_event_event", - "hash": "5g4B0Gd1Wck", - "canonicalFilename": "index.qwik.mjs_Link_component_event_event_5g4B0Gd1Wck", - "path": "../node_modules/@builder.io/qwik-city", - "extension": "mjs", - "parent": "Link_component_8gdLBszqbaM", - "ctxKind": "function", - "ctxName": "event$", - "captures": false, - "loc": [ - 21497, - 21560 - ] -} -*/ -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs_Link_component_a_onClick_kzjavhDI3L0.mjs == - -import { useLexicalScope } from "@builder.io/qwik"; -export const Link_component_a_onClick_kzjavhDI3L0 = (_, elm)=>{ - const [nav2, reload2] = useLexicalScope(); - if (elm.href) nav2(elm.href, reload2); -}; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\";oDA+nBU,CAAC,GAAG;IACF,MAAM,CAAC,MAAM,QAAQ,GAAG;IACxB,IAAI,IAAI,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE;AAC/B\"}") -/* -{ - "origin": "../node_modules/@builder.io/qwik-city/index.qwik.mjs", - "name": "Link_component_a_onClick_kzjavhDI3L0", - "entry": "../node_modules/@builder.io/qwik-city/index.qwik.mjs_entry_Link", - "displayName": "index.qwik.mjs_Link_component_a_onClick", - "hash": "kzjavhDI3L0", - "canonicalFilename": "index.qwik.mjs_Link_component_a_onClick_kzjavhDI3L0", - "path": "../node_modules/@builder.io/qwik-city", - "extension": "mjs", - "parent": "Link_component_8gdLBszqbaM", - "ctxKind": "function", - "ctxName": "_jsxS", - "captures": true, - "loc": [ - 21863, - 21994 - ] -} -*/ -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs_Link_component_8gdLBszqbaM.mjs == - -import { Slot } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { _jsxS } from "@builder.io/qwik"; -import { eventQrl } from "@builder.io/qwik"; -import { _auto_getClientNavPath as getClientNavPath } from "./index.qwik.mjs"; -import { _auto_getPrefetchDataset as getPrefetchDataset } from "./index.qwik.mjs"; -import { qrl } from "@builder.io/qwik"; -import { untrack } from "@builder.io/qwik"; -import { useLocation } from "./index.qwik.mjs"; -import { useNavigate } from "./index.qwik.mjs"; -export const Link_component_8gdLBszqbaM = (props)=>{ - const nav = useNavigate(); - const loc = useLocation(); - const linkProps = { - ...props - }; - const clientNavPath = untrack(()=>getClientNavPath(linkProps, loc)); - const prefetchDataset = untrack(()=>getPrefetchDataset(props, clientNavPath, loc)); - const reload = !!linkProps.reload; - linkProps['preventdefault:click'] = !!clientNavPath; - linkProps.href = clientNavPath || props.href; - const event = eventQrl(/*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_Link_component_event_event_5g4B0Gd1Wck.mjs"), "Link_component_event_event_5g4B0Gd1Wck")); - return /* @__PURE__ */ _jsxS('a', { - ...linkProps, - 'data-prefetch': prefetchDataset, - children: /* @__PURE__ */ _jsxC(Slot, null, 3, 'AD_0'), - onClick$: /*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_Link_component_a_onClick_kzjavhDI3L0.mjs"), "Link_component_a_onClick_kzjavhDI3L0", [ - nav, - reload - ]), - onMouseOver$: event, - onFocus$: event, - onQVisible$: event - }, null, 0, 'AD_1'); -}; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;;;;;;;;;0CAumB6B,CAAC;IAC1B,MAAM,MAAM;IACZ,MAAM,MAAM;IACZ,MAAM,YAAY;QAChB,GAAG,KAAK;IACV;IACA,MAAM,gBAAgB,QAAQ,IAAM,iBAAiB,WAAW;IAChE,MAAM,kBAAkB,QAAQ,IAAM,mBAAmB,OAAO,eAAe;IAC/E,MAAM,SAAS,CAAC,CAAC,UAAU,MAAM;IACjC,SAAS,CAAC,uBAAuB,GAAG,CAAC,CAAC;IACtC,UAAU,IAAI,GAAG,iBAAiB,MAAM,IAAI;IAC5C,MAAM,QAAQ;IAMd,OAAO,aAAa,GAAG,MACrB,KACA;QACE,GAAG,SAAS;QACZ,iBAAiB;QACjB,UAAU,aAAa,GAAG,MAAM,MAAM,MAAM,GAAG;QAC/C,QAAQ;;;;QAQR,cAAc;QACd,UAAU;QACV,aAAa;IACf,GACA,MACA,GACA;AAEJ\"}") -/* -{ - "origin": "../node_modules/@builder.io/qwik-city/index.qwik.mjs", - "name": "Link_component_8gdLBszqbaM", - "entry": "../node_modules/@builder.io/qwik-city/index.qwik.mjs_entry_Link", - "displayName": "index.qwik.mjs_Link_component", - "hash": "8gdLBszqbaM", - "canonicalFilename": "index.qwik.mjs_Link_component_8gdLBszqbaM", - "path": "../node_modules/@builder.io/qwik-city", - "extension": "mjs", - "parent": null, - "ctxKind": "function", - "ctxName": "component$", - "captures": false, - "loc": [ - 20994, - 22216 - ] -} -*/ -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs_routeActionQrl_action_submit_A5bZC7WO00A.mjs == - -import { isServer } from "@builder.io/qwik/build"; -import { noSerialize } from "@builder.io/qwik"; -import { useLexicalScope } from "@builder.io/qwik"; -export const routeActionQrl_action_submit_A5bZC7WO00A = (input = {})=>{ - const [currentAction2, id2, loc2, state2] = useLexicalScope(); - 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; - let form; - if (input instanceof SubmitEvent) { - form = input.target; - data = new FormData(form); - if ((input.submitter instanceof HTMLInputElement || input.submitter instanceof HTMLButtonElement) && input.submitter.name) { - if (input.submitter.name) data.append(input.submitter.name, input.submitter.value); - } - } else data = input; - return new Promise((resolve)=>{ - if (data instanceof FormData) state2.formData = data; - state2.isRunning = true; - loc2.isNavigating = true; - currentAction2.value = { - data, - id: id2, - resolve: noSerialize(resolve) - }; - }).then(({ result, status })=>{ - state2.isRunning = false; - state2.status = status; - state2.value = result; - if (form) { - if (form.getAttribute('data-spa-reset') === 'true') form.reset(); - const detail = { - status, - value: result - }; - form.dispatchEvent(new CustomEvent('submitcompleted', { - bubbles: false, - cancelable: false, - composed: false, - detail - })); - } - return { - status, - value: result - }; - }); -}; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;;wDA+rBM,CAAC,QAAQ,CAAC,CAAC;IACT,MAAM,CAAC,gBAAgB,KAAK,MAAM,OAAO,GAAG;IAC5C,IAAI,UACF,MAAM,IAAI,MAAM,CAAC;2GACgF,CAAC;IACpG,IAAI;IACJ,IAAI;IACJ,IAAI,iBAAiB,aAAa;QAChC,OAAO,MAAM,MAAM;QACnB,OAAO,IAAI,SAAS;QACpB,IACE,CAAC,MAAM,SAAS,YAAY,oBAC1B,MAAM,SAAS,YAAY,iBAAiB,KAC9C,MAAM,SAAS,CAAC,IAAI,EAEpB;YAAA,IAAI,MAAM,SAAS,CAAC,IAAI,EAAE,KAAK,MAAM,CAAC,MAAM,SAAS,CAAC,IAAI,EAAE,MAAM,SAAS,CAAC,KAAK;QAAC;IAEtF,OAAO,OAAO;IACd,OAAO,IAAI,QAAQ,CAAC;QAClB,IAAI,gBAAgB,UAAU,OAAO,QAAQ,GAAG;QAChD,OAAO,SAAS,GAAG;QACnB,KAAK,YAAY,GAAG;QACpB,eAAe,KAAK,GAAG;YACrB;YACA,IAAI;YACJ,SAAS,YAAY;QACvB;IACF,GAAG,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE;QACzB,OAAO,SAAS,GAAG;QACnB,OAAO,MAAM,GAAG;QAChB,OAAO,KAAK,GAAG;QACf,IAAI,MAAM;YACR,IAAI,KAAK,YAAY,CAAC,sBAAsB,QAAQ,KAAK,KAAK;YAC9D,MAAM,SAAS;gBACb;gBACA,OAAO;YACT;YACA,KAAK,aAAa,CAChB,IAAI,YAAY,mBAAmB;gBACjC,SAAS;gBACT,YAAY;gBACZ,UAAU;gBACV;YACF;QAEJ;QACA,OAAO;YACL;YACA,OAAO;QACT;IACF;AACF\"}") -/* -{ - "origin": "../node_modules/@builder.io/qwik-city/index.qwik.mjs", - "name": "routeActionQrl_action_submit_A5bZC7WO00A", - "entry": "../node_modules/@builder.io/qwik-city/index.qwik.mjs_entry_routeActionQrl", - "displayName": "index.qwik.mjs_routeActionQrl_action_submit", - "hash": "A5bZC7WO00A", - "canonicalFilename": "index.qwik.mjs_routeActionQrl_action_submit_A5bZC7WO00A", - "path": "../node_modules/@builder.io/qwik-city", - "extension": "mjs", - "parent": null, - "ctxKind": "function", - "ctxName": "submit", - "captures": true, - "loc": [ - 23627, - 25399 - ] -} -*/ -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs_serverQrl_stuff_wOIPfiQ04l4.mjs == - -import { _deserializeData } from "@builder.io/qwik"; -import { _getContextElement } from "@builder.io/qwik"; -import { _serializeData } from "@builder.io/qwik"; -import { _auto_getSSETransformer as getSSETransformer } from "./index.qwik.mjs"; -import { isServer } from "@builder.io/qwik/build"; -import { _auto_streamAsyncIterator as streamAsyncIterator } from "./index.qwik.mjs"; -import { useLexicalScope } from "@builder.io/qwik"; -import { _auto_useQwikCityEnv as useQwikCityEnv } from "./index.qwik.mjs"; -export const serverQrl_stuff_wOIPfiQ04l4 = async (...args)=>{ - const [qrl2] = useLexicalScope(); - if (isServer) { - const requestEvent = useQwikCityEnv()?.ev; - return qrl2.apply(requestEvent, args); - } else { - const ctxElm = _getContextElement(); - const filtered = args.map((arg)=>{ - if (arg instanceof SubmitEvent && arg.target instanceof HTMLFormElement) return new FormData(arg.target); - else if (arg instanceof Event) return null; - else if (arg instanceof Node) return null; - return arg; - }); - const hash = qrl2.getHash(); - const path = `?qfunc=${qrl2.getHash()}`; - const body = await _serializeData([ - qrl2, - ...filtered - ], false); - const res = await fetch(path, { - method: 'POST', - headers: { - 'Content-Type': 'application/qwik-json', - 'X-QRL': hash - }, - body - }); - const contentType = res.headers.get('Content-Type'); - if (res.ok && contentType === 'text/event-stream') { - const { writable, readable } = getSSETransformer(); - res.body?.pipeTo(writable); - return streamAsyncIterator(readable, ctxElm ?? document.documentElement); - } else if (contentType === 'application/qwik-json') { - const str = await res.text(); - const obj = await _deserializeData(str, ctxElm ?? document.documentElement); - if (res.status === 500) throw obj; - return obj; - } - } -}; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;;;;;;;2CA60BM,OAAO,GAAG;IACR,MAAM,CAAC,KAAK,GAAG;IACf,IAAI,UAAU;QACZ,MAAM,eAAe,kBAAkB;QACvC,OAAO,KAAK,KAAK,CAAC,cAAc;IAClC,OAAO;QACL,MAAM,SAAS;QACf,MAAM,WAAW,KAAK,GAAG,CAAC,CAAC;YACzB,IAAI,eAAe,eAAe,IAAI,MAAM,YAAY,iBACtD,OAAO,IAAI,SAAS,IAAI,MAAM;iBAC3B,IAAI,eAAe,OAAO,OAAO;iBACjC,IAAI,eAAe,MAAM,OAAO;YACrC,OAAO;QACT;QACA,MAAM,OAAO,KAAK,OAAO;QACzB,MAAM,OAAO,CAAC,OAAO,EAAE,KAAK,OAAO,IAAI;QACvC,MAAM,OAAO,MAAM,eAAe;YAAC;eAAS;SAAS,EAAE;QACvD,MAAM,MAAM,MAAM,MAAM,MAAM;YAC5B,QAAQ;YACR,SAAS;gBACP,gBAAgB;gBAChB,SAAS;YACX;YACA;QACF;QACA,MAAM,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC;QACpC,IAAI,IAAI,EAAE,IAAI,gBAAgB,qBAAqB;YACjD,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG;YAC/B,IAAI,IAAI,EAAE,OAAO;YACjB,OAAO,oBAAoB,UAAU,UAAU,SAAS,eAAe;QACzE,OAAO,IAAI,gBAAgB,yBAAyB;YAClD,MAAM,MAAM,MAAM,IAAI,IAAI;YAC1B,MAAM,MAAM,MAAM,iBAAiB,KAAK,UAAU,SAAS,eAAe;YAC1E,IAAI,IAAI,MAAM,KAAK,KAAK,MAAM;YAC9B,OAAO;QACT;IACF;AACF\"}") -/* -{ - "origin": "../node_modules/@builder.io/qwik-city/index.qwik.mjs", - "name": "serverQrl_stuff_wOIPfiQ04l4", - "entry": "../node_modules/@builder.io/qwik-city/index.qwik.mjs_entry_serverQrl", - "displayName": "index.qwik.mjs_serverQrl_stuff", - "hash": "wOIPfiQ04l4", - "canonicalFilename": "index.qwik.mjs_serverQrl_stuff_wOIPfiQ04l4", - "path": "../node_modules/@builder.io/qwik-city", - "extension": "mjs", - "parent": null, - "ctxKind": "function", - "ctxName": "stuff", - "captures": true, - "loc": [ - 28381, - 29960 - ] -} -*/ -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs_GetForm_component_form_onSubmit_p9MSze0ojs4.mjs == - -import { useLexicalScope } from "@builder.io/qwik"; -export const GetForm_component_form_onSubmit_p9MSze0ojs4 = async (_, form)=>{ - const [nav2] = useLexicalScope(); - const formData = new FormData(form); - const params = new URLSearchParams(); - formData.forEach((value, key)=>{ - if (typeof value === 'string') params.append(key, value); - }); - nav2('?' + params.toString(), true).then(()=>{ - if (form.getAttribute('data-spa-reset') === 'true') form.reset(); - form.dispatchEvent(new CustomEvent('submitcompleted', { - bubbles: false, - cancelable: false, - composed: false, - detail: { - status: 200 - } - })); - }); -}; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\";2DA6+BU,OAAO,GAAG;IACR,MAAM,CAAC,KAAK,GAAG;IACf,MAAM,WAAW,IAAI,SAAS;IAC9B,MAAM,SAAS,IAAI;IACnB,SAAS,OAAO,CAAC,CAAC,OAAO;QACvB,IAAI,OAAO,UAAU,UAAU,OAAO,MAAM,CAAC,KAAK;IACpD;IACA,KAAK,MAAM,OAAO,QAAQ,IAAI,MAAM,IAAI,CAAC;QACvC,IAAI,KAAK,YAAY,CAAC,sBAAsB,QAAQ,KAAK,KAAK;QAC9D,KAAK,aAAa,CAChB,IAAI,YAAY,mBAAmB;YACjC,SAAS;YACT,YAAY;YACZ,UAAU;YACV,QAAQ;gBACN,QAAQ;YACV;QACF;IAEJ;AACF\"}") -/* -{ - "origin": "../node_modules/@builder.io/qwik-city/index.qwik.mjs", - "name": "GetForm_component_form_onSubmit_p9MSze0ojs4", - "entry": "../node_modules/@builder.io/qwik-city/index.qwik.mjs_entry_GetForm", - "displayName": "index.qwik.mjs_GetForm_component_form_onSubmit", - "hash": "p9MSze0ojs4", - "canonicalFilename": "index.qwik.mjs_GetForm_component_form_onSubmit_p9MSze0ojs4", - "path": "../node_modules/@builder.io/qwik-city", - "extension": "mjs", - "parent": "GetForm_component_Nk9PlpjQm9Y", - "ctxKind": "function", - "ctxName": "_jsxS", - "captures": true, - "loc": [ - 33229, - 34009 - ] -} -*/ -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs_GetForm_component_Nk9PlpjQm9Y.mjs == - -import { Slot } from "@builder.io/qwik"; -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { _jsxS } from "@builder.io/qwik"; -import { _restProps } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -import { useNavigate } from "./index.qwik.mjs"; -export const GetForm_component_Nk9PlpjQm9Y = (props)=>{ - const rest = _restProps(props, [ - 'action', - 'spaReset', - 'reloadDocument', - 'onSubmit$' - ]); - const nav = useNavigate(); - return /* @__PURE__ */ _jsxS('form', { - ...rest, - children: /* @__PURE__ */ _jsxC(Slot, null, 3, 'BC_0'), - onSubmit$: /*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_GetForm_component_form_onSubmit_p9MSze0ojs4.mjs"), "GetForm_component_form_onSubmit_p9MSze0ojs4", [ - nav - ]) - }, { - action: 'get', - 'preventdefault:submit': _fnSignal((p0)=>!p0.reloadDocument, [ - props - ], '!p0.reloadDocument'), - 'data-spa-reset': _fnSignal((p0)=>p0.spaReset ? 'true' : void 0, [ - props - ], 'p0.spaReset?"true":undefined') - }, 0, 'BC_1'); -}; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\";;;;;;;6CAo+B6B,CAAC;IAC1B,MAAM,OAAO,WAAW,OAAO;QAAC;QAAU;QAAY;QAAkB;KAAY;IACpF,MAAM,MAAM;IACZ,OAAO,aAAa,GAAG,MACrB,QACA;QACE,GAAG,IAAI;QACP,UAAU,aAAa,GAAG,MAAM,MAAM,MAAM,GAAG;QAC/C,SAAS;;;IAyBX,GACA;QACE,QAAQ;QACR,yBAAyB,UACvB,CAAC,KAAO,CAAC,GAAG,cAAc,EAC1B;YAAC;SAAM,EACP;QAEF,kBAAkB,UAChB,CAAC,KAAQ,GAAG,QAAQ,GAAG,SAAS,KAAK,GACrC;YAAC;SAAM,EACP;IAEJ,GACA,GACA;AAEJ\"}") -/* -{ - "origin": "../node_modules/@builder.io/qwik-city/index.qwik.mjs", - "name": "GetForm_component_Nk9PlpjQm9Y", - "entry": "../node_modules/@builder.io/qwik-city/index.qwik.mjs_entry_GetForm", - "displayName": "index.qwik.mjs_GetForm_component", - "hash": "Nk9PlpjQm9Y", - "canonicalFilename": "index.qwik.mjs_GetForm_component_Nk9PlpjQm9Y", - "path": "../node_modules/@builder.io/qwik-city", - "extension": "mjs", - "parent": null, - "ctxKind": "function", - "ctxName": "component$", - "captures": false, - "loc": [ - 32900, - 34478 - ] -} -*/ -============================= ../node_modules/@builder.io/qwik-city/index.qwik.mjs == - -import { qrl } from "@builder.io/qwik"; -import { createContextId, componentQrl, _jsxBranch, useContext, _jsxC, withLocale, _deserializeData, noSerialize, useServerData, useStore, _getContextElement, _jsxS, _jsxQ, _wrapSignal, implicit$FirstArg } from '@builder.io/qwik'; -import { isServer, isDev } from '@builder.io/qwik/build'; -import swRegister from '@qwik-city-sw-register'; -import { z } from 'zod'; -import { z as z2 } from 'zod'; -const RouteStateContext = /* @__PURE__ */ createContextId('qc-s'); -const ContentContext = /* @__PURE__ */ createContextId('qc-c'); -const ContentInternalContext = /* @__PURE__ */ createContextId('qc-ic'); -const DocumentHeadContext = /* @__PURE__ */ createContextId('qc-h'); -const RouteLocationContext = /* @__PURE__ */ createContextId('qc-l'); -const RouteNavigateContext = /* @__PURE__ */ createContextId('qc-n'); -const RouteActionContext = /* @__PURE__ */ createContextId('qc-a'); -const RouterOutlet = /* @__PURE__ */ componentQrl(/*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_RouterOutlet_component_AKetNByE5TM.mjs"), "RouterOutlet_component_AKetNByE5TM")); -const MODULE_CACHE = /* @__PURE__ */ new WeakMap(); -const CLIENT_DATA_CACHE = /* @__PURE__ */ new Map(); -const QACTION_KEY = 'qaction'; -const toPath = (url)=>url.pathname + url.search + url.hash; -const toUrl = (url, baseUrl)=>new URL(url, baseUrl.href); -const isSameOrigin = (a, b)=>a.origin === b.origin; -const isSamePath = (a, b)=>a.pathname + a.search === b.pathname + b.search; -const isSamePathname = (a, b)=>a.pathname === b.pathname; -const isSameOriginDifferentPathname = (a, b)=>isSameOrigin(a, b) && !isSamePath(a, b); -const getClientDataPath = (pathname, pageSearch, action)=>{ - let search = pageSearch ?? ''; - if (action) search += (search ? '&' : '?') + QACTION_KEY + '=' + encodeURIComponent(action.id); - return pathname + (pathname.endsWith('/') ? '' : '/') + 'q-data.json' + search; -}; -const getClientNavPath = (props, baseUrl)=>{ - const href = props.href; - if (typeof href === 'string' && href.trim() !== '' && typeof props.target !== 'string') try { - const linkUrl = toUrl(href, baseUrl.url); - const currentUrl = toUrl('', baseUrl.url); - if (isSameOrigin(linkUrl, currentUrl)) return toPath(linkUrl); - } catch (e) { - console.error(e); - } - else if (props.reload) return toPath(toUrl('', baseUrl.url)); - return null; -}; -const getPrefetchDataset = (props, clientNavPath, currentLoc)=>{ - if (props.prefetch === true && clientNavPath) { - const prefetchUrl = toUrl(clientNavPath, currentLoc.url); - if (!isSamePathname(prefetchUrl, toUrl('', currentLoc.url))) return ''; - } - return null; -}; -const clientNavigate = (win, newUrl, routeNavigate)=>{ - const currentUrl = win.location; - if (isSameOriginDifferentPathname(currentUrl, newUrl)) { - handleScroll(win, currentUrl, newUrl); - win.history.pushState('', '', toPath(newUrl)); - } - if (!win._qCityHistory) { - win._qCityHistory = 1; - win.addEventListener('popstate', ()=>{ - const currentUrl2 = win.location; - const previousUrl = toUrl(routeNavigate.value, currentUrl2); - if (isSameOriginDifferentPathname(currentUrl2, previousUrl)) { - handleScroll(win, previousUrl, currentUrl2); - routeNavigate.value = toPath(new URL(currentUrl2.href)); - } - }); - win.removeEventListener('popstate', win._qCityPopstateFallback); - } -}; -const handleScroll = async (win, previousUrl, newUrl)=>{ - const doc = win.document; - const newHash = newUrl.hash; - if (isSamePath(previousUrl, newUrl)) { - if (previousUrl.hash !== newHash) { - await domWait(); - if (newHash) scrollToHashId(doc, newHash); - else win.scrollTo(0, 0); - } - } else { - if (newHash) for(let i = 0; i < 24; i++){ - await domWait(); - if (scrollToHashId(doc, newHash)) break; - } - else { - await domWait(); - win.scrollTo(0, 0); - } - } -}; -const domWait = ()=>new Promise((resolve)=>setTimeout(resolve, 12)); -const scrollToHashId = (doc, hash)=>{ - const elmId = hash.slice(1); - const elm = doc.getElementById(elmId); - if (elm) elm.scrollIntoView(); - return elm; -}; -const dispatchPrefetchEvent = (prefetchData)=>{ - if (typeof document !== 'undefined') document.dispatchEvent(new CustomEvent('qprefetch', { - detail: prefetchData - })); -}; -const resolveHead = (endpoint, routeLocation, contentModules, locale)=>{ - const head = createDocumentHead(); - const getData = (loaderOrAction)=>{ - const id = loaderOrAction.__id; - if (loaderOrAction.__brand === 'server_loader') { - if (!(id in endpoint.loaders)) throw new Error('You can not get the returned data of a loader that has not been executed for this request.'); - } - const data = endpoint.loaders[id]; - if (data instanceof Promise) throw new Error('Loaders returning a function can not be referred to in the head function.'); - return data; - }; - const headProps = { - head, - withLocale: (fn)=>withLocale(locale, fn), - resolveValue: getData, - ...routeLocation - }; - for(let i = contentModules.length - 1; i >= 0; i--){ - const contentModuleHead = contentModules[i] && contentModules[i].head; - if (contentModuleHead) { - if (typeof contentModuleHead === 'function') resolveDocumentHead(head, withLocale(locale, ()=>contentModuleHead(headProps))); - else if (typeof contentModuleHead === 'object') resolveDocumentHead(head, contentModuleHead); - } - } - return headProps.head; -}; -const resolveDocumentHead = (resolvedHead, updatedHead)=>{ - if (typeof updatedHead.title === 'string') resolvedHead.title = updatedHead.title; - mergeArray(resolvedHead.meta, updatedHead.meta); - mergeArray(resolvedHead.links, updatedHead.links); - mergeArray(resolvedHead.styles, updatedHead.styles); - Object.assign(resolvedHead.frontmatter, updatedHead.frontmatter); -}; -const mergeArray = (existingArr, newArr)=>{ - if (Array.isArray(newArr)) for (const newItem of newArr){ - if (typeof newItem.key === 'string') { - const existingIndex = existingArr.findIndex((i)=>i.key === newItem.key); - if (existingIndex > -1) { - existingArr[existingIndex] = newItem; - continue; - } - } - existingArr.push(newItem); - } -}; -const createDocumentHead = ()=>({ - title: '', - meta: [], - links: [], - styles: [], - frontmatter: {} - }); -const loadRoute = async (routes, menus, cacheModules, pathname)=>{ - if (Array.isArray(routes)) for (const route of routes){ - const match = route[0].exec(pathname); - if (match) { - const loaders = route[1]; - const params = getPathParams(route[2], match); - const routeBundleNames = route[4]; - const mods = new Array(loaders.length); - const pendingLoads = []; - const menuLoader = getMenuLoader(menus, pathname); - let menu = void 0; - loaders.forEach((moduleLoader, i)=>{ - loadModule(moduleLoader, pendingLoads, (routeModule)=>mods[i] = routeModule, cacheModules); - }); - loadModule(menuLoader, pendingLoads, (menuModule)=>menu = menuModule?.default, cacheModules); - if (pendingLoads.length > 0) await Promise.all(pendingLoads); - return [ - params, - mods, - menu, - routeBundleNames - ]; - } - } - return null; -}; -const loadModule = (moduleLoader, pendingLoads, moduleSetter, cacheModules)=>{ - if (typeof moduleLoader === 'function') { - const loadedModule = MODULE_CACHE.get(moduleLoader); - if (loadedModule) moduleSetter(loadedModule); - else { - const l = moduleLoader(); - if (typeof l.then === 'function') pendingLoads.push(l.then((loadedModule2)=>{ - if (cacheModules !== false) MODULE_CACHE.set(moduleLoader, loadedModule2); - moduleSetter(loadedModule2); - })); - else if (l) moduleSetter(l); - } - } -}; -const getMenuLoader = (menus, pathname)=>{ - if (menus) { - pathname = pathname.endsWith('/') ? pathname : pathname + '/'; - const menu = menus.find((m)=>m[0] === pathname || pathname.startsWith(m[0] + (pathname.endsWith('/') ? '' : '/'))); - if (menu) return menu[1]; - } -}; -const getPathParams = (paramNames, match)=>{ - const params = {}; - if (paramNames) for(let i = 0; i < paramNames.length; i++){ - const param = match?.[i + 1] ?? ''; - const v = param.endsWith('/') ? param.slice(0, -1) : param; - params[paramNames[i]] = decodeURIComponent(v); - } - return params; -}; -const loadClientData = async (url, element, clearCache, action)=>{ - const pagePathname = url.pathname; - const pageSearch = url.search; - const clientDataPath = getClientDataPath(pagePathname, pageSearch, action); - let qData = void 0; - if (!action) qData = CLIENT_DATA_CACHE.get(clientDataPath); - dispatchPrefetchEvent({ - links: [ - pagePathname - ] - }); - if (!qData) { - const options = getFetchOptions(action); - if (action) action.data = void 0; - qData = fetch(clientDataPath, options).then((rsp)=>{ - const redirectedURL = new URL(rsp.url); - if (redirectedURL.origin !== location.origin || !isQDataJson(redirectedURL.pathname)) { - location.href = redirectedURL.href; - return; - } - if ((rsp.headers.get('content-type') || '').includes('json')) return rsp.text().then((text)=>{ - const clientData = _deserializeData(text, element); - if (!clientData) { - location.href = url.href; - return; - } - if (clearCache) CLIENT_DATA_CACHE.delete(clientDataPath); - if (clientData.redirect) location.href = clientData.redirect; - else if (action) { - const actionData = clientData.loaders[action.id]; - action.resolve({ - status: rsp.status, - result: actionData - }); - } - return clientData; - }); - else { - location.href = url.href; - return void 0; - } - }); - if (!action) CLIENT_DATA_CACHE.set(clientDataPath, qData); - } - return qData.then((v)=>{ - if (!v) CLIENT_DATA_CACHE.delete(clientDataPath); - return v; - }); -}; -const getFetchOptions = (action)=>{ - const actionData = action?.data; - if (!actionData) return void 0; - if (actionData instanceof FormData) return { - method: 'POST', - body: actionData - }; - else return { - method: 'POST', - body: JSON.stringify(actionData), - headers: { - 'Content-Type': 'application/json, charset=UTF-8' - } - }; -}; -const isQDataJson = (pathname)=>{ - return pathname.endsWith(QDATA_JSON); -}; -const QDATA_JSON = '/q-data.json'; -const useContent = ()=>useContext(ContentContext); -const useDocumentHead = ()=>useContext(DocumentHeadContext); -const useLocation = ()=>useContext(RouteLocationContext); -const useNavigate = ()=>useContext(RouteNavigateContext); -const useAction = ()=>useContext(RouteActionContext); -const useQwikCityEnv = ()=>noSerialize(useServerData('qwikcity')); -const QwikCityProvider = /* @__PURE__ */ componentQrl(/*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_QwikCityProvider_component_TxCFOy819ag.mjs"), "QwikCityProvider_component_TxCFOy819ag")); -const QwikCityMockProvider = /* @__PURE__ */ componentQrl(/*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_QwikCityMockProvider_component_WmYC5H00wtI.mjs"), "QwikCityMockProvider_component_WmYC5H00wtI")); -const Link = /* @__PURE__ */ componentQrl(/*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_Link_component_8gdLBszqbaM.mjs"), "Link_component_8gdLBszqbaM")); -const prefetchLinkResources = (elm, isOnVisible)=>{ - if (elm && elm.href && elm.hasAttribute('data-prefetch')) { - if (!windowInnerWidth) windowInnerWidth = innerWidth; - if (!isOnVisible || isOnVisible && windowInnerWidth < 520) loadClientData(new URL(elm.href), elm); - } -}; -let windowInnerWidth = 0; -const ServiceWorkerRegister = (props)=>_jsxQ('script', { - nonce: _wrapSignal(props, 'nonce') - }, { - dangerouslySetInnerHTML: swRegister - }, null, 3, '1Z_0'); -const routeActionQrl = (actionQrl, ...rest)=>{ - const { id, validators } = getValidators(rest, actionQrl); - function action() { - const loc = useLocation(); - const currentAction = useAction(); - const initialState = { - actionPath: `?${QACTION_KEY}=${id}`, - isRunning: false, - status: void 0, - value: void 0, - formData: void 0 - }; - const state = useStore(()=>{ - const value = currentAction.value; - if (value && value?.id === id) { - const data = value.data; - if (data instanceof FormData) initialState.formData = data; - if (value.output) { - const { status, result } = value.output; - initialState.status = status; - initialState.value = result; - } - } - return initialState; - }); - const submit = /*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_routeActionQrl_action_submit_A5bZC7WO00A.mjs"), "routeActionQrl_action_submit_A5bZC7WO00A", [ - currentAction, - id, - loc, - state - ]); - initialState.submit = submit; - return state; - } - action.__brand = 'server_action'; - action.__validators = validators; - action.__qrl = actionQrl; - action.__id = id; - Object.freeze(action); - return action; -}; -const globalActionQrl = (actionQrl, ...rest)=>{ - const action = routeActionQrl(actionQrl, ...rest); - if (isServer) { - if (typeof globalThis._qwikActionsMap === 'undefined') globalThis._qwikActionsMap = /* @__PURE__ */ new Map(); - globalThis._qwikActionsMap.set(action.__id, action); - } - return action; -}; -const routeAction$ = /* @__PURE__ */ implicit$FirstArg(routeActionQrl); -const globalAction$ = /* @__PURE__ */ implicit$FirstArg(globalActionQrl); -const routeLoaderQrl = (loaderQrl, ...rest)=>{ - const { id, validators } = getValidators(rest, loaderQrl); - function loader() { - return useContext(RouteStateContext, (state)=>{ - if (!(id in state)) throw new Error(`Loader (${id}) was used in a path where the 'loader$' was not declared. - This is likely because the used loader was not exported in a layout.tsx or index.tsx file of the existing route. - For more information check: https://qwik.dev/qwikcity/route-loader/`); - return _wrapSignal(state, id); - }); - } - loader.__brand = 'server_loader'; - loader.__qrl = loaderQrl; - loader.__validators = validators; - loader.__id = id; - Object.freeze(loader); - return loader; -}; -const routeLoader$ = /* @__PURE__ */ implicit$FirstArg(routeLoaderQrl); -const validatorQrl = (validator)=>{ - if (isServer) return { - validate: validator - }; - return void 0; -}; -const validator$ = /* @__PURE__ */ implicit$FirstArg(validatorQrl); -const zodQrl = (qrl)=>{ - if (isServer) { - const schema = qrl.resolve().then((obj)=>{ - if (typeof obj === 'function') obj = obj(z); - if (obj instanceof z.Schema) return obj; - else return z.object(obj); - }); - return { - async validate (ev, inputData) { - const data = inputData ?? await ev.parseBody(); - const result = await (await schema).safeParseAsync(data); - if (result.success) return result; - else { - if (isDev) console.error('\nVALIDATION ERROR\naction$() zod validated failed', '\n - Issues:', result.error.issues); - return { - success: false, - status: 400, - error: result.error.flatten() - }; - } - } - }; - } - return void 0; -}; -const zod$ = /* @__PURE__ */ implicit$FirstArg(zodQrl); -const serverQrl = (qrl1)=>{ - if (isServer) { - const captured = qrl1.getCaptured(); - if (captured && captured.length > 0 && !_getContextElement()) throw new Error('For security reasons, we cannot serialize QRLs that capture lexical scope.'); - } - function stuff() { - return /*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_serverQrl_stuff_wOIPfiQ04l4.mjs"), "serverQrl_stuff_wOIPfiQ04l4", [ - qrl1 - ]); - } - return stuff(); -}; -const server$ = /* @__PURE__ */ implicit$FirstArg(serverQrl); -const getValidators = (rest, qrl)=>{ - let id; - const validators = []; - if (rest.length === 1) { - const options = rest[0]; - if (options && typeof options === 'object') { - if ('validate' in options) validators.push(options); - else { - id = options.id; - if (options.validation) validators.push(...options.validation); - } - } - } else if (rest.length > 1) validators.push(...rest.filter((v)=>!!v)); - if (typeof id === 'string') { - if (isDev) { - if (!/^[\w/.-]+$/.test(id)) throw new Error(`Invalid id: ${id}, id can only contain [a-zA-Z0-9_.-]`); - } - id = `id_${id}`; - } else id = qrl.getHash(); - return { - validators: validators.reverse(), - id - }; -}; -const getSSETransformer = ()=>{ - let currentLine = ''; - const encoder = new TextDecoder(); - const transformer = new TransformStream({ - transform (chunk, controller) { - const lines = encoder.decode(chunk).split('\n\n'); - for(let i = 0; i < lines.length - 1; i++){ - const line = currentLine + lines[i]; - if (line.length === 0) { - controller.terminate(); - break; - } else { - controller.enqueue(parseEvent(line)); - currentLine = ''; - } - } - currentLine += lines[lines.length - 1]; - } - }); - return transformer; -}; -const parseEvent = (message)=>{ - const lines = message.split('\n'); - const event = { - data: '' - }; - let data = ''; - for (const line of lines)if (line.startsWith('data: ')) data += line.slice(6) + '\n'; - else { - const [key, value] = line.split(':'); - if (typeof key === 'string' && typeof value === 'string') event[key] = value.trim(); - } - event.data = data; - return event; -}; -async function* streamAsyncIterator(stream, ctxElm) { - const reader = stream.getReader(); - try { - while(true){ - const { done, value } = await reader.read(); - if (done) return; - const obj = await _deserializeData(value.data, ctxElm); - yield obj; - } - } finally{ - reader.releaseLock(); - } -} -const Form = ({ action, spaReset, reloadDocument, onSubmit$, ...rest }, key)=>{ - _jsxBranch(); - if (action) return _jsxS('form', { - ...rest, - action: _wrapSignal(action, 'actionPath'), - 'preventdefault:submit': !reloadDocument, - ['data-spa-reset']: spaReset ? 'true' : void 0, - onSubmit$: [ - !reloadDocument ? action.submit : void 0, - onSubmit$ - ] - }, { - method: 'post' - }, 0, key); - else return /* @__PURE__ */ _jsxC(GetForm, { - spaReset, - reloadDocument, - onSubmit$, - ...rest - }, 0, key); -}; -const GetForm = /* @__PURE__ */ componentQrl(/*#__PURE__*/ qrl(()=>import("./index.qwik.mjs_GetForm_component_Nk9PlpjQm9Y.mjs"), "GetForm_component_Nk9PlpjQm9Y")); -export { Form, Link, QwikCityMockProvider, QwikCityProvider, RouterOutlet, ServiceWorkerRegister, globalAction$, globalActionQrl, routeAction$, routeActionQrl, routeLoader$, routeLoaderQrl, server$, serverQrl, useContent, useDocumentHead, useLocation, useNavigate, validator$, validatorQrl, z2 as z, zod$, zodQrl }; -export { CLIENT_DATA_CACHE as _auto_CLIENT_DATA_CACHE }; -export { ContentContext as _auto_ContentContext }; -export { ContentInternalContext as _auto_ContentInternalContext }; -export { DocumentHeadContext as _auto_DocumentHeadContext }; -export { RouteActionContext as _auto_RouteActionContext }; -export { RouteLocationContext as _auto_RouteLocationContext }; -export { RouteNavigateContext as _auto_RouteNavigateContext }; -export { RouteStateContext as _auto_RouteStateContext }; -export { clientNavigate as _auto_clientNavigate }; -export { createDocumentHead as _auto_createDocumentHead }; -export { getClientNavPath as _auto_getClientNavPath }; -export { getPrefetchDataset as _auto_getPrefetchDataset }; -export { getSSETransformer as _auto_getSSETransformer }; -export { isSameOriginDifferentPathname as _auto_isSameOriginDifferentPathname }; -export { loadClientData as _auto_loadClientData }; -export { loadRoute as _auto_loadRoute }; -export { prefetchLinkResources as _auto_prefetchLinkResources }; -export { resolveHead as _auto_resolveHead }; -export { streamAsyncIterator as _auto_streamAsyncIterator }; -export { toPath as _auto_toPath }; -export { useQwikCityEnv as _auto_useQwikCityEnv }; - - -Some("{\"version\":3,\"sources\":[\"/user/qwik/node_modules/@builder.io/qwik-city/index.qwik.mjs\"],\"names\":[],\"mappings\":\";AAAA,SACE,eAAe,EACf,YAAY,EAEZ,UAAU,EAGV,UAAU,EACV,KAAK,EAEL,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,aAAa,EAEb,QAAQ,EAIR,kBAAkB,EAMlB,KAAK,EACL,KAAK,EACL,WAAW,EACX,iBAAiB,QAIZ,mBAAmB;AAC1B,SAAoB,QAAQ,EAAE,KAAK,QAAQ,yBAAyB;AAEpE,OAAO,gBAAgB,yBAAyB;AAChD,SAAS,CAAC,QAAQ,MAAM;AACxB,SAAS,KAAK,EAAE,QAAQ,MAAM;AAC9B,MAAM,oBAAoB,aAAa,GAAG,gBAAgB;AAC1D,MAAM,iBAAiB,aAAa,GAAG,gBAAgB;AACvD,MAAM,yBAAyB,aAAa,GAAG,gBAAgB;AAC/D,MAAM,sBAAsB,aAAa,GAAG,gBAAgB;AAC5D,MAAM,uBAAuB,aAAa,GAAG,gBAAgB;AAC7D,MAAM,uBAAuB,aAAa,GAAG,gBAAgB;AAC7D,MAAM,qBAAqB,aAAa,GAAG,gBAAgB;AAC3D,MAAM,eAAe,aAAa,GAAG;AAsCrC,MAAM,eAAe,aAAa,GAAG,IAAI;AACzC,MAAM,oBAAoB,aAAa,GAAG,IAAI;AAC9C,MAAM,cAAc;AACpB,MAAM,SAAS,CAAC,MAAQ,IAAI,QAAQ,GAAG,IAAI,MAAM,GAAG,IAAI,IAAI;AAC5D,MAAM,QAAQ,CAAC,KAAK,UAAY,IAAI,IAAI,KAAK,QAAQ,IAAI;AACzD,MAAM,eAAe,CAAC,GAAG,IAAM,EAAE,MAAM,KAAK,EAAE,MAAM;AACpD,MAAM,aAAa,CAAC,GAAG,IAAM,EAAE,QAAQ,GAAG,EAAE,MAAM,KAAK,EAAE,QAAQ,GAAG,EAAE,MAAM;AAC5E,MAAM,iBAAiB,CAAC,GAAG,IAAM,EAAE,QAAQ,KAAK,EAAE,QAAQ;AAC1D,MAAM,gCAAgC,CAAC,GAAG,IAAM,aAAa,GAAG,MAAM,CAAC,WAAW,GAAG;AACrF,MAAM,oBAAoB,CAAC,UAAU,YAAY;IAC/C,IAAI,SAAS,cAAc;IAC3B,IAAI,QAAQ,UAAU,CAAC,SAAS,MAAM,GAAG,IAAI,cAAc,MAAM,mBAAmB,OAAO,EAAE;IAC7F,OAAO,WAAW,CAAC,SAAS,QAAQ,CAAC,OAAO,KAAK,GAAG,IAAI,gBAAgB;AAC1E;AACA,MAAM,mBAAmB,CAAC,OAAO;IAC/B,MAAM,OAAO,MAAM,IAAI;IACvB,IAAI,OAAO,SAAS,YAAY,KAAK,IAAI,OAAO,MAAM,OAAO,MAAM,MAAM,KAAK,UAC5E,IAAI;QACF,MAAM,UAAU,MAAM,MAAM,QAAQ,GAAG;QACvC,MAAM,aAAa,MAAM,IAAI,QAAQ,GAAG;QACxC,IAAI,aAAa,SAAS,aAAa,OAAO,OAAO;IACvD,EAAE,OAAO,GAAG;QACV,QAAQ,KAAK,CAAC;IAChB;SACG,IAAI,MAAM,MAAM,EAAE,OAAO,OAAO,MAAM,IAAI,QAAQ,GAAG;IAC1D,OAAO;AACT;AACA,MAAM,qBAAqB,CAAC,OAAO,eAAe;IAChD,IAAI,MAAM,QAAQ,KAAK,QAAQ,eAAe;QAC5C,MAAM,cAAc,MAAM,eAAe,WAAW,GAAG;QACvD,IAAI,CAAC,eAAe,aAAa,MAAM,IAAI,WAAW,GAAG,IAAI,OAAO;IACtE;IACA,OAAO;AACT;AACA,MAAM,iBAAiB,CAAC,KAAK,QAAQ;IACnC,MAAM,aAAa,IAAI,QAAQ;IAC/B,IAAI,8BAA8B,YAAY,SAAS;QACrD,aAAa,KAAK,YAAY;QAC9B,IAAI,OAAO,CAAC,SAAS,CAAC,IAAI,IAAI,OAAO;IACvC;IACA,IAAI,CAAC,IAAI,aAAa,EAAE;QACtB,IAAI,aAAa,GAAG;QACpB,IAAI,gBAAgB,CAAC,YAAY;YAC/B,MAAM,cAAc,IAAI,QAAQ;YAChC,MAAM,cAAc,MAAM,cAAc,KAAK,EAAE;YAC/C,IAAI,8BAA8B,aAAa,cAAc;gBAC3D,aAAa,KAAK,aAAa;gBAC/B,cAAc,KAAK,GAAG,OAAO,IAAI,IAAI,YAAY,IAAI;YACvD;QACF;QACA,IAAI,mBAAmB,CAAC,YAAY,IAAI,sBAAsB;IAChE;AACF;AACA,MAAM,eAAe,OAAO,KAAK,aAAa;IAC5C,MAAM,MAAM,IAAI,QAAQ;IACxB,MAAM,UAAU,OAAO,IAAI;IAC3B,IAAI,WAAW,aAAa,SAC1B;QAAA,IAAI,YAAY,IAAI,KAAK,SAAS;YAChC,MAAM;YACN,IAAI,SAAS,eAAe,KAAK;iBAC5B,IAAI,QAAQ,CAAC,GAAG;QACvB;IAAA,OACK;QACL,IAAI,SACF,IAAK,IAAI,IAAI,GAAG,IAAI,IAAI,IAAK;YAC3B,MAAM;YACN,IAAI,eAAe,KAAK,UAAU;QACpC;aACG;YACH,MAAM;YACN,IAAI,QAAQ,CAAC,GAAG;QAClB;IACF;AACF;AACA,MAAM,UAAU,IAAM,IAAI,QAAQ,CAAC,UAAY,WAAW,SAAS;AACnE,MAAM,iBAAiB,CAAC,KAAK;IAC3B,MAAM,QAAQ,KAAK,KAAK,CAAC;IACzB,MAAM,MAAM,IAAI,cAAc,CAAC;IAC/B,IAAI,KAAK,IAAI,cAAc;IAC3B,OAAO;AACT;AACA,MAAM,wBAAwB,CAAC;IAC7B,IAAI,OAAO,aAAa,aACtB,SAAS,aAAa,CACpB,IAAI,YAAY,aAAa;QAC3B,QAAQ;IACV;AAEN;AACA,MAAM,cAAc,CAAC,UAAU,eAAe,gBAAgB;IAC5D,MAAM,OAAO;IACb,MAAM,UAAU,CAAC;QACf,MAAM,KAAK,eAAe,IAAI;QAC9B,IAAI,eAAe,OAAO,KAAK,iBAAiB;YAC9C,IAAI,CAAC,CAAC,MAAM,SAAS,OAAO,GAC1B,MAAM,IAAI,MACR;QAEN;QACA,MAAM,OAAO,SAAS,OAAO,CAAC,GAAG;QACjC,IAAI,gBAAgB,SAClB,MAAM,IAAI,MAAM;QAClB,OAAO;IACT;IACA,MAAM,YAAY;QAChB;QACA,YAAY,CAAC,KAAO,WAAW,QAAQ;QACvC,cAAc;QACd,GAAG,aAAa;IAClB;IACA,IAAK,IAAI,IAAI,eAAe,MAAM,GAAG,GAAG,KAAK,GAAG,IAAK;QACnD,MAAM,oBAAoB,cAAc,CAAC,EAAE,IAAI,cAAc,CAAC,EAAE,CAAC,IAAI;QACrE,IAAI,mBAAmB;YACrB,IAAI,OAAO,sBAAsB,YAC/B,oBACE,MACA,WAAW,QAAQ,IAAM,kBAAkB;iBAE1C,IAAI,OAAO,sBAAsB,UAAU,oBAAoB,MAAM;QAC5E;IACF;IACA,OAAO,UAAU,IAAI;AACvB;AACA,MAAM,sBAAsB,CAAC,cAAc;IACzC,IAAI,OAAO,YAAY,KAAK,KAAK,UAAU,aAAa,KAAK,GAAG,YAAY,KAAK;IACjF,WAAW,aAAa,IAAI,EAAE,YAAY,IAAI;IAC9C,WAAW,aAAa,KAAK,EAAE,YAAY,KAAK;IAChD,WAAW,aAAa,MAAM,EAAE,YAAY,MAAM;IAClD,OAAO,MAAM,CAAC,aAAa,WAAW,EAAE,YAAY,WAAW;AACjE;AACA,MAAM,aAAa,CAAC,aAAa;IAC/B,IAAI,MAAM,OAAO,CAAC,SAChB,KAAK,MAAM,WAAW,OAAQ;QAC5B,IAAI,OAAO,QAAQ,GAAG,KAAK,UAAU;YACnC,MAAM,gBAAgB,YAAY,SAAS,CAAC,CAAC,IAAM,EAAE,GAAG,KAAK,QAAQ,GAAG;YACxE,IAAI,gBAAgB,IAAI;gBACtB,WAAW,CAAC,cAAc,GAAG;gBAC7B;YACF;QACF;QACA,YAAY,IAAI,CAAC;IACnB;AACJ;AACA,MAAM,qBAAqB,IAAM,CAAC;QAChC,OAAO;QACP,MAAM,EAAE;QACR,OAAO,EAAE;QACT,QAAQ,EAAE;QACV,aAAa,CAAC;IAChB,CAAC;AACD,MAAM,YAAY,OAAO,QAAQ,OAAO,cAAc;IACpD,IAAI,MAAM,OAAO,CAAC,SAChB,KAAK,MAAM,SAAS,OAAQ;QAC1B,MAAM,QAAQ,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC;QAC5B,IAAI,OAAO;YACT,MAAM,UAAU,KAAK,CAAC,EAAE;YACxB,MAAM,SAAS,cAAc,KAAK,CAAC,EAAE,EAAE;YACvC,MAAM,mBAAmB,KAAK,CAAC,EAAE;YACjC,MAAM,OAAO,IAAI,MAAM,QAAQ,MAAM;YACrC,MAAM,eAAe,EAAE;YACvB,MAAM,aAAa,cAAc,OAAO;YACxC,IAAI,OAAO,KAAK;YAChB,QAAQ,OAAO,CAAC,CAAC,cAAc;gBAC7B,WACE,cACA,cACA,CAAC,cAAiB,IAAI,CAAC,EAAE,GAAG,aAC5B;YAEJ;YACA,WACE,YACA,cACA,CAAC,aAAgB,OAAO,YAAY,SACpC;YAEF,IAAI,aAAa,MAAM,GAAG,GAAG,MAAM,QAAQ,GAAG,CAAC;YAC/C,OAAO;gBAAC;gBAAQ;gBAAM;gBAAM;aAAiB;QAC/C;IACF;IACF,OAAO;AACT;AACA,MAAM,aAAa,CAAC,cAAc,cAAc,cAAc;IAC5D,IAAI,OAAO,iBAAiB,YAAY;QACtC,MAAM,eAAe,aAAa,GAAG,CAAC;QACtC,IAAI,cAAc,aAAa;aAC1B;YACH,MAAM,IAAI;YACV,IAAI,OAAO,EAAE,IAAI,KAAK,YACpB,aAAa,IAAI,CACf,EAAE,IAAI,CAAC,CAAC;gBACN,IAAI,iBAAiB,OAAO,aAAa,GAAG,CAAC,cAAc;gBAC3D,aAAa;YACf;iBAEC,IAAI,GAAG,aAAa;QAC3B;IACF;AACF;AACA,MAAM,gBAAgB,CAAC,OAAO;IAC5B,IAAI,OAAO;QACT,WAAW,SAAS,QAAQ,CAAC,OAAO,WAAW,WAAW;QAC1D,MAAM,OAAO,MAAM,IAAI,CACrB,CAAC,IAAM,CAAC,CAAC,EAAE,KAAK,YAAY,SAAS,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,QAAQ,CAAC,OAAO,KAAK,GAAG;QAE3F,IAAI,MAAM,OAAO,IAAI,CAAC,EAAE;IAC1B;AACF;AACA,MAAM,gBAAgB,CAAC,YAAY;IACjC,MAAM,SAAS,CAAC;IAChB,IAAI,YACF,IAAK,IAAI,IAAI,GAAG,IAAI,WAAW,MAAM,EAAE,IAAK;QAC1C,MAAM,QAAQ,OAAO,CAAC,IAAI,EAAE,IAAI;QAChC,MAAM,IAAI,MAAM,QAAQ,CAAC,OAAO,MAAM,KAAK,CAAC,GAAG,MAAM;QACrD,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,mBAAmB;IAC7C;IACF,OAAO;AACT;AACA,MAAM,iBAAiB,OAAO,KAAK,SAAS,YAAY;IACtD,MAAM,eAAe,IAAI,QAAQ;IACjC,MAAM,aAAa,IAAI,MAAM;IAC7B,MAAM,iBAAiB,kBAAkB,cAAc,YAAY;IACnE,IAAI,QAAQ,KAAK;IACjB,IAAI,CAAC,QAAQ,QAAQ,kBAAkB,GAAG,CAAC;IAC3C,sBAAsB;QACpB,OAAO;YAAC;SAAa;IACvB;IACA,IAAI,CAAC,OAAO;QACV,MAAM,UAAU,gBAAgB;QAChC,IAAI,QAAQ,OAAO,IAAI,GAAG,KAAK;QAC/B,QAAQ,MAAM,gBAAgB,SAAS,IAAI,CAAC,CAAC;YAC3C,MAAM,gBAAgB,IAAI,IAAI,IAAI,GAAG;YACrC,IAAI,cAAc,MAAM,KAAK,SAAS,MAAM,IAAI,CAAC,YAAY,cAAc,QAAQ,GAAG;gBACpF,SAAS,IAAI,GAAG,cAAc,IAAI;gBAClC;YACF;YACA,IAAI,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,EAAE,QAAQ,CAAC,SACnD,OAAO,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC;gBACtB,MAAM,aAAa,iBAAiB,MAAM;gBAC1C,IAAI,CAAC,YAAY;oBACf,SAAS,IAAI,GAAG,IAAI,IAAI;oBACxB;gBACF;gBACA,IAAI,YAAY,kBAAkB,MAAM,CAAC;gBACzC,IAAI,WAAW,QAAQ,EAAE,SAAS,IAAI,GAAG,WAAW,QAAQ;qBACvD,IAAI,QAAQ;oBACf,MAAM,aAAa,WAAW,OAAO,CAAC,OAAO,EAAE,CAAC;oBAChD,OAAO,OAAO,CAAC;wBACb,QAAQ,IAAI,MAAM;wBAClB,QAAQ;oBACV;gBACF;gBACA,OAAO;YACT;iBACG;gBACH,SAAS,IAAI,GAAG,IAAI,IAAI;gBACxB,OAAO,KAAK;YACd;QACF;QACA,IAAI,CAAC,QAAQ,kBAAkB,GAAG,CAAC,gBAAgB;IACrD;IACA,OAAO,MAAM,IAAI,CAAC,CAAC;QACjB,IAAI,CAAC,GAAG,kBAAkB,MAAM,CAAC;QACjC,OAAO;IACT;AACF;AACA,MAAM,kBAAkB,CAAC;IACvB,MAAM,aAAa,QAAQ;IAC3B,IAAI,CAAC,YAAY,OAAO,KAAK;IAC7B,IAAI,sBAAsB,UACxB,OAAO;QACL,QAAQ;QACR,MAAM;IACR;SAEA,OAAO;QACL,QAAQ;QACR,MAAM,KAAK,SAAS,CAAC;QACrB,SAAS;YACP,gBAAgB;QAClB;IACF;AACJ;AACA,MAAM,cAAc,CAAC;IACnB,OAAO,SAAS,QAAQ,CAAC;AAC3B;AACA,MAAM,aAAa;AACnB,MAAM,aAAa,IAAM,WAAW;AACpC,MAAM,kBAAkB,IAAM,WAAW;AACzC,MAAM,cAAc,IAAM,WAAW;AACrC,MAAM,cAAc,IAAM,WAAW;AACrC,MAAM,YAAY,IAAM,WAAW;AACnC,MAAM,iBAAiB,IAAM,YAAY,cAAc;AACvD,MAAM,mBAAmB,aAAa,GAAG;AAsMzC,MAAM,uBAAuB,aAAa,GAAG;AAwC7C,MAAM,OAAO,aAAa,GAAG;AA0C7B,MAAM,wBAAwB,CAAC,KAAK;IAClC,IAAI,OAAO,IAAI,IAAI,IAAI,IAAI,YAAY,CAAC,kBAAkB;QACxD,IAAI,CAAC,kBAAkB,mBAAmB;QAC1C,IAAI,CAAC,eAAgB,eAAe,mBAAmB,KACrD,eAAe,IAAI,IAAI,IAAI,IAAI,GAAG;IACtC;AACF;AACA,IAAI,mBAAmB;AACvB,MAAM,wBAAwB,CAAC,QAC7B,MACE,UACA;QACE,OAAO,YAAY,OAAO;IAC5B,GACA;QACE,yBAAyB;IAC3B,GACA,MACA,GACA;AAEJ,MAAM,iBAAiB,CAAC,WAAW,GAAG;IACpC,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,cAAc,MAAM;IAC/C,SAAS;QACP,MAAM,MAAM;QACZ,MAAM,gBAAgB;QACtB,MAAM,eAAe;YACnB,YAAY,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,IAAI;YACnC,WAAW;YACX,QAAQ,KAAK;YACb,OAAO,KAAK;YACZ,UAAU,KAAK;QACjB;QACA,MAAM,QAAQ,SAAS;YACrB,MAAM,QAAQ,cAAc,KAAK;YACjC,IAAI,SAAS,OAAO,OAAO,IAAI;gBAC7B,MAAM,OAAO,MAAM,IAAI;gBACvB,IAAI,gBAAgB,UAAU,aAAa,QAAQ,GAAG;gBACtD,IAAI,MAAM,MAAM,EAAE;oBAChB,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM;oBACvC,aAAa,MAAM,GAAG;oBACtB,aAAa,KAAK,GAAG;gBACvB;YACF;YACA,OAAO;QACT;QACA,MAAM;;;;;;QAwDN,aAAa,MAAM,GAAG;QACtB,OAAO;IACT;IACA,OAAO,OAAO,GAAG;IACjB,OAAO,YAAY,GAAG;IACtB,OAAO,KAAK,GAAG;IACf,OAAO,IAAI,GAAG;IACd,OAAO,MAAM,CAAC;IACd,OAAO;AACT;AACA,MAAM,kBAAkB,CAAC,WAAW,GAAG;IACrC,MAAM,SAAS,eAAe,cAAc;IAC5C,IAAI,UAAU;QACZ,IAAI,OAAO,WAAW,eAAe,KAAK,aACxC,WAAW,eAAe,GAAG,aAAa,GAAG,IAAI;QACnD,WAAW,eAAe,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE;IAC9C;IACA,OAAO;AACT;AACA,MAAM,eAAe,aAAa,GAAG,kBAAkB;AACvD,MAAM,gBAAgB,aAAa,GAAG,kBAAkB;AACxD,MAAM,iBAAiB,CAAC,WAAW,GAAG;IACpC,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,cAAc,MAAM;IAC/C,SAAS;QACP,OAAO,WAAW,mBAAmB,CAAC;YACpC,IAAI,CAAC,CAAC,MAAM,KAAK,GACf,MAAM,IAAI,MAAM,CAAC,QAAQ,EAAE,GAAG;;uEAEiC,CAAC;YAClE,OAAO,YAAY,OAAO;QAC5B;IACF;IACA,OAAO,OAAO,GAAG;IACjB,OAAO,KAAK,GAAG;IACf,OAAO,YAAY,GAAG;IACtB,OAAO,IAAI,GAAG;IACd,OAAO,MAAM,CAAC;IACd,OAAO;AACT;AACA,MAAM,eAAe,aAAa,GAAG,kBAAkB;AACvD,MAAM,eAAe,CAAC;IACpB,IAAI,UACF,OAAO;QACL,UAAU;IACZ;IACF,OAAO,KAAK;AACd;AACA,MAAM,aAAa,aAAa,GAAG,kBAAkB;AACrD,MAAM,SAAS,CAAC;IACd,IAAI,UAAU;QACZ,MAAM,SAAS,IAAI,OAAO,GAAG,IAAI,CAAC,CAAC;YACjC,IAAI,OAAO,QAAQ,YAAY,MAAM,IAAI;YACzC,IAAI,eAAe,EAAE,MAAM,EAAE,OAAO;iBAC/B,OAAO,EAAE,MAAM,CAAC;QACvB;QACA,OAAO;YACL,MAAM,UAAS,EAAE,EAAE,SAAS;gBAC1B,MAAM,OAAO,aAAc,MAAM,GAAG,SAAS;gBAC7C,MAAM,SAAS,MAAM,CAAC,MAAM,MAAM,EAAE,cAAc,CAAC;gBACnD,IAAI,OAAO,OAAO,EAAE,OAAO;qBACtB;oBACH,IAAI,OACF,QAAQ,KAAK,CACX,sDACA,iBACA,OAAO,KAAK,CAAC,MAAM;oBAEvB,OAAO;wBACL,SAAS;wBACT,QAAQ;wBACR,OAAO,OAAO,KAAK,CAAC,OAAO;oBAC7B;gBACF;YACF;QACF;IACF;IACA,OAAO,KAAK;AACd;AACA,MAAM,OAAO,aAAa,GAAG,kBAAkB;AAC/C,MAAM,YAAY,CAAC;IACjB,IAAI,UAAU;QACZ,MAAM,WAAW,KAAI,WAAW;QAChC,IAAI,YAAY,SAAS,MAAM,GAAG,KAAK,CAAC,sBACtC,MAAM,IAAI,MAAM;IACpB;IACA,SAAS;QACP;;;IA0CF;IACA,OAAO;AACT;AACA,MAAM,UAAU,aAAa,GAAG,kBAAkB;AAClD,MAAM,gBAAgB,CAAC,MAAM;IAC3B,IAAI;IACJ,MAAM,aAAa,EAAE;IACrB,IAAI,KAAK,MAAM,KAAK,GAAG;QACrB,MAAM,UAAU,IAAI,CAAC,EAAE;QACvB,IAAI,WAAW,OAAO,YAAY;YAChC,IAAI,cAAc,SAAS,WAAW,IAAI,CAAC;iBACtC;gBACH,KAAK,QAAQ,EAAE;gBACf,IAAI,QAAQ,UAAU,EAAE,WAAW,IAAI,IAAI,QAAQ,UAAU;YAC/D;;IAEJ,OAAO,IAAI,KAAK,MAAM,GAAG,GAAG,WAAW,IAAI,IAAI,KAAK,MAAM,CAAC,CAAC,IAAM,CAAC,CAAC;IACpE,IAAI,OAAO,OAAO,UAAU;QAC1B,IAAI,OAAO;YACT,IAAI,CAAC,aAAa,IAAI,CAAC,KACrB,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE,GAAG,oCAAoC,CAAC;QAC3E;QACA,KAAK,CAAC,GAAG,EAAE,IAAI;IACjB,OAAO,KAAK,IAAI,OAAO;IACvB,OAAO;QACL,YAAY,WAAW,OAAO;QAC9B;IACF;AACF;AACA,MAAM,oBAAoB;IACxB,IAAI,cAAc;IAClB,MAAM,UAAU,IAAI;IACpB,MAAM,cAAc,IAAI,gBAAgB;QACtC,WAAU,KAAK,EAAE,UAAU;YACzB,MAAM,QAAQ,QAAQ,MAAM,CAAC,OAAO,KAAK,CAAC;YAC1C,IAAK,IAAI,IAAI,GAAG,IAAI,MAAM,MAAM,GAAG,GAAG,IAAK;gBACzC,MAAM,OAAO,cAAc,KAAK,CAAC,EAAE;gBACnC,IAAI,KAAK,MAAM,KAAK,GAAG;oBACrB,WAAW,SAAS;oBACpB;gBACF,OAAO;oBACL,WAAW,OAAO,CAAC,WAAW;oBAC9B,cAAc;gBAChB;YACF;YACA,eAAe,KAAK,CAAC,MAAM,MAAM,GAAG,EAAE;QACxC;IACF;IACA,OAAO;AACT;AACA,MAAM,aAAa,CAAC;IAClB,MAAM,QAAQ,QAAQ,KAAK,CAAC;IAC5B,MAAM,QAAQ;QACZ,MAAM;IACR;IACA,IAAI,OAAO;IACX,KAAK,MAAM,QAAQ,MACjB,IAAI,KAAK,UAAU,CAAC,WAAW,QAAQ,KAAK,KAAK,CAAC,KAAK;SAClD;QACH,MAAM,CAAC,KAAK,MAAM,GAAG,KAAK,KAAK,CAAC;QAChC,IAAI,OAAO,QAAQ,YAAY,OAAO,UAAU,UAAU,KAAK,CAAC,IAAI,GAAG,MAAM,IAAI;IACnF;IACF,MAAM,IAAI,GAAG;IACb,OAAO;AACT;AACA,gBAAgB,oBAAoB,MAAM,EAAE,MAAM;IAChD,MAAM,SAAS,OAAO,SAAS;IAC/B,IAAI;QACF,MAAO,KAAM;YACX,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,IAAI;YACzC,IAAI,MAAM;YACV,MAAM,MAAM,MAAM,iBAAiB,MAAM,IAAI,EAAE;YAC/C,MAAM;QACR;IACF,SAAU;QACR,OAAO,WAAW;IACpB;AACF;AACA,MAAM,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE;IACtE;IACA,IAAI,QACF,OAAO,MACL,QACA;QACE,GAAG,IAAI;QACP,QAAQ,YAAY,QAAQ;QAC5B,yBAAyB,CAAC;QAC1B,CAAC,iBAAiB,EAAE,WAAW,SAAS,KAAK;QAC7C,WAAW;YAAC,CAAC,iBAAiB,OAAO,MAAM,GAAG,KAAK;YAAG;SAAU;IAClE,GACA;QACE,QAAQ;IACV,GACA,GACA;SAGF,OAAO,aAAa,GAAG,MACrB,SACA;QACE;QACA;QACA;QACA,GAAG,IAAI;IACT,GACA,GACA;AAEN;AACA,MAAM,UAAU,aAAa,GAAG;AAqDhC,SACE,IAAI,EACJ,IAAI,EACJ,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACZ,qBAAqB,EACrB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,cAAc,EACd,OAAO,EACP,SAAS,EACT,UAAU,EACV,eAAe,EACf,WAAW,EACX,WAAW,EACX,UAAU,EACV,YAAY,EACZ,MAAM,CAAC,EACP,IAAI,EACJ,MAAM,GACN\"}") -== DIAGNOSTICS == - -[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_reg_ctx_name_segments.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_reg_ctx_name_segments.snap index 01898440a76..5482472772f 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_reg_ctx_name_segments.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_reg_ctx_name_segments.snap @@ -1,50 +1,55 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 755 +assertion_line: 865 expression: output snapshot_kind: text --- ==INPUT== -import { $, component$, server$ } from '@builder.io/qwik'; +import { $, component$, server$ } from '@qwik.dev/core'; import { foo } from './foo'; export const Works = component$((props) => { - const text = 'hola'; - return ( - <> -
        console.log('in server', text))}>
        -
        foo()}>
        - - ); + const text = 'hola'; + return ( + <> +
        console.log('in server', text))}>
        +
        foo()}>
        + + ); }); ============================= test.js == import "./foo"; -import { componentQrl } from "@builder.io/qwik"; -import { serverQrl } from "@builder.io/qwik"; -import { _regSymbol } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -import { _noopQrl } from "@builder.io/qwik"; -import { _jsxC } from "@builder.io/qwik"; -import { Fragment as _Fragment } from "@builder.io/qwik/jsx-runtime"; -export const Works = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props)=>{ - return /*#__PURE__*/ _jsxC(_Fragment, { - children: [ - /*#__PURE__*/ _jsxQ("div", { - onClick$: serverQrl(/*#__PURE__*/ inlinedQrl(/*#__PURE__*/ _regSymbol(()=>console.log('in server', 'hola'), "gcSPFNpGYgg"), "Works_component_Fragment_div_onClick_server_gcSPFNpGYgg")) - }, null, null, 2, null), - /*#__PURE__*/ _jsxQ("div", null, { - onClick$: /*#__PURE__*/ _noopQrl("Works_component_Fragment_div_onClick_nO4DPVZWP7g") - }, null, 3, null) - ] - }, 1, "u6_0"); -}, "Works_component_t45qL4vNGv0")); +import { componentQrl } from "@qwik.dev/core"; +import { serverQrl } from "@qwik.dev/core"; +import { useLexicalScope } from "@qwik.dev/core"; +import { _regSymbol } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _noopQrl } from "@qwik.dev/core"; +import { Fragment as _Fragment } from "@qwik.dev/core/jsx-runtime"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Works = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl((props)=>{ + const text = _addLoc('hola', "test.tsx", 6, 15); + return /*#__PURE__*/ _jsxSorted(_Fragment, null, null, [ + /*#__PURE__*/ _jsxSorted("div", { + onClick$: serverQrl(/*#__PURE__*/ inlinedQrl(/*#__PURE__*/ _regSymbol(()=>{ + const [text] = useLexicalScope(); + return console.log('in server', text); + }, "w14FKEVFKTE"), "Works_Fragment_div_onClick_server_w14FKEVFKTE", [ + text + ])) + }, null, null, 2, null), + /*#__PURE__*/ _jsxSorted("div", null, { + onClick$: /*#__PURE__*/ _noopQrl("Works_Fragment_div_onClick_oKx0De7Tp5c") + }, null, 3, null) + ], 1, "u6_0"); +}, "Works_component_t45qL4vNGv0")), "test.tsx", 5, 22); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;;;AAGA,OAAO,MAAM,sBAAQ,sCAAW,CAAC;IAE7B,qBACI;;0BACA,MAAC;gBAAI,UAAU,4DAAQ,IAAM,QAAQ,GAAG,CAAC,aAHhC;;0BAIT,MAAC;gBAAI,QAAQ;;;;AAGrB,mCAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;;;;AAGA,OAAO,MAAM,sBAAQ,QAAA,sCAAW,CAAC;IAChC,MAAM,OAAO,QAAA;IACb,qBACC;sBACA,WAAC;YAAI,UAAU,4DAAQ;;uBAAM,QAAQ,GAAG,CAAC,aAAa;;;;;sBACtD,WAAC;YAAI,QAAQ;;;AAGf,uDAAG\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_reg_ctx_name_segments_hoisted.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_reg_ctx_name_segments_hoisted.snap index d7eb4d68d0b..0999662e578 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_reg_ctx_name_segments_hoisted.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_reg_ctx_name_segments_hoisted.snap @@ -1,45 +1,53 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 802 +assertion_line: 912 expression: output snapshot_kind: text --- ==INPUT== -import { $, component$, server$, useStyle$ } from '@builder.io/qwik'; +import { $, component$, server$, useStyle$ } from '@qwik.dev/core'; export const Works = component$((props) => { - useStyle$(STYLES); - const text = 'hola'; - return ( -
        console.log('in server', text))}>
        - ); + useStyle$(STYLES); + const text = 'hola'; + return ( +
        console.log('in server', text))}>
        + ); }); const STYLES = '.class {}'; ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { useStyleQrl } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { serverQrl } from "@builder.io/qwik"; -import { _regSymbol } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -const Works_component_div_onClick_server_OsNoEFc5SM4 = /*#__PURE__*/ _regSymbol(()=>console.log('in server', 'hola'), "OsNoEFc5SM4"); +import { componentQrl } from "@qwik.dev/core"; +import { useStyleQrl } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { serverQrl } from "@qwik.dev/core"; +import { useLexicalScope } from "@qwik.dev/core"; +import { _regSymbol } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +const Works_div_onClick_server_m9AaOyPPsM0 = /*#__PURE__*/ _regSymbol(()=>{ + const [text] = useLexicalScope(); + return console.log('in server', text); +}, "m9AaOyPPsM0"); const Works_component_t45qL4vNGv0 = (props)=>{ useStyleQrl(/*#__PURE__*/ inlinedQrl(STYLES, "Works_component_useStyle_i40UL9JyQpg")); - return /*#__PURE__*/ _jsxQ("div", { - onClick$: serverQrl(/*#__PURE__*/ inlinedQrl(Works_component_div_onClick_server_OsNoEFc5SM4, "Works_component_div_onClick_server_OsNoEFc5SM4")) + const text = _addLoc('hola', "test.tsx", 7, 15); + return /*#__PURE__*/ _jsxSorted("div", { + onClick$: serverQrl(/*#__PURE__*/ inlinedQrl(Works_div_onClick_server_m9AaOyPPsM0, "Works_div_onClick_server_m9AaOyPPsM0", [ + text + ])) }, null, null, 2, "u6_0"); }; -export const Works = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl(Works_component_t45qL4vNGv0, "Works_component_t45qL4vNGv0")); -const STYLES = '.class {}'; +export const Works = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl(Works_component_t45qL4vNGv0, "Works_component_t45qL4vNGv0")), "test.tsx", 5, 22); +const STYLES = _addLoc('.class {}', "test.tsx", 13, 16); export { STYLES as _auto_STYLES }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;gFAO+B,IAAM,QAAQ,GAAG,CAAC,aAFhC;oCAFe,CAAC;IAC7B,qCAAU;IAEV,qBACI,MAAC;QAAI,UAAU;;AAEvB;AANA,OAAO,MAAM,sBAAQ,mGAMlB;AAEH,MAAM,SAAS\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;;sEAOyB;;WAAM,QAAQ,GAAG,CAAC,aAAa;;oCAJxB,CAAC;IAChC,qCAAU;IACV,MAAM,OAAO,QAAA;IACb,qBACC,WAAC;QAAI,UAAU;;;;AAEjB;AANA,OAAO,MAAM,sBAAQ,QAAA,uHAMlB;AAEH,MAAM,SAAS,QAAA\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_reg_ctx_name_segments_inlined.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_reg_ctx_name_segments_inlined.snap index 618341e1012..08d8062ac1e 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_reg_ctx_name_segments_inlined.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_reg_ctx_name_segments_inlined.snap @@ -1,35 +1,43 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 781 +assertion_line: 891 expression: output snapshot_kind: text --- ==INPUT== -import { $, component$, server$ } from '@builder.io/qwik'; +import { $, component$, server$ } from '@qwik.dev/core'; export const Works = component$((props) => { - const text = 'hola'; - return ( -
        console.log('in server', text))}>
        - ); + const text = 'hola'; + return ( +
        console.log('in server', text))}>
        + ); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { serverQrl } from "@builder.io/qwik"; -import { _regSymbol } from "@builder.io/qwik"; -import { inlinedQrl } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -export const Works = /*#__PURE__*/ componentQrl(/*#__PURE__*/ inlinedQrl((props)=>{ - return /*#__PURE__*/ _jsxQ("div", { - onClick$: serverQrl(/*#__PURE__*/ inlinedQrl(/*#__PURE__*/ _regSymbol(()=>console.log('in server', 'hola'), "OsNoEFc5SM4"), "Works_component_div_onClick_server_OsNoEFc5SM4")) +import { componentQrl } from "@qwik.dev/core"; +import { serverQrl } from "@qwik.dev/core"; +import { useLexicalScope } from "@qwik.dev/core"; +import { _regSymbol } from "@qwik.dev/core"; +import { inlinedQrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const Works = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ inlinedQrl((props)=>{ + const text = _addLoc('hola', "test.tsx", 5, 15); + return /*#__PURE__*/ _jsxSorted("div", { + onClick$: serverQrl(/*#__PURE__*/ inlinedQrl(/*#__PURE__*/ _regSymbol(()=>{ + const [text] = useLexicalScope(); + return console.log('in server', text); + }, "m9AaOyPPsM0"), "Works_div_onClick_server_m9AaOyPPsM0", [ + text + ])) }, null, null, 2, "u6_0"); -}, "Works_component_t45qL4vNGv0")); +}, "Works_component_t45qL4vNGv0")), "test.tsx", 4, 22); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;AAEA,OAAO,MAAM,sBAAQ,sCAAW,CAAC;IAE7B,qBACI,MAAC;QAAI,UAAU,4DAAQ,IAAM,QAAQ,GAAG,CAAC,aAFhC;;AAIjB,mCAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;;;;;AAEA,OAAO,MAAM,sBAAQ,QAAA,sCAAW,CAAC;IAChC,MAAM,OAAO,QAAA;IACb,qBACC,WAAC;QAAI,UAAU,4DAAQ;;mBAAM,QAAQ,GAAG,CAAC,aAAa;;;;;AAExD,uDAAG\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_renamed_exports.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_renamed_exports.snap index 14796876963..f5a5cd4dec8 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_renamed_exports.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_renamed_exports.snap @@ -1,97 +1,102 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 964 +assertion_line: 1074 expression: output snapshot_kind: text --- ==INPUT== -import { component$ as Component, $ as onRender, useStore } from '@builder.io/qwik'; +import { component$ as Component, $ as onRender, useStore } from '@qwik.dev/core'; export const App = Component((props) => { - const state = useStore({thing: 0}); + const state = useStore({thing: 0}); - return onRender(() => ( -
        {state.thing}
        - )); + return onRender(() => ( +
        {state.thing}
        + )); }); ============================= test.js == -import { componentQrl } from "@builder.io/qwik"; -import { qrl } from "@builder.io/qwik"; -export const App = /*#__PURE__*/ componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_Component_NuXFTHRjvXE"), "App_Component_NuXFTHRjvXE")); +import { componentQrl } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const App = /*#__PURE__*/ _addLoc(componentQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_App_Component_NuXFTHRjvXE"), "App_Component_NuXFTHRjvXE")), "test.tsx", 5, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,iHAMhB\"}") -============================= test.tsx_App_Component_1_A08tXHb9pEk.js (ENTRY POINT)== +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AAGA,OAAO,MAAM,oBAAM,QAAA,qIAMhB\"}") +============================= test.tsx_App_Component_NuXFTHRjvXE.js (ENTRY POINT)== -import { useLexicalScope } from "@builder.io/qwik"; -import { _fnSignal } from "@builder.io/qwik"; -import { _jsxQ } from "@builder.io/qwik"; -export const App_Component_1_A08tXHb9pEk = ()=>{ - const [state] = useLexicalScope(); - return /*#__PURE__*/ _jsxQ("div", null, null, _fnSignal((p0)=>p0.thing, [ +import { _addLoc } from "@qwik.dev/core/internal"; +import { qrl } from "@qwik.dev/core"; +import { useStore } from "@qwik.dev/core"; +export const App_Component_NuXFTHRjvXE = (props)=>{ + const state = _addLoc(useStore({ + thing: 0 + }), "test.tsx", 6, 16); + return /*#__PURE__*/ qrl(()=>import("./test.tsx_App_Jlq9hNxnCvw"), "App_Jlq9hNxnCvw", [ state - ], "p0.thing"), 3, "u6_0"); + ]); }; -export { _hW } from "@builder.io/qwik"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;2CAMoB;;yBACZ,MAAC,mCAAK,GAAM,KAAK\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;yCAG6B,CAAC;IAC7B,MAAM,QAAQ,QAAA,SAAS;QAAC,OAAO;IAAC;IAEhC;;;AAGD\"}") /* { "origin": "test.tsx", - "name": "App_Component_1_A08tXHb9pEk", + "name": "App_Component_NuXFTHRjvXE", "entry": null, - "displayName": "test.tsx_App_Component_1", - "hash": "A08tXHb9pEk", - "canonicalFilename": "test.tsx_App_Component_1_A08tXHb9pEk", + "displayName": "test.tsx_App_Component", + "hash": "NuXFTHRjvXE", + "canonicalFilename": "test.tsx_App_Component_NuXFTHRjvXE", "path": "", "extension": "js", - "parent": "App_Component_NuXFTHRjvXE", + "parent": null, "ctxKind": "function", - "ctxName": "$", - "captures": true, + "ctxName": "component$", + "captures": false, "loc": [ - 191, - 237 + 115, + 224 + ], + "paramNames": [ + "props" ] } */ -============================= test.tsx_App_Component_NuXFTHRjvXE.js (ENTRY POINT)== +============================= test.tsx_App_Jlq9hNxnCvw.js (ENTRY POINT)== -import { qrl } from "@builder.io/qwik"; -import { useStore } from "@builder.io/qwik"; -export const App_Component_NuXFTHRjvXE = (props)=>{ - const state = useStore({ - thing: 0 - }); - return /*#__PURE__*/ qrl(()=>import("./test.tsx_App_Component_1_A08tXHb9pEk"), "App_Component_1_A08tXHb9pEk", [ - state - ]); +import { useLexicalScope } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +import { _wrapProp } from "@qwik.dev/core"; +export const App_Jlq9hNxnCvw = ()=>{ + const [state] = useLexicalScope(); + return /*#__PURE__*/ _jsxSorted("div", null, null, _wrapProp(state, "thing"), 1, "u6_0"); }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;yCAG6B,CAAC;IAC1B,MAAM,QAAQ,SAAS;QAAC,OAAO;IAAC;IAEhC;;;AAGJ\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;+BAMiB;;yBACf,WAAC,6BAAK\"}") /* { "origin": "test.tsx", - "name": "App_Component_NuXFTHRjvXE", + "name": "App_Jlq9hNxnCvw", "entry": null, - "displayName": "test.tsx_App_Component", - "hash": "NuXFTHRjvXE", - "canonicalFilename": "test.tsx_App_Component_NuXFTHRjvXE", + "displayName": "test.tsx_App", + "hash": "Jlq9hNxnCvw", + "canonicalFilename": "test.tsx_App_Jlq9hNxnCvw", "path": "", "extension": "js", - "parent": null, + "parent": "App_Component_NuXFTHRjvXE", "ctxKind": "function", - "ctxName": "component$", - "captures": false, + "ctxName": "$", + "captures": true, "loc": [ - 117, - 241 + 183, + 220 + ], + "captureNames": [ + "state" ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_server_auth.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_server_auth.snap index 142ea042ed7..68e6fde0116 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_server_auth.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_server_auth.snap @@ -1,6 +1,6 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1767 +assertion_line: 1878 expression: output snapshot_kind: text --- @@ -13,43 +13,43 @@ import Google from 'next-auth/providers/google' import {serverAuth$, auth$} from '@auth/qwik'; export const { onRequest, logout, getSession, signup } = serverAuth$({ - providers: [ - GitHub({ - clientId: process.env.GITHUB_ID, - clientSecret: process.env.GITHUB_SECRET - }), - Facebook({ - clientId: import.meta.env.FACEBOOK_ID, - clientSecret: import.meta.env.FACEBOOK_SECRET - }), - Google({ - clientId: process.env.GOOGLE_ID, - clientSecret: process.env.GOOGLE_SECRET - }) - ] + providers: [ + GitHub({ + clientId: process.env.GITHUB_ID, + clientSecret: process.env.GITHUB_SECRET + }), + Facebook({ + clientId: import.meta.env.FACEBOOK_ID, + clientSecret: import.meta.env.FACEBOOK_SECRET + }), + Google({ + clientId: process.env.GOOGLE_ID, + clientSecret: process.env.GOOGLE_SECRET + }) + ] }); export const { onRequest, logout, getSession, signup } = auth$({ - providers: [ - GitHub({ - clientId: process.env.GITHUB_ID, - clientSecret: process.env.GITHUB_SECRET - }), - Facebook({ - clientId: process.env.FACEBOOK_ID, - clientSecret: process.env.FACEBOOK_SECRET - }), - Google({ - clientId: process.env.GOOGLE_ID, - clientSecret: process.env.GOOGLE_SECRET - }) - ] + providers: [ + GitHub({ + clientId: process.env.GITHUB_ID, + clientSecret: process.env.GITHUB_SECRET + }), + Facebook({ + clientId: process.env.FACEBOOK_ID, + clientSecret: process.env.FACEBOOK_SECRET + }), + Google({ + clientId: process.env.GOOGLE_ID, + clientSecret: process.env.GOOGLE_SECRET + }) + ] }); ============================= test.js == import { serverAuthQrl } from "@auth/qwik"; -import { qrl } from "@builder.io/qwik"; +import { qrl } from "@qwik.dev/core"; import { authQrl } from "@auth/qwik"; export const { onRequest, logout, getSession, signup } = serverAuthQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_serverAuth_qVqpX2a0p9Y"), "serverAuth_qVqpX2a0p9Y")); export const { onRequest, logout, getSession, signup } = authQrl(/*#__PURE__*/ qrl(()=>import("./test.tsx_auth_GU0aY5QCETY"), "auth_GU0aY5QCETY")); @@ -79,7 +79,7 @@ export const auth_GU0aY5QCETY = { }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;gCAuB+D;IAC3D,WAAW;QACX,OAAO;YACH,UAAU,QAAQ,GAAG,CAAC,SAAS;YAC/B,cAAc,QAAQ,GAAG,CAAC,aAAa;QAC3C;QACA,SAAS;YACL,UAAU,QAAQ,GAAG,CAAC,WAAW;YACjC,cAAc,QAAQ,GAAG,CAAC,eAAe;QAC7C;QACA,OAAO;YACH,UAAU,QAAQ,GAAG,CAAC,SAAS;YAC/B,cAAc,QAAQ,GAAG,CAAC,aAAa;QAC3C;KACC;AACL\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;gCAuB+D;IAC9D,WAAW;QACX,OAAO;YACN,UAAU,QAAQ,GAAG,CAAC,SAAS;YAC/B,cAAc,QAAQ,GAAG,CAAC,aAAa;QACxC;QACA,SAAS;YACR,UAAU,QAAQ,GAAG,CAAC,WAAW;YACjC,cAAc,QAAQ,GAAG,CAAC,eAAe;QAC1C;QACA,OAAO;YACN,UAAU,QAAQ,GAAG,CAAC,SAAS;YAC/B,cAAc,QAAQ,GAAG,CAAC,aAAa;QACxC;KACC;AACF\"}") /* { "origin": "test.tsx", @@ -95,8 +95,8 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "ctxName": "auth$", "captures": false, "loc": [ - 704, - 1065 + 644, + 945 ] } */ @@ -123,7 +123,7 @@ export const serverAuth_qVqpX2a0p9Y = { }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;sCAMqE;IACjE,WAAW;QACX,OAAO;YACH,UAAU,QAAQ,GAAG,CAAC,SAAS;YAC/B,cAAc,QAAQ,GAAG,CAAC,aAAa;QAC3C;QACA,SAAS;YACL,UAAU,YAAY,GAAG,CAAC,WAAW;YACrC,cAAc,YAAY,GAAG,CAAC,eAAe;QACjD;QACA,OAAO;YACH,UAAU,QAAQ,GAAG,CAAC,SAAS;YAC/B,cAAc,QAAQ,GAAG,CAAC,aAAa;QAC3C;KACC;AACL\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;sCAMqE;IACpE,WAAW;QACX,OAAO;YACN,UAAU,QAAQ,GAAG,CAAC,SAAS;YAC/B,cAAc,QAAQ,GAAG,CAAC,aAAa;QACxC;QACA,SAAS;YACR,UAAU,YAAY,GAAG,CAAC,WAAW;YACrC,cAAc,YAAY,GAAG,CAAC,eAAe;QAC9C;QACA,OAAO;YACN,UAAU,QAAQ,GAAG,CAAC,SAAS;YAC/B,cAAc,QAAQ,GAAG,CAAC,aAAa;QACxC;KACC;AACF\"}") /* { "origin": "test.tsx", @@ -140,7 +140,7 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma "captures": false, "loc": [ 268, - 637 + 577 ] } */ diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_skip_transform.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_skip_transform.snap index f21abea0d9e..930755072f4 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_skip_transform.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_skip_transform.snap @@ -1,34 +1,35 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 1260 +assertion_line: 1370 expression: output snapshot_kind: text --- ==INPUT== -import { component$ as Component, $ as onRender } from '@builder.io/qwik'; +import { component$ as Component, $ as onRender } from '@qwik.dev/core'; export const handler = $(()=>console.log('hola')); export const App = component$((props) => { - useStyles$('hola'); - return $(() => ( -
        {state.thing}
        - )); + useStyles$('hola'); + return $(() => ( +
        {state.thing}
        + )); }); ============================= test.js == -import { _jsxQ } from "@builder.io/qwik"; -export const handler = $(()=>console.log('hola')); -export const App = component$((props)=>{ +import { _jsxSorted } from "@qwik.dev/core"; +import { _addLoc } from "@qwik.dev/core/internal"; +export const handler = _addLoc($(()=>console.log('hola')), "test.tsx", 5, 24); +export const App = _addLoc(component$((props)=>{ useStyles$('hola'); - return $(()=>/*#__PURE__*/ _jsxQ("div", null, null, state.thing, 3, "u6_0")); -}); + return $(()=>/*#__PURE__*/ _jsxSorted("div", null, null, state.thing, 1, "u6_0")); +}), "test.tsx", 7, 20); -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";AAGA,OAAO,MAAM,UAAU,EAAE,IAAI,QAAQ,GAAG,CAAC,SAAS;AAElD,OAAO,MAAM,MAAM,WAAW,CAAC;IAC3B,WAAW;IACX,OAAO,EAAE,kBACL,MAAC,mBAAK,MAAM,KAAK;AAEzB,GAAG\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,UAAU,QAAA,EAAE,IAAI,QAAQ,GAAG,CAAC,6BAAS;AAElD,OAAO,MAAM,MAAM,QAAA,WAAW,CAAC;IAC9B,WAAW;IACX,OAAO,EAAE,kBACR,WAAC,mBAAK,MAAM,KAAK;AAEnB,uBAAG\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_spread_jsx.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_spread_jsx.snap index b204190e6ee..618dcc43b94 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_spread_jsx.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_spread_jsx.snap @@ -1,103 +1,101 @@ --- source: packages/qwik/src/optimizer/core/src/test.rs -assertion_line: 2255 +assertion_line: 2366 expression: output snapshot_kind: text --- ==INPUT== -import { component$ } from '@builder.io/qwik'; -import { useDocumentHead, useLocation } from '@builder.io/qwik-city'; +import { component$ } from '@qwik.dev/core'; +import { useDocumentHead, useLocation } from '@qwik.dev/router'; /** * The RouterHead component is placed inside of the document `` element. */ export const RouterHead = component$(() => { - const head = useDocumentHead(); - const loc = useLocation(); + const head = useDocumentHead(); + const loc = useLocation(); - return ( - <> - {head.title} + return ( + <> + {head.title} - - - + + + - {head.meta.map((m) => ( - - ))} + {head.meta.map((m) => ( + + ))} - {head.links.map((l) => ( - - ))} + {head.links.map((l) => ( + + ))} - {head.styles.map((s) => ( - + + +
        + + + diff --git a/starters/features/prisma/src/routes/create/index.tsx b/starters/features/prisma/src/routes/create/index.tsx index cef4017e846..a7f4226d2a1 100644 --- a/starters/features/prisma/src/routes/create/index.tsx +++ b/starters/features/prisma/src/routes/create/index.tsx @@ -1,6 +1,6 @@ -import { component$ } from "@builder.io/qwik"; -import { routeAction$, zod$, z, Form } from "@builder.io/qwik-city"; import { PrismaClient } from "@prisma/client"; +import { Form, routeAction$, z, zod$ } from "@qwik.dev/router"; +import { component$ } from "@qwik.dev/core"; export const useCreateUser = routeAction$( async (data) => { diff --git a/starters/features/prisma/src/routes/users/[userId]/index.tsx b/starters/features/prisma/src/routes/users/[userId]/index.tsx index daa1deaf0ff..e93b2532edb 100644 --- a/starters/features/prisma/src/routes/users/[userId]/index.tsx +++ b/starters/features/prisma/src/routes/users/[userId]/index.tsx @@ -1,6 +1,6 @@ -import { component$ } from "@builder.io/qwik"; -import { routeLoader$ } from "@builder.io/qwik-city"; import { PrismaClient } from "@prisma/client"; +import { routeLoader$ } from "@qwik.dev/router"; +import { component$ } from "@qwik.dev/core"; export const useGetUser = routeLoader$(async ({ params, status }) => { const userId = parseInt(params["userId"], 10); diff --git a/starters/features/prisma/src/routes/users/index.tsx b/starters/features/prisma/src/routes/users/index.tsx index 5639906cc25..b110c3dff4d 100644 --- a/starters/features/prisma/src/routes/users/index.tsx +++ b/starters/features/prisma/src/routes/users/index.tsx @@ -1,6 +1,6 @@ -import { component$ } from "@builder.io/qwik"; -import { routeLoader$ } from "@builder.io/qwik-city"; import { PrismaClient } from "@prisma/client"; +import { routeLoader$ } from "@qwik.dev/router"; +import { component$ } from "@qwik.dev/core"; export const useGetUsers = routeLoader$(async () => { const prisma = new PrismaClient(); diff --git a/starters/features/react/package.json b/starters/features/react/package.json index 47f3466eb83..f25223beab2 100644 --- a/starters/features/react/package.json +++ b/starters/features/react/package.json @@ -19,7 +19,7 @@ "namedImports": [ "qwikReact" ], - "importPath": "@builder.io/qwik-react/vite" + "importPath": "@qwik.dev/react/vite" } ], "vitePlugins": [ @@ -28,7 +28,7 @@ } }, "devDependencies": { - "@builder.io/qwik-react": "0.5.0", + "@qwik.dev/react": "0.5.0", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@mui/material": "^5.13.0", diff --git a/starters/features/react/src/integrations/react/mui.tsx b/starters/features/react/src/integrations/react/mui.tsx index c5e4ebe339e..413f7d0c6f8 100644 --- a/starters/features/react/src/integrations/react/mui.tsx +++ b/starters/features/react/src/integrations/react/mui.tsx @@ -1,6 +1,6 @@ /** @jsxImportSource react */ -import { qwikify$ } from "@builder.io/qwik-react"; +import { qwikify$ } from "@qwik.dev/react"; import { Button, Slider } from "@mui/material"; import { DataGrid, GridColDef, GridValueGetterParams } from "@mui/x-data-grid"; diff --git a/starters/features/react/src/routes/react/index.tsx b/starters/features/react/src/routes/react/index.tsx index 4c4adb335be..47b464d5e77 100644 --- a/starters/features/react/src/routes/react/index.tsx +++ b/starters/features/react/src/routes/react/index.tsx @@ -1,5 +1,5 @@ -import { component$, useSignal } from "@builder.io/qwik"; -import type { DocumentHead } from "@builder.io/qwik-city"; +import type { DocumentHead } from "@qwik.dev/router"; +import { component$, useSignal } from "@qwik.dev/core"; import { MUIButton, MUISlider, TableApp } from "~/integrations/react/mui"; export default component$(() => { diff --git a/starters/features/service-worker/package.json b/starters/features/service-worker/package.json index 6d145e7f5dd..0d9f536c2ea 100644 --- a/starters/features/service-worker/package.json +++ b/starters/features/service-worker/package.json @@ -6,7 +6,7 @@ "docs": [], "nextSteps": { "lines": [ - "Now, make sure that you have `` in your `src/root.tsx`. You can import it from `@builder.io/qwik-city`." + "Now, make sure that you have `` in your `src/root.tsx`. You can import it from `@qwik.dev/router`." ] } } diff --git a/starters/features/storybook/src/components/button/button.tsx b/starters/features/storybook/src/components/button/button.tsx index b1a9a076079..463e2aaf543 100644 --- a/starters/features/storybook/src/components/button/button.tsx +++ b/starters/features/storybook/src/components/button/button.tsx @@ -1,4 +1,4 @@ -import { component$, useStylesScoped$, Slot } from "@builder.io/qwik"; +import { component$, Slot, useStylesScoped$ } from "@qwik.dev/core"; export interface ButtonProps { size?: "small" | "medium" | "large"; diff --git a/starters/features/styled-vanilla-extract/src/routes/styled-flower/index.tsx b/starters/features/styled-vanilla-extract/src/routes/styled-flower/index.tsx index 9d04e3f3004..c7bf983582e 100644 --- a/starters/features/styled-vanilla-extract/src/routes/styled-flower/index.tsx +++ b/starters/features/styled-vanilla-extract/src/routes/styled-flower/index.tsx @@ -1,10 +1,10 @@ +import { DocumentHead, useLocation } from "@qwik.dev/router"; import { component$, FunctionComponent, - useVisibleTask$, useStore, -} from "@builder.io/qwik"; -import { DocumentHead, useLocation } from "@builder.io/qwik-city"; + useVisibleTask$, +} from "@qwik.dev/core"; import { Host, odd, pride, Range, Square } from "./flower.css"; type StoredInputProps< diff --git a/starters/features/turso/package.json b/starters/features/turso/package.json index 7cfc5f4bbe5..686cc909621 100644 --- a/starters/features/turso/package.json +++ b/starters/features/turso/package.json @@ -28,6 +28,6 @@ "@libsql/client": "latest" }, "devDependencies": { - "@builder.io/qwik-city": "latest" + "@qwik.dev/router": "latest" } } diff --git a/starters/features/turso/src/utils/turso.ts b/starters/features/turso/src/utils/turso.ts index fc84b71bf94..520b076cea3 100644 --- a/starters/features/turso/src/utils/turso.ts +++ b/starters/features/turso/src/utils/turso.ts @@ -1,4 +1,4 @@ -import type { RequestEventBase } from "@builder.io/qwik-city"; +import type { RequestEventBase } from "@qwik.dev/router"; import { createClient, type Client } from "@libsql/client"; export function tursoClient(requestEvent: RequestEventBase): Client { diff --git a/starters/features/vitest/src/components/example/example.spec.tsx b/starters/features/vitest/src/components/example/example.spec.tsx index 682384c77a6..b36ebed555c 100644 --- a/starters/features/vitest/src/components/example/example.spec.tsx +++ b/starters/features/vitest/src/components/example/example.spec.tsx @@ -1,5 +1,5 @@ -import { createDOM } from "@builder.io/qwik/testing"; -import { test, expect } from "vitest"; +import { createDOM } from "@qwik.dev/core/testing"; +import { expect, test } from "vitest"; import { ExampleTest } from "./example"; test(`[ExampleTest Component]: Should render ⭐`, async () => { diff --git a/starters/features/vitest/src/components/example/example.tsx b/starters/features/vitest/src/components/example/example.tsx index f2866cbada6..8ea82d6dca4 100644 --- a/starters/features/vitest/src/components/example/example.tsx +++ b/starters/features/vitest/src/components/example/example.tsx @@ -1,4 +1,4 @@ -import { component$, useStore } from "@builder.io/qwik"; +import { component$, useStore } from "@qwik.dev/core"; export const ExampleTest = component$((props: { flag: boolean }) => { const state = useStore({ diff --git a/starters/playwright.config.ts b/starters/playwright.config.ts index f47920e7a1b..8da0d52124d 100644 --- a/starters/playwright.config.ts +++ b/starters/playwright.config.ts @@ -1,5 +1,5 @@ -import { expect } from "@playwright/test"; import type { Locator, PlaywrightTestConfig } from "@playwright/test"; +import { expect } from "@playwright/test"; const inGithubCI = !!process.env.GITHUB_ACTIONS; @@ -24,6 +24,7 @@ const config: PlaywrightTestConfig = { height: 600, }, }, + testMatch: "*.e2e.ts", testIgnore: /.*example.spec.tsx?$/, retries: inGithubCI ? 0 : 1, expect: { timeout: inGithubCI ? 120000 : 10000 }, diff --git a/starters/templates/barrel/component/index.tsx.template b/starters/templates/barrel/component/index.tsx.template index f78ba4ecb88..5b43a91bc70 100644 --- a/starters/templates/barrel/component/index.tsx.template +++ b/starters/templates/barrel/component/index.tsx.template @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export interface [name]Props { diff --git a/starters/templates/barrel/route/index.tsx.template b/starters/templates/barrel/route/index.tsx.template index 16edd2ebf65..c1e8a976a47 100644 --- a/starters/templates/barrel/route/index.tsx.template +++ b/starters/templates/barrel/route/index.tsx.template @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export default component$(() => { return ( diff --git a/starters/templates/qwik/component/[slug].tsx.template b/starters/templates/qwik/component/[slug].tsx.template index f78ba4ecb88..5b43a91bc70 100644 --- a/starters/templates/qwik/component/[slug].tsx.template +++ b/starters/templates/qwik/component/[slug].tsx.template @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export interface [name]Props { diff --git a/starters/templates/qwik/route/index.tsx.template b/starters/templates/qwik/route/index.tsx.template index 16edd2ebf65..c1e8a976a47 100644 --- a/starters/templates/qwik/route/index.tsx.template +++ b/starters/templates/qwik/route/index.tsx.template @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export default component$(() => { return ( diff --git a/todo-v2-alpha.txt b/todo-v2-alpha.txt new file mode 100644 index 00000000000..5d78caf1fe2 --- /dev/null +++ b/todo-v2-alpha.txt @@ -0,0 +1,2 @@ +- [ ] Finalize all builds scripts for - worker, typed-routes, insights and devtools(?) +- [ ] Remove all mentions to `labs` \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 0c6c0fdaf62..883dd136fb9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,28 +7,27 @@ "resolveJsonModule": true, "jsx": "react-jsx", "allowArbitraryExtensions": true, - "jsxImportSource": "@builder.io/qwik", + "jsxImportSource": "@qwik.dev/core", "declaration": true, "outDir": "./dist-dev/tsc-out", "declarationDir": "./dist-dev/dts-out", "strict": true, - "verbatimModuleSyntax": true, "moduleResolution": "Bundler", "baseUrl": ".", "assumeChangesOnlyAffectDirectDependencies": true, "noUnusedLocals": true, "paths": { "@qwik-client-manifest": ["packages/qwik/dist/server-modules.d.ts"], - "@qwik-city-plan": ["packages/qwik-city/src/runtime/src/qwik-city-plan.ts"], - "@qwik-city-sw-register-build": [ - "packages/qwik-city/src/buildtime/runtime-generation/sw-register-build.ts" + "@qwik-router-config": ["packages/qwik-router/src/runtime/src/qwik-router-config.ts"], + "@qwik-router-sw-register-build": [ + "packages/qwik-router/src/buildtime/runtime-generation/sw-register-build.ts" ], - "@qwik-city-sw-register": ["packages/qwik-city/src/runtime/src/sw-register-runtime.ts"], - "@qwik-city-not-found-paths": [ - "packages/qwik-city/src/middleware/request-handler/generated/not-found-paths.ts" + "@qwik-router-sw-register": ["packages/qwik-router/src/runtime/src/sw-register-runtime.ts"], + "@qwik-router-not-found-paths": [ + "packages/qwik-router/src/middleware/request-handler/generated/not-found-paths.ts" ], - "@qwik-city-static-paths": [ - "packages/qwik-city/src/middleware/request-handler/generated/static-paths.ts" + "@qwik-router-static-paths": [ + "packages/qwik-router/src/middleware/request-handler/generated/static-paths.ts" ] }, "types": ["node", "vite/client"], @@ -42,21 +41,20 @@ }, "include": [ "packages/create-qwik", - "packages/qwik-auth", - "packages/qwik-worker", "packages/supabase-auth-helpers-qwik", "packages/qwik-react/src", "scripts", "starters/apps/sandbox", "starters/apps/todo-test", "starters/apps/e2e", - "starters/apps/qwikcity-test/**/*", - "starters/apps/qwikcity-test.prod/**/*", + "starters/apps/qwikrouter-test/**/*", + "starters/apps/qwikrouter-test.prod/**/*", "starters/dev-server.ts", "packages/qwik-react/vite", "@types/deno.d.ts", "@types/bun.d.ts", - "types.d.ts" + "types.d.ts", + "packages/qwik-router/global.d.ts" ], "exclude": [ "packages/create-qwik/dist", diff --git a/vitest-setup.ts b/vitest-setup.ts index ca719d15602..d428752057a 100644 --- a/vitest-setup.ts +++ b/vitest-setup.ts @@ -8,6 +8,6 @@ globalThis.qInspector = false; beforeAll(async () => { const { getTestPlatform } = await import('./packages/qwik/src/testing/platform'); - const { setPlatform } = await import('./packages/qwik/src/core/platform/platform'); + const { setPlatform } = await import('./packages/qwik/src/core/shared/platform/platform'); setPlatform(getTestPlatform() as any); }); diff --git a/vitest.config.mts b/vitest.config.mts new file mode 100644 index 00000000000..8e2addf334a --- /dev/null +++ b/vitest.config.mts @@ -0,0 +1,18 @@ +import { qwikVite } from '@qwik.dev/core/optimizer'; +import tsconfigPaths from 'vite-tsconfig-paths'; +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + plugins: [ + qwikVite({ + debug: !true, + srcDir: `./packages/qwik/src`, + }), + tsconfigPaths({ ignoreConfigErrors: true }), + ], + test: { + root: 'packages', + include: ['**/*.spec.?(c|m)[jt]s?(x)', '**/*.unit.?(c|m)[jt]s?(x)', '!qwik/dist', '!*/lib'], + setupFiles: ['./vitest-setup.ts'], + }, +}); diff --git a/vitest.config.ts b/vitest.config.ts deleted file mode 100644 index 7910a25069d..00000000000 --- a/vitest.config.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { defineConfig } from 'vitest/config'; -import tsconfigPaths from 'vite-tsconfig-paths'; - -export default defineConfig({ - plugins: [tsconfigPaths({ ignoreConfigErrors: true })], - test: { - include: [ - 'packages/**/*.unit.?(c|m)[jt]s?(x)', - // Rust build cache - '!packages/qwik/**/target', - '!packages/qwik/dist', - '!packages/*/lib', - '!starters', - '!**/node_modules', - '!dist-dev', - ], - setupFiles: ['./vitest-setup.ts'], - }, -}); diff --git a/vitest.workspace.js b/vitest.workspace.js index 08145815168..3f8159bfa20 100644 --- a/vitest.workspace.js +++ b/vitest.workspace.js @@ -1,4 +1,8 @@ +/** Needed by the vscode vitest integration but it also speeds up vitest cli */ import { defineWorkspace } from 'vitest/config'; +import { join } from 'node:path'; -// needed by the vscode vitest integration but it also speeds up vitest cli -export default defineWorkspace(['./vitest.config.ts']); +export default defineWorkspace([ + // For some reason vitest cli doesn't pick up the config in the root + join(process.cwd(), 'vitest.config.mts'), +]);