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/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/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/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/config.json b/.changeset/config.json index cbdecdfe0a4..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": "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/dry-jobs-repair.md b/.changeset/dry-jobs-repair.md deleted file mode 100644 index 006e3c1ae67..00000000000 --- a/.changeset/dry-jobs-repair.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@builder.io/qwik-city': patch ---- - -FIX: the previous URL now is undefined on first render. 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/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/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-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/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/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/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/pre.json b/.changeset/pre.json new file mode 100644 index 00000000000..54076c0ca2d --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,41 @@ +{ + "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": [ + "brave-files-grin", + "calm-cycles-know", + "chilled-spoons-wonder", + "clever-flowers-drum", + "fast-baboons-itch", + "five-kangaroos-matter", + "fresh-rocks-exercise", + "friendly-gorillas-walk", + "heavy-seas-carry", + "hip-hornets-cheer", + "mean-dingos-hug", + "nervous-terms-explode", + "nine-otters-repeat", + "proud-pillows-try", + "rich-wasps-tease", + "rotten-weeks-tickle", + "sour-zebras-tell", + "sweet-socks-whisper", + "tiny-berries-bow", + "tricky-meals-heal", + "twenty-goats-flow", + "wild-cooks-pay" + ] +} diff --git a/.changeset/proud-carrots-grab.md b/.changeset/proud-carrots-grab.md deleted file mode 100644 index 8f1f62312b0..00000000000 --- a/.changeset/proud-carrots-grab.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@builder.io/qwik': patch ---- - -Fix: add subscription when doing `"prop" in store` 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/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-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/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/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/three-donkeys-admire.md b/.changeset/three-donkeys-admire.md deleted file mode 100644 index 07102f1e72e..00000000000 --- a/.changeset/three-donkeys-admire.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@builder.io/qwik-city': patch ---- - -FIX: server$ functions now correctly throw errors for > 500 error codes 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/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/twenty-paws-argue.md b/.changeset/twenty-paws-argue.md deleted file mode 100644 index af3cd7a28dd..00000000000 --- a/.changeset/twenty-paws-argue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@builder.io/qwik': patch ---- - -FIX: `stoppropagation` functionality 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/.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/.eslintignore b/.eslintignore index ec0b06b7b51..ee47d64c35c 100644 --- a/.eslintignore +++ b/.eslintignore @@ -22,12 +22,9 @@ 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 +vite.config.mts 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 97b49f5b8e3..9c29315c713 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' @@ -77,7 +76,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' ) @@ -150,14 +149,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/**/*', '!**/*.unit.*') }} + key: ${{ hashfiles('qwik-key.txt', 'rust-key.txt', 'packages/qwik-router/**/*', 'packages/qwik-react/**/*', 'packages/eslint-plugin-qwik/**/*', 'packages/create-qwik/**/*', '!**/*.unit.*') }} - run: 'echo ${{ steps.cache-others.outputs.cache-primary-key }} > others-key.txt' - name: 'check cache: docs' id: cache-docs @@ -401,58 +398,40 @@ jobs: if: needs.changes.outputs.build-others == 'true' run: corepack 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: Print QwikRouter Lib Build + run: tree -a packages/qwik-router/lib/ - - name: Upload QwikCity Build Artifacts + - name: Upload QwikRouter Build Artifacts uses: actions/upload-artifact@v4 with: - name: artifact-qwikcity + name: artifact-qwikrouter 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: Upload QwikLabs+React Build Artifacts - uses: actions/upload-artifact@v4 - with: - name: artifact-qwiklabs - 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 @@ -513,14 +492,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 @@ -573,14 +550,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: corepack pnpm install --frozen-lockfile @@ -634,8 +609,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/ @@ -698,8 +673,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/ @@ -713,9 +688,10 @@ jobs: - name: Playwright E2E Tests run: pnpm run test.e2e.${{ 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: @@ -755,8 +731,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/ @@ -817,7 +793,7 @@ jobs: if: | always() && github.repository == 'QwikDev/qwik' && ( - github.ref == 'refs/heads/upcoming' || + github.ref == 'refs/heads/build/v2' || needs.test-unit.result == 'success' ) @@ -855,14 +831,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-* @@ -871,16 +845,40 @@ 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: | + if [ -f "$HOME/.npmrc" ]; then + echo "Found existing user .npmrc file" + if grep -qi "^[[:space:]]*//registry.npmjs.org/:[_-]authToken=" "$HOME/.npmrc"; then + echo "Found existing auth token for the npm registry in the user .npmrc file" + else + echo "Didn't find existing auth token for the npm registry in the user .npmrc file, creating one" + echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" >> "$HOME/.npmrc" + fi + else + echo "No user .npmrc file found, creating one" + echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > "$HOME/.npmrc" + fi + 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 }} + - name: Fixup package.json files run: pnpm run release.fixup-package-json @@ -892,12 +890,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' @@ -911,7 +910,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/.prettierignore b/.prettierignore index be712d47808..a283ec6b543 100644 --- a/.prettierignore +++ b/.prettierignore @@ -38,8 +38,6 @@ packages/insights/drizzle packages/insights/.netlify packages/insights/scripts packages/insights/**/*.gen.d.ts -packages/qwik-labs/lib-types -packages/qwik-labs/vite # TODO: Figure out why this doesn't pass in CI packages/qwik/src/core/props/props.ts 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 36a600c2ea4..9867fa04a90 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -58,7 +58,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 0c0774e2bcd..ef0b9d82af5 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.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" 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" @@ -1258,7 +1222,7 @@ checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1387,20 +1351,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", @@ -1411,9 +1369,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", @@ -1437,9 +1395,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", @@ -1469,7 +1427,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", @@ -1485,16 +1443,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", @@ -1508,9 +1466,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", @@ -1535,14 +1493,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", @@ -1562,9 +1520,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", @@ -1579,13 +1537,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", @@ -1609,17 +1567,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", @@ -1638,13 +1596,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", @@ -1663,9 +1621,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", @@ -1680,11 +1638,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", @@ -1699,9 +1657,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", @@ -1714,9 +1672,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", @@ -1734,16 +1692,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", @@ -1757,7 +1715,7 @@ checksum = "a509f56fca05b39ba6c15f3e58636c3924c78347d63853632ed2ffcb6f5a0ac7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1783,9 +1741,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", @@ -1800,7 +1758,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1809,21 +1767,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" @@ -1834,6 +1777,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" @@ -1853,7 +1806,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1960,9 +1913,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" dependencies = [ "cfg-if 1.0.0", "once_cell", @@ -1971,24 +1924,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1996,22 +1949,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" [[package]] name = "wee_alloc" @@ -2041,15 +1994,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" @@ -2179,7 +2123,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "synstructure", ] @@ -2200,7 +2144,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2220,7 +2164,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "synstructure", ] @@ -2243,5 +2187,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/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/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 b6c2ebf232d..b0a98646444 100644 --- a/e2e/qwik-cli-e2e/package.json +++ b/e2e/qwik-cli-e2e/package.json @@ -1,11 +1,12 @@ { "name": "qwik-cli-e2e", + "version": "0.0.0", "dependencies": { "kleur": "4.1.5" }, "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/setup.ts b/e2e/qwik-cli-e2e/utils/setup.ts index 60096c0b3ad..b772955f306 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', 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/package.json b/package.json index acaa9ad1c06..4e73df42aa1 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": { @@ -39,7 +40,7 @@ "dependencyTypes": [ "dev" ], - "pinVersion": "workspace:^" + "pinVersion": "workspace:*" }, { "label": "Separate prod deps from dev deps", @@ -57,13 +58,6 @@ ], "pinVersion": "1.47.0" }, - { - "label": "Undici should always be * until we remove it", - "dependencies": [ - "undici" - ], - "range": "*" - }, { "label": "use exact version numbers for devDependencies", "dependencyTypes": [ @@ -74,30 +68,11 @@ ] } }, - "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.27.7", "@changesets/get-github-info": "0.6.0", "@changesets/types": "6.0.0", @@ -111,6 +86,8 @@ "@node-rs/helper": "1.6.0", "@octokit/action": "6.1.0", "@playwright/test": "1.47.0", + "@qwik.dev/core": "workspace:*", + "@qwik.dev/router": "workspace:*", "@types/brotli": "1.3.4", "@types/bun": "1.1.6", "@types/cross-spawn": "6.0.6", @@ -128,14 +105,15 @@ "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.20.2", + "esbuild": "0.24.0", "eslint": "8.57.0", + "eslint-plugin-import": "2.29.1", "eslint-plugin-no-only-tests": "3.1.0", - "eslint-plugin-qwik": "workspace:^", + "eslint-plugin-qwik": "workspace:*", "execa": "8.0.1", "express": "4.20.0", "install": "0.13.0", @@ -147,36 +125,35 @@ "prettier-plugin-jsdoc": "1.3.0", "pretty-quick": "4.0.0", "prompts": "2.4.2", - "rollup": "4.19.0", + "rollup": "4.24.2", "semver": "7.6.3", "simple-git-hooks": "2.11.1", "snoop": "1.0.4", "source-map": "0.7.4", "svgo": "3.3.2", "syncpack": "12.3.3", - "terser": "5.31.3", + "terser": "5.36.0", "tmp": "0.2.3", "tree-kill": "1.2.2", "tsx": "4.19.1", "typescript": "5.4.5", - "undici": "*", "vfile": "6.0.2", - "vite": "5.3.5", + "vite": "5.4.10", "vite-imagetools": "7.0.4", - "vite-plugin-dts": "3.9.1", - "vite-tsconfig-paths": "4.3.2", - "vitest": "2.0.5", + "vite-plugin-dts": "4.3.0", + "vite-tsconfig-paths": "5.0.1", + "vitest": "2.1.4", "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" }, - "packageManager": "pnpm@9.0.5", + "packageManager": "pnpm@9.1.2", "pnpm": { "overrides": { "typescript": "5.4.5", @@ -192,23 +169,23 @@ "api.update": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --api --dev", "build": "tsx --require ./scripts/runBefore.ts scripts/index.ts", "build.changelog-formatter": "tsc .changeset/changelog-github-custom.ts && mv .changeset/changelog-github-custom.js .changeset/changelog-github-custom.cjs", - "build.clean": "rm -rf packages/qwik/dist/ && rm -rf packages/qwik-city/lib/ && rm -rf packages/docs/dist/ && rm -rf packages/insights/dist/ && rm -rf packages/qwik-labs/lib/ && rm -rf packages/qwik-labs/vite/", + "build.clean": "rm -rf packages/qwik/dist/ && rm -rf packages/qwik-router/lib/ && rm -rf packages/docs/dist/ && rm -rf packages/insights/dist/", "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 --build --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.full": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --tsc-docs --qwik --supabaseauthhelpers --api --eslint --qwikrouter --qwikworker --qwikreact --cli --platform-binding --wasm", + "build.local": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --tsc-docs --qwik --supabaseauthhelpers --api --eslint --qwikrouter --qwikworker --qwikreact --cli --platform-binding-wasm-copy", "build.only_javascript": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --build --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 --build --api --eslint --qwikrouter --platform-binding --wasm --validate", + "build.vite": "tsx --require ./scripts/runBefore.ts scripts/index.ts --tsc --build --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 --build --qwikrouter --watch --dev --platform-binding", "change": "changeset", "cli": "pnpm build.cli && node packages/create-qwik/dist/create-qwik.cjs && tsx --require ./scripts/runBefore.ts scripts/validate-cli.ts --copy-local-qwik-dist", "cli.qwik": "pnpm build.cli && node packages/qwik/dist/qwik-cli.cjs", @@ -220,9 +197,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*\"", "lint.fix": "eslint --fix \"**/*.ts*\" && pnpm prettier.fix", @@ -235,7 +212,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", @@ -245,14 +222,15 @@ "test.e2e.cli": "pnpm --filter qwik-cli-e2e e2e", "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.run": "tsm scripts/e2e-cli.ts", "test.e2e.firefox": "playwright test starters --browser=firefox --config starters/playwright.config.ts", + "test.e2e.router": "playwright test starters/e2e/qwikrouter --browser=chromium --config starters/playwright.config.ts", "test.e2e.webkit": "playwright test starters --browser=webkit --config starters/playwright.config.ts", "test.rust": "make test", "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 a0cce1eb376..703b297c47c 100644 --- a/packages/create-qwik/CHANGELOG.md +++ b/packages/create-qwik/CHANGELOG.md @@ -1,6 +1,14 @@ # create-qwik -## 1.11.0 +## 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.10.0 @@ -36,4 +44,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 995ad3d0567..d432760382f 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.11.0", - "author": "Builder.io Team", + "version": "2.0.0-alpha.4", + "author": "Qwik Team", "bin": "./create-qwik.cjs", "bugs": "https://github.com/QwikDev/qwik/issues", "devDependencies": { 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 ff8e6e7415e..acd6c14e789 100644 --- a/packages/docs/check-qwik-build.ts +++ b/packages/docs/check-qwik-build.ts @@ -4,11 +4,12 @@ import fs from 'fs'; import path from 'path'; import { spawnSync } from 'child_process'; +import { fileURLToPath } from 'url'; -const __dirname = path.dirname(new URL(import.meta.url).pathname); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); 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 0550f4b40d7..22877e9bcfa 100644 --- a/packages/docs/contributors.ts +++ b/packages/docs/contributors.ts @@ -1,5 +1,4 @@ /* eslint-disable no-console */ -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 991781fc063..8f46d17afd7 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -2,16 +2,14 @@ "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/qwik": "../qwik", + "@builder.io/qwik-city": "../qwik-router", "@builder.io/sdk-qwik": "0.14.31", "@docsearch/css": "3.6.1", "@emotion/react": "11.13.0", @@ -21,6 +19,9 @@ "@mui/system": "5.16.4", "@mui/x-data-grid": "6.20.4", "@qwik-ui/headless": "0.5.0", + "@qwik.dev/core": "workspace:*", + "@qwik.dev/react": "workspace:*", + "@qwik.dev/router": "workspace:*", "@supabase/supabase-js": "2.44.4", "@types/leaflet": "1.9.12", "@types/prismjs": "1.26.4", @@ -40,7 +41,7 @@ "prism-themes": "1.9.0", "prismjs": "1.29.0", "puppeteer": "22.13.1", - "qwik-image": "0.0.10", + "qwik-image": "0.0.15", "react": "18.3.1", "react-dom": "18.3.1", "rehype-pretty-code": "0.11.0", @@ -48,17 +49,17 @@ "shikiji": "0.9.19", "snarkdown": "2.0.0", "tailwindcss": "3.4.6", - "terser": "5.31.3", + "terser": "5.36.0", "tsm": "2.3.0", "typescript": "5.4.5", "undici": "*", "valibot": "0.33.3", - "vite": "5.3.5", + "vite": "5.4.10", "vite-plugin-inspect": "0.8.5", "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" @@ -67,11 +68,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", @@ -83,5 +84,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/postcss.config.js b/packages/docs/postcss.config.cjs similarity index 100% rename from packages/docs/postcss.config.js rename to packages/docs/postcss.config.cjs diff --git a/packages/docs/public/_redirects b/packages/docs/public/_redirects index a4965aab781..4f799cacdb3 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,9 +63,13 @@ /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 \ No newline at end of file +/docs/think-qwik/ /docs/concepts/think-qwik/ 308 +/docs/qwikcity/ /docs/qwikrouter/ 308 +/docs/qwikcity-deprecated-features/ /docs/qwikrouter-deprecated-features/ 308 \ No newline at end of file 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 74064e92901..9eaea2e4887 100644 --- a/packages/docs/scripts/showcase.js +++ b/packages/docs/scripts/showcase.js @@ -134,7 +134,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..430a3129f56 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 = diff --git a/packages/docs/src/components/code-sandbox/index.tsx b/packages/docs/src/components/code-sandbox/index.tsx index ab0fb566500..f5cc6cb5379 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; @@ -101,7 +101,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 60393c1c101..5126ad46be2 100644 --- a/packages/docs/src/components/docsearch/doc-search-modal.tsx +++ b/packages/docs/src/components/docsearch/doc-search-modal.tsx @@ -1,4 +1,4 @@ -import { component$, useSignal, noSerialize, useContextProvider, useTask$ } from '@builder.io/qwik'; +import { component$, useSignal, noSerialize, useContextProvider, useTask$ } from '@qwik.dev/core'; import { MAX_QUERY_SIZE } from './constants'; import { SearchContext } from './context'; import type { DocSearchProps, DocSearchState } from './doc-search'; @@ -12,7 +12,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/build'; +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 4a809788590..83f1d8896ed 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 type { DocSearchHit, InternalDocSearchHit } from './types'; import { type ButtonTranslations, DocSearchButton } from './doc-search-button'; import { DocSearchModal, type ModalTranslations } from './doc-search-modal'; 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 0f7b1e2ad6c..56eda8279bc 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, type QRL } from '@builder.io/qwik'; +import { component$, useVisibleTask$, useContext, type Signal, type QRL } 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 e74e9c2b86d..a8d29c44b60 100644 --- a/packages/docs/src/components/footer/footer.tsx +++ b/packages/docs/src/components/footer/footer.tsx @@ -1,14 +1,14 @@ -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'; 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 a9aa3a20816..d31e5c13ad1 100644 --- a/packages/docs/src/components/header/header.tsx +++ b/packages/docs/src/components/header/header.tsx @@ -1,5 +1,6 @@ -import { useLocation } from '@builder.io/qwik-city'; -import { component$, useStyles$, useContext, useVisibleTask$ } from '@builder.io/qwik'; +import { component$, useContext, useStyles$, useVisibleTask$ } from '@qwik.dev/core'; +import { useLocation } from '@qwik.dev/router'; +import { GlobalStore } from '../../context'; import { DocSearch } from '../docsearch/doc-search'; import { CloseIcon } from '../svgs/close-icon'; import { DiscordLogo } from '../svgs/discord-logo'; @@ -7,14 +8,13 @@ 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 styles from './header.css?inline'; export const Header = component$(() => { useStyles$(styles); 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 58971bb81ce..b08b925d2af 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,12 +1,12 @@ -import { useContent, useLocation } from '@builder.io/qwik-city'; -import { component$, useContext, $, useStyles$, useOnDocument, useSignal } from '@builder.io/qwik'; +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'; +import { EditIcon } from '../svgs/edit-icon'; import { GithubLogo } from '../svgs/github-logo'; import { TwitterLogo } from '../svgs/twitter-logo'; import styles from './on-this-page.css?inline'; -import { EditIcon } from '../svgs/edit-icon'; -import { GlobalStore } from '../../context'; -import { AlertIcon } from '../svgs/alert-icon'; const QWIK_GROUP = [ 'components', @@ -30,7 +30,7 @@ const QWIK_ADVANCED_GROUP = [ 'vite', ]; -const QWIKCITY_GROUP = [ +const QWIKROUTER_GROUP = [ 'action', 'api', 'caching', @@ -42,14 +42,14 @@ const QWIKCITY_GROUP = [ 'middleware', 'pages', 'project-structure', - 'qwikcity', + 'qwikrouter', 'route-loader', 'routing', 'server$', 'troubleshooting', 'validator', ]; -const QWIKCITY_ADVANCED_GROUP = [ +const QWIKROUTER_ADVANCED_GROUP = [ 'content-security-policy', 'menu', 'request-handling', @@ -68,13 +68,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 caff0d98e2c..8cbea051ff6 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 b11009e684e..7bee671db10 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'; @@ -91,8 +91,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 2b6cbcff8ce..3a195f63e57 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/build'; +// import { isBrowser } from '@builder.io/qwik'; 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 a1fc65fc29d..c344efc897d 100644 --- a/packages/docs/src/components/router-head/router-head.tsx +++ b/packages/docs/src/components/router-head/router-head.tsx @@ -1,9 +1,9 @@ /* eslint-disable no-console */ -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..fe53a2aac02 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 { type ContentMenu, routeLoader$, useContent, useLocation } 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/discord-logo.tsx b/packages/docs/src/components/svgs/discord-logo.tsx index a550600ffbc..a75405d6e37 100644 --- a/packages/docs/src/components/svgs/discord-logo.tsx +++ b/packages/docs/src/components/svgs/discord-logo.tsx @@ -1,4 +1,4 @@ -import type { PropsOf } from '@builder.io/qwik'; +import type { PropsOf } from '@qwik.dev/core'; type DiscordLogoProps = { width: number; 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/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 b88f9909ae5..83c7cb93d75 100644 --- a/packages/docs/src/entry.ssr.tsx +++ b/packages/docs/src/entry.ssr.tsx @@ -1,5 +1,5 @@ -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) { 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 6ce706ac5f1..e246e8cf55e 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,18 +8,20 @@ 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 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 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 = ( @@ -41,6 +43,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}`; }; @@ -49,7 +56,8 @@ 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, 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 762ab5d0490..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/build'; // 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 4cdf156fba0..cfc20800ce4 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$, useSignal } from '@builder.io/qwik'; +import { $, component$, 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 5c2ba35c156..6909a098c68 100644 --- a/packages/docs/src/repl/repl-output-panel.tsx +++ b/packages/docs/src/repl/repl-output-panel.tsx @@ -1,4 +1,4 @@ -import { component$, useComputed$ } 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'; @@ -7,7 +7,9 @@ import { ReplTabButtons } from './repl-tab-buttons'; import type { ReplAppInput, ReplStore } from './types'; 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 clientBundlesNoCore = useComputed$(() => // Qwik Core is not interesting and is large, slowing down the UI store.clientBundles.filter((b) => !b.path.endsWith('qwikCore.js')) @@ -65,8 +67,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'; @@ -124,7 +126,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-symbols.tsx b/packages/docs/src/repl/repl-output-symbols.tsx index 47846d85e6e..8cc799aa310 100644 --- a/packages/docs/src/repl/repl-output-symbols.tsx +++ b/packages/docs/src/repl/repl-output-symbols.tsx @@ -1,6 +1,6 @@ -import type { TransformModule } from '@builder.io/qwik/optimizer'; +import { $, component$, useSignal } from '@qwik.dev/core'; +import type { TransformModule } from '@qwik.dev/core/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) => { diff --git a/packages/docs/src/repl/repl-output-update.ts b/packages/docs/src/repl/repl-output-update.ts index 1fe666a0dc6..8b8f23044f0 100644 --- a/packages/docs/src/repl/repl-output-update.ts +++ b/packages/docs/src/repl/repl-output-update.ts @@ -6,21 +6,35 @@ const deepUpdate = (prev: any, next: any) => { 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 key in prev) { + if (!(key in next)) { + delete prev[key]; + // deleting array elements doesn't change the length + prev.length--; + } + } + } else { + for (const key in prev) { + if (!(key in next)) { + delete prev[key]; + } } } }; export const updateReplOutput = async (store: ReplStore, result: ReplResult) => { - store.diagnostics = result.diagnostics; + deepUpdate(store.diagnostics, result.diagnostics); - if (store.diagnostics.length === 0) { - store.html = result.html; + if (result.diagnostics.length === 0) { + if (store.html !== result.html) { + store.html = result.html; + } deepUpdate(store.transformedModules, result.transformedModules); deepUpdate(store.clientBundles, result.clientBundles); deepUpdate(store.ssrModules, result.ssrModules); 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 eed2a554bc9..914ef896c96 100644 --- a/packages/docs/src/repl/repl-version.ts +++ b/packages/docs/src/repl/repl-version.ts @@ -4,7 +4,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( @@ -98,7 +98,7 @@ export const getReplVersion = async (version: string | undefined, offline: boole }); versions.unshift('bundled'); - if (!hasVersion || !version) { + if ((!offline && !hasVersion) || !version) { version = 'bundled'; } @@ -114,11 +114,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.tsx b/packages/docs/src/repl/repl.tsx index b68ad72f894..62e2b561da7 100644 --- a/packages/docs/src/repl/repl.tsx +++ b/packages/docs/src/repl/repl.tsx @@ -1,22 +1,22 @@ /* eslint-disable no-console */ 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/build'; +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); @@ -80,10 +80,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; @@ -170,9 +166,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`, @@ -182,7 +183,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 faebfa0524b..8a78d809b1b 100644 --- a/packages/docs/src/repl/types.ts +++ b/packages/docs/src/repl/types.ts @@ -1,10 +1,10 @@ +import type { NoSerialize } from '@qwik.dev/core'; import type { Diagnostic, QwikManifest, QwikRollupPluginOptions, TransformModule, -} from '@builder.io/qwik/optimizer'; -import type { NoSerialize } from '@builder.io/qwik'; +} from '@qwik.dev/core/optimizer'; export interface ReplAppInput { buildId: number; @@ -129,3 +129,7 @@ export type OutputPanel = | 'diagnostics'; export type OutputDetail = 'options' | 'console'; + +export interface PathInView { + selectedPath: string; +} diff --git a/packages/docs/src/repl/worker/app-bundle-client.ts b/packages/docs/src/repl/worker/app-bundle-client.ts index 6bc1dcbd5a1..def68d27088 100644 --- a/packages/docs/src/repl/worker/app-bundle-client.ts +++ b/packages/docs/src/repl/worker/app-bundle-client.ts @@ -1,9 +1,9 @@ /* eslint-disable no-console */ +import type { Diagnostic, QwikRollupPluginOptions } from '@qwik.dev/core/optimizer'; import type { InputOptions, OutputAsset, OutputChunk } from 'rollup'; -import type { Diagnostic, QwikRollupPluginOptions } from '@builder.io/qwik/optimizer'; import type { ReplInputOptions, ReplModuleOutput, ReplResult } from '../types'; -import type { QwikWorkerGlobal } from './repl-service-worker'; import { replCss, replMinify, replResolver } from './repl-plugins'; +import type { QwikWorkerGlobal } from './repl-service-worker'; export const appBundleClient = async ( options: ReplInputOptions, diff --git a/packages/docs/src/repl/worker/app-bundle-ssr.ts b/packages/docs/src/repl/worker/app-bundle-ssr.ts index 9da8b1bfc8b..33d08b9f6ae 100644 --- a/packages/docs/src/repl/worker/app-bundle-ssr.ts +++ b/packages/docs/src/repl/worker/app-bundle-ssr.ts @@ -1,9 +1,9 @@ /* eslint-disable no-console */ +import type { Diagnostic, QwikRollupPluginOptions } from '@qwik.dev/core/optimizer'; import type { InputOptions } from 'rollup'; -import type { Diagnostic, QwikRollupPluginOptions } from '@builder.io/qwik/optimizer'; import type { ReplInputOptions, ReplResult } from '../types'; -import { replCss, replResolver } from './repl-plugins'; import { getInputs, getOutput } from './app-bundle-client'; +import { replCss, replResolver } from './repl-plugins'; import type { QwikWorkerGlobal } from './repl-service-worker'; export const appBundleSsr = async (options: ReplInputOptions, result: ReplResult) => { diff --git a/packages/docs/src/repl/worker/app-ssr-html.ts b/packages/docs/src/repl/worker/app-ssr-html.ts index 9804c37427c..dda20e63b34 100644 --- a/packages/docs/src/repl/worker/app-ssr-html.ts +++ b/packages/docs/src/repl/worker/app-ssr-html.ts @@ -1,5 +1,5 @@ /* eslint-disable no-console */ -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'; 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 63a00210de0..9e5df826202 100644 --- a/packages/docs/src/repl/worker/repl-dependencies.ts +++ b/packages/docs/src/repl/worker/repl-dependencies.ts @@ -1,20 +1,27 @@ /* eslint-disable no-console */ 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')) { + 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}`); } @@ -73,27 +80,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 2e9cd574f9a..614149224e2 100644 --- a/packages/docs/src/repl/worker/repl-plugins.ts +++ b/packages/docs/src/repl/worker/repl-plugins.ts @@ -1,9 +1,9 @@ +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'; export const replResolver = (options: ReplInputOptions, buildMode: 'client' | 'ssr'): Plugin => { const srcInputs = options.srcInputs; @@ -19,15 +19,16 @@ 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'; + const match = id.match(/(@builder\.io\/qwik|@qwik\.dev\/core)(.*)/); + if (match) { + const pkgPath = match[2]; + if (pkgPath === '/server') { + return '\0qwikServer'; + } + if (/^(|\/jsx(-dev)?-runtime)$/.test(pkgPath)) { + return '\0qwikCore'; + } + console.error(`Unknown package ${id}`, match); } // Simple relative file resolution if (id.startsWith('./')) { @@ -57,13 +58,13 @@ export const replResolver = (options: ReplInputOptions, buildMode: 'client' | 's } if (id === '\0qwikCore') { 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(); } diff --git a/packages/docs/src/repl/worker/repl-request-handler.ts b/packages/docs/src/repl/worker/repl-request-handler.ts index 87555ce9138..4acadc0e0c1 100644 --- a/packages/docs/src/repl/worker/repl-request-handler.ts +++ b/packages/docs/src/repl/worker/repl-request-handler.ts @@ -169,5 +169,5 @@ const injectDevHtml = (clientId: string, html?: string) => { }, true); })();`; - return `${html || ''}`; + return `${html || ''}`; }; diff --git a/packages/docs/src/repl/worker/repl-server.ts b/packages/docs/src/repl/worker/repl-server.ts index 460c703b007..526aab3b0fa 100644 --- a/packages/docs/src/repl/worker/repl-server.ts +++ b/packages/docs/src/repl/worker/repl-server.ts @@ -82,9 +82,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 1c53352dcc5..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/build'); - 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 7e3274e1710..a2157ff3cb8 100644 --- a/packages/docs/src/root.tsx +++ b/packages/docs/src/root.tsx @@ -1,11 +1,11 @@ -import { component$, useContextProvider, useStore } from '@builder.io/qwik'; -import { QwikCityProvider, RouterOutlet, ServiceWorkerRegister } from '@builder.io/qwik-city'; +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'; import { GlobalStore, type SiteStore } from './context'; import './global.css'; -import { BUILDER_PUBLIC_API_KEY } from './constants'; -import { Insights } from '@builder.io/qwik-labs'; export const uwu = /*javascript*/ ` ;(function () { @@ -50,7 +50,7 @@ export default component$(() => { useContextProvider(GlobalStore, store); return ( - + \n```\nBy default, the `prefetchEvent` implementation will be set to `always`.\n\n\n\n\n\n[workerFetchInsert?](#)\n\n\n\n\n\n\n\n'always' \\| 'no-link-support' \\| null\n\n\n\n\n_(Optional)_ `always`: Always include the worker fetch JS runtime.\n\n`no-link-support`: Only include the worker fetch JS runtime when the browser doesn't support `` prefetch/preload/modulepreload.\n\n\n\n", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.prefetchimplementation.md" + "mdFile": "core.prefetchimplementation.md" }, { "name": "PrefetchResource", @@ -98,7 +98,7 @@ "kind": "Interface", "content": "```typescript\nexport interface PrefetchResource \n```\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[imports](#)\n\n\n\n\n\n\n\n[PrefetchResource](#prefetchresource)\\[\\]\n\n\n\n\n\n
\n\n[url](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.prefetchresource.md" + "mdFile": "core.prefetchresource.md" }, { "name": "PrefetchStrategy", @@ -112,7 +112,7 @@ "kind": "Interface", "content": "```typescript\nexport interface PrefetchStrategy \n```\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[implementation?](#)\n\n\n\n\n\n\n\n[PrefetchImplementation](#prefetchimplementation)\n\n\n\n\n_(Optional)_\n\n\n
\n\n[symbolsToPrefetch?](#)\n\n\n\n\n\n\n\n[SymbolsToPrefetch](#symbolstoprefetch)\n\n\n\n\n_(Optional)_\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.prefetchstrategy.md" + "mdFile": "core.prefetchstrategy.md" }, { "name": "QwikLoaderOptions", @@ -126,7 +126,7 @@ "kind": "Interface", "content": "```typescript\nexport interface QwikLoaderOptions \n```\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[include?](#)\n\n\n\n\n\n\n\n'always' \\| 'never' \\| 'auto'\n\n\n\n\n_(Optional)_\n\n\n
\n\n[position?](#)\n\n\n\n\n\n\n\n'top' \\| 'bottom'\n\n\n\n\n_(Optional)_\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.qwikloaderoptions.md" + "mdFile": "core.qwikloaderoptions.md" }, { "name": "Render", @@ -140,7 +140,7 @@ "kind": "TypeAlias", "content": "```typescript\nexport type Render = RenderToString | RenderToStream;\n```\n**References:** [RenderToString](#rendertostring), [RenderToStream](#rendertostream)", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.render.md" + "mdFile": "core.render.md" }, { "name": "RenderOptions", @@ -154,7 +154,7 @@ "kind": "Interface", "content": "```typescript\nexport interface RenderOptions extends SerializeDocumentOptions \n```\n**Extends:** [SerializeDocumentOptions](#serializedocumentoptions)\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[base?](#)\n\n\n\n\n\n\n\nstring \\| ((options: [RenderOptions](#renderoptions)) => string)\n\n\n\n\n_(Optional)_ Specifies the root of the JS files of the client build. Setting a base, will cause the render of the `q:base` attribute in the `q:container` element.\n\n\n
\n\n[containerAttributes?](#)\n\n\n\n\n\n\n\nRecord<string, string>\n\n\n\n\n_(Optional)_\n\n\n
\n\n[containerTagName?](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n_(Optional)_ When set, the app is serialized into a fragment. And the returned html is not a complete document. Defaults to `html`\n\n\n
\n\n[locale?](#)\n\n\n\n\n\n\n\nstring \\| ((options: [RenderOptions](#renderoptions)) => string)\n\n\n\n\n_(Optional)_ Language to use when rendering the document.\n\n\n
\n\n[prefetchStrategy?](#)\n\n\n\n\n\n\n\n[PrefetchStrategy](#prefetchstrategy) \\| null\n\n\n\n\n_(Optional)_\n\n\n
\n\n[qwikLoader?](#)\n\n\n\n\n\n\n\n[QwikLoaderOptions](#qwikloaderoptions)\n\n\n\n\n_(Optional)_ Specifies if the Qwik Loader script is added to the document or not.\n\nDefaults to `{ include: true }`.\n\n\n
\n\n[qwikPrefetchServiceWorker?](#)\n\n\n\n\n\n\n\nQwikPrefetchServiceWorkerOptions\n\n\n\n\n_(Optional)_ Specifies if the Qwik Prefetch Service Worker script is added to the document or not.\n\nDefaults to `{ include: false }`. NOTE: This may be change in the future.\n\n\n
\n\n[serverData?](#)\n\n\n\n\n\n\n\nRecord<string, any>\n\n\n\n\n_(Optional)_\n\n\n
\n\n[snapshot?](#)\n\n\n\n\n\n\n\nboolean\n\n\n\n\n_(Optional)_ Defaults to `true`\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.renderoptions.md" + "mdFile": "core.renderoptions.md" }, { "name": "RenderResult", @@ -168,7 +168,7 @@ "kind": "Interface", "content": "```typescript\nexport interface RenderResult \n```\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[isStatic](#)\n\n\n\n\n\n\n\nboolean\n\n\n\n\n\n
\n\n[manifest?](#)\n\n\n\n\n\n\n\nQwikManifest\n\n\n\n\n_(Optional)_\n\n\n
\n\n[prefetchResources](#)\n\n\n\n\n\n\n\n[PrefetchResource](#prefetchresource)\\[\\]\n\n\n\n\n\n
\n\n[snapshotResult](#)\n\n\n\n\n\n\n\nSnapshotResult \\| undefined\n\n\n\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.renderresult.md" + "mdFile": "core.renderresult.md" }, { "name": "renderToStream", @@ -181,8 +181,8 @@ ], "kind": "Function", "content": "```typescript\nexport type RenderToStream = (opts: RenderToStreamOptions) => Promise;\n```\n**References:** [RenderToStreamOptions](#rendertostreamoptions), [RenderToStreamResult](#rendertostreamresult)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/render.ts", - "mdFile": "qwik.rendertostream.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/ssr-render.ts", + "mdFile": "core.rendertostream.md" }, { "name": "RenderToStream", @@ -196,7 +196,7 @@ "kind": "TypeAlias", "content": "```typescript\nexport type RenderToStream = (opts: RenderToStreamOptions) => Promise;\n```\n**References:** [RenderToStreamOptions](#rendertostreamoptions), [RenderToStreamResult](#rendertostreamresult)", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.rendertostream.md" + "mdFile": "core.rendertostream.md" }, { "name": "RenderToStreamOptions", @@ -210,7 +210,7 @@ "kind": "Interface", "content": "```typescript\nexport interface RenderToStreamOptions extends RenderOptions \n```\n**Extends:** [RenderOptions](#renderoptions)\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[stream](#)\n\n\n\n\n\n\n\nStreamWriter\n\n\n\n\n\n
\n\n[streaming?](#)\n\n\n\n\n\n\n\n[StreamingOptions](#streamingoptions)\n\n\n\n\n_(Optional)_\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.rendertostreamoptions.md" + "mdFile": "core.rendertostreamoptions.md" }, { "name": "RenderToStreamResult", @@ -224,7 +224,7 @@ "kind": "Interface", "content": "```typescript\nexport interface RenderToStreamResult extends RenderResult \n```\n**Extends:** [RenderResult](#renderresult)\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[flushes](#)\n\n\n\n\n\n\n\nnumber\n\n\n\n\n\n
\n\n[size](#)\n\n\n\n\n\n\n\nnumber\n\n\n\n\n\n
\n\n[timing](#)\n\n\n\n\n\n\n\n{ firstFlush: number; render: number; snapshot: number; }\n\n\n\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.rendertostreamresult.md" + "mdFile": "core.rendertostreamresult.md" }, { "name": "renderToString", @@ -237,8 +237,8 @@ ], "kind": "Function", "content": "```typescript\nexport type RenderToString = (opts: RenderToStringOptions) => Promise;\n```\n**References:** [RenderToStringOptions](#rendertostringoptions), [RenderToStringResult](#rendertostringresult)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/render.ts", - "mdFile": "qwik.rendertostring.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/ssr-render.ts", + "mdFile": "core.rendertostring.md" }, { "name": "RenderToString", @@ -252,7 +252,7 @@ "kind": "TypeAlias", "content": "```typescript\nexport type RenderToString = (opts: RenderToStringOptions) => Promise;\n```\n**References:** [RenderToStringOptions](#rendertostringoptions), [RenderToStringResult](#rendertostringresult)", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.rendertostring.md" + "mdFile": "core.rendertostring.md" }, { "name": "RenderToStringOptions", @@ -266,7 +266,7 @@ "kind": "Interface", "content": "```typescript\nexport interface RenderToStringOptions extends RenderOptions \n```\n**Extends:** [RenderOptions](#renderoptions)", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.rendertostringoptions.md" + "mdFile": "core.rendertostringoptions.md" }, { "name": "RenderToStringResult", @@ -278,9 +278,9 @@ } ], "kind": "Interface", - "content": "```typescript\nexport interface RenderToStringResult extends RenderResult \n```\n**Extends:** [RenderResult](#renderresult)\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[html](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n\n
\n\n[timing](#)\n\n\n\n\n\n\n\n{ render: number; snapshot: number; }\n\n\n\n\n\n
", + "content": "```typescript\nexport interface RenderToStringResult extends RenderResult \n```\n**Extends:** [RenderResult](#renderresult)\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[html](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n\n
\n\n[timing](#)\n\n\n\n\n\n\n\n{ firstFlush: number; render: number; snapshot: number; }\n\n\n\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.rendertostringresult.md" + "mdFile": "core.rendertostringresult.md" }, { "name": "resolveManifest", @@ -293,8 +293,8 @@ ], "kind": "Function", "content": "```typescript\nexport declare function resolveManifest(manifest: QwikManifest | ResolvedManifest | undefined): ResolvedManifest | undefined;\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nmanifest\n\n\n\n\nQwikManifest \\| ResolvedManifest \\| undefined\n\n\n\n\n\n
\n**Returns:**\n\nResolvedManifest \\| undefined", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/render.ts", - "mdFile": "qwik.resolvemanifest.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/ssr-render.ts", + "mdFile": "core.resolvemanifest.md" }, { "name": "SerializeDocumentOptions", @@ -308,7 +308,7 @@ "kind": "Interface", "content": "```typescript\nexport interface SerializeDocumentOptions \n```\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[debug?](#)\n\n\n\n\n\n\n\nboolean\n\n\n\n\n_(Optional)_\n\n\n
\n\n[manifest?](#)\n\n\n\n\n\n\n\nQwikManifest \\| ResolvedManifest\n\n\n\n\n_(Optional)_\n\n\n
\n\n[symbolMapper?](#)\n\n\n\n\n\n\n\nSymbolMapperFn\n\n\n\n\n_(Optional)_\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.serializedocumentoptions.md" + "mdFile": "core.serializedocumentoptions.md" }, { "name": "setServerPlatform", @@ -322,7 +322,7 @@ "kind": "Function", "content": "```typescript\nexport declare function setServerPlatform(manifest: QwikManifest | ResolvedManifest | undefined): Promise;\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nmanifest\n\n\n\n\nQwikManifest \\| ResolvedManifest \\| undefined\n\n\n\n\n\n
\n**Returns:**\n\nPromise<void>", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/index.ts", - "mdFile": "qwik.setserverplatform.md" + "mdFile": "core.setserverplatform.md" }, { "name": "StreamingOptions", @@ -336,7 +336,7 @@ "kind": "Interface", "content": "```typescript\nexport interface StreamingOptions \n```\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[inOrder?](#)\n\n\n\n\n\n\n\n[InOrderStreaming](#inorderstreaming)\n\n\n\n\n_(Optional)_\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.streamingoptions.md" + "mdFile": "core.streamingoptions.md" }, { "name": "SymbolsToPrefetch", @@ -350,7 +350,7 @@ "kind": "TypeAlias", "content": "Auto: Prefetch all possible QRLs used by the document. Default\n\n\n```typescript\nexport type SymbolsToPrefetch = 'auto' | ((opts: {\n manifest: QwikManifest;\n}) => PrefetchResource[]);\n```\n**References:** [PrefetchResource](#prefetchresource)", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/types.ts", - "mdFile": "qwik.symbolstoprefetch.md" + "mdFile": "core.symbolstoprefetch.md" }, { "name": "versions", @@ -364,7 +364,7 @@ "kind": "Variable", "content": "```typescript\nversions: {\n readonly qwik: string;\n readonly qwikDom: string;\n}\n```", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/utils.ts", - "mdFile": "qwik.versions.md" + "mdFile": "core.versions.md" } ] } \ No newline at end of file diff --git a/packages/docs/src/routes/api/qwik-server/index.md b/packages/docs/src/routes/api/qwik-server/index.md index 819658c38ec..fed33f87e83 100644 --- a/packages/docs/src/routes/api/qwik-server/index.md +++ b/packages/docs/src/routes/api/qwik-server/index.md @@ -1,8 +1,8 @@ --- -title: \@builder.io/qwik/server API Reference +title: \@qwik.dev/qwik/server API Reference --- -# [API](/api) › @builder.io/qwik/server +# [API](/api) › @qwik.dev/qwik/server ## getQwikLoaderScript @@ -113,7 +113,7 @@ Description -[maximunChunk?](#) +[maximumChunk?](#) @@ -128,7 +128,7 @@ _(Optional)_ -[maximunInitialChunk?](#) +[maximumInitialChunk?](#) @@ -760,7 +760,7 @@ export type RenderToStream = ( **References:** [RenderToStreamOptions](#rendertostreamoptions), [RenderToStreamResult](#rendertostreamresult) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/render.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/ssr-render.ts) ## RenderToStream @@ -909,7 +909,7 @@ export type RenderToString = ( **References:** [RenderToStringOptions](#rendertostringoptions), [RenderToStringResult](#rendertostringresult) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/render.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/ssr-render.ts) ## RenderToString @@ -979,7 +979,7 @@ string -{ render: number; snapshot: number; } +{ firstFlush: number; render: number; snapshot: number; } @@ -1025,7 +1025,7 @@ QwikManifest \| ResolvedManifest \| undefined ResolvedManifest \| undefined -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/render.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/server/ssr-render.ts) ## SerializeDocumentOptions diff --git a/packages/docs/src/routes/api/qwik-testing/api.json b/packages/docs/src/routes/api/qwik-testing/api.json index 9ebb48c90c5..6655a5bf60d 100644 --- a/packages/docs/src/routes/api/qwik-testing/api.json +++ b/packages/docs/src/routes/api/qwik-testing/api.json @@ -1,7 +1,38 @@ { "id": "qwik-testing", - "package": "@builder.io/qwik/testing", + "package": "@qwik.dev/qwik/testing", "members": [ + { + "name": "child", + "id": "elementfixture-child", + "hierarchy": [ + { + "name": "ElementFixture", + "id": "elementfixture-child" + }, + { + "name": "child", + "id": "elementfixture-child" + } + ], + "kind": "Property", + "content": "```typescript\nchild: HTMLElement;\n```", + "mdFile": "core.elementfixture.child.md" + }, + { + "name": "createDocument", + "id": "createdocument", + "hierarchy": [ + { + "name": "createDocument", + "id": "createdocument" + } + ], + "kind": "Function", + "content": "Create emulated `Document` for server environment. Does not implement the full browser `document` and `window` API. This api may be removed in the future.\n\n\n```typescript\nexport declare function createDocument(opts?: MockDocumentOptions): Document;\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nopts\n\n\n\n\nMockDocumentOptions\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nDocument", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/document.ts", + "mdFile": "core.createdocument.md" + }, { "name": "createDOM", "id": "createdom", @@ -12,9 +43,220 @@ } ], "kind": "Function", - "content": "CreatePlatform and CreateDocument\n\n\n```typescript\ncreateDOM: ({ html }?: {\n html?: string;\n}) => Promise<{\n render: (jsxElement: JSXOutput) => Promise;\n screen: HTMLElement;\n userEvent: (queryOrElement: string | Element | keyof HTMLElementTagNameMap | null, eventNameCamel: string | keyof WindowEventMap, eventPayload?: any) => Promise;\n}>\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n{ html }\n\n\n\n\n{ html?: string; }\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nPromise<{ render: (jsxElement: JSXOutput) => Promise<import(\"@builder.io/qwik\").RenderResult>; screen: HTMLElement; userEvent: (queryOrElement: string \\| Element \\| keyof HTMLElementTagNameMap \\| null, eventNameCamel: string \\| keyof WindowEventMap, eventPayload?: any) => Promise<void>; }>", + "content": "CreatePlatform and CreateDocument\n\n\n```typescript\ncreateDOM: ({ html }?: {\n html?: string;\n}) => Promise<{\n render: (jsxElement: JSXOutput) => Promise;\n screen: HTMLElement;\n userEvent: (queryOrElement: string | Element | keyof HTMLElementTagNameMap | null, eventNameCamel: string | keyof WindowEventMap, eventPayload?: any) => Promise;\n}>\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n{ html }\n\n\n\n\n{ html?: string; }\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nPromise<{ render: (jsxElement: JSXOutput) => Promise<import(\"@qwik.dev/core\").RenderResult>; screen: HTMLElement; userEvent: (queryOrElement: string \\| Element \\| keyof HTMLElementTagNameMap \\| null, eventNameCamel: string \\| keyof WindowEventMap, eventPayload?: any) => Promise<void>; }>", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/library.ts", - "mdFile": "qwik.createdom.md" + "mdFile": "core.createdom.md" + }, + { + "name": "document", + "id": "elementfixture-document", + "hierarchy": [ + { + "name": "ElementFixture", + "id": "elementfixture-document" + }, + { + "name": "document", + "id": "elementfixture-document" + } + ], + "kind": "Property", + "content": "```typescript\ndocument: MockDocument;\n```", + "mdFile": "core.elementfixture.document.md" + }, + { + "name": "domRender", + "id": "domrender", + "hierarchy": [ + { + "name": "domRender", + "id": "domrender" + } + ], + "kind": "Function", + "content": "```typescript\nexport declare function domRender(jsx: JSXOutput, opts?: {\n debug?: boolean;\n}): Promise<{\n document: Document;\n container: import(\"@qwik.dev/core/internal\").ClientContainer;\n vNode: _VNode | null;\n getStyles: () => Record;\n}>;\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\njsx\n\n\n\n\nJSXOutput\n\n\n\n\n\n
\n\nopts\n\n\n\n\n{ debug?: boolean; }\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nPromise<{ document: Document; container: import(\"@qwik.dev/core/internal\").ClientContainer; vNode: \\_VNode \\| null; getStyles: () => Record<string, string \\| string\\[\\]>; }>", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/rendering.unit-util.tsx", + "mdFile": "core.domrender.md" + }, + { + "name": "ElementFixture", + "id": "elementfixture", + "hierarchy": [ + { + "name": "ElementFixture", + "id": "elementfixture" + } + ], + "kind": "Class", + "content": "Creates a simple DOM structure for testing components.\n\nBy default `EntityFixture` creates:\n\n```html\n\n \n\n```\n\n\n```typescript\nexport declare class ElementFixture \n```\n\n\n\n\n
\n\nConstructor\n\n\n\n\nModifiers\n\n\n\n\nDescription\n\n\n
\n\n[(constructor)(options)](#)\n\n\n\n\n\n\n\nConstructs a new instance of the `ElementFixture` class\n\n\n
\n\n\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[child](#elementfixture-child)\n\n\n\n\n\n\n\nHTMLElement\n\n\n\n\n\n
\n\n[document](#elementfixture-document)\n\n\n\n\n\n\n\nMockDocument\n\n\n\n\n\n
\n\n[host](#elementfixture-host)\n\n\n\n\n\n\n\nHTMLElement\n\n\n\n\n\n
\n\n[parent](#elementfixture-parent)\n\n\n\n\n\n\n\nHTMLElement\n\n\n\n\n\n
\n\n[superParent](#elementfixture-superparent)\n\n\n\n\n\n\n\nHTMLElement\n\n\n\n\n\n
\n\n[window](#elementfixture-window)\n\n\n\n\n\n\n\nMockWindow\n\n\n\n\n\n
", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/element-fixture.ts", + "mdFile": "core.elementfixture.md" + }, + { + "name": "emulateExecutionOfQwikFuncs", + "id": "emulateexecutionofqwikfuncs", + "hierarchy": [ + { + "name": "emulateExecutionOfQwikFuncs", + "id": "emulateexecutionofqwikfuncs" + } + ], + "kind": "Function", + "content": "```typescript\nexport declare function emulateExecutionOfQwikFuncs(document: Document): void;\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\ndocument\n\n\n\n\nDocument\n\n\n\n\n\n
\n**Returns:**\n\nvoid", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/rendering.unit-util.tsx", + "mdFile": "core.emulateexecutionofqwikfuncs.md" + }, + { + "name": "expectDOM", + "id": "expectdom", + "hierarchy": [ + { + "name": "expectDOM", + "id": "expectdom" + } + ], + "kind": "Function", + "content": "```typescript\nexport declare function expectDOM(actual: Element, expected: string): Promise;\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nactual\n\n\n\n\nElement\n\n\n\n\n\n
\n\nexpected\n\n\n\n\nstring\n\n\n\n\n\n
\n**Returns:**\n\nPromise<void>", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/expect-dom.tsx", + "mdFile": "core.expectdom.md" + }, + { + "name": "getTestPlatform", + "id": "gettestplatform", + "hierarchy": [ + { + "name": "getTestPlatform", + "id": "gettestplatform" + } + ], + "kind": "Function", + "content": "```typescript\nexport declare function getTestPlatform(): TestPlatform;\n```\n**Returns:**\n\nTestPlatform", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/platform.ts", + "mdFile": "core.gettestplatform.md" + }, + { + "name": "host", + "id": "elementfixture-host", + "hierarchy": [ + { + "name": "ElementFixture", + "id": "elementfixture-host" + }, + { + "name": "host", + "id": "elementfixture-host" + } + ], + "kind": "Property", + "content": "```typescript\nhost: HTMLElement;\n```", + "mdFile": "core.elementfixture.host.md" + }, + { + "name": "parent", + "id": "elementfixture-parent", + "hierarchy": [ + { + "name": "ElementFixture", + "id": "elementfixture-parent" + }, + { + "name": "parent", + "id": "elementfixture-parent" + } + ], + "kind": "Property", + "content": "```typescript\nparent: HTMLElement;\n```", + "mdFile": "core.elementfixture.parent.md" + }, + { + "name": "ssrRenderToDom", + "id": "ssrrendertodom", + "hierarchy": [ + { + "name": "ssrRenderToDom", + "id": "ssrrendertodom" + } + ], + "kind": "Function", + "content": "```typescript\nexport declare function ssrRenderToDom(jsx: JSXOutput, opts?: {\n debug?: boolean;\n raw?: boolean;\n}): Promise<{\n container: _DomContainer;\n document: Document;\n vNode: _VirtualVNode | null;\n getStyles: () => Record;\n}>;\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\njsx\n\n\n\n\nJSXOutput\n\n\n\n\n\n
\n\nopts\n\n\n\n\n{ debug?: boolean; raw?: boolean; }\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nPromise<{ container: \\_DomContainer; document: Document; vNode: \\_VirtualVNode \\| null; getStyles: () => Record<string, string \\| string\\[\\]>; }>", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/rendering.unit-util.tsx", + "mdFile": "core.ssrrendertodom.md" + }, + { + "name": "superParent", + "id": "elementfixture-superparent", + "hierarchy": [ + { + "name": "ElementFixture", + "id": "elementfixture-superparent" + }, + { + "name": "superParent", + "id": "elementfixture-superparent" + } + ], + "kind": "Property", + "content": "```typescript\nsuperParent: HTMLElement;\n```", + "mdFile": "core.elementfixture.superparent.md" + }, + { + "name": "trigger", + "id": "trigger", + "hierarchy": [ + { + "name": "trigger", + "id": "trigger" + } + ], + "kind": "Function", + "content": "Trigger an event in unit tests on an element.\n\nFuture deprecation candidate.\n\n\n```typescript\nexport declare function trigger(root: Element, queryOrElement: string | Element | keyof HTMLElementTagNameMap | null, eventNameCamel: string, eventPayload?: any): Promise;\n```\n\n\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nroot\n\n\n\n\nElement\n\n\n\n\n\n
\n\nqueryOrElement\n\n\n\n\nstring \\| Element \\| keyof HTMLElementTagNameMap \\| null\n\n\n\n\n\n
\n\neventNameCamel\n\n\n\n\nstring\n\n\n\n\n\n
\n\neventPayload\n\n\n\n\nany\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nPromise<void>", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/element-fixture.ts", + "mdFile": "core.trigger.md" + }, + { + "name": "vnode_fromJSX", + "id": "vnode_fromjsx", + "hierarchy": [ + { + "name": "vnode_fromJSX", + "id": "vnode_fromjsx" + } + ], + "kind": "Function", + "content": "```typescript\nexport declare function vnode_fromJSX(jsx: JSXOutput): {\n vParent: _ElementVNode;\n vNode: _VNode | null;\n document: _QDocument;\n};\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\njsx\n\n\n\n\nJSXOutput\n\n\n\n\n\n
\n**Returns:**\n\n{ vParent: \\_ElementVNode; vNode: \\_VNode \\| null; document: \\_QDocument; }", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/vdom-diff.unit-util.ts", + "mdFile": "core.vnode_fromjsx.md" + }, + { + "name": "walkJSX", + "id": "walkjsx", + "hierarchy": [ + { + "name": "walkJSX", + "id": "walkjsx" + } + ], + "kind": "Function", + "content": "```typescript\nexport declare function walkJSX(jsx: JSXOutput, apply: {\n enter: (jsx: JSXNodeInternal) => void;\n leave: (jsx: JSXNodeInternal) => void;\n text: (text: _Stringifiable) => void;\n}): void;\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\njsx\n\n\n\n\nJSXOutput\n\n\n\n\n\n
\n\napply\n\n\n\n\n{ enter: (jsx: JSXNodeInternal) => void; leave: (jsx: JSXNodeInternal) => void; text: (text: \\_Stringifiable) => void; }\n\n\n\n\n\n
\n**Returns:**\n\nvoid", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/vdom-diff.unit-util.ts", + "mdFile": "core.walkjsx.md" + }, + { + "name": "window", + "id": "elementfixture-window", + "hierarchy": [ + { + "name": "ElementFixture", + "id": "elementfixture-window" + }, + { + "name": "window", + "id": "elementfixture-window" + } + ], + "kind": "Property", + "content": "```typescript\nwindow: MockWindow;\n```", + "mdFile": "core.elementfixture.window.md" } ] } \ No newline at end of file diff --git a/packages/docs/src/routes/api/qwik-testing/index.md b/packages/docs/src/routes/api/qwik-testing/index.md index b10e643b21e..b8b4645fa0f 100644 --- a/packages/docs/src/routes/api/qwik-testing/index.md +++ b/packages/docs/src/routes/api/qwik-testing/index.md @@ -1,8 +1,55 @@ --- -title: \@builder.io/qwik/testing API Reference +title: \@qwik.dev/qwik/testing API Reference --- -# [API](/api) › @builder.io/qwik/testing +# [API](/api) › @qwik.dev/qwik/testing + +## child + +```typescript +child: HTMLElement; +``` + +## createDocument + +Create emulated `Document` for server environment. Does not implement the full browser `document` and `window` API. This api may be removed in the future. + +```typescript +export declare function createDocument(opts?: MockDocumentOptions): Document; +``` + + + +
+ +Parameter + + + +Type + + + +Description + +
+ +opts + + + +MockDocumentOptions + + + +_(Optional)_ + +
+**Returns:** + +Document + +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/document.ts) ## createDOM @@ -13,7 +60,7 @@ createDOM: ({ html }?: { html?: string }) => Promise<{ render: ( jsxElement: JSXOutput, - ) => Promise; + ) => Promise; screen: HTMLElement; userEvent: ( queryOrElement: string | Element | keyof HTMLElementTagNameMap | null, @@ -52,6 +99,575 @@ _(Optional)_ **Returns:** -Promise<{ render: (jsxElement: JSXOutput) => Promise<import("@builder.io/qwik").RenderResult>; screen: HTMLElement; userEvent: (queryOrElement: string \| Element \| keyof HTMLElementTagNameMap \| null, eventNameCamel: string \| keyof WindowEventMap, eventPayload?: any) => Promise<void>; }> +Promise<{ render: (jsxElement: JSXOutput) => Promise<import("@qwik.dev/core").RenderResult>; screen: HTMLElement; userEvent: (queryOrElement: string \| Element \| keyof HTMLElementTagNameMap \| null, eventNameCamel: string \| keyof WindowEventMap, eventPayload?: any) => Promise<void>; }> [Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/library.ts) + +## document + +```typescript +document: MockDocument; +``` + +## domRender + +```typescript +export declare function domRender( + jsx: JSXOutput, + opts?: { + debug?: boolean; + }, +): Promise<{ + document: Document; + container: import("@qwik.dev/core/internal").ClientContainer; + vNode: _VNode | null; + getStyles: () => Record; +}>; +``` + + + + +
+ +Parameter + + + +Type + + + +Description + +
+ +jsx + + + +JSXOutput + + + +
+ +opts + + + +{ debug?: boolean; } + + + +_(Optional)_ + +
+**Returns:** + +Promise<{ document: Document; container: import("@qwik.dev/core/internal").ClientContainer; vNode: \_VNode \| null; getStyles: () => Record<string, string \| string[]>; }> + +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/rendering.unit-util.tsx) + +## ElementFixture + +Creates a simple DOM structure for testing components. + +By default `EntityFixture` creates: + +```html + + + +``` + +```typescript +export declare class ElementFixture +``` + + + +
+ +Constructor + + + +Modifiers + + + +Description + +
+ +[(constructor)(options)](#) + + + + + +Constructs a new instance of the `ElementFixture` class + +
+ + + + + + + + +
+ +Property + + + +Modifiers + + + +Type + + + +Description + +
+ +[child](#elementfixture-child) + + + + + +HTMLElement + + + +
+ +[document](#elementfixture-document) + + + + + +MockDocument + + + +
+ +[host](#elementfixture-host) + + + + + +HTMLElement + + + +
+ +[parent](#elementfixture-parent) + + + + + +HTMLElement + + + +
+ +[superParent](#elementfixture-superparent) + + + + + +HTMLElement + + + +
+ +[window](#elementfixture-window) + + + + + +MockWindow + + + +
+ +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/element-fixture.ts) + +## emulateExecutionOfQwikFuncs + +```typescript +export declare function emulateExecutionOfQwikFuncs(document: Document): void; +``` + + + +
+ +Parameter + + + +Type + + + +Description + +
+ +document + + + +Document + + + +
+**Returns:** + +void + +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/rendering.unit-util.tsx) + +## expectDOM + +```typescript +export declare function expectDOM( + actual: Element, + expected: string, +): Promise; +``` + + + + +
+ +Parameter + + + +Type + + + +Description + +
+ +actual + + + +Element + + + +
+ +expected + + + +string + + + +
+**Returns:** + +Promise<void> + +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/expect-dom.tsx) + +## getTestPlatform + +```typescript +export declare function getTestPlatform(): TestPlatform; +``` + +**Returns:** + +TestPlatform + +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/platform.ts) + +## host + +```typescript +host: HTMLElement; +``` + +## parent + +```typescript +parent: HTMLElement; +``` + +## ssrRenderToDom + +```typescript +export declare function ssrRenderToDom( + jsx: JSXOutput, + opts?: { + debug?: boolean; + raw?: boolean; + }, +): Promise<{ + container: _DomContainer; + document: Document; + vNode: _VirtualVNode | null; + getStyles: () => Record; +}>; +``` + + + + +
+ +Parameter + + + +Type + + + +Description + +
+ +jsx + + + +JSXOutput + + + +
+ +opts + + + +{ debug?: boolean; raw?: boolean; } + + + +_(Optional)_ + +
+**Returns:** + +Promise<{ container: \_DomContainer; document: Document; vNode: \_VirtualVNode \| null; getStyles: () => Record<string, string \| string[]>; }> + +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/rendering.unit-util.tsx) + +## superParent + +```typescript +superParent: HTMLElement; +``` + +## trigger + +Trigger an event in unit tests on an element. + +Future deprecation candidate. + +```typescript +export declare function trigger( + root: Element, + queryOrElement: string | Element | keyof HTMLElementTagNameMap | null, + eventNameCamel: string, + eventPayload?: any, +): Promise; +``` + + + + + + +
+ +Parameter + + + +Type + + + +Description + +
+ +root + + + +Element + + + +
+ +queryOrElement + + + +string \| Element \| keyof HTMLElementTagNameMap \| null + + + +
+ +eventNameCamel + + + +string + + + +
+ +eventPayload + + + +any + + + +_(Optional)_ + +
+**Returns:** + +Promise<void> + +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/element-fixture.ts) + +## vnode_fromJSX + +```typescript +export declare function vnode_fromJSX(jsx: JSXOutput): { + vParent: _ElementVNode; + vNode: _VNode | null; + document: _QDocument; +}; +``` + + + +
+ +Parameter + + + +Type + + + +Description + +
+ +jsx + + + +JSXOutput + + + +
+**Returns:** + +{ vParent: \_ElementVNode; vNode: \_VNode \| null; document: \_QDocument; } + +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/vdom-diff.unit-util.ts) + +## walkJSX + +```typescript +export declare function walkJSX( + jsx: JSXOutput, + apply: { + enter: (jsx: JSXNodeInternal) => void; + leave: (jsx: JSXNodeInternal) => void; + text: (text: _Stringifiable) => void; + }, +): void; +``` + + + + +
+ +Parameter + + + +Type + + + +Description + +
+ +jsx + + + +JSXOutput + + + +
+ +apply + + + +{ enter: (jsx: JSXNodeInternal) => void; leave: (jsx: JSXNodeInternal) => void; text: (text: \_Stringifiable) => void; } + + + +
+**Returns:** + +void + +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/testing/vdom-diff.unit-util.ts) + +## window + +```typescript +window: MockWindow; +``` diff --git a/packages/docs/src/routes/api/qwik/api.json b/packages/docs/src/routes/api/qwik/api.json index b56d77dcc3c..3595bd3ec82 100644 --- a/packages/docs/src/routes/api/qwik/api.json +++ b/packages/docs/src/routes/api/qwik/api.json @@ -1,21 +1,7 @@ { "id": "qwik", - "package": "@builder.io/qwik", + "package": "@qwik.dev/qwik", "members": [ - { - "name": "_qrlSync", - "id": "_qrlsync", - "hierarchy": [ - { - "name": "_qrlSync", - "id": "_qrlsync" - } - ], - "kind": "Function", - "content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nExtract function into a synchronously loadable QRL.\n\nNOTE: Synchronous QRLs functions can't close over any variables, including exports.\n\n\n```typescript\n_qrlSync: (fn: TYPE, serializedFn?: string) => SyncQRL\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nfn\n\n\n\n\nTYPE\n\n\n\n\nExtracted function\n\n\n
\n\nserializedFn\n\n\n\n\nstring\n\n\n\n\n_(Optional)_ Serialized function in string form.\n\n\n
\n**Returns:**\n\n[SyncQRL](#syncqrl)<TYPE>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts", - "mdFile": "qwik._qrlsync.md" - }, { "name": "\"q:slot\"", "id": "componentbaseprops-_q_slot_", @@ -31,194 +17,7 @@ ], "kind": "PropertySignature", "content": "```typescript\n'q:slot'?: string;\n```", - "mdFile": "qwik.componentbaseprops._q_slot_.md" - }, - { - "name": "\"xlink:actuate\"", - "id": "svgattributes-_xlink_actuate_", - "hierarchy": [ - { - "name": "SVGAttributes", - "id": "svgattributes-_xlink_actuate_" - }, - { - "name": "\"xlink:actuate\"", - "id": "svgattributes-_xlink_actuate_" - } - ], - "kind": "PropertySignature", - "content": "```typescript\n'xlink:actuate'?: string | undefined;\n```", - "mdFile": "qwik.svgattributes._xlink_actuate_.md" - }, - { - "name": "\"xlink:arcrole\"", - "id": "svgattributes-_xlink_arcrole_", - "hierarchy": [ - { - "name": "SVGAttributes", - "id": "svgattributes-_xlink_arcrole_" - }, - { - "name": "\"xlink:arcrole\"", - "id": "svgattributes-_xlink_arcrole_" - } - ], - "kind": "PropertySignature", - "content": "```typescript\n'xlink:arcrole'?: string | undefined;\n```", - "mdFile": "qwik.svgattributes._xlink_arcrole_.md" - }, - { - "name": "\"xlink:href\"", - "id": "svgattributes-_xlink_href_", - "hierarchy": [ - { - "name": "SVGAttributes", - "id": "svgattributes-_xlink_href_" - }, - { - "name": "\"xlink:href\"", - "id": "svgattributes-_xlink_href_" - } - ], - "kind": "PropertySignature", - "content": "```typescript\n'xlink:href'?: string | undefined;\n```", - "mdFile": "qwik.svgattributes._xlink_href_.md" - }, - { - "name": "\"xlink:role\"", - "id": "svgattributes-_xlink_role_", - "hierarchy": [ - { - "name": "SVGAttributes", - "id": "svgattributes-_xlink_role_" - }, - { - "name": "\"xlink:role\"", - "id": "svgattributes-_xlink_role_" - } - ], - "kind": "PropertySignature", - "content": "```typescript\n'xlink:role'?: string | undefined;\n```", - "mdFile": "qwik.svgattributes._xlink_role_.md" - }, - { - "name": "\"xlink:show\"", - "id": "svgattributes-_xlink_show_", - "hierarchy": [ - { - "name": "SVGAttributes", - "id": "svgattributes-_xlink_show_" - }, - { - "name": "\"xlink:show\"", - "id": "svgattributes-_xlink_show_" - } - ], - "kind": "PropertySignature", - "content": "```typescript\n'xlink:show'?: string | undefined;\n```", - "mdFile": "qwik.svgattributes._xlink_show_.md" - }, - { - "name": "\"xlink:title\"", - "id": "svgattributes-_xlink_title_", - "hierarchy": [ - { - "name": "SVGAttributes", - "id": "svgattributes-_xlink_title_" - }, - { - "name": "\"xlink:title\"", - "id": "svgattributes-_xlink_title_" - } - ], - "kind": "PropertySignature", - "content": "```typescript\n'xlink:title'?: string | undefined;\n```", - "mdFile": "qwik.svgattributes._xlink_title_.md" - }, - { - "name": "\"xlink:type\"", - "id": "svgattributes-_xlink_type_", - "hierarchy": [ - { - "name": "SVGAttributes", - "id": "svgattributes-_xlink_type_" - }, - { - "name": "\"xlink:type\"", - "id": "svgattributes-_xlink_type_" - } - ], - "kind": "PropertySignature", - "content": "```typescript\n'xlink:type'?: string | undefined;\n```", - "mdFile": "qwik.svgattributes._xlink_type_.md" - }, - { - "name": "\"xml:base\"", - "id": "svgattributes-_xml_base_", - "hierarchy": [ - { - "name": "SVGAttributes", - "id": "svgattributes-_xml_base_" - }, - { - "name": "\"xml:base\"", - "id": "svgattributes-_xml_base_" - } - ], - "kind": "PropertySignature", - "content": "```typescript\n'xml:base'?: string | undefined;\n```", - "mdFile": "qwik.svgattributes._xml_base_.md" - }, - { - "name": "\"xml:lang\"", - "id": "svgattributes-_xml_lang_", - "hierarchy": [ - { - "name": "SVGAttributes", - "id": "svgattributes-_xml_lang_" - }, - { - "name": "\"xml:lang\"", - "id": "svgattributes-_xml_lang_" - } - ], - "kind": "PropertySignature", - "content": "```typescript\n'xml:lang'?: string | undefined;\n```", - "mdFile": "qwik.svgattributes._xml_lang_.md" - }, - { - "name": "\"xml:space\"", - "id": "svgattributes-_xml_space_", - "hierarchy": [ - { - "name": "SVGAttributes", - "id": "svgattributes-_xml_space_" - }, - { - "name": "\"xml:space\"", - "id": "svgattributes-_xml_space_" - } - ], - "kind": "PropertySignature", - "content": "```typescript\n'xml:space'?: string | undefined;\n```", - "mdFile": "qwik.svgattributes._xml_space_.md" - }, - { - "name": "\"xmlns:xlink\"", - "id": "svgattributes-_xmlns_xlink_", - "hierarchy": [ - { - "name": "SVGAttributes", - "id": "svgattributes-_xmlns_xlink_" - }, - { - "name": "\"xmlns:xlink\"", - "id": "svgattributes-_xmlns_xlink_" - } - ], - "kind": "PropertySignature", - "content": "```typescript\n'xmlns:xlink'?: string | undefined;\n```", - "mdFile": "qwik.svgattributes._xmlns_xlink_.md" + "mdFile": "core.componentbaseprops._q_slot_.md" }, { "name": "$", @@ -231,134 +30,8 @@ ], "kind": "Function", "content": "Qwik Optimizer marker function.\n\nUse `$(...)` to tell Qwik Optimizer to extract the expression in `$(...)` into a lazy-loadable resource referenced by `QRL`.\n\n\n```typescript\n$: (expression: T) => QRL\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nexpression\n\n\n\n\nT\n\n\n\n\nExpression which should be lazy loaded\n\n\n
\n**Returns:**\n\n[QRL](#qrl)<T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts", - "mdFile": "qwik._.md" - }, - { - "name": "AnchorHTMLAttributes", - "id": "anchorhtmlattributes", - "hierarchy": [ - { - "name": "AnchorHTMLAttributes", - "id": "anchorhtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface AnchorHTMLAttributes extends Attrs<'a', T> \n```\n**Extends:** Attrs<'a', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.anchorhtmlattributes.md" - }, - { - "name": "AreaHTMLAttributes", - "id": "areahtmlattributes", - "hierarchy": [ - { - "name": "AreaHTMLAttributes", - "id": "areahtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface AreaHTMLAttributes extends Attrs<'area', T> \n```\n**Extends:** Attrs<'area', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.areahtmlattributes.md" - }, - { - "name": "AriaAttributes", - "id": "ariaattributes", - "hierarchy": [ - { - "name": "AriaAttributes", - "id": "ariaattributes" - } - ], - "kind": "Interface", - "content": "TS defines these with the React syntax which is not compatible with Qwik. E.g. `ariaAtomic` instead of `aria-atomic`.\n\n\n```typescript\nexport interface AriaAttributes \n```\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[\"aria-activedescendant\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_ Identifies the currently active element when DOM focus is on a composite widget, textbox, group, or application.\n\n\n
\n\n[\"aria-atomic\"?](#)\n\n\n\n\n\n\n\n[Booleanish](#booleanish) \\| undefined\n\n\n\n\n_(Optional)_ Indicates whether assistive technologies will present all, or only parts of, the changed region based on the change notifications defined by the aria-relevant attribute.\n\n\n
\n\n[\"aria-autocomplete\"?](#)\n\n\n\n\n\n\n\n'none' \\| 'inline' \\| 'list' \\| 'both' \\| undefined\n\n\n\n\n_(Optional)_ Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be presented if they are made.\n\n\n
\n\n[\"aria-busy\"?](#)\n\n\n\n\n\n\n\n[Booleanish](#booleanish) \\| undefined\n\n\n\n\n_(Optional)_ Indicates an element is being modified and that assistive technologies MAY want to wait until the modifications are complete before exposing them to the user.\n\n\n
\n\n[\"aria-checked\"?](#)\n\n\n\n\n\n\n\nboolean \\| 'false' \\| 'mixed' \\| 'true' \\| undefined\n\n\n\n\n_(Optional)_ Indicates the current \"checked\" state of checkboxes, radio buttons, and other widgets.\n\n\n
\n\n[\"aria-colcount\"?](#)\n\n\n\n\n\n\n\nnumber \\| undefined\n\n\n\n\n_(Optional)_ Defines the total number of columns in a table, grid, or treegrid.\n\n\n
\n\n[\"aria-colindex\"?](#)\n\n\n\n\n\n\n\nnumber \\| undefined\n\n\n\n\n_(Optional)_ Defines an element's column index or position with respect to the total number of columns within a table, grid, or treegrid.\n\n\n
\n\n[\"aria-colspan\"?](#)\n\n\n\n\n\n\n\nnumber \\| undefined\n\n\n\n\n_(Optional)_ Defines the number of columns spanned by a cell or gridcell within a table, grid, or treegrid.\n\n\n
\n\n[\"aria-controls\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_ Identifies the element (or elements) whose contents or presence are controlled by the current element.\n\n\n
\n\n[\"aria-current\"?](#)\n\n\n\n\n\n\n\nboolean \\| 'false' \\| 'true' \\| 'page' \\| 'step' \\| 'location' \\| 'date' \\| 'time' \\| undefined\n\n\n\n\n_(Optional)_ Indicates the element that represents the current item within a container or set of related elements.\n\n\n
\n\n[\"aria-describedby\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_ Identifies the element (or elements) that describes the object.\n\n\n
\n\n[\"aria-details\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_ Identifies the element that provides a detailed, extended description for the object.\n\n\n
\n\n[\"aria-disabled\"?](#)\n\n\n\n\n\n\n\n[Booleanish](#booleanish) \\| undefined\n\n\n\n\n_(Optional)_ Indicates that the element is perceivable but disabled, so it is not editable or otherwise operable.\n\n\n
\n\n[\"aria-dropeffect\"?](#)\n\n\n\n\n\n\n\n'none' \\| 'copy' \\| 'execute' \\| 'link' \\| 'move' \\| 'popup' \\| undefined\n\n\n\n\n_(Optional)_ Indicates what functions can be performed when a dragged object is released on the drop target.\n\n\n
\n\n[\"aria-errormessage\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_ Identifies the element that provides an error message for the object.\n\n\n
\n\n[\"aria-expanded\"?](#)\n\n\n\n\n\n\n\n[Booleanish](#booleanish) \\| undefined\n\n\n\n\n_(Optional)_ Indicates whether the element, or another grouping element it controls, is currently expanded or collapsed.\n\n\n
\n\n[\"aria-flowto\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_ Identifies the next element (or elements) in an alternate reading order of content which, at the user's discretion, allows assistive technology to override the general default of reading in document source order.\n\n\n
\n\n[\"aria-grabbed\"?](#)\n\n\n\n\n\n\n\n[Booleanish](#booleanish) \\| undefined\n\n\n\n\n_(Optional)_ Indicates an element's \"grabbed\" state in a drag-and-drop operation.\n\n\n
\n\n[\"aria-haspopup\"?](#)\n\n\n\n\n\n\n\nboolean \\| 'false' \\| 'true' \\| 'menu' \\| 'listbox' \\| 'tree' \\| 'grid' \\| 'dialog' \\| undefined\n\n\n\n\n_(Optional)_ Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element.\n\n\n
\n\n[\"aria-hidden\"?](#)\n\n\n\n\n\n\n\n[Booleanish](#booleanish) \\| undefined\n\n\n\n\n_(Optional)_ Indicates whether the element is exposed to an accessibility API.\n\n\n
\n\n[\"aria-invalid\"?](#)\n\n\n\n\n\n\n\nboolean \\| 'false' \\| 'true' \\| 'grammar' \\| 'spelling' \\| undefined\n\n\n\n\n_(Optional)_ Indicates the entered value does not conform to the format expected by the application.\n\n\n
\n\n[\"aria-keyshortcuts\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_ Indicates keyboard shortcuts that an author has implemented to activate or give focus to an element.\n\n\n
\n\n[\"aria-label\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_ Defines a string value that labels the current element.\n\n\n
\n\n[\"aria-labelledby\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_ Identifies the element (or elements) that labels the current element.\n\n\n
\n\n[\"aria-level\"?](#)\n\n\n\n\n\n\n\nnumber \\| undefined\n\n\n\n\n_(Optional)_ Defines the hierarchical level of an element within a structure.\n\n\n
\n\n[\"aria-live\"?](#)\n\n\n\n\n\n\n\n'off' \\| 'assertive' \\| 'polite' \\| undefined\n\n\n\n\n_(Optional)_ Indicates that an element will be updated, and describes the types of updates the user agents, assistive technologies, and user can expect from the live region.\n\n\n
\n\n[\"aria-modal\"?](#)\n\n\n\n\n\n\n\n[Booleanish](#booleanish) \\| undefined\n\n\n\n\n_(Optional)_ Indicates whether an element is modal when displayed.\n\n\n
\n\n[\"aria-multiline\"?](#)\n\n\n\n\n\n\n\n[Booleanish](#booleanish) \\| undefined\n\n\n\n\n_(Optional)_ Indicates whether a text box accepts multiple lines of input or only a single line.\n\n\n
\n\n[\"aria-multiselectable\"?](#)\n\n\n\n\n\n\n\n[Booleanish](#booleanish) \\| undefined\n\n\n\n\n_(Optional)_ Indicates that the user may select more than one item from the current selectable descendants.\n\n\n
\n\n[\"aria-orientation\"?](#)\n\n\n\n\n\n\n\n'horizontal' \\| 'vertical' \\| undefined\n\n\n\n\n_(Optional)_ Indicates whether the element's orientation is horizontal, vertical, or unknown/ambiguous.\n\n\n
\n\n[\"aria-owns\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_ Identifies an element (or elements) in order to define a visual, functional, or contextual parent/child relationship between DOM elements where the DOM hierarchy cannot be used to represent the relationship.\n\n\n
\n\n[\"aria-placeholder\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_ Defines a short hint (a word or short phrase) intended to aid the user with data entry when the control has no value. A hint could be a sample value or a brief description of the expected format.\n\n\n
\n\n[\"aria-posinset\"?](#)\n\n\n\n\n\n\n\nnumber \\| undefined\n\n\n\n\n_(Optional)_ Defines an element's number or position in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM.\n\n\n
\n\n[\"aria-pressed\"?](#)\n\n\n\n\n\n\n\nboolean \\| 'false' \\| 'mixed' \\| 'true' \\| undefined\n\n\n\n\n_(Optional)_ Indicates the current \"pressed\" state of toggle buttons.\n\n\n
\n\n[\"aria-readonly\"?](#)\n\n\n\n\n\n\n\n[Booleanish](#booleanish) \\| undefined\n\n\n\n\n_(Optional)_ Indicates that the element is not editable, but is otherwise operable.\n\n\n
\n\n[\"aria-relevant\"?](#)\n\n\n\n\n\n\n\n'additions' \\| 'additions removals' \\| 'additions text' \\| 'all' \\| 'removals' \\| 'removals additions' \\| 'removals text' \\| 'text' \\| 'text additions' \\| 'text removals' \\| undefined\n\n\n\n\n_(Optional)_ Indicates what notifications the user agent will trigger when the accessibility tree within a live region is modified.\n\n\n
\n\n[\"aria-required\"?](#)\n\n\n\n\n\n\n\n[Booleanish](#booleanish) \\| undefined\n\n\n\n\n_(Optional)_ Indicates that user input is required on the element before a form may be submitted.\n\n\n
\n\n[\"aria-roledescription\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_ Defines a human-readable, author-localized description for the role of an element.\n\n\n
\n\n[\"aria-rowcount\"?](#)\n\n\n\n\n\n\n\nnumber \\| undefined\n\n\n\n\n_(Optional)_ Defines the total number of rows in a table, grid, or treegrid.\n\n\n
\n\n[\"aria-rowindex\"?](#)\n\n\n\n\n\n\n\nnumber \\| undefined\n\n\n\n\n_(Optional)_ Defines an element's row index or position with respect to the total number of rows within a table, grid, or treegrid.\n\n\n
\n\n[\"aria-rowspan\"?](#)\n\n\n\n\n\n\n\nnumber \\| undefined\n\n\n\n\n_(Optional)_ Defines the number of rows spanned by a cell or gridcell within a table, grid, or treegrid.\n\n\n
\n\n[\"aria-selected\"?](#)\n\n\n\n\n\n\n\n[Booleanish](#booleanish) \\| undefined\n\n\n\n\n_(Optional)_ Indicates the current \"selected\" state of various widgets.\n\n\n
\n\n[\"aria-setsize\"?](#)\n\n\n\n\n\n\n\nnumber \\| undefined\n\n\n\n\n_(Optional)_ Defines the number of items in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM.\n\n\n
\n\n[\"aria-sort\"?](#)\n\n\n\n\n\n\n\n'none' \\| 'ascending' \\| 'descending' \\| 'other' \\| undefined\n\n\n\n\n_(Optional)_ Indicates if items in a table or grid are sorted in ascending or descending order.\n\n\n
\n\n[\"aria-valuemax\"?](#)\n\n\n\n\n\n\n\nnumber \\| undefined\n\n\n\n\n_(Optional)_ Defines the maximum allowed value for a range widget.\n\n\n
\n\n[\"aria-valuemin\"?](#)\n\n\n\n\n\n\n\nnumber \\| undefined\n\n\n\n\n_(Optional)_ Defines the minimum allowed value for a range widget.\n\n\n
\n\n[\"aria-valuenow\"?](#)\n\n\n\n\n\n\n\nnumber \\| undefined\n\n\n\n\n_(Optional)_ Defines the current value for a range widget.\n\n\n
\n\n[\"aria-valuetext\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_ Defines the human readable text alternative of aria-valuenow for a range widget.\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.ariaattributes.md" - }, - { - "name": "AriaRole", - "id": "ariarole", - "hierarchy": [ - { - "name": "AriaRole", - "id": "ariarole" - } - ], - "kind": "TypeAlias", - "content": "```typescript\nexport type AriaRole = 'alert' | 'alertdialog' | 'application' | 'article' | 'banner' | 'button' | 'cell' | 'checkbox' | 'columnheader' | 'combobox' | 'complementary' | 'contentinfo' | 'definition' | 'dialog' | 'directory' | 'document' | 'feed' | 'figure' | 'form' | 'grid' | 'gridcell' | 'group' | 'heading' | 'img' | 'link' | 'list' | 'listbox' | 'listitem' | 'log' | 'main' | 'marquee' | 'math' | 'menu' | 'menubar' | 'menuitem' | 'menuitemcheckbox' | 'menuitemradio' | 'navigation' | 'none' | 'note' | 'option' | 'presentation' | 'progressbar' | 'radio' | 'radiogroup' | 'region' | 'row' | 'rowgroup' | 'rowheader' | 'scrollbar' | 'search' | 'searchbox' | 'separator' | 'slider' | 'spinbutton' | 'status' | 'switch' | 'tab' | 'table' | 'tablist' | 'tabpanel' | 'term' | 'textbox' | 'timer' | 'toolbar' | 'tooltip' | 'tree' | 'treegrid' | 'treeitem' | (string & {});\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.ariarole.md" - }, - { - "name": "AudioHTMLAttributes", - "id": "audiohtmlattributes", - "hierarchy": [ - { - "name": "AudioHTMLAttributes", - "id": "audiohtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface AudioHTMLAttributes extends Attrs<'audio', T> \n```\n**Extends:** Attrs<'audio', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.audiohtmlattributes.md" - }, - { - "name": "BaseHTMLAttributes", - "id": "basehtmlattributes", - "hierarchy": [ - { - "name": "BaseHTMLAttributes", - "id": "basehtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface BaseHTMLAttributes extends Attrs<'base', T> \n```\n**Extends:** Attrs<'base', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.basehtmlattributes.md" - }, - { - "name": "BlockquoteHTMLAttributes", - "id": "blockquotehtmlattributes", - "hierarchy": [ - { - "name": "BlockquoteHTMLAttributes", - "id": "blockquotehtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface BlockquoteHTMLAttributes extends Attrs<'blockquote', T> \n```\n**Extends:** Attrs<'blockquote', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.blockquotehtmlattributes.md" - }, - { - "name": "Booleanish", - "id": "booleanish", - "hierarchy": [ - { - "name": "Booleanish", - "id": "booleanish" - } - ], - "kind": "TypeAlias", - "content": "```typescript\nexport type Booleanish = boolean | `${boolean}`;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.booleanish.md" - }, - { - "name": "ButtonHTMLAttributes", - "id": "buttonhtmlattributes", - "hierarchy": [ - { - "name": "ButtonHTMLAttributes", - "id": "buttonhtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface ButtonHTMLAttributes extends Attrs<'button', T> \n```\n**Extends:** Attrs<'button', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.buttonhtmlattributes.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/qrl.public.ts", + "mdFile": "core._.md" }, { "name": "cache", @@ -375,21 +48,7 @@ ], "kind": "MethodSignature", "content": "```typescript\ncache(policyOrMilliseconds: number | 'immutable'): void;\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\npolicyOrMilliseconds\n\n\n\n\nnumber \\| 'immutable'\n\n\n\n\n\n
\n**Returns:**\n\nvoid", - "mdFile": "qwik.resourcectx.cache.md" - }, - { - "name": "CanvasHTMLAttributes", - "id": "canvashtmlattributes", - "hierarchy": [ - { - "name": "CanvasHTMLAttributes", - "id": "canvashtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface CanvasHTMLAttributes extends Attrs<'canvas', T> \n```\n**Extends:** Attrs<'canvas', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.canvashtmlattributes.md" + "mdFile": "core.resourcectx.cache.md" }, { "name": "ClassList", @@ -402,8 +61,8 @@ ], "kind": "TypeAlias", "content": "A class list can be a string, a boolean, an array, or an object.\n\nIf it's an array, each item is a class list and they are all added.\n\nIf it's an object, then the keys are class name strings, and the values are booleans that determine if the class name string should be added or not.\n\n\n```typescript\nexport type ClassList = string | undefined | null | false | Record | ClassList[];\n```\n**References:** [ClassList](#classlist)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts", - "mdFile": "qwik.classlist.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts", + "mdFile": "core.classlist.md" }, { "name": "cleanup", @@ -420,35 +79,7 @@ ], "kind": "MethodSignature", "content": "```typescript\ncleanup(): void;\n```\n**Returns:**\n\nvoid", - "mdFile": "qwik.renderresult.cleanup.md" - }, - { - "name": "ColgroupHTMLAttributes", - "id": "colgrouphtmlattributes", - "hierarchy": [ - { - "name": "ColgroupHTMLAttributes", - "id": "colgrouphtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface ColgroupHTMLAttributes extends Attrs<'colgroup', T> \n```\n**Extends:** Attrs<'colgroup', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.colgrouphtmlattributes.md" - }, - { - "name": "ColHTMLAttributes", - "id": "colhtmlattributes", - "hierarchy": [ - { - "name": "ColHTMLAttributes", - "id": "colhtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface ColHTMLAttributes extends Attrs<'col', T> \n```\n**Extends:** Attrs<'col', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.colhtmlattributes.md" + "mdFile": "core.renderresult.cleanup.md" }, { "name": "Component", @@ -461,8 +92,8 @@ ], "kind": "TypeAlias", "content": "Type representing the Qwik component.\n\n`Component` is the type returned by invoking `component$`.\n\n```tsx\ninterface MyComponentProps {\n someProp: string;\n}\nconst MyComponent: Component = component$((props: MyComponentProps) => {\n return {props.someProp};\n});\n```\n\n\n```typescript\nexport type Component = FunctionComponent>;\n```\n**References:** [FunctionComponent](#functioncomponent), [PublicProps](#publicprops)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/component/component.public.ts", - "mdFile": "qwik.component.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/component.public.ts", + "mdFile": "core.component.md" }, { "name": "component$", @@ -475,8 +106,8 @@ ], "kind": "Function", "content": "Declare a Qwik component that can be used to create UI.\n\nUse `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.\n\nSide note: You can also declare regular (standard JSX) components that will have standard synchronous behavior.\n\nQwik 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:\n\n\\#\\#\\# Example\n\nAn example showing how to create a counter component:\n\n```tsx\nexport interface CounterProps {\n initialValue?: number;\n step?: number;\n}\nexport const Counter = component$((props: CounterProps) => {\n const state = useStore({ count: props.initialValue || 0 });\n return (\n
\n {state.count}\n \n
\n );\n});\n```\n- `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.\n\nThe above can then be used like so:\n\n```tsx\nexport const OtherComponent = component$(() => {\n return ;\n});\n```\nSee also: `component`, `useCleanup`, `onResume`, `onPause`, `useOn`, `useOnDocument`, `useOnWindow`, `useStyles`\n\n\n```typescript\ncomponent$: (onMount: OnRenderFn) => Component\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nonMount\n\n\n\n\n[OnRenderFn](#onrenderfn)<PROPS>\n\n\n\n\n\n
\n**Returns:**\n\n[Component](#component)<PROPS>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/component/component.public.ts", - "mdFile": "qwik.component_.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/component.public.ts", + "mdFile": "core.component_.md" }, { "name": "ComponentBaseProps", @@ -489,22 +120,8 @@ ], "kind": "Interface", "content": "```typescript\nexport interface ComponentBaseProps \n```\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[\"q:slot\"?](#componentbaseprops-_q_slot_)\n\n\n\n\n\n\n\nstring\n\n\n\n\n_(Optional)_\n\n\n
\n\n[key?](#)\n\n\n\n\n\n\n\nstring \\| number \\| null \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts", - "mdFile": "qwik.componentbaseprops.md" - }, - { - "name": "componentQrl", - "id": "componentqrl", - "hierarchy": [ - { - "name": "componentQrl", - "id": "componentqrl" - } - ], - "kind": "Function", - "content": "Declare a Qwik component that can be used to create UI.\n\nUse `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.\n\nSide note: You can also declare regular (standard JSX) components that will have standard synchronous behavior.\n\nQwik 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:\n\n\\#\\#\\# Example\n\nAn example showing how to create a counter component:\n\n```tsx\nexport interface CounterProps {\n initialValue?: number;\n step?: number;\n}\nexport const Counter = component$((props: CounterProps) => {\n const state = useStore({ count: props.initialValue || 0 });\n return (\n
\n {state.count}\n \n
\n );\n});\n```\n- `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.\n\nThe above can then be used like so:\n\n```tsx\nexport const OtherComponent = component$(() => {\n return ;\n});\n```\nSee also: `component`, `useCleanup`, `onResume`, `onPause`, `useOn`, `useOnDocument`, `useOnWindow`, `useStyles`\n\n\n```typescript\ncomponentQrl: >(componentQrl: QRL>) => Component\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\ncomponentQrl\n\n\n\n\n[QRL](#qrl)<[OnRenderFn](#onrenderfn)<PROPS>>\n\n\n\n\n\n
\n**Returns:**\n\n[Component](#component)<PROPS>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/component/component.public.ts", - "mdFile": "qwik.componentqrl.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts", + "mdFile": "core.componentbaseprops.md" }, { "name": "ComputedFn", @@ -517,8 +134,22 @@ ], "kind": "TypeAlias", "content": "```typescript\nexport type ComputedFn = () => T;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.computedfn.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-computed.ts", + "mdFile": "core.computedfn.md" + }, + { + "name": "ComputedSignal", + "id": "computedsignal", + "hierarchy": [ + { + "name": "ComputedSignal", + "id": "computedsignal" + } + ], + "kind": "Interface", + "content": "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.\n\n\n```typescript\nexport interface ComputedSignal extends ReadonlySignal \n```\n**Extends:** [ReadonlySignal](#readonlysignal)<T>\n\n\n\n\n
\n\nMethod\n\n\n\n\nDescription\n\n\n
\n\n[force()](#computedsignal-force)\n\n\n\n\nUse this to force recalculation and running subscribers, for example when the calculated value mutates but remains the same object. Useful for third-party libraries.\n\n\n
", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts", + "mdFile": "core.computedsignal.md" }, { "name": "ContextId", @@ -532,7 +163,7 @@ "kind": "Interface", "content": "ContextId is a typesafe ID for your context.\n\nContext is a way to pass stores to the child components without prop-drilling.\n\nUse `createContextId()` to create a `ContextId`. A `ContextId` is just a serializable identifier for the context. It is not the context value itself. See `useContextProvider()` and `useContext()` for the values. Qwik needs a serializable ID for the context so that the it can track context providers and consumers in a way that survives resumability.\n\n\\#\\#\\# Example\n\n```tsx\n// Declare the Context type.\ninterface TodosStore {\n items: string[];\n}\n// Create a Context ID (no data is saved here.)\n// You will use this ID to both create and retrieve the Context.\nexport const TodosContext = createContextId('Todos');\n\n// Example of providing context to child components.\nexport const App = component$(() => {\n useContextProvider(\n TodosContext,\n useStore({\n items: ['Learn Qwik', 'Build Qwik app', 'Profit'],\n })\n );\n\n return ;\n});\n\n// Example of retrieving the context provided by a parent component.\nexport const Items = component$(() => {\n const todos = useContext(TodosContext);\n return (\n
    \n {todos.items.map((item) => (\n
  • {item}
  • \n ))}\n
\n );\n});\n\n```\n\n\n```typescript\nexport interface ContextId \n```\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[\\_\\_brand\\_context\\_type\\_\\_](#)\n\n\n\n\n`readonly`\n\n\n\n\nSTATE\n\n\n\n\nDesign-time property to store type information for the context.\n\n\n
\n\n[id](#)\n\n\n\n\n`readonly`\n\n\n\n\nstring\n\n\n\n\nA unique ID for the context.\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-context.ts", - "mdFile": "qwik.contextid.md" + "mdFile": "core.contextid.md" }, { "name": "CorePlatform", @@ -545,8 +176,8 @@ ], "kind": "Interface", "content": "Low-level API for platform abstraction.\n\nDifferent platforms (browser, node, service workers) may have different ways of handling things such as `requestAnimationFrame` and imports. To make Qwik platform-independent Qwik uses the `CorePlatform` API to access the platform API.\n\n`CorePlatform` also is responsible for importing symbols. The import map is different on the client (browser) then on the server. For this reason, the server has a manifest that is used to map symbols to javascript chunks. The manifest is encapsulated in `CorePlatform`, for this reason, the `CorePlatform` can't be global as there may be multiple applications running at server concurrently.\n\nThis is a low-level API and there should not be a need for you to access this.\n\n\n```typescript\nexport interface CorePlatform \n```\n\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[chunkForSymbol](#)\n\n\n\n\n\n\n\n(symbolName: string, chunk: string \\| null, parent?: string) => readonly \\[symbol: string, chunk: string\\] \\| undefined\n\n\n\n\nRetrieve chunk name for the symbol.\n\nWhen the application is running on the server the symbols may be imported from different files (as server build is typically a single javascript chunk.) For this reason, it is necessary to convert the chunks from server format to client (browser) format. This is done by looking up symbols (which are globally unique) in the manifest. (Manifest is the mapping of symbols to the client chunk names.)\n\n\n
\n\n[importSymbol](#)\n\n\n\n\n\n\n\n(containerEl: Element \\| undefined, url: string \\| URL \\| undefined \\| null, symbol: string) => [ValueOrPromise](#valueorpromise)<any>\n\n\n\n\nRetrieve a symbol value from QRL.\n\nQwik needs to lazy load data and closures. For this Qwik uses QRLs that are serializable references of resources that are needed. The QRLs contain all the information necessary to retrieve the reference using `importSymbol`.\n\nWhy not use `import()`? Because `import()` is relative to the current file, and the current file is always the Qwik framework. So QRLs have additional information that allows them to serialize imports relative to application base rather than the Qwik framework file.\n\n\n
\n\n[isServer](#)\n\n\n\n\n\n\n\nboolean\n\n\n\n\nTrue of running on the server platform.\n\n\n
\n\n[nextTick](#)\n\n\n\n\n\n\n\n(fn: () => any) => Promise<any>\n\n\n\n\nPerform operation on next tick.\n\n\n
\n\n[raf](#)\n\n\n\n\n\n\n\n(fn: () => any) => Promise<any>\n\n\n\n\nPerform operation on next request-animation-frame.\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/platform/types.ts", - "mdFile": "qwik.coreplatform.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/platform/types.ts", + "mdFile": "core.coreplatform.md" }, { "name": "CorrectedToggleEvent", @@ -559,8 +190,8 @@ ], "kind": "Interface", "content": "This corrects the TS definition for ToggleEvent\n\n\n```typescript\nexport interface CorrectedToggleEvent extends Event \n```\n**Extends:** Event\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[newState](#)\n\n\n\n\n`readonly`\n\n\n\n\n'open' \\| 'closed'\n\n\n\n\n\n
\n\n[prevState](#)\n\n\n\n\n`readonly`\n\n\n\n\n'open' \\| 'closed'\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts", - "mdFile": "qwik.correctedtoggleevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts", + "mdFile": "core.correctedtoggleevent.md" }, { "name": "createComputed$", @@ -572,23 +203,9 @@ } ], "kind": "Function", - "content": "> Warning: This API is now obsolete.\n> \n> This is a technology preview\n> \n\nReturns 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.\n\n\n```typescript\ncreateComputed$: (qrl: ComputedFn) => Signal>\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\n[ComputedFn](#computedfn)<T>\n\n\n\n\n\n
\n**Returns:**\n\n[Signal](#signal)<Awaited<T>>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.createcomputed_.md" - }, - { - "name": "createComputedQrl", - "id": "createcomputedqrl", - "hierarchy": [ - { - "name": "createComputedQrl", - "id": "createcomputedqrl" - } - ], - "kind": "Function", - "content": "```typescript\ncreateComputedQrl: (qrl: QRL>) => Signal>\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\n[QRL](#qrl)<[ComputedFn](#computedfn)<T>>\n\n\n\n\n\n
\n**Returns:**\n\n[Signal](#signal)<Awaited<T>>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.createcomputedqrl.md" + "content": "Create a computed signal which is calculated from the given QRL. A computed signal is a signal which is calculated from other signals. When the signals change, the computed signal is recalculated.\n\nThe QRL must be a function which returns the value of the signal. The function must not have side effects, and it mus be synchronous.\n\nIf you need the function to be async, use `useSignal` and `useTask$` instead.\n\n\n```typescript\ncreateComputed$: (qrl: () => T) => T extends Promise ? never : ComputedSignal\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\n() => T\n\n\n\n\n\n
\n**Returns:**\n\nT extends Promise<any> ? never : [ComputedSignal](#computedsignal)<T>", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts", + "mdFile": "core.createcomputed_.md" }, { "name": "createContextId", @@ -602,7 +219,7 @@ "kind": "Function", "content": "Create a context ID to be used in your application. The name should be written with no spaces.\n\nContext is a way to pass stores to the child components without prop-drilling.\n\nUse `createContextId()` to create a `ContextId`. A `ContextId` is just a serializable identifier for the context. It is not the context value itself. See `useContextProvider()` and `useContext()` for the values. Qwik needs a serializable ID for the context so that the it can track context providers and consumers in a way that survives resumability.\n\n\\#\\#\\# Example\n\n```tsx\n// Declare the Context type.\ninterface TodosStore {\n items: string[];\n}\n// Create a Context ID (no data is saved here.)\n// You will use this ID to both create and retrieve the Context.\nexport const TodosContext = createContextId('Todos');\n\n// Example of providing context to child components.\nexport const App = component$(() => {\n useContextProvider(\n TodosContext,\n useStore({\n items: ['Learn Qwik', 'Build Qwik app', 'Profit'],\n })\n );\n\n return ;\n});\n\n// Example of retrieving the context provided by a parent component.\nexport const Items = component$(() => {\n const todos = useContext(TodosContext);\n return (\n
    \n {todos.items.map((item) => (\n
  • {item}
  • \n ))}\n
\n );\n});\n\n```\n\n\n```typescript\ncreateContextId: (name: string) => ContextId\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nname\n\n\n\n\nstring\n\n\n\n\nThe name of the context.\n\n\n
\n**Returns:**\n\n[ContextId](#contextid)<STATE>", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-context.ts", - "mdFile": "qwik.createcontextid.md" + "mdFile": "core.createcontextid.md" }, { "name": "createSignal", @@ -614,550 +231,273 @@ } ], "kind": "Variable", - "content": "> Warning: This API is now obsolete.\n> \n> This is a technology preview\n> \n\nCreates a signal.\n\nIf the initial state is a function, the function is invoked to calculate the actual initial state.\n\n\n```typescript\ncreateSignal: UseSignal\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-signal.ts", - "mdFile": "qwik.createsignal.md" + "content": "Creates a Signal with the given value. If no value is given, the signal is created with `undefined`.\n\n\n```typescript\ncreateSignal: {\n (): Signal;\n (value: T): Signal;\n}\n```", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts", + "mdFile": "core.createsignal.md" }, { "name": "CSSProperties", "id": "cssproperties", "hierarchy": [ { - "name": "CSSProperties", - "id": "cssproperties" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface CSSProperties extends CSS.Properties, CSS.PropertiesHyphen \n```\n**Extends:** CSS.Properties<string \\| number>, CSS.PropertiesHyphen<string \\| number>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.cssproperties.md" - }, - { - "name": "DataHTMLAttributes", - "id": "datahtmlattributes", - "hierarchy": [ - { - "name": "DataHTMLAttributes", - "id": "datahtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface DataHTMLAttributes extends Attrs<'data', T> \n```\n**Extends:** Attrs<'data', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.datahtmlattributes.md" - }, - { - "name": "DelHTMLAttributes", - "id": "delhtmlattributes", - "hierarchy": [ - { - "name": "DelHTMLAttributes", - "id": "delhtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface DelHTMLAttributes extends Attrs<'del', T> \n```\n**Extends:** Attrs<'del', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.delhtmlattributes.md" - }, - { - "name": "DetailsHTMLAttributes", - "id": "detailshtmlattributes", - "hierarchy": [ - { - "name": "DetailsHTMLAttributes", - "id": "detailshtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface DetailsHTMLAttributes extends Attrs<'details', T> \n```\n**Extends:** Attrs<'details', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.detailshtmlattributes.md" - }, - { - "name": "DevJSX", - "id": "devjsx", - "hierarchy": [ - { - "name": "DevJSX", - "id": "devjsx" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface DevJSX \n```\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[columnNumber](#)\n\n\n\n\n\n\n\nnumber\n\n\n\n\n\n
\n\n[fileName](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n\n
\n\n[lineNumber](#)\n\n\n\n\n\n\n\nnumber\n\n\n\n\n\n
\n\n[stack?](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n_(Optional)_\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-node.ts", - "mdFile": "qwik.devjsx.md" - }, - { - "name": "DialogHTMLAttributes", - "id": "dialoghtmlattributes", - "hierarchy": [ - { - "name": "DialogHTMLAttributes", - "id": "dialoghtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface DialogHTMLAttributes extends Attrs<'dialog', T> \n```\n**Extends:** Attrs<'dialog', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.dialoghtmlattributes.md" - }, - { - "name": "DOMAttributes", - "id": "domattributes", - "hierarchy": [ - { - "name": "DOMAttributes", - "id": "domattributes" - } - ], - "kind": "Interface", - "content": "The Qwik-specific attributes that DOM elements accept\n\n\n```typescript\nexport interface DOMAttributes extends DOMAttributesBase, QwikEvents \n```\n**Extends:** DOMAttributesBase<EL>, QwikEvents<EL>\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[class?](#)\n\n\n\n\n\n\n\n[ClassList](#classlist) \\| [Signal](#signal)<[ClassList](#classlist)> \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts", - "mdFile": "qwik.domattributes.md" - }, - { - "name": "EagernessOptions", - "id": "eagernessoptions", - "hierarchy": [ - { - "name": "EagernessOptions", - "id": "eagernessoptions" - } - ], - "kind": "TypeAlias", - "content": "```typescript\nexport type EagernessOptions = 'visible' | 'load' | 'idle';\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.eagernessoptions.md" - }, - { - "name": "Element", - "id": "qwikjsx-element", - "hierarchy": [ - { - "name": "QwikJSX", - "id": "qwikjsx-element" - }, - { - "name": "Element", - "id": "qwikjsx-element" - } - ], - "kind": "TypeAlias", - "content": "```typescript\ntype Element = JSXOutput;\n```\n**References:** [JSXOutput](#jsxoutput)", - "mdFile": "qwik.qwikjsx.element.md" - }, - { - "name": "ElementChildrenAttribute", - "id": "qwikjsx-elementchildrenattribute", - "hierarchy": [ - { - "name": "QwikJSX", - "id": "qwikjsx-elementchildrenattribute" - }, - { - "name": "ElementChildrenAttribute", - "id": "qwikjsx-elementchildrenattribute" - } - ], - "kind": "Interface", - "content": "```typescript\ninterface ElementChildrenAttribute \n```\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[children](#)\n\n\n\n\n\n\n\n[JSXChildren](#jsxchildren)\n\n\n\n\n\n
", - "mdFile": "qwik.qwikjsx.elementchildrenattribute.md" - }, - { - "name": "ElementType", - "id": "qwikjsx-elementtype", - "hierarchy": [ - { - "name": "QwikJSX", - "id": "qwikjsx-elementtype" - }, - { - "name": "ElementType", - "id": "qwikjsx-elementtype" - } - ], - "kind": "TypeAlias", - "content": "```typescript\ntype ElementType = string | FunctionComponent>;\n```\n**References:** [FunctionComponent](#functioncomponent)", - "mdFile": "qwik.qwikjsx.elementtype.md" - }, - { - "name": "EmbedHTMLAttributes", - "id": "embedhtmlattributes", - "hierarchy": [ - { - "name": "EmbedHTMLAttributes", - "id": "embedhtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface EmbedHTMLAttributes extends Attrs<'embed', T> \n```\n**Extends:** Attrs<'embed', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.embedhtmlattributes.md" - }, - { - "name": "ErrorBoundaryStore", - "id": "errorboundarystore", - "hierarchy": [ - { - "name": "ErrorBoundaryStore", - "id": "errorboundarystore" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface ErrorBoundaryStore \n```\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[error](#)\n\n\n\n\n\n\n\nany \\| undefined\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/error-handling.ts", - "mdFile": "qwik.errorboundarystore.md" - }, - { - "name": "event$", - "id": "event_", - "hierarchy": [ - { - "name": "event$", - "id": "event_" - } - ], - "kind": "Function", - "content": "```typescript\nevent$: (qrl: T) => QRL\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\nT\n\n\n\n\n\n
\n**Returns:**\n\n[QRL](#qrl)<T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts", - "mdFile": "qwik.event_.md" - }, - { - "name": "EventHandler", - "id": "eventhandler", - "hierarchy": [ - { - "name": "EventHandler", - "id": "eventhandler" - } - ], - "kind": "TypeAlias", - "content": "A DOM event handler\n\n\n```typescript\nexport type EventHandler = {\n bivarianceHack(event: EV, element: EL): any;\n}['bivarianceHack'];\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts", - "mdFile": "qwik.eventhandler.md" - }, - { - "name": "eventQrl", - "id": "eventqrl", - "hierarchy": [ - { - "name": "eventQrl", - "id": "eventqrl" - } - ], - "kind": "Function", - "content": "```typescript\neventQrl: (qrl: QRL) => QRL\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\n[QRL](#qrl)<T>\n\n\n\n\n\n
\n**Returns:**\n\n[QRL](#qrl)<T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts", - "mdFile": "qwik.eventqrl.md" - }, - { - "name": "FieldsetHTMLAttributes", - "id": "fieldsethtmlattributes", - "hierarchy": [ - { - "name": "FieldsetHTMLAttributes", - "id": "fieldsethtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface FieldsetHTMLAttributes extends Attrs<'fieldset', T> \n```\n**Extends:** Attrs<'fieldset', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.fieldsethtmlattributes.md" - }, - { - "name": "FormHTMLAttributes", - "id": "formhtmlattributes", - "hierarchy": [ - { - "name": "FormHTMLAttributes", - "id": "formhtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface FormHTMLAttributes extends Attrs<'form', T> \n```\n**Extends:** Attrs<'form', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.formhtmlattributes.md" - }, - { - "name": "Fragment", - "id": "fragment", - "hierarchy": [ - { - "name": "Fragment", - "id": "fragment" - } - ], - "kind": "Variable", - "content": "```typescript\nFragment: FunctionComponent<{\n children?: any;\n key?: string | number | null;\n}>\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/jsx-runtime.ts", - "mdFile": "qwik.fragment.md" - }, - { - "name": "FunctionComponent", - "id": "functioncomponent", - "hierarchy": [ - { - "name": "FunctionComponent", - "id": "functioncomponent" - } - ], - "kind": "TypeAlias", - "content": "Any function taking a props object that returns JSXOutput.\n\nThe `key`, `flags` and `dev` parameters are for internal use.\n\n\n```typescript\nexport type FunctionComponent

= {\n renderFn(props: P, key: string | null, flags: number, dev?: DevJSX): JSXOutput;\n}['renderFn'];\n```\n**References:** [DevJSX](#devjsx), [JSXOutput](#jsxoutput)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-node.ts", - "mdFile": "qwik.functioncomponent.md" - }, - { - "name": "getPlatform", - "id": "getplatform", - "hierarchy": [ - { - "name": "getPlatform", - "id": "getplatform" - } - ], - "kind": "Function", - "content": "Retrieve the `CorePlatform`.\n\nThe `CorePlatform` is also responsible for retrieving the Manifest, that contains mappings from symbols to javascript import chunks. For this reason, `CorePlatform` can't be global, but is specific to the application currently running. On server it is possible that many different applications are running in a single server instance, and for this reason the `CorePlatform` is associated with the application document.\n\n\n```typescript\ngetPlatform: () => CorePlatform\n```\n**Returns:**\n\n[CorePlatform](#coreplatform)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/platform/platform.ts", - "mdFile": "qwik.getplatform.md" - }, - { - "name": "h", - "id": "h", - "hierarchy": [ - { - "name": "h", - "id": "h" + "name": "CSSProperties", + "id": "cssproperties" } ], - "kind": "Function", - "content": "```typescript\nexport declare namespace h \n```\n\n\n\n\n\n\n\n\n\n\n
\n\nFunction\n\n\n\n\nDescription\n\n\n
\n\n[h(type)](#)\n\n\n\n\n\n
\n\n[h(type, data)](#)\n\n\n\n\n\n
\n\n[h(type, text)](#)\n\n\n\n\n\n
\n\n[h(type, children)](#)\n\n\n\n\n\n
\n\n[h(type, data, text)](#)\n\n\n\n\n\n
\n\n[h(type, data, children)](#)\n\n\n\n\n\n
\n\n[h(sel, data, children)](#)\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/factory.ts", - "mdFile": "qwik.h.md" + "kind": "Interface", + "content": "```typescript\nexport interface CSSProperties extends CSS.Properties, CSS.PropertiesHyphen \n```\n**Extends:** CSS.Properties<string \\| number>, CSS.PropertiesHyphen<string \\| number>", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-generated.ts", + "mdFile": "core.cssproperties.md" }, { - "name": "h", - "id": "h", + "name": "DevJSX", + "id": "devjsx", "hierarchy": [ { - "name": "h", - "id": "h" + "name": "DevJSX", + "id": "devjsx" } ], - "kind": "Namespace", - "content": "```typescript\nexport declare namespace h \n```\n\n\n\n\n\n\n\n\n\n\n
\n\nFunction\n\n\n\n\nDescription\n\n\n
\n\n[h(type)](#)\n\n\n\n\n\n
\n\n[h(type, data)](#)\n\n\n\n\n\n
\n\n[h(type, text)](#)\n\n\n\n\n\n
\n\n[h(type, children)](#)\n\n\n\n\n\n
\n\n[h(type, data, text)](#)\n\n\n\n\n\n
\n\n[h(type, data, children)](#)\n\n\n\n\n\n
\n\n[h(sel, data, children)](#)\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/factory.ts", - "mdFile": "qwik.h.md" + "kind": "Interface", + "content": "```typescript\nexport interface DevJSX \n```\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[columnNumber](#)\n\n\n\n\n\n\n\nnumber\n\n\n\n\n\n
\n\n[fileName](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n\n
\n\n[lineNumber](#)\n\n\n\n\n\n\n\nnumber\n\n\n\n\n\n
\n\n[stack?](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n_(Optional)_\n\n\n
", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-node.ts", + "mdFile": "core.devjsx.md" }, { - "name": "HrHTMLAttributes", - "id": "hrhtmlattributes", + "name": "DOMAttributes", + "id": "domattributes", "hierarchy": [ { - "name": "HrHTMLAttributes", - "id": "hrhtmlattributes" + "name": "DOMAttributes", + "id": "domattributes" } ], "kind": "Interface", - "content": "```typescript\nexport interface HrHTMLAttributes extends Attrs<'hr', T> \n```\n**Extends:** Attrs<'hr', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.hrhtmlattributes.md" + "content": "The Qwik-specific attributes that DOM elements accept\n\n\n```typescript\nexport interface DOMAttributes extends DOMAttributesBase, QwikEvents \n```\n**Extends:** DOMAttributesBase<EL>, QwikEvents<EL>\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[class?](#)\n\n\n\n\n\n\n\n[ClassList](#classlist) \\| [Signal](#signal)<[ClassList](#classlist)> \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts", + "mdFile": "core.domattributes.md" }, { - "name": "HTMLAttributeAnchorTarget", - "id": "htmlattributeanchortarget", + "name": "EagernessOptions", + "id": "eagernessoptions", "hierarchy": [ { - "name": "HTMLAttributeAnchorTarget", - "id": "htmlattributeanchortarget" + "name": "EagernessOptions", + "id": "eagernessoptions" } ], "kind": "TypeAlias", - "content": "```typescript\nexport type HTMLAttributeAnchorTarget = '_self' | '_blank' | '_parent' | '_top' | (string & {});\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.htmlattributeanchortarget.md" + "content": "```typescript\nexport type EagernessOptions = 'visible' | 'load' | 'idle';\n```", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", + "mdFile": "core.eagernessoptions.md" }, { - "name": "HTMLAttributeReferrerPolicy", - "id": "htmlattributereferrerpolicy", + "name": "Element", + "id": "qwikjsx-element", "hierarchy": [ { - "name": "HTMLAttributeReferrerPolicy", - "id": "htmlattributereferrerpolicy" + "name": "QwikJSX", + "id": "qwikjsx-element" + }, + { + "name": "Element", + "id": "qwikjsx-element" } ], "kind": "TypeAlias", - "content": "```typescript\nexport type HTMLAttributeReferrerPolicy = ReferrerPolicy;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.htmlattributereferrerpolicy.md" + "content": "```typescript\ntype Element = JSXOutput;\n```\n**References:** [JSXOutput](#jsxoutput)", + "mdFile": "core.qwikjsx.element.md" }, { - "name": "HTMLAttributes", - "id": "htmlattributes", + "name": "ElementChildrenAttribute", + "id": "qwikjsx-elementchildrenattribute", "hierarchy": [ { - "name": "HTMLAttributes", - "id": "htmlattributes" + "name": "QwikJSX", + "id": "qwikjsx-elementchildrenattribute" + }, + { + "name": "ElementChildrenAttribute", + "id": "qwikjsx-elementchildrenattribute" } ], "kind": "Interface", - "content": "```typescript\nexport interface HTMLAttributes extends HTMLElementAttrs, DOMAttributes \n```\n**Extends:** [HTMLElementAttrs](#htmlelementattrs), [DOMAttributes](#domattributes)<E>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.htmlattributes.md" + "content": "```typescript\ninterface ElementChildrenAttribute \n```\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[children](#)\n\n\n\n\n\n\n\n[JSXChildren](#jsxchildren)\n\n\n\n\n\n
", + "mdFile": "core.qwikjsx.elementchildrenattribute.md" }, { - "name": "HTMLCrossOriginAttribute", - "id": "htmlcrossoriginattribute", + "name": "ElementType", + "id": "qwikjsx-elementtype", "hierarchy": [ { - "name": "HTMLCrossOriginAttribute", - "id": "htmlcrossoriginattribute" + "name": "QwikJSX", + "id": "qwikjsx-elementtype" + }, + { + "name": "ElementType", + "id": "qwikjsx-elementtype" } ], "kind": "TypeAlias", - "content": "```typescript\nexport type HTMLCrossOriginAttribute = 'anonymous' | 'use-credentials' | '' | undefined;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.htmlcrossoriginattribute.md" + "content": "```typescript\ntype ElementType = string | FunctionComponent>;\n```\n**References:** [FunctionComponent](#functioncomponent)", + "mdFile": "core.qwikjsx.elementtype.md" }, { - "name": "HTMLElementAttrs", - "id": "htmlelementattrs", + "name": "ErrorBoundaryStore", + "id": "errorboundarystore", "hierarchy": [ { - "name": "HTMLElementAttrs", - "id": "htmlelementattrs" + "name": "ErrorBoundaryStore", + "id": "errorboundarystore" } ], "kind": "Interface", - "content": "```typescript\nexport interface HTMLElementAttrs extends HTMLAttributesBase, FilterBase \n```\n**Extends:** HTMLAttributesBase, FilterBase<HTMLElement>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.htmlelementattrs.md" + "content": "```typescript\nexport interface ErrorBoundaryStore \n```\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[error](#)\n\n\n\n\n\n\n\nany \\| undefined\n\n\n\n\n\n
", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/error/error-handling.ts", + "mdFile": "core.errorboundarystore.md" }, { - "name": "HTMLFragment", - "id": "htmlfragment", + "name": "event$", + "id": "event_", "hierarchy": [ { - "name": "HTMLFragment", - "id": "htmlfragment" + "name": "event$", + "id": "event_" } ], - "kind": "Variable", - "content": "```typescript\nHTMLFragment: FunctionComponent<{\n dangerouslySetInnerHTML: string;\n}>\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/jsx-runtime.ts", - "mdFile": "qwik.htmlfragment.md" + "kind": "Function", + "content": "```typescript\nevent$: (qrl: T) => import(\"./qrl.public\").QRL\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\nT\n\n\n\n\n\n
\n**Returns:**\n\nimport(\"./qrl.public\").[QRL](#qrl)<T>", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/qrl.public.dollar.ts", + "mdFile": "core.event_.md" }, { - "name": "HtmlHTMLAttributes", - "id": "htmlhtmlattributes", + "name": "EventHandler", + "id": "eventhandler", "hierarchy": [ { - "name": "HtmlHTMLAttributes", - "id": "htmlhtmlattributes" + "name": "EventHandler", + "id": "eventhandler" } ], - "kind": "Interface", - "content": "```typescript\nexport interface HtmlHTMLAttributes extends Attrs<'html', T> \n```\n**Extends:** Attrs<'html', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.htmlhtmlattributes.md" + "kind": "TypeAlias", + "content": "A DOM event handler\n\n\n```typescript\nexport type EventHandler = {\n bivarianceHack(event: EV, element: EL): any;\n}['bivarianceHack'];\n```", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts", + "mdFile": "core.eventhandler.md" }, { - "name": "HTMLInputAutocompleteAttribute", - "id": "htmlinputautocompleteattribute", + "name": "force", + "id": "computedsignal-force", "hierarchy": [ { - "name": "HTMLInputAutocompleteAttribute", - "id": "htmlinputautocompleteattribute" + "name": "ComputedSignal", + "id": "computedsignal-force" + }, + { + "name": "force", + "id": "computedsignal-force" } ], - "kind": "TypeAlias", - "content": "```typescript\nexport type HTMLInputAutocompleteAttribute = 'on' | 'off' | 'billing' | 'shipping' | 'name' | 'honorific-prefix' | 'given-name' | 'additional-name' | 'family-name' | 'honorific-suffix' | 'nickname' | 'username' | 'new-password' | 'current-password' | 'one-time-code' | 'organization-title' | 'organization' | 'street-address' | 'address-line1' | 'address-line2' | 'address-line3' | 'address-level4' | 'address-level3' | 'address-level2' | 'address-level1' | 'country' | 'country-name' | 'postal-code' | 'cc-name' | 'cc-given-name' | 'cc-additional-name' | 'cc-family-name' | 'cc-number' | 'cc-exp' | 'cc-exp-month' | 'cc-exp-year' | 'cc-csc' | 'cc-type' | 'transaction-currency' | 'transaction-amount' | 'language' | 'bday' | 'bday-day' | 'bday-month' | 'bday-year' | 'sex' | 'url' | 'photo';\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.htmlinputautocompleteattribute.md" + "kind": "MethodSignature", + "content": "Use this to force recalculation and running subscribers, for example when the calculated value mutates but remains the same object. Useful for third-party libraries.\n\n\n```typescript\nforce(): void;\n```\n**Returns:**\n\nvoid", + "mdFile": "core.computedsignal.force.md" + }, + { + "name": "Fragment", + "id": "fragment", + "hierarchy": [ + { + "name": "Fragment", + "id": "fragment" + } + ], + "kind": "Variable", + "content": "```typescript\nFragment: FunctionComponent<{\n children?: any;\n key?: string | number | null;\n}>\n```", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/jsx-runtime.ts", + "mdFile": "core.fragment.md" }, { - "name": "HTMLInputTypeAttribute", - "id": "htmlinputtypeattribute", + "name": "FunctionComponent", + "id": "functioncomponent", "hierarchy": [ { - "name": "HTMLInputTypeAttribute", - "id": "htmlinputtypeattribute" + "name": "FunctionComponent", + "id": "functioncomponent" } ], "kind": "TypeAlias", - "content": "```typescript\nexport type HTMLInputTypeAttribute = 'button' | 'checkbox' | 'color' | 'date' | 'datetime-local' | 'email' | 'file' | 'hidden' | 'image' | 'month' | 'number' | 'password' | 'radio' | 'range' | 'reset' | 'search' | 'submit' | 'tel' | 'text' | 'time' | 'url' | 'week' | (string & {});\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.htmlinputtypeattribute.md" + "content": "Any function taking a props object that returns JSXOutput.\n\nThe `key`, `flags` and `dev` parameters are for internal use.\n\n\n```typescript\nexport type FunctionComponent

= {\n renderFn(props: P, key: string | null, flags: number, dev?: DevJSX): JSXOutput;\n}['renderFn'];\n```\n**References:** [DevJSX](#devjsx), [JSXOutput](#jsxoutput)", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-node.ts", + "mdFile": "core.functioncomponent.md" }, { - "name": "IframeHTMLAttributes", - "id": "iframehtmlattributes", + "name": "getDomContainer", + "id": "getdomcontainer", "hierarchy": [ { - "name": "IframeHTMLAttributes", - "id": "iframehtmlattributes" + "name": "getDomContainer", + "id": "getdomcontainer" } ], - "kind": "Interface", - "content": "```typescript\nexport interface IframeHTMLAttributes extends Attrs<'iframe', T> \n```\n**Extends:** Attrs<'iframe', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.iframehtmlattributes.md" + "kind": "Function", + "content": "```typescript\nexport declare function getDomContainer(element: Element | VNode): IClientContainer;\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nelement\n\n\n\n\nElement \\| VNode\n\n\n\n\n\n
\n**Returns:**\n\nIClientContainer", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/client/dom-container.ts", + "mdFile": "core.getdomcontainer.md" }, { - "name": "ImgHTMLAttributes", - "id": "imghtmlattributes", + "name": "getLocale", + "id": "getlocale", "hierarchy": [ { - "name": "ImgHTMLAttributes", - "id": "imghtmlattributes" + "name": "getLocale", + "id": "getlocale" } ], - "kind": "Interface", - "content": "```typescript\nexport interface ImgHTMLAttributes extends Attrs<'img', T> \n```\n**Extends:** Attrs<'img', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.imghtmlattributes.md" + "kind": "Function", + "content": "Retrieve the current locale.\n\nIf no current locale and there is no `defaultLocale` the function throws an error.\n\n\n```typescript\nexport declare function getLocale(defaultLocale?: string): string;\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\ndefaultLocale\n\n\n\n\nstring\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nstring\n\nThe locale.", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-locale.ts", + "mdFile": "core.getlocale.md" }, { - "name": "implicit$FirstArg", - "id": "implicit_firstarg", + "name": "getPlatform", + "id": "getplatform", "hierarchy": [ { - "name": "implicit$FirstArg", - "id": "implicit_firstarg" + "name": "getPlatform", + "id": "getplatform" } ], "kind": "Function", - "content": "Create a `____$(...)` convenience method from `___(...)`.\n\nIt is very common for functions to take a lazy-loadable resource as a first argument. For this reason, the Qwik Optimizer automatically extracts the first argument from any function which ends in `$`.\n\nThis means that `foo$(arg0)` and `foo($(arg0))` are equivalent with respect to Qwik Optimizer. The former is just a shorthand for the latter.\n\nFor example, these function calls are equivalent:\n\n- `component$(() => {...})` is same as `component($(() => {...}))`\n\n```tsx\nexport function myApi(callback: QRL<() => void>): void {\n // ...\n}\n\nexport const myApi$ = implicit$FirstArg(myApi);\n// type of myApi$: (callback: () => void): void\n\n// can be used as:\nmyApi$(() => console.log('callback'));\n\n// will be transpiled to:\n// FILE: \nmyApi(qrl('./chunk-abc.js', 'callback'));\n\n// FILE: chunk-abc.js\nexport const callback = () => console.log('callback');\n```\n\n\n```typescript\nimplicit$FirstArg: (fn: (qrl: QRL, ...rest: REST) => RET) => ((qrl: FIRST, ...rest: REST) => RET)\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nfn\n\n\n\n\n(qrl: [QRL](#qrl)<FIRST>, ...rest: REST) => RET\n\n\n\n\nA function that should have its first argument automatically `$`.\n\n\n
\n**Returns:**\n\n((qrl: FIRST, ...rest: REST) => RET)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/util/implicit_dollar.ts", - "mdFile": "qwik.implicit_firstarg.md" + "content": "Retrieve the `CorePlatform`.\n\nThe `CorePlatform` is also responsible for retrieving the Manifest, that contains mappings from symbols to javascript import chunks. For this reason, `CorePlatform` can't be global, but is specific to the application currently running. On server it is possible that many different applications are running in a single server instance, and for this reason the `CorePlatform` is associated with the application document.\n\n\n```typescript\ngetPlatform: () => CorePlatform\n```\n**Returns:**\n\n[CorePlatform](#coreplatform)", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/platform/platform.ts", + "mdFile": "core.getplatform.md" }, { - "name": "InputHTMLAttributes", - "id": "inputhtmlattributes", + "name": "h", + "id": "h", "hierarchy": [ { - "name": "InputHTMLAttributes", - "id": "inputhtmlattributes" + "name": "h", + "id": "h" } ], - "kind": "TypeAlias", - "content": "```typescript\nexport type InputHTMLAttributes = Attrs<'input', T, HTMLInputElement>;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.inputhtmlattributes.md" + "kind": "Function", + "content": "The legacy transform, used in special cases like `

`. Note that the children are spread arguments, instead of a prop like in jsx() calls.\n\nAlso note that this disables optimizations.\n\n\n```typescript\nexport declare function h, PROPS extends {} = {}>(type: TYPE, props?: PROPS | null, ...children: any[]): JSXNode;\n```\n\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\ntype\n\n\n\n\nTYPE\n\n\n\n\n\n
\n\nprops\n\n\n\n\nPROPS \\| null\n\n\n\n\n_(Optional)_\n\n\n
\n\nchildren\n\n\n\n\nany\\[\\]\n\n\n\n\n\n
\n**Returns:**\n\n[JSXNode](#jsxnode)<TYPE>", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/jsx-runtime.ts", + "mdFile": "core.h.md" }, { - "name": "InsHTMLAttributes", - "id": "inshtmlattributes", + "name": "implicit$FirstArg", + "id": "implicit_firstarg", "hierarchy": [ { - "name": "InsHTMLAttributes", - "id": "inshtmlattributes" + "name": "implicit$FirstArg", + "id": "implicit_firstarg" } ], - "kind": "Interface", - "content": "```typescript\nexport interface InsHTMLAttributes extends Attrs<'ins', T> \n```\n**Extends:** Attrs<'ins', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.inshtmlattributes.md" + "kind": "Function", + "content": "Create a `____$(...)` convenience method from `___(...)`.\n\nIt is very common for functions to take a lazy-loadable resource as a first argument. For this reason, the Qwik Optimizer automatically extracts the first argument from any function which ends in `$`.\n\nThis means that `foo$(arg0)` and `foo($(arg0))` are equivalent with respect to Qwik Optimizer. The former is just a shorthand for the latter.\n\nFor example, these function calls are equivalent:\n\n- `component$(() => {...})` is same as `component($(() => {...}))`\n\n```tsx\nexport function myApi(callback: QRL<() => void>): void {\n // ...\n}\n\nexport const myApi$ = implicit$FirstArg(myApi);\n// type of myApi$: (callback: () => void): void\n\n// can be used as:\nmyApi$(() => console.log('callback'));\n\n// will be transpiled to:\n// FILE: \nmyApi(qrl('./chunk-abc.js', 'callback'));\n\n// FILE: chunk-abc.js\nexport const callback = () => console.log('callback');\n```\n\n\n```typescript\nimplicit$FirstArg: (fn: (qrl: QRL, ...rest: REST) => RET) => ((qrl: FIRST, ...rest: REST) => RET)\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nfn\n\n\n\n\n(qrl: [QRL](#qrl)<FIRST>, ...rest: REST) => RET\n\n\n\n\nA function that should have its first argument automatically `$`.\n\n\n
\n**Returns:**\n\n((qrl: FIRST, ...rest: REST) => RET)", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/implicit_dollar.ts", + "mdFile": "core.implicit_firstarg.md" }, { "name": "IntrinsicAttributes", @@ -1174,21 +514,24 @@ ], "kind": "Interface", "content": "```typescript\ninterface IntrinsicAttributes extends QwikIntrinsicAttributes \n```\n**Extends:** QwikIntrinsicAttributes", - "mdFile": "qwik.qwikjsx.intrinsicattributes.md" + "mdFile": "core.qwikjsx.intrinsicattributes.md" }, { "name": "IntrinsicElements", - "id": "intrinsicelements", + "id": "qwikjsx-intrinsicelements", "hierarchy": [ + { + "name": "QwikJSX", + "id": "qwikjsx-intrinsicelements" + }, { "name": "IntrinsicElements", - "id": "intrinsicelements" + "id": "qwikjsx-intrinsicelements" } ], "kind": "Interface", - "content": "```typescript\nexport interface IntrinsicElements extends IntrinsicHTMLElements, IntrinsicSVGElements \n```\n**Extends:** IntrinsicHTMLElements, IntrinsicSVGElements", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.intrinsicelements.md" + "content": "```typescript\ninterface IntrinsicElements extends LenientQwikElements \n```\n**Extends:** LenientQwikElements", + "mdFile": "core.qwikjsx.intrinsicelements.md" }, { "name": "isSignal", @@ -1200,9 +543,9 @@ } ], "kind": "Function", - "content": "Checks if a given object is a `Signal`.\n\n\n```typescript\nisSignal: (obj: any) => obj is Signal\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nobj\n\n\n\n\nany\n\n\n\n\nThe object to check if `Signal`.\n\n\n
\n**Returns:**\n\nobj is [Signal](#signal)<T>\n\nBoolean - True if the object is a `Signal`.", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/state/signal.ts", - "mdFile": "qwik.issignal.md" + "content": "```typescript\nisSignal: (value: any) => value is ISignal\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nvalue\n\n\n\n\nany\n\n\n\n\n\n
\n**Returns:**\n\nvalue is [ISignal](#signal)<unknown>", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.ts", + "mdFile": "core.issignal.md" }, { "name": "jsx", @@ -1214,9 +557,9 @@ } ], "kind": "Function", - "content": "Used by the JSX transpilers to create a JSXNode. Note that the optimizer will not use this, instead using \\_jsxQ, \\_jsxS, and \\_jsxC directly.\n\n\n```typescript\njsx: >(type: T, props: T extends FunctionComponent ? PROPS : Record, key?: string | number | null) => JSXNode\n```\n\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\ntype\n\n\n\n\nT\n\n\n\n\n\n
\n\nprops\n\n\n\n\nT extends [FunctionComponent](#functioncomponent)<infer PROPS> ? PROPS : Record<any, unknown>\n\n\n\n\n\n
\n\nkey\n\n\n\n\nstring \\| number \\| null\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\n[JSXNode](#jsxnode)<T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/jsx-runtime.ts", - "mdFile": "qwik.jsx.md" + "content": "Used by the JSX transpilers to create a JSXNode. Note that the optimizer will not use this, instead using \\_jsxSplit and \\_jsxSorted directly.\n\n\n```typescript\njsx: >(type: T, props: T extends FunctionComponent ? PROPS : Props, key?: string | number | null) => JSXNode\n```\n\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\ntype\n\n\n\n\nT\n\n\n\n\n\n
\n\nprops\n\n\n\n\nT extends [FunctionComponent](#functioncomponent)<infer PROPS> ? PROPS : Props\n\n\n\n\n\n
\n\nkey\n\n\n\n\nstring \\| number \\| null\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\n[JSXNode](#jsxnode)<T>", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/jsx-runtime.ts", + "mdFile": "core.jsx.md" }, { "name": "JSXChildren", @@ -1229,8 +572,8 @@ ], "kind": "TypeAlias", "content": "```typescript\nexport type JSXChildren = string | number | boolean | null | undefined | Function | RegExp | JSXChildren[] | Promise | Signal | JSXNode;\n```\n**References:** [JSXChildren](#jsxchildren), [Signal](#signal), [JSXNode](#jsxnode)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts", - "mdFile": "qwik.jsxchildren.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts", + "mdFile": "core.jsxchildren.md" }, { "name": "jsxDEV", @@ -1242,9 +585,9 @@ } ], "kind": "Function", - "content": "```typescript\njsxDEV: >>(type: T, props: T extends FunctionComponent ? PROPS : Record, key: string | number | null | undefined, _isStatic: boolean, opts: JsxDevOpts, _ctx: unknown) => JSXNode\n```\n\n\n\n\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\ntype\n\n\n\n\nT\n\n\n\n\n\n
\n\nprops\n\n\n\n\nT extends [FunctionComponent](#functioncomponent)<infer PROPS> ? PROPS : Record<any, unknown>\n\n\n\n\n\n
\n\nkey\n\n\n\n\nstring \\| number \\| null \\| undefined\n\n\n\n\n\n
\n\n\\_isStatic\n\n\n\n\nboolean\n\n\n\n\n\n
\n\nopts\n\n\n\n\nJsxDevOpts\n\n\n\n\n\n
\n\n\\_ctx\n\n\n\n\nunknown\n\n\n\n\n\n
\n**Returns:**\n\n[JSXNode](#jsxnode)<T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/jsx-runtime.ts", - "mdFile": "qwik.jsxdev.md" + "content": "```typescript\njsxDEV: >(type: T, props: T extends FunctionComponent ? PROPS : Props, key: string | number | null | undefined, _isStatic: boolean, opts: JsxDevOpts, _ctx: unknown) => JSXNode\n```\n\n\n\n\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\ntype\n\n\n\n\nT\n\n\n\n\n\n
\n\nprops\n\n\n\n\nT extends [FunctionComponent](#functioncomponent)<infer PROPS> ? PROPS : Props\n\n\n\n\n\n
\n\nkey\n\n\n\n\nstring \\| number \\| null \\| undefined\n\n\n\n\n\n
\n\n\\_isStatic\n\n\n\n\nboolean\n\n\n\n\n\n
\n\nopts\n\n\n\n\nJsxDevOpts\n\n\n\n\n\n
\n\n\\_ctx\n\n\n\n\nunknown\n\n\n\n\n\n
\n**Returns:**\n\n[JSXNode](#jsxnode)<T>", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/jsx-runtime.ts", + "mdFile": "core.jsxdev.md" }, { "name": "JSXNode", @@ -1257,8 +600,8 @@ ], "kind": "Interface", "content": "A JSX Node, an internal structure. You probably want to use `JSXOutput` instead.\n\n\n```typescript\nexport interface JSXNode \n```\n\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[children](#)\n\n\n\n\n\n\n\n[JSXChildren](#jsxchildren) \\| null\n\n\n\n\n\n
\n\n[dev?](#)\n\n\n\n\n\n\n\n[DevJSX](#devjsx)\n\n\n\n\n_(Optional)_\n\n\n
\n\n[key](#)\n\n\n\n\n\n\n\nstring \\| null\n\n\n\n\n\n
\n\n[props](#)\n\n\n\n\n\n\n\nT extends [FunctionComponent](#functioncomponent)<infer P> ? P : Record<any, unknown>\n\n\n\n\n\n
\n\n[type](#)\n\n\n\n\n\n\n\nT\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-node.ts", - "mdFile": "qwik.jsxnode.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-node.ts", + "mdFile": "core.jsxnode.md" }, { "name": "JSXOutput", @@ -1271,8 +614,8 @@ ], "kind": "TypeAlias", "content": "Any valid output for a component\n\n\n```typescript\nexport type JSXOutput = JSXNode | string | number | boolean | null | undefined | JSXOutput[];\n```\n**References:** [JSXNode](#jsxnode), [JSXOutput](#jsxoutput)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-node.ts", - "mdFile": "qwik.jsxoutput.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-node.ts", + "mdFile": "core.jsxoutput.md" }, { "name": "JSXTagName", @@ -1285,22 +628,8 @@ ], "kind": "TypeAlias", "content": "```typescript\nexport type JSXTagName = keyof HTMLElementTagNameMap | Omit;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts", - "mdFile": "qwik.jsxtagname.md" - }, - { - "name": "KeygenHTMLAttributes", - "id": "keygenhtmlattributes", - "hierarchy": [ - { - "name": "KeygenHTMLAttributes", - "id": "keygenhtmlattributes" - } - ], - "kind": "Interface", - "content": "> Warning: This API is now obsolete.\n> \n> in html5\n> \n\n\n```typescript\nexport interface KeygenHTMLAttributes extends Attrs<'base', T> \n```\n**Extends:** Attrs<'base', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.keygenhtmlattributes.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts", + "mdFile": "core.jsxtagname.md" }, { "name": "KnownEventNames", @@ -1313,120 +642,8 @@ ], "kind": "TypeAlias", "content": "The names of events that Qwik knows about. They are all lowercase, but on the JSX side, they are PascalCase for nicer DX. (`onAuxClick$` vs `onauxclick$`)\n\n\n```typescript\nexport type KnownEventNames = LiteralUnion;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.knowneventnames.md" - }, - { - "name": "LabelHTMLAttributes", - "id": "labelhtmlattributes", - "hierarchy": [ - { - "name": "LabelHTMLAttributes", - "id": "labelhtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface LabelHTMLAttributes extends Attrs<'label', T> \n```\n**Extends:** Attrs<'label', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.labelhtmlattributes.md" - }, - { - "name": "LiHTMLAttributes", - "id": "lihtmlattributes", - "hierarchy": [ - { - "name": "LiHTMLAttributes", - "id": "lihtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface LiHTMLAttributes extends Attrs<'li', T> \n```\n**Extends:** Attrs<'li', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.lihtmlattributes.md" - }, - { - "name": "LinkHTMLAttributes", - "id": "linkhtmlattributes", - "hierarchy": [ - { - "name": "LinkHTMLAttributes", - "id": "linkhtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface LinkHTMLAttributes extends Attrs<'link', T> \n```\n**Extends:** Attrs<'link', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.linkhtmlattributes.md" - }, - { - "name": "MapHTMLAttributes", - "id": "maphtmlattributes", - "hierarchy": [ - { - "name": "MapHTMLAttributes", - "id": "maphtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface MapHTMLAttributes extends Attrs<'map', T> \n```\n**Extends:** Attrs<'map', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.maphtmlattributes.md" - }, - { - "name": "MediaHTMLAttributes", - "id": "mediahtmlattributes", - "hierarchy": [ - { - "name": "MediaHTMLAttributes", - "id": "mediahtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface MediaHTMLAttributes extends HTMLAttributes, Augmented \n```\n**Extends:** [HTMLAttributes](#htmlattributes)<T>, Augmented<HTMLMediaElement, { crossOrigin?: [HTMLCrossOriginAttribute](#htmlcrossoriginattribute); }>\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[crossOrigin?](#)\n\n\n\n\n\n\n\n[HTMLCrossOriginAttribute](#htmlcrossoriginattribute)\n\n\n\n\n_(Optional)_\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.mediahtmlattributes.md" - }, - { - "name": "MenuHTMLAttributes", - "id": "menuhtmlattributes", - "hierarchy": [ - { - "name": "MenuHTMLAttributes", - "id": "menuhtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface MenuHTMLAttributes extends Attrs<'menu', T> \n```\n**Extends:** Attrs<'menu', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.menuhtmlattributes.md" - }, - { - "name": "MetaHTMLAttributes", - "id": "metahtmlattributes", - "hierarchy": [ - { - "name": "MetaHTMLAttributes", - "id": "metahtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface MetaHTMLAttributes extends Attrs<'meta', T> \n```\n**Extends:** Attrs<'meta', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.metahtmlattributes.md" - }, - { - "name": "MeterHTMLAttributes", - "id": "meterhtmlattributes", - "hierarchy": [ - { - "name": "MeterHTMLAttributes", - "id": "meterhtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface MeterHTMLAttributes extends Attrs<'meter', T> \n```\n**Extends:** Attrs<'meter', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.meterhtmlattributes.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.knowneventnames.md" }, { "name": "NativeAnimationEvent", @@ -1439,8 +656,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `AnimationEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type NativeAnimationEvent = AnimationEvent;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.nativeanimationevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.nativeanimationevent.md" }, { "name": "NativeClipboardEvent", @@ -1453,8 +670,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `ClipboardEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type NativeClipboardEvent = ClipboardEvent;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.nativeclipboardevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.nativeclipboardevent.md" }, { "name": "NativeCompositionEvent", @@ -1467,8 +684,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `CompositionEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type NativeCompositionEvent = CompositionEvent;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.nativecompositionevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.nativecompositionevent.md" }, { "name": "NativeDragEvent", @@ -1481,8 +698,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `DragEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type NativeDragEvent = DragEvent;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.nativedragevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.nativedragevent.md" }, { "name": "NativeFocusEvent", @@ -1495,8 +712,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `FocusEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type NativeFocusEvent = FocusEvent;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.nativefocusevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.nativefocusevent.md" }, { "name": "NativeKeyboardEvent", @@ -1509,8 +726,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `KeyboardEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type NativeKeyboardEvent = KeyboardEvent;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.nativekeyboardevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.nativekeyboardevent.md" }, { "name": "NativeMouseEvent", @@ -1523,8 +740,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `MouseEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type NativeMouseEvent = MouseEvent;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.nativemouseevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.nativemouseevent.md" }, { "name": "NativePointerEvent", @@ -1537,8 +754,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `PointerEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type NativePointerEvent = PointerEvent;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.nativepointerevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.nativepointerevent.md" }, { "name": "NativeTouchEvent", @@ -1551,8 +768,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `TouchEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type NativeTouchEvent = TouchEvent;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.nativetouchevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.nativetouchevent.md" }, { "name": "NativeTransitionEvent", @@ -1565,8 +782,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `TransitionEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type NativeTransitionEvent = TransitionEvent;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.nativetransitionevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.nativetransitionevent.md" }, { "name": "NativeUIEvent", @@ -1579,8 +796,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `UIEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type NativeUIEvent = UIEvent;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.nativeuievent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.nativeuievent.md" }, { "name": "NativeWheelEvent", @@ -1588,167 +805,69 @@ "hierarchy": [ { "name": "NativeWheelEvent", - "id": "nativewheelevent" - } - ], - "kind": "TypeAlias", - "content": "> Warning: This API is now obsolete.\n> \n> Use `WheelEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type NativeWheelEvent = WheelEvent;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.nativewheelevent.md" - }, - { - "name": "noSerialize", - "id": "noserialize", - "hierarchy": [ - { - "name": "noSerialize", - "id": "noserialize" - } - ], - "kind": "Function", - "content": "Returned type of the `noSerialize()` function. It will be TYPE or undefined.\n\n\n```typescript\nexport type NoSerialize = (T & {\n __no_serialize__: true;\n}) | undefined;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/state/common.ts", - "mdFile": "qwik.noserialize.md" - }, - { - "name": "NoSerialize", - "id": "noserialize", - "hierarchy": [ - { - "name": "NoSerialize", - "id": "noserialize" - } - ], - "kind": "TypeAlias", - "content": "Returned type of the `noSerialize()` function. It will be TYPE or undefined.\n\n\n```typescript\nexport type NoSerialize = (T & {\n __no_serialize__: true;\n}) | undefined;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/state/common.ts", - "mdFile": "qwik.noserialize.md" - }, - { - "name": "Numberish", - "id": "numberish", - "hierarchy": [ - { - "name": "Numberish", - "id": "numberish" - } - ], - "kind": "TypeAlias", - "content": "```typescript\nexport type Numberish = number | `${number}`;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.numberish.md" - }, - { - "name": "ObjectHTMLAttributes", - "id": "objecthtmlattributes", - "hierarchy": [ - { - "name": "ObjectHTMLAttributes", - "id": "objecthtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface ObjectHTMLAttributes extends Attrs<'object', T> \n```\n**Extends:** Attrs<'object', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.objecthtmlattributes.md" - }, - { - "name": "OlHTMLAttributes", - "id": "olhtmlattributes", - "hierarchy": [ - { - "name": "OlHTMLAttributes", - "id": "olhtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface OlHTMLAttributes extends Attrs<'ol', T> \n```\n**Extends:** Attrs<'ol', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.olhtmlattributes.md" - }, - { - "name": "OnRenderFn", - "id": "onrenderfn", - "hierarchy": [ - { - "name": "OnRenderFn", - "id": "onrenderfn" - } - ], - "kind": "TypeAlias", - "content": "```typescript\nexport type OnRenderFn = (props: PROPS) => JSXOutput;\n```\n**References:** [JSXOutput](#jsxoutput)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/component/component.public.ts", - "mdFile": "qwik.onrenderfn.md" - }, - { - "name": "OnVisibleTaskOptions", - "id": "onvisibletaskoptions", - "hierarchy": [ - { - "name": "OnVisibleTaskOptions", - "id": "onvisibletaskoptions" + "id": "nativewheelevent" } ], - "kind": "Interface", - "content": "```typescript\nexport interface OnVisibleTaskOptions \n```\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[strategy?](#)\n\n\n\n\n\n\n\n[VisibleTaskStrategy](#visibletaskstrategy)\n\n\n\n\n_(Optional)_ The strategy to use to determine when the \"VisibleTask\" should first execute.\n\n- `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.\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.onvisibletaskoptions.md" + "kind": "TypeAlias", + "content": "> Warning: This API is now obsolete.\n> \n> Use `WheelEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type NativeWheelEvent = WheelEvent;\n```", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.nativewheelevent.md" }, { - "name": "OptgroupHTMLAttributes", - "id": "optgrouphtmlattributes", + "name": "noSerialize", + "id": "noserialize", "hierarchy": [ { - "name": "OptgroupHTMLAttributes", - "id": "optgrouphtmlattributes" + "name": "noSerialize", + "id": "noserialize" } ], - "kind": "Interface", - "content": "```typescript\nexport interface OptgroupHTMLAttributes extends Attrs<'optgroup', T> \n```\n**Extends:** Attrs<'optgroup', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.optgrouphtmlattributes.md" + "kind": "Function", + "content": "Returned type of the `noSerialize()` function. It will be TYPE or undefined.\n\n\n```typescript\nexport type NoSerialize = (T & {\n __no_serialize__: true;\n}) | undefined;\n```", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/utils/serialize-utils.ts", + "mdFile": "core.noserialize.md" }, { - "name": "OptionHTMLAttributes", - "id": "optionhtmlattributes", + "name": "NoSerialize", + "id": "noserialize", "hierarchy": [ { - "name": "OptionHTMLAttributes", - "id": "optionhtmlattributes" + "name": "NoSerialize", + "id": "noserialize" } ], - "kind": "Interface", - "content": "```typescript\nexport interface OptionHTMLAttributes extends Attrs<'option', T> \n```\n**Extends:** Attrs<'option', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.optionhtmlattributes.md" + "kind": "TypeAlias", + "content": "Returned type of the `noSerialize()` function. It will be TYPE or undefined.\n\n\n```typescript\nexport type NoSerialize = (T & {\n __no_serialize__: true;\n}) | undefined;\n```", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/utils/serialize-utils.ts", + "mdFile": "core.noserialize.md" }, { - "name": "OutputHTMLAttributes", - "id": "outputhtmlattributes", + "name": "OnRenderFn", + "id": "onrenderfn", "hierarchy": [ { - "name": "OutputHTMLAttributes", - "id": "outputhtmlattributes" + "name": "OnRenderFn", + "id": "onrenderfn" } ], - "kind": "Interface", - "content": "```typescript\nexport interface OutputHTMLAttributes extends Attrs<'output', T> \n```\n**Extends:** Attrs<'output', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.outputhtmlattributes.md" + "kind": "TypeAlias", + "content": "```typescript\nexport type OnRenderFn = (props: PROPS) => JSXOutput;\n```\n**References:** [JSXOutput](#jsxoutput)", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/component.public.ts", + "mdFile": "core.onrenderfn.md" }, { - "name": "ParamHTMLAttributes", - "id": "paramhtmlattributes", + "name": "OnVisibleTaskOptions", + "id": "onvisibletaskoptions", "hierarchy": [ { - "name": "ParamHTMLAttributes", - "id": "paramhtmlattributes" + "name": "OnVisibleTaskOptions", + "id": "onvisibletaskoptions" } ], "kind": "Interface", - "content": "> Warning: This API is now obsolete.\n> \n> Old DOM API\n> \n\n\n```typescript\nexport interface ParamHTMLAttributes extends Attrs<'base', T, HTMLParamElement> \n```\n**Extends:** Attrs<'base', T, HTMLParamElement>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.paramhtmlattributes.md" + "content": "```typescript\nexport interface OnVisibleTaskOptions \n```\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[strategy?](#)\n\n\n\n\n\n\n\n[VisibleTaskStrategy](#visibletaskstrategy)\n\n\n\n\n_(Optional)_ The strategy to use to determine when the \"VisibleTask\" should first execute.\n\n- `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.\n\n\n
", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-visible-task.ts", + "mdFile": "core.onvisibletaskoptions.md" }, { "name": "PrefetchGraph", @@ -1760,9 +879,9 @@ } ], "kind": "Function", - "content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nLoad the prefetch graph for the container.\n\nEach Qwik container needs to include its own prefetch graph.\n\n\n```typescript\nPrefetchGraph: (opts?: {\n base?: string;\n manifestHash?: string;\n manifestURL?: string;\n nonce?: string;\n}) => JSXOutput\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nopts\n\n\n\n\n{ base?: string; manifestHash?: string; manifestURL?: string; nonce?: string; }\n\n\n\n\n_(Optional)_ Options for the loading prefetch graph.\n\n- `base` - Base of the graph. For a default installation this will default to the q:base value `/build/`. But if more than one MFE is installed on the page, then each MFE needs to have its own base. - `manifestHash` - Hash of the manifest file to load. If not provided the hash will be extracted from the container attribute `q:manifest-hash` and assume the default build file `${base}/q-bundle-graph-${manifestHash}.json`. - `manifestURL` - URL of the manifest file to load if non-standard bundle graph location name.\n\n\n
\n**Returns:**\n\n[JSXOutput](#jsxoutput)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/components/prefetch.ts", - "mdFile": "qwik.prefetchgraph.md" + "content": "> This API is provided as a beta preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nLoad the prefetch graph for the container.\n\nEach Qwik container needs to include its own prefetch graph.\n\n\n```typescript\nPrefetchGraph: (opts?: {\n base?: string;\n manifestHash?: string;\n manifestURL?: string;\n nonce?: string;\n}) => JSXOutput\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nopts\n\n\n\n\n{ base?: string; manifestHash?: string; manifestURL?: string; nonce?: string; }\n\n\n\n\n_(Optional)_ Options for the loading prefetch graph.\n\n- `base` - Base of the graph. For a default installation this will default to the q:base value `/build/`. But if more than one MFE is installed on the page, then each MFE needs to have its own base. - `manifestHash` - Hash of the manifest file to load. If not provided the hash will be extracted from the container attribute `q:manifest-hash` and assume the default build file `${base}/q-bundle-graph-${manifestHash}.json`. - `manifestURL` - URL of the manifest file to load if non-standard bundle graph location name.\n\n\n
\n**Returns:**\n\n[JSXOutput](#jsxoutput)", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/prefetch-service-worker/prefetch.ts", + "mdFile": "core.prefetchgraph.md" }, { "name": "PrefetchServiceWorker", @@ -1774,37 +893,9 @@ } ], "kind": "Function", - "content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nInstall a service worker which will prefetch the bundles.\n\nThere can only be one service worker per page. Because there can be many separate Qwik Containers on the page each container needs to load its prefetch graph using `PrefetchGraph` component.\n\n\n```typescript\nPrefetchServiceWorker: (opts: {\n base?: string;\n scope?: string;\n path?: string;\n verbose?: boolean;\n fetchBundleGraph?: boolean;\n nonce?: string;\n}) => JSXNode<'script'>\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nopts\n\n\n\n\n{ base?: string; scope?: string; path?: string; verbose?: boolean; fetchBundleGraph?: boolean; nonce?: string; }\n\n\n\n\nOptions for the prefetch service worker.\n\n- `base` - Base URL for the service worker `import.meta.env.BASE_URL` or `/`. Default is `import.meta.env.BASE_URL` - `scope` - Base URL for when the service-worker will activate. Default is `/` - `path` - Path to the service worker. Default is `qwik-prefetch-service-worker.js` unless you pass a path that starts with a `/` then the base is ignored. Default is `qwik-prefetch-service-worker.js` - `verbose` - Verbose logging for the service worker installation. Default is `false` - `nonce` - Optional nonce value for security purposes, defaults to `undefined`.\n\n\n
\n**Returns:**\n\n[JSXNode](#jsxnode)<'script'>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/components/prefetch.ts", - "mdFile": "qwik.prefetchserviceworker.md" - }, - { - "name": "ProgressHTMLAttributes", - "id": "progresshtmlattributes", - "hierarchy": [ - { - "name": "ProgressHTMLAttributes", - "id": "progresshtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface ProgressHTMLAttributes extends Attrs<'progress', T> \n```\n**Extends:** Attrs<'progress', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.progresshtmlattributes.md" - }, - { - "name": "PropFnInterface", - "id": "propfninterface", - "hierarchy": [ - { - "name": "PropFnInterface", - "id": "propfninterface" - } - ], - "kind": "TypeAlias", - "content": "> Warning: This API is now obsolete.\n> \n> Use `QRL<>` instead\n> \n\n\n```typescript\nexport type PropFnInterface = {\n __qwik_serializable__?: any;\n (...args: ARGS): Promise;\n};\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts", - "mdFile": "qwik.propfninterface.md" + "content": "> This API is provided as a beta preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nInstall a service worker which will prefetch the bundles.\n\nThere can only be one service worker per page. Because there can be many separate Qwik Containers on the page each container needs to load its prefetch graph using `PrefetchGraph` component.\n\n\n```typescript\nPrefetchServiceWorker: (opts: {\n base?: string;\n scope?: string;\n path?: string;\n verbose?: boolean;\n fetchBundleGraph?: boolean;\n nonce?: string;\n}) => JSXOutput\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nopts\n\n\n\n\n{ base?: string; scope?: string; path?: string; verbose?: boolean; fetchBundleGraph?: boolean; nonce?: string; }\n\n\n\n\nOptions for the prefetch service worker.\n\n- `base` - Base URL for the service worker. Default is `import.meta.env.BASE_URL`, which is defined by Vite's `config.base` and defaults to `/`. - `scope` - Base URL for when the service-worker will activate. Default is `/` - `path` - Path to the service worker. Default is `qwik-prefetch-service-worker.js` unless you pass a path that starts with a `/` then the base is ignored. Default is `qwik-prefetch-service-worker.js` - `verbose` - Verbose logging for the service worker installation. Default is `false` - `nonce` - Optional nonce value for security purposes, defaults to `undefined`.\n\n\n
\n**Returns:**\n\n[JSXOutput](#jsxoutput)", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/prefetch-service-worker/prefetch.ts", + "mdFile": "core.prefetchserviceworker.md" }, { "name": "PropFunction", @@ -1817,22 +908,8 @@ ], "kind": "TypeAlias", "content": "Alias for `QRL`. Of historic relevance only.\n\n\n```typescript\nexport type PropFunction = QRL;\n```\n**References:** [QRL](#qrl)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts", - "mdFile": "qwik.propfunction.md" - }, - { - "name": "PropFunctionProps", - "id": "propfunctionprops", - "hierarchy": [ - { - "name": "PropFunctionProps", - "id": "propfunctionprops" - } - ], - "kind": "TypeAlias", - "content": "> Warning: This API is now obsolete.\n> \n> Use `QRL<>` on your function props instead\n> \n\n\n```typescript\nexport type PropFunctionProps> = {\n [K in keyof PROPS]: PROPS[K] extends undefined ? PROPS[K] : PROPS[K] extends ((...args: infer ARGS) => infer RET) | undefined ? PropFnInterface> : PROPS[K];\n};\n```\n**References:** [PropFnInterface](#propfninterface)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/component/component.public.ts", - "mdFile": "qwik.propfunctionprops.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/qrl.public.ts", + "mdFile": "core.propfunction.md" }, { "name": "PropsOf", @@ -1845,8 +922,8 @@ ], "kind": "TypeAlias", "content": "Infers `Props` from the component or tag.\n\n\n```typescript\nexport type PropsOf = COMP extends string ? COMP extends keyof QwikIntrinsicElements ? QwikIntrinsicElements[COMP] : QwikIntrinsicElements['span'] : NonNullable extends never ? never : COMP extends FunctionComponent ? PROPS extends Record ? IsAny extends true ? never : ObjectProps : COMP extends Component ? ObjectProps : PROPS : never;\n```\n**References:** [QwikIntrinsicElements](#qwikintrinsicelements), [FunctionComponent](#functioncomponent), [Component](#component)\n\n\n\n```tsx\nconst Desc = component$(({desc, ...props}: { desc: string } & PropsOf<'div'>) => {\n return
{desc}
;\n});\n\nconst TitleBox = component$(({title, ...props}: { title: string } & PropsOf) => {\n return

{title}

;\n});\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/component/component.public.ts", - "mdFile": "qwik.propsof.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/component.public.ts", + "mdFile": "core.propsof.md" }, { "name": "PublicProps", @@ -1859,8 +936,8 @@ ], "kind": "TypeAlias", "content": "Extends the defined component PROPS, adding the default ones (children and q:slot) and allowing plain functions to QRL arguments.\n\n\n```typescript\nexport type PublicProps = (PROPS extends Record ? Omit & _Only$ : unknown extends PROPS ? {} : PROPS) & ComponentBaseProps & ComponentChildren;\n```\n**References:** [ComponentBaseProps](#componentbaseprops)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/component/component.public.ts", - "mdFile": "qwik.publicprops.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/component.public.ts", + "mdFile": "core.publicprops.md" }, { "name": "qrl", @@ -1873,8 +950,8 @@ ], "kind": "Function", "content": "The `QRL` type represents a lazy-loadable AND serializable resource.\n\nQRL stands for Qwik URL.\n\nUse `QRL` when you want to refer to a lazy-loaded resource. `QRL`s are most often used for code (functions) but can also be used for other resources such as `string`s in the case of styles.\n\n`QRL` is an opaque token that is generated by the Qwik Optimizer. (Do not rely on any properties in `QRL` as it may change between versions.)\n\n\\#\\# Creating `QRL` references\n\nCreating `QRL` is done using `$(...)` function. `$(...)` is a special marker for the Qwik Optimizer that marks that the code should be extracted into a lazy-loaded symbol.\n\n```tsx\nuseOnDocument(\n 'mousemove',\n $((event) => console.log('mousemove', event))\n);\n```\nIn the above code, the Qwik Optimizer detects `$(...)` and transforms the code as shown below:\n\n```tsx\n// FILE: \nuseOnDocument('mousemove', qrl('./chunk-abc.js', 'onMousemove'));\n\n// FILE: chunk-abc.js\nexport const onMousemove = () => console.log('mousemove');\n```\nNOTE: `qrl(...)` is a result of Qwik Optimizer transformation. You should never have to invoke this function directly in your application. The `qrl(...)` function should be invoked only after the Qwik Optimizer transformation.\n\n\\#\\# Using `QRL`s\n\nUse `QRL` type in your application when you want to get a lazy-loadable reference to a resource (most likely a function).\n\n```tsx\n// Example of declaring a custom functions which takes callback as QRL.\nexport function useMyFunction(callback: QRL<() => void>) {\n doExtraStuff();\n // The callback passed to `onDocument` requires `QRL`.\n useOnDocument('mousemove', callback);\n}\n```\nIn the above example, the way to think about the code is that you are not asking for a callback function but rather a reference to a lazy-loadable callback function. Specifically, the function loading should be delayed until it is actually needed. In the above example, the function would not load until after a `mousemove` event on `document` fires.\n\n\\#\\# Resolving `QRL` references\n\nAt times it may be necessary to resolve a `QRL` reference to the actual value. This can be performed using `QRL.resolve(..)` function.\n\n```tsx\n// Assume you have QRL reference to a greet function\nconst lazyGreet: QRL<() => void> = $(() => console.log('Hello World!'));\n\n// Use `qrlImport` to load / resolve the reference.\nconst greet: () => void = await lazyGreet.resolve();\n\n// Invoke it\ngreet();\n```\nNOTE: `element` is needed because `QRL`s are relative and need a base location to resolve against. The base location is encoded in the HTML in the form of `
`.\n\n\\#\\# `QRL.resolved`\n\nOnce `QRL.resolve()` returns, the value is stored under `QRL.resolved`. This allows the value to be used without having to await `QRL.resolve()` again.\n\n\\#\\# Question: Why not just use `import()`?\n\nAt first glance, `QRL` serves the same purpose as `import()`. However, there are three subtle differences that need to be taken into account.\n\n1. `QRL`s must be serializable into HTML. 2. `QRL`s must be resolved by framework relative to `q:base`. 3. `QRL`s must be able to capture lexically scoped variables. 4. `QRL`s encapsulate the difference between running with and without Qwik Optimizer. 5. `QRL`s allow expressing lazy-loaded boundaries without thinking about chunk and symbol names.\n\nLet's assume that you intend to write code such as this:\n\n```tsx\nreturn \n
\n```\n1. Notice there is no easy way to extract chunk (`./chunk-abc.js`) and symbol (`onClick`) into HTML. 2. Notice that even if you could extract it, the `import('./chunk-abc.js')` would become relative to where the `import()` file is declared. Because it is our framework doing the load, the `./chunk-abc.js` would become relative to the framework file. This is not correct, as it should be relative to the original file generated by the bundler. 3. Next, the framework needs to resolve the `./chunk-abc.js` and needs a base location that is encoded in the HTML. 4. The QRL needs to be able to capture lexically scoped variables. (`import()` only allows loading top-level symbols which don't capture variables.) 5. As a developer, you don't want to think about `import` and naming the chunks and symbols. You just want to say: \"this should be lazy.\"\n\nThese are the main reasons why Qwik introduces its own concept of `QRL`.\n\n\n```typescript\nexport type QRL = {\n __qwik_serializable__?: any;\n __brand__QRL__: TYPE;\n resolve(): Promise;\n resolved: undefined | TYPE;\n getCaptured(): unknown[] | null;\n getSymbol(): string;\n getHash(): string;\n dev: QRLDev | null;\n} & BivariantQrlFn, QrlReturn>;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.ts", - "mdFile": "qwik.qrl.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/qrl.ts", + "mdFile": "core.qrl.md" }, { "name": "QRL", @@ -1887,8 +964,8 @@ ], "kind": "TypeAlias", "content": "The `QRL` type represents a lazy-loadable AND serializable resource.\n\nQRL stands for Qwik URL.\n\nUse `QRL` when you want to refer to a lazy-loaded resource. `QRL`s are most often used for code (functions) but can also be used for other resources such as `string`s in the case of styles.\n\n`QRL` is an opaque token that is generated by the Qwik Optimizer. (Do not rely on any properties in `QRL` as it may change between versions.)\n\n\\#\\# Creating `QRL` references\n\nCreating `QRL` is done using `$(...)` function. `$(...)` is a special marker for the Qwik Optimizer that marks that the code should be extracted into a lazy-loaded symbol.\n\n```tsx\nuseOnDocument(\n 'mousemove',\n $((event) => console.log('mousemove', event))\n);\n```\nIn the above code, the Qwik Optimizer detects `$(...)` and transforms the code as shown below:\n\n```tsx\n// FILE: \nuseOnDocument('mousemove', qrl('./chunk-abc.js', 'onMousemove'));\n\n// FILE: chunk-abc.js\nexport const onMousemove = () => console.log('mousemove');\n```\nNOTE: `qrl(...)` is a result of Qwik Optimizer transformation. You should never have to invoke this function directly in your application. The `qrl(...)` function should be invoked only after the Qwik Optimizer transformation.\n\n\\#\\# Using `QRL`s\n\nUse `QRL` type in your application when you want to get a lazy-loadable reference to a resource (most likely a function).\n\n```tsx\n// Example of declaring a custom functions which takes callback as QRL.\nexport function useMyFunction(callback: QRL<() => void>) {\n doExtraStuff();\n // The callback passed to `onDocument` requires `QRL`.\n useOnDocument('mousemove', callback);\n}\n```\nIn the above example, the way to think about the code is that you are not asking for a callback function but rather a reference to a lazy-loadable callback function. Specifically, the function loading should be delayed until it is actually needed. In the above example, the function would not load until after a `mousemove` event on `document` fires.\n\n\\#\\# Resolving `QRL` references\n\nAt times it may be necessary to resolve a `QRL` reference to the actual value. This can be performed using `QRL.resolve(..)` function.\n\n```tsx\n// Assume you have QRL reference to a greet function\nconst lazyGreet: QRL<() => void> = $(() => console.log('Hello World!'));\n\n// Use `qrlImport` to load / resolve the reference.\nconst greet: () => void = await lazyGreet.resolve();\n\n// Invoke it\ngreet();\n```\nNOTE: `element` is needed because `QRL`s are relative and need a base location to resolve against. The base location is encoded in the HTML in the form of `
`.\n\n\\#\\# `QRL.resolved`\n\nOnce `QRL.resolve()` returns, the value is stored under `QRL.resolved`. This allows the value to be used without having to await `QRL.resolve()` again.\n\n\\#\\# Question: Why not just use `import()`?\n\nAt first glance, `QRL` serves the same purpose as `import()`. However, there are three subtle differences that need to be taken into account.\n\n1. `QRL`s must be serializable into HTML. 2. `QRL`s must be resolved by framework relative to `q:base`. 3. `QRL`s must be able to capture lexically scoped variables. 4. `QRL`s encapsulate the difference between running with and without Qwik Optimizer. 5. `QRL`s allow expressing lazy-loaded boundaries without thinking about chunk and symbol names.\n\nLet's assume that you intend to write code such as this:\n\n```tsx\nreturn \n
\n```\n1. Notice there is no easy way to extract chunk (`./chunk-abc.js`) and symbol (`onClick`) into HTML. 2. Notice that even if you could extract it, the `import('./chunk-abc.js')` would become relative to where the `import()` file is declared. Because it is our framework doing the load, the `./chunk-abc.js` would become relative to the framework file. This is not correct, as it should be relative to the original file generated by the bundler. 3. Next, the framework needs to resolve the `./chunk-abc.js` and needs a base location that is encoded in the HTML. 4. The QRL needs to be able to capture lexically scoped variables. (`import()` only allows loading top-level symbols which don't capture variables.) 5. As a developer, you don't want to think about `import` and naming the chunks and symbols. You just want to say: \"this should be lazy.\"\n\nThese are the main reasons why Qwik introduces its own concept of `QRL`.\n\n\n```typescript\nexport type QRL = {\n __qwik_serializable__?: any;\n __brand__QRL__: TYPE;\n resolve(): Promise;\n resolved: undefined | TYPE;\n getCaptured(): unknown[] | null;\n getSymbol(): string;\n getHash(): string;\n dev: QRLDev | null;\n} & BivariantQrlFn, QrlReturn>;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts", - "mdFile": "qwik.qrl.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/qrl.public.ts", + "mdFile": "core.qrl.md" }, { "name": "QRLEventHandlerMulti", @@ -1900,23 +977,9 @@ } ], "kind": "TypeAlias", - "content": "> This API is provided as a beta preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nAn event handler for Qwik events, can be a handler QRL or an array of handler QRLs.\n\n\n```typescript\nexport type QRLEventHandlerMulti = QRL> | undefined | null | QRLEventHandlerMulti[] | EventHandler;\n```\n**References:** [QRL](#qrl), [EventHandler](#eventhandler), [QRLEventHandlerMulti](#qrleventhandlermulti)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts", - "mdFile": "qwik.qrleventhandlermulti.md" - }, - { - "name": "QuoteHTMLAttributes", - "id": "quotehtmlattributes", - "hierarchy": [ - { - "name": "QuoteHTMLAttributes", - "id": "quotehtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface QuoteHTMLAttributes extends Attrs<'q', T> \n```\n**Extends:** Attrs<'q', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.quotehtmlattributes.md" + "content": "An event handler for Qwik events, can be a handler QRL or an array of handler QRLs.\n\n\n```typescript\nexport type QRLEventHandlerMulti = QRL> | undefined | null | QRLEventHandlerMulti[] | EventHandler;\n```\n**References:** [QRL](#qrl), [EventHandler](#eventhandler), [QRLEventHandlerMulti](#qrleventhandlermulti)", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts", + "mdFile": "core.qrleventhandlermulti.md" }, { "name": "QwikAnimationEvent", @@ -1929,8 +992,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `AnimationEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type QwikAnimationEvent = NativeAnimationEvent;\n```\n**References:** [NativeAnimationEvent](#nativeanimationevent)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwikanimationevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwikanimationevent.md" }, { "name": "QwikAttributes", @@ -1943,8 +1006,8 @@ ], "kind": "Interface", "content": "The Qwik DOM attributes without plain handlers, for use as function parameters\n\n\n```typescript\nexport interface QwikAttributes extends DOMAttributesBase, QwikEvents \n```\n**Extends:** DOMAttributesBase<EL>, QwikEvents<EL, false>\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[class?](#)\n\n\n\n\n\n\n\n[ClassList](#classlist) \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts", - "mdFile": "qwik.qwikattributes.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts", + "mdFile": "core.qwikattributes.md" }, { "name": "QwikChangeEvent", @@ -1957,8 +1020,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `Event` and use the second argument to the handler function for the current event target. Also note that in Qwik, onInput$ with the InputEvent is the event that behaves like onChange in React.\n> \n\n\n```typescript\nexport type QwikChangeEvent = Event;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwikchangeevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwikchangeevent.md" }, { "name": "QwikClipboardEvent", @@ -1971,8 +1034,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `ClipboardEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type QwikClipboardEvent = NativeClipboardEvent;\n```\n**References:** [NativeClipboardEvent](#nativeclipboardevent)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwikclipboardevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwikclipboardevent.md" }, { "name": "QwikCompositionEvent", @@ -1985,8 +1048,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `CompositionEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type QwikCompositionEvent = NativeCompositionEvent;\n```\n**References:** [NativeCompositionEvent](#nativecompositionevent)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwikcompositionevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwikcompositionevent.md" }, { "name": "QwikDOMAttributes", @@ -1999,8 +1062,8 @@ ], "kind": "Interface", "content": "```typescript\nexport interface QwikDOMAttributes extends DOMAttributes \n```\n**Extends:** [DOMAttributes](#domattributes)<Element>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik.ts", - "mdFile": "qwik.qwikdomattributes.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik.ts", + "mdFile": "core.qwikdomattributes.md" }, { "name": "QwikDragEvent", @@ -2013,8 +1076,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `DragEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type QwikDragEvent = NativeDragEvent;\n```\n**References:** [NativeDragEvent](#nativedragevent)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwikdragevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwikdragevent.md" }, { "name": "QwikFocusEvent", @@ -2027,8 +1090,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `FocusEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type QwikFocusEvent = NativeFocusEvent;\n```\n**References:** [NativeFocusEvent](#nativefocusevent)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwikfocusevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwikfocusevent.md" }, { "name": "QwikHTMLElements", @@ -2040,9 +1103,9 @@ } ], "kind": "TypeAlias", - "content": "The DOM props without plain handlers, for use inside functions\n\n\n```typescript\nexport type QwikHTMLElements = {\n [tag in keyof HTMLElementTagNameMap]: Augmented & HTMLElementAttrs & QwikAttributes;\n};\n```\n**References:** [HTMLElementAttrs](#htmlelementattrs), [QwikAttributes](#qwikattributes)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.qwikhtmlelements.md" + "content": "The DOM props without plain handlers, for use inside functions\n\n\n```typescript\nexport type QwikHTMLElements = {\n [tag in keyof HTMLElementTagNameMap]: Augmented & HTMLElementAttrs & QwikAttributes;\n};\n```\n**References:** [QwikAttributes](#qwikattributes)", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-generated.ts", + "mdFile": "core.qwikhtmlelements.md" }, { "name": "QwikIdleEvent", @@ -2055,8 +1118,8 @@ ], "kind": "TypeAlias", "content": "Emitted by qwik-loader on document when the document first becomes idle\n\n\n```typescript\nexport type QwikIdleEvent = CustomEvent<{}>;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwikidleevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwikidleevent.md" }, { "name": "QwikInitEvent", @@ -2069,8 +1132,8 @@ ], "kind": "TypeAlias", "content": "Emitted by qwik-loader on document when the document first becomes interactive\n\n\n```typescript\nexport type QwikInitEvent = CustomEvent<{}>;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwikinitevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwikinitevent.md" }, { "name": "QwikIntrinsicElements", @@ -2082,9 +1145,9 @@ } ], "kind": "Interface", - "content": "The interface holds available attributes of both native DOM elements and custom Qwik elements. An example showing how to define a customizable wrapper component:\n\n```tsx\nimport { component$, Slot, type QwikIntrinsicElements } from \"@builder.io/qwik\";\n\ntype WrapperProps = {\n attributes?: QwikIntrinsicElements[\"div\"];\n};\n\nexport default component$(({ attributes }) => {\n return (\n
\n \n
\n );\n});\n```\nNote: It is shorter to use `PropsOf<'div'>`\n\n\n```typescript\nexport interface QwikIntrinsicElements extends QwikHTMLElements, QwikSVGElements \n```\n**Extends:** [QwikHTMLElements](#qwikhtmlelements), [QwikSVGElements](#qwiksvgelements)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-elements.ts", - "mdFile": "qwik.qwikintrinsicelements.md" + "content": "The interface holds available attributes of both native DOM elements and custom Qwik elements. An example showing how to define a customizable wrapper component:\n\n```tsx\nimport { component$, Slot, type QwikIntrinsicElements } from \"@qwik.dev/core\";\n\ntype WrapperProps = {\n attributes?: QwikIntrinsicElements[\"div\"];\n};\n\nexport default component$(({ attributes }) => {\n return (\n
\n \n
\n );\n});\n```\nNote: It is shorter to use `PropsOf<'div'>`\n\n\n```typescript\nexport interface QwikIntrinsicElements extends QwikHTMLElements, QwikSVGElements \n```\n**Extends:** [QwikHTMLElements](#qwikhtmlelements), [QwikSVGElements](#qwiksvgelements)", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-elements.ts", + "mdFile": "core.qwikintrinsicelements.md" }, { "name": "QwikInvalidEvent", @@ -2097,8 +1160,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `Event` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type QwikInvalidEvent = Event;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwikinvalidevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwikinvalidevent.md" }, { "name": "QwikJSX", @@ -2110,9 +1173,9 @@ } ], "kind": "Namespace", - "content": "```typescript\nexport declare namespace QwikJSX \n```\n\n\n\n\n\n\n
\n\nInterface\n\n\n\n\nDescription\n\n\n
\n\n[ElementChildrenAttribute](#qwikjsx-elementchildrenattribute)\n\n\n\n\n\n
\n\n[IntrinsicAttributes](#qwikjsx-intrinsicattributes)\n\n\n\n\n\n
\n\n[IntrinsicElements](#)\n\n\n\n\n\n
\n\n\n\n\n\n
\n\nType Alias\n\n\n\n\nDescription\n\n\n
\n\n[Element](#qwikjsx-element)\n\n\n\n\n\n
\n\n[ElementType](#qwikjsx-elementtype)\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik.ts", - "mdFile": "qwik.qwikjsx.md" + "content": "```typescript\nexport declare namespace QwikJSX \n```\n\n\n\n\n\n\n
\n\nInterface\n\n\n\n\nDescription\n\n\n
\n\n[ElementChildrenAttribute](#qwikjsx-elementchildrenattribute)\n\n\n\n\n\n
\n\n[IntrinsicAttributes](#qwikjsx-intrinsicattributes)\n\n\n\n\n\n
\n\n[IntrinsicElements](#qwikjsx-intrinsicelements)\n\n\n\n\n\n
\n\n\n\n\n\n
\n\nType Alias\n\n\n\n\nDescription\n\n\n
\n\n[Element](#qwikjsx-element)\n\n\n\n\n\n
\n\n[ElementType](#qwikjsx-elementtype)\n\n\n\n\n\n
", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik.ts", + "mdFile": "core.qwikjsx.md" }, { "name": "QwikKeyboardEvent", @@ -2125,8 +1188,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `KeyboardEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type QwikKeyboardEvent = NativeKeyboardEvent;\n```\n**References:** [NativeKeyboardEvent](#nativekeyboardevent)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwikkeyboardevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwikkeyboardevent.md" }, { "name": "QwikMouseEvent", @@ -2139,8 +1202,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `MouseEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type QwikMouseEvent = E;\n```\n**References:** [NativeMouseEvent](#nativemouseevent)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwikmouseevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwikmouseevent.md" }, { "name": "QwikPointerEvent", @@ -2153,8 +1216,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `PointerEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type QwikPointerEvent = NativePointerEvent;\n```\n**References:** [NativePointerEvent](#nativepointerevent)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwikpointerevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwikpointerevent.md" }, { "name": "QwikSubmitEvent", @@ -2167,8 +1230,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `SubmitEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type QwikSubmitEvent = SubmitEvent;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwiksubmitevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwiksubmitevent.md" }, { "name": "QwikSVGElements", @@ -2180,9 +1243,9 @@ } ], "kind": "TypeAlias", - "content": "The SVG props without plain handlers, for use inside functions\n\n\n```typescript\nexport type QwikSVGElements = {\n [K in keyof Omit]: SVGProps;\n};\n```\n**References:** [SVGProps](#svgprops)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.qwiksvgelements.md" + "content": "The SVG props without plain handlers, for use inside functions\n\n\n```typescript\nexport type QwikSVGElements = {\n [K in keyof Omit]: SVGProps;\n};\n```", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-generated.ts", + "mdFile": "core.qwiksvgelements.md" }, { "name": "QwikSymbolEvent", @@ -2194,9 +1257,9 @@ } ], "kind": "TypeAlias", - "content": "Emitted by qwik-loader when a module was lazily loaded\n\n\n```typescript\nexport type QwikSymbolEvent = CustomEvent<{\n symbol: string;\n element: Element;\n reqTime: number;\n}>;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwiksymbolevent.md" + "content": "Emitted by qwik-loader when a module was lazily loaded\n\n\n```typescript\nexport type QwikSymbolEvent = CustomEvent<{\n qBase: string;\n qManifest: string;\n qVersion: string;\n href: string;\n symbol: string;\n element: Element;\n reqTime: number;\n}>;\n```", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwiksymbolevent.md" }, { "name": "QwikTouchEvent", @@ -2209,8 +1272,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `TouchEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type QwikTouchEvent = NativeTouchEvent;\n```\n**References:** [NativeTouchEvent](#nativetouchevent)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwiktouchevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwiktouchevent.md" }, { "name": "QwikTransitionEvent", @@ -2223,8 +1286,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `TransitionEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type QwikTransitionEvent = NativeTransitionEvent;\n```\n**References:** [NativeTransitionEvent](#nativetransitionevent)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwiktransitionevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwiktransitionevent.md" }, { "name": "QwikUIEvent", @@ -2237,8 +1300,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `UIEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type QwikUIEvent = NativeUIEvent;\n```\n**References:** [NativeUIEvent](#nativeuievent)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwikuievent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwikuievent.md" }, { "name": "QwikVisibleEvent", @@ -2251,8 +1314,8 @@ ], "kind": "TypeAlias", "content": "Emitted by qwik-loader when an element becomes visible. Used by `useVisibleTask$`\n\n\n```typescript\nexport type QwikVisibleEvent = CustomEvent;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwikvisibleevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwikvisibleevent.md" }, { "name": "QwikWheelEvent", @@ -2265,8 +1328,8 @@ ], "kind": "TypeAlias", "content": "> Warning: This API is now obsolete.\n> \n> Use `WheelEvent` and use the second argument to the handler function for the current event target\n> \n\n\n```typescript\nexport type QwikWheelEvent = NativeWheelEvent;\n```\n**References:** [NativeWheelEvent](#nativewheelevent)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts", - "mdFile": "qwik.qwikwheelevent.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts", + "mdFile": "core.qwikwheelevent.md" }, { "name": "ReadonlySignal", @@ -2277,10 +1340,10 @@ "id": "readonlysignal" } ], - "kind": "TypeAlias", - "content": "```typescript\nexport type ReadonlySignal = Readonly>;\n```\n**References:** [Signal](#signal)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/state/signal.ts", - "mdFile": "qwik.readonlysignal.md" + "kind": "Interface", + "content": "```typescript\nexport interface ReadonlySignal \n```\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[value](#)\n\n\n\n\n`readonly`\n\n\n\n\nT\n\n\n\n\n\n
", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts", + "mdFile": "core.readonlysignal.md" }, { "name": "render", @@ -2292,9 +1355,9 @@ } ], "kind": "Function", - "content": "Render JSX.\n\nUse this method to render JSX. This function does reconciling which means it always tries to reuse what is already in the DOM (rather then destroy and recreate content.) It returns a cleanup function you could use for cleaning up subscriptions.\n\n\n```typescript\nrender: (parent: Element | Document, jsxOutput: JSXOutput | FunctionComponent, opts?: RenderOptions) => Promise\n```\n\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nparent\n\n\n\n\nElement \\| Document\n\n\n\n\nElement which will act as a parent to `jsxNode`. When possible the rendering will try to reuse existing nodes.\n\n\n
\n\njsxOutput\n\n\n\n\n[JSXOutput](#jsxoutput) \\| [FunctionComponent](#functioncomponent)<any>\n\n\n\n\nJSX to render\n\n\n
\n\nopts\n\n\n\n\n[RenderOptions](#renderoptions)\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nPromise<[RenderResult](#renderresult)>\n\nAn object containing a cleanup function.", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/dom/render.public.ts", - "mdFile": "qwik.render.md" + "content": "Render JSX.\n\nUse this method to render JSX. This function does reconciling which means it always tries to reuse what is already in the DOM (rather then destroy and recreate content.) It returns a cleanup function you could use for cleaning up subscriptions.\n\n\n```typescript\nrender: (parent: Element | Document, jsxNode: JSXOutput | FunctionComponent, opts?: RenderOptions) => Promise\n```\n\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nparent\n\n\n\n\nElement \\| Document\n\n\n\n\nElement which will act as a parent to `jsxNode`. When possible the rendering will try to reuse existing nodes.\n\n\n
\n\njsxNode\n\n\n\n\n[JSXOutput](#jsxoutput) \\| [FunctionComponent](#functioncomponent)<any>\n\n\n\n\nJSX to render\n\n\n
\n\nopts\n\n\n\n\n[RenderOptions](#renderoptions)\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nPromise<[RenderResult](#renderresult)>\n\nAn object containing a cleanup function.", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/client/dom-render.ts", + "mdFile": "core.render.md" }, { "name": "RenderOnce", @@ -2307,8 +1370,8 @@ ], "kind": "Variable", "content": "```typescript\nRenderOnce: FunctionComponent<{\n children?: unknown;\n key?: string | number | null | undefined;\n}>\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/jsx-runtime.ts", - "mdFile": "qwik.renderonce.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/jsx-runtime.ts", + "mdFile": "core.renderonce.md" }, { "name": "RenderOptions", @@ -2321,8 +1384,8 @@ ], "kind": "Interface", "content": "```typescript\nexport interface RenderOptions \n```\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[serverData?](#)\n\n\n\n\n\n\n\nRecord<string, any>\n\n\n\n\n_(Optional)_\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/dom/render.public.ts", - "mdFile": "qwik.renderoptions.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/client/types.ts", + "mdFile": "core.renderoptions.md" }, { "name": "RenderResult", @@ -2335,8 +1398,8 @@ ], "kind": "Interface", "content": "```typescript\nexport interface RenderResult \n```\n\n\n\n\n
\n\nMethod\n\n\n\n\nDescription\n\n\n
\n\n[cleanup()](#renderresult-cleanup)\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/dom/render.public.ts", - "mdFile": "qwik.renderresult.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/client/types.ts", + "mdFile": "core.renderresult.md" }, { "name": "RenderSSROptions", @@ -2348,9 +1411,9 @@ } ], "kind": "Interface", - "content": "```typescript\nexport interface RenderSSROptions \n```\n\n\n\n\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[base?](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n_(Optional)_\n\n\n
\n\n[beforeClose?](#)\n\n\n\n\n\n\n\n(contexts: QContext\\[\\], containerState: ContainerState, containsDynamic: boolean, textNodes: Map<string, string>) => Promise<[JSXNode](#jsxnode)>\n\n\n\n\n_(Optional)_\n\n\n
\n\n[beforeContent?](#)\n\n\n\n\n\n\n\n[JSXNode](#jsxnode)<string>\\[\\]\n\n\n\n\n_(Optional)_\n\n\n
\n\n[containerAttributes](#)\n\n\n\n\n\n\n\nRecord<string, string>\n\n\n\n\n\n
\n\n[containerTagName](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n\n
\n\n[manifestHash](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n\n
\n\n[serverData?](#)\n\n\n\n\n\n\n\nRecord<string, any>\n\n\n\n\n_(Optional)_\n\n\n
\n\n[stream](#)\n\n\n\n\n\n\n\n[StreamWriter](#streamwriter)\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/ssr/render-ssr.ts", - "mdFile": "qwik.renderssroptions.md" + "content": "```typescript\nexport interface RenderSSROptions \n```\n\n\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[base?](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n_(Optional)_\n\n\n
\n\n[containerAttributes](#)\n\n\n\n\n\n\n\nRecord<string, string>\n\n\n\n\n\n
\n\n[containerTagName](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n\n
\n\n[manifestHash](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n\n
\n\n[serverData?](#)\n\n\n\n\n\n\n\nRecord<string, any>\n\n\n\n\n_(Optional)_\n\n\n
\n\n[stream](#)\n\n\n\n\n\n\n\nStreamWriter\n\n\n\n\n\n
", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/ssr/ssr-types.ts", + "mdFile": "core.renderssroptions.md" }, { "name": "Resource", @@ -2362,9 +1425,9 @@ } ], "kind": "Function", - "content": "This method works like an async memoized function that runs whenever some tracked value changes and returns some data.\n\n`useResource` however returns immediate a `ResourceReturn` object that contains the data and a state that indicates if the data is available or not.\n\nThe status can be one of the following:\n\n- 'pending' - the data is not yet available. - 'resolved' - the data is available. - 'rejected' - the data is not available due to an error or timeout.\n\n\\#\\#\\# Example\n\nExample showing how `useResource` to perform a fetch to request the weather, whenever the input city name changes.\n\n```tsx\nconst Cmp = component$(() => {\n const cityS = useSignal('');\n\n const weatherResource = useResource$(async ({ track, cleanup }) => {\n const cityName = track(cityS);\n const abortController = new AbortController();\n cleanup(() => abortController.abort('cleanup'));\n const res = await fetch(`http://weatherdata.com?city=${cityName}`, {\n signal: abortController.signal,\n });\n const data = await res.json();\n return data as { temp: number };\n });\n\n return (\n
\n \n {\n return
Temperature: {weather.temp}
;\n }}\n />\n
\n );\n});\n```\n\n\n```typescript\nResource: (props: ResourceProps) => JSXOutput\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nprops\n\n\n\n\n[ResourceProps](#resourceprops)<T>\n\n\n\n\n\n
\n**Returns:**\n\n[JSXOutput](#jsxoutput)", + "content": "This method works like an async memoized function that runs whenever some tracked value changes and returns some data.\n\n`useResource` however returns immediate a `ResourceReturn` object that contains the data and a state that indicates if the data is available or not.\n\nThe status can be one of the following:\n\n- `pending` - the data is not yet available. - `resolved` - the data is available. - `rejected` - the data is not available due to an error or timeout.\n\nBe 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`.\n\n\\#\\#\\# Example\n\nExample showing how `useResource` to perform a fetch to request the weather, whenever the input city name changes.\n\n```tsx\nconst Cmp = component$(() => {\n const cityS = useSignal('');\n\n const weatherResource = useResource$(async ({ track, cleanup }) => {\n const cityName = track(cityS);\n const abortController = new AbortController();\n cleanup(() => abortController.abort('cleanup'));\n const res = await fetch(`http://weatherdata.com?city=${cityName}`, {\n signal: abortController.signal,\n });\n const data = await res.json();\n return data as { temp: number };\n });\n\n return (\n
\n \n {\n return
Temperature: {weather.temp}
;\n }}\n />\n
\n );\n});\n```\n\n\n```typescript\nResource: (props: ResourceProps) => JSXOutput\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nprops\n\n\n\n\n[ResourceProps](#resourceprops)<T>\n\n\n\n\n\n
\n**Returns:**\n\n[JSXOutput](#jsxoutput)", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts", - "mdFile": "qwik.resource.md" + "mdFile": "core.resource.md" }, { "name": "ResourceCtx", @@ -2377,8 +1440,8 @@ ], "kind": "Interface", "content": "```typescript\nexport interface ResourceCtx \n```\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[previous](#)\n\n\n\n\n`readonly`\n\n\n\n\nT \\| undefined\n\n\n\n\n\n
\n\n[track](#)\n\n\n\n\n`readonly`\n\n\n\n\n[Tracker](#tracker)\n\n\n\n\n\n
\n\n\n\n\n\n
\n\nMethod\n\n\n\n\nDescription\n\n\n
\n\n[cache(policyOrMilliseconds)](#resourcectx-cache)\n\n\n\n\n\n
\n\n[cleanup(callback)](#)\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.resourcectx.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts", + "mdFile": "core.resourcectx.md" }, { "name": "ResourceFn", @@ -2391,8 +1454,8 @@ ], "kind": "TypeAlias", "content": "```typescript\nexport type ResourceFn = (ctx: ResourceCtx) => ValueOrPromise;\n```\n**References:** [ResourceCtx](#resourcectx), [ValueOrPromise](#valueorpromise)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.resourcefn.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts", + "mdFile": "core.resourcefn.md" }, { "name": "ResourceOptions", @@ -2406,7 +1469,7 @@ "kind": "Interface", "content": "Options to pass to `useResource$()`\n\n\n```typescript\nexport interface ResourceOptions \n```\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[timeout?](#)\n\n\n\n\n\n\n\nnumber\n\n\n\n\n_(Optional)_ Timeout in milliseconds. If the resource takes more than the specified millisecond, it will timeout. Resulting on a rejected resource.\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts", - "mdFile": "qwik.resourceoptions.md" + "mdFile": "core.resourceoptions.md" }, { "name": "ResourcePending", @@ -2419,8 +1482,8 @@ ], "kind": "Interface", "content": "```typescript\nexport interface ResourcePending \n```\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[loading](#)\n\n\n\n\n`readonly`\n\n\n\n\nboolean\n\n\n\n\n\n
\n\n[value](#)\n\n\n\n\n`readonly`\n\n\n\n\nPromise<T>\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.resourcepending.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts", + "mdFile": "core.resourcepending.md" }, { "name": "ResourceProps", @@ -2434,7 +1497,7 @@ "kind": "Interface", "content": "```typescript\nexport interface ResourceProps \n```\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[onPending?](#)\n\n\n\n\n\n\n\n() => [JSXOutput](#jsxoutput)\n\n\n\n\n_(Optional)_\n\n\n
\n\n[onRejected?](#)\n\n\n\n\n\n\n\n(reason: Error) => [JSXOutput](#jsxoutput)\n\n\n\n\n_(Optional)_\n\n\n
\n\n[onResolved](#)\n\n\n\n\n\n\n\n(value: T) => [JSXOutput](#jsxoutput)\n\n\n\n\n\n
\n\n[value](#)\n\n\n\n\n`readonly`\n\n\n\n\n[ResourceReturn](#resourcereturn)<T> \\| [Signal](#signal)<Promise<T> \\| T> \\| Promise<T>\n\n\n\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts", - "mdFile": "qwik.resourceprops.md" + "mdFile": "core.resourceprops.md" }, { "name": "ResourceRejected", @@ -2447,8 +1510,8 @@ ], "kind": "Interface", "content": "```typescript\nexport interface ResourceRejected \n```\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[loading](#)\n\n\n\n\n`readonly`\n\n\n\n\nboolean\n\n\n\n\n\n
\n\n[value](#)\n\n\n\n\n`readonly`\n\n\n\n\nPromise<T>\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.resourcerejected.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts", + "mdFile": "core.resourcerejected.md" }, { "name": "ResourceResolved", @@ -2461,8 +1524,8 @@ ], "kind": "Interface", "content": "```typescript\nexport interface ResourceResolved \n```\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[loading](#)\n\n\n\n\n`readonly`\n\n\n\n\nboolean\n\n\n\n\n\n
\n\n[value](#)\n\n\n\n\n`readonly`\n\n\n\n\nPromise<T>\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.resourceresolved.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts", + "mdFile": "core.resourceresolved.md" }, { "name": "ResourceReturn", @@ -2475,36 +1538,8 @@ ], "kind": "TypeAlias", "content": "```typescript\nexport type ResourceReturn = ResourcePending | ResourceResolved | ResourceRejected;\n```\n**References:** [ResourcePending](#resourcepending), [ResourceResolved](#resourceresolved), [ResourceRejected](#resourcerejected)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.resourcereturn.md" - }, - { - "name": "ScriptHTMLAttributes", - "id": "scripthtmlattributes", - "hierarchy": [ - { - "name": "ScriptHTMLAttributes", - "id": "scripthtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface ScriptHTMLAttributes extends Attrs<'script', T> \n```\n**Extends:** Attrs<'script', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.scripthtmlattributes.md" - }, - { - "name": "SelectHTMLAttributes", - "id": "selecthtmlattributes", - "hierarchy": [ - { - "name": "SelectHTMLAttributes", - "id": "selecthtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface SelectHTMLAttributes extends Attrs<'select', T> \n```\n**Extends:** Attrs<'select', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.selecthtmlattributes.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts", + "mdFile": "core.resourcereturn.md" }, { "name": "setPlatform", @@ -2517,8 +1552,8 @@ ], "kind": "Function", "content": "Sets the `CorePlatform`.\n\nThis is useful to override the platform in tests to change the behavior of, `requestAnimationFrame`, and import resolution.\n\n\n```typescript\nsetPlatform: (plt: CorePlatform) => CorePlatform\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nplt\n\n\n\n\n[CorePlatform](#coreplatform)\n\n\n\n\n\n
\n**Returns:**\n\n[CorePlatform](#coreplatform)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/platform/platform.ts", - "mdFile": "qwik.setplatform.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/platform/platform.ts", + "mdFile": "core.setplatform.md" }, { "name": "Signal", @@ -2530,23 +1565,9 @@ } ], "kind": "Interface", - "content": "A signal is a reactive value which can be read and written. When the signal is written, all tasks which are tracking the signal will be re-run and all components that read the signal will be re-rendered.\n\nFurthermore, when a signal value is passed as a prop to a component, the optimizer will automatically forward the signal. This means that `return
hi
` will update the `title` attribute when the signal changes without having to re-render the component.\n\n\n```typescript\nexport interface Signal \n```\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[value](#)\n\n\n\n\n\n\n\nT\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/state/signal.ts", - "mdFile": "qwik.signal.md" - }, - { - "name": "Size", - "id": "size", - "hierarchy": [ - { - "name": "Size", - "id": "size" - } - ], - "kind": "TypeAlias", - "content": "```typescript\nexport type Size = number | string;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.size.md" + "content": "A signal is a reactive value which can be read and written. When the signal is written, all tasks which are tracking the signal will be re-run and all components that read the signal will be re-rendered.\n\nFurthermore, when a signal value is passed as a prop to a component, the optimizer will automatically forward the signal. This means that `return
hi
` will update the `title` attribute when the signal changes without having to re-render the component.\n\n\n```typescript\nexport interface Signal extends ReadonlySignal \n```\n**Extends:** [ReadonlySignal](#readonlysignal)<T>\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[value](#)\n\n\n\n\n\n\n\nT\n\n\n\n\n\n
", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts", + "mdFile": "core.signal.md" }, { "name": "SkipRender", @@ -2559,8 +1580,8 @@ ], "kind": "Variable", "content": "```typescript\nSkipRender: JSXNode\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts", - "mdFile": "qwik.skiprender.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts", + "mdFile": "core.skiprender.md" }, { "name": "Slot", @@ -2572,23 +1593,9 @@ } ], "kind": "Variable", - "content": "Allows to project the children of the current component. can only be used within the context of a component defined with `component$`.\n\n\n```typescript\nSlot: FunctionComponent<{\n name?: string;\n}>\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/slot.public.ts", - "mdFile": "qwik.slot.md" - }, - { - "name": "SlotHTMLAttributes", - "id": "slothtmlattributes", - "hierarchy": [ - { - "name": "SlotHTMLAttributes", - "id": "slothtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface SlotHTMLAttributes extends Attrs<'slot', T> \n```\n**Extends:** Attrs<'slot', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.slothtmlattributes.md" + "content": "Allows to project the children of the current component. can only be used within the context of a component defined with `component$`.\n\n\n```typescript\nSlot: FunctionComponent<{\n name?: string;\n children?: JSXChildren;\n}>\n```", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/slot.public.ts", + "mdFile": "core.slot.md" }, { "name": "SnapshotListener", @@ -2601,8 +1608,8 @@ ], "kind": "Interface", "content": "```typescript\nexport interface SnapshotListener \n```\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[el](#)\n\n\n\n\n\n\n\nElement\n\n\n\n\n\n
\n\n[key](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n\n
\n\n[qrl](#)\n\n\n\n\n\n\n\n[QRL](#qrl)<any>\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/container/container.ts", - "mdFile": "qwik.snapshotlistener.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/ssr/ssr-types.ts", + "mdFile": "core.snapshotlistener.md" }, { "name": "SnapshotMeta", @@ -2615,8 +1622,8 @@ ], "kind": "TypeAlias", "content": "```typescript\nexport type SnapshotMeta = Record;\n```\n**References:** [SnapshotMetaValue](#snapshotmetavalue)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/container/container.ts", - "mdFile": "qwik.snapshotmeta.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/ssr/ssr-types.ts", + "mdFile": "core.snapshotmeta.md" }, { "name": "SnapshotMetaValue", @@ -2629,8 +1636,8 @@ ], "kind": "Interface", "content": "```typescript\nexport interface SnapshotMetaValue \n```\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[c?](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n_(Optional)_\n\n\n
\n\n[h?](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n_(Optional)_\n\n\n
\n\n[s?](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n_(Optional)_\n\n\n
\n\n[w?](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n_(Optional)_\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/container/container.ts", - "mdFile": "qwik.snapshotmetavalue.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/ssr/ssr-types.ts", + "mdFile": "core.snapshotmetavalue.md" }, { "name": "SnapshotResult", @@ -2642,9 +1649,9 @@ } ], "kind": "Interface", - "content": "```typescript\nexport interface SnapshotResult \n```\n\n\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[funcs](#)\n\n\n\n\n\n\n\nstring\\[\\]\n\n\n\n\n\n
\n\n[mode](#)\n\n\n\n\n\n\n\n'render' \\| 'listeners' \\| 'static'\n\n\n\n\n\n
\n\n[objs](#)\n\n\n\n\n\n\n\nany\\[\\]\n\n\n\n\n\n
\n\n[qrls](#)\n\n\n\n\n\n\n\n[QRL](#qrl)\\[\\]\n\n\n\n\n\n
\n\n[resources](#)\n\n\n\n\n\n\n\nResourceReturnInternal<any>\\[\\]\n\n\n\n\n\n
\n\n[state](#)\n\n\n\n\n\n\n\n[SnapshotState](#snapshotstate)\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/container/container.ts", - "mdFile": "qwik.snapshotresult.md" + "content": "```typescript\nexport interface SnapshotResult \n```\n\n\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[funcs](#)\n\n\n\n\n\n\n\nstring\\[\\]\n\n\n\n\n\n
\n\n[mode](#)\n\n\n\n\n\n\n\n'render' \\| 'listeners' \\| 'static'\n\n\n\n\n\n
\n\n[objs?](#)\n\n\n\n\n\n\n\nany\\[\\]\n\n\n\n\n_(Optional)_\n\n\n
\n\n[qrls](#)\n\n\n\n\n\n\n\n[QRL](#qrl)\\[\\]\n\n\n\n\n\n
\n\n[resources](#)\n\n\n\n\n\n\n\nResourceReturnInternal<any>\\[\\]\n\n\n\n\n\n
\n\n[state?](#)\n\n\n\n\n\n\n\n[SnapshotState](#snapshotstate)\n\n\n\n\n_(Optional)_\n\n\n
", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/ssr/ssr-types.ts", + "mdFile": "core.snapshotresult.md" }, { "name": "SnapshotState", @@ -2656,23 +1663,9 @@ } ], "kind": "Interface", - "content": "```typescript\nexport interface SnapshotState \n```\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[ctx](#)\n\n\n\n\n\n\n\n[SnapshotMeta](#snapshotmeta)\n\n\n\n\n\n
\n\n[objs](#)\n\n\n\n\n\n\n\nany\\[\\]\n\n\n\n\n\n
\n\n[refs](#)\n\n\n\n\n\n\n\nRecord<string, string>\n\n\n\n\n\n
\n\n[subs](#)\n\n\n\n\n\n\n\nany\\[\\]\n\n\n\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/container/container.ts", - "mdFile": "qwik.snapshotstate.md" - }, - { - "name": "SourceHTMLAttributes", - "id": "sourcehtmlattributes", - "hierarchy": [ - { - "name": "SourceHTMLAttributes", - "id": "sourcehtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface SourceHTMLAttributes extends Attrs<'source', T> \n```\n**Extends:** Attrs<'source', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.sourcehtmlattributes.md" + "content": "> Warning: This API is now obsolete.\n> \n> not longer used in v2\n> \n\n\n```typescript\nexport interface SnapshotState \n```\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[ctx](#)\n\n\n\n\n\n\n\n[SnapshotMeta](#snapshotmeta)\n\n\n\n\n\n
\n\n[objs](#)\n\n\n\n\n\n\n\nany\\[\\]\n\n\n\n\n\n
\n\n[refs](#)\n\n\n\n\n\n\n\nRecord<string, string>\n\n\n\n\n\n
\n\n[subs](#)\n\n\n\n\n\n\n\nany\\[\\]\n\n\n\n\n\n
", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/ssr/ssr-types.ts", + "mdFile": "core.snapshotstate.md" }, { "name": "SSRComment", @@ -2685,22 +1678,8 @@ ], "kind": "Variable", "content": "```typescript\nSSRComment: FunctionComponent<{\n data: string;\n}>\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts", - "mdFile": "qwik.ssrcomment.md" - }, - { - "name": "SSRHint", - "id": "ssrhint", - "hierarchy": [ - { - "name": "SSRHint", - "id": "ssrhint" - } - ], - "kind": "Variable", - "content": "> Warning: This API is now obsolete.\n> \n> - It has no effect\n> \n\n\n```typescript\nSSRHint: FunctionComponent\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts", - "mdFile": "qwik.ssrhint.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts", + "mdFile": "core.ssrcomment.md" }, { "name": "SSRHintProps", @@ -2713,8 +1692,8 @@ ], "kind": "TypeAlias", "content": "```typescript\nexport type SSRHintProps = {\n dynamic?: boolean;\n};\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts", - "mdFile": "qwik.ssrhintprops.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts", + "mdFile": "core.ssrhintprops.md" }, { "name": "SSRRaw", @@ -2727,8 +1706,8 @@ ], "kind": "Variable", "content": "```typescript\nSSRRaw: FunctionComponent<{\n data: string;\n}>\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts", - "mdFile": "qwik.ssrraw.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts", + "mdFile": "core.ssrraw.md" }, { "name": "SSRStream", @@ -2741,8 +1720,8 @@ ], "kind": "Variable", "content": "```typescript\nSSRStream: FunctionComponent\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts", - "mdFile": "qwik.ssrstream.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts", + "mdFile": "core.ssrstream.md" }, { "name": "SSRStreamBlock", @@ -2754,79 +1733,37 @@ } ], "kind": "Variable", - "content": "```typescript\nSSRStreamBlock: FunctionComponent<{\n children?: any;\n}>\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts", - "mdFile": "qwik.ssrstreamblock.md" + "content": "```typescript\nSSRStreamBlock: FunctionComponent<{\n children?: JSXOutput;\n}>\n```", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts", + "mdFile": "core.ssrstreamblock.md" }, { - "name": "SSRStreamProps", - "id": "ssrstreamprops", + "name": "SSRStreamChildren", + "id": "ssrstreamchildren", "hierarchy": [ { - "name": "SSRStreamProps", - "id": "ssrstreamprops" + "name": "SSRStreamChildren", + "id": "ssrstreamchildren" } ], "kind": "TypeAlias", - "content": "```typescript\nexport type SSRStreamProps = {\n children: AsyncGenerator | ((stream: StreamWriter) => Promise) | (() => AsyncGenerator);\n};\n```\n**References:** [JSXChildren](#jsxchildren), [StreamWriter](#streamwriter)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts", - "mdFile": "qwik.ssrstreamprops.md" + "content": "```typescript\nexport type SSRStreamChildren = AsyncGenerator | ((stream: StreamWriter) => Promise) | (() => AsyncGenerator);\n```\n**References:** [JSXChildren](#jsxchildren)", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts", + "mdFile": "core.ssrstreamchildren.md" }, { - "name": "StreamWriter", - "id": "streamwriter", + "name": "SSRStreamProps", + "id": "ssrstreamprops", "hierarchy": [ { - "name": "StreamWriter", - "id": "streamwriter" + "name": "SSRStreamProps", + "id": "ssrstreamprops" } ], "kind": "TypeAlias", - "content": "```typescript\nexport type StreamWriter = {\n write: (chunk: string) => void;\n};\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/ssr/render-ssr.ts", - "mdFile": "qwik.streamwriter.md" - }, - { - "name": "StyleHTMLAttributes", - "id": "stylehtmlattributes", - "hierarchy": [ - { - "name": "StyleHTMLAttributes", - "id": "stylehtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface StyleHTMLAttributes extends Attrs<'style', T> \n```\n**Extends:** Attrs<'style', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.stylehtmlattributes.md" - }, - { - "name": "SVGAttributes", - "id": "svgattributes", - "hierarchy": [ - { - "name": "SVGAttributes", - "id": "svgattributes" - } - ], - "kind": "Interface", - "content": "The TS types don't include the SVG attributes so we have to define them ourselves\n\nNOTE: These props are probably not complete\n\n\n```typescript\nexport interface SVGAttributes extends AriaAttributes \n```\n**Extends:** [AriaAttributes](#ariaattributes)\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[\"accent-height\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"alignment-baseline\"?](#)\n\n\n\n\n\n\n\n'auto' \\| 'baseline' \\| 'before-edge' \\| 'text-before-edge' \\| 'middle' \\| 'central' \\| 'after-edge' \\| 'text-after-edge' \\| 'ideographic' \\| 'alphabetic' \\| 'hanging' \\| 'mathematical' \\| 'inherit' \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"arabic-form\"?](#)\n\n\n\n\n\n\n\n'initial' \\| 'medial' \\| 'terminal' \\| 'isolated' \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"baseline-shift\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"cap-height\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"clip-path\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"clip-rule\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"color-interpolation-filters\"?](#)\n\n\n\n\n\n\n\n'auto' \\| 's-rGB' \\| 'linear-rGB' \\| 'inherit' \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"color-interpolation\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"color-profile\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"color-rendering\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"dominant-baseline\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"edge-mode\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"enable-background\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"fill-opacity\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"fill-rule\"?](#)\n\n\n\n\n\n\n\n'nonzero' \\| 'evenodd' \\| 'inherit' \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"flood-color\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"flood-opacity\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"font-family\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"font-size-adjust\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"font-size\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"font-stretch\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"font-style\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"font-variant\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"font-weight\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"glyph-name\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"glyph-orientation-horizontal\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"glyph-orientation-vertical\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"horiz-adv-x\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"horiz-origin-x\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"image-rendering\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"letter-spacing\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"lighting-color\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"marker-end\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"marker-mid\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"marker-start\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"overline-position\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"overline-thickness\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"paint-order\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"pointer-events\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"rendering-intent\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"shape-rendering\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"stop-color\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"stop-opacity\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"strikethrough-position\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"strikethrough-thickness\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"stroke-dasharray\"?](#)\n\n\n\n\n\n\n\nstring \\| number \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"stroke-dashoffset\"?](#)\n\n\n\n\n\n\n\nstring \\| number \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"stroke-linecap\"?](#)\n\n\n\n\n\n\n\n'butt' \\| 'round' \\| 'square' \\| 'inherit' \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"stroke-linejoin\"?](#)\n\n\n\n\n\n\n\n'miter' \\| 'round' \\| 'bevel' \\| 'inherit' \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"stroke-miterlimit\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"stroke-opacity\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"stroke-width\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"text-anchor\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"text-decoration\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"text-rendering\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"underline-position\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"underline-thickness\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"unicode-bidi\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"unicode-range\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"units-per-em\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"v-alphabetic\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"v-hanging\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"v-ideographic\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"v-mathematical\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"vector-effect\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"vert-adv-y\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"vert-origin-x\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"vert-origin-y\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"word-spacing\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"writing-mode\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"x-channel-selector\"?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"x-height\"?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"xlink:actuate\"?](#svgattributes-_xlink_actuate_)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"xlink:arcrole\"?](#svgattributes-_xlink_arcrole_)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"xlink:href\"?](#svgattributes-_xlink_href_)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"xlink:role\"?](#svgattributes-_xlink_role_)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"xlink:show\"?](#svgattributes-_xlink_show_)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"xlink:title\"?](#svgattributes-_xlink_title_)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"xlink:type\"?](#svgattributes-_xlink_type_)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"xml:base\"?](#svgattributes-_xml_base_)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"xml:lang\"?](#svgattributes-_xml_lang_)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"xml:space\"?](#svgattributes-_xml_space_)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[\"xmlns:xlink\"?](#svgattributes-_xmlns_xlink_)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[accumulate?](#)\n\n\n\n\n\n\n\n'none' \\| 'sum' \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[additive?](#)\n\n\n\n\n\n\n\n'replace' \\| 'sum' \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[allowReorder?](#)\n\n\n\n\n\n\n\n'no' \\| 'yes' \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[alphabetic?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[amplitude?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[ascent?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[attributeName?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[attributeType?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[autoReverse?](#)\n\n\n\n\n\n\n\n[Booleanish](#booleanish) \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[azimuth?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[baseFrequency?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[baseProfile?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[bbox?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[begin?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[bias?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[by?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[calcMode?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[clip?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[clipPathUnits?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[color?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[contentScriptType?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[contentStyleType?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[crossOrigin?](#)\n\n\n\n\n\n\n\n[HTMLCrossOriginAttribute](#htmlcrossoriginattribute)\n\n\n\n\n_(Optional)_\n\n\n
\n\n[cursor?](#)\n\n\n\n\n\n\n\nnumber \\| string\n\n\n\n\n_(Optional)_\n\n\n
\n\n[cx?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[cy?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[d?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[decelerate?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[descent?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[diffuseConstant?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[direction?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[display?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[divisor?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[dur?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[dx?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[dy?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[elevation?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[end?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[exponent?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[externalResourcesRequired?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[fill?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[filter?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[filterRes?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[filterUnits?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[focusable?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[format?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[fr?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[from?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[fx?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[fy?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[g1?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[g2?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[glyphRef?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[gradientTransform?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[gradientUnits?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[hanging?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[height?](#)\n\n\n\n\n\n\n\n[Size](#size) \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[href?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[id?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[ideographic?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[in?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[in2?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[intercept?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[k?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[k1?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[k2?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[k3?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[k4?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[kernelMatrix?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[kernelUnitLength?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[kerning?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[keyPoints?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[keySplines?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[keyTimes?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[lang?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[lengthAdjust?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[limitingConeAngle?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[local?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[markerHeight?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[markerUnits?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[markerWidth?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[mask?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[maskContentUnits?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[maskUnits?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[mathematical?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[max?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[media?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[method?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[min?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[mode?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[name?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[numOctaves?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[offset?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[opacity?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[operator?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[order?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[orient?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[orientation?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[origin?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[overflow?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[panose1?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[path?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[pathLength?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[patternContentUnits?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[patternTransform?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[patternUnits?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[points?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[pointsAtX?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[pointsAtY?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[pointsAtZ?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[preserveAlpha?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[preserveAspectRatio?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[primitiveUnits?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[r?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[radius?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[refX?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[refY?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[repeatCount?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[repeatDur?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[requiredextensions?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[requiredFeatures?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[restart?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[result?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[role?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[rotate?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[rx?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[ry?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[scale?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[seed?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[slope?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[spacing?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[specularConstant?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[specularExponent?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[speed?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[spreadMethod?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[startOffset?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[stdDeviation?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[stemh?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[stemv?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[stitchTiles?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[string?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[stroke?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[style?](#)\n\n\n\n\n\n\n\n[CSSProperties](#cssproperties) \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[surfaceScale?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[systemLanguage?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[tabindex?](#)\n\n\n\n\n\n\n\nnumber \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[tableValues?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[target?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[targetX?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[targetY?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[textLength?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[to?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[transform?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[type?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[u1?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[u2?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[unicode?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[values?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[version?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[viewBox?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[viewTarget?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[visibility?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[width?](#)\n\n\n\n\n\n\n\n[Size](#size) \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[widths?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[x?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[x1?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[x2?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[xmlns?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[y?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[y1?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[y2?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[yChannelSelector?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[z?](#)\n\n\n\n\n\n\n\nnumber \\| string \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[zoomAndPan?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.svgattributes.md" - }, - { - "name": "SVGProps", - "id": "svgprops", - "hierarchy": [ - { - "name": "SVGProps", - "id": "svgprops" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface SVGProps extends SVGAttributes, QwikAttributes \n```\n**Extends:** [SVGAttributes](#svgattributes), [QwikAttributes](#qwikattributes)<T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.svgprops.md" + "content": "```typescript\nexport type SSRStreamProps = {\n children: SSRStreamChildren;\n};\n```\n**References:** [SSRStreamChildren](#ssrstreamchildren)", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts", + "mdFile": "core.ssrstreamprops.md" }, { "name": "sync$", @@ -2838,9 +1775,9 @@ } ], "kind": "Function", - "content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\nExtract function into a synchronously loadable QRL.\n\nNOTE: Synchronous QRLs functions can't close over any variables, including exports.\n\n\n```typescript\nsync$: (fn: T) => SyncQRL\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nfn\n\n\n\n\nT\n\n\n\n\nFunction to extract.\n\n\n
\n**Returns:**\n\n[SyncQRL](#syncqrl)<T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts", - "mdFile": "qwik.sync_.md" + "content": "Extract function into a synchronously loadable QRL.\n\nNOTE: Synchronous QRLs functions can't close over any variables, including exports.\n\n\n```typescript\nsync$: (fn: T) => SyncQRL\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nfn\n\n\n\n\nT\n\n\n\n\nFunction to extract.\n\n\n
\n**Returns:**\n\n[SyncQRL](#syncqrl)<T>", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/qrl.public.ts", + "mdFile": "core.sync_.md" }, { "name": "SyncQRL", @@ -2852,23 +1789,9 @@ } ], "kind": "Interface", - "content": "> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.\n> \n\n\n\n```typescript\nexport interface SyncQRL extends QRL \n```\n**Extends:** [QRL](#qrl)<TYPE>\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[\\_\\_brand\\_\\_SyncQRL\\_\\_](#)\n\n\n\n\n\n\n\nTYPE\n\n\n\n\n**_(ALPHA)_**\n\n\n
\n\n[dev](#)\n\n\n\n\n\n\n\nQRLDev \\| null\n\n\n\n\n**_(ALPHA)_**\n\n\n
\n\n[resolved](#)\n\n\n\n\n\n\n\nTYPE\n\n\n\n\n**_(ALPHA)_**\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts", - "mdFile": "qwik.syncqrl.md" - }, - { - "name": "TableHTMLAttributes", - "id": "tablehtmlattributes", - "hierarchy": [ - { - "name": "TableHTMLAttributes", - "id": "tablehtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface TableHTMLAttributes extends Attrs<'table', T> \n```\n**Extends:** Attrs<'table', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.tablehtmlattributes.md" + "content": "```typescript\nexport interface SyncQRL extends QRL \n```\n**Extends:** [QRL](#qrl)<TYPE>\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[\\_\\_brand\\_\\_SyncQRL\\_\\_](#)\n\n\n\n\n\n\n\nTYPE\n\n\n\n\n\n
\n\n[dev](#)\n\n\n\n\n\n\n\nQRLDev \\| null\n\n\n\n\n\n
\n\n[resolved](#)\n\n\n\n\n\n\n\nTYPE\n\n\n\n\n\n
", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/qrl.public.ts", + "mdFile": "core.syncqrl.md" }, { "name": "TaskCtx", @@ -2882,7 +1805,7 @@ "kind": "Interface", "content": "```typescript\nexport interface TaskCtx \n```\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[track](#)\n\n\n\n\n\n\n\n[Tracker](#tracker)\n\n\n\n\n\n
\n\n\n\n\n
\n\nMethod\n\n\n\n\nDescription\n\n\n
\n\n[cleanup(callback)](#)\n\n\n\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.taskctx.md" + "mdFile": "core.taskctx.md" }, { "name": "TaskFn", @@ -2896,77 +1819,7 @@ "kind": "TypeAlias", "content": "```typescript\nexport type TaskFn = (ctx: TaskCtx) => ValueOrPromise void)>;\n```\n**References:** [TaskCtx](#taskctx), [ValueOrPromise](#valueorpromise)", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.taskfn.md" - }, - { - "name": "TdHTMLAttributes", - "id": "tdhtmlattributes", - "hierarchy": [ - { - "name": "TdHTMLAttributes", - "id": "tdhtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface TdHTMLAttributes extends Attrs<'td', T> \n```\n**Extends:** Attrs<'td', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.tdhtmlattributes.md" - }, - { - "name": "TextareaHTMLAttributes", - "id": "textareahtmlattributes", - "hierarchy": [ - { - "name": "TextareaHTMLAttributes", - "id": "textareahtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface TextareaHTMLAttributes extends Attrs<'textarea', T> \n```\n**Extends:** Attrs<'textarea', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.textareahtmlattributes.md" - }, - { - "name": "ThHTMLAttributes", - "id": "thhtmlattributes", - "hierarchy": [ - { - "name": "ThHTMLAttributes", - "id": "thhtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface ThHTMLAttributes extends Attrs<'tr', T> \n```\n**Extends:** Attrs<'tr', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.thhtmlattributes.md" - }, - { - "name": "TimeHTMLAttributes", - "id": "timehtmlattributes", - "hierarchy": [ - { - "name": "TimeHTMLAttributes", - "id": "timehtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface TimeHTMLAttributes extends Attrs<'time', T> \n```\n**Extends:** Attrs<'time', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.timehtmlattributes.md" - }, - { - "name": "TitleHTMLAttributes", - "id": "titlehtmlattributes", - "hierarchy": [ - { - "name": "TitleHTMLAttributes", - "id": "titlehtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface TitleHTMLAttributes extends Attrs<'title', T> \n```\n**Extends:** Attrs<'title', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.titlehtmlattributes.md" + "mdFile": "core.taskfn.md" }, { "name": "Tracker", @@ -2980,21 +1833,7 @@ "kind": "Interface", "content": "Used to signal to Qwik which state should be watched for changes.\n\nThe `Tracker` is passed into the `taskFn` of `useTask`. It is intended to be used to wrap state objects in a read proxy which signals to Qwik which properties should be watched for changes. A change to any of the properties causes the `taskFn` to rerun.\n\n\\#\\#\\# Example\n\nThe `obs` passed into the `taskFn` is used to mark `state.count` as a property of interest. Any changes to the `state.count` property will cause the `taskFn` to rerun.\n\n```tsx\nconst Cmp = component$(() => {\n const store = useStore({ count: 0, doubleCount: 0 });\n const signal = useSignal(0);\n useTask$(({ track }) => {\n // Any signals or stores accessed inside the task will be tracked\n const count = track(() => store.count);\n // You can also pass a signal to track() directly\n const signalCount = track(signal);\n store.doubleCount = count + signalCount;\n });\n return (\n
\n \n {store.count} / {store.doubleCount}\n \n {\n store.count++;\n signal.value++;\n }}\n >\n +\n \n
\n );\n});\n```\n\n\n```typescript\nexport interface Tracker \n```", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.tracker.md" - }, - { - "name": "TrackHTMLAttributes", - "id": "trackhtmlattributes", - "hierarchy": [ - { - "name": "TrackHTMLAttributes", - "id": "trackhtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface TrackHTMLAttributes extends Attrs<'track', T> \n```\n**Extends:** Attrs<'track', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.trackhtmlattributes.md" + "mdFile": "core.tracker.md" }, { "name": "untrack", @@ -3008,7 +1847,7 @@ "kind": "Function", "content": "Don't track listeners for this callback\n\n\n```typescript\nuntrack: (fn: () => T) => T\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nfn\n\n\n\n\n() => T\n\n\n\n\n\n
\n**Returns:**\n\nT", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-core.ts", - "mdFile": "qwik.untrack.md" + "mdFile": "core.untrack.md" }, { "name": "unwrapStore", @@ -3020,9 +1859,9 @@ } ], "kind": "Function", - "content": "Get the target value of the Proxy. Useful if you want to clone a store (structureClone, IndexedDB,...)\n\n\n```typescript\nunwrapProxy: (proxy: T) => T\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nproxy\n\n\n\n\nT\n\n\n\n\n\n
\n**Returns:**\n\nT", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/state/common.ts", - "mdFile": "qwik.unwrapstore.md" + "content": "Get the original object that was wrapped by the store. Useful if you want to clone a store (structuredClone, IndexedDB,...)\n\n\n```typescript\nunwrapStore: (value: T) => T\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nvalue\n\n\n\n\nT\n\n\n\n\n\n
\n**Returns:**\n\nT", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/store.ts", + "mdFile": "core.unwrapstore.md" }, { "name": "useComputed$", @@ -3034,23 +1873,9 @@ } ], "kind": "Function", - "content": "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.\n\nThe function must be synchronous and must not have any side effects.\n\nAsync functions are deprecated because:\n\n- 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.\n\nIn v2, async functions won't work.\n\n\n```typescript\nuseComputed$: (qrl: ComputedFn) => Signal>\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\n[ComputedFn](#computedfn)<T>\n\n\n\n\n\n
\n**Returns:**\n\n[Signal](#signal)<Awaited<T>>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.usecomputed_.md" - }, - { - "name": "useComputedQrl", - "id": "usecomputedqrl", - "hierarchy": [ - { - "name": "useComputedQrl", - "id": "usecomputedqrl" - } - ], - "kind": "Function", - "content": "```typescript\nuseComputedQrl: (qrl: QRL>) => Signal>\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\n[QRL](#qrl)<[ComputedFn](#computedfn)<T>>\n\n\n\n\n\n
\n**Returns:**\n\n[Signal](#signal)<Awaited<T>>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.usecomputedqrl.md" + "content": "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.\n\nThe function must be synchronous and must not have any side effects.\n\n\n```typescript\nuseComputed$: (qrl: import(\"./use-computed\").ComputedFn) => T extends Promise ? never : import(\"..\").ReadonlySignal\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\nimport(\"./use-computed\").[ComputedFn](#computedfn)<T>\n\n\n\n\n\n
\n**Returns:**\n\nT extends Promise<any> ? never : import(\"..\").[ReadonlySignal](#readonlysignal)<T>", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-computed-dollar.ts", + "mdFile": "core.usecomputed_.md" }, { "name": "useConstant", @@ -3062,9 +1887,9 @@ } ], "kind": "Function", - "content": "> Warning: This API is now obsolete.\n> \n> This is a technology preview\n> \n\nStores a value which is retained for the lifetime of the component.\n\nIf the value is a function, the function is invoked to calculate the actual value.\n\n\n```typescript\nuseConstant: (value: (() => T) | T) => T\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nvalue\n\n\n\n\n(() => T) \\| T\n\n\n\n\n\n
\n**Returns:**\n\nT", + "content": "Stores a value which is retained for the lifetime of the component. Subsequent calls to `useConstant` will always return the first value given.\n\nIf the value is a function, the function is invoked once to calculate the actual value.\n\n\n```typescript\nuseConstant: (value: (() => T) | T) => T\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nvalue\n\n\n\n\n(() => T) \\| T\n\n\n\n\n\n
\n**Returns:**\n\nT", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-signal.ts", - "mdFile": "qwik.useconstant.md" + "mdFile": "core.useconstant.md" }, { "name": "useContext", @@ -3078,7 +1903,7 @@ "kind": "Variable", "content": "Retrieve Context value.\n\nUse `useContext()` to retrieve the value of context in a component. To retrieve a value a parent component needs to invoke `useContextProvider()` to assign a value.\n\n\\#\\#\\# Example\n\n```tsx\n// Declare the Context type.\ninterface TodosStore {\n items: string[];\n}\n// Create a Context ID (no data is saved here.)\n// You will use this ID to both create and retrieve the Context.\nexport const TodosContext = createContextId('Todos');\n\n// Example of providing context to child components.\nexport const App = component$(() => {\n useContextProvider(\n TodosContext,\n useStore({\n items: ['Learn Qwik', 'Build Qwik app', 'Profit'],\n })\n );\n\n return ;\n});\n\n// Example of retrieving the context provided by a parent component.\nexport const Items = component$(() => {\n const todos = useContext(TodosContext);\n return (\n
    \n {todos.items.map((item) => (\n
  • {item}
  • \n ))}\n
\n );\n});\n\n```\n\n\n```typescript\nuseContext: UseContext\n```", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-context.ts", - "mdFile": "qwik.usecontext.md" + "mdFile": "core.usecontext.md" }, { "name": "useContextProvider", @@ -3092,7 +1917,7 @@ "kind": "Function", "content": "Assign a value to a Context.\n\nUse `useContextProvider()` to assign a value to a context. The assignment happens in the component's function. Once assigned, use `useContext()` in any child component to retrieve the value.\n\nContext is a way to pass stores to the child components without prop-drilling. Note that scalar values are allowed, but for reactivity you need signals or stores.\n\n\\#\\#\\# Example\n\n```tsx\n// Declare the Context type.\ninterface TodosStore {\n items: string[];\n}\n// Create a Context ID (no data is saved here.)\n// You will use this ID to both create and retrieve the Context.\nexport const TodosContext = createContextId('Todos');\n\n// Example of providing context to child components.\nexport const App = component$(() => {\n useContextProvider(\n TodosContext,\n useStore({\n items: ['Learn Qwik', 'Build Qwik app', 'Profit'],\n })\n );\n\n return ;\n});\n\n// Example of retrieving the context provided by a parent component.\nexport const Items = component$(() => {\n const todos = useContext(TodosContext);\n return (\n
    \n {todos.items.map((item) => (\n
  • {item}
  • \n ))}\n
\n );\n});\n\n```\n\n\n```typescript\nuseContextProvider: (context: ContextId, newValue: STATE) => void\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\ncontext\n\n\n\n\n[ContextId](#contextid)<STATE>\n\n\n\n\nThe context to assign a value to.\n\n\n
\n\nnewValue\n\n\n\n\nSTATE\n\n\n\n\n\n
\n**Returns:**\n\nvoid", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-context.ts", - "mdFile": "qwik.usecontextprovider.md" + "mdFile": "core.usecontextprovider.md" }, { "name": "useErrorBoundary", @@ -3106,7 +1931,7 @@ "kind": "Function", "content": "```typescript\nuseErrorBoundary: () => Readonly\n```\n**Returns:**\n\nReadonly<[ErrorBoundaryStore](#errorboundarystore)>", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-error-boundary.ts", - "mdFile": "qwik.useerrorboundary.md" + "mdFile": "core.useerrorboundary.md" }, { "name": "useId", @@ -3120,7 +1945,7 @@ "kind": "Function", "content": "```typescript\nuseId: () => string\n```\n**Returns:**\n\nstring", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-id.ts", - "mdFile": "qwik.useid.md" + "mdFile": "core.useid.md" }, { "name": "useOn", @@ -3134,7 +1959,7 @@ "kind": "Function", "content": "Register a listener on the current component's host element.\n\nUsed to programmatically add event listeners. Useful from custom `use*` methods, which do not have access to the JSX. Otherwise, it's adding a JSX listener in the `
` is a better idea.\n\n\n```typescript\nuseOn: (event: T | T[], eventQrl: EventQRL) => void\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nevent\n\n\n\n\nT \\| T\\[\\]\n\n\n\n\n\n
\n\neventQrl\n\n\n\n\nEventQRL<T>\n\n\n\n\n\n
\n**Returns:**\n\nvoid", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-on.ts", - "mdFile": "qwik.useon.md" + "mdFile": "core.useon.md" }, { "name": "useOnDocument", @@ -3148,7 +1973,7 @@ "kind": "Function", "content": "Register a listener on `document`.\n\nUsed to programmatically add event listeners. Useful from custom `use*` methods, which do not have access to the JSX.\n\n\n```typescript\nuseOnDocument: (event: T | T[], eventQrl: EventQRL) => void\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nevent\n\n\n\n\nT \\| T\\[\\]\n\n\n\n\n\n
\n\neventQrl\n\n\n\n\nEventQRL<T>\n\n\n\n\n\n
\n**Returns:**\n\nvoid", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-on.ts", - "mdFile": "qwik.useondocument.md" + "mdFile": "core.useondocument.md" }, { "name": "useOnWindow", @@ -3162,7 +1987,7 @@ "kind": "Function", "content": "Register a listener on `window`.\n\nUsed to programmatically add event listeners. Useful from custom `use*` methods, which do not have access to the JSX.\n\n\n```typescript\nuseOnWindow: (event: T | T[], eventQrl: EventQRL) => void\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nevent\n\n\n\n\nT \\| T\\[\\]\n\n\n\n\n\n
\n\neventQrl\n\n\n\n\nEventQRL<T>\n\n\n\n\n\n
\n**Returns:**\n\nvoid", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-on.ts", - "mdFile": "qwik.useonwindow.md" + "mdFile": "core.useonwindow.md" }, { "name": "useResource$", @@ -3174,23 +1999,9 @@ } ], "kind": "Function", - "content": "This method works like an async memoized function that runs whenever some tracked value changes and returns some data.\n\n`useResource` however returns immediate a `ResourceReturn` object that contains the data and a state that indicates if the data is available or not.\n\nThe status can be one of the following:\n\n- 'pending' - the data is not yet available. - 'resolved' - the data is available. - 'rejected' - the data is not available due to an error or timeout.\n\n\\#\\#\\# Example\n\nExample showing how `useResource` to perform a fetch to request the weather, whenever the input city name changes.\n\n```tsx\nconst Cmp = component$(() => {\n const cityS = useSignal('');\n\n const weatherResource = useResource$(async ({ track, cleanup }) => {\n const cityName = track(cityS);\n const abortController = new AbortController();\n cleanup(() => abortController.abort('cleanup'));\n const res = await fetch(`http://weatherdata.com?city=${cityName}`, {\n signal: abortController.signal,\n });\n const data = await res.json();\n return data as { temp: number };\n });\n\n return (\n
\n \n {\n return
Temperature: {weather.temp}
;\n }}\n />\n
\n );\n});\n```\n\n\n```typescript\nuseResource$: (generatorFn: ResourceFn, opts?: ResourceOptions) => ResourceReturn\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\ngeneratorFn\n\n\n\n\n[ResourceFn](#resourcefn)<T>\n\n\n\n\n\n
\n\nopts\n\n\n\n\n[ResourceOptions](#resourceoptions)\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\n[ResourceReturn](#resourcereturn)<T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts", - "mdFile": "qwik.useresource_.md" - }, - { - "name": "useResourceQrl", - "id": "useresourceqrl", - "hierarchy": [ - { - "name": "useResourceQrl", - "id": "useresourceqrl" - } - ], - "kind": "Function", - "content": "This method works like an async memoized function that runs whenever some tracked value changes and returns some data.\n\n`useResource` however returns immediate a `ResourceReturn` object that contains the data and a state that indicates if the data is available or not.\n\nThe status can be one of the following:\n\n- `pending` - the data is not yet available. - `resolved` - the data is available. - `rejected` - the data is not available due to an error or timeout.\n\nAvoid using a `try/catch` statement in `useResource$`. If you catch the error instead of passing it, the resource status will never be `rejected`.\n\n\\#\\#\\# Example\n\nExample showing how `useResource` to perform a fetch to request the weather, whenever the input city name changes.\n\n```tsx\nconst Cmp = component$(() => {\n const cityS = useSignal('');\n\n const weatherResource = useResource$(async ({ track, cleanup }) => {\n const cityName = track(cityS);\n const abortController = new AbortController();\n cleanup(() => abortController.abort('cleanup'));\n const res = await fetch(`http://weatherdata.com?city=${cityName}`, {\n signal: abortController.signal,\n });\n const data = await res.json();\n return data as { temp: number };\n });\n\n return (\n
\n \n {\n return
Temperature: {weather.temp}
;\n }}\n />\n
\n );\n});\n```\n\n\n```typescript\nuseResourceQrl: (qrl: QRL>, opts?: ResourceOptions) => ResourceReturn\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\n[QRL](#qrl)<[ResourceFn](#resourcefn)<T>>\n\n\n\n\n\n
\n\nopts\n\n\n\n\n[ResourceOptions](#resourceoptions)\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\n[ResourceReturn](#resourcereturn)<T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts", - "mdFile": "qwik.useresourceqrl.md" + "content": "This method works like an async memoized function that runs whenever some tracked value changes and returns some data.\n\n`useResource` however returns immediate a `ResourceReturn` object that contains the data and a state that indicates if the data is available or not.\n\nThe status can be one of the following:\n\n- `pending` - the data is not yet available. - `resolved` - the data is available. - `rejected` - the data is not available due to an error or timeout.\n\nBe 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`.\n\n\\#\\#\\# Example\n\nExample showing how `useResource` to perform a fetch to request the weather, whenever the input city name changes.\n\n```tsx\nconst Cmp = component$(() => {\n const cityS = useSignal('');\n\n const weatherResource = useResource$(async ({ track, cleanup }) => {\n const cityName = track(cityS);\n const abortController = new AbortController();\n cleanup(() => abortController.abort('cleanup'));\n const res = await fetch(`http://weatherdata.com?city=${cityName}`, {\n signal: abortController.signal,\n });\n const data = await res.json();\n return data as { temp: number };\n });\n\n return (\n
\n \n {\n return
Temperature: {weather.temp}
;\n }}\n />\n
\n );\n});\n```\n\n\n```typescript\nuseResource$: (generatorFn: ResourceFn, opts?: ResourceOptions) => ResourceReturn\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\ngeneratorFn\n\n\n\n\n[ResourceFn](#resourcefn)<T>\n\n\n\n\n\n
\n\nopts\n\n\n\n\n[ResourceOptions](#resourceoptions)\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\n[ResourceReturn](#resourcereturn)<T>", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource-dollar.ts", + "mdFile": "core.useresource_.md" }, { "name": "useServerData", @@ -3204,7 +2015,7 @@ "kind": "Function", "content": "```typescript\nexport declare function useServerData(key: string): T | undefined;\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nkey\n\n\n\n\nstring\n\n\n\n\n\n
\n**Returns:**\n\nT \\| undefined", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-env-data.ts", - "mdFile": "qwik.useserverdata.md" + "mdFile": "core.useserverdata.md" }, { "name": "useSignal", @@ -3216,9 +2027,9 @@ } ], "kind": "Variable", - "content": "Hook that creates a signal that is retained for the lifetime of the component.\n\n\n```typescript\nuseSignal: UseSignal\n```", + "content": "```typescript\nuseSignal: UseSignal\n```", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-signal.ts", - "mdFile": "qwik.usesignal.md" + "mdFile": "core.usesignal.md" }, { "name": "UseSignal", @@ -3230,9 +2041,9 @@ } ], "kind": "Interface", - "content": "Hook that creates a signal that is retained for the lifetime of the component.\n\n\n```typescript\nuseSignal: UseSignal\n```", + "content": "```typescript\nuseSignal: UseSignal\n```", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-signal.ts", - "mdFile": "qwik.usesignal.md" + "mdFile": "core.usesignal.md" }, { "name": "useStore", @@ -3246,7 +2057,7 @@ "kind": "Function", "content": "Creates an object that Qwik can track across serializations.\n\nUse `useStore` to create a state for your application. The returned object is a proxy that has a unique ID. The ID of the object is used in the `QRL`s to refer to the store.\n\n\\#\\#\\# Example\n\nExample showing how `useStore` is used in Counter example to keep track of the count.\n\n```tsx\nconst Stores = component$(() => {\n const counter = useCounter(1);\n\n // Reactivity happens even for nested objects and arrays\n const userData = useStore({\n name: 'Manu',\n address: {\n address: '',\n city: '',\n },\n orgs: [],\n });\n\n // useStore() can also accept a function to calculate the initial value\n const state = useStore(() => {\n return {\n value: expensiveInitialValue(),\n };\n });\n\n return (\n
\n
Counter: {counter.value}
\n \n
\n );\n});\n\nfunction useCounter(step: number) {\n // Multiple stores can be created in custom hooks for convenience and composability\n const counterStore = useStore({\n value: 0,\n });\n useVisibleTask$(() => {\n // Only runs in the client\n const timer = setInterval(() => {\n counterStore.value += step;\n }, 500);\n return () => {\n clearInterval(timer);\n };\n });\n return counterStore;\n}\n```\n\n\n```typescript\nuseStore: (initialState: STATE | (() => STATE), opts?: UseStoreOptions) => STATE\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\ninitialState\n\n\n\n\nSTATE \\| (() => STATE)\n\n\n\n\n\n
\n\nopts\n\n\n\n\n[UseStoreOptions](#usestoreoptions)\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nSTATE", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-store.public.ts", - "mdFile": "qwik.usestore.md" + "mdFile": "core.usestore.md" }, { "name": "UseStoreOptions", @@ -3260,7 +2071,7 @@ "kind": "Interface", "content": "```typescript\nexport interface UseStoreOptions \n```\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[deep?](#)\n\n\n\n\n\n\n\nboolean\n\n\n\n\n_(Optional)_ If `true` then all nested objects and arrays will be tracked as well. Default is `true`.\n\n\n
\n\n[reactive?](#)\n\n\n\n\n\n\n\nboolean\n\n\n\n\n_(Optional)_ If `false` then the object will not be tracked for changes. Default is `true`.\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-store.public.ts", - "mdFile": "qwik.usestoreoptions.md" + "mdFile": "core.usestoreoptions.md" }, { "name": "useStyles$", @@ -3272,23 +2083,9 @@ } ], "kind": "Function", - "content": "A lazy-loadable reference to a component's styles.\n\nComponent 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.)\n\n```tsx\nimport styles from './code-block.css?inline';\n\nexport const CmpStyles = component$(() => {\n useStyles$(styles);\n\n return
Some text
;\n});\n```\n\n\n```typescript\nuseStyles$: (qrl: string) => void\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\nstring\n\n\n\n\n\n
\n**Returns:**\n\nvoid", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-styles.ts", - "mdFile": "qwik.usestyles_.md" - }, - { - "name": "useStylesQrl", - "id": "usestylesqrl", - "hierarchy": [ - { - "name": "useStylesQrl", - "id": "usestylesqrl" - } - ], - "kind": "Function", - "content": "A lazy-loadable reference to a component's styles.\n\nComponent 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.)\n\n```tsx\nimport styles from './code-block.css?inline';\n\nexport const CmpStyles = component$(() => {\n useStyles$(styles);\n\n return
Some text
;\n});\n```\n\n\n```typescript\nuseStylesQrl: (styles: QRL) => void\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nstyles\n\n\n\n\n[QRL](#qrl)<string>\n\n\n\n\n\n
\n**Returns:**\n\nvoid", + "content": "A lazy-loadable reference to a component's styles.\n\nComponent 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.)\n\n```tsx\nimport styles from './code-block.css?inline';\n\nexport const CmpStyles = component$(() => {\n useStyles$(styles);\n\n return
Some text
;\n});\n```\n\n\n```typescript\nuseStyles$: (qrl: string) => UseStyles\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\nstring\n\n\n\n\n\n
\n**Returns:**\n\nUseStyles", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-styles.ts", - "mdFile": "qwik.usestylesqrl.md" + "mdFile": "core.usestyles_.md" }, { "name": "UseStylesScoped", @@ -3302,7 +2099,7 @@ "kind": "Interface", "content": "```typescript\nexport interface UseStylesScoped \n```\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[scopeId](#)\n\n\n\n\n\n\n\nstring\n\n\n\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-styles.ts", - "mdFile": "qwik.usestylesscoped.md" + "mdFile": "core.usestylesscoped.md" }, { "name": "useStylesScoped$", @@ -3316,21 +2113,7 @@ "kind": "Function", "content": "A lazy-loadable reference to a component's styles, that is scoped to the component.\n\nComponent 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.)\n\n```tsx\nimport scoped from './code-block.css?inline';\n\nexport const CmpScopedStyles = component$(() => {\n useStylesScoped$(scoped);\n\n return
Some text
;\n});\n```\n\n\n```typescript\nuseStylesScoped$: (qrl: string) => UseStylesScoped\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\nstring\n\n\n\n\n\n
\n**Returns:**\n\n[UseStylesScoped](#usestylesscoped)", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-styles.ts", - "mdFile": "qwik.usestylesscoped_.md" - }, - { - "name": "useStylesScopedQrl", - "id": "usestylesscopedqrl", - "hierarchy": [ - { - "name": "useStylesScopedQrl", - "id": "usestylesscopedqrl" - } - ], - "kind": "Function", - "content": "A lazy-loadable reference to a component's styles, that is scoped to the component.\n\nComponent 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.)\n\n```tsx\nimport scoped from './code-block.css?inline';\n\nexport const CmpScopedStyles = component$(() => {\n useStylesScoped$(scoped);\n\n return
Some text
;\n});\n```\n\n\n```typescript\nuseStylesScopedQrl: (styles: QRL) => UseStylesScoped\n```\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nstyles\n\n\n\n\n[QRL](#qrl)<string>\n\n\n\n\n\n
\n**Returns:**\n\n[UseStylesScoped](#usestylesscoped)", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-styles.ts", - "mdFile": "qwik.usestylesscopedqrl.md" + "mdFile": "core.usestylesscoped_.md" }, { "name": "useTask$", @@ -3342,9 +2125,9 @@ } ], "kind": "Function", - "content": "Reruns the `taskFn` when the observed inputs change.\n\nUse `useTask` to observe changes on a set of inputs, and then re-execute the `taskFn` when those inputs change.\n\nThe `taskFn` only executes if the observed inputs change. To observe the inputs, use the `obs` function to wrap property reads. This creates subscriptions that will trigger the `taskFn` to rerun.\n\n\n```typescript\nuseTask$: (qrl: TaskFn, opts?: UseTaskOptions | undefined) => void\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\n[TaskFn](#taskfn)\n\n\n\n\n\n
\n\nopts\n\n\n\n\n[UseTaskOptions](#usetaskoptions) \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nvoid", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.usetask_.md" + "content": "Reruns the `taskFn` when the observed inputs change.\n\nUse `useTask` to observe changes on a set of inputs, and then re-execute the `taskFn` when those inputs change.\n\nThe `taskFn` only executes if the observed inputs change. To observe the inputs, use the `obs` function to wrap property reads. This creates subscriptions that will trigger the `taskFn` to rerun.\n\n\n```typescript\nuseTask$: (qrl: import(\"./use-task\").TaskFn, opts?: import(\"./use-task\").UseTaskOptions | undefined) => void\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\nimport(\"./use-task\").[TaskFn](#taskfn)\n\n\n\n\n\n
\n\nopts\n\n\n\n\nimport(\"./use-task\").[UseTaskOptions](#usetaskoptions) \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nvoid", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task-dollar.ts", + "mdFile": "core.usetask_.md" }, { "name": "UseTaskOptions", @@ -3358,21 +2141,7 @@ "kind": "Interface", "content": "```typescript\nexport interface UseTaskOptions \n```\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[eagerness?](#)\n\n\n\n\n\n\n\n[EagernessOptions](#eagernessoptions)\n\n\n\n\n_(Optional)_ - `visible`: run the effect when the element is visible. - `load`: eagerly run the effect when the application resumes.\n\n\n
", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.usetaskoptions.md" - }, - { - "name": "useTaskQrl", - "id": "usetaskqrl", - "hierarchy": [ - { - "name": "useTaskQrl", - "id": "usetaskqrl" - } - ], - "kind": "Function", - "content": "Reruns the `taskFn` when the observed inputs change.\n\nUse `useTask` to observe changes on a set of inputs, and then re-execute the `taskFn` when those inputs change.\n\nThe `taskFn` only executes if the observed inputs change. To observe the inputs, use the `obs` function to wrap property reads. This creates subscriptions that will trigger the `taskFn` to rerun.\n\n\n```typescript\nuseTaskQrl: (qrl: QRL, opts?: UseTaskOptions) => void\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\n[QRL](#qrl)<[TaskFn](#taskfn)>\n\n\n\n\n\n
\n\nopts\n\n\n\n\n[UseTaskOptions](#usetaskoptions)\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nvoid", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.usetaskqrl.md" + "mdFile": "core.usetaskoptions.md" }, { "name": "useVisibleTask$", @@ -3384,23 +2153,9 @@ } ], "kind": "Function", - "content": "```tsx\nconst Timer = component$(() => {\n const store = useStore({\n count: 0,\n });\n\n useVisibleTask$(() => {\n // Only runs in the client\n const timer = setInterval(() => {\n store.count++;\n }, 500);\n return () => {\n clearInterval(timer);\n };\n });\n\n return
{store.count}
;\n});\n```\n\n\n```typescript\nuseVisibleTask$: (qrl: TaskFn, opts?: OnVisibleTaskOptions | undefined) => void\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\n[TaskFn](#taskfn)\n\n\n\n\n\n
\n\nopts\n\n\n\n\n[OnVisibleTaskOptions](#onvisibletaskoptions) \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nvoid", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.usevisibletask_.md" - }, - { - "name": "useVisibleTaskQrl", - "id": "usevisibletaskqrl", - "hierarchy": [ - { - "name": "useVisibleTaskQrl", - "id": "usevisibletaskqrl" - } - ], - "kind": "Function", - "content": "```tsx\nconst Timer = component$(() => {\n const store = useStore({\n count: 0,\n });\n\n useVisibleTask$(() => {\n // Only runs in the client\n const timer = setInterval(() => {\n store.count++;\n }, 500);\n return () => {\n clearInterval(timer);\n };\n });\n\n return
{store.count}
;\n});\n```\n\n\n```typescript\nuseVisibleTaskQrl: (qrl: QRL, opts?: OnVisibleTaskOptions) => void\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\n[QRL](#qrl)<[TaskFn](#taskfn)>\n\n\n\n\n\n
\n\nopts\n\n\n\n\n[OnVisibleTaskOptions](#onvisibletaskoptions)\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nvoid", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.usevisibletaskqrl.md" + "content": "```tsx\nconst Timer = component$(() => {\n const store = useStore({\n count: 0,\n });\n\n useVisibleTask$(() => {\n // Only runs in the client\n const timer = setInterval(() => {\n store.count++;\n }, 500);\n return () => {\n clearInterval(timer);\n };\n });\n\n return
{store.count}
;\n});\n```\n\n\n```typescript\nuseVisibleTask$: (qrl: import(\"./use-task\").TaskFn, opts?: import(\"./use-visible-task\").OnVisibleTaskOptions | undefined) => void\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nqrl\n\n\n\n\nimport(\"./use-task\").[TaskFn](#taskfn)\n\n\n\n\n\n
\n\nopts\n\n\n\n\nimport(\"./use-visible-task\").[OnVisibleTaskOptions](#onvisibletaskoptions) \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n**Returns:**\n\nvoid", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-visible-task-dollar.ts", + "mdFile": "core.usevisibletask_.md" }, { "name": "ValueOrPromise", @@ -3413,8 +2168,8 @@ ], "kind": "TypeAlias", "content": "Type representing a value which is either resolve or a promise.\n\n\n```typescript\nexport type ValueOrPromise = T | Promise;\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/util/types.ts", - "mdFile": "qwik.valueorpromise.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/utils/types.ts", + "mdFile": "core.valueorpromise.md" }, { "name": "version", @@ -3428,21 +2183,7 @@ "kind": "Variable", "content": "QWIK\\_VERSION\n\n\n```typescript\nversion: string\n```", "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/version.ts", - "mdFile": "qwik.version.md" - }, - { - "name": "VideoHTMLAttributes", - "id": "videohtmlattributes", - "hierarchy": [ - { - "name": "VideoHTMLAttributes", - "id": "videohtmlattributes" - } - ], - "kind": "Interface", - "content": "```typescript\nexport interface VideoHTMLAttributes extends Attrs<'video', T> \n```\n**Extends:** Attrs<'video', T>", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.videohtmlattributes.md" + "mdFile": "core.version.md" }, { "name": "VisibleTaskStrategy", @@ -3455,22 +2196,22 @@ ], "kind": "TypeAlias", "content": "```typescript\nexport type VisibleTaskStrategy = 'intersection-observer' | 'document-ready' | 'document-idle';\n```", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts", - "mdFile": "qwik.visibletaskstrategy.md" + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-visible-task.ts", + "mdFile": "core.visibletaskstrategy.md" }, { - "name": "WebViewHTMLAttributes", - "id": "webviewhtmlattributes", + "name": "withLocale", + "id": "withlocale", "hierarchy": [ { - "name": "WebViewHTMLAttributes", - "id": "webviewhtmlattributes" + "name": "withLocale", + "id": "withlocale" } ], - "kind": "Interface", - "content": "> Warning: This API is now obsolete.\n> \n> This is the type for a React Native WebView. It doesn't belong in Qwik (yet?) but we're keeping it for backwards compatibility.\n> \n\n\n```typescript\nexport interface WebViewHTMLAttributes extends HTMLAttributes \n```\n**Extends:** [HTMLAttributes](#htmlattributes)<T>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\nProperty\n\n\n\n\nModifiers\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\n[allowFullScreen?](#)\n\n\n\n\n\n\n\nboolean \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[allowpopups?](#)\n\n\n\n\n\n\n\nboolean \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[autoFocus?](#)\n\n\n\n\n\n\n\nboolean \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[autosize?](#)\n\n\n\n\n\n\n\nboolean \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[blinkfeatures?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[disableblinkfeatures?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[disableguestresize?](#)\n\n\n\n\n\n\n\nboolean \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[disablewebsecurity?](#)\n\n\n\n\n\n\n\nboolean \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[guestinstance?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[httpreferrer?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[nodeintegration?](#)\n\n\n\n\n\n\n\nboolean \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[partition?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[plugins?](#)\n\n\n\n\n\n\n\nboolean \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[preload?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[src?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[useragent?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
\n\n[webpreferences?](#)\n\n\n\n\n\n\n\nstring \\| undefined\n\n\n\n\n_(Optional)_\n\n\n
", - "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts", - "mdFile": "qwik.webviewhtmlattributes.md" + "kind": "Function", + "content": "Override the `getLocale` with `lang` within the `fn` execution.\n\n\n```typescript\nexport declare function withLocale(locale: string, fn: () => T): T;\n```\n\n\n\n\n\n
\n\nParameter\n\n\n\n\nType\n\n\n\n\nDescription\n\n\n
\n\nlocale\n\n\n\n\nstring\n\n\n\n\n\n
\n\nfn\n\n\n\n\n() => T\n\n\n\n\n\n
\n**Returns:**\n\nT", + "editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-locale.ts", + "mdFile": "core.withlocale.md" } ] -} +} \ No newline at end of file diff --git a/packages/docs/src/routes/api/qwik/index.md b/packages/docs/src/routes/api/qwik/index.md index 805484b0d50..769e7349aac 100644 --- a/packages/docs/src/routes/api/qwik/index.md +++ b/packages/docs/src/routes/api/qwik/index.md @@ -1,20 +1,23 @@ --- -title: \@builder.io/qwik API Reference +title: \@qwik.dev/qwik API Reference --- -# [API](/api) › @builder.io/qwik +# [API](/api) › @qwik.dev/qwik -## \_qrlSync +## "q:slot" -> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +```typescript +'q:slot'?: string; +``` -Extract function into a synchronously loadable QRL. +## $ -NOTE: Synchronous QRLs functions can't close over any variables, including exports. +Qwik Optimizer marker function. + +Use `$(...)` to tell Qwik Optimizer to extract the expression in `$(...)` into a lazy-loadable resource referenced by `QRL`. ```typescript -_qrlSync: (fn: TYPE, serializedFn?: string) => - SyncQRL; +$: (expression: T) => QRL; ``` -
@@ -32,117 +35,160 @@ Description
-fn +expression -TYPE +T -Extracted function +Expression which should be lazy loaded
+
+**Returns:** + +[QRL](#qrl)<T> -serializedFn +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/qrl.public.ts) - +## cache -string +```typescript +cache(policyOrMilliseconds: number | 'immutable'): void; +``` + + +
+ +Parameter + + + +Type + + + +Description + +
+ +policyOrMilliseconds -_(Optional)_ Serialized function in string form. +number \| 'immutable' + +
**Returns:** -[SyncQRL](#syncqrl)<TYPE> +void -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts) +## ClassList -## "q:slot" +A class list can be a string, a boolean, an array, or an object. -```typescript -'q:slot'?: string; -``` +If it's an array, each item is a class list and they are all added. -## "xlink:actuate" +If it's an object, then the keys are class name strings, and the values are booleans that determine if the class name string should be added or not. ```typescript -'xlink:actuate'?: string | undefined; +export type ClassList = + | string + | undefined + | null + | false + | Record + | ClassList[]; ``` -## "xlink:arcrole" +**References:** [ClassList](#classlist) + +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts) + +## cleanup ```typescript -'xlink:arcrole'?: string | undefined; +cleanup(): void; ``` -## "xlink:href" +**Returns:** -```typescript -'xlink:href'?: string | undefined; -``` +void -## "xlink:role" +## Component -```typescript -'xlink:role'?: string | undefined; -``` +Type representing the Qwik component. -## "xlink:show" +`Component` is the type returned by invoking `component$`. -```typescript -'xlink:show'?: string | undefined; +```tsx +interface MyComponentProps { + someProp: string; +} +const MyComponent: Component = component$( + (props: MyComponentProps) => { + return {props.someProp}; + }, +); ``` -## "xlink:title" - ```typescript -'xlink:title'?: string | undefined; +export type Component = FunctionComponent>; ``` -## "xlink:type" +**References:** [FunctionComponent](#functioncomponent), [PublicProps](#publicprops) -```typescript -'xlink:type'?: string | undefined; -``` +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/component.public.ts) -## "xml:base" +## component$ -```typescript -'xml:base'?: string | undefined; -``` +Declare a Qwik component that can be used to create UI. -## "xml:lang" +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. -```typescript -'xml:lang'?: string | undefined; -``` +Side note: You can also declare regular (standard JSX) components that will have standard synchronous behavior. -## "xml:space" +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: -```typescript -'xml:space'?: string | undefined; -``` +### Example -## "xmlns:xlink" +An example showing how to create a counter component: -```typescript -'xmlns:xlink'?: string | undefined; +```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. -Qwik Optimizer marker function. +The above can then be used like so: -Use `$(...)` to tell Qwik Optimizer to extract the expression in `$(...)` into a lazy-loadable resource referenced by `QRL`. +```tsx +export const OtherComponent = component$(() => { + return ; +}); +``` + +See also: `component`, `useCleanup`, `onResume`, `onPause`, `useOn`, `useOnDocument`, `useOnWindow`, `useStyles` ```typescript -$: (expression: T) => QRL; +component$: (onMount: OnRenderFn) => Component; ```
@@ -160,50 +206,26 @@ Description
-expression +onMount -T +[OnRenderFn](#onrenderfn)<PROPS> -Expression which should be lazy loaded -
**Returns:** -[QRL](#qrl)<T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts) - -## AnchorHTMLAttributes - -```typescript -export interface AnchorHTMLAttributes extends Attrs<'a', T> -``` - -**Extends:** Attrs<'a', T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) - -## AreaHTMLAttributes - -```typescript -export interface AreaHTMLAttributes extends Attrs<'area', T> -``` - -**Extends:** Attrs<'area', T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +[Component](#component)<PROPS> -## AriaAttributes +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/component.public.ts) -TS defines these with the React syntax which is not compatible with Qwik. E.g. `ariaAtomic` instead of `aria-atomic`. +## ComponentBaseProps ```typescript -export interface AriaAttributes +export interface ComponentBaseProps ``` -
@@ -225,858 +247,833 @@ Description
-["aria-activedescendant"?](#) +["q:slot"?](#componentbaseprops-_q_slot_) -string \| undefined +string -_(Optional)_ Identifies the currently active element when DOM focus is on a composite widget, textbox, group, or application. +_(Optional)_
-["aria-atomic"?](#) +[key?](#) -[Booleanish](#booleanish) \| undefined +string \| number \| null \| undefined -_(Optional)_ Indicates whether assistive technologies will present all, or only parts of, the changed region based on the change notifications defined by the aria-relevant attribute. +_(Optional)_
- -["aria-autocomplete"?](#) +
- +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts) - +## ComputedFn -'none' \| 'inline' \| 'list' \| 'both' \| undefined +```typescript +export type ComputedFn = () => T; +``` - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-computed.ts) -_(Optional)_ Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be presented if they are made. +## ComputedSignal - - +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. -["aria-busy"?](#) +```typescript +export interface ComputedSignal extends ReadonlySignal +``` - +**Extends:** [ReadonlySignal](#readonlysignal)<T> - + - + +
-[Booleanish](#booleanish) \| undefined +Method - + -_(Optional)_ Indicates an element is being modified and that assistive technologies MAY want to wait until the modifications are complete before exposing them to the user. +Description -
+
-["aria-checked"?](#) +[force()](#computedsignal-force) - +Use this to force recalculation and running subscribers, for example when the calculated value mutates but remains the same object. Useful for third-party libraries. -boolean \| 'false' \| 'mixed' \| 'true' \| undefined +
- +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts) -_(Optional)_ Indicates the current "checked" state of checkboxes, radio buttons, and other widgets. +## ContextId - - +ContextId is a typesafe ID for your context. -["aria-colcount"?](#) +Context is a way to pass stores to the child components without prop-drilling. - +Use `createContextId()` to create a `ContextId`. A `ContextId` is just a serializable identifier for the context. It is not the context value itself. See `useContextProvider()` and `useContext()` for the values. Qwik needs a serializable ID for the context so that the it can track context providers and consumers in a way that survives resumability. - +### Example -number \| undefined +```tsx +// Declare the Context type. +interface TodosStore { + items: string[]; +} +// Create a Context ID (no data is saved here.) +// You will use this ID to both create and retrieve the Context. +export const TodosContext = createContextId("Todos"); - +// Example of providing context to child components. +export const App = component$(() => { + useContextProvider( + TodosContext, + useStore({ + items: ["Learn Qwik", "Build Qwik app", "Profit"], + }), + ); -_(Optional)_ Defines the total number of columns in a table, grid, or treegrid. + return ; +}); - - +// Example of retrieving the context provided by a parent component. +export const Items = component$(() => { + const todos = useContext(TodosContext); + return ( +
    + {todos.items.map((item) => ( +
  • {item}
  • + ))} +
+ ); +}); +``` -["aria-colindex"?](#) +```typescript +export interface ContextId +``` - + - + - -
- +Property -number \| undefined + - +Modifiers -_(Optional)_ Defines an element's column index or position with respect to the total number of columns within a table, grid, or treegrid. + -
+Type -["aria-colspan"?](#) + - +Description - +
-number \| undefined +[\_\_brand_context_type\_\_](#) -_(Optional)_ Defines the number of columns spanned by a cell or gridcell within a table, grid, or treegrid. - -
- -["aria-controls"?](#) +`readonly` - - -string \| undefined +STATE -_(Optional)_ Identifies the element (or elements) whose contents or presence are controlled by the current element. +Design-time property to store type information for the context.
-["aria-current"?](#) +[id](#) +`readonly` + -boolean \| 'false' \| 'true' \| 'page' \| 'step' \| 'location' \| 'date' \| 'time' \| undefined +string -_(Optional)_ Indicates the element that represents the current item within a container or set of related elements. +A unique ID for the context.
+
-["aria-describedby"?](#) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-context.ts) - +## CorePlatform - +Low-level API for platform abstraction. -string \| undefined +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. -_(Optional)_ Identifies the element (or elements) that describes the object. +This is a low-level API and there should not be a need for you to access this. - - +```typescript +export interface CorePlatform +``` -["aria-details"?](#) + - + -
- +Property - + -string \| undefined +Modifiers - + -_(Optional)_ Identifies the element that provides a detailed, extended description for the object. +Type -
+ + +Description + +
-["aria-disabled"?](#) +[chunkForSymbol](#) -[Booleanish](#booleanish) \| undefined +(symbolName: string, chunk: string \| null, parent?: string) => readonly [symbol: string, chunk: string] \| undefined -_(Optional)_ Indicates that the element is perceivable but disabled, so it is not editable or otherwise operable. +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.)
-["aria-dropeffect"?](#) +[importSymbol](#) -'none' \| 'copy' \| 'execute' \| 'link' \| 'move' \| 'popup' \| undefined +(containerEl: Element \| undefined, url: string \| URL \| undefined \| null, symbol: string) => [ValueOrPromise](#valueorpromise)<any> -_(Optional)_ Indicates what functions can be performed when a dragged object is released on the drop target. +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.
-["aria-errormessage"?](#) +[isServer](#) -string \| undefined +boolean -_(Optional)_ Identifies the element that provides an error message for the object. +True of running on the server platform.
-["aria-expanded"?](#) +[nextTick](#) -[Booleanish](#booleanish) \| undefined +(fn: () => any) => Promise<any> -_(Optional)_ Indicates whether the element, or another grouping element it controls, is currently expanded or collapsed. +Perform operation on next tick.
-["aria-flowto"?](#) +[raf](#) -string \| undefined +(fn: () => any) => Promise<any> -_(Optional)_ Identifies the next element (or elements) in an alternate reading order of content which, at the user's discretion, allows assistive technology to override the general default of reading in document source order. +Perform operation on next request-animation-frame.
+
-["aria-grabbed"?](#) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/platform/types.ts) - +## CorrectedToggleEvent - +This corrects the TS definition for ToggleEvent -[Booleanish](#booleanish) \| undefined +```typescript +export interface CorrectedToggleEvent extends Event +``` - +**Extends:** Event -_(Optional)_ Indicates an element's "grabbed" state in a drag-and-drop operation. + - - + -
-
+Property -["aria-haspopup"?](#) + - +Modifiers - + -boolean \| 'false' \| 'true' \| 'menu' \| 'listbox' \| 'tree' \| 'grid' \| 'dialog' \| undefined +Type - + -_(Optional)_ Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element. +Description -
+
-["aria-hidden"?](#) +[newState](#) +`readonly` + -[Booleanish](#booleanish) \| undefined +'open' \| 'closed' -_(Optional)_ Indicates whether the element is exposed to an accessibility API. -
-["aria-invalid"?](#) +[prevState](#) +`readonly` + -boolean \| 'false' \| 'true' \| 'grammar' \| 'spelling' \| undefined +'open' \| 'closed' -_(Optional)_ Indicates the entered value does not conform to the format expected by the application. -
- -["aria-keyshortcuts"?](#) +
- +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts) - +## createComputed$ -string \| undefined +Create a computed signal which is calculated from the given QRL. A computed signal is a signal which is calculated from other signals. When the signals change, the computed signal is recalculated. - +The QRL must be a function which returns the value of the signal. The function must not have side effects, and it mus be synchronous. -_(Optional)_ Indicates keyboard shortcuts that an author has implemented to activate or give focus to an element. +If you need the function to be async, use `useSignal` and `useTask$` instead. - - +```typescript +createComputed$: (qrl: () => T) => T extends Promise ? never : ComputedSignal +``` -["aria-label"?](#) + - + +
- +Parameter - + -string \| undefined +Type - + -_(Optional)_ Defines a string value that labels the current element. +Description -
+
-["aria-labelledby"?](#) +qrl +() => T + -string \| undefined +
+**Returns:** - +T extends Promise<any> ? never : [ComputedSignal](#computedsignal)<T> -_(Optional)_ Identifies the element (or elements) that labels the current element. +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts) - - +## createContextId -["aria-level"?](#) +Create a context ID to be used in your application. The name should be written with no spaces. - +Context is a way to pass stores to the child components without prop-drilling. - +Use `createContextId()` to create a `ContextId`. A `ContextId` is just a serializable identifier for the context. It is not the context value itself. See `useContextProvider()` and `useContext()` for the values. Qwik needs a serializable ID for the context so that the it can track context providers and consumers in a way that survives resumability. -number \| undefined +### Example - +```tsx +// Declare the Context type. +interface TodosStore { + items: string[]; +} +// Create a Context ID (no data is saved here.) +// You will use this ID to both create and retrieve the Context. +export const TodosContext = createContextId("Todos"); + +// Example of providing context to child components. +export const App = component$(() => { + useContextProvider( + TodosContext, + useStore({ + items: ["Learn Qwik", "Build Qwik app", "Profit"], + }), + ); -_(Optional)_ Defines the hierarchical level of an element within a structure. + return ; +}); - - +// Example of retrieving the context provided by a parent component. +export const Items = component$(() => { + const todos = useContext(TodosContext); + return ( +
    + {todos.items.map((item) => ( +
  • {item}
  • + ))} +
+ ); +}); +``` -["aria-live"?](#) +```typescript +createContextId: (name: string) => ContextId; +``` - + - + -
- +Parameter -'off' \| 'assertive' \| 'polite' \| undefined + - +Type -_(Optional)_ Indicates that an element will be updated, and describes the types of updates the user agents, assistive technologies, and user can expect from the live region. + -
+Description -["aria-modal"?](#) +
- +name -[Booleanish](#booleanish) \| undefined +string -_(Optional)_ Indicates whether an element is modal when displayed. +The name of the context.
+
+**Returns:** -["aria-multiline"?](#) +[ContextId](#contextid)<STATE> - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-context.ts) - +## createSignal -[Booleanish](#booleanish) \| undefined +Creates a Signal with the given value. If no value is given, the signal is created with `undefined`. - +```typescript +createSignal: { + (): Signal; + (value: T): Signal; +} +``` -_(Optional)_ Indicates whether a text box accepts multiple lines of input or only a single line. +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts) - - +## CSSProperties -["aria-multiselectable"?](#) +```typescript +export interface CSSProperties extends CSS.Properties, CSS.PropertiesHyphen +``` - +**Extends:** CSS.Properties<string \| number>, CSS.PropertiesHyphen<string \| number> - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-generated.ts) -[Booleanish](#booleanish) \| undefined +## DevJSX - +```typescript +export interface DevJSX +``` -_(Optional)_ Indicates that the user may select more than one item from the current selectable descendants. + - - + -
-
+Property -["aria-orientation"?](#) + - +Modifiers - + -'horizontal' \| 'vertical' \| undefined +Type - + -_(Optional)_ Indicates whether the element's orientation is horizontal, vertical, or unknown/ambiguous. +Description -
+
-["aria-owns"?](#) +[columnNumber](#) -string \| undefined +number -_(Optional)_ Identifies an element (or elements) in order to define a visual, functional, or contextual parent/child relationship between DOM elements where the DOM hierarchy cannot be used to represent the relationship. -
-["aria-placeholder"?](#) +[fileName](#) -string \| undefined +string -_(Optional)_ Defines a short hint (a word or short phrase) intended to aid the user with data entry when the control has no value. A hint could be a sample value or a brief description of the expected format. -
-["aria-posinset"?](#) +[lineNumber](#) -number \| undefined +number -_(Optional)_ Defines an element's number or position in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM. -
-["aria-pressed"?](#) +[stack?](#) -boolean \| 'false' \| 'mixed' \| 'true' \| undefined +string -_(Optional)_ Indicates the current "pressed" state of toggle buttons. +_(Optional)_
+
-["aria-readonly"?](#) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-node.ts) - - - - -[Booleanish](#booleanish) \| undefined - - - -_(Optional)_ Indicates that the element is not editable, but is otherwise operable. - - - - -["aria-relevant"?](#) - - +## DOMAttributes - +The Qwik-specific attributes that DOM elements accept -'additions' \| 'additions removals' \| 'additions text' \| 'all' \| 'removals' \| 'removals additions' \| 'removals text' \| 'text' \| 'text additions' \| 'text removals' \| undefined +```typescript +export interface DOMAttributes extends DOMAttributesBase, QwikEvents +``` - +**Extends:** DOMAttributesBase<EL>, QwikEvents<EL> -_(Optional)_ Indicates what notifications the user agent will trigger when the accessibility tree within a live region is modified. + - - + -
-
+Property -["aria-required"?](#) + - +Modifiers - + -[Booleanish](#booleanish) \| undefined +Type - + -_(Optional)_ Indicates that user input is required on the element before a form may be submitted. +Description -
+
-["aria-roledescription"?](#) +[class?](#) -string \| undefined +[ClassList](#classlist) \| [Signal](#signal)<[ClassList](#classlist)> \| undefined -_(Optional)_ Defines a human-readable, author-localized description for the role of an element. +_(Optional)_
- -["aria-rowcount"?](#) - - - - +
-number \| undefined +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts) - +## EagernessOptions -_(Optional)_ Defines the total number of rows in a table, grid, or treegrid. +```typescript +export type EagernessOptions = "visible" | "load" | "idle"; +``` - - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) -["aria-rowindex"?](#) +## Element - +```typescript +type Element = JSXOutput; +``` - +**References:** [JSXOutput](#jsxoutput) -number \| undefined +## ElementChildrenAttribute - +```typescript +interface ElementChildrenAttribute +``` -_(Optional)_ Defines an element's row index or position with respect to the total number of rows within a table, grid, or treegrid. + - - + -
-
+Property -["aria-rowspan"?](#) + - +Modifiers - + -number \| undefined +Type - + -_(Optional)_ Defines the number of rows spanned by a cell or gridcell within a table, grid, or treegrid. +Description -
+
-["aria-selected"?](#) +[children](#) -[Booleanish](#booleanish) \| undefined +[JSXChildren](#jsxchildren) -_(Optional)_ Indicates the current "selected" state of various widgets. -
+
-["aria-setsize"?](#) +## ElementType - +```typescript +type ElementType = string | FunctionComponent>; +``` - +**References:** [FunctionComponent](#functioncomponent) -number \| undefined +## ErrorBoundaryStore - +```typescript +export interface ErrorBoundaryStore +``` -_(Optional)_ Defines the number of items in the current set of listitems or treeitems. Not required if all elements in the set are present in the DOM. + - - + -
-
+Property -["aria-sort"?](#) + - +Modifiers - + -'none' \| 'ascending' \| 'descending' \| 'other' \| undefined +Type - + -_(Optional)_ Indicates if items in a table or grid are sorted in ascending or descending order. +Description -
+
-["aria-valuemax"?](#) +[error](#) -number \| undefined +any \| undefined -_(Optional)_ Defines the maximum allowed value for a range widget. -
- -["aria-valuemin"?](#) - - - - - -number \| undefined - - +
-_(Optional)_ Defines the minimum allowed value for a range widget. +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/error/error-handling.ts) - - +## event$ -["aria-valuenow"?](#) +```typescript +event$: (qrl: T) => import("./qrl.public").QRL; +``` - + - +
- +Parameter -number \| undefined + - +Type -_(Optional)_ Defines the current value for a range widget. + -
+Description -["aria-valuetext"?](#) +
- +qrl -string \| undefined +T -_(Optional)_ Defines the human readable text alternative of aria-valuenow for a range widget. -
+**Returns:** -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) - -## AriaRole - -```typescript -export type AriaRole = - | "alert" - | "alertdialog" - | "application" - | "article" - | "banner" - | "button" - | "cell" - | "checkbox" - | "columnheader" - | "combobox" - | "complementary" - | "contentinfo" - | "definition" - | "dialog" - | "directory" - | "document" - | "feed" - | "figure" - | "form" - | "grid" - | "gridcell" - | "group" - | "heading" - | "img" - | "link" - | "list" - | "listbox" - | "listitem" - | "log" - | "main" - | "marquee" - | "math" - | "menu" - | "menubar" - | "menuitem" - | "menuitemcheckbox" - | "menuitemradio" - | "navigation" - | "none" - | "note" - | "option" - | "presentation" - | "progressbar" - | "radio" - | "radiogroup" - | "region" - | "row" - | "rowgroup" - | "rowheader" - | "scrollbar" - | "search" - | "searchbox" - | "separator" - | "slider" - | "spinbutton" - | "status" - | "switch" - | "tab" - | "table" - | "tablist" - | "tabpanel" - | "term" - | "textbox" - | "timer" - | "toolbar" - | "tooltip" - | "tree" - | "treegrid" - | "treeitem" - | (string & {}); -``` +import("./qrl.public").[QRL](#qrl)<T> -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/qrl.public.dollar.ts) -## AudioHTMLAttributes +## EventHandler + +A DOM event handler ```typescript -export interface AudioHTMLAttributes extends Attrs<'audio', T> +export type EventHandler = { + bivarianceHack(event: EV, element: EL): any; +}["bivarianceHack"]; ``` -**Extends:** Attrs<'audio', T> +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +## force -## BaseHTMLAttributes +Use this to force recalculation and running subscribers, for example when the calculated value mutates but remains the same object. Useful for third-party libraries. ```typescript -export interface BaseHTMLAttributes extends Attrs<'base', T> +force(): void; ``` -**Extends:** Attrs<'base', T> +**Returns:** -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +void -## BlockquoteHTMLAttributes +## Fragment ```typescript -export interface BlockquoteHTMLAttributes extends Attrs<'blockquote', T> +Fragment: FunctionComponent<{ + children?: any; + key?: string | number | null; +}>; ``` -**Extends:** Attrs<'blockquote', T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/jsx-runtime.ts) -## Booleanish - -```typescript -export type Booleanish = boolean | `${boolean}`; -``` +## FunctionComponent -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +Any function taking a props object that returns JSXOutput. -## ButtonHTMLAttributes +The `key`, `flags` and `dev` parameters are for internal use. ```typescript -export interface ButtonHTMLAttributes extends Attrs<'button', T> +export type FunctionComponent

= { + renderFn( + props: P, + key: string | null, + flags: number, + dev?: DevJSX, + ): JSXOutput; +}["renderFn"]; ``` -**Extends:** Attrs<'button', T> +**References:** [DevJSX](#devjsx), [JSXOutput](#jsxoutput) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-node.ts) -## cache +## getDomContainer ```typescript -cache(policyOrMilliseconds: number | 'immutable'): void; +export declare function getDomContainer( + element: Element | VNode, +): IClientContainer; ```
@@ -1094,11 +1091,11 @@ Description
-policyOrMilliseconds +element -number \| 'immutable' +Element \| VNode @@ -1106,161 +1103,128 @@ number \| 'immutable'
**Returns:** -void +IClientContainer + +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/client/dom-container.ts) + +## getLocale -## CanvasHTMLAttributes +Retrieve the current locale. + +If no current locale and there is no `defaultLocale` the function throws an error. ```typescript -export interface CanvasHTMLAttributes extends Attrs<'canvas', T> +export declare function getLocale(defaultLocale?: string): string; ``` -**Extends:** Attrs<'canvas', T> + + +
-[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +Parameter -## ClassList + -A class list can be a string, a boolean, an array, or an object. +Type -If it's an array, each item is a class list and they are all added. + -If it's an object, then the keys are class name strings, and the values are booleans that determine if the class name string should be added or not. +Description -```typescript -export type ClassList = - | string - | undefined - | null - | false - | Record - | ClassList[]; -``` +
-**References:** [ClassList](#classlist) +defaultLocale + + -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts) +string -## cleanup + -```typescript -cleanup(): void; -``` +_(Optional)_ +
**Returns:** -void +string -## ColgroupHTMLAttributes +The locale. -```typescript -export interface ColgroupHTMLAttributes extends Attrs<'colgroup', T> -``` +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-locale.ts) -**Extends:** Attrs<'colgroup', T> +## getPlatform -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +Retrieve the `CorePlatform`. -## ColHTMLAttributes +The `CorePlatform` is also responsible for retrieving the Manifest, that contains mappings from symbols to javascript import chunks. For this reason, `CorePlatform` can't be global, but is specific to the application currently running. On server it is possible that many different applications are running in a single server instance, and for this reason the `CorePlatform` is associated with the application document. ```typescript -export interface ColHTMLAttributes extends Attrs<'col', T> +getPlatform: () => CorePlatform; ``` -**Extends:** Attrs<'col', T> +**Returns:** -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +[CorePlatform](#coreplatform) -## Component +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/platform/platform.ts) -Type representing the Qwik component. +## h -`Component` is the type returned by invoking `component$`. +The legacy transform, used in special cases like `

`. Note that the children are spread arguments, instead of a prop like in jsx() calls. -```tsx -interface MyComponentProps { - someProp: string; -} -const MyComponent: Component = component$( - (props: MyComponentProps) => { - return {props.someProp}; - }, -); -``` +Also note that this disables optimizations. ```typescript -export type Component = FunctionComponent>; +export declare function h< + TYPE extends string | FunctionComponent, + PROPS extends {} = {}, +>(type: TYPE, props?: PROPS | null, ...children: any[]): JSXNode; ``` -**References:** [FunctionComponent](#functioncomponent), [PublicProps](#publicprops) + + + +
-[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/component/component.public.ts) +Parameter -## component$ + -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 +Type -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} - -
- ); -}); -``` +Description -- `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: +type -```tsx -export const OtherComponent = component$(() => { - return ; -}); -``` + -See also: `component`, `useCleanup`, `onResume`, `onPause`, `useOn`, `useOnDocument`, `useOnWindow`, `useStyles` +TYPE -```typescript -component$: (onMount: OnRenderFn) => Component; -``` + - + - +
+
-Parameter +props - + -Type +PROPS \| null - + -Description +_(Optional)_ -
+
-onMount +children -[OnRenderFn](#onrenderfn)<PROPS> +any[] @@ -1268,113 +1232,102 @@ onMount
**Returns:** -[Component](#component)<PROPS> +[JSXNode](#jsxnode)<TYPE> -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/component/component.public.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/jsx-runtime.ts) -## ComponentBaseProps +## implicit$FirstArg -```typescript -export interface ComponentBaseProps -``` +Create a `____$(...)` convenience method from `___(...)`. - - + +
+It is very common for functions to take a lazy-loadable resource as a first argument. For this reason, the Qwik Optimizer automatically extracts the first argument from any function which ends in `$`. -Property +This means that `foo$(arg0)` and `foo($(arg0))` are equivalent with respect to Qwik Optimizer. The former is just a shorthand for the latter. - +For example, these function calls are equivalent: -Modifiers +- `component$(() => {...})` is same as `component($(() => {...}))` - +```tsx +export function myApi(callback: QRL<() => void>): void { + // ... +} -Type +export const myApi$ = implicit$FirstArg(myApi); +// type of myApi$: (callback: () => void): void - +// can be used as: +myApi$(() => console.log("callback")); -Description +// will be transpiled to: +// FILE: +myApi(qrl("./chunk-abc.js", "callback")); -
+// FILE: chunk-abc.js +export const callback = () => console.log("callback"); +``` -["q:slot"?](#componentbaseprops-_q_slot_) +```typescript +implicit$FirstArg: ( + fn: (qrl: QRL, ...rest: REST) => RET, + ) => + (qrl: FIRST, ...rest: REST) => + RET; +``` - + - +
- +Parameter -string + - +Type -_(Optional)_ + -
+Description -[key?](#) +
- +fn -string \| number \| null \| undefined +(qrl: [QRL](#qrl)<FIRST>, ...rest: REST) => RET -_(Optional)_ +A function that should have its first argument automatically `$`.
+**Returns:** -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts) - -## componentQrl - -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: +((qrl: FIRST, ...rest: REST) => RET) -### Example +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/implicit_dollar.ts) -An example showing how to create a counter component: +## IntrinsicAttributes -```tsx -export interface CounterProps { - initialValue?: number; - step?: number; -} -export const Counter = component$((props: CounterProps) => { - const state = useStore({ count: props.initialValue || 0 }); - return ( -
- {state.count} - -
- ); -}); +```typescript +interface IntrinsicAttributes extends QwikIntrinsicAttributes ``` -- `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. +**Extends:** QwikIntrinsicAttributes -The above can then be used like so: +## IntrinsicElements -```tsx -export const OtherComponent = component$(() => { - return ; -}); +```typescript +interface IntrinsicElements extends LenientQwikElements ``` -See also: `component`, `useCleanup`, `onResume`, `onPause`, `useOn`, `useOnDocument`, `useOnWindow`, `useStyles` +**Extends:** LenientQwikElements + +## isSignal ```typescript -componentQrl: >( - componentQrl: QRL>, -) => Component; +isSignal: (value: any) => value is ISignal ```
@@ -1392,11 +1345,11 @@ Description
-componentQrl +value -[QRL](#qrl)<[OnRenderFn](#onrenderfn)<PROPS>> +any @@ -1404,73 +1357,25 @@ componentQrl
**Returns:** -[Component](#component)<PROPS> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/component/component.public.ts) - -## ComputedFn - -```typescript -export type ComputedFn = () => T; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) - -## ContextId - -ContextId is a typesafe ID for your context. - -Context is a way to pass stores to the child components without prop-drilling. - -Use `createContextId()` to create a `ContextId`. A `ContextId` is just a serializable identifier for the context. It is not the context value itself. See `useContextProvider()` and `useContext()` for the values. Qwik needs a serializable ID for the context so that the it can track context providers and consumers in a way that survives resumability. - -### Example - -```tsx -// Declare the Context type. -interface TodosStore { - items: string[]; -} -// Create a Context ID (no data is saved here.) -// You will use this ID to both create and retrieve the Context. -export const TodosContext = createContextId("Todos"); +value is [ISignal](#signal)<unknown> -// Example of providing context to child components. -export const App = component$(() => { - useContextProvider( - TodosContext, - useStore({ - items: ["Learn Qwik", "Build Qwik app", "Profit"], - }), - ); +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.ts) - return ; -}); +## jsx -// Example of retrieving the context provided by a parent component. -export const Items = component$(() => { - const todos = useContext(TodosContext); - return ( -
    - {todos.items.map((item) => ( -
  • {item}
  • - ))} -
- ); -}); -``` +Used by the JSX transpilers to create a JSXNode. Note that the optimizer will not use this, instead using \_jsxSplit and \_jsxSorted directly. ```typescript -export interface ContextId +jsx: >( + type: T, + props: T extends FunctionComponent ? PROPS : Props, + key?: string | number | null, +) => JSXNode; ``` +
-Property - - - -Modifiers +Parameter @@ -1483,63 +1388,83 @@ Description
-[\_\_brand_context_type\_\_](#) +type -`readonly` +T -STATE +
+ +props -Design-time property to store type information for the context. +T extends [FunctionComponent](#functioncomponent)<infer PROPS> ? PROPS : Props + +
-[id](#) +key -`readonly` +string \| number \| null -string - - - -A unique ID for the context. +_(Optional)_
+**Returns:** -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-context.ts) +[JSXNode](#jsxnode)<T> -## CorePlatform +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/jsx-runtime.ts) -Low-level API for platform abstraction. +## JSXChildren -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. +```typescript +export type JSXChildren = + | string + | number + | boolean + | null + | undefined + | Function + | RegExp + | JSXChildren[] + | Promise + | Signal + | JSXNode; +``` -`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. +**References:** [JSXChildren](#jsxchildren), [Signal](#signal), [JSXNode](#jsxnode) -This is a low-level API and there should not be a need for you to access this. +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts) + +## jsxDEV ```typescript -export interface CorePlatform +jsxDEV: >( + type: T, + props: T extends FunctionComponent ? PROPS : Props, + key: string | number | null | undefined, + _isStatic: boolean, + opts: JsxDevOpts, + _ctx: unknown, +) => JSXNode; ``` +
-Property - - - -Modifiers +Parameter @@ -1552,45 +1477,40 @@ Description
-[chunkForSymbol](#) - - +type -(symbolName: string, chunk: string \| null, parent?: string) => readonly [symbol: string, chunk: string] \| undefined +T -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.) -
-[importSymbol](#) +props +T extends [FunctionComponent](#functioncomponent)<infer PROPS> ? PROPS : Props + -(containerEl: Element \| undefined, url: string \| URL \| undefined \| null, symbol: string) => [ValueOrPromise](#valueorpromise)<any> +
- +key -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`. +string \| number \| null \| undefined -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. +
-[isServer](#) - - +\_isStatic @@ -1598,53 +1518,44 @@ boolean -True of running on the server platform. -
-[nextTick](#) - - +opts -(fn: () => any) => Promise<any> +JsxDevOpts -Perform operation on next tick. -
-[raf](#) - - +\_ctx -(fn: () => any) => Promise<any> +unknown -Perform operation on next request-animation-frame. -
+**Returns:** -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/platform/types.ts) +[JSXNode](#jsxnode)<T> -## CorrectedToggleEvent +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/jsx-runtime.ts) -This corrects the TS definition for ToggleEvent +## JSXNode + +A JSX Node, an internal structure. You probably want to use `JSXOutput` instead. ```typescript -export interface CorrectedToggleEvent extends Event +export interface JSXNode ``` -**Extends:** Event - -
Property @@ -1664,356 +1575,302 @@ Description
-[newState](#) +[children](#) -`readonly` - -'open' \| 'closed' +[JSXChildren](#jsxchildren) \| null
-[prevState](#) +[dev?](#) -`readonly` - -'open' \| 'closed' +[DevJSX](#devjsx) +_(Optional)_ +
+
-[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts) +[key](#) -## createComputed$ + -> Warning: This API is now obsolete. -> -> This is a technology preview + -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. +string \| null -```typescript -createComputed$: (qrl: ComputedFn) => Signal>; -``` + - + - +
+
-Parameter +[props](#) - + -Type + - +T extends [FunctionComponent](#functioncomponent)<infer P> ? P : Record<any, unknown> -Description + -
+
-qrl +[type](#) + + -[ComputedFn](#computedfn)<T> +T
-**Returns:** -[Signal](#signal)<Awaited<T>> +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-node.ts) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) +## JSXOutput -## createComputedQrl +Any valid output for a component ```typescript -createComputedQrl: (qrl: QRL>) => Signal>; +export type JSXOutput = + | JSXNode + | string + | number + | boolean + | null + | undefined + | JSXOutput[]; ``` - - -
+**References:** [JSXNode](#jsxnode), [JSXOutput](#jsxoutput) -Parameter +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-node.ts) - +## JSXTagName -Type +```typescript +export type JSXTagName = + | keyof HTMLElementTagNameMap + | Omit; +``` - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts) -Description +## KnownEventNames -
+The names of events that Qwik knows about. They are all lowercase, but on the JSX side, they are PascalCase for nicer DX. (`onAuxClick$` vs `onauxclick$`) -qrl +```typescript +export type KnownEventNames = LiteralUnion; +``` - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -[QRL](#qrl)<[ComputedFn](#computedfn)<T>> +## NativeAnimationEvent - +> Warning: This API is now obsolete. +> +> Use `AnimationEvent` and use the second argument to the handler function for the current event target -
-**Returns:** +```typescript +export type NativeAnimationEvent = AnimationEvent; +``` -[Signal](#signal)<Awaited<T>> +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) +## NativeClipboardEvent -## createContextId +> Warning: This API is now obsolete. +> +> Use `ClipboardEvent` and use the second argument to the handler function for the current event target -Create a context ID to be used in your application. The name should be written with no spaces. +```typescript +export type NativeClipboardEvent = ClipboardEvent; +``` -Context is a way to pass stores to the child components without prop-drilling. +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -Use `createContextId()` to create a `ContextId`. A `ContextId` is just a serializable identifier for the context. It is not the context value itself. See `useContextProvider()` and `useContext()` for the values. Qwik needs a serializable ID for the context so that the it can track context providers and consumers in a way that survives resumability. +## NativeCompositionEvent -### Example +> Warning: This API is now obsolete. +> +> Use `CompositionEvent` and use the second argument to the handler function for the current event target -```tsx -// Declare the Context type. -interface TodosStore { - items: string[]; -} -// Create a Context ID (no data is saved here.) -// You will use this ID to both create and retrieve the Context. -export const TodosContext = createContextId("Todos"); +```typescript +export type NativeCompositionEvent = CompositionEvent; +``` -// Example of providing context to child components. -export const App = component$(() => { - useContextProvider( - TodosContext, - useStore({ - items: ["Learn Qwik", "Build Qwik app", "Profit"], - }), - ); +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) - return ; -}); +## NativeDragEvent -// Example of retrieving the context provided by a parent component. -export const Items = component$(() => { - const todos = useContext(TodosContext); - return ( -
    - {todos.items.map((item) => ( -
  • {item}
  • - ))} -
- ); -}); -``` +> Warning: This API is now obsolete. +> +> Use `DragEvent` and use the second argument to the handler function for the current event target ```typescript -createContextId: (name: string) => ContextId; +export type NativeDragEvent = DragEvent; ``` - - -
- -Parameter +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) - +## NativeFocusEvent -Type +> Warning: This API is now obsolete. +> +> Use `FocusEvent` and use the second argument to the handler function for the current event target - - -Description - -
- -name - - - -string - - - -The name of the context. - -
-**Returns:** - -[ContextId](#contextid)<STATE> +```typescript +export type NativeFocusEvent = FocusEvent; +``` -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-context.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -## createSignal +## NativeKeyboardEvent > Warning: This API is now obsolete. > -> This is a technology preview - -Creates a signal. - -If the initial state is a function, the function is invoked to calculate the actual initial state. +> Use `KeyboardEvent` and use the second argument to the handler function for the current event target ```typescript -createSignal: UseSignal; +export type NativeKeyboardEvent = KeyboardEvent; ``` -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-signal.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -## CSSProperties +## NativeMouseEvent + +> Warning: This API is now obsolete. +> +> Use `MouseEvent` and use the second argument to the handler function for the current event target ```typescript -export interface CSSProperties extends CSS.Properties, CSS.PropertiesHyphen +export type NativeMouseEvent = MouseEvent; ``` -**Extends:** CSS.Properties<string \| number>, CSS.PropertiesHyphen<string \| number> +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +## NativePointerEvent -## DataHTMLAttributes +> Warning: This API is now obsolete. +> +> Use `PointerEvent` and use the second argument to the handler function for the current event target ```typescript -export interface DataHTMLAttributes extends Attrs<'data', T> +export type NativePointerEvent = PointerEvent; ``` -**Extends:** Attrs<'data', T> +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +## NativeTouchEvent -## DelHTMLAttributes +> Warning: This API is now obsolete. +> +> Use `TouchEvent` and use the second argument to the handler function for the current event target ```typescript -export interface DelHTMLAttributes extends Attrs<'del', T> +export type NativeTouchEvent = TouchEvent; ``` -**Extends:** Attrs<'del', T> +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +## NativeTransitionEvent -## DetailsHTMLAttributes +> Warning: This API is now obsolete. +> +> Use `TransitionEvent` and use the second argument to the handler function for the current event target ```typescript -export interface DetailsHTMLAttributes extends Attrs<'details', T> +export type NativeTransitionEvent = TransitionEvent; ``` -**Extends:** Attrs<'details', T> +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +## NativeUIEvent -## DevJSX +> Warning: This API is now obsolete. +> +> Use `UIEvent` and use the second argument to the handler function for the current event target ```typescript -export interface DevJSX +export type NativeUIEvent = UIEvent; ``` - - - - - -
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -[columnNumber](#) - - - - - -number - - - -
- -[fileName](#) - - - - - -string - - - -
- -[lineNumber](#) - - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) - +## NativeWheelEvent -number +> Warning: This API is now obsolete. +> +> Use `WheelEvent` and use the second argument to the handler function for the current event target - +```typescript +export type NativeWheelEvent = WheelEvent; +``` -
+[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -[stack?](#) +## noSerialize - +Returned type of the `noSerialize()` function. It will be TYPE or undefined. - +```typescript +export type NoSerialize = + | (T & { + __no_serialize__: true; + }) + | undefined; +``` -string +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/utils/serialize-utils.ts) - +## NoSerialize -_(Optional)_ +Returned type of the `noSerialize()` function. It will be TYPE or undefined. -
+```typescript +export type NoSerialize = + | (T & { + __no_serialize__: true; + }) + | undefined; +``` -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-node.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/utils/serialize-utils.ts) -## DialogHTMLAttributes +## OnRenderFn ```typescript -export interface DialogHTMLAttributes extends Attrs<'dialog', T> +export type OnRenderFn = (props: PROPS) => JSXOutput; ``` -**Extends:** Attrs<'dialog', T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +**References:** [JSXOutput](#jsxoutput) -## DOMAttributes +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/component.public.ts) -The Qwik-specific attributes that DOM elements accept +## OnVisibleTaskOptions ```typescript -export interface DOMAttributes extends DOMAttributesBase, QwikEvents +export interface OnVisibleTaskOptions ``` -**Extends:** DOMAttributesBase<EL>, QwikEvents<EL> -
Property @@ -2033,52 +1890,45 @@ Description
-[class?](#) +[strategy?](#) -[ClassList](#classlist) \| [Signal](#signal)<[ClassList](#classlist)> \| undefined +[VisibleTaskStrategy](#visibletaskstrategy) -_(Optional)_ +_(Optional)_ 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.
-[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts) - -## EagernessOptions - -```typescript -export type EagernessOptions = "visible" | "load" | "idle"; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-visible-task.ts) -## Element +## PrefetchGraph -```typescript -type Element = JSXOutput; -``` +> This API is provided as a beta preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. -**References:** [JSXOutput](#jsxoutput) +Load the prefetch graph for the container. -## ElementChildrenAttribute +Each Qwik container needs to include its own prefetch graph. ```typescript -interface ElementChildrenAttribute +PrefetchGraph: (opts?: { + base?: string; + manifestHash?: string; + manifestURL?: string; + nonce?: string; +}) => JSXOutput; ```
-Property - - - -Modifiers +Parameter @@ -2091,50 +1941,48 @@ Description
-[children](#) +opts +{ base?: string; manifestHash?: string; manifestURL?: string; nonce?: string; } + -[JSXChildren](#jsxchildren) +_(Optional)_ Options for the loading prefetch graph. - +- `base` - Base of the graph. For a default installation this will default to the q:base value `/build/`. But if more than one MFE is installed on the page, then each MFE needs to have its own base. - `manifestHash` - Hash of the manifest file to load. If not provided the hash will be extracted from the container attribute `q:manifest-hash` and assume the default build file `${base}/q-bundle-graph-${manifestHash}.json`. - `manifestURL` - URL of the manifest file to load if non-standard bundle graph location name.
+**Returns:** -## ElementType - -```typescript -type ElementType = string | FunctionComponent>; -``` - -**References:** [FunctionComponent](#functioncomponent) +[JSXOutput](#jsxoutput) -## EmbedHTMLAttributes +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/prefetch-service-worker/prefetch.ts) -```typescript -export interface EmbedHTMLAttributes extends Attrs<'embed', T> -``` +## PrefetchServiceWorker -**Extends:** Attrs<'embed', T> +> This API is provided as a beta preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +Install a service worker which will prefetch the bundles. -## ErrorBoundaryStore +There can only be one service worker per page. Because there can be many separate Qwik Containers on the page each container needs to load its prefetch graph using `PrefetchGraph` component. ```typescript -export interface ErrorBoundaryStore +PrefetchServiceWorker: (opts: { + base?: string; + scope?: string; + path?: string; + verbose?: boolean; + fetchBundleGraph?: boolean; + nonce?: string; +}) => JSXOutput; ```
-Property - - - -Modifiers +Parameter @@ -2147,7364 +1995,998 @@ Description
-[error](#) +opts +{ base?: string; scope?: string; path?: string; verbose?: boolean; fetchBundleGraph?: boolean; nonce?: string; } + -any \| undefined +Options for the prefetch service worker. - +- `base` - Base URL for the service worker. Default is `import.meta.env.BASE_URL`, which is defined by Vite's `config.base` and defaults to `/`. - `scope` - Base URL for when the service-worker will activate. Default is `/` - `path` - Path to the service worker. Default is `qwik-prefetch-service-worker.js` unless you pass a path that starts with a `/` then the base is ignored. Default is `qwik-prefetch-service-worker.js` - `verbose` - Verbose logging for the service worker installation. Default is `false` - `nonce` - Optional nonce value for security purposes, defaults to `undefined`.
+**Returns:** + +[JSXOutput](#jsxoutput) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/error-handling.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/prefetch-service-worker/prefetch.ts) -## event$ +## PropFunction + +Alias for `QRL`. Of historic relevance only. ```typescript -event$: (qrl: T) => QRL; +export type PropFunction = QRL; ``` - - -
+**References:** [QRL](#qrl) -Parameter - - - -Type - - - -Description - -
- -qrl - - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/qrl.public.ts) -T - - - -
-**Returns:** - -[QRL](#qrl)<T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts) - -## EventHandler +## PropsOf -A DOM event handler +Infers `Props` from the component or tag. ```typescript -export type EventHandler = { - bivarianceHack(event: EV, element: EL): any; -}["bivarianceHack"]; +export type PropsOf = COMP extends string + ? COMP extends keyof QwikIntrinsicElements + ? QwikIntrinsicElements[COMP] + : QwikIntrinsicElements["span"] + : NonNullable extends never + ? never + : COMP extends FunctionComponent + ? PROPS extends Record + ? IsAny extends true + ? never + : ObjectProps + : COMP extends Component + ? ObjectProps + : PROPS + : never; ``` -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts) +**References:** [QwikIntrinsicElements](#qwikintrinsicelements), [FunctionComponent](#functioncomponent), [Component](#component) -## eventQrl +```tsx +const Desc = component$( + ({ desc, ...props }: { desc: string } & PropsOf<"div">) => { + return
{desc}
; + }, +); -```typescript -eventQrl: (qrl: QRL) => QRL; +const TitleBox = component$( + ({ title, ...props }: { title: string } & PropsOf) => { + return ( + +

{title}

+
+ ); + }, +); ``` - - -
- -Parameter - - - -Type - - - -Description - -
- -qrl - - - -[QRL](#qrl)<T> - - - -
-**Returns:** - -[QRL](#qrl)<T> +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/component.public.ts) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts) +## PublicProps -## FieldsetHTMLAttributes +Extends the defined component PROPS, adding the default ones (children and q:slot) and allowing plain functions to QRL arguments. ```typescript -export interface FieldsetHTMLAttributes extends Attrs<'fieldset', T> +export type PublicProps = (PROPS extends Record + ? Omit & _Only$ + : unknown extends PROPS + ? {} + : PROPS) & + ComponentBaseProps & + ComponentChildren; ``` -**Extends:** Attrs<'fieldset', T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) - -## FormHTMLAttributes - -```typescript -export interface FormHTMLAttributes extends Attrs<'form', T> -``` +**References:** [ComponentBaseProps](#componentbaseprops) -**Extends:** Attrs<'form', T> +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/component.public.ts) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +## qrl -## Fragment +The `QRL` type represents a lazy-loadable AND serializable resource. -```typescript -Fragment: FunctionComponent<{ - children?: any; - key?: string | number | null; -}>; -``` +QRL stands for Qwik URL. -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/jsx-runtime.ts) +Use `QRL` when you want to refer to a lazy-loaded resource. `QRL`s are most often used for code (functions) but can also be used for other resources such as `string`s in the case of styles. -## FunctionComponent +`QRL` is an opaque token that is generated by the Qwik Optimizer. (Do not rely on any properties in `QRL` as it may change between versions.) -Any function taking a props object that returns JSXOutput. +\#\# Creating `QRL` references -The `key`, `flags` and `dev` parameters are for internal use. +Creating `QRL` is done using `$(...)` function. `$(...)` is a special marker for the Qwik Optimizer that marks that the code should be extracted into a lazy-loaded symbol. -```typescript -export type FunctionComponent

= { - renderFn( - props: P, - key: string | null, - flags: number, - dev?: DevJSX, - ): JSXOutput; -}["renderFn"]; +```tsx +useOnDocument( + "mousemove", + $((event) => console.log("mousemove", event)), +); ``` -**References:** [DevJSX](#devjsx), [JSXOutput](#jsxoutput) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-node.ts) - -## getPlatform - -Retrieve the `CorePlatform`. +In the above code, the Qwik Optimizer detects `$(...)` and transforms the code as shown below: -The `CorePlatform` is also responsible for retrieving the Manifest, that contains mappings from symbols to javascript import chunks. For this reason, `CorePlatform` can't be global, but is specific to the application currently running. On server it is possible that many different applications are running in a single server instance, and for this reason the `CorePlatform` is associated with the application document. +```tsx +// FILE: +useOnDocument("mousemove", qrl("./chunk-abc.js", "onMousemove")); -```typescript -getPlatform: () => CorePlatform; +// FILE: chunk-abc.js +export const onMousemove = () => console.log("mousemove"); ``` -**Returns:** - -[CorePlatform](#coreplatform) +NOTE: `qrl(...)` is a result of Qwik Optimizer transformation. You should never have to invoke this function directly in your application. The `qrl(...)` function should be invoked only after the Qwik Optimizer transformation. -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/platform/platform.ts) +\#\# Using `QRL`s -## h +Use `QRL` type in your application when you want to get a lazy-loadable reference to a resource (most likely a function). -```typescript -export declare namespace h +```tsx +// Example of declaring a custom functions which takes callback as QRL. +export function useMyFunction(callback: QRL<() => void>) { + doExtraStuff(); + // The callback passed to `onDocument` requires `QRL`. + useOnDocument("mousemove", callback); +} ``` - - - - - - - - -
- -Function - - - -Description - -
- -[h(type)](#) - - - -
- -[h(type, data)](#) - - - -
- -[h(type, text)](#) - - - -
- -[h(type, children)](#) - - +In the above example, the way to think about the code is that you are not asking for a callback function but rather a reference to a lazy-loadable callback function. Specifically, the function loading should be delayed until it is actually needed. In the above example, the function would not load until after a `mousemove` event on `document` fires. -
+\#\# Resolving `QRL` references -[h(type, data, text)](#) +At times it may be necessary to resolve a `QRL` reference to the actual value. This can be performed using `QRL.resolve(..)` function. - +```tsx +// Assume you have QRL reference to a greet function +const lazyGreet: QRL<() => void> = $(() => console.log("Hello World!")); -
+// Use `qrlImport` to load / resolve the reference. +const greet: () => void = await lazyGreet.resolve(); -[h(type, data, children)](#) +// Invoke it +greet(); +``` - +NOTE: `element` is needed because `QRL`s are relative and need a base location to resolve against. The base location is encoded in the HTML in the form of `
`. -
+\#\# `QRL.resolved` -[h(sel, data, children)](#) +Once `QRL.resolve()` returns, the value is stored under `QRL.resolved`. This allows the value to be used without having to await `QRL.resolve()` again. - +\#\# Question: Why not just use `import()`? -
+At first glance, `QRL` serves the same purpose as `import()`. However, there are three subtle differences that need to be taken into account. -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/factory.ts) +1. `QRL`s must be serializable into HTML. 2. `QRL`s must be resolved by framework relative to `q:base`. 3. `QRL`s must be able to capture lexically scoped variables. 4. `QRL`s encapsulate the difference between running with and without Qwik Optimizer. 5. `QRL`s allow expressing lazy-loaded boundaries without thinking about chunk and symbol names. -## h +Let's assume that you intend to write code such as this: -```typescript -export declare namespace h +```tsx +return - -``` - -1. Notice there is no easy way to extract chunk (`./chunk-abc.js`) and symbol (`onClick`) into HTML. 2. Notice that even if you could extract it, the `import('./chunk-abc.js')` would become relative to where the `import()` file is declared. Because it is our framework doing the load, the `./chunk-abc.js` would become relative to the framework file. This is not correct, as it should be relative to the original file generated by the bundler. 3. Next, the framework needs to resolve the `./chunk-abc.js` and needs a base location that is encoded in the HTML. 4. The QRL needs to be able to capture lexically scoped variables. (`import()` only allows loading top-level symbols which don't capture variables.) 5. As a developer, you don't want to think about `import` and naming the chunks and symbols. You just want to say: "this should be lazy." - -These are the main reasons why Qwik introduces its own concept of `QRL`. - -```typescript -export type QRL = { - __qwik_serializable__?: any; - __brand__QRL__: TYPE; - resolve(): Promise; - resolved: undefined | TYPE; - getCaptured(): unknown[] | null; - getSymbol(): string; - getHash(): string; - dev: QRLDev | null; -} & BivariantQrlFn, QrlReturn>; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.ts) - -## QRL - -The `QRL` type represents a lazy-loadable AND serializable resource. - -QRL stands for Qwik URL. - -Use `QRL` when you want to refer to a lazy-loaded resource. `QRL`s are most often used for code (functions) but can also be used for other resources such as `string`s in the case of styles. - -`QRL` is an opaque token that is generated by the Qwik Optimizer. (Do not rely on any properties in `QRL` as it may change between versions.) - -\#\# Creating `QRL` references - -Creating `QRL` is done using `$(...)` function. `$(...)` is a special marker for the Qwik Optimizer that marks that the code should be extracted into a lazy-loaded symbol. - -```tsx -useOnDocument( - "mousemove", - $((event) => console.log("mousemove", event)), -); -``` - -In the above code, the Qwik Optimizer detects `$(...)` and transforms the code as shown below: - -```tsx -// FILE: -useOnDocument("mousemove", qrl("./chunk-abc.js", "onMousemove")); - -// FILE: chunk-abc.js -export const onMousemove = () => console.log("mousemove"); -``` - -NOTE: `qrl(...)` is a result of Qwik Optimizer transformation. You should never have to invoke this function directly in your application. The `qrl(...)` function should be invoked only after the Qwik Optimizer transformation. - -\#\# Using `QRL`s - -Use `QRL` type in your application when you want to get a lazy-loadable reference to a resource (most likely a function). - -```tsx -// Example of declaring a custom functions which takes callback as QRL. -export function useMyFunction(callback: QRL<() => void>) { - doExtraStuff(); - // The callback passed to `onDocument` requires `QRL`. - useOnDocument("mousemove", callback); -} -``` - -In the above example, the way to think about the code is that you are not asking for a callback function but rather a reference to a lazy-loadable callback function. Specifically, the function loading should be delayed until it is actually needed. In the above example, the function would not load until after a `mousemove` event on `document` fires. - -\#\# Resolving `QRL` references - -At times it may be necessary to resolve a `QRL` reference to the actual value. This can be performed using `QRL.resolve(..)` function. - -```tsx -// Assume you have QRL reference to a greet function -const lazyGreet: QRL<() => void> = $(() => console.log("Hello World!")); - -// Use `qrlImport` to load / resolve the reference. -const greet: () => void = await lazyGreet.resolve(); - -// Invoke it -greet(); -``` - -NOTE: `element` is needed because `QRL`s are relative and need a base location to resolve against. The base location is encoded in the HTML in the form of `

`. - -\#\# `QRL.resolved` - -Once `QRL.resolve()` returns, the value is stored under `QRL.resolved`. This allows the value to be used without having to await `QRL.resolve()` again. - -\#\# Question: Why not just use `import()`? - -At first glance, `QRL` serves the same purpose as `import()`. However, there are three subtle differences that need to be taken into account. - -1. `QRL`s must be serializable into HTML. 2. `QRL`s must be resolved by framework relative to `q:base`. 3. `QRL`s must be able to capture lexically scoped variables. 4. `QRL`s encapsulate the difference between running with and without Qwik Optimizer. 5. `QRL`s allow expressing lazy-loaded boundaries without thinking about chunk and symbol names. - -Let's assume that you intend to write code such as this: - -```tsx -return -
-``` - -1. Notice there is no easy way to extract chunk (`./chunk-abc.js`) and symbol (`onClick`) into HTML. 2. Notice that even if you could extract it, the `import('./chunk-abc.js')` would become relative to where the `import()` file is declared. Because it is our framework doing the load, the `./chunk-abc.js` would become relative to the framework file. This is not correct, as it should be relative to the original file generated by the bundler. 3. Next, the framework needs to resolve the `./chunk-abc.js` and needs a base location that is encoded in the HTML. 4. The QRL needs to be able to capture lexically scoped variables. (`import()` only allows loading top-level symbols which don't capture variables.) 5. As a developer, you don't want to think about `import` and naming the chunks and symbols. You just want to say: "this should be lazy." - -These are the main reasons why Qwik introduces its own concept of `QRL`. - -```typescript -export type QRL = { - __qwik_serializable__?: any; - __brand__QRL__: TYPE; - resolve(): Promise; - resolved: undefined | TYPE; - getCaptured(): unknown[] | null; - getSymbol(): string; - getHash(): string; - dev: QRLDev | null; -} & BivariantQrlFn, QrlReturn>; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts) - -## QRLEventHandlerMulti - -> This API is provided as a beta preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. - -An event handler for Qwik events, can be a handler QRL or an array of handler QRLs. - -```typescript -export type QRLEventHandlerMulti = - | QRL> - | undefined - | null - | QRLEventHandlerMulti[] - | EventHandler; -``` - -**References:** [QRL](#qrl), [EventHandler](#eventhandler), [QRLEventHandlerMulti](#qrleventhandlermulti) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts) - -## QuoteHTMLAttributes - -```typescript -export interface QuoteHTMLAttributes extends Attrs<'q', T> -``` - -**Extends:** Attrs<'q', T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) - -## QwikAnimationEvent - -> Warning: This API is now obsolete. -> -> Use `AnimationEvent` and use the second argument to the handler function for the current event target - -```typescript -export type QwikAnimationEvent = NativeAnimationEvent; -``` - -**References:** [NativeAnimationEvent](#nativeanimationevent) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikAttributes - -The Qwik DOM attributes without plain handlers, for use as function parameters - -```typescript -export interface QwikAttributes extends DOMAttributesBase, QwikEvents -``` - -**Extends:** DOMAttributesBase<EL>, QwikEvents<EL, false> - - - -
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -[class?](#) - - - - - -[ClassList](#classlist) \| undefined - - - -_(Optional)_ - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-attributes.ts) - -## QwikChangeEvent - -> Warning: This API is now obsolete. -> -> Use `Event` and use the second argument to the handler function for the current event target. Also note that in Qwik, onInput$ with the InputEvent is the event that behaves like onChange in React. - -```typescript -export type QwikChangeEvent = Event; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikClipboardEvent - -> Warning: This API is now obsolete. -> -> Use `ClipboardEvent` and use the second argument to the handler function for the current event target - -```typescript -export type QwikClipboardEvent = NativeClipboardEvent; -``` - -**References:** [NativeClipboardEvent](#nativeclipboardevent) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikCompositionEvent - -> Warning: This API is now obsolete. -> -> Use `CompositionEvent` and use the second argument to the handler function for the current event target - -```typescript -export type QwikCompositionEvent = NativeCompositionEvent; -``` - -**References:** [NativeCompositionEvent](#nativecompositionevent) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikDOMAttributes - -```typescript -export interface QwikDOMAttributes extends DOMAttributes -``` - -**Extends:** [DOMAttributes](#domattributes)<Element> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik.ts) - -## QwikDragEvent - -> Warning: This API is now obsolete. -> -> Use `DragEvent` and use the second argument to the handler function for the current event target - -```typescript -export type QwikDragEvent = NativeDragEvent; -``` - -**References:** [NativeDragEvent](#nativedragevent) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikFocusEvent - -> Warning: This API is now obsolete. -> -> Use `FocusEvent` and use the second argument to the handler function for the current event target - -```typescript -export type QwikFocusEvent = NativeFocusEvent; -``` - -**References:** [NativeFocusEvent](#nativefocusevent) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikHTMLElements - -The DOM props without plain handlers, for use inside functions - -```typescript -export type QwikHTMLElements = { - [tag in keyof HTMLElementTagNameMap]: Augmented< - HTMLElementTagNameMap[tag], - SpecialAttrs[tag] - > & - HTMLElementAttrs & - QwikAttributes; -}; -``` - -**References:** [HTMLElementAttrs](#htmlelementattrs), [QwikAttributes](#qwikattributes) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) - -## QwikIdleEvent - -Emitted by qwik-loader on document when the document first becomes idle - -```typescript -export type QwikIdleEvent = CustomEvent<{}>; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikInitEvent - -Emitted by qwik-loader on document when the document first becomes interactive - -```typescript -export type QwikInitEvent = CustomEvent<{}>; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikIntrinsicElements - -The interface holds available attributes of both native DOM elements and custom Qwik elements. An example showing how to define a customizable wrapper component: - -```tsx -import { component$, Slot, type QwikIntrinsicElements } from "@builder.io/qwik"; - -type WrapperProps = { - attributes?: QwikIntrinsicElements["div"]; -}; - -export default component$(({ attributes }) => { - return ( -
- -
- ); -}); -``` - -Note: It is shorter to use `PropsOf<'div'>` - -```typescript -export interface QwikIntrinsicElements extends QwikHTMLElements, QwikSVGElements -``` - -**Extends:** [QwikHTMLElements](#qwikhtmlelements), [QwikSVGElements](#qwiksvgelements) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-elements.ts) - -## QwikInvalidEvent - -> Warning: This API is now obsolete. -> -> Use `Event` and use the second argument to the handler function for the current event target - -```typescript -export type QwikInvalidEvent = Event; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikJSX - -```typescript -export declare namespace QwikJSX -``` - - - - - -
- -Interface - - - -Description - -
- -[ElementChildrenAttribute](#qwikjsx-elementchildrenattribute) - - - -
- -[IntrinsicAttributes](#qwikjsx-intrinsicattributes) - - - -
- -[IntrinsicElements](#) - - - -
- - - - -
- -Type Alias - - - -Description - -
- -[Element](#qwikjsx-element) - - - -
- -[ElementType](#qwikjsx-elementtype) - - - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik.ts) - -## QwikKeyboardEvent - -> Warning: This API is now obsolete. -> -> Use `KeyboardEvent` and use the second argument to the handler function for the current event target - -```typescript -export type QwikKeyboardEvent = NativeKeyboardEvent; -``` - -**References:** [NativeKeyboardEvent](#nativekeyboardevent) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikMouseEvent - -> Warning: This API is now obsolete. -> -> Use `MouseEvent` and use the second argument to the handler function for the current event target - -```typescript -export type QwikMouseEvent = E; -``` - -**References:** [NativeMouseEvent](#nativemouseevent) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikPointerEvent - -> Warning: This API is now obsolete. -> -> Use `PointerEvent` and use the second argument to the handler function for the current event target - -```typescript -export type QwikPointerEvent = NativePointerEvent; -``` - -**References:** [NativePointerEvent](#nativepointerevent) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikSubmitEvent - -> Warning: This API is now obsolete. -> -> Use `SubmitEvent` and use the second argument to the handler function for the current event target - -```typescript -export type QwikSubmitEvent = SubmitEvent; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikSVGElements - -The SVG props without plain handlers, for use inside functions - -```typescript -export type QwikSVGElements = { - [K in keyof Omit< - SVGElementTagNameMap, - keyof HTMLElementTagNameMap - >]: SVGProps; -}; -``` - -**References:** [SVGProps](#svgprops) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) - -## QwikSymbolEvent - -Emitted by qwik-loader when a module was lazily loaded - -```typescript -export type QwikSymbolEvent = CustomEvent<{ - symbol: string; - element: Element; - reqTime: number; -}>; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikTouchEvent - -> Warning: This API is now obsolete. -> -> Use `TouchEvent` and use the second argument to the handler function for the current event target - -```typescript -export type QwikTouchEvent = NativeTouchEvent; -``` - -**References:** [NativeTouchEvent](#nativetouchevent) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikTransitionEvent - -> Warning: This API is now obsolete. -> -> Use `TransitionEvent` and use the second argument to the handler function for the current event target - -```typescript -export type QwikTransitionEvent = NativeTransitionEvent; -``` - -**References:** [NativeTransitionEvent](#nativetransitionevent) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikUIEvent - -> Warning: This API is now obsolete. -> -> Use `UIEvent` and use the second argument to the handler function for the current event target - -```typescript -export type QwikUIEvent = NativeUIEvent; -``` - -**References:** [NativeUIEvent](#nativeuievent) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikVisibleEvent - -Emitted by qwik-loader when an element becomes visible. Used by `useVisibleTask$` - -```typescript -export type QwikVisibleEvent = CustomEvent; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## QwikWheelEvent - -> Warning: This API is now obsolete. -> -> Use `WheelEvent` and use the second argument to the handler function for the current event target - -```typescript -export type QwikWheelEvent = NativeWheelEvent; -``` - -**References:** [NativeWheelEvent](#nativewheelevent) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-qwik-events.ts) - -## ReadonlySignal - -```typescript -export type ReadonlySignal = Readonly>; -``` - -**References:** [Signal](#signal) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/state/signal.ts) - -## render - -Render JSX. - -Use this method to render JSX. This function does reconciling which means it always tries to reuse what is already in the DOM (rather then destroy and recreate content.) It returns a cleanup function you could use for cleaning up subscriptions. - -```typescript -render: ( - parent: Element | Document, - jsxOutput: JSXOutput | FunctionComponent, - opts?: RenderOptions, -) => Promise; -``` - - - - - -
- -Parameter - - - -Type - - - -Description - -
- -parent - - - -Element \| Document - - - -Element which will act as a parent to `jsxNode`. When possible the rendering will try to reuse existing nodes. - -
- -jsxOutput - - - -[JSXOutput](#jsxoutput) \| [FunctionComponent](#functioncomponent)<any> - - - -JSX to render - -
- -opts - - - -[RenderOptions](#renderoptions) - - - -_(Optional)_ - -
-**Returns:** - -Promise<[RenderResult](#renderresult)> - -An object containing a cleanup function. - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/dom/render.public.ts) - -## RenderOnce - -```typescript -RenderOnce: FunctionComponent<{ - children?: unknown; - key?: string | number | null | undefined; -}>; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/jsx-runtime.ts) - -## RenderOptions - -```typescript -export interface RenderOptions -``` - - - -
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -[serverData?](#) - - - - - -Record<string, any> - - - -_(Optional)_ - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/dom/render.public.ts) - -## RenderResult - -```typescript -export interface RenderResult -``` - - - -
- -Method - - - -Description - -
- -[cleanup()](#renderresult-cleanup) - - - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/dom/render.public.ts) - -## RenderSSROptions - -```typescript -export interface RenderSSROptions -``` - - - - - - - - - - -
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -[base?](#) - - - - - -string - - - -_(Optional)_ - -
- -[beforeClose?](#) - - - - - -(contexts: QContext[], containerState: ContainerState, containsDynamic: boolean, textNodes: Map<string, string>) => Promise<[JSXNode](#jsxnode)> - - - -_(Optional)_ - -
- -[beforeContent?](#) - - - - - -[JSXNode](#jsxnode)<string>[] - - - -_(Optional)_ - -
- -[containerAttributes](#) - - - - - -Record<string, string> - - - -
- -[containerTagName](#) - - - - - -string - - - -
- -[manifestHash](#) - - - - - -string - - - -
- -[serverData?](#) - - - - - -Record<string, any> - - - -_(Optional)_ - -
- -[stream](#) - - - - - -[StreamWriter](#streamwriter) - - - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/ssr/render-ssr.ts) - -## Resource - -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}
; - }} - /> -
- ); -}); -``` - -```typescript -Resource: (props: ResourceProps) => JSXOutput; -``` - - - -
- -Parameter - - - -Type - - - -Description - -
- -props - - - -[ResourceProps](#resourceprops)<T> - - - -
-**Returns:** - -[JSXOutput](#jsxoutput) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts) - -## ResourceCtx - -```typescript -export interface ResourceCtx -``` - - - - -
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -[previous](#) - - - -`readonly` - - - -T \| undefined - - - -
- -[track](#) - - - -`readonly` - - - -[Tracker](#tracker) - - - -
- - - - -
- -Method - - - -Description - -
- -[cache(policyOrMilliseconds)](#resourcectx-cache) - - - -
- -[cleanup(callback)](#) - - - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) - -## ResourceFn - -```typescript -export type ResourceFn = (ctx: ResourceCtx) => ValueOrPromise; -``` - -**References:** [ResourceCtx](#resourcectx), [ValueOrPromise](#valueorpromise) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) - -## ResourceOptions - -Options to pass to `useResource$()` - -```typescript -export interface ResourceOptions -``` - - - -
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -[timeout?](#) - - - - - -number - - - -_(Optional)_ Timeout in milliseconds. If the resource takes more than the specified millisecond, it will timeout. Resulting on a rejected resource. - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts) - -## ResourcePending - -```typescript -export interface ResourcePending -``` - - - - -
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -[loading](#) - - - -`readonly` - - - -boolean - - - -
- -[value](#) - - - -`readonly` - - - -Promise<T> - - - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) - -## ResourceProps - -```typescript -export interface ResourceProps -``` - - - - - - -
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -[onPending?](#) - - - - - -() => [JSXOutput](#jsxoutput) - - - -_(Optional)_ - -
- -[onRejected?](#) - - - - - -(reason: Error) => [JSXOutput](#jsxoutput) - - - -_(Optional)_ - -
- -[onResolved](#) - - - - - -(value: T) => [JSXOutput](#jsxoutput) - - - -
- -[value](#) - - - -`readonly` - - - -[ResourceReturn](#resourcereturn)<T> \| [Signal](#signal)<Promise<T> \| T> \| Promise<T> - - - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts) - -## ResourceRejected - -```typescript -export interface ResourceRejected -``` - - - - -
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -[loading](#) - - - -`readonly` - - - -boolean - - - -
- -[value](#) - - - -`readonly` - - - -Promise<T> - - - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) - -## ResourceResolved - -```typescript -export interface ResourceResolved -``` - - - - -
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -[loading](#) - - - -`readonly` - - - -boolean - - - -
- -[value](#) - - - -`readonly` - - - -Promise<T> - - - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) - -## ResourceReturn - -```typescript -export type ResourceReturn = - | ResourcePending - | ResourceResolved - | ResourceRejected; -``` - -**References:** [ResourcePending](#resourcepending), [ResourceResolved](#resourceresolved), [ResourceRejected](#resourcerejected) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) - -## ScriptHTMLAttributes - -```typescript -export interface ScriptHTMLAttributes extends Attrs<'script', T> -``` - -**Extends:** Attrs<'script', T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) - -## SelectHTMLAttributes - -```typescript -export interface SelectHTMLAttributes extends Attrs<'select', T> -``` - -**Extends:** Attrs<'select', T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) - -## setPlatform - -Sets the `CorePlatform`. - -This is useful to override the platform in tests to change the behavior of, `requestAnimationFrame`, and import resolution. - -```typescript -setPlatform: (plt: CorePlatform) => CorePlatform; -``` - - - -
- -Parameter - - - -Type - - - -Description - -
- -plt - - - -[CorePlatform](#coreplatform) - - - -
-**Returns:** - -[CorePlatform](#coreplatform) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/platform/platform.ts) - -## Signal - -A signal is a reactive value which can be read and written. When the signal is written, all tasks which are tracking the signal will be re-run and all components that read the signal will be re-rendered. - -Furthermore, when a signal value is passed as a prop to a component, the optimizer will automatically forward the signal. This means that `return
hi
` will update the `title` attribute when the signal changes without having to re-render the component. - -```typescript -export interface Signal -``` - - - -
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -[value](#) - - - - - -T - - - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/state/signal.ts) - -## Size - -```typescript -export type Size = number | string; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) - -## SkipRender - -```typescript -SkipRender: JSXNode; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts) - -## Slot - -Allows to project the children of the current component. can only be used within the context of a component defined with `component$`. - -```typescript -Slot: FunctionComponent<{ - name?: string; -}>; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/slot.public.ts) - -## SlotHTMLAttributes - -```typescript -export interface SlotHTMLAttributes extends Attrs<'slot', T> -``` - -**Extends:** Attrs<'slot', T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) - -## SnapshotListener - -```typescript -export interface SnapshotListener -``` - - - - - -
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -[el](#) - - - - - -Element - - - -
- -[key](#) - - - - - -string - - - -
- -[qrl](#) - - - - - -[QRL](#qrl)<any> - - - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/container/container.ts) - -## SnapshotMeta - -```typescript -export type SnapshotMeta = Record; -``` - -**References:** [SnapshotMetaValue](#snapshotmetavalue) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/container/container.ts) - -## SnapshotMetaValue - -```typescript -export interface SnapshotMetaValue -``` - - - - - - -
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -[c?](#) - - - - - -string - - - -_(Optional)_ - -
- -[h?](#) - - - - - -string - - - -_(Optional)_ - -
- -[s?](#) - - - - - -string - - - -_(Optional)_ - -
- -[w?](#) - - - - - -string - - - -_(Optional)_ - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/container/container.ts) - -## SnapshotResult - -```typescript -export interface SnapshotResult -``` - - - - - - - - -
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -[funcs](#) - - - - - -string[] - - - -
- -[mode](#) - - - - - -'render' \| 'listeners' \| 'static' - - - -
- -[objs](#) - - - - - -any[] - - - -
- -[qrls](#) - - - - - -[QRL](#qrl)[] - - - -
- -[resources](#) - - - - - -ResourceReturnInternal<any>[] - - - -
- -[state](#) - - - - - -[SnapshotState](#snapshotstate) - - - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/container/container.ts) - -## SnapshotState - -```typescript -export interface SnapshotState -``` - - - - - - -
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -[ctx](#) - - - - - -[SnapshotMeta](#snapshotmeta) - - - -
- -[objs](#) - - - - - -any[] - - - -
- -[refs](#) - - - - - -Record<string, string> - - - -
- -[subs](#) - - - - - -any[] - - - -
- -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/container/container.ts) - -## SourceHTMLAttributes - -```typescript -export interface SourceHTMLAttributes extends Attrs<'source', T> -``` - -**Extends:** Attrs<'source', T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) - -## SSRComment - -```typescript -SSRComment: FunctionComponent<{ - data: string; -}>; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts) - -## SSRHint - -> Warning: This API is now obsolete. -> -> - It has no effect - -```typescript -SSRHint: FunctionComponent; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts) - -## SSRHintProps - -```typescript -export type SSRHintProps = { - dynamic?: boolean; -}; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts) - -## SSRRaw - -```typescript -SSRRaw: FunctionComponent<{ - data: string; -}>; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts) - -## SSRStream - -```typescript -SSRStream: FunctionComponent; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts) - -## SSRStreamBlock - -```typescript -SSRStreamBlock: FunctionComponent<{ - children?: any; -}>; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts) - -## SSRStreamProps - -```typescript -export type SSRStreamProps = { - children: - | AsyncGenerator - | ((stream: StreamWriter) => Promise) - | (() => AsyncGenerator); -}; -``` - -**References:** [JSXChildren](#jsxchildren), [StreamWriter](#streamwriter) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/utils.public.ts) - -## StreamWriter - -```typescript -export type StreamWriter = { - write: (chunk: string) => void; -}; -``` - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/ssr/render-ssr.ts) - -## StyleHTMLAttributes - -```typescript -export interface StyleHTMLAttributes extends Attrs<'style', T> -``` - -**Extends:** Attrs<'style', T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) - -## SVGAttributes - -The TS types don't include the SVG attributes so we have to define them ourselves - -NOTE: These props are probably not complete - -```typescript -export interface SVGAttributes extends AriaAttributes -``` - -**Extends:** [AriaAttributes](#ariaattributes) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +
- -Property - - - -Modifiers - - - -Type - - - -Description - -
- -["accent-height"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["alignment-baseline"?](#) - - - - - -'auto' \| 'baseline' \| 'before-edge' \| 'text-before-edge' \| 'middle' \| 'central' \| 'after-edge' \| 'text-after-edge' \| 'ideographic' \| 'alphabetic' \| 'hanging' \| 'mathematical' \| 'inherit' \| undefined - - - -_(Optional)_ - -
- -["arabic-form"?](#) - - - - - -'initial' \| 'medial' \| 'terminal' \| 'isolated' \| undefined - - - -_(Optional)_ - -
- -["baseline-shift"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["cap-height"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["clip-path"?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["clip-rule"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["color-interpolation-filters"?](#) - - - - - -'auto' \| 's-rGB' \| 'linear-rGB' \| 'inherit' \| undefined - - - -_(Optional)_ - -
- -["color-interpolation"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["color-profile"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["color-rendering"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["dominant-baseline"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["edge-mode"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["enable-background"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["fill-opacity"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["fill-rule"?](#) - - - - - -'nonzero' \| 'evenodd' \| 'inherit' \| undefined - - - -_(Optional)_ - -
- -["flood-color"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["flood-opacity"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["font-family"?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["font-size-adjust"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["font-size"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["font-stretch"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["font-style"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["font-variant"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["font-weight"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["glyph-name"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["glyph-orientation-horizontal"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["glyph-orientation-vertical"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["horiz-adv-x"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["horiz-origin-x"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["image-rendering"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["letter-spacing"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["lighting-color"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["marker-end"?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["marker-mid"?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["marker-start"?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["overline-position"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["overline-thickness"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["paint-order"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["pointer-events"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["rendering-intent"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["shape-rendering"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["stop-color"?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["stop-opacity"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["strikethrough-position"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["strikethrough-thickness"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["stroke-dasharray"?](#) - - - - - -string \| number \| undefined - - - -_(Optional)_ - -
- -["stroke-dashoffset"?](#) - - - - - -string \| number \| undefined - - - -_(Optional)_ - -
- -["stroke-linecap"?](#) - - - - - -'butt' \| 'round' \| 'square' \| 'inherit' \| undefined - - - -_(Optional)_ - -
- -["stroke-linejoin"?](#) - - - - - -'miter' \| 'round' \| 'bevel' \| 'inherit' \| undefined - - - -_(Optional)_ - -
- -["stroke-miterlimit"?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["stroke-opacity"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["stroke-width"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["text-anchor"?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["text-decoration"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["text-rendering"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["underline-position"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["underline-thickness"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["unicode-bidi"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["unicode-range"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["units-per-em"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["v-alphabetic"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["v-hanging"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["v-ideographic"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["v-mathematical"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["vector-effect"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["vert-adv-y"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["vert-origin-x"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["vert-origin-y"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["word-spacing"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["writing-mode"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["x-channel-selector"?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["x-height"?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -["xlink:actuate"?](#svgattributes-_xlink_actuate_) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["xlink:arcrole"?](#svgattributes-_xlink_arcrole_) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["xlink:href"?](#svgattributes-_xlink_href_) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["xlink:role"?](#svgattributes-_xlink_role_) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["xlink:show"?](#svgattributes-_xlink_show_) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["xlink:title"?](#svgattributes-_xlink_title_) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["xlink:type"?](#svgattributes-_xlink_type_) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["xml:base"?](#svgattributes-_xml_base_) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["xml:lang"?](#svgattributes-_xml_lang_) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["xml:space"?](#svgattributes-_xml_space_) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -["xmlns:xlink"?](#svgattributes-_xmlns_xlink_) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[accumulate?](#) - - - - - -'none' \| 'sum' \| undefined - - - -_(Optional)_ - -
- -[additive?](#) - - - - - -'replace' \| 'sum' \| undefined - - - -_(Optional)_ - -
- -[allowReorder?](#) - - - - - -'no' \| 'yes' \| undefined - - - -_(Optional)_ - -
- -[alphabetic?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[amplitude?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[ascent?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[attributeName?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[attributeType?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[autoReverse?](#) - - - - - -[Booleanish](#booleanish) \| undefined - - - -_(Optional)_ - -
- -[azimuth?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[baseFrequency?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[baseProfile?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[bbox?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[begin?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[bias?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[by?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[calcMode?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[clip?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[clipPathUnits?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[color?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[contentScriptType?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[contentStyleType?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[crossOrigin?](#) - - - - - -[HTMLCrossOriginAttribute](#htmlcrossoriginattribute) - - - -_(Optional)_ - -
- -[cursor?](#) - - - - - -number \| string - - - -_(Optional)_ - -
- -[cx?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[cy?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[d?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[decelerate?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[descent?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[diffuseConstant?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[direction?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[display?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[divisor?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[dur?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[dx?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[dy?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[elevation?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[end?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[exponent?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[externalResourcesRequired?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[fill?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[filter?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[filterRes?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[filterUnits?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[focusable?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[format?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[fr?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[from?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[fx?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[fy?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[g1?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[g2?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[glyphRef?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[gradientTransform?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[gradientUnits?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[hanging?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[height?](#) - - - - - -[Size](#size) \| undefined - - - -_(Optional)_ - -
- -[href?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[id?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[ideographic?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[in?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[in2?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[intercept?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[k?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[k1?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[k2?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[k3?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[k4?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[kernelMatrix?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[kernelUnitLength?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[kerning?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[keyPoints?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[keySplines?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[keyTimes?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[lang?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[lengthAdjust?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[limitingConeAngle?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[local?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[markerHeight?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[markerUnits?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[markerWidth?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[mask?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[maskContentUnits?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[maskUnits?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[mathematical?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[max?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[media?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[method?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[min?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[mode?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[name?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[numOctaves?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[offset?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[opacity?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[operator?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[order?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[orient?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[orientation?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[origin?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[overflow?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[panose1?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[path?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[pathLength?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[patternContentUnits?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[patternTransform?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[patternUnits?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[points?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[pointsAtX?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[pointsAtY?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[pointsAtZ?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[preserveAlpha?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[preserveAspectRatio?](#) - - - - - -string \| undefined - - - -_(Optional)_ - -
- -[primitiveUnits?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[r?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[radius?](#) - - - - - -number \| string \| undefined - - - -_(Optional)_ - -
- -[refX?](#) - - - - - -number \| string \| undefined +export type QRL = { + __qwik_serializable__?: any; + __brand__QRL__: TYPE; + resolve(): Promise; + resolved: undefined | TYPE; + getCaptured(): unknown[] | null; + getSymbol(): string; + getHash(): string; + dev: QRLDev | null; +} & BivariantQrlFn, QrlReturn>; +``` - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/qrl.ts) -_(Optional)_ +## QRL -
+The `QRL` type represents a lazy-loadable AND serializable resource. -[refY?](#) +QRL stands for Qwik URL. - +Use `QRL` when you want to refer to a lazy-loaded resource. `QRL`s are most often used for code (functions) but can also be used for other resources such as `string`s in the case of styles. - +`QRL` is an opaque token that is generated by the Qwik Optimizer. (Do not rely on any properties in `QRL` as it may change between versions.) -number \| string \| undefined +\#\# Creating `QRL` references - +Creating `QRL` is done using `$(...)` function. `$(...)` is a special marker for the Qwik Optimizer that marks that the code should be extracted into a lazy-loaded symbol. -_(Optional)_ +```tsx +useOnDocument( + "mousemove", + $((event) => console.log("mousemove", event)), +); +``` -
+In the above code, the Qwik Optimizer detects `$(...)` and transforms the code as shown below: -[repeatCount?](#) +```tsx +// FILE: +useOnDocument("mousemove", qrl("./chunk-abc.js", "onMousemove")); - +// FILE: chunk-abc.js +export const onMousemove = () => console.log("mousemove"); +``` - +NOTE: `qrl(...)` is a result of Qwik Optimizer transformation. You should never have to invoke this function directly in your application. The `qrl(...)` function should be invoked only after the Qwik Optimizer transformation. -number \| string \| undefined +\#\# Using `QRL`s - +Use `QRL` type in your application when you want to get a lazy-loadable reference to a resource (most likely a function). -_(Optional)_ +```tsx +// Example of declaring a custom functions which takes callback as QRL. +export function useMyFunction(callback: QRL<() => void>) { + doExtraStuff(); + // The callback passed to `onDocument` requires `QRL`. + useOnDocument("mousemove", callback); +} +``` -
+In the above example, the way to think about the code is that you are not asking for a callback function but rather a reference to a lazy-loadable callback function. Specifically, the function loading should be delayed until it is actually needed. In the above example, the function would not load until after a `mousemove` event on `document` fires. -[repeatDur?](#) +\#\# Resolving `QRL` references - +At times it may be necessary to resolve a `QRL` reference to the actual value. This can be performed using `QRL.resolve(..)` function. - +```tsx +// Assume you have QRL reference to a greet function +const lazyGreet: QRL<() => void> = $(() => console.log("Hello World!")); -number \| string \| undefined +// Use `qrlImport` to load / resolve the reference. +const greet: () => void = await lazyGreet.resolve(); - +// Invoke it +greet(); +``` -_(Optional)_ +NOTE: `element` is needed because `QRL`s are relative and need a base location to resolve against. The base location is encoded in the HTML in the form of `
`. -
+\#\# `QRL.resolved` -[requiredextensions?](#) +Once `QRL.resolve()` returns, the value is stored under `QRL.resolved`. This allows the value to be used without having to await `QRL.resolve()` again. - +\#\# Question: Why not just use `import()`? - +At first glance, `QRL` serves the same purpose as `import()`. However, there are three subtle differences that need to be taken into account. -number \| string \| undefined +1. `QRL`s must be serializable into HTML. 2. `QRL`s must be resolved by framework relative to `q:base`. 3. `QRL`s must be able to capture lexically scoped variables. 4. `QRL`s encapsulate the difference between running with and without Qwik Optimizer. 5. `QRL`s allow expressing lazy-loaded boundaries without thinking about chunk and symbol names. - +Let's assume that you intend to write code such as this: -_(Optional)_ +```tsx +return
+The above code needs to be serialized into DOM such as: -[requiredFeatures?](#) +``` +
+ +
+``` -
+1. Notice there is no easy way to extract chunk (`./chunk-abc.js`) and symbol (`onClick`) into HTML. 2. Notice that even if you could extract it, the `import('./chunk-abc.js')` would become relative to where the `import()` file is declared. Because it is our framework doing the load, the `./chunk-abc.js` would become relative to the framework file. This is not correct, as it should be relative to the original file generated by the bundler. 3. Next, the framework needs to resolve the `./chunk-abc.js` and needs a base location that is encoded in the HTML. 4. The QRL needs to be able to capture lexically scoped variables. (`import()` only allows loading top-level symbols which don't capture variables.) 5. As a developer, you don't want to think about `import` and naming the chunks and symbols. You just want to say: "this should be lazy." - +These are the main reasons why Qwik introduces its own concept of `QRL`. -number \| string \| undefined +```typescript +export type QRL = { + __qwik_serializable__?: any; + __brand__QRL__: TYPE; + resolve(): Promise; + resolved: undefined | TYPE; + getCaptured(): unknown[] | null; + getSymbol(): string; + getHash(): string; + dev: QRLDev | null; +} & BivariantQrlFn, QrlReturn>; +``` - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/qrl.public.ts) -_(Optional)_ +## QRLEventHandlerMulti -
+An event handler for Qwik events, can be a handler QRL or an array of handler QRLs. -[restart?](#) +```typescript +export type QRLEventHandlerMulti = + | QRL> + | undefined + | null + | QRLEventHandlerMulti[] + | EventHandler; +``` - +**References:** [QRL](#qrl), [EventHandler](#eventhandler), [QRLEventHandlerMulti](#qrleventhandlermulti) - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts) -number \| string \| undefined +## QwikAnimationEvent - +> Warning: This API is now obsolete. +> +> Use `AnimationEvent` and use the second argument to the handler function for the current event target -_(Optional)_ +```typescript +export type QwikAnimationEvent = NativeAnimationEvent; +``` -
+**References:** [NativeAnimationEvent](#nativeanimationevent) -[result?](#) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) - +## QwikAttributes - +The Qwik DOM attributes without plain handlers, for use as function parameters -string \| undefined +```typescript +export interface QwikAttributes extends DOMAttributesBase, QwikEvents +``` - +**Extends:** DOMAttributesBase<EL>, QwikEvents<EL, false> -_(Optional)_ + - - + -
-
+Property -[role?](#) + - +Modifiers - + -string \| undefined +Type - + -_(Optional)_ +Description -
+
-[rotate?](#) +[class?](#) -number \| string \| undefined +[ClassList](#classlist) \| undefined _(Optional)_
- -[rx?](#) - - - - - -number \| string \| undefined +
-
+[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-attributes.ts) -_(Optional)_ +## QwikChangeEvent -
+> Warning: This API is now obsolete. +> +> Use `Event` and use the second argument to the handler function for the current event target. Also note that in Qwik, onInput$ with the InputEvent is the event that behaves like onChange in React. -[ry?](#) +```typescript +export type QwikChangeEvent = Event; +``` - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) - +## QwikClipboardEvent -number \| string \| undefined +> Warning: This API is now obsolete. +> +> Use `ClipboardEvent` and use the second argument to the handler function for the current event target - +```typescript +export type QwikClipboardEvent = NativeClipboardEvent; +``` -_(Optional)_ +**References:** [NativeClipboardEvent](#nativeclipboardevent) -
+[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -[scale?](#) +## QwikCompositionEvent - +> Warning: This API is now obsolete. +> +> Use `CompositionEvent` and use the second argument to the handler function for the current event target - +```typescript +export type QwikCompositionEvent = NativeCompositionEvent; +``` -number \| string \| undefined +**References:** [NativeCompositionEvent](#nativecompositionevent) - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -_(Optional)_ +## QwikDOMAttributes -
+```typescript +export interface QwikDOMAttributes extends DOMAttributes +``` -[seed?](#) +**Extends:** [DOMAttributes](#domattributes)<Element> - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik.ts) - +## QwikDragEvent -number \| string \| undefined +> Warning: This API is now obsolete. +> +> Use `DragEvent` and use the second argument to the handler function for the current event target - +```typescript +export type QwikDragEvent = NativeDragEvent; +``` -_(Optional)_ +**References:** [NativeDragEvent](#nativedragevent) -
+[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -[slope?](#) +## QwikFocusEvent - +> Warning: This API is now obsolete. +> +> Use `FocusEvent` and use the second argument to the handler function for the current event target - +```typescript +export type QwikFocusEvent = NativeFocusEvent; +``` -number \| string \| undefined +**References:** [NativeFocusEvent](#nativefocusevent) - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -_(Optional)_ +## QwikHTMLElements -
+The DOM props without plain handlers, for use inside functions -[spacing?](#) +```typescript +export type QwikHTMLElements = { + [tag in keyof HTMLElementTagNameMap]: Augmented< + HTMLElementTagNameMap[tag], + SpecialAttrs[tag] + > & + HTMLElementAttrs & + QwikAttributes; +}; +``` - +**References:** [QwikAttributes](#qwikattributes) - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-generated.ts) -number \| string \| undefined +## QwikIdleEvent - +Emitted by qwik-loader on document when the document first becomes idle -_(Optional)_ +```typescript +export type QwikIdleEvent = CustomEvent<{}>; +``` -
+[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -[specularConstant?](#) +## QwikInitEvent - +Emitted by qwik-loader on document when the document first becomes interactive - +```typescript +export type QwikInitEvent = CustomEvent<{}>; +``` -number \| string \| undefined +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) - +## QwikIntrinsicElements -_(Optional)_ +The interface holds available attributes of both native DOM elements and custom Qwik elements. An example showing how to define a customizable wrapper component: -
+```tsx +import { component$, Slot, type QwikIntrinsicElements } from "@qwik.dev/core"; -[specularExponent?](#) +type WrapperProps = { + attributes?: QwikIntrinsicElements["div"]; +}; - +export default component$(({ attributes }) => { + return ( +
+ +
+ ); +}); +``` -
+Note: It is shorter to use `PropsOf<'div'>` -number \| string \| undefined +```typescript +export interface QwikIntrinsicElements extends QwikHTMLElements, QwikSVGElements +``` - +**Extends:** [QwikHTMLElements](#qwikhtmlelements), [QwikSVGElements](#qwiksvgelements) -_(Optional)_ +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-elements.ts) -
+## QwikInvalidEvent -[speed?](#) +> Warning: This API is now obsolete. +> +> Use `Event` and use the second argument to the handler function for the current event target - +```typescript +export type QwikInvalidEvent = Event; +``` - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -number \| string \| undefined +## QwikJSX - +```typescript +export declare namespace QwikJSX +``` -_(Optional)_ + - + + -
-
+Interface -[spreadMethod?](#) + - +Description - +
-string \| undefined +[ElementChildrenAttribute](#qwikjsx-elementchildrenattribute) -_(Optional)_ -
-[startOffset?](#) +[IntrinsicAttributes](#qwikjsx-intrinsicattributes) - +
-number \| string \| undefined +[IntrinsicElements](#qwikjsx-intrinsicelements) -_(Optional)_ -
+
-[stdDeviation?](#) + + +
- +Type Alias - + -number \| string \| undefined +Description - +
-_(Optional)_ +[Element](#qwikjsx-element) + +
-[stemh?](#) +[ElementType](#qwikjsx-elementtype) - +
-number \| string \| undefined +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik.ts) -
+## QwikKeyboardEvent -_(Optional)_ +> Warning: This API is now obsolete. +> +> Use `KeyboardEvent` and use the second argument to the handler function for the current event target -
+```typescript +export type QwikKeyboardEvent = NativeKeyboardEvent; +``` -[stemv?](#) +**References:** [NativeKeyboardEvent](#nativekeyboardevent) - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) - +## QwikMouseEvent -number \| string \| undefined +> Warning: This API is now obsolete. +> +> Use `MouseEvent` and use the second argument to the handler function for the current event target - +```typescript +export type QwikMouseEvent = E; +``` -_(Optional)_ +**References:** [NativeMouseEvent](#nativemouseevent) -
+[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -[stitchTiles?](#) +## QwikPointerEvent - +> Warning: This API is now obsolete. +> +> Use `PointerEvent` and use the second argument to the handler function for the current event target - +```typescript +export type QwikPointerEvent = NativePointerEvent; +``` -number \| string \| undefined +**References:** [NativePointerEvent](#nativepointerevent) - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -_(Optional)_ +## QwikSubmitEvent -
+> Warning: This API is now obsolete. +> +> Use `SubmitEvent` and use the second argument to the handler function for the current event target -[string?](#) +```typescript +export type QwikSubmitEvent = SubmitEvent; +``` - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) - +## QwikSVGElements -number \| string \| undefined +The SVG props without plain handlers, for use inside functions - +```typescript +export type QwikSVGElements = { + [K in keyof Omit< + SVGElementTagNameMap, + keyof HTMLElementTagNameMap + >]: SVGProps; +}; +``` -_(Optional)_ +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-generated.ts) -
+## QwikSymbolEvent -[stroke?](#) +Emitted by qwik-loader when a module was lazily loaded - +```typescript +export type QwikSymbolEvent = CustomEvent<{ + qBase: string; + qManifest: string; + qVersion: string; + href: string; + symbol: string; + element: Element; + reqTime: number; +}>; +``` - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -string \| undefined +## QwikTouchEvent - +> Warning: This API is now obsolete. +> +> Use `TouchEvent` and use the second argument to the handler function for the current event target -_(Optional)_ +```typescript +export type QwikTouchEvent = NativeTouchEvent; +``` -
+**References:** [NativeTouchEvent](#nativetouchevent) -[style?](#) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) - +## QwikTransitionEvent - +> Warning: This API is now obsolete. +> +> Use `TransitionEvent` and use the second argument to the handler function for the current event target -[CSSProperties](#cssproperties) \| string \| undefined +```typescript +export type QwikTransitionEvent = NativeTransitionEvent; +``` - +**References:** [NativeTransitionEvent](#nativetransitionevent) -_(Optional)_ +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -
+## QwikUIEvent -[surfaceScale?](#) +> Warning: This API is now obsolete. +> +> Use `UIEvent` and use the second argument to the handler function for the current event target - +```typescript +export type QwikUIEvent = NativeUIEvent; +``` - +**References:** [NativeUIEvent](#nativeuievent) -number \| string \| undefined +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) - +## QwikVisibleEvent -_(Optional)_ +Emitted by qwik-loader when an element becomes visible. Used by `useVisibleTask$` -
+```typescript +export type QwikVisibleEvent = CustomEvent; +``` -[systemLanguage?](#) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) - +## QwikWheelEvent - +> Warning: This API is now obsolete. +> +> Use `WheelEvent` and use the second argument to the handler function for the current event target -number \| string \| undefined +```typescript +export type QwikWheelEvent = NativeWheelEvent; +``` - +**References:** [NativeWheelEvent](#nativewheelevent) -_(Optional)_ +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/types/jsx-qwik-events.ts) -
+## ReadonlySignal -[tabindex?](#) +```typescript +export interface ReadonlySignal +``` - + - + - +
- +Property -number \| undefined + - +Modifiers -_(Optional)_ + -
+Type -[tableValues?](#) + - +Description - +
-number \| string \| undefined +[value](#) -_(Optional)_ +`readonly` -
+ -[target?](#) +T - +
-string \| undefined +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts) -
+## render -_(Optional)_ +Render JSX. -
+Use this method to render JSX. This function does reconciling which means it always tries to reuse what is already in the DOM (rather then destroy and recreate content.) It returns a cleanup function you could use for cleaning up subscriptions. -[targetX?](#) +```typescript +render: ( + parent: Element | Document, + jsxNode: JSXOutput | FunctionComponent, + opts?: RenderOptions, +) => Promise; +``` - + - + -
- +Parameter -number \| string \| undefined + - +Type -_(Optional)_ + -
+Description -[targetY?](#) +
- +parent -number \| string \| undefined +Element \| Document -_(Optional)_ +Element which will act as a parent to `jsxNode`. When possible the rendering will try to reuse existing nodes.
-[textLength?](#) - - +jsxNode -number \| string \| undefined +[JSXOutput](#jsxoutput) \| [FunctionComponent](#functioncomponent)<any> -_(Optional)_ +JSX to render
-[to?](#) - - +opts -number \| string \| undefined +[RenderOptions](#renderoptions) _(Optional)_
+
+**Returns:** -[transform?](#) +Promise<[RenderResult](#renderresult)> -
+An object containing a cleanup function. - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/client/dom-render.ts) -string \| undefined +## RenderOnce - +```typescript +RenderOnce: FunctionComponent<{ + children?: unknown; + key?: string | number | null | undefined; +}>; +``` -_(Optional)_ +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/jsx-runtime.ts) -
+## RenderOptions -[type?](#) +```typescript +export interface RenderOptions +``` - + - + -
- +Property -string \| undefined + - +Modifiers -_(Optional)_ + -
+Type + + -[u1?](#) +Description + +
+ +[serverData?](#) -number \| string \| undefined +Record<string, any> _(Optional)_
+
-[u2?](#) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/client/types.ts) -
+## RenderResult - +```typescript +export interface RenderResult +``` -number \| string \| undefined + - + +
- +Method -_(Optional)_ + -
+Description -[unicode?](#) +
- +[cleanup()](#renderresult-cleanup) -number \| string \| undefined +
-
+[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/client/types.ts) -_(Optional)_ +## RenderSSROptions -
+```typescript +export interface RenderSSROptions +``` -[values?](#) + - + -
- +Property - + -string \| undefined +Modifiers - + -_(Optional)_ +Type -
+ + +Description -[version?](#) +
+ +[base?](#) -string \| undefined +string @@ -9513,58 +2995,52 @@ _(Optional)_
-[viewBox?](#) +[containerAttributes](#) -string \| undefined +Record<string, string> -_(Optional)_ -
-[viewTarget?](#) +[containerTagName](#) -number \| string \| undefined +string -_(Optional)_ -
-[visibility?](#) +[manifestHash](#) -number \| string \| undefined +string -_(Optional)_ -
-[width?](#) +[serverData?](#) -[Size](#size) \| undefined +Record<string, any> @@ -9573,198 +3049,208 @@ _(Optional)_
-[widths?](#) +[stream](#) -number \| string \| undefined +StreamWriter -_(Optional)_ -
- -[x?](#) - - +
-
+[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/ssr/ssr-types.ts) -number \| string \| undefined +## Resource - +This method works like an async memoized function that runs whenever some tracked value changes and returns some data. -_(Optional)_ +`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: -[x1?](#) +- `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 -number \| string \| undefined +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(""); -_(Optional)_ + 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}
; + }} + /> +
+ ); +}); +``` -[x2?](#) +```typescript +Resource: (props: ResourceProps) => JSXOutput; +``` -
+ - + -
- +Parameter -number \| string \| undefined + - +Type -_(Optional)_ + -
+Description -[xmlns?](#) +
- +props -string \| undefined +[ResourceProps](#resourceprops)<T> -_(Optional)_ -
- -[y?](#) +
+**Returns:** -
+[JSXOutput](#jsxoutput) - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts) -number \| string \| undefined +## ResourceCtx - +```typescript +export interface ResourceCtx +``` -_(Optional)_ + - - + -
-
+Property -[y1?](#) + - +Modifiers - + -number \| string \| undefined +Type - + -_(Optional)_ +Description -
+
-[y2?](#) +[previous](#) +`readonly` + -number \| string \| undefined +T \| undefined -_(Optional)_ -
-[yChannelSelector?](#) +[track](#) +`readonly` + -string \| undefined +[Tracker](#tracker) -_(Optional)_ -
- -[z?](#) - - +
-
+ - + +
-number \| string \| undefined +Method - + -_(Optional)_ +Description -
+
-[zoomAndPan?](#) +[cache(policyOrMilliseconds)](#resourcectx-cache) - +
-string \| undefined +[cleanup(callback)](#) -_(Optional)_ -
-[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts) -## SVGProps +## ResourceFn ```typescript -export interface SVGProps extends SVGAttributes, QwikAttributes +export type ResourceFn = (ctx: ResourceCtx) => ValueOrPromise; ``` -**Extends:** [SVGAttributes](#svgattributes), [QwikAttributes](#qwikattributes)<T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) - -## sync$ +**References:** [ResourceCtx](#resourcectx), [ValueOrPromise](#valueorpromise) -> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts) -Extract function into a synchronously loadable QRL. +## ResourceOptions -NOTE: Synchronous QRLs functions can't close over any variables, including exports. +Options to pass to `useResource$()` ```typescript -sync$: (fn: T) => SyncQRL; +export interface ResourceOptions ```
-Parameter +Property + + + +Modifiers @@ -9777,34 +3263,29 @@ Description
-fn +[timeout?](#) -T + + +number -Function to extract. +_(Optional)_ Timeout in milliseconds. If the resource takes more than the specified millisecond, it will timeout. Resulting on a rejected resource.
-**Returns:** - -[SyncQRL](#syncqrl)<T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts) -## SyncQRL +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts) -> This API is provided as an alpha preview for developers and may change based on feedback that we receive. Do not use this API in a production environment. +## ResourcePending ```typescript -export interface SyncQRL extends QRL +export interface ResourcePending ``` -**Extends:** [QRL](#qrl)<TYPE> - -
Property @@ -9824,67 +3305,42 @@ Description
-[\_\_brand\_\_SyncQRL\_\_](#) - - - - - -TYPE +[loading](#) -**_(ALPHA)_** - -
- -[dev](#) - - +`readonly` -QRLDev \| null +boolean -**_(ALPHA)_** -
-[resolved](#) +[value](#) +`readonly` + -TYPE +Promise<T> -**_(ALPHA)_** -
-[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/qrl/qrl.public.ts) - -## TableHTMLAttributes - -```typescript -export interface TableHTMLAttributes extends Attrs<'table', T> -``` - -**Extends:** Attrs<'table', T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts) -## TaskCtx +## ResourceProps ```typescript -export interface TaskCtx +export interface ResourceProps ``` -
@@ -9906,204 +3362,136 @@ Description
-[track](#) +[onPending?](#) -[Tracker](#tracker) +() => [JSXOutput](#jsxoutput) -
- - - -
- -Method - - - -Description - -
- -[cleanup(callback)](#) - - +_(Optional)_
+
-[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) +[onRejected?](#) -## TaskFn + -```typescript -export type TaskFn = (ctx: TaskCtx) => ValueOrPromise void)>; -``` + -**References:** [TaskCtx](#taskctx), [ValueOrPromise](#valueorpromise) +(reason: Error) => [JSXOutput](#jsxoutput) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) + -## TdHTMLAttributes +_(Optional)_ -```typescript -export interface TdHTMLAttributes extends Attrs<'td', T> -``` +
-**Extends:** Attrs<'td', T> +[onResolved](#) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) + -## TextareaHTMLAttributes + -```typescript -export interface TextareaHTMLAttributes extends Attrs<'textarea', T> -``` +(value: T) => [JSXOutput](#jsxoutput) -**Extends:** Attrs<'textarea', T> + -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +
-## ThHTMLAttributes +[value](#) -```typescript -export interface ThHTMLAttributes extends Attrs<'tr', T> -``` + -**Extends:** Attrs<'tr', T> +`readonly` -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) + -## TimeHTMLAttributes +[ResourceReturn](#resourcereturn)<T> \| [Signal](#signal)<Promise<T> \| T> \| Promise<T> -```typescript -export interface TimeHTMLAttributes extends Attrs<'time', T> -``` + -**Extends:** Attrs<'time', T> +
-[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts) -## TitleHTMLAttributes +## ResourceRejected ```typescript -export interface TitleHTMLAttributes extends Attrs<'title', T> +export interface ResourceRejected ``` -**Extends:** Attrs<'title', T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) - -## Tracker - -Used to signal to Qwik which state should be watched for changes. - -The `Tracker` is passed into the `taskFn` of `useTask`. It is intended to be used to wrap state objects in a read proxy which signals to Qwik which properties should be watched for changes. A change to any of the properties causes the `taskFn` to rerun. - -### Example - -The `obs` passed into the `taskFn` is used to mark `state.count` as a property of interest. Any changes to the `state.count` property will cause the `taskFn` to rerun. + + + + +
-```tsx -const Cmp = component$(() => { - const store = useStore({ count: 0, doubleCount: 0 }); - const signal = useSignal(0); - useTask$(({ track }) => { - // Any signals or stores accessed inside the task will be tracked - const count = track(() => store.count); - // You can also pass a signal to track() directly - const signalCount = track(signal); - store.doubleCount = count + signalCount; - }); - return ( -
- - {store.count} / {store.doubleCount} - - -
- ); -}); -``` +Property -```typescript -export interface Tracker -``` +
-[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) +Modifiers -## TrackHTMLAttributes + -```typescript -export interface TrackHTMLAttributes extends Attrs<'track', T> -``` +Type -**Extends:** Attrs<'track', T> + -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +Description -## untrack +
-Don't track listeners for this callback +[loading](#) -```typescript -untrack: (fn: () => T) => T; -``` + - + -
+`readonly` -Parameter + - +boolean -Type + - +
-Description +[value](#) -
+ -fn +`readonly` -() => T +Promise<T>
-**Returns:** - -T - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-core.ts) -## unwrapStore +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts) -Get the target value of the Proxy. Useful if you want to clone a store (structureClone, IndexedDB,...) +## ResourceResolved ```typescript -unwrapProxy: (proxy: T) => T; +export interface ResourceResolved ``` +
-Parameter +Property + + + +Modifiers @@ -10116,36 +3504,59 @@ Description
-proxy +[loading](#) -T +`readonly` + + + +boolean + + + +
+ +[value](#) + + + +`readonly` + + + +Promise<T>
-**Returns:** -T +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/state/common.ts) +## ResourceReturn -## useComputed$ +```typescript +export type ResourceReturn = + | ResourcePending + | ResourceResolved + | ResourceRejected; +``` -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. +**References:** [ResourcePending](#resourcepending), [ResourceResolved](#resourceresolved), [ResourceRejected](#resourcerejected) -The function must be synchronous and must not have any side effects. +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts) -Async functions are deprecated because: +## setPlatform -- 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. +Sets the `CorePlatform`. -In v2, async functions won't work. +This is useful to override the platform in tests to change the behavior of, `requestAnimationFrame`, and import resolution. ```typescript -useComputed$: (qrl: ComputedFn) => Signal>; +setPlatform: (plt: CorePlatform) => CorePlatform; ```
@@ -10163,11 +3574,11 @@ Description
-qrl +plt -[ComputedFn](#computedfn)<T> +[CorePlatform](#coreplatform) @@ -10175,19 +3586,29 @@ qrl
**Returns:** -[Signal](#signal)<Awaited<T>> +[CorePlatform](#coreplatform) + +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/platform/platform.ts) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) +## Signal + +A signal is a reactive value which can be read and written. When the signal is written, all tasks which are tracking the signal will be re-run and all components that read the signal will be re-rendered. -## useComputedQrl +Furthermore, when a signal value is passed as a prop to a component, the optimizer will automatically forward the signal. This means that `return
hi
` will update the `title` attribute when the signal changes without having to re-render the component. ```typescript -useComputedQrl: (qrl: QRL>) => Signal>; +export interface Signal extends ReadonlySignal ``` +**Extends:** [ReadonlySignal](#readonlysignal)<T> +
-Parameter +Property + + + +Modifiers @@ -10200,39 +3621,55 @@ Description
-qrl +[value](#) + + -[QRL](#qrl)<[ComputedFn](#computedfn)<T>> +T
-**Returns:** -[Signal](#signal)<Awaited<T>> +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/signal.public.ts) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) +## SkipRender -## useConstant +```typescript +SkipRender: JSXNode; +``` -> Warning: This API is now obsolete. -> -> This is a technology preview +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts) -Stores a value which is retained for the lifetime of the component. +## Slot -If the value is a function, the function is invoked to calculate the actual value. +Allows to project the children of the current component. can only be used within the context of a component defined with `component$`. ```typescript -useConstant: (value: (() => T) | T) => T; +Slot: FunctionComponent<{ + name?: string; + children?: JSXChildren; +}>; +``` + +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/slot.public.ts) + +## SnapshotListener + +```typescript +export interface SnapshotListener ``` -
-Parameter +Property + + + +Modifiers @@ -10245,121 +3682,70 @@ Description
-value +[el](#) -(() => T) \| T - -
-**Returns:** - -T +Element -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-signal.ts) +
-## useContext +
-Retrieve Context value. +[key](#) -Use `useContext()` to retrieve the value of context in a component. To retrieve a value a parent component needs to invoke `useContextProvider()` to assign a value. + -### Example + -```tsx -// Declare the Context type. -interface TodosStore { - items: string[]; -} -// Create a Context ID (no data is saved here.) -// You will use this ID to both create and retrieve the Context. -export const TodosContext = createContextId("Todos"); +string -// Example of providing context to child components. -export const App = component$(() => { - useContextProvider( - TodosContext, - useStore({ - items: ["Learn Qwik", "Build Qwik app", "Profit"], - }), - ); + - return ; -}); +
-// Example of retrieving the context provided by a parent component. -export const Items = component$(() => { - const todos = useContext(TodosContext); - return ( -
    - {todos.items.map((item) => ( -
  • {item}
  • - ))} -
- ); -}); -``` +[qrl](#) -```typescript -useContext: UseContext; -``` +
-[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-context.ts) + -## useContextProvider +[QRL](#qrl)<any> -Assign a value to a Context. + -Use `useContextProvider()` to assign a value to a context. The assignment happens in the component's function. Once assigned, use `useContext()` in any child component to retrieve the value. +
-Context is a way to pass stores to the child components without prop-drilling. Note that scalar values are allowed, but for reactivity you need signals or stores. +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/ssr/ssr-types.ts) -### Example +## SnapshotMeta -```tsx -// Declare the Context type. -interface TodosStore { - items: string[]; -} -// Create a Context ID (no data is saved here.) -// You will use this ID to both create and retrieve the Context. -export const TodosContext = createContextId("Todos"); +```typescript +export type SnapshotMeta = Record; +``` -// Example of providing context to child components. -export const App = component$(() => { - useContextProvider( - TodosContext, - useStore({ - items: ["Learn Qwik", "Build Qwik app", "Profit"], - }), - ); +**References:** [SnapshotMetaValue](#snapshotmetavalue) - return ; -}); +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/ssr/ssr-types.ts) -// Example of retrieving the context provided by a parent component. -export const Items = component$(() => { - const todos = useContext(TodosContext); - return ( -
    - {todos.items.map((item) => ( -
  • {item}
  • - ))} -
- ); -}); -``` +## SnapshotMetaValue ```typescript -useContextProvider: (context: ContextId, newValue: STATE) => void +export interface SnapshotMetaValue ``` -
-Parameter +Property + + + +Modifiers @@ -10372,72 +3758,81 @@ Description
-context +[c?](#) -[ContextId](#contextid)<STATE> + + +string -The context to assign a value to. +_(Optional)_
-newValue +[h?](#) -STATE + + +string +_(Optional)_ +
-**Returns:** +
-void +[s?](#) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-context.ts) + -## useErrorBoundary + -```typescript -useErrorBoundary: () => Readonly; -``` +string -**Returns:** + -Readonly<[ErrorBoundaryStore](#errorboundarystore)> +_(Optional)_ -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-error-boundary.ts) +
-## useId +[w?](#) -```typescript -useId: () => string; -``` + -**Returns:** + string -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-id.ts) + -## useOn +_(Optional)_ -Register a listener on the current component's host element. +
-Used to programmatically add event listeners. Useful from custom `use*` methods, which do not have access to the JSX. Otherwise, it's adding a JSX listener in the `
` is a better idea. +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/ssr/ssr-types.ts) + +## SnapshotResult ```typescript -useOn: (event: T | T[], eventQrl: EventQRL) => void +export interface SnapshotResult ``` -
-Parameter +Property + + + +Modifiers @@ -10450,98 +3845,107 @@ Description
-event +[funcs](#) -T \| T[] + + +string[]
-eventQrl +[mode](#) -EventQRL<T> + + +'render' \| 'listeners' \| 'static'
-**Returns:** +
-void +[objs?](#) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-on.ts) + -## useOnDocument + -Register a listener on `document`. +any[] -Used to programmatically add event listeners. Useful from custom `use*` methods, which do not have access to the JSX. + -```typescript -useOnDocument: (event: T | T[], eventQrl: EventQRL) => void -``` +_(Optional)_ - + - +
+
-Parameter +[qrls](#) - + -Type + - +[QRL](#qrl)[] -Description + -
+
-event +[resources](#) -T \| T[] + + +ResourceReturnInternal<any>[]
-eventQrl +[state?](#) -EventQRL<T> + + +[SnapshotState](#snapshotstate) +_(Optional)_ +
-**Returns:** -void - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-on.ts) - -## useOnWindow +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/ssr/ssr-types.ts) -Register a listener on `window`. +## SnapshotState -Used to programmatically add event listeners. Useful from custom `use*` methods, which do not have access to the JSX. +> Warning: This API is now obsolete. +> +> not longer used in v2 ```typescript -useOnWindow: (event: T | T[], eventQrl: EventQRL) => void +export interface SnapshotState ``` -
-Parameter +Property + + + +Modifiers @@ -10554,178 +3958,191 @@ Description
-event +[ctx](#) -T \| T[] + + +[SnapshotMeta](#snapshotmeta)
-eventQrl +[objs](#) -EventQRL<T> + + +any[]
-**Returns:** +
-void +[refs](#) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-on.ts) + -## useResource$ + -This method works like an async memoized function that runs whenever some tracked value changes and returns some data. +Record<string, string> -`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. +[subs](#) -### 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(""); +any[] - 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}
; - }} - /> -
- ); -}); +
+ +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/ssr/ssr-types.ts) + +## SSRComment + +```typescript +SSRComment: FunctionComponent<{ + data: string; +}>; ``` +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts) + +## SSRHintProps + ```typescript -useResource$: (generatorFn: ResourceFn, opts?: ResourceOptions) => - ResourceReturn; +export type SSRHintProps = { + dynamic?: boolean; +}; ``` - - - -
+[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts) -Parameter +## SSRRaw - +```typescript +SSRRaw: FunctionComponent<{ + data: string; +}>; +``` -Type +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts) - +## SSRStream -Description +```typescript +SSRStream: FunctionComponent; +``` -
+[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts) -generatorFn +## SSRStreamBlock - +```typescript +SSRStreamBlock: FunctionComponent<{ + children?: JSXOutput; +}>; +``` -[ResourceFn](#resourcefn)<T> +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts) - +## SSRStreamChildren -
+```typescript +export type SSRStreamChildren = + | AsyncGenerator + | ((stream: StreamWriter) => Promise) + | (() => AsyncGenerator); +``` -opts +**References:** [JSXChildren](#jsxchildren) - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts) -[ResourceOptions](#resourceoptions) +## SSRStreamProps - +```typescript +export type SSRStreamProps = { + children: SSRStreamChildren; +}; +``` -_(Optional)_ +**References:** [SSRStreamChildren](#ssrstreamchildren) -
-**Returns:** +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/jsx/utils.public.ts) -[ResourceReturn](#resourcereturn)<T> +## sync$ -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts) +Extract function into a synchronously loadable QRL. + +NOTE: Synchronous QRLs functions can't close over any variables, including exports. + +```typescript +sync$: (fn: T) => SyncQRL; +``` + + + +
+ +Parameter + + + +Type + + -## useResourceQrl +Description -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. +fn -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. +T -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 +Function to extract. -Example showing how `useResource` to perform a fetch to request the weather, whenever the input city name changes. +
+**Returns:** -```tsx -const Cmp = component$(() => { - const cityS = useSignal(""); +[SyncQRL](#syncqrl)<T> - 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 }; - }); +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/qrl.public.ts) - return ( -
- - { - return
Temperature: {weather.temp}
; - }} - /> -
- ); -}); -``` +## SyncQRL ```typescript -useResourceQrl: (qrl: QRL>, opts?: ResourceOptions) => - ResourceReturn; +export interface SyncQRL extends QRL ``` +**Extends:** [QRL](#qrl)<TYPE> + +
-Parameter +Property + + + +Modifiers @@ -10738,44 +4155,60 @@ Description
-qrl +[\_\_brand\_\_SyncQRL\_\_](#) + + -[QRL](#qrl)<[ResourceFn](#resourcefn)<T>> +TYPE
-opts +[dev](#) -[ResourceOptions](#resourceoptions) + + +QRLDev \| null -_(Optional)_ +
+ +[resolved](#) + + + + + +TYPE + +
-**Returns:** -[ResourceReturn](#resourcereturn)<T> - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/qrl.public.ts) -## useServerData +## TaskCtx ```typescript -export declare function useServerData(key: string): T | undefined; +export interface TaskCtx ```
-Parameter +Property + + + +Modifiers @@ -10788,104 +4221,100 @@ Description
-key +[track](#) -string + + +[Tracker](#tracker)
-**Returns:** -T \| undefined + + +
-[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-env-data.ts) +Method -## useSignal + -Hook that creates a signal that is retained for the lifetime of the component. +Description -```typescript -useSignal: UseSignal; -``` +
-[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-signal.ts) +[cleanup(callback)](#) -## UseSignal + + +
+ +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) -Hook that creates a signal that is retained for the lifetime of the component. +## TaskFn ```typescript -useSignal: UseSignal; +export type TaskFn = (ctx: TaskCtx) => ValueOrPromise void)>; ``` -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-signal.ts) +**References:** [TaskCtx](#taskctx), [ValueOrPromise](#valueorpromise) -## useStore +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) -Creates an object that Qwik can track across serializations. +## Tracker -Use `useStore` to create a state for your application. The returned object is a proxy that has a unique ID. The ID of the object is used in the `QRL`s to refer to the store. +Used to signal to Qwik which state should be watched for changes. + +The `Tracker` is passed into the `taskFn` of `useTask`. It is intended to be used to wrap state objects in a read proxy which signals to Qwik which properties should be watched for changes. A change to any of the properties causes the `taskFn` to rerun. ### Example -Example showing how `useStore` is used in Counter example to keep track of the count. +The `obs` passed into the `taskFn` is used to mark `state.count` as a property of interest. Any changes to the `state.count` property will cause the `taskFn` to rerun. ```tsx -const Stores = component$(() => { - const counter = useCounter(1); - - // Reactivity happens even for nested objects and arrays - const userData = useStore({ - name: "Manu", - address: { - address: "", - city: "", - }, - orgs: [], - }); - - // useStore() can also accept a function to calculate the initial value - const state = useStore(() => { - return { - value: expensiveInitialValue(), - }; +const Cmp = component$(() => { + const store = useStore({ count: 0, doubleCount: 0 }); + const signal = useSignal(0); + useTask$(({ track }) => { + // Any signals or stores accessed inside the task will be tracked + const count = track(() => store.count); + // You can also pass a signal to track() directly + const signalCount = track(signal); + store.doubleCount = count + signalCount; }); - return (
-
Counter: {counter.value}
- + + {store.count} / {store.doubleCount} + +
); }); +``` -function useCounter(step: number) { - // Multiple stores can be created in custom hooks for convenience and composability - const counterStore = useStore({ - value: 0, - }); - useVisibleTask$(() => { - // Only runs in the client - const timer = setInterval(() => { - counterStore.value += step; - }, 500); - return () => { - clearInterval(timer); - }; - }); - return counterStore; -} +```typescript +export interface Tracker ``` +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) + +## untrack + +Don't track listeners for this callback + ```typescript -useStore: ( - initialState: STATE | (() => STATE), - opts?: UseStoreOptions, -) => STATE; +untrack: (fn: () => T) => T; ``` -
@@ -10903,48 +4332,33 @@ Description
-initialState - - - -STATE \| (() => STATE) - - - -
- -opts +fn -[UseStoreOptions](#usestoreoptions) +() => T -_(Optional)_ -
**Returns:** -STATE +T -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-store.public.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-core.ts) -## UseStoreOptions +## unwrapStore + +Get the original object that was wrapped by the store. Useful if you want to clone a store (structuredClone, IndexedDB,...) ```typescript -export interface UseStoreOptions +unwrapStore: (value: T) => T; ``` - - +
-Property - - - -Modifiers +Parameter @@ -10954,59 +4368,33 @@ Type Description -
- -[deep?](#) - - - - - -boolean - - - -_(Optional)_ If `true` then all nested objects and arrays will be tracked as well. Default is `true`. - -
- -[reactive?](#) +
- +value -boolean +T -_(Optional)_ If `false` then the object will not be tracked for changes. Default is `true`. -
+**Returns:** -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-store.public.ts) - -## useStyles$ - -A lazy-loadable reference to a component's styles. +T -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.) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/signal/store.ts) -```tsx -import styles from "./code-block.css?inline"; +## useComputed$ -export const CmpStyles = component$(() => { - useStyles$(styles); +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. - return
Some text
; -}); -``` +The function must be synchronous and must not have any side effects. ```typescript -useStyles$: (qrl: string) => void +useComputed$: (qrl: import("./use-computed").ComputedFn) => T extends Promise ? never : import("..").ReadonlySignal ```
@@ -11028,7 +4416,7 @@ qrl -string +import("./use-computed").[ComputedFn](#computedfn)<T> @@ -11036,28 +4424,18 @@ string
**Returns:** -void - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-styles.ts) - -## useStylesQrl - -A lazy-loadable reference to a component's styles. +T extends Promise<any> ? never : import("..").[ReadonlySignal](#readonlysignal)<T> -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.) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-computed-dollar.ts) -```tsx -import styles from "./code-block.css?inline"; +## useConstant -export const CmpStyles = component$(() => { - useStyles$(styles); +Stores a value which is retained for the lifetime of the component. Subsequent calls to `useConstant` will always return the first value given. - return
Some text
; -}); -``` +If the value is a function, the function is invoked once to calculate the actual value. ```typescript -useStylesQrl: (styles: QRL) => void +useConstant: (value: (() => T) | T) => T; ```
@@ -11075,11 +4453,11 @@ Description
-styles +value -[QRL](#qrl)<string> +(() => T) \| T @@ -11087,23 +4465,109 @@ styles
**Returns:** -void +T -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-styles.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-signal.ts) -## UseStylesScoped +## useContext + +Retrieve Context value. + +Use `useContext()` to retrieve the value of context in a component. To retrieve a value a parent component needs to invoke `useContextProvider()` to assign a value. + +### Example + +```tsx +// Declare the Context type. +interface TodosStore { + items: string[]; +} +// Create a Context ID (no data is saved here.) +// You will use this ID to both create and retrieve the Context. +export const TodosContext = createContextId("Todos"); + +// Example of providing context to child components. +export const App = component$(() => { + useContextProvider( + TodosContext, + useStore({ + items: ["Learn Qwik", "Build Qwik app", "Profit"], + }), + ); + + return ; +}); + +// Example of retrieving the context provided by a parent component. +export const Items = component$(() => { + const todos = useContext(TodosContext); + return ( +
    + {todos.items.map((item) => ( +
  • {item}
  • + ))} +
+ ); +}); +``` ```typescript -export interface UseStylesScoped +useContext: UseContext; ``` - +
+[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-context.ts) -Property +## useContextProvider - +Assign a value to a Context. -Modifiers +Use `useContextProvider()` to assign a value to a context. The assignment happens in the component's function. Once assigned, use `useContext()` in any child component to retrieve the value. + +Context is a way to pass stores to the child components without prop-drilling. Note that scalar values are allowed, but for reactivity you need signals or stores. + +### Example + +```tsx +// Declare the Context type. +interface TodosStore { + items: string[]; +} +// Create a Context ID (no data is saved here.) +// You will use this ID to both create and retrieve the Context. +export const TodosContext = createContextId("Todos"); + +// Example of providing context to child components. +export const App = component$(() => { + useContextProvider( + TodosContext, + useStore({ + items: ["Learn Qwik", "Build Qwik app", "Profit"], + }), + ); + + return ; +}); + +// Example of retrieving the context provided by a parent component. +export const Items = component$(() => { + const todos = useContext(TodosContext); + return ( +
    + {todos.items.map((item) => ( +
  • {item}
  • + ))} +
+ ); +}); +``` + +```typescript +useContextProvider: (context: ContextId, newValue: STATE) => void +``` + + +
+ +Parameter @@ -11116,39 +4580,67 @@ Description
-[scopeId](#) +context +[ContextId](#contextid)<STATE> + -string +The context to assign a value to. + +
+ +newValue + + + +STATE
+**Returns:** -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-styles.ts) +void -## useStylesScoped$ +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-context.ts) -A lazy-loadable reference to a component's styles, that is scoped to the component. +## useErrorBoundary -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.) +```typescript +useErrorBoundary: () => Readonly; +``` -```tsx -import scoped from "./code-block.css?inline"; +**Returns:** -export const CmpScopedStyles = component$(() => { - useStylesScoped$(scoped); +Readonly<[ErrorBoundaryStore](#errorboundarystore)> - return
Some text
; -}); +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-error-boundary.ts) + +## useId + +```typescript +useId: () => string; ``` +**Returns:** + +string + +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-id.ts) + +## useOn + +Register a listener on the current component's host element. + +Used to programmatically add event listeners. Useful from custom `use*` methods, which do not have access to the JSX. Otherwise, it's adding a JSX listener in the `
` is a better idea. + ```typescript -useStylesScoped$: (qrl: string) => UseStylesScoped; +useOn: (event: T | T[], eventQrl: EventQRL) => void ``` -
@@ -11166,40 +4658,41 @@ Description
-qrl +event -string +T \| T[]
-**Returns:** +
-[UseStylesScoped](#usestylesscoped) +eventQrl -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-styles.ts) + -## useStylesScopedQrl +EventQRL<T> -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.) +
+**Returns:** -```tsx -import scoped from "./code-block.css?inline"; +void -export const CmpScopedStyles = component$(() => { - useStylesScoped$(scoped); +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-on.ts) - return
Some text
; -}); -``` +## useOnDocument + +Register a listener on `document`. + +Used to programmatically add event listeners. Useful from custom `use*` methods, which do not have access to the JSX. ```typescript -useStylesScopedQrl: (styles: QRL) => UseStylesScoped; +useOnDocument: (event: T | T[], eventQrl: EventQRL) => void ``` +
@@ -11217,11 +4710,22 @@ Description
-styles +event + + + +T \| T[] + + + +
+ +eventQrl -[QRL](#qrl)<string> +EventQRL<T> @@ -11229,20 +4733,18 @@ styles
**Returns:** -[UseStylesScoped](#usestylesscoped) - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-styles.ts) +void -## useTask$ +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-on.ts) -Reruns the `taskFn` when the observed inputs change. +## useOnWindow -Use `useTask` to observe changes on a set of inputs, and then re-execute the `taskFn` when those inputs change. +Register a listener on `window`. -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. +Used to programmatically add event listeners. Useful from custom `use*` methods, which do not have access to the JSX. ```typescript -useTask$: (qrl: TaskFn, opts?: UseTaskOptions | undefined) => void +useOnWindow: (event: T | T[], eventQrl: EventQRL) => void ```
@@ -11260,48 +4762,86 @@ Description
-qrl +event -[TaskFn](#taskfn) +T \| T[]
-opts +eventQrl -[UseTaskOptions](#usetaskoptions) \| undefined +EventQRL<T> -_(Optional)_ -
**Returns:** void -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-on.ts) -## UseTaskOptions +## useResource$ + +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}
; + }} + /> +
+ ); +}); +``` ```typescript -export interface UseTaskOptions +useResource$: (generatorFn: ResourceFn, opts?: ResourceOptions) => + ResourceReturn; ``` + -
-Property - - - -Modifiers +Parameter @@ -11314,33 +4854,39 @@ Description
-[eagerness?](#) +generatorFn +[ResourceFn](#resourcefn)<T> + -[EagernessOptions](#eagernessoptions) +
+ +opts -_(Optional)_ - `visible`: run the effect when the element is visible. - `load`: eagerly run the effect when the application resumes. +[ResourceOptions](#resourceoptions) -
+ -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) +_(Optional)_ -## useTaskQrl + + +**Returns:** -Reruns the `taskFn` when the observed inputs change. +[ResourceReturn](#resourcereturn)<T> -Use `useTask` to observe changes on a set of inputs, and then re-execute the `taskFn` when those inputs change. +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-resource-dollar.ts) -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. +## useServerData ```typescript -useTaskQrl: (qrl: QRL, opts?: UseTaskOptions) => void +export declare function useServerData(key: string): T | undefined; ``` -
@@ -11358,59 +4904,100 @@ Description
-qrl +key -[QRL](#qrl)<[TaskFn](#taskfn)> +string
+
+**Returns:** -opts +T \| undefined - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-env-data.ts) -[UseTaskOptions](#usetaskoptions) +## useSignal - +```typescript +useSignal: UseSignal; +``` -_(Optional)_ +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-signal.ts) - - -**Returns:** +## UseSignal -void +```typescript +useSignal: UseSignal; +``` -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-signal.ts) -## useVisibleTask$ +## useStore + +Creates an object that Qwik can track across serializations. + +Use `useStore` to create a state for your application. The returned object is a proxy that has a unique ID. The ID of the object is used in the `QRL`s to refer to the store. + +### Example + +Example showing how `useStore` is used in Counter example to keep track of the count. ```tsx -const Timer = component$(() => { - const store = useStore({ - count: 0, +const Stores = component$(() => { + const counter = useCounter(1); + + // Reactivity happens even for nested objects and arrays + const userData = useStore({ + name: "Manu", + address: { + address: "", + city: "", + }, + orgs: [], + }); + + // useStore() can also accept a function to calculate the initial value + const state = useStore(() => { + return { + value: expensiveInitialValue(), + }; }); + return ( +
+
Counter: {counter.value}
+ +
+ ); +}); + +function useCounter(step: number) { + // Multiple stores can be created in custom hooks for convenience and composability + const counterStore = useStore({ + value: 0, + }); useVisibleTask$(() => { // Only runs in the client const timer = setInterval(() => { - store.count++; + counterStore.value += step; }, 500); return () => { clearInterval(timer); }; }); - - return
{store.count}
; -}); + return counterStore; +} ``` ```typescript -useVisibleTask$: (qrl: TaskFn, opts?: OnVisibleTaskOptions | undefined) => void +useStore: ( + initialState: STATE | (() => STATE), + opts?: UseStoreOptions, +) => STATE; ```
@@ -11428,11 +5015,11 @@ Description
-qrl +initialState -[TaskFn](#taskfn) +STATE \| (() => STATE) @@ -11443,7 +5030,7 @@ opts -[OnVisibleTaskOptions](#onvisibletaskoptions) \| undefined +[UseStoreOptions](#usestoreoptions) @@ -11453,39 +5040,23 @@ _(Optional)_
**Returns:** -void - -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) - -## useVisibleTaskQrl - -```tsx -const Timer = component$(() => { - const store = useStore({ - count: 0, - }); +STATE - useVisibleTask$(() => { - // Only runs in the client - const timer = setInterval(() => { - store.count++; - }, 500); - return () => { - clearInterval(timer); - }; - }); +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-store.public.ts) - return
{store.count}
; -}); -``` +## UseStoreOptions ```typescript -useVisibleTaskQrl: (qrl: QRL, opts?: OnVisibleTaskOptions) => void +export interface UseStoreOptions ```
-Parameter +Property + + + +Modifiers @@ -11498,88 +5069,95 @@ Description
-qrl +[deep?](#) -[QRL](#qrl)<[TaskFn](#taskfn)> + + +boolean +_(Optional)_ If `true` then all nested objects and arrays will be tracked as well. Default is `true`. +
-opts +[reactive?](#) + + -[OnVisibleTaskOptions](#onvisibletaskoptions) +boolean -_(Optional)_ +_(Optional)_ If `false` then the object will not be tracked for changes. Default is `true`.
-**Returns:** -void +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-store.public.ts) -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) +## useStyles$ -## ValueOrPromise +A lazy-loadable reference to a component's styles. -Type representing a value which is either resolve or a promise. +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
; +}); +``` ```typescript -export type ValueOrPromise = T | Promise; +useStyles$: (qrl: string) => UseStyles; ``` -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/util/types.ts) + + +
-## version +Parameter -QWIK_VERSION + -```typescript -version: string; -``` +Type -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/version.ts) + + +Description -## VideoHTMLAttributes +
-```typescript -export interface VideoHTMLAttributes extends Attrs<'video', T> -``` +qrl -**Extends:** Attrs<'video', T> + -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +string -## VisibleTaskStrategy + -```typescript -export type VisibleTaskStrategy = - | "intersection-observer" - | "document-ready" - | "document-idle"; -``` +
+**Returns:** -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) +UseStyles -## WebViewHTMLAttributes +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-styles.ts) -> Warning: This API is now obsolete. -> -> This is the type for a React Native WebView. It doesn't belong in Qwik (yet?) but we're keeping it for backwards compatibility. +## UseStylesScoped ```typescript -export interface WebViewHTMLAttributes extends HTMLAttributes +export interface UseStylesScoped ``` -**Extends:** [HTMLAttributes](#htmlattributes)<T> - -
Property @@ -11599,259 +5177,317 @@ Description
-[allowFullScreen?](#) +[scopeId](#) -boolean \| undefined +string -_(Optional)_ -
+
-[allowpopups?](#) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-styles.ts) - +## useStylesScoped$ - +A lazy-loadable reference to a component's styles, that is scoped to the component. -boolean \| undefined +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"; -_(Optional)_ +export const CmpScopedStyles = component$(() => { + useStylesScoped$(scoped); - - + return
Some text
; +}); +``` -[autoFocus?](#) +```typescript +useStylesScoped$: (qrl: string) => UseStylesScoped; +``` - + - + -
- +Parameter -boolean \| undefined + - +Type -_(Optional)_ + -
+Description -[autosize?](#) +
- +qrl -boolean \| undefined +string -_(Optional)_ -
+
+**Returns:** -[blinkfeatures?](#) +[UseStylesScoped](#usestylesscoped) - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-styles.ts) - +## useTask$ + +Reruns the `taskFn` when the observed inputs change. -string \| undefined +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. -_(Optional)_ +```typescript +useTask$: (qrl: import("./use-task").TaskFn, opts?: import("./use-task").UseTaskOptions | undefined) => void +``` - - + + -
-[disableblinkfeatures?](#) +Parameter - + - +Type + + + +Description + +
-string \| undefined +qrl -_(Optional)_ +import("./use-task").[TaskFn](#taskfn) + +
-[disableguestresize?](#) - - +opts -boolean \| undefined +import("./use-task").[UseTaskOptions](#usetaskoptions) \| undefined _(Optional)_
+
+**Returns:** -[disablewebsecurity?](#) +void - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task-dollar.ts) - +## UseTaskOptions -boolean \| undefined +```typescript +export interface UseTaskOptions +``` - + - + -
-_(Optional)_ +Property -
+ + +Modifiers -[guestinstance?](#) + + +Type + + + +Description + +
+ +[eagerness?](#) -string \| undefined +[EagernessOptions](#eagernessoptions) -_(Optional)_ +_(Optional)_ - `visible`: run the effect when the element is visible. - `load`: eagerly run the effect when the application resumes.
+
-[httpreferrer?](#) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-task.ts) - +## useVisibleTask$ - +```tsx +const Timer = component$(() => { + const store = useStore({ + count: 0, + }); + + useVisibleTask$(() => { + // Only runs in the client + const timer = setInterval(() => { + store.count++; + }, 500); + return () => { + clearInterval(timer); + }; + }); -string \| undefined + return
{store.count}
; +}); +``` - +```typescript +useVisibleTask$: (qrl: import("./use-task").TaskFn, opts?: import("./use-visible-task").OnVisibleTaskOptions | undefined) => void +``` -_(Optional)_ + - + -
-
+Parameter + + -[nodeintegration?](#) +Type - + - +Description + +
-boolean \| undefined +qrl -_(Optional)_ +import("./use-task").[TaskFn](#taskfn) + +
-[partition?](#) - - +opts -string \| undefined +import("./use-visible-task").[OnVisibleTaskOptions](#onvisibletaskoptions) \| undefined _(Optional)_
+
+**Returns:** -[plugins?](#) +void - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-visible-task-dollar.ts) - +## ValueOrPromise -boolean \| undefined +Type representing a value which is either resolve or a promise. - +```typescript +export type ValueOrPromise = T | Promise; +``` -_(Optional)_ +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/utils/types.ts) - - +## version -[preload?](#) +QWIK_VERSION - +```typescript +version: string; +``` - +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/version.ts) -string \| undefined +## VisibleTaskStrategy - +```typescript +export type VisibleTaskStrategy = + | "intersection-observer" + | "document-ready" + | "document-idle"; +``` -_(Optional)_ +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-visible-task.ts) - - +## withLocale -[src?](#) +Override the `getLocale` with `lang` within the `fn` execution. - +```typescript +export declare function withLocale(locale: string, fn: () => T): T; +``` - + - +
+ +Parameter -string \| undefined + - +Type -_(Optional)_ + -
+Description -[useragent?](#) +
- +locale -string \| undefined +string -_(Optional)_ -
-[webpreferences?](#) - - +fn -string \| undefined +() => T -_(Optional)_ -
+**Returns:** + +T -[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/render/jsx/types/jsx-generated.ts) +[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/use/use-locale.ts) diff --git a/packages/docs/src/routes/community/layout.tsx b/packages/docs/src/routes/community/layout.tsx index baf0fd04bba..a486d8d65f6 100644 --- a/packages/docs/src/routes/community/layout.tsx +++ b/packages/docs/src/routes/community/layout.tsx @@ -1,4 +1,4 @@ -import { component$, Slot, useStyles$ } from '@builder.io/qwik'; +import { component$, Slot, useStyles$ } from '@qwik.dev/core'; import { SideBar } from '../../components/sidebar/sidebar'; import { Footer } from '../../components/footer/footer'; import { Header } from '../../components/header/header'; diff --git a/packages/docs/src/routes/demo/api/add/index.tsx b/packages/docs/src/routes/demo/api/add/index.tsx index dc04821556c..23628fd1991 100644 --- a/packages/docs/src/routes/demo/api/add/index.tsx +++ b/packages/docs/src/routes/demo/api/add/index.tsx @@ -1,4 +1,4 @@ -import type { RequestHandler } from '@builder.io/qwik-city'; +import type { RequestHandler } from '@qwik.dev/router'; export const onGet: RequestHandler = async ({ query, json }) => { const a = Number.parseFloat(query.get('a') || '0'); diff --git a/packages/docs/src/routes/demo/component/child/index.tsx b/packages/docs/src/routes/demo/component/child/index.tsx index 5a8ede86a03..3a9e6347791 100644 --- a/packages/docs/src/routes/demo/component/child/index.tsx +++ b/packages/docs/src/routes/demo/component/child/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/packages/docs/src/routes/demo/component/inline-child/index.tsx b/packages/docs/src/routes/demo/component/inline-child/index.tsx index f5b580ef95d..8976dc8a84d 100644 --- a/packages/docs/src/routes/demo/component/inline-child/index.tsx +++ b/packages/docs/src/routes/demo/component/inline-child/index.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; // Inline component: declared using a standard function. export const MyButton = (props: { text: string }) => { diff --git a/packages/docs/src/routes/demo/component/lazy/index.tsx b/packages/docs/src/routes/demo/component/lazy/index.tsx index 943c3c0a9d7..410939112c7 100644 --- a/packages/docs/src/routes/demo/component/lazy/index.tsx +++ b/packages/docs/src/routes/demo/component/lazy/index.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export const Child = component$(() => { return

child

; diff --git a/packages/docs/src/routes/demo/component/primitive-props/index.tsx b/packages/docs/src/routes/demo/component/primitive-props/index.tsx index 67dc562f34e..ab3f23e46b2 100644 --- a/packages/docs/src/routes/demo/component/primitive-props/index.tsx +++ b/packages/docs/src/routes/demo/component/primitive-props/index.tsx @@ -1,5 +1,5 @@ -import { component$, useSignal } from '@builder.io/qwik'; -import type { Signal } from '@builder.io/qwik'; +import { component$, useSignal } from '@qwik.dev/core'; +import type { Signal } from '@qwik.dev/core'; interface ItemProps { name?: string; diff --git a/packages/docs/src/routes/demo/component/props/index.tsx b/packages/docs/src/routes/demo/component/props/index.tsx index 2de9d0a7688..0bc553cd599 100644 --- a/packages/docs/src/routes/demo/component/props/index.tsx +++ b/packages/docs/src/routes/demo/component/props/index.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; interface ItemProps { name?: string; diff --git a/packages/docs/src/routes/demo/component/ref/index.tsx b/packages/docs/src/routes/demo/component/ref/index.tsx index 74c1640f8c7..b38905c7e1f 100644 --- a/packages/docs/src/routes/demo/component/ref/index.tsx +++ b/packages/docs/src/routes/demo/component/ref/index.tsx @@ -1,4 +1,4 @@ -import { component$, useVisibleTask$, useSignal } from '@builder.io/qwik'; +import { component$, useVisibleTask$, useSignal } from '@qwik.dev/core'; export default component$(() => { const width = useSignal(0); diff --git a/packages/docs/src/routes/demo/component/reference-props/index.tsx b/packages/docs/src/routes/demo/component/reference-props/index.tsx index d72716f6858..53adfc77426 100644 --- a/packages/docs/src/routes/demo/component/reference-props/index.tsx +++ b/packages/docs/src/routes/demo/component/reference-props/index.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; interface ItemProps { details: { diff --git a/packages/docs/src/routes/demo/component/relativeUrl/index.tsx b/packages/docs/src/routes/demo/component/relativeUrl/index.tsx index 1116217dcb4..8bdbbf84dee 100644 --- a/packages/docs/src/routes/demo/component/relativeUrl/index.tsx +++ b/packages/docs/src/routes/demo/component/relativeUrl/index.tsx @@ -1,5 +1,5 @@ -import { component$ } from '@builder.io/qwik'; -import { useLocation } from '@builder.io/qwik-city'; +import { component$ } from '@qwik.dev/core'; +import { useLocation } from '@qwik.dev/router'; export default component$(() => { const loc = useLocation(); diff --git a/packages/docs/src/routes/demo/component/simple/index.tsx b/packages/docs/src/routes/demo/component/simple/index.tsx index feee7892fd5..8430072f58c 100644 --- a/packages/docs/src/routes/demo/component/simple/index.tsx +++ b/packages/docs/src/routes/demo/component/simple/index.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export default component$(() => { return
Hello World!
; diff --git a/packages/docs/src/routes/demo/component/useId/index.tsx b/packages/docs/src/routes/demo/component/useId/index.tsx index 6b919d25ab5..ec96deb77c8 100644 --- a/packages/docs/src/routes/demo/component/useId/index.tsx +++ b/packages/docs/src/routes/demo/component/useId/index.tsx @@ -1,9 +1,4 @@ -import { - component$, - useId, - useSignal, - useVisibleTask$, -} from '@builder.io/qwik'; +import { component$, useId, useSignal, useVisibleTask$ } from '@qwik.dev/core'; export default component$(() => { const elemIdSignal = useSignal(null); diff --git a/packages/docs/src/routes/demo/context/minimal/index.tsx b/packages/docs/src/routes/demo/context/minimal/index.tsx index 9c8e93c107f..aef648dfeb9 100644 --- a/packages/docs/src/routes/demo/context/minimal/index.tsx +++ b/packages/docs/src/routes/demo/context/minimal/index.tsx @@ -1,9 +1,9 @@ -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' diff --git a/packages/docs/src/routes/demo/cookbook/algolia-search/index.tsx b/packages/docs/src/routes/demo/cookbook/algolia-search/index.tsx index 03c1a730453..47b1fbda80c 100644 --- a/packages/docs/src/routes/demo/cookbook/algolia-search/index.tsx +++ b/packages/docs/src/routes/demo/cookbook/algolia-search/index.tsx @@ -1,4 +1,4 @@ -import { $, component$, useSignal, useStylesScoped$ } from '@builder.io/qwik'; +import { $, component$, useSignal, useStylesScoped$ } from '@qwik.dev/core'; type AlgoliaResult = { hits: { diff --git a/packages/docs/src/routes/demo/cookbook/combine-request-handlers/index.tsx b/packages/docs/src/routes/demo/cookbook/combine-request-handlers/index.tsx index de9999fe1d0..6a63cdce988 100644 --- a/packages/docs/src/routes/demo/cookbook/combine-request-handlers/index.tsx +++ b/packages/docs/src/routes/demo/cookbook/combine-request-handlers/index.tsx @@ -1,4 +1,4 @@ -import type { RequestHandler } from '@builder.io/qwik-city'; +import type { RequestHandler } from '@qwik.dev/router'; /** * Combines multiple request handlers into a single request handler. diff --git a/packages/docs/src/routes/demo/cookbook/debouncer/index.tsx b/packages/docs/src/routes/demo/cookbook/debouncer/index.tsx index 429d0b771ea..57040f7face 100644 --- a/packages/docs/src/routes/demo/cookbook/debouncer/index.tsx +++ b/packages/docs/src/routes/demo/cookbook/debouncer/index.tsx @@ -4,7 +4,7 @@ import { component$, type QRL, useStylesScoped$, -} from '@builder.io/qwik'; +} from '@qwik.dev/core'; export const useDebouncer = (fn: QRL<(args: any) => void>, delay: number) => { const timeoutId = useSignal(); diff --git a/packages/docs/src/routes/demo/cookbook/drag&drop/advanced/index.tsx b/packages/docs/src/routes/demo/cookbook/drag&drop/advanced/index.tsx new file mode 100644 index 00000000000..b0c1b02311f --- /dev/null +++ b/packages/docs/src/routes/demo/cookbook/drag&drop/advanced/index.tsx @@ -0,0 +1,193 @@ +import { component$, sync$, useSignal, $ } from '@builder.io/qwik'; + +type Item = { + id: number; + content: string; +}; + +export default component$(() => { + const items1 = useSignal([ + { id: 1, content: '📱 Phone' }, + { id: 2, content: '💻 Laptop' }, + { id: 3, content: '🎧 Headphones' }, + ]); + + const items2 = useSignal([ + { id: 4, content: '⌚️ Watch' }, + { id: 5, content: '🖱 Mouse' }, + { id: 6, content: '⌨️ Keyboard' }, + ]); + + return ( +
+
{ + currentTarget.setAttribute('data-over', 'true'); + })} + onDragLeave$={sync$((_: DragEvent, currentTarget: HTMLDivElement) => { + currentTarget.removeAttribute('data-over'); + })} + onDrop$={[ + sync$((e: DragEvent, currentTarget: HTMLDivElement) => { + const id = e.dataTransfer?.getData('text/plain'); + currentTarget.dataset.droppedId = id; + currentTarget.removeAttribute('data-over'); + }), + $((e, currentTarget) => { + const draggedElementId = currentTarget.dataset.droppedId; + const isDropZone = currentTarget.hasAttribute('data-dropzone'); + + if (draggedElementId) { + const itemId = parseInt(draggedElementId); + const item = items2.value.find((i) => i.id === itemId); + + if (item && isDropZone) { + items2.value = items2.value.filter((i) => i.id !== itemId); + items1.value = [...items1.value, item]; + } else { + const newItems = [...items1.value]; + const targetId = parseInt( + (e.target as HTMLDivElement).dataset.id || '0' + ); + if (targetId === 0) return; + + const targetIndex = items1.value.findIndex( + (i) => i.id === targetId + ); + const draggedIndex = items1.value.findIndex( + (i) => i.id === itemId + ); + + if (draggedIndex !== -1) { + // Sorting in the same container + swapElements(newItems, draggedIndex, targetIndex); + items1.value = newItems; + } else { + // Sorting between containers + if (!item) return; + items2.value = items2.value.filter((i) => i.id !== itemId); + insertElement(newItems, targetIndex, item); + items1.value = newItems; + } + } + } + }), + ]} + > +

Container 1

+ {items1.value.map((item) => ( +
{ + const itemId = currentTarget.getAttribute('data-id'); + if (e.dataTransfer && itemId) { + e.dataTransfer.setData('text/plain', itemId); + } + } + )} + > + {item.content} +
+ ))} +
+ +
{ + currentTarget.setAttribute('data-over', 'true'); + }} + onDragLeave$={[ + sync$((_: DragEvent, currentTarget: HTMLDivElement) => { + currentTarget.removeAttribute('data-over'); + }), + ]} + onDrop$={[ + sync$((e: DragEvent, currentTarget: HTMLDivElement) => { + const id = e.dataTransfer?.getData('text/plain'); + currentTarget.dataset.droppedId = id; + currentTarget.removeAttribute('data-over'); + }), + $((e, currentTarget) => { + const draggedElementId = currentTarget.dataset.droppedId; + const isDropZone = currentTarget.hasAttribute('data-dropzone'); + + if (draggedElementId) { + const itemId = parseInt(draggedElementId); + const item = items1.value.find((i) => i.id === itemId); + + if (isDropZone && item) { + items1.value = items1.value.filter((i) => i.id !== itemId); + items2.value = [...items2.value, item]; + } else { + const targetId = parseInt( + (e.target as HTMLDivElement).dataset.id || '0' + ); + if (targetId === 0) return; + const newItems = [...items2.value]; + const draggedIndex = items2.value.findIndex( + (i) => i.id === itemId + ); + const targetIndex = items2.value.findIndex( + (i) => i.id === targetId + ); + if (draggedIndex !== -1) { + // Sorting in the same container + swapElements(newItems, targetIndex, draggedIndex); + items2.value = newItems; + } else { + // Sorting between containers + if (!item) return; + items1.value = items1.value.filter((i) => i.id !== itemId); + insertElement(newItems, targetIndex, item); + items2.value = newItems; + } + } + } + }), + ]} + > +

Container 2

+ {items2.value.map((item) => ( +
{ + const itemId = currentTarget.getAttribute('data-id'); + if (e.dataTransfer && itemId) { + e.dataTransfer.setData('text/plain', itemId); + } + } + )} + > + {item.content} +
+ ))} +
+
+ ); +}); + +function swapElements(arr: Item[], index1: number, index2: number) { + arr[index1] = arr.splice(index2, 1, arr[index1])[0]; + + return arr; +} + +function insertElement(arr: Item[], index: number, item: Item) { + arr.splice(index, 0, item); + return arr; +} diff --git a/packages/docs/src/routes/demo/cookbook/drag&drop/basic/index.tsx b/packages/docs/src/routes/demo/cookbook/drag&drop/basic/index.tsx new file mode 100644 index 00000000000..ba1a1d470a3 --- /dev/null +++ b/packages/docs/src/routes/demo/cookbook/drag&drop/basic/index.tsx @@ -0,0 +1,119 @@ +import { component$, sync$, useSignal, $ } from '@builder.io/qwik'; + +export default component$(() => { + const items1 = useSignal([ + { id: 1, content: '📱 Phone' }, + { id: 2, content: '💻 Laptop' }, + { id: 3, content: '🎧 Headphones' }, + ]); + + const items2 = useSignal([ + { id: 4, content: '⌚️ Watch' }, + { id: 5, content: '🖱 Mouse' }, + { id: 6, content: '⌨️ Keyboard' }, + ]); + + return ( +
+
{ + currentTarget.setAttribute('data-over', 'true'); + })} + onDragLeave$={sync$((_: DragEvent, currentTarget: HTMLDivElement) => { + currentTarget.removeAttribute('data-over'); + })} + onDrop$={[ + sync$((e: DragEvent, currentTarget: HTMLDivElement) => { + const id = e.dataTransfer?.getData('text'); + currentTarget.dataset.droppedId = id; + currentTarget.removeAttribute('data-over'); + }), + $((_, currentTarget) => { + const id = currentTarget.dataset.droppedId; + if (id) { + const itemId = parseInt(id); + const item = [...items2.value].find((i) => i.id === itemId); + if (item) { + items2.value = items2.value.filter((i) => i.id !== itemId); + items1.value = [...items1.value, item]; + } + } + }), + ]} + > +

Container 1

+ {items1.value.map((item) => ( +
{ + const itemId = currentTarget.getAttribute('data-id'); + if (e.dataTransfer && itemId) { + e.dataTransfer?.setData('text/plain', itemId); + } + } + )} + > + {item.content} +
+ ))} +
+ +
{ + currentTarget.setAttribute('data-over', 'true'); + })} + onDragLeave$={sync$((_: DragEvent, currentTarget: HTMLDivElement) => { + currentTarget.removeAttribute('data-over'); + })} + onDrop$={[ + sync$((e: DragEvent, currentTarget: HTMLDivElement) => { + const id = e.dataTransfer?.getData('text'); + currentTarget.dataset.droppedId = id; + currentTarget.removeAttribute('data-over'); + }), + $((_, currentTarget) => { + const id = currentTarget.dataset.droppedId; + if (id) { + const itemId = parseInt(id); + const item = [...items1.value].find((i) => i.id === itemId); + if (item) { + items1.value = items1.value.filter((i) => i.id !== itemId); + items2.value = [...items2.value, item]; + } + } + }), + ]} + > +

Container 2

+ {items2.value.map((item) => ( +
{ + const itemId = currentTarget.getAttribute('data-id'); + if (e.dataTransfer && itemId) { + e.dataTransfer?.setData('text/plain', itemId); + } + } + )} + > + {item.content} +
+ ))} +
+
+ ); +}); diff --git a/packages/docs/src/routes/demo/cookbook/glob-import/examples/example1.tsx b/packages/docs/src/routes/demo/cookbook/glob-import/examples/example1.tsx index 4d6941122f5..1cf4f8ef1c1 100644 --- a/packages/docs/src/routes/demo/cookbook/glob-import/examples/example1.tsx +++ b/packages/docs/src/routes/demo/cookbook/glob-import/examples/example1.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export default component$(() => { return ( diff --git a/packages/docs/src/routes/demo/cookbook/glob-import/examples/example2.tsx b/packages/docs/src/routes/demo/cookbook/glob-import/examples/example2.tsx index af1f2158762..e9871b0af80 100644 --- a/packages/docs/src/routes/demo/cookbook/glob-import/examples/example2.tsx +++ b/packages/docs/src/routes/demo/cookbook/glob-import/examples/example2.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export default component$(() => { return ( diff --git a/packages/docs/src/routes/demo/cookbook/glob-import/examples/example3.tsx b/packages/docs/src/routes/demo/cookbook/glob-import/examples/example3.tsx index d1a900489fb..541590157ce 100644 --- a/packages/docs/src/routes/demo/cookbook/glob-import/examples/example3.tsx +++ b/packages/docs/src/routes/demo/cookbook/glob-import/examples/example3.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export default component$(() => { return ( diff --git a/packages/docs/src/routes/demo/cookbook/glob-import/index.tsx b/packages/docs/src/routes/demo/cookbook/glob-import/index.tsx index fa90285ca31..dd13a13eb22 100644 --- a/packages/docs/src/routes/demo/cookbook/glob-import/index.tsx +++ b/packages/docs/src/routes/demo/cookbook/glob-import/index.tsx @@ -1,17 +1,8 @@ -import { - type Component, - component$, - useSignal, - useTask$, -} from '@builder.io/qwik'; -import { isDev } from '@builder.io/qwik/build'; +import { component$, type Component } from '@qwik.dev/core'; -const metaGlobComponents: Record = import.meta.glob( +const metaGlobComponents = import.meta.glob( '/src/routes/demo/cookbook/glob-import/examples/*', - { - import: 'default', - eager: isDev ? false : true, - } + { import: 'default' } ); export default component$(() => { @@ -24,15 +15,14 @@ export default component$(() => { ); }); +const loaded: Record = {}; export const MetaGlobExample = component$<{ name: string }>(({ name }) => { - const MetaGlobComponent = useSignal>(); - const componentPath = `/src/routes/demo/cookbook/glob-import/examples/${name}.tsx`; - - useTask$(async () => { - MetaGlobComponent.value = isDev - ? await metaGlobComponents[componentPath]() // We need to call `await metaGlobComponents[componentPath]()` in development as it is `eager:false` - : metaGlobComponents[componentPath]; // We need to directly access the `metaGlobComponents[componentPath]` expression in preview/production as it is `eager:true` - }); + const Cmp = loaded[name]; + if (!Cmp) { + const componentPath = `/src/routes/demo/cookbook/glob-import/examples/${name}.tsx`; + const promise = metaGlobComponents[componentPath](); + throw promise.then((c) => (loaded[name] = c)); + } - return <>{MetaGlobComponent.value && }; + return ; }); diff --git a/packages/docs/src/routes/demo/cookbook/leaflet-map/index.tsx b/packages/docs/src/routes/demo/cookbook/leaflet-map/index.tsx index f65ea1308bb..a7a25cbf444 100644 --- a/packages/docs/src/routes/demo/cookbook/leaflet-map/index.tsx +++ b/packages/docs/src/routes/demo/cookbook/leaflet-map/index.tsx @@ -5,7 +5,7 @@ import { useStyles$, useVisibleTask$, type Signal, -} from '@builder.io/qwik'; +} from '@qwik.dev/core'; import * as L from 'leaflet'; import leafletStyles from 'leaflet/dist/leaflet.css?inline'; diff --git a/packages/docs/src/routes/demo/cookbook/mediaController/index.tsx b/packages/docs/src/routes/demo/cookbook/mediaController/index.tsx index 0995dfad358..b7513ef7bb3 100644 --- a/packages/docs/src/routes/demo/cookbook/mediaController/index.tsx +++ b/packages/docs/src/routes/demo/cookbook/mediaController/index.tsx @@ -3,8 +3,8 @@ import { useSignal, useStylesScoped$, useVisibleTask$, -} from '@builder.io/qwik'; -import { useLocation } from '@builder.io/qwik-city'; +} from '@qwik.dev/core'; +import { useLocation } from '@qwik.dev/router'; const AUDIO_SRC = 'https://cdn.builder.io/o/assets%2F5b8073f890b043be81574f96cfd1250b%2Fafe011812da146a5b2263196cb25f263?alt=media&token=c017cd87-0598-4af2-8afd-e9b5a3fba078&apiKey=5b8073f890b043be81574f96cfd1250b'; diff --git a/packages/docs/src/routes/demo/cookbook/nav-link/example/index.tsx b/packages/docs/src/routes/demo/cookbook/nav-link/example/index.tsx index 174c8b0d446..495a532fd8d 100644 --- a/packages/docs/src/routes/demo/cookbook/nav-link/example/index.tsx +++ b/packages/docs/src/routes/demo/cookbook/nav-link/example/index.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; import { NavLink } from '..'; export default component$(() => { diff --git a/packages/docs/src/routes/demo/cookbook/nav-link/index.tsx b/packages/docs/src/routes/demo/cookbook/nav-link/index.tsx index 563fffc30a1..14236d03538 100644 --- a/packages/docs/src/routes/demo/cookbook/nav-link/index.tsx +++ b/packages/docs/src/routes/demo/cookbook/nav-link/index.tsx @@ -1,5 +1,5 @@ -import { Slot, component$ } from '@builder.io/qwik'; -import { Link, useLocation, type LinkProps } from '@builder.io/qwik-city'; +import { Slot, component$ } from '@qwik.dev/core'; +import { Link, useLocation, type LinkProps } from '@qwik.dev/router'; type NavLinkProps = LinkProps & { activeClass?: string }; diff --git a/packages/docs/src/routes/demo/cookbook/portal/index.tsx b/packages/docs/src/routes/demo/cookbook/portal/index.tsx index d9c5cb12675..ddcd6c1e9bf 100644 --- a/packages/docs/src/routes/demo/cookbook/portal/index.tsx +++ b/packages/docs/src/routes/demo/cookbook/portal/index.tsx @@ -4,10 +4,10 @@ import { useContext, useStylesScoped$, useTask$, -} from '@builder.io/qwik'; -import { PortalCloseAPIContextId, PortalAPI } from './portal-provider'; +} from '@qwik.dev/core'; +import { useLocation } from '@qwik.dev/router'; import PopupExampleCSS from './popup-example.css?inline'; -import { useLocation } from '@builder.io/qwik-city'; +import { PortalAPI, PortalCloseAPIContextId } from './portal-provider'; export default component$(() => { // Retrieve the portal API diff --git a/packages/docs/src/routes/demo/cookbook/portal/layout.tsx b/packages/docs/src/routes/demo/cookbook/portal/layout.tsx index 1adf2b8e735..5c9419f20b9 100644 --- a/packages/docs/src/routes/demo/cookbook/portal/layout.tsx +++ b/packages/docs/src/routes/demo/cookbook/portal/layout.tsx @@ -1,4 +1,4 @@ -import { Slot, component$ } from '@builder.io/qwik'; +import { Slot, component$ } from '@qwik.dev/core'; import { Portal, PortalProvider } from './portal-provider'; export default component$(() => { diff --git a/packages/docs/src/routes/demo/cookbook/portal/portal-provider.tsx b/packages/docs/src/routes/demo/cookbook/portal/portal-provider.tsx index 6345f6899ef..58b65ab2d4c 100644 --- a/packages/docs/src/routes/demo/cookbook/portal/portal-provider.tsx +++ b/packages/docs/src/routes/demo/cookbook/portal/portal-provider.tsx @@ -11,7 +11,7 @@ import { type QRL, type Signal, type JSXOutput, -} from '@builder.io/qwik'; +} from '@qwik.dev/core'; import CSS from './portal-provider.css?inline'; // Define public API for opening up Portals diff --git a/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/index.tsx b/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/index.tsx index 35a40a0e9a4..66ae3cbe606 100644 --- a/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/index.tsx +++ b/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/index.tsx @@ -1,5 +1,5 @@ -import { component$ } from '@builder.io/qwik'; -import { Form } from '@builder.io/qwik-city'; +import { component$ } from '@qwik.dev/core'; +import { Form } from '@qwik.dev/router'; import { useCommonRouteAction, useCommonRouteLoader } from './shared/loaders'; // As mentioned, here we are re-exporting them diff --git a/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/shared/loaders.ts b/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/shared/loaders.ts index 8c0f1e17bf8..bf274c50825 100644 --- a/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/shared/loaders.ts +++ b/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/shared/loaders.ts @@ -1,4 +1,4 @@ -import { routeAction$, routeLoader$ } from '@builder.io/qwik-city'; +import { routeAction$, routeLoader$ } from '@qwik.dev/router'; export const useCommonRouteAction = routeAction$(async () => { // ... diff --git a/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/third-party/index.tsx b/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/third-party/index.tsx index ebd7e7a5556..4a28f0f6404 100644 --- a/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/third-party/index.tsx +++ b/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/third-party/index.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; import { ThirdPartyPaymentComponent } from './third-party-library'; // As mentioned, here we are re-exporting the third-party loader diff --git a/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/third-party/third-party-library.tsx b/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/third-party/third-party-library.tsx index c9b03718c3b..2c6757c9e13 100644 --- a/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/third-party/third-party-library.tsx +++ b/packages/docs/src/routes/demo/cookbook/re-exporting-loaders/third-party/third-party-library.tsx @@ -1,5 +1,5 @@ -import { component$ } from '@builder.io/qwik'; -import { routeLoader$ } from '@builder.io/qwik-city'; +import { component$ } from '@qwik.dev/core'; +import { routeLoader$ } from '@qwik.dev/router'; export const useThirdPartyPaymentLoader = routeLoader$(() => { return { name: 'John Doe' }; diff --git a/packages/docs/src/routes/demo/cookbook/streaming-deferred-loaders/index.tsx b/packages/docs/src/routes/demo/cookbook/streaming-deferred-loaders/index.tsx index 069e2e37b6b..8b9c2b0a399 100644 --- a/packages/docs/src/routes/demo/cookbook/streaming-deferred-loaders/index.tsx +++ b/packages/docs/src/routes/demo/cookbook/streaming-deferred-loaders/index.tsx @@ -1,5 +1,5 @@ -import { Resource, component$ } from '@builder.io/qwik'; -import { routeLoader$ } from '@builder.io/qwik-city'; +import { Resource, component$ } from '@qwik.dev/core'; +import { routeLoader$ } from '@qwik.dev/router'; export const useMyData = routeLoader$(() => { return async () => { diff --git a/packages/docs/src/routes/demo/cookbook/sync-event/index.tsx b/packages/docs/src/routes/demo/cookbook/sync-event/index.tsx index d3cf9049fcc..3e8303c542b 100644 --- a/packages/docs/src/routes/demo/cookbook/sync-event/index.tsx +++ b/packages/docs/src/routes/demo/cookbook/sync-event/index.tsx @@ -1,4 +1,4 @@ -import { component$, useSignal, sync$, $ } from '@builder.io/qwik'; +import { component$, useSignal, sync$, $ } from '@qwik.dev/core'; export default component$(() => { const shouldPreventDefault = useSignal(true); diff --git a/packages/docs/src/routes/demo/events/custom-event/index.tsx b/packages/docs/src/routes/demo/events/custom-event/index.tsx index 278cf252845..142657f1847 100644 --- a/packages/docs/src/routes/demo/events/custom-event/index.tsx +++ b/packages/docs/src/routes/demo/events/custom-event/index.tsx @@ -1,4 +1,4 @@ -import { component$, type QRL, Slot, useStore } from '@builder.io/qwik'; +import { component$, type QRL, Slot, useStore } from '@qwik.dev/core'; export default component$(() => { return ( diff --git a/packages/docs/src/routes/demo/events/extracted-handler/index.tsx b/packages/docs/src/routes/demo/events/extracted-handler/index.tsx index cb9a1e5beea..9d83da18609 100644 --- a/packages/docs/src/routes/demo/events/extracted-handler/index.tsx +++ b/packages/docs/src/routes/demo/events/extracted-handler/index.tsx @@ -1,4 +1,4 @@ -import { component$, useSignal, $ } from '@builder.io/qwik'; +import { component$, useSignal, $ } from '@qwik.dev/core'; export default component$(() => { const count = useSignal(0); diff --git a/packages/docs/src/routes/demo/events/global-events/index.tsx b/packages/docs/src/routes/demo/events/global-events/index.tsx index 78a489d501c..96029c7c2ea 100644 --- a/packages/docs/src/routes/demo/events/global-events/index.tsx +++ b/packages/docs/src/routes/demo/events/global-events/index.tsx @@ -1,4 +1,4 @@ -import { component$, useSignal } from '@builder.io/qwik'; +import { component$, useSignal } from '@qwik.dev/core'; export default component$(() => { const scroll = useSignal(0); diff --git a/packages/docs/src/routes/demo/events/mouse-position/index.tsx b/packages/docs/src/routes/demo/events/mouse-position/index.tsx index e617760a439..df30396f3c2 100644 --- a/packages/docs/src/routes/demo/events/mouse-position/index.tsx +++ b/packages/docs/src/routes/demo/events/mouse-position/index.tsx @@ -1,4 +1,4 @@ -import { component$, useSignal } from '@builder.io/qwik'; +import { component$, useSignal } from '@qwik.dev/core'; export default component$(() => { const position = useSignal<{ x: number; y: number }>(); diff --git a/packages/docs/src/routes/demo/events/preventdefault/index.tsx b/packages/docs/src/routes/demo/events/preventdefault/index.tsx index 74313407242..b2bdb19f792 100644 --- a/packages/docs/src/routes/demo/events/preventdefault/index.tsx +++ b/packages/docs/src/routes/demo/events/preventdefault/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/packages/docs/src/routes/demo/events/synchronous/index.tsx b/packages/docs/src/routes/demo/events/synchronous/index.tsx index 4a87f0efa3c..b67f32049c5 100644 --- a/packages/docs/src/routes/demo/events/synchronous/index.tsx +++ b/packages/docs/src/routes/demo/events/synchronous/index.tsx @@ -1,4 +1,4 @@ -import { component$, useSignal, useVisibleTask$ } from '@builder.io/qwik'; +import { component$, useSignal, useVisibleTask$ } from '@qwik.dev/core'; export default component$(() => { const draggableRef = useSignal(); diff --git a/packages/docs/src/routes/demo/events/target/index.tsx b/packages/docs/src/routes/demo/events/target/index.tsx index f4a12a58cf4..76939647da8 100644 --- a/packages/docs/src/routes/demo/events/target/index.tsx +++ b/packages/docs/src/routes/demo/events/target/index.tsx @@ -1,4 +1,4 @@ -import { component$, useSignal } from '@builder.io/qwik'; +import { component$, useSignal } from '@qwik.dev/core'; export default component$(() => { const currentElm = useSignal(null); diff --git a/packages/docs/src/routes/demo/events/use-on/index.tsx b/packages/docs/src/routes/demo/events/use-on/index.tsx index 3df7ee5703e..383c64c4435 100644 --- a/packages/docs/src/routes/demo/events/use-on/index.tsx +++ b/packages/docs/src/routes/demo/events/use-on/index.tsx @@ -1,4 +1,4 @@ -import { $, component$, useOnDocument, useStore } from '@builder.io/qwik'; +import { $, component$, useOnDocument, useStore } from '@qwik.dev/core'; // Assume reusable use method that does not have access to JSX // but needs to register event handlers. diff --git a/packages/docs/src/routes/demo/events/use-on/use-on-window/index.tsx b/packages/docs/src/routes/demo/events/use-on/use-on-window/index.tsx index 50513e64cad..5de8766a2f8 100644 --- a/packages/docs/src/routes/demo/events/use-on/use-on-window/index.tsx +++ b/packages/docs/src/routes/demo/events/use-on/use-on-window/index.tsx @@ -1,4 +1,4 @@ -import { $, component$, useOnWindow, useSignal } from '@builder.io/qwik'; +import { $, component$, useOnWindow, useSignal } from '@qwik.dev/core'; // Custom hook to manage the dropdown state. Listens to click events on the window. // If the clicked element is not the dropdown toggle button, it closes the dropdown. diff --git a/packages/docs/src/routes/demo/getting-started/01-route/index.tsx b/packages/docs/src/routes/demo/getting-started/01-route/index.tsx index 6a53f50f8a0..798102c29a6 100644 --- a/packages/docs/src/routes/demo/getting-started/01-route/index.tsx +++ b/packages/docs/src/routes/demo/getting-started/01-route/index.tsx @@ -1,4 +1,4 @@ -import { component$ } from '@builder.io/qwik'; +import { component$ } from '@qwik.dev/core'; export default component$(() => { return
A Joke!
; diff --git a/packages/docs/src/routes/demo/getting-started/02-loading-data/index.tsx b/packages/docs/src/routes/demo/getting-started/02-loading-data/index.tsx index 741b25cf79d..6d54671654f 100644 --- a/packages/docs/src/routes/demo/getting-started/02-loading-data/index.tsx +++ b/packages/docs/src/routes/demo/getting-started/02-loading-data/index.tsx @@ -1,5 +1,5 @@ -import { component$ } from '@builder.io/qwik'; -import { routeLoader$ } from '@builder.io/qwik-city'; +import { component$ } from '@qwik.dev/core'; +import { routeLoader$ } from '@qwik.dev/router'; export const useDadJoke = routeLoader$(async () => { const response = await fetch('https://icanhazdadjoke.com/', { diff --git a/packages/docs/src/routes/demo/getting-started/03-posting-data/index.tsx b/packages/docs/src/routes/demo/getting-started/03-posting-data/index.tsx index b673148db7d..72bb62e64ca 100644 --- a/packages/docs/src/routes/demo/getting-started/03-posting-data/index.tsx +++ b/packages/docs/src/routes/demo/getting-started/03-posting-data/index.tsx @@ -1,5 +1,5 @@ -import { component$ } from '@builder.io/qwik'; -import { routeLoader$, Form, routeAction$ } from '@builder.io/qwik-city'; +import { component$ } from '@qwik.dev/core'; +import { Form, routeAction$, routeLoader$ } from '@qwik.dev/router'; export const useDadJoke = routeLoader$(async () => { const response = await fetch('https://icanhazdadjoke.com/', { diff --git a/packages/docs/src/routes/demo/getting-started/04-state/index.tsx b/packages/docs/src/routes/demo/getting-started/04-state/index.tsx index df9e492806f..b182b1970fb 100644 --- a/packages/docs/src/routes/demo/getting-started/04-state/index.tsx +++ b/packages/docs/src/routes/demo/getting-started/04-state/index.tsx @@ -1,5 +1,5 @@ -import { component$, useSignal } from '@builder.io/qwik'; -import { routeLoader$, Form, routeAction$ } from '@builder.io/qwik-city'; +import { component$, useSignal } from '@qwik.dev/core'; +import { Form, routeAction$, routeLoader$ } from '@qwik.dev/router'; export const useDadJoke = routeLoader$(async () => { const response = await fetch('https://icanhazdadjoke.com/', { diff --git a/packages/docs/src/routes/demo/getting-started/05-tasks/index.tsx b/packages/docs/src/routes/demo/getting-started/05-tasks/index.tsx index bf30c4a698d..5cff8fdefce 100644 --- a/packages/docs/src/routes/demo/getting-started/05-tasks/index.tsx +++ b/packages/docs/src/routes/demo/getting-started/05-tasks/index.tsx @@ -1,10 +1,5 @@ -import { component$, useSignal, useTask$ } from '@builder.io/qwik'; -import { - routeLoader$, - Form, - routeAction$, - server$, -} from '@builder.io/qwik-city'; +import { component$, useSignal, useTask$ } from '@qwik.dev/core'; +import { Form, routeAction$, routeLoader$, server$ } from '@qwik.dev/router'; export const useDadJoke = routeLoader$(async () => { const response = await fetch('https://icanhazdadjoke.com/', { diff --git a/packages/docs/src/routes/demo/getting-started/06-styling/index.tsx b/packages/docs/src/routes/demo/getting-started/06-styling/index.tsx index 7e20073d6f1..4ce7c9a585a 100644 --- a/packages/docs/src/routes/demo/getting-started/06-styling/index.tsx +++ b/packages/docs/src/routes/demo/getting-started/06-styling/index.tsx @@ -3,13 +3,8 @@ import { useSignal, useStylesScoped$, useTask$, -} from '@builder.io/qwik'; -import { - routeLoader$, - Form, - routeAction$, - server$, -} from '@builder.io/qwik-city'; +} from '@qwik.dev/core'; +import { Form, routeAction$, routeLoader$, server$ } from '@qwik.dev/router'; import styles from './index.css?inline'; export const useDadJoke = routeLoader$(async () => { diff --git a/packages/docs/src/routes/demo/integration/img/qwik-image/index.tsx b/packages/docs/src/routes/demo/integration/img/qwik-image/index.tsx index d26ffcc0c72..dd7fffc77f9 100644 --- a/packages/docs/src/routes/demo/integration/img/qwik-image/index.tsx +++ b/packages/docs/src/routes/demo/integration/img/qwik-image/index.tsx @@ -1,4 +1,4 @@ -import { $, component$ } from '@builder.io/qwik'; +import { $, component$ } from '@qwik.dev/core'; import { Image, type ImageTransformerProps, diff --git a/packages/docs/src/routes/demo/integration/img/unpic/simple/index.tsx b/packages/docs/src/routes/demo/integration/img/unpic/simple/index.tsx deleted file mode 100644 index 915a2aa213e..00000000000 --- a/packages/docs/src/routes/demo/integration/img/unpic/simple/index.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { component$ } from '@builder.io/qwik'; -import { Image } from '@unpic/qwik'; - -export default component$(() => { - return ( - A lovely bath - ); -}); diff --git a/packages/docs/src/routes/demo/integration/modular-forms/index.tsx b/packages/docs/src/routes/demo/integration/modular-forms/index.tsx index 96d6b110c25..046495f2943 100644 --- a/packages/docs/src/routes/demo/integration/modular-forms/index.tsx +++ b/packages/docs/src/routes/demo/integration/modular-forms/index.tsx @@ -1,9 +1,9 @@ // @ts-nocheck /* eslint-disable @typescript-eslint/no-unused-vars */ -import { $, component$, type QRL } from '@builder.io/qwik'; -import { routeLoader$ } from '@builder.io/qwik-city'; import type { InitialValues, SubmitHandler } from '@modular-forms/qwik'; import { formAction$, useForm, valiForm$ } from '@modular-forms/qwik'; +import { $, component$, type QRL } from '@qwik.dev/core'; +import { routeLoader$ } from '@qwik.dev/router'; import * as v from 'valibot'; const LoginSchema = v.object({ diff --git a/packages/docs/src/routes/demo/layout.tsx b/packages/docs/src/routes/demo/layout.tsx index 7e1dadaef6c..200efacd5b3 100644 --- a/packages/docs/src/routes/demo/layout.tsx +++ b/packages/docs/src/routes/demo/layout.tsx @@ -1,6 +1,6 @@ /* eslint-disable no-console */ -import { component$, Slot } from '@builder.io/qwik'; -import { useStyles$ } from '@builder.io/qwik'; +import { component$, Slot } from '@qwik.dev/core'; +import { useStyles$ } from '@qwik.dev/core'; import STYLES from './demo-reset.css?inline'; export default component$(() => { diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/basePathname/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/basePathname/index.tsx deleted file mode 100644 index 4aa53db4581..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/basePathname/index.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async ({ basePathname, json }) => { - json(200, { basePathname }); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/cacheControl/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/cacheControl/index.tsx deleted file mode 100644 index 4a810521325..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/cacheControl/index.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -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/qwikcity/middleware/component/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/component/index.tsx deleted file mode 100644 index ea408259580..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/component/index.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { component$ } from '@builder.io/qwik'; -import { type RequestHandler } from '@builder.io/qwik-city'; - -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/qwikcity/middleware/cookie/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/cookie/index.tsx deleted file mode 100644 index 6b4d475f9ed..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/cookie/index.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -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/qwikcity/middleware/env/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/env/index.tsx deleted file mode 100644 index 652cb22ec37..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/env/index.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -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/qwikcity/middleware/error/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/error/index.tsx deleted file mode 100644 index 6c143429984..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/error/index.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async ({ error }) => { - throw error(500, 'ERROR: Demonstration of an error response.'); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/exit/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/exit/index.tsx deleted file mode 100644 index f9ba76eb886..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/exit/index.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async ({ exit }) => { - throw exit(); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/getWritableStream/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/getWritableStream/index.tsx deleted file mode 100644 index 2fb3aaeb186..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/getWritableStream/index.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import type { RequestHandler } from '@builder.io/qwik-city'; - -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/qwikcity/middleware/headerSent/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/headerSent/index.tsx deleted file mode 100644 index ff3cc0a72b5..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/headerSent/index.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -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/qwikcity/middleware/headers/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/headers/index.tsx deleted file mode 100644 index 8822cef27d9..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/headers/index.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -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/qwikcity/middleware/html/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/html/index.tsx deleted file mode 100644 index 07e2de5e39c..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/html/index.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async ({ html }) => { - html( - 200, - ` - - -

HTML response

- - ` - ); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/json/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/json/index.tsx deleted file mode 100644 index f56d4509ad6..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/json/index.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async ({ json }) => { - json(200, { hello: 'world' }); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/layout.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/layout.tsx deleted file mode 100644 index 84b09612e89..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/layout.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onRequest: RequestHandler = async ({ next }) => { - try { - await next(); - } catch (error) { - if ( - error && - typeof error === 'object' && - 'message' in error && - typeof error.message === 'string' && - error.message == 'ERROR: Demonstration of an error response.' - ) { - // ignore this error - return; - } - throw error; - } -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/locale/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/locale/index.tsx deleted file mode 100644 index 7639872db54..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/locale/index.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -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/qwikcity/middleware/method/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/method/index.tsx deleted file mode 100644 index a8f48e72538..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/method/index.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onRequest: RequestHandler = async ({ method, json }) => { - json(200, { method }); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/next/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/next/index.tsx deleted file mode 100644 index 8b3080beaea..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/next/index.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -// 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/qwikcity/middleware/params/[myId]/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/params/[myId]/index.tsx deleted file mode 100644 index 9483b9068b1..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/params/[myId]/index.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -export const onGet: RequestHandler = async ({ params, json }) => { - json(200, { params }); -}; diff --git a/packages/docs/src/routes/demo/qwikcity/middleware/parseBody/index.tsx b/packages/docs/src/routes/demo/qwikcity/middleware/parseBody/index.tsx deleted file mode 100644 index 46bc86e597e..00000000000 --- a/packages/docs/src/routes/demo/qwikcity/middleware/parseBody/index.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { type RequestHandler } from '@builder.io/qwik-city'; - -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/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..b5e20630acf --- /dev/null +++ b/packages/docs/src/routes/demo/qwikrouter/middleware/layout.tsx @@ -0,0 +1,19 @@ +import { type RequestHandler } from '@qwik.dev/router'; + +export const onRequest: RequestHandler = async ({ next }) => { + try { + await next(); + } catch (error) { + if ( + error && + typeof error === 'object' && + 'message' in error && + typeof error.message === 'string' && + error.message == 'ERROR: Demonstration of an error response.' + ) { + // 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 d836e53327f..ca2d3144dd7 100644 --- a/packages/docs/src/routes/demo/react/children/react.tsx +++ b/packages/docs/src/routes/demo/react/children/react.tsx @@ -1,6 +1,6 @@ /** @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 fbbc042beaa..7c38cb090ba 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,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-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 c1f9497425e..66076e2a446 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,5 +1,5 @@ /** @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 797056215bd..ffe659299ef 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,5 +1,5 @@ /** @jsxImportSource react */ -import { qwikify$ } from '@builder.io/qwik-react'; +import { qwikify$ } from '@qwik.dev/react'; function Button({ onClick }: { onClick: () => void }) { console.log('React
@@ -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 6db212704ac..00000000000 --- a/packages/docs/src/routes/docs/(qwikcity)/advanced/content-security-policy/index.mdx +++ /dev/null @@ -1,123 +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/build"; - -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("; ")); -}; -``` - -### Add it to the service worker as well - -```tsx {12,22} /nonce/ title="src/root.ts" -import { component$, useServerData } from "@builder.io/qwik"; -import { - QwikCityProvider, - RouterOutlet, - ServiceWorkerRegister, -} from "@builder.io/qwik-city"; -import { RouterHead } from "./components/router-head/router-head"; -import { isDev } from "@builder.io/qwik/build"; - -import "./global.css"; - -export default component$(() => { - const nonce = useServerData("nonce"); - return ( - - - - {!isDev && } - - - - - - {!isDev && } - - - ); -}); -``` - -### 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 e10ca2aae61..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 hirarchy 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 browers 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)/advanced/speculative-module-fetching/index.mdx b/packages/docs/src/routes/docs/(qwikcity)/advanced/speculative-module-fetching/index.mdx deleted file mode 100644 index 7bd9ed28371..00000000000 --- a/packages/docs/src/routes/docs/(qwikcity)/advanced/speculative-module-fetching/index.mdx +++ /dev/null @@ -1,199 +0,0 @@ ---- -title: Speculative Module Fetching | Advanced -description: Learn how Qwik handles loading bundles in the background and filling the cache with Speculative Module Fetching. -contributors: - - ulic75 - - mhevery - - adamdbradley - - hamatoyogi - - manucorporat - - mrhoodz - - thejackshelton - - zanettin - - wtlin1228 - - aendel - - jemsco -updated_at: '2023-06-25T19:43:33Z' -created_at: '2023-03-20T23:45:13Z' ---- - -# Speculative Module Fetching - -Qwik is able to load a page and become interactive extremely fast due to its ability to startup _without_ JavaScript. In addition to this, Speculative Module Fetching is a powerful feature that allows Qwik to pre-populate the browser's cache in a background thread. - -Qwik's goal is to optimize loading by caching only the necessary parts of the application based on potential user interactions. It avoids loading unnecessary bundles by understanding which interactions are not possible. - -- [Pre-populating the Cache with a Service Worker](#pre-populating-the-cache-with-a-service-worker) -- [Caching Request and Response Pairs](#caching-request-and-response-pairs) -- [Parallelizing Network Requests](#parallelizing-network-requests) - -### Pre-populating the Cache - -Each page load will pre-populate the cache with bundles that _could_ be executed on the page by the user at that moment. For example, let's say that the page has a click listener on a button. When the page loads, the service worker's first job is to ensure the code for that click listener is already in the [cache](#cache-api). When the user clicks the button, Qwik makes a request to the event listener's function and any code dependencies to execute that function. The goal is for the code to already be in the [browser's cache](https://developer.mozilla.org/en-US/docs/Web/API/Cache) ready to execute. - -The initial page load prepares the cache for the next probable interaction and also downloads other necessary code incrementally in a separate thread. When a follow-up interaction happens, such as opening a modal or menu, Qwik will emit another event with additional code that could be used since the last interaction. Pre-populating the cache happens continuously as users interact with the application. - -### Pre-populate Cache Event - -The recommended strategy is to use a [service worker](#pre-populating-the-cache-with-a-service-worker) to populate the [browser's cache](https://developer.mozilla.org/en-US/docs/Web/API/Cache). The Qwik framework itself should use the [prefetchEvent](../../../(qwik)/advanced/modules-prefetching/index.mdx#implementation) implementation, which is already the default. - -## Pre-populating the Cache with a Service Worker - -Traditionally, a service worker is used to cache most or all of the bundles that an application uses. [Service workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers) are commonly seen only as a way to make an application work offline. - -Qwik City uses service workers quite differently to provide a powerful caching strategy. Instead of downloading the entire application, the goal is to use the service worker to dynamically pre-populate the cache with what's _possible_ to execute. By _not_ downloading the entire application, resources are freed up, enabling users to request only the necessary parts they _could_ use to complete their current task on the screen. - -Additionally, the service worker will automatically add listeners for these events emitted from Qwik. - -### Background Task - -An advantage of using a service worker is that it's also an extension of a [worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API), which runs in a background thread. - -> Web Workers makes it possible to run a script operation in a background thread separate from the main execution thread of a web application. The advantage of this is that laborious processing can be performed in a separate thread, allowing the main (usually the UI) thread to run without being blocked/slowed down. - -By pre-populating the cache from within a service worker (which is a worker), we're able to essentially run the code in a background task, in order to not interfere with the main UI thread. By not interfering with the main thread, we can enhance the performance of the Qwik application for users. - -### Interactively Pre-populating the Cache - -Qwik itself should be configured to use the [prefetchEvent](../../../(qwik)/advanced/modules-prefetching/index.mdx#implementation) implementation. This is the default. When Qwik emits the event, the service worker registration actively forwards the event data to the installed and active service worker. - -Running in a background thread, the service worker then fetches the modules and adds them to the browser’s [Cache](https://developer.mozilla.org/en-US/docs/Web/API/Cache). The main thread only needs to emit data about the required bundles, while the service worker’s sole focus is to cache those bundles. - -1. If the browser already has it cached? Great, do nothing! -2. If the browser hasn't already cached this bundle, then let's kick off the fetch request. - -> The service worker ensures that multiple requests for the same bundle [do not happen at the same time](#avoiding-duplicate-requests). - -## Caching Request and Response Pairs - -In many traditional frameworks, the preferred strategy is to use the html `` tag with a `rel` attribute set to `prefetch`, `preload` or `modulepreload`. However, due to [known issues](../../../(qwik)/advanced/modules-prefetching/index.mdx#link-rel) Qwik avoids using this approach as the default prefetching strategy, it can still be [configured](../../../(qwik)/advanced/modules-prefetching/index.mdx) if required. - -Instead, Qwik prefers to use a newer approach that takes full advantage of the browser's [Cache API](https://developer.mozilla.org/en-US/docs/Web/API/Cache), which is better supported compared to [modulepreload](../../../(qwik)/advanced/modules-prefetching/index.mdx#link-rel). - -### Cache API - -The [Cache API](https://developer.mozilla.org/en-US/docs/Web/API/Cache), often associated with service workers, is a way to store request and response pairs in order for an application to work offline. In addition to enabling applications to work without connectivity, the same Cache API provides an extremely powerful caching mechanism available to Qwik. - -Using the installed and activated [service worker](#pre-populating-the-cache-with-a-service-worker) to intercept requests, Qwik is able to handle specific requests for _known_ bundles. In contrast to the common way service workers are used, the default does not attempt to handle all requests, only known bundles generated by Qwik. The site's installed service worker can still be [customized by each site](#user-service-worker-code). - -An advantage of Qwik's optimizer is that it generates a `q-manifest.json` file. The `q-manifest.json` includes a detailed module graph of how bundles are associated and which symbols are within each bundle. This same module graph data is provided to the service worker allowing for every network request for known bundles to be handled by the cache. - -### Dynamic Imports and Caching - -When Qwik requests a module it uses a dynamic `import()`. For example, let's say a user interaction happened, requiring Qwik to execute a dynamic import for `/build/q-abc.js`. The code to do so would look something like this: - -```ts -const module = await import('/build/q-abc.js'); -``` - -What's important here is that Qwik itself has no knowledge of a prefetching or caching strategy. It's simply making a request for a URL. However, because we've installed a service worker, and the service worker is intercepting requests, it's able to inspect the URL and say, "look, this is a request for `/build/q-abc.js`! This is one of our bundles! Let's first check to see if we already have this in the cache before we do an actual network request." - -This is the power of the service worker and Cache API! In another thread, Qwik pre-populates the cache for modules the user may soon request. If these modules are already cached, then the browser doesn't need to do anything. - -## Parallelizing Network Requests - -In the [Caching Request and Response Pairs](#cache-api) docs we explained the powerful combination of the [Cache](https://developer.mozilla.org/en-US/docs/Web/API/Cache) and [Service Worker](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker) APIs. However, in Qwik, we can go further by ensuring that duplicate requests are not created for the same bundle and prevent network waterfalls, all from within the background thread. - -### Avoiding Duplicate Requests - -As an example, let's say an end-user currently has a very slow connection. When they first request the landing page, the device downloads the HTML and renders the content (an area where Qwik really shines). On this slow connection, it'd be a shame if users had to download several hundred more kilobytes just to [make their app work and become interactive](https://www.builder.io/blog/hydration-is-pure-overhead). - -However, because the app was built with Qwik, the end-user doesn't need to download the entire application for it to become interactive. Instead, the end-user already downloaded the SSR rendered HTML app, and any interactive parts, such as an "Add to cart" button, can be prefetched immediately. - -> Note that we're only prefetching the actual listener code, and _not_ the entire stack of the component tree render functions. - -In this extremely common real-world example of a device with a slow connection, the device immediately starts to pre-populate the cache for the possible interactions that are visible by the end-user. However, due to their slow connection, even though we started to cache the modules as soon as possible in a [background thread](#background-task), the fetch request itself could still be in flight. - -For demo purposes, let's say the fetching for this bundle takes two seconds. However, after one second of viewing the page, the user clicks on the button. - -In a traditional framework, there's a good chance that absolutely nothing would happen! The event listener can't be added to the button yet if the framework hasn't finished downloading, hydrating and re-rendering. This means that the user's interaction would just be lost. - -With Qwik's caching strategy, if a user clicks a button and we already initiated a request one second earlier, with only one second remaining until it's fully received, then the end-user only needs to wait for that one second. Remember, they're on a slow connection in this demo. Luckily the user already received the fully rendered landing page and are already looking at a completed page. Next, they're only pre-populating the cache with the parts of the app they could interact with, and their slow connection is dedicated to just those bundle(s). This is in contrast to their slow connection downloading all of the app, just to execute one listener. - -Qwik can intercept requests for known bundles. If a fetch is in flight in a background thread and a user requests the same bundle, it'll ensure that the second request is able to re-use the same bundle, which may already be done downloading. Trying to perform any of this with the [link](../../../(qwik)/advanced/modules-prefetching/index.mdx#link-rel) also shows why Qwik preferred to use the caching API and intercepts requests with a service worker as the default instead of using [link](../../../(qwik)/advanced/modules-prefetching/index.mdx#link-rel). - -### Reducing Network Waterfalls - -A network waterfall occurs when multiple requests are made sequentially, one after another. This sequential process can degrade performance significantly since the time to download all necessary modules is extended, compared to a scenario where all modules begin downloading at the same time in parallel. - -Below is an example with three modules: A, B and C. Module A imports B, and B imports C. The HTML document is what starts the waterfall by first requesting Module A. - -```ts -import './b.js'; -console.log('Module A'); -``` - -```ts -import './c.js'; -console.log('Module B'); -``` - -```ts -console.log('Module C'); -``` - -```html - -``` - -In this example, when Module `A` is first requested, the browser has no idea that it should also start requesting Module `B` and `C`. It doesn't even know it needs to start requesting Module `B`, until AFTER Module `A` has finished downloading. It's a common problem in that the browser doesn't know ahead of time what it should start to request, until after each module has finished downloading. - -However, because our service worker contains a module graph generated from the manifest, we do know all of the modules which _will_ be requested next. So when either user interaction or a prefetch for a bundle happens, the browser initiates the request for all of the bundles that _will_ be requested. This allows us to drastically reduce the time it takes to request all bundles. - -## User Service Worker Code - -The default service worker that is installed by Qwik City can still be controlled entirely by the application. For example, the source file `src/routes/service-worker.ts` becomes `/service-worker.js`, which is the script requested by the browser. Notice how its place within `src/routes` still follows the same directory-based routing pattern. - -Below is an example of a default `src/routes/service-worker.ts` source file: - -```ts -import { setupServiceWorker } from '@builder.io/qwik-city/service-worker'; - -setupServiceWorker(); - -addEventListener('install', () => self.skipWaiting()); - -addEventListener('activate', (ev) => ev.waitUntil(self.clients.claim())); -``` - -The source code for `src/routes/service-worker.ts` can be modified which includes opting-in, or opting-out, of setting up Qwik City's service worker. - -Notice that the `setupServiceWorker()` function is imported from `@builder.io/qwik-city/service-worker` and executed at the top of the source file. Developers have the flexibility to modify when and where this function is called according to their needs. For example, if a developer prefers to handle fetch requests first, they can add their fetch listener above the `setupServiceWorker()`. Or if they didn't want to use Qwik City's service worker at all, they would just remove `setupServiceWorker()` from the file. - -Additionally, the default `src/routes/service-worker.ts` file comes with an [install](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/install_event) and [activate](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/activate_event) event listeners, each added at the bottom of the file. The callbacks provided are the recommended callbacks. However, the developer can modify these callbacks depending on their own app's requirements. - -Another important note is that Qwik City's request intercepting is _only_ for Qwik bundles, it does not attempt to handle any requests which are not a part of its build. - -So while Qwik City does provide a way to help prefetch and cache bundles, it does not take full control of the app's service worker. This still allows developers to add their service worker logic without conflicting with Qwik. - -## Disabled During Development - -Speculative module fetching only kicks in preview or on a production build. In development, the service worker is disabled which also disables speculative module fetching. This is because during development we want to always ensure the latest development code is being used, rather than what's been previously cached. - - -### HTTP Cache vs. Service Worker Cache - -Speculative module fetching may not appear to be working partly due to the various levels of caching. For example, the browser itself may cache requests in its [HTTP cache](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching), and the service worker may cache requests in the [Cache API](https://developer.mozilla.org/en-US/docs/Web/API/Cache). Just emptying one of the caches may not be enough to see the effects of speculative module fetching. - -### Misleading Empty Cache and Hard Reload - -When developers run [Empty Cache and Hard Reload](https://developer.chrome.com/blog/hard-reload/), it's a bit misleading because it actually _only_ empties the browser's HTTP cache. It's not, however, emptying the service worker's cache. Even though the browser's HTTP cache is empty, the service worker still has the previous cached requests. - -Additionally, when "Empty Cache and Hard Reload" is used, the browser sends a `no-cache` cache-control header in the _request_ to the server. Because the request has a `no-cache` cache-control header, the service worker purposely does not use its own cache, and instead the browser performs the usual HTTP fetch again. - -### Emptying the Service Worker Cache - -The recommended way to test speculative module fetching is to: - -- **Unregister the service worker**: In Chrome DevTools, go to the Application tab, and under Service Workers, click the "Unregister" link for the for your site's service worker. -- **Delete the "QwikBuild" Cache Storage**: In Chrome DevTools, go to the Application tab, and under Cache Storage on the left side, right click "Delete" on the "QwikBuild" cache storage. -- **Do not hard reload**: Instead of hard reloading, which would send a no-cache cache-control to the service worker, just click the URL bar and hit enter. This will send a normal request as if you were a first time visitor. - -Note that this process is only for testing the speculative module fetching, and is not required for new builds. Each build will create a new service worker, and the old service worker will be automatically unregistered. - -### Debug Mode - -The service worker in Qwik core, which uses the `` and `` components in `root.tsx` has a debug mode. - -To see the service worker logs, add `window.qwikPrefetchSW.push(['verbose', '', []])` to the JavaScript console and press the `Enter` key. - 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 9df224ecbe1..00000000000 --- a/packages/docs/src/routes/docs/(qwikcity)/api/index.mdx +++ /dev/null @@ -1,493 +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/components/prefetch.unit.tsx b/packages/qwik/src/core/components/prefetch.unit.tsx deleted file mode 100644 index cc33e76b1bb..00000000000 --- a/packages/qwik/src/core/components/prefetch.unit.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import { describe, expect, it } from 'vitest'; -import { PrefetchServiceWorker, PrefetchGraph } from './prefetch'; -import { renderToString } from '../../server/render'; - -const DEBUG = false; -function log(...args: any[]) { - if (DEBUG) { - // eslint-disable-next-line no-console - console.log(...args); - } -} - -describe('PrefetchServiceWorker', () => { - describe('render', () => { - it('should render', async () => { - const output = await renderToString(, { containerTagName: 'div' }); - log('>>>>', output.html); - }); - - it('should render with a nonce', async () => { - const output = await renderToString(, { - containerTagName: 'div', - }); - expect(output.html).to.contain(' - ` - ); - - assert.deepEqual(JSON.parse(script.textContent!), { - refs: { - '1': '1 2 f o 8 i 7 6 k! o l 0 n', - }, - ctx: {}, - objs: [ - '\u0012j', - 1, - 'hola', - 12, - { - thing: '3', - }, - 123, - false, - true, - null, - 'string', - { - hola: '1', - }, - 'hello', - ['b'], - ['1', '9', '6', 'a', 'c'], - '\u0010/runtimeQRL#_', - { - a: '4', - b: '2', - c: '5', - d: '6', - e: '7', - f: '8', - g: 'o', - h: 'd', - i: 'e', - }, - 2, - {}, - ['1', 'g', '2', 'h'], - 0, - { - count: 'j', - }, - '\u0002/runtimeQRL#_', - 'ok', - '\u0012m', - '\u0001', - ], - subs: [['4 #0 0 #2']], - }); -}); - -export const LexicalScope_render = () => { - const [a, b, c, d, e, f, g, h, state, noserialize] = useLexicalScope(); - return ( -
-

{JSON.stringify(a)}

-

{JSON.stringify(b)}

-

{JSON.stringify(c)}

-

{String(d)}

-

{String(e)}

-

{JSON.stringify(f)}

-

{JSON.stringify(g)}

-

{JSON.stringify(h)}

-

{noserialize.text}

- -
- ); -}; - -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..c611a5f8a61 --- /dev/null +++ b/packages/qwik/src/core/debug.ts @@ -0,0 +1,95 @@ +import { isQrl } from '../server/prefetch-strategy'; +import { isJSXNode } from './shared/jsx/jsx-runtime'; +import { isTask } from './use/use-task'; +import { vnode_getProp, vnode_isVNode } from './client/vnode'; +import { ComputedSignal, WrappedSignal, isSignal } from './signal/signal'; +import { isStore } from './signal/store'; +import { DEBUG_TYPE } from './shared/types'; + +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 WrappedSignal) { + return 'WrappedSignal'; + } else if (value instanceof ComputedSignal) { + 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 type = value.type; + if (typeof type === 'function') { + type = type.name || 'Component'; + } + 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 e3bb1fe01de..9ae8ab7acf2 100644 --- a/packages/qwik/src/core/index.ts +++ b/packages/qwik/src/core/index.ts @@ -1,17 +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 '@qwik.dev/core/build'; ////////////////////////////////////////////////////////////////////////////////////////// // Developer Event API @@ -22,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, @@ -66,73 +69,85 @@ 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, +} 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 } from './use/use-computed'; +export { useComputedQrl } from './use/use-computed'; +export type { OnVisibleTaskOptions, VisibleTaskStrategy } from './use/use-visible-task'; +export { useVisibleTaskQrl } from './use/use-visible-task'; +export type { EagernessOptions, TaskCtx, TaskFn, Tracker, UseTaskOptions } 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-dollar'; 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 './signal/signal.public'; +export { isSignal, createSignal, createComputedQrl, createComputed$ } from './signal/signal.public'; +export { EffectPropData as _EffectData } from './signal/signal'; ////////////////////////////////////////////////////////////////////////////////////////// // 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 { 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, @@ -165,12 +180,12 @@ export type { QwikUIEvent, QwikWheelEvent, QwikTransitionEvent, -} 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..d173f70544b 100644 --- a/packages/qwik/src/core/internal.ts +++ b/packages/qwik/src/core/internal.ts @@ -1,18 +1,38 @@ -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'; +export { _walkJSX } from './ssr/ssr-render-jsx'; +export { _SharedContainer } from './shared/shared-container'; +export { _hW } from './use/use-task'; +export { _wrapSignal, _wrapProp } from './signal/signal-utils'; +export { _restProps } from './shared/utils/prop'; +export { _IMMUTABLE } from './shared/utils/constants'; +export { _CONST_PROPS, _VAR_PROPS } from './shared/utils/constants'; +export { _weakSerialize } from './shared/utils/serialize-utils'; +export { verifySerializable as _verifySerializable } from './shared/utils/serialize-utils'; 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 { _jsxSorted, _jsxSplit, isJSXNode as _isJSXNode } from './shared/jsx/jsx-runtime'; +export { _fnSignal } from './shared/qrl/inlined-fn'; +export type { + ContainerElement as _ContainerElement, + VNode as _VNode, + VNodeFlags as _VNodeFlags, + VirtualVNode as _VirtualVNode, + TextVNode as _TextVNode, + QDocument as _QDocument, + ElementVNode as _ElementVNode, +} from './client/types'; +export { + isStringifiable as _isStringifiable, + type Stringifiable as _Stringifiable, +} from './shared-types'; +export { + DomContainer as _DomContainer, + getDomContainer as _getDomContainer, +} from './client/dom-container'; +export { EMPTY_ARRAY as _EMPTY_ARRAY } from './shared/utils/flyweight'; +export { _serialize, _deserialize } from './shared/shared-serialization'; +export { _jsxQ, _jsxC, _jsxS } from './shared/jsx/jsx-runtime'; 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/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.ts b/packages/qwik/src/core/qrl/qrl.ts deleted file mode 100644 index fbb7b00217b..00000000000 --- a/packages/qwik/src/core/qrl/qrl.ts +++ /dev/null @@ -1,301 +0,0 @@ -import { EMPTY_ARRAY } from '../util/flyweight'; -import type { QRL } from './qrl.public'; -import { - assertQrl, - createQRL, - emitEvent, - getSymbolHash, - isSyncQrl, - type QRLInternal, -} from './qrl-class'; -import { isFunction, isString } from '../util/types'; -import { - qError, - QError_dynamicImportFailed, - QError_qrlMissingChunk, - QError_unknownTypeArgument, -} from '../error/error'; -import { qRuntimeQrl, qSerialize } from '../util/qdev'; -import { getPlatform } from '../platform/platform'; -import { assertDefined, assertTrue, assertElement } from '../error/assert'; -import type { ContainerState, MustGetObjID } from '../container/container'; -import type { QContext } from '../state/context'; -import { mapJoin } from '../container/pause'; -import { throwErrorAndStop } from '../util/log'; - -// https://regexr.com/68v72 -const EXTRACT_IMPORT_PATH = /\(\s*(['"])([^\1]+)\1\s*\)/; - -// https://regexr.com/690ds -const EXTRACT_SELF_IMPORT = /Promise\s*\.\s*resolve/; - -// https://regexr.com/6a83h -const EXTRACT_FILE_NAME = /[\\/(]([\w\d.\-_]+\.(js|ts)x?):/; - -const announcedQRL = /*#__PURE__*/ new Set(); - -/** @public */ -export interface QRLDev { - file: string; - lo: number; - hi: number; -} - -// -// !!DO NOT EDIT THIS COMMENT DIRECTLY!!! -// (edit ../readme.md#qrl instead) -/** - * Used by Qwik Optimizer to point to lazy-loaded resources. - * - * This function should be used by the Qwik Optimizer only. The function should not be directly - * referred to in the source code of the application. - * - * @param chunkOrFn - Chunk name (or function which is stringified to extract chunk name) - * @param symbol - Symbol to lazy load - * @param lexicalScopeCapture - A set of lexically scoped variables to capture. - * @public - * @see `QRL`, `$(...)` - */ -// -export const qrl = ( - chunkOrFn: string | (() => Promise), - symbol: string, - lexicalScopeCapture: any[] = EMPTY_ARRAY, - stackOffset = 0 -): QRL => { - let chunk: string | null = null; - let symbolFn: null | (() => Promise>) = null; - if (isFunction(chunkOrFn)) { - symbolFn = chunkOrFn; - if (qSerialize) { - let match: RegExpMatchArray | null; - const srcCode = String(chunkOrFn); - if ((match = srcCode.match(EXTRACT_IMPORT_PATH)) && match[2]) { - chunk = match[2]; - } else if ((match = srcCode.match(EXTRACT_SELF_IMPORT))) { - const ref = 'QWIK-SELF'; - const frames = new Error(ref).stack!.split('\n'); - const start = frames.findIndex((f) => f.includes(ref)); - const frame = frames[start + 2 + stackOffset]; - match = frame.match(EXTRACT_FILE_NAME); - if (!match) { - chunk = 'main'; - } else { - chunk = match[1]; - } - } else { - throw qError(QError_dynamicImportFailed, srcCode); - } - } - } else if (isString(chunkOrFn)) { - chunk = chunkOrFn; - } else { - throw qError(QError_unknownTypeArgument, chunkOrFn); - } - - if (!announcedQRL.has(symbol)) { - // Emit event - announcedQRL.add(symbol); - emitEvent('qprefetch', { - symbols: [getSymbolHash(symbol)], - bundles: chunk && [chunk], - }); - } - - // Unwrap subscribers - return createQRL(chunk, symbol, null, symbolFn, null, lexicalScopeCapture, null); -}; - -/** @internal */ -export const inlinedQrl = ( - symbol: T, - symbolName: string, - lexicalScopeCapture: any[] = EMPTY_ARRAY -): QRL => { - // Unwrap subscribers - return createQRL(null, symbolName, symbol, null, null, lexicalScopeCapture, null); -}; - -/** @internal */ -export const _noopQrl = ( - symbolName: string, - lexicalScopeCapture: any[] = EMPTY_ARRAY -): QRL => { - return createQRL(null, symbolName, null, null, null, lexicalScopeCapture, null); -}; - -/** @internal */ -export const _noopQrlDEV = ( - symbolName: string, - opts: QRLDev, - lexicalScopeCapture: any[] = EMPTY_ARRAY -): QRL => { - const newQrl = _noopQrl(symbolName, lexicalScopeCapture) as QRLInternal; - newQrl.dev = opts; - return newQrl; -}; - -/** @internal */ -export const qrlDEV = ( - chunkOrFn: string | (() => Promise), - symbol: string, - opts: QRLDev, - lexicalScopeCapture: any[] = EMPTY_ARRAY -): QRL => { - const newQrl = qrl(chunkOrFn, symbol, lexicalScopeCapture, 1) as QRLInternal; - newQrl.dev = opts; - return newQrl; -}; - -/** @internal */ -export const inlinedQrlDEV = ( - symbol: T, - symbolName: string, - opts: QRLDev, - lexicalScopeCapture: any[] = EMPTY_ARRAY -): QRL => { - const qrl = inlinedQrl(symbol, symbolName, lexicalScopeCapture) as QRLInternal; - qrl.dev = opts; - return qrl; -}; - -export interface QRLSerializeOptions { - $getObjId$?: MustGetObjID; - $addRefMap$?: (obj: any) => string; - $containerState$?: ContainerState; -} - -export const serializeQRL = (qrl: QRLInternal, opts: QRLSerializeOptions = {}) => { - assertTrue(qSerialize, 'In order to serialize a QRL, qSerialize must be true'); - assertQrl(qrl); - let symbol = qrl.$symbol$; - let chunk = qrl.$chunk$; - const refSymbol = qrl.$refSymbol$ ?? symbol; - const platform = getPlatform(); - - if (platform) { - const result = platform.chunkForSymbol(refSymbol, chunk, qrl.dev?.file); - if (result) { - chunk = result[1]; - if (!qrl.$refSymbol$) { - symbol = result[0]; - } - } else { - console.error('serializeQRL: Cannot resolve symbol', symbol, 'in', chunk, qrl.dev?.file); - } - } - - if (qRuntimeQrl && chunk == null) { - chunk = '/runtimeQRL'; - symbol = '_'; - } - if (chunk == null) { - throw qError(QError_qrlMissingChunk, qrl.$symbol$); - } - if (chunk.startsWith('./')) { - chunk = chunk.slice(2); - } - if (isSyncQrl(qrl)) { - if (opts.$containerState$) { - const fn = qrl.resolved as Function; - const containerState = opts.$containerState$; - const fnStrKey = ((fn as any).serialized as string) || fn.toString(); - let id = containerState.$inlineFns$.get(fnStrKey); - if (id === undefined) { - id = containerState.$inlineFns$.size; - containerState.$inlineFns$.set(fnStrKey, id); - } - symbol = String(id); - } else { - throwErrorAndStop('Sync QRL without containerState'); - } - } - let output = `${chunk}#${symbol}`; - const capture = qrl.$capture$; - const captureRef = qrl.$captureRef$; - if (captureRef && captureRef.length) { - if (opts.$getObjId$) { - output += `[${mapJoin(captureRef, opts.$getObjId$, ' ')}]`; - } else if (opts.$addRefMap$) { - output += `[${mapJoin(captureRef, opts.$addRefMap$, ' ')}]`; - } - } else if (capture && capture.length > 0) { - output += `[${capture.join(' ')}]`; - } - return output; -}; - -export const serializeQRLs = ( - existingQRLs: QRLInternal[], - containerState: ContainerState, - elCtx: QContext -): string => { - assertElement(elCtx.$element$); - const opts: QRLSerializeOptions = { - $containerState$: containerState, - $addRefMap$: (obj) => addToArray(elCtx.$refMap$, obj), - }; - return mapJoin(existingQRLs, (qrl) => serializeQRL(qrl, opts), '\n'); -}; - -/** `./chunk#symbol[captures] */ -export const parseQRL = (qrl: string, containerEl?: Element): QRLInternal => { - const endIdx = qrl.length; - const hashIdx = indexOf(qrl, 0, '#'); - const captureIdx = indexOf(qrl, hashIdx, '['); - - const chunkEndIdx = Math.min(hashIdx, captureIdx); - const chunk = qrl.substring(0, chunkEndIdx); - - const symbolStartIdx = hashIdx == endIdx ? hashIdx : hashIdx + 1; - const symbolEndIdx = captureIdx; - const symbol = - symbolStartIdx == symbolEndIdx ? 'default' : qrl.substring(symbolStartIdx, symbolEndIdx); - - const captureStartIdx = captureIdx; - const captureEndIdx = endIdx; - const capture = - captureStartIdx === captureEndIdx - ? EMPTY_ARRAY - : qrl.substring(captureStartIdx + 1, captureEndIdx - 1).split(' '); - - const iQrl = createQRL(chunk, symbol, null, null, capture, null, null); - if (containerEl) { - iQrl.$setContainer$(containerEl); - } - return iQrl as QRLInternal; -}; - -const indexOf = (text: string, startIdx: number, char: string) => { - const endIdx = text.length; - const charIdx = text.indexOf(char, startIdx == endIdx ? 0 : startIdx); - return charIdx == -1 ? endIdx : charIdx; -}; - -const addToArray = (array: any[], obj: any) => { - const index = array.indexOf(obj); - if (index === -1) { - array.push(obj); - return String(array.length - 1); - } - return String(index); -}; - -export const inflateQrl = (qrl: QRLInternal, elCtx: QContext) => { - assertDefined(qrl.$capture$, 'invoke: qrl capture must be defined inside useLexicalScope()', qrl); - return (qrl.$captureRef$ = qrl.$capture$.map((idx) => { - const int = parseInt(idx, 10); - const obj = elCtx.$refMap$[int]; - assertTrue(elCtx.$refMap$.length > int, 'out of bounds inflate access', idx); - return obj; - })); -}; - -/** @internal */ -export const _regSymbol = (symbol: any, hash: string) => { - if (typeof (globalThis as any).__qwik_reg_symbols === 'undefined') { - (globalThis as any).__qwik_reg_symbols = new Map(); - } - (globalThis as any).__qwik_reg_symbols.set(hash, symbol); - return symbol; -}; diff --git a/packages/qwik/src/core/readme.md b/packages/qwik/src/core/readme.md index bb284ef80c4..914648a538b 100644 --- a/packages/qwik/src/core/readme.md +++ b/packages/qwik/src/core/readme.md @@ -56,7 +56,7 @@ The status can be one of the following: - `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`. +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 @@ -391,7 +391,8 @@ Assign a value to a Context. Use `useContextProvider()` to assign a value to a context. The assignment happens in the component's function. Once assigned, use `useContext()` in any child component to retrieve the value. -Context is a way to pass stores to the child components without prop-drilling. +Context is a way to pass stores to the child components without prop-drilling. Note that scalar +values are allowed, but for reactivity you need signals or stores. ### Example diff --git a/packages/qwik/src/core/render/README.md b/packages/qwik/src/core/render/README.md deleted file mode 100644 index 9266a95f075..00000000000 --- a/packages/qwik/src/core/render/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# `render` sub-system - -Rendering sub-system of `Qwik`. Currently, only `JSX` implementation is present, but the system is designed to support other rendering systems provided that they abide by these rules: - -- Must be able to render by reusing existing DOM nodes (rather than replace existing DOM nodes). -- Must have a mechanism for rendering `Qwik` special attributes. - -## JSX - -Qwik uses `JSX` syntax, which converts `` into a function call tree like `jsx(Tag, {prop: true}, jsx(Child, null, null))`. `jsx()`, in turn, converts such a call tree into nested JsxNode objects, and then a render pass runs each type (`Tag` in this case) with the props, including the prop `children` - -In Qwik, wrapping a component with `component$` creates a wrapped component, where the children are not passed to the original component. Instead, the original component must return `` elements and those act as placeholders for the `children`. - -The component is executed first, and then the children are executed, inside the context of the deepest `` component. - -## DOM structure - -Everything managed by Qwik is inside a container. This is a DOM element with the attribute `q:container`. For Qwik-City applications, this is normally the `` element. - -Every Qwik component renders a pair of comments and then its contents. The open comment is `` with extra metadata encoded, and the closing comment is ``. - -The contents are `` elements that are waiting for their slot to become available, ` - -
- -
- - - ` - ); - await trigger(fixture.host, 'button', 'click'); - await expectDOM( - fixture.host, - ` - - - -
-
- Hello - -
-
- -
- ` - ); -}); - -test('should render component external props', async () => { - const fixture = new ElementFixture(); - - await render( - fixture.host, - - ); - await expectRendered( - fixture, - '{"thing":"World","innerHTML":"123","dangerouslySetInnerHTML":"432"}' - ); -}); - -test('should render a blank component', async () => { - const fixture = new ElementFixture(); - - await render(fixture.host, ); - await expectRendered(fixture, `
WORKS
`); -}); - -test('should render a div then a component', async () => { - const fixture = new ElementFixture(); - - await render(fixture.host, ); - await expectDOM( - fixture.host, - ` - - -
-
Normal div
- -
- -
` - ); - await trigger(fixture.host, 'button', 'click'); - await expectDOM( - fixture.host, - ` - - - - - - ` - ); -}); - -test('should process clicks', async () => { - const fixture = new ElementFixture(); - - await render(fixture.host, ); - await expectDOM( - fixture.host, - ` - - - - 0 - - - ` - ); - await trigger(fixture.host, 'button.increment', 'click'); - await expectDOM( - fixture.host, - ` - - - - 5 - - - ` - ); -}); - -test('should project no content', async () => { - const fixture = new ElementFixture(); - - await render(fixture.host, ); - await expectRendered( - fixture, - ` -
- - - - - - -
` - ); -}); - -test('should project un-named slot text', async () => { - const fixture = new ElementFixture(); - - await render(fixture.host, projection); - await expectRendered( - fixture, - ` -
- - projection - - - - - -
` - ); -}); - -test('should project un-named slot component', async () => { - const fixture = new ElementFixture(); - - await render( - fixture.host, - - - - ); -}); - -test('should render host events on the first element', async () => { - const fixture = new ElementFixture(); - - await render(fixture.host, ); - await expectDOM( - fixture.host, - ` - - - hello -
- thing -
- stuff - -
` - ); -}); - -test('should project named slot component', async () => { - const fixture = new ElementFixture(); - - await render( - fixture.host, - - PROJECTION - DETAILS - DESCRIPTION - - ); - await expectRendered( - fixture, - ` -
- - PROJECTION - - - DETAILS - - - DESCRIPTION - -
` - ); -}); - -test('should project multiple slot with same name', async () => { - const fixture = new ElementFixture(); - - await render( - fixture.host, - - DETAILS1 - DETAILS2 - IGNORE - - ); - await expectDOM( - fixture.host, - ` - - - -
- - - - DETAILS1 - DETAILS2 - - - -
- -
- ` - ); -}); -test('should not destroy projection when reruns', async () => { - const fixture = new ElementFixture(); - - await render( - fixture.host, - - PROJECTION - - ); - await expectRendered( - fixture, - ` -
- - PROJECTION - -
` - ); -}); - -test('should render into host component', async () => { - const fixture = new ElementFixture(); - - await render( - fixture.host, - - ); - await expectRendered( - fixture, - ` - - ` - ); -}); - -test('should render a promise', async () => { - const fixture = new ElementFixture(); - await render(fixture.host,
{Promise.resolve('WORKS')}
); - await expectRendered(fixture, '
WORKS
'); -}); - -test('should render a component with hooks', async () => { - const fixture = new ElementFixture(); - - await render(fixture.host, ); - await expectRendered( - fixture, - ` -
-
true
-
-
true
-
-
false
-
true
-
` - ); - - await pauseContainer(fixture.host); - await expectRendered( - fixture, - ` -
-
true
-
true
-
true
-
true
-
false
-
true
-
` - ); -}); - -test('should insert a style', async () => { - const fixture = new ElementFixture(); - - await render(fixture.host, ); - const style = fixture.document.querySelector(`style[q\\:style]`); - assert.include(style!.textContent!, 'color: red'); - await expectRendered(fixture, 'Hello World'); -}); -test('should render #text nodes', async () => { - const fixture = new ElementFixture(); - - const lines = ['hola', 'adios']; - await render( - fixture.host, - - {lines.map((a) => { - return ( - - Hola {a} - - ); - })} - - ); - await expectRendered( - fixture, - ` - - Hola hola - Hola adios - ` - ); - - // Ensure all SVG elements have the SVG namespace - const namespaces = Array.from(fixture.host.querySelectorAll('text')).map( - (e: any) => e.namespaceURI - ); - assert.deepEqual(namespaces, ['http://www.w3.org/2000/svg', 'http://www.w3.org/2000/svg']); -}); - -test('should render class object correctly', async () => { - const fixture = new ElementFixture(); - - await render( - fixture.host, -
- ); - await expectRendered(fixture, `
`); -}); - -test('should render class array correctly', async () => { - const fixture = new ElementFixture(); - - await render( - fixture.host, -
- ); - await expectRendered(fixture, `
`); -}); - -test('should re-render classes correctly', async () => { - const fixture = new ElementFixture(); - - await render(fixture.host, ); - await expectDOM( - fixture.host, - ` - - - -
Div 1
-
Div 2
- -
` - ); - - await trigger(fixture.host, 'button', 'click'); - - await expectDOM( - fixture.host, - ` - - - -
Div 1
-
Div 2
- -
` - ); -}); - -test('should render camelCase attributes', async () => { - const fixture = new ElementFixture(); - - await render( - fixture.host, - - - - ); - await expectRendered( - fixture, - ` - - - ` - ); -}); - -test('should render path', async () => { - const fixture = new ElementFixture(); - - await render( - fixture.host, -
- Dude!! - - - -
- ); - await expectRendered( - fixture, - ` -
- Dude!! - - - -
` - ); -}); - -test('should render foreignObject properly', async () => { - const fixture = new ElementFixture(); - - const Text = 'text' as any; - await render( - fixture.host, -
- - Start - - - - start - - -
hello
- - - - -
Still outside svg
-
-
- bye -
- Hello - Bye -
- end -
- ); - for (const el of Array.from(fixture.host.querySelectorAll('.is-html'))) { - assert.equal(el.namespaceURI, 'http://www.w3.org/1999/xhtml', el.outerHTML); - } - for (const el of Array.from(fixture.host.querySelectorAll('.is-svg'))) { - assert.equal(el.namespaceURI, 'http://www.w3.org/2000/svg', el.outerHTML); - } - - await expectRendered( - fixture, - ` -
- Start - - start - -
hello
- - - - -
Still outside svg
-
-
- bye -
- Hello - Bye -
- end -
` - ); -}); - -test('should clean up subscriptions after calling the returned cleanup function', async () => { - const fixture = new ElementFixture(); - - const spies = { - cleanupSpy: false, - }; - - const { cleanup } = await render(fixture.host, ); - - cleanup(); - - assert.equal(spies.cleanupSpy, true); -}); - -async function expectRendered(fixture: ElementFixture, expected: string) { - const firstNode = getFirstNode(fixture.host); - return await expectDOM(firstNode, expected); -} - -function getFirstNode(el: Element) { - let firstNode = el.firstElementChild!; - while (firstNode.nodeName === 'STYLE') { - firstNode = firstNode.nextElementSibling!; - } - return firstNode; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// Hello World -////////////////////////////////////////////////////////////////////////////////////////// -export const HelloWorld = component$((props: { name?: string }) => { - useStylesQrl(inlinedQrl(`span.� { color: red; }`, 'style-1')); - const state = useStore({ salutation: 'Hello' }); - return ( - - {state.salutation} {props.name || 'World'} - - ); -}); - -////////////////////////////////////////////////////////////////////////////////////////// -// Hello World -////////////////////////////////////////////////////////////////////////////////////////// -export const HelloWorldScoped = component$(() => { - useStylesScopedQrl(inlinedQrl(`.stuff { color: red; }`, 'style-scoped-1')); - const state = useStore({ cond: false }); - return ( -
- {state.cond && ( -
- Hello - -
- )} - {!state.cond && ( - - )} -
- ); -}); - -////////////////////////////////////////////////////////////////////////////////////////// -// Hello World -////////////////////////////////////////////////////////////////////////////////////////// -export const RenderProps = component$((props: Record) => { - return ( - - {JSON.stringify(props)} - - ); -}); - -////////////////////////////////////////////////////////////////////////////////////////// -// Render Classes -////////////////////////////////////////////////////////////////////////////////////////// -export const RenderClasses = component$(() => { - const state = useStore({ - count: 0, - }); - return ( - <> - -
- Div 1 -
-
- Div 2 -
- - ); -}); - -////////////////////////////////////////////////////////////////////////////////////////// -// Counter -////////////////////////////////////////////////////////////////////////////////////////// - -export const Counter = component$((props: { step?: number }) => { - const state = useStore({ count: 0 }); - const step = Number(props.step || 1); - return ( - <> - - {state.count} - - - ); -}); -export const Counter_add = () => { - const [state, args] = useLexicalScope(); - state.count += args.value; -}; - -////////////////////////////////////////////////////////////////////////////////////////// -// Project -////////////////////////////////////////////////////////////////////////////////////////// -export const Project = component$(() => { - return ( -
- - - -
- ); -}); - -export const SimpleProject = component$(() => { - return ( -
- -
- ); -}); - -////////////////////////////////////////////////////////////////////////////////////////// -// HostFixture -////////////////////////////////////////////////////////////////////////////////////////// -export const HostFixture = component$((props: { hostAttrs?: string; content?: string }) => { - return
{props.content}
; -}); - -////////////////////////////////////////////////////////////////////////////////////////// -export const InnerHTMLComponent = component$(() => { - const html = 'WORKS'; - return ( -
-
not rendered
-
- ); -}); - -////////////////////////////////////////////////////////////////////////////////////////// - -export const ToggleRootComponent = component$(() => { - const state = useStore({ - cond: false, - }); - return ( -
- {state.cond ? :
Normal div
} - -
- ); -}); - -export const ToggleChild = component$(() => { - return ( -
-
this is ToggleChild
-
- ); -}); - -export const Transparent = component$(() => { - return ; -}); - -export const UseEvents = component$(() => { - useVisibleTask$(() => { - console.warn('hello'); - }); - useOn( - 'click', - inlinedQrl(() => { - console.warn('click'); - }, 'use-on-click') - ); - return ( - <> - hello -
thing
- stuff - - ); -}); - -////////////////////////////////////////////////////////////////////////////////////////// -export const Hooks = component$(() => { - const taskDestroyDiv = useSignal(); - const visibleTaskDiv = useSignal(); - const visibleTaskDestroyDiv = useSignal(); - - const state = useStore({ - task: 'false', - server: 'false', - }); - - useTask$(() => { - state.task = 'true'; - return () => { - taskDestroyDiv.value!.textContent = 'true'; - }; - }); - - useVisibleTask$(() => { - visibleTaskDiv.value!.textContent = 'true'; - return () => { - visibleTaskDestroyDiv.value!.textContent = 'true'; - }; - }); - - return ( -
-
-
- -
{state.task}
-
- -
{state.server}
- -
true
-
- ); -}); - -////////////////////////////////////////////////////////////////////////////////////////// - -export const CleanupComponent = component$((props: { spies: { cleanupSpy: boolean } }) => { - useTask$(({ cleanup }) => { - cleanup(() => { - props.spies.cleanupSpy = true; - }); - }); - - return ( -
-
true
-
- ); -}); - -suite('should properly render styles from style prop', () => { - const RenderJSX = component$(() => { - const pStyles = { - fontSize: 30, // auto-converted to px - fontWeight: 800, // shouldn't get converted to px - }; - return ( -
-
-

Big square

-
-
- ); - }); - - test('SSR jsx style render', async () => { - const output = await renderToString(, { containerTagName: 'div' }); - const document = createDocument(); - document.body.innerHTML = output.html; - const main = document.querySelector('#root')!; - const resultHTML = `

Big square

`; - assert.equal(main.innerHTML, resultHTML); - }); - - test('CSR jsx style render', async () => { - const { screen, render } = await createDOM(); - - await render(); - const main = screen.querySelector('#root')!; - const resultHTML = `

Big square

`; - assert.equal(main.innerHTML, resultHTML); - }); -}); - -test('should render value="" on option', async () => { - const { screen, render } = await createDOM(); - - await render( - - ); - const option = screen.querySelector('option')!; - assert.isTrue(option.hasAttribute('value')); - assert.equal(option.getAttribute('value'), ''); - assert.equal(option.outerHTML, ''); -}); diff --git a/packages/qwik/src/core/render/dom/signals.ts b/packages/qwik/src/core/render/dom/signals.ts deleted file mode 100644 index d410865f864..00000000000 --- a/packages/qwik/src/core/render/dom/signals.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { getLastSubscription, type SubscriberSignal } from '../../state/common'; -import { getContext, tryGetContext } from '../../state/context'; -import { trackSignal } from '../../use/use-core'; -import { logError } from '../../util/log'; -import { serializeClassWithHost, stringifyStyle } from '../execute-component'; -import type { RenderContext } from '../types'; -import { insertBefore, removeNode } from './operations'; -import { getVdom, processData, type ProcessedJSXNode } from './render-dom'; -import type { QwikElement } from './virtual-element'; -import { SVG_NS, createElm, diffVnode, getVnodeFromEl, smartSetProperty } from './visitor'; -import { Virtual, JSXNodeImpl } from '../jsx/jsx-runtime'; -import { isPromise } from '../../util/promises'; -import { isQwikElement } from '../../util/element'; - -export const executeSignalOperation = (rCtx: RenderContext, operation: SubscriberSignal) => { - try { - const type = operation[0]; - const staticCtx = rCtx.$static$; - switch (type) { - case 1: - case 2: { - let elm; - let hostElm; - if (type === 1) { - elm = operation[1]; - hostElm = operation[3]; - } else { - elm = operation[3]; - hostElm = operation[1]; - } - // assertTrue(elm.isConnected, 'element must be connected to the dom'); - // assertTrue(hostElm.isConnected, 'host element must be connected to the dom'); - const elCtx = tryGetContext(elm); - if (elCtx == null) { - return; - } - const prop = operation[4]; - const isSVG = elm.namespaceURI === SVG_NS; - staticCtx.$containerState$.$subsManager$.$clearSignal$(operation); - let value = trackSignal(operation[2], operation.slice(0, -1) as any) as any; - if (prop === 'class') { - value = serializeClassWithHost(value, tryGetContext(hostElm)); - } else if (prop === 'style') { - value = stringifyStyle(value); - } - const vdom = getVdom(elCtx); - if (prop in vdom.$props$ && vdom.$props$[prop] === value) { - return; - } - vdom.$props$[prop] = value; - return smartSetProperty(staticCtx, elm, prop, value, isSVG); - } - case 3: - case 4: { - const elm = operation[3]; - if (!staticCtx.$visited$.includes(elm)) { - // assertTrue(elm.isConnected, 'text node must be connected to the dom'); - staticCtx.$containerState$.$subsManager$.$clearSignal$(operation); - // MISKO: I believe no `invocationContext` is OK because the JSX in signal - // has already been converted to JSX and there is nothing to execute there. - const invocationContext = undefined; - let signalValue = trackSignal(operation[2], operation.slice(0, -1) as any); - const subscription = getLastSubscription()!; - - if (Array.isArray(signalValue)) { - signalValue = new JSXNodeImpl(Virtual, {}, null, signalValue, 0, null); - } - let newVnode = processData(signalValue, invocationContext) as - | ProcessedJSXNode - | undefined; - if (isPromise(newVnode)) { - logError('Rendering promises in JSX signals is not supported'); - } else { - if (newVnode === undefined) { - newVnode = processData('', invocationContext) as ProcessedJSXNode; - } - const oldVnode = getVnodeFromEl(elm); - const element = getQwikElement(operation[1]); - rCtx.$cmpCtx$ = getContext(element, rCtx.$static$.$containerState$); - if ( - oldVnode.$type$ == newVnode.$type$ && - oldVnode.$key$ == newVnode.$key$ && - oldVnode.$id$ == newVnode.$id$ - ) { - diffVnode(rCtx, oldVnode, newVnode, 0); - } else { - const promises: Promise[] = []; // TODO(misko): hook this up - const oldNode = oldVnode.$elm$; - const newElm = createElm(rCtx, newVnode, 0, promises); - if (promises.length) { - logError('Rendering promises in JSX signals is not supported'); - } - subscription[3] = newElm; - insertBefore(rCtx.$static$, elm.parentElement!, newElm, oldNode); - oldNode && removeNode(staticCtx, oldNode); - } - } - } - } - } - } catch (e) { - // Ignore - } -}; -function getQwikElement(element: QwikElement | Text): QwikElement { - while (element) { - if (isQwikElement(element)) { - return element; - } - element = element.parentElement!; - } - throw new Error('Not found'); -} diff --git a/packages/qwik/src/core/render/dom/virtual-element.ts b/packages/qwik/src/core/render/dom/virtual-element.ts deleted file mode 100644 index 26dd161f9a5..00000000000 --- a/packages/qwik/src/core/render/dom/virtual-element.ts +++ /dev/null @@ -1,398 +0,0 @@ -import { assertEqual, assertFail, assertTrue } from '../../error/assert'; -import { VIRTUAL_SYMBOL } from '../../state/constants'; -import { - isComment, - isElement, - isNodeElement, - isQwikElement, - isVirtualElement, -} from '../../util/element'; -import { qSerialize, seal } from '../../util/qdev'; -import { directGetAttribute } from '../fast-calls'; -import { createElement } from './operations'; -import { SVG_NS, getChildren } from './visitor'; - -export interface VirtualElement { - readonly open: Comment; - readonly close: Comment; - readonly isSvg: boolean; - readonly insertBefore: (node: T, child: Node | null) => T; - readonly appendChild: (node: T) => T; - readonly insertBeforeTo: (newParent: QwikElement, child: Node | null) => void; - readonly appendTo: (newParent: QwikElement) => void; - readonly ownerDocument: Document; - readonly namespaceURI: string; - readonly nodeType: 111; - readonly childNodes: Node[]; - readonly firstChild: Node | null; - readonly previousSibling: Node | null; - readonly nextSibling: Node | null; - readonly remove: () => void; - readonly closest: (query: string) => Element | null; - readonly hasAttribute: (prop: string) => boolean; - readonly getAttribute: (prop: string) => string | null; - readonly removeAttribute: (prop: string) => void; - readonly querySelector: (query: string) => QwikElement | null; - readonly querySelectorAll: (query: string) => QwikElement[]; - readonly compareDocumentPosition: (other: Node) => number; - readonly matches: (query: string) => boolean; - readonly setAttribute: (prop: string, value: string) => void; - readonly removeChild: (node: Node) => void; - readonly localName: string; - readonly nodeName: string; - readonly isConnected: boolean; - readonly parentElement: Element | null; - innerHTML: string; -} - -export type QwikElement = Element | VirtualElement; - -export const newVirtualElement = (doc: Document, isSvg: boolean): VirtualElement => { - const open = doc.createComment('qv '); - const close = doc.createComment('/qv'); - return new VirtualElementImpl(open, close, isSvg); -}; - -export const parseVirtualAttributes = (str: string): Record => { - if (!str) { - return {}; - } - const attributes = str.split(' '); - return Object.fromEntries( - attributes.map((attr) => { - const index = attr.indexOf('='); - if (index >= 0) { - return [attr.slice(0, index), unescape(attr.slice(index + 1))]; - } else { - return [attr, '']; - } - }) - ); -}; - -export const serializeVirtualAttributes = (map: Record) => { - const attributes: string[] = []; - Object.entries(map).forEach(([key, value]) => { - if (!value) { - attributes.push(`${key}`); - } else { - attributes.push(`${key}=${escape(value)}`); - } - }); - return attributes.join(' '); -}; - -const SHOW_COMMENT = 128; -const FILTER_ACCEPT = 1; -const FILTER_REJECT = 2; - -export const walkerVirtualByAttribute = (el: Element, prop: string, value: string) => { - return el.ownerDocument.createTreeWalker(el, SHOW_COMMENT, { - acceptNode(c) { - const virtual = getVirtualElement(c as Comment); - if (virtual) { - return directGetAttribute(virtual, prop) === value ? FILTER_ACCEPT : FILTER_REJECT; - } - return FILTER_REJECT; - }, - }); -}; - -export const queryVirtualByAttribute = (el: Element, prop: string, value: string) => { - const walker = walkerVirtualByAttribute(el, prop, value); - const open = walker.firstChild(); - if (open) { - return getVirtualElement(open as Comment); - } - return null; -}; - -export const queryAllVirtualByAttribute = (el: Element, prop: string, value: string) => { - const walker = walkerVirtualByAttribute(el, prop, value); - const pars: VirtualElement[] = []; - let currentNode: Node | null = null; - while ((currentNode = walker.nextNode())) { - pars.push(getVirtualElement(currentNode as Comment)!); - } - return pars; -}; - -export const escape = (s: string) => { - return s.replace(/ /g, '+'); -}; - -export const unescape = (s: string) => { - return s.replace(/\+/g, ' '); -}; - -export const VIRTUAL = ':virtual'; - -export class VirtualElementImpl implements VirtualElement { - ownerDocument: Document; - _qc_: any = null; - - readonly nodeType = 111 as const; - readonly localName = VIRTUAL; - readonly nodeName = VIRTUAL; - - private $attributes$: Record; - private $template$: HTMLTemplateElement; - - constructor( - readonly open: Comment, - readonly close: Comment, - readonly isSvg: boolean - ) { - const doc = (this.ownerDocument = open.ownerDocument); - this.$template$ = createElement(doc, 'template', false) as HTMLTemplateElement; - this.$attributes$ = parseVirtualAttributes(open.data.slice(3)); - assertTrue(open.data.startsWith('qv '), 'comment is not a qv'); - (open as any)[VIRTUAL_SYMBOL] = this; - (close as any)[VIRTUAL_SYMBOL] = this; - seal(this); - } - - insertBefore(node: T, ref: Node | null): T { - const parent = this.parentElement; - if (parent) { - const ref2 = ref ? ref : this.close; - parent.insertBefore(node, ref2); - } else { - this.$template$.insertBefore(node, ref); - } - return node; - } - - remove() { - const parent = this.parentElement; - if (parent) { - const ch = this.childNodes; - assertEqual(this.$template$.childElementCount, 0, 'children should be empty'); - parent.removeChild(this.open); - for (let i = 0; i < ch.length; i++) { - this.$template$.appendChild(ch[i]); - } - parent.removeChild(this.close); - } - } - - appendChild(node: T): T { - return this.insertBefore(node, null); - } - - insertBeforeTo(newParent: QwikElement, child: Node | null) { - // const ch = this.childNodes; - const ch = this.childNodes; - // TODO - // if (this.parentElement) { - // console.warn('already attached'); - // } - newParent.insertBefore(this.open, child); - for (const c of ch) { - newParent.insertBefore(c, child); - } - newParent.insertBefore(this.close, child); - assertEqual(this.$template$.childElementCount, 0, 'children should be empty'); - } - - appendTo(newParent: QwikElement) { - this.insertBeforeTo(newParent, null); - } - - get namespaceURI() { - return this.parentElement?.namespaceURI ?? ''; - } - - removeChild(child: Node) { - if (this.parentElement) { - this.parentElement.removeChild(child); - } else { - this.$template$.removeChild(child); - } - } - - getAttribute(prop: string) { - return this.$attributes$[prop] ?? null; - } - - hasAttribute(prop: string) { - return prop in this.$attributes$; - } - - setAttribute(prop: string, value: string) { - this.$attributes$[prop] = value; - if (qSerialize) { - this.open.data = updateComment(this.$attributes$); - } - } - - removeAttribute(prop: string) { - delete this.$attributes$[prop]; - if (qSerialize) { - this.open.data = updateComment(this.$attributes$); - } - } - - matches(_: string) { - return false; - } - - compareDocumentPosition(other: Node) { - return this.open.compareDocumentPosition(other); - } - - closest(query: string) { - const parent = this.parentElement; - if (parent) { - return parent.closest(query); - } - return null; - } - - querySelectorAll(query: string) { - const result: QwikElement[] = []; - const ch = getChildren(this, isNodeElement); - ch.forEach((el) => { - if (isQwikElement(el)) { - if (el.matches(query)) { - result.push(el); - } - result.concat(Array.from(el.querySelectorAll(query))); - } - }); - return result; - } - - querySelector(query: string) { - for (const el of this.childNodes) { - if (isElement(el)) { - if (el.matches(query)) { - return el; - } - const v = el.querySelector(query); - if (v !== null) { - return v; - } - } - } - return null; - } - - get innerHTML() { - return ''; - } - - set innerHTML(html: string) { - const parent = this.parentElement; - if (parent) { - this.childNodes.forEach((a) => this.removeChild(a)); - this.$template$.innerHTML = html; - parent.insertBefore(this.$template$.content, this.close); - } else { - this.$template$.innerHTML = html; - } - } - - get firstChild() { - if (this.parentElement) { - const first = this.open.nextSibling; - if (first === this.close) { - return null; - } - return first; - } else { - return this.$template$.firstChild; - } - } - get nextSibling() { - return this.close.nextSibling; - } - get previousSibling() { - return this.open.previousSibling; - } - get childNodes(): Node[] { - if (!this.parentElement) { - return Array.from(this.$template$.childNodes) as any; - } - const nodes: Node[] = []; - let node: Node | null = this.open; - while ((node = node.nextSibling)) { - if (node === this.close) { - break; - } - nodes.push(node); - } - return nodes; - } - get isConnected() { - return this.open.isConnected; - } - /** The DOM parent element (not the vDOM parent, use findVirtual for that) */ - get parentElement() { - return this.open.parentElement; - } -} - -const updateComment = (attributes: Record) => { - return `qv ${serializeVirtualAttributes(attributes)}`; -}; - -export const processVirtualNodes = (node: T): T | VirtualElement => { - if (node == null) { - return null as T; - } - - if (isComment(node)) { - const virtual = getVirtualElement(node); - if (virtual) { - return virtual; - } - } - return node; -}; - -const findClose = (open: Comment): Comment => { - let node: Node | null = open; - let stack = 1; - while ((node = node.nextSibling)) { - if (isComment(node)) { - // We don't want to resume virtual nodes but if they're already resumed, use them - const virtual = (node as any)[VIRTUAL_SYMBOL] as ChildNode; - if (virtual) { - // This is not our existing virtual node because otherwise findClose wouldn't have been called - node = virtual; - } else if (node.data.startsWith('qv ')) { - stack++; - } else if (node.data === '/qv') { - stack--; - if (stack === 0) { - return node; - } - } - } - } - assertFail('close not found'); -}; - -export const getVirtualElement = (open: Comment): VirtualElement | null => { - const virtual = (open as any)[VIRTUAL_SYMBOL]; - if (virtual) { - return virtual; - } - if (open.data.startsWith('qv ')) { - const close = findClose(open); - return new VirtualElementImpl(open, close, open.parentElement?.namespaceURI === SVG_NS); - } - return null; -}; - -export const getRootNode = (node: Node | VirtualElement | null): Node => { - if (node == null) { - return null as any; // TODO - } - if (isVirtualElement(node)) { - return node.open; - } else { - return node; - } -}; diff --git a/packages/qwik/src/core/render/dom/visitor.ts b/packages/qwik/src/core/render/dom/visitor.ts deleted file mode 100644 index 21a2c8e3652..00000000000 --- a/packages/qwik/src/core/render/dom/visitor.ts +++ /dev/null @@ -1,1262 +0,0 @@ -import type { OnRenderFn } from '../../component/component.public'; -import { getEventName, setRef, type ContainerState } from '../../container/container'; -import { - assertDefined, - assertElement, - assertEqual, - assertFail, - assertQwikElement, - assertTrue, -} from '../../error/assert'; -import { assertQrl, isQrl } from '../../qrl/qrl-class'; -import { PREVENT_DEFAULT, isOnProp, setEvent } from '../../state/listeners'; -import { isElement, isQwikElement, isText, isVirtualElement } from '../../util/element'; -import { logWarn } from '../../util/log'; -import { ELEMENT_ID, OnRenderProp, QSlot, QSlotRef, QSlotS, QStyle } from '../../util/markers'; -import { isPromise, maybeThen, promiseAll, promiseAllLazy } from '../../util/promises'; -import { qDev, qInspector, qTest } from '../../util/qdev'; -import type { ValueOrPromise } from '../../util/types'; -import { - dangerouslySetInnerHTML, - isAriaAttribute, - jsxToString, - pushRenderContext, - serializeClassWithHost, - setQId, - static_listeners, - static_subtree, - stringifyStyle, -} from '../execute-component'; -import { directGetAttribute, directSetAttribute } from '../fast-calls'; -import { SKIP_RENDER_TYPE, isJSXNode } from '../jsx/jsx-runtime'; -import type { RenderContext, RenderStaticContext } from '../types'; -import { - ProcessedJSXNodeImpl, - getVdom, - processData, - renderComponent, - type ProcessedJSXNode, -} from './render-dom'; -import { - VIRTUAL, - getRootNode, - newVirtualElement, - processVirtualNodes, - queryAllVirtualByAttribute, - type QwikElement, - type VirtualElement, -} from './virtual-element'; - -import { isBrowser } from '@builder.io/qwik/build'; -import { - getProxyTarget, - getSubscriptionManager, - type SubscriberC, - type SubscriptionManager, -} from '../../state/common'; -import { _IMMUTABLE, _IMMUTABLE_PREFIX } from '../../state/constants'; -import { - HOST_FLAG_DIRTY, - HOST_FLAG_NEED_ATTACH_LISTENER, - cleanupContext, - createContext, - getContext, - tryGetContext, - type QContext, -} from '../../state/context'; -import { isSignal } from '../../state/signal'; -import { ReadWriteProxyHandler, createPropsState, createProxy } from '../../state/store'; -import { trackSignal } from '../../use/use-core'; -import { EMPTY_OBJ } from '../../util/flyweight'; -import { - appendChild, - createElement, - createTemplate, - executeDOMRender, - getKey, - insertAfter, - insertBefore, - prepend, - removeNode, - setAttribute, - setKey, - setProperty, - setPropertyPost, -} from './operations'; - -export const SVG_NS = 'http://www.w3.org/2000/svg'; - -export const IS_SVG = 1 << 0; -export const IS_HEAD = 1 << 1; -export const IS_IMMUTABLE = 1 << 2; - -type KeyToIndexMap = { [key: string]: number }; - -const CHILDREN_PLACEHOLDER: ProcessedJSXNode[] = []; -type PropHandler = ( - staticCtx: RenderStaticContext, - el: HTMLElement, - newValue: any, - ProcessedJSXNodeImpl: string -) => boolean; - -export type ChildrenMode = 'root' | 'head' | 'elements'; - -export const smartUpdateChildren = ( - ctx: RenderContext, - oldVnode: ProcessedJSXNode, - newVnode: ProcessedJSXNode, - flags: number -) => { - assertQwikElement(oldVnode.$elm$); - - const ch = newVnode.$children$; - if (ch.length === 1 && ch[0].$type$ === SKIP_RENDER_TYPE) { - newVnode.$children$ = oldVnode.$children$; - return; - } - const elm = oldVnode.$elm$; - const needsDOMRead = oldVnode.$children$ === CHILDREN_PLACEHOLDER; - let filter = isChildComponent; - if (needsDOMRead) { - const isHead = elm.nodeName === 'HEAD'; - if (isHead) { - filter = isHeadChildren; - flags |= IS_HEAD; - } - } - - const oldCh = getVnodeChildren(oldVnode, filter); - if (oldCh.length > 0 && ch.length > 0) { - return diffChildren(ctx, elm, oldCh, ch, flags); - } else if (oldCh.length > 0 && ch.length === 0) { - return removeChildren(ctx.$static$, oldCh, 0, oldCh.length - 1); - } else if (ch.length > 0) { - return addChildren(ctx, elm, null, ch, 0, ch.length - 1, flags); - } -}; - -export const getVnodeChildren = ( - oldVnode: ProcessedJSXNode, - filter: (el: Node | VirtualElement) => boolean -) => { - const oldCh = oldVnode.$children$; - const elm = oldVnode.$elm$ as Element; - if (oldCh === CHILDREN_PLACEHOLDER) { - return (oldVnode.$children$ = getChildrenVnodes(elm, filter)); - } - return oldCh; -}; - -export const diffChildren = ( - ctx: RenderContext, - parentElm: QwikElement, - oldCh: ProcessedJSXNode[], - newCh: ProcessedJSXNode[], - flags: number -): ValueOrPromise => { - let oldStartIdx = 0; - let newStartIdx = 0; - let oldEndIdx = oldCh.length - 1; - let oldStartVnode = oldCh[0] as ProcessedJSXNode | undefined; - let oldEndVnode = oldCh[oldEndIdx] as ProcessedJSXNode | undefined; - let newEndIdx = newCh.length - 1; - let newStartVnode = newCh[0] as ProcessedJSXNode | undefined; - let newEndVnode = newCh[newEndIdx] as ProcessedJSXNode | undefined; - let oldKeyToIdx: KeyToIndexMap | undefined; - let idxInOld: number; - let elmToMove: ProcessedJSXNode; - const results: any[] = []; - const staticCtx = ctx.$static$; - - while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) { - if (oldStartVnode == null) { - oldStartVnode = oldCh[++oldStartIdx]; // Vnode might have been moved left - } else if (oldEndVnode == null) { - oldEndVnode = oldCh[--oldEndIdx]; - } else if (newStartVnode == null) { - newStartVnode = newCh[++newStartIdx]; - } else if (newEndVnode == null) { - newEndVnode = newCh[--newEndIdx]; - } else if (oldStartVnode.$id$ === newStartVnode.$id$) { - results.push(diffVnode(ctx, oldStartVnode, newStartVnode, flags)); - oldStartVnode = oldCh[++oldStartIdx]; - newStartVnode = newCh[++newStartIdx]; - } else if (oldEndVnode.$id$ === newEndVnode.$id$) { - results.push(diffVnode(ctx, oldEndVnode, newEndVnode, flags)); - oldEndVnode = oldCh[--oldEndIdx]; - newEndVnode = newCh[--newEndIdx]; - } else if (oldStartVnode.$key$ && oldStartVnode.$id$ === newEndVnode.$id$) { - assertDefined(oldStartVnode.$elm$, 'oldStartVnode $elm$ must be defined'); - assertDefined(oldEndVnode.$elm$, 'oldEndVnode $elm$ must be defined'); - - // Vnode moved right - results.push(diffVnode(ctx, oldStartVnode, newEndVnode, flags)); - insertAfter(staticCtx, parentElm, oldStartVnode.$elm$, oldEndVnode.$elm$); - oldStartVnode = oldCh[++oldStartIdx]; - newEndVnode = newCh[--newEndIdx]; - } else if (oldEndVnode.$key$ && oldEndVnode.$id$ === newStartVnode.$id$) { - assertDefined(oldStartVnode.$elm$, 'oldStartVnode $elm$ must be defined'); - assertDefined(oldEndVnode.$elm$, 'oldEndVnode $elm$ must be defined'); - - // Vnode moved left - results.push(diffVnode(ctx, oldEndVnode, newStartVnode, flags)); - insertBefore(staticCtx, parentElm, oldEndVnode.$elm$, oldStartVnode.$elm$); - oldEndVnode = oldCh[--oldEndIdx]; - newStartVnode = newCh[++newStartIdx]; - } else { - if (oldKeyToIdx === undefined) { - oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx); - } - idxInOld = oldKeyToIdx[newStartVnode.$key$ as string]; - if (idxInOld === undefined) { - // New element - const newElm = createElm(ctx, newStartVnode, flags, results); - insertBefore(staticCtx, parentElm, newElm, oldStartVnode?.$elm$); - } else { - elmToMove = oldCh[idxInOld]; - if (elmToMove.$type$ !== newStartVnode.$type$) { - const newElm = createElm(ctx, newStartVnode, flags, results); - // TO CHECK: should we not await these promises? - maybeThen(newElm, (newElm) => { - insertBefore(staticCtx, parentElm, newElm, oldStartVnode?.$elm$); - }); - } else { - results.push(diffVnode(ctx, elmToMove, newStartVnode, flags)); - oldCh[idxInOld] = undefined as any; - assertDefined(elmToMove.$elm$, 'elmToMove $elm$ must be defined'); - insertBefore(staticCtx, parentElm, elmToMove.$elm$, oldStartVnode.$elm$); - } - } - newStartVnode = newCh[++newStartIdx]; - } - } - - if (newStartIdx <= newEndIdx) { - const before = newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].$elm$; - results.push(addChildren(ctx, parentElm, before, newCh, newStartIdx, newEndIdx, flags)); - } - - let wait = promiseAll(results) as any; - if (oldStartIdx <= oldEndIdx) { - wait = maybeThen(wait, () => { - removeChildren(staticCtx, oldCh, oldStartIdx, oldEndIdx); - }); - } - return wait; -}; - -export const getChildren = (elm: QwikElement, filter: (el: Node | VirtualElement) => boolean) => { - const end = isVirtualElement(elm) ? elm.close : null; - const nodes: (Node | VirtualElement)[] = []; - let node: Node | null | VirtualElement = elm.firstChild; - while ((node = processVirtualNodes(node))) { - if (filter(node)) { - nodes.push(node); - } - node = node.nextSibling; - if (node === end) { - break; - } - } - return nodes; -}; - -// export const getChildren = (elm: QwikElement, mode: ChildrenMode): (Node | VirtualElement)[] => { -// // console.warn('DOM READ: getChildren()', elm); -// switch (mode) { -// case 'root': -// return getCh(elm, isChildComponent); -// case 'head': -// return getCh(elm, isHeadChildren); -// case 'elements': -// return getCh(elm, isNodeElement); -// } -// }; - -const getChildrenVnodes = (elm: QwikElement, filter: (el: Node | VirtualElement) => boolean) => { - return getChildren(elm, filter).map(getVnodeFromEl); -}; - -export const getVnodeFromEl = (el: Node | VirtualElement) => { - if (isElement(el)) { - return tryGetContext(el)?.$vdom$ ?? domToVnode(el); - } - return domToVnode(el); -}; - -export const domToVnode = (node: Node | VirtualElement): ProcessedJSXNode => { - if (isQwikElement(node)) { - const t = new ProcessedJSXNodeImpl( - node.localName, - {}, - null, - CHILDREN_PLACEHOLDER, - 0, - getKey(node) - ); - t.$elm$ = node; - return t; - } else if (isText(node)) { - const t = new ProcessedJSXNodeImpl( - node.nodeName, - EMPTY_OBJ, - null, - CHILDREN_PLACEHOLDER, - 0, - null - ); - t.$text$ = node.data; - t.$elm$ = node; - return t; - } - assertFail('Invalid node type'); -}; - -const isHeadChildren = (node: Node | VirtualElement): boolean => { - const type = node.nodeType; - if (type === 1) { - return (node as Element).hasAttribute('q:head'); - } - return type === 111; -}; - -export const isSlotTemplate = (node: Node | VirtualElement): node is Element => { - return node.nodeName === 'Q:TEMPLATE'; -}; - -export const isChildComponent = (node: Node | VirtualElement): boolean => { - const type = node.nodeType; - if (type === 3 || type === 111) { - return true; - } - if (type !== 1) { - return false; - } - const nodeName = node.nodeName; - if (nodeName === 'Q:TEMPLATE') { - return false; - } - if (nodeName === 'HEAD') { - return (node as Element).hasAttribute('q:head'); - } - if (nodeName === 'STYLE') { - return !(node as Element).hasAttribute(QStyle); - } - return true; -}; - -export const splitChildren = (input: ProcessedJSXNode[]): Record => { - const output: Record = {}; - for (const item of input) { - const key = getSlotName(item); - const node = - output[key] ?? - (output[key] = new ProcessedJSXNodeImpl( - VIRTUAL, - { - [QSlotS]: '', - }, - null, - [], - 0, - key - )); - node.$children$.push(item); - } - return output; -}; - -export const diffVnode = ( - rCtx: RenderContext, - oldVnode: ProcessedJSXNode, - newVnode: ProcessedJSXNode, - flags: number -): ValueOrPromise => { - assertEqual(oldVnode.$type$, newVnode.$type$, 'old and new vnodes type must be the same'); - assertEqual(oldVnode.$key$, newVnode.$key$, 'old and new vnodes key must be the same'); - assertEqual(oldVnode.$id$, newVnode.$id$, 'old and new vnodes key must be the same'); - const elm = oldVnode.$elm$; - const tag = newVnode.$type$; - const staticCtx = rCtx.$static$; - const containerState = staticCtx.$containerState$; - const currentComponent = rCtx.$cmpCtx$; - assertDefined(elm, 'while patching element must be defined'); - assertDefined(currentComponent, 'while patching current component must be defined'); - - newVnode.$elm$ = elm; - - // Render text nodes - if (tag === '#text') { - staticCtx.$visited$.push(elm); - const signal = newVnode.$signal$; - if (signal) { - newVnode.$text$ = jsxToString( - trackSignal(signal, [4, currentComponent.$element$, signal, elm as Text]) - ); - } - setProperty(staticCtx, elm, 'data', newVnode.$text$); - return; - } else if (tag === '#signal') { - return; - } - assertQwikElement(elm); - - const props = newVnode.$props$; - const vnodeFlags = newVnode.$flags$; - const elCtx = getContext(elm, containerState); - - if (tag !== VIRTUAL) { - // Track SVG state - let isSvg = (flags & IS_SVG) !== 0; - if (!isSvg && tag === 'svg') { - flags |= IS_SVG; - isSvg = true; - } - - if (props !== EMPTY_OBJ) { - // elCtx.$vdom$ = newVnode; - if ((vnodeFlags & static_listeners) === 0) { - elCtx.li.length = 0; - } - const values = oldVnode.$props$; - newVnode.$props$ = values; - for (const prop in props) { - let newValue = props[prop]; - if (prop === 'ref') { - assertElement(elm); - if (newValue !== undefined) { - setRef(newValue, elm); - } - continue; - } - - if (isOnProp(prop)) { - const normalized = setEvent(elCtx.li, prop, newValue, containerState.$containerEl$); - addQwikEvent(staticCtx, elm, normalized); - continue; - } - - if (isSignal(newValue)) { - newValue = trackSignal(newValue, [1, currentComponent.$element$, newValue, elm, prop]); - } - if (prop === 'class') { - newValue = serializeClassWithHost(newValue, currentComponent); - } else if (prop === 'style') { - newValue = stringifyStyle(newValue); - } - if (values[prop] !== newValue) { - values[prop] = newValue; - smartSetProperty(staticCtx, elm as HTMLElement, prop, newValue, isSvg); - } - } - } - if (vnodeFlags & static_subtree) { - return; - } - - if (isSvg && tag === 'foreignObject') { - flags &= ~IS_SVG; - } - - const setsInnerHTML = props[dangerouslySetInnerHTML] !== undefined; - if (setsInnerHTML) { - if (qDev && newVnode.$children$.length > 0) { - logWarn('Node can not have children when innerHTML is set'); - } - return; - } - if (tag === 'textarea') { - return; - } - return smartUpdateChildren(rCtx, oldVnode, newVnode, flags); - } else if (OnRenderProp in props) { - const cmpProps = props.props; - setComponentProps(containerState, elCtx, cmpProps); - let needsRender = !!(elCtx.$flags$ & HOST_FLAG_DIRTY); - // TODO: review this corner case - if (!needsRender && !elCtx.$componentQrl$ && !elCtx.$element$.hasAttribute(ELEMENT_ID)) { - setQId(rCtx, elCtx); - elCtx.$componentQrl$ = cmpProps[OnRenderProp]; - assertQrl(elCtx.$componentQrl$ as any); - needsRender = true; - } - - // Rendering of children of component is more complicated, - // since the children must be projected into the rendered slots - // In addition, nested children might need rerendering, if that's the case - // we need to render the nested component, and wait before projecting the content - // since otherwise we don't know where the slots - if (needsRender) { - return maybeThen(renderComponent(rCtx, elCtx, flags), () => - renderContentProjection(rCtx, elCtx, newVnode, flags) - ); - } - return renderContentProjection(rCtx, elCtx, newVnode, flags); - } else if (QSlotS in props) { - assertDefined(currentComponent.$slots$, 'current component slots must be a defined array'); - currentComponent.$slots$.push(newVnode); - return; - } else if (dangerouslySetInnerHTML in props) { - setProperty(staticCtx, elm, 'innerHTML', props[dangerouslySetInnerHTML]); - return; - } - if (vnodeFlags & static_subtree) { - return; - } - return smartUpdateChildren(rCtx, oldVnode, newVnode, flags); -}; - -const renderContentProjection = ( - rCtx: RenderContext, - hostCtx: QContext, - vnode: ProcessedJSXNode, - flags: number -): ValueOrPromise => { - if (vnode.$flags$ & static_subtree) { - return; - } - const newChildren = vnode.$children$; - const staticCtx = rCtx.$static$; - const splittedNewChildren = splitChildren(newChildren); - const slotMaps = getSlotMap(hostCtx); - - // Remove content from empty slots - for (const key in slotMaps.slots) { - if (!splittedNewChildren[key]) { - const slotEl = slotMaps.slots[key]; - const oldCh = getChildrenVnodes(slotEl, isChildComponent); - if (oldCh.length > 0) { - // getVdom(slotEl).$children$ = []; - const slotCtx = tryGetContext(slotEl); - if (slotCtx && slotCtx.$vdom$) { - slotCtx.$vdom$.$children$ = []; - } - removeChildren(staticCtx, oldCh, 0, oldCh.length - 1); - } - } - } - - // Remove empty templates - for (const key in slotMaps.templates) { - const templateEl = slotMaps.templates[key]; - if (templateEl && !splittedNewChildren[key]) { - slotMaps.templates[key] = undefined; - removeNode(staticCtx, templateEl); - } - } - - // Render into slots - return promiseAll( - Object.keys(splittedNewChildren).map((slotName) => { - const newVdom = splittedNewChildren[slotName]; - const slotCtx = getSlotCtx( - staticCtx, - slotMaps, - hostCtx, - slotName, - rCtx.$static$.$containerState$ - ); - const oldVdom = getVdom(slotCtx); - const slotRctx = pushRenderContext(rCtx); - const slotEl = slotCtx.$element$ as VirtualElement; - slotRctx.$slotCtx$ = slotCtx; - slotCtx.$vdom$ = newVdom; - newVdom.$elm$ = slotEl; - let newFlags = flags & ~IS_SVG; - if (slotEl.isSvg) { - newFlags |= IS_SVG; - } - - const index = staticCtx.$addSlots$.findIndex((slot) => slot[0] === slotEl); - if (index >= 0) { - staticCtx.$addSlots$.splice(index, 1); - } - return smartUpdateChildren(slotRctx, oldVdom, newVdom, newFlags); - }) - ) as any; -}; - -const addChildren = ( - ctx: RenderContext, - parentElm: QwikElement, - before: Node | VirtualElement | null, - vnodes: ProcessedJSXNode[], - startIdx: number, - endIdx: number, - flags: number -): ValueOrPromise => { - const promises: Promise[] = []; - for (; startIdx <= endIdx; ++startIdx) { - const ch = vnodes[startIdx]; - assertDefined(ch, 'render: node must be defined at index', startIdx, vnodes); - const elm = createElm(ctx, ch, flags, promises); - insertBefore(ctx.$static$, parentElm, elm, before); - } - return promiseAllLazy(promises); -}; - -const removeChildren = ( - staticCtx: RenderStaticContext, - nodes: ProcessedJSXNode[], - startIdx: number, - endIdx: number -): void => { - for (; startIdx <= endIdx; ++startIdx) { - const ch = nodes[startIdx]; - if (ch) { - assertDefined(ch.$elm$, 'vnode elm must be defined'); - removeNode(staticCtx, ch.$elm$); - } - } -}; - -const getSlotCtx = ( - staticCtx: RenderStaticContext, - slotMaps: SlotMaps, - hostCtx: QContext, - slotName: string, - containerState: ContainerState -): QContext => { - // If a slot is known, render children inside - const slotEl = slotMaps.slots[slotName]; - if (slotEl) { - return getContext(slotEl, containerState); - } - // Otherwise we park the children in a template - const templateEl = slotMaps.templates[slotName]; - if (templateEl) { - return getContext(templateEl, containerState); - } - const template = createTemplate(staticCtx.$doc$, slotName); - const elCtx = createContext(template); - elCtx.$parentCtx$ = hostCtx; - prepend(staticCtx, hostCtx.$element$, template); - slotMaps.templates[slotName] = template; - return elCtx; -}; - -const getSlotName = (node: ProcessedJSXNode): string => { - return node.$props$[QSlot] ?? ''; -}; - -export const createElm = ( - rCtx: RenderContext, - vnode: ProcessedJSXNode, - flags: number, - promises: Promise[] -): Node | VirtualElement => { - const tag = vnode.$type$; - const doc = rCtx.$static$.$doc$; - const currentComponent = rCtx.$cmpCtx$; - if (tag === '#text') { - return (vnode.$elm$ = doc.createTextNode(vnode.$text$)); - } - - if (tag === '#signal') { - const signal = vnode.$signal$!; - assertDefined(signal, 'expecting signal here'); - assertDefined(currentComponent, 'signals can not be used outside components'); - const signalValue = signal.value; - if (isJSXNode(signalValue)) { - // convert signal value to ProcessedJSXNode - const processedSignal = processData(signalValue); - if (isSignal(processedSignal)) { - throw new Error('NOT IMPLEMENTED: Promise'); - } else if (Array.isArray(processedSignal)) { - throw new Error('NOT IMPLEMENTED: Array'); - } else { - // crate elements - const elm = createElm(rCtx, processedSignal as ProcessedJSXNode, flags, promises); - // create subscription - trackSignal( - signal, - flags & IS_IMMUTABLE - ? ([3, elm, signal, elm] as SubscriberC) - : ([4, currentComponent.$element$, signal, elm] as SubscriberC) - ); - // update the vNode for future diff. - return (vnode.$elm$ = elm); - } - } else { - // create element - const elm = doc.createTextNode(vnode.$text$); - elm.data = vnode.$text$ = jsxToString(signalValue); - // create subscription - trackSignal( - signal, - flags & IS_IMMUTABLE - ? ([3, elm, signal, elm] as SubscriberC) - : ([4, currentComponent.$element$, signal, elm] as SubscriberC) - ); - // update the vNode for future diff. - return (vnode.$elm$ = elm); - } - } - - let elm: QwikElement; - let isSvg = !!(flags & IS_SVG); - if (!isSvg && tag === 'svg') { - flags |= IS_SVG; - isSvg = true; - } - const isVirtual = tag === VIRTUAL; - const props = vnode.$props$; - const staticCtx = rCtx.$static$; - const containerState = staticCtx.$containerState$; - if (isVirtual) { - elm = newVirtualElement(doc, isSvg); - } else if (tag === 'head') { - elm = doc.head; - flags |= IS_HEAD; - } else { - elm = createElement(doc, tag, isSvg); - flags &= ~IS_HEAD; - } - if (vnode.$flags$ & static_subtree) { - flags |= IS_IMMUTABLE; - } - - vnode.$elm$ = elm; - const elCtx = createContext(elm); - if (rCtx.$slotCtx$) { - elCtx.$parentCtx$ = rCtx.$slotCtx$; - elCtx.$realParentCtx$ = rCtx.$cmpCtx$!; - } else { - elCtx.$parentCtx$ = rCtx.$cmpCtx$; - } - if (!isVirtual) { - if (qDev && qInspector) { - const dev = vnode.$dev$; - if (dev) { - directSetAttribute( - elm, - 'data-qwik-inspector', - `${dev.fileName}:${dev.lineNumber}:${dev.columnNumber}` - ); - } - } - if (vnode.$immutableProps$) { - const immProps = - props !== EMPTY_OBJ - ? Object.fromEntries( - Object.entries(vnode.$immutableProps$).map(([k, v]) => [ - k, - v === _IMMUTABLE ? props[k] : v, - ]) - ) - : vnode.$immutableProps$; - setProperties(staticCtx, elCtx, currentComponent, immProps, isSvg, true); - } - if (props !== EMPTY_OBJ) { - elCtx.$vdom$ = vnode; - const p = vnode.$immutableProps$ - ? Object.fromEntries(Object.entries(props).filter(([k]) => !(k in vnode.$immutableProps$!))) - : props; - vnode.$props$ = setProperties(staticCtx, elCtx, currentComponent, p, isSvg, false); - } - if (isSvg && tag === 'foreignObject') { - isSvg = false; - flags &= ~IS_SVG; - } - if (currentComponent) { - const scopedIds = currentComponent.$scopeIds$; - if (scopedIds) { - scopedIds.forEach((styleId) => { - (elm as Element).classList.add(styleId); - }); - } - if (currentComponent.$flags$ & HOST_FLAG_NEED_ATTACH_LISTENER) { - elCtx.li.push(...currentComponent.li); - currentComponent.$flags$ &= ~HOST_FLAG_NEED_ATTACH_LISTENER; - } - } - for (const listener of elCtx.li) { - addQwikEvent(staticCtx, elm, listener[0]); - } - const setsInnerHTML = props[dangerouslySetInnerHTML] !== undefined; - if (setsInnerHTML) { - if (qDev && vnode.$children$.length > 0) { - logWarn('Node can not have children when innerHTML is set'); - } - return elm; - } - if (isSvg && tag === 'foreignObject') { - isSvg = false; - flags &= ~IS_SVG; - } - } else if (OnRenderProp in props) { - const renderQRL = props[OnRenderProp]; - assertQrl>(renderQRL); - const target = createPropsState(); - const manager = containerState.$subsManager$.$createManager$(); - const proxy = new Proxy(target, new ReadWriteProxyHandler(containerState, manager)); - const expectProps = props.props; - containerState.$proxyMap$.set(target, proxy); - elCtx.$props$ = proxy; - if (expectProps !== EMPTY_OBJ) { - const immutableMeta = ((target as any)[_IMMUTABLE] = - (expectProps as any)[_IMMUTABLE] ?? EMPTY_OBJ); - - for (const prop in expectProps) { - if (prop !== 'children' && prop !== QSlot) { - const immutableValue = immutableMeta[prop]; - if (isSignal(immutableValue)) { - target[_IMMUTABLE_PREFIX + prop] = immutableValue; - } else { - target[prop] = expectProps[prop]; - } - } - } - } - setQId(rCtx, elCtx); - - // Run mount hook - elCtx.$componentQrl$ = renderQRL; - - const wait = maybeThen(renderComponent(rCtx, elCtx, flags), () => { - let children = vnode.$children$; - if (children.length === 0) { - return; - } - if (children.length === 1 && children[0].$type$ === SKIP_RENDER_TYPE) { - children = children[0].$children$; - } - const slotMap = getSlotMap(elCtx); - const p: Promise[] = []; - const splittedNewChildren = splitChildren(children); - for (const slotName in splittedNewChildren) { - const newVnode = splittedNewChildren[slotName]; - const slotCtx = getSlotCtx(staticCtx, slotMap, elCtx, slotName, staticCtx.$containerState$); - const slotRctx = pushRenderContext(rCtx); - const slotEl = slotCtx.$element$ as VirtualElement; - slotRctx.$slotCtx$ = slotCtx; - slotCtx.$vdom$ = newVnode; - newVnode.$elm$ = slotEl; - let newFlags = flags & ~IS_SVG; - if (slotEl.isSvg) { - newFlags |= IS_SVG; - } - for (const node of newVnode.$children$) { - const nodeElm = createElm(slotRctx, node, newFlags, p); - assertDefined(node.$elm$, 'vnode elm must be defined'); - assertEqual(nodeElm, node.$elm$, 'vnode elm must be defined'); - appendChild(staticCtx, slotEl, nodeElm); - } - } - return promiseAllLazy(p); - }); - if (isPromise(wait)) { - promises.push(wait); - } - return elm; - } else if (QSlotS in props) { - assertDefined(currentComponent, 'slot can only be used inside component'); - assertDefined(currentComponent.$slots$, 'current component slots must be a defined array'); - - setKey(elm, vnode.$key$); - directSetAttribute(elm, QSlotRef, currentComponent.$id$); - directSetAttribute(elm, QSlotS, ''); - currentComponent.$slots$.push(vnode); - staticCtx.$addSlots$.push([elm, currentComponent.$element$]); - } else if (dangerouslySetInnerHTML in props) { - setProperty(staticCtx, elm, 'innerHTML', props[dangerouslySetInnerHTML]); - return elm; - } - - let children = vnode.$children$; - if (children.length === 0) { - return elm; - } - if (children.length === 1 && children[0].$type$ === SKIP_RENDER_TYPE) { - children = children[0].$children$; - } - const nodes = children.map((ch) => createElm(rCtx, ch, flags, promises)); - for (const node of nodes) { - directAppendChild(elm, node); - } - return elm; -}; - -interface SlotMaps { - slots: Record; - templates: Record; -} - -const getSlots = (elCtx: QContext): ProcessedJSXNode[] => { - const slots = elCtx.$slots$; - if (!slots) { - const parent = elCtx.$element$.parentElement; - assertDefined(parent, 'component should be already attached to the dom'); - return (elCtx.$slots$ = readDOMSlots(elCtx)); - } - return slots; -}; - -const getSlotMap = (elCtx: QContext): SlotMaps => { - const slotsArray = getSlots(elCtx); - const slots: Record = {}; - const templates: Record = {}; - const t = Array.from(elCtx.$element$.childNodes).filter(isSlotTemplate); - - // Map virtual slots - for (const vnode of slotsArray) { - assertQwikElement(vnode.$elm$); - slots[vnode.$key$ ?? ''] = vnode.$elm$; - } - // Map templates - for (const elm of t) { - templates[directGetAttribute(elm, QSlot) ?? ''] = elm; - } - return { slots, templates }; -}; - -const readDOMSlots = (elCtx: QContext): ProcessedJSXNode[] => { - const parent = elCtx.$element$.parentElement; - assertDefined(parent, 'component should be already attached to the dom'); - return queryAllVirtualByAttribute(parent, QSlotRef, elCtx.$id$).map(domToVnode); -}; - -const handleStyle: PropHandler = (ctx, elm, newValue) => { - setProperty(ctx, elm.style, 'cssText', newValue); - return true; -}; - -const handleClass: PropHandler = (ctx, elm, newValue) => { - assertTrue( - newValue == null || typeof newValue === 'string', - 'class newValue must be either nullish or string', - newValue - ); - if (elm.namespaceURI === SVG_NS) { - setAttribute(ctx, elm, 'class', newValue); - } else { - setProperty(ctx, elm, 'className', newValue); - } - return true; -}; - -const checkBeforeAssign: PropHandler = (ctx, elm, newValue, prop) => { - if (prop in elm) { - // a selected