diff --git a/apps/svelte.dev/content/docs/cli/20-commands/10-sv-create.md b/apps/svelte.dev/content/docs/cli/20-commands/10-sv-create.md index 1034091a21..21ebdf4f3d 100644 --- a/apps/svelte.dev/content/docs/cli/20-commands/10-sv-create.md +++ b/apps/svelte.dev/content/docs/cli/20-commands/10-sv-create.md @@ -13,6 +13,16 @@ npx sv create [options] [path] ## Options +### `--from-playground ` + +Create a SvelteKit project from a [playground](/playground) URL. This downloads all playground files, detects external dependencies, and sets up a complete SvelteKit project structure with everything ready to go. + +Example: + +```sh +npx sv create --from-playground="https://svelte.dev/playground/hello-world" +``` + ### `--template ` Which project template to use: diff --git a/apps/svelte.dev/content/docs/kit/10-getting-started/30-project-structure.md b/apps/svelte.dev/content/docs/kit/10-getting-started/30-project-structure.md index 345b9efe7d..4795c42ff5 100644 --- a/apps/svelte.dev/content/docs/kit/10-getting-started/30-project-structure.md +++ b/apps/svelte.dev/content/docs/kit/10-getting-started/30-project-structure.md @@ -53,6 +53,7 @@ The `src` directory contains the meat of your project. Everything except `src/ro - `error.html` is the page that is rendered when everything else fails. It can contain the following placeholders: - `%sveltekit.status%` — the HTTP status - `%sveltekit.error.message%` — the error message + - `%sveltekit.version%` — the deployment version, which can be specified with the [`version`](configuration#version) configuration - `hooks.client.js` contains your client [hooks](hooks) - `hooks.server.js` contains your server [hooks](hooks) - `service-worker.js` contains your [service worker](service-workers) diff --git a/apps/svelte.dev/content/docs/kit/20-core-concepts/60-remote-functions.md b/apps/svelte.dev/content/docs/kit/20-core-concepts/60-remote-functions.md index 91b29cbd54..7a5646486b 100644 --- a/apps/svelte.dev/content/docs/kit/20-core-concepts/60-remote-functions.md +++ b/apps/svelte.dev/content/docs/kit/20-core-concepts/60-remote-functions.md @@ -173,9 +173,62 @@ Any query can be re-fetched via its `refresh` method, which retrieves the latest > [!NOTE] Queries are cached while they're on the page, meaning `getPosts() === getPosts()`. This means you don't need a reference like `const posts = getPosts()` in order to update the query. +## query.batch + +`query.batch` works like `query` except that it batches requests that happen within the same macrotask. This solves the so-called n+1 problem: rather than each query resulting in a separate database call (for example), simultaneous queries are grouped together. + +On the server, the callback receives an array of the arguments the function was called with. It must return a function of the form `(input: Input, index: number) => Output`. SvelteKit will then call this with each of the input arguments to resolve the individual calls with their results. + +```js +/// file: weather.remote.js +// @filename: ambient.d.ts +declare module '$lib/server/database' { + export function sql(strings: TemplateStringsArray, ...values: any[]): Promise; +} +// @filename: index.js +// ---cut--- +import * as v from 'valibot'; +import { query } from '$app/server'; +import * as db from '$lib/server/database'; + +export const getWeather = query.batch(v.string(), async (cities) => { + const weather = await db.sql` + SELECT * FROM weather + WHERE city = ANY(${cities}) + `; + const lookup = new Map(weather.map(w => [w.city, w])); + + return (city) => lookup.get(city); +}); +``` + +```svelte + + + +

Weather

+ +{#each cities.slice(0, limit) as city} +

{city.name}

+ +{/each} + +{#if cities.length > limit} + +{/if} +``` + ## form -The `form` function makes it easy to write data to the server. It takes a callback that receives the current [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData)... +The `form` function makes it easy to write data to the server. It takes a callback that receives `data` constructed from the submitted [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData)... ```ts @@ -207,30 +260,28 @@ export const getPosts = query(async () => { /* ... */ }); export const getPost = query(v.string(), async (slug) => { /* ... */ }); -export const createPost = form(async (data) => { - // Check the user is logged in - const user = await auth.getUser(); - if (!user) error(401, 'Unauthorized'); - - const title = data.get('title'); - const content = data.get('content'); - - // Check the data is valid - if (typeof title !== 'string' || typeof content !== 'string') { - error(400, 'Title and content are required'); +export const createPost = form( + v.object({ + title: v.pipe(v.string(), v.nonEmpty()), + content:v.pipe(v.string(), v.nonEmpty()) + }), + async ({ title, content }) => { + // Check the user is logged in + const user = await auth.getUser(); + if (!user) error(401, 'Unauthorized'); + + const slug = title.toLowerCase().replace(/ /g, '-'); + + // Insert into the database + await db.sql` + INSERT INTO post (slug, title, content) + VALUES (${slug}, ${title}, ${content}) + `; + + // Redirect to the newly created page + redirect(303, `/blog/${slug}`); } - - const slug = title.toLowerCase().replace(/ /g, '-'); - - // Insert into the database - await db.sql` - INSERT INTO post (slug, title, content) - VALUES (${slug}, ${title}, ${content}) - `; - - // Redirect to the newly created page - redirect(303, `/blog/${slug}`); -}); +); ``` ...and returns an object that can be spread onto a `
` element. The callback is called whenever the form is submitted. @@ -258,7 +309,184 @@ export const createPost = form(async (data) => {
``` -The form object contains `method` and `action` properties that allow it to work without JavaScript (i.e. it submits data and reloads the page). It also has an `onsubmit` handler that progressively enhances the form when JavaScript is available, submitting data *without* reloading the entire page. +As with `query`, if the callback uses the submitted `data`, it should be [validated](#query-Query-arguments) by passing a [Standard Schema](https://standardschema.dev) as the first argument to `form`. The one difference is to `query` is that the schema inputs must all be of type `string` or `File`, since that's all the original `FormData` provides. You can however coerce the value into a different type — how to do that depends on the validation library you use. + +```ts +/// file: src/routes/count.remote.js +import * as v from 'valibot'; +import { form } from '$app/server'; + +export const setCount = form( + v.object({ + // Valibot: + count: v.pipe(v.string(), v.transform((s) => Number(s)), v.number()), + // Zod: + // count: z.coerce.number() + }), + async ({ count }) => { + // ... + } +); +``` + +The `name` attributes on the form controls must correspond to the properties of the schema — `title` and `content` in this case. If you schema contains objects, use object notation: + +```svelte + + + +{#each jobs as job, idx} + + +{/each} +``` + +To indicate a repeated field, use a `[]` suffix: + +```svelte + + + +``` + +If you'd like type safety and autocomplete when setting `name` attributes, use the form object's `field` method: + +```svelte + +``` + +This will error during typechecking if `title` does not exist on your schema. + +The form object contains `method` and `action` properties that allow it to work without JavaScript (i.e. it submits data and reloads the page). It also has an [attachment](/docs/svelte/@attach) that progressively enhances the form when JavaScript is available, submitting data *without* reloading the entire page. + +### Validation + +If the submitted data doesn't pass the schema, the callback will not run. Instead, the form object's `issues` object will be populated: + +```svelte +
+ + + + + +
+``` + +You don't need to wait until the form is submitted to validate the data — you can call `validate()` programmatically, for example in an `oninput` callback (which will validate the data on every keystroke) or an `onchange` callback: + +```svelte +
createPost.validate()}> + +
+``` + +By default, issues will be ignored if they belong to form controls that haven't yet been interacted with. To validate _all_ inputs, call `validate({ includeUntouched: true })`. + +For client-side validation, you can specify a _preflight_ schema which will populate `issues` and prevent data being sent to the server if the data doesn't validate: + +```svelte + + +

Create a new post

+ +
+ +
+``` + +> [!NOTE] The preflight schema can be the same object as your server-side schema, if appropriate, though it won't be able to do server-side checks like 'this value already exists in the database'. Note that you cannot export a schema from a `.remote.ts` or `.remote.js` file, so the schema must either be exported from a shared module, or from a ` + + + + { + // Simulate a user filling out the form + await userEvent.type(canvas.getByTestId('email'), 'email@provider.com'); + await userEvent.type(canvas.getByTestId('password'), 'a-random-password'); + await userEvent.click(canvas.getByRole('button')); + + // Run assertions + await expect(args.onSubmit).toHaveBeenCalledTimes(1); + await expect(canvas.getByText('You’re in!')).toBeInTheDocument(); + }} +/> +``` + ## E2E tests using Playwright E2E (short for 'end to end') tests allow you to test your full application through the eyes of the user. This section uses [Playwright](https://playwright.dev/) as an example, but you can also use other solutions like [Cypress](https://www.cypress.io/) or [NightwatchJS](https://nightwatchjs.org/). diff --git a/apps/svelte.dev/content/docs/svelte/98-reference/.generated/client-warnings.md b/apps/svelte.dev/content/docs/svelte/98-reference/.generated/client-warnings.md index 6f1d677fe9..c95ace2229 100644 --- a/apps/svelte.dev/content/docs/svelte/98-reference/.generated/client-warnings.md +++ b/apps/svelte.dev/content/docs/svelte/98-reference/.generated/client-warnings.md @@ -312,6 +312,27 @@ Reactive `$state(...)` proxies and the values they proxy have different identiti To resolve this, ensure you're comparing values where both values were created with `$state(...)`, or neither were. Note that `$state.raw(...)` will _not_ create a state proxy. +### state_proxy_unmount + +``` +Tried to unmount a state proxy, rather than a component +``` + +`unmount` was called with a state proxy: + +```js +import { mount, unmount } from 'svelte'; +import Component from './Component.svelte'; +let target = document.body; +// ---cut--- +let component = $state(mount(Component, { target })); + +// later... +unmount(component); +``` + +Avoid using `$state` here. If `component` _does_ need to be reactive for some reason, use `$state.raw` instead. + ### svelte_boundary_reset_noop ``` diff --git a/apps/svelte.dev/content/docs/svelte/98-reference/.generated/server-errors.md b/apps/svelte.dev/content/docs/svelte/98-reference/.generated/server-errors.md index c3e8b53c31..6263032212 100644 --- a/apps/svelte.dev/content/docs/svelte/98-reference/.generated/server-errors.md +++ b/apps/svelte.dev/content/docs/svelte/98-reference/.generated/server-errors.md @@ -1,5 +1,19 @@ +### await_invalid + +``` +Encountered asynchronous work while rendering synchronously. +``` + +You (or the framework you're using) called [`render(...)`](svelte-server#render) with a component containing an `await` expression. Either `await` the result of `render` or wrap the `await` (or the component containing it) in a [``](svelte-boundary) with a `pending` snippet. + +### html_deprecated + +``` +The `html` property of server render results has been deprecated. Use `body` instead. +``` + ### lifecycle_function_unavailable ``` diff --git a/apps/svelte.dev/content/docs/svelte/98-reference/.generated/server-warnings.md b/apps/svelte.dev/content/docs/svelte/98-reference/.generated/server-warnings.md new file mode 100644 index 0000000000..26b3628be9 --- /dev/null +++ b/apps/svelte.dev/content/docs/svelte/98-reference/.generated/server-warnings.md @@ -0,0 +1,9 @@ + + +### experimental_async_ssr + +``` +Attempted to use asynchronous rendering without `experimental.async` enabled +``` + +Set `experimental.async: true` in your compiler options (usually in `svelte.config.js`) to use async server rendering. This render ran synchronously. diff --git a/apps/svelte.dev/content/docs/svelte/98-reference/.generated/shared-errors.md b/apps/svelte.dev/content/docs/svelte/98-reference/.generated/shared-errors.md index de34b3f5da..6c31aaafd0 100644 --- a/apps/svelte.dev/content/docs/svelte/98-reference/.generated/shared-errors.md +++ b/apps/svelte.dev/content/docs/svelte/98-reference/.generated/shared-errors.md @@ -1,25 +1,5 @@ -### await_outside_boundary - -``` -Cannot await outside a `` with a `pending` snippet -``` - -The `await` keyword can only appear in a `$derived(...)` or template expression, or at the top level of a component's ` {#snippet main()} - + {#key iframe_key} + + {/key}
{#if bundle?.error} diff --git a/packages/repl/src/lib/Repl.svelte b/packages/repl/src/lib/Repl.svelte index 4565c80f82..bca019c8cf 100644 --- a/packages/repl/src/lib/Repl.svelte +++ b/packages/repl/src/lib/Repl.svelte @@ -127,8 +127,6 @@ ...workspace.current!, contents: migration!.code }); - - rebundle(); } let width = $state(0); @@ -142,7 +140,7 @@ ? new Bundler({ svelte_version: svelteVersion, onversion: (version) => { - workspace.svelte_version = version; + workspace.set_svelte_version(version); onversion?.(version); }, onstatus: (message) => { diff --git a/packages/repl/src/lib/Workspace.svelte.ts b/packages/repl/src/lib/Workspace.svelte.ts index dd89b8460c..a0a027778c 100644 --- a/packages/repl/src/lib/Workspace.svelte.ts +++ b/packages/repl/src/lib/Workspace.svelte.ts @@ -407,14 +407,13 @@ export class Workspace { selected?: string ) { this.states.clear(); - this.set(new_files, selected); - - this.mark_saved(); - this.#tailwind = options.tailwind; this.#aliases = options.aliases; - const bundle = this.#onreset(new_files); + const bundle = this.set(new_files, selected); + + this.mark_saved(); + const diagnostics = this.#reset_diagnostics(); return Promise.all([bundle, diagnostics]) @@ -458,7 +457,7 @@ export class Workspace { } } - this.#onreset?.(this.files); + return this.#onreset?.(this.files); } unlink(view: EditorView) { @@ -507,10 +506,12 @@ export class Workspace { return this.#svelte_version; } - set svelte_version(value) { + set_svelte_version(value: string, notify = false) { this.#svelte_version = value; - this.#update_file(this.#current); - this.#reset_diagnostics(); + if (notify) { + this.#update_file(this.#current); + this.#reset_diagnostics(); + } } get vim() { diff --git a/packages/repl/src/lib/workers/bundler/index.ts b/packages/repl/src/lib/workers/bundler/index.ts index 6e84324a03..1a35db2918 100644 --- a/packages/repl/src/lib/workers/bundler/index.ts +++ b/packages/repl/src/lib/workers/bundler/index.ts @@ -76,7 +76,11 @@ self.addEventListener('message', async (event: MessageEvent) console.log('[bundle worker result]', result); - if (JSON.stringify(result.error) === JSON.stringify(ABORT)) return; + // error object might be augmented, see https://github.com/rollup/rollup/blob/76a3b8ede4729a71eb522fc29f7d550a4358827b/docs/plugin-development/index.md#thiserror, + // hence only check that the specific abort property we set is there + if ((result.error as any)?.svelte_bundler_aborted === ABORT.svelte_bundler_aborted) { + return; + } if (result && uid === current_id) postMessage(result); }); } catch (e) { @@ -111,7 +115,7 @@ function get_svelte(svelte_version: string) { return ready; } -const ABORT = { aborted: true }; +const ABORT = { svelte_bundler_aborted: true }; let previous: { key: string; diff --git a/packages/repl/src/lib/workers/bundler/plugins/commonjs.ts b/packages/repl/src/lib/workers/bundler/plugins/commonjs.ts index 20d569c945..7840688f59 100644 --- a/packages/repl/src/lib/workers/bundler/plugins/commonjs.ts +++ b/packages/repl/src/lib/workers/bundler/plugins/commonjs.ts @@ -42,6 +42,9 @@ const plugin: Plugin = { context.next(); }, AssignmentExpression: (node, context) => { + // walk children to find nested requires + context.next(); + if (node.operator !== '=') return; if (node.left.type !== 'MemberExpression') return; if (node.left.object.type !== 'Identifier' || node.left.object.name !== 'exports') return; @@ -53,8 +56,6 @@ const plugin: Plugin = { `export const ${node.left.property.name} = module.exports.${node.left.property.name};` ); } - - context.next(); } }); diff --git a/packages/repl/src/lib/workers/typescript-strip-types.ts b/packages/repl/src/lib/workers/typescript-strip-types.ts index 17cc079424..fcefb99512 100644 --- a/packages/repl/src/lib/workers/typescript-strip-types.ts +++ b/packages/repl/src/lib/workers/typescript-strip-types.ts @@ -9,24 +9,32 @@ const ParserWithTS = acorn.Parser.extend(tsPlugin()); * @param {FunctionExpression | FunctionDeclaration} node * @param {Context} context */ -function remove_this_param( +function remove_this_param_and_optional( node: acorn.FunctionExpression | acorn.FunctionDeclaration, context: Context ) { - const param = node.params[0] as any; - if (param?.type === 'Identifier' && param.name === 'this') { - if (param.typeAnnotation) { - // the type annotation is blanked by another visitor, do it in two parts to prevent an overwrite error - ts_blank_space(context, { start: param.start, end: param.typeAnnotation.start }); - ts_blank_space(context, { - start: param.typeAnnotation.end, - end: node.params[1]?.start || param.end - }); - } else { - ts_blank_space(context, { - start: param.start, - end: node.params[1]?.start || param.end - }); + for (const param of node.params as Array>) { + if (param?.type === 'Identifier') { + if (param.name === 'this') { + if (param.typeAnnotation) { + // the type annotation is blanked by another visitor, do it in two parts to prevent an overwrite error + ts_blank_space(context, { start: param.start, end: param.typeAnnotation.start }); + ts_blank_space(context, { + start: param.typeAnnotation.end, + end: node.params[1]?.start || param.end + }); + } else { + ts_blank_space(context, { + start: param.start, + end: node.params[1]?.start || param.end + }); + } + } else if (param.optional) { + const question_start = context.state.ms.original.indexOf('?', param.start); + if (question_start !== -1 && question_start < param.end) { + ts_blank_space(context, { start: question_start, end: question_start + 1 }); + } + } } } return context.next(); @@ -83,6 +91,12 @@ const visitors: Visitors = { ts_blank_space(context, { start: node.start, end: node.start + node.accessibility.length }); } + delete node.typeAnnotation; + delete node.typeParameters; + delete node.typeArguments; + delete node.returnType; + delete node.accessibility; + context.next(); }, Decorator(node, context) { @@ -201,8 +215,8 @@ const visitors: Visitors = { ts_blank_space(context, { start: node.start, end: node.expression.start }); context.visit(node.expression); }, - FunctionExpression: remove_this_param, - FunctionDeclaration: remove_this_param, + FunctionExpression: remove_this_param_and_optional, + FunctionDeclaration: remove_this_param_and_optional, TSDeclareFunction(node, context) { ts_blank_space(context, node); return empty; @@ -239,6 +253,16 @@ const visitors: Visitors = { } context.next(); }, + VariableDeclarator(node, context) { + if (node.definite && node.id.type === 'Identifier') { + const definite_start = context.state.ms.original.indexOf( + '!', + node.id.start + node.id.name.length + ); + ts_blank_space(context, { start: definite_start, end: definite_start + 1 }); + } + context.next(); + }, TSModuleDeclaration(node, context) { if (!node.body) { ts_blank_space(context, node); diff --git a/packages/site-kit/src/lib/codemirror/index.js b/packages/site-kit/src/lib/codemirror/index.js index 24152606a3..be75f54d3c 100644 --- a/packages/site-kit/src/lib/codemirror/index.js +++ b/packages/site-kit/src/lib/codemirror/index.js @@ -25,13 +25,18 @@ const logic_block_snippets = [ label: '#await :then', type: 'keyword' }), - snippetCompletion('#key ${}}\n\n{/key', { label: '#key', type: 'keyword' }) + snippetCompletion('#key ${}}\n\n{/key', { label: '#key', type: 'keyword' }), + snippetCompletion('#snippet ${}()}\n\n{/snippet', { + label: '#snippet', + type: 'keyword' + }) ]; const special_tag_snippets = [ snippetCompletion('@html ${}', { label: '@html', type: 'keyword' }), snippetCompletion('@debug ${}', { label: '@debug', type: 'keyword' }), - snippetCompletion('@const ${}', { label: '@const', type: 'keyword' }) + snippetCompletion('@const ${}', { label: '@const', type: 'keyword' }), + snippetCompletion('@render ${}()', { label: '@render', type: 'keyword' }) ]; /** diff --git a/packages/site-kit/src/lib/nav/MobileMenu.svelte b/packages/site-kit/src/lib/nav/MobileMenu.svelte index 98fa16fe1b..a1c6a2cd29 100644 --- a/packages/site-kit/src/lib/nav/MobileMenu.svelte +++ b/packages/site-kit/src/lib/nav/MobileMenu.svelte @@ -147,7 +147,9 @@
diff --git a/packages/site-kit/src/lib/nav/Nav.svelte b/packages/site-kit/src/lib/nav/Nav.svelte index b71147ad06..d6dd5b5e0f 100644 --- a/packages/site-kit/src/lib/nav/Nav.svelte +++ b/packages/site-kit/src/lib/nav/Nav.svelte @@ -6,7 +6,7 @@ Top navigation bar for the application. It provides a slot for the left side, th import { overlay_open, on_this_page_open } from '../stores'; import { search } from '../state/search.svelte'; import Icon from '../components/Icon.svelte'; - import { page } from '$app/stores'; + import { page } from '$app/state'; import ThemeToggle from '../components/ThemeToggle.svelte'; import MobileMenu from './MobileMenu.svelte'; import type { NavigationLink } from '../types'; @@ -86,7 +86,7 @@ Top navigation bar for the application. It provides a slot for the left side, th {link.title} @@ -99,8 +99,8 @@ Top navigation bar for the application. It provides a slot for the left side, th @@ -113,7 +113,7 @@ Top navigation bar for the application. It provides a slot for the left side, th {:else} {link.title} @@ -133,7 +133,7 @@ Top navigation bar for the application. It provides a slot for the left side, th - + @@ -169,7 +169,7 @@ Top navigation bar for the application. It provides a slot for the left side, th open = !open; if (open) { - const segment = $page.url.pathname.split('/')[1]; + const segment = page.url.pathname.split('/')[1]; current = links.find((link) => link.slug === segment); } }} diff --git a/packages/site-kit/src/lib/search/SearchBox.svelte b/packages/site-kit/src/lib/search/SearchBox.svelte index 8950621681..a59ec7b4a3 100644 --- a/packages/site-kit/src/lib/search/SearchBox.svelte +++ b/packages/site-kit/src/lib/search/SearchBox.svelte @@ -408,6 +408,7 @@ It appears when the user clicks on the `Search` component or presses the corresp .results { overflow: auto; overscroll-behavior-y: none; + scrollbar-color: var(--sk-scrollbar) var(--sk-bg-2); } .results-container { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2f2912f035..c31f57c991 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,7 +31,7 @@ importers: version: 2.0.0(svelte@5.38.2) '@sveltejs/amp': specifier: ^1.1.5 - version: 1.1.5(@sveltejs/kit@2.37.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4))) + version: 1.1.5(@sveltejs/kit@2.42.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4))) '@sveltejs/repl': specifier: workspace:* version: link:../../packages/repl @@ -52,7 +52,7 @@ importers: version: 1.3.2 '@vercel/speed-insights': specifier: ^1.1.0 - version: 1.1.0(@sveltejs/kit@2.37.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2) + version: 1.1.0(@sveltejs/kit@2.42.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2) '@webcontainer/api': specifier: ^1.1.5 version: 1.1.9 @@ -113,13 +113,13 @@ importers: version: 2.43.4 '@sveltejs/adapter-vercel': specifier: ^5.10.2 - version: 5.10.2(@sveltejs/kit@2.37.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(rollup@4.46.4) + version: 5.10.2(@sveltejs/kit@2.42.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(rollup@4.46.4) '@sveltejs/enhanced-img': specifier: ^0.8.1 version: 0.8.1(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(rollup@4.46.4)(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)) '@sveltejs/kit': - specifier: ^2.37.0 - version: 2.37.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)) + specifier: ^2.42.0 + version: 2.42.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)) '@sveltejs/site-kit': specifier: workspace:* version: link:../../packages/site-kit @@ -1343,8 +1343,8 @@ packages: '@opentelemetry/api': optional: true - '@sveltejs/kit@2.37.0': - resolution: {integrity: sha512-xgKtpjQ6Ry4mdShd01ht5AODUsW7+K1iValPDq7QX8zI1hWOKREH9GjG8SRCN5tC4K7UXmMhuQam7gbLByVcnw==} + '@sveltejs/kit@2.42.0': + resolution: {integrity: sha512-ujAqGi88jAHL0eC5OAuH/w9X8uyPEJnFM4Pq6hjO0QARtlVPMKRd5yL5tQ4V9Ts+EHE5JH60CIUAhuUGUxwBUQ==} engines: {node: '>=18.13'} hasBin: true peerDependencies: @@ -4052,9 +4052,9 @@ snapshots: dependencies: '@sveltejs/kit': 2.34.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@24.3.0)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@24.3.0)(lightningcss@1.30.1)(tsx@4.20.4)) - '@sveltejs/adapter-vercel@5.10.2(@sveltejs/kit@2.37.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(rollup@4.46.4)': + '@sveltejs/adapter-vercel@5.10.2(@sveltejs/kit@2.42.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(rollup@4.46.4)': dependencies: - '@sveltejs/kit': 2.37.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)) + '@sveltejs/kit': 2.42.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)) '@vercel/nft': 0.30.0(rollup@4.46.4) esbuild: 0.25.9 transitivePeerDependencies: @@ -4062,9 +4062,9 @@ snapshots: - rollup - supports-color - '@sveltejs/amp@1.1.5(@sveltejs/kit@2.37.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))': + '@sveltejs/amp@1.1.5(@sveltejs/kit@2.42.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))': dependencies: - '@sveltejs/kit': 2.37.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)) + '@sveltejs/kit': 2.42.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)) '@sveltejs/enhanced-img@0.8.1(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(rollup@4.46.4)(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4))': dependencies: @@ -4117,7 +4117,7 @@ snapshots: svelte: 5.38.2 vite: 7.0.4(@types/node@24.3.0)(lightningcss@1.30.1)(tsx@4.20.4) - '@sveltejs/kit@2.37.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4))': + '@sveltejs/kit@2.42.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4))': dependencies: '@standard-schema/spec': 1.0.0 '@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0) @@ -4299,9 +4299,9 @@ snapshots: - rollup - supports-color - '@vercel/speed-insights@1.1.0(@sveltejs/kit@2.37.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)': + '@vercel/speed-insights@1.1.0(@sveltejs/kit@2.42.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)': optionalDependencies: - '@sveltejs/kit': 2.37.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)) + '@sveltejs/kit': 2.42.0(@sveltejs/vite-plugin-svelte@6.1.3(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)))(svelte@5.38.2)(vite@7.0.4(@types/node@20.19.6)(lightningcss@1.30.1)(tsx@4.20.4)) svelte: 5.38.2 '@vitest/expect@3.2.4':